[{"data":1,"prerenderedAt":919},["ShallowReactive",2],{"bml-reference-examples":3},{"data":4,"body":5},{},{"type":6,"children":7},"root",[8,17,32,95,609,740,753,760,769,781,789,798,806,815,823,832,840,851,859,868,876,885,893,902,910],{"type":9,"tag":10,"props":11,"children":13},"element","h1",{"id":12},"bml-examples",[14],{"type":15,"value":16},"text","BML examples",{"type":9,"tag":18,"props":19,"children":20},"p",{},[21,23,30],{"type":15,"value":22},"Representative source files for the ",{"type":9,"tag":24,"props":25,"children":27},"a",{"href":26},"\u002Fbml-reference\u002Fgrammar",[28],{"type":15,"value":29},"current grammar",{"type":15,"value":31},". These are hand-authored\nlanguage, renderer, and integration examples.",{"type":9,"tag":18,"props":33,"children":34},{},[35,37,44,46,51,53,58,60,65,67,72,74,79,81,86,88,93],{"type":15,"value":36},"The files are meant to live in one project. ",{"type":9,"tag":38,"props":39,"children":41},"code",{"className":40},"",[42],{"type":15,"value":43},"lists.bml",{"type":15,"value":45}," uses ",{"type":9,"tag":38,"props":47,"children":48},{"className":40},[49],{"type":15,"value":50},"list-item.bml",{"type":15,"value":52}," and the generated\nclient for its ",{"type":9,"tag":38,"props":54,"children":55},{"className":40},[56],{"type":15,"value":57},"ListOps",{"type":15,"value":59}," contract; ",{"type":9,"tag":38,"props":61,"children":62},{"className":40},[63],{"type":15,"value":64},"list-ops.kt",{"type":15,"value":66}," shows the matching server implementation and\ndispatcher wiring. ",{"type":9,"tag":38,"props":68,"children":69},{"className":40},[70],{"type":15,"value":71},"task-list.bml",{"type":15,"value":73}," pairs with ",{"type":9,"tag":38,"props":75,"children":76},{"className":40},[77],{"type":15,"value":78},"task-list-view-model.kt",{"type":15,"value":80}," and reuses the same list row.\nPlace the BML files under ",{"type":9,"tag":38,"props":82,"children":83},{"className":40},[84],{"type":15,"value":85},"src\u002Fmain\u002Fbml",{"type":15,"value":87}," and the Kotlin files under ",{"type":9,"tag":38,"props":89,"children":90},{"className":40},[91],{"type":15,"value":92},"src\u002Fmain\u002Fkotlin\u002Fexample",{"type":15,"value":94},".",{"type":9,"tag":96,"props":97,"children":98},"table",{},[99,123],{"type":9,"tag":100,"props":101,"children":102},"thead",{},[103],{"type":9,"tag":104,"props":105,"children":106},"tr",{},[107,113,118],{"type":9,"tag":108,"props":109,"children":110},"th",{},[111],{"type":15,"value":112},"File",{"type":9,"tag":108,"props":114,"children":115},{},[116],{"type":15,"value":117},"Kind",{"type":9,"tag":108,"props":119,"children":120},{},[121],{"type":15,"value":122},"Notable constructs exercised",{"type":9,"tag":124,"props":125,"children":126},"tbody",{},[127,162,223,268,321,352,442,513,551],{"type":9,"tag":104,"props":128,"children":129},{},[130,138,143],{"type":9,"tag":131,"props":132,"children":133},"td",{},[134],{"type":9,"tag":38,"props":135,"children":136},{"className":40},[137],{"type":15,"value":50},{"type":9,"tag":131,"props":139,"children":140},{},[141],{"type":15,"value":142},"component",{"type":9,"tag":131,"props":144,"children":145},{},[146,148,153,155,160],{"type":15,"value":147},"a reusable list row with typed props, scoped CSS, bound and interpolated attributes, ",{"type":9,"tag":38,"props":149,"children":150},{"className":40},[151],{"type":15,"value":152},"\u003Cif>",{"type":15,"value":154},", and a default ",{"type":9,"tag":38,"props":156,"children":157},{"className":40},[158],{"type":15,"value":159},"\u003Cslot\u002F>",{"type":15,"value":161}," for row actions",{"type":9,"tag":104,"props":163,"children":164},{},[165,172,177],{"type":9,"tag":131,"props":166,"children":167},{},[168],{"type":9,"tag":38,"props":169,"children":170},{"className":40},[171],{"type":15,"value":43},{"type":9,"tag":131,"props":173,"children":174},{},[175],{"type":15,"value":176},"page",{"type":9,"tag":131,"props":178,"children":179},{},[180,182,187,189,194,196,201,203,208,210,214,216,221],{"type":15,"value":181},"a complete HTML document, ",{"type":9,"tag":38,"props":183,"children":184},{"className":40},[185],{"type":15,"value":186},"route",{"type":15,"value":188}," + typed param ",{"type":9,"tag":38,"props":190,"children":191},{"className":40},[192],{"type":15,"value":193},"{id:UUID}",{"type":15,"value":195},", ",{"type":9,"tag":38,"props":197,"children":198},{"className":40},[199],{"type":15,"value":200},"\u003Cscript server provides>",{"type":15,"value":202},", a ",{"type":9,"tag":38,"props":204,"children":205},{"className":40},[206],{"type":15,"value":207},"\u003Ccontract>",{"type":15,"value":209}," called through its generated ",{"type":9,"tag":38,"props":211,"children":212},{"className":40},[213],{"type":15,"value":57},{"type":15,"value":215}," TypeScript client, the ",{"type":9,"tag":38,"props":217,"children":218},{"className":40},[219],{"type":15,"value":220},"list-item",{"type":15,"value":222}," component, and an isolated Sortable island",{"type":9,"tag":104,"props":224,"children":225},{},[226,233,238],{"type":9,"tag":131,"props":227,"children":228},{},[229],{"type":9,"tag":38,"props":230,"children":231},{"className":40},[232],{"type":15,"value":64},{"type":9,"tag":131,"props":234,"children":235},{},[236],{"type":15,"value":237},"Kotlin contract implementation",{"type":9,"tag":131,"props":239,"children":240},{},[241,243,247,249,254,256,261,263],{"type":15,"value":242},"implements the generated ",{"type":9,"tag":38,"props":244,"children":245},{"className":40},[246],{"type":15,"value":57},{"type":15,"value":248}," server interface with the request's ",{"type":9,"tag":38,"props":250,"children":251},{"className":40},[252],{"type":15,"value":253},"GraphQLClient",{"type":15,"value":255}," and wires ",{"type":9,"tag":38,"props":257,"children":258},{"className":40},[259],{"type":15,"value":260},"ListOpsDispatcher",{"type":15,"value":262}," into ",{"type":9,"tag":38,"props":264,"children":265},{"className":40},[266],{"type":15,"value":267},"BmlServer",{"type":9,"tag":104,"props":269,"children":270},{},[271,278,282],{"type":9,"tag":131,"props":272,"children":273},{},[274],{"type":9,"tag":38,"props":275,"children":276},{"className":40},[277],{"type":15,"value":71},{"type":9,"tag":131,"props":279,"children":280},{},[281],{"type":15,"value":176},{"type":9,"tag":131,"props":283,"children":284},{},[285,287,292,294,299,301,306,308,313,315,319],{"type":15,"value":286},"a no-client-code live ViewModel with ",{"type":9,"tag":38,"props":288,"children":289},{"className":40},[290],{"type":15,"value":291},"scope=\"server-session\"",{"type":15,"value":293},", declarative ",{"type":9,"tag":38,"props":295,"children":296},{"className":40},[297],{"type":15,"value":298},"@submit",{"type":15,"value":300},"\u002F",{"type":9,"tag":38,"props":302,"children":303},{"className":40},[304],{"type":15,"value":305},"@click",{"type":15,"value":307}," actions, ",{"type":9,"tag":38,"props":309,"children":310},{"className":40},[311],{"type":15,"value":312},"form.title",{"type":15,"value":314},", island re-rendering, and slotted ",{"type":9,"tag":38,"props":316,"children":317},{"className":40},[318],{"type":15,"value":220},{"type":15,"value":320}," actions",{"type":9,"tag":104,"props":322,"children":323},{},[324,331,336],{"type":9,"tag":131,"props":325,"children":326},{},[327],{"type":9,"tag":38,"props":328,"children":329},{"className":40},[330],{"type":15,"value":78},{"type":9,"tag":131,"props":332,"children":333},{},[334],{"type":15,"value":335},"Kotlin ViewModel",{"type":9,"tag":131,"props":337,"children":338},{},[339,341,346,348],{"type":15,"value":340},"the ",{"type":9,"tag":38,"props":342,"children":343},{"className":40},[344],{"type":15,"value":345},"@Serializable",{"type":15,"value":347},", mutable server model used by ",{"type":9,"tag":38,"props":349,"children":350},{"className":40},[351],{"type":15,"value":71},{"type":9,"tag":104,"props":353,"children":354},{},[355,363,367],{"type":9,"tag":131,"props":356,"children":357},{},[358],{"type":9,"tag":38,"props":359,"children":360},{"className":40},[361],{"type":15,"value":362},"card.bml",{"type":9,"tag":131,"props":364,"children":365},{},[366],{"type":15,"value":142},{"type":9,"tag":131,"props":368,"children":369},{},[370,375,376,381,383,388,390,395,397,402,404,409,411,417,419,424,425,430,431,435,437],{"type":9,"tag":38,"props":371,"children":372},{"className":40},[373],{"type":15,"value":374},"\u003Ccomponent tag>",{"type":15,"value":195},{"type":9,"tag":38,"props":377,"children":378},{"className":40},[379],{"type":15,"value":380},"\u003Cprop>",{"type":15,"value":382}," (",{"type":9,"tag":38,"props":384,"children":385},{"className":40},[386],{"type":15,"value":387},"required",{"type":15,"value":389},", expr ",{"type":9,"tag":38,"props":391,"children":392},{"className":40},[393],{"type":15,"value":394},":default=\"null\"",{"type":15,"value":396},", attr ",{"type":9,"tag":38,"props":398,"children":399},{"className":40},[400],{"type":15,"value":401},"default=\"1\"",{"type":15,"value":403},"), component-scoped ",{"type":9,"tag":38,"props":405,"children":406},{"className":40},[407],{"type":15,"value":408},"\u003Cscript server>",{"type":15,"value":410},", attribute ",{"type":9,"tag":412,"props":413,"children":414},"strong",{},[415],{"type":15,"value":416},"spread",{"type":15,"value":418}," ",{"type":9,"tag":38,"props":420,"children":421},{"className":40},[422],{"type":15,"value":423},"{...attrs}",{"type":15,"value":195},{"type":9,"tag":38,"props":426,"children":427},{"className":40},[428],{"type":15,"value":429},"\u003Cif>\u002F\u003Celse>",{"type":15,"value":195},{"type":9,"tag":38,"props":432,"children":433},{"className":40},[434],{"type":15,"value":159},{"type":15,"value":436},", bound attr ",{"type":9,"tag":38,"props":438,"children":439},{"className":40},[440],{"type":15,"value":441},":href=\"…\"",{"type":9,"tag":104,"props":443,"children":444},{},[445,453,457],{"type":9,"tag":131,"props":446,"children":447},{},[448],{"type":9,"tag":38,"props":449,"children":450},{"className":40},[451],{"type":15,"value":452},"anchor.bml",{"type":9,"tag":131,"props":454,"children":455},{},[456],{"type":15,"value":142},{"type":9,"tag":131,"props":458,"children":459},{},[460,465,467,472,474,484,485,490,492,496,497,501,503,507,508],{"type":9,"tag":412,"props":461,"children":462},{},[463],{"type":15,"value":464},"overriding",{"type":15,"value":466}," a built-in (",{"type":9,"tag":38,"props":468,"children":469},{"className":40},[470],{"type":15,"value":471},"tag=\"a\"",{"type":15,"value":473},"), the ",{"type":9,"tag":412,"props":475,"children":476},{},[477,482],{"type":9,"tag":38,"props":478,"children":479},{"className":40},[480],{"type":15,"value":481},"html:",{"type":15,"value":483}," native escape hatch",{"type":15,"value":382},{"type":9,"tag":38,"props":486,"children":487},{"className":40},[488],{"type":15,"value":489},"\u003Chtml:a>",{"type":15,"value":491},") to avoid recursion, ",{"type":9,"tag":38,"props":493,"children":494},{"className":40},[495],{"type":15,"value":380},{"type":15,"value":195},{"type":9,"tag":38,"props":498,"children":499},{"className":40},[500],{"type":15,"value":200},{"type":15,"value":502},", bound attrs ",{"type":9,"tag":38,"props":504,"children":505},{"className":40},[506],{"type":15,"value":441},{"type":15,"value":300},{"type":9,"tag":38,"props":509,"children":510},{"className":40},[511],{"type":15,"value":512},":rel=\"…\"",{"type":9,"tag":104,"props":514,"children":515},{},[516,524,528],{"type":9,"tag":131,"props":517,"children":518},{},[519],{"type":9,"tag":38,"props":520,"children":521},{"className":40},[522],{"type":15,"value":523},"site-header.bml",{"type":9,"tag":131,"props":525,"children":526},{},[527],{"type":15,"value":142},{"type":9,"tag":131,"props":529,"children":530},{},[531,533,538,540,544,546],{"type":15,"value":532},"reusable ",{"type":9,"tag":38,"props":534,"children":535},{"className":40},[536],{"type":15,"value":537},"\u003Ccomponent>",{"type":15,"value":539},", typed prop, native HTML, default ",{"type":9,"tag":38,"props":541,"children":542},{"className":40},[543],{"type":15,"value":159},{"type":15,"value":545},", and HTML entity ",{"type":9,"tag":38,"props":547,"children":548},{"className":40},[549],{"type":15,"value":550},"&copy;",{"type":9,"tag":104,"props":552,"children":553},{},[554,562,567],{"type":9,"tag":131,"props":555,"children":556},{},[557],{"type":9,"tag":38,"props":558,"children":559},{"className":40},[560],{"type":15,"value":561},"welcome-email.bml",{"type":9,"tag":131,"props":563,"children":564},{},[565],{"type":15,"value":566},"message (email channel)",{"type":9,"tag":131,"props":568,"children":569},{},[570,572,577,578,583,585,590,591,596,597,602,604],{"type":15,"value":571},"typed message payload, localized ",{"type":9,"tag":38,"props":573,"children":574},{"className":40},[575],{"type":15,"value":576},"\u003Csubject>",{"type":15,"value":195},{"type":9,"tag":38,"props":579,"children":580},{"className":40},[581],{"type":15,"value":582},"\u003Cstyle bml-inline>",{"type":15,"value":584},", table-safe HTML, ",{"type":9,"tag":412,"props":586,"children":587},{},[588],{"type":15,"value":589},"raw output",{"type":15,"value":418},{"type":9,"tag":38,"props":592,"children":593},{"className":40},[594],{"type":15,"value":595},"{@ … }",{"type":15,"value":195},{"type":9,"tag":38,"props":598,"children":599},{"className":40},[600],{"type":15,"value":601},"\u003Cif>\u002F\u003Celse-if>\u002F\u003Celse>",{"type":15,"value":603},", and ",{"type":9,"tag":38,"props":605,"children":606},{"className":40},[607],{"type":15,"value":608},"\u003Cfor>",{"type":9,"tag":18,"props":610,"children":611},{},[612,614,619,620,624,626,631,633,637,638,643,645,649,650,655,657,662,664,669,671,675,676,680,682,686,687,691,692,697,698,703,705,710,712,717,719,724,726,731,733,738],{"type":15,"value":613},"Construct coverage (grammar §): elements\u002Fvoid\u002Fself-closing, ",{"type":9,"tag":38,"props":615,"children":616},{"className":40},[617],{"type":15,"value":618},"QName",{"type":15,"value":300},{"type":9,"tag":38,"props":621,"children":622},{"className":40},[623],{"type":15,"value":481},{"type":15,"value":625}," (§3.1, §7);\nstatic \u002F bound (",{"type":9,"tag":38,"props":627,"children":628},{"className":40},[629],{"type":15,"value":630},":attr=\"expr\"",{"type":15,"value":632},") \u002F spread attributes (§3.2); ",{"type":9,"tag":38,"props":634,"children":635},{"className":40},[636],{"type":15,"value":408},{"type":15,"value":300},{"type":9,"tag":38,"props":639,"children":640},{"className":40},[641],{"type":15,"value":642},"\u003Cscript client>",{"type":15,"value":644},"\u002F\n",{"type":9,"tag":38,"props":646,"children":647},{"className":40},[648],{"type":15,"value":207},{"type":15,"value":300},{"type":9,"tag":38,"props":651,"children":652},{"className":40},[653],{"type":15,"value":654},"\u003Cstyle>",{"type":15,"value":656}," raw regions (§3.3); ",{"type":9,"tag":38,"props":658,"children":659},{"className":40},[660],{"type":15,"value":661},"\u003Cpage>",{"type":15,"value":663}," (§4.1); component ",{"type":9,"tag":38,"props":665,"children":666},{"className":40},[667],{"type":15,"value":668},"\u003Cslot>",{"type":15,"value":670}," (§4.2);\n",{"type":9,"tag":38,"props":672,"children":673},{"className":40},[674],{"type":15,"value":537},{"type":15,"value":300},{"type":9,"tag":38,"props":677,"children":678},{"className":40},[679],{"type":15,"value":380},{"type":15,"value":681}," (§4.3); ",{"type":9,"tag":38,"props":683,"children":684},{"className":40},[685],{"type":15,"value":608},{"type":15,"value":300},{"type":9,"tag":38,"props":688,"children":689},{"className":40},[690],{"type":15,"value":152},{"type":15,"value":300},{"type":9,"tag":38,"props":693,"children":694},{"className":40},[695],{"type":15,"value":696},"\u003Celse-if>",{"type":15,"value":300},{"type":9,"tag":38,"props":699,"children":700},{"className":40},[701],{"type":15,"value":702},"\u003Celse>",{"type":15,"value":704}," (§4.4); ",{"type":9,"tag":38,"props":706,"children":707},{"className":40},[708],{"type":15,"value":709},"\u003Cdata>",{"type":15,"value":711}," (§4.5);\n",{"type":9,"tag":38,"props":713,"children":714},{"className":40},[715],{"type":15,"value":716},"\u003Cisland>",{"type":15,"value":718}," (§4.6); ",{"type":9,"tag":38,"props":720,"children":721},{"className":40},[722],{"type":15,"value":723},"provides",{"type":15,"value":725}," scope + route params + props (§5); live ViewModels and declarative\nserver actions; expressions and ",{"type":9,"tag":38,"props":727,"children":728},{"className":40},[729],{"type":15,"value":730},"{@ }",{"type":15,"value":732}," raw output (§6, §8); comments ",{"type":9,"tag":38,"props":734,"children":735},{"className":40},[736],{"type":15,"value":737},"{# #}",{"type":15,"value":739}," (§2.2).",{"type":9,"tag":18,"props":741,"children":742},{},[743,745,751],{"type":15,"value":744},"Deferred islands and declarative server actions are covered in the ",{"type":9,"tag":24,"props":746,"children":748},{"href":747},"\u002Fbml-reference\u002Fislands",[749],{"type":15,"value":750},"islands reference",{"type":15,"value":752},".\nFeatures still reserved for future work are listed in grammar §10.",{"type":9,"tag":754,"props":755,"children":757},"h2",{"id":756},"source-files",[758],{"type":15,"value":759},"Source files",{"type":9,"tag":761,"props":762,"children":764},"h3",{"id":763},"anchorbml",[765],{"type":9,"tag":38,"props":766,"children":767},{"className":40},[768],{"type":15,"value":452},{"type":9,"tag":770,"props":771,"children":776},"pre",{"className":772,"code":774,"filename":-1,"highlights":-1,"language":775,"meta":40},[773],"language-bml","{# Component: override the built-in `a` tag.\n   Exercises: overriding an overrideable built-in, the `html:` native escape hatch\n   (so emitting an anchor does not recurse into this override), and a server `provides`.\n   Protected tags (page\u002Fisland\u002Ffor\u002F…) cannot be overridden this way. #}\n\u003Ccomponent tag=\"a\">\n  \u003Cprop name=\"href\" type=\"String\" required\u002F>\n  \u003Cprop name=\"external\" type=\"Boolean\" default=\"false\"\u002F>\n\n  \u003Cscript server provides=\"rel\">\n    if (external) \"noopener noreferrer\" else null\n  \u003C\u002Fscript>\n\n  \u003Chtml:a :href=\"href\" :rel=\"rel\" data-tracked=\"true\">\n    \u003Cslot\u002F>\n  \u003C\u002Fhtml:a>\n\u003C\u002Fcomponent>\n","bml",[777],{"type":9,"tag":38,"props":778,"children":779},{"__ignoreMap":40},[780],{"type":15,"value":774},{"type":9,"tag":761,"props":782,"children":784},{"id":783},"cardbml",[785],{"type":9,"tag":38,"props":786,"children":787},{"className":40},[788],{"type":15,"value":362},{"type":9,"tag":770,"props":790,"children":793},{"className":791,"code":792,"filename":-1,"highlights":-1,"language":775,"meta":40},[773],"{# Component: a reusable `card` tag.\n   Exercises: \u003Ccomponent tag>, typed \u003Cprop> (required \u002F expr default \u002F attr default),\n   a component-scoped \u003Cscript server>, interpolation in attributes, \u003Cif>\u002F\u003Celse>, \u003Cslot>. #}\n\u003Ccomponent tag=\"card\">\n  \u003Cprop name=\"title\" type=\"String\" required\u002F>\n  \u003Cprop name=\"href\" type=\"String?\" :default=\"null\"\u002F>\n  \u003Cprop name=\"elevation\" type=\"Int\" default=\"1\"\u002F>\n\n  \u003Carticle class=\"card card-elev-{ elevation }\" {...attrs}>\n    \u003Cheader class=\"card-head\">\n      \u003Cif href != null>\n        \u003Ca :href=\"href\">{ title }\u003C\u002Fa>\n      \u003Celse>\n        \u003Ch3>{ title }\u003C\u002Fh3>\n      \u003C\u002Fif>\n    \u003C\u002Fheader>\n    \u003Cdiv class=\"card-body\">\n      \u003Cslot\u002F>\n    \u003C\u002Fdiv>\n  \u003C\u002Farticle>\n\u003C\u002Fcomponent>\n",[794],{"type":9,"tag":38,"props":795,"children":796},{"__ignoreMap":40},[797],{"type":15,"value":792},{"type":9,"tag":761,"props":799,"children":801},{"id":800},"list-itembml",[802],{"type":9,"tag":38,"props":803,"children":804},{"className":40},[805],{"type":15,"value":50},{"type":9,"tag":770,"props":807,"children":810},{"className":808,"code":809,"filename":-1,"highlights":-1,"language":775,"meta":40},[773],"{# Reusable row rendered by lists.bml and task-list.bml. #}\n\u003Ccomponent tag=\"list-item\">\n  \u003Cprop name=\"id\" type=\"String\" required\u002F>\n  \u003Cprop name=\"label\" type=\"String\" required\u002F>\n  \u003Cprop name=\"pinned\" type=\"Boolean\" default=\"false\"\u002F>\n  \u003Cprop name=\"position\" type=\"Int\" required\u002F>\n\n  \u003Cstyle scoped>\n    .item { display: flex; align-items: center; gap: 0.75rem; }\n    .label { flex: 1; }\n    .badge { font-size: 0.75rem; text-transform: uppercase; }\n  \u003C\u002Fstyle>\n\n  \u003Cli :data-id=\"id\" class=\"item item-{ position }\">\n    \u003Cspan class=\"label\">{ label }\u003C\u002Fspan>\n    \u003Cif pinned>\n      \u003Cspan class=\"badge\">pinned\u003C\u002Fspan>\n    \u003C\u002Fif>\n    \u003Cslot\u002F>\n  \u003C\u002Fli>\n\u003C\u002Fcomponent>\n",[811],{"type":9,"tag":38,"props":812,"children":813},{"__ignoreMap":40},[814],{"type":15,"value":809},{"type":9,"tag":761,"props":816,"children":818},{"id":817},"listsbml",[819],{"type":9,"tag":38,"props":820,"children":821},{"className":40},[822],{"type":15,"value":43},{"type":9,"tag":770,"props":824,"children":827},{"className":825,"code":826,"filename":-1,"highlights":-1,"language":775,"meta":40},[773],"{# Page: a sortable list.\n   `ListOps` is compiled into a typed TypeScript client and a Kotlin dispatcher.\n   `list-item` comes from list-item.bml in the same BML source set. #}\n\u003Cpage route=\"\u002Flists\u002F{id:UUID}\">\n\n  \u003Cscript server provides=\"listView\">\n    \u002F\u002F `bosca` is the generated typed Kotlin GraphQL client; GetListView is a generated operation.\n    bosca.query(GetListView(id = id)).list\n  \u003C\u002Fscript>\n\n  \u003Ccontract>\n    interface ListOps {\n        suspend fun reorder(listId: String, ids: List\u003CString>)\n    }\n  \u003C\u002Fcontract>\n\n  \u003Chtml lang=\"en\">\n    \u003Chead>\u003Ctitle>{ listView.title }\u003C\u002Ftitle>\u003C\u002Fhead>\n    \u003Cbody>\n      \u003Cheader class=\"list-header\">\n        \u003Ch1>{ listView.title }\u003C\u002Fh1>\n        \u003Cif listView.items.isEmpty()>\n          \u003Cp class=\"empty\">This list has no items yet.\u003C\u002Fp>\n        \u003Celse>\n          \u003Cp class=\"count\">{ listView.items.size } items\u003C\u002Fp>\n        \u003C\u002Fif>\n      \u003C\u002Fheader>\n\n      \u003Cisland name=\"sortable\" client=\"ts\" :id=\"id.toString()\">\n        \u003Cul data-items class=\"sortable\">\n          \u003Cfor (index, item) in listView.items>\n            \u003Clist-item\n              :id=\"item.id.toString()\"\n              :label=\"item.label\"\n              :pinned=\"item.pinned\"\n              :position=\"index\"\n            \u002F>\n          \u003C\u002Ffor>\n        \u003C\u002Ful>\n\n        \u003Cscript client>\n          import Sortable from \"sortablejs\"\n          import { ListOps } from \".\u002FListOps\"\n\n          \u002F\u002F Each instance scopes DOM access to its root and gets a unique Sortable group.\n          const listId = ctx.props.id as string\n          const list = ctx.root.querySelector\u003CHTMLUListElement>(\"[data-items]\")!\n          const sortable = Sortable.create(list, {\n            animation: 150,\n            group: ctx.scoped(\"items\"),\n            onEnd: async () => {\n              const ids = [...list.children].map((item) => (item as HTMLElement).dataset.id!)\n              await ListOps.reorder(listId, ids)\n            },\n          })\n          ctx.onUnmount(() => sortable.destroy())\n        \u003C\u002Fscript>\n      \u003C\u002Fisland>\n    \u003C\u002Fbody>\n  \u003C\u002Fhtml>\n\u003C\u002Fpage>\n",[828],{"type":9,"tag":38,"props":829,"children":830},{"__ignoreMap":40},[831],{"type":15,"value":826},{"type":9,"tag":761,"props":833,"children":835},{"id":834},"list-opskt",[836],{"type":9,"tag":38,"props":837,"children":838},{"className":40},[839],{"type":15,"value":64},{"type":9,"tag":770,"props":841,"children":846},{"className":842,"code":844,"filename":-1,"highlights":-1,"language":845,"meta":40},[843],"language-kotlin","package example\n\nimport bml.generated.ListOps\nimport bml.generated.ListOpsDispatcher\nimport bosca.bml.graphql.GraphQLClient\nimport bosca.bml.render.BmlContractDispatcher\nimport kotlinx.serialization.json.JsonArray\nimport kotlinx.serialization.json.JsonPrimitive\nimport kotlinx.serialization.json.buildJsonObject\nimport kotlinx.serialization.json.put\n\n\u002F** Implements the server half generated from the `ListOps` contract in lists.bml. *\u002F\nclass ListOpsImpl : ListOps {\n    override suspend fun reorder(gql: GraphQLClient, listId: String, ids: List\u003CString>) {\n        gql.execute(\n            query = REORDER_LIST,\n            variables = buildJsonObject {\n                put(\"listId\", listId)\n                put(\"ids\", JsonArray(ids.map { JsonPrimitive(it) }))\n            },\n            operationName = \"ReorderList\",\n        )\n    }\n\n    private companion object {\n        val REORDER_LIST = \"\"\"\n            mutation ReorderList(${ '$' }listId: ID!, ${ '$' }ids: [ID!]!) {\n              reorderList(listId: ${ '$' }listId, ids: ${ '$' }ids)\n            }\n        \"\"\".trimIndent()\n    }\n}\n\n\u002F** Pass this list as `BmlServer(..., contracts = listContracts())`. *\u002F\nfun listContracts(): List\u003CBmlContractDispatcher> =\n    listOf(ListOpsDispatcher(ListOpsImpl()))\n","kotlin",[847],{"type":9,"tag":38,"props":848,"children":849},{"__ignoreMap":40},[850],{"type":15,"value":844},{"type":9,"tag":761,"props":852,"children":854},{"id":853},"task-listbml",[855],{"type":9,"tag":38,"props":856,"children":857},{"className":40},[858],{"type":15,"value":71},{"type":9,"tag":770,"props":860,"children":863},{"className":861,"code":862,"filename":-1,"highlights":-1,"language":775,"meta":40},[773],"{# A no-client-code live ViewModel example.\n   BML sends actions to TaskListViewModel and re-renders this island after each method call. #}\n\u003Cpage route=\"\u002Ftasks\">\n  \u003Cscript server provides=\"tasks\" scope=\"server-session\">\n    example.TaskListViewModel()\n  \u003C\u002Fscript>\n\n  \u003Chtml lang=\"en\">\n    \u003Chead>\u003Ctitle>Tasks\u003C\u002Ftitle>\u003C\u002Fhead>\n    \u003Cbody>\n      \u003Cmain>\n        \u003Ch1>Tasks\u003C\u002Fh1>\n\n        \u003Cisland name=\"task-list\">\n          \u003Cform @submit=\"tasks.add(form.title)\">\n            \u003Clabel for=\"task-title\">New task\u003C\u002Flabel>\n            \u003Cinput id=\"task-title\" name=\"title\" required\u002F>\n            \u003Cbutton type=\"submit\">Add\u003C\u002Fbutton>\n          \u003C\u002Fform>\n\n          \u003Cif tasks.items.isEmpty()>\n            \u003Cp>No tasks yet.\u003C\u002Fp>\n          \u003Celse>\n            \u003Cul>\n              \u003Cfor (index, item) in tasks.items>\n                \u003Clist-item\n                  :id=\"item.id\"\n                  :label=\"item.title\"\n                  :position=\"index\"\n                >\n                  \u003Cbutton @click=\"tasks.toggle(item.id)\">\n                    \u003Cif item.completed>Reopen\u003Celse>Complete\u003C\u002Fif>\n                  \u003C\u002Fbutton>\n                  \u003Cbutton @click=\"tasks.remove(item.id)\">Remove\u003C\u002Fbutton>\n                \u003C\u002Flist-item>\n              \u003C\u002Ffor>\n            \u003C\u002Ful>\n          \u003C\u002Fif>\n        \u003C\u002Fisland>\n      \u003C\u002Fmain>\n    \u003C\u002Fbody>\n  \u003C\u002Fhtml>\n\u003C\u002Fpage>\n",[864],{"type":9,"tag":38,"props":865,"children":866},{"__ignoreMap":40},[867],{"type":15,"value":862},{"type":9,"tag":761,"props":869,"children":871},{"id":870},"task-list-view-modelkt",[872],{"type":9,"tag":38,"props":873,"children":874},{"className":40},[875],{"type":15,"value":78},{"type":9,"tag":770,"props":877,"children":880},{"className":878,"code":879,"filename":-1,"highlights":-1,"language":845,"meta":40},[843],"package example\n\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class TaskItem(\n    val id: String,\n    val title: String,\n    val completed: Boolean = false,\n)\n\n\u002F** Mutable, serializable state used by task-list.bml's declarative server actions. *\u002F\n@Serializable\nclass TaskListViewModel {\n    var items: List\u003CTaskItem> = listOf(\n        TaskItem(id = \"1\", title = \"Read the BML guide\", completed = true),\n        TaskItem(id = \"2\", title = \"Build an island\"),\n    )\n        private set\n\n    private var nextId: Int = 3\n\n    fun add(title: String) {\n        val trimmed = title.trim()\n        if (trimmed.isEmpty()) return\n        items = items + TaskItem(id = (nextId++).toString(), title = trimmed)\n    }\n\n    fun toggle(id: String) {\n        items = items.map { item ->\n            if (item.id == id) item.copy(completed = !item.completed) else item\n        }\n    }\n\n    fun remove(id: String) {\n        items = items.filterNot { it.id == id }\n    }\n}\n",[881],{"type":9,"tag":38,"props":882,"children":883},{"__ignoreMap":40},[884],{"type":15,"value":879},{"type":9,"tag":761,"props":886,"children":888},{"id":887},"site-headerbml",[889],{"type":9,"tag":38,"props":890,"children":891},{"className":40},[892],{"type":15,"value":523},{"type":9,"tag":770,"props":894,"children":897},{"className":895,"code":896,"filename":-1,"highlights":-1,"language":775,"meta":40},[773],"{# Component: reusable site chrome. Pages still own their full document skeleton. #}\n\u003Ccomponent tag=\"site-header\">\n  \u003Cprop name=\"home\" type=\"String\" default=\"\u002F\"\u002F>\n\n  \u003Cheader class=\"site-header\">\n    \u003Ca :href=\"home\">\u003Cslot\u002F>\u003C\u002Fa>\n    \u003Cspan class=\"copyright\">&copy; Bosca\u003C\u002Fspan>\n  \u003C\u002Fheader>\n\u003C\u002Fcomponent>\n",[898],{"type":9,"tag":38,"props":899,"children":900},{"__ignoreMap":40},[901],{"type":15,"value":896},{"type":9,"tag":761,"props":903,"children":905},{"id":904},"welcome-emailbml",[906],{"type":9,"tag":38,"props":907,"children":908},{"className":40},[909],{"type":15,"value":561},{"type":9,"tag":770,"props":911,"children":914},{"className":912,"code":913,"filename":-1,"highlights":-1,"language":775,"meta":40},[773],"{# Message: a welcome template with an email channel. #}\n\u003Cmessage key=\"welcome\">\n  \u003Cscript server provides=\"m\">message.payload(WelcomePayload.serializer())\u003C\u002Fscript>\n\n  \u003Cemail>\n    \u003Csubject t=\"welcome.subject\">Welcome, { message.recipientName ?: \"friend\" }!\u003C\u002Fsubject>\n\n    \u003Cstyle bml-inline>\n      .greeting { font-size: 18px; font-weight: 600; }\n      .muted { color: #667085; }\n    \u003C\u002Fstyle>\n\n    \u003Chtml>\n      \u003Cbody>\n        \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">\n          \u003Ctr>\n            \u003Ctd>\n              \u003Cp class=\"greeting\">Welcome, { m.firstName }!\u003C\u002Fp>\n              \u003Cdiv class=\"intro\">{@ m.welcomeHtml }\u003C\u002Fdiv>\n\n              \u003Cif m.organizations.isEmpty()>\n                \u003Cp class=\"muted\">Create your first organization to get started.\u003C\u002Fp>\n              \u003Celse-if m.organizations.size == 1>\n                \u003Cp class=\"muted\">You're a member of 1 organization.\u003C\u002Fp>\n              \u003Celse>\n                \u003Cp class=\"muted\">You're a member of { m.organizations.size } organizations.\u003C\u002Fp>\n              \u003C\u002Fif>\n\n              \u003Cif m.organizations.isNotEmpty()>\n                \u003Cul>\n                  \u003Cfor org in m.organizations>\n                    \u003Cli>{ org.name }\u003C\u002Fli>\n                  \u003C\u002Ffor>\n                \u003C\u002Ful>\n              \u003C\u002Fif>\n\n              \u003Ca :href=\"m.dashboardUrl\">Open your dashboard\u003C\u002Fa>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n        \u003C\u002Ftable>\n      \u003C\u002Fbody>\n    \u003C\u002Fhtml>\n  \u003C\u002Femail>\n\u003C\u002Fmessage>\n",[915],{"type":9,"tag":38,"props":916,"children":917},{"__ignoreMap":40},[918],{"type":15,"value":913},1790541170518]