[{"data":1,"prerenderedAt":883},["ShallowReactive",2],{"navigation_docs":3,"-guide-packaging":223,"-guide-packaging-surround":878},[4,26,96,105,202],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":25},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","i-lucide-download",{"title":16,"path":17,"stem":18,"icon":19},"The first app","\u002Fgetting-started\u002Ffirst-app","1.getting-started\u002F2.first-app","i-lucide-play",{"title":21,"path":22,"stem":23,"icon":24},"The first test","\u002Fgetting-started\u002Ffirst-test","1.getting-started\u002F3.first-test","i-lucide-flask-conical",false,{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":25},"Guide","i-lucide-book-open","\u002Fguide","2.guide",[32,37,42,47,52,57,62,67,72,77,81,86,91],{"title":33,"path":34,"stem":35,"icon":36},"Components","\u002Fguide\u002Fcomponents","2.guide\u002F01.components","i-lucide-component",{"title":38,"path":39,"stem":40,"icon":41},"Inputs and forms","\u002Fguide\u002Finputs-and-forms","2.guide\u002F02.inputs-and-forms","i-lucide-text-cursor-input",{"title":43,"path":44,"stem":45,"icon":46},"Scrolling and viewports","\u002Fguide\u002Fscrolling","2.guide\u002F03.scrolling","i-lucide-scroll-text",{"title":48,"path":49,"stem":50,"icon":51},"Overlays and layers","\u002Fguide\u002Foverlays","2.guide\u002F04.overlays","i-lucide-layers",{"title":53,"path":54,"stem":55,"icon":56},"Styles and theme","\u002Fguide\u002Fstyles","2.guide\u002F05.styles","i-lucide-palette",{"title":58,"path":59,"stem":60,"icon":61},"Composables","\u002Fguide\u002Fcomposables","2.guide\u002F06.composables","i-lucide-puzzle",{"title":63,"path":64,"stem":65,"icon":66},"Widgets","\u002Fguide\u002Fwidgets","2.guide\u002F07.widgets","i-lucide-blocks",{"title":68,"path":69,"stem":70,"icon":71},"The assistant","\u002Fguide\u002Fassistant","2.guide\u002F08.assistant","i-lucide-message-square",{"title":73,"path":74,"stem":75,"icon":76},"The same app on the web","\u002Fguide\u002Fweb","2.guide\u002F09.web","i-lucide-globe",{"title":78,"path":79,"stem":80,"icon":24},"Testing","\u002Fguide\u002Ftesting","2.guide\u002F10.testing",{"title":82,"path":83,"stem":84,"icon":85},"Running and packaging","\u002Fguide\u002Fpackaging","2.guide\u002F11.packaging","i-lucide-package",{"title":87,"path":88,"stem":89,"icon":90},"The terminal contract","\u002Fguide\u002Fterminal","2.guide\u002F12.terminal","i-lucide-square-terminal",{"title":92,"path":93,"stem":94,"icon":95},"Benchmarks","\u002Fguide\u002Fbenchmarks","2.guide\u002F13.benchmarks","i-lucide-gauge",{"title":97,"icon":98,"path":99,"stem":100,"children":101,"page":25},"AI and agents","i-lucide-bot","\u002Fai","3.ai",[102],{"title":97,"path":103,"stem":104,"icon":98},"\u002Fai\u002Fagents","3.ai\u002F1.agents",{"title":106,"icon":107,"path":108,"stem":109,"children":110},"Decisions","i-lucide-scale","\u002Fdecisions","4.decisions",[111,114,118,122,126,130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,194,198],{"title":112,"path":108,"stem":113,"icon":46},"All decisions","4.decisions\u002Findex",{"title":115,"path":116,"stem":117},"0001. kyo-ui is the DSL","\u002Fdecisions\u002F0001-kyo-ui-is-the-dsl","4.decisions\u002F0001-kyo-ui-is-the-dsl",{"title":119,"path":120,"stem":121},"0002. jatatui renders the cells","\u002Fdecisions\u002F0002-jatatui-renders-the-cells","4.decisions\u002F0002-jatatui-renders-the-cells",{"title":123,"path":124,"stem":125},"0003. Pin Kyo 1.0.0-RC7 and JDK 25","\u002Fdecisions\u002F0003-pin-kyo-rc7-and-jdk-25","4.decisions\u002F0003-pin-kyo-rc7-and-jdk-25",{"title":127,"path":128,"stem":129},"0004. Public Kyo APIs only","\u002Fdecisions\u002F0004-public-kyo-apis-only","4.decisions\u002F0004-public-kyo-apis-only",{"title":131,"path":132,"stem":133},"0005. A SOFT frame contract and an own watcher loop","\u002Fdecisions\u002F0005-soft-frame-contract-and-own-watcher-loop","4.decisions\u002F0005-soft-frame-contract-and-own-watcher-loop",{"title":135,"path":136,"stem":137},"0006. Purity: edge files, lint and a pure painter","\u002Fdecisions\u002F0006-purity-edge-files-and-lint","4.decisions\u002F0006-purity-edge-files-and-lint",{"title":139,"path":140,"stem":141},"0007. Compiler flags from sbt-tpolecat","\u002Fdecisions\u002F0007-compiler-flags-from-sbt-tpolecat","4.decisions\u002F0007-compiler-flags-from-sbt-tpolecat",{"title":143,"path":144,"stem":145},"0008. The artifact split: runner, app, testkit and core","\u002Fdecisions\u002F0008-artifact-split-runner-app-testkit-core","4.decisions\u002F0008-artifact-split-runner-app-testkit-core",{"title":147,"path":148,"stem":149},"0009. tui4s-use and tui4s-widgets, cross-built","\u002Fdecisions\u002F0009-use-and-widgets-cross-built","4.decisions\u002F0009-use-and-widgets-cross-built",{"title":151,"path":152,"stem":153},"0010. The flagship assistant is the blueprint of a real app","\u002Fdecisions\u002F0010-the-flagship-assistant-as-blueprint","4.decisions\u002F0010-the-flagship-assistant-as-blueprint",{"title":155,"path":156,"stem":157},"0011. The web target: a standalone Scala.js app and one theme","\u002Fdecisions\u002F0011-web-target-standalone-scalajs-and-one-theme","4.decisions\u002F0011-web-target-standalone-scalajs-and-one-theme",{"title":159,"path":160,"stem":161},"0012. The documentation is example-first","\u002Fdecisions\u002F0012-documentation-is-example-first","4.decisions\u002F0012-documentation-is-example-first",{"title":163,"path":164,"stem":165},"0013. Benchmarks in the repository, with their own build","\u002Fdecisions\u002F0013-benchmarks-in-repo-with-own-build","4.decisions\u002F0013-benchmarks-in-repo-with-own-build",{"title":167,"path":168,"stem":169},"0014. Release per module, by tag, as 0.1.0-RC1","\u002Fdecisions\u002F0014-release-per-module-tags-and-rc1","4.decisions\u002F0014-release-per-module-tags-and-rc1",{"title":171,"path":172,"stem":173},"0015. Packaging: the AOT cache in the start scripts, native-image as an option","\u002Fdecisions\u002F0015-packaging-aot-cache-and-native-image","4.decisions\u002F0015-packaging-aot-cache-and-native-image",{"title":175,"path":176,"stem":177},"0016. Process: lean mode and agent roles","\u002Fdecisions\u002F0016-process-lean-mode-and-agent-roles","4.decisions\u002F0016-process-lean-mode-and-agent-roles",{"title":179,"path":180,"stem":181},"0017. Deferred: templates, mouse, the kitty keyboard protocol and Windows","\u002Fdecisions\u002F0017-deferred-templates-mouse-and-kitty","4.decisions\u002F0017-deferred-templates-mouse-and-kitty",{"title":183,"path":184,"stem":185},"0018. pini4s is a vendored Git submodule","\u002Fdecisions\u002F0018-pini4s-as-a-vendored-submodule","4.decisions\u002F0018-pini4s-as-a-vendored-submodule",{"title":187,"path":188,"stem":189},"0019. Upstream issues are drafts that the user posts","\u002Fdecisions\u002F0019-upstream-kyo-issues-as-drafts","4.decisions\u002F0019-upstream-kyo-issues-as-drafts",{"title":191,"path":192,"stem":193},"0020. Release from the Actions form","\u002Fdecisions\u002F0020-release-from-the-actions-form","4.decisions\u002F0020-release-from-the-actions-form",{"title":195,"path":196,"stem":197},"0021. The rulebook is CONTRIBUTING.md","\u002Fdecisions\u002F0021-the-rulebook-is-contributing-md","4.decisions\u002F0021-the-rulebook-is-contributing-md",{"title":199,"path":200,"stem":201},"0022. The logo is text","\u002Fdecisions\u002F0022-the-logo-is-text","4.decisions\u002F0022-the-logo-is-text",{"title":203,"icon":204,"path":205,"stem":206,"children":207,"page":25},"Project","i-lucide-compass","\u002Fproject","5.project",[208,213,218],{"title":209,"path":210,"stem":211,"icon":212},"Roadmap","\u002Fproject\u002Froadmap","5.project\u002F1.roadmap","i-lucide-map",{"title":214,"path":215,"stem":216,"icon":217},"Contributing","\u002Fproject\u002Fcontributing","5.project\u002F2.contributing","i-lucide-git-pull-request",{"title":219,"path":220,"stem":221,"icon":222},"Security","\u002Fproject\u002Fsecurity","5.project\u002F3.security","i-lucide-shield",{"id":224,"title":82,"body":225,"description":871,"extension":872,"links":873,"meta":874,"navigation":875,"path":83,"seo":876,"stem":84,"__hash__":877},"docs\u002F2.guide\u002F11.packaging.md",{"type":226,"value":227,"toc":861},"minimark",[228,258,274,400,407,412,415,505,518,522,525,530,549,572,575,600,606,610,630,660,682,686,699,756,760,779,783,846,857],[229,230,235],"pre",{"className":231,"code":232,"language":233,"meta":234,"style":234},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sbt examples\u002Flaunchers\nexamples\u002Ftarget\u002Fbin\u002Fcounter\nsbt examples\u002FUniversal\u002FpackageBin   # a ZIP with a launcher for each example and its JARs\n","sh","",[236,237,238,246,252],"code",{"__ignoreMap":234},[239,240,243],"span",{"class":241,"line":242},"line",1,[239,244,245],{},"sbt examples\u002Flaunchers\n",[239,247,249],{"class":241,"line":248},2,[239,250,251],{},"examples\u002Ftarget\u002Fbin\u002Fcounter\n",[239,253,255],{"class":241,"line":254},3,[239,256,257],{},"sbt examples\u002FUniversal\u002FpackageBin   # a ZIP with a launcher for each example and its JARs\n",[259,260,261,262,265,266,269,270,273],"p",{},"A ",[236,263,264],{},"TuiApp"," reads its command-line arguments with ",[236,267,268],{},"args",", and gives its options with ",[236,271,272],{},"options",". The Printing example sends the captured output to a log file:",[229,275,280],{"className":276,"code":277,"filename":278,"language":279,"meta":234,"style":234},"language-scala shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","    def options(args: Chunk[String]): TuiOptions = args.toSeq match\n        case Seq(\"--log\", file, _*) =>\n          TuiOptions(logFile = Some(Paths.get(file)))\n        case _                      => TuiOptions()\n","Printing.scala","scala",[236,281,282,331,362,384],{"__ignoreMap":234},[239,283,284,288,292,296,299,302,306,309,312,315,318,321,324,327],{"class":241,"line":242},[239,285,287],{"class":286},"sMK4o","    def",[239,289,291],{"class":290},"s2Zo4"," options",[239,293,295],{"class":294},"sTEyZ","(",[239,297,268],{"class":298},"sHdIc",[239,300,301],{"class":294},": ",[239,303,305],{"class":304},"sBMFI","Chunk",[239,307,308],{"class":294},"[",[239,310,311],{"class":304},"String",[239,313,314],{"class":294},"])",[239,316,317],{"class":286},":",[239,319,320],{"class":304}," TuiOptions",[239,322,323],{"class":286}," =",[239,325,326],{"class":294}," args.toSeq ",[239,328,330],{"class":329},"s7zQu","match\n",[239,332,333,336,339,341,344,348,350,353,356,359],{"class":241,"line":248},[239,334,335],{"class":329},"        case",[239,337,338],{"class":304}," Seq",[239,340,295],{"class":294},[239,342,343],{"class":286},"\"",[239,345,347],{"class":346},"sfazB","--log",[239,349,343],{"class":286},[239,351,352],{"class":294},", file, ",[239,354,355],{"class":286},"_*",[239,357,358],{"class":294},") ",[239,360,361],{"class":286},"=>\n",[239,363,364,367,370,373,376,378,381],{"class":241,"line":254},[239,365,366],{"class":304},"          TuiOptions",[239,368,369],{"class":294},"(logFile ",[239,371,372],{"class":286},"=",[239,374,375],{"class":304}," Some",[239,377,295],{"class":294},[239,379,380],{"class":304},"Paths",[239,382,383],{"class":294},".get(file)))\n",[239,385,387,389,392,395,397],{"class":241,"line":386},4,[239,388,335],{"class":329},[239,390,391],{"class":294}," _                      ",[239,393,394],{"class":286},"=>",[239,396,320],{"class":304},[239,398,399],{"class":294},"()\n",[259,401,402,403,406],{},"Its main class has ",[236,404,405],{},"override def options: TuiOptions = Printing.options(args)",".",[408,409,411],"h2",{"id":410},"the-jvm-flags","The JVM flags",[259,413,414],{},"The start scripts of the examples (sbt-native-packager) give these flags:",[416,417,418,431],"table",{},[419,420,421],"thead",{},[422,423,424,428],"tr",{},[425,426,427],"th",{},"Flag",[425,429,430],{},"Why",[432,433,434,452,465,475,494],"tbody",{},[422,435,436,442],{},[437,438,439],"td",{},[236,440,441],{},"--enable-native-access=ALL-UNNAMED",[437,443,444,445,448,449,406],{},"The terminal library (crossterm) is native. Without the flag, JDK 25 prints a warning into the terminal before the UI starts. With ",[236,446,447],{},"--illegal-native-access=deny",", the run fails with ",[236,450,451],{},"TuiError.NativeAccessDenied",[422,453,454,459],{},[437,455,456],{},[236,457,458],{},"--sun-misc-unsafe-memory-access=allow",[437,460,461,462,406],{},"Kyo and Scala use ",[236,463,464],{},"sun.misc.Unsafe",[422,466,467,472],{},[437,468,469],{},[236,470,471],{},"-Xss16m",[437,473,474],{},"Kyo's deep stacks.",[422,476,477,486],{},[437,478,479,482,483],{},[236,480,481],{},"-XX:TieredStopAtLevel=1"," and ",[236,484,485],{},"-XX:+UseSerialGC",[437,487,488,489,493],{},"A faster start and less memory (",[490,491,492],"a",{"href":172},"ADR 0015",").",[422,495,496,502],{},[437,497,498,501],{},[236,499,500],{},"-Dkyo.scheduler.cycleIntervalNs=10000000"," and three more scheduler values",[437,503,504],{},"Fewer split frames under load, and less CPU when the app is idle.",[259,506,261,507,509,510,513,514,517],{},[236,508,264],{}," sets the scheduler values in code before Kyo starts its scheduler. An app with a main of its own (a ",[236,511,512],{},"KyoApp"," that calls ",[236,515,516],{},"Tui.run",") gives them as JVM flags. The ZIP does not hold a JDK: the machine needs JDK 25.",[408,519,521],{"id":520},"start-modes","Start modes",[259,523,524],{},"A start script starts the JVM. Two modes start faster: the AOT cache of JDK 25, and a GraalVM native binary.",[526,527,529],"h3",{"id":528},"the-aot-cache","The AOT cache",[229,531,533],{"className":231,"code":532,"language":233,"meta":234,"style":234},"sbt examples\u002Flaunchers\nexamples\u002Ftarget\u002Fbin\u002Faot-train            # all the apps; or: aot-train counter dashboard\nexamples\u002Ftarget\u002Fbin\u002Fcounter              # starts with aot\u002Fcounter.aot\n",[236,534,535,539,544],{"__ignoreMap":234},[239,536,537],{"class":241,"line":242},[239,538,245],{},[239,540,541],{"class":241,"line":248},[239,542,543],{},"examples\u002Ftarget\u002Fbin\u002Faot-train            # all the apps; or: aot-train counter dashboard\n",[239,545,546],{"class":241,"line":254},[239,547,548],{},"examples\u002Ftarget\u002Fbin\u002Fcounter              # starts with aot\u002Fcounter.aot\n",[259,550,551,552,555,556,559,560,563,564,567,568,571],{},"In an unpacked ZIP, run ",[236,553,554],{},"bin\u002Faot-train",". It starts each app in a pseudo-terminal of its own, sends keys and quits. Then it writes ",[236,557,558],{},"aot\u002F\u003Capp>.aot"," (about 40 MB, about 9 s for each app) and ",[236,561,562],{},"aot\u002F\u003Capp>.jdk"," (the text of ",[236,565,566],{},"java -version","). It needs ",[236,569,570],{},"python3",". After each training, it starts the JVM once with the new cache, and it fails when the JVM cannot use the cache.",[259,573,574],{},"A start script uses the cache only when:",[576,577,578,586,594],"ul",{},[579,580,581,482,583,585],"li",{},[236,582,558],{},[236,584,562],{}," exist,",[579,587,588,590,591,593],{},[236,589,566],{}," gives the text of ",[236,592,562],{},", and",[579,595,596,597,406],{},"the command has no ",[236,598,599],{},"-java-home",[259,601,602,603,605],{},"Else the script starts without the cache, as before. The JVM also rejects a cache when the jars changed: the app then starts without the cache, with no message. Train again after a change of the JDK or of the jars. The ZIP holds ",[236,604,554],{},", but no cache: a cache is valid only for the JDK that made it.",[526,607,609],{"id":608},"a-native-binary","A native binary",[229,611,613],{"className":231,"code":612,"language":233,"meta":234,"style":234},"scripts\u002Fnative-image.sh counter -Os      # -Os: a small binary; -Ob: a quick build\nexamples\u002Ftarget\u002Fnative\u002Fcounter\npython3 scripts\u002Fnative-smoke.py examples\u002Ftarget\u002Fnative\u002Fcounter\n",[236,614,615,620,625],{"__ignoreMap":234},[239,616,617],{"class":241,"line":242},[239,618,619],{},"scripts\u002Fnative-image.sh counter -Os      # -Os: a small binary; -Ob: a quick build\n",[239,621,622],{"class":241,"line":248},[239,623,624],{},"examples\u002Ftarget\u002Fnative\u002Fcounter\n",[239,626,627],{"class":241,"line":254},[239,628,629],{},"python3 scripts\u002Fnative-smoke.py examples\u002Ftarget\u002Fnative\u002Fcounter\n",[259,631,632,633,636,637,640,641,644,645,648,649,652,653,482,656,659],{},"The script needs GraalVM for JDK 25. The Community Edition is sufficient. Put ",[236,634,635],{},"native-image"," on ",[236,638,639],{},"PATH",", or set ",[236,642,643],{},"GRAALVM_HOME",". The script stages the distribution, reads the main class and the class path of the start script, and writes ",[236,646,647],{},"examples\u002Ftarget\u002Fnative\u002F\u003Capp>",". ",[236,650,651],{},"native-smoke.py"," starts the binary in a pseudo-terminal, presses ",[236,654,655],{},"+",[236,657,658],{},"q",", and checks the screen, the exit code and the restore.",[259,661,662,663,666,667,670,671,674,675,678,679,493],{},"The jar of ",[236,664,665],{},"tui4s-runner"," holds the native-image metadata (",[236,668,669],{},"META-INF\u002Fnative-image","): the crossterm library of each platform and the ",[236,672,673],{},"isatty"," downcall. This metadata is sufficient for the examples. An app that uses more of Kyo or of the JDK can need more entries: at run time, a ",[236,676,677],{},"Missing...RegistrationError"," names the entry. Put such entries in the metadata of the app (its own ",[236,680,681],{},"META-INF\u002Fnative-image\u002F\u003Cgroup>\u002F\u003Cartifact>\u002Freachability-metadata.json",[526,683,685],{"id":684},"the-numbers","The numbers",[259,687,688,689,692,693,493],{},"The Counter on the machine ",[236,690,691],{},"container-4vcpu"," of the bench: 4 vCPU (Intel Xeon, 2.10 GHz), 15.7 GB, Linux, a shared build container; the median of 3 runs, 2026-10-20 (",[490,694,698],{"href":695,"rel":696},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fblob\u002Fmain\u002Fbench\u002FPERFORMANCE.md",[697],"nofollow","bench\u002FPERFORMANCE.md",[416,700,701,715],{},[419,702,703],{},[422,704,705,708,712],{},[425,706,707],{},"Start mode",[425,709,711],{"align":710},"right","First frame",[425,713,714],{"align":710},"RSS",[432,716,717,732,745],{},[422,718,719,726,729],{},[437,720,721,722,725],{},"JVM, without the AOT cache and the two ",[236,723,724],{},"-XX"," flags",[437,727,728],{"align":710},"1,227 ms",[437,730,731],{"align":710},"129 MB",[422,733,734,739,742],{},[437,735,736,737,725],{},"JVM, with the AOT cache and the two ",[236,738,724],{},[437,740,741],{"align":710},"444 ms",[437,743,744],{"align":710},"115 MB",[422,746,747,750,753],{},[437,748,749],{},"Native binary (GraalVM CE 25)",[437,751,752],{"align":710},"25 ms",[437,754,755],{"align":710},"40 MB",[408,757,759],{"id":758},"output-while-the-ui-runs","Output while the UI runs",[259,761,762,763,766,767,770,771,774,775,778],{},"A print to stdout or stderr would write over the screen. So the run captures ",[236,764,765],{},"System.out",", ",[236,768,769],{},"System.err"," and Scala's ",[236,772,773],{},"println",", and prints the lines after it restores the terminal. With ",[236,776,777],{},"logFile",", the lines go to that file.",[408,780,782],{"id":781},"exit-codes-and-signals","Exit codes and signals",[416,784,785,795],{},[419,786,787],{},[422,788,789,792],{},[425,790,791],{},"How the run ends",[425,793,794],{},"Exit code",[432,796,797,808,816,826,836],{},[422,798,799,805],{},[437,800,801,804],{},[236,802,803],{},"Tui.quit",", or the key Ctrl-C",[437,806,807],{},"0",[422,809,810,813],{},[437,811,812],{},"A failure of the UI (printed after the restore)",[437,814,815],{},"1",[422,817,818,823],{},[437,819,820],{},[236,821,822],{},"kill -TERM",[437,824,825],{},"143",[422,827,828,833],{},[437,829,830],{},[236,831,832],{},"kill -INT",[437,834,835],{},"130",[422,837,838,843],{},[437,839,840],{},[236,841,842],{},"kill -HUP",[437,844,845],{},"129",[259,847,848,849,852,853,856],{},"On a signal or a ",[236,850,851],{},"System.exit",", a shutdown hook interrupts the run and waits at most 2 s for the restore of the terminal. In raw mode, the key Ctrl-C is a key, not a signal: ",[236,854,855],{},"TuiOptions(ctrlCQuits = false)"," gives it to the app.",[858,859,860],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":234,"searchDepth":248,"depth":248,"links":862},[863,864,869,870],{"id":410,"depth":248,"text":411},{"id":520,"depth":248,"text":521,"children":865},[866,867,868],{"id":528,"depth":254,"text":529},{"id":608,"depth":254,"text":609},{"id":684,"depth":254,"text":685},{"id":758,"depth":248,"text":759},{"id":781,"depth":248,"text":782},"The start scripts, the JVM flags, the AOT cache, a native binary, the options of a TuiApp, the exit codes and the signals.","md",null,{},{"icon":85},{"title":82,"description":871},"9dHiljidM8dDnmmvbMbspQX5KdiFB4ShNUaBTqypiDM",[879,881],{"title":78,"path":79,"stem":80,"description":880,"icon":24,"children":-1},"Test an app on the headless test kit, and check the real terminal with the PTY kit.",{"title":87,"path":88,"stem":89,"description":882,"icon":90,"children":-1},"What the runner does to the terminal, and how each way that a run ends restores it.",1792528755324]