package Ġworld . ph ant asm al . web . core . stores Ċ Ċ import Ġkotlinx . browser . window Ċ import Ġkotlinx . coroutines . launch Ċ import Ġorg . w 3 c . dom . events . Keyboard Event Ċ import Ġworld . ph ant asm al . core . dis posable . Disposable Ċ import Ġworld . ph ant asm al . core . dis posable . Dis poser Ċ import Ġworld . ph ant asm al . core . dis posable . dis posable Ċ import Ġworld . ph ant asm al . observable . cell . Cell Ċ import Ġworld . ph ant asm al . observable . cell . Mutable Cell Ċ import Ġworld . ph ant asm al . observable . cell . eq Ċ import Ġworld . ph ant asm al . observable . cell . mutable Cell Ċ import Ġworld . ph ant asm al . web . core . Pw Tool Type Ċ import Ġworld . ph ant asm al . web . core . models . Server Ċ import Ġworld . ph ant asm al . we bui . dom . dis posable Listener Ċ import Ġworld . ph ant asm al . we bui . stores . Store Ċ Ċ interface ĠApplication Url Ġ{ ĊĠĠĠ Ġval Ġurl : ĠCell < String > ĊĊĠĠĠ Ġfun Ġpush Url ( url : ĠString ) ĊĊĠĠĠ Ġfun Ġreplace Url ( url : ĠString ) Ċ } Ċ Ċ class ĠUi Store ( private Ġval Ġapplication Url : ĠApplication Url ) Ġ: ĠStore () Ġ{ ĊĠĠĠ Ġprivate Ġval Ġ_ current Tool : ĠMutable Cell < Pw Tool Type > ĊĊĠĠĠ Ġprivate Ġval Ġ_ path Ġ= Ġmutable Cell ("") ĊĠĠĠ Ġprivate Ġval Ġ_ server Ġ= Ġmutable Cell ( Server . E ph ine a ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMaps Ġfull Ġpaths Ġto Ġmaps Ġof Ġparameters Ġand Ġtheir Ġvalues . ĠIn Ġother Ġwords Ġwe Ġkeep Ġtrack Ġof ĊĠĠĠĠ Ġ* Ġparameter Ġvalues Ġper Ġ[ application Url ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġparameters : ĠMutable Map < String , ĠMutable Map < String , ĠMutable Cell < String ? >>> Ġ= ĊĠĠĠĠĠĠĠ Ġmutable Map Of () ĊĠĠĠ Ġprivate Ġval Ġglobal KeyDown Handlers : ĠMutable Map < String , Ġsuspend Ġ( e : ĠKeyboard Event ) Ġ-> ĠUnit > Ġ= ĊĠĠĠĠĠĠĠ Ġmutable Map Of () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠEnabled Ġalpha Ġfeatures . ĠAlpha Ġfeatures Ġcan Ġbe Ġturned Ġon Ġby Ġadding Ġa Ġfeatures Ġparameter Ġwith ĊĠĠĠĠ Ġ* Ġthe Ġcomma - separated Ġfeature Ġnames Ġas Ġvalue . ĊĠĠĠĠ Ġ* ĠE . g . Ġ`/ viewer ? features = f 1 , f 2 , f 3 ` ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġfeatures : ĠMutable Set < String > Ġ= Ġmutable Set Of () ĊĊĠĠĠ Ġprivate Ġval Ġtools : ĠList < Pw Tool Type > Ġ= ĠP w Tool Type . values (). toList () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġdefault Ġtool Ġthat Ġis Ġloaded . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġdefault Tool : ĠP w Tool Type Ġ= ĠP w Tool Type . Viewer ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġtool Ġthat Ġis Ġcurrently Ġvisible . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġcurrent Tool : ĠCell < Pw Tool Type > ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMap Ġof Ġtools Ġto Ġa Ġboolean Ġcell Ġthat Ġsays Ġwhether Ġthey Ġare Ġthe Ġcurrent Ġtool Ġor Ġnot . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġtool To Active : ĠMap < Pw Tool Type , ĠCell < Boolean >> ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApplication ĠURL Ġwithout Ġthe Ġtool Ġpath Ġprefix . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpath : ĠCell < String > Ġ= Ġ_ path ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġprivate Ġserver Ġwe 're Ġcurrently Ġshowing Ġdata Ġand Ġtools Ġfor . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġserver : ĠCell < Server > Ġ= Ġ_ server ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ current Tool Ġ= Ġmutable Cell ( default Tool ) ĊĠĠĠĠĠĠĠ Ġcurrent Tool Ġ= Ġ_ current Tool ĊĊĠĠĠĠĠĠĠ Ġtool To Active Ġ= Ġtools . associate With Ġ{ Ġtool Ġ-> Ġcurrent Tool Ġeq Ġtool Ġ} ĊĊĠĠĠĠĠĠĠ Ġadd Dis pos ables ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwindow . dis posable Listener (" keydown ", Ġ:: dispatch Global KeyDown ), ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġobserve Now ( application Url . url ) Ġ{ ĠsetData From Url ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠsetCurrent Tool ( tool : ĠP w Tool Type ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( tool Ġ!= Ġcurrent Tool . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Application Url ( tool , Ġpath Ġ= Ġ"", Ġreplace Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsetCurrent Tool ( tool , Ġpath Ġ= Ġ"") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUpdates Ġ[ path ] Ġto Ġ[ prefix ] Ġif Ġthe Ġcurrent Ġpath Ġdoesn 't Ġstart Ġwith Ġ[ prefix ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġset Path Prefix ( prefix : ĠString , Ġreplace : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! path . value . startsWith ( prefix )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Application Url ( current Tool . value , Ġprefix , Ġreplace ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ path . value Ġ= Ġprefix ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġregister Parameter ( ĊĠĠĠĠĠĠĠ Ġtool : ĠP w Tool Type , ĊĠĠĠĠĠĠĠ Ġpath : ĠString , ĊĠĠĠĠĠĠĠ Ġparameter : ĠString , ĊĠĠĠĠĠĠĠ Ġset Initial Value : Ġ( String ?) Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠ Ġvalue : ĠCell < String ? >, ĊĠĠĠĠĠĠĠ ĠonChange : Ġ( String ?) Ġ-> ĠUnit , ĊĠĠĠ Ġ): ĠDis posable Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( parameter Ġ!== ĠFEATURE S _ PARAM ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ FEATURES _ PARAM Ġcan 't Ġbe Ġset Ġbecause Ġit Ġis Ġa Ġglobal Ġparameter ." ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠpathParams Ġ= Ġparameters . get Or Put ("/ ${ tool . slug }$ path ", Ġ:: mutable Map Of ) ĊĠĠĠĠĠĠĠ Ġval Ġparam Ġ= ĠpathParams . get Or Put ( parameter ) Ġ{ Ġmutable Cell ( null ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġset Initial Value ( param . value ) ĊĊĠĠĠĠĠĠĠ Ġvalue . value . let Ġ{ Ġv Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( v Ġ!= Ġparam . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Parameter ( tool , Ġpath , Ġparam , Ġv , Ġreplace Url Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠDis poser ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue . observe Change Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . value Ġ!= Ġparam . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Parameter ( tool , Ġpath , Ġparam , Ġit . value , Ġreplace Url Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparam . observe Change Ġ{ ĠonChange ( it . value ) Ġ}, ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġset Parameter ( ĊĠĠĠĠĠĠĠ Ġtool : ĠP w Tool Type , ĊĠĠĠĠĠĠĠ Ġpath : ĠString , ĊĠĠĠĠĠĠĠ Ġparameter : ĠMutable Cell < String ? >, ĊĠĠĠĠĠĠĠ Ġvalue : ĠString ?, ĊĠĠĠĠĠĠĠ Ġreplace Url : ĠBoolean , ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġparameter . value Ġ= Ġvalue ĊĊĠĠĠĠĠĠĠ Ġif Ġ( this . current Tool . value Ġ== Ġtool Ġ&& Ġthis . path . value Ġ== Ġpath ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Application Url ( tool , Ġpath , Ġreplace Url ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Global KeyDown ( ĊĠĠĠĠĠĠĠ Ġtool : ĠP w Tool Type , ĊĠĠĠĠĠĠĠ Ġbinding : ĠString , ĊĠĠĠĠĠĠĠ Ġhandler : Ġsuspend Ġ( Keyboard Event ) Ġ-> ĠUnit , ĊĠĠĠ Ġ): ĠDis posable Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġhandler Key ( tool , Ġbinding ) ĊĠĠĠĠĠĠĠ Ġrequire ( key Ġ! in Ġglobal KeyDown Handlers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ""" Binding Ġ"$ binding " Ġalready Ġexists Ġfor Ġtool Ġ$ tool .""" ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġglobal KeyDown Handlers [ key ] Ġ= Ġhandler ĊĊĠĠĠĠĠĠĠ Ġreturn Ġdis posable Ġ{ Ġglobal KeyDown Handlers . remove ( key ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSets Ġ[ current Tool ], Ġ[ path ], Ġ[ parameters ] Ġand Ġ[ features ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠsetData From Url ( url : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Split Ġ= Ġurl . split (" ?") ĊĠĠĠĠĠĠĠ Ġval Ġfull Path Ġ= Ġurl Split [ 0 ] ĊĠĠĠĠĠĠĠ Ġval Ġparams Str Ġ= Ġurl Split . get OrNull ( 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġsecond Slash Idx Ġ= Ġfull Path . indexOf ("/", Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġtool Str Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( second Slash Idx Ġ== Ġ- 1 ) Ġfull Path . substring ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġfull Path . substring ( 1 , Ġsecond Slash Idx ) ĊĊĠĠĠĠĠĠĠ Ġval Ġtool Ġ= ĠS LU G _ TO _ PW _ TOOL [ tool Str ] ĊĠĠĠĠĠĠĠ Ġval Ġpath Ġ= Ġif Ġ( second Slash Idx Ġ== Ġ- 1 ) Ġ"" Ġelse Ġfull Path . substring ( second Slash Idx ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( params Str Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparams Ġ= Ġparameters . get Or Put ( fullPath , Ġ:: mutable Map Of ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( p Ġin Ġparams Str . split ("& ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( param , Ġvalue ) Ġ= Ġp . split (" =", Ġlimit Ġ= Ġ 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( param Ġ== ĠFEATURE S _ PARAM ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( feature Ġin Ġvalue . split ("," )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfeatures . add ( feature ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . get Or Put ( param ) Ġ{ Ġmutable Cell ( value ) Ġ}. value Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġactual Tool Ġ= Ġtool Ġ?: Ġdefault Tool ĊĠĠĠĠĠĠĠ Ġthis . setCurrent Tool ( actual Tool , Ġpath ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( tool Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Application Url ( actual Tool , Ġpath , Ġreplace Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠsetCurrent Tool ( tool : ĠP w Tool Type , Ġpath : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ path . value Ġ= Ġpath ĊĠĠĠĠĠĠĠ Ġ_ current Tool . value Ġ= Ġtool ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Application Url ( tool : ĠP w Tool Type , Ġpath : ĠString , Ġreplace : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfull Path Ġ= Ġ"/ ${ tool . slug }${ path }" ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= Ġmutable Map Of < String , ĠString >() ĊĊĠĠĠĠĠĠĠ Ġparameters [ fullPath ]?. forEach Ġ{ Ġ( k , Ġv ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġv . value ?. let Ġ{ Ġparams [ k ] Ġ= Ġit Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( features . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams [ FEATURES _ PARAM ] Ġ= Ġfeatures . join ToString (",") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġparam Str Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( params . isEmpty ()) Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ" ?" Ġ+ Ġparams . map Ġ{ Ġ( k , Ġv ) Ġ-> Ġ"$ k =$ v " Ġ}. join ToString ("& ") ĊĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġ"${ fullPath }${ param Str }" ĊĊĠĠĠĠĠĠĠ Ġif Ġ( replace ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Url . replace Url ( url ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapplication Url . push Url ( url ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdispatch Global KeyDown ( e : ĠKeyboard Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbinding Parts Ġ= Ġmutable ListOf < String >() ĊĊĠĠĠĠĠĠĠ Ġif Ġ( e . ctrl Key ) Ġbinding Parts . add (" Ctrl ") ĊĠĠĠĠĠĠĠ Ġif Ġ( e . alt Key ) Ġbinding Parts . add (" Alt ") ĊĠĠĠĠĠĠĠ Ġif Ġ( e . shift Key ) Ġbinding Parts . add (" Shift ") ĊĠĠĠĠĠĠĠ Ġbinding Parts . add ( e . key . uppercase ()) ĊĊĠĠĠĠĠĠĠ Ġval Ġbinding Ġ= Ġbinding Parts . join ToString ("- ") ĊĊĠĠĠĠĠĠĠ Ġval Ġhandler Ġ= Ġglobal KeyDown Handlers [ handler Key ( current Tool . value , Ġbinding )] ĊĊĠĠĠĠĠĠĠ Ġif Ġ( handler Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . preventDefault () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscope . launch Ġ{ Ġhandler ( e ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandler Key ( tool : ĠP w Tool Type , Ġbinding : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ"$ tool Ġ-> Ġ$ binding " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠFEATURE S _ PARAM Ġ= Ġ" features " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠS LU G _ TO _ PW _ TOOL : ĠMap < String , ĠP w Tool Type > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠP w Tool Type . values (). associate By Ġ{ Ġit . slug Ġ} ĊĠĠĠ Ġ} Ċ } Ċ