package Ġcom . jetbrains . edu . learning . step ik . hyper skill . api Ċ Ċ import Ġcom . fasterxml . jackson . databind . ObjectMapper Ċ import Ġcom . fasterxml . jackson . databind . module . Simple Module Ċ import Ġcom . intellij . ide . Browser Util Ċ import Ġcom . intellij . openapi . application . Application Manager Ċ import Ġcom . intellij . openapi . application . run In Ed t Ċ import Ġcom . intellij . openapi . components . service Ċ import Ġcom . intellij . openapi . diagnostic . Logger Ċ import Ġcom . intellij . openapi . progress . Progress Manager Ċ import Ġcom . intellij . openapi . project . Project Ċ import Ġcom . jetbrains . edu . learning .* Ċ import Ġcom . jetbrains . edu . learning . auth Utils . OAuth Utils . Grant Type . AUTHORIZATION _ CODE Ċ import Ġcom . jetbrains . edu . learning . auth Utils . OAuth Utils . Grant Type . REFRESH _ TOKEN Ċ import Ġcom . jetbrains . edu . learning . auth Utils . OAuth Utils . check Builtin Port Valid Ċ import Ġcom . jetbrains . edu . learning . course Format . Course Ċ import Ġcom . jetbrains . edu . learning . course Format . Framework Lesson Ċ import Ġcom . jetbrains . edu . learning . course Format . Lesson Ċ import Ġcom . jetbrains . edu . learning . course Format . tasks . Task Ċ import Ġcom . jetbrains . edu . learning . messages . E du Core Bundle Ċ import Ġcom . jetbrains . edu . learning . step ik . Py Char m Step Options Ċ import Ġcom . jetbrains . edu . learning . step ik . api .* Ċ import Ġcom . jetbrains . edu . learning . step ik . hyper skill .* Ċ import Ġcom . jetbrains . edu . learning . step ik . hyper skill . checker . WebSocket Connection State Ċ import Ġcom . jetbrains . edu . learning . step ik . hyper skill . course Format . Hyper skill Course Ċ import Ġcom . jetbrains . edu . learning . step ik . hyper skill . course Generation . Hyper skill Task Builder Ċ import Ġcom . jetbrains . edu . learning . step ik . hyper skill . settings . Hyper skill Settings Ċ import Ġcom . jetbrains . edu . learning . submissions . Submission Ċ import Ġcom . jetbrains . edu . learning . task Description . ui . Task Description View Ċ import Ġcom . jetbrains . edu . learning . task Description . ui . tab . Tab Manager . Tab Type . TOP ICS _ TAB Ċ import Ġokhttp 3 .* Ċ import Ġretrofit 2 . Call Ċ import Ġretrofit 2 . converter . jackson . Jack son Converter Factory Ċ import Ġjava . util . concurrent . Count DownLatch Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ abstract Ġclass ĠHyper skill Connector Ġ{ ĊĊĠ Ġprivate Ġvar Ġauthorization Bus Connection Ġ= ĠApplication Manager . getApplication (). message Bus . connect () ĊĊĠ Ġprivate Ġval Ġconnection Pool : ĠConnection Pool Ġ= ĠConnection Pool () ĊĠ Ġprivate Ġval Ġconverter Factory : ĠJack son Converter Factory ĊĠ Ġval ĠobjectMapper : ĠObjectMapper ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġval Ġmodule Ġ= ĠSimple Module () ĊĠĠĠ Ġmodule . add Deserializer ( Py Char m Step Options :: class . java , ĠJack son Step Options Deserializer ()) ĊĠĠĠ ĠobjectMapper Ġ= ĠSte pi k Connector . create Mapper ( module ) ĊĠĠĠ Ġconverter Factory Ġ= ĠJack son Converter Factory . create ( object Mapper ) ĊĠ Ġ} ĊĊĠ Ġprotected Ġabstract Ġval ĠbaseUrl : ĠString ĊĊĠ Ġprivate Ġval Ġauthorization Service : ĠHyper skill Service ĊĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠ Ġval Ġretrofit Ġ= Ġcreate Ret rofit Builder ( baseUrl , Ġconnection Pool ) ĊĠĠĠĠĠĠĠ Ġ. add Converter Factory ( converter Factory ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠ Ġreturn Ġretrofit . create ( Hyper skill Service :: class . java ) ĊĠĠĠ Ġ} ĊĊĠ Ġprivate Ġval Ġservice : ĠHyper skill Service ĊĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠ Ġval Ġaccount Ġ= ĠHyper skill Settings . INSTANCE . account ĊĠĠĠĠĠ Ġval ĠaccessToken Ġ= Ġaccount ?. get AccessToken () ĊĠĠĠĠĠ Ġreturn Ġservice ( account , ĠaccessToken ) ĊĠĠĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġservice ( account : ĠHyper skill Account ?, ĠaccessToken : ĠString ?): ĠHyper skill Service Ġ{ ĊĠĠĠ Ġif Ġ(! is UnitTest Mode Ġ&& Ġaccount Ġ!= Ġnull Ġ&& Ġ! account . is Up ToDate ()) Ġ{ ĊĠĠĠĠĠ Ġaccount . refresh Tokens () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġretrofit Ġ= Ġcreate Ret rofit Builder ( baseUrl , Ġconnection Pool , ĠaccessToken Ġ= ĠaccessToken ) ĊĠĠĠĠĠ Ġ. add Converter Factory ( converter Factory ) ĊĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġreturn Ġretrofit . create ( Hyper skill Service :: class . java ) ĊĠ Ġ} ĊĊĠ Ġ// ĠAuthorization Ġrequests : ĊĊĠ Ġfun Ġdo Authorize ( var arg Ġpost Login Actions : ĠRunnable ) Ġ{ ĊĠĠĠ Ġif Ġ(! check Builtin Port Valid ()) Ġreturn ĊĊĠĠĠ Ġcreate Authorization Listener (* post Login Actions ) ĊĠĠĠ ĠBrowser Util . browse ( AUTHOR IS ATION _ CODE _ URL ) ĊĠ Ġ} ĊĊĠ Ġfun Ġlogin ( code : ĠString ): ĠBoolean Ġ{ ĊĠĠĠ Ġval Ġresponse Ġ= Ġauthorization Service . get Tokens ( CLIENT _ ID , ĠCLIENT _ SECRET , ĠRED I RECT _ URI , Ġcode , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAUTH ORIZ ATION _ CODE ). execute Handling Exceptions () ĊĠĠĠ Ġval Ġtoken Info Ġ= Ġresponse ?. body () Ġ?: Ġreturn Ġfalse ĊĠĠĠ Ġval Ġaccount Ġ= ĠHyper skill Account ( token Info . expires In ) ĊĠĠĠ Ġval ĠcurrentUser Ġ= ĠgetCurrent User ( account , Ġtoken Info . accessToken ) Ġ?: Ġreturn Ġfalse ĊĠĠĠ Ġaccount . userInfo Ġ= ĠcurrentUser ĊĠĠĠ ĠHyper skill Settings . INSTANCE . account Ġ= Ġaccount ĊĠĠĠ Ġaccount . save Tokens ( token Info ) ĊĠĠĠ ĠApplication Manager . getApplication (). message Bus . sync Publisher ( AUTHORIZATION _ TOPIC ). user LoggedIn () ĊĠĠĠ Ġreturn Ġtrue ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠHyper skill Account . refresh Tokens () Ġ{ ĊĠĠĠ Ġval Ġrefresh Token Ġ= Ġget RefreshToken () Ġ?: Ġreturn ĊĠĠĠ Ġval Ġresponse Ġ= Ġauthorization Service . refresh Tokens ( REFRESH _ TOKEN , ĠCLIENT _ ID , ĠCLIENT _ SECRET , Ġrefresh Token ). execute Handling Exceptions () ĊĠĠĠ Ġval Ġtokens Ġ= Ġresponse ?. body () ĊĠĠĠ Ġif Ġ( tokens Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġtoken Expires In Ġ= Ġtokens . expires In ĊĠĠĠĠĠ Ġsave Tokens ( tokens ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ// ĠGet Ġrequests : ĊĊĠ Ġfun ĠgetCurrent User ( account : ĠHyper skill Account , ĠaccessToken : ĠString ?): ĠHyper skill Profile Info ? Ġ{ ĊĠĠĠ Ġval Ġresponse Ġ= Ġservice ( account , ĠaccessToken ). getCurrent UserInfo (). execute Handling Exceptions () ĊĠĠĠ Ġval ĠuserInfo Ġ= Ġresponse ?. body ()?. profiles ?. first OrNull () ĊĠĠĠ Ġif Ġ( userInfo ?. is Guest Ġ== Ġtrue ) Ġ{ ĊĠĠĠĠĠ Ġ// Ġit Ġmeans Ġthat Ġsession Ġis Ġbroken Ġand Ġwe Ġshould Ġforce Ġuser Ġto Ġre login ĊĠĠĠĠĠ ĠLOG . warn (" User Ġ${ userInfo . fullname } Ġ${ userInfo . email } Ġis Ġanonymous ") ĊĠĠĠĠĠ ĠHyper skill Settings . INSTANCE . account Ġ= Ġnull ĊĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠuserInfo ĊĠ Ġ} ĊĊĠ Ġfun Ġget Stages ( projectId : ĠInt ): ĠList < Hyper skill Stage >? Ġ{ ĊĠĠĠ Ġval Ġresponse Ġ= Ġservice . stages ( projectId ). execute Handling Exceptions () ĊĠĠĠ Ġreturn Ġresponse ?. body ()?. stages ĊĠ Ġ} ĊĊĠ Ġfun Ġget Project ( projectId : ĠInt ): ĠResult < Hyper skill Project , ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġservice . project ( projectId ). execute Parsing Errors ( true ). flatMap Ġ{ ĊĠĠĠĠĠ Ġval Ġresult Ġ= Ġit . body ()?. projects ?. first OrNull () ĊĠĠĠĠĠ Ġif Ġ( result Ġ== Ġnull ) ĠErr ( it . message ()) Ġelse ĠOk ( result ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġget Step Sources ( step Ids : ĠList < Int >): ĠResult < List < Hyper skill Step Source >, ĠString > Ġ= ĊĠĠĠ Ġservice . steps ( step Ids . join ToString ( separator Ġ= Ġ", ")). execute And Extract From Body (). flatMap Ġ{ ĠOk ( it . steps ) Ġ} ĊĊĠ Ġfun Ġget Steps For Topic ( topic : ĠInt ): ĠResult < List < Hyper skill Step Source >, ĠString > Ġ= ĊĠĠĠ Ġservice . steps ( topic ). execute And Extract From Body (). flatMap Ġ{ ĠOk ( it . steps ) Ġ} ĊĊĠ Ġfun Ġget Step Source ( step Id : ĠInt ): ĠResult < Hyper skill Step Source , ĠString > Ġ= ĊĠĠĠ Ġservice . steps ( step Id . toString ()). execute And Extract From Body (). flatMap Ġ{ ĊĠĠĠĠĠ Ġval Ġresult Ġ= Ġit . steps . first OrNull () ĊĠĠĠĠĠ Ġif Ġ( result Ġ== Ġnull ) ĠErr (" Can 't Ġget Ġstep Ġsource Ġwith Ġ$ step Id Ġid ") Ġelse ĠOk ( result ) ĊĠĠĠ Ġ} ĊĊĠ Ġfun Ġfill Topics ( course : ĠHyper skill Course , Ġproject : ĠProject ) Ġ{ ĊĠĠĠ Ġfor Ġ(( task Index , Ġstage ) Ġin Ġcourse . stages . with Index ()) Ġ{ ĊĠĠĠĠĠ Ġval Ġtopics Ġ= ĠgetAll Topics ( stage ) ĊĠĠĠĠĠ Ġif Ġ( topics . isEmpty ()) Ġcontinue ĊĊĠĠĠĠĠ Ġcourse . task To Topics [ task Index ] Ġ= Ġtopics ĊĠĠĠĠĠ Ġrun In Ed t Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( project . is Disposed ) Ġreturn @ run In Ed t ĊĠĠĠĠĠĠĠ ĠTask Description View . getInstance ( project ). update Tab ( TOP ICS _ TAB ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠgetAll Topics ( stage : ĠHyper skill Stage ): ĠList < Hyper skill Topic > Ġ{ ĊĠĠĠ Ġvar Ġpage Ġ= Ġ 1 ĊĠĠĠ Ġval Ġtopics Ġ= Ġmutable ListOf < Hyper skill Topic >() ĊĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠ Ġval Ġtopics List Ġ= Ġservice . topics ( stage . id , Ġpage ). execute Handling Exceptions ( true )?. body () Ġ?: Ġbreak ĊĠĠĠĠĠ Ġtopics . addAll ( topics List . topics . filter Ġ{ Ġit . theory Id Ġ!= Ġnull Ġ}) ĊĠĠĠĠĠ Ġpage Ġ+= Ġ 1 ĊĠĠĠ Ġ} ĊĠĠĠ Ġwhile Ġ( topics List . topics . isNotEmpty () Ġ&& Ġtopics List . meta [" has _ next "] Ġ== Ġtrue ) ĊĠĠĠ Ġreturn Ġtopics ĊĠ Ġ} ĊĊĠ Ġfun Ġget Lesson ( course : ĠHyper skill Course , Ġattachment Link : ĠString ): ĠLess on Ġ{ ĊĠĠĠ Ġval Ġprogress Indicator Ġ= ĠProgress Manager . getInstance (). progress Indicator ĊĊĠĠĠ Ġval Ġlesson Ġ= ĠFramework Lesson () ĊĠĠĠ Ġlesson . index Ġ= Ġ 1 ĊĠĠĠ Ġlesson . course Ġ= Ġcourse ĊĠĠĠ Ġprogress Indicator ?. check Canceled () ĊĠĠĠ Ġval Ġstep Sources Ġ= Ġget Step Sources ( course . stages . map Ġ{ Ġit . step Id Ġ}). onError Ġ{ Ġempty List () Ġ} ĊĊĠĠĠ Ġprogress Indicator ?. check Canceled () ĊĠĠĠ Ġval Ġtasks Ġ= Ġget Tasks ( course , Ġlesson , Ġstep Sources ) ĊĠĠĠ Ġfor Ġ( task Ġin Ġtasks ) Ġ{ ĊĠĠĠĠĠ Ġlesson . add Task ( task ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġlesson . sort Items () ĊĠĠĠ Ġload And Fill Additional Course Info ( course , Ġattachment Link ) ĊĠĠĠ Ġload And Fill Lesson Additional Info ( lesson ) ĊĠĠĠ Ġreturn Ġlesson ĊĠ Ġ} ĊĊĠ Ġfun Ġget Problems ( course : ĠCourse , Ġlesson : ĠLess on , Ġsteps : ĠList < Int >): ĠList < Task > Ġ{ ĊĠĠĠ Ġval Ġstep Sources Ġ= Ġget Step Sources ( steps ). onError Ġ{ Ġempty List () Ġ} ĊĠĠĠ Ġreturn Ġget Tasks ( course , Ġlesson , Ġstep Sources ) ĊĠ Ġ} ĊĊĠ Ġfun Ġload Stages ( hyper skill Course : ĠHyper skill Course ): ĠBoolean Ġ{ ĊĠĠĠ Ġval Ġhyper skill Project Ġ= Ġhyper skill Course . hyper skill Project Ġ?: Ġerror (" No ĠHyper skill Ġproject ") ĊĠĠĠ Ġval ĠprojectId Ġ= Ġhyper skill Project . id ĊĠĠĠ Ġif Ġ( hyper skill Course . stages . isEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġval Ġstages Ġ= Ġget Stages ( projectId ) Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠ Ġhyper skill Course . stages Ġ= Ġstages ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġstages Ġ= Ġhyper skill Course . stages ĊĠĠĠ Ġval Ġlesson Ġ= Ġget Lesson ( hyper skill Course , Ġhyper skill Project . ide Files ) ĊĠĠĠ Ġif Ġ( lesson . task List . size Ġ!= Ġstages . size ) Ġ{ ĊĠĠĠĠĠ ĠLOG . warn (" Course Ġhas Ġ${ stages . size } Ġstages , Ġbut Ġ${ lesson . task List . size } Ġtasks ") ĊĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġlesson . task List . forEach Indexed Ġ{ Ġindex , Ġtask Ġ-> ĊĠĠĠĠĠ Ġtask . feedback Link Ġ= Ġfeedback Link ( projectId , Ġstages [ index ]) ĊĠĠĠĠĠ Ġtask . name Ġ= Ġstages [ index ]. title ĊĠĠĠ Ġ} ĊĠĠĠ Ġlesson . name Ġ= Ġhyper skill Course . name ĊĊĠĠĠ Ġ// ĠWe Ġwant Ġproject Ġlesson Ġto Ġbe Ġthe Ġfirst ĊĠĠĠ Ġ// ĠIt 's Ġpossible Ġto Ġopen ĠPro blems Ġin ĠIDE Ġwithout Ġloading Ġproject Ġlesson Ġ( stages ) ĊĠĠĠ Ġ// ĠSo Ġwe Ġneed Ġto Ġupdate Ġindices Ġof Ġexisting ĠPro blems Ġin Ġthis Ġcase ĊĠĠĠ Ġif Ġ( hyper skill Course . lessons . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġfor Ġ( existing Lesson Ġin Ġhyper skill Course . lessons ) Ġ{ ĊĠĠĠĠĠĠĠ Ġexisting Lesson . index Ġ+= Ġ 1 ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġhyper skill Course . add Lesson ( lesson ) ĊĠĠĠ Ġhyper skill Course . sort Items () ĊĠĠĠ Ġreturn Ġtrue ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġfeedback Link ( project : ĠInt , Ġstage : ĠHyper skill Stage ): ĠString Ġ{ ĊĠĠĠ Ġreturn Ġ"${ stage Link ( project , Ġstage . id )} $ HY PER SK ILL _ COMMENT _ AN CH OR " ĊĠ Ġ} ĊĊĠ Ġfun Ġget Sub missions ( step Ids : ĠSet < Int >): ĠList < Submission > Ġ{ ĊĠĠĠ Ġval ĠuserId Ġ= ĠHyper skill Settings . INSTANCE . account ?. userInfo ?. id Ġ?: Ġreturn Ġempty List () ĊĠĠĠ Ġvar ĠcurrentPage Ġ= Ġ 1 ĊĠĠĠ Ġval Ġall Sub missions Ġ= Ġmutable ListOf < Submission >() ĊĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠ Ġval Ġsubmissions List Ġ= Ġservice . submission ( userId , Ġstep Ids . join ToString ( separator Ġ= Ġ", "), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠcurrentPage ). execute Handling Exceptions ()?. body () Ġ?: Ġbreak ĊĠĠĠĠĠ Ġval Ġsubmissions Ġ= Ġsubmissions List . submissions ĊĠĠĠĠĠ Ġall Sub missions . addAll ( submissions ) ĊĠĠĠĠĠ Ġif Ġ( submissions . isEmpty () Ġ|| Ġ! submissions List . meta . containsKey (" has _ next ") Ġ|| Ġsubmissions List . meta [" has _ next "] Ġ== Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ ĠcurrentPage Ġ+= Ġ 1 ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġall Sub missions ĊĠ Ġ} ĊĊĠ Ġfun Ġget Submission ById ( submission Id : ĠInt ): ĠResult < Submission , ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġwith Token Refresh IfNeeded Ġ{ Ġservice . submission ( submission Id ). execute And Extract First ( Sub missions List :: submissions ) Ġ} ĊĠ Ġ} ĊĊĠ Ġfun ĠgetUser ( userId : ĠInt ): ĠResult < User , ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġservice . user ( userId ). execute And Extract First ( Users List :: users ) ĊĠ Ġ} ĊĊĠ Ġfun Ġget Active Attempt ( step : ĠInt ): ĠResult < Attempt ?, ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġwith Token Refresh IfNeeded Ġ{ ĊĠĠĠĠĠ Ġval ĠuserId Ġ= ĠHyper skill Settings . INSTANCE . account ?. userInfo ?. id ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġreturn @ with Token Refresh IfNeeded ĠErr (" Attempt Ġto Ġget Ġlist Ġof Ġattempts Ġfor Ġun authorized Ġuser ") ĊĠĠĠĠĠ Ġval Ġattempts Ġ= Ġservice . attempts ( step , ĠuserId ). execute Parsing Errors ( true ). flatMap Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġit . body ()?. attempts ĊĠĠĠĠĠĠĠ Ġif Ġ( result Ġ== Ġnull ) ĠErr ( it . message ()) Ġelse ĠOk ( result ) ĊĠĠĠĠĠ Ġ}. onError Ġ{ Ġreturn @ with Token Refresh IfNeeded ĠErr ( it ) Ġ} ĊĊĠĠĠĠĠ Ġval Ġactive Attempt Ġ= Ġattempts . first OrNull Ġ{ Ġit . isActive Ġ&& Ġit . isRunning Ġ} ĊĠĠĠĠĠ ĠOk ( active Attempt ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġget Dataset ( attempt Id : ĠInt ): ĠResult < String , ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġservice . dataset ( attempt Id ). execute Parsing Errors (). flatMap Ġ{ ĊĠĠĠĠĠ Ġval Ġresponse Body Ġ= Ġit . body () Ġ?: Ġreturn @ flatMap ĠErr ( E du Core Bundle . message (" error . failed . to . parse . response ")) ĊĠĠĠĠĠ ĠOk ( response Body . string ()) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ// ĠPost Ġrequests : ĊĊĠ Ġfun Ġpost Submission ( submission : ĠSubmission ): ĠResult < Submission , ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġwith Token Refresh IfNeeded Ġ{ Ġservice . submission ( submission ). execute And Extract First ( Sub missions List :: submissions ) Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġpost Attempt ( step : ĠInt ): ĠResult < Attempt , ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġwith Token Refresh IfNeeded Ġ{ Ġservice . attempt ( Attempt ( step )). execute And Extract First ( Attempts List :: attempts ) Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġmark Theory Completed ( step : ĠInt ): ĠResult < Any , ĠString > Ġ= ĊĠĠĠ Ġwith Token Refresh IfNeeded Ġ{ Ġservice . complete Step ( step ). execute Parsing Errors ( true ) Ġ} ĊĊĠ Ġfun Ġget WebSocket Configuration (): ĠResult < WebSocket Configuration , ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġwith Token Refresh IfNeeded Ġ{ Ġservice . websocket (). execute And Extract From Body () Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġsend Frontend Events ( events : ĠList < Hyper skill Frontend Event >): ĠResult < List < Hyper skill Frontend Event >, ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġwith Token Refresh IfNeeded Ġ{ Ġservice . send Frontend Events ( events ). execute And Extract From Body () Ġ}. map Ġ{ Ġit . events Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġsend Time Sp ent Events ( events : ĠList < Hyper skill Time Sp ent Event >): ĠResult < List < Hyper skill Time Sp ent Event >, ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġwith Token Refresh IfNeeded Ġ{ Ġservice . send Time Sp ent Events ( events ). execute And Extract From Body () Ġ}. map Ġ{ Ġit . events Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġ< T > ĠCall < T >. execute And Extract From Body (): ĠResult < T , ĠString > Ġ{ ĊĠĠĠ Ġreturn Ġexecute Parsing Errors ( true ). flatMap Ġ{ ĊĠĠĠĠĠ Ġval Ġresult Ġ= Ġit . body () ĊĠĠĠĠĠ Ġif Ġ( result Ġ== Ġnull ) ĠErr ( it . message ()) Ġelse ĠOk ( result ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġ< T > Ġwith Token Refresh IfNeeded ( call : Ġ() Ġ-> ĠResult < T , ĠString >): ĠResult < T , ĠString > Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= Ġcall () ĊĠĠĠ Ġif Ġ(! is UnitTest Mode Ġ&& Ġ! Application Manager . getApplication (). is Internal ĊĠĠĠĠĠĠĠ Ġ&& Ġresult Ġis ĠErr Ġ&& Ġresult . error Ġ== ĠE du Core Bundle . message (" error . access . den ied ")) Ġ{ ĊĠĠĠĠĠ ĠHyper skill Settings . INSTANCE . account ?. refresh Tokens () ĊĠĠĠĠĠ Ġreturn Ġcall () ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġcreate Authorization Listener ( var arg Ġpost Login Actions : ĠRunnable ) Ġ{ ĊĠĠĠ Ġauthorization Bus Connection . disconnect () ĊĠĠĠ Ġauthorization Bus Connection Ġ= ĠApplication Manager . getApplication (). message Bus . connect () ĊĠĠĠ Ġauthorization Bus Connection . subscribe ( AUTHORIZATION _ TOPIC , Ġobject Ġ: ĠE du Log In Listener Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun Ġuser Logged Out () Ġ{} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġuser LoggedIn () Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( action Ġin Ġpost Login Actions ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġaction . run () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠ Ġ} ĊĊĠ Ġfun Ġconnect To WebSocket WithTimeout ( time Out Sec : ĠLong , Ġurl : ĠString , ĠinitialState : ĠWebSocket Connection State ): ĠWebSocket Connection State Ġ{ ĊĊĠĠĠ Ġfun Ġlog Event ( eventName : ĠString , Ġstate : ĠWebSocket Connection State , Ġmessage : ĠString ) Ġ= ĊĠĠĠĠĠ ĠLOG . debug (" WS : Ġnew Ġevent . ĠEvent =$ eventName , Ġstate =${ state :: class . java . simple Name }, Ġmessage =${ message }") ĊĊĠĠĠ Ġval Ġclient Ġ= ĠOk HttpClient () ĊĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠ Ġvar Ġstate Ġ= ĠinitialState ĊĠĠĠ Ġval Ġsocket Ġ= Ġcreate WebSocket ( client , Ġurl , Ġobject Ġ: ĠWebSocket Listener () Ġ{ ĊĠĠĠĠĠ Ġprivate Ġfun Ġhandle Event ( eventName : ĠString , Ġweb Socket : ĠWebSocket , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog Event ( eventName , Ġstate , Ġmessage ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġstate Ġ= Ġstate . handle Event ( web Socket , Ġmessage ) ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( state . is Terminal ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠLOG . error ( e ) ĊĠĠĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġon Open ( web Socket : ĠWebSocket , Ġresponse : ĠResponse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhandle Event (" open ", Ġweb Socket , Ġresponse . message ()) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġon Failure ( web Socket : ĠWebSocket , Ġt : ĠThrowable , Ġresponse : ĠResponse ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog Event (" failure ", Ġstate , Ġresponse ?. message () Ġ?: Ġ" no Ġmessage ") ĊĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġon Message ( web Socket : ĠWebSocket , Ġtext : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhandle Event (" message ", Ġweb Socket , Ġtext ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġon Closed ( web Socket : ĠWebSocket , Ġcode : ĠInt , Ġreason : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog Event (" closure ", Ġstate , Ġreason ) ĊĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĊĠĠĠ Ġl atch . await ( time Out Sec , ĠTimeUnit . SECONDS ) ĊĠĠĠ Ġsocket . close ( 1 0 0 0 , Ġnull ) ĊĠĠĠ Ġclient . dispatcher (). executor Service (). shutdown () ĊĠĠĠ Ġreturn Ġstate ĊĠ Ġ} ĊĊĠ Ġprotected Ġopen Ġfun Ġcreate WebSocket ( client : ĠOk HttpClient , Ġurl : ĠString , Ġlistener : ĠWebSocket Listener ): ĠWebSocket Ġ= ĊĠĠĠ Ġclient . new WebSocket ( Request . Builder (). url ( url ). build (), Ġlistener ) ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġval ĠLOG Ġ= ĠLogger . getInstance (" com . jetbrains . edu . learning . Hyper skill Connector ") ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġval ĠAUTH ORIZ ATION _ TOPIC Ġ= Ġcom . intellij . util . messages . Topic . create (" E du . hyper skill LoggedIn ", ĠE du Log In Listener :: class . java ) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun ĠgetInstance (): ĠHyper skill Connector Ġ= Ġservice () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreate Ġnew Ġtasks Ġin Ġlesson . ĠTasks Ġget Ġfrom Ġstep Sources ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Tasks ( course : ĠCourse , Ġlesson : ĠLess on , Ġstep Sources : ĠList < Hyper skill Step Source >): ĠList < Task > Ġ{ ĊĠĠĠĠĠ Ġval Ġhyper skill Course Ġ= Ġcourse Ġas ĠHyper skill Course ĊĠĠĠĠĠ Ġreturn Ġstep Sources . map NotNull Ġ{ Ġstep Ġ-> ĊĠĠĠĠĠĠĠ ĠHyper skill Task Builder ( course , Ġlesson , Ġstep ). build () ĊĠĠĠĠĠĠĠĠĠ Ġ? . also Ġ{ Ġhyper skill Course . update Additional Files ( step ) Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠHyper skill Course . update Additional Files ( step Source : ĠHyper skill Step Source ) Ġ{ ĊĠĠĠĠĠ Ġval Ġfiles Ġ= Ġ( step Source . block ?. options Ġas ĠPy Char m Step Options ). hyper skill ?. files Ġ?: Ġreturn ĊĠĠĠĠĠ Ġadditional Files . addAll ( files . filter Ġ{ Ġtask File Ġ-> ĊĠĠĠĠĠĠĠ Ġtask File . name Ġ! in Ġadditional Files . map Ġ{ Ġit . name Ġ} ĊĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ