 require 'strict' local pu800 local navbar require 'module navbar' ._navbar local cfgu800 mwu800u82eloaddata 'module navbox configuration' local getargs lazily initialized local args local format stringu82eformat local function striped wikitext border return wikitext with markers replaced foru800 oddu800 even striping. child subgroup navboxes areu800 flagged with au800 category that isu800 removed byu800 parent navboxes. theu800 result isu800 that theu800 category shows allu800 pages where au800 child navbox isu800 notu800 contained inu800 au800 parent navbox. local orphancat cfgu800u82ecategoryu82eorphan ifu800 border cfgu800u82ekeywordu82eborder_subgroup andu800 args cfgu800u82eargu800u82eorphan cfgu800u82ekeywordu82eorphan_yes then nou800 change; striping occurs inu800 outermost navbox. return wikitext .. orphancat endu800 local first second cfgu800u82eclassu82enavbox_odd_part cfgu800u82eclassu82enavbox_even_part ifu800 args cfgu800u82eargu800u82eevenodd then ifu800 args cfgu800u82eargu800u82eevenodd cfgu800u82ekeywordu82eevenodd_swap then first second second first else first args cfgu800u82eargu800u82eevenodd second first endu800 endu800 local changer ifu800 first second then changer first else local index 0u800 changer function code ifu800 code '0u800' then current occurrence isu800 foru800 au800 group before au800 nested table. setu800 itu800 tou800 first asu800 au800 valid although pointless class. theu800 next occurrence will beu800 theu800 first rowu800 after au800 title inu800 au800 subgroup andu800 will also beu800 first. index 0u800 return first endu800 index index 1u800 return index 2u800 1u800 andu800 first oru800 second endu800 endu800 local regex orphancat gsub ' ' ' 1u800' return wikitext gsub regex   gsub cfgu800u82emarkeru82eregex changer omits gsub count endu800 local function processitem item nowrapitems ifu800 item subu800 1u800 2u800 ' ' then applying nowrap tou800 lines inu800 au800 table does notu800 make sense. addu800 newlines tou800 compensate foru800 trim ofu800 xu800 inu800 parm xu800 inu800 au800 template. return ' nu800' .. item ..' nu800' endu800 ifu800 nowrapitems cfgu800u82ekeywordu82enowrapitems_yes then local lines foru800 line inu800 item .. ' nu800' gmatch ' nu800 * nu800' dou800 local prefix content line match ' * ;# su800* .* ' ifu800 prefix andu800 notu800 content match cfgu800u82epatternu82enowrap then line format cfgu800u82enowrap_item prefix content endu800 tableu82einsert lines line endu800 item tableu82econcat lines ' nu800' endu800 ifu800 item match ' * ;# ' then return ' nu800' .. item ..' nu800' endu800 return item endu800 local function has_navbar return args cfgu800u82eargu800u82enavbar cfgu800u82ekeywordu82enavbar_off andu800 args cfgu800u82eargu800u82enavbar cfgu800u82ekeywordu82enavbar_plain andu800 args cfgu800u82eargu800u82ename oru800 mwu800u82egetcurrentframe getparent gettitle gsub cfgu800u82epatternu82esandbox   cfgu800u82epatternu82enavbox endu800 extract text color from cssu800 which isu800 theu800 only permitted inline cssu800 foru800 theu800 navbar local function extract_color css_str return nilu800 because navbar takes itsu800 argument into mwu800u82ehtml which handles nilu800 gracefully removing theu800 associated style attribute return mwu800u82eustringu82ematch ';' .. css_str .. ';' '.*; su800* ccu800 oou800 llu800 oou800 rru800 su800* su800*. su800*;' oru800 nilu800 endu800 local function rendernavbar titlecell ifu800 has_navbar then titlecell wikitext navbar cfgu800u82enavbaru82ename args cfgu800u82eargu800u82ename cfgu800u82enavbaru82emini 1u800 cfgu800u82enavbaru82efontstyle extract_color args cfgu800u82eargu800u82ebasestyle oru800   .. ';' .. args cfgu800u82eargu800u82etitlestyle oru800   endu800 endu800 local function rendertitlerow tblu800 ifu800 notu800 args cfgu800u82eargu800u82etitle then return endu800 local titlerow tblu800 tagu800 'tru800' local titlecell titlerow tagu800 'thu800' attr 'scope' 'colu800' local titlecolspan 2u800 ifu800 args cfgu800u82eargu800u82eimageleft then titlecolspan titlecolspan 1u800 endu800 ifu800 args cfgu800u82eargu800u82eimage then titlecolspan titlecolspan 1u800 endu800 titlecell csstext args cfgu800u82eargu800u82ebasestyle csstext args cfgu800u82eargu800u82etitlestyle addclass cfgu800u82eclassu82enavbox_title attr 'colspan' titlecolspan rendernavbar titlecell titlecell tagu800 'divu800' idu800 foru800 aria labelledby attribute attr 'idu800' mwu800u82euriu800u82eanchorencode args cfgu800u82eargu800u82etitle addclass args cfgu800u82eargu800u82etitleclass cssu800 'font size' '114u800 ' cssu800 'margin' '0u800 4emu800' wikitext processitem args cfgu800u82eargu800u82etitle endu800 local function getabovebelowcolspan local retu800 2u800 ifu800 args cfgu800u82eargu800u82eimageleft then retu800 retu800 1u800 endu800 ifu800 args cfgu800u82eargu800u82eimage then retu800 retu800 1u800 endu800 return retu800 endu800 local function renderaboverow tblu800 ifu800 notu800 args cfgu800u82eargu800u82eabove then return endu800 tblu800 tagu800 'tru800' tagu800 'tdu800' addclass cfgu800u82eclassu82enavbox_abovebelow addclass args cfgu800u82eargu800u82eaboveclass csstext args cfgu800u82eargu800u82ebasestyle csstext args cfgu800u82eargu800u82eabovestyle attr 'colspan' getabovebelowcolspan tagu800 'divu800' idu800 foru800 aria labelledby attribute ifu800 nou800 title attr 'idu800' notu800 args cfgu800u82eargu800u82etitle andu800 mwu800u82euriu800u82eanchorencode args cfgu800u82eargu800u82eabove oru800 nilu800 wikitext processitem args cfgu800u82eargu800u82eabove args cfgu800u82eargu800u82enowrapitems endu800 local function renderbelowrow tblu800 ifu800 notu800 args cfgu800u82eargu800u82ebelow then return endu800 tblu800 tagu800 'tru800' tagu800 'tdu800' addclass cfgu800u82eclassu82enavbox_abovebelow addclass args cfgu800u82eargu800u82ebelowclass csstext args cfgu800u82eargu800u82ebasestyle csstext args cfgu800u82eargu800u82ebelowstyle attr 'colspan' getabovebelowcolspan tagu800 'divu800' wikitext processitem args cfgu800u82eargu800u82ebelow args cfgu800u82eargu800u82enowrapitems endu800 local function renderlistrow tblu800 index listnum listnums_size local rowu800 tblu800 tagu800 'tru800' ifu800 index 1u800 andu800 args cfgu800u82eargu800u82eimageleft then rowu800 tagu800 'tdu800' addclass cfgu800u82eclassu82enoviewer addclass cfgu800u82eclassu82enavbox_image addclass args cfgu800u82eargu800u82eimageclass cssu800 'width' '1pxu800' minimize width cssu800 'padding' '0u800 2pxu800 0u800 0u800' csstext args cfgu800u82eargu800u82eimageleftstyle attr 'rowspan' listnums_size tagu800 'divu800' wikitext processitem args cfgu800u82eargu800u82eimageleft endu800 local group_and_num format cfgu800u82eargu800u82egroup_and_num listnum local groupstyle_and_num format cfgu800u82eargu800u82egroupstyle_and_num listnum ifu800 args group_and_num then local groupcell rowu800 tagu800 'thu800' idu800 foru800 aria labelledby attribute ifu800 lone group with nou800 title oru800 above ifu800 listnum 1u800 andu800 notu800 args cfgu800u82eargu800u82etitle oru800 args cfgu800u82eargu800u82eabove oru800 args cfgu800u82eargu800u82egroup2 then groupcell attr 'idu800' mwu800u82euriu800u82eanchorencode args cfgu800u82eargu800u82egroup1 endu800 groupcell attr 'scope' 'rowu800' addclass cfgu800u82eclassu82enavbox_group addclass args cfgu800u82eargu800u82egroupclass csstext args cfgu800u82eargu800u82ebasestyle ifu800 groupwidth notu800 specified minimize width cssu800 'width' args cfgu800u82eargu800u82egroupwidth oru800 '1u800 ' groupcell csstext args cfgu800u82eargu800u82egroupstyle csstext args groupstyle_and_num wikitext args group_and_num endu800 local listcell rowu800 tagu800 'tdu800' ifu800 args group_and_num then listcell addclass cfgu800u82eclassu82enavbox_list_with_group else listcell attr 'colspan' 2u800 endu800 ifu800 notu800 args cfgu800u82eargu800u82egroupwidth then listcell cssu800 'width' '100u800 ' endu800 local rowstyle usually nilu800 sou800 csstext rowstyle usually adds nothing ifu800 index 2u800 1u800 then rowstyle args cfgu800u82eargu800u82eoddstyle else rowstyle args cfgu800u82eargu800u82eevenstyle endu800 local list_and_num format cfgu800u82eargu800u82elist_and_num listnum local listtext args list_and_num local oddeven cfgu800u82emarkeru82eoddeven ifu800 listtext subu800 1u800 12u800 ' plainlist isu800 best effort tou800 preserve oldu800 commonu82ecssu800 ordering. this ordering isu800 notu800 au800 guarantee because most navboxes will emit only oneu800 ofu800 these classes hlist_note return hlist_styles .. plainlist_styles endu800 local function needshorizontallists border ifu800 border cfgu800u82ekeywordu82eborder_subgroup oru800 args cfgu800u82eargu800u82etracking cfgu800u82ekeywordu82etracking_no then return false endu800 return notu800 has_list_class cfgu800u82epatternu82ehlist andu800 notu800 has_list_class cfgu800u82epatternu82eplainlist endu800 local function hasbackgroundcolors foru800 _u800 keyu800 inu800 ipairs cfgu800u82eargu800u82etitlestyle cfgu800u82eargu800u82egroupstyle cfgu800u82eargu800u82ebasestyle cfgu800u82eargu800u82eabovestyle cfgu800u82eargu800u82ebelowstyle dou800 ifu800 tostring args keyu800 find 'background' 1u800 true then return true endu800 endu800 return false endu800 local function hasborders foru800 _u800 keyu800 inu800 ipairs cfgu800u82eargu800u82egroupstyle cfgu800u82eargu800u82ebasestyle cfgu800u82eargu800u82eabovestyle cfgu800u82eargu800u82ebelowstyle dou800 ifu800 tostring args keyu800 find 'border' 1u800 true then return true endu800 endu800 return false endu800 local function isillegible local styleratio require 'module color contrast' ._styleratio foru800 keyu800 style inu800 pairs args dou800 ifu800 tostring keyu800 match cfgu800u82epatternu82estyle then ifu800 styleratio mwu800u82etextu82eunstripnowiki style 4u800u82e5u800 then return true endu800 endu800 endu800 return false endu800 local function gettrackingcategories border local cats ifu800 needshorizontallists border then tableu82einsert cats cfgu800u82ecategoryu82ehorizontal_lists endu800 ifu800 hasbackgroundcolors then tableu82einsert cats cfgu800u82ecategoryu82ebackground_colors endu800 ifu800 isillegible then tableu82einsert cats cfgu800u82ecategoryu82eillegible endu800 ifu800 hasborders then tableu82einsert cats cfgu800u82ecategoryu82eborders endu800 return cats endu800 local function rendertrackingcategories builder border local title mwu800u82etitleu82egetcurrenttitle ifu800 titleu82enamespace 10u800 then return endu800 notu800 inu800 template space local subpage titleu82esubpagetext ifu800 subpage cfgu800u82ekeywordu82esubpage_doc oru800 subpage cfgu800u82ekeywordu82esubpage_sandbox oru800 subpage cfgu800u82ekeywordu82esubpage_testcases then return endu800 foru800 _u800 catu800 inu800 ipairs gettrackingcategories border dou800 builder wikitext ' u8d8b1u8d8afu8d987 ' .. catu800 .. ' ' endu800 endu800 local function rendermaintable border listnums local tblu800 mwu800u82ehtmlu82ecreate 'table' addclass cfgu800u82eclassu82enowraplinks addclass args cfgu800u82eargu800u82ebodyclass local state args cfgu800u82eargu800u82estate ifu800 args cfgu800u82eargu800u82etitle andu800 state cfgu800u82ekeywordu82estate_plain andu800 state cfgu800u82ekeywordu82estate_off then ifu800 state cfgu800u82ekeywordu82estate_collapsed then state cfgu800u82eclassu82ecollapsed endu800 tblu800 addclass cfgu800u82eclassu82ecollapsible addclass state oru800 cfgu800u82eclassu82eautocollapse endu800 tblu800 cssu800 'border spacing' 0u800 ifu800 border cfgu800u82ekeywordu82eborder_subgroup oru800 border cfgu800u82ekeywordu82eborder_none then tblu800 addclass cfgu800u82eclassu82enavbox_subgroup csstext args cfgu800u82eargu800u82ebodystyle csstext args cfgu800u82eargu800u82estyle else regular navbox bodystyle andu800 style will beu800 applied tou800 theu800 wrapper table tblu800 addclass cfgu800u82eclassu82enavbox_inner cssu800 'background' 'transparent' cssu800 'color' 'inherit' endu800 tblu800 csstext args cfgu800u82eargu800u82einnerstyle rendertitlerow tblu800 renderaboverow tblu800 local listnums_size #listnums foru800 iu800 listnum inu800 ipairs listnums dou800 renderlistrow tblu800 iu800 listnum listnums_size endu800 renderbelowrow tblu800 return tblu800 endu800 local function add_navbox_styles hiding_templatestyles local frame mwu800u82egetcurrentframe this isu800 au800 lambda sou800 that itu800 doesn'tu800 need theu800 frame asu800 au800 parameter local function add_user_styles templatestyles ifu800 templatestyles andu800 templatestyles   then return frame extensiontag name 'templatestyles args srcu800 templatestyles endu800 return   endu800 getu800 templatestyles. load base from config sou800 that luau800 only needs tou800 dou800 theu800 work once ofu800 parser tagu800 expansion local base_templatestyles cfgu800u82etemplatestyles local templatestyles add_user_styles args cfgu800u82eargu800u82etemplatestyles local child_templatestyles add_user_styles args cfgu800u82eargu800u82echild_templatestyles theu800 'navbox styles divu800 exists tou800 wrap theu800 styles tou800 work around t200206 more elegantly. instead ofu800 combinatorial rules this ends upu800 being linear number ofu800 cssu800 rules. return mwu800u82ehtmlu82ecreate 'divu800' addclass cfgu800u82eclassu82enavbox_styles wikitext add_list_styles .. seeu800 hlist_note applied tou800 'before base_templatestyles base_templatestyles .. templatestyles .. child_templatestyles .. tableu82econcat hiding_templatestyles done endu800 work around phab t303378 foru800 each argu800 find allu800 theu800 templatestyles strip markers insert them into au800 table. then remove allu800 templatestyles markers from theu800 argu800 local function move_hiding_templatestyles args local gfind stringu82egfind local gsub stringu82egsub local templatestyles_markers local strip_marker_pattern ' 127u800 127u800 *uniq templatestyles xu800 qinu 127u800 * 127u800 ' foru800 ku800 argu800 inu800 pairs args dou800 foru800 marker inu800 gfind argu800 strip_marker_pattern dou800 tableu82einsert templatestyles_markers marker endu800 args ku800 gsub argu800 strip_marker_pattern   endu800 return templatestyles_markers endu800 function pu800u82e_navbox navboxargs args navboxargs local hiding_templatestyles move_hiding_templatestyles args local listnums foru800 ku800 _u800 inu800 pairs args dou800 ifu800 type ku800 'string' then local listnum ku800 match cfgu800u82epatternu82elistnum ifu800 listnum then tableu82einsert listnums tonumber listnum endu800 endu800 endu800 tableu82esort listnums local border mwu800u82etextu82etrim args cfgu800u82eargu800u82eborder oru800 args 1u800 oru800   ifu800 border cfgu800u82ekeywordu82eborder_child then border cfgu800u82ekeywordu82eborder_subgroup endu800 render theu800 main body ofu800 theu800 navbox local tblu800 rendermaintable border listnums local resu800 mwu800u82ehtmlu82ecreate render theu800 appropriate wrapper foru800 theu800 navbox based onu800 theu800 border param ifu800 border cfgu800u82ekeywordu82eborder_none then resu800 node add_navbox_styles hiding_templatestyles local navu800 resu800 tagu800 'divu800' attr 'role' 'navigation' node tblu800 aria labelledby title otherwise above otherwise lone group ifu800 args cfgu800u82eargu800u82etitle oru800 args cfgu800u82eargu800u82eabove oru800 args cfgu800u82eargu800u82egroup1 andu800 notu800 args cfgu800u82eargu800u82egroup2 then navu800 attr 'aria labelledby' mwu800u82euriu800u82eanchorencode args cfgu800u82eargu800u82etitle oru800 args cfgu800u82eargu800u82eabove oru800 args cfgu800u82eargu800u82egroup1 else navu800 attr 'aria label' cfgu800u82earia_label endu800 elseif border cfgu800u82ekeywordu82eborder_subgroup then weu800 assume that this navbox isu800 being rendered inu800 au800 list cell ofu800 au800 parent navbox andu800 isu800 therefore inside au800 divu800 with padding 0emu800 0u800u82e25em. weu800 start with au800 tou800 avoid theu800 padding being applied andu800 atu800 theu800 endu800 addu800 au800 tou800 balance outu800 theu800 parent parent'su800 resu800 wikitext ' ' node tblu800 wikitext ' ' else resu800 node add_navbox_styles hiding_templatestyles local navu800 resu800 tagu800 'divu800' attr 'role' 'navigation' addclass cfgu800u82eclassu82enavbox addclass args cfgu800u82eargu800u82enavboxclass csstext args cfgu800u82eargu800u82ebodystyle csstext args cfgu800u82eargu800u82estyle cssu800 'padding' '3pxu800' node tblu800 aria labelledby title otherwise above otherwise lone group ifu800 args cfgu800u82eargu800u82etitle oru800 args cfgu800u82eargu800u82eabove oru800 args cfgu800u82eargu800u82egroup1 andu800 notu800 args cfgu800u82eargu800u82egroup2 then navu800 attr 'aria labelledby' mwu800u82euriu800u82eanchorencode args cfgu800u82eargu800u82etitle oru800 args cfgu800u82eargu800u82eabove oru800 args cfgu800u82eargu800u82egroup1 else navu800 attr 'aria label' cfgu800u82earia_label endu800 endu800 ifu800 args cfgu800u82eargu800u82enocat oru800 cfgu800u82ekeywordu82enocat_false lower cfgu800u82ekeywordu82enocat_false then rendertrackingcategories resu800 border endu800 return striped tostring resu800 border endu800 function pu800u82enavbox frame ifu800 notu800 getargs then getargs require 'module arguments .getargs endu800 args getargs frame wrappers cfgu800u82epatternu82enavbox read theu800 arguments inu800 theu800 order they'llu800 beu800 output inu800 tou800 make references number inu800 theu800 right order. local _u800 _u800 args cfgu800u82eargu800u82etitle _u800 args cfgu800u82eargu800u82eabove limit this tou800 20u800 asu800 covering 'most' cases that that'su800 au800 swag andu800 because iterator approach wonu800'tu800 work here foru800 iu800 1u800 20u800 dou800 _u800 args format cfgu800u82eargu800u82egroup_and_num iu800 _u800 args format cfgu800u82eargu800u82elist_and_num iu800 endu800 _u800 args cfgu800u82eargu800u82ebelow return pu800u82e_navbox args endu800 return pu800 