package Ġio Ċ Ċ import Ġcom . s der col in . har mo lo id . core . model . Content Ċ import Ġcom . s der col in . har mo lo id . core . model . KEY _ IN _ OCT AVE Ċ import Ġcom . s der col in . har mo lo id . core . model . Note Ċ import Ġcom . s der col in . har mo lo id . core . model . Note Shift Ċ import Ġcom . s der col in . har mo lo id . core . model . Time Signature Ċ import Ġcom . s der col in . har mo lo id . core . model . Track Ċ import Ġexception . Illegal File Exception Ċ import Ġexternal . generate UUID Ċ import Ġmodel . Export Result Ċ import Ġmodel . Format Ċ import Ġmodel . Project Ċ import Ġmodel . Tick Counter Ċ import Ġorg . w 3 c . dom . Document Ċ import Ġorg . w 3 c . dom . Element Ċ import Ġorg . w 3 c . dom . XML Document Ċ import Ġorg . w 3 c . dom . parsing . DOM Parser Ċ import Ġorg . w 3 c . dom . parsing . XML Serializer Ċ import Ġorg . w 3 c . files . Blob Ċ import Ġorg . w 3 c . files . Blob Property Bag Ċ import Ġorg . w 3 c . files . File Ċ import Ġutil . clone Ċ import Ġutil . getElement ListBy TagName Ċ import Ġutil . get Required Attribute Ċ import Ġutil . get Required Attribute As Integer Ċ import Ġutil . get Required Attribute As Long Ċ import Ġutil . get Single Element By TagName Ċ import Ġutil . get Single Element By TagName OrNull Ċ import Ġutil . insert After This Ċ import Ġutil . name Without Extension Ċ import Ġutil . read Text Ċ Ċ object ĠC cs Ġ{ ĊĠĠĠ Ġsuspend Ġfun Ġparse ( file : ĠFile ): ĠProject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠprojectName Ġ= Ġfile . name Without Extension ĊĠĠĠĠĠĠĠ Ġval Ġtext Ġ= Ġfile . read Text () ĊĠĠĠĠĠĠĠ Ġval Ġparser Ġ= ĠDOM Parser () ĊĠĠĠĠĠĠĠ Ġval Ġdocument Ġ= Ġparser . parse FromString ( text , Ġ" text / xml ") Ġas ĠXML Document ĊĊĠĠĠĠĠĠĠ Ġval Ġscenario Node Ġ= Ġdocument . documentElement Ġ?: Ġthrow ĠIllegal File Exception . Xml Root NotFound () ĊĠĠĠĠĠĠĠ Ġval Ġscene Node Ġ= Ġscenario Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Sequence ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Scene ") ĊĠĠĠĠĠĠĠ Ġval Ġunit Nodes Ġ= Ġscene Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Units ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. getElement ListBy TagName (" Unit ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . getAttribute (" Category ") Ġ== Ġ" S inger Song " Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġgroup Nodes Ġ= Ġscene Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Groups ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. getElement ListBy TagName (" Group ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . getAttribute (" Category ") Ġ== Ġ" S inger Song " Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġresults Ġ= Ġunit Nodes . map Indexed Ġ{ Ġindex , Ġunit Node Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠgroupId Ġ= Ġunit Node . getAttribute (" Group ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroup Ġ= ĠgroupId ?. let Ġ{ Ġid Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgroup Nodes . find Ġ{ Ġit . getAttribute (" Id ") Ġ== Ġid Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtrack Name Ġ= Ġgroup ?. getAttribute (" Name ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparse Track ( index , Ġunit Node , Ġtrack Name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtime Signatures Ġ= Ġmerge Time Signatures ( results ) ĊĠĠĠĠĠĠĠ Ġval Ġtracks Ġ= Ġresults . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTrack . build ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . index , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . notes , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtime Signatures ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠProject ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġformat Ġ= ĠFormat . C cs , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput Files Ġ= ĠlistOf ( file ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= ĠprojectName , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= ĠContent ( tracks ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmerge Time Signatures ( ĊĠĠĠĠĠĠĠ Ġresults : ĠList < Track Parse Result > ĊĠĠĠ Ġ): ĠList < Time Signature > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġresults . first OrNull Ġ{ Ġit . time Signatures . isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . time Signatures . let Ġ{ Ġit Ġ?: ĠlistOf ( Time Signature . default ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Track ( index : ĠInt , Ġunit Node : ĠElement , Ġname : ĠString ?): ĠTrack Parse Result Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtime Nodes Ġ= Ġunit Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName OrNull (" Song ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . get Single Element By TagName OrNull (" Beat ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . getElement ListBy TagName (" Time "). or Empty () ĊĊĠĠĠĠĠĠĠ Ġval Ġtick Counter Ġ= ĠTick Counter ( TICK _ RATE ) ĊĠĠĠĠĠĠĠ Ġval Ġtime Signatures Ġ= Ġtime Nodes . map NotNull Ġ{ Ġtime Node Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtick Ġ= Ġtime Node . getAttribute (" Clock ") ?. to Long OrNull () Ġ?: Ġreturn @ map NotNull Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnum erator Ġ= Ġtime Node . getAttribute (" Be ats ") ?. toInt OrNull () Ġ?: Ġreturn @ map NotNull Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdenominator Ġ= Ġtime Node . getAttribute (" Beat Type ") ?. toInt OrNull () Ġ?: Ġreturn @ map NotNull Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtick Counter . goTo Tick ( tick , Ġnum erator , Ġdenominator ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTime Signature ( tick Counter . measure , Ġnum erator , Ġdenominator ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnotes Ġ= Ġunit Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName OrNull (" Song ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . get Single Element By TagName OrNull (" Score ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . getElement ListBy TagName (" Note "). or Empty () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Indexed Ġ{ Ġnote Index , Ġelement Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtick On Ġ= Ġ( element . get Required Attribute As Long (" Clock ") Ġ/ ĠT ICK _ RATE ). to Long () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtick Off Ġ= Ġtick On Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( element . get Required Attribute As Long (" Duration ") Ġ/ ĠT ICK _ RATE ). to Long () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpitch Step Ġ= Ġelement . get Required Attribute As Integer (" Pitch Step ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpitch Oct ave Ġ= Ġelement . get Required Attribute As Integer (" Pitch Oct ave ") Ġ- ĠO CT AVE _ OFFSET ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġpitch Step Ġ+ Ġpitch Oct ave Ġ* ĠKEY _ IN _ OCT AVE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġly ric Ġ= Ġelement . get Required Attribute (" Ly ric ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNote ( note Index , Ġkey , Ġtick On , Ġtick Off , Ġly ric ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠTrack Parse Result ( index , Ġname Ġ?: Ġ" Track Ġ${ index Ġ+ Ġ 1 }", Ġnotes , Ġtime Signatures ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġdata Ġclass ĠTrack Parse Result ( ĊĠĠĠĠĠĠĠ Ġval Ġindex : ĠInt , ĊĠĠĠĠĠĠĠ Ġval Ġname : ĠString , ĊĠĠĠĠĠĠĠ Ġval Ġnotes : ĠList < Note >, ĊĠĠĠĠĠĠĠ Ġval Ġtime Signatures : ĠList < Time Signature > ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġsuspend Ġfun Ġgenerate ( project : ĠProject ): ĠExport Result Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdocument Ġ= Ġgenerate Content ( project ) ĊĠĠĠĠĠĠĠ Ġval Ġserializer Ġ= ĠXML Serializer () ĊĠĠĠĠĠĠĠ Ġval Ġcontent Ġ= Ġserializer . serialize ToString ( document ) ĊĠĠĠĠĠĠĠ Ġval Ġblob Ġ= ĠBlob ( array Of ( content ), ĠBlob Property Bag (" application / octet - stream ")) ĊĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġproject . name Ġ+ ĠFormat . C cs . extension ĊĠĠĠĠĠĠĠ Ġreturn ĠExport Result ( blob , Ġname ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġgenerate Content ( project : ĠProject ): ĠDocument Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtext Ġ= Ġproject . input Files . first (). read Text () ĊĠĠĠĠĠĠĠ Ġval Ġparser Ġ= ĠDOM Parser () ĊĠĠĠĠĠĠĠ Ġval Ġdocument Ġ= Ġparser . parse FromString ( text , Ġ" text / xml ") Ġas ĠXML Document ĊĠĠĠĠĠĠĠ Ġval Ġscenario Node Ġ= Ġrequire NotNull ( document . documentElement ) ĊĠĠĠĠĠĠĠ Ġval Ġscene Node Ġ= Ġscenario Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Sequence ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Scene ") ĊĊĠĠĠĠĠĠĠ Ġval Ġunit Nodes Ġ= Ġscene Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Units ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. getElement ListBy TagName (" Unit ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . getAttribute (" Category ") Ġ== Ġ" S inger Song " Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġgroup Nodes Ġ= Ġscene Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Groups ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. getElement ListBy TagName (" Group ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . getAttribute (" Category ") Ġ== Ġ" S inger Song " Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġunit To Group Node Pairs Ġ= Ġunit Nodes . map Ġ{ Ġunit Node Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroup Node Ġ= Ġgroup Nodes . first Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . get Required Attribute (" Id ") Ġ== Ġunit Node . get Required Attribute (" Group ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġunit Node Ġto Ġgroup Node ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġunit To Group Node Pairs . zip ( project . content . tracks ). forEach Ġ{ Ġ( node Pair , Ġtrack ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( unit Node , Ġgroup Node ) Ġ= Ġnode Pair ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcurrent Unit Node Ġ= Ġunit Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcurrent Group Node Ġ= Ġgroup Node ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtrack Ch or us Ġ= Ġproject . chor us [ project . content . tracks . indexOf ( track )] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( track Ch or us . isEmpty ()) Ġreturn @ forEach ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( track . bars . isEmpty ()) Ġreturn @ forEach ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrack Ch or us . forEach Ġ{ Ġ( har mony , Ġnote Sh ifts ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġgenerate UUID () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Track Name Ġ= Ġharmony . get Har monic Track Name ( track . name ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Group Node Ġ= Ġgroup Node . clone () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Group Node . setAttribute (" Name ", Ġnew Track Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Group Node . setAttribute (" Id ", Ġid ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Group Node . insert After This ( new Group Node ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Group Node Ġ= Ġnew Group Node ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Unit Node Ġ= Ġunit Node . clone () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Unit Node . setAttribute (" Group ", Ġid ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapply Note Sh ifts To Track Node ( new Unit Node , Ġnote Sh ifts ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Unit Node . insert After This ( new Unit Node ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Unit Node Ġ= Ġnew Unit Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġdocument ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġapply Note Sh ifts To Track Node ( ĊĠĠĠĠĠĠĠ Ġunit Node : ĠElement , ĊĠĠĠĠĠĠĠ Ġnote Sh ifts : ĠList < Note Shift > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnote Sh ifts Map Ġ= Ġnote Sh ifts . map Ġ{ Ġit . note Index Ġto Ġit . key Delta Ġ}. toMap () ĊĠĠĠĠĠĠĠ Ġunit Node . get Single Element By TagName (" Song ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Single Element By TagName (" Score ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. getElement ListBy TagName (" Note ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Indexed Ġ{ Ġindex , Ġnote Node Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Delta Ġ= Ġnote Sh ifts Map [ index ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Delta Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnote Node . parentElement ?. removeChild ( note Node ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpitch Step Ġ= Ġnote Node . get Required Attribute As Integer (" Pitch Step ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpitch Oct ave Ġ= Ġnote Node . get Required Attribute As Integer (" Pitch Oct ave ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġpitch Step Ġ+ Ġpitch Oct ave Ġ* ĠKEY _ IN _ OCT AVE Ġ+ Ġkey Delta ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnote Node . setAttribute (" Pitch Step ", Ġ( key Ġ% ĠKEY _ IN _ OCT AVE ). toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnote Node . setAttribute (" Pitch Oct ave ", Ġ( key Ġ/ ĠKEY _ IN _ OCT AVE ). toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠT ICK _ RATE Ġ= Ġ 2 . 0 ĊĠĠĠ Ġprivate Ġconst Ġval ĠO CT AVE _ OFFSET Ġ= Ġ- 1 Ċ } Ċ