I'm not drawing the edges yet.
Tested with file 'input' which was generated using unfurl.lua.
HMH2GYB6BLH4HE7N6J6ZK57RKFICWXSU3KJL7EGYTXJ5DC5XHBIQC json = require 'json'https = require 'ssl.https'-- Construct an URL to query the Mastodon API.-- I have no idea if ActivityPub carves out the id space between federating-- hosts (how would it even do that?!) so I'm going to remember two things for-- each Mastodon link: a host and an id. The host includes the protocol.function url_from_ml(ml)return ('%s/api/v1/statuses/%d'):format(ml.host, ml.id)end-- We can parse the Mastodon link from the following formats:-- https://merveilles.town/users/bd/statuses/109791902220118251-- https://merveilles.town/@bd/109791902220118251function ml_from_url(url)local host, user, id = url:match('^([^/]*://[^/]*)/@([^/]*)/(%d*)$')if host then return {host=host, user=user, id=id} endlocal host, user, id = url:match('^([^/]*://[^/]*)/users/([^/]*)/statuses/(%d*)$')if host then return {host=host, user=user, id=id} endend-- Given a mastodon link, return all information about it.function get(ml)local url = url_from_ml(ml)local response, code, response_headers, status = https.request(url)local basic_info = json.decode(response)local response, code, response_headers, status = https.request(url..'/context')local rels = json.decode(response)return {host=ml.host, user=ml.user, id=ml.id, url=basic_info.url, content=basic_info.content, replies_count=basic_info.replies_count, ancestors=rels.ancestors, descendants=rels.descendants}endposts = {}to_process = {}if #arg == 0 thenio.stderr:write('provide a Mastodon URL on the command line\n')os.exit(1)endlocal result = get(ml_from_url(arg[1]))if result.ancestors thenresult = get(ml_from_url(result.ancestors[1].url))endlocal filename = os.tmpname()local f = io.open(filename, 'w')f:write(json.encode(result))f:close()print(filename)--? os.execute('love . '..filename)--? os.remove(filename)
{"id": "108484209780107901","descendants": [{"mentions": [{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"},{"id": "106796781598736714","url": "https://merveilles.town/@klardotsh","acct": "klardotsh","username": "klardotsh"},{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"}],"created_at": "2022-06-16T01:56:46.299Z","in_reply_to_id": "108484209780107901","visibility": "unlisted","replies_count": 0,"media_attachments": [],"url": "https://merveilles.town/@peregrine/108484664118600227","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\">@<span>neauoire</span></a></span> <span class=\"h-card\"><a href=\"https://merveilles.town/@klardotsh\" class=\"u-url mention\">@<span>klardotsh</span></a></span> <span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\">@<span>akkartik</span></a></span> mine was running really well with alpine/postmarketos but then it stopped working suddenly. I\u2019ve got the probe to debug it but time is a premium.</p>","account": {"display_name": "Jason","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/008/386/original/eb73c0e860fabb04.jpg","following_count": 433,"header": "https://merveilles.town/headers/original/missing.png","last_status_at": "2023-02-04","acct": "peregrine","bot": false,"discoverable": false,"fields": [{"name": "Site","value": "<a href=\"https://www.jasonstiebs.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">jasonstiebs.com</span><span class=\"invisible\"></span></a>","verified_at": "2019-07-24T14:19:15.619+00:00"}],"header_static": "https://merveilles.town/headers/original/missing.png","emojis": [],"url": "https://merveilles.town/@peregrine","noindex": true,"statuses_count": 3605,"locked": false,"followers_count": 410,"group": false,"created_at": "2019-01-08T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/008/386/original/eb73c0e860fabb04.jpg","id": "8386","note": "<p>To strive, to seek, to find, and not to yield.</p>","username": "peregrine"},"favourites_count": 0,"in_reply_to_account_id": "5","tags": [],"id": "108484664118600227","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/peregrine/statuses/108484664118600227","local_only": false,"language": "en"},{"mentions": [{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"}],"created_at": "2022-06-16T02:32:21.276Z","in_reply_to_id": "108484209780107901","visibility": "unlisted","replies_count": 1,"media_attachments": [],"url": "https://merveilles.town/@akkartik/108484804035996290","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\">@<span>neauoire</span></a></span> So starting Love2d destabilizes _other programs_ running on the same computer?!</p>","account": {"display_name": "Kartik Agaram","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","following_count": 175,"header": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","last_status_at": "2023-02-04","acct": "akkartik","bot": false,"discoverable": true,"fields": [{"name": "Bio","value": "<a href=\"http://akkartik.name/about\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">akkartik.name/about</span><span class=\"invisible\"></span></a>","verified_at": "2022-06-02T20:56:23.240+00:00"},{"name": "Subcultures","value": "<a href=\"https://futureofcoding.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">futureofcoding.org</span><span class=\"invisible\"></span></a>, <a href=\"https://ribbonfarm.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">ribbonfarm.com</span><span class=\"invisible\"></span></a>, <a href=\"http://arclanguage.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">arclanguage.org</span><span class=\"invisible\"></span></a>"}],"header_static": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","emojis": [],"url": "https://merveilles.town/@akkartik","noindex": false,"statuses_count": 2903,"locked": false,"followers_count": 947,"group": false,"created_at": "2020-10-29T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","id": "97481","note": "<p>Building simple, low-maintenance programs that reward curiosity about their internals.</p>","username": "akkartik"},"favourites_count": 0,"in_reply_to_account_id": "5","tags": [],"id": "108484804035996290","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/akkartik/statuses/108484804035996290","local_only": false,"language": "en"},{"mentions": [{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"}],"created_at": "2022-06-16T15:13:34.810Z","in_reply_to_id": "108484804035996290","visibility": "unlisted","replies_count": 1,"media_attachments": [],"url": "https://merveilles.town/@neauoire/108487797296779644","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\">@<span>akkartik</span></a></span> yes, I remember uxn had that same issue a while back, it might be a sdl issue.</p>","account": {"display_name": "Devine Lu Linvega","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/000/005/original/58e2b4d75f889a43.jpg","following_count": 918,"header": "https://assets.merveilles.town/accounts/headers/000/000/005/original/de27e6ccfcb5bb96.jpg","last_status_at": "2023-02-05","acct": "neauoire","bot": false,"discoverable": true,"fields": [{"name": "memex","value": "<a href=\"https://wiki.xxiivv.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">wiki.xxiivv.com</span><span class=\"invisible\"></span></a>"},{"name": "seasteading","value": "<a href=\"https://100r.co\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">100r.co</span><span class=\"invisible\"></span></a>"},{"name": "pronouns","value": "they/them"},{"name": "b12 deficient","value": ""}],"header_static": "https://assets.merveilles.town/accounts/headers/000/000/005/original/de27e6ccfcb5bb96.jpg","emojis": [],"url": "https://merveilles.town/@neauoire","noindex": true,"statuses_count": 58107,"locked": false,"followers_count": 9512,"group": false,"created_at": "2018-12-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/000/005/original/58e2b4d75f889a43.jpg","id": "5","note": "<p>It\u2019s always night under the ultraviolet sun.</p>","username": "neauoire"},"favourites_count": 1,"in_reply_to_account_id": "97481","tags": [],"id": "108487797296779644","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/neauoire/statuses/108487797296779644","local_only": false,"language": "en"},{"mentions": [{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"}],"created_at": "2022-08-06T00:44:27.301Z","in_reply_to_id": "108487797296779644","visibility": "unlisted","replies_count": 2,"media_attachments": [],"url": "https://merveilles.town/@akkartik/108773157588384635","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\">@<span>neauoire</span></a></span> I've been thinking about this thread today. As I've been spending more time in my note-taking app, my computer has been heating up. I'll probably soon need to dig into the memory footprint of pensive.love. Which makes me wonder what life is like in a parallel universe where I accepted the 16-bit restriction and went with Uxn.</p>","account": {"display_name": "Kartik Agaram","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","following_count": 175,"header": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","last_status_at": "2023-02-04","acct": "akkartik","bot": false,"discoverable": true,"fields": [{"name": "Bio","value": "<a href=\"http://akkartik.name/about\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">akkartik.name/about</span><span class=\"invisible\"></span></a>","verified_at": "2022-06-02T20:56:23.240+00:00"},{"name": "Subcultures","value": "<a href=\"https://futureofcoding.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">futureofcoding.org</span><span class=\"invisible\"></span></a>, <a href=\"https://ribbonfarm.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">ribbonfarm.com</span><span class=\"invisible\"></span></a>, <a href=\"http://arclanguage.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">arclanguage.org</span><span class=\"invisible\"></span></a>"}],"header_static": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","emojis": [],"url": "https://merveilles.town/@akkartik","noindex": false,"statuses_count": 2903,"locked": false,"followers_count": 947,"group": false,"created_at": "2020-10-29T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","id": "97481","note": "<p>Building simple, low-maintenance programs that reward curiosity about their internals.</p>","username": "akkartik"},"favourites_count": 0,"in_reply_to_account_id": "5","tags": [],"id": "108773157588384635","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/akkartik/statuses/108773157588384635","local_only": false,"language": "en"},{"mentions": [{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"}],"created_at": "2022-08-06T03:12:42.364Z","in_reply_to_id": "108773157588384635","visibility": "unlisted","replies_count": 1,"media_attachments": [],"url": "https://merveilles.town/@neauoire/108773740535209678","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\">@<span>akkartik</span></a></span> I'd prefer to see you build a 16-bit version of Mu based on your own vision of a dream cpu.</p>","account": {"display_name": "Devine Lu Linvega","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/000/005/original/58e2b4d75f889a43.jpg","following_count": 918,"header": "https://assets.merveilles.town/accounts/headers/000/000/005/original/de27e6ccfcb5bb96.jpg","last_status_at": "2023-02-05","acct": "neauoire","bot": false,"discoverable": true,"fields": [{"name": "memex","value": "<a href=\"https://wiki.xxiivv.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">wiki.xxiivv.com</span><span class=\"invisible\"></span></a>"},{"name": "seasteading","value": "<a href=\"https://100r.co\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">100r.co</span><span class=\"invisible\"></span></a>"},{"name": "pronouns","value": "they/them"},{"name": "b12 deficient","value": ""}],"header_static": "https://assets.merveilles.town/accounts/headers/000/000/005/original/de27e6ccfcb5bb96.jpg","emojis": [],"url": "https://merveilles.town/@neauoire","noindex": true,"statuses_count": 58107,"locked": false,"followers_count": 9512,"group": false,"created_at": "2018-12-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/000/005/original/58e2b4d75f889a43.jpg","id": "5","note": "<p>It\u2019s always night under the ultraviolet sun.</p>","username": "neauoire"},"favourites_count": 1,"in_reply_to_account_id": "97481","tags": [],"id": "108773740535209678","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/neauoire/statuses/108773740535209678","local_only": false,"language": "en"},{"mentions": [{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"}],"created_at": "2022-08-06T03:24:16.582Z","in_reply_to_id": "108773740535209678","visibility": "unlisted","replies_count": 1,"media_attachments": [],"url": "https://merveilles.town/@akkartik/108773786031071521","emojis": [{"static_url": "https://assets.merveilles.town/custom_emojis/images/000/097/490/static/c558045d44d97bbe.png","url": "https://assets.merveilles.town/custom_emojis/images/000/097/490/original/c558045d44d97bbe.png","visible_in_picker": true,"shortcode": "pilin"}],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\">@<span>neauoire</span></a></span> :pilin: I still miss Mu but nah, I'm done building things to build things for a while. Now I just want to build things.</p>","account": {"display_name": "Kartik Agaram","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","following_count": 175,"header": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","last_status_at": "2023-02-04","acct": "akkartik","bot": false,"discoverable": true,"fields": [{"name": "Bio","value": "<a href=\"http://akkartik.name/about\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">akkartik.name/about</span><span class=\"invisible\"></span></a>","verified_at": "2022-06-02T20:56:23.240+00:00"},{"name": "Subcultures","value": "<a href=\"https://futureofcoding.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">futureofcoding.org</span><span class=\"invisible\"></span></a>, <a href=\"https://ribbonfarm.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">ribbonfarm.com</span><span class=\"invisible\"></span></a>, <a href=\"http://arclanguage.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">arclanguage.org</span><span class=\"invisible\"></span></a>"}],"header_static": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","emojis": [],"url": "https://merveilles.town/@akkartik","noindex": false,"statuses_count": 2903,"locked": false,"followers_count": 947,"group": false,"created_at": "2020-10-29T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","id": "97481","note": "<p>Building simple, low-maintenance programs that reward curiosity about their internals.</p>","username": "akkartik"},"favourites_count": 2,"in_reply_to_account_id": "5","tags": [],"id": "108773786031071521","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/akkartik/statuses/108773786031071521","local_only": false,"language": "en"},{"mentions": [{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"}],"created_at": "2022-08-06T03:37:47.646Z","in_reply_to_id": "108773786031071521","visibility": "unlisted","replies_count": 0,"media_attachments": [],"url": "https://merveilles.town/@neauoire/108773839184494768","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\">@<span>akkartik</span></a></span> I totally understand. </p><p>Scoping uxn to be a year long project turned out to be a good idea, I haven't actually worked on uxn itself since last winter, and it paid itself over many times since in how it allowed me to actually get things done thereafter.</p><p>Well, in any case, if you're ever tired of your fancyful 32 bits, I'd be happy to help you figure out how to twist uxntal into fun hings.</p>","account": {"display_name": "Devine Lu Linvega","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/000/005/original/58e2b4d75f889a43.jpg","following_count": 918,"header": "https://assets.merveilles.town/accounts/headers/000/000/005/original/de27e6ccfcb5bb96.jpg","last_status_at": "2023-02-05","acct": "neauoire","bot": false,"discoverable": true,"fields": [{"name": "memex","value": "<a href=\"https://wiki.xxiivv.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">wiki.xxiivv.com</span><span class=\"invisible\"></span></a>"},{"name": "seasteading","value": "<a href=\"https://100r.co\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">100r.co</span><span class=\"invisible\"></span></a>"},{"name": "pronouns","value": "they/them"},{"name": "b12 deficient","value": ""}],"header_static": "https://assets.merveilles.town/accounts/headers/000/000/005/original/de27e6ccfcb5bb96.jpg","emojis": [],"url": "https://merveilles.town/@neauoire","noindex": true,"statuses_count": 58107,"locked": false,"followers_count": 9512,"group": false,"created_at": "2018-12-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/000/005/original/58e2b4d75f889a43.jpg","id": "5","note": "<p>It\u2019s always night under the ultraviolet sun.</p>","username": "neauoire"},"favourites_count": 1,"in_reply_to_account_id": "97481","tags": [],"id": "108773839184494768","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/neauoire/statuses/108773839184494768","local_only": false,"language": "en"},{"mentions": [{"id": "119861","url": "https://mathstodon.xyz/@Chartodon","acct": "Chartodon@mathstodon.xyz","username": "Chartodon"},{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"},{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"}],"sensitive": false,"in_reply_to_id": "108773157588384635","visibility": "unlisted","replies_count": 1,"media_attachments": [],"spoiler_text": "","url": "https://mathstodon.xyz/@ColinTheMathmo/108777555755564003","content": "<p>Calling <span class=\"h-card\"><a href=\"https://mathstodon.xyz/@Chartodon\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>Chartodon</span></a></span> ...</p><p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>akkartik</span></a></span> <span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>neauoire</span></a></span></p>","emojis": [],"language": "en","uri": "https://mathstodon.xyz/users/ColinTheMathmo/statuses/108777555755564003","tags": [],"id": "108777631981309044","activity_pub_type": "Note","account": {"display_name": "Colin the Mathmo","avatar_static": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","following_count": 5690,"header": "https://merveilles.town/headers/original/missing.png","last_status_at": "2023-02-04","acct": "ColinTheMathmo@mathstodon.xyz","bot": false,"discoverable": true,"header_static": "https://merveilles.town/headers/original/missing.png","fields": [{"name": "Web site","value": "<a href=\"https://www.solipsys.co.uk\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">solipsys.co.uk</span><span class=\"invisible\"></span></a>","verified_at": "2022-11-25T17:54:39.472+00:00"},{"name": "Pronouns","value": "He/Him"}],"url": "https://mathstodon.xyz/@ColinTheMathmo","emojis": [],"statuses_count": 18127,"locked": false,"followers_count": 3071,"group": false,"created_at": "2017-04-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","id": "7606","note": "<p>Fulltime freelance provider of outreach and enhancement in maths ... I talk a lot. About maths.</p><p>I talk about other stuff too, like ballroom dancing, juggling, unicycling, education, engineering, software, and \"other things\".</p><p>But mostly about maths.</p><p>I tend to follow back, but only if you have something in your profile.</p>","username": "ColinTheMathmo"},"created_at": "2022-08-06T19:22:58.000Z","favourites_count": 0,"reblogs_count": 0,"in_reply_to_account_id": "97481"},{"mentions": [{"id": "7606","url": "https://mathstodon.xyz/@ColinTheMathmo","acct": "ColinTheMathmo@mathstodon.xyz","username": "ColinTheMathmo"}],"sensitive": false,"in_reply_to_id": "108777631981309044","visibility": "public","replies_count": 1,"media_attachments": [],"spoiler_text": "","url": "https://mathstodon.xyz/@Chartodon/108777592043247122","content": "<p><span class=\"h-card\"><a href=\"https://mathstodon.xyz/@ColinTheMathmo\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>ColinTheMathmo</span></a></span></p><p>Your chart is ready, and can be found here:</p><p><a href=\"https://www.solipsys.co.uk/Chartodon/108777555755564003.svg\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"ellipsis\">solipsys.co.uk/Chartodon/10877</span><span class=\"invisible\">7555755564003.svg</span></a></p><p>Things may have changed since I started compiling that, and some things may have been inaccessible.</p><p>In particular, the very nature of the fediverse means some toots may never have made it to my instance, in which case I can't see them, and can't include them.</p><p>The chart will eventually be deleted, so if you'd like to keep it, make sure you download a copy.</p>","emojis": [],"language": "en","uri": "https://mathstodon.xyz/users/Chartodon/statuses/108777592043247122","tags": [],"id": "108777676497099592","activity_pub_type": "Note","account": {"display_name": "","avatar_static": "https://assets.merveilles.town/cache/accounts/avatars/000/119/861/original/f72319f1c4abc0ff.png","following_count": 5,"header": "https://merveilles.town/headers/original/missing.png","last_status_at": "2023-01-27","acct": "Chartodon@mathstodon.xyz","bot": false,"discoverable": false,"header_static": "https://merveilles.town/headers/original/missing.png","fields": [{"name": "Current Status","value": "Dormant"},{"name": "Awaiting","value": "Final testing"}],"url": "https://mathstodon.xyz/@Chartodon","emojis": [],"statuses_count": 502,"locked": false,"followers_count": 167,"group": false,"created_at": "2021-04-04T00:00:00.000Z","avatar": "https://assets.merveilles.town/cache/accounts/avatars/000/119/861/original/f72319f1c4abc0ff.png","id": "119861","note": "<p>Experimental account to provide charts of discussions. </p><p>Invoke me by replying to a toot with a single line saying \"Calling <span class=\"h-card\"><a href=\"https://mathstodon.xyz/@Chartodon\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>Chartodon</span></a></span>\".</p><p>I may take a while to reply, depending on how busy I am, and how extensive the discussion.</p><p>Currently I'm being upgraded to take a parameter that changes the rendering, but that's still in progress. To see the status, reply to a post with this:</p><p>\"Calling <span class=\"h-card\"><a href=\"https://mathstodon.xyz/@Chartodon\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>Chartodon</span></a></span> Help\"</p>","username": "Chartodon"},"created_at": "2022-08-06T19:32:11.000Z","favourites_count": 0,"reblogs_count": 0,"in_reply_to_account_id": "7606"},{"mentions": [{"id": "7606","url": "https://mathstodon.xyz/@ColinTheMathmo","acct": "ColinTheMathmo@mathstodon.xyz","username": "ColinTheMathmo"},{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"},{"id": "119861","url": "https://mathstodon.xyz/@Chartodon","acct": "Chartodon@mathstodon.xyz","username": "Chartodon"}],"created_at": "2022-08-06T20:59:35.170Z","in_reply_to_id": "108777676497099592","visibility": "public","replies_count": 2,"media_attachments": [],"url": "https://merveilles.town/@akkartik/108777935677948998","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://mathstodon.xyz/@ColinTheMathmo\" class=\"u-url mention\">@<span>ColinTheMathmo</span></a></span> To my infinite regret, I accidentally delete-and-redrafted the wrong post so you can't tell what <span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\">@<span>neauoire</span></a></span> is responding to up top. For future reference, here's the question that started this thread:</p><p>"On uxn do you find yourself more frequently running out of time or memory?"</p><p><span class=\"h-card\"><a href=\"https://mathstodon.xyz/@Chartodon\" class=\"u-url mention\">@<span>Chartodon</span></a></span></p>","account": {"display_name": "Kartik Agaram","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","following_count": 175,"header": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","last_status_at": "2023-02-04","acct": "akkartik","bot": false,"discoverable": true,"fields": [{"name": "Bio","value": "<a href=\"http://akkartik.name/about\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">akkartik.name/about</span><span class=\"invisible\"></span></a>","verified_at": "2022-06-02T20:56:23.240+00:00"},{"name": "Subcultures","value": "<a href=\"https://futureofcoding.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">futureofcoding.org</span><span class=\"invisible\"></span></a>, <a href=\"https://ribbonfarm.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">ribbonfarm.com</span><span class=\"invisible\"></span></a>, <a href=\"http://arclanguage.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">arclanguage.org</span><span class=\"invisible\"></span></a>"}],"header_static": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","emojis": [],"url": "https://merveilles.town/@akkartik","noindex": false,"statuses_count": 2903,"locked": false,"followers_count": 947,"group": false,"created_at": "2020-10-29T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","id": "97481","note": "<p>Building simple, low-maintenance programs that reward curiosity about their internals.</p>","username": "akkartik"},"favourites_count": 0,"in_reply_to_account_id": "119861","tags": [],"id": "108777935677948998","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/akkartik/statuses/108777935677948998","local_only": false,"language": "en"},{"mentions": [{"id": "7606","url": "https://mathstodon.xyz/@ColinTheMathmo","acct": "ColinTheMathmo@mathstodon.xyz","username": "ColinTheMathmo"},{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"},{"id": "119861","url": "https://mathstodon.xyz/@Chartodon","acct": "Chartodon@mathstodon.xyz","username": "Chartodon"}],"created_at": "2022-08-06T21:18:48.723Z","in_reply_to_id": "108777935677948998","visibility": "public","replies_count": 1,"media_attachments": [],"url": "https://merveilles.town/@akkartik/108778011277220784","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://mathstodon.xyz/@ColinTheMathmo\" class=\"u-url mention\">@<span>ColinTheMathmo</span></a></span> <span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\">@<span>neauoire</span></a></span> <span class=\"h-card\"><a href=\"https://mathstodon.xyz/@Chartodon\" class=\"u-url mention\">@<span>Chartodon</span></a></span> Whoa, I had no idea so much happened on this thread.</p>","account": {"display_name": "Kartik Agaram","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","following_count": 175,"header": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","last_status_at": "2023-02-04","acct": "akkartik","bot": false,"discoverable": true,"fields": [{"name": "Bio","value": "<a href=\"http://akkartik.name/about\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">akkartik.name/about</span><span class=\"invisible\"></span></a>","verified_at": "2022-06-02T20:56:23.240+00:00"},{"name": "Subcultures","value": "<a href=\"https://futureofcoding.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">futureofcoding.org</span><span class=\"invisible\"></span></a>, <a href=\"https://ribbonfarm.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">ribbonfarm.com</span><span class=\"invisible\"></span></a>, <a href=\"http://arclanguage.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">arclanguage.org</span><span class=\"invisible\"></span></a>"}],"header_static": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","emojis": [],"url": "https://merveilles.town/@akkartik","noindex": false,"statuses_count": 2903,"locked": false,"followers_count": 947,"group": false,"created_at": "2020-10-29T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","id": "97481","note": "<p>Building simple, low-maintenance programs that reward curiosity about their internals.</p>","username": "akkartik"},"favourites_count": 0,"in_reply_to_account_id": "119861","tags": [],"id": "108778011277220784","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/akkartik/statuses/108778011277220784","local_only": false,"language": "en"},{"mentions": [{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"},{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"}],"sensitive": false,"in_reply_to_id": "108778011277220784","visibility": "public","replies_count": 0,"media_attachments": [],"spoiler_text": "","url": "https://mathstodon.xyz/@ColinTheMathmo/108778517362369814","content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>akkartik</span></a></span> That's part of the value of Chartodon ... so often it unearths corners of a conversation you never knew existed.</p><p><span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>neauoire</span></a></span></p>","emojis": [],"language": "en","uri": "https://mathstodon.xyz/users/ColinTheMathmo/statuses/108778517362369814","tags": [],"id": "108778819048771769","activity_pub_type": "Note","account": {"display_name": "Colin the Mathmo","avatar_static": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","following_count": 5690,"header": "https://merveilles.town/headers/original/missing.png","last_status_at": "2023-02-04","acct": "ColinTheMathmo@mathstodon.xyz","bot": false,"discoverable": true,"header_static": "https://merveilles.town/headers/original/missing.png","fields": [{"name": "Web site","value": "<a href=\"https://www.solipsys.co.uk\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">solipsys.co.uk</span><span class=\"invisible\"></span></a>","verified_at": "2022-11-25T17:54:39.472+00:00"},{"name": "Pronouns","value": "He/Him"}],"url": "https://mathstodon.xyz/@ColinTheMathmo","emojis": [],"statuses_count": 18127,"locked": false,"followers_count": 3071,"group": false,"created_at": "2017-04-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","id": "7606","note": "<p>Fulltime freelance provider of outreach and enhancement in maths ... I talk a lot. About maths.</p><p>I talk about other stuff too, like ballroom dancing, juggling, unicycling, education, engineering, software, and \"other things\".</p><p>But mostly about maths.</p><p>I tend to follow back, but only if you have something in your profile.</p>","username": "ColinTheMathmo"},"created_at": "2022-08-06T23:27:30.000Z","favourites_count": 1,"reblogs_count": 0,"in_reply_to_account_id": "97481"},{"mentions": [{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"},{"id": "5","url": "https://merveilles.town/@neauoire","acct": "neauoire","username": "neauoire"}],"sensitive": false,"in_reply_to_id": "108777935677948998","visibility": "public","replies_count": 1,"media_attachments": [],"spoiler_text": "","url": "https://mathstodon.xyz/@ColinTheMathmo/108778428454523121","content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>akkartik</span></a></span> If you have a link to the original comment then I can manually cross-link to make the chart more complete.</p><p><span class=\"h-card\"><a href=\"https://merveilles.town/@neauoire\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>neauoire</span></a></span></p>","emojis": [],"language": "en","uri": "https://mathstodon.xyz/users/ColinTheMathmo/statuses/108778428454523121","tags": [],"id": "108778717523358367","activity_pub_type": "Note","account": {"display_name": "Colin the Mathmo","avatar_static": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","following_count": 5690,"header": "https://merveilles.town/headers/original/missing.png","last_status_at": "2023-02-04","acct": "ColinTheMathmo@mathstodon.xyz","bot": false,"discoverable": true,"header_static": "https://merveilles.town/headers/original/missing.png","fields": [{"name": "Web site","value": "<a href=\"https://www.solipsys.co.uk\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">solipsys.co.uk</span><span class=\"invisible\"></span></a>","verified_at": "2022-11-25T17:54:39.472+00:00"},{"name": "Pronouns","value": "He/Him"}],"url": "https://mathstodon.xyz/@ColinTheMathmo","emojis": [],"statuses_count": 18127,"locked": false,"followers_count": 3071,"group": false,"created_at": "2017-04-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","id": "7606","note": "<p>Fulltime freelance provider of outreach and enhancement in maths ... I talk a lot. About maths.</p><p>I talk about other stuff too, like ballroom dancing, juggling, unicycling, education, engineering, software, and \"other things\".</p><p>But mostly about maths.</p><p>I tend to follow back, but only if you have something in your profile.</p>","username": "ColinTheMathmo"},"created_at": "2022-08-06T23:04:54.000Z","favourites_count": 0,"reblogs_count": 0,"in_reply_to_account_id": "97481"},{"mentions": [{"id": "7606","url": "https://mathstodon.xyz/@ColinTheMathmo","acct": "ColinTheMathmo@mathstodon.xyz","username": "ColinTheMathmo"}],"created_at": "2022-08-07T01:46:47.981Z","in_reply_to_id": "108778717523358367","visibility": "public","replies_count": 2,"media_attachments": [],"url": "https://merveilles.town/@akkartik/108779065047526734","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://mathstodon.xyz/@ColinTheMathmo\" class=\"u-url mention\">@<span>ColinTheMathmo</span></a></span> That was the problem: I deleted the original by mistake. And it already had responses so I couldn't fix the issue.</p><p>Maybe just wire up <a href=\"https://merveilles.town/@akkartik/108777935677948998\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">merveilles.town/@akkartik/1087</span><span class=\"invisible\">77935677948998</span></a> and deal with a cycle? \ud83d\ude00</p>","account": {"display_name": "Kartik Agaram","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","following_count": 175,"header": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","last_status_at": "2023-02-04","acct": "akkartik","bot": false,"discoverable": true,"fields": [{"name": "Bio","value": "<a href=\"http://akkartik.name/about\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">akkartik.name/about</span><span class=\"invisible\"></span></a>","verified_at": "2022-06-02T20:56:23.240+00:00"},{"name": "Subcultures","value": "<a href=\"https://futureofcoding.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">futureofcoding.org</span><span class=\"invisible\"></span></a>, <a href=\"https://ribbonfarm.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">ribbonfarm.com</span><span class=\"invisible\"></span></a>, <a href=\"http://arclanguage.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">arclanguage.org</span><span class=\"invisible\"></span></a>"}],"header_static": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","emojis": [],"url": "https://merveilles.town/@akkartik","noindex": false,"statuses_count": 2903,"locked": false,"followers_count": 947,"group": false,"created_at": "2020-10-29T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","id": "97481","note": "<p>Building simple, low-maintenance programs that reward curiosity about their internals.</p>","username": "akkartik"},"favourites_count": 1,"in_reply_to_account_id": "7606","tags": [],"id": "108779065047526734","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/akkartik/statuses/108779065047526734","local_only": false,"language": "en"},{"mentions": [{"id": "7606","url": "https://mathstodon.xyz/@ColinTheMathmo","acct": "ColinTheMathmo@mathstodon.xyz","username": "ColinTheMathmo"}],"created_at": "2022-08-07T03:31:36.036Z","in_reply_to_id": "108779065047526734","visibility": "public","replies_count": 0,"media_attachments": [],"url": "https://merveilles.town/@akkartik/108779477141581528","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://mathstodon.xyz/@ColinTheMathmo\" class=\"u-url mention\">@<span>ColinTheMathmo</span></a></span> To clarify, I hit delete-and-redraft on the parent of the comment I intended. When I realized my mistake I didn't actually redraft the comment I deleted.</p>","account": {"display_name": "Kartik Agaram","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","following_count": 175,"header": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","last_status_at": "2023-02-04","acct": "akkartik","bot": false,"discoverable": true,"fields": [{"name": "Bio","value": "<a href=\"http://akkartik.name/about\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">akkartik.name/about</span><span class=\"invisible\"></span></a>","verified_at": "2022-06-02T20:56:23.240+00:00"},{"name": "Subcultures","value": "<a href=\"https://futureofcoding.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">futureofcoding.org</span><span class=\"invisible\"></span></a>, <a href=\"https://ribbonfarm.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">ribbonfarm.com</span><span class=\"invisible\"></span></a>, <a href=\"http://arclanguage.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">arclanguage.org</span><span class=\"invisible\"></span></a>"}],"header_static": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","emojis": [],"url": "https://merveilles.town/@akkartik","noindex": false,"statuses_count": 2903,"locked": false,"followers_count": 947,"group": false,"created_at": "2020-10-29T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","id": "97481","note": "<p>Building simple, low-maintenance programs that reward curiosity about their internals.</p>","username": "akkartik"},"favourites_count": 1,"in_reply_to_account_id": "7606","tags": [],"id": "108779477141581528","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/akkartik/statuses/108779477141581528","local_only": false,"language": "en"},{"mentions": [{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"}],"sensitive": false,"in_reply_to_id": "108779065047526734","visibility": "public","replies_count": 1,"media_attachments": [],"spoiler_text": "","url": "https://mathstodon.xyz/@ColinTheMathmo/108781062386855801","content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>akkartik</span></a></span> I've updated the chart, but not done anything about tying in other toots.</p><p>I hope it's useful as it stands, but if I can do anything, don't hesitate to ask.</p>","emojis": [],"language": "en","uri": "https://mathstodon.xyz/users/ColinTheMathmo/statuses/108781062386855801","tags": [],"id": "108781062449311628","activity_pub_type": "Note","account": {"display_name": "Colin the Mathmo","avatar_static": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","following_count": 5690,"header": "https://merveilles.town/headers/original/missing.png","last_status_at": "2023-02-04","acct": "ColinTheMathmo@mathstodon.xyz","bot": false,"discoverable": true,"header_static": "https://merveilles.town/headers/original/missing.png","fields": [{"name": "Web site","value": "<a href=\"https://www.solipsys.co.uk\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">solipsys.co.uk</span><span class=\"invisible\"></span></a>","verified_at": "2022-11-25T17:54:39.472+00:00"},{"name": "Pronouns","value": "He/Him"}],"url": "https://mathstodon.xyz/@ColinTheMathmo","emojis": [],"statuses_count": 18127,"locked": false,"followers_count": 3071,"group": false,"created_at": "2017-04-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","id": "7606","note": "<p>Fulltime freelance provider of outreach and enhancement in maths ... I talk a lot. About maths.</p><p>I talk about other stuff too, like ballroom dancing, juggling, unicycling, education, engineering, software, and \"other things\".</p><p>But mostly about maths.</p><p>I tend to follow back, but only if you have something in your profile.</p>","username": "ColinTheMathmo"},"created_at": "2022-08-07T10:14:44.000Z","favourites_count": 0,"reblogs_count": 0,"in_reply_to_account_id": "97481"},{"mentions": [{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"}],"sensitive": false,"in_reply_to_id": "108781062449311628","visibility": "public","replies_count": 1,"media_attachments": [],"spoiler_text": "","url": "https://mathstodon.xyz/@ColinTheMathmo/108781833193554031","content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>akkartik</span></a></span> Just checking that you are aware that clicking on a node will open the toot.</p>","emojis": [],"language": "en","uri": "https://mathstodon.xyz/users/ColinTheMathmo/statuses/108781833193554031","tags": [],"id": "108781833272834693","activity_pub_type": "Note","account": {"display_name": "Colin the Mathmo","avatar_static": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","following_count": 5690,"header": "https://merveilles.town/headers/original/missing.png","last_status_at": "2023-02-04","acct": "ColinTheMathmo@mathstodon.xyz","bot": false,"discoverable": true,"header_static": "https://merveilles.town/headers/original/missing.png","fields": [{"name": "Web site","value": "<a href=\"https://www.solipsys.co.uk\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">solipsys.co.uk</span><span class=\"invisible\"></span></a>","verified_at": "2022-11-25T17:54:39.472+00:00"},{"name": "Pronouns","value": "He/Him"}],"url": "https://mathstodon.xyz/@ColinTheMathmo","emojis": [],"statuses_count": 18127,"locked": false,"followers_count": 3071,"group": false,"created_at": "2017-04-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","id": "7606","note": "<p>Fulltime freelance provider of outreach and enhancement in maths ... I talk a lot. About maths.</p><p>I talk about other stuff too, like ballroom dancing, juggling, unicycling, education, engineering, software, and \"other things\".</p><p>But mostly about maths.</p><p>I tend to follow back, but only if you have something in your profile.</p>","username": "ColinTheMathmo"},"created_at": "2022-08-07T13:30:46.000Z","favourites_count": 0,"reblogs_count": 0,"in_reply_to_account_id": "97481"},{"mentions": [{"id": "7606","url": "https://mathstodon.xyz/@ColinTheMathmo","acct": "ColinTheMathmo@mathstodon.xyz","username": "ColinTheMathmo"}],"created_at": "2022-08-07T14:34:39.835Z","in_reply_to_id": "108781833272834693","visibility": "public","replies_count": 1,"media_attachments": [],"url": "https://merveilles.town/@akkartik/108782084412547499","emojis": [],"spoiler_text": "","application": {"name": "Web"},"content": "<p><span class=\"h-card\"><a href=\"https://mathstodon.xyz/@ColinTheMathmo\" class=\"u-url mention\">@<span>ColinTheMathmo</span></a></span> I wasn't, thanks! I didn't mean to sound like I was requesting a feature.</p>","account": {"display_name": "Kartik Agaram","avatar_static": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","following_count": 175,"header": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","last_status_at": "2023-02-04","acct": "akkartik","bot": false,"discoverable": true,"fields": [{"name": "Bio","value": "<a href=\"http://akkartik.name/about\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">akkartik.name/about</span><span class=\"invisible\"></span></a>","verified_at": "2022-06-02T20:56:23.240+00:00"},{"name": "Subcultures","value": "<a href=\"https://futureofcoding.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">futureofcoding.org</span><span class=\"invisible\"></span></a>, <a href=\"https://ribbonfarm.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">ribbonfarm.com</span><span class=\"invisible\"></span></a>, <a href=\"http://arclanguage.org\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">http://</span><span class=\"\">arclanguage.org</span><span class=\"invisible\"></span></a>"}],"header_static": "https://assets.merveilles.town/accounts/headers/000/097/481/original/7fee86fcd284ec0c.png","emojis": [],"url": "https://merveilles.town/@akkartik","noindex": false,"statuses_count": 2903,"locked": false,"followers_count": 947,"group": false,"created_at": "2020-10-29T00:00:00.000Z","avatar": "https://assets.merveilles.town/accounts/avatars/000/097/481/original/ef2bdad0770b53bd.png","id": "97481","note": "<p>Building simple, low-maintenance programs that reward curiosity about their internals.</p>","username": "akkartik"},"favourites_count": 0,"in_reply_to_account_id": "7606","tags": [],"id": "108782084412547499","reblogs_count": 0,"activity_pub_type": "","sensitive": false,"uri": "https://merveilles.town/users/akkartik/statuses/108782084412547499","local_only": false,"language": "en"},{"mentions": [{"id": "97481","url": "https://merveilles.town/@akkartik","acct": "akkartik","username": "akkartik"}],"sensitive": false,"in_reply_to_id": "108782084412547499","visibility": "public","replies_count": 0,"media_attachments": [],"spoiler_text": "","url": "https://mathstodon.xyz/@ColinTheMathmo/108782196397681430","content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\" rel=\"nofollow noopener noreferrer\" target=\"_blank\">@<span>akkartik</span></a></span> No, I didn't think you were, I just thought I'd mention it in passing because many people see the \"SVG\" affix and assume it's static.</p>","emojis": [],"language": "en","uri": "https://mathstodon.xyz/users/ColinTheMathmo/statuses/108782196397681430","tags": [],"id": "108782196466255655","activity_pub_type": "Note","account": {"display_name": "Colin the Mathmo","avatar_static": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","following_count": 5690,"header": "https://merveilles.town/headers/original/missing.png","last_status_at": "2023-02-04","acct": "ColinTheMathmo@mathstodon.xyz","bot": false,"discoverable": true,"header_static": "https://merveilles.town/headers/original/missing.png","fields": [{"name": "Web site","value": "<a href=\"https://www.solipsys.co.uk\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">solipsys.co.uk</span><span class=\"invisible\"></span></a>","verified_at": "2022-11-25T17:54:39.472+00:00"},{"name": "Pronouns","value": "He/Him"}],"url": "https://mathstodon.xyz/@ColinTheMathmo","emojis": [],"statuses_count": 18127,"locked": false,"followers_count": 3071,"group": false,"created_at": "2017-04-14T00:00:00.000Z","avatar": "https://assets.merveilles.town/cache/accounts/avatars/000/007/606/original/50d014198abc91e1.png","id": "7606","note": "<p>Fulltime freelance provider of outreach and enhancement in maths ... I talk a lot. About maths.</p><p>I talk about other stuff too, like ballroom dancing, juggling, unicycling, education, engineering, software, and \"other things\".</p><p>But mostly about maths.</p><p>I tend to follow back, but only if you have something in your profile.</p>","username": "ColinTheMathmo"},"created_at": "2022-08-07T15:03:08.000Z","favourites_count": 1,"reblogs_count": 0,"in_reply_to_account_id": "97481"}],"ancestors": [],"content": "<p><span class=\"h-card\"><a href=\"https://merveilles.town/@klardotsh\" class=\"u-url mention\">@<span>klardotsh</span></a></span> <span class=\"h-card\"><a href=\"https://merveilles.town/@akkartik\" class=\"u-url mention\">@<span>akkartik</span></a></span> Love2d has this really bad issue on PB, everytime I start it, it makes the screen flicker white, and after that some program have a hard time recovering, like firefox will not redraw its body unless I resize the window, which is incredibly annoying.</p>","host": "https://merveilles.town","url": "https://merveilles.town/@neauoire/108484209780107901","replies_count": 2,"user": "neauoire"}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id)-- position the root between xlo and xhi to be closer to children with fewer trackslocal parent = nodes[id]if parent.children == nil thenadd_node(xlo, y, parent.content)returnendlocal total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#parent.children-1 dolocal child_id = parent.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendlocal parent_x = total_boundaries / (#parent.children-1)local parent_xlo = parent_x - 620/2local parent_surface_node = add_node(parent_xlo, y, parent.content)local curr_boundary = xlofor _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]render_node_and_descendants(nodes, child_id, y + box_height(parent_surface_node) + 50, curr_boundary, curr_boundary + 620*child.ntracks)curr_boundary = curr_boundary + 620*child.ntracksendend
{"Input_filename":436,"fw_parent":544,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":545,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
{"Input_filename":436,"fw_parent":543,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":543,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id)-- position the root between xlo and xhi to be closer to children with fewer trackslocal parent = nodes[id]if parent.children == nil thenadd_node(xlo, y, parent.content)returnendlocal total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#parent.children-1 dolocal child_id = parent.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendlocal parent_x = total_boundaries / (#parent.children-1)local parent_xlo = parent_x - 620/2local parent_surface_node = add_node(parent_xlo, y, parent.content)local curr_boundary = xlofor _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]render_node_and_descendants(nodes, child_id, y + box_height(parent_surface_node), curr_boundary, curr_boundary + 620*child.ntracks)curr_boundary = curr_boundary + 620*child.ntracksendend
{"Input_filename":436,"fw_parent":542,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"center_x_above_children":542,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":543,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
{"Input_filename":436,"fw_parent":541,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"center_x_above_children":542,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":541,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
center_x_above_children = function(nodes, parent, xlo, xhi)-- given parent has n children, each of whom occupies various numbers of tracks, return the x of the center, somewhere between xlo and xhiif parent.children == nil thenreturn (xlo+xhi)/2endlocal total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#parent.children-1 dolocal child_id = parent.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendreturn total_boundaries / (#parent.children-1)end
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id)-- position the root between xlo and xhi to be closer to children with fewer trackslocal parent = nodes[id]local parent_x = center_x_above_children(nodes, parent, xlo, xhi)local parent_xlo = parent_x - 620/2local parent_surface_node = add_node(parent_xlo, y, parent.content)local curr_boundary = xlofor _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]render_node_and_descendants(nodes, child_id, y + box_height(parent_surface_node), curr_boundary, curr_boundary + 620*child.ntracks)curr_boundary = curr_boundary + 620*child.ntracksendend
{"Input_filename":436,"fw_parent":540,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"center_x_above_children":540,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":541,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
{"Input_filename":436,"fw_parent":539,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"center_x_above_children":540,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":539,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
center_x_above_children = function(nodes, parent, xlo, xhi)-- given parent has n children, each of whom occupies various numbers of tracks, return the x of the center, somewhere between xlo and xhiif parent.children == nil thenreturn (xlo+xheight)/2endlocal total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#parent.children-1 dolocal child_id = parent.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendreturn total_boundaries / (#parent.children-1)end
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id)-- position the root between xlo and xhi to be closer to children with fewer trackslocal parent = nodes[id]local total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#parent.children-1 dolocal child_id = parent.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendlocal parent_x = total_boundaries / (#parent.children-1)local parent_xlo = parent_x - 620/2local parent_surface_node = add_node(parent_xlo, y, parent.content)local curr_boundary = xlofor _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]render_node_and_descendants(nodes, child_id, y + box_height(parent_surface_node), curr_boundary, curr_boundary + 620*child.ntracks)curr_boundary = curr_boundary + 620*child.ntracksendend
{"Input_filename":436,"fw_parent":538,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":539,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)-- position the root between xlo and xhi to be closer to children with fewer trackslocal parent = nodes[id]local total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#parent.children-1 dolocal child_id = parent.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendlocal parent_x = total_boundaries / (#parent.children-1)local parent_xlo = parent_x - 620/2local parent_surface_node = add_node(parent_xlo, y, parent.content)local curr_boundary = xlofor _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]render_node_and_descendants(nodes, child_id, y + box_height(parent_surface_node), curr_boundary, curr_boundary + 620*child.ntracks)curr_boundary = curr_boundary + 620*child.ntracksendend
{"Input_filename":436,"fw_parent":537,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":538,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)-- position the root between xlo and xhi to be closer to children with fewer trackslocal node = nodes[id]local total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#node.children-1 dolocal child_id = node.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendlocal parent_x = total_boundaries / (#node.children-1)local parent_xlo = parent_x - 620/2local parent_surface_node = add_node(parent_xlo, y, node.content)local curr_boundary = xlofor _,child_id in ipairs(node.children) dolocal child = nodes[child_id]render_node_and_descendants(nodes, child_id, y + box_height(node), curr_boundary, curr_boundary + 620*child.ntracks)curr_boundary = curr_boundary + 620*child.ntracksendend
{"Input_filename":436,"fw_parent":536,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":537,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
{"Input_filename":436,"fw_parent":535,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":536,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":535,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
add_node = function(x, y, text)local surface_node = {x=x, y=y,width=600,type='text',data=split_lines(dehtml(text)),bg={r=0.7,g=0.7, b=1.0},}compute_layout(surface_node, surface_node.x, surface_node.y, Surface)return surface_nodeend
render_node_and_descendants = function(nodes, id, y, xlo, xhi)-- position the root between xlo and xhi to be closer to children with fewer trackslocal node = nodes[id]local total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#node.children-1 dolocal child_id = node.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendlocal parent_x = total_boundaries / (#node.children-1)local parent_xlo = parent_x - 620/2add_node(parent_xlo, y, node.content)local curr_boundary = xlofor _,child_id in ipairs(node.children) dolocal child = nodes[child_id]render_node_and_descendants(nodes, child_id, y + box_height(node), curr_boundary, curr_boundary + 620*child.ntracks)curr_boundary = curr_boundary + 620*child.ntracksendend
{"Input_filename":436,"fw_parent":534,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":480,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":535,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)-- position the root between xlo and xhi to be closer to children with fewer trackslocal node = nodes[id]local total_boundaries = 0local curr_boundary = xlofor child_idx = 1,#node.children-1 dolocal child_id = node.children[child_idx]local child = nodes[child_id]curr_boundary = curr_boundary + 620 * child.ntrackstotal_boundaries = total_boundaries + curr_boundaryendlocal parent_x = total_boundaries / (#node.children-1)local parent_xlo = parent_x - 620/2add_node(parent_xlo, y, nodes[id].content)end
{"Input_filename":436,"fw_parent":533,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":480,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":534,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id, nodes[id].contents)add_node(xlo, y, nodes[id].content)end
{"Input_filename":436,"fw_parent":532,"fw_app":"mastodon-luaML","initialize_editor":338,"update_editor_box":430,"ntracks":505,"compute_ntracks":519,"on.text_input":388,"render_thread_to_surface":525,"dehtml":456,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":474,"B":379,"scale":7,"Surface":434,"split_lines":469,"on":1,"vx":5,"box_height":345,"Viewport":303,"compute_layout":385,"font":353,"on.code_change":473,"vy":8,"line_height":365,"add_node":480,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"render_node_and_descendants":533,"on.update":368,"add_thick_line":400,"on.keychord_press":391,"Cursor_node":172,"on.draw":418,"copy_shape":396,"to_text":180}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id, nodes[id].contents)add_node(xlo, y, nodes[id].content)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":531,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":532,"add_thick_line":400,"render_thread_to_surface":525,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id, nodes[id].contents)add_node(x, y, nodes[id].content)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":530,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":531,"add_thick_line":400,"render_thread_to_surface":525,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id, nodes[id].contents)add_node(x, y, nodes[id].content)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":529,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":530,"add_thick_line":400,"render_thread_to_surface":525,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id, nodes[id].contents)add_node(x, y, nodes[id].contents)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":528,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":529,"add_thick_line":400,"render_thread_to_surface":525,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id, nodes[id].contents)add_node(x, y, nodes[id].contents)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":527,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":528,"add_thick_line":400,"render_thread_to_surface":525,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)print(id)add_node(x, y, nodes[id].contents)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":526,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":527,"add_thick_line":400,"render_thread_to_surface":525,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_node_and_descendants = function(nodes, id, y, xlo, xhi)add_node(x, y, nodes[id].contents)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":525,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":526,"add_thick_line":400,"render_thread_to_surface":525,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- parents can overlap columns with children and more distant descendants-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- sort children by timefor _,x in pairs(nodes) doif x.children thentable.sort(x.children)endend-- compute number of tracks neededfor _,x in pairs(nodes) doif x.ntracks == nil thenx.ntracks = compute_ntracks(nodes, x)endendfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesrender_node_and_descendants(nodes, root.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * root.ntracks)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":524,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":525,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":523,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":523,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- parents can overlap columns with children and more distant descendants-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- sort children by timefor _,x in pairs(nodes) dotable.sort(x.children)end-- compute number of tracks neededfor _,x in pairs(nodes) doif x.ntracks == nil thenx.ntracks = compute_ntracks(nodes, x)endendfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesrender_node_and_descendants(nodes, root.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * root.ntracks)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":522,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":523,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- parents can overlap columns with children and more distant descendants-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) doif x.ntracks == nil thenx.ntracks = compute_ntracks(nodes, x)endendfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesrender_node_and_descendants(nodes, root.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * root.ntracks)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":521,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":522,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- parents can overlap columns with children and more distant descendants-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) doif x.ntracks == nil thenx.ntracks = compute_ntracks(nodes, x)endendfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesrender_node_and_descendants(nodes, thread_data.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * root.ntracks)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":520,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":521,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- parents can overlap columns with children and more distant descendants-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) doif x.ntracks == nil thenx.ntracks = compute_ntracks(nodes, x)endendfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesprint('aa', root.id, root.ntracks)-- render_node_and_descendants(nodes, thread_data.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * thread_data.ntracks)-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":519,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":520,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":518,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":518,"dehtml":456,"copy_shape":396,"compute_ntracks":519,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ntracks = function(nodes, parent)-- leaf nodes need 1 trackif parent.children == nil thenreturn 1end-- otherwise add up the tracks needed by all children (parent will fit in among them)-- if we have a single child, it will slide into the same track. This is desirable.local result = 0for _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]result = result + ntracks(nodes, child)endreturn resultend
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) doif x.ntracks == nil thenx.ntracks = compute_ntracks(nodes, x)endendfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesprint('aa', root.id, root.ntracks)-- render_node_and_descendants(nodes, thread_data.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * thread_data.ntracks)-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":517,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":518,"dehtml":456,"copy_shape":396,"compute_ntracks":516,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) doprint('compute ntracks', x.id)compute_ntracks(nodes, x)endfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesprint('aa', root.id, root.ntracks)-- render_node_and_descendants(nodes, thread_data.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * thread_data.ntracks)-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":516,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":517,"dehtml":456,"copy_shape":396,"compute_ntracks":516,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":515,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":515,"dehtml":456,"copy_shape":396,"compute_ntracks":516,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ntracks = function(nodes, parent)-- leaf nodes need 1 trackif parent.children == nil thenreturn 1end-- otherwise add up the tracks needed by all children (parent will fit in among them)-- if we have a single child, it will slide into the same track. This is desirable.local result = 0for _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]result = result + ntracks(nodes, child)endreturn resultend
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesprint('aa', root.id, root.ntracks)-- render_node_and_descendants(nodes, thread_data.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * thread_data.ntracks)-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":514,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":515,"dehtml":456,"copy_shape":396,"compute_ntracks":506,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xendlocal root = thread_data-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= root.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesprint('aa', root.ntracks)-- render_node_and_descendants(nodes, thread_data.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * thread_data.ntracks)-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":513,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":514,"dehtml":456,"copy_shape":396,"compute_ntracks":506,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- prepare the tracks-- each track is 600px + 20px of gutter between nodesprint('aa', thread_data.ntracks)-- render_node_and_descendants(nodes, thread_data.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * thread_data.ntracks)-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"on.initialize":446,"vy":8,"fw_parent":511,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"Cursor_node":172,"vx":5,"Surface":434,"Viewport":303,"render_node_and_descendants":482,"add_thick_line":400,"render_thread_to_surface":513,"dehtml":456,"copy_shape":396,"compute_ntracks":506,"split_lines":469,"on.mouse_press":179,"load_from_iterator":463,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_node_and_descendants = function(node, descendants, id, y, xlo, xhi)add_node(x, y, node[id].contents)local nchildren = #descendants[id]-- to render n children we require 600*n + 20*(n-1) px of widthlocal children = {}for i,x in ipairs(descendants[id]) doend
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":506,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":511,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":512,"on.initialize":446,"render_thread_to_surface":511,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":506,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":510,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":511,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = nodes[y]print(x.id, c.id, c.ntracks)endendend-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":506,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":509,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":510,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) dolocal c = node[y]print(x.id, c.id, c.ntracks)endendend-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":506,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":508,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":509,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) doif x.children thenfor _,y in pairs(x.children) doprint(x.id, y.id, y.ntracks)endendend-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":506,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":507,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":508,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) dofor _,y in pairs(x.children) doprint(x.id, y.id, y.ntracks)endend-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":506,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":506,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":507,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":506,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":505,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":504,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ntracks = function(nodes, parent)-- leaf nodes need 1 trackif parent.children == nil thenreturn 1end-- otherwise add up the tracks needed by all children (parent will fit in among them)local result = 0for _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]result = result + ntracks(nodes, child)endreturn resultend
ntracks = function(nodes, parent)-- memoizeif parent.ntracks == nil thenparent.ntracks = compute_ntracks(nodes, parent)endreturn parent.ntracksend
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":505,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":503,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":504,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":504,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ntracks(nodes, x)endfor _,x in pairs(nodes) doprint(x.id, x.in_reply_to_id, x.ntracks)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":502,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":503,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":503,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":504,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":502,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"compute_ntracks":503,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":502,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":501,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ntracks = function(nodes, parent)-- leaf nodes need 1 trackif parent.children == nil thenreturn 1end-- otherwise add up the tracks needed by all children (parent will fit in among them)local result = 0for _,child_id in ipairs(parent.children) dolocal child = nodes[child_id]result = result + ntracks(nodes, child)endreturn resultend
ntracks = function(nodes, parent)if parent.ntracks == nil thencompute_ntracks(nodes, parent)endassert(parent.ntracks)return parent.ntracksend
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"ntracks":502,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":501,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":501,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)-- design constraints:-- trees only, no graphs or DAGs-- parents above children-- a child shares its parent's column exactly only if it's an only child-- siblings never share a column-- siblings never overlap columns-- siblings always occupy the same row-- cousins/aunts/nephews never overlap columnsSurface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute number of tracks neededfor _,x in pairs(nodes) docompute_ndescendants(nodes, x)endfor _,x in pairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":500,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":501,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":500,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":499,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":497,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ndescendants = function(node, parent)if parent.ndescendants then return parent.ndescendants endlocal result = 0if parent.children thenfor _,child_id in ipairs(parent.children) dolocal child = node[child_id]result = result + compute_ndescendants(node, child) + 1endendparent.ndescendants = resultreturn resultend
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":499,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":498,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":497,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ndescendants = function(node, parent)if parent.ndescendants then return parent.ndescendants endlocal result = 1if parent.children thenfor _,child_id in ipairs(parent.children) dolocal child = node[child_id]result = result + compute_ndescendants(node, child)endendparent.ndescendants = resultreturn resultend
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":498,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":497,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":497,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ndescendants = function(node, parent)if parent.ndescendants then return parent.ndescendants endlocal result = 1if parents.children thenfor _,child_id in ipairs(parent.children) dolocal child = node[child_id]result = result + compute_ndescendants(node, child)endendparent.ndescendants = resultreturn resultend
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute ndescendantsfor _,x in pairs(nodes) docompute_ndescendants(nodes, x)endfor _,x in pairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":496,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":497,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute ndescendantsfor _,x in pairs(nodes) docompute_nescendants(nodes, x)endfor _,x in pairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":495,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":496,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x.id ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute ndescendantsfor _,x in pairs(nodes) docompute_descendants(nodes, x)endfor _,x in pairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":494,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":495,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idif x ~= thread_data.id thenassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)endend-- compute ndescendantsfor _,x in pairs(nodes) docompute_descendants(nodes, x)endfor _,x in pairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":493,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":494,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id or x.id == thread_data.id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in pairs(nodes) docompute_descendants(nodes, x)endfor _,x in pairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":492,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":493,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in pairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in pairs(nodes) docompute_descendants(nodes, x)endfor _,x in pairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":491,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":492,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_dataprint(#nodes)for _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in ipairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in ipairs(nodes) docompute_descendants(nodes, x)endfor _,x in ipairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":490,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":491,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in ipairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in ipairs(nodes) docompute_descendants(nodes, x)endprint(#nodes)for _,x in ipairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":489,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":490,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}print('aaa')-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in ipairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in ipairs(nodes) docompute_descendants(nodes, x)endfor _,x in ipairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":488,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":489,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in ipairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in ipairs(nodes) docompute_descendants(nodes, x)endfor _,x in ipairs(nodes) doprint(x.id, x.in_reply_to_id, x.ndescendants)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":487,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":488,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":487,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":486,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":486,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ndescendants = function(node, parent)if parent.ndescendants then return parent.ndescendants endlocal result = 1for _,child_id in ipairs(parent.children) dolocal child = node[child_id]result = result + compute_ndescendants(node, child)endparent.ndescendants = resultreturn resultend
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in ipairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in ipairs(nodes) docompute_descendants(nodes, x)end-- render_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":483,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":485,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":486,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal nodes = {} -- id to objectnodes[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donodes[x.id] = xend-- compute childrenfor _,x in ipairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id)local parent = nodes[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in ipairs(nodes) docompute_descendants(nodes, x)endrender_node_and_descendants(nodes, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":483,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":484,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":485,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_thread_to_surface = function(thread_data)Surface = {}-- compute mapping from ids to nodeslocal node = {} -- id to objectnode[thread_data.id] = thread_datafor _,x in ipairs(thread_data.descendants) donode[x.id] = xend-- compute childrenfor _,x in ipairs(nodes) doparent_id = x.in_reply_to_idassert(parent_id)local parent = node[parent_id]if parent.children == nil thenparent.children = {}endtable.insert(parent.children, x.id)end-- compute ndescendantsfor _,x in ipairs(node) docompute_descendants(node, x)endrender_node_and_descendants(node, descendants, thread_data.id, 0, 0)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":483,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":483,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":484,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"compute_ndescendants":483,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":482,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":479,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
compute_ndescendants = function(node, parent)if parent.ndescendants then return parent.ndescendants endlocal result = 1for _,child_id in ipairs(parent.children) dolocal child = node[child_id]result = result + compute_ndescendants(node, child)endreturn resultend
render_node_and_descendants = function(node, descendants, id, x, y)add_node(x, y, node[id].contents)end
{"on.text_input":388,"update_editor_box":430,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"load_from_iterator":463,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"initialize_editor":338,"Surface":434,"on":1,"fw_app":"mastodon-luaML","on.draw":418,"fw_parent":480,"vx":5,"vy":8,"Viewport":303,"render_node_and_descendants":482,"on.initialize":446,"render_thread_to_surface":479,"dehtml":456,"copy_shape":396,"to_text":180,"split_lines":469,"on.mouse_press":179,"add_thick_line":400,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"Input_filename":436,"on.keychord_press":391}
render_node_and_descendants(node, descendants, id, x, y)add_node(x, y, node[id].contents)end
{"render_node_and_descendants(node,":481,"on.text_input":388,"on.initialize":446,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"Surface":434,"update_editor_box":430,"fw_app":"mastodon-luaML","on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"split_lines":469,"load_from_iterator":463,"vy":8,"dehtml":456,"copy_shape":396,"fw_parent":480,"Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":479,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
{"on.text_input":388,"on.initialize":446,"A":474,"scale":7,"B":379,"line_height":365,"schema1_of_y":366,"y_of_schema1":364,"add_node":480,"to_text":180,"box_height":345,"font":353,"compute_layout":385,"on.code_change":473,"Surface":434,"update_editor_box":430,"fw_app":"mastodon-luaML","on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"split_lines":469,"load_from_iterator":463,"vy":8,"dehtml":456,"copy_shape":396,"fw_parent":479,"Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":479,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"Input_filename":436,"on.keychord_press":391}
add_node = function(x, y, text)local tmp = {x=x, y=y,width=600,type='text',data=split_lines(dehtml(text)),bg={r=0.7,g=0.7, b=1.0},}compute_layout(tmp, tmp.x, tmp.y, Surface)end
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=split_lines(dehtml(thread_data.content)),bg={r=0.7,g=0.7, b=1.0},}compute_layout(tmp, tmp.x, tmp.y, Surface)local node = {} -- id to objectlocal descendants = {} -- node id to array of descendant idsfor i,x in ipairs(thread_data.descendants) doprint(i, x.id, x.in_reply_to_id)node[x.id] = xparent_id = x.in_reply_to_idassert(parent_id)if descendants[parent_id] == nil thendescendants[parent_id] = {}endtable.insert(descendants[parent_id], x.id)endprint('immediate children')for i,x in ipairs(descendants[thread_data.id]) doprint(x)endend
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":473,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":478,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":479,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":474,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=split_lines(dehtml(thread_data.content)),bg={r=0.7,g=0.7, b=1.0},}compute_layout(tmp, tmp.x, tmp.y, Surface)local node = {} -- id to objectlocal descendants = {} -- node id to array of descendant idsfor i,x in ipairs(thread_data.descendants) doprint(i, x.id, x.in_reply_to_id)node[x.id] = xparent_id = x.in_reply_to_idassert(parent_id)if descendants[parent_id] == nil thendescendants[parent_id] = {}endtable.insert(descendants[parent_id], x.id)endend
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":473,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":477,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":478,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":474,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=split_lines(dehtml(thread_data.content))}compute_layout(tmp, tmp.x, tmp.y, Surface)for i,x in ipairs(thread_data.descendants) doprint(i, x.id, x.in_reply_to_id)endend
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":473,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":476,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":477,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":474,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=split_lines(dehtml(thread_data.content))}compute_layout(tmp, tmp.x, tmp.y, Surface)print(#thread_data.descendants)end
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":473,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":475,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":476,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":474,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=split_lines(dehtml(thread_data.content))}compute_layout(tmp, tmp.x, tmp.y, Surface)print(#tmp.descendants)end
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":473,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":474,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":475,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":474,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":473,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":473,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":472,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":474,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
A = function(filename)if filename thenlocal f = io.open(filename)assert(f)local thread_data = json.decode(f:read('*a'))render_thread_to_surface(thread_data)endB()end
on.code_change = function()print('code changed', Input_filename)A(Input_filename) -- just in case we edited somethingend
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":473,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":472,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":472,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":455,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=split_lines(dehtml(thread_data.content))}compute_layout(tmp, tmp.x, tmp.y, Surface)end
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":458,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":471,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":472,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":455,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,w=600,type='text',data=split_lines(dehtml(thread_data.content))}compute_layout(tmp, tmp.x, tmp.y, Surface)end
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":458,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":470,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":471,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":455,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
render_thread_to_surface = function(thread_data)-- Surface = {}local tmp = {x=0, y=0,w=600,type='text',data=split_lines(dehtml(thread_data.content))}compute_layout(tmp, tmp.x, tmp.y, Surface)end
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":458,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":469,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":470,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":455,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
split_lines = function(s)return load_from_iterator(s:gmatch('[^\r\n]+'))end
{"copy_shape":396,"font":353,"Input_filename":436,"update_editor_box":430,"to_text":180,"line_height":365,"box_height":345,"compute_layout":385,"schema1_of_y":366,"on.code_change":458,"y_of_schema1":364,"Surface":434,"B":379,"on.draw":418,"load_from_iterator":463,"Viewport":303,"scale":7,"fw_parent":468,"fw_app":"mastodon-luaML","Cursor_node":172,"on.mouse_press":179,"render_thread_to_surface":468,"on.mouse_release":367,"initialize_editor":338,"on.text_input":388,"on.keychord_press":391,"on.initialize":446,"on":1,"A":455,"split_lines":469,"vy":8,"vx":5,"on.update":368,"add_thick_line":400,"dehtml":456}
render_thread_to_surface = function(thread_data)-- Surface = {}local tmp = {x=0, y=0,w=600,type='text',data=load_from_iterator(dehtml(thread_data.content):gmatch("[^\r\n]+"))}compute_layout(tmp, tmp.x, tmp.y, Surface)end
{"on.initialize":446,"box_height":345,"A":455,"load_from_iterator":463,"B":379,"schema1_of_y":366,"font":353,"Surface":434,"y_of_schema1":364,"scale":7,"on.draw":418,"Cursor_node":172,"vx":5,"Viewport":303,"on.text_input":388,"Input_filename":436,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"on.keychord_press":391,"on":1,"render_thread_to_surface":468,"dehtml":456,"add_thick_line":400,"copy_shape":396,"fw_parent":467,"on.code_change":458,"fw_app":"mastodon-luaML","line_height":365,"to_text":180,"compute_layout":385,"vy":8,"update_editor_box":430}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,w=600,type='text',data=load_from_iterator(dehtml(thread_data.content):gmatch("[^\r\n]+"))}compute_layout(tmp, tmp.x, tmp.y, Surface)end
{"Surface":434,"on.draw":418,"vx":5,"render_thread_to_surface":467,"Viewport":303,"add_thick_line":400,"vy":8,"copy_shape":396,"line_height":365,"to_text":180,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"font":353,"on.keychord_press":391,"Cursor_node":172,"update_editor_box":430,"on.text_input":388,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":455,"load_from_iterator":463,"B":379,"fw_parent":466,"box_height":345,"Input_filename":436,"compute_layout":385,"scale":7,"on":1,"fw_app":"mastodon-luaML","on.code_change":458,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,w=600,type='text',data=load_from_iterator(dehtml(thread_data.content):gmatch("[^\r\n]+"))}table.insert(Surface, tmp)end
{"Surface":434,"on.draw":418,"vx":5,"render_thread_to_surface":466,"Viewport":303,"add_thick_line":400,"vy":8,"copy_shape":396,"line_height":365,"to_text":180,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"font":353,"on.keychord_press":391,"Cursor_node":172,"update_editor_box":430,"on.text_input":388,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":455,"load_from_iterator":463,"B":379,"fw_parent":465,"box_height":345,"Input_filename":436,"compute_layout":385,"scale":7,"on":1,"fw_app":"mastodon-luaML","on.code_change":458,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=load_from_iterator(dehtml(thread_data.content):gmatch("[^\r\n]+"))}print(type(tmp.data), #tmp.data)table.insert(Surface, tmp)end
{"Surface":434,"on.draw":418,"vx":5,"render_thread_to_surface":465,"Viewport":303,"add_thick_line":400,"vy":8,"copy_shape":396,"line_height":365,"to_text":180,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"font":353,"on.keychord_press":391,"Cursor_node":172,"update_editor_box":430,"on.text_input":388,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":455,"load_from_iterator":463,"B":379,"fw_parent":464,"box_height":345,"Input_filename":436,"compute_layout":385,"scale":7,"on":1,"fw_app":"mastodon-luaML","on.code_change":458,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=load_from_iterator(dehtml(thread_data.content):gmatch("[^\r\n]+"))}table.insert(Surface, tmp)end
{"Surface":434,"on.draw":418,"vx":5,"render_thread_to_surface":464,"Viewport":303,"add_thick_line":400,"vy":8,"copy_shape":396,"line_height":365,"to_text":180,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"font":353,"on.keychord_press":391,"Cursor_node":172,"update_editor_box":430,"on.text_input":388,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":455,"load_from_iterator":463,"B":379,"fw_parent":463,"box_height":345,"Input_filename":436,"compute_layout":385,"scale":7,"on":1,"fw_app":"mastodon-luaML","on.code_change":458,"dehtml":456}
load_from_iterator = function(f)local result = {}local i,line,drawing = 0, ''while true dolocal line = f()if line == nil then break endtable.insert(result, line)endif #result == 0 thentable.insert(result, '')endreturn resultend
{"Surface":434,"on.draw":418,"vx":5,"render_thread_to_surface":462,"Viewport":303,"add_thick_line":400,"vy":8,"copy_shape":396,"line_height":365,"to_text":180,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"font":353,"on.keychord_press":391,"Cursor_node":172,"update_editor_box":430,"on.text_input":388,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":455,"load_from_iterator":463,"B":379,"fw_parent":462,"box_height":345,"Input_filename":436,"compute_layout":385,"scale":7,"on":1,"fw_app":"mastodon-luaML","on.code_change":458,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=dehtml(thread_data.content)}table.insert(Surface, tmp)end
{"Surface":434,"on.draw":418,"vx":5,"render_thread_to_surface":462,"Viewport":303,"add_thick_line":400,"vy":8,"copy_shape":396,"line_height":365,"to_text":180,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"font":353,"on.keychord_press":391,"Cursor_node":172,"update_editor_box":430,"on.text_input":388,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":455,"B":379,"fw_parent":461,"box_height":345,"Input_filename":436,"compute_layout":385,"scale":7,"on":1,"fw_app":"mastodon-luaML","on.code_change":458,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=dehtml(thread_data.content)}print('rerendering')table.insert(Surface, tmp)end
{"Surface":434,"on.draw":418,"vx":5,"render_thread_to_surface":461,"Viewport":303,"add_thick_line":400,"vy":8,"copy_shape":396,"line_height":365,"to_text":180,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"font":353,"on.keychord_press":391,"Cursor_node":172,"update_editor_box":430,"on.text_input":388,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":455,"B":379,"fw_parent":460,"box_height":345,"Input_filename":436,"compute_layout":385,"scale":7,"on":1,"fw_app":"mastodon-luaML","on.code_change":458,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,width=600,type='text',data=dehtml(thread_data.content)}table.insert(Surface, tmp)end
{"Surface":434,"on.draw":418,"vx":5,"render_thread_to_surface":460,"Viewport":303,"add_thick_line":400,"vy":8,"copy_shape":396,"line_height":365,"to_text":180,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"on.update":368,"font":353,"on.keychord_press":391,"Cursor_node":172,"update_editor_box":430,"on.text_input":388,"schema1_of_y":366,"on.initialize":446,"y_of_schema1":364,"A":455,"B":379,"fw_parent":459,"box_height":345,"Input_filename":436,"compute_layout":385,"scale":7,"on":1,"fw_app":"mastodon-luaML","on.code_change":458,"dehtml":456}
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {x=0, y=0,type='text',data=dehtml(thread_data.content)}table.insert(Surface, tmp)end
{"vy":8,"fw_parent":458,"render_thread_to_surface":459,"on.mouse_press":179,"on.mouse_release":367,"initialize_editor":338,"add_thick_line":400,"on":1,"on.keychord_press":391,"scale":7,"update_editor_box":430,"on.initialize":446,"schema1_of_y":366,"B":379,"y_of_schema1":364,"line_height":365,"compute_layout":385,"Cursor_node":172,"on.code_change":458,"to_text":180,"font":353,"dehtml":456,"on.text_input":388,"Input_filename":436,"Surface":434,"A":455,"on.update":368,"on.draw":418,"copy_shape":396,"vx":5,"box_height":345,"Viewport":303,"fw_app":"mastodon-luaML"}
on.code_change = function()print('code changed 2', Input_filename)A(Input_filename) -- just in case we edited somethingend
{"on.update":368,"on.keychord_press":391,"render_thread_to_surface":454,"scale":7,"add_thick_line":400,"copy_shape":396,"to_text":180,"dehtml":456,"fw_parent":457,"fw_app":"mastodon-luaML","box_height":345,"compute_layout":385,"font":353,"on.code_change":458,"schema1_of_y":366,"y_of_schema1":364,"B":379,"on.draw":418,"update_editor_box":430,"vx":5,"on":1,"Viewport":303,"on.text_input":388,"Surface":434,"vy":8,"on.initialize":446,"Input_filename":436,"Cursor_node":172,"A":455,"on.mouse_press":179,"line_height":365,"on.mouse_release":367,"initialize_editor":338}
on.code_change = function()print('code changed 2')A(Input_filename) -- just in case we edited somethingend
{"on.update":368,"on.keychord_press":391,"render_thread_to_surface":454,"scale":7,"add_thick_line":400,"copy_shape":396,"to_text":180,"dehtml":456,"fw_parent":456,"fw_app":"mastodon-luaML","box_height":345,"compute_layout":385,"font":353,"on.code_change":457,"schema1_of_y":366,"y_of_schema1":364,"B":379,"on.draw":418,"update_editor_box":430,"vx":5,"on":1,"Viewport":303,"on.text_input":388,"Surface":434,"vy":8,"on.initialize":446,"Input_filename":436,"Cursor_node":172,"A":455,"on.mouse_press":179,"line_height":365,"on.mouse_release":367,"initialize_editor":338}
{"on.update":368,"on.keychord_press":391,"render_thread_to_surface":454,"scale":7,"add_thick_line":400,"copy_shape":396,"to_text":180,"dehtml":456,"fw_parent":455,"fw_app":"mastodon-luaML","box_height":345,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"y_of_schema1":364,"B":379,"on.draw":418,"update_editor_box":430,"vx":5,"on":1,"Viewport":303,"on.text_input":388,"Surface":434,"vy":8,"on.initialize":446,"Input_filename":436,"Cursor_node":172,"A":455,"on.mouse_press":179,"line_height":365,"on.mouse_release":367,"initialize_editor":338}
dehtml = function(s)return s:gsub('<[^>]*>', '')end
{"on.update":368,"on.keychord_press":391,"render_thread_to_surface":454,"scale":7,"add_thick_line":400,"copy_shape":396,"to_text":180,"dehtml":452,"fw_parent":454,"fw_app":"mastodon-luaML","box_height":345,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"y_of_schema1":364,"B":379,"on.draw":418,"update_editor_box":430,"vx":5,"on":1,"Viewport":303,"on.text_input":388,"Surface":434,"vy":8,"on.initialize":446,"Input_filename":436,"Cursor_node":172,"A":455,"on.mouse_press":179,"line_height":365,"on.mouse_release":367,"initialize_editor":338}
A = function(filename)if filename thenprint('reading', filename)local f = io.open(filename)assert(f)local thread_data = json.decode(f:read('*a'))render_thread_to_surface(thread_data)endB()end
render_thread_to_surface = function(thread_data)Surface = {}local tmp = {type='text',data=dehtml(thread_data.content)}table.insert(Surface, tmp)end
{"on.update":368,"on.keychord_press":391,"render_thread_to_surface":454,"scale":7,"add_thick_line":400,"copy_shape":396,"to_text":180,"dehtml":452,"fw_parent":453,"fw_app":"mastodon-luaML","box_height":345,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"y_of_schema1":364,"B":379,"on.draw":418,"update_editor_box":430,"vx":5,"on":1,"Viewport":303,"on.text_input":388,"Surface":434,"vy":8,"on.initialize":446,"Input_filename":436,"Cursor_node":172,"A":449,"on.mouse_press":179,"line_height":365,"on.mouse_release":367,"initialize_editor":338}
render_thread_to_surface = function(thread_data)love.graphics.print(thread_data.content)end
{"on.update":368,"on.keychord_press":391,"render_thread_to_surface":453,"scale":7,"add_thick_line":400,"copy_shape":396,"to_text":180,"dehtml":452,"fw_parent":452,"fw_app":"mastodon-luaML","box_height":345,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"y_of_schema1":364,"B":379,"on.draw":418,"update_editor_box":430,"vx":5,"on":1,"Viewport":303,"on.text_input":388,"Surface":434,"vy":8,"on.initialize":446,"Input_filename":436,"Cursor_node":172,"A":449,"on.mouse_press":179,"line_height":365,"on.mouse_release":367,"initialize_editor":338}
{"on.update":368,"on.keychord_press":391,"render_thread_to_surface":451,"scale":7,"add_thick_line":400,"copy_shape":396,"to_text":180,"dehtml":452,"fw_parent":451,"fw_app":"mastodon-luaML","box_height":345,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"y_of_schema1":364,"B":379,"on.draw":418,"update_editor_box":430,"vx":5,"on":1,"Viewport":303,"on.text_input":388,"Surface":434,"vy":8,"on.initialize":446,"Input_filename":436,"Cursor_node":172,"A":449,"on.mouse_press":179,"line_height":365,"on.mouse_release":367,"initialize_editor":338}
dehtml = function(s)return s:gsub('<[^>]*>', '')end
render_thread_to_surface = function(thread_data)end
{"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"render_thread_to_surface":451,"font":353,"on.code_change":443,"schema1_of_y":366,"initialize_editor":338,"fw_parent":450,"on.text_input":388,"scale":7,"fw_app":"mastodon-luaML","y_of_schema1":364,"on":1,"copy_shape":396,"on.draw":418,"to_text":180,"vx":5,"add_thick_line":400,"Viewport":303,"Input_filename":436,"on.mouse_release":367,"vy":8,"Surface":434,"on.initialize":446,"Cursor_node":172,"A":449,"on.mouse_press":179,"line_height":365,"update_editor_box":430,"B":379}
render_thread_to_surface = function(thread_data)end
{"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"render_thread_to_surface":450,"font":353,"on.code_change":443,"schema1_of_y":366,"initialize_editor":338,"fw_parent":449,"on.text_input":388,"scale":7,"fw_app":"mastodon-luaML","y_of_schema1":364,"on":1,"copy_shape":396,"on.draw":418,"to_text":180,"vx":5,"add_thick_line":400,"Viewport":303,"Input_filename":436,"on.mouse_release":367,"vy":8,"Surface":434,"on.initialize":446,"Cursor_node":172,"A":449,"on.mouse_press":179,"line_height":365,"update_editor_box":430,"B":379}
{"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"initialize_editor":338,"fw_parent":448,"on.text_input":388,"scale":7,"fw_app":"mastodon-luaML","y_of_schema1":364,"on":1,"copy_shape":396,"on.draw":418,"to_text":180,"vx":5,"add_thick_line":400,"Viewport":303,"Input_filename":436,"on.mouse_release":367,"vy":8,"Surface":434,"on.initialize":446,"Cursor_node":172,"A":449,"on.mouse_press":179,"line_height":365,"update_editor_box":430,"B":379}
A = function(filename)if filename thenlocal f = io.open(filename)assert(f)local thread_data = json.decode(f:read('*a'))render_thread_to_surface(thread_data)endB()end
{"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"initialize_editor":338,"fw_parent":446,"on.text_input":388,"scale":7,"fw_app":"mastodon-luaML","y_of_schema1":364,"on":1,"copy_shape":396,"on.draw":418,"to_text":180,"vx":5,"add_thick_line":400,"Viewport":303,"Input_filename":436,"on.mouse_release":367,"vy":8,"Surface":434,"on.initialize":446,"Cursor_node":172,"A":448,"on.mouse_press":179,"line_height":365,"update_editor_box":430,"B":379}
A = function(filename)if filename thenlocal f = io.open(filename)assert(f)local thread_data = json.decode(f:read('*a'))endB()end
{"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"on.text_input":388,"update_editor_box":430,"fw_app":"mastodon-luaML","scale":7,"B":379,"y_of_schema1":364,"on":1,"copy_shape":396,"on.draw":418,"to_text":180,"vx":5,"add_thick_line":400,"Viewport":303,"on.initialize":446,"Surface":434,"vy":8,"on.mouse_release":367,"Input_filename":436,"Cursor_node":172,"A":447,"on.mouse_press":179,"line_height":365,"fw_parent":446,"initialize_editor":338}
A = function(filename)if filename thenlocal f = io.open(filename)assert(f)local thread_data = json.decode(f:read('*a))endB()end
on.initialize = function(arg)Input_filename = arg[1]A(Input_filename)end
{"on.update":368,"box_height":345,"on.keychord_press":391,"compute_layout":385,"font":353,"on.code_change":443,"schema1_of_y":366,"on.text_input":388,"update_editor_box":430,"fw_app":"mastodon-luaML","scale":7,"B":379,"y_of_schema1":364,"on":1,"copy_shape":396,"on.draw":418,"to_text":180,"vx":5,"add_thick_line":400,"Viewport":303,"on.initialize":446,"Surface":434,"vy":8,"on.mouse_release":367,"Input_filename":436,"Cursor_node":172,"A":444,"on.mouse_press":179,"line_height":365,"fw_parent":445,"initialize_editor":338}
on.initialize = function(arg)Input_filename = arg[1]A(Input_filename)end
{"on.mouse_press":179,"initialize_editor":338,"on.mouse_release":367,"box_height":345,"on.update":368,"compute_layout":385,"on.keychord_press":391,"on.text_input":388,"Input_filename":436,"y_of_schema1":364,"A":444,"copy_shape":396,"fw_parent":444,"line_height":365,"fw_app":"mastodon-luaML","on.code_change":443,"to_text":180,"Surface":434,"font":353,"on.initialize":445,"on.draw":418,"on":1,"vx":5,"add_thick_line":400,"Viewport":303,"B":379,"update_editor_box":430,"vy":8,"scale":7,"Cursor_node":172,"schema1_of_y":366}
{"A":444,"on.mouse_press":179,"Cursor_node":172,"y_of_schema1":364,"initialize_editor":338,"copy_shape":396,"scale":7,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":441,"B":379,"on.code_change":443,"schema1_of_y":366,"Input_filename":436,"fw_app":"mastodon-luaML","on.update":368,"fw_parent":443,"update_editor_box":430,"Surface":434,"add_thick_line":400,"on.mouse_release":367,"on.draw":418,"on":1,"vx":5,"on.text_input":388,"Viewport":303,"font":353,"to_text":180,"vy":8,"line_height":365}
A = function(filename)if filename thenlocal f = io.open(filename)assert(f)endB()end
on.code_change = function()print('code changed')A(Input_filename) -- just in case we edited somethingend
{"A":438,"on.mouse_press":179,"Cursor_node":172,"y_of_schema1":364,"initialize_editor":338,"copy_shape":396,"scale":7,"box_height":345,"on.keychord_press":391,"compute_layout":385,"on.initialize":441,"B":379,"on.code_change":443,"schema1_of_y":366,"Input_filename":436,"fw_app":"mastodon-luaML","on.update":368,"fw_parent":442,"update_editor_box":430,"Surface":434,"add_thick_line":400,"on.mouse_release":367,"on.draw":418,"on":1,"vx":5,"on.text_input":388,"Viewport":303,"font":353,"to_text":180,"vy":8,"line_height":365}
on.code_change = function()print('code changed')if Input_filename thenA(Input_filename) -- just in case we edited somethingendend
{"on.mouse_release":367,"initialize_editor":338,"on.update":368,"y_of_schema1":364,"on.keychord_press":391,"compute_layout":385,"Input_filename":436,"on.code_change":442,"box_height":345,"font":353,"Cursor_node":172,"line_height":365,"to_text":180,"copy_shape":396,"Surface":434,"scale":7,"on.text_input":388,"on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"update_editor_box":430,"fw_parent":441,"vy":8,"fw_app":"mastodon-luaML","B":379,"schema1_of_y":366,"on.initialize":441,"on.mouse_press":179,"A":438}
on.initialize = function(arg)if #arg == 0 then return endInput_filename = arg[1]A(Input_filename)end
{"on.mouse_release":367,"initialize_editor":338,"on.update":368,"y_of_schema1":364,"on.keychord_press":391,"compute_layout":385,"Input_filename":436,"on.code_change":306,"box_height":345,"font":353,"Cursor_node":172,"line_height":365,"to_text":180,"copy_shape":396,"Surface":434,"scale":7,"on.text_input":388,"on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"update_editor_box":430,"fw_parent":440,"vy":8,"fw_app":"mastodon-luaML","B":379,"schema1_of_y":366,"on.initialize":441,"on.mouse_press":179,"A":438}
on.initialize = function(arg)if #arg == 0 then return endprint('aa', #arg)Input_filename = arg[1]A(Input_filename)end
{"on.mouse_release":367,"initialize_editor":338,"on.update":368,"y_of_schema1":364,"on.keychord_press":391,"compute_layout":385,"Input_filename":436,"on.code_change":306,"box_height":345,"font":353,"Cursor_node":172,"line_height":365,"to_text":180,"copy_shape":396,"Surface":434,"scale":7,"on.text_input":388,"on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"update_editor_box":430,"fw_parent":439,"vy":8,"fw_app":"mastodon-luaML","B":379,"schema1_of_y":366,"on.initialize":440,"on.mouse_press":179,"A":438}
on.initialize = function(arg)if #arg == 0 then return endprint(#arg)Input_filename = arg[1]A(Input_filename)end
{"on.mouse_release":367,"initialize_editor":338,"on.update":368,"y_of_schema1":364,"on.keychord_press":391,"compute_layout":385,"Input_filename":436,"on.code_change":306,"box_height":345,"font":353,"Cursor_node":172,"line_height":365,"to_text":180,"copy_shape":396,"Surface":434,"scale":7,"on.text_input":388,"on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"update_editor_box":430,"fw_parent":438,"vy":8,"fw_app":"mastodon-luaML","B":379,"schema1_of_y":366,"on.initialize":439,"on.mouse_press":179,"A":438}
{"on.mouse_release":367,"initialize_editor":338,"on.update":368,"y_of_schema1":364,"on.keychord_press":391,"compute_layout":385,"Input_filename":436,"on.code_change":306,"box_height":345,"font":353,"Cursor_node":172,"line_height":365,"to_text":180,"copy_shape":396,"Surface":434,"scale":7,"on.text_input":388,"on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"update_editor_box":430,"fw_parent":437,"vy":8,"fw_app":"mastodon-luaML","B":379,"schema1_of_y":366,"on.initialize":437,"on.mouse_press":179,"A":438}
A = function(filename)local f = io.open(filename)assert(f)B()end
on.initialize = function(arg)if #arg == 0 then return endInput_filename = arg[1]A(Input_filename)end
{"on.mouse_release":367,"initialize_editor":338,"on.update":368,"y_of_schema1":364,"on.keychord_press":391,"compute_layout":385,"Input_filename":436,"on.code_change":306,"box_height":345,"font":353,"Cursor_node":172,"line_height":365,"to_text":180,"copy_shape":396,"Surface":434,"scale":7,"on.text_input":388,"on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"update_editor_box":430,"fw_parent":436,"vy":8,"fw_app":"mastodon-luaML","B":379,"schema1_of_y":366,"on.initialize":437,"on.mouse_press":179,"A":431}
{"on.mouse_release":367,"initialize_editor":338,"on.update":368,"y_of_schema1":364,"on.keychord_press":391,"compute_layout":385,"Input_filename":436,"on.code_change":306,"box_height":345,"font":353,"Cursor_node":172,"line_height":365,"to_text":180,"copy_shape":396,"Surface":434,"scale":7,"on.text_input":388,"on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"update_editor_box":430,"fw_parent":435,"vy":8,"fw_app":"mastodon-luaML","B":379,"schema1_of_y":366,"on.initialize":435,"on.mouse_press":179,"A":431}
Input_filename = nil
on.initialize = function(arg)A(arg)end
{"on.mouse_release":367,"initialize_editor":338,"on.update":368,"y_of_schema1":364,"on.keychord_press":391,"compute_layout":385,"on.code_change":306,"box_height":345,"font":353,"Cursor_node":172,"line_height":365,"to_text":180,"copy_shape":396,"Surface":434,"scale":7,"on.text_input":388,"on.draw":418,"add_thick_line":400,"vx":5,"on":1,"Viewport":303,"update_editor_box":430,"fw_parent":434,"vy":8,"fw_app":"mastodon-luaML","B":379,"schema1_of_y":366,"on.initialize":435,"on.mouse_press":179,"A":431}
{"on.keychord_press":391,"schema1_of_y":366,"on.text_input":388,"initialize_editor":338,"on":1,"y_of_schema1":364,"A":431,"compute_layout":385,"to_text":180,"Surface":434,"B":379,"vy":8,"on.draw":418,"on.initialize":350,"vx":5,"line_height":365,"Viewport":303,"fw_parent":433,"update_editor_box":430,"fw_app":"mastodon-luaML","add_thick_line":400,"scale":7,"copy_shape":396,"on.code_change":306,"on.mouse_press":179,"on.update":368,"on.mouse_release":367,"Cursor_node":172,"font":353,"box_height":345}
Surface = {-- test data{type='line', data={0,-1000, 0,1000}},{type='line', data={-10000,0, 10000,0}},{type='rectangle', x=50,y=50, w=20,h=80, r=1,g=0,b=0},{type='circle', x=300,y=200, radius=40, r=1,g=0,b=1},{type='arc', x=0,y=0, radius=50, angle1=0, angle2=math.pi*2/3},{type='ellipse', x=100,y=100, radiusx=10, radiusy=50},{type='bezier', data={25,25, 25,125, 75,25, 125,25}},}
{"A":431,"on.draw":418,"on.keychord_press":391,"vx":5,"B":379,"Viewport":303,"add_thick_line":400,"schema1_of_y":366,"copy_shape":396,"initialize_editor":338,"on":1,"box_height":345,"on.mouse_press":179,"font":353,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"on.code_change":306,"scale":7,"y_of_schema1":364,"on.initialize":350,"on.text_input":388,"update_editor_box":430,"fw_parent":432,"compute_layout":385,"fw_app":"mastodon-luaML","vy":8,"Surface":422,"to_text":180,"line_height":365}
{"A":431,"on.draw":418,"on.keychord_press":391,"vx":5,"B":379,"Viewport":303,"add_thick_line":400,"schema1_of_y":366,"copy_shape":396,"initialize_editor":338,"on":1,"box_height":345,"on.mouse_press":179,"font":353,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"on.code_change":306,"scale":7,"y_of_schema1":364,"on.initialize":350,"on.text_input":388,"update_editor_box":430,"fw_parent":431,"compute_layout":385,"fw_app":"mastodon-luaML","Page2":429,"vy":8,"Surface":422,"to_text":180,"line_height":365}
{"A":431,"on.draw":418,"on.keychord_press":391,"vx":5,"B":379,"Viewport":303,"add_thick_line":400,"schema1_of_y":366,"copy_shape":396,"Page":381,"initialize_editor":338,"on":1,"box_height":345,"on.mouse_press":179,"font":353,"on.mouse_release":367,"Cursor_node":172,"on.update":368,"on.code_change":306,"scale":7,"y_of_schema1":364,"on.initialize":350,"on.text_input":388,"update_editor_box":430,"fw_parent":430,"compute_layout":385,"fw_app":"mastodon-luaML","Page2":429,"vy":8,"Surface":422,"to_text":180,"line_height":365}
A = function(preserve_screen_top_of_cursor_node)-- continue the pipelineB(preserve_screen_top_of_cursor_node)-- TODO: ugly that we're manipulating editor objects twiceend