1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495openCore_kernelopenImportmoduleView_spec=structtypet={key:string->Vdom.Node.t;plain_text:string->Vdom.Node.t}letplain=letopenVdomin{key=Node.text;plain_text=Node.text};;letwith_classes~key_class~plain_text_class=lettext_spanclass_text=letopenVdominNode.span[Attr.class_class_][Node.texttext]in{key=text_spankey_class;plain_text=text_spanplain_text_class};;endmoduleCommand=structtypet={keys:Keystroke.tlist;description:string}[@@derivingsexp,compare]moduleFormat=structtypet=[`Keysof[`Sepofstring]|`Descriptionof(string->string)option|`Textofstring]listletdefault=[`Text"Press ";`Keys(`Sep" or ");`Text" to ";`Description(SomeString.uncapitalize);`Text"."];;endletview_keyst(view_spec:View_spec.t)~sep=letkeys=t.keys|>List.map~f:Keystroke.to_string_hum(* Dedup keystrokes that map to the same string, e.g. Enter and NumpadEnter. *)|>List.dedup_and_sort~compare:String.compare|>List.map~f:view_spec.keyinList.interspersekeys~sep:(view_spec.plain_textsep);;letview_description?(f=Fn.id)t(view_spec:View_spec.t)=view_spec.plain_text(ft.description);;letviewtview_specformat=letopenVdominNode.div[](List.concat_mapformat~f:(function|`Keys(`Sepsep)->view_keystview_spec~sep|`Descriptionf->[view_description?ftview_spec]|`Texttext->[view_spec.plain_texttext]));;endtypet=Command.tlist[@@derivingsexp,compare]letempty=[]letis_empty=List.is_emptyletof_command_list=Fn.idletcommands=Fn.idletadd_commandtcommand=t@[command]letview_rows?(sep=" or ")t(view_spec:View_spec.t)=letopenVdominletalignhow=Css_gen.(text_alignhow)|>Attr.styleinList.map(commandst)~f:(funcommand->Node.tr[][Node.td[align`Right](Command.view_keyscommandview_spec~sep@[view_spec.plain_text" : "]);Node.td[align`Left][Command.view_descriptioncommandview_spec]]);;letview?septview_spec=Vdom.Node.table[](view_rows?septview_spec)