Full Code of fastn-stack/fastn for AI

main a473f41d5af1 cached
2749 files
24.2 MB
6.5M tokens
8992 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (25,947K chars total). Download the full file to get everything.
Repository: fastn-stack/fastn
Branch: main
Commit: a473f41d5af1
Files: 2749
Total size: 24.2 MB

Directory structure:
gitextract_5tz6h9ik/

├── .all-contributorsrc
├── .dockerignore
├── .gitattributes
├── .github/
│   ├── Dockerfile
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── code_issue.md
│   │   └── config.yml
│   ├── RELEASE_TEMPLATE.md
│   ├── dependabot.yml
│   ├── dprint-ci.json
│   ├── lib/
│   │   └── README.md
│   ├── scripts/
│   │   ├── populate-table.py
│   │   ├── run-integration-tests.sh
│   │   └── test-server.py
│   └── workflows/
│       ├── create-release.yml
│       ├── deploy-fastn-com.yml
│       ├── email-critical-tests.yml
│       ├── optimize-images.yml
│       └── tests-and-formatting.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .rusty-hook.toml
├── Cargo.toml
├── Changelog.md
├── Cheatsheet.md
├── DOCUMENTATION_PLAN.md
├── LICENSE
├── README.md
├── SECURITY.md
├── WINDOWS_INSTALLER.md
├── clift/
│   ├── Cargo.toml
│   └── src/
│       ├── api/
│       │   ├── commit_upload.rs
│       │   ├── initiate_upload.rs
│       │   └── mod.rs
│       ├── commands/
│       │   ├── mod.rs
│       │   └── upload.rs
│       ├── lib.rs
│       └── utils/
│           ├── call_api.rs
│           ├── generate_hash.rs
│           ├── get_local_files.rs
│           ├── github_token.rs
│           ├── mod.rs
│           ├── site_token.rs
│           ├── update_token.rs
│           └── uploader.rs
├── design/
│   ├── README.md
│   ├── apps.toml
│   ├── cli.toml
│   ├── design-system.toml
│   ├── dynamic.toml
│   ├── font.toml
│   ├── github.md
│   ├── js-runtime/
│   │   ├── README.md
│   │   ├── building.md
│   │   ├── compilation.md
│   │   ├── crate.md
│   │   ├── dynamic-class-css.md
│   │   ├── list.md
│   │   ├── markdown.md
│   │   ├── markup.md
│   │   ├── registry.md
│   │   ├── roles.md
│   │   ├── ssr.md
│   │   ├── syntax.md
│   │   └── which-quick-js.md
│   ├── new-design.md
│   ├── package-manager.toml
│   ├── processors.toml
│   ├── purpose.toml
│   ├── routes.toml
│   ├── runtime/
│   │   ├── README.md
│   │   ├── browser.md
│   │   ├── build.md
│   │   ├── compilation.md
│   │   ├── data-layer.md
│   │   ├── dom.md
│   │   ├── features.md
│   │   ├── linking.md
│   │   ├── ssr.md
│   │   └── strings.md
│   ├── server.toml
│   ├── sitemap.toml
│   └── ssg.toml
├── events.diff
├── fastn/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
├── fastn-builtins/
│   ├── Cargo.toml
│   └── src/
│       ├── constants.rs
│       └── lib.rs
├── fastn-context/
│   ├── Cargo.toml
│   ├── NEXT-complete-design.md
│   ├── NEXT-counters.md
│   ├── NEXT-locks.md
│   ├── NEXT-metrics-and-data.md
│   ├── NEXT-monitoring.md
│   ├── NEXT-operation-tracking.md
│   ├── NEXT-status-distribution.md
│   ├── README-FULL.md
│   ├── README.md
│   ├── examples/
│   │   └── minimal_test.rs
│   └── src/
│       ├── context.rs
│       ├── lib.rs
│       └── status.rs
├── fastn-context-macros/
│   ├── Cargo.toml
│   └── src/
│       └── lib.rs
├── fastn-core/
│   ├── Cargo.toml
│   ├── bot_user_agents.txt
│   ├── fastn.js
│   ├── fastn2022.js
│   ├── fbt-tests/
│   │   ├── 01-help/
│   │   │   └── cmd.p1
│   │   ├── 02-hello/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fastn.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── fail_doc.ftd
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── fail_doc.ftd
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 03-nested-document/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── index.ftd
│   │   │   │       └── nested/
│   │   │   │           ├── document.ftd
│   │   │   │           └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── manifest.json
│   │   │       └── nested/
│   │   │           ├── document/
│   │   │           │   └── index.html
│   │   │           ├── document.ftd
│   │   │           ├── index.ftd
│   │   │           └── index.html
│   │   ├── 04-import-code-block/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── index.ftd
│   │   │   │       └── lib.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── lib/
│   │   │       │   └── index.html
│   │   │       ├── lib.ftd
│   │   │       └── manifest.json
│   │   ├── 05-hello-font/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── hello/
│   │   │   │       │   └── world/
│   │   │   │       │       └── test.py
│   │   │   │       ├── hello.py
│   │   │   │       ├── index
│   │   │   │       ├── index.ftd
│   │   │   │       └── index.md
│   │   │   └── output/
│   │   │       ├── -/
│   │   │       │   └── www.amitu.com/
│   │   │       │       ├── hello/
│   │   │       │       │   └── world/
│   │   │       │       │       └── test.py
│   │   │       │       ├── hello.py
│   │   │       │       ├── index
│   │   │       │       └── index.ftd
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── hello/
│   │   │       │   └── world/
│   │   │       │       └── test.py
│   │   │       ├── hello.py
│   │   │       ├── index
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 06-nested-document-sync/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── .fpm.ftd
│   │   │       └── amitu/
│   │   │           ├── FASTN.ftd
│   │   │           ├── index.ftd
│   │   │           └── nested/
│   │   │               ├── document.ftd
│   │   │               └── index.ftd
│   │   ├── 07-hello-tracks/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── .history/
│   │   │   │       │   ├── .latest.ftd
│   │   │   │       │   ├── FPM.1639765778133988000.ftd
│   │   │   │       │   ├── hello.1639765778133988000.txt
│   │   │   │       │   ├── index-track.1639765778133988000.ftd
│   │   │   │       │   └── index.1639765778133988000.ftd
│   │   │   │       ├── FPM.ftd
│   │   │   │       ├── hello.txt
│   │   │   │       ├── index-track.ftd
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       └── index-track.ftd.track
│   │   ├── 08-static-assets/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css
│   │   │       ├── code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css
│   │   │       ├── code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css
│   │   │       ├── code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css
│   │   │       ├── code-theme-256C21B515FC9E77F95D88689A4086B9D9406B7AAE3A273780FE8B8748C5A7D2.css
│   │   │       ├── code-theme-4DD8479BE14A755645BC09FF433FB70EB4CB28F0CBF3CA98DCB71B244B85B194.css
│   │   │       ├── code-theme-60E02531E77333F3F1B636C4FC43E976EA9F41AD75268B2DD825C33C68B573A6.css
│   │   │       ├── code-theme-6EB6F03F9F578742CA0CD1189693E43A6135D910989ADD88CA3C0D6117EE24D7.css
│   │   │       ├── code-theme-7852E516BA094B01897820BB3432BE553FE5B28F00E9CA0EBC9DFFB8312EE8BF.css
│   │   │       ├── code-theme-792C7BB9F4C8DFF3E0CBC354D2084DBF71BC5750C2C1357F0E7D936867AFAB62.css
│   │   │       ├── code-theme-88F91252A8A0EA125B4BA2C7B85E65580DB580F1477931AADCB5118E4E69D1CD.css
│   │   │       ├── code-theme-8C59190F5018F48CCBB063359072EE9053D04923BBC5D1BA52B574E78D8C536A.css
│   │   │       ├── code-theme-8CCA3D600F91FA55950DF3132F2ABE4BA14CEEA13CD23E157BF6A137762B8452.css
│   │   │       ├── code-theme-95B9118AFC8631777EEBBD89B2066C3706A6DF3579B14F41AF05564E41CAA09C.css
│   │   │       ├── code-theme-96E503EA0E8F80C5DDF81545C9B1A40DE4CDB7CD8F52664F747FD9E7BB0207B8.css
│   │   │       ├── code-theme-99CD7B013C96C4632F0AEA39AC265387B814AE85A7D33666A4AE4BEFF59016D0.css
│   │   │       ├── code-theme-9A3284FD117DFF7CFD432FF860A5E14169FA592BC3DA4F5E8A6975143F5EA07F.css
│   │   │       ├── code-theme-9A45313F167DBD90654BFD5BB3BC0BDF6AE447485C30B0389ADA7B49C069E46A.css
│   │   │       ├── code-theme-A24DC8F09D03756A62923E8A883CAE3B938D54E2813F0855312D2554DBE97BAD.css
│   │   │       ├── code-theme-A352AF572179AB980583D41BC41ADDBA36C4C17757A34C1C6AAAF2C253E25CE3.css
│   │   │       ├── code-theme-B3AEA322EADEDA61F0E219845A0E9C8E73F6345E49362B46E6F52CEE40471248.css
│   │   │       ├── code-theme-B68AA27E05B319F04A9CD747AADBF9B9CD791E040DEC519AE9544B4FF65DDBAC.css
│   │   │       ├── code-theme-CFBB665E50E0439263BF0F3D59B1F0F20F40F379C81B1B14AA9E16DDF70F70E6.css
│   │   │       ├── code-theme-DC76F700474E809F7BA2D9914793D04881B17EA4699BA9C568C83D32A18B0173.css
│   │   │       ├── default-73755E118EA14B5B124FF4106E51628B7152E1302B3ED37177480A59413FF762.js
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── manifest.json
│   │   │       ├── markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
│   │   │       ├── prism-73F718B9234C00C5C14AB6A11BF239A103F0B0F93B69CD55CB5C6530501182EB.css
│   │   │       └── prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
│   │   ├── 09-markdown-pages/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── index.ftd
│   │   │   │       └── page.md
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css
│   │   │       ├── code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css
│   │   │       ├── code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css
│   │   │       ├── code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css
│   │   │       ├── code-theme-256C21B515FC9E77F95D88689A4086B9D9406B7AAE3A273780FE8B8748C5A7D2.css
│   │   │       ├── code-theme-4DD8479BE14A755645BC09FF433FB70EB4CB28F0CBF3CA98DCB71B244B85B194.css
│   │   │       ├── code-theme-60E02531E77333F3F1B636C4FC43E976EA9F41AD75268B2DD825C33C68B573A6.css
│   │   │       ├── code-theme-6EB6F03F9F578742CA0CD1189693E43A6135D910989ADD88CA3C0D6117EE24D7.css
│   │   │       ├── code-theme-7852E516BA094B01897820BB3432BE553FE5B28F00E9CA0EBC9DFFB8312EE8BF.css
│   │   │       ├── code-theme-792C7BB9F4C8DFF3E0CBC354D2084DBF71BC5750C2C1357F0E7D936867AFAB62.css
│   │   │       ├── code-theme-88F91252A8A0EA125B4BA2C7B85E65580DB580F1477931AADCB5118E4E69D1CD.css
│   │   │       ├── code-theme-8C59190F5018F48CCBB063359072EE9053D04923BBC5D1BA52B574E78D8C536A.css
│   │   │       ├── code-theme-8CCA3D600F91FA55950DF3132F2ABE4BA14CEEA13CD23E157BF6A137762B8452.css
│   │   │       ├── code-theme-95B9118AFC8631777EEBBD89B2066C3706A6DF3579B14F41AF05564E41CAA09C.css
│   │   │       ├── code-theme-96E503EA0E8F80C5DDF81545C9B1A40DE4CDB7CD8F52664F747FD9E7BB0207B8.css
│   │   │       ├── code-theme-99CD7B013C96C4632F0AEA39AC265387B814AE85A7D33666A4AE4BEFF59016D0.css
│   │   │       ├── code-theme-9A3284FD117DFF7CFD432FF860A5E14169FA592BC3DA4F5E8A6975143F5EA07F.css
│   │   │       ├── code-theme-9A45313F167DBD90654BFD5BB3BC0BDF6AE447485C30B0389ADA7B49C069E46A.css
│   │   │       ├── code-theme-A24DC8F09D03756A62923E8A883CAE3B938D54E2813F0855312D2554DBE97BAD.css
│   │   │       ├── code-theme-A352AF572179AB980583D41BC41ADDBA36C4C17757A34C1C6AAAF2C253E25CE3.css
│   │   │       ├── code-theme-B3AEA322EADEDA61F0E219845A0E9C8E73F6345E49362B46E6F52CEE40471248.css
│   │   │       ├── code-theme-B68AA27E05B319F04A9CD747AADBF9B9CD791E040DEC519AE9544B4FF65DDBAC.css
│   │   │       ├── code-theme-CFBB665E50E0439263BF0F3D59B1F0F20F40F379C81B1B14AA9E16DDF70F70E6.css
│   │   │       ├── code-theme-DC76F700474E809F7BA2D9914793D04881B17EA4699BA9C568C83D32A18B0173.css
│   │   │       ├── default-19D2867920A9DCA55CE23FEDCE770D4077F08B32526E28D226376463C3C1C583.js
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── manifest.json
│   │   │       ├── markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
│   │   │       ├── prism-73F718B9234C00C5C14AB6A11BF239A103F0B0F93B69CD55CB5C6530501182EB.css
│   │   │       └── prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
│   │   ├── 10-readme-index/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FPM.ftd
│   │   │   │       └── README.md
│   │   │   └── output/
│   │   │       ├── FPM/
│   │   │       │   └── index.html
│   │   │       └── index.html
│   │   ├── 11-readme-with-index/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── README.md
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 12-translation/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FPM.ftd
│   │   │   │       ├── blog.ftd
│   │   │   │       └── not-render.ftd
│   │   │   └── output/
│   │   │       ├── -/
│   │   │       │   ├── index.html
│   │   │       │   └── translation-status/
│   │   │       │       └── index.html
│   │   │       ├── FPM.ftd
│   │   │       ├── blog/
│   │   │       │   └── index.html
│   │   │       ├── db/
│   │   │       │   └── index.html
│   │   │       ├── index.html
│   │   │       └── lib/
│   │   │           └── index.html
│   │   ├── 13-translation-hindi/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── .history/
│   │   │   │       │   ├── .latest.ftd
│   │   │   │       │   └── lib.1640192744709173000.ftd
│   │   │   │       ├── .tracks/
│   │   │   │       │   └── lib.ftd.track
│   │   │   │       ├── FPM/
│   │   │   │       │   └── translation/
│   │   │   │       │       └── out-of-date.ftd
│   │   │   │       ├── FPM.ftd
│   │   │   │       └── lib.ftd
│   │   │   └── output/
│   │   │       ├── FPM/
│   │   │       │   ├── index.html
│   │   │       │   └── translation-status/
│   │   │       │       └── index.html
│   │   │       ├── FPM.ftd
│   │   │       ├── index.html
│   │   │       └── lib/
│   │   │           └── index.html
│   │   ├── 14-translation-mark-upto-date-and-translation-status/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── .history/
│   │   │   │       │   ├── .latest.ftd
│   │   │   │       │   └── lib.1639759839283128000.ftd
│   │   │   │       ├── FPM.ftd
│   │   │   │       └── lib.ftd
│   │   │   └── output/
│   │   │       └── lib.ftd.track
│   │   ├── 15-fpm-dependency-alias/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 16-include-processor/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── FASTN.ftd
│   │   │   │   ├── code/
│   │   │   │   │   └── dummy_code.rs
│   │   │   │   └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 17-sitemap/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       ├── guide/
│   │   │       │   └── install.ftd
│   │   │       └── index.ftd
│   │   ├── 18-fmt/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── FASTN.ftd
│   │   │   │   └── index.ftd
│   │   │   └── output/
│   │   │       ├── .fastn/
│   │   │       │   └── config.json
│   │   │       ├── FASTN.ftd
│   │   │       └── index.ftd
│   │   ├── 19-offline-build/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── FASTN.ftd
│   │   │   │   └── index.ftd
│   │   │   └── output/
│   │   │       ├── -/
│   │   │       │   └── fastn-stack.github.io/
│   │   │       │       └── fastn-js/
│   │   │       │           └── download.js
│   │   │       ├── FASTN.ftd
│   │   │       ├── code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css
│   │   │       ├── code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css
│   │   │       ├── code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css
│   │   │       ├── code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css
│   │   │       ├── code-theme-256C21B515FC9E77F95D88689A4086B9D9406B7AAE3A273780FE8B8748C5A7D2.css
│   │   │       ├── code-theme-4DD8479BE14A755645BC09FF433FB70EB4CB28F0CBF3CA98DCB71B244B85B194.css
│   │   │       ├── code-theme-60E02531E77333F3F1B636C4FC43E976EA9F41AD75268B2DD825C33C68B573A6.css
│   │   │       ├── code-theme-6EB6F03F9F578742CA0CD1189693E43A6135D910989ADD88CA3C0D6117EE24D7.css
│   │   │       ├── code-theme-7852E516BA094B01897820BB3432BE553FE5B28F00E9CA0EBC9DFFB8312EE8BF.css
│   │   │       ├── code-theme-792C7BB9F4C8DFF3E0CBC354D2084DBF71BC5750C2C1357F0E7D936867AFAB62.css
│   │   │       ├── code-theme-88F91252A8A0EA125B4BA2C7B85E65580DB580F1477931AADCB5118E4E69D1CD.css
│   │   │       ├── code-theme-8C59190F5018F48CCBB063359072EE9053D04923BBC5D1BA52B574E78D8C536A.css
│   │   │       ├── code-theme-8CCA3D600F91FA55950DF3132F2ABE4BA14CEEA13CD23E157BF6A137762B8452.css
│   │   │       ├── code-theme-95B9118AFC8631777EEBBD89B2066C3706A6DF3579B14F41AF05564E41CAA09C.css
│   │   │       ├── code-theme-96E503EA0E8F80C5DDF81545C9B1A40DE4CDB7CD8F52664F747FD9E7BB0207B8.css
│   │   │       ├── code-theme-99CD7B013C96C4632F0AEA39AC265387B814AE85A7D33666A4AE4BEFF59016D0.css
│   │   │       ├── code-theme-9A3284FD117DFF7CFD432FF860A5E14169FA592BC3DA4F5E8A6975143F5EA07F.css
│   │   │       ├── code-theme-9A45313F167DBD90654BFD5BB3BC0BDF6AE447485C30B0389ADA7B49C069E46A.css
│   │   │       ├── code-theme-A24DC8F09D03756A62923E8A883CAE3B938D54E2813F0855312D2554DBE97BAD.css
│   │   │       ├── code-theme-A352AF572179AB980583D41BC41ADDBA36C4C17757A34C1C6AAAF2C253E25CE3.css
│   │   │       ├── code-theme-B3AEA322EADEDA61F0E219845A0E9C8E73F6345E49362B46E6F52CEE40471248.css
│   │   │       ├── code-theme-B68AA27E05B319F04A9CD747AADBF9B9CD791E040DEC519AE9544B4FF65DDBAC.css
│   │   │       ├── code-theme-CFBB665E50E0439263BF0F3D59B1F0F20F40F379C81B1B14AA9E16DDF70F70E6.css
│   │   │       ├── code-theme-DC76F700474E809F7BA2D9914793D04881B17EA4699BA9C568C83D32A18B0173.css
│   │   │       ├── default-A1BB16FF145420D65E4C815B5AD6C4DA6435B25A2B2ED162A798FF368CEBF57B.js
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── manifest.json
│   │   │       ├── markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
│   │   │       ├── prism-73F718B9234C00C5C14AB6A11BF239A103F0B0F93B69CD55CB5C6530501182EB.css
│   │   │       └── prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
│   │   ├── 20-fastn-update-check/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       └── index.ftd
│   │   ├── 21-http-endpoint/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       └── index.ftd
│   │   ├── 22-request-data-processor/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── FASTN.ftd
│   │   │   │   ├── err.ftd
│   │   │   │   └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css
│   │   │       ├── code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css
│   │   │       ├── code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css
│   │   │       ├── code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css
│   │   │       ├── code-theme-256C21B515FC9E77F95D88689A4086B9D9406B7AAE3A273780FE8B8748C5A7D2.css
│   │   │       ├── code-theme-4DD8479BE14A755645BC09FF433FB70EB4CB28F0CBF3CA98DCB71B244B85B194.css
│   │   │       ├── code-theme-60E02531E77333F3F1B636C4FC43E976EA9F41AD75268B2DD825C33C68B573A6.css
│   │   │       ├── code-theme-6EB6F03F9F578742CA0CD1189693E43A6135D910989ADD88CA3C0D6117EE24D7.css
│   │   │       ├── code-theme-7852E516BA094B01897820BB3432BE553FE5B28F00E9CA0EBC9DFFB8312EE8BF.css
│   │   │       ├── code-theme-792C7BB9F4C8DFF3E0CBC354D2084DBF71BC5750C2C1357F0E7D936867AFAB62.css
│   │   │       ├── code-theme-88F91252A8A0EA125B4BA2C7B85E65580DB580F1477931AADCB5118E4E69D1CD.css
│   │   │       ├── code-theme-8C59190F5018F48CCBB063359072EE9053D04923BBC5D1BA52B574E78D8C536A.css
│   │   │       ├── code-theme-8CCA3D600F91FA55950DF3132F2ABE4BA14CEEA13CD23E157BF6A137762B8452.css
│   │   │       ├── code-theme-95B9118AFC8631777EEBBD89B2066C3706A6DF3579B14F41AF05564E41CAA09C.css
│   │   │       ├── code-theme-96E503EA0E8F80C5DDF81545C9B1A40DE4CDB7CD8F52664F747FD9E7BB0207B8.css
│   │   │       ├── code-theme-99CD7B013C96C4632F0AEA39AC265387B814AE85A7D33666A4AE4BEFF59016D0.css
│   │   │       ├── code-theme-9A3284FD117DFF7CFD432FF860A5E14169FA592BC3DA4F5E8A6975143F5EA07F.css
│   │   │       ├── code-theme-9A45313F167DBD90654BFD5BB3BC0BDF6AE447485C30B0389ADA7B49C069E46A.css
│   │   │       ├── code-theme-A24DC8F09D03756A62923E8A883CAE3B938D54E2813F0855312D2554DBE97BAD.css
│   │   │       ├── code-theme-A352AF572179AB980583D41BC41ADDBA36C4C17757A34C1C6AAAF2C253E25CE3.css
│   │   │       ├── code-theme-B3AEA322EADEDA61F0E219845A0E9C8E73F6345E49362B46E6F52CEE40471248.css
│   │   │       ├── code-theme-B68AA27E05B319F04A9CD747AADBF9B9CD791E040DEC519AE9544B4FF65DDBAC.css
│   │   │       ├── code-theme-CFBB665E50E0439263BF0F3D59B1F0F20F40F379C81B1B14AA9E16DDF70F70E6.css
│   │   │       ├── code-theme-DC76F700474E809F7BA2D9914793D04881B17EA4699BA9C568C83D32A18B0173.css
│   │   │       ├── default-D4F9C23DF6372E1C3161B3560431CCE641AED44770DD55B8AAB3DBEB0A1F3533.js
│   │   │       ├── err.ftd
│   │   │       ├── manifest.json
│   │   │       ├── markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
│   │   │       ├── prism-73F718B9234C00C5C14AB6A11BF239A103F0B0F93B69CD55CB5C6530501182EB.css
│   │   │       └── prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
│   │   ├── 23-toc-processor-test/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       └── index.ftd
│   │   ├── 27-wasm-backend/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   └── amitu/
│   │   │   │       ├── FPM.ftd
│   │   │   │       ├── backend.wasm
│   │   │   │       ├── index.ftd
│   │   │   │       ├── post-two.ftd
│   │   │   │       └── post.ftd
│   │   │   ├── output/
│   │   │   │   ├── -/
│   │   │   │   │   ├── index.html
│   │   │   │   │   └── www.amitu.com/
│   │   │   │   │       └── backend.wasm
│   │   │   │   ├── FPM.ftd
│   │   │   │   ├── index.html
│   │   │   │   ├── post/
│   │   │   │   │   └── index.html
│   │   │   │   └── post-two/
│   │   │   │       └── index.html
│   │   │   └── wasm_backend/
│   │   │       ├── .cargo/
│   │   │       │   └── config
│   │   │       ├── .gitignore
│   │   │       ├── Cargo.toml
│   │   │       └── src/
│   │   │           ├── lib.rs
│   │   │           └── types.rs
│   │   ├── 28-text-input-VALUE/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       ├── actions/
│   │   │       │   └── create-account.ftd
│   │   │       └── index.ftd
│   │   └── fbt.p1
│   ├── ftd/
│   │   ├── design.ftd
│   │   ├── fastn-lib.ftd
│   │   ├── info.ftd
│   │   ├── markdown.ftd
│   │   ├── processors.ftd
│   │   └── translation/
│   │       ├── available-languages.ftd
│   │       ├── missing.ftd
│   │       ├── never-marked.ftd
│   │       ├── original-status.ftd
│   │       ├── out-of-date.ftd
│   │       ├── translation-status.ftd
│   │       └── upto-date.ftd
│   ├── ftd_2022.html
│   ├── redirect.html
│   ├── src/
│   │   ├── auto_import.rs
│   │   ├── catch_panic.rs
│   │   ├── commands/
│   │   │   ├── Changelog.md
│   │   │   ├── build.rs
│   │   │   ├── check.rs
│   │   │   ├── fmt.rs
│   │   │   ├── mod.rs
│   │   │   ├── query.rs
│   │   │   ├── serve.rs
│   │   │   ├── test.rs
│   │   │   └── translation_status.rs
│   │   ├── config/
│   │   │   ├── config_temp.rs
│   │   │   ├── mod.rs
│   │   │   └── utils.rs
│   │   ├── doc.rs
│   │   ├── ds.rs
│   │   ├── error.rs
│   │   ├── file.rs
│   │   ├── font.rs
│   │   ├── google_sheets.rs
│   │   ├── host_builtins.rs
│   │   ├── http.rs
│   │   ├── i18n/
│   │   │   ├── mod.rs
│   │   │   └── translation.rs
│   │   ├── lib.rs
│   │   ├── library/
│   │   │   ├── document.rs
│   │   │   ├── fastn_dot_ftd.rs
│   │   │   ├── mod.rs
│   │   │   └── toc.rs
│   │   ├── library2022/
│   │   │   ├── cr_meta.rs
│   │   │   ├── get_version_data.rs
│   │   │   ├── mod.rs
│   │   │   ├── processor/
│   │   │   │   ├── apps.rs
│   │   │   │   ├── document.rs
│   │   │   │   ├── fetch_file.rs
│   │   │   │   ├── figma_tokens.rs
│   │   │   │   ├── figma_typography_tokens.rs
│   │   │   │   ├── get_data.rs
│   │   │   │   ├── google_sheets.rs
│   │   │   │   ├── http.rs
│   │   │   │   ├── lang.rs
│   │   │   │   ├── lang_details.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── package_query.rs
│   │   │   │   ├── pg.rs
│   │   │   │   ├── query.rs
│   │   │   │   ├── request_data.rs
│   │   │   │   ├── sitemap.rs
│   │   │   │   ├── sql.rs
│   │   │   │   ├── sqlite.rs
│   │   │   │   ├── toc.rs
│   │   │   │   ├── user_details.rs
│   │   │   │   └── user_group.rs
│   │   │   └── utils.rs
│   │   ├── manifest/
│   │   │   ├── manifest_to_package.rs
│   │   │   ├── mod.rs
│   │   │   └── utils.rs
│   │   ├── migrations/
│   │   │   ├── fastn_migrations.rs
│   │   │   └── mod.rs
│   │   ├── package/
│   │   │   ├── app.rs
│   │   │   ├── dependency.rs
│   │   │   ├── mod.rs
│   │   │   ├── package_doc.rs
│   │   │   └── redirects.rs
│   │   ├── sitemap/
│   │   │   ├── dynamic_urls.rs
│   │   │   ├── mod.rs
│   │   │   ├── section.rs
│   │   │   ├── toc.rs
│   │   │   └── utils.rs
│   │   ├── snapshot.rs
│   │   ├── tracker.rs
│   │   ├── translation.rs
│   │   ├── utils.rs
│   │   ├── version.rs
│   │   └── wasm.rs
│   └── test_fastn.ftd
├── fastn-daemon/
│   ├── Cargo.toml
│   └── src/
│       ├── cli.rs
│       ├── init.rs
│       ├── lib.rs
│       ├── main.rs
│       ├── remote.rs
│       ├── run.rs
│       └── status.rs
├── fastn-ds/
│   ├── .gitignore
│   ├── Cargo.toml
│   └── src/
│       ├── http.rs
│       ├── lib.rs
│       ├── main.rs
│       ├── reqwest_util.rs
│       ├── user_data.rs
│       └── utils.rs
├── fastn-expr/
│   ├── Cargo.toml
│   └── src/
│       ├── interpolator.rs
│       ├── lib.rs
│       ├── parser.rs
│       └── tokenizer.rs
├── fastn-issues/
│   ├── Cargo.toml
│   └── src/
│       ├── initialization.rs
│       ├── initialization_display.rs
│       └── lib.rs
├── fastn-js/
│   ├── Cargo.toml
│   ├── README.md
│   ├── ftd-js.css
│   ├── js/
│   │   ├── dom.js
│   │   ├── fastn.js
│   │   ├── fastn_test.js
│   │   ├── ftd-language.js
│   │   ├── ftd.js
│   │   ├── postInit.js
│   │   ├── test.js
│   │   ├── utils.js
│   │   ├── virtual.js
│   │   └── web-component.js
│   ├── marked.js
│   ├── prism/
│   │   ├── prism-bash.js
│   │   ├── prism-diff.js
│   │   ├── prism-javascript.js
│   │   ├── prism-json.js
│   │   ├── prism-line-highlight.css
│   │   ├── prism-line-highlight.js
│   │   ├── prism-line-numbers.css
│   │   ├── prism-line-numbers.js
│   │   ├── prism-markdown.js
│   │   ├── prism-python.js
│   │   ├── prism-rust.js
│   │   ├── prism-sql.js
│   │   └── prism.js
│   ├── src/
│   │   ├── ast.rs
│   │   ├── component.rs
│   │   ├── component_invocation.rs
│   │   ├── component_statement.rs
│   │   ├── conditional_component.rs
│   │   ├── constants.rs
│   │   ├── device.rs
│   │   ├── event.rs
│   │   ├── lib.rs
│   │   ├── loop_component.rs
│   │   ├── main.rs
│   │   ├── mutable_variable.rs
│   │   ├── or_type.rs
│   │   ├── property.rs
│   │   ├── record.rs
│   │   ├── ssr.rs
│   │   ├── static_variable.rs
│   │   ├── to_js.rs
│   │   ├── udf.rs
│   │   ├── udf_statement.rs
│   │   └── utils.rs
│   └── tests/
│       ├── 01-basic.html
│       ├── 02-basic-event.html
│       ├── 03-event-1.html
│       ├── 04-component.html
│       ├── 05-complex-component.html
│       ├── 06-complex.html
│       ├── 07-dynamic-dom.html
│       ├── 08-dynamic-dom-2.html
│       ├── 09-dynamic-dom-3.html
│       ├── 10-dynamic-dom-list.html
│       ├── 11-record.html
│       ├── 12-record-update.html
│       ├── 13-string-refs.html
│       ├── 14-passing-mutable.html
│       ├── 15-conditional-property.html
│       ├── 16-color.html
│       └── 17-children.html
├── fastn-lang/
│   ├── Cargo.toml
│   └── src/
│       ├── error.rs
│       ├── language.rs
│       └── lib.rs
├── fastn-package/
│   ├── Cargo.toml
│   ├── create-db.sql
│   ├── fastn_2021.ftd
│   ├── fastn_2023.ftd
│   └── src/
│       ├── lib.rs
│       └── old_fastn.rs
├── fastn-preact/
│   ├── README.md
│   └── examples/
│       ├── .fastn/
│       │   └── config.json
│       ├── 01-counter.ftd
│       ├── 01-counter.html
│       ├── 02-counter-component.ftd
│       ├── 02-counter-component.html
│       ├── 03-js-interop.ftd
│       ├── 03-js-interop.html
│       ├── 04-record-field.ftd
│       ├── 04-record-field.html
│       ├── 05-list.ftd
│       ├── 05-list.html
│       ├── 06-record-2-broken.html
│       ├── 06-record-2-fixed.html
│       ├── 06-record-2.ftd
│       ├── 07-nested-record.ftd
│       ├── 07-nested-record.html
│       ├── 08-nested-list-with-fastn-data.html
│       ├── 08-nested-list.ftd
│       ├── 08-nested-list.html
│       ├── FASTN.ftd
│       └── index.ftd
├── fastn-remote/
│   ├── Cargo.toml
│   └── src/
│       ├── cli.rs
│       ├── init.rs
│       ├── lib.rs
│       ├── listen.rs
│       ├── main.rs
│       ├── rexec.rs
│       ├── rshell.rs
│       └── run.rs
├── fastn-resolved/
│   ├── Cargo.toml
│   └── src/
│       ├── component.rs
│       ├── evalexpr/
│       │   ├── context/
│       │   │   ├── mod.rs
│       │   │   └── predefined/
│       │   │       └── mod.rs
│       │   ├── error/
│       │   │   ├── display.rs
│       │   │   └── mod.rs
│       │   ├── feature_serde/
│       │   │   └── mod.rs
│       │   ├── function/
│       │   │   ├── builtin.rs
│       │   │   └── mod.rs
│       │   ├── interface/
│       │   │   └── mod.rs
│       │   ├── mod.rs
│       │   ├── operator/
│       │   │   ├── display.rs
│       │   │   └── mod.rs
│       │   ├── token/
│       │   │   ├── display.rs
│       │   │   └── mod.rs
│       │   ├── tree/
│       │   │   ├── display.rs
│       │   │   ├── iter.rs
│       │   │   └── mod.rs
│       │   └── value/
│       │       ├── display.rs
│       │       ├── mod.rs
│       │       └── value_type.rs
│       ├── expression.rs
│       ├── function.rs
│       ├── kind.rs
│       ├── lib.rs
│       ├── module_thing.rs
│       ├── or_type.rs
│       ├── record.rs
│       ├── tdoc.rs
│       ├── value.rs
│       ├── variable.rs
│       └── web_component.rs
├── fastn-runtime/
│   ├── .gitignore
│   ├── Cargo.toml
│   └── src/
│       ├── element.rs
│       ├── extensions.rs
│       ├── fastn_type_functions.rs
│       ├── html.rs
│       ├── lib.rs
│       ├── main.rs
│       ├── resolver.rs
│       ├── tdoc.rs
│       ├── utils.rs
│       └── value.rs
├── fastn-update/
│   ├── Cargo.toml
│   └── src/
│       ├── lib.rs
│       └── utils.rs
├── fastn-utils/
│   ├── Cargo.toml
│   └── src/
│       ├── lib.rs
│       └── sql.rs
├── fastn-wasm/
│   ├── Cargo.toml
│   └── src/
│       ├── ast.rs
│       ├── elem.rs
│       ├── export.rs
│       ├── expression.rs
│       ├── func.rs
│       ├── func_def.rs
│       ├── helpers.rs
│       ├── import.rs
│       ├── lib.rs
│       ├── memory.rs
│       ├── pl.rs
│       ├── table.rs
│       └── ty.rs
├── fastn-wasm-runtime/
│   ├── 1.wast
│   ├── Cargo.toml
│   ├── columns.clj
│   ├── columns.ftd
│   ├── src/
│   │   ├── control.rs
│   │   ├── document.rs
│   │   ├── dom.rs
│   │   ├── element.rs
│   │   ├── event.rs
│   │   ├── f.wat
│   │   ├── g.wast
│   │   ├── lib.rs
│   │   ├── main.rs
│   │   ├── memory/
│   │   │   ├── gc.rs
│   │   │   ├── heap.rs
│   │   │   ├── helper.rs
│   │   │   ├── mod.rs
│   │   │   ├── pointer.rs
│   │   │   ├── ui.rs
│   │   │   └── wasm.rs
│   │   ├── operation.rs
│   │   ├── renderable/
│   │   │   ├── dom_helpers.rs
│   │   │   └── mod.rs
│   │   ├── server/
│   │   │   ├── dom.rs
│   │   │   ├── html.rs
│   │   │   └── mod.rs
│   │   ├── terminal/
│   │   │   └── mod.rs
│   │   ├── wasm.rs
│   │   ├── wasm_helpers.rs
│   │   ├── web/
│   │   │   ├── dom.rs
│   │   │   ├── exports.rs
│   │   │   ├── linker.js
│   │   │   ├── main.rs
│   │   │   └── mod.rs
│   │   └── wgpu/
│   │       ├── boilerplate.rs
│   │       ├── control.rs
│   │       ├── event.rs
│   │       ├── mod.rs
│   │       ├── operations.rs
│   │       ├── rectangles.rs
│   │       ├── rectangles.wgsl
│   │       └── runtime.rs
│   ├── t.wat
│   └── test.wasm
├── fastn-xtask/
│   ├── Cargo.toml
│   └── src/
│       ├── build_wasm.rs
│       ├── helpers.rs
│       ├── lib.rs
│       ├── optimise_wasm.rs
│       ├── publish_app.rs
│       ├── run_template.rs
│       ├── run_ui.rs
│       ├── run_www.rs
│       ├── update_template.rs
│       ├── update_ui.rs
│       └── update_www.rs
├── fastn.com/
│   ├── .fastn/
│   │   └── config.json
│   ├── .gitattributes
│   ├── 404.ftd
│   ├── FASTN/
│   │   ├── ds.ftd
│   │   └── featured-ds.ftd
│   ├── FASTN.ftd
│   ├── README.md
│   ├── ambassadors/
│   │   ├── how-it-works.ftd
│   │   └── index.ftd
│   ├── assets/
│   │   ├── js/
│   │   │   ├── download.js
│   │   │   ├── figma.js
│   │   │   └── typo.js
│   │   └── links.css
│   ├── author/
│   │   ├── how-to/
│   │   │   ├── create-fastn-package.ftd
│   │   │   ├── create-font-package.ftd
│   │   │   ├── fifthtry-hosting.ftd
│   │   │   ├── github-pages.ftd
│   │   │   ├── install.ftd
│   │   │   ├── open-terminal.ftd
│   │   │   ├── sublime.ftd
│   │   │   ├── upload-image-ide.ftd
│   │   │   ├── vercel.ftd
│   │   │   └── vscode.ftd
│   │   ├── index.ftd
│   │   └── setup/
│   │       ├── hello.ftd
│   │       ├── macos.ftd
│   │       ├── uninstall.ftd
│   │       └── windows.ftd
│   ├── backend/
│   │   ├── app.ftd
│   │   ├── country-details/
│   │   │   ├── dynamic-country-list-page.ftd
│   │   │   ├── http-data-modelling.ftd
│   │   │   └── index.ftd
│   │   ├── custom-urls.ftd
│   │   ├── django.ftd
│   │   ├── dynamic-urls.ftd
│   │   ├── endpoint.ftd
│   │   ├── env-vars.ftd
│   │   ├── ftd-redirect.ftd
│   │   ├── index.ftd
│   │   ├── redirects.ftd
│   │   └── wasm.ftd
│   ├── best-practices/
│   │   ├── auto-import.ftd
│   │   ├── commenting-guidelines.ftd
│   │   ├── container-guidelines.ftd
│   │   ├── device.ftd
│   │   ├── dump.md
│   │   ├── formatting.ftd
│   │   ├── fscript-guidelines.ftd
│   │   ├── import.ftd
│   │   ├── index.ftd
│   │   ├── inherited-types.ftd
│   │   ├── optional-arg-not-null.ftd
│   │   ├── property-guidelines.ftd
│   │   ├── same-argument-attribute-type.ftd
│   │   ├── self-referencing.ftd
│   │   ├── style-argument.ftd
│   │   ├── use-conditions.ftd
│   │   ├── utils.ftd
│   │   └── variable-type.ftd
│   ├── blog/
│   │   ├── acme.ftd
│   │   ├── authors.ftd
│   │   ├── breakpoint.ftd
│   │   ├── cli-check-for-updates.ftd
│   │   ├── content-library.ftd
│   │   ├── design-system-part-2.ftd
│   │   ├── design-system.ftd
│   │   ├── domain-components.ftd
│   │   ├── figma.ftd
│   │   ├── index.ftd
│   │   ├── lib.ftd
│   │   ├── meta-data-blog.ftd
│   │   ├── personal-website-1.ftd
│   │   ├── philippines.ftd
│   │   ├── prove-you-wrong.ftd
│   │   ├── search.ftd
│   │   ├── show-cs.ftd
│   │   ├── strongly-typed.ftd
│   │   ├── the-intimidation-of-programming.ftd
│   │   ├── trizwitlabs.ftd
│   │   ├── web-components.ftd
│   │   ├── wittyhacks.ftd
│   │   └── writer-journey.ftd
│   ├── book/
│   │   ├── 01-introduction/
│   │   │   ├── 00-why-fastn.ftd
│   │   │   ├── 01-fifthtry.ftd
│   │   │   ├── 02-local-setup.ftd
│   │   │   ├── 03-hello-world.ftd
│   │   │   ├── 04-about-ide.ftd
│   │   │   ├── 05-create-website.ftd
│   │   │   ├── 06-manual-upload.ftd
│   │   │   ├── 07-fastn-essentials.ftd
│   │   │   ├── 08-about-fastn.ftd
│   │   │   ├── 09-about-index.ftd
│   │   │   ├── 10-use-design-system.ftd
│   │   │   └── 11-use-component-library.ftd
│   │   ├── 02-local-setup/
│   │   │   ├── 01-local-setup.ftd
│   │   │   └── 02-hello-world.ftd
│   │   ├── 03-fifthtry/
│   │   │   ├── 00-about-ide.ftd
│   │   │   └── 01-create-website.ftd
│   │   ├── 04-fastn-routing/
│   │   │   ├── 01-fifthtry.ftd
│   │   │   ├── 01-github.ftd
│   │   │   ├── 02-repo.ftd
│   │   │   ├── 03-gh-pages.ftd
│   │   │   ├── 04-codespaces.ftd
│   │   │   └── 05-first-edit.ftd
│   │   ├── 05-fastn-basics/
│   │   │   └── 01-intro.ftd
│   │   ├── 1-foreword.ftd
│   │   ├── 2-preface.ftd
│   │   ├── 3-intro.ftd
│   │   ├── appendix/
│   │   │   ├── a-http.ftd
│   │   │   ├── b-url.ftd
│   │   │   ├── c-terminal.ftd
│   │   │   ├── d-common-commands.ftd
│   │   │   ├── e-install.ftd
│   │   │   ├── f-editor.ftd
│   │   │   ├── g-hosting.ftd
│   │   │   └── index.ftd
│   │   └── index.ftd
│   ├── brand-guidelines.ftd
│   ├── case-study/
│   │   └── todo.ftd
│   ├── certificates/
│   │   ├── champions/
│   │   │   ├── adarsh-gupta.ftd
│   │   │   ├── ajit-garg.ftd
│   │   │   ├── atharva-pise.ftd
│   │   │   ├── ayush-soni.ftd
│   │   │   ├── govindaraman.ftd
│   │   │   ├── jahanvi-raycha.ftd
│   │   │   ├── krish-gupta.ftd
│   │   │   ├── rutuja-kapate.ftd
│   │   │   ├── sayak-saha.ftd
│   │   │   ├── shantnu-fartode.ftd
│   │   │   └── sreejita-dutta.ftd
│   │   └── index.ftd
│   ├── cms.ftd
│   ├── community/
│   │   ├── events/
│   │   │   ├── roadshow.ftd
│   │   │   └── roadshows/
│   │   │       ├── ahmedabad.ftd
│   │   │       ├── bangalore.ftd
│   │   │       ├── bhopal.ftd
│   │   │       ├── delhi.ftd
│   │   │       ├── hyderabad.ftd
│   │   │       ├── indore.ftd
│   │   │       ├── jaipur.ftd
│   │   │       ├── kolkata.ftd
│   │   │       ├── lucknow.ftd
│   │   │       ├── mumbai.ftd
│   │   │       ├── nagpur.ftd
│   │   │       └── ujjain.ftd
│   │   └── weekly-contest.ftd
│   ├── community.ftd
│   ├── compare/
│   │   ├── react.ftd
│   │   └── webflow.ftd
│   ├── components/
│   │   ├── certificate.ftd
│   │   ├── common.ftd
│   │   ├── json-exporter.ftd
│   │   ├── social-links.ftd
│   │   ├── typo-exporter.ftd
│   │   └── utils.ftd
│   ├── consulting.ftd
│   ├── content-library/
│   │   ├── compare.ftd
│   │   └── index.ftd
│   ├── contribute-code.ftd
│   ├── cs/
│   │   ├── create-cs.ftd
│   │   ├── figma-to-ftd.ftd
│   │   ├── ftd-to-figma.ftd
│   │   ├── modify-cs.ftd
│   │   ├── sample-codes/
│   │   │   └── create-cs.ftd
│   │   └── use-color-package.ftd
│   ├── d/
│   │   ├── architecture.ftd
│   │   ├── fastn-core-crate.ftd
│   │   ├── fastn-crate.ftd
│   │   ├── fastn-package-spec.ftd
│   │   ├── fastn-package.ftd
│   │   ├── ftd-crate.ftd
│   │   ├── index.ftd
│   │   ├── m.ftd
│   │   ├── next-edition.ftd
│   │   └── v0.5/
│   │       └── index.ftd
│   ├── demo.ftd
│   ├── deploy/
│   │   ├── heroku.ftd
│   │   └── index.ftd
│   ├── design.css
│   ├── donate.ftd
│   ├── events/
│   │   ├── 01.ftd
│   │   ├── hackodisha.ftd
│   │   ├── index.ftd
│   │   ├── web-dev-using-ftd.ftd
│   │   ├── webdev-with-ftd.ftd
│   │   └── weekly-contest/
│   │       ├── index.ftd
│   │       ├── week-1-quote-event.ftd
│   │       ├── week-1-quote.ftd
│   │       ├── week-2-code.ftd
│   │       ├── week-3-hero.ftd
│   │       └── week-4-cta.ftd
│   ├── examples/
│   │   ├── iframe-demo.ftd
│   │   └── index.ftd
│   ├── expander/
│   │   ├── basic-ui.ftd
│   │   ├── border-radius.ftd
│   │   ├── button.ftd
│   │   ├── components.ftd
│   │   ├── ds/
│   │   │   ├── ds-cs.ftd
│   │   │   ├── ds-page.ftd
│   │   │   ├── ds-typography.ftd
│   │   │   ├── markdown.ftd
│   │   │   ├── meta-data.ftd
│   │   │   └── understanding-sitemap.ftd
│   │   ├── events.ftd
│   │   ├── hello-world.ftd
│   │   ├── imagemodule/
│   │   │   └── index.ftd
│   │   ├── index.ftd
│   │   ├── layout/
│   │   │   └── index.ftd
│   │   ├── lib.ftd
│   │   ├── polish.ftd
│   │   ├── publish.ftd
│   │   └── sitemap-document.ftd
│   ├── f.ftd
│   ├── featured/
│   │   ├── blog-templates.ftd
│   │   ├── blogs/
│   │   │   ├── blog-components.ftd
│   │   │   ├── blog-template-1.ftd
│   │   │   ├── blue-wave.ftd
│   │   │   ├── dash-dash-ds.ftd
│   │   │   ├── doc-site.ftd
│   │   │   ├── galaxia.ftd
│   │   │   ├── little-blue.ftd
│   │   │   ├── mg-blog.ftd
│   │   │   ├── mr-blog.ftd
│   │   │   ├── ms-blog.ftd
│   │   │   ├── navy-nebula.ftd
│   │   │   ├── pink-tree.ftd
│   │   │   ├── rocky.ftd
│   │   │   ├── simple-blog.ftd
│   │   │   └── yellow-lily.ftd
│   │   ├── components/
│   │   │   ├── admonitions/
│   │   │   │   └── index.ftd
│   │   │   ├── bling/
│   │   │   │   └── index.ftd
│   │   │   ├── business-cards/
│   │   │   │   ├── card-1.ftd
│   │   │   │   ├── gradient-card.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── midnight-card.ftd
│   │   │   │   ├── pattern-card.ftd
│   │   │   │   └── sunset-card.ftd
│   │   │   ├── buttons/
│   │   │   │   └── index.ftd
│   │   │   ├── code-block.ftd
│   │   │   ├── footers/
│   │   │   │   ├── footer-3.ftd
│   │   │   │   ├── footer.ftd
│   │   │   │   └── index.ftd
│   │   │   ├── headers/
│   │   │   │   ├── header.ftd
│   │   │   │   └── index.ftd
│   │   │   ├── index.ftd
│   │   │   ├── language-switcher.ftd
│   │   │   ├── modals/
│   │   │   │   ├── index.ftd
│   │   │   │   ├── modal-1.ftd
│   │   │   │   └── modal-cover.ftd
│   │   │   ├── quotes/
│   │   │   │   ├── author-icon-quotes/
│   │   │   │   │   ├── demo-1.ftd
│   │   │   │   │   └── index.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── quotes-with-images/
│   │   │   │   │   ├── demo-1.ftd
│   │   │   │   │   └── index.ftd
│   │   │   │   └── simple-quotes/
│   │   │   │       ├── demo-1.ftd
│   │   │   │       ├── demo-10.ftd
│   │   │   │       ├── demo-11.ftd
│   │   │   │       ├── demo-12.ftd
│   │   │   │       ├── demo-2.ftd
│   │   │   │       ├── demo-3.ftd
│   │   │   │       ├── demo-4.ftd
│   │   │   │       ├── demo-5.ftd
│   │   │   │       ├── demo-6.ftd
│   │   │   │       ├── demo-7.ftd
│   │   │   │       ├── demo-8.ftd
│   │   │   │       ├── demo-9.ftd
│   │   │   │       └── index.ftd
│   │   │   └── subscription-form.ftd
│   │   ├── contributors/
│   │   │   ├── designers/
│   │   │   │   ├── govindaraman-s/
│   │   │   │   │   └── index.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── jay-kumar/
│   │   │   │   │   └── index.ftd
│   │   │   │   ├── muskan-verma/
│   │   │   │   │   └── index.ftd
│   │   │   │   └── yashveer-mehra/
│   │   │   │       └── index.ftd
│   │   │   └── developers/
│   │   │       ├── arpita-jaiswal/
│   │   │       │   └── index.ftd
│   │   │       ├── ganesh-salunke/
│   │   │       │   └── index.ftd
│   │   │       ├── index.ftd
│   │   │       ├── meenu-kumari/
│   │   │       │   └── index.ftd
│   │   │       ├── priyanka-yadav/
│   │   │       │   └── index.ftd
│   │   │       ├── saurabh-garg/
│   │   │       │   └── index.ftd
│   │   │       ├── saurabh-lohiya/
│   │   │       │   └── index.ftd
│   │   │       └── shaheen-senpai/
│   │   │           └── index.ftd
│   │   ├── cs/
│   │   │   ├── blog-template-1-cs.ftd
│   │   │   ├── blog-template-cs.ftd
│   │   │   ├── blue-heal-cs.ftd
│   │   │   ├── blue-shades.ftd
│   │   │   ├── dark-flame-cs.ftd
│   │   │   ├── forest-cs.ftd
│   │   │   ├── green-shades.ftd
│   │   │   ├── index.ftd
│   │   │   ├── little-blue-cs.ftd
│   │   │   ├── midnight-rush-cs.ftd
│   │   │   ├── midnight-storm-cs.ftd
│   │   │   ├── misty-gray-cs.ftd
│   │   │   ├── navy-nebula-cs.ftd
│   │   │   ├── orange-shades.ftd
│   │   │   ├── pink-tree-cs.ftd
│   │   │   ├── pretty-cs.ftd
│   │   │   ├── red-shades.ftd
│   │   │   ├── saturated-sunset-cs.ftd
│   │   │   ├── violet-shades.ftd
│   │   │   ├── winter-cs.ftd
│   │   │   └── yellow-lily-cs.ftd
│   │   ├── design.ftd
│   │   ├── doc-sites.ftd
│   │   ├── ds/
│   │   │   ├── api-ds.ftd
│   │   │   ├── blue-sapphire-template.ftd
│   │   │   ├── dash-dash-ds.ftd
│   │   │   ├── doc-site.ftd
│   │   │   ├── docusaurus-theme.ftd
│   │   │   ├── forest-template.ftd
│   │   │   ├── framework.ftd
│   │   │   ├── midnight-storm.ftd
│   │   │   ├── misty-gray.ftd
│   │   │   ├── mr-ds.ftd
│   │   │   └── spider-book-ds.ftd
│   │   ├── filter.css
│   │   ├── fonts/
│   │   │   ├── arpona.ftd
│   │   │   ├── arya.ftd
│   │   │   ├── biro.ftd
│   │   │   ├── blaka.ftd
│   │   │   ├── index.ftd
│   │   │   ├── inter.ftd
│   │   │   ├── karma.ftd
│   │   │   ├── khand.ftd
│   │   │   ├── lato.ftd
│   │   │   ├── lobster.ftd
│   │   │   ├── mulish.ftd
│   │   │   ├── opensans.ftd
│   │   │   ├── paul-jackson.ftd
│   │   │   ├── pragati-narrow.ftd
│   │   │   ├── roboto-mono.ftd
│   │   │   ├── roboto.ftd
│   │   │   └── tiro.ftd
│   │   ├── fonts-typography.ftd
│   │   ├── index.ftd
│   │   ├── landing/
│   │   │   ├── ct-landing.ftd
│   │   │   ├── docusaurus-theme.ftd
│   │   │   ├── forest-foss-template.ftd
│   │   │   ├── midnight-storm-landing.ftd
│   │   │   ├── misty-gray-landing.ftd
│   │   │   ├── mr-landing.ftd
│   │   │   └── studious-couscous.ftd
│   │   ├── landing-pages.ftd
│   │   ├── new-sections.ftd
│   │   ├── portfolios/
│   │   │   ├── index.ftd
│   │   │   ├── johny-ps.ftd
│   │   │   ├── portfolio.ftd
│   │   │   └── texty-ps.ftd
│   │   ├── resumes/
│   │   │   ├── caffiene.ftd
│   │   │   ├── index.ftd
│   │   │   ├── resume-1.ftd
│   │   │   └── resume-10.ftd
│   │   ├── sections/
│   │   │   ├── accordions/
│   │   │   │   ├── accordion.ftd
│   │   │   │   └── index.ftd
│   │   │   ├── cards/
│   │   │   │   ├── card-1.ftd
│   │   │   │   ├── hastag-card.ftd
│   │   │   │   ├── icon-card.ftd
│   │   │   │   ├── image-card-1.ftd
│   │   │   │   ├── image-gallery-ig.ftd
│   │   │   │   ├── imagen-ig.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── magnifine-card.ftd
│   │   │   │   ├── metric-card.ftd
│   │   │   │   ├── news-card.ftd
│   │   │   │   ├── overlay-card.ftd
│   │   │   │   └── profile-card.ftd
│   │   │   ├── heros/
│   │   │   │   ├── circle-hero.ftd
│   │   │   │   ├── hero-bottom-hug-search.ftd
│   │   │   │   ├── hero-bottom-hug.ftd
│   │   │   │   ├── hero-left-hug-expanded-search.ftd
│   │   │   │   ├── hero-left-hug-expanded.ftd
│   │   │   │   ├── hero-right-hug-expanded-search.ftd
│   │   │   │   ├── hero-right-hug-expanded.ftd
│   │   │   │   ├── hero-right-hug-large.ftd
│   │   │   │   ├── hero-right-hug-search-label.ftd
│   │   │   │   ├── hero-right-hug-search.ftd
│   │   │   │   ├── hero-right-hug.ftd
│   │   │   │   ├── hero-sticky-image.ftd
│   │   │   │   ├── hero-with-2-cta.ftd
│   │   │   │   ├── hero-with-background.ftd
│   │   │   │   ├── hero-with-search.ftd
│   │   │   │   ├── hero-with-social.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   └── parallax-hero.ftd
│   │   │   ├── index.ftd
│   │   │   ├── kvt/
│   │   │   │   ├── index.ftd
│   │   │   │   └── kvt-1.ftd
│   │   │   ├── pricing/
│   │   │   │   ├── index.ftd
│   │   │   │   ├── price-box.ftd
│   │   │   │   └── price-card.ftd
│   │   │   ├── slides/
│   │   │   │   ├── crispy-presentation-theme.ftd
│   │   │   │   ├── giggle-presentation-template.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── rotary-presentation-template.ftd
│   │   │   │   ├── simple-dark-slides.ftd
│   │   │   │   ├── simple-light-slides.ftd
│   │   │   │   └── streamline-slides.ftd
│   │   │   ├── steppers/
│   │   │   │   ├── base-stepper.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── stepper-background.ftd
│   │   │   │   ├── stepper-border-box.ftd
│   │   │   │   ├── stepper-box.ftd
│   │   │   │   ├── stepper-left-image.ftd
│   │   │   │   ├── stepper-left-right.ftd
│   │   │   │   └── stepper-step.ftd
│   │   │   ├── team/
│   │   │   │   ├── index.ftd
│   │   │   │   ├── member-tile.ftd
│   │   │   │   ├── member.ftd
│   │   │   │   └── team-card.ftd
│   │   │   └── testimonials/
│   │   │       ├── index.ftd
│   │   │       ├── testimonial-card.ftd
│   │   │       ├── testimonial-nav-card.ftd
│   │   │       └── testimonial-square-card.ftd
│   │   ├── website-categories.ftd
│   │   └── workshops/
│   │       ├── event-1.ftd
│   │       ├── index.ftd
│   │       └── workshop-1.ftd
│   ├── features/
│   │   ├── community.ftd
│   │   ├── cs.ftd
│   │   ├── design.ftd
│   │   ├── index.ftd
│   │   ├── package-manager.ftd
│   │   ├── server.ftd
│   │   ├── sitemap.ftd
│   │   └── static.ftd
│   ├── frontend/
│   │   ├── design-system.ftd
│   │   ├── index.ftd
│   │   ├── make-page-responsive.ftd
│   │   └── why.ftd
│   ├── ftd/
│   │   ├── attributes.ftd
│   │   ├── audio.ftd
│   │   ├── boolean.ftd
│   │   ├── built-in-functions.ftd
│   │   ├── built-in-rive-functions.ftd
│   │   ├── built-in-types.ftd
│   │   ├── built-in-variables.ftd
│   │   ├── checkbox.ftd
│   │   ├── code.ftd
│   │   ├── column.ftd
│   │   ├── comments.ftd
│   │   ├── common.ftd
│   │   ├── components.ftd
│   │   ├── container-attributes.ftd
│   │   ├── container-root-attributes.ftd
│   │   ├── container.ftd
│   │   ├── data-modelling.ftd
│   │   ├── decimal.ftd
│   │   ├── desktop.ftd
│   │   ├── document.ftd
│   │   ├── events.ftd
│   │   ├── export-exposing.ftd
│   │   ├── external-css.ftd
│   │   ├── functions.ftd
│   │   ├── headers.ftd
│   │   ├── iframe.ftd
│   │   ├── image.ftd
│   │   ├── index.ftd
│   │   ├── integer.ftd
│   │   ├── js-in-function.ftd
│   │   ├── kernel.ftd
│   │   ├── list.ftd
│   │   ├── local-storage.ftd
│   │   ├── loop.ftd
│   │   ├── mobile.ftd
│   │   ├── module.ftd
│   │   ├── optionals.ftd
│   │   ├── or-type.ftd
│   │   ├── p1-grammar.ftd
│   │   ├── record.ftd
│   │   ├── rive-events.ftd
│   │   ├── rive.ftd
│   │   ├── row.ftd
│   │   ├── setup.ftd
│   │   ├── text-attributes.ftd
│   │   ├── text-input.ftd
│   │   ├── text.ftd
│   │   ├── translation.ftd
│   │   ├── ui.ftd
│   │   ├── use-js-css.ftd
│   │   ├── utils.ftd
│   │   ├── variables.ftd
│   │   ├── video.ftd
│   │   ├── visibility.ftd
│   │   └── web-component.ftd
│   ├── ftd-host/
│   │   ├── accessing-files.ftd
│   │   ├── accessing-fonts.ftd
│   │   ├── assets.ftd
│   │   ├── auth.ftd
│   │   ├── foreign-variable.ftd
│   │   ├── get-data.ftd
│   │   ├── http.ftd
│   │   ├── import.ftd
│   │   ├── index.ftd
│   │   ├── package-query.ftd
│   │   ├── pg.ftd
│   │   ├── processor.ftd
│   │   ├── request-data.ftd
│   │   └── sql.ftd
│   ├── functions.js
│   ├── get-started/
│   │   ├── basics.ftd
│   │   ├── browse-pick.ftd
│   │   ├── create-website.ftd
│   │   ├── editor.ftd
│   │   ├── github.ftd
│   │   └── theme.ftd
│   ├── glossary.ftd
│   ├── home-old.ftd
│   ├── home.ftd
│   ├── index.ftd
│   ├── install.sh
│   ├── lib.ftd-0.2
│   ├── old-fastn-sitemap-links.ftd
│   ├── planning/
│   │   ├── border-radius/
│   │   │   └── index.ftd
│   │   ├── button/
│   │   │   └── index.ftd
│   │   ├── country-details/
│   │   │   ├── index.ftd
│   │   │   ├── script1.ftd
│   │   │   ├── script2.ftd
│   │   │   └── script3.ftd
│   │   ├── creators-series.ftd
│   │   ├── developer-course.ftd
│   │   ├── documentation-systems.ftd
│   │   ├── index.ftd
│   │   ├── orientation-planning-video.ftd
│   │   ├── page-nomenclature/
│   │   │   └── index.ftd
│   │   ├── page-nomenclature.ftd
│   │   ├── post-card/
│   │   │   └── index.ftd
│   │   ├── rive/
│   │   │   ├── index.ftd
│   │   │   └── script.txt
│   │   ├── sitemap-features/
│   │   │   ├── document.ftd
│   │   │   └── page-nomenclature.ftd
│   │   ├── temp.md
│   │   ├── temp2.ftd
│   │   └── user-journey.md
│   ├── podcast/
│   │   ├── fastn-p2p-emails.ftd
│   │   ├── index.ftd
│   │   ├── new-fastn-architecture.ftd
│   │   └── sustainability-and-consultancy.ftd
│   ├── qr-codes.ftd
│   ├── rfcs/
│   │   ├── 0000-dependency-versioning.ftd
│   │   ├── 0001-rfc-process.ftd
│   │   ├── 0002-fastn-update.ftd
│   │   ├── 0003-variable-interpolation.ftd
│   │   ├── 0004-incremental-build.ftd
│   │   ├── index.ftd
│   │   ├── lib.ftd
│   │   └── rfc-template.ftd
│   ├── search.ftd
│   ├── search.js
│   ├── select-book-theme.ftd-0.2
│   ├── student-programs/
│   │   ├── ambassador.ftd
│   │   ├── ambassadors/
│   │   │   ├── ajit-garg.ftd
│   │   │   ├── all-ambassadors.ftd
│   │   │   ├── ayush-soni.ftd
│   │   │   └── govindaraman.ftd
│   │   ├── champion.ftd
│   │   ├── champions/
│   │   │   ├── ajit-garg.ftd
│   │   │   ├── all-champions.ftd
│   │   │   ├── arpita-jaiswal.ftd
│   │   │   ├── ayush-soni.ftd
│   │   │   ├── ganesh-salunke.ftd
│   │   │   ├── govindaraman.ftd
│   │   │   ├── harsh-singh.ftd
│   │   │   ├── jahanvi-raycha.ftd
│   │   │   ├── meenu-kumari.ftd
│   │   │   ├── priyanka-yadav.ftd
│   │   │   ├── rithik-seth.ftd
│   │   │   └── saurabh-lohiya.ftd
│   │   ├── introductory-event.ftd
│   │   └── lead.ftd
│   ├── support.ftd
│   ├── syllabus.ftd
│   ├── tutorials/
│   │   └── basic.ftd
│   ├── typo/
│   │   ├── typo-json-to-ftd.ftd
│   │   └── typo-to-json.ftd
│   ├── u/
│   │   ├── arpita-jaiswal.ftd
│   │   ├── ganesh-salunke.ftd
│   │   ├── govindaraman-s.ftd
│   │   ├── index.ftd
│   │   ├── jay-kumar.ftd
│   │   ├── meenu-kumari.ftd
│   │   ├── muskan-verma.ftd
│   │   ├── priyanka-yadav.ftd
│   │   ├── saurabh-garg.ftd
│   │   ├── saurabh-lohiya.ftd
│   │   ├── shaheen-senpai.ftd
│   │   └── yashveer-mehra.ftd
│   ├── users/
│   │   └── index.ftd
│   ├── utils.ftd
│   ├── vercel.json
│   ├── web-component.js
│   ├── why/
│   │   ├── content.ftd
│   │   ├── design.ftd
│   │   ├── easy.ftd
│   │   ├── fullstack.ftd
│   │   ├── geeks.ftd
│   │   └── stable.ftd
│   └── workshop/
│       ├── 01-hello-world.ftd
│       ├── 02-add-quote.ftd
│       ├── 03-add-doc-site.ftd
│       ├── 04-publish-on-github.ftd
│       ├── 05-basics-of-text.ftd
│       ├── 06-add-image-and-video.ftd
│       ├── 07-create-new-page.ftd
│       ├── 08-creating-ds.ftd
│       ├── 09-add-sitemap.ftd
│       ├── 10-change-theme.ftd
│       ├── 11-change-cs-typo.ftd
│       ├── 12-document.ftd
│       ├── 13-use-redirect.ftd
│       ├── 14-seo-meta.ftd
│       ├── 15-add-banner.ftd
│       ├── 16-add-sidebar.ftd
│       ├── 17-portfolio.ftd
│       ├── devs/
│       │   └── index.ftd
│       ├── index.ftd
│       └── learn.ftd
├── fbt/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
├── fbt_lib/
│   ├── Cargo.toml
│   └── src/
│       ├── copy_dir.rs
│       ├── dir_diff.rs
│       ├── lib.rs
│       ├── run.rs
│       └── types.rs
├── flake.nix
├── ftd/
│   ├── Cargo.toml
│   ├── README.md
│   ├── build.html
│   ├── build.js
│   ├── examples/
│   │   ├── 01-input.ftd
│   │   ├── absolute_positioning.ftd
│   │   ├── action-increment-decrement-local-variable.ftd
│   │   ├── action-increment-decrement-on-component.ftd
│   │   ├── action-increment-decrement.ftd
│   │   ├── always-include.ftd
│   │   ├── anchor-position.ftd
│   │   ├── animated.ftd
│   │   ├── api-onclick.ftd
│   │   ├── architecture-diagram.ftd
│   │   ├── auto-nesting.ftd
│   │   ├── background-image.ftd
│   │   ├── basic-loop-on-record.ftd
│   │   ├── buggy-open.ftd
│   │   ├── color.ftd
│   │   ├── comic.ftd
│   │   ├── comic_scene_crop_scale.ftd
│   │   ├── comic_with_scene_without_comicgen.ftd
│   │   ├── comment_check.ftd
│   │   ├── condition-on-optional.ftd
│   │   ├── conditional-attribute-tab.ftd
│   │   ├── conditional-attributes.ftd
│   │   ├── conditional-variable.ftd
│   │   ├── container-switch.ftd
│   │   ├── container-test.ftd
│   │   ├── deep-nested-open-container.ftd
│   │   ├── deep-open-container.ftd
│   │   ├── dom-construct.ftd
│   │   ├── escape-body.ftd
│   │   ├── event-on-click-outside.ftd
│   │   ├── event-on-focus-blur.ftd
│   │   ├── event-on-focus.ftd
│   │   ├── event-onclick-toggle.ftd
│   │   ├── event-set.ftd
│   │   ├── event-stop-propagation.ftd
│   │   ├── event-toggle-creating-a-tree.ftd
│   │   ├── event-toggle-for-loop.ftd
│   │   ├── event-toggle-local-variable-for-component.ftd
│   │   ├── event-toggle-local-variable.ftd
│   │   ├── event-toggle-on-inner-container.ftd
│   │   ├── example.ftd
│   │   ├── external-variable.ftd
│   │   ├── font.ftd
│   │   ├── ft.ftd
│   │   ├── ftd-input-default-value.ftd
│   │   ├── global-key-event.ftd
│   │   ├── grid-sample.ftd
│   │   ├── grid.ftd
│   │   ├── hello-world.ftd
│   │   ├── http-api.ftd
│   │   ├── image-title.ftd
│   │   ├── image.ftd
│   │   ├── internal-links.ftd
│   │   ├── intra-page-link-2.ftd
│   │   ├── intra-page-link-heading.ftd
│   │   ├── intra-page-link.ftd
│   │   ├── lib.ftd
│   │   ├── line-clamp.ftd
│   │   ├── markdown-color.ftd
│   │   ├── markup-line.ftd
│   │   ├── markup.ftd
│   │   ├── message.ftd
│   │   ├── mouse-in-text.ftd
│   │   ├── mygate.ftd
│   │   ├── nested-component.ftd
│   │   ├── nested-open-container.ftd
│   │   ├── new-syntax.ftd
│   │   ├── open-container-with-id.ftd
│   │   ├── open-container-with-if.ftd
│   │   ├── open-with-append-at.ftd
│   │   ├── optional-condition.ftd
│   │   ├── optional-ftd-ui.ftd
│   │   ├── optional-pass-to-optional.ftd
│   │   ├── pass-by-reference.ftd
│   │   ├── pass-optional.ftd
│   │   ├── presentation.ftd
│   │   ├── record-reinitialisation.ftd
│   │   ├── record.ftd
│   │   ├── reference-linking.ftd
│   │   ├── region.ftd
│   │   ├── rendering-ft-page.ftd
│   │   ├── slides.ftd
│   │   ├── spacing-and-image-link.ftd
│   │   ├── spacing.ftd
│   │   ├── submit.ftd
│   │   ├── t1.ftd
│   │   ├── test-video.ftd
│   │   ├── test.dev.ftd
│   │   ├── test.ftd
│   │   ├── test1.ftd
│   │   ├── test2.ftd
│   │   ├── text-indent.ftd
│   │   ├── universal-attributes.ftd
│   │   └── variable-component.ftd
│   ├── ftd-js.css
│   ├── ftd-js.html
│   ├── ftd.css
│   ├── ftd.html
│   ├── ftd.js
│   ├── github-stuff/
│   │   ├── dependabot.yml
│   │   └── workflows/
│   │       └── rust.yml
│   ├── prism/
│   │   ├── prism-bash.js
│   │   ├── prism-diff.js
│   │   ├── prism-javascript.js
│   │   ├── prism-json.js
│   │   ├── prism-line-highlight.css
│   │   ├── prism-line-highlight.js
│   │   ├── prism-line-numbers.css
│   │   ├── prism-line-numbers.js
│   │   ├── prism-markdown.js
│   │   ├── prism-python.js
│   │   ├── prism-rust.js
│   │   ├── prism-sql.js
│   │   └── prism.js
│   ├── rt.html
│   ├── scripts/
│   │   └── create-huge-ftd.py
│   ├── src/
│   │   ├── document_store.rs
│   │   ├── executor/
│   │   │   ├── code.rs
│   │   │   ├── dummy.rs
│   │   │   ├── element.rs
│   │   │   ├── fastn_type_functions.rs
│   │   │   ├── main.rs
│   │   │   ├── markup.rs
│   │   │   ├── mod.rs
│   │   │   ├── rive.rs
│   │   │   ├── styles.rs
│   │   │   ├── tdoc.rs
│   │   │   ├── test.rs
│   │   │   ├── utils.rs
│   │   │   ├── value.rs
│   │   │   └── youtube_id.rs
│   │   ├── ftd2021/
│   │   │   ├── code.rs
│   │   │   ├── component.rs
│   │   │   ├── condition.rs
│   │   │   ├── constants.rs
│   │   │   ├── di/
│   │   │   │   ├── definition.rs
│   │   │   │   ├── import.rs
│   │   │   │   ├── invocation.rs
│   │   │   │   ├── main.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── property.rs
│   │   │   │   ├── record.rs
│   │   │   │   ├── t/
│   │   │   │   │   ├── 1-import.ftd
│   │   │   │   │   ├── 1-import.json
│   │   │   │   │   ├── 2-import.ftd
│   │   │   │   │   ├── 2-import.json
│   │   │   │   │   ├── 3-record.ftd
│   │   │   │   │   ├── 3-record.json
│   │   │   │   │   ├── 4-record.ftd
│   │   │   │   │   ├── 4-record.json
│   │   │   │   │   ├── 5-variable.ftd
│   │   │   │   │   ├── 5-variable.json
│   │   │   │   │   ├── 6-variable.ftd
│   │   │   │   │   ├── 6-variable.json
│   │   │   │   │   ├── 7-variable.ftd
│   │   │   │   │   ├── 7-variable.json
│   │   │   │   │   ├── 8-component.ftd
│   │   │   │   │   ├── 8-component.json
│   │   │   │   │   ├── 9-component.ftd
│   │   │   │   │   └── 9-component.json
│   │   │   │   ├── test.rs
│   │   │   │   └── utils.rs
│   │   │   ├── dnode.rs
│   │   │   ├── event.rs
│   │   │   ├── execute_doc.rs
│   │   │   ├── html.rs
│   │   │   ├── interpreter/
│   │   │   │   ├── main.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── tdoc.rs
│   │   │   │   ├── test.rs
│   │   │   │   ├── things/
│   │   │   │   │   ├── expression.rs
│   │   │   │   │   ├── kind.rs
│   │   │   │   │   ├── mod.rs
│   │   │   │   │   ├── property_value.rs
│   │   │   │   │   └── variable.rs
│   │   │   │   └── utils.rs
│   │   │   ├── markup.rs
│   │   │   ├── mod.rs
│   │   │   ├── or_type.rs
│   │   │   ├── p1/
│   │   │   │   ├── header.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── parser.rs
│   │   │   │   ├── section.rs
│   │   │   │   ├── sub_section.rs
│   │   │   │   └── to_string.rs
│   │   │   ├── p2/
│   │   │   │   ├── document.rs
│   │   │   │   ├── element.rs
│   │   │   │   ├── event.rs
│   │   │   │   ├── expression.rs
│   │   │   │   ├── interpreter.rs
│   │   │   │   ├── kind.rs
│   │   │   │   ├── library.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── record.rs
│   │   │   │   ├── tdoc.rs
│   │   │   │   └── utils.rs
│   │   │   ├── rendered.rs
│   │   │   ├── rt.rs
│   │   │   ├── test.rs
│   │   │   ├── ui.rs
│   │   │   ├── value_with_default.rs
│   │   │   ├── variable.rs
│   │   │   └── youtube_id.rs
│   │   ├── html/
│   │   │   ├── data.rs
│   │   │   ├── dependencies.rs
│   │   │   ├── dummy_html.rs
│   │   │   ├── events.rs
│   │   │   ├── fastn_type_functions.rs
│   │   │   ├── functions.rs
│   │   │   ├── main.rs
│   │   │   ├── mod.rs
│   │   │   ├── test.rs
│   │   │   ├── utils.rs
│   │   │   └── variable_dependencies.rs
│   │   ├── interpreter/
│   │   │   ├── main.rs
│   │   │   ├── mod.rs
│   │   │   ├── prelude.rs
│   │   │   ├── tdoc.rs
│   │   │   ├── test.rs
│   │   │   ├── things/
│   │   │   │   ├── component.rs
│   │   │   │   ├── expression.rs
│   │   │   │   ├── function.rs
│   │   │   │   ├── kind.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── or_type.rs
│   │   │   │   ├── record.rs
│   │   │   │   ├── value.rs
│   │   │   │   ├── variable.rs
│   │   │   │   └── web_component.rs
│   │   │   └── utils.rs
│   │   ├── js/
│   │   │   ├── ftd_test_helpers.rs
│   │   │   └── mod.rs
│   │   ├── lib.rs
│   │   ├── main.rs
│   │   ├── node/
│   │   │   ├── main.rs
│   │   │   ├── mod.rs
│   │   │   ├── node_data.rs
│   │   │   ├── raw_node.rs
│   │   │   ├── test.rs
│   │   │   ├── utils.rs
│   │   │   └── value.rs
│   │   ├── parser.rs
│   │   ├── stack_overflow_test.rs
│   │   ├── taffy.rs
│   │   ├── terminal.rs
│   │   ├── test_helper.rs
│   │   └── wasm/
│   │       ├── document.rs
│   │       ├── mod.rs
│   │       ├── value.rs
│   │       └── variable.rs
│   ├── syntax/
│   │   ├── elm.sublime-syntax
│   │   ├── ftd.sublime-syntax
│   │   └── toml.sublime-syntax
│   ├── t/
│   │   ├── assets/
│   │   │   ├── bell-icon.riv
│   │   │   ├── fastn-anime.riv
│   │   │   ├── fastn.riv
│   │   │   ├── panda.riv
│   │   │   ├── plane_mouse_tracking.riv
│   │   │   ├── test.css
│   │   │   ├── test.js
│   │   │   ├── todo.js
│   │   │   ├── toggleufbot.riv
│   │   │   └── web_component.js
│   │   ├── executor/
│   │   │   ├── 1-component.ftd
│   │   │   ├── 1-component.json
│   │   │   ├── 10-or-type.ftd
│   │   │   ├── 10-or-type.json
│   │   │   ├── 11-web-component.ftd
│   │   │   ├── 11-web-component.json
│   │   │   ├── 2-component.ftd
│   │   │   ├── 2-component.json
│   │   │   ├── 3-component.ftd
│   │   │   ├── 3-component.json
│   │   │   ├── 4-component.ftd
│   │   │   ├── 4-component.json
│   │   │   ├── 5-component-recursion.ftd
│   │   │   ├── 5-component-recursion.json
│   │   │   ├── 6-function.ftd
│   │   │   ├── 6-function.json
│   │   │   ├── 7-event.ftd
│   │   │   ├── 7-event.json
│   │   │   ├── 8-external-children.ftd
│   │   │   ├── 8-external-children.json
│   │   │   ├── 9-conditional-component.ftd
│   │   │   └── 9-conditional-component.json
│   │   ├── html/
│   │   │   ├── 1-component.ftd
│   │   │   ├── 1-component.html
│   │   │   ├── 10-conditional-properties.ftd
│   │   │   ├── 10-conditional-properties.html
│   │   │   ├── 100-linear-gradient.ftd
│   │   │   ├── 100-linear-gradient.html
│   │   │   ├── 100-re-export.ftd
│   │   │   ├── 100-re-export.html
│   │   │   ├── 101-re-re-export.ftd
│   │   │   ├── 101-re-re-export.html
│   │   │   ├── 102-access-modifiers.ftd
│   │   │   ├── 102-access-modifiers.html
│   │   │   ├── 103-block-header-record.ftd
│   │   │   ├── 103-block-header-record.html
│   │   │   ├── 104-block-header-record-extended.ftd
│   │   │   ├── 104-block-header-record-extended.html
│   │   │   ├── 105-document-breakpoint.ftd
│   │   │   ├── 105-document-breakpoint.html
│   │   │   ├── 106-comments.ftd
│   │   │   ├── 106-comments.html
│   │   │   ├── 107-old-fastn-code-syntax.ftd
│   │   │   ├── 107-old-fastn-code-syntax.html
│   │   │   ├── 108-linear-gradient-conditional.ftd
│   │   │   ├── 108-linear-gradient-conditional.html
│   │   │   ├── 109-image-fit.ftd
│   │   │   ├── 109-image-fit.html
│   │   │   ├── 11-external-children.ftd
│   │   │   ├── 11-external-children.html
│   │   │   ├── 110-fallback-fonts.ftd
│   │   │   ├── 110-fallback-fonts.html
│   │   │   ├── 12-conditional-component.ftd
│   │   │   ├── 12-conditional-component.html
│   │   │   ├── 13-image.ftd
│   │   │   ├── 13-image.html
│   │   │   ├── 14-processor.ftd
│   │   │   ├── 14-processor.html
│   │   │   ├── 15-foreign-variable.ftd
│   │   │   ├── 15-foreign-variable.html
│   │   │   ├── 16-or-type.ftd
│   │   │   ├── 16-or-type.html
│   │   │   ├── 17-record.ftd
│   │   │   ├── 17-record.html
│   │   │   ├── 18-styles.ftd
│   │   │   ├── 18-styles.html
│   │   │   ├── 19-complex-styles.ftd
│   │   │   ├── 19-complex-styles.html
│   │   │   ├── 2-component.ftd
│   │   │   ├── 2-component.html
│   │   │   ├── 20-link.ftd
│   │   │   ├── 20-link.html
│   │   │   ├── 21-color.ftd
│   │   │   ├── 21-color.html
│   │   │   ├── 22-test.ftd
│   │   │   ├── 22-test.html
│   │   │   ├── 23-alignment.ftd
│   │   │   ├── 23-alignment.html
│   │   │   ├── 23-doc-site.ftd
│   │   │   ├── 23-doc-site.html
│   │   │   ├── 24-margin.ftd
│   │   │   ├── 24-margin.html
│   │   │   ├── 25-expander.ftd
│   │   │   ├── 25-expander.html
│   │   │   ├── 25-overflow.ftd
│   │   │   ├── 25-overflow.html
│   │   │   ├── 26-border.ftd
│   │   │   ├── 26-border.html
│   │   │   ├── 27-optional.ftd
│   │   │   ├── 27-optional.html
│   │   │   ├── 28-complex.ftd
│   │   │   ├── 28-complex.html
│   │   │   ├── 29-slides.ftd
│   │   │   ├── 29-slides.html
│   │   │   ├── 3-component.ftd
│   │   │   ├── 3-component.html
│   │   │   ├── 30-slides.ftd
│   │   │   ├── 30-slides.html
│   │   │   ├── 31-message.ftd
│   │   │   ├── 31-message.html
│   │   │   ├── 32-test.ftd
│   │   │   ├── 32-test.html
│   │   │   ├── 33-component-using-css.ftd
│   │   │   ├── 33-component-using-css.html
│   │   │   ├── 33-using-css.ftd
│   │   │   ├── 33-using-css.html
│   │   │   ├── 34-device.ftd
│   │   │   ├── 34-device.html
│   │   │   ├── 35-condition-on-color.ftd
│   │   │   ├── 35-condition-on-color.html
│   │   │   ├── 36-test.ftd
│   │   │   ├── 36-test.html
│   │   │   ├── 37-cursor.ftd
│   │   │   ├── 37-cursor.html
│   │   │   ├── 38-role.ftd
│   │   │   ├── 38-role.html
│   │   │   ├── 39-events.ftd
│   │   │   ├── 39-events.html
│   │   │   ├── 4-component.ftd
│   │   │   ├── 4-component.html
│   │   │   ├── 40-anchor.ftd
│   │   │   ├── 40-anchor.html
│   │   │   ├── 41-responsive-type.ftd
│   │   │   ├── 41-responsive-type.html
│   │   │   ├── 42-default-function.ftd
│   │   │   ├── 42-default-function.html
│   │   │   ├── 43-default-colors-types.ftd
│   │   │   ├── 43-default-colors-types.html
│   │   │   ├── 44-region.ftd
│   │   │   ├── 44-region.html
│   │   │   ├── 45-using-hyphen.ftd
│   │   │   ├── 45-using-hyphen.html
│   │   │   ├── 46-record-in-pscript.ftd
│   │   │   ├── 46-record-in-pscript.html
│   │   │   ├── 47-white-space.ftd
│   │   │   ├── 47-white-space.html
│   │   │   ├── 48-basic-functions.ftd
│   │   │   ├── 48-basic-functions.html
│   │   │   ├── 49-import.ftd
│   │   │   ├── 49-import.html
│   │   │   ├── 5-component-recursion.ftd
│   │   │   ├── 5-component-recursion.html
│   │   │   ├── 50-using-import.ftd
│   │   │   ├── 50-using-import.html
│   │   │   ├── 51-text-transform.ftd
│   │   │   ├── 51-text-transform.html
│   │   │   ├── 52-code-and-iframe.ftd
│   │   │   ├── 52-code-and-iframe.html
│   │   │   ├── 53-decimal.ftd
│   │   │   ├── 53-decimal.html
│   │   │   ├── 53-font-family.ftd
│   │   │   ├── 53-font-family.html
│   │   │   ├── 54-input.ftd
│   │   │   ├── 54-input.html
│   │   │   ├── 55-inherited.ftd
│   │   │   ├── 55-inherited.html
│   │   │   ├── 55-line-clamp.ftd
│   │   │   ├── 55-line-clamp.html
│   │   │   ├── 56-passing-events.ftd
│   │   │   ├── 56-passing-events.html
│   │   │   ├── 57-border-style.ftd
│   │   │   ├── 57-border-style.html
│   │   │   ├── 58-id.ftd
│   │   │   ├── 58-id.html
│   │   │   ├── 59-sticky.ftd
│   │   │   ├── 59-sticky.html
│   │   │   ├── 6-function.ftd
│   │   │   ├── 6-function.html
│   │   │   ├── 60-region-id-slug.ftd
│   │   │   ├── 60-region-id-slug.html
│   │   │   ├── 61-loop-variable.ftd
│   │   │   ├── 61-loop-variable.html
│   │   │   ├── 62-spacing.ftd
│   │   │   ├── 62-spacing.html
│   │   │   ├── 63-checkbox.ftd
│   │   │   ├── 63-checkbox.html
│   │   │   ├── 64-muliple-node-dep.ftd
│   │   │   ├── 64-muliple-node-dep.html
│   │   │   ├── 64-multiple-node-dep-1.ftd
│   │   │   ├── 64-multiple-node-dep-1.html
│   │   │   ├── 65-mut-loop.ftd
│   │   │   ├── 65-mut-loop.html
│   │   │   ├── 66-inheritance.ftd
│   │   │   ├── 66-inheritance.html
│   │   │   ├── 67-enabled.ftd
│   │   │   ├── 67-enabled.html
│   │   │   ├── 68-anchor-id.ftd
│   │   │   ├── 68-anchor-id.html
│   │   │   ├── 69-inside-loop.ftd
│   │   │   ├── 69-inside-loop.html
│   │   │   ├── 7-events.ftd
│   │   │   ├── 7-events.html
│   │   │   ├── 70-figma-json-to-ftd.ftd
│   │   │   ├── 70-figma-json-to-ftd.html
│   │   │   ├── 70-length-check.ftd
│   │   │   ├── 70-length-check.html
│   │   │   ├── 71-web-component.ftd
│   │   │   ├── 71-web-component.html
│   │   │   ├── 72-external-js.ftd
│   │   │   ├── 72-external-js.html
│   │   │   ├── 73-complex-ftd-ui.ftd
│   │   │   ├── 73-complex-ftd-ui.html
│   │   │   ├── 74-import-complex-ftd-ui.ftd
│   │   │   ├── 74-import-complex-ftd-ui.html
│   │   │   ├── 75-ui-list-display.ftd
│   │   │   ├── 75-ui-list-display.html
│   │   │   ├── 76-inter-argument.ftd
│   │   │   ├── 76-inter-argument.html
│   │   │   ├── 77-property-source-fix.ftd
│   │   │   ├── 77-property-source-fix.html
│   │   │   ├── 79-shorthand-lists.ftd
│   │   │   ├── 79-shorthand-lists.html
│   │   │   ├── 8-counter.ftd
│   │   │   ├── 8-counter.html
│   │   │   ├── 80-module.ftd
│   │   │   ├── 80-module.html
│   │   │   ├── 81-markdown.ftd
│   │   │   ├── 81-markdown.html
│   │   │   ├── 82-text-style.ftd
│   │   │   ├── 82-text-style.html
│   │   │   ├── 83-text-indent.ftd
│   │   │   ├── 83-text-indent.html
│   │   │   ├── 84-ftd-ui-list-issue.ftd
│   │   │   ├── 84-ftd-ui-list-issue.html
│   │   │   ├── 85-bg-image.ftd
│   │   │   ├── 85-bg-image.html
│   │   │   ├── 86-ftd-document.ftd
│   │   │   ├── 86-ftd-document.html
│   │   │   ├── 86-shadow.ftd
│   │   │   ├── 86-shadow.html
│   │   │   ├── 87-bg-repeat-original.html
│   │   │   ├── 87-bg-repeat.ftd
│   │   │   ├── 87-bg-repeat.html
│   │   │   ├── 87-mutability.ftd
│   │   │   ├── 87-mutability.html
│   │   │   ├── 88-ftd-length.ftd
│   │   │   ├── 88-ftd-length.html
│   │   │   ├── 89-display.ftd
│   │   │   ├── 89-display.html
│   │   │   ├── 9-conditional-properties.ftd
│   │   │   ├── 9-conditional-properties.html
│   │   │   ├── 90-img-alt.ftd
│   │   │   ├── 90-img-alt.html
│   │   │   ├── 91-opacity.ftd
│   │   │   ├── 91-opacity.html
│   │   │   ├── 92-rive.ftd
│   │   │   ├── 92-rive.html
│   │   │   ├── 93-rive-bell.ftd
│   │   │   ├── 93-rive-bell.html
│   │   │   ├── 94-rive-toggle.ftd
│   │   │   ├── 94-rive-toggle.html
│   │   │   ├── 95-rive-bell-animation.ftd
│   │   │   ├── 95-rive-bell-animation.html
│   │   │   ├── 96-rive-truck-animation.ftd
│   │   │   ├── 96-rive-truck-animation.html
│   │   │   ├── 97-rive-fastn.ftd
│   │   │   ├── 97-rive-fastn.html
│   │   │   ├── 98-device.ftd
│   │   │   ├── 98-device.html
│   │   │   ├── 99-unoptimized-device.ftd
│   │   │   ├── 99-unoptimized-device.html
│   │   │   ├── check.ftd
│   │   │   ├── check.html
│   │   │   ├── function.ftd
│   │   │   ├── function.html
│   │   │   ├── get.ftd
│   │   │   ├── get.html
│   │   │   ├── h-100.ftd
│   │   │   ├── h-100.html
│   │   │   ├── resume.ftd
│   │   │   ├── resume.html
│   │   │   ├── sd.ftd
│   │   │   └── sd.html
│   │   ├── interpreter/
│   │   │   ├── 1-record.ftd
│   │   │   ├── 1-record.json
│   │   │   ├── 10-component-definition.ftd
│   │   │   ├── 10-component-definition.json
│   │   │   ├── 11-component-definition.ftd
│   │   │   ├── 11-component-definition.json
│   │   │   ├── 12-component-definition.ftd
│   │   │   ├── 12-component-definition.json
│   │   │   ├── 13-component-definition.ftd
│   │   │   ├── 13-component-definition.json
│   │   │   ├── 14-component-definition.ftd
│   │   │   ├── 14-component-definition.json
│   │   │   ├── 15-component-iteration.ftd
│   │   │   ├── 15-component-iteration.json
│   │   │   ├── 16-component-recursion.ftd
│   │   │   ├── 16-component-recursion.json
│   │   │   ├── 17-function.ftd
│   │   │   ├── 17-function.json
│   │   │   ├── 18-event.ftd
│   │   │   ├── 18-event.json
│   │   │   ├── 19-external-children.ftd
│   │   │   ├── 19-external-children.json
│   │   │   ├── 2-record.ftd
│   │   │   ├── 2-record.json
│   │   │   ├── 20-or-type.ftd
│   │   │   ├── 20-or-type.json
│   │   │   ├── 21-record-event.ftd
│   │   │   ├── 21-record-event.json
│   │   │   ├── 22-inherited.ftd
│   │   │   ├── 22-inherited.json
│   │   │   ├── 23-web-component.ftd
│   │   │   ├── 23-web-component.json
│   │   │   ├── 24-device.ftd
│   │   │   ├── 24-device.json
│   │   │   ├── 25-kwargs.ftd
│   │   │   ├── 25-kwargs.json
│   │   │   ├── 26-infinite-loop.error
│   │   │   ├── 26-infinite-loop.ftd
│   │   │   ├── 27-infinite-loop.error
│   │   │   ├── 27-infinite-loop.ftd
│   │   │   ├── 28-infinite-loop.error
│   │   │   ├── 28-infinite-loop.ftd
│   │   │   ├── 29-infinite-loop.error
│   │   │   ├── 29-infinite-loop.ftd
│   │   │   ├── 3-record.ftd
│   │   │   ├── 3-record.json
│   │   │   ├── 30-infinite-loop.error
│   │   │   ├── 30-infinite-loop.ftd
│   │   │   ├── 31-infinite-loop.error
│   │   │   ├── 31-infinite-loop.ftd
│   │   │   ├── 32-recursion.ftd
│   │   │   ├── 32-recursion.json
│   │   │   ├── 4-variable.ftd
│   │   │   ├── 4-variable.json
│   │   │   ├── 5-variable.ftd
│   │   │   ├── 5-variable.json
│   │   │   ├── 6-variable-invocation.ftd
│   │   │   ├── 6-variable-invocation.json
│   │   │   ├── 7-variable-invocation.ftd
│   │   │   ├── 7-variable-invocation.json
│   │   │   ├── 8-variable-invocation.ftd
│   │   │   ├── 8-variable-invocation.json
│   │   │   ├── 9-component-definition.ftd
│   │   │   └── 9-component-definition.json
│   │   ├── js/
│   │   │   ├── 01-basic-module.ftd
│   │   │   ├── 01-basic-module.html
│   │   │   ├── 01-basic.ftd
│   │   │   ├── 01-basic.html
│   │   │   ├── 02-property.ftd
│   │   │   ├── 02-property.html
│   │   │   ├── 03-common-properties.ftd
│   │   │   ├── 03-common-properties.html
│   │   │   ├── 04-variable.ftd
│   │   │   ├── 04-variable.html
│   │   │   ├── 05-dynamic-dom-list.ftd
│   │   │   ├── 05-dynamic-dom-list.html
│   │   │   ├── 06-dynamic-dom-list-2.ftd
│   │   │   ├── 06-dynamic-dom-list-2.html
│   │   │   ├── 07-dynamic-dom-record-list.ftd
│   │   │   ├── 07-dynamic-dom-record-list.html
│   │   │   ├── 08-inherited.ftd
│   │   │   ├── 08-inherited.html
│   │   │   ├── 09-text-properties.ftd
│   │   │   ├── 09-text-properties.html
│   │   │   ├── 10-color-test.ftd
│   │   │   ├── 10-color-test.html
│   │   │   ├── 100-template.ftd
│   │   │   ├── 100-template.html
│   │   │   ├── 101-response.ftd
│   │   │   ├── 101-response.html
│   │   │   ├── 102-response.ftd
│   │   │   ├── 102-response.html
│   │   │   ├── 103-ftd-json-templ.ftd
│   │   │   ├── 103-ftd-json-templ.html
│   │   │   ├── 103-iframe.ftd
│   │   │   ├── 103-iframe.html
│   │   │   ├── 104-a-export-star.ftd
│   │   │   ├── 104-a-export-star.html
│   │   │   ├── 104-b-export-star.ftd
│   │   │   ├── 104-b-export-star.html
│   │   │   ├── 104-j-export-star.ftd
│   │   │   ├── 104-j-export-star.html
│   │   │   ├── 104-k-export-star.ftd
│   │   │   ├── 104-k-export-star.html
│   │   │   ├── 11-device.ftd
│   │   │   ├── 11-device.html
│   │   │   ├── 12-children.ftd
│   │   │   ├── 12-children.html
│   │   │   ├── 13-non-style-properties.ftd
│   │   │   ├── 13-non-style-properties.html
│   │   │   ├── 14-code.ftd
│   │   │   ├── 14-code.html
│   │   │   ├── 15-function-call-in-property.ftd
│   │   │   ├── 15-function-call-in-property.html
│   │   │   ├── 16-container.ftd
│   │   │   ├── 16-container.html
│   │   │   ├── 17-clone.ftd
│   │   │   ├── 17-clone.html
│   │   │   ├── 17-events.ftd
│   │   │   ├── 17-events.html
│   │   │   ├── 18-rive.ftd
│   │   │   ├── 18-rive.html
│   │   │   ├── 19-image.ftd
│   │   │   ├── 19-image.html
│   │   │   ├── 20-background-properties.ftd
│   │   │   ├── 20-background-properties.html
│   │   │   ├── 21-markdown.ftd
│   │   │   ├── 21-markdown.html
│   │   │   ├── 22-document.ftd
│   │   │   ├── 22-document.html
│   │   │   ├── 23-record-list.ftd
│   │   │   ├── 23-record-list.html
│   │   │   ├── 24-device.ftd
│   │   │   ├── 24-device.html
│   │   │   ├── 24-re-export-star-with-custom-def.ftd
│   │   │   ├── 24-re-export-star-with-custom-def.html
│   │   │   ├── 24-re-export-star.ftd
│   │   │   ├── 24-re-export-star.html
│   │   │   ├── 24-re-export.ftd
│   │   │   ├── 24-re-export.html
│   │   │   ├── 25-re-re-export-star-with-custom-def.ftd
│   │   │   ├── 25-re-re-export-star-with-custom-def.html
│   │   │   ├── 25-re-re-export-star.ftd
│   │   │   ├── 25-re-re-export-star.html
│   │   │   ├── 25-re-re-export.ftd
│   │   │   ├── 25-re-re-export.html
│   │   │   ├── 26-re-export.ftd
│   │   │   ├── 26-re-export.html
│   │   │   ├── 27-for-loop.ftd
│   │   │   ├── 27-for-loop.html
│   │   │   ├── 28-mutable-component-arguments.ftd
│   │   │   ├── 28-mutable-component-arguments.html
│   │   │   ├── 28-web-component.ftd
│   │   │   ├── 28-web-component.html
│   │   │   ├── 29-dom-list.ftd
│   │   │   ├── 29-dom-list.html
│   │   │   ├── 30-web-component.ftd
│   │   │   ├── 30-web-component.html
│   │   │   ├── 31-advance-list.ftd
│   │   │   ├── 31-advance-list.html
│   │   │   ├── 31-ftd-len.ftd
│   │   │   ├── 31-ftd-len.html
│   │   │   ├── 32-ftd-len.ftd
│   │   │   ├── 32-ftd-len.html
│   │   │   ├── 33-list-indexing.ftd
│   │   │   ├── 33-list-indexing.html
│   │   │   ├── 34-ftd-ui.ftd
│   │   │   ├── 34-ftd-ui.html
│   │   │   ├── 36-single-ui.ftd
│   │   │   ├── 36-single-ui.html
│   │   │   ├── 37-expander.ftd
│   │   │   ├── 37-expander.html
│   │   │   ├── 38-background-image-properties.ftd
│   │   │   ├── 38-background-image-properties.html
│   │   │   ├── 40-code-themes.ftd
│   │   │   ├── 40-code-themes.html
│   │   │   ├── 41-document-favicon.ftd
│   │   │   ├── 41-document-favicon.html
│   │   │   ├── 42-links.ftd
│   │   │   ├── 42-links.html
│   │   │   ├── 43-image-object-fit.ftd
│   │   │   ├── 43-image-object-fit.html
│   │   │   ├── 44-local-storage.ftd
│   │   │   ├── 44-local-storage.html
│   │   │   ├── 44-module.ftd
│   │   │   ├── 44-module.html
│   │   │   ├── 45-re-module.ftd
│   │   │   ├── 45-re-module.html
│   │   │   ├── 45-re-re-module.ftd
│   │   │   ├── 45-re-re-module.html
│   │   │   ├── 46-code-languages.ftd
│   │   │   ├── 46-code-languages.html
│   │   │   ├── 47-ftd-code-syntax.ftd
│   │   │   ├── 47-ftd-code-syntax.html
│   │   │   ├── 48-video.ftd
│   │   │   ├── 48-video.html
│   │   │   ├── 49-align-content.ftd
│   │   │   ├── 49-align-content.html
│   │   │   ├── 50-iframe-fullscreen.ftd
│   │   │   ├── 50-iframe-fullscreen.html
│   │   │   ├── 51-markdown-table.ftd
│   │   │   ├── 51-markdown-table.html
│   │   │   ├── 52-events.ftd
│   │   │   ├── 52-events.html
│   │   │   ├── 53-link-color.ftd
│   │   │   ├── 53-link-color.html
│   │   │   ├── 54-class-fix.ftd
│   │   │   ├── 54-class-fix.html
│   │   │   ├── 56-title-fix.ftd
│   │   │   ├── 56-title-fix.html
│   │   │   ├── 57-code-dark-mode.ftd
│   │   │   ├── 57-code-dark-mode.html
│   │   │   ├── 59-text-shadow.ftd
│   │   │   ├── 59-text-shadow.html
│   │   │   ├── 60-conditional-module-headers.ftd
│   │   │   ├── 60-conditional-module-headers.html
│   │   │   ├── 61-functions.ftd
│   │   │   ├── 61-functions.html
│   │   │   ├── 62-fallback-fonts.ftd
│   │   │   ├── 62-fallback-fonts.html
│   │   │   ├── 63-external-js.ftd
│   │   │   ├── 63-external-js.html
│   │   │   ├── 64-selectable.ftd
│   │   │   ├── 64-selectable.html
│   │   │   ├── 65-legacy.ftd
│   │   │   ├── 65-legacy.html
│   │   │   ├── 66-backdrop-filter.ftd
│   │   │   ├── 66-backdrop-filter.html
│   │   │   ├── 67-counter.ftd
│   │   │   ├── 67-counter.html
│   │   │   ├── 68-mask.ftd
│   │   │   ├── 68-mask.html
│   │   │   ├── 69-chained-dot-value-in-functions.ftd
│   │   │   ├── 69-chained-dot-value-in-functions.html
│   │   │   ├── 72-document-breakpoint.ftd
│   │   │   ├── 72-document-breakpoint.html
│   │   │   ├── 73-loops-inside-list.ftd
│   │   │   ├── 73-loops-inside-list.html
│   │   │   ├── 74-default-text-value.ftd
│   │   │   ├── 74-default-text-value.html
│   │   │   ├── 78-data-for-module.ftd
│   │   │   ├── 78-data-for-module.html
│   │   │   ├── 78-module-using-record.ftd
│   │   │   ├── 78-module-using-record.html
│   │   │   ├── 79-module-using-function.ftd
│   │   │   ├── 79-module-using-function.html
│   │   │   ├── 80-or-type-constant.ftd
│   │   │   ├── 80-or-type-constant.html
│   │   │   ├── 81-or-type-test.ftd
│   │   │   ├── 81-or-type-test.html
│   │   │   ├── 82-or-type-module.ftd
│   │   │   ├── 82-or-type-module.html
│   │   │   ├── 85-export-or-type.ftd
│   │   │   ├── 85-export-or-type.html
│   │   │   ├── 86-import-or-type.ftd
│   │   │   ├── 86-import-or-type.html
│   │   │   ├── 87-or-type-module-export.ftd
│   │   │   ├── 87-or-type-module-export.html
│   │   │   ├── 88-body-children.ftd
│   │   │   ├── 88-body-children.html
│   │   │   ├── 88-module-reference-wrap-in-variant.ftd
│   │   │   ├── 88-module-reference-wrap-in-variant.html
│   │   │   ├── 89-nested-or-type.ftd
│   │   │   ├── 89-nested-or-type.html
│   │   │   ├── 90-error.error
│   │   │   ├── 90-error.ftd
│   │   │   ├── 91-component-event.ftd
│   │   │   ├── 91-component-event.html
│   │   │   ├── 92-self-reference-record.ftd
│   │   │   ├── 92-self-reference-record.html
│   │   │   ├── 93-reference-data.ftd
│   │   │   ├── 93-reference-data.html
│   │   │   ├── 94-kw-args.ftd
│   │   │   ├── 94-kw-args.html
│   │   │   ├── 95-record-closure.ftd
│   │   │   ├── 95-record-closure.html
│   │   │   ├── 96-download-tag.ftd
│   │   │   ├── 96-download-tag.html
│   │   │   ├── 97-clone-mutability-check.ftd
│   │   │   ├── 97-clone-mutability-check.html
│   │   │   ├── 98-audio.ftd
│   │   │   ├── 98-audio.html
│   │   │   ├── 99-ftd-json.ftd
│   │   │   ├── 99-ftd-json.html
│   │   │   ├── loop.ftd
│   │   │   └── loop.html
│   │   ├── node/
│   │   │   ├── 1-component.ftd
│   │   │   ├── 1-component.json
│   │   │   ├── 2-component.ftd
│   │   │   ├── 2-component.json
│   │   │   ├── 3-component.ftd
│   │   │   ├── 3-component.json
│   │   │   ├── 4-component.ftd
│   │   │   ├── 4-component.json
│   │   │   ├── 5-component-recursion.ftd
│   │   │   ├── 5-component-recursion.json
│   │   │   ├── 6-function.ftd
│   │   │   ├── 6-function.json
│   │   │   ├── 7-web-component.ftd
│   │   │   └── 7-web-component.json
│   │   └── should-work/
│   │       └── 01-mutable-local-variable.ftd
│   ├── taffy.ftd
│   ├── terminal.ftd
│   ├── tests/
│   │   ├── creating-a-tree.ftd
│   │   ├── fifthtry/
│   │   │   └── ft.ftd
│   │   ├── hello-world-variable.ftd
│   │   ├── hello-world.ftd
│   │   ├── inner_container.ftd
│   │   └── reference.ftd
│   ├── theme/
│   │   ├── fastn-theme-1.dark.tmTheme
│   │   ├── fastn-theme-1.light.tmTheme
│   │   ├── fastn-theme.dark.tmTheme
│   │   └── fastn-theme.light.tmTheme
│   ├── theme_css/
│   │   ├── coldark-theme.dark.css
│   │   ├── coldark-theme.light.css
│   │   ├── coy-theme.css
│   │   ├── dracula-theme.css
│   │   ├── duotone-theme.dark.css
│   │   ├── duotone-theme.earth.css
│   │   ├── duotone-theme.forest.css
│   │   ├── duotone-theme.light.css
│   │   ├── duotone-theme.sea.css
│   │   ├── duotone-theme.space.css
│   │   ├── fastn-theme.dark.css
│   │   ├── fastn-theme.light.css
│   │   ├── fire.light.css
│   │   ├── gruvbox-theme.dark.css
│   │   ├── gruvbox-theme.light.css
│   │   ├── laserwave-theme.css
│   │   ├── material-theme.dark.css
│   │   ├── material-theme.light.css
│   │   ├── nightowl-theme.css
│   │   ├── one-theme.dark.css
│   │   ├── one-theme.light.css
│   │   ├── vs-theme.dark.css
│   │   ├── vs-theme.light.css
│   │   └── ztouch-theme.css
│   ├── ts/
│   │   ├── index.ts
│   │   ├── post_init.ts
│   │   ├── types/
│   │   │   ├── function.d.ts
│   │   │   └── index.d.ts
│   │   └── utils.ts
│   └── tsconfig.json
├── ftd-ast/
│   ├── Cargo.toml
│   ├── src/
│   │   ├── ast.rs
│   │   ├── component.rs
│   │   ├── constants.rs
│   │   ├── function.rs
│   │   ├── import.rs
│   │   ├── kind.rs
│   │   ├── lib.rs
│   │   ├── or_type.rs
│   │   ├── record.rs
│   │   ├── test.rs
│   │   ├── utils.rs
│   │   ├── variable.rs
│   │   └── web_component.rs
│   └── t/
│       └── ast/
│           ├── 1-import.ftd
│           ├── 1-import.json
│           ├── 10-variable-invocation.ftd
│           ├── 10-variable-invocation.json
│           ├── 11-component-definition.ftd
│           ├── 11-component-definition.json
│           ├── 12-component-definition.ftd
│           ├── 12-component-definition.json
│           ├── 13-component-invocation.ftd
│           ├── 13-component-invocation.json
│           ├── 14-function.ftd
│           ├── 14-function.json
│           ├── 15-or-type.ftd
│           ├── 15-or-type.json
│           ├── 16-ui-list.ftd
│           ├── 16-ui-list.json
│           ├── 17-web-component.ftd
│           ├── 17-web-component.json
│           ├── 18-re-export.ftd
│           ├── 18-re-export.json
│           ├── 19-shorthand-list.ftd
│           ├── 19-shorthand-list.json
│           ├── 2-import.ftd
│           ├── 2-import.json
│           ├── 20-list-processor.ftd
│           ├── 20-list-processor.json
│           ├── 3-record.ftd
│           ├── 3-record.json
│           ├── 4-record.ftd
│           ├── 4-record.json
│           ├── 5-variable-definition.ftd
│           ├── 5-variable-definition.json
│           ├── 6-variable-definition.ftd
│           ├── 6-variable-definition.json
│           ├── 7-variable-definition.ftd
│           ├── 7-variable-definition.json
│           ├── 8-variable-invocation.ftd
│           ├── 8-variable-invocation.json
│           ├── 9-variable-invocation.ftd
│           └── 9-variable-invocation.json
├── ftd-p1/
│   ├── Cargo.toml
│   ├── src/
│   │   ├── header.rs
│   │   ├── lib.rs
│   │   ├── parser.rs
│   │   ├── section.rs
│   │   ├── test.rs
│   │   └── utils.rs
│   └── t/
│       └── p1/
│           ├── 01.01.ftd
│           ├── 01.ftd
│           ├── 01.json
│           ├── 02.ftd
│           ├── 02.json
│           ├── 03.ftd
│           ├── 03.json
│           ├── 04.ftd
│           ├── 04.json
│           ├── 05-comments.ftd
│           ├── 05-comments.json
│           ├── 06-complex-header.ftd
│           ├── 06-complex-header.json
│           ├── 07-more-complex.ftd
│           └── 07-more-complex.json
├── install.nsi
├── integration-tests/
│   ├── FASTN.ftd
│   ├── _tests/
│   │   ├── 01-hello-world-using-sql-processor.test.ftd
│   │   ├── 02-hello-world-using-endpoint.test.ftd
│   │   ├── 03-hello-world-using-fixture.test.ftd
│   │   ├── 04-multi-endpoint-test.test.ftd
│   │   ├── 05-wasm-routes.test.ftd
│   │   ├── 11-fastn-redirect.test.ftd
│   │   ├── 14-http-headers.test.ftd
│   │   └── fixtures/
│   │       └── hello-world-using-endpoint.test.ftd
│   ├── dummy-json-auth.ftd
│   ├── hello-world-sql.ftd
│   ├── hello.ftd
│   ├── redirect-to-hello.ftd
│   └── wasm/
│       ├── Cargo.toml
│       ├── flake.nix
│       ├── rust-toolchain.toml
│       └── src/
│           └── lib.rs
├── iroh-signing-abstraction-proposal.md
├── neovim-ftd.lua
├── rust-toolchain.toml
├── t/
│   ├── .fastn/
│   │   └── config.json
│   ├── FASTN.ftd
│   └── index.ftd
├── v0.5/
│   ├── .claude/
│   │   └── notify.sh
│   ├── ARCHITECTURE.md
│   ├── CLAUDE.md
│   ├── Cargo.toml
│   ├── DESIGN.md
│   ├── FASTN.ftd
│   ├── FASTN_LANGUAGE_SPEC.md
│   ├── FASTN_SPEC_VIEWER_SIMPLIFIED.md
│   ├── KEYRING_NOTES.md
│   ├── MANUAL_TESTING_README.md
│   ├── MVP-IMPLEMENTATION-PLAN.md
│   ├── MVP.md
│   ├── NEXT_STEPS.md
│   ├── README.md
│   ├── THUNDERBIRD_SETUP.md
│   ├── agent-tutorial.md
│   ├── ascii-rendering-design.md
│   ├── clippy.toml
│   ├── fastn/
│   │   ├── .fastn/
│   │   │   └── packages/
│   │   │       └── foo.com/
│   │   │           └── ds/
│   │   │               └── FASTN.ftd
│   │   ├── Cargo.toml
│   │   ├── FASTN.ftd
│   │   ├── amitu-notes.md
│   │   ├── index.ftd
│   │   ├── index.html
│   │   └── src/
│   │       ├── commands/
│   │       │   ├── build.rs
│   │       │   ├── mod.rs
│   │       │   ├── render.rs
│   │       │   └── serve.rs
│   │       ├── definition_provider.rs
│   │       ├── lib.rs
│   │       ├── main.rs
│   │       └── section_provider.rs
│   ├── fastn-account/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   └── src/
│   │       ├── account/
│   │       │   ├── create.rs
│   │       │   └── load.rs
│   │       ├── account.rs
│   │       ├── account_manager.rs
│   │       ├── alias.rs
│   │       ├── auth.rs
│   │       ├── automerge.rs
│   │       ├── errors.rs
│   │       ├── http_routes.rs
│   │       ├── lib.rs
│   │       ├── p2p.rs
│   │       └── template_context.rs
│   ├── fastn-ansi-renderer/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── ansi_canvas.rs
│   │   │   ├── canvas.rs
│   │   │   ├── components/
│   │   │   │   ├── mod.rs
│   │   │   │   └── text.rs
│   │   │   ├── css_mapper.rs
│   │   │   ├── document_renderer.rs
│   │   │   ├── ftd_types.rs
│   │   │   ├── layout.rs
│   │   │   ├── lib.rs
│   │   │   ├── renderer.rs
│   │   │   └── taffy_integration.rs
│   │   └── tests/
│   │       ├── basic_rendering.rs
│   │       ├── end_to_end_pipeline.rs
│   │       └── taffy_integration.rs
│   ├── fastn-automerge/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── Cargo.toml
│   │   ├── ERROR_HANDLING_PLAN.md
│   │   ├── README.md
│   │   ├── TUTORIAL.md
│   │   ├── amitu-notes.md
│   │   ├── src/
│   │   │   ├── cli/
│   │   │   │   ├── args.rs
│   │   │   │   ├── commands.rs
│   │   │   │   ├── mod.rs
│   │   │   │   └── utils.rs
│   │   │   ├── db.rs
│   │   │   ├── error.rs.backup
│   │   │   ├── lib.rs
│   │   │   ├── main.rs
│   │   │   ├── migration.rs
│   │   │   ├── tests.rs
│   │   │   └── utils.rs
│   │   └── tests/
│   │       └── cli_tests.rs
│   ├── fastn-automerge-derive/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── lib.rs
│   ├── fastn-cli-test-utils/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   └── src/
│   │       ├── examples.rs
│   │       ├── fastn_mail.rs
│   │       ├── fastn_rig.rs
│   │       ├── lib.rs
│   │       ├── simple.rs
│   │       └── test_env.rs
│   ├── fastn-compiler/
│   │   ├── Cargo.toml
│   │   ├── src/
│   │   │   ├── compiler.rs
│   │   │   ├── f-script/
│   │   │   │   └── README.md
│   │   │   ├── incremental-parsing.txt
│   │   │   ├── lib.rs
│   │   │   └── utils.rs
│   │   └── t/
│   │       ├── 000-tutorial.ftd
│   │       ├── 001-empty.ftd
│   │       ├── 002-few-comments.ftd
│   │       ├── 003-module-doc.ftd
│   │       └── 004-simple-section.ftd
│   ├── fastn-continuation/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── provider.rs
│   │       ├── result.rs
│   │       └── ur.rs
│   ├── fastn-entity-amitu-notes.md
│   ├── fastn-fbr/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── errors.rs
│   │       ├── lib.rs
│   │       ├── router.rs
│   │       └── template_context.rs
│   ├── fastn-id52/
│   │   ├── CHANGELOG.md
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── amitu-notes.md
│   │   └── src/
│   │       ├── automerge.rs
│   │       ├── dns.rs
│   │       ├── errors.rs
│   │       ├── keyring.rs
│   │       ├── keys.rs
│   │       ├── lib.rs
│   │       └── main.rs
│   ├── fastn-mail/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── amitu-notes.md
│   │   └── src/
│   │       ├── automerge.rs
│   │       ├── cli.rs
│   │       ├── database.rs
│   │       ├── errors.rs
│   │       ├── imap/
│   │       │   ├── client.rs
│   │       │   ├── commands.rs
│   │       │   ├── fetch.rs
│   │       │   ├── list_folders.rs
│   │       │   ├── mod.rs
│   │       │   ├── search.rs
│   │       │   ├── select_folder.rs
│   │       │   ├── store_flags.rs
│   │       │   └── thread.rs
│   │       ├── lib.rs
│   │       ├── main.rs
│   │       ├── p2p_receive_email.rs
│   │       ├── store/
│   │       │   ├── create.rs
│   │       │   ├── create_bounce_message.rs
│   │       │   ├── get_emails_for_peer.rs
│   │       │   ├── get_pending_deliveries.rs
│   │       │   ├── mark_delivered_to_peer.rs
│   │       │   ├── mod.rs
│   │       │   └── smtp_receive/
│   │       │       ├── mod.rs
│   │       │       └── validate_email_for_smtp.rs
│   │       ├── types.rs
│   │       └── utils.rs
│   ├── fastn-net/
│   │   ├── CHANGELOG.md
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── dot_fastn/
│   │   │   │   ├── init_if_required.rs
│   │   │   │   ├── lock.rs
│   │   │   │   └── mod.rs
│   │   │   ├── errors.rs
│   │   │   ├── get_endpoint.rs
│   │   │   ├── get_stream.rs
│   │   │   ├── graceful.rs
│   │   │   ├── http.rs
│   │   │   ├── http_connection_manager.rs
│   │   │   ├── http_to_peer.rs
│   │   │   ├── lib.rs
│   │   │   ├── peer_to_http.rs
│   │   │   ├── ping.rs
│   │   │   ├── protocol.rs
│   │   │   ├── secret.rs
│   │   │   ├── tcp.rs
│   │   │   ├── utils.rs
│   │   │   └── utils_iroh.rs
│   │   └── tests/
│   │       └── test_protocol_generic.rs
│   ├── fastn-net-test/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── lib.rs
│   │   │   ├── receiver.rs
│   │   │   └── sender.rs
│   │   └── tests/
│   │       ├── debug_test_env.rs
│   │       └── end_to_end.rs
│   ├── fastn-p2p/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── client.rs
│   │   │   ├── coordination.rs
│   │   │   ├── globals.rs
│   │   │   ├── lib.rs
│   │   │   ├── macros.rs
│   │   │   └── server/
│   │   │       ├── handle.rs
│   │   │       ├── listener.rs
│   │   │       ├── management.rs
│   │   │       ├── mod.rs
│   │   │       └── request.rs
│   │   └── tests/
│   │       └── multi_protocol_server.rs
│   ├── fastn-p2p-macros/
│   │   ├── Cargo.toml
│   │   ├── examples/
│   │   │   ├── basic.rs
│   │   │   ├── configured.rs
│   │   │   ├── double_ctrl_c.rs
│   │   │   └── signal_test.rs
│   │   └── src/
│   │       └── lib.rs
│   ├── fastn-p2p-test/
│   │   ├── Cargo.toml
│   │   ├── src/
│   │   │   ├── lib.rs
│   │   │   ├── receiver.rs
│   │   │   └── sender.rs
│   │   └── tests/
│   │       ├── end_to_end.rs
│   │       ├── full_mesh.rs
│   │       ├── multi_message.rs
│   │       ├── multi_receiver.rs
│   │       ├── multi_sender.rs
│   │       └── stress_test.rs
│   ├── fastn-package/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── reader.rs
│   │       └── test.rs
│   ├── fastn-rig/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── automerge.rs
│   │   │   ├── bin/
│   │   │   │   └── test_utils.rs
│   │   │   ├── certs/
│   │   │   │   ├── errors.rs
│   │   │   │   ├── filesystem.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── self_signed.rs
│   │   │   │   └── storage.rs
│   │   │   ├── email_delivery_p2p.rs
│   │   │   ├── email_poller_p2p.rs
│   │   │   ├── errors.rs
│   │   │   ├── http_proxy.rs
│   │   │   ├── http_routes.rs
│   │   │   ├── http_server.rs
│   │   │   ├── imap/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── protocol.rs
│   │   │   │   ├── server.rs
│   │   │   │   └── session.rs
│   │   │   ├── lib.rs
│   │   │   ├── main.rs
│   │   │   ├── p2p_server.rs
│   │   │   ├── protocols.rs
│   │   │   ├── rig.rs
│   │   │   ├── run.rs
│   │   │   ├── smtp/
│   │   │   │   ├── mod.rs
│   │   │   │   └── parser.rs
│   │   │   ├── template_context.rs
│   │   │   └── test_utils.rs
│   │   └── tests/
│   │       ├── cli_tests.rs
│   │       ├── email_end_to_end_plaintext.rs
│   │       ├── email_end_to_end_plaintext.sh
│   │       └── email_end_to_end_starttls.rs
│   ├── fastn-router/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── http_proxy.rs
│   │       ├── http_types.rs
│   │       ├── lib.rs
│   │       ├── reader.rs
│   │       └── route.rs
│   ├── fastn-section/
│   │   ├── Cargo.toml
│   │   ├── GRAMMAR.md
│   │   ├── PARSING_TUTORIAL.md
│   │   ├── README.md
│   │   └── src/
│   │       ├── debug.rs
│   │       ├── error.rs
│   │       ├── lib.rs
│   │       ├── parser/
│   │       │   ├── body.rs
│   │       │   ├── condition.rs
│   │       │   ├── doc_comment.rs
│   │       │   ├── header_value.rs
│   │       │   ├── headers.rs
│   │       │   ├── identifier.rs
│   │       │   ├── identifier_reference.rs
│   │       │   ├── kind.rs
│   │       │   ├── kinded_name.rs
│   │       │   ├── kinded_reference.rs
│   │       │   ├── mod.rs
│   │       │   ├── section.rs
│   │       │   ├── section_init.rs
│   │       │   ├── tes.rs
│   │       │   ├── test.rs
│   │       │   └── visibility.rs
│   │       ├── scanner.rs
│   │       ├── utils.rs
│   │       ├── warning.rs
│   │       └── wiggin.rs
│   ├── fastn-spec-viewer/
│   │   ├── Cargo.toml
│   │   ├── DIFF_OUTPUT_DESIGN.md
│   │   ├── README.md
│   │   ├── SPEC_FORMAT_DESIGN.md
│   │   └── src/
│   │       ├── embedded_specs.rs
│   │       ├── lib.rs
│   │       ├── main.rs
│   │       └── spec_renderer.rs
│   ├── fastn-static/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       └── main.rs
│   ├── fastn-unresolved/
│   │   ├── ARCHITECTURE.md
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── TESTING.md
│   │   └── src/
│   │       ├── debug.rs
│   │       ├── lib.rs
│   │       ├── parser/
│   │       │   ├── component_invocation.rs
│   │       │   ├── function_definition.rs
│   │       │   ├── import.rs
│   │       │   └── mod.rs
│   │       ├── resolver/
│   │       │   ├── arguments.rs
│   │       │   ├── component_invocation.rs
│   │       │   ├── definition.rs
│   │       │   ├── mod.rs
│   │       │   └── symbol.rs
│   │       └── utils.rs
│   ├── fastn-update/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── lib.rs
│   ├── fastn-utils/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       └── section_provider.rs
│   ├── fastn-wasm/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── aws.rs
│   │       ├── crypto.rs
│   │       ├── ds.rs
│   │       ├── email.rs
│   │       ├── env.rs
│   │       ├── helpers.rs
│   │       ├── http/
│   │       │   ├── get_request.rs
│   │       │   ├── mod.rs
│   │       │   ├── send_request.rs
│   │       │   └── send_response.rs
│   │       ├── lib.rs
│   │       ├── macros.rs
│   │       ├── pg/
│   │       │   ├── batch_execute.rs
│   │       │   ├── connect.rs
│   │       │   ├── create_pool.rs
│   │       │   ├── db_error.rs
│   │       │   ├── execute.rs
│   │       │   ├── mod.rs
│   │       │   └── query.rs
│   │       ├── process_http_request.rs
│   │       ├── register.rs
│   │       ├── sqlite/
│   │       │   ├── batch_execute.rs
│   │       │   ├── connect.rs
│   │       │   ├── execute.rs
│   │       │   ├── mod.rs
│   │       │   └── query.rs
│   │       └── store.rs
│   ├── manual-testing/
│   │   ├── setup-fastn-email.sh
│   │   ├── test-apple-mail.sh
│   │   └── test-smtp-imap-cli.sh
│   ├── rfc-there-be-dragons.md
│   ├── specs/
│   │   ├── CLAUDE.md
│   │   ├── components/
│   │   │   ├── button.ftd
│   │   │   └── button.rendered
│   │   └── text/
│   │       ├── basic.ftd
│   │       ├── basic.rendered
│   │       ├── with-border.ftd
│   │       └── with-border.rendered
│   └── test.sh
└── vendor.yml

================================================
FILE CONTENTS
================================================

================================================
FILE: .all-contributorsrc
================================================
{
  "files": [
    "README.md"
  ],
  "imageSize": 100,
  "commit": false,
  "commitConvention": "angular",
  "contributors": [
    {
      "login": "Arpita-Jaiswal",
      "name": "Arpita Jaiswal",
      "avatar_url": "https://avatars.githubusercontent.com/u/26044181?v=4",
      "profile": "https://github.com/Arpita-Jaiswal",
      "contributions": [
        "code",
        "doc",
        "example",
        "eventOrganizing",
        "ideas",
        "maintenance",
        "mentoring",
        "review",
        "tool",
        "test",
        "tutorial",
        "video",
        "blog"
      ]
    },
    {
      "login": "amitu",
      "name": "Amit Upadhyay",
      "avatar_url": "https://avatars.githubusercontent.com/u/58662?v=4",
      "profile": "https://www.fifthtry.com",
      "contributions": [
        "code",
        "doc",
        "example",
        "eventOrganizing",
        "ideas",
        "maintenance",
        "mentoring",
        "review",
        "tool",
        "test",
        "tutorial",
        "video",
        "blog"
      ]
    },
    {
      "login": "Heulitig",
      "name": "Rithik Seth",
      "avatar_url": "https://avatars.githubusercontent.com/u/106665190?v=4",
      "profile": "https://github.com/Heulitig",
      "contributions": [
        "code",
        "doc",
        "test",
        "ideas",
        "review",
        "maintenance",
        "blog"
      ]
    },
    {
      "login": "gsalunke",
      "name": "Ganesh Salunke",
      "avatar_url": "https://avatars.githubusercontent.com/u/68585007?v=4",
      "profile": "https://github.com/gsalunke",
      "contributions": [
        "code",
        "doc",
        "test",
        "ideas",
        "mentoring",
        "review"
      ]
    },
    {
      "login": "priyanka9634",
      "name": "Priyanka",
      "avatar_url": "https://avatars.githubusercontent.com/u/102957031?v=4",
      "profile": "https://github.com/priyanka9634",
      "contributions": [
        "code",
        "doc"
      ]
    },
    {
      "login": "gargajit",
      "name": "Ajit Garg",
      "avatar_url": "https://avatars.githubusercontent.com/u/118595104?v=4",
      "profile": "https://github.com/gargajit",
      "contributions": [
        "code",
        "doc",
        "blog"
      ]
    },
    {
      "login": "AbrarNitk",
      "name": "Abrar Khan",
      "avatar_url": "https://avatars.githubusercontent.com/u/17473503?v=4",
      "profile": "https://github.com/AbrarNitk",
      "contributions": [
        "code",
        "doc",
        "review",
        "test"
      ]
    },
    {
      "login": "sharmashobhit",
      "name": "Shobhit Sharma",
      "avatar_url": "https://avatars.githubusercontent.com/u/1982566?v=4",
      "profile": "https://github.com/sharmashobhit",
      "contributions": [
        "code",
        "doc",
        "test"
      ]
    },
    {
      "login": "AviralVerma13",
      "name": "Aviral Verma",
      "avatar_url": "https://avatars.githubusercontent.com/u/106665143?v=4",
      "profile": "http://fifthtry.com",
      "contributions": [
        "code",
        "doc",
        "test",
        "ideas"
      ]
    }
  ],
  "contributorsPerLine": 7,
  "skipCi": true,
  "repoType": "github",
  "repoHost": "https://github.com",
  "projectName": "fastn",
  "projectOwner": "fastn-stack"
}


================================================
FILE: .dockerignore
================================================
# editor and OS junk
.idea
**/.DS_Store

ftd/t/js/**.manual.html
ftd/t/js/**.script.html

# nix symlink to the build output
result

.direnv
.envrc

# Rust stuff
target
**/*.rs.bk

# fastn test
fastn-core/tests/**/.build

fastn-core/tests/**/.packages/fifthtry.github.io/package-info/

/**/.packages
/**/.remote-state


docs
.env
.env.swp


================================================
FILE: .gitattributes
================================================
# We do not want to list generated html files in statistics that Github shows
# on our repo page.
# Refer: https://github.com/github/linguist/blob/master/docs/overrides.md

**.html linguist-generated
default-*.js linguist-generated
default-*.css linguist-generated
fastn-core/fbt-tests/** linguist-generated
manifest.json linguist-generated
fastn.com/.packages/** linguist-vendored
ftd/t/executor/*.json linguist-generated
ftd/t/interpreter/*.json linguist-generated
ftd/t/node/*.json linguist-generated

================================================
FILE: .github/Dockerfile
================================================
FROM ekidd/rust-musl-builder

# We need to add the source code to the image because `rust-musl-builder`
# assumes a UID of 1000
ADD --chown=rust:rust . ./

RUN sudo chown rust -R /opt/rust

RUN rustup target add x86_64-unknown-linux-musl

CMD RUSTFLAGS="-Clink-arg=-Wl,--allow-multiple-definition" cargo build --release --features=auth


================================================
FILE: .github/FUNDING.yml
================================================
open_collective: fastn


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug Report
about: Create a bug report.
labels: bug
---

Your issue may already be reported! Please search on the [`fastn` issue tracker](https://github.com/fastn-stack/fastn/issues) before creating one.

<!--- fastn Issue Tracker is only for bugs or defects, please 
      suggest feature requests and ideas on 
      https://github.com/orgs/fastn-stack/discussions/categories/ideas-rfcs -->

<!-- PLEASE DO NOT REPORT SECURITY ISSUE IN PUBLIC, mail it to
security@fifthtry.com -->

## What Are You Doing?

<!--- Please tell us what is triggering the problematic behaviour -->

## Expected Behaviour:

<!--- What were you hoping to happen -->

## Current Behavior

<!--- What happened insted? -->

## Possible Solution

<!--- Not obligatory, but suggest a fix/reason for the bug -->

## Context

<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->

## Severity

<!-- Please tell us how severe is this problem for you. Can you
not use fastn at all. Is this an annoyance, or blocker? Are you
losing data because of it? If suspect this is a SECURITY issue, 
please do not create public issue and mail to security@fifthtry.com
instead. -->

## Your Environment

<!--- Include as many relevant details about the environment you experienced the bug in -->

- `fastn` Version (I.e, output of `fastn -v`):
- Operating System:
- Web Browser:


================================================
FILE: .github/ISSUE_TEMPLATE/code_issue.md
================================================
---
name: Code Issue
about: You have found some issue with the code?
labels: code-issue
---

Your issue may already be reported! Please search on the [`fastn` issue tracker](https://github.com/fastn-stack/fastn/issues) before creating one.

<!--- fastn Issue Tracker is only for bugs or defects, please 
      suggest feature requests and ideas on 
      https://github.com/orgs/fastn-stack/discussions/categories/ideas-rfcs -->

<!-- This is only for code related to features already implemented, if you are proposing to extend
any existing feature, please go the ideas-rfcs discussion linked above -->

## What part of code do you find problematic?

<!--- Link to source file and line number here. You can also copypaste code snippet. -->

## Descript what is wrong with this code?

<!-- found a code fragment with missing test? A dependency is out of date? We are using Rust wrong?
Found a more effecient way to write any function? Recommending any refactor? -->



================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: fastn Discord
    url: https://discord.gg/fwhk5m3AMG
    about: fastn developer discussion and community chat
  - name: Feature Requests and Ideas
    url: https://github.com/orgs/fastn-stack/discussions/categories/ideas-rfcs
    about: Create a Discussion instead of issue for ideas and proposals


================================================
FILE: .github/RELEASE_TEMPLATE.md
================================================
[`fastn` - Full-stack Web Development Made Easy](https://fastn.com/home/)

Checkout fastn installation step: https://fastn.com/install/.

Note: `fastn_linux_musl_x86_64` is not built with `musl` libc, it is built with
`glibc` and is a static binary. The name is kept for consistency with older
releases.

GitHub Sha: GITHUB_SHA  
Date: DATE  



================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
  - package-ecosystem: "cargo" # See documentation for possible values
    directory: "/" # Location of package manifests
    schedule:
      interval: "weekly"


================================================
FILE: .github/dprint-ci.json
================================================
{
  "prettier": {
    "indentWidth": 4
  },
  "includes": ["fastn-js/js/**/*.js"],
  "plugins": [
    "https://plugins.dprint.dev/prettier-0.32.0.json@fa93f05ab38f00c6de138f7747372585c661f79dfb11d7f1209c069b56680820"
  ]
}


================================================
FILE: .github/lib/README.md
================================================
## libpq, libcrypto-3, libssl-3

These DLLs are essential for specific PostgreSQL-related dependencies on Windows.
They are included in the installer and will be extracted into the installation directory of fastn on Windows.

The DLLs are designed for PostgreSQL v16 but are also compatible with version 14. 
However, future compatibility may change, requiring these DLLs to be updated to their latest version.

Note: All these DLLs are x86_64 since the 32-bit versions are not supported by 64-bit systems and binaries (the fastn executable is a 64-bit binary).

Downloaded from:
- [libpq](https://www.dllme.com/dll/files/libpq) / SHA1: 349d82a57355ad6be58cfe983a6b67160892e8cd
- [libssl-3-x64](https://www.dllme.com/dll/files/libssl-3-x64) / SHA1: d57a7a562ffe6bf8c51478da8cd15f9364e97923
- [libcrypto-3-x64](https://www.dllme.com/dll/files/libcrypto-3-x64) / SHA1: 2e2cff1ab2b229cbc0f266bf51a2c08ce06f58e9

These DLLs are included in the install.nsi script in both the installer and uninstall sections.


================================================
FILE: .github/scripts/populate-table.py
================================================
import sqlite3
import os


def create_table():
    connection = sqlite3.connect(get_database_path(os.environ["FASTN_DB_URL"]))

    try:
        # Create a cursor object to execute SQL queries
        cursor = connection.cursor()
        # Execute a query to create the 'test' table if it doesn't exist
        cursor.execute(
            """
            CREATE TABLE IF NOT EXISTS test (
                id SERIAL PRIMARY KEY,
                data VARCHAR(255) NOT NULL
            );
            """
        )

        cursor.close()

        # Commit the changes
        connection.commit()

    finally:
        # Close the database connection
        connection.close()


def insert_data():
    connection = sqlite3.connect(get_database_path(os.environ["FASTN_DB_URL"]))

    try:
        # Create a cursor object to execute SQL queries
        cursor = connection.cursor()
        # Insert test data into the 'test' table
        cursor.execute("INSERT INTO test (data) VALUES ('Hello, World!');")

        # Commit the changes
        connection.commit()

    finally:
        # Close the database connection
        connection.close()


# Function to strip 'sqlite:///' prefix if present
def get_database_path(uri):
    prefix = 'sqlite:///'
    if uri.startswith(prefix):
        return uri[len(prefix):]
    return uri


if __name__ == "__main__":
    # Create the 'test' table
    create_table()

    # Insert test data into the 'test' table
    insert_data()


================================================
FILE: .github/scripts/run-integration-tests.sh
================================================
#!/bin/bash
export FASTN_ROOT=`pwd`

# Enable xtrace and pipefail
set -o xtrace
set -eou pipefail

echo "Installing python server dependencies"
pip install Flask psycopg2

echo "Waiting for postgres to be ready"
timeout=30
until pg_isready -h localhost -p 5432 -U testuser -d testdb || ((timeout-- <= 0)); do
  sleep 1
done

echo "Populating test data"
python "${FASTN_ROOT}/.github/scripts/populate-table.py"

echo "Starting test python server"
python "${FASTN_ROOT}/.github/scripts/test-server.py" &
# Waiting for the server to start
sleep 10

ls

echo "Running integration tests"
cd "${FASTN_ROOT}/integration-tests" || exit 1
fastn test --headless


================================================
FILE: .github/scripts/test-server.py
================================================
from flask import Flask, jsonify
import sqlite3
import os

app = Flask(__name__)


def fetch_data():
    # Connect to the PostgreSQL database
    connection = sqlite3.connect(get_database_path(os.environ["FASTN_DB_URL"]))

    try:
        # Create a cursor object to execute SQL queries
        cursor = connection.cursor()
        # Execute a query to fetch data from the 'test' table
        cursor.execute("SELECT * FROM test;")

        # Fetch first row from the result set
        row = cursor.fetchone()

        data = dict()
        if row is not None:
            data = {
                "id": row[0],
                "data": row[1],
            }

    finally:
        # Close the database connection
        connection.close()

    return data


@app.route('/get-data/', methods=['GET'])
def get_data():
    # Fetch data from the 'test' table
    data = fetch_data()

    # Return the data as JSON
    json_result = jsonify(data)
    print(json_result)
    return json_result


def get_database_path(uri):
    prefix = 'sqlite:///'
    if uri.startswith(prefix):
        return uri[len(prefix):]
    return uri


if __name__ == '__main__':
    # Run the Flask application on port 5000
    print("Starting python server")
    app.run(port=5000)


================================================
FILE: .github/workflows/create-release.yml
================================================
name: Create a new release

on:
  workflow_dispatch:
    inputs:
      releaseTag:
        description: 'Release Tag'
        required: true
      productionRelease:
        type: boolean
        description: Mark release as production ready
jobs:
  release-ubuntu:
    name: Build for Linux
    # using the oldest available ubuntu on github CI to provide maximum compatibility with glibc versions
    # update RELEASE_TEMPLATE with the glibc version
    # on ubuntu-22.04, glibc version is 2.35
    runs-on: ubuntu-latest
    env:
      CARGO_TERM_COLOR: always
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
            ftd/target
            fifthtry_content/target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: Install static glibc
        run: |
          sudo apt update && sudo apt install -y libc6-dev
      - name: print rustc version
        run: rustc --version
      - name: cargo build (linux)
        run: |
          RUSTFLAGS="-C target-feature=+crt-static" cargo build --target x86_64-unknown-linux-gnu --bin fastn --release
      - name: print fastn version
        run: ./target/x86_64-unknown-linux-gnu/release/fastn --version
      - name: print file info
        run: |
          file ./target/x86_64-unknown-linux-gnu/release/fastn
          ldd ./target/x86_64-unknown-linux-gnu/release/fastn
      - uses: actions/upload-artifact@v4
        with:
          name: linux_x86_64
          path: target/x86_64-unknown-linux-gnu/release/fastn
  build-windows:
    name: Build for Windows
    runs-on: windows-2022
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
            ftd/target
            fifthtry_content/target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: print rustc version
        run: rustc --version
      - name: cargo build (windows)
        run: cargo build --release
      - name: print fastn version
        run: target\release\fastn.exe --version
      - uses: actions/upload-artifact@v4
        with:
          name: windows_x64_latest
          path: target/release/fastn.exe
  release-windows:
    runs-on: ubuntu-latest
    needs: [ build-windows ]
    name: Make installer for windows build
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: windows_x64_latest
          path: result/bin/
      - name: check exe
        run: |
          ls -la result/bin/
      - name: Install NSIS & Plugins
        run: |
          sudo apt update && sudo apt install -y nsis nsis-pluginapi
          sudo chown -R $(whoami) /usr/share/nsis/Plugins/
          
          wget https://github.com/GsNSIS/EnVar/releases/download/v0.3.1/EnVar-Plugin.zip
          unzip EnVar-Plugin.zip -d EnVar-Plugin
          sudo mv EnVar-Plugin/Plugins/amd64-unicode/* /usr/share/nsis/Plugins/amd64-unicode/
          sudo mv EnVar-Plugin/Plugins/x86-ansi/* /usr/share/nsis/Plugins/x86-ansi/
          sudo mv EnVar-Plugin/Plugins/x86-unicode/* /usr/share/nsis/Plugins/x86-unicode/
      - name: Create Installer
        run: makensis -V3 -DCURRENT_WD=${{ github.workspace }} -DVERSION=${{ github.event.inputs.releaseTag }} install.nsi
      - uses: actions/upload-artifact@v4
        with:
          name: windows_x64_installer.exe
          path: windows_x64_installer.exe
  release-macos:
    name: Build for MacOS
    # don't use later versions, as else our binary will be built for arm64,
    # and will not work on older macs that are based on x86_64 (intel)
    # https://github.com/fastn-stack/fastn/issues/2099
    runs-on: macos-13
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
            ftd/target
            fifthtry_content/target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: print rustc version
        run: rustc --version
      - name: Run Build
        id: build-macos
        continue-on-error: false
        run: cargo build --release
      - name: print fastn version
        run: ./target/release/fastn --version
      - name: print file info
        run: |
          file ./target/release/fastn
          otool -L ./target/release/fastn
      - uses: actions/upload-artifact@v4
        with:
          name: macos_x64_latest
          path: |
            target/release/fastn
  create-release:
    name: Create github tag and release
    runs-on: ubuntu-latest
    needs: [ release-ubuntu, release-macos, release-windows ]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: macos_x64_latest
          path: ~/download/macos
      - uses: actions/download-artifact@v4
        with:
          name: linux_x86_64
          path: ~/download/linux
      - uses: actions/download-artifact@v4
        with:
          name: windows_x64_latest
          path: ~/download/windows
      - uses: actions/download-artifact@v4
        with:
          name: windows_x64_installer.exe
          path: ~/download/windows
      - name: Rename assets
        run: |
          mv ~/download/windows/fastn.exe ~/download/windows/fastn_windows_x86_64.exe
          mv ~/download/windows/windows_x64_installer.exe ~/download/windows/fastn_setup.exe
          mv ~/download/macos/fastn ~/download/macos/fastn_macos_x86_64
          mv ~/download/linux/fastn ~/download/linux/fastn_linux_musl_x86_64
      - name: Update .github/RELEASE_TEMPLATE.md
        run: |
          sed -i "s/GITHUB_SHA/${GITHUB_SHA}/g" .github/RELEASE_TEMPLATE.md
          sed -i "s/DATE/$(date)/g" .github/RELEASE_TEMPLATE.md
      - name: setup release template
        run: |
          awk -v version="### fastn: ${{ github.event.inputs.releaseTag }}" '
            $0 == version { found=1; print; next }
            found && /^## [0-9]{2}/ { exit }
            found && /^### fastn / { exit }
            found { print }
          ' Changelog.md | sed "1s/.*/# What's Changed/" >> .github/RELEASE_TEMPLATE.md
      - uses: ncipollo/release-action@v1
        with:
          artifacts: "~/download/windows/fastn_windows_x86_64.exe,~/download/windows/fastn_setup.exe,~/download/macos/fastn_macos_x86_64,~/download/linux/fastn_linux_musl_x86_64"
          # we generate release notes manually in the previous step
          generateReleaseNotes: false
          token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ github.event.inputs.releaseTag }}
          prerelease: ${{ github.event.inputs.productionRelease && github.event.inputs.productionRelease == 'false' }}
          bodyFile: .github/RELEASE_TEMPLATE.md


================================================
FILE: .github/workflows/deploy-fastn-com.yml
================================================
name: Deploy fastn.com

on:
  workflow_dispatch:
  push:
    branches: [ main ]
    paths:
      - 'fastn.com/**'
      - '.github/workflows/deploy-fastn-com.yml'

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      # https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions
      FIFTHTRY_SITE_WRITE_TOKEN: ${{ secrets.FIFTHTRY_SITE_WRITE_TOKEN }}
    steps:
      - uses: actions/checkout@v4
      - run: source <(curl -fsSL https://fastn.com/install.sh)
      - run: |
          # TODO: remove below line when https://github.com/FifthTry/dotcom/issues/361 is done
          rm .gitignore # so that `fastn upload` uploads .packages/ too
          cd fastn.com
          echo "Using $(fastn --version) to upload fastn.com to FifthTry"
          # Requires FIFTHTRY_SITE_WRITE_TOKEN to be set
          fastn upload fastn >> $GITHUB_STEP_SUMMARY


================================================
FILE: .github/workflows/email-critical-tests.yml
================================================
name: 🎯 Critical Email System Tests

on:
  push:
    branches: [ main ]
    paths:
      - 'v0.5/**'
  pull_request:
    branches: [ main ]
    paths:
      - 'v0.5/**'
  workflow_dispatch:

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  critical-email-tests:
    name: 🎯 Critical Email Pipeline Tests
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install Rust toolchain
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable

    - name: Cache cargo registry
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry/index/
          ~/.cargo/registry/cache/
          ~/.cargo/git/db/
        key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
        restore-keys: |
          ${{ runner.os }}-cargo-registry-

    - name: Cache cargo build
      uses: actions/cache@v4
      with:
        path: v0.5/target/
        key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
        restore-keys: |
          ${{ runner.os }}-cargo-build-

    - name: Install system dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y build-essential pkg-config libssl-dev jq

    - name: 🔨 Pre-compile Email System Binaries  
      working-directory: v0.5
      run: |
        echo "🔨 Pre-compiling email system binaries (direct approach)..."
        echo "Building required binaries to isolate compilation time from test execution"
        
        echo "📦 Building fastn-rig..."
        time cargo build --bin fastn-rig
        
        echo "📦 Building fastn-mail with net features..."
        time cargo build --bin fastn-mail --features net
        
        echo "📦 Building test_utils..."
        time cargo build --bin test_utils
        
        echo "✅ All email system binaries pre-compiled (direct build approach)"
        echo "⏱️ Compilation time isolated from test execution"

    - name: 🎯 Run Critical Email System Tests
      working-directory: v0.5
      env:
        SKIP_KEYRING: true
      run: |
        echo "🎯 Running ALL critical tests in fastn email system (PRE-COMPILED)"
        echo "These tests validate the complete email pipeline:"
        echo "  - Plain text SMTP → fastn-p2p → INBOX delivery"  
        echo "  - STARTTLS SMTP → fastn-p2p → INBOX delivery"
        echo "  - Single-rig mode: 2 accounts in 1 rig (intra-rig P2P)"
        echo "  - Multi-rig mode: 1 account per rig (inter-rig P2P)"
        echo "  - IMAP dual verification: protocol vs filesystem"
        echo "  - Certificate generation and TLS infrastructure"
        echo "  - End-to-end email system integration"
        echo
        echo "⏱️  Timing: This step measures PURE email system performance"
        echo "⏱️  Compilation time excluded from this measurement"
        echo
        
        # Make test script executable
        chmod +x test.sh
        
        # Run ALL tests: single+multi rig modes × rust+bash tests
        echo "🧪 Starting comprehensive email tests at: $(date)"
        start_time=$(date +%s)
        
        timeout 900 ./test.sh --all || {
          echo "❌ Tests failed or timed out after 15 minutes"
          exit 1
        }
        
        end_time=$(date +%s)
        duration=$((end_time - start_time))
        echo "⏱️  Email tests completed in: ${duration} seconds"

    - name: 📊 Test Results Summary
      if: always()
      run: |
        if [ $? -eq 0 ]; then
          echo "🎉 ✅ CRITICAL EMAIL TESTS PASSED"
          echo "✅ fastn email system is fully operational" 
          echo "🚀 Ready for production email deployment"
        else
          echo "❌ 🚨 CRITICAL EMAIL TESTS FAILED"
          echo "❌ fastn email system has critical issues"
          echo "🔧 Investigate email pipeline problems before proceeding"
        fi

  # Optional: Run individual tests for better failure isolation  
  plain-text-test:
    name: 📧 Plain Text Email Test
    runs-on: ubuntu-latest
    if: github.event_name == 'workflow_dispatch'
    
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install Rust toolchain
      uses: dtolnay/rust-toolchain@stable

    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry/
          v0.5/target/
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

    - name: Install system dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y build-essential pkg-config libssl-dev jq

    - name: 📧 Run Plain Text Email Test
      working-directory: v0.5
      run: |
        chmod +x test.sh
        ./test.sh  # Default bash test

  starttls-test:
    name: 🔐 STARTTLS Email Test
    runs-on: ubuntu-latest  
    if: github.event_name == 'workflow_dispatch'
    
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install Rust toolchain
      uses: dtolnay/rust-toolchain@stable

    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry/
          v0.5/target/
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

    - name: Install system dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y build-essential pkg-config libssl-dev

    - name: 🔐 Run STARTTLS Email Test
      working-directory: v0.5
      run: |
        chmod +x test.sh
        ./test.sh --rust

================================================
FILE: .github/workflows/optimize-images.yml
================================================
# https://github.com/calibreapp/image-actions
name: Optimize Images
on:
  push:
    branches:
      - main
    paths:
      - 'fastn.com/**.jpg'
      - 'fastn.com/**.jpeg'
      - 'fastn.com/**.png'
      - 'fastn.com/**.webp'
jobs:
  build:
    name: calibreapp/image-actions
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
      - name: Compress Images
        id: calibre
        uses: calibreapp/image-actions@main
        with:
          githubToken: ${{ secrets.GITHUB_TOKEN }}
          compressOnly: true # don't make a commit!
          ignorePaths: 'fastn-core/**'
      - name: Create New Pull Request If Needed
        if: steps.calibre.outputs.markdown != ''
        uses: peter-evans/create-pull-request@v7
        with:
          title: Compressed Images
          branch-suffix: timestamp
          commit-message: Compressed Images
          body: ${{ steps.calibre.outputs.markdown }}


================================================
FILE: .github/workflows/tests-and-formatting.yml
================================================
name: Tests and Formatting

on:
  workflow_dispatch:
  push:
    branches: [ main ]
    paths:
      # Order matters!
      # See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore
      - '**.rs'
      - '**.ftd' # ftd/html/js/css are fbt-tests items mostly
      - '**.p1'
      - '**.html'
      - '**.js'
      - '**.css'
      - 'Cargo.*'
      - '**/Cargo.toml'
      - '!t/**' # We use this for playground
      - '!fastn.com/**'
      - '!v0.5/**' # TODO: remove this when we're ready to release v0.5
      - '!.github/**'
      - '.github/workflows/tests-and-formatting.yml'
  pull_request:
    branches: [ main ]
    paths:
      # Order matters!
      # See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore
      - '**.rs'
      - '**.ftd' # ftd/html/js/css are fbt-tests items mostly
      - '**.p1'
      - '**.html'
      - '**.js'
      - '**.css'
      - 'Cargo.*'
      - '**/Cargo.toml'
      - '!t/**' # We use this for playground
      - '!fastn.com/**'
      - '!v0.5/**' # TODO: remove this when we're ready to release v0.5
      - '!.github/**'
      - '.github/workflows/tests-and-formatting.yml'
jobs:
  tests-and-formatting:
    name: Rust/JS Checks/Formatting
    runs-on: ubuntu-latest
    env:
      FASTN_DB_URL: sqlite:///test.sqlite
      DEBUG: true
      FASTN_ENABLE_AUTH: true
      FASTN_ENABLE_EMAIL: false
    steps:
      - name: Check out
        uses: actions/checkout@v4
      #      - name: Set up cargo cache
      #        uses: actions/cache@v3 # there is also https://github.com/Swatinem/rust-cache
      #        continue-on-error: false
      #        with:
      #          path: |
      #            ~/.cargo/registry/index/
      #            ~/.cargo/registry/cache/
      #            ~/.cargo/git/db/
      #            target/
      #          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      #          restore-keys: ${{ runner.os }}-cargo-
      - name: Run cargo fmt
        id: fmt
        run: cargo fmt --all -- --check
        continue-on-error: true
      - name: Run cargo clippy
        id: clippy
        continue-on-error: true
        run: cargo clippy --all -- -D warnings
      #      - name: Install cargo check tools
      #        run: |
      #          cargo install --locked cargo-deny || true
      #          cargo install --locked cargo-outdated || true
      #          cargo install --locked cargo-udeps || true
      #          cargo install --locked cargo-audit || true
      #          cargo install --locked cargo-pants || true
      #      - name: Check
      #        run: |
      #          cargo deny check
      #          cargo outdated --exit-code 1
      #          cargo udeps
      #          rm -rf ~/.cargo/advisory-db
      #          cargo audit
      #          cargo pants
      - name: Run cargo test
        # cd fastn-core && fbt -f
        # cargo test html_test_all -- --nocapture fix=true
        # cargo test fastn_js_test_all -- --nocapture fix=true
        # cargo test p1_test_all -- --nocapture fix=true
        # cargo test interpreter_test_all -- --nocapture fix=true
        # cargo test executor_test_all -- --nocapture fix=true
        id: test
        continue-on-error: true
        run: cargo test
      #      - name: Run integration tests
      #        id: integration-test
      #        continue-on-error: true
      #        run: |
      #          bash .github/scripts/run-integration-tests.sh
      - name: Check if JS code is properly formatted
        # curl -fsSL https://dprint.dev/install.sh | sh
        # /Users/amitu/.dprint/bin/dprint fmt --config .github/dprint-ci.json
        id: js-fmt
        uses: dprint/check@v2.2
        with:
          config-path: .github/dprint-ci.json
      - name: Check if code is properly formatted
        if: steps.fmt.outcome != 'success'
        run: exit 1
      - name: Check if clippy is happy
        if: steps.clippy.outcome != 'success'
        run: exit 1
      - name: Check if js-fmt is happy
        if: steps.js-fmt.outcome != 'success'
        run: exit 1
      - name: Check if test succeeded
        if: steps.test.outcome != 'success'
        run: exit 1
#      - name: Check if integration test passed
#        if: steps.integration-test.outcome != 'success'
#        run: exit 1


================================================
FILE: .gitignore
================================================
# editor and OS junk
.idea
**/.DS_Store

ftd/t/js/**.manual.html
ftd/t/js/**.script.html
integration-tests/_tests/**.script.html
integration-tests/wasm/target
integration-tests/test.wasm

# nix symlink to the build output
result

fastn.com/.packages

.direnv
.envrc

# Rust stuff
target
**/*.rs.bk

# fastn test
fastn-core/tests/**/.build

fastn-core/tests/**/.packages/fifthtry.github.io/package-info/

/**/.packages
/**/.remote-state


docs
.env
.env.swp

# Test directories
v0.5/test-fastn-home*


================================================
FILE: .pre-commit-config.yaml
================================================
repos:
-   repo: https://github.com/ambv/black
    rev: 21.7b0
    hooks:
    - id: black
      language_version: python

-   repo: local
    hooks:
    -   id: rustfmt
        name: Rust format
        entry: cargo
        language: system
        args:
        - fmt
        - --
        files: \.rs$
    -   id: clippy
        name: Clippy
        entry: cargo-clippy 
        language: system
        args:
        - --all
        - --tests
        files: \.rss$
        pass_filenames: false


================================================
FILE: .rusty-hook.toml
================================================
[hooks]
pre-commit = "cargo test"
pre-push = "cargo clippy && cargo fmt -- --check"

[logging]
verbose = true


================================================
FILE: Cargo.toml
================================================
[workspace]
members = [
    "clift",
    "fastn",
    "fastn-builtins",
    "fastn-context",
    "fastn-context-macros",
    "fastn-core",
    "fastn-daemon",
    "fastn-ds",
    "fastn-expr",
    "fastn-issues",
    "fastn-js",
    "fastn-lang",
    "fastn-package",
    "fastn-runtime",
    "fastn-remote",
    "fastn-update",
    "fastn-utils",
    "fastn-xtask",
    "fbt",
    "fbt_lib",
    "ftd",
    "ftd-ast",
    "ftd-p1",
]
exclude = ["fastn-wasm-runtime", "fastn-wasm", "integration-tests/wasm", "v0.5", "fastn-resolved"]
resolver = "2"

[workspace.package]
authors = [
    "Amit Upadhyay <upadhyay@gmail.com>",
    "Arpita Jaiswal <arpita@fifthtry.com>",
    "Sourabh Garg <sourabh@fifthtry.com>",
    "Shobhit Sharma <shobhit@fifthtry.com>",
    "Abrar Khan <abrar@fifthtry.com>",
    "Rithik Seth <rithik@fifthtry.com>",
    "Ganesh Salunke <ganesh@fifthtry.com>",
    "Siddhant Kumar <siddhant@fifthtry.com>",
]
edition = "2024"
description = "fastn: Full-stack Web Development Made Easy"
license = "UPL-1.0"
repository = "https://github.com/fastn-stack/fastn"
homepage = "https://fastn.com"
rust-version = "1.89"

[profile.release]
# Enabling this descreased our binary size from 30M to 27M on linux (as of 12th Jun 2023).
# The build time went up (no objective data). Disabling it for now. It made a huge difference
# in fastn-wasm-runtime wasm size (without lto: 2.1M with lto: 518K).

strip = true
# lto = true
# opt-level = "z"
# panic = "abort"

[workspace.dependencies]
# Please do not specify a dependency more precisely than needed. If version "1" works, do
# not specify "1.1.42". This reduces the number of total dependencies. For example, if you
# specify 1.1.42 and someone else who only needed "1" also specified 1.1.37, we end up having
# the same dependency getting compiled twice.
#
# In the future, we may discover that our code does not indeed work with "1", say it ony works
# for 1.1 onwards, or 1.1.25 onwards, in which case use >= 1.1.25 etc. Saying our code
# only works for 1.1.42 and not 1.1.41 nor 1.1.43 is really weird, and most likely wrong.
#
# If you are not using the latest version intentionally, please do not list it in this section
# and create its own [dependencies.<name>] section. Also, document it with why are you not
# using the latest dependency, and what is the plan to move to the latest version.

accept-language = "3"
actix-http = "3"
actix-web = "4"
antidote = "1"
async-recursion = "1"
async-trait = "0.1"
bytes = "1"
camino = "1"
chrono = { version = "0.4", features = ["serde"] }
clap = "4"
clift.path = "clift"
colored = "3"
css-color-parser = "0.1"
deadpool = "0.10"
deadpool-postgres = "0.12"
diffy = "0.4"
dirs = "6"
dotenvy = "0.15"
enum-iterator = "0.6"
enum-iterator-derive = "0.6"
env_logger = "0.11"
fastn-builtins.path = "fastn-builtins"
fastn-context.path = "fastn-context"
fastn-core.path = "fastn-core"
fastn-ds.path = "fastn-ds"
fastn-daemon.path = "fastn-daemon"
fastn-expr.path = "fastn-expr"
fastn-issues.path = "fastn-issues"
fastn-js.path = "fastn-js"
fastn-package.path = "fastn-package"
fastn-resolved = { path = "fastn-resolved" }
fastn-runtime = { path = "fastn-runtime", features = ["owned-tdoc"] }
fastn-remote.path = "fastn-remote"
fastn-update.path = "fastn-update"
fastn-utils.path = "fastn-utils"
fastn-id52.path = "v0.5/fastn-id52"
fastn-wasm.path = "v0.5/fastn-wasm"
fastn-p2p = { path = "v0.5/fastn-p2p" }
fbt-lib.path = "fbt_lib"
format_num = "0.1"
ft-sys-shared = { version = "0.2.1", features = ["rusqlite", "host-only"] }
ftd-ast.path = "ftd-ast"
ftd-p1.path = "ftd-p1"
ftd.path = "ftd"
futures = "0.3"
futures-core = "0.3"
futures-util = { version = "0.3", default-features = false, features = ["std"] }
http = "1"
ignore = "0.4"
include_dir = "0.7"
indexmap = { version = "2", features = ["serde"] }
indoc = "2"
itertools = "0.14"
mime_guess = "2"
once_cell = "1"
prettify-js = "0.1.0"
pretty = "0.12"
pretty_assertions = "1"
quick-js = "0.4"
rand = "0.9"
realm-lang = "0.1"
regex = "1"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
rquickjs = { version = "0.9", features = ["macro"] }
scc = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sha2 = "0.10"
slug = "0.1"
snafu = "0.8"
thiserror = "2"
tokio = { version = "1", features = ["full"] }
tokio-postgres = { version = "0.7", features = ["with-serde_json-1", "with-uuid-1"] }
tokio-util = "0.7"
tracing = "0.1"
url = "2"
walkdir = "2"
wasmtime = "36"
zip = "4"


[workspace.dependencies.fastn-observer]
git = "https://github.com/fastn-stack/fastn-observer"
rev = "5f64c7b"


[workspace.dependencies.rusqlite]
version = "0.31"
features = [
    # We are using the bundled version of rusqlite, so we do not need sqlitelib, headers as a
    # dependency. By default, if we do not bundle, our binary will link against system
    # provided sqlite, which would have been a good thing, if we used system sqlite, our
    # binary size would be smaller, compile time lesser, but unfortunately we can not assume
    # sqlite dynamic library is installed on everyone's machine. We can choose to give two
    # binaries, one with bundled, one without, but it is not worth the tradeoff right now.
    "bundled",
    "column_decltype",
]


[workspace.dependencies.hyper]
version = "1"
default-features = false
features = ["http1", "server"]


[workspace.dependencies.syntect]
# We use syntect for syntax highlighting feature in ftd.code.
version = "5"

# By default, syntect uses https://docs.rs/onig/. Rust has two popular regular expression
# crates, `regex` and `onig`. `onig` is a wrapper over a library implemented in C:
# https://github.com/kkos/oniguruma. https://docs.rs/regex/ is a pure Rust implementation.
#
# We are using `regex` ourselves. `comrak` also uses `regex`. So we disable their default
# feature (which brought in onig), and use `default-fancy`, which uses `fancy-regex`, which
# in turn uses `regex`.
default-features = false
features = [
    # TODO: This feature brings in a lot of feaures, we have to pare it down to exactly
    #       the features we need.
    "default-fancy"
]

[workspace.dependencies.comrak]
# We use comrak for markup processing.
version = "0.41"
# By default, comrak ships with support for syntax highlighting using syntext for "fenced
# code blocks". We have disabled that by not using default features. We did that because
# we already have a way to show code in ftd, ftd.code. Further, comark requires syntect 4.6,
# and we are using 5, which means we have two sytnax highlighting libraries.
#
# Further, in future we'll have to manipulate the markup at AST level, instead of using the
# to_string() interface. https://fpm.dev/journal/#markdown-styling. So in the meanwhile
# we are disabling their conflicting syntect implementation.
default-features = false


================================================
FILE: Changelog.md
================================================
# `fastn` Change Log

## 17 September 2025

### fastn: 0.4.113

- fix: Do not override query params of http processor's target url. PR #2209.

## 20 August 2025

### fastn: 0.4.112

- fix: Escape more chars while constructing a string for js output. See PR #2180.

### fastn: 0.4.111

- dce62c437 - Add support for simple function calls in `url` header of the `http` processor. See PR #2179.

## 29 July 2025

### fastn: 0.4.110

- d93c5b1da: Fix `for` loops counter when working across modules. See PR #2172 for more.

## 9 July 2025

### fastn: 0.4.109

- c17958678: Avoid infinite loop in certain conditions. See PR #2170 for more.

## 3 July 2025

### fastn: 0.4.108

- fix: Filter out `null` from url query params in the http processor.
- windows release: windows-2019 -> 2021 because 2019 is retired by Github.

## 30 June 2025

### fastn: 0.4.107

- bb676ea45 - `$ftd.set-current-language(lang: string)` function.
- 47c8e20a8 - Resolve requested language before auto processing imports.

## 19 June 2025

### fastn: 0.4.106

- 83cf66346 - Server render meta tags if request is from a bot.
- doc: `ftd.type`'s font-family attribute can take fallback fonts.

## 16 June 2025

### fastn: 0.4.105

- fix(http processor): Send unquoted string in url query param to preserve old
  behaviour.
- fix: Handle import of system packages from `inherited-` caller module
  correctly.
- fix: Only consider main package when resolving imports for `provided-via`.
- See: https://github.com/fastn-stack/fastn/pull/2151 for more details.

## 11 June 2025

### fastn: 0.4.104

- 348030b8a: Fix correctly reflect overriden components for system packages. See
  issue #2139.
- a42da86f6: Handle package local relative urls in http processor. See PR #2144.
- 7551fc8f4: Handle wasm modules in mountpoint of app dependencies when called
  through http processor. See PR #2144.

## 10 June 2025

### fastn: 0.4.103

- Fix: Send POST request body with a wasm+proxy:// url used in an http
  processor.
- 2757a1e68: Support for tuple style POST body params is in ftd.submit_form,
  this works similar to the ftd.http function.
- bcdf41325: Support form form level errors in ftd.submit_form.

## 25 May 2025

### fastn: 0.4.102

- 6e35b7911 - Build static fastn for x86_64-linux-gnu

## 09 May 2025

### fastn: 0.4.101

- Switch to UPL license.
- cfc0780b9: Fix: Consider `sitemap` items when resolving imports

## 28 March 2025

### fastn: 0.4.100

- Add `autofocus` attribute to `ftd.text-input` component.

# FTD Change Log (Old)

## 23 February 2023

- [Added web-component](https://github.com/ftd-lang/ftd/commit/f7c47c197f347bd2b48f0995b82aeaaf760ce44a)
- copy_to_clipboard -> ftd.copy_to_clipboard
- http -> ftd.http

## 2 February 2023

- [Added enabled property in ftd.checkbox and ftd.text-input](https://github.com/ftd-lang/ftd/commit/12425b68b56c2f475f3630ddb0484de70479aad0)

## 1 February 2023

<details>
<summary>Breaking Change: Renamed `fpm` To `fastn`</summary>
`fpm` cli is renamed to `fastn`. We renamed `FPM.ftd` to `FASTN.ftd` and 
`-- import: fpm` becomes `-- import: fastn`. We have also renamed github 
repository `fpm` to `fastn`.

- Fastn PR: https://github.com/ftd-lang/fastn/pull/755

</details>

<details>
<summary>Inbuilt <b>Clamp</b>: no longer supported
<a href="https://github.com/ftd-lang/ftd/blob/main/Cheatsheet.
md#clamp">Clamp example</a>
</summary>

- Regular Clamp

```ftd
-- integer $num: 0

-- ftd.integer: $num
$on-click$: $clamp($a = $num, by = 1, clamp = 6)

-- void clamp(a,by,clamp):
integer $a:
integer by:
integer clamp:


a = (a + by) % clamp
```

- Clamp with min and max

```ftd
-- integer $num: 1

-- ftd.integer: $num
$on-click$: $clamp($a = $num, by = 1, min = 1, max = 6)

-- void clamp(a,by,min,max):
integer $a:
integer by: 1
integer min: 0
integer max: 5


a = (((a - min) + by) % (max - min)) + min
```

</details>

## 31 January 2023

<details>

<summary><b>Breaking change</b> <a href="https://github.com/ftd-lang/ftd/pull/566/commits/e1722eacf386d3c515000c79a86e7ffb91f2df6c">Inherited types changed</a></summary>

Breaking changes

- `$inherited.types.copy-relaxed` -> `$inherited.types.copy-regular`
- `$inherited.types.copy-tight` -> `$inherited.types.copy-small`
- `$inherited.types.label-big` -> `$inherited.types.label-large`

Headings:

- `$inherited.types.heading-tiny` is added
- rest have weight, line-height, weight updates

Copy:

- added `$inherited.types.copy-regular` and `$inherited.types.copy-small`
- rest have size and `$inherited.types.line-height` changes

Specialized Text:

- `$inherited.types.source-code` is added
- rest have size and line-height changes

Labels:

- `$inherited.types.label-big` is changed to label-large
- `$inherited.types.label-small` is updated with new size and line-height values

Button:

- All button types which are added are new
- added `$inherited.types.button-large`, `$inherited.types.button-medium`,
  `$inherited.types.button-small`, link types

</details>

## 30 January 2023

- [Added ftd.checkbox](https://github.com/ftd-lang/ftd/pull/564/commits/483060b31dcce626599fc0bca8d7e6261d0c37a8)

## 27 January 2023

<details>

<summary><b>Breaking change</b>: <a href="https://github.com/ftd-lang/ftd/pull/557/commits/37569f9df70ce60f161a1260e6fa09827f8f0875">Merged spacing with spacing-mode</a></summary>

- use `spacing.fixed.px: 20` instead of `spacing.px: 20`
- use `spacing: space-around` instead of `spacing-mode: space-around` (same for
  `space-between` and `space-evenly`)

</details>

## 25 January 2023

- [Added sticky css](https://github.com/ftd-lang/ftd/pull/553/commits/a3b43d09b7b968d8242559e96dbff7c356104880)
- [Added
  `id` attr](https://github.com/ftd-lang/ftd/pull/554/commits/7321ba5253d565683e35e078606567f302633eaf)
- [Added slugify `id` for
  `region`s](https://github.com/ftd-lang/ftd/pull/556/commits/a419d0155bd4299c4efab91ad55557f92bc21f0f)
- [Added
  `LOOP.COUNTER`](https://github.com/ftd-lang/ftd/commit/9d31c722814d5cd9ded21be9de2b310b1d4cb0b8)

## 24 January 2023

- [Added border-style](https://github.com/ftd-lang/ftd/pull/549/commits/6f08e0ce2b9eeb5aa8da5bb418b60fcc0b221d05)
- [Added ftd.enable-dark-mode, ftd.enable-light-mode, ftd.enable-system-mode](https://github.com/ftd-lang/ftd/commit/723b1f50e3e1564c112c926ec024198fa843e42f)

## 23 January 2023

- [Added line-clamp](https://github.com/ftd-lang/ftd/pull/544/commits/b50d8ef371ead95679838e862d0ea956e7655b39)

## 19 January 2023

- [Added ftd.text-input](https://github.com/ftd-lang/ftd/pull/543/commits/b86f74b45322e53f8a9acf43155b4bb0aa1a19b3)

## 18 January 2023

- [Added on-blur, on-focus events](https://github.com/ftd-lang/ftd/pull/540/commits/d0416a7eb2d5b4fa6172b4f32cf442161427e4db)
- [Added on-change, on-input events](https://github.com/ftd-lang/ftd/commit/06d6d91fb10c63e01dbfbe02d4913b8b8e8f1594)
- [Added ftd.decimal](https://github.com/ftd-lang/ftd/pull/536/commits/114c1af8a9e159b11f9f2eb62dfd3839b1dd9e4b)
- [Added ftd fonts](https://github.com/ftd-lang/ftd/pull/535/commits/aeeb33f97645f97fc7360b46fe8ec9afc6d52416)

## 17 January 2023

- [Added
  `ftd.input`](https://github.com/ftd-lang/ftd/pull/535/commits/99702d33ce6b3485ed9a7481709cb85f3ee7fddf)

## 13 January 2023

- Major
  Change: [Converted executor from recursion to loop](https://github.com/ftd-lang/ftd/pull/529/commits/f305bc187f006bb49e2cbdaf1f35bbd62e151d67)

## 12 January 2023

- [Added
  `ftd.iframe`](https://github.com/ftd-lang/ftd/pull/523/commits/dbddbff69ff203e338b594f31c165a4fcf10afbe)
- [Added
  `z-index`](https://github.com/ftd-lang/ftd/pull/523/commits/6acf81e42290901ef127cf23687f39ea48e88d9a)

## 11th January 2023

- [Added text-transform css](https://github.com/ftd-lang/ftd/pull/529/commits/0cae01d1a5b9b7a3775bd60d1c36a8230e5d74cc)
- [Added `auto` variant in
  `ftd.resizing`](https://github.com/ftd-lang/ftd/pull/523/commits/939fce3398b6f5612eceffab8931c71d7341af55)

## 10th January 2023

- [Added white-space css](https://github.com/ftd-lang/ftd/pull/523/commits/af5b339f1b6ff04a0738dbbfda4186d57d27fd27)
- [Added basic ftd functions](https://github.com/ftd-lang/ftd/pull/524/commits/f268014568ef75e86e989ef80de0089ad614e07f)
- [Added
  `ftd.breakpoint-width`](https://github.com/ftd-lang/ftd/pull/524/commits/537b8cfd356f91e0059edbd04987c0a3f0dbf8a6)
- [
  `ftd.device` type string to or-type](https://github.com/ftd-lang/ftd/pull/524/commits/85da36d3eecddcefad8b3acc9800458d4c740f34)
- [Added
  `ftd.code`](https://github.com/ftd-lang/ftd/commit/5c5a8214d69276fe587949a364199ab8a2407e71)

## 9th January 2023

- [Added inherited type](https://github.com/ftd-lang/ftd/commit/b1fe8af46cd35c51c3b37312d9c1a6466a54d1e5)
- [Added inherited color](https://github.com/ftd-lang/ftd/commit/8c22529da64f449620f937ed18d466c6256dfb74)
- [Added ftd regions (v0.3)](https://github.com/ftd-lang/ftd/commit/cf460d1cc41734effc3cd998c943dc102eb4232d)

## 6th January 2023

- [Added `ftd.responsive-length` and `responsive` variant of type `ftd.
  responsive-length` in
  `ftd.length`](https://github.com/ftd-lang/ftd/commit/2376c2746670fc8fef67b909b5798bf16e3d8986)

## 5th January 2023

- [Added anchor, top, bottom, left and right property](https://github.com/ftd-lang/ftd/commit/d86de625f8786738862bc6aaf33cc8665c7f73f5)

## 4th January 2023

- [Added mouse-enter, mouse-leave, on-click-outside, on-global-key and on-global-key-seq](https://github.com/ftd-lang/ftd/commit/003f3262075abb009ace6cb76dbd9083d8a333a2)

## 3rd January 2023

- [Added role property](https://github.com/ftd-lang/ftd/commit/69bc02ad65358580f2247726aef78e1958b3716f)

## 2nd January 2023

- [Added cursor property and cursor as pointer in event](https://github.com/ftd-lang/ftd/commit/64aa657a13ab24d932d56a2ddf9bcb77982a7752)
- [Added http and copy_to_clipboard in build.js](https://github.com/ftd-lang/ftd/commit/7eb9e879ff94ced3ed53d7d1584d63975b1a6b2f)

## 30th December 2022

- Major Change: [`ftd.length variant from `anonymous record
  ` to `regular`](https://github.com/ftd-lang/ftd/commit/c4e7e591e515c5dfef1647e3f447e77a2f94c538)
- [Added set_value_by_id in js](https://github.com/ftd-lang/ftd/commit/e6f65267cbe57888e0fd510dd15bb56032bf8e7a)

## 29th December 2022

- Added CSS and JS
- Added classes property
- Added ftd.device

## 28th December 2022

- Added resize
- [Change min-height, min-width, max-width, max-height type from ftd.length to ftd.resizing](https://github.com/ftd-lang/ftd/commit/edad6b2899d940c11bd30c47fb15b08c6c04ad78)
- [or-type constant construction shorthand (only short-hand allowed)](https://github.com/ftd-lang/ftd/commit/a1ae3726eef848554ccf81a7f4270aeb6daa37ce)
  [The Video link](https://www.loom.com/share/ee239d4840a74eb087f53ad6445a49a8)

## 27th December 2022

- [Fix the stack overflow issue](https://github.com/ftd-lang/ftd/commit/d7438e7b0476be7cddf7ca5b67409f3515afb910)
- [Added benchmark](https://github.com/ftd-lang/ftd/commit/f7ed86c87f648547b1107c066383511645039290)
- [Added default function(is_empty, enable_dark_mode, enable_light_mode,
  enable_system_mode)](https://github.com/ftd-lang/ftd/commit/46d7a1596259e8a916d76228cb6997caaf3fb226)

## 26th December 2022

- [Added more variants in
  `ftd.length` (calc, vh, vw, em, rem)](https://github.com/ftd-lang/ftd/commit/60bd50c5a9306be1b305601c037e39810ef6206a)
- [Added
  `open-in-new-tab`](https://github.com/ftd-lang/ftd/commit/048024c468f8cc5a47f72dabdd2454499aaca314)

## 24th December 2022

- [created Cheatsheet files](https://github.com/ftd-lang/ftd/commit/8df76b5b66dd31b9c647a848c6dd4277b434c7fe)


================================================
FILE: Cheatsheet.md
================================================
# FTD Cheat Sheet

This cheatsheet describes 0.3 syntax.

## Variables And Basic Types

```ftd
-- boolean foo: true


-- integer x: 10
-- decimal y: 1.0
-- string message: Hello World

-- string multi-line-message:

This is can scan multiple paras.
```

By default all variable are immutable.

## Mutable Variable

To make a variable mutable, declare them with `$` prefix:

```ftd
-- boolean $foo: true

-- $foo: false
```

Conditional updates:

```ftd
-- boolean $foo: true
-- boolean bar: true

-- $foo: false
if: { bar }
```

## Optional Variables

```ftd
;; both are equivalent
-- optional boolean bar: NULL
-- optional boolean bar:

-- optional string $message: hello

-- $message: NULL

;; Not yet implemented
-- $message: \NULL  
```

## Records

Records are like `struct` in Rust or C. Or classes in other languages. They currently
only store data, methods are not yet allowed.

```ftd
-- record person:
caption name:
optional integer age:
optional body bio:

;; name is cattion so it goes in the "section line"
-- person me: Alice
age: 10

She sits on the floor and reads a book all day.

;; body ends when a new section starts or end of file is reached 

;; we are not specifying the age and bio as they are optional
-- person you: Bob

;; caption is an alias for string type
-- person jack:
name: jack

;; field lookup uses `.dot` syntax

-- string name: $me.name
```

Fields can be given default values:

```ftd
-- record person:
caption name:
;; age will be 18 by default
integer age: 18
;; nickname if not specified will be same as name
string nickname: $person.name
optional body bio:
```

Record can refer to themselves:

```ftd
-- record employee:
caption name:
string title: 
optional employee manager:

-- employee bob: Bob
title: CEO

-- employee jack: Jack
title: Programmer
manager: $bob
```


## Or Type

`or-type` are like `enum` or Rust.

```ftd
-- record hsl:
integer hue:
decimal saturation:
decimal lightness:

;; we are creating a new type called color
-- or-type color:

;; new type can be defined as well
-- record rgb:
integer red:
integer green:
integer blue:

;; it can refer to existing types
-- hsl hsl:

;; hex value of the color
-- string hex:

;; one of the css named colors
-- string css:

;; or-type must have an end clause
-- end: color

;; we are defining a variable called `red` using the `color.rgb` variant
;; the type `red` is `color`
-- color.rgb red:
red: 255
green: 0
blue: 0

-- color.hex green: #00FF00
```

`or-type` can also contain constant variants:

```ftd
-- record rgb:
integer red:
integer green:
integer blue:

-- or-type color:

-- rgb rgb:
-- constant rgb red:
red: 255
green: 0
blue: 0

-- end: color
```

Now `$color.red` is a named constant.


The `or-type` can have three types of variant:

- `regular`: This accepts value and it has defined type/kind
- `constant`: This doesn't accept. The value is provided during declaration and is non-changeable.
- `anonymous-record`: The new record type/kind is created during declaration.
  It also accepts value.

```ftd
-- or-type color:

;; regular
-- string hex:

;; constant
-- const string foo-red: red

;; anonymous-record
-- record dl:
caption string dark:
string light: $dl.dark


;; Using regular type variant
-- ftd.text: Hello
color.hex: #ffffff

;; Using anonymous-record type variant
-- ftd.text: Hello
color.dl: blue
```

## Lists

```ftd
-- integer list foo:
-- integer: 10
-- integer: 20
-- integer: 30
-- end: foo

-- color list colors:

-- color.rgb:
red: 255
green: 0
blue: 0

-- color.hex: #00FF00

-- end: colors
```

Record containing a list:

```ftd
-- record person:
caption name:
person list friends:



-- person alice: Alice
-- alice.friends:

-- person: Bob

;; friends of bob:
-- person.friends:
-- person: Jill
-- person: Sam
-- end: person.friends

;; jack has no friends
-- person: Jack

-- end: alice.friends
```

list of list not yet supported.

## Function

```ftd
-- integer add(x,y):
integer x:
integer y:

sum = x + y;
x + y
```

NOTE: `-- integer add(x,y):` can not contain space yet, eg `-- integer add(x, y):` is
not allowed.

By default, arguments are immutable, to make them mutable use `$` prefix:

```ftd
-- void increment(what,by_how_much):
integer $what:
integer by_how_much:

what += by_how_much
```

# Kernel Components

FTD comes with following kernel components:

## `ftd.text` - To display text or strings 

```ftd
-- ftd.text: hello world
```

## `ftd.text` Attributes

### `optional caption or body`: the text to show

```ftd
-- ftd.text:

This is a body text.
```

### `style`: `optional ftd.text-style list`

```ftd
-- or-type text-style:
 
-- constant string underline: underline
-- constant string italic: italic
-- constant string strike: strike
-- constant string heavy: heavy
-- constant string extra-bold: extra-bold
-- constant string semi-bold: semi-bold
-- constant string bold: bold
-- constant string medium: medium
-- constant string regular: regular
-- constant string light: light
-- constant string extra-light: extra-light
-- constant string hairline: hairline

-- end: text-style
```

### `text-align`: `ftd.text-align`
### `line-clamp`: `optional integer`

## `ftd.code` - To render a code block

```ftd 
-- ftd.code: 
lang: rs

def func() {
  println!("Hello World");
}
```

## `ftd.code` attributes

### `lang`: `optional string` -> To specify code language.
`Default lang = txt` 
### `theme`: `optional string` -> To specify the theme
`Default theme = base16.ocean-dark`

Currently includes these themes

`base16-ocean.dark`, `base16-eighties.dark`, `base16-mocha.dark`, `base16-ocean.light`
`Solarized (dark)`, `Solarized (light)`

Also see InspiredGitHub from [here](https://github.com/sethlopezme/InspiredGitHub.tmtheme)

### `body`: `string` -> specify the code to display
### `line-clamp`: `optional integer` -> clamps the specified number of lines
### `text-align`: `ftd.text-align` -> specify text alignment
(Refer or-type `ftd.text-align` to know all possible values)

## `ftd.decimal` - To display decimal values

```ftd 
-- decimal pi: 3.142

-- ftd.decimal: 1.5

;; To display decimal variables
-- ftd.decimal: $pi
```

## `ftd.decimal` attributes

### `value`: `caption or body` -> decimal value to be rendered

### `text-align`: `ftd.text-align -> specify text alignment

### `line-clamp`: `optional integer`

## `ftd.iframe` - To render an iframe

```ftd 
-- ftd.iframe: 
src: https://www.fifthtry.com/

-- ftd.iframe: 
youtube: 10MHfy3b3c8

-- ftd.iframe:

<p>Hello world!</p>
```

## `ftd.iframe` attributes

### `src`: `optional caption string`
### `youtube`: `optional string` -> It accepts the youtube `vid` or `video id`.
### `srcdoc`: `optional body string`

Either src or youtube or srcdoc value is required. If any two or more than 
two of these are given or none is given would result to an error.

### 'loading': `optional ftd.loading`
Default: `lazy`

```ftd
-- or-type loading:

-- constant string lazy: lazy
-- constant string eager: eager

-- end: loading
```


## `ftd.text-input` - To take text input from user 

```ftd 
-- ftd.text-input: 
placeholder: Type Something Here...
type: password

-- ftd.text-input:
placeholder: Type Something Here...
multiline: true
```

## `ftd.text-input` attributes

### `placeholder`: `optional string` -> Adjusts a visible text inside the input field
### `value`: `optional string`
### `default-value`: `optional string`
### `enabled`: `optional boolean` -> Sets whether the text-input is enabled or disabled
### `multiline`: `optional boolean` -> To allow multiline input
### `type`: `optional ftd.text-input-type` -> Sets the type of text input

```ftd
-- or-type text-input-type:
-- constant string text: text
-- constant string email: email
-- constant string password: password
-- constant string url: url
-- end: text-input-type
```

By default, `type` is set to `ftd.text-input-type.text`

## `ftd.checkbox` - To render a checkbox

This code will create a simple checkbox.
```ftd
-- ftd.checkbox:
```

To know the current value of checkbox, you can use
a special variable `$CHECKED` to access it.

```ftd
-- boolean $is-checked: false

-- ftd.checkbox:
$on-click$: $ftd.set-bool($a = $is-checked, v = $CHECKED)
```

## `ftd.checkbox` Attributes

### `checked`: `optional boolean` -> Default checkbox value
### `enabled`: `optional boolean` -> Sets whether the checkbox is enabled or disabled

By default, `checkbox` is not selected

```ftd
;; In this case, the checkbox will be 
;; pre-selected by default

-- ftd.checkbox:
checked: true
```

## `ftd.image` - To render an image

```ftd 
-- ftd.image: 
src: $assets.files.static.fifthtry-logo.svg
```

## `ftd.image` attributes

### `src`: `ftd.image-src`

```ftd
-- record image-src:
string light:
string dark: $light
```




## Common Attributes

- `id`: `optional string`
- `padding`: `optional ftd.length`
- `padding-left`: `optional ftd.length`
- `padding-right`: `optional ftd.length`
- `padding-top`: `optional ftd.length`
- `padding-bottom`: `optional ftd.length`
- `padding-horizontal`: `optional ftd.length`
- `padding-vertical`: `optional ftd.length`
- `margin`: `optional ftd.length`
- `margin-left`: `optional ftd.length`
- `margin-right`: `optional ftd.length`
- `margin-top`: `optional ftd.length`
- `margin-bottom`: `optional ftd.length`
- `margin-horizontal`: `optional ftd.length`
- `margin-vertical`: `optional ftd.length`
- `border-width`: `optional ftd.length`
- `border-radius`: `optional ftd.length`
- `border-bottom-width`: `optional ftd.length`
- `border-top-width`: `optional ftd.length`
- `border-left-width`: `optional ftd.length`
- `border-right-width`: `optional ftd.length`
- `border-top-left-radius`: `optional ftd.length`
- `border-top-right-radius`: `optional ftd.length`
- `border-bottom-left-radius`: `optional ftd.length`
- `border-bottom-right-radius`: `optional ftd.length`

**`ftd.length`**

```ftd
-- or-type length:

-- integer px:
-- decimal percent:
-- string calc:
-- integer vh:
-- integer vw:
-- integer vmin:
-- integer vmax:
-- decimal dvh;
-- decimal lvh;
-- decimal svh;
-- decimal em:
-- decimal rem:
-- ftd.responsive-length responsive:

-- end: length

-- record responsive-length:
ftd.length desktop:
ftd.length mobile: $responsive-length.desktop
```

- `border-color`: `optional ftd.color`
- `border-bottom-color`: `optional ftd.color`
- `border-top-color`: `optional ftd.color`
- `border-left-color`: `optional ftd.color`
- `border-right-color`: `optional ftd.color`
- `color`: `optional ftd.color`

**`ftd.color`**


```ftd
-- record color:
caption light:
string dark: $color.light
```

- `min-width`: `optional ftd.resizing`
- `max-width`: `optional ftd.resizing`
- `min-height`: `optional ftd.resizing`
- `max-height`: `optional ftd.resizing`
- `width`: `optional ftd.resizing` (default: `auto`)
- `height`: `optional ftd.resizing` (default: `auto`)


**`ftd.resizing`**

```ftd
-- or-type resizing:

-- constant string fill-container: fill-container
-- constant string hug-content: hug-content
-- constant string auto: auto
-- ftd.length fixed:

-- end: resizing
```

- `link`: `string`
- `open-in-new-tab`: `optional boolean`

- `background`: `optional ftd.background`


**`ftd.background`**

```ftd
-- or-type background:

-- ftd.color solid:
-- ftd.background-image image:

-- end: background
```

- `align-self`: `optional ftd.align-self`

**`ftd.align-self`**

```ftd
-- or-type align-self:

-- constant string start: start
-- constant string center: center
-- constant string end: end

-- end: align-self
```

- `overflow`: `optional ftd.overflow`
- `overflow-x`: `optional ftd.overflow`
- `overflow-y`: `optional ftd.overflow`

**`ftd.overflow`**

```ftd
-- or-type overflow:

-- constant string scroll: scroll
-- constant string visible: visible
-- constant string hidden: hidden
-- constant string auto: auto

-- end: overflow
```

- `cursor`: `optional ftd.cursor`


**`ftd.cursor`**

```ftd
-- or-type cursor:

-- constant string default: default
-- constant string none: none
-- constant string context-menu: context-menu
-- constant string help: help
-- constant string pointer: pointer
-- constant string progress: progress
-- constant string wait: wait
-- constant string cell: cell
-- constant string crosshair: crosshair
-- constant string text: text
-- constant string vertical-text: vertical-text
-- constant string alias: alias
-- constant string copy: copy
-- constant string move: move
-- constant string no-drop: no-drop
-- constant string not-allowed: not-allowed
-- constant string grab: grab
-- constant string grabbing: grabbing
-- constant string e-resize: e-resize
-- constant string n-resize: n-resize
-- constant string ne-resize: ne-resize
-- constant string nw-resize: nw-resize
-- constant string s-resize: s-resize
-- constant string se-resize: se-resize
-- constant string sw-resize: sw-resize
-- constant string w-resize: w-resize
-- constant string ew-resize: ew-resize
-- constant string ns-resize: ns-resize
-- constant string nesw-resize: nesw-resize
-- constant string nwse-resize: nwse-resize
-- constant string col-resize: col-resize
-- constant string row-resize: row-resize
-- constant string all-scroll: all-scroll
-- constant string zoom-in: zoom-in
-- constant string zoom-out: zoom-out

-- end: cursor
```

- `region`: `optional ftd.region`

**`ftd.region`**

```ftd
;; NOTE
;; 1. Using conditionals with region is not supported yet.
;; 2. Only one region can be specified as region value.

-- or-type region:

-- constant string h1: h1
-- constant string h2: h2
-- constant string h3: h3
-- constant string h4: h4
-- constant string h5: h5
-- constant string h6: h6

-- end: region
```

- `white-space`: `optional ftd.white-space`

**`ftd.white-space`**

```ftd 

-- or-type white-space:

-- constant string normal: normal
-- constant string nowrap: nowrap
-- constant string pre: pre 
-- constant string pre-wrap: pre-wrap
-- constant string pre-line: pre-line
-- constant string break-spaces: break-spaces

-- end: white-space
```

- `text-transform`: `optional ftd.text-transform`

**`ftd.text-transform`**

```ftd 
-- or-type text-transform:

-- constant string none: none
-- constant string capitalize: capitalize
-- constant string uppercase: uppercase
-- constant string lowercase: lowercase
-- constant string initial: initial 
-- constant string inherit: inherit

-- end: text-transform
```

- `classes`: string list (classes are created in css)


- `border-style`: `optional ftd.border-style list`

**`ftd.border-style`**

```ftd
-- or-type border-style:

-- constant string dotted: dotted
-- constant string dashed: dashed
-- constant string solid: solid
-- constant string double: double
-- constant string groove: groove 
-- constant string ridge: ridge
-- constant string inset: inset
-- constant string outset: outset

-- end: border-style
```


## Container Attributes

- `wrap`: `optional boolean`

- `align-content`: `optional ftd.align`

**`ftd.align`**

```ftd
-- or-type align:

-- constant string top-left: top-left
-- constant string top-center: top-center
-- constant string top-right: top-right
-- constant string right: right
-- constant string left: left
-- constant string center: center
-- constant string bottom-left: bottom-left
-- constant string bottom-center: bottom-center
-- constant string bottom-right: bottom-right

-- end: align
```


- `spacing`: `optional ftd.spacing`

**`ftd.spacing`**

```ftd
-- or-type spacing:

-- ftd.length fixed:
-- constant string space-between: space-between
-- constant string space-around: space-around
-- constant string space-evenly: space-evenly

-- end: spacing
```

- `resize`: `optional ftd.resize`


**`ftd.resize`**

```ftd
-- or-type resize:

-- constant string both: both
-- constant string horizontal: horizontal
-- constant string vertical: vertical

-- end: resize
```

- `role`: `optional ftd.responsive-type`


```ftd
-- record responsive-type:
caption ftd.type desktop:
ftd.type mobile: $responsive-type.desktop

-- record type:
optional ftd.font-size size:
optional ftd.font-size line-height:
optional ftd.font-size letter-spacing:
optional integer weight:
optional string font-family:

-- or-type font-size:

-- integer px:
-- decimal em:
-- decimal rem:

-- end: font-size
```


- `anchor`: `optional ftd.anchor`

```ftd
-- or-type anchor:

-- constant string parent: absolute
-- constant string window: fixed
-- string id:

-- end: anchor
```

- `z-index`: `optional integer`

# Text Attributes

- `text-align`: `ftd.text-align`

### `ftd.text-align`

```ftd
-- or-type text-align:
-- constant string start: start
-- constant string center: center
-- constant string end: end
-- constant string justify: justify
-- end: text-align
```

- `line-clamp`: `optional integer`
- `sticky`: `optional boolean`

# Events

- `on-click`
- `on-change`
- `on-input`
- `on-blur`
- `on-focus`
- `on-mouse-enter`
- `on-mouse-leave`
- `on-click-outside`
- `on-global-key[<keys>]`
- `on-global-key-seq[<keys>]`

# Default functions

## `append($a: mutable list, v: string)`

This is a default ftd function that will append a string `v`
to the end of the given mutable string list `a`.

```ftd
-- void append(a,v):
string list $a:
string v:

ftd.append(a, v);
```

## `insert_at($a: mutable list, v: string, num: integer)`

This is a default ftd function that will insert a string `v`
at the index `num` in the given mutable string list `a`.

```ftd
-- void insert_at(a,v,num):
string list $a:
string v:
integer num:

ftd.insert_at(a, v, num);
```

## `delete_at($a: mutable list, v: integer)`

This is a default ftd function that will delete the string
from index `num` from the given mutable string list `a`.

```ftd
-- void delete_at(a,num):
string list $a:
integer num:

ftd.delete_at(a, num);
```

## `clear($a: mutable list)`

This is a default ftd function that will clear the given
mutable string list `a`.

```ftd
-- void clear(a):
string list $a:

ftd.clear(a);
```

## `set-list($a: mutable list, v: list)`

This is a default ftd function that will assign a new list `v` to the
existing mutable list `a`.

```ftd
-- void set_list(a,v):
string list $a:
string list v:

ftd.set_list(a, v);
```

## `toggle($a: bool)`

This is FScript function. It will toggle the boolean variable which is passed 
as argument `a` to this function.

```ftd
-- boolean $b: false

-- ftd.boolean: $b

-- ftd.text: Click to toggle
$on-click$: $ftd.toggle($a = $b)
```

## `increment($a: integer)`

This is FScript function. It will increment the integer variable by 1 which is passed
as argument `a` to this function.

```ftd
-- integer $x: 1

-- ftd.integer: $x

-- ftd.text: Click to increment by 1 
$on-click$: $ftd.increment($a = $x)
```

## `increment-by($a: integer, v: integer)`

This is FScript function. It will increment the integer variable by value `v` which is passed
as argument `a` to this function.

```ftd
-- integer $x: 1

-- ftd.integer: $x

-- ftd.text: Click to increment by 5 
$on-click$: $ftd.increment-by($a = $x, v = 5)
```

## `set-bool($a: bool, v: bool)`

This is FScript function. It will set the boolean variable by value `v` which is passed
as argument `a` to this function.

```ftd
-- boolean $b: false

-- ftd.boolean: $b

-- ftd.text: Click to set the boolean as true 
$on-click$: $ftd.set-bool($a = $b, v = true)
```

## `set-string($a: string, v: string)`

This is FScript function. It will set the string variable by value `v` which is passed
as argument `a` to this function.

```ftd
-- string $s: Hello

-- ftd.text: $s

-- ftd.text: Click to set the string as World 
$on-click$: $ftd.set-string($a = $s, v = World)
```

## `set-integer($a: integer, v: integer)`

This is FScript function. It will set the integer variable by value `v` which is passed
as argument `a` to this function.

```ftd
-- integer $x: 1

-- ftd.integer: $x

-- ftd.text: Click to set the integer as 100 
$on-click$: $ftd.set-integer($a = $x, v = 100)
```


## `is_empty(a: any)`

This is FScript function. It gives if the value passed to argument `a` is null or empty.


```ftd
-- optional string name:

-- ftd.text: $name
if: { !is_empty(name) }

-- string list names:

-- display-name:
if: { !is_empty(names) }
```

## `enable_dark_mode()`

This is FScript as well as a standard ftd function. This function enables the dark mode.

```ftd
-- ftd.text: Dark Mode
$on-click$: $set-dark()

-- void set-dark():

enable_dark_mode()
```

Alternatively you can do
```ftd
-- ftd.text: Click to set Dark Mode
$on-click$: $ftd.enable-dark-mode()
```

## `enable_light_mode()`

This is FScript as well as a standard ftd function. This function enables the light mode.

```ftd
-- ftd.text: Light Mode
$on-click$: $set-light()

-- void set-light():

enable_light_mode()
```

Alternatively you can do
```ftd
-- ftd.text: Click to set Light Mode
$on-click$: $ftd.enable-light-mode()
```

## `enable_system_mode()`

This is FScript as well as a standard ftd function. This function enables the system mode.

```ftd
-- ftd.text: System Mode
$on-click$: $set-system()

-- void set-system():

enable_system_mode()
```

Alternatively you can do
```ftd
-- ftd.text: Click to set System Mode
$on-click$: $ftd.enable-system-mode()
```


## `ftd.copy_to_clipboard()`

This is FScript as well as a standard ftd function. This function enables copy content in clipboard.

```ftd
-- ftd.text: Copy
$on-click$: $copy-me-call(text = Copy me ⭐️)

-- void copy-me-call(text):
string text:

ftd.copy_to_clipboard(text)
```

Alternatively you can do
```ftd
-- ftd.text: Click to set System Mode
$on-click$: $ftd.copy-to-clipboard(a = Copy me ⭐️)
```

## `ftd.http(url: string, method: string, ...request-data)`

This function is used to make http request

- For `GET` requests, the request-data will sent as `query parameters`

- For `POST` requests, the request-data will be sent as request `body`

- We can either pass `named` data or `unnamed` data as
  `request-data` values.

- For `named` data, the values need to be passed as `(key,value)` tuples.

  For example `ftd.http("www.fifthtry.com", "post", ("name": "John"),("age": 25))`

  request-data = `{ "name": "John", "age": 25 }`

```ftd
-- ftd.text: Click to send POST request
$on-click$: $http-call(url = https://www.fifthtry.com, method = post, name = John, age = 23)

-- void http-call(url,method,name,age):
string url:
string method:
string name:
integer age: 

;; Named request-data
ftd.http(url, method, ("name": name),("age": age))
```

- For `unnamed` data, i.e when keys are not passed with data values, then the keys will be indexed 
  based on the order in which these values are passed. 
 
  For example `http("www.fifthtry.com", "post", "John", 25)`

  request-data = `{ "0": "John", "1": 25 }`

```ftd
-- ftd.text: Click to send POST request
$on-click$: $http-call(url = https://www.fifthtry.com, method = post, name = John, age = 23)

-- void http-call(url,method,name,age):
string url:
string method:
string name:
integer age: 

;; Unnamed request-data
http(url, method, name, age)
```

- In case if a unnamed `record` variable is passed as request-data,
  in that case, the record's `field` names will be used as key values.

  For example: Let's say we have a `Person` record, and we have created a `alice` 
  record of `Person` type. And if we pass this `alice` variable as request-data
  then request-data will be `{ "name" : "Alice", "age": 22 }`

```ftd
-- record Person: 
caption name: 
integer age: 

-- Person alice: Alice
age: 22

-- ftd.text: Click to send POST request
$on-click$: $http-call(url = https://www.fifthtry.com, method = post, person = $alice)

-- void http-call(url,method,person):
string url:
string method:
Person person:

;; Unnamed record as request-data
http(url, method, person)
```

Response JSON:

- To redirect:
```json
{
  "redirect": "fifthtry.com"
}
```


- To reload:
```json
{
  "reload": true
}
```

- To update ftd data from backend:
```json
{
  "data": {
    "<module-name>#<variable-name>": <value>
  }
}
```

- [Discussions#511](https://github.com/ftd-lang/ftd/discussions/511)

- To update error data:
```json
{
  "errors": {
    "<module-name>#<variable-name>": <value>
  }
}
```

- [Discussions#511](https://github.com/ftd-lang/ftd/discussions/511)


# Some frequently used functions

## Clamp

- Regular Clamp

```ftd
-- integer $num: 0

-- ftd.integer: $num
$on-click$: $clamp($a = $num, by = 1, clamp = 6)

-- void clamp(a,by,clamp):
integer $a:
integer by:
integer clamp:


a = (a + by) % clamp
```

- Clamp with min and max

```ftd
-- integer $num: 1

-- ftd.integer: $num
$on-click$: $clamp($a = $num, by = 1, min = 1, max = 6)

-- void clamp(a,by,min,max):
integer $a:
integer by: 1
integer min: 0
integer max: 5


a = (((a - min) + by) % (max - min)) + min
```




# How to run examples for FTD: 0.3

- Create empty files `<number>-<name>.ftd` and `<number>-<name>.html` in `t/html` 
  folder.
- Run `cargo test html_test_all -- --nocapture fix=true <optional: path=<prefix of the file name>>`

## Optional commands to check html in examples
- Run `cargo run`
- Run `cd docs`
- Run `python3 -m http.server 8000`


# Default Variable

## `ftd.device`

The `ftd.device` variable is a mutable variable of type `ftd.
device-data` which is an or-type.

```ftd
-- or-type device-data:

-- constant string mobile: mobile
-- constant string desktop: desktop

-- end: device-data

-- ftd.device-data $device: desktop
```

## `ftd.breakpoint-width`

The `ftd.breakpoint-width` variable is a mutable variable of type `ftd.
breakpoint-width-data` which is a record.

```ftd
-- record breakpoint-width-data:
integer mobile:

-- ftd.breakpoint-width-data $breakpoint-width:
mobile: 768
```

## `ftd.font-display`
This variable is a mutable string variable which can be 
used to change the font family of `headings` and `labels` 
under inherited types which includes `heading-large`, 
`heading-medium`, `heading-small`,`heading-hero`, 
`label-big`, `label-small`

By default `ftd.font-display` is set to `sans-serif`

```ftd
-- $ftd.font-display: cursive

-- ftd.text: Hello world
role: $inherited.types.heading-large
```

## `ftd.font-copy`
This variable is a mutable string variable which can be
used to change the font family of `copy` type fonts
under inherited types which includes `copy-tight`,
`copy-relaxed` and `copy-large`

By default `ftd.font-copy` is set to `sans-serif`

```ftd
-- $ftd.font-copy: cursive

-- ftd.text: Hello world
role: $inherited.types.copy-large
```

## `ftd.font-code`
This variable is a mutable string variable which can be
used to change the font family of `fine-print` and `blockquote` fonts
under inherited types.

By default `ftd.font-code` is set to `sans-serif`

```ftd
-- $ftd.font-code: cursive

-- ftd.text: Hello world
role: $inherited.types.fine-print
```

## `inherited.types`

The `inherited.types` variable is of type `ftd.type-data` which is a record.

```ftd
-- record type-data:
ftd.responsive-type heading-hero:
ftd.responsive-type heading-large:
ftd.responsive-type heading-medium:
ftd.responsive-type heading-small:
ftd.responsive-type heading-tiny:
ftd.responsive-type copy-large:
ftd.responsive-type copy-regular:
ftd.responsive-type copy-small:
ftd.responsive-type fine-print:
ftd.responsive-type blockquote:
ftd.responsive-type source-code:
ftd.responsive-type label-large:
ftd.responsive-type label-small:
ftd.responsive-type button-large:
ftd.responsive-type button-medium:
ftd.responsive-type button-small:
ftd.responsive-type link:
```

The fields in record `type-data` are of type `ftd.responsive-type` which is 
another record with `desktop` and `mobile` fields of type `ftd.type`

In `inherited.types` variable, value of all the fields is same for both 
`desktop` and `mobile`. So just mentioning the value for one only.

For desktop: 

- `heading-hero`:
  size: 80
  line-height: 104
  weight: 400

- `heading-large`:
  size: 50
  line-height: 65
  weight: 400

- `heading-medium`:
  size: 38
  line-height: 57
  weight: 400

- `heading-small`:
  size: 24
  line-height: 31
  weight: 400

- `heading-tiny`:
  size: 20
  line-height: 26
  weight: 400

- `copy-large`:
  size: 22
  line-height: 34
  weight: 400

- `copy-regular`:
  size: 18
  line-height: 30
  weight: 400

- `copy-small`:
  size: 14
  line-height: 24
  weight: 400

- `fine-print`:
  size: 12
  line-height: 16
  weight: 400

- `blockquote`:
  size: 16
  line-height: 21
  weight: 400

- `source-code`:
  size: 18
  line-height: 30
  weight: 400

- `label-large`:
  size: 14
  line-height: 19
  weight: 400

- `label-small`:
  size: 12
  line-height: 16
  weight: 400

- `button-large`:
  size: 18
  line-height: 24
  weight: 400

- `button-medium`:
  size: 16
  line-height: 21
  weight: 400

- `button-small`:
  size: 14
  line-height: 19
  weight: 400

- `link`:
  size: 14
  line-height: 19
  weight: 400


## `inherited.colors`

The `inherited.colors` variable is of type `ftd.color-scheme` which is a record.

```ftd
-- record color-scheme:
ftd.background-colors background:
ftd.color border:
ftd.color border-strong:
ftd.color text:
ftd.color text-strong:
ftd.color shadow:
ftd.color scrim:
ftd.cta-colors cta-primary:
ftd.cta-colors cta-secondary:
ftd.cta-colors cta-tertiary:
ftd.cta-colors cta-danger:
ftd.pst accent:
ftd.btb error:
ftd.btb success:
ftd.btb info:
ftd.btb warning:
ftd.custom-colors custom:

-- record background-colors:
ftd.color base:
ftd.color step-1:
ftd.color step-2:
ftd.color overlay:
ftd.color code:

-- record cta-colors:
ftd.color base:
ftd.color hover:
ftd.color pressed:
ftd.color disabled:
ftd.color focused:
ftd.color border:
ftd.color text:

-- record pst:
ftd.color primary:
ftd.color secondary:
ftd.color tertiary:

-- record btb:
ftd.color base:
ftd.color text:
ftd.color border:

-- record custom-colors:
ftd.color one:
ftd.color two:
ftd.color three:
ftd.color four:
ftd.color five:
ftd.color six:
ftd.color seven:
ftd.color eight:
ftd.color nine:
ftd.color ten:
```

The `inherited.colors` has following value:

- `background`:
  1. `base`: `#18181b`
  2. `step-1`: `#141414`
  3. `step-2`: `#585656`
  4. `overlay`: `rgba(0, 0, 0, 0.8)`
  3. `code`: `#2B303B`
  
- `border`: `#434547`
- `border-strong`: `#919192`
- `text`: `#a8a29e`
- `text-strong`: `#ffffff`
- `shadow`: `#007f9b`
- `scrim`: `#007f9b`
- `cta-primary`:
  1. `base`: `#2dd4bf`
  2. `hover`: `#2c9f90`
  3. `pressed`: `#2cc9b5`
  4. `disabled`: `rgba(44, 201, 181, 0.1)`
  5. `focused`: `#2cbfac`
  6. `border`: `#2b8074`
  7. `text`: `#feffff`
- `cta-secondary`:
  1. `base`: `#4fb2df`
  2. `hover`: `#40afe1`
  3. `pressed`: `#4fb2df`
  4. `disabled`: `rgba(79, 178, 223, 0.1)`
  5. `focused`: `#4fb1df`
  6. `border`: `#209fdb`
  7. `text`: `#ffffff`
- `cta-tertiary`:
  1. `base`: `#556375`
  2. `hover`: `#c7cbd1`
  3. `pressed`: `#3b4047`
  4. `disabled`: `rgba(85, 99, 117, 0.1)`
  5. `focused`: `#e0e2e6`
  6. `border`: `#e2e4e7`
  7. `text`: `#ffffff`
- `cta-danger`:
  1. `base`: `#1C1B1F`
  2. `hover`: `#1C1B1F`
  3. `pressed`: `#1C1B1F`
  4. `disabled`: `#1C1B1F`
  5. `focused`: `#1C1B1F`
  6. `border`: `#1C1B1F`
  7. `text`: `#1C1B1F`
- `accent`:
  1. `primary`: `#2dd4bf`
  2. `secondary`: `#4fb2df`
  3. `tertiary`: `#c5cbd7`
- `error`:
  1. `base`: `#f5bdbb`
  2. `text`: `#c62a21`
  3. `border`: `#df2b2b`
- `success`:
  1. `base`: `#e3f0c4`
  2. `text`: `#467b28`
  3. `border`: `#3d741f`
- `info`:
  1. `base`: `#c4edfd`
  2. `text`: `#205694`
  3. `border`: `#205694`
- `warning`:
  1. `base`: `#fbefba`
  2. `text`: `#966220`
  3. `border`: `#966220`
- `custom`:
  1. `one`: `#ed753a`
  1. `two`: `#f3db5f`
  1. `three`: `#8fdcf8`
  1. `four`: `#7a65c7`
  1. `five`: `#eb57be`
  1. `six`: `#ef8dd6`
  1. `seven`: `#7564be`
  1. `eight`: `#d554b3`
  1. `nine`: `#ec8943`
  1. `ten`: `#da7a4a`


## Understanding Loop

`$loop$` loops over each item in an array, making the item available in a 
context argument in component


```ftd
-- string list names:

-- string: Ayushi
-- string: Arpita

-- end: names

-- ftd.text: $obj
$loop$: $names as $obj
```

The output would be:

```
Ayushi
Arpita
```

### `LOOP.COUNTER`

The current iteration of the loop (0-indexed)

```ftd
-- string list names:

-- string: Ayushi
-- string: Arpita

-- end: names

-- foo: $obj
idx: $LOOP.COUNTER
$loop$: $names as $obj


-- component foo:
caption name:
integer idx:

-- ftd.row:
spacing.px: 30

-- ftd.text: $foo.name
-- ftd.integer: $foo.idx

-- end: ftd.row

-- end: foo
```

The output would be:

```
Ayushi     0
Arpita     1
```


================================================
FILE: DOCUMENTATION_PLAN.md
================================================
# fastn.com Documentation & Specification Plan

## Overview
Transform fastn.com into the comprehensive hub for all fastn development, specifications, and design decisions. **Primary focus: Complete comprehensive fastn 0.4 documentation before moving to v0.5 content.** This ensures the current stable release is thoroughly documented for developers and the community.

## Current State Analysis

### Existing Documentation Structure
```
fastn.com/
├── ftd/                    # FTD Language docs (needs major updates)
├── docs/                   # General documentation  
├── get-started/           # Onboarding (needs review)
├── examples/              # Code examples (expand)
├── best-practices/        # Development practices (expand)  
├── tutorial/              # Learning materials (update)
└── book/                  # fastn book (comprehensive review needed)
```

### Issues Identified
1. **Outdated Content**: Many .ftd files reference old syntax/features
2. **Incomplete Coverage**: Missing comprehensive language specification
3. **Scattered Information**: Design decisions not centralized
4. **Limited Examples**: Need more practical, real-world examples
5. **Missing v0.5 Content**: No documentation of new architecture

## Proposed New Structure

### 1. Add v0.5 Development Hub
```
fastn.com/
├── v0.5/                           # NEW: v0.5 development documentation
│   ├── architecture/               # System architecture documents
│   │   ├── compiler-pipeline.ftd   # fastn-section → fastn-unresolved → fastn-resolved → fastn-compiler flow
│   │   ├── rendering-engine.ftd    # fastn-runtime architecture
│   │   ├── terminal-rendering.ftd  # Terminal rendering design & specs
│   │   ├── css-semantics.ftd       # CSS-like property system
│   │   └── continuation-system.ftd # fastn-continuation architecture
│   ├── design-decisions/           # Major design choices and rationale
│   │   ├── ssl-design.ftd          # SSL/TLS integration design
│   │   ├── automerge-integration.ftd # Automerge design decisions
│   │   ├── p2p-architecture.ftd    # P2P networking design
│   │   └── breaking-changes.ftd    # v0.4 → v0.5 breaking changes
│   ├── implementation-status/      # Current development status
│   │   ├── compiler-status.ftd     # What's implemented in compiler
│   │   ├── runtime-status.ftd      # Runtime implementation status
│   │   └── roadmap.ftd            # Development roadmap
│   └── specifications/             # Technical specifications
│       ├── terminal-rendering-spec.ftd # Comprehensive terminal rendering spec
│       ├── css-property-mapping.ftd    # CSS property to terminal mapping
│       └── component-behavior.ftd      # Component behavior specifications
```

### 2. Complete FTD 0.4 Language Specification (PRIORITY)
```
fastn.com/
├── language-spec/                  # NEW: Comprehensive language specification for fastn 0.4
│   ├── index.ftd                  # Language overview
│   ├── syntax/                    # Syntax specification
│   │   ├── sections.ftd           # Section syntax rules
│   │   ├── headers.ftd            # Header syntax and semantics
│   │   ├── comments.ftd           # Comment syntax
│   │   └── grammar.ftd            # Complete BNF grammar
│   ├── type-system/               # Type system specification
│   │   ├── primitive-types.ftd    # boolean, integer, decimal, string
│   │   ├── derived-types.ftd      # ftd.color, ftd.length, etc.
│   │   ├── records.ftd            # Record type definitions
│   │   ├── or-types.ftd           # Or-type definitions
│   │   └── type-inference.ftd     # Type inference rules
│   ├── components/                # Component system
│   │   ├── definition.ftd         # Component definition syntax
│   │   ├── invocation.ftd         # Component invocation rules
│   │   ├── arguments.ftd          # Argument passing semantics
│   │   ├── children.ftd           # Children handling
│   │   └── inheritance.ftd        # Property inheritance rules
│   ├── variables/                 # Variable system
│   │   ├── declaration.ftd        # Variable declaration rules
│   │   ├── scoping.ftd           # Scoping rules
│   │   ├── mutability.ftd        # Mutable vs immutable
│   │   └── references.ftd        # Variable references
│   ├── functions/                 # Function system
│   │   ├── definition.ftd         # Function definition
│   │   ├── calls.ftd             # Function calls
│   │   ├── expressions.ftd       # Expression evaluation
│   │   └── built-ins.ftd         # Built-in functions
│   └── modules/                   # Module system
│       ├── imports.ftd           # Import semantics
│       ├── exports.ftd           # Export rules
│       ├── aliases.ftd           # Alias system
│       └── package-system.ftd    # Package management
```

### 3. Enhanced Component Documentation
```
fastn.com/ftd/
├── kernel-components/              # ENHANCED: Comprehensive kernel docs
│   ├── text.ftd                   # Enhanced with more examples
│   ├── column.ftd                 # Layout behavior, CSS mapping
│   ├── row.ftd                    # Flexbox semantics
│   ├── container.ftd              # Box model behavior
│   ├── image.ftd                  # Media handling
│   ├── video.ftd                  # Video component
│   ├── audio.ftd                  # NEW: Audio component docs
│   ├── checkbox.ftd               # Form controls
│   ├── text-input.ftd             # Input handling
│   ├── iframe.ftd                 # Embedded content
│   ├── code.ftd                   # Code display
│   ├── rive.ftd                   # Animation support
│   ├── document.ftd               # Document root
│   ├── desktop.ftd                # Device-specific rendering
│   └── mobile.ftd                 # Mobile-specific behavior
├── terminal-rendering/             # NEW: Terminal-specific documentation
│   ├── overview.ftd               # Terminal rendering principles
│   ├── ascii-art-layouts.ftd      # ASCII box-drawing specifications
│   ├── ansi-color-support.ftd     # Color handling in terminals
│   ├── responsive-terminal.ftd    # Adapting to terminal width
│   └── interactive-elements.ftd   # Terminal interaction patterns
```

### 4. Comprehensive Examples & Tutorials
```
fastn.com/
├── examples/                       # EXPANDED: Real-world examples
│   ├── basic/                     # Simple component usage
│   ├── layouts/                   # Layout patterns
│   ├── forms/                     # Form building
│   ├── interactive/               # Interactive components
│   ├── responsive/                # Responsive design
│   ├── terminal-apps/             # NEW: Terminal application examples
│   └── full-applications/         # Complete application examples
├── cookbook/                       # NEW: Common patterns and solutions
│   ├── component-patterns/        # Reusable component patterns
│   ├── layout-recipes/            # Common layout solutions
│   ├── styling-techniques/        # Advanced styling
│   └── performance-tips/          # Optimization techniques
```

## Implementation Phases

**Priority Order: Complete fastn 0.4 documentation first, then move to v0.5**

### Phase 1: fastn 0.4 Documentation Foundation (Week 1-2)
1. ✅ **Audit existing content** - Identified outdated information in current fastn.com
2. ✅ **Write documentation standards** - Established testing guidelines and debug cheat sheet in CLAUDE.md
3. 🚧 **Begin comprehensive FTD 0.4 language specification** - **PR READY**: Complete framework at `/spec/` with all 6 major sections
4. ✅ **Update existing kernel component docs** - **COMPLETED**: Added missing `ftd.audio` component documentation

### Phase 2: Complete fastn 0.4 Language Specification (Week 3-4)
1. **Finish comprehensive language specification** - Expand existing framework with detailed content
2. ✅ **Enhanced component documentation** - **COMPLETED**: Added `ftd.audio`, updated sitemap
3. **Create comprehensive examples library** - Real-world usage patterns
4. **Write cookbook entries** - Common patterns and solutions for 0.4

### Phase 3: fastn 0.4 Polish & Community Ready (Week 5-6)
1. **Review and update all 0.4 content** - Ensure consistency and accuracy
2. **Add interactive examples** - Live code examples where possible
3. **Create learning paths** - Guided learning sequences for fastn 0.4
4. **Community contribution guides** - How to contribute to fastn documentation

### Phase 4: Begin v0.5 Documentation (Week 7-8)
1. **Create v0.5 directory structure** - Set up new documentation hierarchy
2. **Architecture documentation** - Document v0.5 architecture decisions
3. **Design decision documentation** - SSL, P2P, Automerge, terminal rendering design docs
4. **Create v0.5 specifications** - Terminal rendering, CSS mapping, component behavior specs

## Content Standards

### Documentation Quality Standards
1. **Complete Examples** - Every feature must have working examples
2. **ASCII Output Specs** - Terminal rendering must show expected output
3. **Cross-References** - Comprehensive linking between related concepts
4. **Version Compatibility** - Clear indication of version requirements
5. **Testing Instructions** - How to test/verify examples

### Code Example Standards
```ftd
-- ds.rendered: Example Title
  -- ds.rendered.input:
  
  \-- ftd.text: Hello World
  color: red
  
  -- ds.rendered.output:
  
    -- ftd.text: Hello World
    color: red
    
  -- end: ds.rendered.output

-- end: ds.rendered

-- ds.terminal-output: Terminal Rendering

```
Hello World  (in red)
```

-- end: ds.terminal-output
```

### File Organization Standards
- `.ftd` extension for all documentation
- Clear hierarchical structure
- Consistent naming conventions
- Index files for each directory
- Cross-reference files for navigation

## Success Metrics

1. **Completeness** - 100% coverage of language features
2. **Accuracy** - All examples tested against v0.5 codebase
3. **Usability** - Clear navigation and discoverability
4. **Community Adoption** - External contributions and feedback
5. **Developer Productivity** - Faster onboarding and development

## Progress Status (Updated 2025-09-08)

### ✅ Completed
- **ftd.audio component documentation** - Live at `/ftd/audio/` and `/book/audio/` with proper layout
- **Documentation testing standards** - CLAUDE.md with build/test procedures and debugging cheat sheet
- **Language specification framework** - Complete structure at `/spec/` (6 sections)
- **Built-in types accuracy audit** - Fixed 3 critical issues in built-in-types.ftd:
  - Corrected ftd.fetch-priority → ftd.image-fetch-priority type name
  - Added 7 missing text-input-type variants (datetime, date, time, month, week, color, file)
  - Fixed vh/vw/vmin/vmax data types from integer to decimal
- **Built-in functions accuracy audit** - Fixed 3 critical issues in built-in-functions.ftd:
  - Fixed insert_at function parameter order in implementation example
  - Corrected delete_at parameter name from 'v' to 'num'
  - Fixed copy-to-clipboard parameter name from 'text' to 'a'
- **Kernel component documentation audit** - Systematically reviewed 12 components:
  - Added missing role attribute to ftd.text
  - Fixed fetch-priority type reference in ftd.image  
  - Fixed copy-paste error in ftd.column description
  - Verified accuracy of 9 other kernel components (container, row, checkbox, text-input, video, iframe, code, desktop, mobile)

### 🚧 In Progress (PR Ready)
- **Language Specification** - Branch: `docs/language-specification-framework`
  - All 6 major sections created: syntax, types, components, variables, functions, modules
  - Clean URL structure: `/spec/section/` 
  - All pages tested and working
  - Ready for content expansion

### 📋 Next Priority Tasks

**Phase 1 Documentation Foundation - NEARLY COMPLETE:**
- ✅ Kernel component audit complete (12/12 components reviewed)
- ✅ Major reference docs accurate (built-in-types, built-in-functions)
- 🚧 Language specification framework ready for review

**Phase 2 Candidates (Pick Next):**
1. **Add missing built-in functions** - Math/string functions found in audit but not documented
2. **Create comprehensive examples library** - Real-world usage patterns  
3. **Set up terminal rendering documentation structure** - Prepare for v0.5 content
4. **Audit remaining documentation files** - Review non-kernel components and guides

This plan transforms fastn.com into the definitive resource for fastn development, ensuring that design decisions are documented, specifications are comprehensive, and developers have the resources they need to be productive.

================================================
FILE: LICENSE
================================================
Copyright (c) [2025] [FifthTry, Inc and Contributors]

The Universal Permissive License (UPL), Version 1.0

Subject to the condition set forth below, permission is hereby granted to any
person obtaining a copy of this software, associated documentation and/or data
(collectively the "Software"), free of charge and under any and all copyright
rights in the Software, and any and all patent rights owned or freely
licensable by each licensor hereunder covering either (i) the unmodified
Software as contributed to or provided by such licensor, or (ii) the Larger
Works (as defined below), to deal in both

(a) the Software, and
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
one is included with the Software (each a "Larger Work" to which the Software
is contributed by such licensors),

without restriction, including without limitation the rights to copy, create
derivative works of, display, perform, and distribute the Software and make,
use, sell, offer for sale, import, export, have made, and have sold the
Software and the Larger Work(s), and to sublicense the foregoing rights on
either these or other terms.

This license is subject to the following condition:
The above copyright notice and either this complete permission notice or at
a minimum a reference to the UPL must be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<div align="center">

[![Contributors](https://img.shields.io/github/contributors/fastn-stack/fastn?color=dark-green)](https://github.com/fastn-stack/fastn/graphs/contributors)
[![Issues](https://img.shields.io/github/issues/fastn-stack/fastn)](https://github.com/fastn-stack/fastn/issues)
[![License](https://img.shields.io/github/license/fastn-stack/fastn)](https://github.com/fastn-stack/fastn/blob/main/LICENSE)
[![Discord](https://img.shields.io/discord/793929082483769345?logo=discord)](https://fastn.com/discord/)

</div>

<div align="center">
    <img src="assets/fastn.svg" width="150" alt="fastn"/>
</div>

# `fastn` - Full-stack Web Development Made Easy

`fastn` is a programming language and a web-framework for building user
interfaces and content-centric websites. `fastn` is easy to learn, especially
for non-programmers, but does not compromise on what you can build with it.

Install from https://fastn.com/install/ or download directly from [GitHub
Releases](https://github.com/fastn-stack/fastn/releases).

## Features

## Minimal Syntax

A Hello World program in `fastn`:

```ftd
;; comments begin with `;;`
;; save this file as index.ftd
-- ftd.text: Hello World! 😀
```

You'll also need a `FASTN.ftd` file that stores information about your fastn
package:

```ftd
-- import: fastn

;; your package name
-- fastn.package: my-first-fastn-package
```

Save these two files and run `fastn serve` from the project dir. Visit the
printed URL and you'll see "Hello World! 😀" printed in your browser.

In addition to `ftd.text`, other kernel components exist that helps you create
UIs. You can learn about them at https://fastn.com/kernel/.

You can create custom components on top of these kernel components:

```ftd
;; Component Definition
-- component card:
;; these are the arguments along with their types. `caption` is just string
;; with a special position
caption title:
;; `ftd.image-src` is a record type that allows you to specify two image urls,
;; for dark and light mode.
ftd.image-src background:
;; `body` is a `string` type but gets a special position to help you write
;; multi-line texts.
body description:

;; component body begins after a newline
-- ftd.column:

-- ftd.image:
src: $card.background

-- ftd.text: $card.title
role: h2

-- ftd.text: $card.description

-- end: ftd.column

-- end: card

;; This is how you call the `card` component
-- card: Hello world! **markdown is supported!**
;; `$fastn-assets` is a special import. See: https://fastn.com/assets/
background: $fastn-assets.files.images.fastn.svg

A `body` is just a `string` type but gets a special position to help you
write multi-line texts. And markdown is supported so I can 
[ask for donation!](https://fastn.com/donate/) ;)
```

If you had used `string` instead of `caption` and `body`, then you'd have to do:

```ftd
-- card: 
title: Hello world! **markdown is supported!**
background: $fastn-assets.files.images.fastn.svg

-- card.body:

A `body` is just a `string` type but gets a special position to help you
write multi-line texts. And markdown is supported so I can 
[ask for donation!](https://fastn.com/donate/) ;)

-- end: card
```

You can learn more about built in data types at https://fastn.com/built-in-types/.

A short **language tour** is available at https://fastn.com/geeks/.

## Routing

`fastn` support file-system based routing. For the following fs hierarchy:

```
├── ednet
│   ├── intro.ftd
│   └── xray.ftd
├── fastn
│   ├── index.ftd
├── FASTN.ftd
├── index.ftd
├── new.png
```

`/ednet/{intro, xray}`, `/fastn/`, `/` and `/new.png` URLs will be served by
`fastn serve` webserver automatically.

`fastn` also supports [dynamic-urls](https://fastn.com/dynamic-urls/),
[sitemap](https://fastn.com/understanding-sitemap/-/build/) and,
[url-mappings](https://fastn.com/redirects/-/backend/).

## Processors

processors are executed on the server side, and can be used to fetch data from
APIs, databases, or any other source. They are used to collect data before
rendering it on the client side.

```ftd
-- import: fastn/processors

-- record user:
string email:
string name:

-- user my-user:
$processor$: processors.http
url: https://jsonplaceholder.typicode.com/users/1

-- ftd.text: $my-user.email
```

See https://fastn.com/http/ to learn more about the `http` and other processors.

## `fastn` for Static Sites

`fastn` websites can be compiled into static html, css and, js and can be
deployed on any static hosting providers like [Github
Pages](https://fastn.com/github-pages/) and
[Vercel](https://fastn.com/vercel/).

## More Features

- Support for custom backends using WASM and [`ft-sdk`](https://github.com/fastn-stack/ft-sdk/).
- Support for custom css and js. See https://fastn.com/use-js-css/.
- First class support for for web-components. See https://fastn.com/web-component/.
- Easy to migrate from a static site generator like 11ty, Hugo, etc.
- Built-in package management system, opinionated [design
  system](https://design-system.fifthtry.site/), dark mode support, designed for
  [responsive UIs](https://fastn.com/making-responsive-pages/). Oh My!


## `fastn` 0.5

We're currently working on `fastn` 0.5. It will add support for making
offline-first p2p apps based on [iroh](https://github.com/n0-computer/iroh) and
[automerge](https://github.com/automerge/automerge) along with some breaking
changes to the language.

To learn more, see:

- [0.5 ARCHITECTURE.md](https://github.com/fastn-stack/fastn/blob/main/v0.5/ARCHITECTURE.md).
- [Video discussion on YouTube](https://www.youtube.com/watch?v=H9d1Dn8Jn0I).
- [Existing github discussions](https://github.com/orgs/fastn-stack/discussions?discussions_q=is%3Aopen+label%3A0.5-brainstorm).

## FifthTry Hosting

We, [FifthTry](https://www.fifthtry.com) also offer our own hosting solution for
your static and dynamic sites. Using FifthTry hosting frees you from devops
needs, and you get a fully integrated, managed hosting solution, that a
non-programmers can use with ease.

## Contributors

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
  <tbody>
    <tr>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/Arpita-Jaiswal"><img src="https://avatars.githubusercontent.com/u/26044181?v=4?s=100" width="100px;" alt="Arpita Jaiswal"/><br /><sub><b>Arpita Jaiswal</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=Arpita-Jaiswal" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=Arpita-Jaiswal" title="Documentation">📖</a> <a href="#example-Arpita-Jaiswal" title="Examples">💡</a> <a href="#eventOrganizing-Arpita-Jaiswal" title="Event Organizing">📋</a> <a href="#ideas-Arpita-Jaiswal" title="Ideas, Planning, & Feedback">🤔</a> <a href="#maintenance-Arpita-Jaiswal" title="Maintenance">🚧</a> <a href="#mentoring-Arpita-Jaiswal" title="Mentoring">🧑‍🏫</a> <a href="https://github.com/fastn-stack/fastn/pulls?q=is%3Apr+reviewed-by%3AArpita-Jaiswal" title="Reviewed Pull Requests">👀</a> <a href="#tool-Arpita-Jaiswal" title="Tools">🔧</a> <a href="https://github.com/fastn-stack/fastn/commits?author=Arpita-Jaiswal" title="Tests">⚠️</a> <a href="#tutorial-Arpita-Jaiswal" title="Tutorials">✅</a> <a href="#video-Arpita-Jaiswal" title="Videos">📹</a> <a href="#blog-Arpita-Jaiswal" title="Blogposts">📝</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://www.fifthtry.com"><img src="https://avatars.githubusercontent.com/u/58662?v=4?s=100" width="100px;" alt="Amit Upadhyay"/><br /><sub><b>Amit Upadhyay</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=amitu" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=amitu" title="Documentation">📖</a> <a href="#example-amitu" title="Examples">💡</a> <a href="#eventOrganizing-amitu" title="Event Organizing">📋</a> <a href="#ideas-amitu" title="Ideas, Planning, & Feedback">🤔</a> <a href="#maintenance-amitu" title="Maintenance">🚧</a> <a href="#mentoring-amitu" title="Mentoring">🧑‍🏫</a> <a href="https://github.com/fastn-stack/fastn/pulls?q=is%3Apr+reviewed-by%3Aamitu" title="Reviewed Pull Requests">👀</a> <a href="#tool-amitu" title="Tools">🔧</a> <a href="https://github.com/fastn-stack/fastn/commits?author=amitu" title="Tests">⚠️</a> <a href="#tutorial-amitu" title="Tutorials">✅</a> <a href="#video-amitu" title="Videos">📹</a> <a href="#blog-amitu" title="Blogposts">📝</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/Heulitig"><img src="https://avatars.githubusercontent.com/u/106665190?v=4?s=100" width="100px;" alt="Rithik Seth"/><br /><sub><b>Rithik Seth</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=Heulitig" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=Heulitig" title="Documentation">📖</a> <a href="https://github.com/fastn-stack/fastn/commits?author=Heulitig" title="Tests">⚠️</a> <a href="#ideas-Heulitig" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/fastn-stack/fastn/pulls?q=is%3Apr+reviewed-by%3AHeulitig" title="Reviewed Pull Requests">👀</a> <a href="#maintenance-Heulitig" title="Maintenance">🚧</a> <a href="#blog-Heulitig" title="Blogposts">📝</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/gsalunke"><img src="https://avatars.githubusercontent.com/u/68585007?v=4?s=100" width="100px;" alt="Ganesh Salunke"/><br /><sub><b>Ganesh Salunke</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=gsalunke" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=gsalunke" title="Documentation">📖</a> <a href="https://github.com/fastn-stack/fastn/commits?author=gsalunke" title="Tests">⚠️</a> <a href="#ideas-gsalunke" title="Ideas, Planning, & Feedback">🤔</a> <a href="#mentoring-gsalunke" title="Mentoring">🧑‍🏫</a> <a href="https://github.com/fastn-stack/fastn/pulls?q=is%3Apr+reviewed-by%3Agsalunke" title="Reviewed Pull Requests">👀</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/priyanka9634"><img src="https://avatars.githubusercontent.com/u/102957031?v=4?s=100" width="100px;" alt="Priyanka"/><br /><sub><b>Priyanka</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=priyanka9634" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=priyanka9634" title="Documentation">📖</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/gargajit"><img src="https://avatars.githubusercontent.com/u/118595104?v=4?s=100" width="100px;" alt="Ajit Garg"/><br /><sub><b>Ajit Garg</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=gargajit" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=gargajit" title="Documentation">📖</a> <a href="#blog-gargajit" title="Blogposts">📝</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/AbrarNitk"><img src="https://avatars.githubusercontent.com/u/17473503?v=4?s=100" width="100px;" alt="Abrar Khan"/><br /><sub><b>Abrar Khan</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=AbrarNitk" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=AbrarNitk" title="Documentation">📖</a> <a href="https://github.com/fastn-stack/fastn/pulls?q=is%3Apr+reviewed-by%3AAbrarNitk" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/fastn-stack/fastn/commits?author=AbrarNitk" title="Tests">⚠️</a></td>
    </tr>
    <tr>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/sharmashobhit"><img src="https://avatars.githubusercontent.com/u/1982566?v=4?s=100" width="100px;" alt="Shobhit Sharma"/><br /><sub><b>Shobhit Sharma</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=sharmashobhit" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=sharmashobhit" title="Documentation">📖</a> <a href="https://github.com/fastn-stack/fastn/commits?author=sharmashobhit" title="Tests">⚠️</a></td>
      <td align="center" valign="top" width="14.28%"><a href="http://fifthtry.com"><img src="https://avatars.githubusercontent.com/u/106665143?v=4?s=100" width="100px;" alt="Aviral Verma"/><br /><sub><b>Aviral Verma</b></sub></a><br /><a href="https://github.com/fastn-stack/fastn/commits?author=AviralVerma13" title="Code">💻</a> <a href="https://github.com/fastn-stack/fastn/commits?author=AviralVerma13" title="Documentation">📖</a> <a href="https://github.com/fastn-stack/fastn/commits?author=AviralVerma13" title="Tests">⚠️</a> <a href="#ideas-AviralVerma13" title="Ideas, Planning, & Feedback">🤔</a></td>
    </tr>
  </tbody>
</table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

## License

This project is licensed under the terms of the **UPL-1.0**.


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

We are in early development phase of this project, and only support the latest release. We request you to keep updating
`fastn` periodically. `fastn` is backed by [FifthTry](https://fifthtry.com), and we intend to switch to a longer support cycle soon.

## Reporting a Vulnerability

To report any security vulnerability with `fastn` and any of the related projects, please send a mail to 
`security@fifthtry.com`.


================================================
FILE: WINDOWS_INSTALLER.md
================================================
# Fastn Windows Installer

## Introduction

The Windows installer for Fastn is built using NSIS (Nullsoft Scriptable Install System), a popular tool for creating Windows installers. NSIS is configured using its own scripting language. The configuration script is named `install.nsi` and can be found in the root folder. Some changes were made in the `release.yml`, which are mentioned below. Additionally, an icon for the installer named `fastn.ico` was added to the root folder.

## Changes Made

1. Updated the `release.yml` file to incorporate Windows installer support for the Fastn executable.
2. Integrated NSIS into the build process using the `makensis` GitHub Action. This action allows the execution of NSIS scripts during the build workflow.
3. Added the `install.nsi` script to the root folder of the Fastn project. This script configures the NSIS installer.
4. Some other important details:
    - The installer uses the NSIS MUI.
    - The color scheme is set to a dark color scheme to match the color scheme of the Fastn website:
      ```nsi
      !define MUI_INSTFILESPAGE_COLORS "FFFFFF 000000"
      !define MUI_BGCOLOR 000000
      !define MUI_TEXTCOLOR ffffff
      ```
    - The default icon is replaced with `fastn.ico`.
    ```nsi
    !define MUI_ICON "fastn.ico"
    ```
    - We are using version 3 of NSIS.

## Installer Functionality

The Fastn installer performs the following tasks:

1. Shows a Welcome and License Page.
2. Extracts all necessary files to either the default location (Program Files) or a user-defined folder.
3. Checks if the required path variable is already set up on the system. If not, it automatically configures the correct path variable to ensure seamless execution of Fastn without any issues.

## Code Changes

The following code in the `release-windows` job is responsible for building the installer from the executable built by `cargo` in the previous step:

```yaml
- name: Download EnVar Plugin for NSIS
  uses: carlosperate/download-file-action@v1.0.3
  with:
    file-url: https://nsis.sourceforge.io/mediawiki/images/7/7f/EnVar_plugin.zip
    file-name: envar_plugin.zip
    location: ${{ github.workspace }}
- name: Extract EnVar plugin
  run: 7z x -o"${{ github.workspace }}/NSIS_Plugins" "${{ github.workspace }}/envar_plugin.zip"
- name: Create installer
  uses: joncloud/makensis-action@v4
  with:
    arguments: /V3 /DCURRENT_WD=${{ github.workspace }} /DVERSION=${{ github.event.inputs.releaseTag }}
    additional-plugin-paths: ${{ github.workspace }}/NSIS_Plugins/Plugins
- uses: actions/upload-artifact@v2
  with:
    name: windows_x64_installer.exe
    path: windows_x64_installer.exe
```

Explanation:

1. Download the EnVar Plugin for NSIS, which is required for correctly configuring path variables in Windows.
2. Extract the plugin to the appropriate location.
3. Create the installer executable by specifying the following inputs:
   - `CURRENT_WD`: The current Github Working Directory.
   - `VERSION`: The release tag.

In the `create-release` job, we download the `windows_x64_installer.exe` artifact and rename it to `fastn_setup`. In the next step, it is added to the `artifacts` list as part of the files to be released.

================================================
FILE: clift/Cargo.toml
================================================
[package]
name = "clift"
version = "0.1.6"
edition.workspace = true
rust-version.workspace = true

[dependencies]
clap.workspace = true
ignore.workspace = true
reqwest.workspace = true
serde.workspace = true
serde_json.workspace = true
sha2.workspace = true
thiserror.workspace = true
tokio.workspace = true


================================================
FILE: clift/src/api/commit_upload.rs
================================================
fn endpoint() -> String {
    clift::api::endpoint("commit-upload")
}

#[derive(serde::Serialize)]
pub struct CommitUploadRequest {
    site: String,
    upload_session_id: i64,
    tejar_file_id: Option<i64>,
}

#[derive(Debug, thiserror::Error)]
pub enum CommitUploadError {
    #[error("cant call api: {0}")]
    CantCallAPI(#[from] reqwest::Error),
}

pub async fn commit_upload(
    site_slug: &str,
    data: &clift::api::InitiateUploadResponse,
    update_token: &clift::utils::UpdateToken,
) -> Result<(), CommitUploadError> {
    let response = clift::utils::call_api(
        reqwest::Client::new()
            .post(clift::api::commit_upload::endpoint())
            .json(&CommitUploadRequest {
                site: site_slug.to_string(),
                upload_session_id: data.upload_session_id,
                tejar_file_id: data.tejar_file_id,
            }),
        update_token,
    )
    .await?;

    if !response.status().is_success() {
        todo!("response.text(): {:?}", response.text().await)
    }

    Ok(())
}


================================================
FILE: clift/src/api/initiate_upload.rs
================================================
fn endpoint() -> String {
    clift::api::endpoint("initiate-upload")
}

#[derive(serde::Serialize)]
pub enum InitiateUploadRequest {
    Folder {
        site: String,
        files: Vec<ContentToUpload>,
        folder: String,
        dry_run: bool,
    },
    File {
        site: String,
        file: ContentToUpload,
        dry_run: bool,
    },
}

impl InitiateUploadRequest {
    pub fn get_site(&self) -> String {
        match self {
            InitiateUploadRequest::Folder { site, .. }
            | InitiateUploadRequest::File { site, .. } => site.clone(),
        }
    }
    pub fn is_dry_run(&self) -> bool {
        match self {
            InitiateUploadRequest::Folder { dry_run, .. }
            | InitiateUploadRequest::File { dry_run, .. } => *dry_run,
        }
    }
}

#[derive(serde::Deserialize, Debug)]
pub struct InitiateUploadResponse {
    pub new_files: Vec<String>,
    pub updated_files: Vec<String>,
    #[serde(default)]
    pub deleted_files: Vec<String>,
    pub upload_session_id: i64,
    pub tejar_file_id: Option<i64>,
    pub pre_signed_request: Option<PreSignedRequest>,
}

#[derive(serde::Deserialize, Clone, Debug)]
pub struct PreSignedRequest {
    pub url: String,
    pub method: String,
    pub headers: std::collections::HashMap<String, String>,
}

#[derive(Debug, serde::Serialize)]
pub struct ContentToUpload {
    pub file_name: String,   // name of the file
    pub sha256_hash: String, // hash of the file
    pub file_size: usize,    // size of the file
}

#[derive(Debug, thiserror::Error)]
pub enum InitiateUploadError {
    #[error("cant call api: {0}")]
    CantCallAPI(#[from] reqwest::Error),
    #[error("cant read body during error: {0}")]
    CantReadBodyDuringError(reqwest::Error),
    #[error("got error from api: {0}")]
    APIError(String),
    #[error("cant parse json: {0}")]
    CantParseJson(#[from] serde_json::Error),
    #[error("got failure from ft: {0:?}")]
    GotFailure(std::collections::HashMap<String, String>),
}

pub async fn initiate_upload(
    to_upload: clift::api::InitiateUploadRequest,
    update_token: &clift::utils::UpdateToken,
) -> Result<InitiateUploadResponse, InitiateUploadError> {
    let response = clift::utils::call_api(
        reqwest::Client::new()
            .post(clift::api::initiate_upload::endpoint())
            .json(&to_upload),
        update_token,
    )
    .await
    .map_err(InitiateUploadError::CantCallAPI)?;

    if !response.status().is_success() {
        return Err(InitiateUploadError::APIError(
            response
                .text()
                .await
                .map_err(InitiateUploadError::CantReadBodyDuringError)?,
        ));
    }

    let json: clift::api::ApiResponse<InitiateUploadResponse> = response.json().await?;

    if !json.success {
        // TODO: remove unwrap
        return Err(InitiateUploadError::GotFailure(json.errors.unwrap()));
    }

    Ok(json.data.unwrap()) // TODO: remove unwrap
}


================================================
FILE: clift/src/api/mod.rs
================================================
pub mod commit_upload;
pub mod initiate_upload;

pub use commit_upload::{CommitUploadError, CommitUploadRequest, commit_upload};
pub use initiate_upload::{
    ContentToUpload, InitiateUploadError, InitiateUploadRequest, InitiateUploadResponse,
    PreSignedRequest, initiate_upload,
};

pub const ENDPOINT: &str = "https://www.fifthtry.com";

#[derive(serde::Deserialize)]
pub struct ApiResponse<T> {
    pub data: Option<T>,
    pub errors: Option<std::collections::HashMap<String, String>>,
    pub success: bool,
}

pub fn endpoint(name: &str) -> String {
    format!(
        "{prefix}/ft2/api/{name}/",
        prefix = std::env::var("DEBUG_API_FIFTHTRY_COM")
            .as_ref()
            .map(|s| s.as_str())
            .unwrap_or_else(|_| clift::api::ENDPOINT)
    )
}


================================================
FILE: clift/src/commands/mod.rs
================================================
mod upload;

pub use upload::{UploadError, upload_file, upload_folder};


================================================
FILE: clift/src/commands/upload.rs
================================================
pub async fn upload_file(
    site_slug: &str,
    file: &str,
    dry_run: bool,
) -> Result<(), crate::commands::upload::UploadError> {
    let current_dir = std::env::current_dir().map_err(|_| UploadError::CanNotReadCurrentDir)?;
    let file = clift::utils::path_to_content(&current_dir, &current_dir.join(file)).await?;
    upload(
        &current_dir,
        clift::api::InitiateUploadRequest::File {
            site: site_slug.to_string(),
            file,
            dry_run,
        },
    )
    .await
}

pub async fn upload_folder(
    site_slug: &str,
    folder: &str,
    dry_run: bool,
) -> Result<(), crate::commands::upload::UploadError> {
    let current_dir = std::env::current_dir().map_err(|_| UploadError::CanNotReadCurrentDir)?;
    let files = clift::utils::get_local_files(&current_dir, folder).await?;
    upload(
        &current_dir,
        clift::api::InitiateUploadRequest::Folder {
            site: site_slug.to_string(),
            files,
            folder: folder.to_string(),
            dry_run,
        },
    )
    .await
}

pub async fn upload(
    current_dir: &std::path::Path,
    to_upload: clift::api::InitiateUploadRequest,
) -> Result<(), UploadError> {
    let update_token = clift::utils::update_token()?;
    println!("Initialing Upload....");

    let site_slug = to_upload.get_site();
    let dry_run = to_upload.is_dry_run();
    let data = clift::api::initiate_upload(to_upload, &update_token).await?;

    if dry_run {
        for file in data.new_files.iter() {
            println!("New File: {file}");
        }
        for file in data.updated_files.iter() {
            println!("Updated File: {file}");
        }
        for file in data.deleted_files.iter() {
            println!("Deleted File: {file}");
        }
        println!("Dry Run Done");
        return Ok(());
    }

    if let (Some(pre_signed_request), Some(tejar_file_id)) =
        (data.pre_signed_request.clone(), data.tejar_file_id)
    {
        upload_(&data, pre_signed_request, tejar_file_id, current_dir).await?;
    } else {
        println!("Nothing to upload!");
    }

    println!("Committing Upload...");

    clift::api::commit_upload(site_slug.as_str(), &data, &update_token).await?;

    println!("Upload Done");
    Ok(())
}

async fn upload_(
    data: &clift::api::InitiateUploadResponse,
    pre_signed_request: clift::api::PreSignedRequest,
    tejar_file_id: i64,
    current_dir: &std::path::Path,
) -> Result<(), UploadError> {
    let mut uploader = match std::env::var("DEBUG_USE_TEJAR_FOLDER") {
        Ok(path) => {
            let path = std::path::PathBuf::from(path).join(format!("{tejar_file_id}.tejar"));
            println!("DEBUG_USE_TEJAR_FOLDER: {path:?}");
            clift::utils::Uploader::debug(&path).await?
        }
        Err(_) => {
            println!("using s3");
            clift::utils::Uploader::s3(pre_signed_request)
        }
    };

    upload_files(
        &mut uploader,
        data.new_files.as_slice(),
        current_dir,
        "Added",
    )
    .await?;
    upload_files(
        &mut uploader,
        data.updated_files.as_slice(),
        current_dir,
        "Updated",
    )
    .await?;
    for file in data.deleted_files.iter() {
        println!("{file}.... Deleted");
    }

    Ok(uploader.commit().await?)
}

async fn upload_files(
    uploader: &mut clift::utils::Uploader,
    files: &[String],
    current_dir: &std::path::Path,
    status: &str,
) -> Result<(), UploadError> {
    for file_name in files.iter() {
        uploader.upload(&current_dir.join(file_name)).await?;
        println!("{file_name}.... {status}");
    }

    Ok(())
}

#[derive(thiserror::Error, Debug)]
pub enum UploadError {
    #[error("CanNotReadCurrentDir")]
    CanNotReadCurrentDir,

    #[error("Cant Read Tokens: {0}")]
    CantReadTokens(#[from] clift::utils::UpdateTokenError),

    #[error("CantInitiateUpload: {0}")]
    CantInitiateUpload(#[from] clift::api::InitiateUploadError),

    #[error("CantCommitUpload: {0}")]
    CantCommitUpload(#[from] clift::api::CommitUploadError),

    #[error("CantUpload: {0}")]
    CantUpload(#[from] clift::utils::UploaderError),

    #[error("cant get local files: {0}")]
    CantGetLocalFiles(#[from] clift::utils::GetLocalFilesError),
}


================================================
FILE: clift/src/lib.rs
================================================
#![deny(unused_crate_dependencies)]

extern crate self as clift;

pub mod commands;

pub mod api;
pub mod utils;

pub fn attach_cmd(cmd: clap::Command) -> clap::Command {
    cmd.subcommand(
        clap::Command::new("upload")
            .about("Uploads files in current directory to www.fifthtry.com.")
            .arg(clap::arg!(<"site-slug"> "The site-slug of this site.").required(true))
            .arg(clap::arg!(--file <FILE> "Only upload a single file.").required(false))
            .arg(clap::arg!(--folder <FOLDER> "Only upload a single folder.").required(false))
            .arg(clap::arg!(--"dry-run" "Do not actually upload anything.")),
    )
}

pub async fn upload(matches: &clap::ArgMatches) {
    let upload = matches
        .subcommand_matches("upload")
        .expect("this function is only called after this check in main");
    let site = upload
        .get_one::<String>("site-slug")
        .expect("this is a required argument");
    let file = upload.get_one::<String>("file");
    let folder = upload.get_one::<String>("folder");
    let dry_run = *upload.get_one::<bool>("dry-run").unwrap_or(&false);

    if file.is_some() && folder.is_some() {
        eprintln!("both --file and --folder can not be specified");
        return;
    }

    if let Some(file) = file {
        if let Err(e) = clift::commands::upload_file(site, file, dry_run).await {
            eprintln!("Upload failed: {e}");
            std::process::exit(1);
        }
        return;
    }

    if let Some(folder) = folder {
        if let Err(e) = clift::commands::upload_folder(site, folder, dry_run).await {
            eprintln!("Upload failed: {e}");
            std::process::exit(1);
        }

        return;
    }

    if let Err(e) = clift::commands::upload_folder(site, "", dry_run).await {
        eprintln!("Upload failed: {e}");
        std::process::exit(1);
    }
}


================================================
FILE: clift/src/utils/call_api.rs
================================================
pub async fn call_api(
    mut request_builder: reqwest::RequestBuilder,
    token: &clift::utils::UpdateToken,
) -> reqwest::Result<reqwest::Response> {
    match token {
        clift::utils::UpdateToken::SiteToken(clift::utils::SiteToken(token)) => {
            request_builder = request_builder.header("X-FIFTHTRY-SITE-WRITE-TOKEN", token);
        }
        clift::utils::UpdateToken::GithubToken(token) => {
            request_builder = request_builder
                .header(
                    "X-FIFTHTRY-GH-ACTIONS-ID-TOKEN-REQUEST-TOKEN",
                    token.token.clone(),
                )
                .header(
                    "X-FIFTHTRY-GH-ACTIONS-ID-TOKEN-REQUEST-URL",
                    token.url.clone(),
                );
        }
    }
    request_builder.send().await
}


================================================
FILE: clift/src/utils/generate_hash.rs
================================================
// Warning: this function is used in `ft` too which checks the changes in the
// file content and hence ensures that only diff file is uploaded.
// If this function ever needed to be changed then make sure to change the
// corresponding function in `ft` too.
// https://github.com/FifthTry/ft/blob/main/ft-db/src/utils.rs
// This hash can be created using cli command:
// `shasum -a 256 <file-path>` or `echo -n "<string>" | shasum -a 256`
pub fn generate_hash(content: impl AsRef<[u8]>) -> String {
    use sha2::Digest;
    use sha2::digest::FixedOutput;
    let mut hasher = sha2::Sha256::new();
    hasher.update(content);
    format!("{:X}", hasher.finalize_fixed())
}


================================================
FILE: clift/src/utils/get_local_files.rs
================================================
#[derive(Debug, thiserror::Error)]
pub enum GetLocalFilesError {
    #[error("CanNotReadFile {1}: {0}")]
    CantReadFile(std::io::Error, String),
}

pub async fn get_local_files(
    current_dir: &std::path::Path,
    folder: &str,
) -> Result<Vec<clift::api::ContentToUpload>, GetLocalFilesError> {
    let ignore_path = ignore::WalkBuilder::new(current_dir.join(folder))
        .hidden(false)
        .git_ignore(true)
        .git_exclude(true)
        .git_global(true)
        .ignore(true)
        .parents(true)
        .build();

    let mut files = vec![];
    for path in ignore_path.flatten() {
        if path.path().is_dir() {
            continue;
        }

        let content = path_to_content(current_dir, path.path()).await?;

        if content.file_name.starts_with(".git/")
            || content.file_name.starts_with(".github/")
            || content.file_name.eq(".gitignore")
        {
            continue;
        }

        files.push(content);
    }

    Ok(files)
}

pub async fn path_to_content(
    current_dir: &std::path::Path,
    path: &std::path::Path,
) -> Result<clift::api::ContentToUpload, GetLocalFilesError> {
    let path_without_package_dir = path
        .to_str()
        .unwrap()
        .to_string()
        .trim_start_matches(current_dir.to_str().unwrap())
        .trim_start_matches('/')
        .to_string();

    let content = tokio::fs::read(path)
        .await
        .map_err(|e| GetLocalFilesError::CantReadFile(e, path.to_string_lossy().to_string()))?;

    Ok(clift::api::ContentToUpload {
        file_name: path_without_package_dir,
        // TODO: create the hash using file stream instead of reading entire
        //       file content into memory
        sha256_hash: clift::utils::generate_hash(&content),
        file_size: content.len(),
    })
}


================================================
FILE: clift/src/utils/github_token.rs
================================================
pub struct GithubOidcActionToken {
    pub token: String,
    pub url: String,
}

#[derive(Debug, thiserror::Error)]
pub enum GithubActionIdTokenRequestError {
    #[error("Token missing {0}")]
    TokenMissing(std::env::VarError),
    #[error("Url missing {0}")]
    UrlMissing(std::env::VarError),
}

pub fn github_oidc_action_token() -> Result<GithubOidcActionToken, GithubActionIdTokenRequestError>
{
    let token = std::env::var("ACTIONS_ID_TOKEN_REQUEST_TOKEN")
        .map_err(GithubActionIdTokenRequestError::TokenMissing)?;
    let url = std::env::var("ACTIONS_ID_TOKEN_REQUEST_URL")
        .map_err(GithubActionIdTokenRequestError::UrlMissing)?;

    Ok(GithubOidcActionToken { token, url })
}


================================================
FILE: clift/src/utils/mod.rs
================================================
mod call_api;
mod generate_hash;
mod get_local_files;
mod github_token;
mod site_token;
mod update_token;
mod uploader;

pub use call_api::call_api;
pub use generate_hash::generate_hash;
pub use get_local_files::{GetLocalFilesError, get_local_files, path_to_content};
pub use github_token::{
    GithubActionIdTokenRequestError, GithubOidcActionToken, github_oidc_action_token,
};
pub use site_token::SiteToken;
pub use update_token::{UpdateToken, UpdateTokenError, update_token};
pub use uploader::{Uploader, UploaderError};


================================================
FILE: clift/src/utils/site_token.rs
================================================
pub struct SiteToken(pub String);

impl SiteToken {
    pub fn from_env() -> Result<Self, std::env::VarError> {
        Ok(Self(std::env::var("FIFTHTRY_SITE_WRITE_TOKEN")?))
    }
}


================================================
FILE: clift/src/utils/update_token.rs
================================================
pub enum UpdateToken {
    SiteToken(clift::utils::SiteToken),
    GithubToken(clift::utils::GithubOidcActionToken),
}

#[derive(Debug, thiserror::Error)]
pub enum UpdateTokenError {
    #[error("SiteToken: {0}")]
    SiteToken(#[from] std::env::VarError),
    #[error("GithubToken: {0}")]
    GithubToken(#[from] clift::utils::GithubActionIdTokenRequestError),
}

pub fn update_token() -> Result<UpdateToken, UpdateTokenError> {
    match clift::utils::github_oidc_action_token() {
        Ok(token) => Ok(UpdateToken::GithubToken(token)),
        Err(clift::utils::GithubActionIdTokenRequestError::TokenMissing(e)) => {
            eprintln!("Github OIDC Token missing: {e}, trying SiteToken...");
            Ok(UpdateToken::SiteToken(clift::utils::SiteToken::from_env()?))
        }
        Err(e) => Err(e.into()),
    }
}


================================================
FILE: clift/src/utils/uploader.rs
================================================
pub enum Uploader {
    File(tokio::fs::File),
    S3(clift::api::PreSignedRequest, Vec<u8>),
}

#[derive(thiserror::Error, Debug)]
pub enum UploaderError {
    #[error("io error {0}")]
    IOError(#[from] std::io::Error),
    #[error("reqwest error {0}")]
    S3PutRequestSendError(#[from] reqwest::Error),
    #[error("reqwest error {0}")]
    S3PutError(reqwest::StatusCode, String),
}

impl Uploader {
    pub async fn debug(path: &std::path::Path) -> Result<Uploader, UploaderError> {
        let file = tokio::fs::File::create(path).await?;
        Ok(Uploader::File(file))
    }

    pub fn s3(sr: clift::api::PreSignedRequest) -> Uploader {
        Uploader::S3(sr, vec![])
    }

    pub async fn upload(&mut self, path: &std::path::Path) -> Result<(), UploaderError> {
        use tokio::io::AsyncWriteExt;
        match self {
            Uploader::File(file) => file.write_all(&tokio::fs::read(path).await?).await?,
            Uploader::S3(_, v) => {
                v.append(&mut tokio::fs::read(path).await?);
            }
        }
        Ok(())
    }

    pub async fn commit(&mut self) -> Result<(), UploaderError> {
        if let Uploader::S3(sr, v) = self {
            let client = reqwest::Client::new();
            let mut request = client.request(
                reqwest::Method::from_bytes(sr.method.as_bytes()).unwrap(),
                &sr.url,
            );
            for (k, v) in sr.headers.iter() {
                request = request.header(k, v);
            }

            let resp = request.body(v.clone()).send().await?;
            let status_code = resp.status();
            let body = resp.text().await?;

            if status_code.is_success() {
                println!("upload done: {status_code}");
            } else {
                println!("upload failed: {status_code}");
                println!("body: {}", body.as_str());
                return Err(UploaderError::S3PutError(status_code, body));
            }
        }

        Ok(())
    }
}


================================================
FILE: design/README.md
================================================
# FPM Design

Download art from https://github.com/vitiral/artifact/releases/tag/1.0.1

Unzip the `art` binary and move to ~/bin/. Ensure `.zshrc` says 
`export PATH=$PATH:$HOME/bin`.

On Mac if you get error from OS, locate the file in "Finder", and then right click
and select "Open", it will show a warning and "Open" button, click Open and close the
newly launched terminal. Go back to shell and run `art` and it will work now.

Run `art serve`.

If you add a new file, you will have to restart the `art serve` server and reload
the page in browser.

================================================
FILE: design/apps.toml
================================================
[REQ-app]
partof = [
    'REQ-package_manager-fpm_ftd',
    'REQ-package_manager-main',
    'REQ-purpose',
]
text = '''
A [[REQ-package_manager-dependency]] can be installed in a [[REQ-package_manager-main]] as an "app".

To do an `fpm.app` entry has to be added to [[REQ-package_manager-fpm_ftd]].

FPM has a feature for installing applications. A user can use a fpm package as
fpm apps also. An app can be installed multiple times on different urls. Each application are be isolated from each other. 


Consider a todo app, same app I can use for different purpose. 

- abrark.com/family-todos/
- abrark.com/work-todos/
- abrark.com/personal-todos/


FPM Apps feature will support to use fpm package as dependency while installing 
the application.

FPM Apps will support authentication with FPM `auth groups` and `identity`.

FPM Apps will support mount point url, where the app should be mounted in the 
browser.

While implementing FPM Apps feature we have to give a fpm processor to access 
the `apps`.

FPM Apps will support the `endpoint` in it, where the data will be 
stored of the different application.

FPM Apps will support the config

Questions: Will there be any difference b/w fpm dependency and fpm package to 
use in the application.

'''


================================================
FILE: design/cli.toml
================================================
[REQ-cli]
partof = 'REQ-purpose'
text = '''
FPM is shipped as a CLI tool.

It contains the following main comments:

- [[REQ-cli-version]]
- [[REQ-cli-serve]]
- [[REQ-cli-build]]'''

[REQ-cli-build]
partof = 'REQ-ssg'
text = '''
FPM is a [[REQ-ssg]] and `fpm build` is the main command to build a static site.

`fpm build` implements [[REQ-cli-build-download_on_demand]] feature.

`fpm build` also supports [[REQ-cli-build-base]] feature.

[[REQ-cli-build-ignore_failed]] `fpm build` can also be instructed to ignore failed files and continue building or to stop at first error.'''

[REQ-cli-serve]
partof = [
    'REQ-dynamic',
    'REQ-server',
]
text = '''
`fpm serve` runs a local HTTP server.

You can configure the port on which fpm cli listens using [[REQ-cli-serve-port]].

You can configure the IP on which the server binds: [[REQ-cli-serve-bind]].'''

[REQ-cli-version]
text = '`fpm` CLI can print its version number. '


================================================
FILE: design/design-system.toml
================================================
[REQ-design_system]
partof = 'REQ-purpose'
text = '''
FPM comes with a design system for ensuring websites authors can use our color scheme packages, font pairing packages etc to quickly create good looking website.

You can think of FPM design system as an alternative to material design system.'''

[REQ-design_system-color_scheme]
text = 'FPM lets you create color scheme packages, used to distribute color schemes.'

[REQ-design_system-font_pairings]
partof = 'REQ-font'
text = 'Font Pairings are packages to distribute font pairings. They use one or more [[REQ-font]]s as package dependency.'


================================================
FILE: design/dynamic.toml
================================================
[REQ-dynamic]
partof = [
    'REQ-purpose',
    'REQ-server',
    'REQ-ssg',
]
text = 'FPM normally serves the content of files in the package. But they can also serve dynamic pages. '


================================================
FILE: design/font.toml
================================================
[REQ-font]
partof = [
    'REQ-purpose',
    'REQ-server',
    'REQ-ssg',
]
text = '''
Websites powered by FPM need fonts. Normally people link to Google Fonts for serving fonts. FPM instead has a concept of font packages. 

Anyone can create a font package from a Google Font using [[REQ-font-import_script]].'''

[REQ-font-import_script]
text = 'We have a script which can convert any Google Font file to a fpm package.'


================================================
FILE: design/github.md
================================================
# How Does Github Login Work?

The auth related stuff is in `fastn_core::auth` module.

## Login

To login we send user to `/-/auth/login?provider=github&next=<optional redirect url>`.

The `next` can be used to send the user to arbitrary URL after successful signing.

We use `oauth2` crate for authentication with github.

## Callback URL

The callback URL is 

## CSRF Token

Are we CSRF safe? We are generating a CSRF token using `oauth2::CsrfToken::new_random` in 
`fastn_core::auth::github::login()`, but we are not checking it in `fastn_core::auth::github::callback()`. I think
we aught to, else we may be susceptible to CSRF. Not sure how someone can use CSRF in this context, but given
the library supports should too.

How would we verify? Easiest thing would be to store it in a cookie. This is what Django does, stores CSRF token in
cookie, and verifies that tokens match on POST request etc. 



================================================
FILE: design/js-runtime/README.md
================================================
# O.4 Release

- prototype stage
  - [x] bug: node issue
  - [x] amitu: quickjs issue
  - [x] arpita: bug: infinite loop
  - [x] arpita: list addition example
  - [x] container
  - [x] Avoid Dynamic CSS
  - [x] conditionalDom
  - [x] forLoopDom
  - [x] record
  - [ ] role
  - [ ] inherited
  - [ ] the new ast (full ftd ast which is input to JS generation)
  - [x] list index change example
  - [x] list of optional record
  - [ ] light/dark mode
  - [ ] responsive
  - [x] css class generation
  - [x] js generation
  - [ ] static markdown compiler
  - [ ] markdown as innerHTML
- release
  - [ ] port fastn cli to use 0.4
  - [ ] all the properties
- post release
  - [ ] proper markdown support
  - [ ] code block
    - [ ] `ds_<highlight_name>`
    - [ ] line numbering
    - [ ] code context
  - [ ] proper markup support
  - [ ] variable interpolation
  - [ ] use 0.4 in FASTN.ftd


================================================
FILE: design/js-runtime/building.md
================================================
# Building

## Debugging

```sh
python3 -m http.server
```

## To Run Manual Tests

Run this from `ftd` folder.

This will build `ftd/t/js/*.manual.html` files. You can open them in browser.

```sh
cargo test fastn_js_test_all -- --nocapture manual=true
```

If you want to build a single file: 

```sh
cargo test fastn_js_test_all -- --nocapture manual=true path=02
```


## To Run All Tests

```sh
cargo test fastn_js_test_all
```

## To "Fix" Tests

If the tests are failing because you have made changes to JS/HTML etc, and snapshotted HTMLs are wrong, run
the following to update the snapshot:

```shell
cargo test fastn_js_test_all -- --nocapture fix=true
```

You can also pass `path` argument to update a single file.

================================================
FILE: design/js-runtime/compilation.md
================================================
# Compilation Of FTD to JS

## Naming Convention

For every symbol in ftd, we will have a corresponding symbol in JS. We will use the following naming convention:
`fastn-community.github.io/doc-site/page` will be compiled to `fastn$$$community$github$io$$doc_site$$page`. We will 
replace the subdomain separators with `$` and path separators with `$$`. We will also replace `-` with `$$$`. We will
also use `$` for module to symbol separator. `fastn-community.github.io/doc-site/page.x` will be 
`fastn$$$community$github$io$$doc_site$$page$x`. GZip/deflate will compress these long variable names well. Or we will
use some standard JS minifier.

## Module

We compile all ftd modules into a single JS file. It is possible to compile each ftd module into separate js files, and
use JavaScript's module system. We are not considering it for now, to keep things simple.

## static Global Variable

A global variable, eg in:

```ftd
-- integer x: 10
-- ftd.integer: $x 
```

```js
(function() {
    function main(root) {
        // fastn_js::Ast::StaticVariable
        let x = 10;
        let i = fastn.create_kernel(root, fastn.ElementKind.Integer);
        i.set_property_static(fastn.Property.IntegerValue, x);
    }
})()
```


## Component Definition

Component definitions will be compiled into functions.


```ftd
-- integer $x: 10        ;; mutable
-- integer y: 20         ;; static
-- integer z: $x + $y   ;; formula 

-- foo: 
$x: $x

-- foo: 
$x: $x
 
-- ftd.integer: $z

-- component foo:
integer $x:

-- ftd.integer: { $foo.x + 20 }
$on-click$: { foo.x += 1 }

-- end: foo
```

```js
(function () {
    function main(root) {
        let x = fastn.mutable(10);
        let y = 20;

        let z = fastn.formula([x], function () {
            x.get() + y
        });

        let t = fastn_dom.createKernel(root, fastn_dom.ElementKind.Integer);
        t.set_property(fastn.Property.IntegerValue, [z], function () {
            z.get()
        });

        let f = foo(root, x);
        let f = foo(root, x);
    }

    function foo(root, x) {
        let i = fastn.create_kernel(root, fastn.ElementKind.Integer);

        i.add_event_handler(fastn.Event.Click, function () {
            x.set(x.get() + 1);
        });

        i.set_property(fastn.Property.IntegerValue, [x], function () {
            x.get() + 20
        });
    }
})();
```

## `fastn.Closure`

We are writing code in Rust, but its only for reference, code will actually be written in JS.

```rust
// formula and dynamic property
struct Closure {
    cached_value: Value,
    func: Fn,
    ui: Option<(Node, Property)>,
}

impl Closure {
    fn update_ui(&self) {
        if let Some(ui) = self.ui {
            ui.update(self.cached_value);
        }
    }
    fn update(&self) {
        self.cached_value = self.func();
        self.update_ui()
    }
}
```

## `fastn.Mutable`

```rust
struct Mutable {
    value: Value,
    closures: Vec<Closure>,
}

impl Multable {
    fn get(&self) -> Value {
        self.value
    }
    fn set(&self, new: Value) {
        self.value = new;
        for c in self.closures {
            c.call();
        }
    }
    fn add_closure(&mut self, closure: Closure) {
        self.closures.push(closure);
    }
}
```

## `Node.setStaticProperty()`

```js
function setStaticProperty(kind, value) {
    if (kind === fastn_dom.PropertyKind.Width_Px) {
        this.#node.style.width = value + "px";
    } else if (kind === fastn_dom.PropertyKind.Color_RGB) {
        this.#node.style.color = value;
    } else if (kind === fastn_dom.PropertyKind.IntegerValue) {
        this.#node.innerHTML = value;
    } else {
        throw ("invalid fastn_dom.PropertyKind: " + kind);
    }
}
```


## `Node.setDynamicProperty()`

```js
function setDynamicProperty(kind, deps, func) {
    let closure = fastn.closure(func).addNodeProperty(this, kind);
    for (let dep in deps) {
        deps[dep].addClosure(closure);
    }
}
```

## `fastn.formula()`

```js
function formula (deps, func) {
    let closure = fastn.closure(func);
    let mutable = new Mutable(closure.get());
    for (let dep in deps) {
        deps[dep].addClosure(new Closure(function () {
            closure.update();
            mutable.set(closure.get());
        }));
    }

    return mutable;
}
```


================================================
FILE: design/js-runtime/crate.md
================================================
# Rust Create: `fastn-js-runtime` (create alias `js_runtime`)

We will need a crate to convert the output of ftd interpreter to JavaScript file.


================================================
FILE: design/js-runtime/dynamic-class-css.md
================================================
# How are we adding CSS properties to a node?

Earlier, we used to provide inline styles in DOM node. Now, we are using 
class. 

So let's say we have ftd file something like this

```ftd
-- ftd.text: Hello Ritesh
padding.px: 40
```

So we'll create corresponding class for each property (`padding`). To do 
this, we have created a function in js `attachCss`. 

## `attachCss` function

This function creates a unique class for each property and value pair. 
For instance, for above property `padding`, this function would create class,
`p-0`, lets say, which looks like this

```css
.p-0 {
    padding: 40px;
}
```

### In `ssr` mode

When our program runs in `ssr` mode, then all these classes get collected by 
`fastn_dom.classes` object and later converted into String by `fastn_dom.
getClassesAsString` function.

### In `normal` mode

When our program runs in `normal` mode, i.e., `client-side rendering` mode, 
then this function, first, tries to find corresponding class, if found then 
it attach the class to the node else it dynamically creates a class and 
attach it.

The problem with this approach is what if the value of property is mutable 
or is a formula having mutable value passed as parameter.

Consider the following code:

```ftd
-- integer $i: 1

-- ftd.text: Hello
margin.px: $i
$on-click$: { i = i + 1; }
```

Now for every click on the node, it will create a new class. Since the 
property `margin` has mutable value `i` which has infinite cardinality which 
in turn results in creating lots of classes. This is also true for 
properties having value as formula having mutable variables passed as parameter.

To save us from this insanity, we'll check if we are passing such values to 
the property, then we'll refrain `attachCss` from creating class and just 
attach inline style.


## `fastn_dom.getClassesAsString` function

This function converts the classes and it's properties stored in `fastn_dom.
classes` object to a corresponding string.

```js
fastn_dom.classes = {"p-0": {property: "padding", value: "40px"}}
```
For the above entry, the function will generate the following string

```css
.p-0 {
    padding: 40px;
}
```


================================================
FILE: design/js-runtime/list.md
================================================
# How Do We Handle Lists?

```ftd
-- person $p: H

-- person list people:

-- person: A
-- person: B
-- person: $p

-- end: people

-- boolean $show-title: true

-- show-person: $p
for: ($p, $idx) in $people
idx: { idx + 2 }
show-title: $show-title

-- component show-person:
person $p:

-- ftd.text: $show-person.p.name

-- end: show-person
```

```js
let people = fastn.mutableList();

people.push({name: 'A'});
people.push({name: 'B'});

let show_title = fastn.mutable(true);

fastn.forLoop(root, people, [show_title], function(v) {
    // element_constructor
    return showPerson(v, show_title);
});


function showPerson(parent, person, show_title) {
    let n = fastn_dom.createKernel(parent, fastn_dom.ElementKind.Text);
    n.setDynamicProperty(fastn_dom.PropertyKind.StringValue, [person], function() {
        person.get()
    })
    n.done();
}
```

`fastn.forLoop` will create a fragment (`document.createDocumentFragment()`) and insert it in the root element. The
node returned by the constructor will be added in the fragment, not in the node.

Since a list should have common type, we should create a static class also, which has same signature as mutable, so code
works same on both static and mutable values.

We have to kind of modifications: a. modifying the elements of the list, b. modifying the list itself. 

To modify element of a list we do not have to do anything special. Eg if we modify `$p` things will just work, the
closure we passed in `showPerson()` would be triggered, it will return a new value, and DOM would get updated with that
value.

To modify the list itself, we have to call `push()`, `insertAt()` or `removeAt()` etc. If we add an element in the
end then also we have no issues, we create a new node. But if we insert an element in the middle, or we remove an
element from the middle. If the `element_constructor` is not dependent on the order, again we have no issue, we just
attach a new node in the fragment at the right place.

If the `element_constructor` is dependent on the order, then we have to do some work.


================================================
FILE: design/js-runtime/markdown.md
================================================
# How Are We Handling Markdown?

Markdown parser creates a tree, with items like h1, link, list etc. We currently render these elements in HTML and
ftd authors can not change the way they are rendered. Say if we want to add an on-hover property to every inline `code`
block in Markdown text, we can not do it.

The design allows you to provide your own component constructors for every element in markdown.

## `ftd.markdown` module

We are creating a new module, `ftd.markdown`:

```ftd
;; content of ftd/markdown.ftd
-- component h1:
caption title:

-- end: h1
```

This module defines a component for each element we can encounter in markdown, e.g. h1, link etc.

## `markdown` argument to `ftd.text`

We add a new argument to `ftd.text`:

```ftd
-- component ftd.text:
caption or body text:
module markdown: ftd.markdown 
```

## `ds.markdown` module

`ds.markdown` component will provide their own module, `ds`.

```ftd
-- component markdown:

-- ftd.text:
markdown: current-module

-- end: markdown
```

We are planning `current-package`, so `current-module` goes well with it.

## JavaScript

```js
let t = fastn.mutable("# hello world");
let m = fastn.markdown(parent, [t], {h1: h1, link: link, list: list});

// for each h1 h2 etc we have a function defined already
function h1() {
    
}
```

Markdown parser will create a tree, and call `h1` etc. on the tree to convert it to a DOM tree. If the text changes 
entire DOM tree will be re-created.

## Static Markdown Compilation

```md
# hello world

this is some text
```

```html
<h1>hello world</h1>
<p>this is some text</p>
```

```js
function main(parent) {
    let t = fastn_dom.createKernel(parent, fastn_dom.ElementKind.TextContainer);
    ds_h1(t, "hello world");
    ds_text(t, "this is some text");
}

function ds_h1() {}
function ds_text() {}
```


================================================
FILE: design/js-runtime/markup.md
================================================
# Markup

We have ftd specific extension to markdown, we call it `markup`. `markup` allows you to refer to specific component in
your text.

```ftd
-- ftd.text: hello {foo: markup}

-- component foo:
caption text:

;; body omitted

-- end: foo
```

We have called the component `foo` using the `markup syntax`, `{<component-name>: <component-argument>}`. The component
could be defined in current module, or can be imported. If imported the full name has to be used, eg `foo.bar`. The
`<component-argument>` is passed as `caption` to the component, and if the component has marked the caption optional,
or provided a default value for caption, the `<component-argument>` can be omitted, e.g. `{foo}`.

Currently the `markup` syntax does not allow you to pass any other argument, other than `caption`.

## Parsing Markup In Frontend

We are going to support markup syntax on dynamically constructed string, so frontend can generate strings, which may
refer to components which may not be present in the page at all. To ensure this does not happen we have to either place
some restrictions on the components you can use in markup, or we have to download component definitions on demand.

We are currently not considering download on demand. We are going to place restrictions on the components you can use.

## `always-include`

In normal mode we use tree shaking, any component that is not called when the page is getting rendered on the server
is not included in the bundle. We are going to allow a marker, `-- always-include: foo`, which will ensure that `foo`
is always included in the bundle.

## Missing Component

We will add `misssing-component` to `ftd.markdown` module, which will render the text with a red background. `doc-site`
etc can change the style to fit their theme.

## Choice 1: Markup In All Strings

If we allow markup etc in all strings, we will have to maintain [registry](registry.md). This is "registry approach for
markup etc".

## Choice 2: Static Strings Markup

If we allow markup, markdown, variable interpolation etc only in static strings (strings that were part of original ftd
document), we can handle markup etc differently:

```js
function main(parent) {
    let t = fastn_dom.createKernel(parent, fastn_dom.ElementKind.TextContainer);
    fastn_dom.appendProperty(fastn_dom.PropertyKind.TextSpan, "hello ");
    foo(t, "markup");
}

function foo(parent, text) {
    // ...    
}
```

This is "static compilation approach for markup etc".

## Decision: Static Compilation Only in 0.4

For keeping our life simple we will use this approach. We will not have to write parser for markup etc in JS, nor we 
will have to write, debug the registry related code. If this proves to be too limiting we will review this in later
releases.

It looks like markup etc in dynamic string is only needed in meta kind of applications, like creating frameworks etc,
instead of direct application logic. We maybe wrong, but we are picking the simpler approach for now.


================================================
FILE: design/js-runtime/registry.md
================================================
# Component and Variable Registry

We are generating JS like this:

```js
function main (root) {
    let x = fastn.mutable(10);
    let y = 20;
    let z = fastn.formula([x], function () { return x.get() * y; })
    foo(root, x);
    foo(root, x);
    let i = fastn_dom.createKernel(root, fastn_dom.ElementKind.Integer);
    i.setProperty(fastn_dom.PropertyKind.IntegerValue, z);
    i.done();
}

function foo(root, x) {
    let i = fastn_dom.createKernel(root, fastn_dom.ElementKind.Integer);
    i.setDynamicProperty(fastn_dom.PropertyKind.IntegerValue, [x], function () { return x.get() + 20; });
    i.setStaticProperty(fastn_dom.PropertyKind.Color_RGB, "red");
    i.addEventHandler(fastn_dom.Event.Click, function () {
        x.set(x.get() + 1);
    });
    i.done();
}
```

As you see, when we need to refer to `x`, we directly refer to the variable `x`. When we need to refer to `foo`, we call
the function named `foo` in current scope.

All the globals across all modules are initialised in the `main()` function. All the components are converted to 
functions. This is all done at compile time, when the JS is generated.

For resolving components used in [markup](markup.md), and for doing [variable interpolation](variable-interpolation.md),
we will need to resolve variables and components at runtime. We will do this by maintaining a registry of all the 
variables and components.

```js
let foo = fastn.component("index.foo", function(idx, root, x) {
    let localRegistry = fastn.local_registry();
    
    let x2 = fastn.mutable(localRegistry, "x2", 10);
    
    let i = fastn_dom.createKernel(root, fastn_dom.ElementKind.Integer);
    i.setDynamicProperty(fastn_dom.PropertyKind.IntegerValue, [x], function () { return x.get() + 20; });
    i.setStaticProperty(fastn_dom.PropertyKind.Color_RGB, "red");
    i.addEventHandler(fastn_dom.Event.Click, function () {
        x.set(x.get() + 1);
    });
    i.done();
})

function main (root) {
    let x = fastn.mutable("index.x", 10);
    let y = fastn.static("index.y", 20);
    let z = fastn.formula("index.z", [x], function () { return x.get() * y; })
    
    foo(root, x);
    foo(root, x);
    let i = fastn_dom.createKernel(root, fastn_dom.ElementKind.Integer);
    i.setProperty(fastn_dom.PropertyKind.IntegerValue, z);
    i.done();
}
```


================================================
FILE: design/js-runtime/roles.md
================================================
# roles

Some properties are not just values, but roles. The exact value that gets attached to the DOM depends on the role, and
is determined by the runtime. For example the color role keeps track of two colors, and based on user's color 
preferences, the color changes.

## CSS Classes

We use css classes to manage roles. For each role type, eg color is a role type, we have a unique prefix, eg all color
roles will have a class name starting with `c_`. The class name is generated from the role id, which is unique among
all roles for that role type. The ID is auto incremented integer, so the third role created will have the id 3.

When the role is created, we immediately create the corresponding class. When the role is attached to a DOM node, we
attach the corresponding class to the node.

Example:

```css
body.dark .c_3_color {
    color: red;
}

body.light .c_3_color {
    color: green;
}
```

The job of the runtime is to attach the correct class to the body. The descendent selector then ensures all elements
get the right color.

### `_color` suffix

We attached the role `c_3` to the DOM node as the `color` property. We encode the property we attach in the name of
the class.

```css
body.dark .c_3_border_color {
    border-color: red;
}

body.light .c_3_color > {
    border-color: green;
}
```

### SSR

In SSR mode we keep track of all unique classes used by the app. We then generate a CSS file with all the classes.

### Non SSR Mode

In regular mode, after page is running in browser, whenever a class is needed (is being attached to the node) and is 
found missing, we add it to the DOM. W can optimise it by keeping an in-memory cache of all the classes that are 
attached so far, and only add the missing ones. 

## color

We have a color type, with .dark and .light to represent colors in light and dark modes.

When we construct such a color in ftd, we create a `fastn.color()`. This will create a global role, with a unique
`id`. When the role is attached to DOM node, the class corresponding to the `id` will be added to the node.

```ftd
-- ftd.color c:
light: green
dark: red

-- ftd.text: hello
color: $c
```

```js
// note that `fastn.color` accepts both static and mutable values for the two colors
let c = fastn.color("green", "red");

// c.id is globally unique (among all colors), c.class_name is `c_{c.id}`. 
let e = fastn_dom.createKernel(parent, fastn_dom.ElementKind.Text);

// this attaches `c_{c.id}_color` class to the element
e.setProperty(fastn_dom.PropertyKind.Color, c);
```

## Type

For typography we use https://fastn.com/built-in-types#ftd-responsive-type, eg:

```ftd
-- ftd.type desktop-type:
size.px: 40
weight: 900
font-family: cursive
line-height.px: 65
letter-spacing.px: 5

-- ftd.type mobile-type:
size.px: 20
weight: 100
font-family: fantasy
line-height.px: 35
letter-spacing.px: 3

-- ftd.responsive-type responsive-typography:
desktop: $desktop-type
mobile: $mobile-type

-- ftd.text: Hello World
role: $responsive-typography
```

```js
let desktop_type = fastn.type({
    size: fastn.mutable(40),
    weight: fastn.mutable(900),
    font_family: fastn.mutable("cursive"),
    line_height: fastn.mutable(65),
    letter_spacing: fastn.mutable(5)
});
let mobile_type = fastn.type({
    size: fastn.mutable(20),
    weight: fastn.mutable(100),
    font_family: fastn.mutable("fantasy"),
    line_height: fastn.mutable(35),
    letter_spacing: fastn.mutable(3)
});

let responsive_typography = fastn.responsiveType({
    desktop: desktop_type,
    mobile: mobile_type
});

let text = fastn.text("Hello World");
text.setProperty(fastn.PropertyKind.Type, responsive_typography);
```


```css
body.desktop .t_3 {
    size: 40px;
    font-family: "times";
}

body.mobile .t_3 > {
    border-color: green;
}
```

## Length

```ftd
-- ftd.responsive-length p:
desktop.px: 20
mobile.percent: 10

-- ftd.text: Hello
padding.responsive: $p
border-width.responsive: $p
```

```js
let p = fastn.responsiveLength({
    desktop: fastn.mutable({"px": 20}),
    mobile: fastn.mutable({"percent": 10})
});

let text = fastn.text("Hello");
// attaches `p_{p.id}_padding` class to the element
text.setProperty(fastn.PropertyKind.Padding, p);
// attaches `p_{p.id}_border_width` class to the element
text.setProperty(fastn.PropertyKind.BorderWidth, p);
```


================================================
FILE: design/js-runtime/ssr.md
================================================
# Server Side Rendering

We have to send fully rendered HTML to crawlers. Since in `fastn build` we can not serve different content based on
user agent, the HTML we send must include server rendered HTML.

Once browser loads server rendered content, we can either nuke it and recreate the entire DOM, but it may cause flicker
etc, so ideally we should re-use the DOM and "hydrate it" by attaching event handlers.

To do server side rendering we can continue our JS approach, and use or create a `jsdom` like library, which keeps 
track of event handlers to each DOM node. Dom nodes will be identified by unique IDs (we can keep a global integer as
dom ID and keep incrementing it whenever a new dom node is constructed).

When an event handler is attached the server side jsdom will store it in a map of id to event spec, and it will be 
handed over to the page.


// 1. ssr mode (fastn build)

// a. ssr mode: when page is getting constructed on the server (index.ftd -> index.html (html generated by the main())
// b. hydrating mode: when page is getting constructed on the client
// c. normal mode (after the document is loaded in the page, and event handlers are configured)

// 2. fastn server

// if useragent is not crawler: leave the <body> empty so page size is low



================================================
FILE: design/js-runtime/syntax.md
================================================
# Syntax Highlighting

We are only implementing static parsing for now. In 0.4 we will continue to use syntect highlighter and innerHTML.

```rust
fn main() {
    println!("Hello, world!"); // <1>
}
```

```js
function main(parent) {
    let t = fastn_dom.createKernel(parent, fastn_dom.ElementKind.CodeContainer);
    ds_keyword(t, "fn");
    ds_space(t, " ");
    ds_identifier(t, "main", code_context);
    ds_space(t, " ");
    ds_paren(t, "(");
    ds_string(t, `"hello world"`);

    // `// <1>` will call `note`.
    ds_code_note(t, 1, code_context);
    // `// {foo}` will call foo
    foo(t, code_context); 
}
```

Refer https://crates.io/crates/tree-sitter-highlight for actual `highlight_names` we will be using. For each 
`highlight_name` we will have a `ds_` function.

## `code_context`

```ftd
-- record code-context:
integer line-number:
string current-line:
string full-code:
string lang:
```

## "Intellisence"

Any of the `highlight_name` can have associated help text, which will be another "ftd.ui", that will be shown on hover.

```js
function main(parent) {
    let t = fastn_dom.createKernel(parent, fastn_dom.ElementKind.CodeContainer);
    ds_keyword(t, "fn");
    ds_space(t, " ");
    // main has main_help associated with it. ds_identifier can change the look of the main, to indicate to reader that
    // main has help associated with it. And on hover, main_help will be shown.
    ds_identifier(t, "main", {help: main_help});
}

function main_help() {
    
}
```


## Command Click: jump to definition

Any of the symbols can have an associated link, which is where the user will be taken when they command click on the 
symbol. We will pass `link` as an argument to `ds_` functions.


```ftd
-- fastn.package:
python-root: python/src
```

```ftd
-- ds.code:
lang: py
code-processor: lsp
python-root: python/src
diff: <old-commit-hash>

import foo

def main():
    foo.bar
```

```js
function main(parent) {
    let t = fastn_dom.createKernel(parent, fastn_dom.ElementKind.CodeContainer);
    let line = fastn_dom.createKernel(t, fastn_dom.ElementKind.CodeLine);
    ds_line_number(line, code_context);
    ds_line_diff(line);
    ds_line_blame(line);
    ds_keyword(line, "fn");
    ds_space(line, " ");
    // main has main_help associated with it. ds_identifier can change the look of the main, to indicate to reader that
    // main has help associated with it. And on hover, main_help will be shown.
    ds_identifier(line, "main", {link: main_link});
}
```

## ftd.code-ui module

We will create such a module, with UI for all UI we support. We support all the `highlight_names`. We also support 
gutter elements like `line_number`. We support `note`. We also allow arbitrary components in comments (`// {foo}`).

Other gutter items are diff, and blame so far. 

## Code Processors

We have to create a bunch of code processors, like `lsp`, which when enabled adds help and jump to definition, view all
references etc to all symbols. `line-no` processor adds line number. `diff` processor adds diff UI. `blame` processor
adds blame UI.

Depending on which all code processors you have included in the code block, the generated JS will be different. We only
have a fixed number of possible UI, eg line_no, diff-ui etc, which will be part of our `ftd.code-ui` module, so any 
package can fully customise the look and feel of the code block.

## Expand Collapse Regions

```js
function main(parent) {
    let t = fastn_dom.createKernel(parent, fastn_dom.ElementKind.CodeContainer);
    let region_1 = ds_region(t, region_context);
    ds_region_gutter(region_1, code_context, region_context);
    let line = fastn_dom.createKernel(region_1, fastn_dom.ElementKind.CodeLine);
    ds_line_number(line, code_context);
    ds_line_diff(line);
    ds_line_blame(line);
    ds_keyword(line, "fn");
    ds_space(line, " ");
    // main has main_help associated with it. ds_identifier can change the look of the main, to indicate to reader that
    // main has help associated with it. And on hover, main_help will be shown.
    ds_identifier(line, "main", {link: main_link});
}
```

`region_context` is the text to show when the region is collapsed.


================================================
FILE: design/js-runtime/which-quick-js.md
================================================
# Which wrapper of quickjs to use?

To run javascript code in rust, we need to use a wrapper of quickjs. We have two options:

|                 | quickjs-rs   | rquickjs    |
|-----------------|--------------|-------------|
| Last Commit     | Aug 10, 2021 | Jun 9, 2023 |
| QuickJS Version | 2020-09-06   | 2021-03-27  |
| Google Rank     | 1-4          | 5           |
| GH Stars        | 507          | 213         |
| GH Used By      | 156          | 177         |
| Async Support   | No (?)       | Yes         |



================================================
FILE: design/new-design.md
================================================
# FTD to HTML

## How can we do this in 0.5?

We go `String, String` (document-id, source code) -> `ftd:p1::Section`
then to `ftd::ast::Ast`. We store in `documents: Map<String, Document>`.

x.ftd
y.ftd

```ftd
-- import: y

-- integer $a: 2

-- integer x: 2 * $y.one

-- integer z: 4 * $y.one
```

```rust
struct State {
    documents: std::collections::BTreeMap<String, Document>,
    types: Map<String, Sourced<Type>>,
}

struct Document {
    aliases: Map<String, String>,
    ast: Vec<ftd::ast::Ast>
}

struct Sourced<T> {
    file: String,
    line: usize,
    value: T,
}

enum Type {
    Integer,
    MutableInteger,
}
```

Once we have `documents`, we can write `document_to_js`.

```json
{
  "x.a": "MutableInteger",
  "x.x": "Integer"
}
```

```js
let foo_bar__x = 2;  // foo/bar.ftd
```

```ftd
-- integer $k: 1
 
-- integer x:
$processor$: <> 
k: $k

-- integer y: $x * 2

-- ftd.integer: $k
$on-click$: { k += 1 }

-- ftd.integer: $y
```

### Type Checking

The generated JS should work if everything is correct, else we will get runtime error. We do
not want runtime errors, so we implement a type check pass on `documents`.

The type checker will create `bag: Map<String, ftd::interpreter::Thing>` containing symbols from
all documents (starting from source document, and only things that are referred from there).

Type checker will go through every Ast in source document, and for each symbol identified, it will
check if it is present in `types`. If not, it will try to add the symbol in the bag.

## How is HTML generated, given ftd source file in 0.4?

First we parse:

```rust
pub fn parse_doc(name: &str, source: &str) -> ftd::interpreter::Result<ftd::interpreter::Document> {
    let mut s = ftd::interpreter::interpret(name, source)?;

    // .. skipped ..
}
```

We then run the interpreter loop:

```rust
pub fn parse_doc(name: &str, source: &str) -> ftd::interpreter::Result<ftd::interpreter::Document> {
    let mut s = ftd::interpreter::interpret(name, source)?;
    loop {
        match s {
            ftd::interpreter::Interpreter::Done { document: doc } => {
                break;
            }
            ftd::interpreter::Interpreter::StuckOnImport {
                module, state: st, ..
            } => {
                s = st.continue_after_import(
                    module.as_str(),
                    document,
                    foreign_variable,
                    foreign_function,
                    0,
                )?;
            }
            ftd::interpreter::Interpreter::StuckOnProcessor {
                state, ast, module, ..
            } => {
                s = state.continue_after_processor(value, ast)?;
            }
            ftd::interpreter::Interpreter::StuckOnForeignVariable {
                state,
                module,
                variable,
                ..
            } => {
                s = state.continue_after_variable(module.as_str(), variable.as_str(), value)?;
            }
        }
    }
    Ok(document)
}
```

We then convert the document to JS using `ftd::js::document_into_js_ast()`.

## Main Journey

```rust
// ftd::p1::Section
pub struct Section {
    pub name: String,
    pub kind: Option<String>,
    pub caption: Option<ftd::p1::Header>,
    pub headers: ftd::p1::Headers,
    pub body: Option<Body>,
    pub sub_sections: Vec<Section>,
    pub is_commented: bool,
    pub line_number: usize,
    pub block_body: bool,
}

pub enum AST {
    // ftd::ast::Ast
    #[serde(rename = "import")]
    Import(ftd::ast::Import),
    #[serde(rename = "record")]
    Record(ftd::ast::Record),
    #[serde(rename = "or-type")]
    OrType(ftd::ast::OrType),
    VariableDefinition(ftd::ast::VariableDefinition),
    VariableInvocation(ftd::ast::VariableInvocation),
    ComponentDefinition(ftd::ast::ComponentDefinition),
    #[serde(rename = "component-invocation")]
    ComponentInvocation(ftd::ast::Component),
    FunctionDefinition(ftd::ast::Function),
    WebComponentDefinition(ftd::ast::WebComponentDefinition),
}

pub struct Document {
    pub data: indexmap::IndexMap<String, ftd::interpreter::Thing>,
    pub name: String,
    pub tree: Vec<fastn_resolved::Component>,
    pub aliases: ftd::Map<String>,
    pub js: std::collections::HashSet<String>,
    pub css: std::collections::HashSet<String>,
}
```

## P1 Parser

```rust
pub struct Body {
    pub line_number: usize,
    pub value: String,
}

pub struct Headers(pub Vec<Header>);

pub enum Header {
    KV(ftd::p1::header::KV),
    Section(ftd::p1::header::SectionInfo),
    BlockRecordHeader(ftd::p1::header::BlockRecordHeader),
}

pub struct KV {
    pub line_number: usize,
    pub key: String,
    pub kind: Option<String>,
    pub value: Option<String>,
    pub condition: Option<String>,
    pub access_modifier: AccessModifier,
    pub source: KVSource,
}

pub struct SectionInfo {
    pub line_number: usize,
    pub key: String,
    pub kind: Option<String>,
    pub section: Vec<ftd::p1::Section>,
    pub condition: Option<String>,
}

pub struct BlockRecordHeader {
    pub key: String,
    pub kind: Option<String>,
    pub caption: Option<String>,
    pub body: (Option<String>, Option<usize>),
    pub fields: Vec<Header>,
    pub condition: Option<String>,
    pub line_number: usize,
}
```

## AST

```rust
pub struct ParsedDocument {
    pub name: String,
    pub ast: Vec<ftd::ast::AST>,
    pub processing_imports: bool,
    pub doc_aliases: ftd::Map<String>,
    pub re_exports: ReExport,
    pub exposings: ftd::Map<String>,
    pub foreign_variable: Vec<String>,
    pub foreign_function: Vec<String>,
}


pub struct Import {
    pub module: String,
    pub alias: String,
    #[serde(rename = "line-number")]
    pub line_number: usize,
    pub exports: Option<Export>,
    pub exposing: Option<Exposing>,
}

pub struct Record {
    pub name: String,
    pub fields: Vec<Field>,
    pub line_number: usize,
}
```

## Interpreter

```rust
pub struct InterpreterState {
    pub id: String,
    pub bag: indexmap::IndexMap<String, ftd::interpreter::Thing>,
    pub js: std::collections::HashSet<String>,
    pub css: std::collections::HashSet<String>,
    pub to_process: ToProcess,
    pub pending_imports: PendingImports,
    pub parsed_libs: ftd::Map<ParsedDocument>,
    pub instructions: Vec<fastn_resolved::Component>,
}

pub enum Interpreter {
    StuckOnImport {
        module: String,
        state: InterpreterState,
        caller_module: String,
    },
    Done {
        document: Document,
    },
    StuckOnProcessor {
        state: InterpreterState,
        ast: ftd::ast::AST,
        module: String,
        processor: String,
        caller_module: String,
    },
    StuckOnForeignVariable {
        state: InterpreterState,
        module: String,
        variable: String,
        caller_module: String,
    },
}

pub struct Document {
    pub data: indexmap::IndexMap<String, ftd::interpreter::Thing>,
    pub name: String,
    pub tree: Vec<fastn_resolved::Component>,
    pub aliases: ftd::Map<String>,
    pub js: std::collections::HashSet<String>,
    pub css: std::collections::HashSet<String>,
}

pub struct Component {
    pub id: Option<String>,
    pub name: String,
    pub properties: Vec<Property>,
    pub iteration: Box<Option<Loop>>,
    pub condition: Box<Option<fastn_resolved::Expression>>,
    pub events: Vec<Event>,
    pub children: Vec<Component>,
    pub source: ComponentSource,
    pub line_number: usize,
}
```

## JS

```rust
pub struct JSAstData {
    // fastn_js::JSAstData
    /// This contains asts of things (other than `ftd`) and instructions/tree
    pub asts: Vec<fastn_js::Ast>,
    /// This contains external scripts provided by user and also `ftd`
    /// internally supports (like rive).
    pub scripts: Vec<String>,
}

pub enum Ast {
    // fastn_js::Ast
    Component(fastn_js::Component),
    UDF(fastn_js::UDF),
    // user defined function
    StaticVariable(fastn_js::StaticVariable),
    MutableVariable(fastn_js::MutableVariable),
    MutableList(fastn_js::MutableList),
    RecordInstance(fastn_js::RecordInstance),
    OrType(fastn_js::OrType),
    Export { from: String, to: String },
}

pub struct Component {
    pub name: String,
    pub params: Vec<String>,
    pub args: Vec<(String, fastn_js::SetPropertyValue, bool)>,
    // Vec<(name, value, is_mutable)>
    pub body: Vec<fastn_js::ComponentStatement>,
}

pub enum SetPropertyValue {
    Reference(String),
    Value(fastn_js::Value),
    Formula(fastn_js::Formula),
    Clone(String),
}
```


================================================
FILE: design/package-manager.toml
================================================
[REQ-package_manager]
partof = 'REQ-purpose'
text = 'FPM acts as a package manager for FTD files. FPM packages can be used to distribute ftd files, as well as to distribute static assets like images, icons, font files, and so on.'

[REQ-package_manager-fpm_ftd]
partof = [
    'REQ-package_manager-main',
    'REQ-package_manager-package',
]
text = '''
Every [[REQ-package_manager-package]] contains a `FPM.ftd` file.

This file contains `fpm.package` declaration. It also contains [[REQ-package_manager-dependency]], [[REQ-package_manager-auto_import]], [[REQ-sitemap]], [[REQ-app]], [[REQ-dynamic]] URLs, [[REQ-auth-group]] specifications.'''

[REQ-package_manager-main]
partof = 'REQ-cli-serve'
text = '''
When FPM is running, there is always a main package, which corresponds to the folder in which the [[REQ-cli-serve]] was launched from.

This folder must be a valid [[REQ-package_manager-package]].'''

[REQ-package_manager-package]
text = 'A FPM package must contain at least one file: `FPM.ftd` [[REQ-package_manager-fpm_ftd]]. Packages usually also contain `index.ftd` file.'


================================================
FILE: design/processors.toml
================================================


================================================
FILE: design/purpose.toml
================================================
[REQ-purpose]
text = '''
FPM is a [[REQ-cli]] that serves as:

- [[REQ-ssg]]: static site generator
- [[REQ-package_manager]]: FTD package manager
- [[REQ-server]]: HTTP Server, for local or prod

'''


================================================
FILE: design/routes.toml
================================================
[REQ-routes]
partof = [
    'REQ-cli-build',
    'REQ-cli-serve',
    'REQ-dynamic',
    'REQ-ssg',
]
text = '''
FPM serve or build handle a bunch of "routes". 

- [[REQ-routes-self_ftd]]
- [[REQ-routes-dep_ftd]]
- [[REQ-routes-self_md]]
- [[REQ-routes-dep_md]]
- [[REQ-routes-self_media]]
- [[REQ-routes-dep_media]]
- [[REQ-routes-self_dynamic]]
- [[REQ-routes-dep_dynamic]]
- [[REQ-routes-mountpoint]]'''

[REQ-routes-self_ftd]
text = '''
Any ftd file in the [[REQ-package_manager-main]] is served. Exception, any ftd file that is target of [[REQ-routes-self_dynamic]] is not served on their "natural url".

# [[.natural_url]]

If a file is foo.ftd, the natural URL is `/foo/`. If the file name is `index.ftd` it is omitted, eg `index.ftd` is served on `/`, and `foo/index.ftd` is served on `/foo/`.

# [[.index_conflict]]

If both `foo.ftd` and `foo/index.ftd` are present it is an error.'''


================================================
FILE: design/runtime/README.md
================================================
# Design Of `fastn_runtime`

- [compilation of `.ftd` file to `.wasm`](compilation.md)
- [data layer, how is data store in memory](data-layer.md)
  - [how are strings stored](strings.md)
- [how we work in browser environment](browser.md)
  - [what does linker.js do?](linking.md)
  - [server side rendering](ssr.md)
  - [building for browser](build.md)
- [how we handle dom, both in browser and outside browser](dom.md)


================================================
FILE: design/runtime/browser.md
================================================
# Browser

[Back To Design Home](./).

`fastn_runtime` uses `WebAssembly` for executing functions defined in the ftd file, event handlers etc. 

## `doc.wasm`

Every ftd file is converted to a wasm file (refer [`compilation.md`](compilation.md) for details). In this document we 
will call the  file `doc.wasm` i.e. `doc.ftd` gets compiled into `doc.wasm`.

## `doc.json` and `doc.html`

The `doc.wasm` file is used to create a wasm instance, and a function named `main` that is exported by `doc.wasm` is
called. The `main` creates all the global variables, and the DOM. The variable data, the event handlers and the DOM,
are captured in two files, `doc.json` and `doc.html`. 

`doc.html` contains fully rendered static version of `doc.ftd`. It will look exactly how it should but event handlers 
would not work. 

## `linker.js`

Checkout [`linker.md`](linking.md) for details. For now we are going ahead with the Approach a discussed there.

## `runtime.wasm`

The runtime itself is written in Rust and gets compiled into a file `runtime.wasm`. 

### Versioning

The `runtime.wasm` only changes when `fastn` itself changes, so we can serve the `runtime.wasm` from a global CDN, and
the actual URL for `runtime.wasm` can be versioned, like `runtime-<hash>.wasm`.

## Server Side Rendering

Checkout the [`ssr.md`](ssr.md) for a discussion on server side render. 



================================================
FILE: design/runtime/build.md
================================================
# Building For Browser

We have to build two wasm files, `doc.wasm` and `runtime.wasm`. `doc.wasm` is built using [the compilation 
process](compilation.md). This document describes how to create `runtime.wasm` file, and how to test it locally,
without `fastn` server running.

## Setup

We have to install wasm32 target.

```sh
rustup target add wasm32-unknown-unknown
```

You have to re-run this command when you upgrade the Rust version.

## Building `runtime.wasm`

From `fastn-runtime` folder, run the following command:

```sh
cargo build --target wasm32-unknown-unknown --no-default-features --features=browser
```

Attach `--release` flag to create smaller binaries.

```txt
-rwxr-xr-x@ 1 amitu  staff   4.3M Jun 11 19:11 ../target/wasm32-unknown-unknown/debug/fastn_runtime.wasm
-rwxr-xr-x@ 1 amitu  staff   2.1M Jun 11 19:10 ../target/wasm32-unknown-unknown/release/fastn_runtime.wasm
```

## Minimize using `wasm-opt`

```sh
wasm-opt -O3  ../target/wasm32-unknown-unknown/release/fastn_runtime.wasm  -o f.wasm
ls -lh f.wasm
-rw-r--r--@ 1 amitu  staff   1.8M Jun 12 07:18 f.wasm
```

Gzip:

```shell
gzip f.wasm
ls -lh f.wasm.gz
-rw-r--r--@ 1 amitu  staff   397K Jun 12 07:18 f.wasm.gz
```

## Enabling `lto`


```toml
[profile.release]
lto = true
```

With LTO enabled, the sizes are:

```txt
-rwxr-xr-x@ 1 amitu  staff   4.3M Jun 11 19:11 ../target/wasm32-unknown-unknown/debug/fastn_runtime.wasm
-rwxr-xr-x@ 1 amitu  staff   518K Jun 12 07:24 ../target/wasm32-unknown-unknown/release/fastn_runtime.wasm
-rw-r--r--@ 1 amitu  staff   417K Jun 12 07:25 f.wasm
-rw-r--r--@ 1 amitu  staff   108K Jun 12 07:26 f.wasm.gz
```

## After Stripping Debug Info

```toml
[profile.release]
lto = true
strip = true
```

```shell
-rwxr-xr-x@ 1 amitu  staff   4.3M Jun 11 19:11 ../target/wasm32-unknown-unknown/debug/fastn_runtime.wasm
-rwxr-xr-x@ 1 amitu  staff   400K Jun 12 07:57 ../target/wasm32-unknown-unknown/release/fastn_runtime.wasm
-rw-r--r--@ 1 amitu  staff   353K Jun 12 07:58 f.wasm
-rw-r--r--@ 1 amitu  staff    89K Jun 12 07:58 f.wasm.gz
```

## `opt-level z` and `abort`

```toml
[profile.release]
lto = true
strip = true
opt-level = "z"
panic = "abort"
```

```shell
-rwxr-xr-x@ 1 amitu  staff   4.3M Jun 11 19:11 ../target/wasm32-unknown-unknown/debug/fastn_runtime.wasm
-rwxr-xr-x@ 1 amitu  staff   343K Jun 12 09:30 ../target/wasm32-unknown-unknown/release/fastn_runtime.wasm
-rw-r--r--@ 1 amitu  staff   322K Jun 12 09:31 f.wasm
-rw-r--r--@ 1 amitu  staff    88K Jun 12 09:31 f.wasm.gz
```


================================================
FILE: design/runtime/compilation.md
================================================
# Compilation

[Back To Design Home](./).

`fastn-runtime` crate uses `wasm` to render all ftd programs. The input ftd file is compiled into a `wasm` file and is
fed to `fastn_runtime`. This document describes how the compilation process works, and how each ftd construct is mapped
to corresponding `wasm` construct.

================================================
FILE: design/runtime/data-layer.md
================================================
# Data Layer

[Back To Design Home](./).

`doc.ftd` gets compiled into `doc.wasm` (read [`compilation.md`](compilation.md) for details), and runtime executes the
wasm program.

================================================
FILE: design/runtime/dom.md
================================================
# Dom

[Back To Design Home](./).

We have two operating modes. In `internal-dom` mode we maintain full DOM tree, and in `browser-dom` mode we rely on an 
external system to maintain the dom.

The compiled wasm code expects a bunch of dom related functions that we provide. Eg `create_kernel()`, 
`set_property_i32()` and so on. Such functions mutate the dom.

Note fastn language does not have any concept of querying the UI, so you can never get a handle to a dom node, or
ask questions like if it is visible or what's it's content. The language is strictly one way. Documents contains data,
UI is derived from data, and UI has event handlers that can change data, and based on those data changes the UI will
get updated.

When the document is getting rendered on the server side, we operate in internal-dom mode. At the end of original page 
creation, the dom is converted to HTML, which transferred to the browser. In the browser the DOM is managed by the
browser, so we do not have to maintain our own DOM, this is called browser-dom mode. Refer [`browser.md`](browser.md)
for details.

When we are running in the native mode, say fastn uses WebGPU to render the DOM, or when we use curses based rendering,
the dom tree is maintained by us, and the renderer is used to transform the dom to things that can be rendered by WebGPU
or terminal. Refer [`gpu.md`](gpu.md) and [`terminal.md`](terminal.md) for details.

# Roles

For some attributes like `ftd.color`, `ftd.length` and `ftd.typography`, we create classes. In our  
[data-layer](data-layer.md), we treat these types as simple records, and store their data in `fastn_runtime::Memory.vec`.
We also store the pointers corresponding to each role in `fastn_runtime::Memory.text_roles: 
Vec<fastn_runtime::Pointerkey>` and so on. 

The only way to change the color of a text is to first construct a `ftd.color` instance, and then pass it to 
`dom.set_property_vec(node, TextColor.i32(), role)`. For each role we create a CSS class, eg if the ftd.color has 
pointer id of `1v1`, we will create a class `c_1v1` and attach it to the `node`. 

In case of `internal-dom`, we store the `fastn_runtime::Pointerkey`, eg

```rust
struct ColorPointer(fastn_runtime::Pointerkey);

struct TextStyle {
    color: Option<fastn_runtime::ColorPointer>,
}
```

In case of `browser-dom` (when running in browser), we directly modify the class list for the text node, eg

```js
document.getElementById("1v1").t.classList.push("c_1v1");
```

# Non Role Properties

Other properties like `align`, `href` etc, we store the computed property in the DOM in case of `internal-dom`, eg

```rust
enum Align {
    Left,
    Right,
    Justify
}

struct CommonStyle {
    align: Option<Align>
}
```

When we generate HTML such properties would be added inline to the dom node either as attribute or as inline style.

================================================
FILE: design/runtime/features.md
================================================
# Features Used In This Crate

We have 4 main compilation targets for this crate:

1. browser
2. fastn serve/fastn build
3. gpu
4. terminal

================================================
FILE: design/runtime/linking.md
================================================
# `linker.js`

[Back To Design Home](./).

Read [`browser.md`](browser.md) first for context.

Once `doc.html` loads, it loads `linker.js`, which downloads `doc.json`, `doc.wasm`, `runtime.wasm` to make the
event handlers work.

`linker.js` creates two wasm instances, one for `runtime.wasm` and the other for `doc.wasm`. The `runtime instance` is 
fed `doc.json` as we are not going to call the `main` function of `doc.wasm` from browser, as main's job was to create 
the  DOM tree, and initialise `fastn_runtime::Memory`.

`doc.wasm` is created with assumption that a bunch of functions are exported by the host (eg `create_i32()`,
`create_kernel()` and so on). And `doc.wasm` itself exports `main()`, `call_by_index(idx: i32, func_data:
fastn_runtime::Pointer) -> fastn_runtime::Pointer` and `void_by_index(idx: i32, func_data: fastn_runtime::Pointer)`.

The `doc.call_by_index()` and `doc.void_by_index()` are called from runtime, and they internally call
`runtime.create_kernel()`, `runtime.create_i32()` etc (it can happen recursively as well, eg `runtime.set_i32()` may
trigger `doc.call_by_index()` which may call `runtime.create_kernel()` and on ond on).

`linker.js` connects the two sides. We can do this in two ways, a. wrapper functions, and b. function tables.

## Approach a: Wrapper Functions

`linker.js` can create wrapper functions for the two sides, eg:

```js
const importObject = {
  imports: { 
    // doc_instance will call create_kernel etc, which gets forwarded to runtime_instance
    create_kernel: (arguments) => runtime_instance.exports.create_kernel.apply(null, arguments), 
    .. all the exports from runtime, source: fastn_runtime::Dom::register_functions() ..
    
    // runtime_instance will call call_by_index etc, which gets forwarded to doc_instance
    call_by_index: (arguments) => doc_instance.exports.call_by_index.apply(null, arguments),
    void_by_index: (arguments) => doc_instance.exports.void_by_index.apply(null, arguments),
  },
};

let runtime_instance = null;
let doc_instance = null;

WebAssembly.instantiateStreaming(fetch("runtime.wasm"), importObject).then(
  (obj) => runtime_instance = obj.instance; // check if both are loaded, if so call .start on both
);

WebAssembly.instantiateStreaming(fetch("doc.wasm"), importObject).then(
  (obj) => doc_instance = obj.instance;
);
```

For each method in both the instances, we create a wrapper JS function, and the wrapper will call the corresponding
exported function on the other instance.

Wasm files then import the methods they are interested in, eg `doc.wasm`:

```wat
(module
    (import "fastn" "create_frame" (func $create_frame))
    ..
    
    (func main
        (call create_kernel)
    )
)
```

## Approach b: Function Tables

Wasm has a concept of function tables.

```js
let number_of_exports_in_runtime = 10; // say
let number_of_exports_in_doc = 2; // only call_by_index and void_by_index

var table = new WebAssembly.Table({
    initial: number_of_exports_in_runtime + number_of_exports_in_doc, 
    element: "externref"
});

const importObject = {
    linker: {
        table: table,
    }
}

let runtime_instance = null;
let doc_instance = null;

WebAssembly.instantiateStreaming(fetch("runtime.wasm"), importObject).then(
  (obj) => runtime_instance = obj.instance;
);

WebAssembly.instantiateStreaming(fetch("doc.wasm"), importObject).then(
  (obj) => doc_instance = obj.instance;
);
```

And in our `doc.wasm` file we have:

```wat
(module
    (import "linker" "table" ??)
    (elem (i32.const 0) $call_by_index $void_by_index)
    
    (func $create_kernel
        (call_inderct $create_kernel_type (i32.const 2))
    )
    
    (func $main (export "main")  
        (call $create_kernel)    
    )
    
    (func $call_by_index ..)
    (func $void_by_index ..)  
)
```

`doc.wasm` gets the first two slots, starting from index `0`, in the table to export the two methods. `runtime.wasm`
uses the rest of the slots:

```wat
(module
    (import "linker" "table" ??)
    (elem (i32.const 2) $create_kernel ..)
    
    (func $create_kernel (export "")  ..)
)
```

`runtime.wasm` populates slots starting from index `2`.

When they need to call each other, they use `(call_indirect)` instead of `(call)`.


### Challenge With Table Approach

How to use tables from wasm generated from Rust? Not yet clear.

================================================
FILE: design/runtime/ssr.md
================================================
# Main On Server Vs Main In Browser

[Back To Design Home](./).

Or, to ssr or not?

We have two main way to construct the initial DOM tree.

First is we can construct the DOM tree on server side, by running the `doc.wasm`'s `main()` on server side, constructing
a `internal-dom` (refer [`dom.md`](dom.md) for details) (along with memory snapshot, `doc.json`), and serializing the
`internal-dom` to HTML. Finally in browser we attach the event handlers, and proxy dom mutation methods exposed by
`runtime.wasm` to real browser DOM. Note that since `main()` has already run on server, we do not run it in browser.
Download .txt
gitextract_5tz6h9ik/

├── .all-contributorsrc
├── .dockerignore
├── .gitattributes
├── .github/
│   ├── Dockerfile
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── code_issue.md
│   │   └── config.yml
│   ├── RELEASE_TEMPLATE.md
│   ├── dependabot.yml
│   ├── dprint-ci.json
│   ├── lib/
│   │   └── README.md
│   ├── scripts/
│   │   ├── populate-table.py
│   │   ├── run-integration-tests.sh
│   │   └── test-server.py
│   └── workflows/
│       ├── create-release.yml
│       ├── deploy-fastn-com.yml
│       ├── email-critical-tests.yml
│       ├── optimize-images.yml
│       └── tests-and-formatting.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .rusty-hook.toml
├── Cargo.toml
├── Changelog.md
├── Cheatsheet.md
├── DOCUMENTATION_PLAN.md
├── LICENSE
├── README.md
├── SECURITY.md
├── WINDOWS_INSTALLER.md
├── clift/
│   ├── Cargo.toml
│   └── src/
│       ├── api/
│       │   ├── commit_upload.rs
│       │   ├── initiate_upload.rs
│       │   └── mod.rs
│       ├── commands/
│       │   ├── mod.rs
│       │   └── upload.rs
│       ├── lib.rs
│       └── utils/
│           ├── call_api.rs
│           ├── generate_hash.rs
│           ├── get_local_files.rs
│           ├── github_token.rs
│           ├── mod.rs
│           ├── site_token.rs
│           ├── update_token.rs
│           └── uploader.rs
├── design/
│   ├── README.md
│   ├── apps.toml
│   ├── cli.toml
│   ├── design-system.toml
│   ├── dynamic.toml
│   ├── font.toml
│   ├── github.md
│   ├── js-runtime/
│   │   ├── README.md
│   │   ├── building.md
│   │   ├── compilation.md
│   │   ├── crate.md
│   │   ├── dynamic-class-css.md
│   │   ├── list.md
│   │   ├── markdown.md
│   │   ├── markup.md
│   │   ├── registry.md
│   │   ├── roles.md
│   │   ├── ssr.md
│   │   ├── syntax.md
│   │   └── which-quick-js.md
│   ├── new-design.md
│   ├── package-manager.toml
│   ├── processors.toml
│   ├── purpose.toml
│   ├── routes.toml
│   ├── runtime/
│   │   ├── README.md
│   │   ├── browser.md
│   │   ├── build.md
│   │   ├── compilation.md
│   │   ├── data-layer.md
│   │   ├── dom.md
│   │   ├── features.md
│   │   ├── linking.md
│   │   ├── ssr.md
│   │   └── strings.md
│   ├── server.toml
│   ├── sitemap.toml
│   └── ssg.toml
├── events.diff
├── fastn/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
├── fastn-builtins/
│   ├── Cargo.toml
│   └── src/
│       ├── constants.rs
│       └── lib.rs
├── fastn-context/
│   ├── Cargo.toml
│   ├── NEXT-complete-design.md
│   ├── NEXT-counters.md
│   ├── NEXT-locks.md
│   ├── NEXT-metrics-and-data.md
│   ├── NEXT-monitoring.md
│   ├── NEXT-operation-tracking.md
│   ├── NEXT-status-distribution.md
│   ├── README-FULL.md
│   ├── README.md
│   ├── examples/
│   │   └── minimal_test.rs
│   └── src/
│       ├── context.rs
│       ├── lib.rs
│       └── status.rs
├── fastn-context-macros/
│   ├── Cargo.toml
│   └── src/
│       └── lib.rs
├── fastn-core/
│   ├── Cargo.toml
│   ├── bot_user_agents.txt
│   ├── fastn.js
│   ├── fastn2022.js
│   ├── fbt-tests/
│   │   ├── 01-help/
│   │   │   └── cmd.p1
│   │   ├── 02-hello/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fastn.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── fail_doc.ftd
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── fail_doc.ftd
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 03-nested-document/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── index.ftd
│   │   │   │       └── nested/
│   │   │   │           ├── document.ftd
│   │   │   │           └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── manifest.json
│   │   │       └── nested/
│   │   │           ├── document/
│   │   │           │   └── index.html
│   │   │           ├── document.ftd
│   │   │           ├── index.ftd
│   │   │           └── index.html
│   │   ├── 04-import-code-block/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── index.ftd
│   │   │   │       └── lib.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── lib/
│   │   │       │   └── index.html
│   │   │       ├── lib.ftd
│   │   │       └── manifest.json
│   │   ├── 05-hello-font/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── hello/
│   │   │   │       │   └── world/
│   │   │   │       │       └── test.py
│   │   │   │       ├── hello.py
│   │   │   │       ├── index
│   │   │   │       ├── index.ftd
│   │   │   │       └── index.md
│   │   │   └── output/
│   │   │       ├── -/
│   │   │       │   └── www.amitu.com/
│   │   │       │       ├── hello/
│   │   │       │       │   └── world/
│   │   │       │       │       └── test.py
│   │   │       │       ├── hello.py
│   │   │       │       ├── index
│   │   │       │       └── index.ftd
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── hello/
│   │   │       │   └── world/
│   │   │       │       └── test.py
│   │   │       ├── hello.py
│   │   │       ├── index
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 06-nested-document-sync/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── .fpm.ftd
│   │   │       └── amitu/
│   │   │           ├── FASTN.ftd
│   │   │           ├── index.ftd
│   │   │           └── nested/
│   │   │               ├── document.ftd
│   │   │               └── index.ftd
│   │   ├── 07-hello-tracks/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── .history/
│   │   │   │       │   ├── .latest.ftd
│   │   │   │       │   ├── FPM.1639765778133988000.ftd
│   │   │   │       │   ├── hello.1639765778133988000.txt
│   │   │   │       │   ├── index-track.1639765778133988000.ftd
│   │   │   │       │   └── index.1639765778133988000.ftd
│   │   │   │       ├── FPM.ftd
│   │   │   │       ├── hello.txt
│   │   │   │       ├── index-track.ftd
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       └── index-track.ftd.track
│   │   ├── 08-static-assets/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css
│   │   │       ├── code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css
│   │   │       ├── code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css
│   │   │       ├── code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css
│   │   │       ├── code-theme-256C21B515FC9E77F95D88689A4086B9D9406B7AAE3A273780FE8B8748C5A7D2.css
│   │   │       ├── code-theme-4DD8479BE14A755645BC09FF433FB70EB4CB28F0CBF3CA98DCB71B244B85B194.css
│   │   │       ├── code-theme-60E02531E77333F3F1B636C4FC43E976EA9F41AD75268B2DD825C33C68B573A6.css
│   │   │       ├── code-theme-6EB6F03F9F578742CA0CD1189693E43A6135D910989ADD88CA3C0D6117EE24D7.css
│   │   │       ├── code-theme-7852E516BA094B01897820BB3432BE553FE5B28F00E9CA0EBC9DFFB8312EE8BF.css
│   │   │       ├── code-theme-792C7BB9F4C8DFF3E0CBC354D2084DBF71BC5750C2C1357F0E7D936867AFAB62.css
│   │   │       ├── code-theme-88F91252A8A0EA125B4BA2C7B85E65580DB580F1477931AADCB5118E4E69D1CD.css
│   │   │       ├── code-theme-8C59190F5018F48CCBB063359072EE9053D04923BBC5D1BA52B574E78D8C536A.css
│   │   │       ├── code-theme-8CCA3D600F91FA55950DF3132F2ABE4BA14CEEA13CD23E157BF6A137762B8452.css
│   │   │       ├── code-theme-95B9118AFC8631777EEBBD89B2066C3706A6DF3579B14F41AF05564E41CAA09C.css
│   │   │       ├── code-theme-96E503EA0E8F80C5DDF81545C9B1A40DE4CDB7CD8F52664F747FD9E7BB0207B8.css
│   │   │       ├── code-theme-99CD7B013C96C4632F0AEA39AC265387B814AE85A7D33666A4AE4BEFF59016D0.css
│   │   │       ├── code-theme-9A3284FD117DFF7CFD432FF860A5E14169FA592BC3DA4F5E8A6975143F5EA07F.css
│   │   │       ├── code-theme-9A45313F167DBD90654BFD5BB3BC0BDF6AE447485C30B0389ADA7B49C069E46A.css
│   │   │       ├── code-theme-A24DC8F09D03756A62923E8A883CAE3B938D54E2813F0855312D2554DBE97BAD.css
│   │   │       ├── code-theme-A352AF572179AB980583D41BC41ADDBA36C4C17757A34C1C6AAAF2C253E25CE3.css
│   │   │       ├── code-theme-B3AEA322EADEDA61F0E219845A0E9C8E73F6345E49362B46E6F52CEE40471248.css
│   │   │       ├── code-theme-B68AA27E05B319F04A9CD747AADBF9B9CD791E040DEC519AE9544B4FF65DDBAC.css
│   │   │       ├── code-theme-CFBB665E50E0439263BF0F3D59B1F0F20F40F379C81B1B14AA9E16DDF70F70E6.css
│   │   │       ├── code-theme-DC76F700474E809F7BA2D9914793D04881B17EA4699BA9C568C83D32A18B0173.css
│   │   │       ├── default-73755E118EA14B5B124FF4106E51628B7152E1302B3ED37177480A59413FF762.js
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── manifest.json
│   │   │       ├── markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
│   │   │       ├── prism-73F718B9234C00C5C14AB6A11BF239A103F0B0F93B69CD55CB5C6530501182EB.css
│   │   │       └── prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
│   │   ├── 09-markdown-pages/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── index.ftd
│   │   │   │       └── page.md
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css
│   │   │       ├── code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css
│   │   │       ├── code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css
│   │   │       ├── code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css
│   │   │       ├── code-theme-256C21B515FC9E77F95D88689A4086B9D9406B7AAE3A273780FE8B8748C5A7D2.css
│   │   │       ├── code-theme-4DD8479BE14A755645BC09FF433FB70EB4CB28F0CBF3CA98DCB71B244B85B194.css
│   │   │       ├── code-theme-60E02531E77333F3F1B636C4FC43E976EA9F41AD75268B2DD825C33C68B573A6.css
│   │   │       ├── code-theme-6EB6F03F9F578742CA0CD1189693E43A6135D910989ADD88CA3C0D6117EE24D7.css
│   │   │       ├── code-theme-7852E516BA094B01897820BB3432BE553FE5B28F00E9CA0EBC9DFFB8312EE8BF.css
│   │   │       ├── code-theme-792C7BB9F4C8DFF3E0CBC354D2084DBF71BC5750C2C1357F0E7D936867AFAB62.css
│   │   │       ├── code-theme-88F91252A8A0EA125B4BA2C7B85E65580DB580F1477931AADCB5118E4E69D1CD.css
│   │   │       ├── code-theme-8C59190F5018F48CCBB063359072EE9053D04923BBC5D1BA52B574E78D8C536A.css
│   │   │       ├── code-theme-8CCA3D600F91FA55950DF3132F2ABE4BA14CEEA13CD23E157BF6A137762B8452.css
│   │   │       ├── code-theme-95B9118AFC8631777EEBBD89B2066C3706A6DF3579B14F41AF05564E41CAA09C.css
│   │   │       ├── code-theme-96E503EA0E8F80C5DDF81545C9B1A40DE4CDB7CD8F52664F747FD9E7BB0207B8.css
│   │   │       ├── code-theme-99CD7B013C96C4632F0AEA39AC265387B814AE85A7D33666A4AE4BEFF59016D0.css
│   │   │       ├── code-theme-9A3284FD117DFF7CFD432FF860A5E14169FA592BC3DA4F5E8A6975143F5EA07F.css
│   │   │       ├── code-theme-9A45313F167DBD90654BFD5BB3BC0BDF6AE447485C30B0389ADA7B49C069E46A.css
│   │   │       ├── code-theme-A24DC8F09D03756A62923E8A883CAE3B938D54E2813F0855312D2554DBE97BAD.css
│   │   │       ├── code-theme-A352AF572179AB980583D41BC41ADDBA36C4C17757A34C1C6AAAF2C253E25CE3.css
│   │   │       ├── code-theme-B3AEA322EADEDA61F0E219845A0E9C8E73F6345E49362B46E6F52CEE40471248.css
│   │   │       ├── code-theme-B68AA27E05B319F04A9CD747AADBF9B9CD791E040DEC519AE9544B4FF65DDBAC.css
│   │   │       ├── code-theme-CFBB665E50E0439263BF0F3D59B1F0F20F40F379C81B1B14AA9E16DDF70F70E6.css
│   │   │       ├── code-theme-DC76F700474E809F7BA2D9914793D04881B17EA4699BA9C568C83D32A18B0173.css
│   │   │       ├── default-19D2867920A9DCA55CE23FEDCE770D4077F08B32526E28D226376463C3C1C583.js
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── manifest.json
│   │   │       ├── markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
│   │   │       ├── prism-73F718B9234C00C5C14AB6A11BF239A103F0B0F93B69CD55CB5C6530501182EB.css
│   │   │       └── prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
│   │   ├── 10-readme-index/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FPM.ftd
│   │   │   │       └── README.md
│   │   │   └── output/
│   │   │       ├── FPM/
│   │   │       │   └── index.html
│   │   │       └── index.html
│   │   ├── 11-readme-with-index/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       ├── README.md
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 12-translation/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FPM.ftd
│   │   │   │       ├── blog.ftd
│   │   │   │       └── not-render.ftd
│   │   │   └── output/
│   │   │       ├── -/
│   │   │       │   ├── index.html
│   │   │       │   └── translation-status/
│   │   │       │       └── index.html
│   │   │       ├── FPM.ftd
│   │   │       ├── blog/
│   │   │       │   └── index.html
│   │   │       ├── db/
│   │   │       │   └── index.html
│   │   │       ├── index.html
│   │   │       └── lib/
│   │   │           └── index.html
│   │   ├── 13-translation-hindi/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── .history/
│   │   │   │       │   ├── .latest.ftd
│   │   │   │       │   └── lib.1640192744709173000.ftd
│   │   │   │       ├── .tracks/
│   │   │   │       │   └── lib.ftd.track
│   │   │   │       ├── FPM/
│   │   │   │       │   └── translation/
│   │   │   │       │       └── out-of-date.ftd
│   │   │   │       ├── FPM.ftd
│   │   │   │       └── lib.ftd
│   │   │   └── output/
│   │   │       ├── FPM/
│   │   │       │   ├── index.html
│   │   │       │   └── translation-status/
│   │   │       │       └── index.html
│   │   │       ├── FPM.ftd
│   │   │       ├── index.html
│   │   │       └── lib/
│   │   │           └── index.html
│   │   ├── 14-translation-mark-upto-date-and-translation-status/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── .history/
│   │   │   │       │   ├── .latest.ftd
│   │   │   │       │   └── lib.1639759839283128000.ftd
│   │   │   │       ├── FPM.ftd
│   │   │   │       └── lib.ftd
│   │   │   └── output/
│   │   │       └── lib.ftd.track
│   │   ├── 15-fpm-dependency-alias/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .fpm.ftd
│   │   │   │   └── amitu/
│   │   │   │       ├── FASTN.ftd
│   │   │   │       └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 16-include-processor/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── FASTN.ftd
│   │   │   │   ├── code/
│   │   │   │   │   └── dummy_code.rs
│   │   │   │   └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
│   │   │       ├── default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       └── manifest.json
│   │   ├── 17-sitemap/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       ├── guide/
│   │   │       │   └── install.ftd
│   │   │       └── index.ftd
│   │   ├── 18-fmt/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── FASTN.ftd
│   │   │   │   └── index.ftd
│   │   │   └── output/
│   │   │       ├── .fastn/
│   │   │       │   └── config.json
│   │   │       ├── FASTN.ftd
│   │   │       └── index.ftd
│   │   ├── 19-offline-build/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── FASTN.ftd
│   │   │   │   └── index.ftd
│   │   │   └── output/
│   │   │       ├── -/
│   │   │       │   └── fastn-stack.github.io/
│   │   │       │       └── fastn-js/
│   │   │       │           └── download.js
│   │   │       ├── FASTN.ftd
│   │   │       ├── code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css
│   │   │       ├── code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css
│   │   │       ├── code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css
│   │   │       ├── code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css
│   │   │       ├── code-theme-256C21B515FC9E77F95D88689A4086B9D9406B7AAE3A273780FE8B8748C5A7D2.css
│   │   │       ├── code-theme-4DD8479BE14A755645BC09FF433FB70EB4CB28F0CBF3CA98DCB71B244B85B194.css
│   │   │       ├── code-theme-60E02531E77333F3F1B636C4FC43E976EA9F41AD75268B2DD825C33C68B573A6.css
│   │   │       ├── code-theme-6EB6F03F9F578742CA0CD1189693E43A6135D910989ADD88CA3C0D6117EE24D7.css
│   │   │       ├── code-theme-7852E516BA094B01897820BB3432BE553FE5B28F00E9CA0EBC9DFFB8312EE8BF.css
│   │   │       ├── code-theme-792C7BB9F4C8DFF3E0CBC354D2084DBF71BC5750C2C1357F0E7D936867AFAB62.css
│   │   │       ├── code-theme-88F91252A8A0EA125B4BA2C7B85E65580DB580F1477931AADCB5118E4E69D1CD.css
│   │   │       ├── code-theme-8C59190F5018F48CCBB063359072EE9053D04923BBC5D1BA52B574E78D8C536A.css
│   │   │       ├── code-theme-8CCA3D600F91FA55950DF3132F2ABE4BA14CEEA13CD23E157BF6A137762B8452.css
│   │   │       ├── code-theme-95B9118AFC8631777EEBBD89B2066C3706A6DF3579B14F41AF05564E41CAA09C.css
│   │   │       ├── code-theme-96E503EA0E8F80C5DDF81545C9B1A40DE4CDB7CD8F52664F747FD9E7BB0207B8.css
│   │   │       ├── code-theme-99CD7B013C96C4632F0AEA39AC265387B814AE85A7D33666A4AE4BEFF59016D0.css
│   │   │       ├── code-theme-9A3284FD117DFF7CFD432FF860A5E14169FA592BC3DA4F5E8A6975143F5EA07F.css
│   │   │       ├── code-theme-9A45313F167DBD90654BFD5BB3BC0BDF6AE447485C30B0389ADA7B49C069E46A.css
│   │   │       ├── code-theme-A24DC8F09D03756A62923E8A883CAE3B938D54E2813F0855312D2554DBE97BAD.css
│   │   │       ├── code-theme-A352AF572179AB980583D41BC41ADDBA36C4C17757A34C1C6AAAF2C253E25CE3.css
│   │   │       ├── code-theme-B3AEA322EADEDA61F0E219845A0E9C8E73F6345E49362B46E6F52CEE40471248.css
│   │   │       ├── code-theme-B68AA27E05B319F04A9CD747AADBF9B9CD791E040DEC519AE9544B4FF65DDBAC.css
│   │   │       ├── code-theme-CFBB665E50E0439263BF0F3D59B1F0F20F40F379C81B1B14AA9E16DDF70F70E6.css
│   │   │       ├── code-theme-DC76F700474E809F7BA2D9914793D04881B17EA4699BA9C568C83D32A18B0173.css
│   │   │       ├── default-A1BB16FF145420D65E4C815B5AD6C4DA6435B25A2B2ED162A798FF368CEBF57B.js
│   │   │       ├── index.ftd
│   │   │       ├── index.html
│   │   │       ├── manifest.json
│   │   │       ├── markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
│   │   │       ├── prism-73F718B9234C00C5C14AB6A11BF239A103F0B0F93B69CD55CB5C6530501182EB.css
│   │   │       └── prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
│   │   ├── 20-fastn-update-check/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       └── index.ftd
│   │   ├── 21-http-endpoint/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       └── index.ftd
│   │   ├── 22-request-data-processor/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   ├── FASTN.ftd
│   │   │   │   ├── err.ftd
│   │   │   │   └── index.ftd
│   │   │   └── output/
│   │   │       ├── FASTN.ftd
│   │   │       ├── code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css
│   │   │       ├── code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css
│   │   │       ├── code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css
│   │   │       ├── code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css
│   │   │       ├── code-theme-256C21B515FC9E77F95D88689A4086B9D9406B7AAE3A273780FE8B8748C5A7D2.css
│   │   │       ├── code-theme-4DD8479BE14A755645BC09FF433FB70EB4CB28F0CBF3CA98DCB71B244B85B194.css
│   │   │       ├── code-theme-60E02531E77333F3F1B636C4FC43E976EA9F41AD75268B2DD825C33C68B573A6.css
│   │   │       ├── code-theme-6EB6F03F9F578742CA0CD1189693E43A6135D910989ADD88CA3C0D6117EE24D7.css
│   │   │       ├── code-theme-7852E516BA094B01897820BB3432BE553FE5B28F00E9CA0EBC9DFFB8312EE8BF.css
│   │   │       ├── code-theme-792C7BB9F4C8DFF3E0CBC354D2084DBF71BC5750C2C1357F0E7D936867AFAB62.css
│   │   │       ├── code-theme-88F91252A8A0EA125B4BA2C7B85E65580DB580F1477931AADCB5118E4E69D1CD.css
│   │   │       ├── code-theme-8C59190F5018F48CCBB063359072EE9053D04923BBC5D1BA52B574E78D8C536A.css
│   │   │       ├── code-theme-8CCA3D600F91FA55950DF3132F2ABE4BA14CEEA13CD23E157BF6A137762B8452.css
│   │   │       ├── code-theme-95B9118AFC8631777EEBBD89B2066C3706A6DF3579B14F41AF05564E41CAA09C.css
│   │   │       ├── code-theme-96E503EA0E8F80C5DDF81545C9B1A40DE4CDB7CD8F52664F747FD9E7BB0207B8.css
│   │   │       ├── code-theme-99CD7B013C96C4632F0AEA39AC265387B814AE85A7D33666A4AE4BEFF59016D0.css
│   │   │       ├── code-theme-9A3284FD117DFF7CFD432FF860A5E14169FA592BC3DA4F5E8A6975143F5EA07F.css
│   │   │       ├── code-theme-9A45313F167DBD90654BFD5BB3BC0BDF6AE447485C30B0389ADA7B49C069E46A.css
│   │   │       ├── code-theme-A24DC8F09D03756A62923E8A883CAE3B938D54E2813F0855312D2554DBE97BAD.css
│   │   │       ├── code-theme-A352AF572179AB980583D41BC41ADDBA36C4C17757A34C1C6AAAF2C253E25CE3.css
│   │   │       ├── code-theme-B3AEA322EADEDA61F0E219845A0E9C8E73F6345E49362B46E6F52CEE40471248.css
│   │   │       ├── code-theme-B68AA27E05B319F04A9CD747AADBF9B9CD791E040DEC519AE9544B4FF65DDBAC.css
│   │   │       ├── code-theme-CFBB665E50E0439263BF0F3D59B1F0F20F40F379C81B1B14AA9E16DDF70F70E6.css
│   │   │       ├── code-theme-DC76F700474E809F7BA2D9914793D04881B17EA4699BA9C568C83D32A18B0173.css
│   │   │       ├── default-D4F9C23DF6372E1C3161B3560431CCE641AED44770DD55B8AAB3DBEB0A1F3533.js
│   │   │       ├── err.ftd
│   │   │       ├── manifest.json
│   │   │       ├── markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
│   │   │       ├── prism-73F718B9234C00C5C14AB6A11BF239A103F0B0F93B69CD55CB5C6530501182EB.css
│   │   │       └── prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
│   │   ├── 23-toc-processor-test/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       └── index.ftd
│   │   ├── 27-wasm-backend/
│   │   │   ├── cmd.p1
│   │   │   ├── input/
│   │   │   │   └── amitu/
│   │   │   │       ├── FPM.ftd
│   │   │   │       ├── backend.wasm
│   │   │   │       ├── index.ftd
│   │   │   │       ├── post-two.ftd
│   │   │   │       └── post.ftd
│   │   │   ├── output/
│   │   │   │   ├── -/
│   │   │   │   │   ├── index.html
│   │   │   │   │   └── www.amitu.com/
│   │   │   │   │       └── backend.wasm
│   │   │   │   ├── FPM.ftd
│   │   │   │   ├── index.html
│   │   │   │   ├── post/
│   │   │   │   │   └── index.html
│   │   │   │   └── post-two/
│   │   │   │       └── index.html
│   │   │   └── wasm_backend/
│   │   │       ├── .cargo/
│   │   │       │   └── config
│   │   │       ├── .gitignore
│   │   │       ├── Cargo.toml
│   │   │       └── src/
│   │   │           ├── lib.rs
│   │   │           └── types.rs
│   │   ├── 28-text-input-VALUE/
│   │   │   ├── cmd.p1
│   │   │   └── input/
│   │   │       ├── FASTN.ftd
│   │   │       ├── actions/
│   │   │       │   └── create-account.ftd
│   │   │       └── index.ftd
│   │   └── fbt.p1
│   ├── ftd/
│   │   ├── design.ftd
│   │   ├── fastn-lib.ftd
│   │   ├── info.ftd
│   │   ├── markdown.ftd
│   │   ├── processors.ftd
│   │   └── translation/
│   │       ├── available-languages.ftd
│   │       ├── missing.ftd
│   │       ├── never-marked.ftd
│   │       ├── original-status.ftd
│   │       ├── out-of-date.ftd
│   │       ├── translation-status.ftd
│   │       └── upto-date.ftd
│   ├── ftd_2022.html
│   ├── redirect.html
│   ├── src/
│   │   ├── auto_import.rs
│   │   ├── catch_panic.rs
│   │   ├── commands/
│   │   │   ├── Changelog.md
│   │   │   ├── build.rs
│   │   │   ├── check.rs
│   │   │   ├── fmt.rs
│   │   │   ├── mod.rs
│   │   │   ├── query.rs
│   │   │   ├── serve.rs
│   │   │   ├── test.rs
│   │   │   └── translation_status.rs
│   │   ├── config/
│   │   │   ├── config_temp.rs
│   │   │   ├── mod.rs
│   │   │   └── utils.rs
│   │   ├── doc.rs
│   │   ├── ds.rs
│   │   ├── error.rs
│   │   ├── file.rs
│   │   ├── font.rs
│   │   ├── google_sheets.rs
│   │   ├── host_builtins.rs
│   │   ├── http.rs
│   │   ├── i18n/
│   │   │   ├── mod.rs
│   │   │   └── translation.rs
│   │   ├── lib.rs
│   │   ├── library/
│   │   │   ├── document.rs
│   │   │   ├── fastn_dot_ftd.rs
│   │   │   ├── mod.rs
│   │   │   └── toc.rs
│   │   ├── library2022/
│   │   │   ├── cr_meta.rs
│   │   │   ├── get_version_data.rs
│   │   │   ├── mod.rs
│   │   │   ├── processor/
│   │   │   │   ├── apps.rs
│   │   │   │   ├── document.rs
│   │   │   │   ├── fetch_file.rs
│   │   │   │   ├── figma_tokens.rs
│   │   │   │   ├── figma_typography_tokens.rs
│   │   │   │   ├── get_data.rs
│   │   │   │   ├── google_sheets.rs
│   │   │   │   ├── http.rs
│   │   │   │   ├── lang.rs
│   │   │   │   ├── lang_details.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── package_query.rs
│   │   │   │   ├── pg.rs
│   │   │   │   ├── query.rs
│   │   │   │   ├── request_data.rs
│   │   │   │   ├── sitemap.rs
│   │   │   │   ├── sql.rs
│   │   │   │   ├── sqlite.rs
│   │   │   │   ├── toc.rs
│   │   │   │   ├── user_details.rs
│   │   │   │   └── user_group.rs
│   │   │   └── utils.rs
│   │   ├── manifest/
│   │   │   ├── manifest_to_package.rs
│   │   │   ├── mod.rs
│   │   │   └── utils.rs
│   │   ├── migrations/
│   │   │   ├── fastn_migrations.rs
│   │   │   └── mod.rs
│   │   ├── package/
│   │   │   ├── app.rs
│   │   │   ├── dependency.rs
│   │   │   ├── mod.rs
│   │   │   ├── package_doc.rs
│   │   │   └── redirects.rs
│   │   ├── sitemap/
│   │   │   ├── dynamic_urls.rs
│   │   │   ├── mod.rs
│   │   │   ├── section.rs
│   │   │   ├── toc.rs
│   │   │   └── utils.rs
│   │   ├── snapshot.rs
│   │   ├── tracker.rs
│   │   ├── translation.rs
│   │   ├── utils.rs
│   │   ├── version.rs
│   │   └── wasm.rs
│   └── test_fastn.ftd
├── fastn-daemon/
│   ├── Cargo.toml
│   └── src/
│       ├── cli.rs
│       ├── init.rs
│       ├── lib.rs
│       ├── main.rs
│       ├── remote.rs
│       ├── run.rs
│       └── status.rs
├── fastn-ds/
│   ├── .gitignore
│   ├── Cargo.toml
│   └── src/
│       ├── http.rs
│       ├── lib.rs
│       ├── main.rs
│       ├── reqwest_util.rs
│       ├── user_data.rs
│       └── utils.rs
├── fastn-expr/
│   ├── Cargo.toml
│   └── src/
│       ├── interpolator.rs
│       ├── lib.rs
│       ├── parser.rs
│       └── tokenizer.rs
├── fastn-issues/
│   ├── Cargo.toml
│   └── src/
│       ├── initialization.rs
│       ├── initialization_display.rs
│       └── lib.rs
├── fastn-js/
│   ├── Cargo.toml
│   ├── README.md
│   ├── ftd-js.css
│   ├── js/
│   │   ├── dom.js
│   │   ├── fastn.js
│   │   ├── fastn_test.js
│   │   ├── ftd-language.js
│   │   ├── ftd.js
│   │   ├── postInit.js
│   │   ├── test.js
│   │   ├── utils.js
│   │   ├── virtual.js
│   │   └── web-component.js
│   ├── marked.js
│   ├── prism/
│   │   ├── prism-bash.js
│   │   ├── prism-diff.js
│   │   ├── prism-javascript.js
│   │   ├── prism-json.js
│   │   ├── prism-line-highlight.css
│   │   ├── prism-line-highlight.js
│   │   ├── prism-line-numbers.css
│   │   ├── prism-line-numbers.js
│   │   ├── prism-markdown.js
│   │   ├── prism-python.js
│   │   ├── prism-rust.js
│   │   ├── prism-sql.js
│   │   └── prism.js
│   ├── src/
│   │   ├── ast.rs
│   │   ├── component.rs
│   │   ├── component_invocation.rs
│   │   ├── component_statement.rs
│   │   ├── conditional_component.rs
│   │   ├── constants.rs
│   │   ├── device.rs
│   │   ├── event.rs
│   │   ├── lib.rs
│   │   ├── loop_component.rs
│   │   ├── main.rs
│   │   ├── mutable_variable.rs
│   │   ├── or_type.rs
│   │   ├── property.rs
│   │   ├── record.rs
│   │   ├── ssr.rs
│   │   ├── static_variable.rs
│   │   ├── to_js.rs
│   │   ├── udf.rs
│   │   ├── udf_statement.rs
│   │   └── utils.rs
│   └── tests/
│       ├── 01-basic.html
│       ├── 02-basic-event.html
│       ├── 03-event-1.html
│       ├── 04-component.html
│       ├── 05-complex-component.html
│       ├── 06-complex.html
│       ├── 07-dynamic-dom.html
│       ├── 08-dynamic-dom-2.html
│       ├── 09-dynamic-dom-3.html
│       ├── 10-dynamic-dom-list.html
│       ├── 11-record.html
│       ├── 12-record-update.html
│       ├── 13-string-refs.html
│       ├── 14-passing-mutable.html
│       ├── 15-conditional-property.html
│       ├── 16-color.html
│       └── 17-children.html
├── fastn-lang/
│   ├── Cargo.toml
│   └── src/
│       ├── error.rs
│       ├── language.rs
│       └── lib.rs
├── fastn-package/
│   ├── Cargo.toml
│   ├── create-db.sql
│   ├── fastn_2021.ftd
│   ├── fastn_2023.ftd
│   └── src/
│       ├── lib.rs
│       └── old_fastn.rs
├── fastn-preact/
│   ├── README.md
│   └── examples/
│       ├── .fastn/
│       │   └── config.json
│       ├── 01-counter.ftd
│       ├── 01-counter.html
│       ├── 02-counter-component.ftd
│       ├── 02-counter-component.html
│       ├── 03-js-interop.ftd
│       ├── 03-js-interop.html
│       ├── 04-record-field.ftd
│       ├── 04-record-field.html
│       ├── 05-list.ftd
│       ├── 05-list.html
│       ├── 06-record-2-broken.html
│       ├── 06-record-2-fixed.html
│       ├── 06-record-2.ftd
│       ├── 07-nested-record.ftd
│       ├── 07-nested-record.html
│       ├── 08-nested-list-with-fastn-data.html
│       ├── 08-nested-list.ftd
│       ├── 08-nested-list.html
│       ├── FASTN.ftd
│       └── index.ftd
├── fastn-remote/
│   ├── Cargo.toml
│   └── src/
│       ├── cli.rs
│       ├── init.rs
│       ├── lib.rs
│       ├── listen.rs
│       ├── main.rs
│       ├── rexec.rs
│       ├── rshell.rs
│       └── run.rs
├── fastn-resolved/
│   ├── Cargo.toml
│   └── src/
│       ├── component.rs
│       ├── evalexpr/
│       │   ├── context/
│       │   │   ├── mod.rs
│       │   │   └── predefined/
│       │   │       └── mod.rs
│       │   ├── error/
│       │   │   ├── display.rs
│       │   │   └── mod.rs
│       │   ├── feature_serde/
│       │   │   └── mod.rs
│       │   ├── function/
│       │   │   ├── builtin.rs
│       │   │   └── mod.rs
│       │   ├── interface/
│       │   │   └── mod.rs
│       │   ├── mod.rs
│       │   ├── operator/
│       │   │   ├── display.rs
│       │   │   └── mod.rs
│       │   ├── token/
│       │   │   ├── display.rs
│       │   │   └── mod.rs
│       │   ├── tree/
│       │   │   ├── display.rs
│       │   │   ├── iter.rs
│       │   │   └── mod.rs
│       │   └── value/
│       │       ├── display.rs
│       │       ├── mod.rs
│       │       └── value_type.rs
│       ├── expression.rs
│       ├── function.rs
│       ├── kind.rs
│       ├── lib.rs
│       ├── module_thing.rs
│       ├── or_type.rs
│       ├── record.rs
│       ├── tdoc.rs
│       ├── value.rs
│       ├── variable.rs
│       └── web_component.rs
├── fastn-runtime/
│   ├── .gitignore
│   ├── Cargo.toml
│   └── src/
│       ├── element.rs
│       ├── extensions.rs
│       ├── fastn_type_functions.rs
│       ├── html.rs
│       ├── lib.rs
│       ├── main.rs
│       ├── resolver.rs
│       ├── tdoc.rs
│       ├── utils.rs
│       └── value.rs
├── fastn-update/
│   ├── Cargo.toml
│   └── src/
│       ├── lib.rs
│       └── utils.rs
├── fastn-utils/
│   ├── Cargo.toml
│   └── src/
│       ├── lib.rs
│       └── sql.rs
├── fastn-wasm/
│   ├── Cargo.toml
│   └── src/
│       ├── ast.rs
│       ├── elem.rs
│       ├── export.rs
│       ├── expression.rs
│       ├── func.rs
│       ├── func_def.rs
│       ├── helpers.rs
│       ├── import.rs
│       ├── lib.rs
│       ├── memory.rs
│       ├── pl.rs
│       ├── table.rs
│       └── ty.rs
├── fastn-wasm-runtime/
│   ├── 1.wast
│   ├── Cargo.toml
│   ├── columns.clj
│   ├── columns.ftd
│   ├── src/
│   │   ├── control.rs
│   │   ├── document.rs
│   │   ├── dom.rs
│   │   ├── element.rs
│   │   ├── event.rs
│   │   ├── f.wat
│   │   ├── g.wast
│   │   ├── lib.rs
│   │   ├── main.rs
│   │   ├── memory/
│   │   │   ├── gc.rs
│   │   │   ├── heap.rs
│   │   │   ├── helper.rs
│   │   │   ├── mod.rs
│   │   │   ├── pointer.rs
│   │   │   ├── ui.rs
│   │   │   └── wasm.rs
│   │   ├── operation.rs
│   │   ├── renderable/
│   │   │   ├── dom_helpers.rs
│   │   │   └── mod.rs
│   │   ├── server/
│   │   │   ├── dom.rs
│   │   │   ├── html.rs
│   │   │   └── mod.rs
│   │   ├── terminal/
│   │   │   └── mod.rs
│   │   ├── wasm.rs
│   │   ├── wasm_helpers.rs
│   │   ├── web/
│   │   │   ├── dom.rs
│   │   │   ├── exports.rs
│   │   │   ├── linker.js
│   │   │   ├── main.rs
│   │   │   └── mod.rs
│   │   └── wgpu/
│   │       ├── boilerplate.rs
│   │       ├── control.rs
│   │       ├── event.rs
│   │       ├── mod.rs
│   │       ├── operations.rs
│   │       ├── rectangles.rs
│   │       ├── rectangles.wgsl
│   │       └── runtime.rs
│   ├── t.wat
│   └── test.wasm
├── fastn-xtask/
│   ├── Cargo.toml
│   └── src/
│       ├── build_wasm.rs
│       ├── helpers.rs
│       ├── lib.rs
│       ├── optimise_wasm.rs
│       ├── publish_app.rs
│       ├── run_template.rs
│       ├── run_ui.rs
│       ├── run_www.rs
│       ├── update_template.rs
│       ├── update_ui.rs
│       └── update_www.rs
├── fastn.com/
│   ├── .fastn/
│   │   └── config.json
│   ├── .gitattributes
│   ├── 404.ftd
│   ├── FASTN/
│   │   ├── ds.ftd
│   │   └── featured-ds.ftd
│   ├── FASTN.ftd
│   ├── README.md
│   ├── ambassadors/
│   │   ├── how-it-works.ftd
│   │   └── index.ftd
│   ├── assets/
│   │   ├── js/
│   │   │   ├── download.js
│   │   │   ├── figma.js
│   │   │   └── typo.js
│   │   └── links.css
│   ├── author/
│   │   ├── how-to/
│   │   │   ├── create-fastn-package.ftd
│   │   │   ├── create-font-package.ftd
│   │   │   ├── fifthtry-hosting.ftd
│   │   │   ├── github-pages.ftd
│   │   │   ├── install.ftd
│   │   │   ├── open-terminal.ftd
│   │   │   ├── sublime.ftd
│   │   │   ├── upload-image-ide.ftd
│   │   │   ├── vercel.ftd
│   │   │   └── vscode.ftd
│   │   ├── index.ftd
│   │   └── setup/
│   │       ├── hello.ftd
│   │       ├── macos.ftd
│   │       ├── uninstall.ftd
│   │       └── windows.ftd
│   ├── backend/
│   │   ├── app.ftd
│   │   ├── country-details/
│   │   │   ├── dynamic-country-list-page.ftd
│   │   │   ├── http-data-modelling.ftd
│   │   │   └── index.ftd
│   │   ├── custom-urls.ftd
│   │   ├── django.ftd
│   │   ├── dynamic-urls.ftd
│   │   ├── endpoint.ftd
│   │   ├── env-vars.ftd
│   │   ├── ftd-redirect.ftd
│   │   ├── index.ftd
│   │   ├── redirects.ftd
│   │   └── wasm.ftd
│   ├── best-practices/
│   │   ├── auto-import.ftd
│   │   ├── commenting-guidelines.ftd
│   │   ├── container-guidelines.ftd
│   │   ├── device.ftd
│   │   ├── dump.md
│   │   ├── formatting.ftd
│   │   ├── fscript-guidelines.ftd
│   │   ├── import.ftd
│   │   ├── index.ftd
│   │   ├── inherited-types.ftd
│   │   ├── optional-arg-not-null.ftd
│   │   ├── property-guidelines.ftd
│   │   ├── same-argument-attribute-type.ftd
│   │   ├── self-referencing.ftd
│   │   ├── style-argument.ftd
│   │   ├── use-conditions.ftd
│   │   ├── utils.ftd
│   │   └── variable-type.ftd
│   ├── blog/
│   │   ├── acme.ftd
│   │   ├── authors.ftd
│   │   ├── breakpoint.ftd
│   │   ├── cli-check-for-updates.ftd
│   │   ├── content-library.ftd
│   │   ├── design-system-part-2.ftd
│   │   ├── design-system.ftd
│   │   ├── domain-components.ftd
│   │   ├── figma.ftd
│   │   ├── index.ftd
│   │   ├── lib.ftd
│   │   ├── meta-data-blog.ftd
│   │   ├── personal-website-1.ftd
│   │   ├── philippines.ftd
│   │   ├── prove-you-wrong.ftd
│   │   ├── search.ftd
│   │   ├── show-cs.ftd
│   │   ├── strongly-typed.ftd
│   │   ├── the-intimidation-of-programming.ftd
│   │   ├── trizwitlabs.ftd
│   │   ├── web-components.ftd
│   │   ├── wittyhacks.ftd
│   │   └── writer-journey.ftd
│   ├── book/
│   │   ├── 01-introduction/
│   │   │   ├── 00-why-fastn.ftd
│   │   │   ├── 01-fifthtry.ftd
│   │   │   ├── 02-local-setup.ftd
│   │   │   ├── 03-hello-world.ftd
│   │   │   ├── 04-about-ide.ftd
│   │   │   ├── 05-create-website.ftd
│   │   │   ├── 06-manual-upload.ftd
│   │   │   ├── 07-fastn-essentials.ftd
│   │   │   ├── 08-about-fastn.ftd
│   │   │   ├── 09-about-index.ftd
│   │   │   ├── 10-use-design-system.ftd
│   │   │   └── 11-use-component-library.ftd
│   │   ├── 02-local-setup/
│   │   │   ├── 01-local-setup.ftd
│   │   │   └── 02-hello-world.ftd
│   │   ├── 03-fifthtry/
│   │   │   ├── 00-about-ide.ftd
│   │   │   └── 01-create-website.ftd
│   │   ├── 04-fastn-routing/
│   │   │   ├── 01-fifthtry.ftd
│   │   │   ├── 01-github.ftd
│   │   │   ├── 02-repo.ftd
│   │   │   ├── 03-gh-pages.ftd
│   │   │   ├── 04-codespaces.ftd
│   │   │   └── 05-first-edit.ftd
│   │   ├── 05-fastn-basics/
│   │   │   └── 01-intro.ftd
│   │   ├── 1-foreword.ftd
│   │   ├── 2-preface.ftd
│   │   ├── 3-intro.ftd
│   │   ├── appendix/
│   │   │   ├── a-http.ftd
│   │   │   ├── b-url.ftd
│   │   │   ├── c-terminal.ftd
│   │   │   ├── d-common-commands.ftd
│   │   │   ├── e-install.ftd
│   │   │   ├── f-editor.ftd
│   │   │   ├── g-hosting.ftd
│   │   │   └── index.ftd
│   │   └── index.ftd
│   ├── brand-guidelines.ftd
│   ├── case-study/
│   │   └── todo.ftd
│   ├── certificates/
│   │   ├── champions/
│   │   │   ├── adarsh-gupta.ftd
│   │   │   ├── ajit-garg.ftd
│   │   │   ├── atharva-pise.ftd
│   │   │   ├── ayush-soni.ftd
│   │   │   ├── govindaraman.ftd
│   │   │   ├── jahanvi-raycha.ftd
│   │   │   ├── krish-gupta.ftd
│   │   │   ├── rutuja-kapate.ftd
│   │   │   ├── sayak-saha.ftd
│   │   │   ├── shantnu-fartode.ftd
│   │   │   └── sreejita-dutta.ftd
│   │   └── index.ftd
│   ├── cms.ftd
│   ├── community/
│   │   ├── events/
│   │   │   ├── roadshow.ftd
│   │   │   └── roadshows/
│   │   │       ├── ahmedabad.ftd
│   │   │       ├── bangalore.ftd
│   │   │       ├── bhopal.ftd
│   │   │       ├── delhi.ftd
│   │   │       ├── hyderabad.ftd
│   │   │       ├── indore.ftd
│   │   │       ├── jaipur.ftd
│   │   │       ├── kolkata.ftd
│   │   │       ├── lucknow.ftd
│   │   │       ├── mumbai.ftd
│   │   │       ├── nagpur.ftd
│   │   │       └── ujjain.ftd
│   │   └── weekly-contest.ftd
│   ├── community.ftd
│   ├── compare/
│   │   ├── react.ftd
│   │   └── webflow.ftd
│   ├── components/
│   │   ├── certificate.ftd
│   │   ├── common.ftd
│   │   ├── json-exporter.ftd
│   │   ├── social-links.ftd
│   │   ├── typo-exporter.ftd
│   │   └── utils.ftd
│   ├── consulting.ftd
│   ├── content-library/
│   │   ├── compare.ftd
│   │   └── index.ftd
│   ├── contribute-code.ftd
│   ├── cs/
│   │   ├── create-cs.ftd
│   │   ├── figma-to-ftd.ftd
│   │   ├── ftd-to-figma.ftd
│   │   ├── modify-cs.ftd
│   │   ├── sample-codes/
│   │   │   └── create-cs.ftd
│   │   └── use-color-package.ftd
│   ├── d/
│   │   ├── architecture.ftd
│   │   ├── fastn-core-crate.ftd
│   │   ├── fastn-crate.ftd
│   │   ├── fastn-package-spec.ftd
│   │   ├── fastn-package.ftd
│   │   ├── ftd-crate.ftd
│   │   ├── index.ftd
│   │   ├── m.ftd
│   │   ├── next-edition.ftd
│   │   └── v0.5/
│   │       └── index.ftd
│   ├── demo.ftd
│   ├── deploy/
│   │   ├── heroku.ftd
│   │   └── index.ftd
│   ├── design.css
│   ├── donate.ftd
│   ├── events/
│   │   ├── 01.ftd
│   │   ├── hackodisha.ftd
│   │   ├── index.ftd
│   │   ├── web-dev-using-ftd.ftd
│   │   ├── webdev-with-ftd.ftd
│   │   └── weekly-contest/
│   │       ├── index.ftd
│   │       ├── week-1-quote-event.ftd
│   │       ├── week-1-quote.ftd
│   │       ├── week-2-code.ftd
│   │       ├── week-3-hero.ftd
│   │       └── week-4-cta.ftd
│   ├── examples/
│   │   ├── iframe-demo.ftd
│   │   └── index.ftd
│   ├── expander/
│   │   ├── basic-ui.ftd
│   │   ├── border-radius.ftd
│   │   ├── button.ftd
│   │   ├── components.ftd
│   │   ├── ds/
│   │   │   ├── ds-cs.ftd
│   │   │   ├── ds-page.ftd
│   │   │   ├── ds-typography.ftd
│   │   │   ├── markdown.ftd
│   │   │   ├── meta-data.ftd
│   │   │   └── understanding-sitemap.ftd
│   │   ├── events.ftd
│   │   ├── hello-world.ftd
│   │   ├── imagemodule/
│   │   │   └── index.ftd
│   │   ├── index.ftd
│   │   ├── layout/
│   │   │   └── index.ftd
│   │   ├── lib.ftd
│   │   ├── polish.ftd
│   │   ├── publish.ftd
│   │   └── sitemap-document.ftd
│   ├── f.ftd
│   ├── featured/
│   │   ├── blog-templates.ftd
│   │   ├── blogs/
│   │   │   ├── blog-components.ftd
│   │   │   ├── blog-template-1.ftd
│   │   │   ├── blue-wave.ftd
│   │   │   ├── dash-dash-ds.ftd
│   │   │   ├── doc-site.ftd
│   │   │   ├── galaxia.ftd
│   │   │   ├── little-blue.ftd
│   │   │   ├── mg-blog.ftd
│   │   │   ├── mr-blog.ftd
│   │   │   ├── ms-blog.ftd
│   │   │   ├── navy-nebula.ftd
│   │   │   ├── pink-tree.ftd
│   │   │   ├── rocky.ftd
│   │   │   ├── simple-blog.ftd
│   │   │   └── yellow-lily.ftd
│   │   ├── components/
│   │   │   ├── admonitions/
│   │   │   │   └── index.ftd
│   │   │   ├── bling/
│   │   │   │   └── index.ftd
│   │   │   ├── business-cards/
│   │   │   │   ├── card-1.ftd
│   │   │   │   ├── gradient-card.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── midnight-card.ftd
│   │   │   │   ├── pattern-card.ftd
│   │   │   │   └── sunset-card.ftd
│   │   │   ├── buttons/
│   │   │   │   └── index.ftd
│   │   │   ├── code-block.ftd
│   │   │   ├── footers/
│   │   │   │   ├── footer-3.ftd
│   │   │   │   ├── footer.ftd
│   │   │   │   └── index.ftd
│   │   │   ├── headers/
│   │   │   │   ├── header.ftd
│   │   │   │   └── index.ftd
│   │   │   ├── index.ftd
│   │   │   ├── language-switcher.ftd
│   │   │   ├── modals/
│   │   │   │   ├── index.ftd
│   │   │   │   ├── modal-1.ftd
│   │   │   │   └── modal-cover.ftd
│   │   │   ├── quotes/
│   │   │   │   ├── author-icon-quotes/
│   │   │   │   │   ├── demo-1.ftd
│   │   │   │   │   └── index.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── quotes-with-images/
│   │   │   │   │   ├── demo-1.ftd
│   │   │   │   │   └── index.ftd
│   │   │   │   └── simple-quotes/
│   │   │   │       ├── demo-1.ftd
│   │   │   │       ├── demo-10.ftd
│   │   │   │       ├── demo-11.ftd
│   │   │   │       ├── demo-12.ftd
│   │   │   │       ├── demo-2.ftd
│   │   │   │       ├── demo-3.ftd
│   │   │   │       ├── demo-4.ftd
│   │   │   │       ├── demo-5.ftd
│   │   │   │       ├── demo-6.ftd
│   │   │   │       ├── demo-7.ftd
│   │   │   │       ├── demo-8.ftd
│   │   │   │       ├── demo-9.ftd
│   │   │   │       └── index.ftd
│   │   │   └── subscription-form.ftd
│   │   ├── contributors/
│   │   │   ├── designers/
│   │   │   │   ├── govindaraman-s/
│   │   │   │   │   └── index.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── jay-kumar/
│   │   │   │   │   └── index.ftd
│   │   │   │   ├── muskan-verma/
│   │   │   │   │   └── index.ftd
│   │   │   │   └── yashveer-mehra/
│   │   │   │       └── index.ftd
│   │   │   └── developers/
│   │   │       ├── arpita-jaiswal/
│   │   │       │   └── index.ftd
│   │   │       ├── ganesh-salunke/
│   │   │       │   └── index.ftd
│   │   │       ├── index.ftd
│   │   │       ├── meenu-kumari/
│   │   │       │   └── index.ftd
│   │   │       ├── priyanka-yadav/
│   │   │       │   └── index.ftd
│   │   │       ├── saurabh-garg/
│   │   │       │   └── index.ftd
│   │   │       ├── saurabh-lohiya/
│   │   │       │   └── index.ftd
│   │   │       └── shaheen-senpai/
│   │   │           └── index.ftd
│   │   ├── cs/
│   │   │   ├── blog-template-1-cs.ftd
│   │   │   ├── blog-template-cs.ftd
│   │   │   ├── blue-heal-cs.ftd
│   │   │   ├── blue-shades.ftd
│   │   │   ├── dark-flame-cs.ftd
│   │   │   ├── forest-cs.ftd
│   │   │   ├── green-shades.ftd
│   │   │   ├── index.ftd
│   │   │   ├── little-blue-cs.ftd
│   │   │   ├── midnight-rush-cs.ftd
│   │   │   ├── midnight-storm-cs.ftd
│   │   │   ├── misty-gray-cs.ftd
│   │   │   ├── navy-nebula-cs.ftd
│   │   │   ├── orange-shades.ftd
│   │   │   ├── pink-tree-cs.ftd
│   │   │   ├── pretty-cs.ftd
│   │   │   ├── red-shades.ftd
│   │   │   ├── saturated-sunset-cs.ftd
│   │   │   ├── violet-shades.ftd
│   │   │   ├── winter-cs.ftd
│   │   │   └── yellow-lily-cs.ftd
│   │   ├── design.ftd
│   │   ├── doc-sites.ftd
│   │   ├── ds/
│   │   │   ├── api-ds.ftd
│   │   │   ├── blue-sapphire-template.ftd
│   │   │   ├── dash-dash-ds.ftd
│   │   │   ├── doc-site.ftd
│   │   │   ├── docusaurus-theme.ftd
│   │   │   ├── forest-template.ftd
│   │   │   ├── framework.ftd
│   │   │   ├── midnight-storm.ftd
│   │   │   ├── misty-gray.ftd
│   │   │   ├── mr-ds.ftd
│   │   │   └── spider-book-ds.ftd
│   │   ├── filter.css
│   │   ├── fonts/
│   │   │   ├── arpona.ftd
│   │   │   ├── arya.ftd
│   │   │   ├── biro.ftd
│   │   │   ├── blaka.ftd
│   │   │   ├── index.ftd
│   │   │   ├── inter.ftd
│   │   │   ├── karma.ftd
│   │   │   ├── khand.ftd
│   │   │   ├── lato.ftd
│   │   │   ├── lobster.ftd
│   │   │   ├── mulish.ftd
│   │   │   ├── opensans.ftd
│   │   │   ├── paul-jackson.ftd
│   │   │   ├── pragati-narrow.ftd
│   │   │   ├── roboto-mono.ftd
│   │   │   ├── roboto.ftd
│   │   │   └── tiro.ftd
│   │   ├── fonts-typography.ftd
│   │   ├── index.ftd
│   │   ├── landing/
│   │   │   ├── ct-landing.ftd
│   │   │   ├── docusaurus-theme.ftd
│   │   │   ├── forest-foss-template.ftd
│   │   │   ├── midnight-storm-landing.ftd
│   │   │   ├── misty-gray-landing.ftd
│   │   │   ├── mr-landing.ftd
│   │   │   └── studious-couscous.ftd
│   │   ├── landing-pages.ftd
│   │   ├── new-sections.ftd
│   │   ├── portfolios/
│   │   │   ├── index.ftd
│   │   │   ├── johny-ps.ftd
│   │   │   ├── portfolio.ftd
│   │   │   └── texty-ps.ftd
│   │   ├── resumes/
│   │   │   ├── caffiene.ftd
│   │   │   ├── index.ftd
│   │   │   ├── resume-1.ftd
│   │   │   └── resume-10.ftd
│   │   ├── sections/
│   │   │   ├── accordions/
│   │   │   │   ├── accordion.ftd
│   │   │   │   └── index.ftd
│   │   │   ├── cards/
│   │   │   │   ├── card-1.ftd
│   │   │   │   ├── hastag-card.ftd
│   │   │   │   ├── icon-card.ftd
│   │   │   │   ├── image-card-1.ftd
│   │   │   │   ├── image-gallery-ig.ftd
│   │   │   │   ├── imagen-ig.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── magnifine-card.ftd
│   │   │   │   ├── metric-card.ftd
│   │   │   │   ├── news-card.ftd
│   │   │   │   ├── overlay-card.ftd
│   │   │   │   └── profile-card.ftd
│   │   │   ├── heros/
│   │   │   │   ├── circle-hero.ftd
│   │   │   │   ├── hero-bottom-hug-search.ftd
│   │   │   │   ├── hero-bottom-hug.ftd
│   │   │   │   ├── hero-left-hug-expanded-search.ftd
│   │   │   │   ├── hero-left-hug-expanded.ftd
│   │   │   │   ├── hero-right-hug-expanded-search.ftd
│   │   │   │   ├── hero-right-hug-expanded.ftd
│   │   │   │   ├── hero-right-hug-large.ftd
│   │   │   │   ├── hero-right-hug-search-label.ftd
│   │   │   │   ├── hero-right-hug-search.ftd
│   │   │   │   ├── hero-right-hug.ftd
│   │   │   │   ├── hero-sticky-image.ftd
│   │   │   │   ├── hero-with-2-cta.ftd
│   │   │   │   ├── hero-with-background.ftd
│   │   │   │   ├── hero-with-search.ftd
│   │   │   │   ├── hero-with-social.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   └── parallax-hero.ftd
│   │   │   ├── index.ftd
│   │   │   ├── kvt/
│   │   │   │   ├── index.ftd
│   │   │   │   └── kvt-1.ftd
│   │   │   ├── pricing/
│   │   │   │   ├── index.ftd
│   │   │   │   ├── price-box.ftd
│   │   │   │   └── price-card.ftd
│   │   │   ├── slides/
│   │   │   │   ├── crispy-presentation-theme.ftd
│   │   │   │   ├── giggle-presentation-template.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── rotary-presentation-template.ftd
│   │   │   │   ├── simple-dark-slides.ftd
│   │   │   │   ├── simple-light-slides.ftd
│   │   │   │   └── streamline-slides.ftd
│   │   │   ├── steppers/
│   │   │   │   ├── base-stepper.ftd
│   │   │   │   ├── index.ftd
│   │   │   │   ├── stepper-background.ftd
│   │   │   │   ├── stepper-border-box.ftd
│   │   │   │   ├── stepper-box.ftd
│   │   │   │   ├── stepper-left-image.ftd
│   │   │   │   ├── stepper-left-right.ftd
│   │   │   │   └── stepper-step.ftd
│   │   │   ├── team/
│   │   │   │   ├── index.ftd
│   │   │   │   ├── member-tile.ftd
│   │   │   │   ├── member.ftd
│   │   │   │   └── team-card.ftd
│   │   │   └── testimonials/
│   │   │       ├── index.ftd
│   │   │       ├── testimonial-card.ftd
│   │   │       ├── testimonial-nav-card.ftd
│   │   │       └── testimonial-square-card.ftd
│   │   ├── website-categories.ftd
│   │   └── workshops/
│   │       ├── event-1.ftd
│   │       ├── index.ftd
│   │       └── workshop-1.ftd
│   ├── features/
│   │   ├── community.ftd
│   │   ├── cs.ftd
│   │   ├── design.ftd
│   │   ├── index.ftd
│   │   ├── package-manager.ftd
│   │   ├── server.ftd
│   │   ├── sitemap.ftd
│   │   └── static.ftd
│   ├── frontend/
│   │   ├── design-system.ftd
│   │   ├── index.ftd
│   │   ├── make-page-responsive.ftd
│   │   └── why.ftd
│   ├── ftd/
│   │   ├── attributes.ftd
│   │   ├── audio.ftd
│   │   ├── boolean.ftd
│   │   ├── built-in-functions.ftd
│   │   ├── built-in-rive-functions.ftd
│   │   ├── built-in-types.ftd
│   │   ├── built-in-variables.ftd
│   │   ├── checkbox.ftd
│   │   ├── code.ftd
│   │   ├── column.ftd
│   │   ├── comments.ftd
│   │   ├── common.ftd
│   │   ├── components.ftd
│   │   ├── container-attributes.ftd
│   │   ├── container-root-attributes.ftd
│   │   ├── container.ftd
│   │   ├── data-modelling.ftd
│   │   ├── decimal.ftd
│   │   ├── desktop.ftd
│   │   ├── document.ftd
│   │   ├── events.ftd
│   │   ├── export-exposing.ftd
│   │   ├── external-css.ftd
│   │   ├── functions.ftd
│   │   ├── headers.ftd
│   │   ├── iframe.ftd
│   │   ├── image.ftd
│   │   ├── index.ftd
│   │   ├── integer.ftd
│   │   ├── js-in-function.ftd
│   │   ├── kernel.ftd
│   │   ├── list.ftd
│   │   ├── local-storage.ftd
│   │   ├── loop.ftd
│   │   ├── mobile.ftd
│   │   ├── module.ftd
│   │   ├── optionals.ftd
│   │   ├── or-type.ftd
│   │   ├── p1-grammar.ftd
│   │   ├── record.ftd
│   │   ├── rive-events.ftd
│   │   ├── rive.ftd
│   │   ├── row.ftd
│   │   ├── setup.ftd
│   │   ├── text-attributes.ftd
│   │   ├── text-input.ftd
│   │   ├── text.ftd
│   │   ├── translation.ftd
│   │   ├── ui.ftd
│   │   ├── use-js-css.ftd
│   │   ├── utils.ftd
│   │   ├── variables.ftd
│   │   ├── video.ftd
│   │   ├── visibility.ftd
│   │   └── web-component.ftd
│   ├── ftd-host/
│   │   ├── accessing-files.ftd
│   │   ├── accessing-fonts.ftd
│   │   ├── assets.ftd
│   │   ├── auth.ftd
│   │   ├── foreign-variable.ftd
│   │   ├── get-data.ftd
│   │   ├── http.ftd
│   │   ├── import.ftd
│   │   ├── index.ftd
│   │   ├── package-query.ftd
│   │   ├── pg.ftd
│   │   ├── processor.ftd
│   │   ├── request-data.ftd
│   │   └── sql.ftd
│   ├── functions.js
│   ├── get-started/
│   │   ├── basics.ftd
│   │   ├── browse-pick.ftd
│   │   ├── create-website.ftd
│   │   ├── editor.ftd
│   │   ├── github.ftd
│   │   └── theme.ftd
│   ├── glossary.ftd
│   ├── home-old.ftd
│   ├── home.ftd
│   ├── index.ftd
│   ├── install.sh
│   ├── lib.ftd-0.2
│   ├── old-fastn-sitemap-links.ftd
│   ├── planning/
│   │   ├── border-radius/
│   │   │   └── index.ftd
│   │   ├── button/
│   │   │   └── index.ftd
│   │   ├── country-details/
│   │   │   ├── index.ftd
│   │   │   ├── script1.ftd
│   │   │   ├── script2.ftd
│   │   │   └── script3.ftd
│   │   ├── creators-series.ftd
│   │   ├── developer-course.ftd
│   │   ├── documentation-systems.ftd
│   │   ├── index.ftd
│   │   ├── orientation-planning-video.ftd
│   │   ├── page-nomenclature/
│   │   │   └── index.ftd
│   │   ├── page-nomenclature.ftd
│   │   ├── post-card/
│   │   │   └── index.ftd
│   │   ├── rive/
│   │   │   ├── index.ftd
│   │   │   └── script.txt
│   │   ├── sitemap-features/
│   │   │   ├── document.ftd
│   │   │   └── page-nomenclature.ftd
│   │   ├── temp.md
│   │   ├── temp2.ftd
│   │   └── user-journey.md
│   ├── podcast/
│   │   ├── fastn-p2p-emails.ftd
│   │   ├── index.ftd
│   │   ├── new-fastn-architecture.ftd
│   │   └── sustainability-and-consultancy.ftd
│   ├── qr-codes.ftd
│   ├── rfcs/
│   │   ├── 0000-dependency-versioning.ftd
│   │   ├── 0001-rfc-process.ftd
│   │   ├── 0002-fastn-update.ftd
│   │   ├── 0003-variable-interpolation.ftd
│   │   ├── 0004-incremental-build.ftd
│   │   ├── index.ftd
│   │   ├── lib.ftd
│   │   └── rfc-template.ftd
│   ├── search.ftd
│   ├── search.js
│   ├── select-book-theme.ftd-0.2
│   ├── student-programs/
│   │   ├── ambassador.ftd
│   │   ├── ambassadors/
│   │   │   ├── ajit-garg.ftd
│   │   │   ├── all-ambassadors.ftd
│   │   │   ├── ayush-soni.ftd
│   │   │   └── govindaraman.ftd
│   │   ├── champion.ftd
│   │   ├── champions/
│   │   │   ├── ajit-garg.ftd
│   │   │   ├── all-champions.ftd
│   │   │   ├── arpita-jaiswal.ftd
│   │   │   ├── ayush-soni.ftd
│   │   │   ├── ganesh-salunke.ftd
│   │   │   ├── govindaraman.ftd
│   │   │   ├── harsh-singh.ftd
│   │   │   ├── jahanvi-raycha.ftd
│   │   │   ├── meenu-kumari.ftd
│   │   │   ├── priyanka-yadav.ftd
│   │   │   ├── rithik-seth.ftd
│   │   │   └── saurabh-lohiya.ftd
│   │   ├── introductory-event.ftd
│   │   └── lead.ftd
│   ├── support.ftd
│   ├── syllabus.ftd
│   ├── tutorials/
│   │   └── basic.ftd
│   ├── typo/
│   │   ├── typo-json-to-ftd.ftd
│   │   └── typo-to-json.ftd
│   ├── u/
│   │   ├── arpita-jaiswal.ftd
│   │   ├── ganesh-salunke.ftd
│   │   ├── govindaraman-s.ftd
│   │   ├── index.ftd
│   │   ├── jay-kumar.ftd
│   │   ├── meenu-kumari.ftd
│   │   ├── muskan-verma.ftd
│   │   ├── priyanka-yadav.ftd
│   │   ├── saurabh-garg.ftd
│   │   ├── saurabh-lohiya.ftd
│   │   ├── shaheen-senpai.ftd
│   │   └── yashveer-mehra.ftd
│   ├── users/
│   │   └── index.ftd
│   ├── utils.ftd
│   ├── vercel.json
│   ├── web-component.js
│   ├── why/
│   │   ├── content.ftd
│   │   ├── design.ftd
│   │   ├── easy.ftd
│   │   ├── fullstack.ftd
│   │   ├── geeks.ftd
│   │   └── stable.ftd
│   └── workshop/
│       ├── 01-hello-world.ftd
│       ├── 02-add-quote.ftd
│       ├── 03-add-doc-site.ftd
│       ├── 04-publish-on-github.ftd
│       ├── 05-basics-of-text.ftd
│       ├── 06-add-image-and-video.ftd
│       ├── 07-create-new-page.ftd
│       ├── 08-creating-ds.ftd
│       ├── 09-add-sitemap.ftd
│       ├── 10-change-theme.ftd
│       ├── 11-change-cs-typo.ftd
│       ├── 12-document.ftd
│       ├── 13-use-redirect.ftd
│       ├── 14-seo-meta.ftd
│       ├── 15-add-banner.ftd
│       ├── 16-add-sidebar.ftd
│       ├── 17-portfolio.ftd
│       ├── devs/
│       │   └── index.ftd
│       ├── index.ftd
│       └── learn.ftd
├── fbt/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
├── fbt_lib/
│   ├── Cargo.toml
│   └── src/
│       ├── copy_dir.rs
│       ├── dir_diff.rs
│       ├── lib.rs
│       ├── run.rs
│       └── types.rs
├── flake.nix
├── ftd/
│   ├── Cargo.toml
│   ├── README.md
│   ├── build.html
│   ├── build.js
│   ├── examples/
│   │   ├── 01-input.ftd
│   │   ├── absolute_positioning.ftd
│   │   ├── action-increment-decrement-local-variable.ftd
│   │   ├── action-increment-decrement-on-component.ftd
│   │   ├── action-increment-decrement.ftd
│   │   ├── always-include.ftd
│   │   ├── anchor-position.ftd
│   │   ├── animated.ftd
│   │   ├── api-onclick.ftd
│   │   ├── architecture-diagram.ftd
│   │   ├── auto-nesting.ftd
│   │   ├── background-image.ftd
│   │   ├── basic-loop-on-record.ftd
│   │   ├── buggy-open.ftd
│   │   ├── color.ftd
│   │   ├── comic.ftd
│   │   ├── comic_scene_crop_scale.ftd
│   │   ├── comic_with_scene_without_comicgen.ftd
│   │   ├── comment_check.ftd
│   │   ├── condition-on-optional.ftd
│   │   ├── conditional-attribute-tab.ftd
│   │   ├── conditional-attributes.ftd
│   │   ├── conditional-variable.ftd
│   │   ├── container-switch.ftd
│   │   ├── container-test.ftd
│   │   ├── deep-nested-open-container.ftd
│   │   ├── deep-open-container.ftd
│   │   ├── dom-construct.ftd
│   │   ├── escape-body.ftd
│   │   ├── event-on-click-outside.ftd
│   │   ├── event-on-focus-blur.ftd
│   │   ├── event-on-focus.ftd
│   │   ├── event-onclick-toggle.ftd
│   │   ├── event-set.ftd
│   │   ├── event-stop-propagation.ftd
│   │   ├── event-toggle-creating-a-tree.ftd
│   │   ├── event-toggle-for-loop.ftd
│   │   ├── event-toggle-local-variable-for-component.ftd
│   │   ├── event-toggle-local-variable.ftd
│   │   ├── event-toggle-on-inner-container.ftd
│   │   ├── example.ftd
│   │   ├── external-variable.ftd
│   │   ├── font.ftd
│   │   ├── ft.ftd
│   │   ├── ftd-input-default-value.ftd
│   │   ├── global-key-event.ftd
│   │   ├── grid-sample.ftd
│   │   ├── grid.ftd
│   │   ├── hello-world.ftd
│   │   ├── http-api.ftd
│   │   ├── image-title.ftd
│   │   ├── image.ftd
│   │   ├── internal-links.ftd
│   │   ├── intra-page-link-2.ftd
│   │   ├── intra-page-link-heading.ftd
│   │   ├── intra-page-link.ftd
│   │   ├── lib.ftd
│   │   ├── line-clamp.ftd
│   │   ├── markdown-color.ftd
│   │   ├── markup-line.ftd
│   │   ├── markup.ftd
│   │   ├── message.ftd
│   │   ├── mouse-in-text.ftd
│   │   ├── mygate.ftd
│   │   ├── nested-component.ftd
│   │   ├── nested-open-container.ftd
│   │   ├── new-syntax.ftd
│   │   ├── open-container-with-id.ftd
│   │   ├── open-container-with-if.ftd
│   │   ├── open-with-append-at.ftd
│   │   ├── optional-condition.ftd
│   │   ├── optional-ftd-ui.ftd
│   │   ├── optional-pass-to-optional.ftd
│   │   ├── pass-by-reference.ftd
│   │   ├── pass-optional.ftd
│   │   ├── presentation.ftd
│   │   ├── record-reinitialisation.ftd
│   │   ├── record.ftd
│   │   ├── reference-linking.ftd
│   │   ├── region.ftd
│   │   ├── rendering-ft-page.ftd
│   │   ├── slides.ftd
│   │   ├── spacing-and-image-link.ftd
│   │   ├── spacing.ftd
│   │   ├── submit.ftd
│   │   ├── t1.ftd
│   │   ├── test-video.ftd
│   │   ├── test.dev.ftd
│   │   ├── test.ftd
│   │   ├── test1.ftd
│   │   ├── test2.ftd
│   │   ├── text-indent.ftd
│   │   ├── universal-attributes.ftd
│   │   └── variable-component.ftd
│   ├── ftd-js.css
│   ├── ftd-js.html
│   ├── ftd.css
│   ├── ftd.html
│   ├── ftd.js
│   ├── github-stuff/
│   │   ├── dependabot.yml
│   │   └── workflows/
│   │       └── rust.yml
│   ├── prism/
│   │   ├── prism-bash.js
│   │   ├── prism-diff.js
│   │   ├── prism-javascript.js
│   │   ├── prism-json.js
│   │   ├── prism-line-highlight.css
│   │   ├── prism-line-highlight.js
│   │   ├── prism-line-numbers.css
│   │   ├── prism-line-numbers.js
│   │   ├── prism-markdown.js
│   │   ├── prism-python.js
│   │   ├── prism-rust.js
│   │   ├── prism-sql.js
│   │   └── prism.js
│   ├── rt.html
│   ├── scripts/
│   │   └── create-huge-ftd.py
│   ├── src/
│   │   ├── document_store.rs
│   │   ├── executor/
│   │   │   ├── code.rs
│   │   │   ├── dummy.rs
│   │   │   ├── element.rs
│   │   │   ├── fastn_type_functions.rs
│   │   │   ├── main.rs
│   │   │   ├── markup.rs
│   │   │   ├── mod.rs
│   │   │   ├── rive.rs
│   │   │   ├── styles.rs
│   │   │   ├── tdoc.rs
│   │   │   ├── test.rs
│   │   │   ├── utils.rs
│   │   │   ├── value.rs
│   │   │   └── youtube_id.rs
│   │   ├── ftd2021/
│   │   │   ├── code.rs
│   │   │   ├── component.rs
│   │   │   ├── condition.rs
│   │   │   ├── constants.rs
│   │   │   ├── di/
│   │   │   │   ├── definition.rs
│   │   │   │   ├── import.rs
│   │   │   │   ├── invocation.rs
│   │   │   │   ├── main.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── property.rs
│   │   │   │   ├── record.rs
│   │   │   │   ├── t/
│   │   │   │   │   ├── 1-import.ftd
│   │   │   │   │   ├── 1-import.json
│   │   │   │   │   ├── 2-import.ftd
│   │   │   │   │   ├── 2-import.json
│   │   │   │   │   ├── 3-record.ftd
│   │   │   │   │   ├── 3-record.json
│   │   │   │   │   ├── 4-record.ftd
│   │   │   │   │   ├── 4-record.json
│   │   │   │   │   ├── 5-variable.ftd
│   │   │   │   │   ├── 5-variable.json
│   │   │   │   │   ├── 6-variable.ftd
│   │   │   │   │   ├── 6-variable.json
│   │   │   │   │   ├── 7-variable.ftd
│   │   │   │   │   ├── 7-variable.json
│   │   │   │   │   ├── 8-component.ftd
│   │   │   │   │   ├── 8-component.json
│   │   │   │   │   ├── 9-component.ftd
│   │   │   │   │   └── 9-component.json
│   │   │   │   ├── test.rs
│   │   │   │   └── utils.rs
│   │   │   ├── dnode.rs
│   │   │   ├── event.rs
│   │   │   ├── execute_doc.rs
│   │   │   ├── html.rs
│   │   │   ├── interpreter/
│   │   │   │   ├── main.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── tdoc.rs
│   │   │   │   ├── test.rs
│   │   │   │   ├── things/
│   │   │   │   │   ├── expression.rs
│   │   │   │   │   ├── kind.rs
│   │   │   │   │   ├── mod.rs
│   │   │   │   │   ├── property_value.rs
│   │   │   │   │   └── variable.rs
│   │   │   │   └── utils.rs
│   │   │   ├── markup.rs
│   │   │   ├── mod.rs
│   │   │   ├── or_type.rs
│   │   │   ├── p1/
│   │   │   │   ├── header.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── parser.rs
│   │   │   │   ├── section.rs
│   │   │   │   ├── sub_section.rs
│   │   │   │   └── to_string.rs
│   │   │   ├── p2/
│   │   │   │   ├── document.rs
│   │   │   │   ├── element.rs
│   │   │   │   ├── event.rs
│   │   │   │   ├── expression.rs
│   │   │   │   ├── interpreter.rs
│   │   │   │   ├── kind.rs
│   │   │   │   ├── library.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── record.rs
│   │   │   │   ├── tdoc.rs
│   │   │   │   └── utils.rs
│   │   │   ├── rendered.rs
│   │   │   ├── rt.rs
│   │   │   ├── test.rs
│   │   │   ├── ui.rs
│   │   │   ├── value_with_default.rs
│   │   │   ├── variable.rs
│   │   │   └── youtube_id.rs
│   │   ├── html/
│   │   │   ├── data.rs
│   │   │   ├── dependencies.rs
│   │   │   ├── dummy_html.rs
│   │   │   ├── events.rs
│   │   │   ├── fastn_type_functions.rs
│   │   │   ├── functions.rs
│   │   │   ├── main.rs
│   │   │   ├── mod.rs
│   │   │   ├── test.rs
│   │   │   ├── utils.rs
│   │   │   └── variable_dependencies.rs
│   │   ├── interpreter/
│   │   │   ├── main.rs
│   │   │   ├── mod.rs
│   │   │   ├── prelude.rs
│   │   │   ├── tdoc.rs
│   │   │   ├── test.rs
│   │   │   ├── things/
│   │   │   │   ├── component.rs
│   │   │   │   ├── expression.rs
│   │   │   │   ├── function.rs
│   │   │   │   ├── kind.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── or_type.rs
│   │   │   │   ├── record.rs
│   │   │   │   ├── value.rs
│   │   │   │   ├── variable.rs
│   │   │   │   └── web_component.rs
│   │   │   └── utils.rs
│   │   ├── js/
│   │   │   ├── ftd_test_helpers.rs
│   │   │   └── mod.rs
│   │   ├── lib.rs
│   │   ├── main.rs
│   │   ├── node/
│   │   │   ├── main.rs
│   │   │   ├── mod.rs
│   │   │   ├── node_data.rs
│   │   │   ├── raw_node.rs
│   │   │   ├── test.rs
│   │   │   ├── utils.rs
│   │   │   └── value.rs
│   │   ├── parser.rs
│   │   ├── stack_overflow_test.rs
│   │   ├── taffy.rs
│   │   ├── terminal.rs
│   │   ├── test_helper.rs
│   │   └── wasm/
│   │       ├── document.rs
│   │       ├── mod.rs
│   │       ├── value.rs
│   │       └── variable.rs
│   ├── syntax/
│   │   ├── elm.sublime-syntax
│   │   ├── ftd.sublime-syntax
│   │   └── toml.sublime-syntax
│   ├── t/
│   │   ├── assets/
│   │   │   ├── bell-icon.riv
│   │   │   ├── fastn-anime.riv
│   │   │   ├── fastn.riv
│   │   │   ├── panda.riv
│   │   │   ├── plane_mouse_tracking.riv
│   │   │   ├── test.css
│   │   │   ├── test.js
│   │   │   ├── todo.js
│   │   │   ├── toggleufbot.riv
│   │   │   └── web_component.js
│   │   ├── executor/
│   │   │   ├── 1-component.ftd
│   │   │   ├── 1-component.json
│   │   │   ├── 10-or-type.ftd
│   │   │   ├── 10-or-type.json
│   │   │   ├── 11-web-component.ftd
│   │   │   ├── 11-web-component.json
│   │   │   ├── 2-component.ftd
│   │   │   ├── 2-component.json
│   │   │   ├── 3-component.ftd
│   │   │   ├── 3-component.json
│   │   │   ├── 4-component.ftd
│   │   │   ├── 4-component.json
│   │   │   ├── 5-component-recursion.ftd
│   │   │   ├── 5-component-recursion.json
│   │   │   ├── 6-function.ftd
│   │   │   ├── 6-function.json
│   │   │   ├── 7-event.ftd
│   │   │   ├── 7-event.json
│   │   │   ├── 8-external-children.ftd
│   │   │   ├── 8-external-children.json
│   │   │   ├── 9-conditional-component.ftd
│   │   │   └── 9-conditional-component.json
│   │   ├── html/
│   │   │   ├── 1-component.ftd
│   │   │   ├── 1-component.html
│   │   │   ├── 10-conditional-properties.ftd
│   │   │   ├── 10-conditional-properties.html
│   │   │   ├── 100-linear-gradient.ftd
│   │   │   ├── 100-linear-gradient.html
│   │   │   ├── 100-re-export.ftd
│   │   │   ├── 100-re-export.html
│   │   │   ├── 101-re-re-export.ftd
│   │   │   ├── 101-re-re-export.html
│   │   │   ├── 102-access-modifiers.ftd
│   │   │   ├── 102-access-modifiers.html
│   │   │   ├── 103-block-header-record.ftd
│   │   │   ├── 103-block-header-record.html
│   │   │   ├── 104-block-header-record-extended.ftd
│   │   │   ├── 104-block-header-record-extended.html
│   │   │   ├── 105-document-breakpoint.ftd
│   │   │   ├── 105-document-breakpoint.html
│   │   │   ├── 106-comments.ftd
│   │   │   ├── 106-comments.html
│   │   │   ├── 107-old-fastn-code-syntax.ftd
│   │   │   ├── 107-old-fastn-code-syntax.html
│   │   │   ├── 108-linear-gradient-conditional.ftd
│   │   │   ├── 108-linear-gradient-conditional.html
│   │   │   ├── 109-image-fit.ftd
│   │   │   ├── 109-image-fit.html
│   │   │   ├── 11-external-children.ftd
│   │   │   ├── 11-external-children.html
│   │   │   ├── 110-fallback-fonts.ftd
│   │   │   ├── 110-fallback-fonts.html
│   │   │   ├── 12-conditional-component.ftd
│   │   │   ├── 12-conditional-component.html
│   │   │   ├── 13-image.ftd
│   │   │   ├── 13-image.html
│   │   │   ├── 14-processor.ftd
│   │   │   ├── 14-processor.html
│   │   │   ├── 15-foreign-variable.ftd
│   │   │   ├── 15-foreign-variable.html
│   │   │   ├── 16-or-type.ftd
│   │   │   ├── 16-or-type.html
│   │   │   ├── 17-record.ftd
│   │   │   ├── 17-record.html
│   │   │   ├── 18-styles.ftd
│   │   │   ├── 18-styles.html
│   │   │   ├── 19-complex-styles.ftd
│   │   │   ├── 19-complex-styles.html
│   │   │   ├── 2-component.ftd
│   │   │   ├── 2-component.html
│   │   │   ├── 20-link.ftd
│   │   │   ├── 20-link.html
│   │   │   ├── 21-color.ftd
│   │   │   ├── 21-color.html
│   │   │   ├── 22-test.ftd
│   │   │   ├── 22-test.html
│   │   │   ├── 23-alignment.ftd
│   │   │   ├── 23-alignment.html
│   │   │   ├── 23-doc-site.ftd
│   │   │   ├── 23-doc-site.html
│   │   │   ├── 24-margin.ftd
│   │   │   ├── 24-margin.html
│   │   │   ├── 25-expander.ftd
│   │   │   ├── 25-expander.html
│   │   │   ├── 25-overflow.ftd
│   │   │   ├── 25-overflow.html
│   │   │   ├── 26-border.ftd
│   │   │   ├── 26-border.html
│   │   │   ├── 27-optional.ftd
│   │   │   ├── 27-optional.html
│   │   │   ├── 28-complex.ftd
│   │   │   ├── 28-complex.html
│   │   │   ├── 29-slides.ftd
│   │   │   ├── 29-slides.html
│   │   │   ├── 3-component.ftd
│   │   │   ├── 3-component.html
│   │   │   ├── 30-slides.ftd
│   │   │   ├── 30-slides.html
│   │   │   ├── 31-message.ftd
│   │   │   ├── 31-message.html
│   │   │   ├── 32-test.ftd
│   │   │   ├── 32-test.html
│   │   │   ├── 33-component-using-css.ftd
│   │   │   ├── 33-component-using-css.html
│   │   │   ├── 33-using-css.ftd
│   │   │   ├── 33-using-css.html
│   │   │   ├── 34-device.ftd
│   │   │   ├── 34-device.html
│   │   │   ├── 35-condition-on-color.ftd
│   │   │   ├── 35-condition-on-color.html
│   │   │   ├── 36-test.ftd
│   │   │   ├── 36-test.html
│   │   │   ├── 37-cursor.ftd
│   │   │   ├── 37-cursor.html
│   │   │   ├── 38-role.ftd
│   │   │   ├── 38-role.html
│   │   │   ├── 39-events.ftd
│   │   │   ├── 39-events.html
│   │   │   ├── 4-component.ftd
│   │   │   ├── 4-component.html
│   │   │   ├── 40-anchor.ftd
│   │   │   ├── 40-anchor.html
│   │   │   ├── 41-responsive-type.ftd
│   │   │   ├── 41-responsive-type.html
│   │   │   ├── 42-default-function.ftd
│   │   │   ├── 42-default-function.html
│   │   │   ├── 43-default-colors-types.ftd
│   │   │   ├── 43-default-colors-types.html
│   │   │   ├── 44-region.ftd
│   │   │   ├── 44-region.html
│   │   │   ├── 45-using-hyphen.ftd
│   │   │   ├── 45-using-hyphen.html
│   │   │   ├── 46-record-in-pscript.ftd
│   │   │   ├── 46-record-in-pscript.html
│   │   │   ├── 47-white-space.ftd
│   │   │   ├── 47-white-space.html
│   │   │   ├── 48-basic-functions.ftd
│   │   │   ├── 48-basic-functions.html
│   │   │   ├── 49-import.ftd
│   │   │   ├── 49-import.html
│   │   │   ├── 5-component-recursion.ftd
│   │   │   ├── 5-component-recursion.html
│   │   │   ├── 50-using-import.ftd
│   │   │   ├── 50-using-import.html
│   │   │   ├── 51-text-transform.ftd
│   │   │   ├── 51-text-transform.html
│   │   │   ├── 52-code-and-iframe.ftd
│   │   │   ├── 52-code-and-iframe.html
│   │   │   ├── 53-decimal.ftd
│   │   │   ├── 53-decimal.html
│   │   │   ├── 53-font-family.ftd
│   │   │   ├── 53-font-family.html
│   │   │   ├── 54-input.ftd
│   │   │   ├── 54-input.html
│   │   │   ├── 55-inherited.ftd
│   │   │   ├── 55-inherited.html
│   │   │   ├── 55-line-clamp.ftd
│   │   │   ├── 55-line-clamp.html
│   │   │   ├── 56-passing-events.ftd
│   │   │   ├── 56-passing-events.html
│   │   │   ├── 57-border-style.ftd
│   │   │   ├── 57-border-style.html
│   │   │   ├── 58-id.ftd
│   │   │   ├── 58-id.html
│   │   │   ├── 59-sticky.ftd
│   │   │   ├── 59-sticky.html
│   │   │   ├── 6-function.ftd
│   │   │   ├── 6-function.html
│   │   │   ├── 60-region-id-slug.ftd
│   │   │   ├── 60-region-id-slug.html
│   │   │   ├── 61-loop-variable.ftd
│   │   │   ├── 61-loop-variable.html
│   │   │   ├── 62-spacing.ftd
│   │   │   ├── 62-spacing.html
│   │   │   ├── 63-checkbox.ftd
│   │   │   ├── 63-checkbox.html
│   │   │   ├── 64-muliple-node-dep.ftd
│   │   │   ├── 64-muliple-node-dep.html
│   │   │   ├── 64-multiple-node-dep-1.ftd
│   │   │   ├── 64-multiple-node-dep-1.html
│   │   │   ├── 65-mut-loop.ftd
│   │   │   ├── 65-mut-loop.html
│   │   │   ├── 66-inheritance.ftd
│   │   │   ├── 66-inheritance.html
│   │   │   ├── 67-enabled.ftd
│   │   │   ├── 67-enabled.html
│   │   │   ├── 68-anchor-id.ftd
│   │   │   ├── 68-anchor-id.html
│   │   │   ├── 69-inside-loop.ftd
│   │   │   ├── 69-inside-loop.html
│   │   │   ├── 7-events.ftd
│   │   │   ├── 7-events.html
│   │   │   ├── 70-figma-json-to-ftd.ftd
│   │   │   ├── 70-figma-json-to-ftd.html
│   │   │   ├── 70-length-check.ftd
│   │   │   ├── 70-length-check.html
│   │   │   ├── 71-web-component.ftd
│   │   │   ├── 71-web-component.html
│   │   │   ├── 72-external-js.ftd
│   │   │   ├── 72-external-js.html
│   │   │   ├── 73-complex-ftd-ui.ftd
│   │   │   ├── 73-complex-ftd-ui.html
│   │   │   ├── 74-import-complex-ftd-ui.ftd
│   │   │   ├── 74-import-complex-ftd-ui.html
│   │   │   ├── 75-ui-list-display.ftd
│   │   │   ├── 75-ui-list-display.html
│   │   │   ├── 76-inter-argument.ftd
│   │   │   ├── 76-inter-argument.html
│   │   │   ├── 77-property-source-fix.ftd
│   │   │   ├── 77-property-source-fix.html
│   │   │   ├── 79-shorthand-lists.ftd
│   │   │   ├── 79-shorthand-lists.html
│   │   │   ├── 8-counter.ftd
│   │   │   ├── 8-counter.html
│   │   │   ├── 80-module.ftd
│   │   │   ├── 80-module.html
│   │   │   ├── 81-markdown.ftd
│   │   │   ├── 81-markdown.html
│   │   │   ├── 82-text-style.ftd
│   │   │   ├── 82-text-style.html
│   │   │   ├── 83-text-indent.ftd
│   │   │   ├── 83-text-indent.html
│   │   │   ├── 84-ftd-ui-list-issue.ftd
│   │   │   ├── 84-ftd-ui-list-issue.html
│   │   │   ├── 85-bg-image.ftd
│   │   │   ├── 85-bg-image.html
│   │   │   ├── 86-ftd-document.ftd
│   │   │   ├── 86-ftd-document.html
│   │   │   ├── 86-shadow.ftd
│   │   │   ├── 86-shadow.html
│   │   │   ├── 87-bg-repeat-original.html
│   │   │   ├── 87-bg-repeat.ftd
│   │   │   ├── 87-bg-repeat.html
│   │   │   ├── 87-mutability.ftd
│   │   │   ├── 87-mutability.html
│   │   │   ├── 88-ftd-length.ftd
│   │   │   ├── 88-ftd-length.html
│   │   │   ├── 89-display.ftd
│   │   │   ├── 89-display.html
│   │   │   ├── 9-conditional-properties.ftd
│   │   │   ├── 9-conditional-properties.html
│   │   │   ├── 90-img-alt.ftd
│   │   │   ├── 90-img-alt.html
│   │   │   ├── 91-opacity.ftd
│   │   │   ├── 91-opacity.html
│   │   │   ├── 92-rive.ftd
│   │   │   ├── 92-rive.html
│   │   │   ├── 93-rive-bell.ftd
│   │   │   ├── 93-rive-bell.html
│   │   │   ├── 94-rive-toggle.ftd
│   │   │   ├── 94-rive-toggle.html
│   │   │   ├── 95-rive-bell-animation.ftd
│   │   │   ├── 95-rive-bell-animation.html
│   │   │   ├── 96-rive-truck-animation.ftd
│   │   │   ├── 96-rive-truck-animation.html
│   │   │   ├── 97-rive-fastn.ftd
│   │   │   ├── 97-rive-fastn.html
│   │   │   ├── 98-device.ftd
│   │   │   ├── 98-device.html
│   │   │   ├── 99-unoptimized-device.ftd
│   │   │   ├── 99-unoptimized-device.html
│   │   │   ├── check.ftd
│   │   │   ├── check.html
│   │   │   ├── function.ftd
│   │   │   ├── function.html
│   │   │   ├── get.ftd
│   │   │   ├── get.html
│   │   │   ├── h-100.ftd
│   │   │   ├── h-100.html
│   │   │   ├── resume.ftd
│   │   │   ├── resume.html
│   │   │   ├── sd.ftd
│   │   │   └── sd.html
│   │   ├── interpreter/
│   │   │   ├── 1-record.ftd
│   │   │   ├── 1-record.json
│   │   │   ├── 10-component-definition.ftd
│   │   │   ├── 10-component-definition.json
│   │   │   ├── 11-component-definition.ftd
│   │   │   ├── 11-component-definition.json
│   │   │   ├── 12-component-definition.ftd
│   │   │   ├── 12-component-definition.json
│   │   │   ├── 13-component-definition.ftd
│   │   │   ├── 13-component-definition.json
│   │   │   ├── 14-component-definition.ftd
│   │   │   ├── 14-component-definition.json
│   │   │   ├── 15-component-iteration.ftd
│   │   │   ├── 15-component-iteration.json
│   │   │   ├── 16-component-recursion.ftd
│   │   │   ├── 16-component-recursion.json
│   │   │   ├── 17-function.ftd
│   │   │   ├── 17-function.json
│   │   │   ├── 18-event.ftd
│   │   │   ├── 18-event.json
│   │   │   ├── 19-external-children.ftd
│   │   │   ├── 19-external-children.json
│   │   │   ├── 2-record.ftd
│   │   │   ├── 2-record.json
│   │   │   ├── 20-or-type.ftd
│   │   │   ├── 20-or-type.json
│   │   │   ├── 21-record-event.ftd
│   │   │   ├── 21-record-event.json
│   │   │   ├── 22-inherited.ftd
│   │   │   ├── 22-inherited.json
│   │   │   ├── 23-web-component.ftd
│   │   │   ├── 23-web-component.json
│   │   │   ├── 24-device.ftd
│   │   │   ├── 24-device.json
│   │   │   ├── 25-kwargs.ftd
│   │   │   ├── 25-kwargs.json
│   │   │   ├── 26-infinite-loop.error
│   │   │   ├── 26-infinite-loop.ftd
│   │   │   ├── 27-infinite-loop.error
│   │   │   ├── 27-infinite-loop.ftd
│   │   │   ├── 28-infinite-loop.error
│   │   │   ├── 28-infinite-loop.ftd
│   │   │   ├── 29-infinite-loop.error
│   │   │   ├── 29-infinite-loop.ftd
│   │   │   ├── 3-record.ftd
│   │   │   ├── 3-record.json
│   │   │   ├── 30-infinite-loop.error
│   │   │   ├── 30-infinite-loop.ftd
│   │   │   ├── 31-infinite-loop.error
│   │   │   ├── 31-infinite-loop.ftd
│   │   │   ├── 32-recursion.ftd
│   │   │   ├── 32-recursion.json
│   │   │   ├── 4-variable.ftd
│   │   │   ├── 4-variable.json
│   │   │   ├── 5-variable.ftd
│   │   │   ├── 5-variable.json
│   │   │   ├── 6-variable-invocation.ftd
│   │   │   ├── 6-variable-invocation.json
│   │   │   ├── 7-variable-invocation.ftd
│   │   │   ├── 7-variable-invocation.json
│   │   │   ├── 8-variable-invocation.ftd
│   │   │   ├── 8-variable-invocation.json
│   │   │   ├── 9-component-definition.ftd
│   │   │   └── 9-component-definition.json
│   │   ├── js/
│   │   │   ├── 01-basic-module.ftd
│   │   │   ├── 01-basic-module.html
│   │   │   ├── 01-basic.ftd
│   │   │   ├── 01-basic.html
│   │   │   ├── 02-property.ftd
│   │   │   ├── 02-property.html
│   │   │   ├── 03-common-properties.ftd
│   │   │   ├── 03-common-properties.html
│   │   │   ├── 04-variable.ftd
│   │   │   ├── 04-variable.html
│   │   │   ├── 05-dynamic-dom-list.ftd
│   │   │   ├── 05-dynamic-dom-list.html
│   │   │   ├── 06-dynamic-dom-list-2.ftd
│   │   │   ├── 06-dynamic-dom-list-2.html
│   │   │   ├── 07-dynamic-dom-record-list.ftd
│   │   │   ├── 07-dynamic-dom-record-list.html
│   │   │   ├── 08-inherited.ftd
│   │   │   ├── 08-inherited.html
│   │   │   ├── 09-text-properties.ftd
│   │   │   ├── 09-text-properties.html
│   │   │   ├── 10-color-test.ftd
│   │   │   ├── 10-color-test.html
│   │   │   ├── 100-template.ftd
│   │   │   ├── 100-template.html
│   │   │   ├── 101-response.ftd
│   │   │   ├── 101-response.html
│   │   │   ├── 102-response.ftd
│   │   │   ├── 102-response.html
│   │   │   ├── 103-ftd-json-templ.ftd
│   │   │   ├── 103-ftd-json-templ.html
│   │   │   ├── 103-iframe.ftd
│   │   │   ├── 103-iframe.html
│   │   │   ├── 104-a-export-star.ftd
│   │   │   ├── 104-a-export-star.html
│   │   │   ├── 104-b-export-star.ftd
│   │   │   ├── 104-b-export-star.html
│   │   │   ├── 104-j-export-star.ftd
│   │   │   ├── 104-j-export-star.html
│   │   │   ├── 104-k-export-star.ftd
│   │   │   ├── 104-k-export-star.html
│   │   │   ├── 11-device.ftd
│   │   │   ├── 11-device.html
│   │   │   ├── 12-children.ftd
│   │   │   ├── 12-children.html
│   │   │   ├── 13-non-style-properties.ftd
│   │   │   ├── 13-non-style-properties.html
│   │   │   ├── 14-code.ftd
│   │   │   ├── 14-code.html
│   │   │   ├── 15-function-call-in-property.ftd
│   │   │   ├── 15-function-call-in-property.html
│   │   │   ├── 16-container.ftd
│   │   │   ├── 16-container.html
│   │   │   ├── 17-clone.ftd
│   │   │   ├── 17-clone.html
│   │   │   ├── 17-events.ftd
│   │   │   ├── 17-events.html
│   │   │   ├── 18-rive.ftd
│   │   │   ├── 18-rive.html
│   │   │   ├── 19-image.ftd
│   │   │   ├── 19-image.html
│   │   │   ├── 20-background-properties.ftd
│   │   │   ├── 20-background-properties.html
│   │   │   ├── 21-markdown.ftd
│   │   │   ├── 21-markdown.html
│   │   │   ├── 22-document.ftd
│   │   │   ├── 22-document.html
│   │   │   ├── 23-record-list.ftd
│   │   │   ├── 23-record-list.html
│   │   │   ├── 24-device.ftd
│   │   │   ├── 24-device.html
│   │   │   ├── 24-re-export-star-with-custom-def.ftd
│   │   │   ├── 24-re-export-star-with-custom-def.html
│   │   │   ├── 24-re-export-star.ftd
│   │   │   ├── 24-re-export-star.html
│   │   │   ├── 24-re-export.ftd
│   │   │   ├── 24-re-export.html
│   │   │   ├── 25-re-re-export-star-with-custom-def.ftd
│   │   │   ├── 25-re-re-export-star-with-custom-def.html
│   │   │   ├── 25-re-re-export-star.ftd
│   │   │   ├── 25-re-re-export-star.html
│   │   │   ├── 25-re-re-export.ftd
│   │   │   ├── 25-re-re-export.html
│   │   │   ├── 26-re-export.ftd
│   │   │   ├── 26-re-export.html
│   │   │   ├── 27-for-loop.ftd
│   │   │   ├── 27-for-loop.html
│   │   │   ├── 28-mutable-component-arguments.ftd
│   │   │   ├── 28-mutable-component-arguments.html
│   │   │   ├── 28-web-component.ftd
│   │   │   ├── 28-web-component.html
│   │   │   ├── 29-dom-list.ftd
│   │   │   ├── 29-dom-list.html
│   │   │   ├── 30-web-component.ftd
│   │   │   ├── 30-web-component.html
│   │   │   ├── 31-advance-list.ftd
│   │   │   ├── 31-advance-list.html
│   │   │   ├── 31-ftd-len.ftd
│   │   │   ├── 31-ftd-len.html
│   │   │   ├── 32-ftd-len.ftd
│   │   │   ├── 32-ftd-len.html
│   │   │   ├── 33-list-indexing.ftd
│   │   │   ├── 33-list-indexing.html
│   │   │   ├── 34-ftd-ui.ftd
│   │   │   ├── 34-ftd-ui.html
│   │   │   ├── 36-single-ui.ftd
│   │   │   ├── 36-single-ui.html
│   │   │   ├── 37-expander.ftd
│   │   │   ├── 37-expander.html
│   │   │   ├── 38-background-image-properties.ftd
│   │   │   ├── 38-background-image-properties.html
│   │   │   ├── 40-code-themes.ftd
│   │   │   ├── 40-code-themes.html
│   │   │   ├── 41-document-favicon.ftd
│   │   │   ├── 41-document-favicon.html
│   │   │   ├── 42-links.ftd
│   │   │   ├── 42-links.html
│   │   │   ├── 43-image-object-fit.ftd
│   │   │   ├── 43-image-object-fit.html
│   │   │   ├── 44-local-storage.ftd
│   │   │   ├── 44-local-storage.html
│   │   │   ├── 44-module.ftd
│   │   │   ├── 44-module.html
│   │   │   ├── 45-re-module.ftd
│   │   │   ├── 45-re-module.html
│   │   │   ├── 45-re-re-module.ftd
│   │   │   ├── 45-re-re-module.html
│   │   │   ├── 46-code-languages.ftd
│   │   │   ├── 46-code-languages.html
│   │   │   ├── 47-ftd-code-syntax.ftd
│   │   │   ├── 47-ftd-code-syntax.html
│   │   │   ├── 48-video.ftd
│   │   │   ├── 48-video.html
│   │   │   ├── 49-align-content.ftd
│   │   │   ├── 49-align-content.html
│   │   │   ├── 50-iframe-fullscreen.ftd
│   │   │   ├── 50-iframe-fullscreen.html
│   │   │   ├── 51-markdown-table.ftd
│   │   │   ├── 51-markdown-table.html
│   │   │   ├── 52-events.ftd
│   │   │   ├── 52-events.html
│   │   │   ├── 53-link-color.ftd
│   │   │   ├── 53-link-color.html
│   │   │   ├── 54-class-fix.ftd
│   │   │   ├── 54-class-fix.html
│   │   │   ├── 56-title-fix.ftd
│   │   │   ├── 56-title-fix.html
│   │   │   ├── 57-code-dark-mode.ftd
│   │   │   ├── 57-code-dark-mode.html
│   │   │   ├── 59-text-shadow.ftd
│   │   │   ├── 59-text-shadow.html
│   │   │   ├── 60-conditional-module-headers.ftd
│   │   │   ├── 60-conditional-module-headers.html
│   │   │   ├── 61-functions.ftd
│   │   │   ├── 61-functions.html
│   │   │   ├── 62-fallback-fonts.ftd
│   │   │   ├── 62-fallback-fonts.html
│   │   │   ├── 63-external-js.ftd
│   │   │   ├── 63-external-js.html
│   │   │   ├── 64-selectable.ftd
│   │   │   ├── 64-selectable.html
│   │   │   ├── 65-legacy.ftd
│   │   │   ├── 65-legacy.html
│   │   │   ├── 66-backdrop-filter.ftd
│   │   │   ├── 66-backdrop-filter.html
│   │   │   ├── 67-counter.ftd
│   │   │   ├── 67-counter.html
│   │   │   ├── 68-mask.ftd
│   │   │   ├── 68-mask.html
│   │   │   ├── 69-chained-dot-value-in-functions.ftd
│   │   │   ├── 69-chained-dot-value-in-functions.html
│   │   │   ├── 72-document-breakpoint.ftd
│   │   │   ├── 72-document-breakpoint.html
│   │   │   ├── 73-loops-inside-list.ftd
│   │   │   ├── 73-loops-inside-list.html
│   │   │   ├── 74-default-text-value.ftd
│   │   │   ├── 74-default-text-value.html
│   │   │   ├── 78-data-for-module.ftd
│   │   │   ├── 78-data-for-module.html
│   │   │   ├── 78-module-using-record.ftd
│   │   │   ├── 78-module-using-record.html
│   │   │   ├── 79-module-using-function.ftd
│   │   │   ├── 79-module-using-function.html
│   │   │   ├── 80-or-type-constant.ftd
│   │   │   ├── 80-or-type-constant.html
│   │   │   ├── 81-or-type-test.ftd
│   │   │   ├── 81-or-type-test.html
│   │   │   ├── 82-or-type-module.ftd
│   │   │   ├── 82-or-type-module.html
│   │   │   ├── 85-export-or-type.ftd
│   │   │   ├── 85-export-or-type.html
│   │   │   ├── 86-import-or-type.ftd
│   │   │   ├── 86-import-or-type.html
│   │   │   ├── 87-or-type-module-export.ftd
│   │   │   ├── 87-or-type-module-export.html
│   │   │   ├── 88-body-children.ftd
│   │   │   ├── 88-body-children.html
│   │   │   ├── 88-module-reference-wrap-in-variant.ftd
│   │   │   ├── 88-module-reference-wrap-in-variant.html
│   │   │   ├── 89-nested-or-type.ftd
│   │   │   ├── 89-nested-or-type.html
│   │   │   ├── 90-error.error
│   │   │   ├── 90-error.ftd
│   │   │   ├── 91-component-event.ftd
│   │   │   ├── 91-component-event.html
│   │   │   ├── 92-self-reference-record.ftd
│   │   │   ├── 92-self-reference-record.html
│   │   │   ├── 93-reference-data.ftd
│   │   │   ├── 93-reference-data.html
│   │   │   ├── 94-kw-args.ftd
│   │   │   ├── 94-kw-args.html
│   │   │   ├── 95-record-closure.ftd
│   │   │   ├── 95-record-closure.html
│   │   │   ├── 96-download-tag.ftd
│   │   │   ├── 96-download-tag.html
│   │   │   ├── 97-clone-mutability-check.ftd
│   │   │   ├── 97-clone-mutability-check.html
│   │   │   ├── 98-audio.ftd
│   │   │   ├── 98-audio.html
│   │   │   ├── 99-ftd-json.ftd
│   │   │   ├── 99-ftd-json.html
│   │   │   ├── loop.ftd
│   │   │   └── loop.html
│   │   ├── node/
│   │   │   ├── 1-component.ftd
│   │   │   ├── 1-component.json
│   │   │   ├── 2-component.ftd
│   │   │   ├── 2-component.json
│   │   │   ├── 3-component.ftd
│   │   │   ├── 3-component.json
│   │   │   ├── 4-component.ftd
│   │   │   ├── 4-component.json
│   │   │   ├── 5-component-recursion.ftd
│   │   │   ├── 5-component-recursion.json
│   │   │   ├── 6-function.ftd
│   │   │   ├── 6-function.json
│   │   │   ├── 7-web-component.ftd
│   │   │   └── 7-web-component.json
│   │   └── should-work/
│   │       └── 01-mutable-local-variable.ftd
│   ├── taffy.ftd
│   ├── terminal.ftd
│   ├── tests/
│   │   ├── creating-a-tree.ftd
│   │   ├── fifthtry/
│   │   │   └── ft.ftd
│   │   ├── hello-world-variable.ftd
│   │   ├── hello-world.ftd
│   │   ├── inner_container.ftd
│   │   └── reference.ftd
│   ├── theme/
│   │   ├── fastn-theme-1.dark.tmTheme
│   │   ├── fastn-theme-1.light.tmTheme
│   │   ├── fastn-theme.dark.tmTheme
│   │   └── fastn-theme.light.tmTheme
│   ├── theme_css/
│   │   ├── coldark-theme.dark.css
│   │   ├── coldark-theme.light.css
│   │   ├── coy-theme.css
│   │   ├── dracula-theme.css
│   │   ├── duotone-theme.dark.css
│   │   ├── duotone-theme.earth.css
│   │   ├── duotone-theme.forest.css
│   │   ├── duotone-theme.light.css
│   │   ├── duotone-theme.sea.css
│   │   ├── duotone-theme.space.css
│   │   ├── fastn-theme.dark.css
│   │   ├── fastn-theme.light.css
│   │   ├── fire.light.css
│   │   ├── gruvbox-theme.dark.css
│   │   ├── gruvbox-theme.light.css
│   │   ├── laserwave-theme.css
│   │   ├── material-theme.dark.css
│   │   ├── material-theme.light.css
│   │   ├── nightowl-theme.css
│   │   ├── one-theme.dark.css
│   │   ├── one-theme.light.css
│   │   ├── vs-theme.dark.css
│   │   ├── vs-theme.light.css
│   │   └── ztouch-theme.css
│   ├── ts/
│   │   ├── index.ts
│   │   ├── post_init.ts
│   │   ├── types/
│   │   │   ├── function.d.ts
│   │   │   └── index.d.ts
│   │   └── utils.ts
│   └── tsconfig.json
├── ftd-ast/
│   ├── Cargo.toml
│   ├── src/
│   │   ├── ast.rs
│   │   ├── component.rs
│   │   ├── constants.rs
│   │   ├── function.rs
│   │   ├── import.rs
│   │   ├── kind.rs
│   │   ├── lib.rs
│   │   ├── or_type.rs
│   │   ├── record.rs
│   │   ├── test.rs
│   │   ├── utils.rs
│   │   ├── variable.rs
│   │   └── web_component.rs
│   └── t/
│       └── ast/
│           ├── 1-import.ftd
│           ├── 1-import.json
│           ├── 10-variable-invocation.ftd
│           ├── 10-variable-invocation.json
│           ├── 11-component-definition.ftd
│           ├── 11-component-definition.json
│           ├── 12-component-definition.ftd
│           ├── 12-component-definition.json
│           ├── 13-component-invocation.ftd
│           ├── 13-component-invocation.json
│           ├── 14-function.ftd
│           ├── 14-function.json
│           ├── 15-or-type.ftd
│           ├── 15-or-type.json
│           ├── 16-ui-list.ftd
│           ├── 16-ui-list.json
│           ├── 17-web-component.ftd
│           ├── 17-web-component.json
│           ├── 18-re-export.ftd
│           ├── 18-re-export.json
│           ├── 19-shorthand-list.ftd
│           ├── 19-shorthand-list.json
│           ├── 2-import.ftd
│           ├── 2-import.json
│           ├── 20-list-processor.ftd
│           ├── 20-list-processor.json
│           ├── 3-record.ftd
│           ├── 3-record.json
│           ├── 4-record.ftd
│           ├── 4-record.json
│           ├── 5-variable-definition.ftd
│           ├── 5-variable-definition.json
│           ├── 6-variable-definition.ftd
│           ├── 6-variable-definition.json
│           ├── 7-variable-definition.ftd
│           ├── 7-variable-definition.json
│           ├── 8-variable-invocation.ftd
│           ├── 8-variable-invocation.json
│           ├── 9-variable-invocation.ftd
│           └── 9-variable-invocation.json
├── ftd-p1/
│   ├── Cargo.toml
│   ├── src/
│   │   ├── header.rs
│   │   ├── lib.rs
│   │   ├── parser.rs
│   │   ├── section.rs
│   │   ├── test.rs
│   │   └── utils.rs
│   └── t/
│       └── p1/
│           ├── 01.01.ftd
│           ├── 01.ftd
│           ├── 01.json
│           ├── 02.ftd
│           ├── 02.json
│           ├── 03.ftd
│           ├── 03.json
│           ├── 04.ftd
│           ├── 04.json
│           ├── 05-comments.ftd
│           ├── 05-comments.json
│           ├── 06-complex-header.ftd
│           ├── 06-complex-header.json
│           ├── 07-more-complex.ftd
│           └── 07-more-complex.json
├── install.nsi
├── integration-tests/
│   ├── FASTN.ftd
│   ├── _tests/
│   │   ├── 01-hello-world-using-sql-processor.test.ftd
│   │   ├── 02-hello-world-using-endpoint.test.ftd
│   │   ├── 03-hello-world-using-fixture.test.ftd
│   │   ├── 04-multi-endpoint-test.test.ftd
│   │   ├── 05-wasm-routes.test.ftd
│   │   ├── 11-fastn-redirect.test.ftd
│   │   ├── 14-http-headers.test.ftd
│   │   └── fixtures/
│   │       └── hello-world-using-endpoint.test.ftd
│   ├── dummy-json-auth.ftd
│   ├── hello-world-sql.ftd
│   ├── hello.ftd
│   ├── redirect-to-hello.ftd
│   └── wasm/
│       ├── Cargo.toml
│       ├── flake.nix
│       ├── rust-toolchain.toml
│       └── src/
│           └── lib.rs
├── iroh-signing-abstraction-proposal.md
├── neovim-ftd.lua
├── rust-toolchain.toml
├── t/
│   ├── .fastn/
│   │   └── config.json
│   ├── FASTN.ftd
│   └── index.ftd
├── v0.5/
│   ├── .claude/
│   │   └── notify.sh
│   ├── ARCHITECTURE.md
│   ├── CLAUDE.md
│   ├── Cargo.toml
│   ├── DESIGN.md
│   ├── FASTN.ftd
│   ├── FASTN_LANGUAGE_SPEC.md
│   ├── FASTN_SPEC_VIEWER_SIMPLIFIED.md
│   ├── KEYRING_NOTES.md
│   ├── MANUAL_TESTING_README.md
│   ├── MVP-IMPLEMENTATION-PLAN.md
│   ├── MVP.md
│   ├── NEXT_STEPS.md
│   ├── README.md
│   ├── THUNDERBIRD_SETUP.md
│   ├── agent-tutorial.md
│   ├── ascii-rendering-design.md
│   ├── clippy.toml
│   ├── fastn/
│   │   ├── .fastn/
│   │   │   └── packages/
│   │   │       └── foo.com/
│   │   │           └── ds/
│   │   │               └── FASTN.ftd
│   │   ├── Cargo.toml
│   │   ├── FASTN.ftd
│   │   ├── amitu-notes.md
│   │   ├── index.ftd
│   │   ├── index.html
│   │   └── src/
│   │       ├── commands/
│   │       │   ├── build.rs
│   │       │   ├── mod.rs
│   │       │   ├── render.rs
│   │       │   └── serve.rs
│   │       ├── definition_provider.rs
│   │       ├── lib.rs
│   │       ├── main.rs
│   │       └── section_provider.rs
│   ├── fastn-account/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   └── src/
│   │       ├── account/
│   │       │   ├── create.rs
│   │       │   └── load.rs
│   │       ├── account.rs
│   │       ├── account_manager.rs
│   │       ├── alias.rs
│   │       ├── auth.rs
│   │       ├── automerge.rs
│   │       ├── errors.rs
│   │       ├── http_routes.rs
│   │       ├── lib.rs
│   │       ├── p2p.rs
│   │       └── template_context.rs
│   ├── fastn-ansi-renderer/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── ansi_canvas.rs
│   │   │   ├── canvas.rs
│   │   │   ├── components/
│   │   │   │   ├── mod.rs
│   │   │   │   └── text.rs
│   │   │   ├── css_mapper.rs
│   │   │   ├── document_renderer.rs
│   │   │   ├── ftd_types.rs
│   │   │   ├── layout.rs
│   │   │   ├── lib.rs
│   │   │   ├── renderer.rs
│   │   │   └── taffy_integration.rs
│   │   └── tests/
│   │       ├── basic_rendering.rs
│   │       ├── end_to_end_pipeline.rs
│   │       └── taffy_integration.rs
│   ├── fastn-automerge/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── Cargo.toml
│   │   ├── ERROR_HANDLING_PLAN.md
│   │   ├── README.md
│   │   ├── TUTORIAL.md
│   │   ├── amitu-notes.md
│   │   ├── src/
│   │   │   ├── cli/
│   │   │   │   ├── args.rs
│   │   │   │   ├── commands.rs
│   │   │   │   ├── mod.rs
│   │   │   │   └── utils.rs
│   │   │   ├── db.rs
│   │   │   ├── error.rs.backup
│   │   │   ├── lib.rs
│   │   │   ├── main.rs
│   │   │   ├── migration.rs
│   │   │   ├── tests.rs
│   │   │   └── utils.rs
│   │   └── tests/
│   │       └── cli_tests.rs
│   ├── fastn-automerge-derive/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── lib.rs
│   ├── fastn-cli-test-utils/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   └── src/
│   │       ├── examples.rs
│   │       ├── fastn_mail.rs
│   │       ├── fastn_rig.rs
│   │       ├── lib.rs
│   │       ├── simple.rs
│   │       └── test_env.rs
│   ├── fastn-compiler/
│   │   ├── Cargo.toml
│   │   ├── src/
│   │   │   ├── compiler.rs
│   │   │   ├── f-script/
│   │   │   │   └── README.md
│   │   │   ├── incremental-parsing.txt
│   │   │   ├── lib.rs
│   │   │   └── utils.rs
│   │   └── t/
│   │       ├── 000-tutorial.ftd
│   │       ├── 001-empty.ftd
│   │       ├── 002-few-comments.ftd
│   │       ├── 003-module-doc.ftd
│   │       └── 004-simple-section.ftd
│   ├── fastn-continuation/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── provider.rs
│   │       ├── result.rs
│   │       └── ur.rs
│   ├── fastn-entity-amitu-notes.md
│   ├── fastn-fbr/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── errors.rs
│   │       ├── lib.rs
│   │       ├── router.rs
│   │       └── template_context.rs
│   ├── fastn-id52/
│   │   ├── CHANGELOG.md
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── amitu-notes.md
│   │   └── src/
│   │       ├── automerge.rs
│   │       ├── dns.rs
│   │       ├── errors.rs
│   │       ├── keyring.rs
│   │       ├── keys.rs
│   │       ├── lib.rs
│   │       └── main.rs
│   ├── fastn-mail/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── amitu-notes.md
│   │   └── src/
│   │       ├── automerge.rs
│   │       ├── cli.rs
│   │       ├── database.rs
│   │       ├── errors.rs
│   │       ├── imap/
│   │       │   ├── client.rs
│   │       │   ├── commands.rs
│   │       │   ├── fetch.rs
│   │       │   ├── list_folders.rs
│   │       │   ├── mod.rs
│   │       │   ├── search.rs
│   │       │   ├── select_folder.rs
│   │       │   ├── store_flags.rs
│   │       │   └── thread.rs
│   │       ├── lib.rs
│   │       ├── main.rs
│   │       ├── p2p_receive_email.rs
│   │       ├── store/
│   │       │   ├── create.rs
│   │       │   ├── create_bounce_message.rs
│   │       │   ├── get_emails_for_peer.rs
│   │       │   ├── get_pending_deliveries.rs
│   │       │   ├── mark_delivered_to_peer.rs
│   │       │   ├── mod.rs
│   │       │   └── smtp_receive/
│   │       │       ├── mod.rs
│   │       │       └── validate_email_for_smtp.rs
│   │       ├── types.rs
│   │       └── utils.rs
│   ├── fastn-net/
│   │   ├── CHANGELOG.md
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── dot_fastn/
│   │   │   │   ├── init_if_required.rs
│   │   │   │   ├── lock.rs
│   │   │   │   └── mod.rs
│   │   │   ├── errors.rs
│   │   │   ├── get_endpoint.rs
│   │   │   ├── get_stream.rs
│   │   │   ├── graceful.rs
│   │   │   ├── http.rs
│   │   │   ├── http_connection_manager.rs
│   │   │   ├── http_to_peer.rs
│   │   │   ├── lib.rs
│   │   │   ├── peer_to_http.rs
│   │   │   ├── ping.rs
│   │   │   ├── protocol.rs
│   │   │   ├── secret.rs
│   │   │   ├── tcp.rs
│   │   │   ├── utils.rs
│   │   │   └── utils_iroh.rs
│   │   └── tests/
│   │       └── test_protocol_generic.rs
│   ├── fastn-net-test/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── lib.rs
│   │   │   ├── receiver.rs
│   │   │   └── sender.rs
│   │   └── tests/
│   │       ├── debug_test_env.rs
│   │       └── end_to_end.rs
│   ├── fastn-p2p/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── client.rs
│   │   │   ├── coordination.rs
│   │   │   ├── globals.rs
│   │   │   ├── lib.rs
│   │   │   ├── macros.rs
│   │   │   └── server/
│   │   │       ├── handle.rs
│   │   │       ├── listener.rs
│   │   │       ├── management.rs
│   │   │       ├── mod.rs
│   │   │       └── request.rs
│   │   └── tests/
│   │       └── multi_protocol_server.rs
│   ├── fastn-p2p-macros/
│   │   ├── Cargo.toml
│   │   ├── examples/
│   │   │   ├── basic.rs
│   │   │   ├── configured.rs
│   │   │   ├── double_ctrl_c.rs
│   │   │   └── signal_test.rs
│   │   └── src/
│   │       └── lib.rs
│   ├── fastn-p2p-test/
│   │   ├── Cargo.toml
│   │   ├── src/
│   │   │   ├── lib.rs
│   │   │   ├── receiver.rs
│   │   │   └── sender.rs
│   │   └── tests/
│   │       ├── end_to_end.rs
│   │       ├── full_mesh.rs
│   │       ├── multi_message.rs
│   │       ├── multi_receiver.rs
│   │       ├── multi_sender.rs
│   │       └── stress_test.rs
│   ├── fastn-package/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── reader.rs
│   │       └── test.rs
│   ├── fastn-rig/
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── src/
│   │   │   ├── automerge.rs
│   │   │   ├── bin/
│   │   │   │   └── test_utils.rs
│   │   │   ├── certs/
│   │   │   │   ├── errors.rs
│   │   │   │   ├── filesystem.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── self_signed.rs
│   │   │   │   └── storage.rs
│   │   │   ├── email_delivery_p2p.rs
│   │   │   ├── email_poller_p2p.rs
│   │   │   ├── errors.rs
│   │   │   ├── http_proxy.rs
│   │   │   ├── http_routes.rs
│   │   │   ├── http_server.rs
│   │   │   ├── imap/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── protocol.rs
│   │   │   │   ├── server.rs
│   │   │   │   └── session.rs
│   │   │   ├── lib.rs
│   │   │   ├── main.rs
│   │   │   ├── p2p_server.rs
│   │   │   ├── protocols.rs
│   │   │   ├── rig.rs
│   │   │   ├── run.rs
│   │   │   ├── smtp/
│   │   │   │   ├── mod.rs
│   │   │   │   └── parser.rs
│   │   │   ├── template_context.rs
│   │   │   └── test_utils.rs
│   │   └── tests/
│   │       ├── cli_tests.rs
│   │       ├── email_end_to_end_plaintext.rs
│   │       ├── email_end_to_end_plaintext.sh
│   │       └── email_end_to_end_starttls.rs
│   ├── fastn-router/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── http_proxy.rs
│   │       ├── http_types.rs
│   │       ├── lib.rs
│   │       ├── reader.rs
│   │       └── route.rs
│   ├── fastn-section/
│   │   ├── Cargo.toml
│   │   ├── GRAMMAR.md
│   │   ├── PARSING_TUTORIAL.md
│   │   ├── README.md
│   │   └── src/
│   │       ├── debug.rs
│   │       ├── error.rs
│   │       ├── lib.rs
│   │       ├── parser/
│   │       │   ├── body.rs
│   │       │   ├── condition.rs
│   │       │   ├── doc_comment.rs
│   │       │   ├── header_value.rs
│   │       │   ├── headers.rs
│   │       │   ├── identifier.rs
│   │       │   ├── identifier_reference.rs
│   │       │   ├── kind.rs
│   │       │   ├── kinded_name.rs
│   │       │   ├── kinded_reference.rs
│   │       │   ├── mod.rs
│   │       │   ├── section.rs
│   │       │   ├── section_init.rs
│   │       │   ├── tes.rs
│   │       │   ├── test.rs
│   │       │   └── visibility.rs
│   │       ├── scanner.rs
│   │       ├── utils.rs
│   │       ├── warning.rs
│   │       └── wiggin.rs
│   ├── fastn-spec-viewer/
│   │   ├── Cargo.toml
│   │   ├── DIFF_OUTPUT_DESIGN.md
│   │   ├── README.md
│   │   ├── SPEC_FORMAT_DESIGN.md
│   │   └── src/
│   │       ├── embedded_specs.rs
│   │       ├── lib.rs
│   │       ├── main.rs
│   │       └── spec_renderer.rs
│   ├── fastn-static/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       └── main.rs
│   ├── fastn-unresolved/
│   │   ├── ARCHITECTURE.md
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   ├── TESTING.md
│   │   └── src/
│   │       ├── debug.rs
│   │       ├── lib.rs
│   │       ├── parser/
│   │       │   ├── component_invocation.rs
│   │       │   ├── function_definition.rs
│   │       │   ├── import.rs
│   │       │   └── mod.rs
│   │       ├── resolver/
│   │       │   ├── arguments.rs
│   │       │   ├── component_invocation.rs
│   │       │   ├── definition.rs
│   │       │   ├── mod.rs
│   │       │   └── symbol.rs
│   │       └── utils.rs
│   ├── fastn-update/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       └── lib.rs
│   ├── fastn-utils/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       └── section_provider.rs
│   ├── fastn-wasm/
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── aws.rs
│   │       ├── crypto.rs
│   │       ├── ds.rs
│   │       ├── email.rs
│   │       ├── env.rs
│   │       ├── helpers.rs
│   │       ├── http/
│   │       │   ├── get_request.rs
│   │       │   ├── mod.rs
│   │       │   ├── send_request.rs
│   │       │   └── send_response.rs
│   │       ├── lib.rs
│   │       ├── macros.rs
│   │       ├── pg/
│   │       │   ├── batch_execute.rs
│   │       │   ├── connect.rs
│   │       │   ├── create_pool.rs
│   │       │   ├── db_error.rs
│   │       │   ├── execute.rs
│   │       │   ├── mod.rs
│   │       │   └── query.rs
│   │       ├── process_http_request.rs
│   │       ├── register.rs
│   │       ├── sqlite/
│   │       │   ├── batch_execute.rs
│   │       │   ├── connect.rs
│   │       │   ├── execute.rs
│   │       │   ├── mod.rs
│   │       │   └── query.rs
│   │       └── store.rs
│   ├── manual-testing/
│   │   ├── setup-fastn-email.sh
│   │   ├── test-apple-mail.sh
│   │   └── test-smtp-imap-cli.sh
│   ├── rfc-there-be-dragons.md
│   ├── specs/
│   │   ├── CLAUDE.md
│   │   ├── components/
│   │   │   ├── button.ftd
│   │   │   └── button.rendered
│   │   └── text/
│   │       ├── basic.ftd
│   │       ├── basic.rendered
│   │       ├── with-border.ftd
│   │       └── with-border.rendered
│   └── test.sh
└── vendor.yml
Download .txt
Showing preview only (729K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (8992 symbols across 672 files)

FILE: .github/scripts/populate-table.py
  function create_table (line 5) | def create_table():
  function insert_data (line 31) | def insert_data():
  function get_database_path (line 49) | def get_database_path(uri):

FILE: .github/scripts/test-server.py
  function fetch_data (line 8) | def fetch_data():
  function get_data (line 36) | def get_data():
  function get_database_path (line 46) | def get_database_path(uri):

FILE: clift/src/api/commit_upload.rs
  function endpoint (line 1) | fn endpoint() -> String {
  type CommitUploadRequest (line 6) | pub struct CommitUploadRequest {
  type CommitUploadError (line 13) | pub enum CommitUploadError {
  function commit_upload (line 18) | pub async fn commit_upload(

FILE: clift/src/api/initiate_upload.rs
  function endpoint (line 1) | fn endpoint() -> String {
  type InitiateUploadRequest (line 6) | pub enum InitiateUploadRequest {
    method get_site (line 21) | pub fn get_site(&self) -> String {
    method is_dry_run (line 27) | pub fn is_dry_run(&self) -> bool {
  type InitiateUploadResponse (line 36) | pub struct InitiateUploadResponse {
  type PreSignedRequest (line 47) | pub struct PreSignedRequest {
  type ContentToUpload (line 54) | pub struct ContentToUpload {
  type InitiateUploadError (line 61) | pub enum InitiateUploadError {
  function initiate_upload (line 74) | pub async fn initiate_upload(

FILE: clift/src/api/mod.rs
  constant ENDPOINT (line 10) | pub const ENDPOINT: &str = "https://www.fifthtry.com";
  type ApiResponse (line 13) | pub struct ApiResponse<T> {
  function endpoint (line 19) | pub fn endpoint(name: &str) -> String {

FILE: clift/src/commands/upload.rs
  function upload_file (line 1) | pub async fn upload_file(
  function upload_folder (line 19) | pub async fn upload_folder(
  function upload (line 38) | pub async fn upload(
  function upload_ (line 79) | async fn upload_(
  function upload_files (line 118) | async fn upload_files(
  type UploadError (line 133) | pub enum UploadError {

FILE: clift/src/lib.rs
  function attach_cmd (line 10) | pub fn attach_cmd(cmd: clap::Command) -> clap::Command {
  function upload (line 21) | pub async fn upload(matches: &clap::ArgMatches) {

FILE: clift/src/utils/call_api.rs
  function call_api (line 1) | pub async fn call_api(

FILE: clift/src/utils/generate_hash.rs
  function generate_hash (line 8) | pub fn generate_hash(content: impl AsRef<[u8]>) -> String {

FILE: clift/src/utils/get_local_files.rs
  type GetLocalFilesError (line 2) | pub enum GetLocalFilesError {
  function get_local_files (line 7) | pub async fn get_local_files(
  function path_to_content (line 41) | pub async fn path_to_content(

FILE: clift/src/utils/github_token.rs
  type GithubOidcActionToken (line 1) | pub struct GithubOidcActionToken {
  type GithubActionIdTokenRequestError (line 7) | pub enum GithubActionIdTokenRequestError {
  function github_oidc_action_token (line 14) | pub fn github_oidc_action_token() -> Result<GithubOidcActionToken, Githu...

FILE: clift/src/utils/site_token.rs
  type SiteToken (line 1) | pub struct SiteToken(pub String);
    method from_env (line 4) | pub fn from_env() -> Result<Self, std::env::VarError> {

FILE: clift/src/utils/update_token.rs
  type UpdateToken (line 1) | pub enum UpdateToken {
  type UpdateTokenError (line 7) | pub enum UpdateTokenError {
  function update_token (line 14) | pub fn update_token() -> Result<UpdateToken, UpdateTokenError> {

FILE: clift/src/utils/uploader.rs
  type Uploader (line 1) | pub enum Uploader {
    method debug (line 17) | pub async fn debug(path: &std::path::Path) -> Result<Uploader, Uploade...
    method s3 (line 22) | pub fn s3(sr: clift::api::PreSignedRequest) -> Uploader {
    method upload (line 26) | pub async fn upload(&mut self, path: &std::path::Path) -> Result<(), U...
    method commit (line 37) | pub async fn commit(&mut self) -> Result<(), UploaderError> {
  type UploaderError (line 7) | pub enum UploaderError {

FILE: fastn-builtins/src/constants.rs
  constant FTD_BREAKPOINT_WIDTH (line 4) | pub const FTD_BREAKPOINT_WIDTH: &str = "ftd#breakpoint-width";
  constant FTD_BREAKPOINT_WIDTH_DATA (line 5) | pub const FTD_BREAKPOINT_WIDTH_DATA: &str = "ftd#breakpoint-width-data";
  constant FTD_DEVICE (line 7) | pub const FTD_DEVICE: &str = "ftd#device";
  constant FTD_DEVICE_DATA (line 8) | pub const FTD_DEVICE_DATA: &str = "ftd#device-data";
  constant FTD_DEVICE_DATA_MOBILE (line 9) | pub const FTD_DEVICE_DATA_MOBILE: &str = "ftd#device-data.mobile";
  constant FTD_DEVICE_DATA_DESKTOP (line 10) | pub const FTD_DEVICE_DATA_DESKTOP: &str = "ftd#device-data.desktop";
  constant FTD_LENGTH (line 12) | pub const FTD_LENGTH: &str = "ftd#length";
  constant FTD_LENGTH_PX (line 13) | pub const FTD_LENGTH_PX: &str = "ftd#length.px";
  constant FTD_LENGTH_PERCENT (line 14) | pub const FTD_LENGTH_PERCENT: &str = "ftd#length.percent";
  constant FTD_LENGTH_CALC (line 15) | pub const FTD_LENGTH_CALC: &str = "ftd#length.calc";
  constant FTD_LENGTH_VH (line 16) | pub const FTD_LENGTH_VH: &str = "ftd#length.vh";
  constant FTD_LENGTH_VW (line 17) | pub const FTD_LENGTH_VW: &str = "ftd#length.vw";
  constant FTD_LENGTH_VMIN (line 18) | pub const FTD_LENGTH_VMIN: &str = "ftd#length.vmin";
  constant FTD_LENGTH_VMAX (line 19) | pub const FTD_LENGTH_VMAX: &str = "ftd#length.vmax";
  constant FTD_LENGTH_DVH (line 20) | pub const FTD_LENGTH_DVH: &str = "ftd#length.dvh";
  constant FTD_LENGTH_LVH (line 21) | pub const FTD_LENGTH_LVH: &str = "ftd#length.lvh";
  constant FTD_LENGTH_SVH (line 22) | pub const FTD_LENGTH_SVH: &str = "ftd#length.svh";
  constant FTD_LENGTH_EM (line 23) | pub const FTD_LENGTH_EM: &str = "ftd#length.em";
  constant FTD_LENGTH_REM (line 24) | pub const FTD_LENGTH_REM: &str = "ftd#length.rem";
  constant FTD_LENGTH_RESPONSIVE (line 25) | pub const FTD_LENGTH_RESPONSIVE: &str = "ftd#length.responsive";
  constant FTD_RESPONSIVE_LENGTH (line 27) | pub const FTD_RESPONSIVE_LENGTH: &str = "ftd#responsive-length";
  constant FTD_RESPONSIVE_LENGTH_DESKTOP (line 28) | pub const FTD_RESPONSIVE_LENGTH_DESKTOP: &str = "ftd#responsive-length.d...
  constant FTD_ALIGN (line 30) | pub const FTD_ALIGN: &str = "ftd#align";
  constant FTD_ALIGN_TOP_LEFT (line 31) | pub const FTD_ALIGN_TOP_LEFT: &str = "ftd#align.top-left";
  constant FTD_ALIGN_TOP_CENTER (line 32) | pub const FTD_ALIGN_TOP_CENTER: &str = "ftd#align.top-center";
  constant FTD_ALIGN_TOP_RIGHT (line 33) | pub const FTD_ALIGN_TOP_RIGHT: &str = "ftd#align.top-right";
  constant FTD_ALIGN_RIGHT (line 34) | pub const FTD_ALIGN_RIGHT: &str = "ftd#align.right";
  constant FTD_ALIGN_LEFT (line 35) | pub const FTD_ALIGN_LEFT: &str = "ftd#align.left";
  constant FTD_ALIGN_CENTER (line 36) | pub const FTD_ALIGN_CENTER: &str = "ftd#align.center";
  constant FTD_ALIGN_BOTTOM_LEFT (line 37) | pub const FTD_ALIGN_BOTTOM_LEFT: &str = "ftd#align.bottom-left";
  constant FTD_ALIGN_BOTTOM_CENTER (line 38) | pub const FTD_ALIGN_BOTTOM_CENTER: &str = "ftd#align.bottom-center";
  constant FTD_ALIGN_BOTTOM_RIGHT (line 39) | pub const FTD_ALIGN_BOTTOM_RIGHT: &str = "ftd#align.bottom-right";
  constant FTD_RESIZING (line 41) | pub const FTD_RESIZING: &str = "ftd#resizing";
  constant FTD_RESIZING_HUG_CONTENT (line 42) | pub const FTD_RESIZING_HUG_CONTENT: &str = "ftd#resizing.hug-content";
  constant FTD_RESIZING_FILL_CONTAINER (line 43) | pub const FTD_RESIZING_FILL_CONTAINER: &str = "ftd#resizing.fill-contain...
  constant FTD_RESIZING_AUTO (line 44) | pub const FTD_RESIZING_AUTO: &str = "ftd#resizing.auto";
  constant FTD_RESIZING_FIXED (line 45) | pub const FTD_RESIZING_FIXED: &str = "ftd#resizing.fixed";
  constant FTD_COLOR (line 47) | pub const FTD_COLOR: &str = "ftd#color";
  constant FTD_COLOR_LIGHT (line 48) | pub const FTD_COLOR_LIGHT: &str = "ftd#color.light";
  constant FTD_BACKGROUND (line 50) | pub const FTD_BACKGROUND: &str = "ftd#background";
  constant FTD_BACKGROUND_SOLID (line 51) | pub const FTD_BACKGROUND_SOLID: &str = "ftd#background.solid";
  constant FTD_BACKGROUND_IMAGE (line 52) | pub const FTD_BACKGROUND_IMAGE: &str = "ftd#background.image";
  constant FTD_BACKGROUND_LINEAR_GRADIENT (line 53) | pub const FTD_BACKGROUND_LINEAR_GRADIENT: &str = "ftd#background.linear-...
  constant FTD_LENGTH_PAIR (line 55) | pub const FTD_LENGTH_PAIR: &str = "ftd#length-pair";
  constant FTD_LENGTH_PAIR_X (line 56) | pub const FTD_LENGTH_PAIR_X: &str = "ftd#length-pair.x";
  constant FTD_LENGTH_PAIR_Y (line 57) | pub const FTD_LENGTH_PAIR_Y: &str = "ftd#length-pair.y";
  constant FTD_BG_IMAGE (line 59) | pub const FTD_BG_IMAGE: &str = "ftd#background-image";
  constant FTD_BG_IMAGE_SRC (line 60) | pub const FTD_BG_IMAGE_SRC: &str = "ftd#background-image.src";
  constant FTD_BG_IMAGE_REPEAT (line 61) | pub const FTD_BG_IMAGE_REPEAT: &str = "ftd#background-image.repeat";
  constant FTD_LINEAR_GRADIENT (line 63) | pub const FTD_LINEAR_GRADIENT: &str = "ftd#linear-gradient";
  constant FTD_LINEAR_GRADIENT_DIRECTION (line 64) | pub const FTD_LINEAR_GRADIENT_DIRECTION: &str = "ftd#linear-gradient.dir...
  constant FTD_LINEAR_GRADIENT_COLORS (line 65) | pub const FTD_LINEAR_GRADIENT_COLORS: &str = "ftd#linear-gradient.colors";
  constant FTD_LINEAR_GRADIENT_COLOR (line 67) | pub const FTD_LINEAR_GRADIENT_COLOR: &str = "ftd#linear-gradient-color";
  constant FTD_LINEAR_GRADIENT_COLOR_NAME (line 68) | pub const FTD_LINEAR_GRADIENT_COLOR_NAME: &str = "ftd#linear-gradient-co...
  constant FTD_LINEAR_GRADIENT_COLOR_START (line 69) | pub const FTD_LINEAR_GRADIENT_COLOR_START: &str = "ftd#linear-gradient-c...
  constant FTD_LINEAR_GRADIENT_COLOR_END (line 70) | pub const FTD_LINEAR_GRADIENT_COLOR_END: &str = "ftd#linear-gradient-col...
  constant FTD_LINEAR_GRADIENT_COLOR_STOP_POSITION (line 71) | pub const FTD_LINEAR_GRADIENT_COLOR_STOP_POSITION: &str = "ftd#linear-gr...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS (line 73) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS: &str = "ftd#linear-gradient-di...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_ANGLE (line 74) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_ANGLE: &str = "ftd#linear-gradi...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_TURN (line 75) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_TURN: &str = "ftd#linear-gradie...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_LEFT (line 76) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_LEFT: &str = "ftd#linear-gradie...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_RIGHT (line 77) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_RIGHT: &str = "ftd#linear-gradi...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_TOP (line 78) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_TOP: &str = "ftd#linear-gradien...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_BOTTOM (line 79) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_BOTTOM: &str = "ftd#linear-grad...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_TOP_LEFT (line 80) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_TOP_LEFT: &str = "ftd#linear-gr...
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_TOP_RIGHT (line 81) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_TOP_RIGHT: &str =
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_BOTTOM_LEFT (line 83) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_BOTTOM_LEFT: &str =
  constant FTD_LINEAR_GRADIENT_DIRECTIONS_BOTTOM_RIGHT (line 85) | pub const FTD_LINEAR_GRADIENT_DIRECTIONS_BOTTOM_RIGHT: &str =
  constant FTD_BACKGROUND_REPEAT (line 88) | pub const FTD_BACKGROUND_REPEAT: &str = "ftd#background-repeat";
  constant FTD_BACKGROUND_REPEAT_BOTH_REPEAT (line 89) | pub const FTD_BACKGROUND_REPEAT_BOTH_REPEAT: &str = "ftd#background-repe...
  constant FTD_BACKGROUND_REPEAT_X_REPEAT (line 90) | pub const FTD_BACKGROUND_REPEAT_X_REPEAT: &str = "ftd#background-repeat....
  constant FTD_BACKGROUND_REPEAT_Y_REPEAT (line 91) | pub const FTD_BACKGROUND_REPEAT_Y_REPEAT: &str = "ftd#background-repeat....
  constant FTD_BACKGROUND_REPEAT_NO_REPEAT (line 92) | pub const FTD_BACKGROUND_REPEAT_NO_REPEAT: &str = "ftd#background-repeat...
  constant FTD_BACKGROUND_REPEAT_SPACE (line 93) | pub const FTD_BACKGROUND_REPEAT_SPACE: &str = "ftd#background-repeat.spa...
  constant FTD_BACKGROUND_REPEAT_ROUND (line 94) | pub const FTD_BACKGROUND_REPEAT_ROUND: &str = "ftd#background-repeat.rou...
  constant FTD_BACKGROUND_SIZE (line 96) | pub const FTD_BACKGROUND_SIZE: &str = "ftd#background-size";
  constant FTD_BACKGROUND_SIZE_AUTO (line 97) | pub const FTD_BACKGROUND_SIZE_AUTO: &str = "ftd#background-size.auto";
  constant FTD_BACKGROUND_SIZE_COVER (line 98) | pub const FTD_BACKGROUND_SIZE_COVER: &str = "ftd#background-size.cover";
  constant FTD_BACKGROUND_SIZE_CONTAIN (line 99) | pub const FTD_BACKGROUND_SIZE_CONTAIN: &str = "ftd#background-size.conta...
  constant FTD_BACKGROUND_SIZE_LENGTH (line 100) | pub const FTD_BACKGROUND_SIZE_LENGTH: &str = "ftd#background-size.length";
  constant FTD_BACKGROUND_POSITION (line 102) | pub const FTD_BACKGROUND_POSITION: &str = "ftd#background-position";
  constant FTD_BACKGROUND_POSITION_LEFT (line 103) | pub const FTD_BACKGROUND_POSITION_LEFT: &str = "ftd#background-position....
  constant FTD_BACKGROUND_POSITION_CENTER (line 104) | pub const FTD_BACKGROUND_POSITION_CENTER: &str = "ftd#background-positio...
  constant FTD_BACKGROUND_POSITION_RIGHT (line 105) | pub const FTD_BACKGROUND_POSITION_RIGHT: &str = "ftd#background-position...
  constant FTD_BACKGROUND_POSITION_LEFT_TOP (line 106) | pub const FTD_BACKGROUND_POSITION_LEFT_TOP: &str = "ftd#background-posit...
  constant FTD_BACKGROUND_POSITION_LEFT_CENTER (line 107) | pub const FTD_BACKGROUND_POSITION_LEFT_CENTER: &str = "ftd#background-po...
  constant FTD_BACKGROUND_POSITION_LEFT_BOTTOM (line 108) | pub const FTD_BACKGROUND_POSITION_LEFT_BOTTOM: &str = "ftd#background-po...
  constant FTD_BACKGROUND_POSITION_CENTER_TOP (line 109) | pub const FTD_BACKGROUND_POSITION_CENTER_TOP: &str = "ftd#background-pos...
  constant FTD_BACKGROUND_POSITION_CENTER_CENTER (line 110) | pub const FTD_BACKGROUND_POSITION_CENTER_CENTER: &str = "ftd#background-...
  constant FTD_BACKGROUND_POSITION_CENTER_BOTTOM (line 111) | pub const FTD_BACKGROUND_POSITION_CENTER_BOTTOM: &str = "ftd#background-...
  constant FTD_BACKGROUND_POSITION_RIGHT_TOP (line 112) | pub const FTD_BACKGROUND_POSITION_RIGHT_TOP: &str = "ftd#background-posi...
  constant FTD_BACKGROUND_POSITION_RIGHT_CENTER (line 113) | pub const FTD_BACKGROUND_POSITION_RIGHT_CENTER: &str = "ftd#background-p...
  constant FTD_BACKGROUND_POSITION_RIGHT_BOTTOM (line 114) | pub const FTD_BACKGROUND_POSITION_RIGHT_BOTTOM: &str = "ftd#background-p...
  constant FTD_BACKGROUND_POSITION_LENGTH (line 115) | pub const FTD_BACKGROUND_POSITION_LENGTH: &str = "ftd#background-positio...
  constant FTD_RAW_IMAGE_SRC (line 117) | pub const FTD_RAW_IMAGE_SRC: &str = "ftd#raw-image-src";
  constant FTD_IMAGE_SRC (line 119) | pub const FTD_IMAGE_SRC: &str = "ftd#image-src";
  constant FTD_IMAGE_SRC_LIGHT (line 120) | pub const FTD_IMAGE_SRC_LIGHT: &str = "ftd#image-src.light";
  constant FTD_IMAGE_SRC_DARK (line 121) | pub const FTD_IMAGE_SRC_DARK: &str = "ftd#image-src.dark";
  constant FTD_IMAGE_FIT (line 123) | pub const FTD_IMAGE_FIT: &str = "ftd#image-fit";
  constant FTD_IMAGE_FIT_NONE (line 124) | pub const FTD_IMAGE_FIT_NONE: &str = "ftd#image-fit.none";
  constant FTD_IMAGE_FIT_COVER (line 125) | pub const FTD_IMAGE_FIT_COVER: &str = "ftd#image-fit.cover";
  constant FTD_IMAGE_FIT_CONTAIN (line 126) | pub const FTD_IMAGE_FIT_CONTAIN: &str = "ftd#image-fit.contain";
  constant FTD_IMAGE_FIT_FILL (line 127) | pub const FTD_IMAGE_FIT_FILL: &str = "ftd#image-fit.fill";
  constant FTD_IMAGE_FIT_SCALE_DOWN (line 128) | pub const FTD_IMAGE_FIT_SCALE_DOWN: &str = "ftd#image-fit.scale-down";
  constant FTD_IMAGE_FETCH_PRIORITY (line 130) | pub const FTD_IMAGE_FETCH_PRIORITY: &str = "ftd#image-fetch-priority";
  constant FTD_IMAGE_FETCH_PRIORITY_AUTO (line 131) | pub const FTD_IMAGE_FETCH_PRIORITY_AUTO: &str = "ftd#image-fetch-priorit...
  constant FTD_IMAGE_FETCH_PRIORITY_HIGH (line 132) | pub const FTD_IMAGE_FETCH_PRIORITY_HIGH: &str = "ftd#image-fetch-priorit...
  constant FTD_IMAGE_FETCH_PRIORITY_LOW (line 133) | pub const FTD_IMAGE_FETCH_PRIORITY_LOW: &str = "ftd#image-fetch-priority...
  constant FTD_VIDEO_SRC (line 135) | pub const FTD_VIDEO_SRC: &str = "ftd#video-src";
  constant FTD_VIDEO_SRC_LIGHT (line 136) | pub const FTD_VIDEO_SRC_LIGHT: &str = "ftd#video-src.light";
  constant FTD_VIDEO_SRC_DARK (line 137) | pub const FTD_VIDEO_SRC_DARK: &str = "ftd#video-src.dark";
  constant FTD_VIDEO_POSTER (line 139) | pub const FTD_VIDEO_POSTER: &str = "ftd#video-poster";
  constant FTD_VIDEO_POSTER_LIGHT (line 140) | pub const FTD_VIDEO_POSTER_LIGHT: &str = "ftd#video-poster.light";
  constant FTD_VIDEO_POSTER_DARK (line 141) | pub const FTD_VIDEO_POSTER_DARK: &str = "ftd#video-poster.dark";
  constant FTD_VIDEO_AUTOPLAY (line 143) | pub const FTD_VIDEO_AUTOPLAY: &str = "ftd#video-autoplay";
  constant FTD_VIDEO_MUTED (line 144) | pub const FTD_VIDEO_MUTED: &str = "ftd#muted";
  constant FTD_VIDEO_CONTROLS (line 145) | pub const FTD_VIDEO_CONTROLS: &str = "ftd#video-controls";
  constant FTD_VIDEO_LOOP (line 146) | pub const FTD_VIDEO_LOOP: &str = "ftd#video-loop";
  constant FTD_SPACING (line 148) | pub const FTD_SPACING: &str = "ftd#spacing";
  constant FTD_SPACING_FIXED (line 149) | pub const FTD_SPACING_FIXED: &str = "ftd#spacing.fixed";
  constant FTD_SPACING_SPACE_BETWEEN (line 150) | pub const FTD_SPACING_SPACE_BETWEEN: &str = "ftd#spacing.space-between";
  constant FTD_SPACING_SPACE_AROUND (line 151) | pub const FTD_SPACING_SPACE_AROUND: &str = "ftd#spacing.space-around";
  constant FTD_SPACING_SPACE_EVENLY (line 152) | pub const FTD_SPACING_SPACE_EVENLY: &str = "ftd#spacing.space-evenly";
  constant FTD_ALIGN_SELF (line 154) | pub const FTD_ALIGN_SELF: &str = "ftd#align-self";
  constant FTD_ALIGN_SELF_START (line 155) | pub const FTD_ALIGN_SELF_START: &str = "ftd#align-self.start";
  constant FTD_ALIGN_SELF_CENTER (line 156) | pub const FTD_ALIGN_SELF_CENTER: &str = "ftd#align-self.center";
  constant FTD_ALIGN_SELF_END (line 157) | pub const FTD_ALIGN_SELF_END: &str = "ftd#align-self.end";
  constant FTD_TEXT_ALIGN (line 159) | pub const FTD_TEXT_ALIGN: &str = "ftd#text-align";
  constant FTD_TEXT_ALIGN_START (line 160) | pub const FTD_TEXT_ALIGN_START: &str = "ftd#text-align.start";
  constant FTD_TEXT_ALIGN_CENTER (line 161) | pub const FTD_TEXT_ALIGN_CENTER: &str = "ftd#text-align.center";
  constant FTD_TEXT_ALIGN_END (line 162) | pub const FTD_TEXT_ALIGN_END: &str = "ftd#text-align.end";
  constant FTD_TEXT_ALIGN_JUSTIFY (line 163) | pub const FTD_TEXT_ALIGN_JUSTIFY: &str = "ftd#text-align.justify";
  constant FTD_SHADOW (line 165) | pub const FTD_SHADOW: &str = "ftd#shadow";
  constant FTD_SHADOW_COLOR (line 166) | pub const FTD_SHADOW_COLOR: &str = "ftd#shadow.color";
  constant FTD_OVERFLOW (line 169) | pub const FTD_OVERFLOW: &str = "ftd#overflow";
  constant FTD_OVERFLOW_SCROLL (line 170) | pub const FTD_OVERFLOW_SCROLL: &str = "ftd#overflow.scroll";
  constant FTD_OVERFLOW_VISIBLE (line 171) | pub const FTD_OVERFLOW_VISIBLE: &str = "ftd#overflow.visible";
  constant FTD_OVERFLOW_HIDDEN (line 172) | pub const FTD_OVERFLOW_HIDDEN: &str = "ftd#overflow.hidden";
  constant FTD_OVERFLOW_AUTO (line 173) | pub const FTD_OVERFLOW_AUTO: &str = "ftd#overflow.auto";
  constant FTD_RESIZE (line 175) | pub const FTD_RESIZE: &str = "ftd#resize";
  constant FTD_RESIZE_HORIZONTAL (line 176) | pub const FTD_RESIZE_HORIZONTAL: &str = "ftd#resize.horizontal";
  constant FTD_RESIZE_VERTICAL (line 177) | pub const FTD_RESIZE_VERTICAL: &str = "ftd#resize.vertical";
  constant FTD_RESIZE_BOTH (line 178) | pub const FTD_RESIZE_BOTH: &str = "ftd#resize.both";
  constant FTD_CURSOR (line 181) | pub const FTD_CURSOR: &str = "ftd#cursor";
  constant FTD_CURSOR_DEFAULT (line 182) | pub const FTD_CURSOR_DEFAULT: &str = "ftd#cursor.default";
  constant FTD_CURSOR_NONE (line 183) | pub const FTD_CURSOR_NONE: &str = "ftd#cursor.none";
  constant FTD_CURSOR_CONTEXT_MENU (line 184) | pub const FTD_CURSOR_CONTEXT_MENU: &str = "ftd#cursor.context-menu";
  constant FTD_CURSOR_HELP (line 185) | pub const FTD_CURSOR_HELP: &str = "ftd#cursor.help";
  constant FTD_CURSOR_POINTER (line 186) | pub const FTD_CURSOR_POINTER: &str = "ftd#cursor.pointer";
  constant FTD_CURSOR_PROGRESS (line 187) | pub const FTD_CURSOR_PROGRESS: &str = "ftd#cursor.progress";
  constant FTD_CURSOR_WAIT (line 188) | pub const FTD_CURSOR_WAIT: &str = "ftd#cursor.wait";
  constant FTD_CURSOR_CELL (line 189) | pub const FTD_CURSOR_CELL: &str = "ftd#cursor.cell";
  constant FTD_CURSOR_CROSSHAIR (line 190) | pub const FTD_CURSOR_CROSSHAIR: &str = "ftd#cursor.crosshair";
  constant FTD_CURSOR_TEXT (line 191) | pub const FTD_CURSOR_TEXT: &str = "ftd#cursor.text";
  constant FTD_CURSOR_VERTICAL_TEXT (line 192) | pub const FTD_CURSOR_VERTICAL_TEXT: &str = "ftd#cursor.vertical-text";
  constant FTD_CURSOR_ALIAS (line 193) | pub const FTD_CURSOR_ALIAS: &str = "ftd#cursor.alias";
  constant FTD_CURSOR_COPY (line 194) | pub const FTD_CURSOR_COPY: &str = "ftd#cursor.copy";
  constant FTD_CURSOR_MOVE (line 195) | pub const FTD_CURSOR_MOVE: &str = "ftd#cursor.move";
  constant FTD_CURSOR_NO_DROP (line 196) | pub const FTD_CURSOR_NO_DROP: &str = "ftd#cursor.no-drop";
  constant FTD_CURSOR_NOT_ALLOWED (line 197) | pub const FTD_CURSOR_NOT_ALLOWED: &str = "ftd#cursor.not-allowed";
  constant FTD_CURSOR_GRAB (line 198) | pub const FTD_CURSOR_GRAB: &str = "ftd#cursor.grab";
  constant FTD_CURSOR_GRABBING (line 199) | pub const FTD_CURSOR_GRABBING: &str = "ftd#cursor.grabbing";
  constant FTD_CURSOR_E_RESIZE (line 200) | pub const FTD_CURSOR_E_RESIZE: &str = "ftd#cursor.e-resize";
  constant FTD_CURSOR_N_RESIZE (line 201) | pub const FTD_CURSOR_N_RESIZE: &str = "ftd#cursor.n-resize";
  constant FTD_CURSOR_NE_RESIZE (line 202) | pub const FTD_CURSOR_NE_RESIZE: &str = "ftd#cursor.ne-resize";
  constant FTD_CURSOR_NW_RESIZE (line 203) | pub const FTD_CURSOR_NW_RESIZE: &str = "ftd#cursor.nw-resize";
  constant FTD_CURSOR_S_RESIZE (line 204) | pub const FTD_CURSOR_S_RESIZE: &str = "ftd#cursor.s-resize";
  constant FTD_CURSOR_SE_RESIZE (line 205) | pub const FTD_CURSOR_SE_RESIZE: &str = "ftd#cursor.se-resize";
  constant FTD_CURSOR_SW_RESIZE (line 206) | pub const FTD_CURSOR_SW_RESIZE: &str = "ftd#cursor.sw-resize";
  constant FTD_CURSOR_W_RESIZE (line 207) | pub const FTD_CURSOR_W_RESIZE: &str = "ftd#cursor.w-resize";
  constant FTD_CURSOR_EW_RESIZE (line 208) | pub const FTD_CURSOR_EW_RESIZE: &str = "ftd#cursor.ew-resize";
  constant FTD_CURSOR_NS_RESIZE (line 209) | pub const FTD_CURSOR_NS_RESIZE: &str = "ftd#cursor.ns-resize";
  constant FTD_CURSOR_NESW_RESIZE (line 210) | pub const FTD_CURSOR_NESW_RESIZE: &str = "ftd#cursor.nesw-resize";
  constant FTD_CURSOR_NWSE_RESIZE (line 211) | pub const FTD_CURSOR_NWSE_RESIZE: &str = "ftd#cursor.nwse-resize";
  constant FTD_CURSOR_COL_RESIZE (line 212) | pub const FTD_CURSOR_COL_RESIZE: &str = "ftd#cursor.col-resize";
  constant FTD_CURSOR_ROW_RESIZE (line 213) | pub const FTD_CURSOR_ROW_RESIZE: &str = "ftd#cursor.row-resize";
  constant FTD_CURSOR_ALL_SCROLL (line 214) | pub const FTD_CURSOR_ALL_SCROLL: &str = "ftd#cursor.all-scroll";
  constant FTD_CURSOR_ZOOM_IN (line 215) | pub const FTD_CURSOR_ZOOM_IN: &str = "ftd#cursor.zoom-in";
  constant FTD_CURSOR_ZOOM_OUT (line 216) | pub const FTD_CURSOR_ZOOM_OUT: &str = "ftd#cursor.zoom-out";
  constant FTD_FONT_SIZE (line 218) | pub const FTD_FONT_SIZE: &str = "ftd#font-size";
  constant FTD_FONT_SIZE_PX (line 219) | pub const FTD_FONT_SIZE_PX: &str = "ftd#font-size.px";
  constant FTD_FONT_SIZE_EM (line 220) | pub const FTD_FONT_SIZE_EM: &str = "ftd#font-size.em";
  constant FTD_FONT_SIZE_REM (line 221) | pub const FTD_FONT_SIZE_REM: &str = "ftd#font-size.rem";
  constant FTD_TYPE (line 223) | pub const FTD_TYPE: &str = "ftd#type";
  constant FTD_RESPONSIVE_TYPE (line 225) | pub const FTD_RESPONSIVE_TYPE: &str = "ftd#responsive-type";
  constant FTD_RESPONSIVE_TYPE_DESKTOP (line 226) | pub const FTD_RESPONSIVE_TYPE_DESKTOP: &str = "ftd#responsive-type.deskt...
  constant FTD_ANCHOR (line 228) | pub const FTD_ANCHOR: &str = "ftd#anchor";
  constant FTD_ANCHOR_WINDOW (line 229) | pub const FTD_ANCHOR_WINDOW: &str = "ftd#anchor.window";
  constant FTD_ANCHOR_PARENT (line 230) | pub const FTD_ANCHOR_PARENT: &str = "ftd#anchor.parent";
  constant FTD_ANCHOR_ID (line 231) | pub const FTD_ANCHOR_ID: &str = "ftd#anchor.id";
  constant FTD_COLOR_SCHEME (line 233) | pub const FTD_COLOR_SCHEME: &str = "ftd#color-scheme";
  constant FTD_BACKGROUND_COLOR (line 234) | pub const FTD_BACKGROUND_COLOR: &str = "ftd#background-colors";
  constant FTD_CTA_COLOR (line 235) | pub const FTD_CTA_COLOR: &str = "ftd#cta-colors";
  constant FTD_PST (line 236) | pub const FTD_PST: &str = "ftd#pst";
  constant FTD_BTB (line 237) | pub const FTD_BTB: &str = "ftd#btb";
  constant FTD_CUSTOM_COLORS (line 238) | pub const FTD_CUSTOM_COLORS: &str = "ftd#custom-colors";
  constant FTD_TYPE_DATA (line 240) | pub const FTD_TYPE_DATA: &str = "ftd#type-data";
  constant FTD_TEXT_INPUT_TYPE (line 242) | pub const FTD_TEXT_INPUT_TYPE: &str = "ftd#text-input-type";
  constant FTD_TEXT_INPUT_TYPE_TEXT (line 243) | pub const FTD_TEXT_INPUT_TYPE_TEXT: &str = "ftd#text-input-type.text";
  constant FTD_TEXT_INPUT_TYPE_EMAIL (line 244) | pub const FTD_TEXT_INPUT_TYPE_EMAIL: &str = "ftd#text-input-type.email";
  constant FTD_TEXT_INPUT_TYPE_PASSWORD (line 245) | pub const FTD_TEXT_INPUT_TYPE_PASSWORD: &str = "ftd#text-input-type.pass...
  constant FTD_TEXT_INPUT_TYPE_URL (line 246) | pub const FTD_TEXT_INPUT_TYPE_URL: &str = "ftd#text-input-type.url";
  constant FTD_TEXT_INPUT_TYPE_DATETIME (line 247) | pub const FTD_TEXT_INPUT_TYPE_DATETIME: &str = "ftd#text-input-type.date...
  constant FTD_TEXT_INPUT_TYPE_DATE (line 248) | pub const FTD_TEXT_INPUT_TYPE_DATE: &str = "ftd#text-input-type.date";
  constant FTD_TEXT_INPUT_TYPE_TIME (line 249) | pub const FTD_TEXT_INPUT_TYPE_TIME: &str = "ftd#text-input-type.time";
  constant FTD_TEXT_INPUT_TYPE_MONTH (line 250) | pub const FTD_TEXT_INPUT_TYPE_MONTH: &str = "ftd#text-input-type.month";
  constant FTD_TEXT_INPUT_TYPE_WEEK (line 251) | pub const FTD_TEXT_INPUT_TYPE_WEEK: &str = "ftd#text-input-type.week";
  constant FTD_TEXT_INPUT_TYPE_COLOR (line 252) | pub const FTD_TEXT_INPUT_TYPE_COLOR: &str = "ftd#text-input-type.color";
  constant FTD_TEXT_INPUT_TYPE_FILE (line 253) | pub const FTD_TEXT_INPUT_TYPE_FILE: &str = "ftd#text-input-type.file";
  constant FTD_REGION (line 255) | pub const FTD_REGION: &str = "ftd#region";
  constant FTD_REGION_H1 (line 256) | pub const FTD_REGION_H1: &str = "ftd#region.h1";
  constant FTD_REGION_H2 (line 257) | pub const FTD_REGION_H2: &str = "ftd#region.h2";
  constant FTD_REGION_H3 (line 258) | pub const FTD_REGION_H3: &str = "ftd#region.h3";
  constant FTD_REGION_H4 (line 259) | pub const FTD_REGION_H4: &str = "ftd#region.h4";
  constant FTD_REGION_H5 (line 260) | pub const FTD_REGION_H5: &str = "ftd#region.h5";
  constant FTD_REGION_H6 (line 261) | pub const FTD_REGION_H6: &str = "ftd#region.h6";
  constant FTD_DISPLAY (line 263) | pub const FTD_DISPLAY: &str = "ftd#display";
  constant FTD_DISPLAY_BLOCK (line 264) | pub const FTD_DISPLAY_BLOCK: &str = "ftd#display.block";
  constant FTD_DISPLAY_INLINE (line 265) | pub const FTD_DISPLAY_INLINE: &str = "ftd#display.inline";
  constant FTD_DISPLAY_INLINE_BLOCK (line 266) | pub const FTD_DISPLAY_INLINE_BLOCK: &str = "ftd#display.inline-block";
  constant FTD_WHITESPACE (line 268) | pub const FTD_WHITESPACE: &str = "ftd#white-space";
  constant FTD_WHITESPACE_NORMAL (line 269) | pub const FTD_WHITESPACE_NORMAL: &str = "ftd#white-space.normal";
  constant FTD_WHITESPACE_NOWRAP (line 270) | pub const FTD_WHITESPACE_NOWRAP: &str = "ftd#white-space.nowrap";
  constant FTD_WHITESPACE_PRE (line 271) | pub const FTD_WHITESPACE_PRE: &str = "ftd#white-space.pre";
  constant FTD_WHITESPACE_PREWRAP (line 272) | pub const FTD_WHITESPACE_PREWRAP: &str = "ftd#white-space.pre-wrap";
  constant FTD_WHITESPACE_PRELINE (line 273) | pub const FTD_WHITESPACE_PRELINE: &str = "ftd#white-space.pre-line";
  constant FTD_WHITESPACE_BREAKSPACES (line 274) | pub const FTD_WHITESPACE_BREAKSPACES: &str = "ftd#white-space.break-spac...
  constant FTD_TEXT_TRANSFORM (line 276) | pub const FTD_TEXT_TRANSFORM: &str = "ftd#text-transform";
  constant FTD_TEXT_TRANSFORM_NONE (line 277) | pub const FTD_TEXT_TRANSFORM_NONE: &str = "ftd#text-transform.none";
  constant FTD_TEXT_TRANSFORM_CAPITALIZE (line 278) | pub const FTD_TEXT_TRANSFORM_CAPITALIZE: &str = "ftd#text-transform.capi...
  constant FTD_TEXT_TRANSFORM_UPPERCASE (line 279) | pub const FTD_TEXT_TRANSFORM_UPPERCASE: &str = "ftd#text-transform.upper...
  constant FTD_TEXT_TRANSFORM_LOWERCASE (line 280) | pub const FTD_TEXT_TRANSFORM_LOWERCASE: &str = "ftd#text-transform.lower...
  constant FTD_TEXT_TRANSFORM_INITIAL (line 281) | pub const FTD_TEXT_TRANSFORM_INITIAL: &str = "ftd#text-transform.initial";
  constant FTD_TEXT_TRANSFORM_INHERIT (line 282) | pub const FTD_TEXT_TRANSFORM_INHERIT: &str = "ftd#text-transform.inherit";
  constant FTD_LOADING (line 284) | pub const FTD_LOADING: &str = "ftd#loading";
  constant FTD_LOADING_EAGER (line 285) | pub const FTD_LOADING_EAGER: &str = "ftd#loading.eager";
  constant FTD_LOADING_LAZY (line 286) | pub const FTD_LOADING_LAZY: &str = "ftd#loading.lazy";
  constant FTD_SPECIAL_VALUE (line 288) | pub const FTD_SPECIAL_VALUE: &str = "$VALUE";
  constant FTD_SPECIAL_CHECKED (line 289) | pub const FTD_SPECIAL_CHECKED: &str = "$CHECKED";
  constant FTD_INHERITED (line 290) | pub const FTD_INHERITED: &str = "inherited";
  constant FTD_LOOP_COUNTER (line 291) | pub const FTD_LOOP_COUNTER: &str = "LOOP.COUNTER";
  constant FTD_DEFAULT_TYPES (line 292) | pub const FTD_DEFAULT_TYPES: &str = "default-types";
  constant FTD_DEFAULT_COLORS (line 293) | pub const FTD_DEFAULT_COLORS: &str = "default-colors";
  constant FTD_NONE (line 294) | pub const FTD_NONE: &str = "none";
  constant FTD_NO_VALUE (line 295) | pub const FTD_NO_VALUE: &str = "NO-VALUE";
  constant FTD_IGNORE_KEY (line 296) | pub const FTD_IGNORE_KEY: &str = "IGNORE-KEY";
  constant FTD_REMOVE_KEY (line 297) | pub const FTD_REMOVE_KEY: &str = "REMOVE-KEY";
  constant FTD_BORDER_STYLE (line 299) | pub const FTD_BORDER_STYLE: &str = "ftd#border-style";
  constant FTD_BORDER_STYLE_DOTTED (line 300) | pub const FTD_BORDER_STYLE_DOTTED: &str = "ftd#border-style.dotted";
  constant FTD_BORDER_STYLE_DASHED (line 301) | pub const FTD_BORDER_STYLE_DASHED: &str = "ftd#border-style.dashed";
  constant FTD_BORDER_STYLE_SOLID (line 302) | pub const FTD_BORDER_STYLE_SOLID: &str = "ftd#border-style.solid";
  constant FTD_BORDER_STYLE_DOUBLE (line 303) | pub const FTD_BORDER_STYLE_DOUBLE: &str = "ftd#border-style.double";
  constant FTD_BORDER_STYLE_GROOVE (line 304) | pub const FTD_BORDER_STYLE_GROOVE: &str = "ftd#border-style.groove";
  constant FTD_BORDER_STYLE_RIDGE (line 305) | pub const FTD_BORDER_STYLE_RIDGE: &str = "ftd#border-style.ridge";
  constant FTD_BORDER_STYLE_INSET (line 306) | pub const FTD_BORDER_STYLE_INSET: &str = "ftd#border-style.inset";
  constant FTD_BORDER_STYLE_OUTSET (line 307) | pub const FTD_BORDER_STYLE_OUTSET: &str = "ftd#border-style.outset";
  constant FTD_EMPTY_STR (line 309) | pub const FTD_EMPTY_STR: &str = "";
  constant FTD_VALUE_UNCHANGED (line 310) | pub const FTD_VALUE_UNCHANGED: &str = "unchanged";
  constant FTD_TEXT_STYLE (line 311) | pub const FTD_TEXT_STYLE: &str = "ftd#text-style";
  constant FTD_TEXT_STYLE_ITALIC (line 312) | pub const FTD_TEXT_STYLE_ITALIC: &str = "ftd#text-style.italic";
  constant FTD_TEXT_STYLE_UNDERLINE (line 313) | pub const FTD_TEXT_STYLE_UNDERLINE: &str = "ftd#text-style.underline";
  constant FTD_TEXT_STYLE_STRIKE (line 314) | pub const FTD_TEXT_STYLE_STRIKE: &str = "ftd#text-style.strike";
  constant FTD_TEXT_STYLE_WEIGHT_HEAVY (line 315) | pub const FTD_TEXT_STYLE_WEIGHT_HEAVY: &str = "ftd#text-style.heavy";
  constant FTD_TEXT_STYLE_WEIGHT_EXTRA_BOLD (line 316) | pub const FTD_TEXT_STYLE_WEIGHT_EXTRA_BOLD: &str = "ftd#text-style.extra...
  constant FTD_TEXT_STYLE_WEIGHT_BOLD (line 317) | pub const FTD_TEXT_STYLE_WEIGHT_BOLD: &str = "ftd#text-style.bold";
  constant FTD_TEXT_STYLE_WEIGHT_SEMI_BOLD (line 318) | pub const FTD_TEXT_STYLE_WEIGHT_SEMI_BOLD: &str = "ftd#text-style.semi-b...
  constant FTD_TEXT_STYLE_WEIGHT_MEDIUM (line 319) | pub const FTD_TEXT_STYLE_WEIGHT_MEDIUM: &str = "ftd#text-style.medium";
  constant FTD_TEXT_STYLE_WEIGHT_REGULAR (line 320) | pub const FTD_TEXT_STYLE_WEIGHT_REGULAR: &str = "ftd#text-style.regular";
  constant FTD_TEXT_STYLE_WEIGHT_LIGHT (line 321) | pub const FTD_TEXT_STYLE_WEIGHT_LIGHT: &str = "ftd#text-style.light";
  constant FTD_TEXT_STYLE_WEIGHT_EXTRA_LIGHT (line 322) | pub const FTD_TEXT_STYLE_WEIGHT_EXTRA_LIGHT: &str = "ftd#text-style.extr...
  constant FTD_TEXT_STYLE_WEIGHT_HAIRLINE (line 323) | pub const FTD_TEXT_STYLE_WEIGHT_HAIRLINE: &str = "ftd#text-style.hairline";
  constant FTD_LINK_REL (line 325) | pub const FTD_LINK_REL: &str = "ftd#link-rel";
  constant FTD_LINK_REL_NO_FOLLOW (line 326) | pub const FTD_LINK_REL_NO_FOLLOW: &str = "ftd#link-rel.no-follow";
  constant FTD_LINK_REL_SPONSORED (line 327) | pub const FTD_LINK_REL_SPONSORED: &str = "ftd#link-rel.sponsored";
  constant FTD_LINK_REL_UGC (line 328) | pub const FTD_LINK_REL_UGC: &str = "ftd#link-rel.ugc";
  constant FTD_BACKDROP_MULTI (line 330) | pub const FTD_BACKDROP_MULTI: &str = "ftd#backdrop-multi";
  constant FTD_BACKDROP_FILTER (line 331) | pub const FTD_BACKDROP_FILTER: &str = "ftd#backdrop-filter";
  constant FTD_BACKDROP_FILTER_BLUR (line 332) | pub const FTD_BACKDROP_FILTER_BLUR: &str = "ftd#backdrop-filter.blur";
  constant FTD_BACKDROP_FILTER_BRIGHTNESS (line 333) | pub const FTD_BACKDROP_FILTER_BRIGHTNESS: &str = "ftd#backdrop-filter.br...
  constant FTD_BACKDROP_FILTER_CONTRAST (line 334) | pub const FTD_BACKDROP_FILTER_CONTRAST: &str = "ftd#backdrop-filter.cont...
  constant FTD_BACKDROP_FILTER_GRAYSCALE (line 335) | pub const FTD_BACKDROP_FILTER_GRAYSCALE: &str = "ftd#backdrop-filter.gra...
  constant FTD_BACKDROP_FILTER_INVERT (line 336) | pub const FTD_BACKDROP_FILTER_INVERT: &str = "ftd#backdrop-filter.invert";
  constant FTD_BACKDROP_FILTER_OPACITY (line 337) | pub const FTD_BACKDROP_FILTER_OPACITY: &str = "ftd#backdrop-filter.opaci...
  constant FTD_BACKDROP_FILTER_SEPIA (line 338) | pub const FTD_BACKDROP_FILTER_SEPIA: &str = "ftd#backdrop-filter.sepia";
  constant FTD_BACKDROP_FILTER_SATURATE (line 339) | pub const FTD_BACKDROP_FILTER_SATURATE: &str = "ftd#backdrop-filter.satu...
  constant FTD_BACKDROP_FILTER_MULTI (line 340) | pub const FTD_BACKDROP_FILTER_MULTI: &str = "ftd#backdrop-filter.multi";
  constant FTD_MASK_IMAGE_DATA (line 342) | pub const FTD_MASK_IMAGE_DATA: &str = "ftd#mask-image";
  constant FTD_MASK_IMAGE_DATA_SRC (line 343) | pub const FTD_MASK_IMAGE_DATA_SRC: &str = "ftd#mask-image.src";
  constant FTD_MASK_IMAGE_DATA_LINEAR_GRADIENT (line 344) | pub const FTD_MASK_IMAGE_DATA_LINEAR_GRADIENT: &str = "ftd#mask-image.li...
  constant FTD_MASK (line 346) | pub const FTD_MASK: &str = "ftd#mask";
  constant FTD_MASK_IMAGE (line 347) | pub const FTD_MASK_IMAGE: &str = "ftd#mask.image";
  constant FTD_MASK_MULTI (line 348) | pub const FTD_MASK_MULTI: &str = "ftd#mask.multi";
  constant FTD_MASK_MULTI_DATA (line 350) | pub const FTD_MASK_MULTI_DATA: &str = "ftd#mask-multi";
  constant FTD_MASK_SIZE (line 352) | pub const FTD_MASK_SIZE: &str = "ftd#mask-size";
  constant FTD_MASK_SIZE_FIXED (line 353) | pub const FTD_MASK_SIZE_FIXED: &str = "ftd#mask-size.fixed";
  constant FTD_MASK_SIZE_COVER (line 354) | pub const FTD_MASK_SIZE_COVER: &str = "ftd#mask-size.cover";
  constant FTD_MASK_SIZE_CONTAIN (line 355) | pub const FTD_MASK_SIZE_CONTAIN: &str = "ftd#mask-size.contain";
  constant FTD_MASK_SIZE_AUTO (line 356) | pub const FTD_MASK_SIZE_AUTO: &str = "ftd#mask-size.auto";
  constant FTD_MASK_REPEAT (line 358) | pub const FTD_MASK_REPEAT: &str = "ftd#mask-repeat";
  constant FTD_MASK_REPEAT_BOTH_REPEAT (line 359) | pub const FTD_MASK_REPEAT_BOTH_REPEAT: &str = "ftd#mask-repeat.repeat";
  constant FTD_MASK_REPEAT_X_REPEAT (line 360) | pub const FTD_MASK_REPEAT_X_REPEAT: &str = "ftd#mask-repeat.repeat-x";
  constant FTD_MASK_REPEAT_Y_REPEAT (line 361) | pub const FTD_MASK_REPEAT_Y_REPEAT: &str = "ftd#mask-repeat.repeat-y";
  constant FTD_MASK_REPEAT_NO_REPEAT (line 362) | pub const FTD_MASK_REPEAT_NO_REPEAT: &str = "ftd#mask-repeat.no-repeat";
  constant FTD_MASK_REPEAT_SPACE (line 363) | pub const FTD_MASK_REPEAT_SPACE: &str = "ftd#mask-repeat.space";
  constant FTD_MASK_REPEAT_ROUND (line 364) | pub const FTD_MASK_REPEAT_ROUND: &str = "ftd#mask-repeat.round";
  constant FTD_MASK_POSITION (line 366) | pub const FTD_MASK_POSITION: &str = "ftd#mask-position";
  constant FTD_MASK_POSITION_LEFT (line 367) | pub const FTD_MASK_POSITION_LEFT: &str = "ftd#mask-position.left";
  constant FTD_MASK_POSITION_CENTER (line 368) | pub const FTD_MASK_POSITION_CENTER: &str = "ftd#mask-position.center";
  constant FTD_MASK_POSITION_RIGHT (line 369) | pub const FTD_MASK_POSITION_RIGHT: &str = "ftd#mask-position.right";
  constant FTD_MASK_POSITION_LEFT_TOP (line 370) | pub const FTD_MASK_POSITION_LEFT_TOP: &str = "ftd#mask-position.left-top";
  constant FTD_MASK_POSITION_LEFT_CENTER (line 371) | pub const FTD_MASK_POSITION_LEFT_CENTER: &str = "ftd#mask-position.left-...
  constant FTD_MASK_POSITION_LEFT_BOTTOM (line 372) | pub const FTD_MASK_POSITION_LEFT_BOTTOM: &str = "ftd#mask-position.left-...
  constant FTD_MASK_POSITION_CENTER_TOP (line 373) | pub const FTD_MASK_POSITION_CENTER_TOP: &str = "ftd#mask-position.center...
  constant FTD_MASK_POSITION_CENTER_CENTER (line 374) | pub const FTD_MASK_POSITION_CENTER_CENTER: &str = "ftd#mask-position.cen...
  constant FTD_MASK_POSITION_CENTER_BOTTOM (line 375) | pub const FTD_MASK_POSITION_CENTER_BOTTOM: &str = "ftd#mask-position.cen...
  constant FTD_MASK_POSITION_RIGHT_TOP (line 376) | pub const FTD_MASK_POSITION_RIGHT_TOP: &str = "ftd#mask-position.right-t...
  constant FTD_MASK_POSITION_RIGHT_CENTER (line 377) | pub const FTD_MASK_POSITION_RIGHT_CENTER: &str = "ftd#mask-position.righ...
  constant FTD_MASK_POSITION_RIGHT_BOTTOM (line 378) | pub const FTD_MASK_POSITION_RIGHT_BOTTOM: &str = "ftd#mask-position.righ...
  constant FTD_MASK_POSITION_LENGTH (line 379) | pub const FTD_MASK_POSITION_LENGTH: &str = "ftd#mask-position.length";
  constant FASTN_GET_QUERY_PARAMS (line 381) | pub const FASTN_GET_QUERY_PARAMS: &str = "fastn#query";

FILE: fastn-builtins/src/lib.rs
  type Map (line 8) | pub type Map<T> = std::collections::BTreeMap<String, T>;
  function default_aliases (line 16) | pub fn default_aliases() -> Map<String> {
  function default_functions (line 41) | pub fn default_functions() -> Map<fastn_resolved::evalexpr::Function> {
  function default_context (line 141) | pub fn default_context()
  function default_bag (line 157) | pub fn default_bag() -> indexmap::IndexMap<String, fastn_resolved::Defin...
  function default_migration_bag (line 10736) | pub fn default_migration_bag() -> indexmap::IndexMap<String, fastn_resol...
  function fastn_migration_function (line 10744) | pub fn fastn_migration_function() -> fastn_resolved::ComponentDefinition {
  function default_test_bag (line 10769) | pub fn default_test_bag() -> indexmap::IndexMap<String, fastn_resolved::...
  function fastn_get_function (line 10817) | pub fn fastn_get_function() -> fastn_resolved::ComponentDefinition {
  function fastn_post_function (line 10875) | pub fn fastn_post_function() -> fastn_resolved::ComponentDefinition {
  function fastn_redirect_function (line 10931) | pub fn fastn_redirect_function() -> fastn_resolved::ComponentDefinition {
  function fastn_test_function (line 10944) | pub fn fastn_test_function() -> fastn_resolved::ComponentDefinition {
  function builtins (line 10972) | pub fn builtins() -> &'static indexmap::IndexMap<String, fastn_resolved:...
  function image_function (line 10976) | pub fn image_function() -> fastn_resolved::ComponentDefinition {
  function audio_function (line 11019) | pub fn audio_function() -> fastn_resolved::ComponentDefinition {
  function video_function (line 11064) | pub fn video_function() -> fastn_resolved::ComponentDefinition {
  function boolean_function (line 11123) | pub fn boolean_function() -> fastn_resolved::ComponentDefinition {
  function checkbox_function (line 11165) | pub fn checkbox_function() -> fastn_resolved::ComponentDefinition {
  function text_input_function (line 11194) | pub fn text_input_function() -> fastn_resolved::ComponentDefinition {
  function integer_function (line 11261) | pub fn integer_function() -> fastn_resolved::ComponentDefinition {
  function decimal_function (line 11303) | pub fn decimal_function() -> fastn_resolved::ComponentDefinition {
  function markup_function (line 11339) | pub fn markup_function() -> fastn_resolved::ComponentDefinition {
  function row_function (line 11361) | pub fn row_function() -> fastn_resolved::ComponentDefinition {
  function rive_function (line 11378) | pub fn rive_function() -> fastn_resolved::ComponentDefinition {
  function container_function (line 11442) | pub fn container_function() -> fastn_resolved::ComponentDefinition {
  function desktop_function (line 11464) | pub fn desktop_function() -> fastn_resolved::ComponentDefinition {
  function mobile_function (line 11474) | pub fn mobile_function() -> fastn_resolved::ComponentDefinition {
  function code_function (line 11484) | pub fn code_function() -> fastn_resolved::ComponentDefinition {
  function iframe_function (line 11527) | pub fn iframe_function() -> fastn_resolved::ComponentDefinition {
  function column_function (line 11570) | pub fn column_function() -> fastn_resolved::ComponentDefinition {
  function document_function (line 11587) | pub fn document_function() -> fastn_resolved::ComponentDefinition {
  function response_function (line 11750) | pub fn response_function() -> fastn_resolved::ComponentDefinition {
  function container_root_arguments (line 11791) | fn container_root_arguments() -> Vec<fastn_resolved::Argument> {
  function container_arguments (line 11814) | fn container_arguments() -> Vec<fastn_resolved::Argument> {
  function common_arguments (line 11843) | fn common_arguments() -> Vec<fastn_resolved::Argument> {
  function text_arguments (line 12280) | fn text_arguments() -> Vec<fastn_resolved::Argument> {

FILE: fastn-context-macros/src/lib.rs
  function main (line 7) | pub fn main(_args: TokenStream, input: TokenStream) -> TokenStream {

FILE: fastn-context/examples/minimal_test.rs
  function main (line 5) | async fn main() -> Result<(), Box<dyn std::error::Error>> {

FILE: fastn-context/src/context.rs
  type Context (line 2) | pub struct Context {
    method new (line 21) | pub fn new(name: &str) -> std::sync::Arc<Context> {
    method child (line 32) | pub fn child(&self, name: &str) -> ContextBuilder {
    method spawn (line 52) | pub fn spawn<F>(&self, task: F) -> tokio::task::JoinHandle<F::Output>
    method spawn_child (line 61) | pub fn spawn_child<F, Fut>(&self, name: &str, task: F) -> tokio::task:...
    method wait (line 72) | pub async fn wait(&self) {
    method cancelled (line 84) | pub fn cancelled(&self) -> tokio_util::sync::WaitForCancellationFuture...
    method is_cancelled (line 89) | pub fn is_cancelled(&self) -> bool {
    method cancel (line 94) | pub fn cancel(&self) {
    method persist (line 99) | pub fn persist(&self) {
    method status (line 105) | pub fn status(&self) -> crate::status::ContextStatus {
  method clone (line 122) | fn clone(&self) -> Self {
  type ContextBuilder (line 134) | pub struct ContextBuilder {
    method spawn (line 140) | pub fn spawn<F, Fut>(self, task: F) -> tokio::task::JoinHandle<Fut::Ou...
  function global (line 156) | pub fn global() -> std::sync::Arc<Context> {

FILE: fastn-context/src/status.rs
  type Status (line 3) | pub struct Status {
    method fmt (line 70) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    method display_context (line 107) | fn display_context(
  type ContextStatus (line 11) | pub struct ContextStatus {
  constant MAX_PERSISTED_CONTEXTS (line 24) | const MAX_PERSISTED_CONTEXTS: usize = 10;
  function add_persisted_context (line 27) | pub fn add_persisted_context(context_status: ContextStatus) {
  function status (line 46) | pub fn status() -> Status {
  function status_with_latest (line 55) | pub fn status_with_latest() -> Status {

FILE: fastn-core/fastn.js
  function p (line 113) | function p(e) {
  function h (line 117) | function h(t) {
  function v (line 121) | function v(t) {

FILE: fastn-core/fastn2022.js
  function p (line 73) | function p(e) {
  function h (line 77) | function h(t) {
  function v (line 81) | function v(t) {

FILE: fastn-core/fbt-tests/02-hello/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
  function handle_function (line 19) | function handle_function(evt, id, action, obj, function_arguments) {
  function handle_event (line 57) | function handle_event(evt, id, action, obj) {
  function initialise_device (line 477) | function initialise_device() {
  function get_device (line 554) | function get_device() {
  function set_cookie (line 665) | function set_cookie(name, value) {
  function system_dark_mode (line 668) | function system_dark_mode() {
  function initialise_dark_mode (line 671) | function initialise_dark_mode() {
  function get_cookie (line 675) | function get_cookie(name, def) {
  function update_dark_mode (line 680) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 698) | function start_watching_dark_mode_system_preference() {
  constant DEVICE_SUFFIX (line 706) | const DEVICE_SUFFIX = "____device";
  function console_log (line 707) | function console_log(...message) {
  function isObject (line 712) | function isObject(obj) {
  function stringToHTML (line 715) | function stringToHTML(str) {
  function get_name_and_remaining (line 721) | function get_name_and_remaining(name) {
  function split_once (line 735) | function split_once(name, split_at) {
  function deepCopy (line 742) | function deepCopy(object) {
  function change_value (line 748) | function change_value(function_arguments, data, id) {
  function isFunctionArgument (line 772) | function isFunctionArgument(object) {
  function set_data_value (line 803) | function set_data_value(data, name, value) {
  function resolve_reference (line 821) | function resolve_reference(reference, data, value, checked) {
  function get_data_value (line 840) | function get_data_value(data, name) {
  function JSONstringify (line 843) | function JSONstringify(f) {
  function download_text (line 851) | function download_text(filename, text) {
  function len (line 858) | function len(data) {
  function fallbackCopyTextToClipboard (line 861) | function fallbackCopyTextToClipboard(text) {
  function changeElementId (line 1066) | function changeElementId(element, suffix, add) {
  function updatedID (line 1083) | function updatedID(str, flag, suffix) {

FILE: fastn-core/fbt-tests/03-nested-document/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
  function handle_function (line 19) | function handle_function(evt, id, action, obj, function_arguments) {
  function handle_event (line 57) | function handle_event(evt, id, action, obj) {
  function initialise_device (line 477) | function initialise_device() {
  function get_device (line 554) | function get_device() {
  function set_cookie (line 665) | function set_cookie(name, value) {
  function system_dark_mode (line 668) | function system_dark_mode() {
  function initialise_dark_mode (line 671) | function initialise_dark_mode() {
  function get_cookie (line 675) | function get_cookie(name, def) {
  function update_dark_mode (line 680) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 698) | function start_watching_dark_mode_system_preference() {
  constant DEVICE_SUFFIX (line 706) | const DEVICE_SUFFIX = "____device";
  function console_log (line 707) | function console_log(...message) {
  function isObject (line 712) | function isObject(obj) {
  function stringToHTML (line 715) | function stringToHTML(str) {
  function get_name_and_remaining (line 721) | function get_name_and_remaining(name) {
  function split_once (line 735) | function split_once(name, split_at) {
  function deepCopy (line 742) | function deepCopy(object) {
  function change_value (line 748) | function change_value(function_arguments, data, id) {
  function isFunctionArgument (line 772) | function isFunctionArgument(object) {
  function set_data_value (line 803) | function set_data_value(data, name, value) {
  function resolve_reference (line 821) | function resolve_reference(reference, data, value, checked) {
  function get_data_value (line 840) | function get_data_value(data, name) {
  function JSONstringify (line 843) | function JSONstringify(f) {
  function download_text (line 851) | function download_text(filename, text) {
  function len (line 858) | function len(data) {
  function fallbackCopyTextToClipboard (line 861) | function fallbackCopyTextToClipboard(text) {
  function changeElementId (line 1066) | function changeElementId(element, suffix, add) {
  function updatedID (line 1083) | function updatedID(str, flag, suffix) {

FILE: fastn-core/fbt-tests/04-import-code-block/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
  function handle_function (line 19) | function handle_function(evt, id, action, obj, function_arguments) {
  function handle_event (line 57) | function handle_event(evt, id, action, obj) {
  function initialise_device (line 477) | function initialise_device() {
  function get_device (line 554) | function get_device() {
  function set_cookie (line 665) | function set_cookie(name, value) {
  function system_dark_mode (line 668) | function system_dark_mode() {
  function initialise_dark_mode (line 671) | function initialise_dark_mode() {
  function get_cookie (line 675) | function get_cookie(name, def) {
  function update_dark_mode (line 680) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 698) | function start_watching_dark_mode_system_preference() {
  constant DEVICE_SUFFIX (line 706) | const DEVICE_SUFFIX = "____device";
  function console_log (line 707) | function console_log(...message) {
  function isObject (line 712) | function isObject(obj) {
  function stringToHTML (line 715) | function stringToHTML(str) {
  function get_name_and_remaining (line 721) | function get_name_and_remaining(name) {
  function split_once (line 735) | function split_once(name, split_at) {
  function deepCopy (line 742) | function deepCopy(object) {
  function change_value (line 748) | function change_value(function_arguments, data, id) {
  function isFunctionArgument (line 772) | function isFunctionArgument(object) {
  function set_data_value (line 803) | function set_data_value(data, name, value) {
  function resolve_reference (line 821) | function resolve_reference(reference, data, value, checked) {
  function get_data_value (line 840) | function get_data_value(data, name) {
  function JSONstringify (line 843) | function JSONstringify(f) {
  function download_text (line 851) | function download_text(filename, text) {
  function len (line 858) | function len(data) {
  function fallbackCopyTextToClipboard (line 861) | function fallbackCopyTextToClipboard(text) {
  function changeElementId (line 1066) | function changeElementId(element, suffix, add) {
  function updatedID (line 1083) | function updatedID(str, flag, suffix) {

FILE: fastn-core/fbt-tests/05-hello-font/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
  function handle_function (line 19) | function handle_function(evt, id, action, obj, function_arguments) {
  function handle_event (line 57) | function handle_event(evt, id, action, obj) {
  function initialise_device (line 477) | function initialise_device() {
  function get_device (line 554) | function get_device() {
  function set_cookie (line 665) | function set_cookie(name, value) {
  function system_dark_mode (line 668) | function system_dark_mode() {
  function initialise_dark_mode (line 671) | function initialise_dark_mode() {
  function get_cookie (line 675) | function get_cookie(name, def) {
  function update_dark_mode (line 680) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 698) | function start_watching_dark_mode_system_preference() {
  constant DEVICE_SUFFIX (line 706) | const DEVICE_SUFFIX = "____device";
  function console_log (line 707) | function console_log(...message) {
  function isObject (line 712) | function isObject(obj) {
  function stringToHTML (line 715) | function stringToHTML(str) {
  function get_name_and_remaining (line 721) | function get_name_and_remaining(name) {
  function split_once (line 735) | function split_once(name, split_at) {
  function deepCopy (line 742) | function deepCopy(object) {
  function change_value (line 748) | function change_value(function_arguments, data, id) {
  function isFunctionArgument (line 772) | function isFunctionArgument(object) {
  function set_data_value (line 803) | function set_data_value(data, name, value) {
  function resolve_reference (line 821) | function resolve_reference(reference, data, value, checked) {
  function get_data_value (line 840) | function get_data_value(data, name) {
  function JSONstringify (line 843) | function JSONstringify(f) {
  function download_text (line 851) | function download_text(filename, text) {
  function len (line 858) | function len(data) {
  function fallbackCopyTextToClipboard (line 861) | function fallbackCopyTextToClipboard(text) {
  function changeElementId (line 1066) | function changeElementId(element, suffix, add) {
  function updatedID (line 1083) | function updatedID(str, flag, suffix) {

FILE: fastn-core/fbt-tests/08-static-assets/output/default-73755E118EA14B5B124FF4106E51628B7152E1302B3ED37177480A59413FF762.js
  function t (line 111) | function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null...
  function n (line 111) | function n(t){e.defaults=t}
  function c (line 111) | function c(e,t){if(t){if(s.test(e))return e.replace(r,a)}else if(i.test(...
  function u (line 111) | function u(e,t){e="string"==typeof e?e:e.source,t=t||"";const n={replace...
  function g (line 111) | function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return nul...
  function f (line 111) | function f(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,r=t;for(;--r...
  function d (line 111) | function d(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){...
  function x (line 111) | function x(e,t,n,s){const r=t.href,i=t.title?c(t.title):null,l=e[1].repl...
  class b (line 111) | class b{options;rules;lexer;constructor(t){this.options=t||e.defaults}sp...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method space (line 111) | space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)...
    method code (line 111) | code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].repla...
    method fences (line 111) | fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n...
    method heading (line 111) | heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].t...
    method hr (line 111) | hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[...
    method blockquote (line 111) | blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const ...
    method list (line 111) | list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();co...
    method html (line 111) | html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html"...
    method def (line 111) | def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLower...
    method table (line 111) | table(e){const t=this.rules.block.table.exec(e);if(t){if(!/[:|]/.test(...
    method lheading (line 111) | lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type...
    method paragraph (line 111) | paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e=...
    method text (line 111) | text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",...
    method escape (line 111) | escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"e...
    method tag (line 111) | tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.st...
    method link (line 111) | link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim...
    method reflink (line 111) | reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.r...
    method emStrong (line 111) | emStrong(e,t,n=""){let s=this.rules.inline.emStrong.lDelim.exec(e);if(...
    method codespan (line 111) | codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].re...
    method br (line 111) | br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t...
    method del (line 111) | del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",ra...
    method autolink (line 111) | autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;r...
    method url (line 111) | url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2]...
    method inlineText (line 111) | inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;retur...
  class _ (line 111) | class _{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.t...
    method constructor (line 111) | constructor(t){this.tokens=[],this.tokens.links=Object.create(null),th...
    method rules (line 111) | static get rules(){return{block:m,inline:w}}
    method lex (line 111) | static lex(e,t){return new _(t).lex(e)}
    method lexInline (line 111) | static lexInline(e,t){return new _(t).inlineTokens(e)}
    method lex (line 111) | lex(e){let t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this....
    method blockTokens (line 111) | blockTokens(e,t=[]){let n,s,r,i;for(e=this.options.pedantic?e.replace(...
    method inline (line 111) | inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}
    method inlineTokens (line 111) | inlineTokens(e,t=[]){let n,s,r,i,l,o,a=e;if(this.tokens.links){const e...
  class y (line 111) | class y{options;constructor(t){this.options=t||e.defaults}code(e,t,n){co...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method code (line 111) | code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$...
    method blockquote (line 111) | blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}
    method html (line 111) | html(e,t){return e}
    method heading (line 111) | heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}
    method hr (line 111) | hr(){return"<hr>\n"}
    method list (line 111) | list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"'...
    method listitem (line 111) | listitem(e,t,n){return`<li>${e}</li>\n`}
    method checkbox (line 111) | checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="ch...
    method paragraph (line 111) | paragraph(e){return`<p>${e}</p>\n`}
    method table (line 111) | table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+...
    method tablerow (line 111) | tablerow(e){return`<tr>\n${e}</tr>\n`}
    method tablecell (line 111) | tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align=...
    method strong (line 111) | strong(e){return`<strong>${e}</strong>`}
    method em (line 111) | em(e){return`<em>${e}</em>`}
    method codespan (line 111) | codespan(e){return`<code>${e}</code>`}
    method br (line 111) | br(){return"<br>"}
    method del (line 111) | del(e){return`<del>${e}</del>`}
    method link (line 111) | link(e,t,n){const s=g(e);if(null===s)return n;let r='<a href="'+(e=s)+...
    method image (line 111) | image(e,t,n){const s=g(e);if(null===s)return n;let r=`<img src="${e=s}...
    method text (line 111) | text(e){return e}
  class $ (line 111) | class ${strong(e){return e}em(e){return e}codespan(e){return e}del(e){re...
    method strong (line 111) | strong(e){return e}
    method em (line 111) | em(e){return e}
    method codespan (line 111) | codespan(e){return e}
    method del (line 111) | del(e){return e}
    method html (line 111) | html(e){return e}
    method text (line 111) | text(e){return e}
    method link (line 111) | link(e,t,n){return""+n}
    method image (line 111) | image(e,t,n){return""+n}
    method br (line 111) | br(){return""}
  class z (line 111) | class z{options;renderer;textRenderer;constructor(t){this.options=t||e.d...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults,this.options.renderer=this.o...
    method parse (line 111) | static parse(e,t){return new z(t).parse(e)}
    method parseInline (line 111) | static parseInline(e,t){return new z(t).parseInline(e)}
    method parse (line 111) | parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(thi...
    method parseInline (line 111) | parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s+...
  class T (line 111) | class T{options;constructor(t){this.options=t||e.defaults}static passThr...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method preprocess (line 111) | preprocess(e){return e}
    method postprocess (line 111) | postprocess(e){return e}
  class R (line 111) | class R{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,p...
    method constructor (line 111) | constructor(...e){this.use(...e)}
    method walkTokens (line 111) | walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(thi...
    method use (line 111) | use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:...
    method setOptions (line 111) | setOptions(e){return this.defaults={...this.defaults,...e},this}
    method #e (line 111) | #e(e,t){return(n,s)=>{const r={...s},i={...this.defaults,...r};!0===th...
    method #t (line 111) | #t(e,t){return n=>{if(n.message+="\nPlease report this to https://gith...
  function A (line 111) | function A(e,t){return S.parse(e,t)}
  class Closure (line 113) | class Closure {
    method constructor (line 120) | constructor(func, execute = true) {
    method get (line 127) | get() {
    method getFormula (line 131) | getFormula() {
    method addNodeProperty (line 135) | addNodeProperty(node, property, inherited) {
    method update (line 144) | update() {
    method getNode (line 149) | getNode() {
    method updateUi (line 153) | updateUi() {
  class Mutable (line 171) | class Mutable {
    method constructor (line 177) | constructor(val) {
    method closures (line 187) | closures() {
    method get (line 191) | get(key) {
    method forLoop (line 203) | forLoop(root, dom_constructor) {
    method setWithoutUpdate (line 212) | setWithoutUpdate(value) {
    method set (line 244) | set(value) {
    method unlinkNode (line 251) | unlinkNode(node) {
    method addClosure (line 257) | addClosure(closure) {
    method removeClosure (line 261) | removeClosure(closure) {
    method equalMutable (line 265) | equalMutable(other) {
    method getClone (line 275) | getClone() {
  class Proxy (line 280) | class Proxy {
    method constructor (line 286) | constructor(targets, differentiator) {
    method addClosure (line 303) | addClosure(closure) {
    method removeClosure (line 307) | removeClosure(closure) {
    method update (line 311) | update() {
    method get (line 315) | get(key) {
    method set (line 327) | set(value) {
  class MutableList (line 336) | class MutableList {
    method constructor (line 341) | constructor(list) {
    method addClosure (line 353) | addClosure(closure) {
    method unlinkNode (line 357) | unlinkNode(node) {
    method forLoop (line 363) | forLoop(root, dom_constructor) {
    method getList (line 369) | getList() {
    method contains (line 373) | contains(item) {
    method getLength (line 381) | getLength() {
    method get (line 385) | get(idx) {
    method set (line 392) | set(index, value) {
    method deleteEmptyWatchers (line 445) | deleteEmptyWatchers() {
    method insertAt (line 464) | insertAt(index, value) {
    method push (line 483) | push(value) {
    method deleteAt (line 487) | deleteAt(index) {
    method clearAll (line 503) | clearAll() {
    method pop (line 513) | pop() {
    method getClone (line 517) | getClone() {
  class RecordInstance (line 576) | class RecordInstance {
    method constructor (line 580) | constructor(obj) {
    method getAllFields (line 594) | getAllFields() {
    method getClonedFields (line 598) | getClonedFields() {
    method addClosure (line 615) | addClosure(closure) {
    method unlinkNode (line 619) | unlinkNode(node) {
    method get (line 625) | get(key) {
    method set (line 629) | set(key, value) {
    method setAndReturn (line 649) | setAndReturn(key, value) {
    method replace (line 654) | replace(obj) {
    method toObject (line 668) | toObject() {
    method getClone (line 677) | getClone() {
  class Module (line 691) | class Module {
    method constructor (line 695) | constructor(name, global) {
    method getName (line 700) | getName() {
    method get (line 704) | get(function_name) {
  function getClassAsString (line 866) | function getClassAsString(className, obj) {
  class PropertyValueAsClosure (line 1546) | class PropertyValueAsClosure {
    method constructor (line 1549) | constructor(closureFunction, deps) {
  class Node2 (line 1557) | class Node2 {
    method constructor (line 1575) | constructor(parentOrSibiling, kind) {
    method createNode (line 1616) | createNode(kind) {
    method getTagName (line 1638) | getTagName() {
    method getParent (line 1641) | getParent() {
    method removeAllFaviconLinks (line 1644) | removeAllFaviconLinks() {
    method setFavicon (line 1654) | setFavicon(url) {
    method updateTextInputValue (line 1670) | updateTextInputValue() {
    method attachAttribute (line 1682) | attachAttribute(property, value) {
    method removeAttribute (line 1691) | removeAttribute(property) {
    method updateTagName (line 1694) | updateTagName(name) {
    method updateToAnchor (line 1714) | updateToAnchor(url) {
    method updatePositionForNodeById (line 1734) | updatePositionForNodeById(node_id, value) {
    method updateParentPosition (line 1743) | updateParentPosition(value) {
    method updateMetaTitle (line 1756) | updateMetaTitle(value) {
    method addMetaTagByName (line 1764) | addMetaTagByName(name, value) {
    method addMetaTagByProperty (line 1778) | addMetaTagByProperty(property, value) {
    method removeMetaTagByName (line 1792) | removeMetaTagByName(name) {
    method removeMetaTagByProperty (line 1806) | removeMetaTagByProperty(property) {
    method attachCss (line 1821) | attachCss(property, value, createClass, className) {
    method attachShadow (line 1898) | attachShadow(value) {
    method attachBackdropMultiFilter (line 1933) | attachBackdropMultiFilter(value) {
    method attachTextShadow (line 1952) | attachTextShadow(value) {
    method getLinearGradientString (line 1983) | getLinearGradientString(value) {
    method attachLinearGradientCss (line 2028) | attachLinearGradientCss(value) {
    method attachBackgroundImageCss (line 2076) | attachBackgroundImageCss(value) {
    method attachMaskImageCss (line 2137) | attachMaskImageCss(value, vendorPrefix) {
    method attachMaskSizeCss (line 2225) | attachMaskSizeCss(value, vendorPrefix) {
    method attachMaskMultiCss (line 2243) | attachMaskMultiCss(value, vendorPrefix) {
    method attachExternalCss (line 2276) | attachExternalCss(css) {
    method attachExternalJs (line 2291) | attachExternalJs(js) {
    method attachColorCss (line 2304) | attachColorCss(property, value, visited) {
    method attachRoleCss (line 2356) | attachRoleCss(value) {
    method attachTextStyles (line 2395) | attachTextStyles(styles) {
    method attachAlignContent (line 2416) | attachAlignContent(value, node_kind) {
    method attachImageSrcClosures (line 2505) | attachImageSrcClosures(staticValue) {
    method attachLinkColor (line 2590) | attachLinkColor(value) {
    method setStaticProperty (line 2671) | setStaticProperty(kind, value, inherited) {
    method setProperty (line 3468) | setProperty(kind, value, inherited) {
    method setDynamicProperty (line 3489) | setDynamicProperty(kind, deps, func, inherited) {
    method getNode (line 3501) | getNode() {
    method getExtraData (line 3504) | getExtraData() {
    method getChildren (line 3507) | getChildren() {
    method mergeFnCalls (line 3510) | mergeFnCalls(current, newFunc) {
    method addEventHandler (line 3516) | addEventHandler(event, func) {
    method destroy (line 3557) | destroy() {
    method #addToGlobalMeta (line 3580) | #addToGlobalMeta(key, value, kind) {
    method #removeFromGlobalMeta (line 3584) | #removeFromGlobalMeta(key) {
  class ConditionalDom (line 3591) | class ConditionalDom {
    method constructor (line 3599) | constructor(parent, deps, condition, node_constructor) {
    method getParent (line 3649) | getParent() {
  class ParentNodeWithSibiling (line 3671) | class ParentNodeWithSibiling {
    method constructor (line 3674) | constructor(parent, sibiling) {
    method getParent (line 3678) | getParent() {
    method getSibiling (line 3681) | getSibiling() {
  class ForLoop (line 3686) | class ForLoop {
    method constructor (line 3692) | constructor(parent, node_constructor, list) {
    method createNode (line 3708) | createNode(index, resizeBodyHeight = true) {
    method createAllNode (line 3730) | createAllNode() {
    method deleteAllNode (line 3738) | deleteAllNode(resizeBodyHeight = true) {
    method getWrapper (line 3749) | getWrapper() {
    method deleteNode (line 3752) | deleteNode(index) {
    method getParent (line 3758) | getParent() {
  method htmlNode (line 3767) | htmlNode(kind) {
  method createStyle (line 3818) | createStyle(cssClass, obj) {
  method getStaticValue (line 3834) | getStaticValue(obj) {
  method getInheritedValues (line 3847) | getInheritedValues(default_args, inherited, function_args) {
  method removeNonFastnClasses (line 3869) | removeNonFastnClasses(node) {
  method staticToMutables (line 3894) | staticToMutables(obj) {
  method mutableToStaticValue (line 3922) | mutableToStaticValue(obj) {
  method flattenMutable (line 3940) | flattenMutable(value) {
  method getFlattenStaticValue (line 3948) | getFlattenStaticValue(obj) {
  method getter (line 3965) | getter(value) {
  method getterByKey (line 3973) | getterByKey(value, index) {
  method setter (line 3985) | setter(variable, value) {
  method defaultPropertyValue (line 3993) | defaultPropertyValue(_propertyValue) {
  method sameResponsiveRole (line 3996) | sameResponsiveRole(desktop, mobile) {
  method getRoleValues (line 4005) | getRoleValues(value) {
  method clone (line 4023) | clone(value) {
  method getListItem (line 4038) | getListItem(value) {
  method getEventKey (line 4047) | getEventKey(event) {
  method createNestedObject (line 4054) | createNestedObject(currentObject, path, value) {
  method markdown_inline (line 4090) | markdown_inline(i) {
  method process_post_markdown (line 4111) | process_post_markdown(node, body) {
  method isNull (line 4150) | isNull(a) {
  method isCommentNode (line 4153) | isCommentNode(node) {
  method isWrapperNode (line 4156) | isWrapperNode(node) {
  method nextSibling (line 4159) | nextSibling(node, parent) {
  method createNodeHelper (line 4172) | createNodeHelper(node, classes, attributes) {
  method addCssFile (line 4184) | addCssFile(url) {
  method addCodeTheme (line 4195) | addCodeTheme(theme) {
  method findAndRemoveHighlighter (line 4224) | findAndRemoveHighlighter(text) {
  method getNodeValue (line 4253) | getNodeValue(node) {
  method getNodeCheckedState (line 4256) | getNodeCheckedState(node) {
  method setFullHeight (line 4259) | setFullHeight() {
  method resetFullHeight (line 4264) | resetFullHeight() {
  method highlightCode (line 4269) | highlightCode(codeElement, extraCodeData) {
  method slugify (line 4280) | slugify(str) {
  method getEventListeners (line 4292) | getEventListeners(node) {
  method flattenArray (line 4303) | flattenArray(arr) {
  method toSnakeCase (line 4306) | toSnakeCase(value) {
  method escapeHtmlInCode (line 4322) | escapeHtmlInCode(str) {
  method escapeHtmlInMarkdown (line 4326) | escapeHtmlInMarkdown(str) {
  method getArgs (line 4366) | getArgs(default_args, passed_args) {
  method replaceBodyStyleAndChildren (line 4392) | replaceBodyStyleAndChildren(newChildrenWrapper) {
  method flattenArray (line 4404) | flattenArray(arr) {
  method spaces (line 4421) | spaces(s) {
  method replace_last_occurrence (line 4454) | replace_last_occurrence(s, old_word, new_word) {
  method repeated_space (line 4469) | repeated_space(n) {
  method mergeNumbers (line 4483) | mergeNumbers(numbers) {
  method addUnderscoreToStart (line 4513) | addUnderscoreToStart(text) {
  method replaceChildren (line 4530) | replaceChildren(parent, newChildrenWrapper) {
  method setCookie (line 4548) | setCookie(cookieName, cookieValue) {
  method getCookie (line 4568) | getCookie(cookieName) {
  class ClassList (line 4594) | class ClassList {
    method add (line 4596) | add(item) {
    method remove (line 4600) | remove(itemToRemove) {
    method toString (line 4603) | toString() {
    method getClasses (line 4606) | getClasses() {
  class Node (line 4611) | class Node {
    method constructor (line 4617) | constructor(id, tagName) {
    method appendChild (line 4628) | appendChild(c) {
    method insertBefore (line 4632) | insertBefore(node, index) {
    method getChildren (line 4636) | getChildren() {
    method setAttribute (line 4640) | setAttribute(attribute, value) {
    method getAttribute (line 4644) | getAttribute(attribute) {
    method removeAttribute (line 4648) | removeAttribute(attribute) {
    method updateTagName (line 4653) | updateTagName(tagName) {
    method toHtmlAsString (line 4657) | toHtmlAsString() {
    method getDataIdString (line 4670) | getDataIdString() {
    method getIdString (line 4674) | getIdString() {
    method getClassString (line 4678) | getClassString() {
    method getStyleString (line 4683) | getStyleString() {
    method getAttributesString (line 4690) | getAttributesString() {
  class Document2 (line 4703) | class Document2 {
    method createElement (line 4704) | createElement(tagName) {
  function addClosureToBreakpointWidth (line 4727) | function addClosureToBreakpointWidth() {
  class MutableVariable (line 4780) | class MutableVariable {
    method constructor (line 4782) | constructor(value) {
    method get (line 4786) | get() {
    method set (line 4790) | set(value) {
    method on_change (line 4794) | on_change(func) {
  class MutableListVariable (line 4799) | class MutableListVariable {
    method constructor (line 4801) | constructor(value) {
    method get (line 4804) | get() {
    method set (line 4807) | set(index, list) {
    method insertAt (line 4814) | insertAt(index, value) {
    method deleteAt (line 4817) | deleteAt(index) {
    method push (line 4820) | push(value) {
    method pop (line 4823) | pop() {
    method clearAll (line 4826) | clearAll() {
    method on_change (line 4829) | on_change(func) {
  class RecordVariable (line 4834) | class RecordVariable {
    method constructor (line 4836) | constructor(value) {
    method get (line 4840) | get() {
    method set (line 4844) | set(record) {
    method on_change (line 4848) | on_change(func) {
  class StaticVariable (line 4852) | class StaticVariable {
    method constructor (line 4855) | constructor(value) {
    method get (line 4867) | get() {
    method on_change (line 4871) | on_change(func) {
  method _get_key (line 5244) | _get_key(key) {
  method set (line 5255) | set(key, value) {
  method get (line 5265) | get(key) {
  method delete (line 5282) | delete(key) {
  function legacyNameToJS (line 5310) | function legacyNameToJS(s) {
  function getDocNameAndRemaining (line 5328) | function getDocNameAndRemaining(s) {
  function isMutable (line 5346) | function isMutable(obj) {
  function initialise_click_outside_events (line 5636) | function initialise_click_outside_events() {
  function initialise_global_key_events (line 5650) | function initialise_global_key_events() {
  function initialise_device (line 5708) | function initialise_device() {
  function set_cookie (line 5791) | function set_cookie(name, value) {
  function system_dark_mode (line 5794) | function system_dark_mode() {
  function initialise_dark_mode (line 5800) | function initialise_dark_mode() {
  function get_cookie (line 5804) | function get_cookie(name, def) {
  function update_dark_mode (line 5811) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 5832) | function start_watching_dark_mode_system_preference() {

FILE: fastn-core/fbt-tests/08-static-assets/output/markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
  function t (line 7) | function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null...
  function n (line 7) | function n(t){e.defaults=t}
  function c (line 7) | function c(e,t){if(t){if(s.test(e))return e.replace(r,a)}else if(i.test(...
  function u (line 7) | function u(e,t){e="string"==typeof e?e:e.source,t=t||"";const n={replace...
  function g (line 7) | function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return nul...
  function f (line 7) | function f(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,r=t;for(;--r...
  function d (line 7) | function d(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){...
  function x (line 7) | function x(e,t,n,s){const r=t.href,i=t.title?c(t.title):null,l=e[1].repl...
  class b (line 7) | class b{options;rules;lexer;constructor(t){this.options=t||e.defaults}sp...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method space (line 7) | space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)...
    method code (line 7) | code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].repla...
    method fences (line 7) | fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n...
    method heading (line 7) | heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].t...
    method hr (line 7) | hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[...
    method blockquote (line 7) | blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const ...
    method list (line 7) | list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();co...
    method html (line 7) | html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html"...
    method def (line 7) | def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLower...
    method table (line 7) | table(e){const t=this.rules.block.table.exec(e);if(t){if(!/[:|]/.test(...
    method lheading (line 7) | lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type...
    method paragraph (line 7) | paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e=...
    method text (line 7) | text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",...
    method escape (line 7) | escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"e...
    method tag (line 7) | tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.st...
    method link (line 7) | link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim...
    method reflink (line 7) | reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.r...
    method emStrong (line 7) | emStrong(e,t,n=""){let s=this.rules.inline.emStrong.lDelim.exec(e);if(...
    method codespan (line 7) | codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].re...
    method br (line 7) | br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t...
    method del (line 7) | del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",ra...
    method autolink (line 7) | autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;r...
    method url (line 7) | url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2]...
    method inlineText (line 7) | inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;retur...
  class _ (line 7) | class _{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.t...
    method constructor (line 7) | constructor(t){this.tokens=[],this.tokens.links=Object.create(null),th...
    method rules (line 7) | static get rules(){return{block:m,inline:w}}
    method lex (line 7) | static lex(e,t){return new _(t).lex(e)}
    method lexInline (line 7) | static lexInline(e,t){return new _(t).inlineTokens(e)}
    method lex (line 7) | lex(e){let t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this....
    method blockTokens (line 7) | blockTokens(e,t=[]){let n,s,r,i;for(e=this.options.pedantic?e.replace(...
    method inline (line 7) | inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}
    method inlineTokens (line 7) | inlineTokens(e,t=[]){let n,s,r,i,l,o,a=e;if(this.tokens.links){const e...
  class y (line 7) | class y{options;constructor(t){this.options=t||e.defaults}code(e,t,n){co...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method code (line 7) | code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$...
    method blockquote (line 7) | blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}
    method html (line 7) | html(e,t){return e}
    method heading (line 7) | heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}
    method hr (line 7) | hr(){return"<hr>\n"}
    method list (line 7) | list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"'...
    method listitem (line 7) | listitem(e,t,n){return`<li>${e}</li>\n`}
    method checkbox (line 7) | checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="ch...
    method paragraph (line 7) | paragraph(e){return`<p>${e}</p>\n`}
    method table (line 7) | table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+...
    method tablerow (line 7) | tablerow(e){return`<tr>\n${e}</tr>\n`}
    method tablecell (line 7) | tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align=...
    method strong (line 7) | strong(e){return`<strong>${e}</strong>`}
    method em (line 7) | em(e){return`<em>${e}</em>`}
    method codespan (line 7) | codespan(e){return`<code>${e}</code>`}
    method br (line 7) | br(){return"<br>"}
    method del (line 7) | del(e){return`<del>${e}</del>`}
    method link (line 7) | link(e,t,n){const s=g(e);if(null===s)return n;let r='<a href="'+(e=s)+...
    method image (line 7) | image(e,t,n){const s=g(e);if(null===s)return n;let r=`<img src="${e=s}...
    method text (line 7) | text(e){return e}
  class $ (line 7) | class ${strong(e){return e}em(e){return e}codespan(e){return e}del(e){re...
    method strong (line 7) | strong(e){return e}
    method em (line 7) | em(e){return e}
    method codespan (line 7) | codespan(e){return e}
    method del (line 7) | del(e){return e}
    method html (line 7) | html(e){return e}
    method text (line 7) | text(e){return e}
    method link (line 7) | link(e,t,n){return""+n}
    method image (line 7) | image(e,t,n){return""+n}
    method br (line 7) | br(){return""}
  class z (line 7) | class z{options;renderer;textRenderer;constructor(t){this.options=t||e.d...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults,this.options.renderer=this.o...
    method parse (line 7) | static parse(e,t){return new z(t).parse(e)}
    method parseInline (line 7) | static parseInline(e,t){return new z(t).parseInline(e)}
    method parse (line 7) | parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(thi...
    method parseInline (line 7) | parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s+...
  class T (line 7) | class T{options;constructor(t){this.options=t||e.defaults}static passThr...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method preprocess (line 7) | preprocess(e){return e}
    method postprocess (line 7) | postprocess(e){return e}
  class R (line 7) | class R{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,p...
    method constructor (line 7) | constructor(...e){this.use(...e)}
    method walkTokens (line 7) | walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(thi...
    method use (line 7) | use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:...
    method setOptions (line 7) | setOptions(e){return this.defaults={...this.defaults,...e},this}
    method #e (line 7) | #e(e,t){return(n,s)=>{const r={...s},i={...this.defaults,...r};!0===th...
    method #t (line 7) | #t(e,t){return n=>{if(n.message+="\nPlease report this to https://gith...
  function A (line 7) | function A(e,t){return S.parse(e,t)}

FILE: fastn-core/fbt-tests/08-static-assets/output/prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
  function l (line 7) | function l(e){i.highlightedCode=e,j.hooks.run("before-insert",i),i.eleme...
  function C (line 7) | function C(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=...
  function O (line 7) | function O(e,t,n,a){e.lastIndex=t;n=e.exec(n);return n&&a&&n[1]&&(a=n[1]...
  function s (line 7) | function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e...
  function z (line 7) | function z(e,t,n){var a=t.next,n={value:n,prev:t,next:a};return t.next=n...
  function T (line 7) | function T(e,t,n){for(var a=t.next,r=0;r<n&&a!==e.tail;r++)a=a.next;(t.n...
  function a (line 7) | function a(){j.manual||j.highlightAll()}
  function c (line 7) | function c(e,t){var n=(n=e.className).replace(a," ")+" language-"+t;e.cl...
  function r (line 17) | function r(e){return+e.substr(0,e.length-2)}
  function s (line 17) | function s(e,t){return Array.prototype.slice.call((t||document).querySel...
  function l (line 17) | function l(e,t){return e.classList.contains(t)}
  function a (line 17) | function a(e){e()}
  function u (line 17) | function u(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data...
  function c (line 17) | function c(){var e=location.hash.slice(1);s(".temporary.line-highlight")...
  function r (line 28) | function r(e){if(0!=(e=e.filter((function(e){var n,t=(n=e,n?window.getCo...
  function e (line 60) | function e(n){return n=n.replace(/<inner>/g,(function(){return"(?:\\\\.|...

FILE: fastn-core/fbt-tests/09-markdown-pages/output/default-19D2867920A9DCA55CE23FEDCE770D4077F08B32526E28D226376463C3C1C583.js
  function t (line 111) | function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null...
  function n (line 111) | function n(t){e.defaults=t}
  function c (line 111) | function c(e,t){if(t){if(s.test(e))return e.replace(r,a)}else if(i.test(...
  function u (line 111) | function u(e,t){e="string"==typeof e?e:e.source,t=t||"";const n={replace...
  function g (line 111) | function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return nul...
  function f (line 111) | function f(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,r=t;for(;--r...
  function d (line 111) | function d(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){...
  function x (line 111) | function x(e,t,n,s){const r=t.href,i=t.title?c(t.title):null,l=e[1].repl...
  class b (line 111) | class b{options;rules;lexer;constructor(t){this.options=t||e.defaults}sp...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method space (line 111) | space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)...
    method code (line 111) | code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].repla...
    method fences (line 111) | fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n...
    method heading (line 111) | heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].t...
    method hr (line 111) | hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[...
    method blockquote (line 111) | blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const ...
    method list (line 111) | list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();co...
    method html (line 111) | html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html"...
    method def (line 111) | def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLower...
    method table (line 111) | table(e){const t=this.rules.block.table.exec(e);if(t){if(!/[:|]/.test(...
    method lheading (line 111) | lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type...
    method paragraph (line 111) | paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e=...
    method text (line 111) | text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",...
    method escape (line 111) | escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"e...
    method tag (line 111) | tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.st...
    method link (line 111) | link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim...
    method reflink (line 111) | reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.r...
    method emStrong (line 111) | emStrong(e,t,n=""){let s=this.rules.inline.emStrong.lDelim.exec(e);if(...
    method codespan (line 111) | codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].re...
    method br (line 111) | br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t...
    method del (line 111) | del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",ra...
    method autolink (line 111) | autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;r...
    method url (line 111) | url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2]...
    method inlineText (line 111) | inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;retur...
  class _ (line 111) | class _{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.t...
    method constructor (line 111) | constructor(t){this.tokens=[],this.tokens.links=Object.create(null),th...
    method rules (line 111) | static get rules(){return{block:m,inline:w}}
    method lex (line 111) | static lex(e,t){return new _(t).lex(e)}
    method lexInline (line 111) | static lexInline(e,t){return new _(t).inlineTokens(e)}
    method lex (line 111) | lex(e){let t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this....
    method blockTokens (line 111) | blockTokens(e,t=[]){let n,s,r,i;for(e=this.options.pedantic?e.replace(...
    method inline (line 111) | inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}
    method inlineTokens (line 111) | inlineTokens(e,t=[]){let n,s,r,i,l,o,a=e;if(this.tokens.links){const e...
  class y (line 111) | class y{options;constructor(t){this.options=t||e.defaults}code(e,t,n){co...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method code (line 111) | code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$...
    method blockquote (line 111) | blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}
    method html (line 111) | html(e,t){return e}
    method heading (line 111) | heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}
    method hr (line 111) | hr(){return"<hr>\n"}
    method list (line 111) | list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"'...
    method listitem (line 111) | listitem(e,t,n){return`<li>${e}</li>\n`}
    method checkbox (line 111) | checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="ch...
    method paragraph (line 111) | paragraph(e){return`<p>${e}</p>\n`}
    method table (line 111) | table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+...
    method tablerow (line 111) | tablerow(e){return`<tr>\n${e}</tr>\n`}
    method tablecell (line 111) | tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align=...
    method strong (line 111) | strong(e){return`<strong>${e}</strong>`}
    method em (line 111) | em(e){return`<em>${e}</em>`}
    method codespan (line 111) | codespan(e){return`<code>${e}</code>`}
    method br (line 111) | br(){return"<br>"}
    method del (line 111) | del(e){return`<del>${e}</del>`}
    method link (line 111) | link(e,t,n){const s=g(e);if(null===s)return n;let r='<a href="'+(e=s)+...
    method image (line 111) | image(e,t,n){const s=g(e);if(null===s)return n;let r=`<img src="${e=s}...
    method text (line 111) | text(e){return e}
  class $ (line 111) | class ${strong(e){return e}em(e){return e}codespan(e){return e}del(e){re...
    method strong (line 111) | strong(e){return e}
    method em (line 111) | em(e){return e}
    method codespan (line 111) | codespan(e){return e}
    method del (line 111) | del(e){return e}
    method html (line 111) | html(e){return e}
    method text (line 111) | text(e){return e}
    method link (line 111) | link(e,t,n){return""+n}
    method image (line 111) | image(e,t,n){return""+n}
    method br (line 111) | br(){return""}
  class z (line 111) | class z{options;renderer;textRenderer;constructor(t){this.options=t||e.d...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults,this.options.renderer=this.o...
    method parse (line 111) | static parse(e,t){return new z(t).parse(e)}
    method parseInline (line 111) | static parseInline(e,t){return new z(t).parseInline(e)}
    method parse (line 111) | parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(thi...
    method parseInline (line 111) | parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s+...
  class T (line 111) | class T{options;constructor(t){this.options=t||e.defaults}static passThr...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method preprocess (line 111) | preprocess(e){return e}
    method postprocess (line 111) | postprocess(e){return e}
  class R (line 111) | class R{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,p...
    method constructor (line 111) | constructor(...e){this.use(...e)}
    method walkTokens (line 111) | walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(thi...
    method use (line 111) | use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:...
    method setOptions (line 111) | setOptions(e){return this.defaults={...this.defaults,...e},this}
    method #e (line 111) | #e(e,t){return(n,s)=>{const r={...s},i={...this.defaults,...r};!0===th...
    method #t (line 111) | #t(e,t){return n=>{if(n.message+="\nPlease report this to https://gith...
  function A (line 111) | function A(e,t){return S.parse(e,t)}
  class Closure (line 113) | class Closure {
    method constructor (line 120) | constructor(func, execute = true) {
    method get (line 127) | get() {
    method getFormula (line 131) | getFormula() {
    method addNodeProperty (line 135) | addNodeProperty(node, property, inherited) {
    method update (line 144) | update() {
    method getNode (line 149) | getNode() {
    method updateUi (line 153) | updateUi() {
  class Mutable (line 171) | class Mutable {
    method constructor (line 177) | constructor(val) {
    method closures (line 187) | closures() {
    method get (line 191) | get(key) {
    method forLoop (line 203) | forLoop(root, dom_constructor) {
    method setWithoutUpdate (line 212) | setWithoutUpdate(value) {
    method set (line 244) | set(value) {
    method unlinkNode (line 251) | unlinkNode(node) {
    method addClosure (line 257) | addClosure(closure) {
    method removeClosure (line 261) | removeClosure(closure) {
    method equalMutable (line 265) | equalMutable(other) {
    method getClone (line 275) | getClone() {
  class Proxy (line 280) | class Proxy {
    method constructor (line 286) | constructor(targets, differentiator) {
    method addClosure (line 303) | addClosure(closure) {
    method removeClosure (line 307) | removeClosure(closure) {
    method update (line 311) | update() {
    method get (line 315) | get(key) {
    method set (line 327) | set(value) {
  class MutableList (line 336) | class MutableList {
    method constructor (line 341) | constructor(list) {
    method addClosure (line 353) | addClosure(closure) {
    method unlinkNode (line 357) | unlinkNode(node) {
    method forLoop (line 363) | forLoop(root, dom_constructor) {
    method getList (line 369) | getList() {
    method contains (line 373) | contains(item) {
    method getLength (line 381) | getLength() {
    method get (line 385) | get(idx) {
    method set (line 392) | set(index, value) {
    method deleteEmptyWatchers (line 445) | deleteEmptyWatchers() {
    method insertAt (line 464) | insertAt(index, value) {
    method push (line 483) | push(value) {
    method deleteAt (line 487) | deleteAt(index) {
    method clearAll (line 503) | clearAll() {
    method pop (line 513) | pop() {
    method getClone (line 517) | getClone() {
  class RecordInstance (line 576) | class RecordInstance {
    method constructor (line 580) | constructor(obj) {
    method getAllFields (line 594) | getAllFields() {
    method getClonedFields (line 598) | getClonedFields() {
    method addClosure (line 615) | addClosure(closure) {
    method unlinkNode (line 619) | unlinkNode(node) {
    method get (line 625) | get(key) {
    method set (line 629) | set(key, value) {
    method setAndReturn (line 649) | setAndReturn(key, value) {
    method replace (line 654) | replace(obj) {
    method toObject (line 668) | toObject() {
    method getClone (line 677) | getClone() {
  class Module (line 691) | class Module {
    method constructor (line 695) | constructor(name, global) {
    method getName (line 700) | getName() {
    method get (line 704) | get(function_name) {
  function getClassAsString (line 866) | function getClassAsString(className, obj) {
  class PropertyValueAsClosure (line 1546) | class PropertyValueAsClosure {
    method constructor (line 1549) | constructor(closureFunction, deps) {
  class Node2 (line 1557) | class Node2 {
    method constructor (line 1575) | constructor(parentOrSibiling, kind) {
    method createNode (line 1616) | createNode(kind) {
    method getTagName (line 1638) | getTagName() {
    method getParent (line 1641) | getParent() {
    method removeAllFaviconLinks (line 1644) | removeAllFaviconLinks() {
    method setFavicon (line 1654) | setFavicon(url) {
    method updateTextInputValue (line 1670) | updateTextInputValue() {
    method attachAttribute (line 1682) | attachAttribute(property, value) {
    method removeAttribute (line 1691) | removeAttribute(property) {
    method updateTagName (line 1694) | updateTagName(name) {
    method updateToAnchor (line 1714) | updateToAnchor(url) {
    method updatePositionForNodeById (line 1734) | updatePositionForNodeById(node_id, value) {
    method updateParentPosition (line 1743) | updateParentPosition(value) {
    method updateMetaTitle (line 1756) | updateMetaTitle(value) {
    method addMetaTagByName (line 1764) | addMetaTagByName(name, value) {
    method addMetaTagByProperty (line 1778) | addMetaTagByProperty(property, value) {
    method removeMetaTagByName (line 1792) | removeMetaTagByName(name) {
    method removeMetaTagByProperty (line 1806) | removeMetaTagByProperty(property) {
    method attachCss (line 1821) | attachCss(property, value, createClass, className) {
    method attachShadow (line 1898) | attachShadow(value) {
    method attachBackdropMultiFilter (line 1933) | attachBackdropMultiFilter(value) {
    method attachTextShadow (line 1952) | attachTextShadow(value) {
    method getLinearGradientString (line 1983) | getLinearGradientString(value) {
    method attachLinearGradientCss (line 2028) | attachLinearGradientCss(value) {
    method attachBackgroundImageCss (line 2076) | attachBackgroundImageCss(value) {
    method attachMaskImageCss (line 2137) | attachMaskImageCss(value, vendorPrefix) {
    method attachMaskSizeCss (line 2225) | attachMaskSizeCss(value, vendorPrefix) {
    method attachMaskMultiCss (line 2243) | attachMaskMultiCss(value, vendorPrefix) {
    method attachExternalCss (line 2276) | attachExternalCss(css) {
    method attachExternalJs (line 2291) | attachExternalJs(js) {
    method attachColorCss (line 2304) | attachColorCss(property, value, visited) {
    method attachRoleCss (line 2356) | attachRoleCss(value) {
    method attachTextStyles (line 2395) | attachTextStyles(styles) {
    method attachAlignContent (line 2416) | attachAlignContent(value, node_kind) {
    method attachImageSrcClosures (line 2505) | attachImageSrcClosures(staticValue) {
    method attachLinkColor (line 2590) | attachLinkColor(value) {
    method setStaticProperty (line 2671) | setStaticProperty(kind, value, inherited) {
    method setProperty (line 3468) | setProperty(kind, value, inherited) {
    method setDynamicProperty (line 3489) | setDynamicProperty(kind, deps, func, inherited) {
    method getNode (line 3501) | getNode() {
    method getExtraData (line 3504) | getExtraData() {
    method getChildren (line 3507) | getChildren() {
    method mergeFnCalls (line 3510) | mergeFnCalls(current, newFunc) {
    method addEventHandler (line 3516) | addEventHandler(event, func) {
    method destroy (line 3557) | destroy() {
    method #addToGlobalMeta (line 3580) | #addToGlobalMeta(key, value, kind) {
    method #removeFromGlobalMeta (line 3584) | #removeFromGlobalMeta(key) {
  class ConditionalDom (line 3591) | class ConditionalDom {
    method constructor (line 3599) | constructor(parent, deps, condition, node_constructor) {
    method getParent (line 3649) | getParent() {
  class ParentNodeWithSibiling (line 3671) | class ParentNodeWithSibiling {
    method constructor (line 3674) | constructor(parent, sibiling) {
    method getParent (line 3678) | getParent() {
    method getSibiling (line 3681) | getSibiling() {
  class ForLoop (line 3686) | class ForLoop {
    method constructor (line 3692) | constructor(parent, node_constructor, list) {
    method createNode (line 3708) | createNode(index, resizeBodyHeight = true) {
    method createAllNode (line 3730) | createAllNode() {
    method deleteAllNode (line 3738) | deleteAllNode(resizeBodyHeight = true) {
    method getWrapper (line 3749) | getWrapper() {
    method deleteNode (line 3752) | deleteNode(index) {
    method getParent (line 3758) | getParent() {
  method htmlNode (line 3767) | htmlNode(kind) {
  method createStyle (line 3818) | createStyle(cssClass, obj) {
  method getStaticValue (line 3834) | getStaticValue(obj) {
  method getInheritedValues (line 3847) | getInheritedValues(default_args, inherited, function_args) {
  method removeNonFastnClasses (line 3869) | removeNonFastnClasses(node) {
  method staticToMutables (line 3894) | staticToMutables(obj) {
  method mutableToStaticValue (line 3922) | mutableToStaticValue(obj) {
  method flattenMutable (line 3940) | flattenMutable(value) {
  method getFlattenStaticValue (line 3948) | getFlattenStaticValue(obj) {
  method getter (line 3965) | getter(value) {
  method getterByKey (line 3973) | getterByKey(value, index) {
  method setter (line 3985) | setter(variable, value) {
  method defaultPropertyValue (line 3993) | defaultPropertyValue(_propertyValue) {
  method sameResponsiveRole (line 3996) | sameResponsiveRole(desktop, mobile) {
  method getRoleValues (line 4005) | getRoleValues(value) {
  method clone (line 4023) | clone(value) {
  method getListItem (line 4038) | getListItem(value) {
  method getEventKey (line 4047) | getEventKey(event) {
  method createNestedObject (line 4054) | createNestedObject(currentObject, path, value) {
  method markdown_inline (line 4090) | markdown_inline(i) {
  method process_post_markdown (line 4111) | process_post_markdown(node, body) {
  method isNull (line 4150) | isNull(a) {
  method isCommentNode (line 4153) | isCommentNode(node) {
  method isWrapperNode (line 4156) | isWrapperNode(node) {
  method nextSibling (line 4159) | nextSibling(node, parent) {
  method createNodeHelper (line 4172) | createNodeHelper(node, classes, attributes) {
  method addCssFile (line 4184) | addCssFile(url) {
  method addCodeTheme (line 4195) | addCodeTheme(theme) {
  method findAndRemoveHighlighter (line 4224) | findAndRemoveHighlighter(text) {
  method getNodeValue (line 4253) | getNodeValue(node) {
  method getNodeCheckedState (line 4256) | getNodeCheckedState(node) {
  method setFullHeight (line 4259) | setFullHeight() {
  method resetFullHeight (line 4264) | resetFullHeight() {
  method highlightCode (line 4269) | highlightCode(codeElement, extraCodeData) {
  method slugify (line 4280) | slugify(str) {
  method getEventListeners (line 4292) | getEventListeners(node) {
  method flattenArray (line 4303) | flattenArray(arr) {
  method toSnakeCase (line 4306) | toSnakeCase(value) {
  method escapeHtmlInCode (line 4322) | escapeHtmlInCode(str) {
  method escapeHtmlInMarkdown (line 4326) | escapeHtmlInMarkdown(str) {
  method getArgs (line 4366) | getArgs(default_args, passed_args) {
  method replaceBodyStyleAndChildren (line 4392) | replaceBodyStyleAndChildren(newChildrenWrapper) {
  method flattenArray (line 4404) | flattenArray(arr) {
  method spaces (line 4421) | spaces(s) {
  method replace_last_occurrence (line 4454) | replace_last_occurrence(s, old_word, new_word) {
  method repeated_space (line 4469) | repeated_space(n) {
  method mergeNumbers (line 4483) | mergeNumbers(numbers) {
  method addUnderscoreToStart (line 4513) | addUnderscoreToStart(text) {
  method replaceChildren (line 4530) | replaceChildren(parent, newChildrenWrapper) {
  method setCookie (line 4548) | setCookie(cookieName, cookieValue) {
  method getCookie (line 4568) | getCookie(cookieName) {
  class ClassList (line 4594) | class ClassList {
    method add (line 4596) | add(item) {
    method remove (line 4600) | remove(itemToRemove) {
    method toString (line 4603) | toString() {
    method getClasses (line 4606) | getClasses() {
  class Node (line 4611) | class Node {
    method constructor (line 4617) | constructor(id, tagName) {
    method appendChild (line 4628) | appendChild(c) {
    method insertBefore (line 4632) | insertBefore(node, index) {
    method getChildren (line 4636) | getChildren() {
    method setAttribute (line 4640) | setAttribute(attribute, value) {
    method getAttribute (line 4644) | getAttribute(attribute) {
    method removeAttribute (line 4648) | removeAttribute(attribute) {
    method updateTagName (line 4653) | updateTagName(tagName) {
    method toHtmlAsString (line 4657) | toHtmlAsString() {
    method getDataIdString (line 4670) | getDataIdString() {
    method getIdString (line 4674) | getIdString() {
    method getClassString (line 4678) | getClassString() {
    method getStyleString (line 4683) | getStyleString() {
    method getAttributesString (line 4690) | getAttributesString() {
  class Document2 (line 4703) | class Document2 {
    method createElement (line 4704) | createElement(tagName) {
  function addClosureToBreakpointWidth (line 4727) | function addClosureToBreakpointWidth() {
  class MutableVariable (line 4780) | class MutableVariable {
    method constructor (line 4782) | constructor(value) {
    method get (line 4786) | get() {
    method set (line 4790) | set(value) {
    method on_change (line 4794) | on_change(func) {
  class MutableListVariable (line 4799) | class MutableListVariable {
    method constructor (line 4801) | constructor(value) {
    method get (line 4804) | get() {
    method set (line 4807) | set(index, list) {
    method insertAt (line 4814) | insertAt(index, value) {
    method deleteAt (line 4817) | deleteAt(index) {
    method push (line 4820) | push(value) {
    method pop (line 4823) | pop() {
    method clearAll (line 4826) | clearAll() {
    method on_change (line 4829) | on_change(func) {
  class RecordVariable (line 4834) | class RecordVariable {
    method constructor (line 4836) | constructor(value) {
    method get (line 4840) | get() {
    method set (line 4844) | set(record) {
    method on_change (line 4848) | on_change(func) {
  class StaticVariable (line 4852) | class StaticVariable {
    method constructor (line 4855) | constructor(value) {
    method get (line 4867) | get() {
    method on_change (line 4871) | on_change(func) {
  method _get_key (line 5244) | _get_key(key) {
  method set (line 5255) | set(key, value) {
  method get (line 5265) | get(key) {
  method delete (line 5282) | delete(key) {
  function legacyNameToJS (line 5310) | function legacyNameToJS(s) {
  function getDocNameAndRemaining (line 5328) | function getDocNameAndRemaining(s) {
  function isMutable (line 5346) | function isMutable(obj) {
  function initialise_click_outside_events (line 5636) | function initialise_click_outside_events() {
  function initialise_global_key_events (line 5650) | function initialise_global_key_events() {
  function initialise_device (line 5708) | function initialise_device() {
  function set_cookie (line 5791) | function set_cookie(name, value) {
  function system_dark_mode (line 5794) | function system_dark_mode() {
  function initialise_dark_mode (line 5800) | function initialise_dark_mode() {
  function get_cookie (line 5804) | function get_cookie(name, def) {
  function update_dark_mode (line 5811) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 5832) | function start_watching_dark_mode_system_preference() {

FILE: fastn-core/fbt-tests/09-markdown-pages/output/markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
  function t (line 7) | function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null...
  function n (line 7) | function n(t){e.defaults=t}
  function c (line 7) | function c(e,t){if(t){if(s.test(e))return e.replace(r,a)}else if(i.test(...
  function u (line 7) | function u(e,t){e="string"==typeof e?e:e.source,t=t||"";const n={replace...
  function g (line 7) | function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return nul...
  function f (line 7) | function f(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,r=t;for(;--r...
  function d (line 7) | function d(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){...
  function x (line 7) | function x(e,t,n,s){const r=t.href,i=t.title?c(t.title):null,l=e[1].repl...
  class b (line 7) | class b{options;rules;lexer;constructor(t){this.options=t||e.defaults}sp...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method space (line 7) | space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)...
    method code (line 7) | code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].repla...
    method fences (line 7) | fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n...
    method heading (line 7) | heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].t...
    method hr (line 7) | hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[...
    method blockquote (line 7) | blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const ...
    method list (line 7) | list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();co...
    method html (line 7) | html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html"...
    method def (line 7) | def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLower...
    method table (line 7) | table(e){const t=this.rules.block.table.exec(e);if(t){if(!/[:|]/.test(...
    method lheading (line 7) | lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type...
    method paragraph (line 7) | paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e=...
    method text (line 7) | text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",...
    method escape (line 7) | escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"e...
    method tag (line 7) | tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.st...
    method link (line 7) | link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim...
    method reflink (line 7) | reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.r...
    method emStrong (line 7) | emStrong(e,t,n=""){let s=this.rules.inline.emStrong.lDelim.exec(e);if(...
    method codespan (line 7) | codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].re...
    method br (line 7) | br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t...
    method del (line 7) | del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",ra...
    method autolink (line 7) | autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;r...
    method url (line 7) | url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2]...
    method inlineText (line 7) | inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;retur...
  class _ (line 7) | class _{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.t...
    method constructor (line 7) | constructor(t){this.tokens=[],this.tokens.links=Object.create(null),th...
    method rules (line 7) | static get rules(){return{block:m,inline:w}}
    method lex (line 7) | static lex(e,t){return new _(t).lex(e)}
    method lexInline (line 7) | static lexInline(e,t){return new _(t).inlineTokens(e)}
    method lex (line 7) | lex(e){let t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this....
    method blockTokens (line 7) | blockTokens(e,t=[]){let n,s,r,i;for(e=this.options.pedantic?e.replace(...
    method inline (line 7) | inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}
    method inlineTokens (line 7) | inlineTokens(e,t=[]){let n,s,r,i,l,o,a=e;if(this.tokens.links){const e...
  class y (line 7) | class y{options;constructor(t){this.options=t||e.defaults}code(e,t,n){co...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method code (line 7) | code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$...
    method blockquote (line 7) | blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}
    method html (line 7) | html(e,t){return e}
    method heading (line 7) | heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}
    method hr (line 7) | hr(){return"<hr>\n"}
    method list (line 7) | list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"'...
    method listitem (line 7) | listitem(e,t,n){return`<li>${e}</li>\n`}
    method checkbox (line 7) | checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="ch...
    method paragraph (line 7) | paragraph(e){return`<p>${e}</p>\n`}
    method table (line 7) | table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+...
    method tablerow (line 7) | tablerow(e){return`<tr>\n${e}</tr>\n`}
    method tablecell (line 7) | tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align=...
    method strong (line 7) | strong(e){return`<strong>${e}</strong>`}
    method em (line 7) | em(e){return`<em>${e}</em>`}
    method codespan (line 7) | codespan(e){return`<code>${e}</code>`}
    method br (line 7) | br(){return"<br>"}
    method del (line 7) | del(e){return`<del>${e}</del>`}
    method link (line 7) | link(e,t,n){const s=g(e);if(null===s)return n;let r='<a href="'+(e=s)+...
    method image (line 7) | image(e,t,n){const s=g(e);if(null===s)return n;let r=`<img src="${e=s}...
    method text (line 7) | text(e){return e}
  class $ (line 7) | class ${strong(e){return e}em(e){return e}codespan(e){return e}del(e){re...
    method strong (line 7) | strong(e){return e}
    method em (line 7) | em(e){return e}
    method codespan (line 7) | codespan(e){return e}
    method del (line 7) | del(e){return e}
    method html (line 7) | html(e){return e}
    method text (line 7) | text(e){return e}
    method link (line 7) | link(e,t,n){return""+n}
    method image (line 7) | image(e,t,n){return""+n}
    method br (line 7) | br(){return""}
  class z (line 7) | class z{options;renderer;textRenderer;constructor(t){this.options=t||e.d...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults,this.options.renderer=this.o...
    method parse (line 7) | static parse(e,t){return new z(t).parse(e)}
    method parseInline (line 7) | static parseInline(e,t){return new z(t).parseInline(e)}
    method parse (line 7) | parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(thi...
    method parseInline (line 7) | parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s+...
  class T (line 7) | class T{options;constructor(t){this.options=t||e.defaults}static passThr...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method preprocess (line 7) | preprocess(e){return e}
    method postprocess (line 7) | postprocess(e){return e}
  class R (line 7) | class R{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,p...
    method constructor (line 7) | constructor(...e){this.use(...e)}
    method walkTokens (line 7) | walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(thi...
    method use (line 7) | use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:...
    method setOptions (line 7) | setOptions(e){return this.defaults={...this.defaults,...e},this}
    method #e (line 7) | #e(e,t){return(n,s)=>{const r={...s},i={...this.defaults,...r};!0===th...
    method #t (line 7) | #t(e,t){return n=>{if(n.message+="\nPlease report this to https://gith...
  function A (line 7) | function A(e,t){return S.parse(e,t)}

FILE: fastn-core/fbt-tests/09-markdown-pages/output/prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
  function l (line 7) | function l(e){i.highlightedCode=e,j.hooks.run("before-insert",i),i.eleme...
  function C (line 7) | function C(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=...
  function O (line 7) | function O(e,t,n,a){e.lastIndex=t;n=e.exec(n);return n&&a&&n[1]&&(a=n[1]...
  function s (line 7) | function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e...
  function z (line 7) | function z(e,t,n){var a=t.next,n={value:n,prev:t,next:a};return t.next=n...
  function T (line 7) | function T(e,t,n){for(var a=t.next,r=0;r<n&&a!==e.tail;r++)a=a.next;(t.n...
  function a (line 7) | function a(){j.manual||j.highlightAll()}
  function c (line 7) | function c(e,t){var n=(n=e.className).replace(a," ")+" language-"+t;e.cl...
  function r (line 17) | function r(e){return+e.substr(0,e.length-2)}
  function s (line 17) | function s(e,t){return Array.prototype.slice.call((t||document).querySel...
  function l (line 17) | function l(e,t){return e.classList.contains(t)}
  function a (line 17) | function a(e){e()}
  function u (line 17) | function u(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data...
  function c (line 17) | function c(){var e=location.hash.slice(1);s(".temporary.line-highlight")...
  function r (line 28) | function r(e){if(0!=(e=e.filter((function(e){var n,t=(n=e,n?window.getCo...
  function e (line 60) | function e(n){return n=n.replace(/<inner>/g,(function(){return"(?:\\\\.|...

FILE: fastn-core/fbt-tests/11-readme-with-index/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
  function handle_function (line 19) | function handle_function(evt, id, action, obj, function_arguments) {
  function handle_event (line 57) | function handle_event(evt, id, action, obj) {
  function initialise_device (line 477) | function initialise_device() {
  function get_device (line 554) | function get_device() {
  function set_cookie (line 665) | function set_cookie(name, value) {
  function system_dark_mode (line 668) | function system_dark_mode() {
  function initialise_dark_mode (line 671) | function initialise_dark_mode() {
  function get_cookie (line 675) | function get_cookie(name, def) {
  function update_dark_mode (line 680) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 698) | function start_watching_dark_mode_system_preference() {
  constant DEVICE_SUFFIX (line 706) | const DEVICE_SUFFIX = "____device";
  function console_log (line 707) | function console_log(...message) {
  function isObject (line 712) | function isObject(obj) {
  function stringToHTML (line 715) | function stringToHTML(str) {
  function get_name_and_remaining (line 721) | function get_name_and_remaining(name) {
  function split_once (line 735) | function split_once(name, split_at) {
  function deepCopy (line 742) | function deepCopy(object) {
  function change_value (line 748) | function change_value(function_arguments, data, id) {
  function isFunctionArgument (line 772) | function isFunctionArgument(object) {
  function set_data_value (line 803) | function set_data_value(data, name, value) {
  function resolve_reference (line 821) | function resolve_reference(reference, data, value, checked) {
  function get_data_value (line 840) | function get_data_value(data, name) {
  function JSONstringify (line 843) | function JSONstringify(f) {
  function download_text (line 851) | function download_text(filename, text) {
  function len (line 858) | function len(data) {
  function fallbackCopyTextToClipboard (line 861) | function fallbackCopyTextToClipboard(text) {
  function changeElementId (line 1066) | function changeElementId(element, suffix, add) {
  function updatedID (line 1083) | function updatedID(str, flag, suffix) {

FILE: fastn-core/fbt-tests/15-fpm-dependency-alias/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
  function handle_function (line 19) | function handle_function(evt, id, action, obj, function_arguments) {
  function handle_event (line 57) | function handle_event(evt, id, action, obj) {
  function initialise_device (line 477) | function initialise_device() {
  function get_device (line 554) | function get_device() {
  function set_cookie (line 665) | function set_cookie(name, value) {
  function system_dark_mode (line 668) | function system_dark_mode() {
  function initialise_dark_mode (line 671) | function initialise_dark_mode() {
  function get_cookie (line 675) | function get_cookie(name, def) {
  function update_dark_mode (line 680) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 698) | function start_watching_dark_mode_system_preference() {
  constant DEVICE_SUFFIX (line 706) | const DEVICE_SUFFIX = "____device";
  function console_log (line 707) | function console_log(...message) {
  function isObject (line 712) | function isObject(obj) {
  function stringToHTML (line 715) | function stringToHTML(str) {
  function get_name_and_remaining (line 721) | function get_name_and_remaining(name) {
  function split_once (line 735) | function split_once(name, split_at) {
  function deepCopy (line 742) | function deepCopy(object) {
  function change_value (line 748) | function change_value(function_arguments, data, id) {
  function isFunctionArgument (line 772) | function isFunctionArgument(object) {
  function set_data_value (line 803) | function set_data_value(data, name, value) {
  function resolve_reference (line 821) | function resolve_reference(reference, data, value, checked) {
  function get_data_value (line 840) | function get_data_value(data, name) {
  function JSONstringify (line 843) | function JSONstringify(f) {
  function download_text (line 851) | function download_text(filename, text) {
  function len (line 858) | function len(data) {
  function fallbackCopyTextToClipboard (line 861) | function fallbackCopyTextToClipboard(text) {
  function changeElementId (line 1066) | function changeElementId(element, suffix, add) {
  function updatedID (line 1083) | function updatedID(str, flag, suffix) {

FILE: fastn-core/fbt-tests/16-include-processor/input/code/dummy_code.rs
  function main (line 7) | fn main() {

FILE: fastn-core/fbt-tests/16-include-processor/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js
  function handle_function (line 19) | function handle_function(evt, id, action, obj, function_arguments) {
  function handle_event (line 57) | function handle_event(evt, id, action, obj) {
  function initialise_device (line 477) | function initialise_device() {
  function get_device (line 554) | function get_device() {
  function set_cookie (line 665) | function set_cookie(name, value) {
  function system_dark_mode (line 668) | function system_dark_mode() {
  function initialise_dark_mode (line 671) | function initialise_dark_mode() {
  function get_cookie (line 675) | function get_cookie(name, def) {
  function update_dark_mode (line 680) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 698) | function start_watching_dark_mode_system_preference() {
  constant DEVICE_SUFFIX (line 706) | const DEVICE_SUFFIX = "____device";
  function console_log (line 707) | function console_log(...message) {
  function isObject (line 712) | function isObject(obj) {
  function stringToHTML (line 715) | function stringToHTML(str) {
  function get_name_and_remaining (line 721) | function get_name_and_remaining(name) {
  function split_once (line 735) | function split_once(name, split_at) {
  function deepCopy (line 742) | function deepCopy(object) {
  function change_value (line 748) | function change_value(function_arguments, data, id) {
  function isFunctionArgument (line 772) | function isFunctionArgument(object) {
  function set_data_value (line 803) | function set_data_value(data, name, value) {
  function resolve_reference (line 821) | function resolve_reference(reference, data, value, checked) {
  function get_data_value (line 840) | function get_data_value(data, name) {
  function JSONstringify (line 843) | function JSONstringify(f) {
  function download_text (line 851) | function download_text(filename, text) {
  function len (line 858) | function len(data) {
  function fallbackCopyTextToClipboard (line 861) | function fallbackCopyTextToClipboard(text) {
  function changeElementId (line 1066) | function changeElementId(element, suffix, add) {
  function updatedID (line 1083) | function updatedID(str, flag, suffix) {

FILE: fastn-core/fbt-tests/19-offline-build/output/-/fastn-stack.github.io/fastn-js/download.js
  function download_as_image (line 3) | function download_as_image(element_id, filename) {
  function download_as_jpeg (line 21) | function download_as_jpeg(element_id, filename) {
  function download_as_png (line 36) | function download_as_png(element_id, filename) {
  function download_as_svg (line 52) | function download_as_svg(element_id, filename) {
  function download_text (line 67) | function download_text(filename, text) {

FILE: fastn-core/fbt-tests/19-offline-build/output/default-A1BB16FF145420D65E4C815B5AD6C4DA6435B25A2B2ED162A798FF368CEBF57B.js
  function t (line 111) | function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null...
  function n (line 111) | function n(t){e.defaults=t}
  function c (line 111) | function c(e,t){if(t){if(s.test(e))return e.replace(r,a)}else if(i.test(...
  function u (line 111) | function u(e,t){e="string"==typeof e?e:e.source,t=t||"";const n={replace...
  function g (line 111) | function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return nul...
  function f (line 111) | function f(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,r=t;for(;--r...
  function d (line 111) | function d(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){...
  function x (line 111) | function x(e,t,n,s){const r=t.href,i=t.title?c(t.title):null,l=e[1].repl...
  class b (line 111) | class b{options;rules;lexer;constructor(t){this.options=t||e.defaults}sp...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method space (line 111) | space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)...
    method code (line 111) | code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].repla...
    method fences (line 111) | fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n...
    method heading (line 111) | heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].t...
    method hr (line 111) | hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[...
    method blockquote (line 111) | blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const ...
    method list (line 111) | list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();co...
    method html (line 111) | html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html"...
    method def (line 111) | def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLower...
    method table (line 111) | table(e){const t=this.rules.block.table.exec(e);if(t){if(!/[:|]/.test(...
    method lheading (line 111) | lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type...
    method paragraph (line 111) | paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e=...
    method text (line 111) | text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",...
    method escape (line 111) | escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"e...
    method tag (line 111) | tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.st...
    method link (line 111) | link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim...
    method reflink (line 111) | reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.r...
    method emStrong (line 111) | emStrong(e,t,n=""){let s=this.rules.inline.emStrong.lDelim.exec(e);if(...
    method codespan (line 111) | codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].re...
    method br (line 111) | br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t...
    method del (line 111) | del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",ra...
    method autolink (line 111) | autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;r...
    method url (line 111) | url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2]...
    method inlineText (line 111) | inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;retur...
  class _ (line 111) | class _{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.t...
    method constructor (line 111) | constructor(t){this.tokens=[],this.tokens.links=Object.create(null),th...
    method rules (line 111) | static get rules(){return{block:m,inline:w}}
    method lex (line 111) | static lex(e,t){return new _(t).lex(e)}
    method lexInline (line 111) | static lexInline(e,t){return new _(t).inlineTokens(e)}
    method lex (line 111) | lex(e){let t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this....
    method blockTokens (line 111) | blockTokens(e,t=[]){let n,s,r,i;for(e=this.options.pedantic?e.replace(...
    method inline (line 111) | inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}
    method inlineTokens (line 111) | inlineTokens(e,t=[]){let n,s,r,i,l,o,a=e;if(this.tokens.links){const e...
  class y (line 111) | class y{options;constructor(t){this.options=t||e.defaults}code(e,t,n){co...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method code (line 111) | code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$...
    method blockquote (line 111) | blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}
    method html (line 111) | html(e,t){return e}
    method heading (line 111) | heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}
    method hr (line 111) | hr(){return"<hr>\n"}
    method list (line 111) | list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"'...
    method listitem (line 111) | listitem(e,t,n){return`<li>${e}</li>\n`}
    method checkbox (line 111) | checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="ch...
    method paragraph (line 111) | paragraph(e){return`<p>${e}</p>\n`}
    method table (line 111) | table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+...
    method tablerow (line 111) | tablerow(e){return`<tr>\n${e}</tr>\n`}
    method tablecell (line 111) | tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align=...
    method strong (line 111) | strong(e){return`<strong>${e}</strong>`}
    method em (line 111) | em(e){return`<em>${e}</em>`}
    method codespan (line 111) | codespan(e){return`<code>${e}</code>`}
    method br (line 111) | br(){return"<br>"}
    method del (line 111) | del(e){return`<del>${e}</del>`}
    method link (line 111) | link(e,t,n){const s=g(e);if(null===s)return n;let r='<a href="'+(e=s)+...
    method image (line 111) | image(e,t,n){const s=g(e);if(null===s)return n;let r=`<img src="${e=s}...
    method text (line 111) | text(e){return e}
  class $ (line 111) | class ${strong(e){return e}em(e){return e}codespan(e){return e}del(e){re...
    method strong (line 111) | strong(e){return e}
    method em (line 111) | em(e){return e}
    method codespan (line 111) | codespan(e){return e}
    method del (line 111) | del(e){return e}
    method html (line 111) | html(e){return e}
    method text (line 111) | text(e){return e}
    method link (line 111) | link(e,t,n){return""+n}
    method image (line 111) | image(e,t,n){return""+n}
    method br (line 111) | br(){return""}
  class z (line 111) | class z{options;renderer;textRenderer;constructor(t){this.options=t||e.d...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults,this.options.renderer=this.o...
    method parse (line 111) | static parse(e,t){return new z(t).parse(e)}
    method parseInline (line 111) | static parseInline(e,t){return new z(t).parseInline(e)}
    method parse (line 111) | parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(thi...
    method parseInline (line 111) | parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s+...
  class T (line 111) | class T{options;constructor(t){this.options=t||e.defaults}static passThr...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method preprocess (line 111) | preprocess(e){return e}
    method postprocess (line 111) | postprocess(e){return e}
  class R (line 111) | class R{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,p...
    method constructor (line 111) | constructor(...e){this.use(...e)}
    method walkTokens (line 111) | walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(thi...
    method use (line 111) | use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:...
    method setOptions (line 111) | setOptions(e){return this.defaults={...this.defaults,...e},this}
    method #e (line 111) | #e(e,t){return(n,s)=>{const r={...s},i={...this.defaults,...r};!0===th...
    method #t (line 111) | #t(e,t){return n=>{if(n.message+="\nPlease report this to https://gith...
  function A (line 111) | function A(e,t){return S.parse(e,t)}
  class Closure (line 113) | class Closure {
    method constructor (line 120) | constructor(func, execute = true) {
    method get (line 127) | get() {
    method getFormula (line 131) | getFormula() {
    method addNodeProperty (line 135) | addNodeProperty(node, property, inherited) {
    method update (line 144) | update() {
    method getNode (line 149) | getNode() {
    method updateUi (line 153) | updateUi() {
  class Mutable (line 171) | class Mutable {
    method constructor (line 177) | constructor(val) {
    method closures (line 187) | closures() {
    method get (line 191) | get(key) {
    method forLoop (line 203) | forLoop(root, dom_constructor) {
    method setWithoutUpdate (line 212) | setWithoutUpdate(value) {
    method set (line 244) | set(value) {
    method unlinkNode (line 251) | unlinkNode(node) {
    method addClosure (line 257) | addClosure(closure) {
    method removeClosure (line 261) | removeClosure(closure) {
    method equalMutable (line 265) | equalMutable(other) {
    method getClone (line 275) | getClone() {
  class Proxy (line 280) | class Proxy {
    method constructor (line 286) | constructor(targets, differentiator) {
    method addClosure (line 303) | addClosure(closure) {
    method removeClosure (line 307) | removeClosure(closure) {
    method update (line 311) | update() {
    method get (line 315) | get(key) {
    method set (line 327) | set(value) {
  class MutableList (line 336) | class MutableList {
    method constructor (line 341) | constructor(list) {
    method addClosure (line 353) | addClosure(closure) {
    method unlinkNode (line 357) | unlinkNode(node) {
    method forLoop (line 363) | forLoop(root, dom_constructor) {
    method getList (line 369) | getList() {
    method contains (line 373) | contains(item) {
    method getLength (line 381) | getLength() {
    method get (line 385) | get(idx) {
    method set (line 392) | set(index, value) {
    method deleteEmptyWatchers (line 445) | deleteEmptyWatchers() {
    method insertAt (line 464) | insertAt(index, value) {
    method push (line 483) | push(value) {
    method deleteAt (line 487) | deleteAt(index) {
    method clearAll (line 503) | clearAll() {
    method pop (line 513) | pop() {
    method getClone (line 517) | getClone() {
  class RecordInstance (line 576) | class RecordInstance {
    method constructor (line 580) | constructor(obj) {
    method getAllFields (line 594) | getAllFields() {
    method getClonedFields (line 598) | getClonedFields() {
    method addClosure (line 615) | addClosure(closure) {
    method unlinkNode (line 619) | unlinkNode(node) {
    method get (line 625) | get(key) {
    method set (line 629) | set(key, value) {
    method setAndReturn (line 649) | setAndReturn(key, value) {
    method replace (line 654) | replace(obj) {
    method toObject (line 668) | toObject() {
    method getClone (line 677) | getClone() {
  class Module (line 691) | class Module {
    method constructor (line 695) | constructor(name, global) {
    method getName (line 700) | getName() {
    method get (line 704) | get(function_name) {
  function getClassAsString (line 866) | function getClassAsString(className, obj) {
  class PropertyValueAsClosure (line 1546) | class PropertyValueAsClosure {
    method constructor (line 1549) | constructor(closureFunction, deps) {
  class Node2 (line 1557) | class Node2 {
    method constructor (line 1575) | constructor(parentOrSibiling, kind) {
    method createNode (line 1616) | createNode(kind) {
    method getTagName (line 1638) | getTagName() {
    method getParent (line 1641) | getParent() {
    method removeAllFaviconLinks (line 1644) | removeAllFaviconLinks() {
    method setFavicon (line 1654) | setFavicon(url) {
    method updateTextInputValue (line 1670) | updateTextInputValue() {
    method attachAttribute (line 1682) | attachAttribute(property, value) {
    method removeAttribute (line 1691) | removeAttribute(property) {
    method updateTagName (line 1694) | updateTagName(name) {
    method updateToAnchor (line 1714) | updateToAnchor(url) {
    method updatePositionForNodeById (line 1734) | updatePositionForNodeById(node_id, value) {
    method updateParentPosition (line 1743) | updateParentPosition(value) {
    method updateMetaTitle (line 1756) | updateMetaTitle(value) {
    method addMetaTagByName (line 1764) | addMetaTagByName(name, value) {
    method addMetaTagByProperty (line 1778) | addMetaTagByProperty(property, value) {
    method removeMetaTagByName (line 1792) | removeMetaTagByName(name) {
    method removeMetaTagByProperty (line 1806) | removeMetaTagByProperty(property) {
    method attachCss (line 1821) | attachCss(property, value, createClass, className) {
    method attachShadow (line 1898) | attachShadow(value) {
    method attachBackdropMultiFilter (line 1933) | attachBackdropMultiFilter(value) {
    method attachTextShadow (line 1952) | attachTextShadow(value) {
    method getLinearGradientString (line 1983) | getLinearGradientString(value) {
    method attachLinearGradientCss (line 2028) | attachLinearGradientCss(value) {
    method attachBackgroundImageCss (line 2076) | attachBackgroundImageCss(value) {
    method attachMaskImageCss (line 2137) | attachMaskImageCss(value, vendorPrefix) {
    method attachMaskSizeCss (line 2225) | attachMaskSizeCss(value, vendorPrefix) {
    method attachMaskMultiCss (line 2243) | attachMaskMultiCss(value, vendorPrefix) {
    method attachExternalCss (line 2276) | attachExternalCss(css) {
    method attachExternalJs (line 2291) | attachExternalJs(js) {
    method attachColorCss (line 2304) | attachColorCss(property, value, visited) {
    method attachRoleCss (line 2356) | attachRoleCss(value) {
    method attachTextStyles (line 2395) | attachTextStyles(styles) {
    method attachAlignContent (line 2416) | attachAlignContent(value, node_kind) {
    method attachImageSrcClosures (line 2505) | attachImageSrcClosures(staticValue) {
    method attachLinkColor (line 2590) | attachLinkColor(value) {
    method setStaticProperty (line 2671) | setStaticProperty(kind, value, inherited) {
    method setProperty (line 3468) | setProperty(kind, value, inherited) {
    method setDynamicProperty (line 3489) | setDynamicProperty(kind, deps, func, inherited) {
    method getNode (line 3501) | getNode() {
    method getExtraData (line 3504) | getExtraData() {
    method getChildren (line 3507) | getChildren() {
    method mergeFnCalls (line 3510) | mergeFnCalls(current, newFunc) {
    method addEventHandler (line 3516) | addEventHandler(event, func) {
    method destroy (line 3557) | destroy() {
    method #addToGlobalMeta (line 3580) | #addToGlobalMeta(key, value, kind) {
    method #removeFromGlobalMeta (line 3584) | #removeFromGlobalMeta(key) {
  class ConditionalDom (line 3591) | class ConditionalDom {
    method constructor (line 3599) | constructor(parent, deps, condition, node_constructor) {
    method getParent (line 3649) | getParent() {
  class ParentNodeWithSibiling (line 3671) | class ParentNodeWithSibiling {
    method constructor (line 3674) | constructor(parent, sibiling) {
    method getParent (line 3678) | getParent() {
    method getSibiling (line 3681) | getSibiling() {
  class ForLoop (line 3686) | class ForLoop {
    method constructor (line 3692) | constructor(parent, node_constructor, list) {
    method createNode (line 3708) | createNode(index, resizeBodyHeight = true) {
    method createAllNode (line 3730) | createAllNode() {
    method deleteAllNode (line 3738) | deleteAllNode(resizeBodyHeight = true) {
    method getWrapper (line 3749) | getWrapper() {
    method deleteNode (line 3752) | deleteNode(index) {
    method getParent (line 3758) | getParent() {
  method htmlNode (line 3767) | htmlNode(kind) {
  method createStyle (line 3818) | createStyle(cssClass, obj) {
  method getStaticValue (line 3834) | getStaticValue(obj) {
  method getInheritedValues (line 3847) | getInheritedValues(default_args, inherited, function_args) {
  method removeNonFastnClasses (line 3869) | removeNonFastnClasses(node) {
  method staticToMutables (line 3894) | staticToMutables(obj) {
  method mutableToStaticValue (line 3922) | mutableToStaticValue(obj) {
  method flattenMutable (line 3940) | flattenMutable(value) {
  method getFlattenStaticValue (line 3948) | getFlattenStaticValue(obj) {
  method getter (line 3965) | getter(value) {
  method getterByKey (line 3973) | getterByKey(value, index) {
  method setter (line 3985) | setter(variable, value) {
  method defaultPropertyValue (line 3993) | defaultPropertyValue(_propertyValue) {
  method sameResponsiveRole (line 3996) | sameResponsiveRole(desktop, mobile) {
  method getRoleValues (line 4005) | getRoleValues(value) {
  method clone (line 4023) | clone(value) {
  method getListItem (line 4038) | getListItem(value) {
  method getEventKey (line 4047) | getEventKey(event) {
  method createNestedObject (line 4054) | createNestedObject(currentObject, path, value) {
  method markdown_inline (line 4090) | markdown_inline(i) {
  method process_post_markdown (line 4111) | process_post_markdown(node, body) {
  method isNull (line 4150) | isNull(a) {
  method isCommentNode (line 4153) | isCommentNode(node) {
  method isWrapperNode (line 4156) | isWrapperNode(node) {
  method nextSibling (line 4159) | nextSibling(node, parent) {
  method createNodeHelper (line 4172) | createNodeHelper(node, classes, attributes) {
  method addCssFile (line 4184) | addCssFile(url) {
  method addCodeTheme (line 4195) | addCodeTheme(theme) {
  method findAndRemoveHighlighter (line 4224) | findAndRemoveHighlighter(text) {
  method getNodeValue (line 4253) | getNodeValue(node) {
  method getNodeCheckedState (line 4256) | getNodeCheckedState(node) {
  method setFullHeight (line 4259) | setFullHeight() {
  method resetFullHeight (line 4264) | resetFullHeight() {
  method highlightCode (line 4269) | highlightCode(codeElement, extraCodeData) {
  method slugify (line 4280) | slugify(str) {
  method getEventListeners (line 4292) | getEventListeners(node) {
  method flattenArray (line 4303) | flattenArray(arr) {
  method toSnakeCase (line 4306) | toSnakeCase(value) {
  method escapeHtmlInCode (line 4322) | escapeHtmlInCode(str) {
  method escapeHtmlInMarkdown (line 4326) | escapeHtmlInMarkdown(str) {
  method getArgs (line 4366) | getArgs(default_args, passed_args) {
  method replaceBodyStyleAndChildren (line 4392) | replaceBodyStyleAndChildren(newChildrenWrapper) {
  method flattenArray (line 4404) | flattenArray(arr) {
  method spaces (line 4421) | spaces(s) {
  method replace_last_occurrence (line 4454) | replace_last_occurrence(s, old_word, new_word) {
  method repeated_space (line 4469) | repeated_space(n) {
  method mergeNumbers (line 4483) | mergeNumbers(numbers) {
  method addUnderscoreToStart (line 4513) | addUnderscoreToStart(text) {
  method replaceChildren (line 4530) | replaceChildren(parent, newChildrenWrapper) {
  method setCookie (line 4548) | setCookie(cookieName, cookieValue) {
  method getCookie (line 4568) | getCookie(cookieName) {
  class ClassList (line 4594) | class ClassList {
    method add (line 4596) | add(item) {
    method remove (line 4600) | remove(itemToRemove) {
    method toString (line 4603) | toString() {
    method getClasses (line 4606) | getClasses() {
  class Node (line 4611) | class Node {
    method constructor (line 4617) | constructor(id, tagName) {
    method appendChild (line 4628) | appendChild(c) {
    method insertBefore (line 4632) | insertBefore(node, index) {
    method getChildren (line 4636) | getChildren() {
    method setAttribute (line 4640) | setAttribute(attribute, value) {
    method getAttribute (line 4644) | getAttribute(attribute) {
    method removeAttribute (line 4648) | removeAttribute(attribute) {
    method updateTagName (line 4653) | updateTagName(tagName) {
    method toHtmlAsString (line 4657) | toHtmlAsString() {
    method getDataIdString (line 4670) | getDataIdString() {
    method getIdString (line 4674) | getIdString() {
    method getClassString (line 4678) | getClassString() {
    method getStyleString (line 4683) | getStyleString() {
    method getAttributesString (line 4690) | getAttributesString() {
  class Document2 (line 4703) | class Document2 {
    method createElement (line 4704) | createElement(tagName) {
  function addClosureToBreakpointWidth (line 4727) | function addClosureToBreakpointWidth() {
  class MutableVariable (line 4780) | class MutableVariable {
    method constructor (line 4782) | constructor(value) {
    method get (line 4786) | get() {
    method set (line 4790) | set(value) {
    method on_change (line 4794) | on_change(func) {
  class MutableListVariable (line 4799) | class MutableListVariable {
    method constructor (line 4801) | constructor(value) {
    method get (line 4804) | get() {
    method set (line 4807) | set(index, list) {
    method insertAt (line 4814) | insertAt(index, value) {
    method deleteAt (line 4817) | deleteAt(index) {
    method push (line 4820) | push(value) {
    method pop (line 4823) | pop() {
    method clearAll (line 4826) | clearAll() {
    method on_change (line 4829) | on_change(func) {
  class RecordVariable (line 4834) | class RecordVariable {
    method constructor (line 4836) | constructor(value) {
    method get (line 4840) | get() {
    method set (line 4844) | set(record) {
    method on_change (line 4848) | on_change(func) {
  class StaticVariable (line 4852) | class StaticVariable {
    method constructor (line 4855) | constructor(value) {
    method get (line 4867) | get() {
    method on_change (line 4871) | on_change(func) {
  method _get_key (line 5244) | _get_key(key) {
  method set (line 5255) | set(key, value) {
  method get (line 5265) | get(key) {
  method delete (line 5282) | delete(key) {
  function legacyNameToJS (line 5310) | function legacyNameToJS(s) {
  function getDocNameAndRemaining (line 5328) | function getDocNameAndRemaining(s) {
  function isMutable (line 5346) | function isMutable(obj) {
  function initialise_click_outside_events (line 5636) | function initialise_click_outside_events() {
  function initialise_global_key_events (line 5650) | function initialise_global_key_events() {
  function initialise_device (line 5708) | function initialise_device() {
  function set_cookie (line 5791) | function set_cookie(name, value) {
  function system_dark_mode (line 5794) | function system_dark_mode() {
  function initialise_dark_mode (line 5800) | function initialise_dark_mode() {
  function get_cookie (line 5804) | function get_cookie(name, def) {
  function update_dark_mode (line 5811) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 5832) | function start_watching_dark_mode_system_preference() {

FILE: fastn-core/fbt-tests/19-offline-build/output/markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
  function t (line 7) | function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null...
  function n (line 7) | function n(t){e.defaults=t}
  function c (line 7) | function c(e,t){if(t){if(s.test(e))return e.replace(r,a)}else if(i.test(...
  function u (line 7) | function u(e,t){e="string"==typeof e?e:e.source,t=t||"";const n={replace...
  function g (line 7) | function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return nul...
  function f (line 7) | function f(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,r=t;for(;--r...
  function d (line 7) | function d(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){...
  function x (line 7) | function x(e,t,n,s){const r=t.href,i=t.title?c(t.title):null,l=e[1].repl...
  class b (line 7) | class b{options;rules;lexer;constructor(t){this.options=t||e.defaults}sp...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method space (line 7) | space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)...
    method code (line 7) | code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].repla...
    method fences (line 7) | fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n...
    method heading (line 7) | heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].t...
    method hr (line 7) | hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[...
    method blockquote (line 7) | blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const ...
    method list (line 7) | list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();co...
    method html (line 7) | html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html"...
    method def (line 7) | def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLower...
    method table (line 7) | table(e){const t=this.rules.block.table.exec(e);if(t){if(!/[:|]/.test(...
    method lheading (line 7) | lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type...
    method paragraph (line 7) | paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e=...
    method text (line 7) | text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",...
    method escape (line 7) | escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"e...
    method tag (line 7) | tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.st...
    method link (line 7) | link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim...
    method reflink (line 7) | reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.r...
    method emStrong (line 7) | emStrong(e,t,n=""){let s=this.rules.inline.emStrong.lDelim.exec(e);if(...
    method codespan (line 7) | codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].re...
    method br (line 7) | br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t...
    method del (line 7) | del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",ra...
    method autolink (line 7) | autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;r...
    method url (line 7) | url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2]...
    method inlineText (line 7) | inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;retur...
  class _ (line 7) | class _{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.t...
    method constructor (line 7) | constructor(t){this.tokens=[],this.tokens.links=Object.create(null),th...
    method rules (line 7) | static get rules(){return{block:m,inline:w}}
    method lex (line 7) | static lex(e,t){return new _(t).lex(e)}
    method lexInline (line 7) | static lexInline(e,t){return new _(t).inlineTokens(e)}
    method lex (line 7) | lex(e){let t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this....
    method blockTokens (line 7) | blockTokens(e,t=[]){let n,s,r,i;for(e=this.options.pedantic?e.replace(...
    method inline (line 7) | inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}
    method inlineTokens (line 7) | inlineTokens(e,t=[]){let n,s,r,i,l,o,a=e;if(this.tokens.links){const e...
  class y (line 7) | class y{options;constructor(t){this.options=t||e.defaults}code(e,t,n){co...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method code (line 7) | code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$...
    method blockquote (line 7) | blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}
    method html (line 7) | html(e,t){return e}
    method heading (line 7) | heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}
    method hr (line 7) | hr(){return"<hr>\n"}
    method list (line 7) | list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"'...
    method listitem (line 7) | listitem(e,t,n){return`<li>${e}</li>\n`}
    method checkbox (line 7) | checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="ch...
    method paragraph (line 7) | paragraph(e){return`<p>${e}</p>\n`}
    method table (line 7) | table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+...
    method tablerow (line 7) | tablerow(e){return`<tr>\n${e}</tr>\n`}
    method tablecell (line 7) | tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align=...
    method strong (line 7) | strong(e){return`<strong>${e}</strong>`}
    method em (line 7) | em(e){return`<em>${e}</em>`}
    method codespan (line 7) | codespan(e){return`<code>${e}</code>`}
    method br (line 7) | br(){return"<br>"}
    method del (line 7) | del(e){return`<del>${e}</del>`}
    method link (line 7) | link(e,t,n){const s=g(e);if(null===s)return n;let r='<a href="'+(e=s)+...
    method image (line 7) | image(e,t,n){const s=g(e);if(null===s)return n;let r=`<img src="${e=s}...
    method text (line 7) | text(e){return e}
  class $ (line 7) | class ${strong(e){return e}em(e){return e}codespan(e){return e}del(e){re...
    method strong (line 7) | strong(e){return e}
    method em (line 7) | em(e){return e}
    method codespan (line 7) | codespan(e){return e}
    method del (line 7) | del(e){return e}
    method html (line 7) | html(e){return e}
    method text (line 7) | text(e){return e}
    method link (line 7) | link(e,t,n){return""+n}
    method image (line 7) | image(e,t,n){return""+n}
    method br (line 7) | br(){return""}
  class z (line 7) | class z{options;renderer;textRenderer;constructor(t){this.options=t||e.d...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults,this.options.renderer=this.o...
    method parse (line 7) | static parse(e,t){return new z(t).parse(e)}
    method parseInline (line 7) | static parseInline(e,t){return new z(t).parseInline(e)}
    method parse (line 7) | parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(thi...
    method parseInline (line 7) | parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s+...
  class T (line 7) | class T{options;constructor(t){this.options=t||e.defaults}static passThr...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method preprocess (line 7) | preprocess(e){return e}
    method postprocess (line 7) | postprocess(e){return e}
  class R (line 7) | class R{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,p...
    method constructor (line 7) | constructor(...e){this.use(...e)}
    method walkTokens (line 7) | walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(thi...
    method use (line 7) | use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:...
    method setOptions (line 7) | setOptions(e){return this.defaults={...this.defaults,...e},this}
    method #e (line 7) | #e(e,t){return(n,s)=>{const r={...s},i={...this.defaults,...r};!0===th...
    method #t (line 7) | #t(e,t){return n=>{if(n.message+="\nPlease report this to https://gith...
  function A (line 7) | function A(e,t){return S.parse(e,t)}

FILE: fastn-core/fbt-tests/19-offline-build/output/prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
  function l (line 7) | function l(e){i.highlightedCode=e,j.hooks.run("before-insert",i),i.eleme...
  function C (line 7) | function C(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=...
  function O (line 7) | function O(e,t,n,a){e.lastIndex=t;n=e.exec(n);return n&&a&&n[1]&&(a=n[1]...
  function s (line 7) | function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e...
  function z (line 7) | function z(e,t,n){var a=t.next,n={value:n,prev:t,next:a};return t.next=n...
  function T (line 7) | function T(e,t,n){for(var a=t.next,r=0;r<n&&a!==e.tail;r++)a=a.next;(t.n...
  function a (line 7) | function a(){j.manual||j.highlightAll()}
  function c (line 7) | function c(e,t){var n=(n=e.className).replace(a," ")+" language-"+t;e.cl...
  function r (line 17) | function r(e){return+e.substr(0,e.length-2)}
  function s (line 17) | function s(e,t){return Array.prototype.slice.call((t||document).querySel...
  function l (line 17) | function l(e,t){return e.classList.contains(t)}
  function a (line 17) | function a(e){e()}
  function u (line 17) | function u(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data...
  function c (line 17) | function c(){var e=location.hash.slice(1);s(".temporary.line-highlight")...
  function r (line 28) | function r(e){if(0!=(e=e.filter((function(e){var n,t=(n=e,n?window.getCo...
  function e (line 60) | function e(n){return n=n.replace(/<inner>/g,(function(){return"(?:\\\\.|...

FILE: fastn-core/fbt-tests/22-request-data-processor/output/default-D4F9C23DF6372E1C3161B3560431CCE641AED44770DD55B8AAB3DBEB0A1F3533.js
  function t (line 111) | function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null...
  function n (line 111) | function n(t){e.defaults=t}
  function c (line 111) | function c(e,t){if(t){if(s.test(e))return e.replace(r,a)}else if(i.test(...
  function u (line 111) | function u(e,t){e="string"==typeof e?e:e.source,t=t||"";const n={replace...
  function g (line 111) | function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return nul...
  function f (line 111) | function f(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,r=t;for(;--r...
  function d (line 111) | function d(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){...
  function x (line 111) | function x(e,t,n,s){const r=t.href,i=t.title?c(t.title):null,l=e[1].repl...
  class b (line 111) | class b{options;rules;lexer;constructor(t){this.options=t||e.defaults}sp...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method space (line 111) | space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)...
    method code (line 111) | code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].repla...
    method fences (line 111) | fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n...
    method heading (line 111) | heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].t...
    method hr (line 111) | hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[...
    method blockquote (line 111) | blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const ...
    method list (line 111) | list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();co...
    method html (line 111) | html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html"...
    method def (line 111) | def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLower...
    method table (line 111) | table(e){const t=this.rules.block.table.exec(e);if(t){if(!/[:|]/.test(...
    method lheading (line 111) | lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type...
    method paragraph (line 111) | paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e=...
    method text (line 111) | text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",...
    method escape (line 111) | escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"e...
    method tag (line 111) | tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.st...
    method link (line 111) | link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim...
    method reflink (line 111) | reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.r...
    method emStrong (line 111) | emStrong(e,t,n=""){let s=this.rules.inline.emStrong.lDelim.exec(e);if(...
    method codespan (line 111) | codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].re...
    method br (line 111) | br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t...
    method del (line 111) | del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",ra...
    method autolink (line 111) | autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;r...
    method url (line 111) | url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2]...
    method inlineText (line 111) | inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;retur...
  class _ (line 111) | class _{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.t...
    method constructor (line 111) | constructor(t){this.tokens=[],this.tokens.links=Object.create(null),th...
    method rules (line 111) | static get rules(){return{block:m,inline:w}}
    method lex (line 111) | static lex(e,t){return new _(t).lex(e)}
    method lexInline (line 111) | static lexInline(e,t){return new _(t).inlineTokens(e)}
    method lex (line 111) | lex(e){let t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this....
    method blockTokens (line 111) | blockTokens(e,t=[]){let n,s,r,i;for(e=this.options.pedantic?e.replace(...
    method inline (line 111) | inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}
    method inlineTokens (line 111) | inlineTokens(e,t=[]){let n,s,r,i,l,o,a=e;if(this.tokens.links){const e...
  class y (line 111) | class y{options;constructor(t){this.options=t||e.defaults}code(e,t,n){co...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method code (line 111) | code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$...
    method blockquote (line 111) | blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}
    method html (line 111) | html(e,t){return e}
    method heading (line 111) | heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}
    method hr (line 111) | hr(){return"<hr>\n"}
    method list (line 111) | list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"'...
    method listitem (line 111) | listitem(e,t,n){return`<li>${e}</li>\n`}
    method checkbox (line 111) | checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="ch...
    method paragraph (line 111) | paragraph(e){return`<p>${e}</p>\n`}
    method table (line 111) | table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+...
    method tablerow (line 111) | tablerow(e){return`<tr>\n${e}</tr>\n`}
    method tablecell (line 111) | tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align=...
    method strong (line 111) | strong(e){return`<strong>${e}</strong>`}
    method em (line 111) | em(e){return`<em>${e}</em>`}
    method codespan (line 111) | codespan(e){return`<code>${e}</code>`}
    method br (line 111) | br(){return"<br>"}
    method del (line 111) | del(e){return`<del>${e}</del>`}
    method link (line 111) | link(e,t,n){const s=g(e);if(null===s)return n;let r='<a href="'+(e=s)+...
    method image (line 111) | image(e,t,n){const s=g(e);if(null===s)return n;let r=`<img src="${e=s}...
    method text (line 111) | text(e){return e}
  class $ (line 111) | class ${strong(e){return e}em(e){return e}codespan(e){return e}del(e){re...
    method strong (line 111) | strong(e){return e}
    method em (line 111) | em(e){return e}
    method codespan (line 111) | codespan(e){return e}
    method del (line 111) | del(e){return e}
    method html (line 111) | html(e){return e}
    method text (line 111) | text(e){return e}
    method link (line 111) | link(e,t,n){return""+n}
    method image (line 111) | image(e,t,n){return""+n}
    method br (line 111) | br(){return""}
  class z (line 111) | class z{options;renderer;textRenderer;constructor(t){this.options=t||e.d...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults,this.options.renderer=this.o...
    method parse (line 111) | static parse(e,t){return new z(t).parse(e)}
    method parseInline (line 111) | static parseInline(e,t){return new z(t).parseInline(e)}
    method parse (line 111) | parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(thi...
    method parseInline (line 111) | parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s+...
  class T (line 111) | class T{options;constructor(t){this.options=t||e.defaults}static passThr...
    method constructor (line 111) | constructor(t){this.options=t||e.defaults}
    method preprocess (line 111) | preprocess(e){return e}
    method postprocess (line 111) | postprocess(e){return e}
  class R (line 111) | class R{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,p...
    method constructor (line 111) | constructor(...e){this.use(...e)}
    method walkTokens (line 111) | walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(thi...
    method use (line 111) | use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:...
    method setOptions (line 111) | setOptions(e){return this.defaults={...this.defaults,...e},this}
    method #e (line 111) | #e(e,t){return(n,s)=>{const r={...s},i={...this.defaults,...r};!0===th...
    method #t (line 111) | #t(e,t){return n=>{if(n.message+="\nPlease report this to https://gith...
  function A (line 111) | function A(e,t){return S.parse(e,t)}
  class Closure (line 113) | class Closure {
    method constructor (line 120) | constructor(func, execute = true) {
    method get (line 127) | get() {
    method getFormula (line 131) | getFormula() {
    method addNodeProperty (line 135) | addNodeProperty(node, property, inherited) {
    method update (line 144) | update() {
    method getNode (line 149) | getNode() {
    method updateUi (line 153) | updateUi() {
  class Mutable (line 171) | class Mutable {
    method constructor (line 177) | constructor(val) {
    method closures (line 187) | closures() {
    method get (line 191) | get(key) {
    method forLoop (line 203) | forLoop(root, dom_constructor) {
    method setWithoutUpdate (line 212) | setWithoutUpdate(value) {
    method set (line 244) | set(value) {
    method unlinkNode (line 251) | unlinkNode(node) {
    method addClosure (line 257) | addClosure(closure) {
    method removeClosure (line 261) | removeClosure(closure) {
    method equalMutable (line 265) | equalMutable(other) {
    method getClone (line 275) | getClone() {
  class Proxy (line 280) | class Proxy {
    method constructor (line 286) | constructor(targets, differentiator) {
    method addClosure (line 303) | addClosure(closure) {
    method removeClosure (line 307) | removeClosure(closure) {
    method update (line 311) | update() {
    method get (line 315) | get(key) {
    method set (line 327) | set(value) {
  class MutableList (line 336) | class MutableList {
    method constructor (line 341) | constructor(list) {
    method addClosure (line 353) | addClosure(closure) {
    method unlinkNode (line 357) | unlinkNode(node) {
    method forLoop (line 363) | forLoop(root, dom_constructor) {
    method getList (line 369) | getList() {
    method contains (line 373) | contains(item) {
    method getLength (line 381) | getLength() {
    method get (line 385) | get(idx) {
    method set (line 392) | set(index, value) {
    method deleteEmptyWatchers (line 445) | deleteEmptyWatchers() {
    method insertAt (line 464) | insertAt(index, value) {
    method push (line 483) | push(value) {
    method deleteAt (line 487) | deleteAt(index) {
    method clearAll (line 503) | clearAll() {
    method pop (line 513) | pop() {
    method getClone (line 517) | getClone() {
  class RecordInstance (line 576) | class RecordInstance {
    method constructor (line 580) | constructor(obj) {
    method getAllFields (line 594) | getAllFields() {
    method getClonedFields (line 598) | getClonedFields() {
    method addClosure (line 615) | addClosure(closure) {
    method unlinkNode (line 619) | unlinkNode(node) {
    method get (line 625) | get(key) {
    method set (line 629) | set(key, value) {
    method setAndReturn (line 649) | setAndReturn(key, value) {
    method replace (line 654) | replace(obj) {
    method toObject (line 668) | toObject() {
    method getClone (line 677) | getClone() {
  class Module (line 691) | class Module {
    method constructor (line 695) | constructor(name, global) {
    method getName (line 700) | getName() {
    method get (line 704) | get(function_name) {
  function getClassAsString (line 866) | function getClassAsString(className, obj) {
  class PropertyValueAsClosure (line 1546) | class PropertyValueAsClosure {
    method constructor (line 1549) | constructor(closureFunction, deps) {
  class Node2 (line 1557) | class Node2 {
    method constructor (line 1575) | constructor(parentOrSibiling, kind) {
    method createNode (line 1616) | createNode(kind) {
    method getTagName (line 1638) | getTagName() {
    method getParent (line 1641) | getParent() {
    method removeAllFaviconLinks (line 1644) | removeAllFaviconLinks() {
    method setFavicon (line 1654) | setFavicon(url) {
    method updateTextInputValue (line 1670) | updateTextInputValue() {
    method attachAttribute (line 1682) | attachAttribute(property, value) {
    method removeAttribute (line 1691) | removeAttribute(property) {
    method updateTagName (line 1694) | updateTagName(name) {
    method updateToAnchor (line 1714) | updateToAnchor(url) {
    method updatePositionForNodeById (line 1734) | updatePositionForNodeById(node_id, value) {
    method updateParentPosition (line 1743) | updateParentPosition(value) {
    method updateMetaTitle (line 1756) | updateMetaTitle(value) {
    method addMetaTagByName (line 1764) | addMetaTagByName(name, value) {
    method addMetaTagByProperty (line 1778) | addMetaTagByProperty(property, value) {
    method removeMetaTagByName (line 1792) | removeMetaTagByName(name) {
    method removeMetaTagByProperty (line 1806) | removeMetaTagByProperty(property) {
    method attachCss (line 1821) | attachCss(property, value, createClass, className) {
    method attachShadow (line 1898) | attachShadow(value) {
    method attachBackdropMultiFilter (line 1933) | attachBackdropMultiFilter(value) {
    method attachTextShadow (line 1952) | attachTextShadow(value) {
    method getLinearGradientString (line 1983) | getLinearGradientString(value) {
    method attachLinearGradientCss (line 2028) | attachLinearGradientCss(value) {
    method attachBackgroundImageCss (line 2076) | attachBackgroundImageCss(value) {
    method attachMaskImageCss (line 2137) | attachMaskImageCss(value, vendorPrefix) {
    method attachMaskSizeCss (line 2225) | attachMaskSizeCss(value, vendorPrefix) {
    method attachMaskMultiCss (line 2243) | attachMaskMultiCss(value, vendorPrefix) {
    method attachExternalCss (line 2276) | attachExternalCss(css) {
    method attachExternalJs (line 2291) | attachExternalJs(js) {
    method attachColorCss (line 2304) | attachColorCss(property, value, visited) {
    method attachRoleCss (line 2356) | attachRoleCss(value) {
    method attachTextStyles (line 2395) | attachTextStyles(styles) {
    method attachAlignContent (line 2416) | attachAlignContent(value, node_kind) {
    method attachImageSrcClosures (line 2505) | attachImageSrcClosures(staticValue) {
    method attachLinkColor (line 2590) | attachLinkColor(value) {
    method setStaticProperty (line 2671) | setStaticProperty(kind, value, inherited) {
    method setProperty (line 3468) | setProperty(kind, value, inherited) {
    method setDynamicProperty (line 3489) | setDynamicProperty(kind, deps, func, inherited) {
    method getNode (line 3501) | getNode() {
    method getExtraData (line 3504) | getExtraData() {
    method getChildren (line 3507) | getChildren() {
    method mergeFnCalls (line 3510) | mergeFnCalls(current, newFunc) {
    method addEventHandler (line 3516) | addEventHandler(event, func) {
    method destroy (line 3557) | destroy() {
    method #addToGlobalMeta (line 3580) | #addToGlobalMeta(key, value, kind) {
    method #removeFromGlobalMeta (line 3584) | #removeFromGlobalMeta(key) {
  class ConditionalDom (line 3591) | class ConditionalDom {
    method constructor (line 3599) | constructor(parent, deps, condition, node_constructor) {
    method getParent (line 3649) | getParent() {
  class ParentNodeWithSibiling (line 3671) | class ParentNodeWithSibiling {
    method constructor (line 3674) | constructor(parent, sibiling) {
    method getParent (line 3678) | getParent() {
    method getSibiling (line 3681) | getSibiling() {
  class ForLoop (line 3686) | class ForLoop {
    method constructor (line 3692) | constructor(parent, node_constructor, list) {
    method createNode (line 3708) | createNode(index, resizeBodyHeight = true) {
    method createAllNode (line 3730) | createAllNode() {
    method deleteAllNode (line 3738) | deleteAllNode(resizeBodyHeight = true) {
    method getWrapper (line 3749) | getWrapper() {
    method deleteNode (line 3752) | deleteNode(index) {
    method getParent (line 3758) | getParent() {
  method htmlNode (line 3767) | htmlNode(kind) {
  method createStyle (line 3818) | createStyle(cssClass, obj) {
  method getStaticValue (line 3834) | getStaticValue(obj) {
  method getInheritedValues (line 3847) | getInheritedValues(default_args, inherited, function_args) {
  method removeNonFastnClasses (line 3869) | removeNonFastnClasses(node) {
  method staticToMutables (line 3894) | staticToMutables(obj) {
  method mutableToStaticValue (line 3922) | mutableToStaticValue(obj) {
  method flattenMutable (line 3940) | flattenMutable(value) {
  method getFlattenStaticValue (line 3948) | getFlattenStaticValue(obj) {
  method getter (line 3965) | getter(value) {
  method getterByKey (line 3973) | getterByKey(value, index) {
  method setter (line 3985) | setter(variable, value) {
  method defaultPropertyValue (line 3993) | defaultPropertyValue(_propertyValue) {
  method sameResponsiveRole (line 3996) | sameResponsiveRole(desktop, mobile) {
  method getRoleValues (line 4005) | getRoleValues(value) {
  method clone (line 4023) | clone(value) {
  method getListItem (line 4038) | getListItem(value) {
  method getEventKey (line 4047) | getEventKey(event) {
  method createNestedObject (line 4054) | createNestedObject(currentObject, path, value) {
  method markdown_inline (line 4090) | markdown_inline(i) {
  method process_post_markdown (line 4111) | process_post_markdown(node, body) {
  method isNull (line 4150) | isNull(a) {
  method isCommentNode (line 4153) | isCommentNode(node) {
  method isWrapperNode (line 4156) | isWrapperNode(node) {
  method nextSibling (line 4159) | nextSibling(node, parent) {
  method createNodeHelper (line 4172) | createNodeHelper(node, classes, attributes) {
  method addCssFile (line 4184) | addCssFile(url) {
  method addCodeTheme (line 4195) | addCodeTheme(theme) {
  method findAndRemoveHighlighter (line 4224) | findAndRemoveHighlighter(text) {
  method getNodeValue (line 4253) | getNodeValue(node) {
  method getNodeCheckedState (line 4256) | getNodeCheckedState(node) {
  method setFullHeight (line 4259) | setFullHeight() {
  method resetFullHeight (line 4264) | resetFullHeight() {
  method highlightCode (line 4269) | highlightCode(codeElement, extraCodeData) {
  method slugify (line 4280) | slugify(str) {
  method getEventListeners (line 4292) | getEventListeners(node) {
  method flattenArray (line 4303) | flattenArray(arr) {
  method toSnakeCase (line 4306) | toSnakeCase(value) {
  method escapeHtmlInCode (line 4322) | escapeHtmlInCode(str) {
  method escapeHtmlInMarkdown (line 4326) | escapeHtmlInMarkdown(str) {
  method getArgs (line 4366) | getArgs(default_args, passed_args) {
  method replaceBodyStyleAndChildren (line 4392) | replaceBodyStyleAndChildren(newChildrenWrapper) {
  method flattenArray (line 4404) | flattenArray(arr) {
  method spaces (line 4421) | spaces(s) {
  method replace_last_occurrence (line 4454) | replace_last_occurrence(s, old_word, new_word) {
  method repeated_space (line 4469) | repeated_space(n) {
  method mergeNumbers (line 4483) | mergeNumbers(numbers) {
  method addUnderscoreToStart (line 4513) | addUnderscoreToStart(text) {
  method replaceChildren (line 4530) | replaceChildren(parent, newChildrenWrapper) {
  method setCookie (line 4548) | setCookie(cookieName, cookieValue) {
  method getCookie (line 4568) | getCookie(cookieName) {
  class ClassList (line 4594) | class ClassList {
    method add (line 4596) | add(item) {
    method remove (line 4600) | remove(itemToRemove) {
    method toString (line 4603) | toString() {
    method getClasses (line 4606) | getClasses() {
  class Node (line 4611) | class Node {
    method constructor (line 4617) | constructor(id, tagName) {
    method appendChild (line 4628) | appendChild(c) {
    method insertBefore (line 4632) | insertBefore(node, index) {
    method getChildren (line 4636) | getChildren() {
    method setAttribute (line 4640) | setAttribute(attribute, value) {
    method getAttribute (line 4644) | getAttribute(attribute) {
    method removeAttribute (line 4648) | removeAttribute(attribute) {
    method updateTagName (line 4653) | updateTagName(tagName) {
    method toHtmlAsString (line 4657) | toHtmlAsString() {
    method getDataIdString (line 4670) | getDataIdString() {
    method getIdString (line 4674) | getIdString() {
    method getClassString (line 4678) | getClassString() {
    method getStyleString (line 4683) | getStyleString() {
    method getAttributesString (line 4690) | getAttributesString() {
  class Document2 (line 4703) | class Document2 {
    method createElement (line 4704) | createElement(tagName) {
  function addClosureToBreakpointWidth (line 4727) | function addClosureToBreakpointWidth() {
  class MutableVariable (line 4780) | class MutableVariable {
    method constructor (line 4782) | constructor(value) {
    method get (line 4786) | get() {
    method set (line 4790) | set(value) {
    method on_change (line 4794) | on_change(func) {
  class MutableListVariable (line 4799) | class MutableListVariable {
    method constructor (line 4801) | constructor(value) {
    method get (line 4804) | get() {
    method set (line 4807) | set(index, list) {
    method insertAt (line 4814) | insertAt(index, value) {
    method deleteAt (line 4817) | deleteAt(index) {
    method push (line 4820) | push(value) {
    method pop (line 4823) | pop() {
    method clearAll (line 4826) | clearAll() {
    method on_change (line 4829) | on_change(func) {
  class RecordVariable (line 4834) | class RecordVariable {
    method constructor (line 4836) | constructor(value) {
    method get (line 4840) | get() {
    method set (line 4844) | set(record) {
    method on_change (line 4848) | on_change(func) {
  class StaticVariable (line 4852) | class StaticVariable {
    method constructor (line 4855) | constructor(value) {
    method get (line 4867) | get() {
    method on_change (line 4871) | on_change(func) {
  method _get_key (line 5244) | _get_key(key) {
  method set (line 5255) | set(key, value) {
  method get (line 5265) | get(key) {
  method delete (line 5282) | delete(key) {
  function legacyNameToJS (line 5310) | function legacyNameToJS(s) {
  function getDocNameAndRemaining (line 5328) | function getDocNameAndRemaining(s) {
  function isMutable (line 5346) | function isMutable(obj) {
  function initialise_click_outside_events (line 5636) | function initialise_click_outside_events() {
  function initialise_global_key_events (line 5650) | function initialise_global_key_events() {
  function initialise_device (line 5708) | function initialise_device() {
  function set_cookie (line 5791) | function set_cookie(name, value) {
  function system_dark_mode (line 5794) | function system_dark_mode() {
  function initialise_dark_mode (line 5800) | function initialise_dark_mode() {
  function get_cookie (line 5804) | function get_cookie(name, def) {
  function update_dark_mode (line 5811) | function update_dark_mode() {
  function start_watching_dark_mode_system_preference (line 5832) | function start_watching_dark_mode_system_preference() {

FILE: fastn-core/fbt-tests/22-request-data-processor/output/markdown-24E09EFC0C2B9A11DEA9AC71888EB3A1E85864FA7D9C95A3EB5075A0E0F49A5F.js
  function t (line 7) | function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null...
  function n (line 7) | function n(t){e.defaults=t}
  function c (line 7) | function c(e,t){if(t){if(s.test(e))return e.replace(r,a)}else if(i.test(...
  function u (line 7) | function u(e,t){e="string"==typeof e?e:e.source,t=t||"";const n={replace...
  function g (line 7) | function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return nul...
  function f (line 7) | function f(e,t){const n=e.replace(/\|/g,((e,t,n)=>{let s=!1,r=t;for(;--r...
  function d (line 7) | function d(e,t,n){const s=e.length;if(0===s)return"";let r=0;for(;r<s;){...
  function x (line 7) | function x(e,t,n,s){const r=t.href,i=t.title?c(t.title):null,l=e[1].repl...
  class b (line 7) | class b{options;rules;lexer;constructor(t){this.options=t||e.defaults}sp...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method space (line 7) | space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)...
    method code (line 7) | code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].repla...
    method fences (line 7) | fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n...
    method heading (line 7) | heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].t...
    method hr (line 7) | hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[...
    method blockquote (line 7) | blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const ...
    method list (line 7) | list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();co...
    method html (line 7) | html(e){const t=this.rules.block.html.exec(e);if(t){return{type:"html"...
    method def (line 7) | def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLower...
    method table (line 7) | table(e){const t=this.rules.block.table.exec(e);if(t){if(!/[:|]/.test(...
    method lheading (line 7) | lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type...
    method paragraph (line 7) | paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e=...
    method text (line 7) | text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",...
    method escape (line 7) | escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"e...
    method tag (line 7) | tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.st...
    method link (line 7) | link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim...
    method reflink (line 7) | reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.r...
    method emStrong (line 7) | emStrong(e,t,n=""){let s=this.rules.inline.emStrong.lDelim.exec(e);if(...
    method codespan (line 7) | codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].re...
    method br (line 7) | br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t...
    method del (line 7) | del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",ra...
    method autolink (line 7) | autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;r...
    method url (line 7) | url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2]...
    method inlineText (line 7) | inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;retur...
  class _ (line 7) | class _{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.t...
    method constructor (line 7) | constructor(t){this.tokens=[],this.tokens.links=Object.create(null),th...
    method rules (line 7) | static get rules(){return{block:m,inline:w}}
    method lex (line 7) | static lex(e,t){return new _(t).lex(e)}
    method lexInline (line 7) | static lexInline(e,t){return new _(t).inlineTokens(e)}
    method lex (line 7) | lex(e){let t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this....
    method blockTokens (line 7) | blockTokens(e,t=[]){let n,s,r,i;for(e=this.options.pedantic?e.replace(...
    method inline (line 7) | inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}
    method inlineTokens (line 7) | inlineTokens(e,t=[]){let n,s,r,i,l,o,a=e;if(this.tokens.links){const e...
  class y (line 7) | class y{options;constructor(t){this.options=t||e.defaults}code(e,t,n){co...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method code (line 7) | code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$...
    method blockquote (line 7) | blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}
    method html (line 7) | html(e,t){return e}
    method heading (line 7) | heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}
    method hr (line 7) | hr(){return"<hr>\n"}
    method list (line 7) | list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"'...
    method listitem (line 7) | listitem(e,t,n){return`<li>${e}</li>\n`}
    method checkbox (line 7) | checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="ch...
    method paragraph (line 7) | paragraph(e){return`<p>${e}</p>\n`}
    method table (line 7) | table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+...
    method tablerow (line 7) | tablerow(e){return`<tr>\n${e}</tr>\n`}
    method tablecell (line 7) | tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align=...
    method strong (line 7) | strong(e){return`<strong>${e}</strong>`}
    method em (line 7) | em(e){return`<em>${e}</em>`}
    method codespan (line 7) | codespan(e){return`<code>${e}</code>`}
    method br (line 7) | br(){return"<br>"}
    method del (line 7) | del(e){return`<del>${e}</del>`}
    method link (line 7) | link(e,t,n){const s=g(e);if(null===s)return n;let r='<a href="'+(e=s)+...
    method image (line 7) | image(e,t,n){const s=g(e);if(null===s)return n;let r=`<img src="${e=s}...
    method text (line 7) | text(e){return e}
  class $ (line 7) | class ${strong(e){return e}em(e){return e}codespan(e){return e}del(e){re...
    method strong (line 7) | strong(e){return e}
    method em (line 7) | em(e){return e}
    method codespan (line 7) | codespan(e){return e}
    method del (line 7) | del(e){return e}
    method html (line 7) | html(e){return e}
    method text (line 7) | text(e){return e}
    method link (line 7) | link(e,t,n){return""+n}
    method image (line 7) | image(e,t,n){return""+n}
    method br (line 7) | br(){return""}
  class z (line 7) | class z{options;renderer;textRenderer;constructor(t){this.options=t||e.d...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults,this.options.renderer=this.o...
    method parse (line 7) | static parse(e,t){return new z(t).parse(e)}
    method parseInline (line 7) | static parseInline(e,t){return new z(t).parseInline(e)}
    method parse (line 7) | parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const r=e[s];if(thi...
    method parseInline (line 7) | parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s+...
  class T (line 7) | class T{options;constructor(t){this.options=t||e.defaults}static passThr...
    method constructor (line 7) | constructor(t){this.options=t||e.defaults}
    method preprocess (line 7) | preprocess(e){return e}
    method postprocess (line 7) | postprocess(e){return e}
  class R (line 7) | class R{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,p...
    method constructor (line 7) | constructor(...e){this.use(...e)}
    method walkTokens (line 7) | walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(thi...
    method use (line 7) | use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:...
    method setOptions (line 7) | setOptions(e){return this.defaults={...this.defaults,...e},this}
    method #e (line 7) | #e(e,t){return(n,s)=>{const r={...s},i={...this.defaults,...r};!0===th...
    method #t (line 7) | #t(e,t){return n=>{if(n.message+="\nPlease report this to https://gith...
  function A (line 7) | function A(e,t){return S.parse(e,t)}

FILE: fastn-core/fbt-tests/22-request-data-processor/output/prism-CA83672C9FB5C7D63C2C934C352CC777CD7A3ADFDA7E61DCCF80CAF1EF35FB49.js
  function l (line 7) | function l(e){i.highlightedCode=e,j.hooks.run("before-insert",i),i.eleme...
  function C (line 7) | function C(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=...
  function O (line 7) | function O(e,t,n,a){e.lastIndex=t;n=e.exec(n);return n&&a&&n[1]&&(a=n[1]...
  function s (line 7) | function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e...
  function z (line 7) | function z(e,t,n){var a=t.next,n={value:n,prev:t,next:a};return t.next=n...
  function T (line 7) | function T(e,t,n){for(var a=t.next,r=0;r<n&&a!==e.tail;r++)a=a.next;(t.n...
  function a (line 7) | function a(){j.manual||j.highlightAll()}
  function c (line 7) | function c(e,t){var n=(n=e.className).replace(a," ")+" language-"+t;e.cl...
  function r (line 17) | function r(e){return+e.substr(0,e.length-2)}
  function s (line 17) | function s(e,t){return Array.prototype.slice.call((t||document).querySel...
  function l (line 17) | function l(e,t){return e.classList.contains(t)}
  function a (line 17) | function a(e){e()}
  function u (line 17) | function u(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data...
  function c (line 17) | function c(){var e=location.hash.slice(1);s(".temporary.line-highlight")...
  function r (line 28) | function r(e){if(0!=(e=e.filter((function(e){var n,t=(n=e,n?window.getCo...
  function e (line 60) | function e(n){return n=n.replace(/<inner>/g,(function(){return"(?:\\\\.|...

FILE: fastn-core/fbt-tests/27-wasm-backend/wasm_backend/src/lib.rs
  function handlerequest (line 7) | fn handlerequest(a: guest_backend::Httprequest) -> guest_backend::Httpre...

FILE: fastn-core/fbt-tests/27-wasm-backend/wasm_backend/src/types.rs
  type SubscribeData (line 4) | pub(crate) struct SubscribeData {
  type LikeData (line 9) | pub(crate) struct LikeData {

FILE: fastn-core/src/auto_import.rs
  type AutoImport (line 2) | pub struct AutoImport {

FILE: fastn-core/src/catch_panic.rs
  type CatchPanic (line 48) | pub struct CatchPanic;
    type Response (line 54) | type Response = ServiceResponse<B>;
    type Error (line 55) | type Error = actix_web::Error;
    type Transform (line 56) | type Transform = CatchPanicMiddleware<S>;
    type InitError (line 57) | type InitError = ();
    type Future (line 58) | type Future = Ready<Result<Self::Transform, Self::InitError>>;
    method new_transform (line 60) | fn new_transform(&self, service: S) -> Self::Future {
  type CatchPanicMiddleware (line 67) | pub struct CatchPanicMiddleware<S> {
  type Response (line 75) | type Response = ServiceResponse<B>;
  type Error (line 76) | type Error = actix_web::Error;
  type Future (line 77) | type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
  function call (line 81) | fn call(&self, req: ServiceRequest) -> Self::Future {
  constant INTERNAL_SERVER_ERROR_MESSAGE (line 95) | const INTERNAL_SERVER_ERROR_MESSAGE: &str = "500 Server Error";
  function test_app (line 109) | fn test_app() -> App<
  function pass_through_no_panic (line 132) | async fn pass_through_no_panic() {
  function catch_panic_return_internal_server_error_response (line 143) | async fn catch_panic_return_internal_server_error_response() {

FILE: fastn-core/src/commands/build.rs
  function build (line 3) | pub async fn build(
  function get_build_content (line 94) | pub(crate) fn get_build_content() -> std::io::Result<std::collections::B...
  function find_all_files_recursively (line 108) | fn find_all_files_recursively(
  constant FILE_NAME (line 128) | const FILE_NAME: &str = "fastn.cache";
  function get (line 130) | pub(crate) fn get() -> std::io::Result<(bool, Cache)> {
  type Cache (line 154) | pub(crate) struct Cache {
    method cache_it (line 165) | pub(crate) fn cache_it(&self) -> fastn_core::Result<()> {
    method get_file_hash (line 169) | pub(crate) fn get_file_hash(&mut self, path: &str) -> fastn_core::Resu...
  type File (line 194) | pub(crate) struct File {
  type Document (line 200) | pub(crate) struct Document {
  function get_dependency_name_without_package_name (line 206) | fn get_dependency_name_without_package_name(package_name: &str, dependen...
  function is_virtual_dep (line 216) | fn is_virtual_dep(path: &str) -> bool {
  function handle_dependency_file (line 225) | async fn handle_dependency_file(
  function remove_deleted_documents (line 264) | async fn remove_deleted_documents(
  function incremental_build (line 315) | async fn incremental_build(
  function handle_only_id (line 476) | async fn handle_only_id(
  function handle_file (line 509) | async fn handle_file(
  function is_cached (line 549) | fn is_cached<'a>(
  function remove_extension (line 630) | fn remove_extension(id: &str) -> String {
  function handle_file_ (line 640) | async fn handle_file_(
  function default_build_files (line 754) | pub async fn default_build_files(
  function get_documents_for_current_package (line 818) | async fn get_documents_for_current_package(
  function process_static (line 868) | async fn process_static(

FILE: fastn-core/src/commands/check.rs
  constant INDEX_FILE (line 1) | pub const INDEX_FILE: &str = "index.html";
  constant BUILD_FOLDER (line 2) | pub const BUILD_FOLDER: &str = ".build";
  constant IGNORED_DIRECTORIES (line 3) | pub const IGNORED_DIRECTORIES: [&str; 4] = ["-", "images", "static", "as...
  function post_build_check (line 5) | pub async fn post_build_check(config: &fastn_core::Config) -> fastn_core...
  function is_ignored_directory (line 67) | fn is_ignored_directory(path: &camino::Utf8PathBuf) -> bool {

FILE: fastn-core/src/commands/fmt.rs
  function fmt (line 1) | pub async fn fmt(
  type Section (line 39) | struct Section {
    method new_comment (line 56) | fn new_comment(value: &str) -> Section {
    method new_empty (line 63) | fn new_empty(value: &str) -> Section {
    method new_section (line 70) | fn new_section(name: &str, value: &str) -> Section {
  type SectionKind (line 45) | enum SectionKind {
  function format_sections (line 82) | fn format_sections(sections: Vec<Section>, indentation: bool) -> String {
  function format_section (line 93) | fn format_section(section: &Section, indentation: Option<i32>) -> String {
  function format_section_kind (line 111) | fn format_section_kind(
  function add_indentation (line 131) | fn add_indentation(input: &str, indentation: Option<i32>) -> String {
  function parsed_to_sections (line 145) | fn parsed_to_sections(input: &str) -> Vec<Section> {
  function end_section (line 171) | fn end_section(input: &mut String, sections: &mut Vec<Section>) -> bool {
  function end_section_name (line 214) | fn end_section_name(input: &str) -> Option<String> {
  function section (line 221) | fn section(input: &mut String) -> Option<Section> {
  function remove_comment_from_section_value_if_its_comment_for_other_section (line 272) | fn remove_comment_from_section_value_if_its_comment_for_other_section(
  function get_section_name (line 289) | fn get_section_name(input: &str) -> Option<String> {
  function empty_section (line 313) | fn empty_section(input: &mut String) -> Option<Section> {
  function comment_section (line 336) | fn comment_section(input: &mut String) -> Option<Section> {

FILE: fastn-core/src/commands/query.rs
  function query (line 1) | pub async fn query(
  function get_ftd_json (line 56) | pub(crate) fn get_ftd_json(
  function get_p1_json (line 75) | fn get_p1_json(document: &fastn_core::Document) -> fastn_core::Result<se...
  function get_ast_json (line 85) | fn get_ast_json(document: &fastn_core::Document) -> fastn_core::Result<s...

FILE: fastn-core/src/commands/serve.rs
  function handle_redirect (line 2) | fn handle_redirect(
  function serve_file (line 17) | async fn serve_file(
  function guess_mime_type (line 159) | fn guess_mime_type(path: &str) -> mime_guess::Mime {
  func
Copy disabled (too large) Download .json
Condensed preview — 2749 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (27,034K chars).
[
  {
    "path": ".all-contributorsrc",
    "chars": 3312,
    "preview": "{\n  \"files\": [\n    \"README.md\"\n  ],\n  \"imageSize\": 100,\n  \"commit\": false,\n  \"commitConvention\": \"angular\",\n  \"contribut"
  },
  {
    "path": ".dockerignore",
    "chars": 338,
    "preview": "# editor and OS junk\n.idea\n**/.DS_Store\n\nftd/t/js/**.manual.html\nftd/t/js/**.script.html\n\n# nix symlink to the build out"
  },
  {
    "path": ".gitattributes",
    "chars": 503,
    "preview": "# We do not want to list generated html files in statistics that Github shows\n# on our repo page.\n# Refer: https://githu"
  },
  {
    "path": ".github/Dockerfile",
    "chars": 336,
    "preview": "FROM ekidd/rust-musl-builder\n\n# We need to add the source code to the image because `rust-musl-builder`\n# assumes a UID "
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 23,
    "preview": "open_collective: fastn\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1468,
    "preview": "---\nname: Bug Report\nabout: Create a bug report.\nlabels: bug\n---\n\nYour issue may already be reported! Please search on t"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/code_issue.md",
    "chars": 967,
    "preview": "---\nname: Code Issue\nabout: You have found some issue with the code?\nlabels: code-issue\n---\n\nYour issue may already be r"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 351,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: fastn Discord\n    url: https://discord.gg/fwhk5m3AMG\n    about: fas"
  },
  {
    "path": ".github/RELEASE_TEMPLATE.md",
    "chars": 344,
    "preview": "[`fastn` - Full-stack Web Development Made Easy](https://fastn.com/home/)\n\nCheckout fastn installation step: https://fas"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 504,
    "preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
  },
  {
    "path": ".github/dprint-ci.json",
    "chars": 223,
    "preview": "{\n  \"prettier\": {\n    \"indentWidth\": 4\n  },\n  \"includes\": [\"fastn-js/js/**/*.js\"],\n  \"plugins\": [\n    \"https://plugins.d"
  },
  {
    "path": ".github/lib/README.md",
    "chars": 1005,
    "preview": "## libpq, libcrypto-3, libssl-3\n\nThese DLLs are essential for specific PostgreSQL-related dependencies on Windows.\nThey "
  },
  {
    "path": ".github/scripts/populate-table.py",
    "chars": 1471,
    "preview": "import sqlite3\nimport os\n\n\ndef create_table():\n    connection = sqlite3.connect(get_database_path(os.environ[\"FASTN_DB_U"
  },
  {
    "path": ".github/scripts/run-integration-tests.sh",
    "chars": 652,
    "preview": "#!/bin/bash\nexport FASTN_ROOT=`pwd`\n\n# Enable xtrace and pipefail\nset -o xtrace\nset -eou pipefail\n\necho \"Installing pyth"
  },
  {
    "path": ".github/scripts/test-server.py",
    "chars": 1258,
    "preview": "from flask import Flask, jsonify\nimport sqlite3\nimport os\n\napp = Flask(__name__)\n\n\ndef fetch_data():\n    # Connect to th"
  },
  {
    "path": ".github/workflows/create-release.yml",
    "chars": 7106,
    "preview": "name: Create a new release\n\non:\n  workflow_dispatch:\n    inputs:\n      releaseTag:\n        description: 'Release Tag'\n  "
  },
  {
    "path": ".github/workflows/deploy-fastn-com.yml",
    "chars": 905,
    "preview": "name: Deploy fastn.com\n\non:\n  workflow_dispatch:\n  push:\n    branches: [ main ]\n    paths:\n      - 'fastn.com/**'\n      "
  },
  {
    "path": ".github/workflows/email-critical-tests.yml",
    "chars": 5524,
    "preview": "name: 🎯 Critical Email System Tests\n\non:\n  push:\n    branches: [ main ]\n    paths:\n      - 'v0.5/**'\n  pull_request:\n   "
  },
  {
    "path": ".github/workflows/optimize-images.yml",
    "chars": 956,
    "preview": "# https://github.com/calibreapp/image-actions\nname: Optimize Images\non:\n  push:\n    branches:\n      - main\n    paths:\n  "
  },
  {
    "path": ".github/workflows/tests-and-formatting.yml",
    "chars": 4477,
    "preview": "name: Tests and Formatting\n\non:\n  workflow_dispatch:\n  push:\n    branches: [ main ]\n    paths:\n      # Order matters!\n  "
  },
  {
    "path": ".gitignore",
    "chars": 499,
    "preview": "# editor and OS junk\n.idea\n**/.DS_Store\n\nftd/t/js/**.manual.html\nftd/t/js/**.script.html\nintegration-tests/_tests/**.scr"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 497,
    "preview": "repos:\n-   repo: https://github.com/ambv/black\n    rev: 21.7b0\n    hooks:\n    - id: black\n      language_version: python"
  },
  {
    "path": ".rusty-hook.toml",
    "chars": 110,
    "preview": "[hooks]\npre-commit = \"cargo test\"\npre-push = \"cargo clippy && cargo fmt -- --check\"\n\n[logging]\nverbose = true\n"
  },
  {
    "path": "Cargo.toml",
    "chars": 6827,
    "preview": "[workspace]\nmembers = [\n    \"clift\",\n    \"fastn\",\n    \"fastn-builtins\",\n    \"fastn-context\",\n    \"fastn-context-macros\","
  },
  {
    "path": "Changelog.md",
    "chars": 11480,
    "preview": "# `fastn` Change Log\n\n## 17 September 2025\n\n### fastn: 0.4.113\n\n- fix: Do not override query params of http processor's "
  },
  {
    "path": "Cheatsheet.md",
    "chars": 32366,
    "preview": "# FTD Cheat Sheet\n\nThis cheatsheet describes 0.3 syntax.\n\n## Variables And Basic Types\n\n```ftd\n-- boolean foo: true\n\n\n--"
  },
  {
    "path": "DOCUMENTATION_PLAN.md",
    "chars": 12590,
    "preview": "# fastn.com Documentation & Specification Plan\n\n## Overview\nTransform fastn.com into the comprehensive hub for all fastn"
  },
  {
    "path": "LICENSE",
    "chars": 1844,
    "preview": "Copyright (c) [2025] [FifthTry, Inc and Contributors]\n\nThe Universal Permissive License (UPL), Version 1.0\n\nSubject to t"
  },
  {
    "path": "README.md",
    "chars": 13059,
    "preview": "<div align=\"center\">\n\n[![Contributors](https://img.shields.io/github/contributors/fastn-stack/fastn?color=dark-green)](h"
  },
  {
    "path": "SECURITY.md",
    "chars": 457,
    "preview": "# Security Policy\n\n## Supported Versions\n\nWe are in early development phase of this project, and only support the latest"
  },
  {
    "path": "WINDOWS_INSTALLER.md",
    "chars": 3204,
    "preview": "# Fastn Windows Installer\n\n## Introduction\n\nThe Windows installer for Fastn is built using NSIS (Nullsoft Scriptable Ins"
  },
  {
    "path": "clift/Cargo.toml",
    "chars": 308,
    "preview": "[package]\nname = \"clift\"\nversion = \"0.1.6\"\nedition.workspace = true\nrust-version.workspace = true\n\n[dependencies]\nclap.w"
  },
  {
    "path": "clift/src/api/commit_upload.rs",
    "chars": 1043,
    "preview": "fn endpoint() -> String {\n    clift::api::endpoint(\"commit-upload\")\n}\n\n#[derive(serde::Serialize)]\npub struct CommitUplo"
  },
  {
    "path": "clift/src/api/initiate_upload.rs",
    "chars": 2969,
    "preview": "fn endpoint() -> String {\n    clift::api::endpoint(\"initiate-upload\")\n}\n\n#[derive(serde::Serialize)]\npub enum InitiateUp"
  },
  {
    "path": "clift/src/api/mod.rs",
    "chars": 783,
    "preview": "pub mod commit_upload;\npub mod initiate_upload;\n\npub use commit_upload::{CommitUploadError, CommitUploadRequest, commit_"
  },
  {
    "path": "clift/src/commands/mod.rs",
    "chars": 72,
    "preview": "mod upload;\n\npub use upload::{UploadError, upload_file, upload_folder};\n"
  },
  {
    "path": "clift/src/commands/upload.rs",
    "chars": 4289,
    "preview": "pub async fn upload_file(\n    site_slug: &str,\n    file: &str,\n    dry_run: bool,\n) -> Result<(), crate::commands::uploa"
  },
  {
    "path": "clift/src/lib.rs",
    "chars": 1892,
    "preview": "#![deny(unused_crate_dependencies)]\n\nextern crate self as clift;\n\npub mod commands;\n\npub mod api;\npub mod utils;\n\npub fn"
  },
  {
    "path": "clift/src/utils/call_api.rs",
    "chars": 813,
    "preview": "pub async fn call_api(\n    mut request_builder: reqwest::RequestBuilder,\n    token: &clift::utils::UpdateToken,\n) -> req"
  },
  {
    "path": "clift/src/utils/generate_hash.rs",
    "chars": 674,
    "preview": "// Warning: this function is used in `ft` too which checks the changes in the\n// file content and hence ensures that onl"
  },
  {
    "path": "clift/src/utils/get_local_files.rs",
    "chars": 1825,
    "preview": "#[derive(Debug, thiserror::Error)]\npub enum GetLocalFilesError {\n    #[error(\"CanNotReadFile {1}: {0}\")]\n    CantReadFil"
  },
  {
    "path": "clift/src/utils/github_token.rs",
    "chars": 707,
    "preview": "pub struct GithubOidcActionToken {\n    pub token: String,\n    pub url: String,\n}\n\n#[derive(Debug, thiserror::Error)]\npub"
  },
  {
    "path": "clift/src/utils/mod.rs",
    "chars": 526,
    "preview": "mod call_api;\nmod generate_hash;\nmod get_local_files;\nmod github_token;\nmod site_token;\nmod update_token;\nmod uploader;\n"
  },
  {
    "path": "clift/src/utils/site_token.rs",
    "chars": 182,
    "preview": "pub struct SiteToken(pub String);\n\nimpl SiteToken {\n    pub fn from_env() -> Result<Self, std::env::VarError> {\n        "
  },
  {
    "path": "clift/src/utils/update_token.rs",
    "chars": 828,
    "preview": "pub enum UpdateToken {\n    SiteToken(clift::utils::SiteToken),\n    GithubToken(clift::utils::GithubOidcActionToken),\n}\n\n"
  },
  {
    "path": "clift/src/utils/uploader.rs",
    "chars": 2004,
    "preview": "pub enum Uploader {\n    File(tokio::fs::File),\n    S3(clift::api::PreSignedRequest, Vec<u8>),\n}\n\n#[derive(thiserror::Err"
  },
  {
    "path": "design/README.md",
    "chars": 553,
    "preview": "# FPM Design\n\nDownload art from https://github.com/vitiral/artifact/releases/tag/1.0.1\n\nUnzip the `art` binary and move "
  },
  {
    "path": "design/apps.toml",
    "chars": 1258,
    "preview": "[REQ-app]\npartof = [\n    'REQ-package_manager-fpm_ftd',\n    'REQ-package_manager-main',\n    'REQ-purpose',\n]\ntext = '''\n"
  },
  {
    "path": "design/cli.toml",
    "chars": 930,
    "preview": "[REQ-cli]\npartof = 'REQ-purpose'\ntext = '''\nFPM is shipped as a CLI tool.\n\nIt contains the following main comments:\n\n- ["
  },
  {
    "path": "design/design-system.toml",
    "chars": 598,
    "preview": "[REQ-design_system]\npartof = 'REQ-purpose'\ntext = '''\nFPM comes with a design system for ensuring websites authors can u"
  },
  {
    "path": "design/dynamic.toml",
    "chars": 185,
    "preview": "[REQ-dynamic]\npartof = [\n    'REQ-purpose',\n    'REQ-server',\n    'REQ-ssg',\n]\ntext = 'FPM normally serves the content o"
  },
  {
    "path": "design/font.toml",
    "chars": 423,
    "preview": "[REQ-font]\npartof = [\n    'REQ-purpose',\n    'REQ-server',\n    'REQ-ssg',\n]\ntext = '''\nWebsites powered by FPM need font"
  },
  {
    "path": "design/github.md",
    "chars": 907,
    "preview": "# How Does Github Login Work?\n\nThe auth related stuff is in `fastn_core::auth` module.\n\n## Login\n\nTo login we send user "
  },
  {
    "path": "design/js-runtime/README.md",
    "chars": 888,
    "preview": "# O.4 Release\n\n- prototype stage\n  - [x] bug: node issue\n  - [x] amitu: quickjs issue\n  - [x] arpita: bug: infinite loop"
  },
  {
    "path": "design/js-runtime/building.md",
    "chars": 725,
    "preview": "# Building\n\n## Debugging\n\n```sh\npython3 -m http.server\n```\n\n## To Run Manual Tests\n\nRun this from `ftd` folder.\n\nThis wi"
  },
  {
    "path": "design/js-runtime/compilation.md",
    "chars": 4277,
    "preview": "# Compilation Of FTD to JS\n\n## Naming Convention\n\nFor every symbol in ftd, we will have a corresponding symbol in JS. We"
  },
  {
    "path": "design/js-runtime/crate.md",
    "chars": 145,
    "preview": "# Rust Create: `fastn-js-runtime` (create alias `js_runtime`)\n\nWe will need a crate to convert the output of ftd interpr"
  },
  {
    "path": "design/js-runtime/dynamic-class-css.md",
    "chars": 2160,
    "preview": "# How are we adding CSS properties to a node?\n\nEarlier, we used to provide inline styles in DOM node. Now, we are using "
  },
  {
    "path": "design/js-runtime/list.md",
    "chars": 2063,
    "preview": "# How Do We Handle Lists?\n\n```ftd\n-- person $p: H\n\n-- person list people:\n\n-- person: A\n-- person: B\n-- person: $p\n\n-- e"
  },
  {
    "path": "design/js-runtime/markdown.md",
    "chars": 1818,
    "preview": "# How Are We Handling Markdown?\n\nMarkdown parser creates a tree, with items like h1, link, list etc. We currently render"
  },
  {
    "path": "design/js-runtime/markup.md",
    "chars": 2986,
    "preview": "# Markup\n\nWe have ftd specific extension to markdown, we call it `markup`. `markup` allows you to refer to specific comp"
  },
  {
    "path": "design/js-runtime/registry.md",
    "chars": 2313,
    "preview": "# Component and Variable Registry\n\nWe are generating JS like this:\n\n```js\nfunction main (root) {\n    let x = fastn.mutab"
  },
  {
    "path": "design/js-runtime/roles.md",
    "chars": 4301,
    "preview": "# roles\n\nSome properties are not just values, but roles. The exact value that gets attached to the DOM depends on the ro"
  },
  {
    "path": "design/js-runtime/ssr.md",
    "chars": 1276,
    "preview": "# Server Side Rendering\n\nWe have to send fully rendered HTML to crawlers. Since in `fastn build` we can not serve differ"
  },
  {
    "path": "design/js-runtime/syntax.md",
    "chars": 4177,
    "preview": "# Syntax Highlighting\n\nWe are only implementing static parsing for now. In 0.4 we will continue to use syntect highlight"
  },
  {
    "path": "design/js-runtime/which-quick-js.md",
    "chars": 520,
    "preview": "# Which wrapper of quickjs to use?\n\nTo run javascript code in rust, we need to use a wrapper of quickjs. We have two opt"
  },
  {
    "path": "design/new-design.md",
    "chars": 8521,
    "preview": "# FTD to HTML\n\n## How can we do this in 0.5?\n\nWe go `String, String` (document-id, source code) -> `ftd:p1::Section`\nthe"
  },
  {
    "path": "design/package-manager.toml",
    "chars": 1086,
    "preview": "[REQ-package_manager]\npartof = 'REQ-purpose'\ntext = 'FPM acts as a package manager for FTD files. FPM packages can be us"
  },
  {
    "path": "design/processors.toml",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "design/purpose.toml",
    "chars": 201,
    "preview": "[REQ-purpose]\ntext = '''\nFPM is a [[REQ-cli]] that serves as:\n\n- [[REQ-ssg]]: static site generator\n- [[REQ-package_mana"
  },
  {
    "path": "design/routes.toml",
    "chars": 895,
    "preview": "[REQ-routes]\npartof = [\n    'REQ-cli-build',\n    'REQ-cli-serve',\n    'REQ-dynamic',\n    'REQ-ssg',\n]\ntext = '''\nFPM ser"
  },
  {
    "path": "design/runtime/README.md",
    "chars": 420,
    "preview": "# Design Of `fastn_runtime`\n\n- [compilation of `.ftd` file to `.wasm`](compilation.md)\n- [data layer, how is data store "
  },
  {
    "path": "design/runtime/browser.md",
    "chars": 1365,
    "preview": "# Browser\n\n[Back To Design Home](./).\n\n`fastn_runtime` uses `WebAssembly` for executing functions defined in the ftd fil"
  },
  {
    "path": "design/runtime/build.md",
    "chars": 2509,
    "preview": "# Building For Browser\n\nWe have to build two wasm files, `doc.wasm` and `runtime.wasm`. `doc.wasm` is built using [the c"
  },
  {
    "path": "design/runtime/compilation.md",
    "chars": 316,
    "preview": "# Compilation\n\n[Back To Design Home](./).\n\n`fastn-runtime` crate uses `wasm` to render all ftd programs. The input ftd f"
  },
  {
    "path": "design/runtime/data-layer.md",
    "chars": 175,
    "preview": "# Data Layer\n\n[Back To Design Home](./).\n\n`doc.ftd` gets compiled into `doc.wasm` (read [`compilation.md`](compilation.m"
  },
  {
    "path": "design/runtime/dom.md",
    "chars": 2842,
    "preview": "# Dom\n\n[Back To Design Home](./).\n\nWe have two operating modes. In `internal-dom` mode we maintain full DOM tree, and in"
  },
  {
    "path": "design/runtime/features.md",
    "chars": 139,
    "preview": "# Features Used In This Crate\n\nWe have 4 main compilation targets for this crate:\n\n1. browser\n2. fastn serve/fastn build"
  },
  {
    "path": "design/runtime/linking.md",
    "chars": 4331,
    "preview": "# `linker.js`\n\n[Back To Design Home](./).\n\nRead [`browser.md`](browser.md) first for context.\n\nOnce `doc.html` loads, it"
  },
  {
    "path": "design/runtime/ssr.md",
    "chars": 2769,
    "preview": "# Main On Server Vs Main In Browser\n\n[Back To Design Home](./).\n\nOr, to ssr or not?\n\nWe have two main way to construct t"
  },
  {
    "path": "design/runtime/strings.md",
    "chars": 1967,
    "preview": "# Strings\n\n[Back To Design Home](./).\n\nWe store strings like everything else in `fastn_runtime::Memory.string`.\n\n## Stri"
  },
  {
    "path": "design/server.toml",
    "chars": 238,
    "preview": "[REQ-server]\npartof = 'REQ-purpose'\ntext = 'FPM acts a HTTP server. It can be used to preview the package content locall"
  },
  {
    "path": "design/sitemap.toml",
    "chars": 124,
    "preview": "[REQ-sitemap]\npartof = 'REQ-purpose'\ntext = 'FPM packages can contain a sitemap. Sitemap is used to organise your websit"
  },
  {
    "path": "design/ssg.toml",
    "chars": 425,
    "preview": "[REQ-ssg]\npartof = 'REQ-purpose'\ntext = '''\nFPM can be used as a static site generator.\n\nFPM converts a bunch of ftd and"
  },
  {
    "path": "events.diff",
    "chars": 2878,
    "preview": "diff --git a/fastn-js/js/ftd.js b/fastn-js/js/ftd.js\nindex 9ec65539e..0e4ebe486 100644\n--- a/fastn-js/js/ftd.js\n+++ b/fa"
  },
  {
    "path": "fastn/Cargo.toml",
    "chars": 841,
    "preview": "[package]\nname = \"fastn\"\nversion = \"0.4.113\"\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = true\n"
  },
  {
    "path": "fastn/src/main.rs",
    "chars": 16492,
    "preview": "#![deny(unused_extern_crates)]\n#![deny(unused_crate_dependencies)]\n\npub fn main() {\n    fastn_observer::observe();\n\n    "
  },
  {
    "path": "fastn-builtins/Cargo.toml",
    "chars": 364,
    "preview": "[package]\nname = \"fastn-builtins\"\nversion = \"0.1.0\"\nauthors.workspace = true\nedition.workspace = true\ndescription.worksp"
  },
  {
    "path": "fastn-builtins/src/constants.rs",
    "chars": 21014,
    "preview": "pub static FTD_HIGHLIGHTER: std::sync::LazyLock<regex::Regex> =\n    std::sync::LazyLock::new(|| regex::Regex::new(r\"((;;"
  },
  {
    "path": "fastn-builtins/src/lib.rs",
    "chars": 738555,
    "preview": "#![allow(clippy::derive_partial_eq_without_eq, clippy::get_first)]\n#![warn(clippy::used_underscore_binding)]\n\nextern cra"
  },
  {
    "path": "fastn-context/Cargo.toml",
    "chars": 365,
    "preview": "[package]\nname = \"fastn-context\"\nversion = \"0.1.0\"\nauthors.workspace = true\nedition.workspace = true\ndescription.workspa"
  },
  {
    "path": "fastn-context/NEXT-complete-design.md",
    "chars": 29058,
    "preview": "# fastn-context: Hierarchical Application Context for Debugging and Operations\n\nThis crate provides a hierarchical conte"
  },
  {
    "path": "fastn-context/NEXT-counters.md",
    "chars": 1013,
    "preview": "# NEXT: Global Counter Storage System\n\nFeatures for persistent counter tracking with dotted path keys.\n\n## Counter Types"
  },
  {
    "path": "fastn-context/NEXT-locks.md",
    "chars": 897,
    "preview": "# NEXT: Named Locks and Deadlock Detection\n\nFeatures for named lock monitoring and deadlock detection.\n\n## Named Lock Ty"
  },
  {
    "path": "fastn-context/NEXT-metrics-and-data.md",
    "chars": 3562,
    "preview": "# NEXT: Metrics and Data Storage\n\nFeatures for storing metrics and arbitrary data on contexts for debugging and monitori"
  },
  {
    "path": "fastn-context/NEXT-monitoring.md",
    "chars": 926,
    "preview": "# NEXT: Comprehensive Monitoring System\n\nFeatures planned for future implementation after basic Context system is workin"
  },
  {
    "path": "fastn-context/NEXT-operation-tracking.md",
    "chars": 2717,
    "preview": "# NEXT: Operation Tracking for Precise Debugging\n\nFeatures for tracking exactly where tasks are stuck using named await "
  },
  {
    "path": "fastn-context/NEXT-status-distribution.md",
    "chars": 1064,
    "preview": "# NEXT: P2P Status Distribution\n\nFeatures for distributed status monitoring over P2P network.\n\n## Remote Status Access\n\n"
  },
  {
    "path": "fastn-context/README-FULL.md",
    "chars": 29058,
    "preview": "# fastn-context: Hierarchical Application Context for Debugging and Operations\n\nThis crate provides a hierarchical conte"
  },
  {
    "path": "fastn-context/README.md",
    "chars": 10585,
    "preview": "# fastn-context: Hierarchical Application Context for Debugging and Operations\n\nThis crate provides a hierarchical conte"
  },
  {
    "path": "fastn-context/examples/minimal_test.rs",
    "chars": 2479,
    "preview": "/// Test the minimal fastn-context API needed for fastn-p2p integration\n/// This validates our basic Context design befo"
  },
  {
    "path": "fastn-context/src/context.rs",
    "chars": 5111,
    "preview": "/// Hierarchical context for task management and cancellation\npub struct Context {\n    /// Context name for debugging\n  "
  },
  {
    "path": "fastn-context/src/lib.rs",
    "chars": 368,
    "preview": "#![warn(unused_extern_crates)]\n#![deny(unused_crate_dependencies)]\n\nuse tokio as _; // used by main macro\nuse tokio_util"
  },
  {
    "path": "fastn-context/src/status.rs",
    "chars": 4307,
    "preview": "/// Status snapshot of the context tree\n#[derive(Debug, Clone)]\npub struct Status {\n    pub global_context: ContextStatu"
  },
  {
    "path": "fastn-context-macros/Cargo.toml",
    "chars": 377,
    "preview": "[package]\nname = \"fastn-context-macros\"\nversion = \"0.1.0\"\nauthors.workspace = true\nedition.workspace = true\ndescription."
  },
  {
    "path": "fastn-context-macros/src/lib.rs",
    "chars": 1158,
    "preview": "use proc_macro::TokenStream;\nuse quote::quote;\nuse syn::{ItemFn, parse_macro_input};\n\n/// Main function attribute macro "
  },
  {
    "path": "fastn-core/Cargo.toml",
    "chars": 1668,
    "preview": "[package]\nname = \"fastn-core\"\nversion = \"0.1.0\"\nauthors.workspace = true\nedition.workspace = true\nlicense.workspace = tr"
  },
  {
    "path": "fastn-core/bot_user_agents.txt",
    "chars": 444,
    "preview": "Googlebot\nGoogle-InspectionTool\nGoogleOther\nGoogle-Extended\nGooglebot-Image\nGooglebot-News\nGooglebot-Video\nStorebot-Goog"
  },
  {
    "path": "fastn-core/fastn.js",
    "chars": 5647,
    "preview": "(function () {\n    const FPM_IS_FALLBACK = \"fpm#is-fallback\";\n    const FPM_TRANSLATION_DIFF_OPEN = \"fpm#translation-dif"
  },
  {
    "path": "fastn-core/fastn2022.js",
    "chars": 4168,
    "preview": "(function() {\n    /*! instant.page v5.1.0 - (C) 2019-2020 Alexandre Dieulot - https://instant.page/license */\n    let t,"
  },
  {
    "path": "fastn-core/fbt-tests/01-help/cmd.p1",
    "chars": 805,
    "preview": "-- fbt:\ncmd: $FBT_CWD/../target/debug/fastn --test --help\n\nWill have to be updated every time version changes.\n\n-- stdou"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/cmd.p1",
    "chars": 395,
    "preview": "-- fbt:\ncmd: cd amitu && $FBT_CWD/../target/debug/fastn --test build --edition 2022 --ignore-failed\noutput: amitu/.build"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/input/.fastn.ftd",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/input/amitu/FASTN.ftd",
    "chars": 185,
    "preview": "-- import: fastn\n\n-- fastn.package: www.amitu.com\ndownload-base-url: amitu\ncanonical-url: https://some-other-site.com/\nz"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/input/amitu/fail_doc.ftd",
    "chars": 47,
    "preview": "-- import: xyz\n\n-- xyz.dummy_component: Caption"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/input/amitu/index.ftd",
    "chars": 1049,
    "preview": "-- ftd.document: My title\ntitle if { !flag }: MY TITLE\nog-title if { !flag }: MY OG TITLE\ndescription: MY DESCRIPTION\nog"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/output/FASTN.ftd",
    "chars": 185,
    "preview": "-- import: fastn\n\n-- fastn.package: www.amitu.com\ndownload-base-url: amitu\ncanonical-url: https://some-other-site.com/\nz"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js",
    "chars": 43513,
    "preview": "\"use strict\";\nwindow.ftd = (function () {\n    let ftd_data = {};\n    let exports = {};\n    // Setting up default value o"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/output/default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css",
    "chars": 2848,
    "preview": "*, :after, :before {\n    box-sizing: inherit;\n}\n\n*, pre, div {\n    padding: 0;\n    margin: 0;\n    gap: 0;\n    outline: n"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/output/fail_doc.ftd",
    "chars": 47,
    "preview": "-- import: xyz\n\n-- xyz.dummy_component: Caption"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/output/index.ftd",
    "chars": 1049,
    "preview": "-- ftd.document: My title\ntitle if { !flag }: MY TITLE\nog-title if { !flag }: MY OG TITLE\ndescription: MY DESCRIPTION\nog"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/output/index.html",
    "chars": 25383,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" style=\"height: 100%;\">\n<head>\n<meta charset=\"UTF-8\"><base href=\"/\">\n<meta name=\"viewport"
  },
  {
    "path": "fastn-core/fbt-tests/02-hello/output/manifest.json",
    "chars": 656,
    "preview": "{\n  \"files\": {\n    \"FASTN.ftd\": {\n      \"name\": \"FASTN.ftd\",\n      \"checksum\": \"FC694BA4CFBB582F3EA48B5AB0C7F380E76271D1"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/cmd.p1",
    "chars": 387,
    "preview": "-- fbt:\ncmd: cd amitu && $FBT_CWD/../target/debug/fastn --test build --edition 2022\noutput: amitu/.build\n\n\n-- stdout:\n\nN"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/input/.fpm.ftd",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/input/amitu/FASTN.ftd",
    "chars": 133,
    "preview": "-- import: fastn\n\n-- fastn.package: amitu\ndownload-base-url: amitu\nzip: https://codeload.github.com/amitu/dotcom/zip/ref"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/input/amitu/index.ftd",
    "chars": 18,
    "preview": "-- ftd.text: hello"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/input/amitu/nested/document.ftd",
    "chars": 28,
    "preview": "-- ftd.text: nested document"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/input/amitu/nested/index.ftd",
    "chars": 73,
    "preview": "-- ftd.text: This should be rendered inside amitu/nested/index/index.html"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/FASTN.ftd",
    "chars": 133,
    "preview": "-- import: fastn\n\n-- fastn.package: amitu\ndownload-base-url: amitu\nzip: https://codeload.github.com/amitu/dotcom/zip/ref"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js",
    "chars": 43513,
    "preview": "\"use strict\";\nwindow.ftd = (function () {\n    let ftd_data = {};\n    let exports = {};\n    // Setting up default value o"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css",
    "chars": 2848,
    "preview": "*, :after, :before {\n    box-sizing: inherit;\n}\n\n*, pre, div {\n    padding: 0;\n    margin: 0;\n    gap: 0;\n    outline: n"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/index.ftd",
    "chars": 18,
    "preview": "-- ftd.text: hello"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/index.html",
    "chars": 11930,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" style=\"height: 100%;\">\n<head>\n<meta charset=\"UTF-8\"><base href=\"/\">\n<meta name=\"viewport"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/manifest.json",
    "chars": 838,
    "preview": "{\n  \"files\": {\n    \"FASTN.ftd\": {\n      \"name\": \"FASTN.ftd\",\n      \"checksum\": \"559F3A361A9CBB52F16F2EEF4DDF10AE07DF04A6"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/nested/document/index.html",
    "chars": 11940,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" style=\"height: 100%;\">\n<head>\n<meta charset=\"UTF-8\"><base href=\"/\">\n<meta name=\"viewport"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/nested/document.ftd",
    "chars": 28,
    "preview": "-- ftd.text: nested document"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/nested/index.ftd",
    "chars": 73,
    "preview": "-- ftd.text: This should be rendered inside amitu/nested/index/index.html"
  },
  {
    "path": "fastn-core/fbt-tests/03-nested-document/output/nested/index.html",
    "chars": 11985,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" style=\"height: 100%;\">\n<head>\n<meta charset=\"UTF-8\"><base href=\"/\">\n<meta name=\"viewport"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/cmd.p1",
    "chars": 328,
    "preview": "-- fbt:\ncmd: cd amitu && $FBT_CWD/../target/debug/fastn --test build --edition 2022\noutput: amitu/.build\n\n\n-- stdout:\n\nN"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/input/.fpm.ftd",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/input/amitu/FASTN.ftd",
    "chars": 108,
    "preview": "-- import: fastn\n\n-- fastn.package: amitu\nzip: https://codeload.github.com/amitu/dotcom/zip/refs/heads/main\n"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/input/amitu/index.ftd",
    "chars": 89,
    "preview": "-- import: amitu/lib\n\n-- lib.block:\n\n-- ftd.text:\n\nHeading 1 content\n\n\n-- end: lib.block\n"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/input/amitu/lib.ftd",
    "chars": 134,
    "preview": "-- component block:\nchildren wrapper:\n\n-- ftd.row:\nbackground.solid: #000000\nchildren: $block.wrapper\n\n-- end: ftd.row\n\n"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/output/FASTN.ftd",
    "chars": 108,
    "preview": "-- import: fastn\n\n-- fastn.package: amitu\nzip: https://codeload.github.com/amitu/dotcom/zip/refs/heads/main\n"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js",
    "chars": 43513,
    "preview": "\"use strict\";\nwindow.ftd = (function () {\n    let ftd_data = {};\n    let exports = {};\n    // Setting up default value o"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/output/default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css",
    "chars": 2848,
    "preview": "*, :after, :before {\n    box-sizing: inherit;\n}\n\n*, pre, div {\n    padding: 0;\n    margin: 0;\n    gap: 0;\n    outline: n"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/output/index.ftd",
    "chars": 89,
    "preview": "-- import: amitu/lib\n\n-- lib.block:\n\n-- ftd.text:\n\nHeading 1 content\n\n\n-- end: lib.block\n"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/output/index.html",
    "chars": 12070,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" style=\"height: 100%;\">\n<head>\n<meta charset=\"UTF-8\"><base href=\"/\">\n<meta name=\"viewport"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/output/lib/index.html",
    "chars": 11864,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" style=\"height: 100%;\">\n<head>\n<meta charset=\"UTF-8\"><base href=\"/\">\n<meta name=\"viewport"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/output/lib.ftd",
    "chars": 134,
    "preview": "-- component block:\nchildren wrapper:\n\n-- ftd.row:\nbackground.solid: #000000\nchildren: $block.wrapper\n\n-- end: ftd.row\n\n"
  },
  {
    "path": "fastn-core/fbt-tests/04-import-code-block/output/manifest.json",
    "chars": 645,
    "preview": "{\n  \"files\": {\n    \"FASTN.ftd\": {\n      \"name\": \"FASTN.ftd\",\n      \"checksum\": \"D9C4CCA8AD92C095EF449652CE5310F2BBE690D9"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/cmd.p1",
    "chars": 902,
    "preview": "-- fbt:\ncmd: cd amitu && $FBT_CWD/../target/debug/fastn --test build --edition 2022\noutput: amitu/.build\n\n-- stdout:\n\nNo"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/input/.fpm.ftd",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/input/amitu/FASTN.ftd",
    "chars": 727,
    "preview": "-- import: fastn\n\n-- fastn.package: www.amitu.com\nzip: https://codeload.github.com/amitu/dotcom/zip/refs/heads/main\n\n\n--"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/input/amitu/hello/world/test.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/input/amitu/hello.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/input/amitu/index",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/input/amitu/index.ftd",
    "chars": 768,
    "preview": "-- import: www.amitu.com/assets\n\n-- ftd.type roboto:\nfont-family: $assets.fonts.Roboto\nsize.px: 10\nweight: 100\nline-heig"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/input/amitu/index.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/-/www.amitu.com/hello/world/test.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/-/www.amitu.com/hello.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/-/www.amitu.com/index",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/-/www.amitu.com/index.ftd",
    "chars": 768,
    "preview": "-- import: www.amitu.com/assets\n\n-- ftd.type roboto:\nfont-family: $assets.fonts.Roboto\nsize.px: 10\nweight: 100\nline-heig"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/FASTN.ftd",
    "chars": 727,
    "preview": "-- import: fastn\n\n-- fastn.package: www.amitu.com\nzip: https://codeload.github.com/amitu/dotcom/zip/refs/heads/main\n\n\n--"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/default-47D9AFCD179BB157D8432FE0DC7B328F231E1CDACA1CB36790A41EAC123C7461.js",
    "chars": 43513,
    "preview": "\"use strict\";\nwindow.ftd = (function () {\n    let ftd_data = {};\n    let exports = {};\n    // Setting up default value o"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/default-C5FF83A8B3723F00CC5D810569E9D4ADF83311143685244B4504BD9A34F6904F.css",
    "chars": 2848,
    "preview": "*, :after, :before {\n    box-sizing: inherit;\n}\n\n*, pre, div {\n    padding: 0;\n    margin: 0;\n    gap: 0;\n    outline: n"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/hello/world/test.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/hello.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/index",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/index.ftd",
    "chars": 768,
    "preview": "-- import: www.amitu.com/assets\n\n-- ftd.type roboto:\nfont-family: $assets.fonts.Roboto\nsize.px: 10\nweight: 100\nline-heig"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/index.html",
    "chars": 22237,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" style=\"height: 100%;\">\n<head>\n<meta charset=\"UTF-8\"><base href=\"/\">\n<meta name=\"viewport"
  },
  {
    "path": "fastn-core/fbt-tests/05-hello-font/output/manifest.json",
    "chars": 1276,
    "preview": "{\n  \"files\": {\n    \"FASTN.ftd\": {\n      \"name\": \"FASTN.ftd\",\n      \"checksum\": \"C08736376A2C9A13DFB62EDFFF1ED7D14294B962"
  },
  {
    "path": "fastn-core/fbt-tests/06-nested-document-sync/cmd.p1",
    "chars": 428,
    "preview": "-- fbt:\ncmd: cd amitu && $FBT_CWD/../target/debug/fastn --test sync index.ftd nested/document.ftd && $FBT_CWD/../target/"
  },
  {
    "path": "fastn-core/fbt-tests/06-nested-document-sync/input/.fpm.ftd",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/06-nested-document-sync/input/amitu/FASTN.ftd",
    "chars": 67,
    "preview": "-- import: fastn\n\n-- fastn.package: amitu\ndownload-base-url: amitu\n"
  },
  {
    "path": "fastn-core/fbt-tests/06-nested-document-sync/input/amitu/index.ftd",
    "chars": 18,
    "preview": "-- ftd.text: hello"
  },
  {
    "path": "fastn-core/fbt-tests/06-nested-document-sync/input/amitu/nested/document.ftd",
    "chars": 28,
    "preview": "-- ftd.text: nested document"
  },
  {
    "path": "fastn-core/fbt-tests/06-nested-document-sync/input/amitu/nested/index.ftd",
    "chars": 73,
    "preview": "-- ftd.text: This should be rendered inside amitu/nested/index/index.html"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/cmd.p1",
    "chars": 1111,
    "preview": "-- fbt:\ncmd: cd amitu && $FBT_CWD/../target/debug/fastn --test start-tracking index-track.ftd --target index.ftd && $FBT"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/.fpm.ftd",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/.history/.latest.ftd",
    "chars": 254,
    "preview": "-- import: fpm\n\n-- fpm.snapshot: FPM.ftd\ntimestamp: 1639765778133988000\n\n-- fpm.snapshot: hello.txt\ntimestamp: 163976577"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/.history/FPM.1639765778133988000.ftd",
    "chars": 57,
    "preview": "-- import: fpm\n\n-- fpm.package: www.amitu.com\nzip: amitu\n"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/.history/hello.1639765778133988000.txt",
    "chars": 12,
    "preview": "Hello World!"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/.history/index-track.1639765778133988000.ftd",
    "chars": 18,
    "preview": "-- ftd.text: hello"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/.history/index.1639765778133988000.ftd",
    "chars": 24,
    "preview": "-- ftd.text: hello world"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/FPM.ftd",
    "chars": 71,
    "preview": "-- import: fpm\n\n-- fpm.package: www.amitu.com\ndownload-base-url: amitu\n"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/hello.txt",
    "chars": 12,
    "preview": "Hello World!"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/index-track.ftd",
    "chars": 18,
    "preview": "-- ftd.text: hello"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/input/amitu/index.ftd",
    "chars": 18,
    "preview": "-- ftd.text: hello"
  },
  {
    "path": "fastn-core/fbt-tests/07-hello-tracks/output/index-track.ftd.track",
    "chars": 112,
    "preview": "-- import: fpm\n\n-- fpm.track: index.ftd\nself-timestamp: 1639765778133988000\nother-timestamp: 1639765778133988000"
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/cmd.p1",
    "chars": 423,
    "preview": "-- fbt:\ncmd: cd amitu && $FBT_CWD/../target/debug/fastn --test build\noutput: amitu/.build\n\n-- stdout:\n\nNo dependencies i"
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/input/.fpm.ftd",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/input/amitu/FASTN.ftd",
    "chars": 116,
    "preview": "-- import: fastn\n\n-- fastn.package: www.amitu.com\nzip: https://codeload.github.com/amitu/dotcom/zip/refs/heads/main\n"
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/input/amitu/index.ftd",
    "chars": 18,
    "preview": "-- ftd.text: hello"
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/output/FASTN.ftd",
    "chars": 116,
    "preview": "-- import: fastn\n\n-- fastn.package: www.amitu.com\nzip: https://codeload.github.com/amitu/dotcom/zip/refs/heads/main\n"
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/output/code-theme-06E6F84E43C61CB1653D9F4FACD46B7EBCB3CD8A48EFAEF2E5BE3E9E9212D1E6.css",
    "chars": 3428,
    "preview": "/**\n * Gruvbox light theme\n *\n * Based on Gruvbox: https://github.com/morhetz/gruvbox\n * Adapted from PrismJS gruvbox-da"
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/output/code-theme-0800A18B1822D6AFDAF807CF840379A2DB3483A1F058CA29FBCFB3815CA76148.css",
    "chars": 4459,
    "preview": "/*\nName:   Duotone Light\nAuthor: Simurai, adapted from DuoTone themes for Atom (http://simurai.com/projects/2016/01/01/d"
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/output/code-theme-0CA636E4954E3FC6184FB8000174F8EAA6C61DB10F6A18D74740E6D2032C1A2E.css",
    "chars": 2404,
    "preview": "/**\n * Dracula Theme originally by Zeno Rocha [@zenorocha]\n * https://draculatheme.com/\n *\n * Ported for PrismJS by Albe"
  },
  {
    "path": "fastn-core/fbt-tests/08-static-assets/output/code-theme-0F444C6433C356376F7E92122F6C521FE40242BEC9D9E050359EE1DF4A9D5E6D.css",
    "chars": 3213,
    "preview": "/*\n * Laserwave Theme originally by Jared Jones for Visual Studio Code\n * https://github.com/Jaredk3nt/laserwave\n *\n * P"
  }
]

// ... and 2549 more files (download for full content)

About this extraction

This page contains the full source code of the fastn-stack/fastn GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2749 files (24.2 MB), approximately 6.5M tokens, and a symbol index with 8992 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!