DIRECTORY Event USING [Adjust, Clef, Grace, Invisible, KeySignature, Measure, SetStave, Staves, Sync], MusicDefs, Note USING [Delta, Duration, GetBackTie, Width], Piece USING [NearestEvent], Real USING [Fix], Score USING [GetAccidental, GetKey, GetMetronome], Selection USING [AddLine], Sheet USING [FindStaves, FindLine, Height, Reset], Voice USING [ClearState, Correct, max, SetState, State, StatePTR]; SpacingImpl: CEDAR PROGRAM IMPORTS Event, MusicDefs, Note, Piece, Real, Score, Selection, Sheet, Voice EXPORTS Score = BEGIN OPEN MusicDefs; ts: PUBLIC TimeSignature; ScalePhysical: PUBLIC PROC[score: ScorePTR, n: INTEGER] = { sync: SyncPTR; end, delta: Time _ 0; IF n < 0 THEN RETURN; score.sheet.display _ physical; score.sheet.density _ n; FOR i: NAT IN [0..score.length) DO IF score[i] = NIL THEN LOOP; IF score[i].type = staves AND score[i].time < 5 THEN {score[i].time _ -1; LOOP}; score[i].time _ 0; sync _ IF score[i].type = sync THEN Event.Sync[score[i]] ELSE NIL; IF sync # NIL THEN FOR j: NAT IN [0..sync.length) DO IF sync.note[j] = NIL THEN EXIT; IF sync.note[j].duration = 0 THEN LOOP; IF sync.note[j].toc = 0 THEN LOOP; sync.time _ sync.note[j].toc/n+delta; IF sync.time < end THEN delta _ end+10-sync.time; IF sync.time < end THEN sync.time _ end+10; EXIT; ENDLOOP; end _ MAX[end, score[i].time]; ENDLOOP; IF score.length = 0 THEN RETURN; IF score[score.length-1].time = 0 THEN score[score.length-1].time _ end+20; FOR i: NAT DECREASING IN [0..score.length-1) DO IF score[i].time # 0 THEN LOOP; IF score[i].type = measure THEN score[i].time _ score[i+1].time-3 -- IN [measure..endMeasure] ELSE score[i].time _ score[i+1].time; ENDLOOP; }; LogicalToPhysical: PUBLIC PROC[score: ScorePTR, begin, end: Time] = { ss: Voice.StatePTR ~ NEW[Voice.State]; sum, max, delta, maxDuration, duration, lastSum: Time _ 0; metronome: INTEGER; n: NotePTR; Voice.ClearState[ss]; sum _ 256*8; FOR i: NAT IN [0..Voice.max) DO ss[i].sum _ sum; ENDLOOP; metronome _ Score.GetMetronome[score, 0]; FOR i: NAT IN [0..score.length) DO event: EventPTR ~ score[i]; IF event.time < begin THEN LOOP; IF event.time > end THEN EXIT; WITH event SELECT FROM ev: MetronomePTR => metronome _ ev.metronome; sync: SyncPTR => { max _ Voice.SetState[ss, sync, metronome]; IF max < sum THEN sum _ sum + maxDuration ELSE sum _ max; FOR j: NAT IN [0..Voice.max) DO IF ss[j].found THEN ss[j].sum _ sum; ENDLOOP; maxDuration _ 0; FOR j: NAT IN [0..Voice.max) DO IF ss[j].found THEN maxDuration _ MAX[maxDuration, ss[j].duration]; ENDLOOP; IF maxDuration = 0 THEN { -- no logical notes in sync toc: Time _ duration _ 0; FOR j: NAT IN [0..sync.length) DO IF (n _ sync.note[j]) = NIL THEN EXIT; toc _ MAX[toc, n.toc]; duration _ MAX[duration, n.duration]; ENDLOOP; sum _ toc + delta; -- use offset and play physically FOR j: NAT IN [0..Voice.max) DO ss[j].sum _ MAX[ss[j].sum, sum+duration]; ENDLOOP; }; FOR j: NAT IN [0..sync.length) DO IF (n _ sync.note[j]) = NIL THEN EXIT; IF n.toc # 0 THEN delta _ sum-n.toc; IF n.value # unknown THEN n.duration _ Duration[score, n, metronome]; n.toc _ lastSum _ sum; ENDLOOP; }; ENDCASE; ENDLOOP; }; Duration: PROC[score: ScorePTR, n: NotePTR, metronome: INTEGER] RETURNS[INTEGER] = { l: REAL _ 1; tie: NotePTR _ n; d: LONG INTEGER _ Note.Duration[n, metronome]; WHILE tie.tied DO IF tie.embellish = trill THEN EXIT; tie _ Note.GetBackTie[score, tie]; d _ MIN[d + Note.Duration[tie, metronome], 32000]; ENDLOOP; RETURN[7*(d/8)]; }; Justify: PUBLIC PROC[score: ScorePTR, begin, end: Time] = { i: NAT; one, s: REAL _ 1; key: INTEGER _ 0; shorten: BOOLEAN _ FALSE; lineBegin, lineEnd, delta, unjustifiedTime: Time _ 0; firstML, lastML, ML1, ML2: NAT _ 0; IF score[0] = NIL THEN RETURN; IF begin >= end THEN {score.flash _ TRUE; RETURN}; [firstML, lastML] _ SelectMeasures[score, begin, end]; Voice.Correct[score, score[firstML].time, score[lastML].time]; [firstML, lastML] _ SelectMeasures[score, begin, end]; -- may have changed IF firstML = lastML THEN lastML _ score.length-1; key _ Score.GetKey[score, score[firstML].time]; lineBegin _ score.sheet[Sheet.FindLine[score.sheet, score[firstML].time+1]].time-1; ShowLogical[score, firstML, lastML]; unjustifiedTime _ score[firstML].time; i _ ML1 _ ML2 _ firstML; DO i _ i+1; IF i > lastML THEN EXIT; -- FOR i: CARDINAL IN (firstML..lastML] DO IF ML1 = i-1 THEN { -- initialize delta _ 0; IF score[ML2].time = lineBegin OR ML2 = 0 THEN FOR j: NAT IN [i..score.length) DO IF (score[j].type = sync OR Measure[score[j]]) AND delta = 0 THEN EXIT; -- no leading signature score[j].time _ score[j].time-delta; IF score[j].type = keySignature AND delta = 0 THEN { IF j > lastML THEN EXIT; IF ~Event.Invisible[score, j, unjustifiedTime] THEN EXIT; key _ Event.KeySignature[score[j]].key; delta _ ABS[key*8]; LOOP}; ENDLOOP; lineEnd _ lineBegin+score.sheet.width-MAX[ABS[key*8], 8]}; -- end initialization IF score[i].type = keySignature THEN key _ Event.KeySignature[score[i]].key; IF NOT Measure[score[i]] THEN LOOP; SELECT TRUE FROM -- have we found the end of the line? i = 0 => LOOP; i = lastML => ML2 _ i; score[i].type = staves => ML2 _ i; score[i].time-unjustifiedTime < lineEnd-lineBegin => {ML2 _ i; LOOP}; score[i].time-unjustifiedTime = lineEnd-lineBegin => ML2 _ i; ENDCASE ; IF ML1 = ML2 AND score[ML1].time # lineBegin THEN {-- start on the next line delta _ lineEnd-score[ML1].time; FOR j: NAT IN [ML1..score.length) DO score[j].time _ score[j].time+delta; ENDLOOP; lineBegin _ lineEnd; i _ ML2; -- back up (this is why the iteration is so strange) LOOP}; IF ML1 = ML2 THEN {-- the measure's too big to fit on one line!! lineEnd _ lineBegin+score.sheet.width - MAX[ABS[key*8], 8]; LOOP}; IF score[ML2].time = score[ML1].time THEN LOOP; s _ one*(lineEnd-score[ML1].time)/(score[ML2].time-unjustifiedTime); IF s > 2 AND ML2 = score.length-1 AND score[ML2].type # staves THEN {s _ MIN[s, 2]; shorten _ TRUE}; IF s > 10 THEN s _ 1; -- for empty lines FOR j: NAT IN (ML1..ML2) DO score[j].time _ Real.Fix[(score[j].time-unjustifiedTime)*s+score[ML1].time]; ENDLOOP; IF shorten THEN score[ML2].time _ ((score[ML2].time-unjustifiedTime)*2+score[ML1].time) ELSE {unjustifiedTime _ score[ML2].time; score[ML2].time _ lineEnd}; lineBegin _ lineEnd; ML1 _ ML2; i _ ML2; -- back up (this is why the iteration is so strange) ENDLOOP; delta _ score[lastML].time-unjustifiedTime; FOR i: NAT IN (lastML..score.length) DO score[i].time _ score[i].time+delta; ENDLOOP; Sheet.Reset[score]; Selection.AddLine[score, score[firstML].time+1, score[lastML].time-1]; }; SelectMeasures: PROC[score: ScorePTR, t1, t2: Time] RETURNS[s1, s2: NAT] = { m: NAT; delta: Time _ 10000; s1 _ s2 _ 0; m _ Piece.NearestEvent[score, t1]; FOR i: NAT DECREASING IN [0..m] DO IF NOT Measure[score[i]] THEN LOOP; delta _ ABS[score[m].time - score[i].time]; s1 _ i; EXIT; ENDLOOP; IF t1 < delta THEN {s1 _ 0; delta _ t1}; -- include beginning FOR i: NAT IN [m..score.length) DO IF NOT Measure[score[i]] THEN LOOP; IF score[i].time >= t2 THEN EXIT; IF ABS[score[i].time-score[m].time] < delta THEN s1 _ i; EXIT; ENDLOOP; delta _ 10000; m _ Piece.NearestEvent[score, t2]; FOR i: NAT DECREASING IN [0..m] DO IF NOT Measure[score[i]] THEN LOOP; IF score[i].time <= t1 THEN EXIT; delta _ ABS[score[m].time-score[i].time]; s2 _ i; EXIT; ENDLOOP; FOR i: NAT IN [m..score.length) DO IF NOT Measure[score[i]] THEN LOOP; IF ABS[score[i].time-score[m].time] < delta THEN s2 _ i; EXIT; ENDLOOP; IF s1 > s2 THEN s2 _ s1; -- no measure }; ShowLogical: PUBLIC PROC[score: ScorePTR, firstEvent, lastEvent: CARDINAL] = { ss: Voice.StatePTR ~ NEW[Voice.State]; prior: EventPTR _ NIL; staves: StavesPTR; delta, endTime, break: Time; sheet: SheetPTR _ score.sheet; lastTime _ 0; Voice.ClearState[ss]; vs^ _ ALL[0]; ps^ _ ALL[0]; IF score.sheet.display = physical THEN score.sheet.density _ 3; IF score.sheet.density > 30 THEN score.sheet.density _ 3; score.sheet.display _ graphical; IF firstEvent = 0 THEN score[0].time _ 0; endTime _ score[lastEvent].time; break _ score[firstEvent].time; [] _ Voice.SetState[ss, score[firstEvent]]; staves _ Sheet.FindStaves[sheet, score[firstEvent].time]; sheet[0].time _ 0; FOR i: NAT IN [1..sheet.length) DO sheet[i].time _ 1000000; ENDLOOP; prior _ score[firstEvent]; SetBackState[score, ps, score[firstEvent]]; FOR i: NAT IN (firstEvent..lastEvent] DO event: EventPTR ~ score[i]; WITH event SELECT FROM sync: SyncPTR => Event.Adjust[score, sync]; ENDCASE; event.time _ prior.time+1; IF Event.Clef[event] AND Event.Invisible[score, i, break] THEN event.time _ prior.time+1 ELSE { event.time _ Distance[score, prior, event, ss]; prior _ event; SetBackState[score, ps, event]; }; WITH event SELECT FROM newKey: KeySignaturePTR => sheet[0].key _ newKey.key; newStaves: StavesPTR => { break _ newStaves.time; Event.SetStave[score, staves, newStaves]; sheet[0].staves _ staves _ newStaves; }; ENDCASE; ENDLOOP; delta _ score[lastEvent].time - endTime; FOR i: NAT IN (lastEvent..score.length) DO score[i].time _ score[i].time + delta; ENDLOOP; IF test THEN FOR i: NAT IN [1..score.length) DO IF score[i].time < score[i-1].time THEN ERROR; ENDLOOP; }; lastTime: Time; vs: REF VoiceOffset _ NEW[VoiceOffset]; ps: REF OffsetState _ NEW[OffsetState]; Distance: PROC[score: ScorePTR, a, b: EventPTR, ss: Voice.StatePTR] RETURNS[Time] = { n: NotePTR; d: INTEGER; acc: Accidental; related: BOOLEAN _ FALSE; oldss: Voice.State _ ss^; time, toc, max, start: Time _ 0; i, j, height, up, down: NAT _ 0; max _ Voice.SetState[ss, b, 128, FALSE]; IF b.type = sync AND Event.Grace[Event.Sync[b]] THEN max _ max+10; -- move to the following note's max FOR j: NAT IN [0..Voice.max) DO IF oldss[j].found THEN vs[j] _ a.time; IF oldss[j].found AND ss[j].found THEN related _ TRUE; ENDLOOP; IF a.type # sync OR b.type # sync THEN related _ TRUE; toc _ max-lastTime; IF NOT related THEN { mod: Time _ toc MOD 256; IF mod < 0 THEN mod _ mod+256; IF mod < 2 OR mod > 254 THEN related _ TRUE; }; IF NOT related THEN FOR j: NAT IN [0..Voice.max) DO IF NOT ss[j].found THEN LOOP; IF start > vs[j] THEN LOOP; toc _ max-oldss[j].sum; start _ vs[j]; ENDLOOP; IF related THEN start _ a.time; IF b.type = sync OR (a.type = sync AND Measure[b]) THEN SELECT TRUE FROM a.type = sync AND Event.Grace[Event.Sync[a]] => time _ start+6+score.sheet.density/2; toc > 12000 => time _ start+10+20*score.sheet.density; toc > 6000 => time _ start+8+12*score.sheet.density; toc > 3000 => time _ start+8+8*score.sheet.density; toc > 1500 => time _ start+8+4*score.sheet.density; toc > 750 => time _ start+8+2*score.sheet.density; ENDCASE => time _ start+8+score.sheet.density; lastTime _ max; IF Event.Clef[a] AND Event.Clef[b] THEN RETURN[a.time]; IF b.type = sync THEN FOR i: NAT IN [0..Event.Sync[b].length) DO IF (n _ Event.Sync[b].note[i]) = NIL THEN EXIT; height _ Index[Sheet.Height[score.sheet, time+1, n.pitch, n.staff]]; IF NOT score.sheet.accidental THEN d _ 2 ELSE SELECT (acc _ Score.GetAccidental[score, n]) FROM inKey => d _ 2; doubleFlat => d _ 17; ENDCASE => d _ 12; IF score.sheet.display = graphical THEN d _ d- Note.Delta[score.sheet, n]- n.accDelta; IF ~n.rest THEN {up _ 1; down _ 1} ELSE SELECT n.value FROM quarter => {up _ 3; down _ 3}; eighth => {up _ 3; down _ 3}; sixteenth => {up _ 3; down _ 3}; thirtysecond => {up _ 3; down _ 3}; ENDCASE => {up _ 0; down _ 0}; up _ MIN[height+up+1, off]; down _ MAX[height, down]-down; FOR j: NAT IN [down..up) DO time _ MAX[time, ps[j]+d]; ENDLOOP; IF n.rest THEN LOOP; IF score.sheet.accidental THEN SELECT acc FROM sharp, natural => FOR j: NAT IN [MAX[height, 3]-3..MIN[height+4, off]) DO IF j IN [height-1..height+1] THEN LOOP; time _ MAX[time, ps[j]+d]; ENDLOOP; flat, doubleFlat => FOR j: NAT IN [MIN[height+2, off-1]..MIN[height+6, off]) DO time _ MAX[time, ps[j]+d]; ENDLOOP; ENDCASE; d _ Note.Delta[score.sheet, n]+5; FOR i: NAT IN [Index[score.sheet[0].staves.staff[n.staff].y+40]..height] DO time _ MAX[time, ps[i]+d]; ENDLOOP; FOR i: NAT IN [height..Index[score.sheet[0].staves.staff[n.staff].y-8]] DO time _ MAX[time, ps[i]+d]; ENDLOOP; IF n.stemUp THEN FOR j: NAT IN (height..MIN[height+9, off]) DO time _ MAX[time, ps[j]-8]; ENDLOOP ELSE FOR j: NAT IN [MAX[height, 8]-8..height) DO time _ MAX[time, ps[j]]; ENDLOOP; ENDLOOP; SELECT TRUE FROM Measure[b] => { FOR i: NAT IN [0..off) DO time _ MAX[time, ps[i]]; ENDLOOP; FOR i: NAT IN [0..Voice.max) DO time _ MAX[time, vs[i]+4]; ENDLOOP; IF a.type = sync THEN IF b.type = staves THEN time _ time + 6 ELSE time _ time+ measure[Event.Measure[b].measure] ELSE time _ time+3; }; b.type = sync => NULL; b.type = staves => { -- clef, octava1, octava2 FOR i: NAT IN [0..off) DO time _ MAX[time, ps[i]]; ENDLOOP; time _ time+3; }; ENDCASE => { FOR i: NAT IN [0..off) DO time _ MAX[time, ps[i]]; ENDLOOP; }; IF Measure[a] AND Measure[b] THEN time _ a.time+100; IF a.type = measure AND b.type = staves THEN -- IF a.type IN EventType[repeat1..m5] IF Event.Measure[a].measure # measure AND Event.Staves[b].staves = style THEN RETURN[a.time]; RETURN[MAX[time, a.time+4]]; }; SetBackState: PROC[score: ScorePTR, ps: REF OffsetState, s: EventPTR] = { n: NotePTR; width: Time _ 0; offset: NAT; here: Time _ s.time; key: INTEGER _ Score.GetKey[score, s.time]; top, bottom: NAT; IF s.type = sync THEN FOR i: NAT IN [0..Event.Sync[s].length) DO IF (n _ Event.Sync[s].note[i]) = NIL THEN EXIT; IF score.sheet.display = graphical THEN here _ Note.Delta[score.sheet, n]+s.time; offset _ Index[Sheet.Height[score.sheet, s.time, n.pitch, n.staff]]; width _ Note.Width[n]; IF n.rest AND n.value IN [eighth..sixteenth] THEN width _ 12; IF n.dotted THEN width _ width+8; ps[offset] _ MAX[ps[offset], here+width]; IF n.rest THEN LOOP; width _ Note.Width[n]+3; FOR i: NAT IN [Index[score.sheet[0].staves.staff[n.staff].y+40]..offset] DO ps[i] _ MAX[ps[i], here+width]; ENDLOOP; FOR i: NAT IN [offset..Index[score.sheet[0].staves.staff[n.staff].y-8]] DO ps[i] _ MAX[ps[i], here+width]; ENDLOOP; IF n.value = whole OR n.value = unknown THEN LOOP; IF n.stemUp THEN { width _ Note.Width[n]; IF n.value > quarter AND (n.beam = NIL OR NOT n.beam.beamed) THEN width _ 14; IF width = 14 AND n.grace THEN width _ 10; FOR j: NAT IN (offset..MIN[offset+8, off]) DO ps[j] _ MAX[ps[j], here+width]; ENDLOOP} ELSE { IF n.value > quarter AND (n.beam = NIL OR NOT n.beam.beamed) THEN width _ 6 ELSE width _ 0; IF width = 6 AND n.grace THEN width _ 4; FOR j: NAT IN [MAX[offset, 7]-7..offset) DO ps[j] _ MAX[ps[j], here+width]; ENDLOOP}; ENDLOOP; IF s.type = sync THEN RETURN; top _ Index[0]; bottom _ Index[Sheet.Height[score.sheet, s.time, , 3]]; WITH s SELECT FROM ev: MetronomePTR => RETURN; ev: TimeSignaturePTR => width _ 14; ev: KeySignaturePTR => width _ 8*ABS[key]; ev: MeasurePTR => width _ measure[ev.measure]; ev: StavesPTR => IF ev.staves = style THEN width _ 6 ELSE { bottom _ Index[Sheet.Height[score.sheet, s.time, , ev.value]]; top _ bottom+10; width _ 20; }; ENDCASE => RETURN; top _ MIN[top, off-1]; bottom _ MIN[bottom, off-1]; FOR i: NAT IN [bottom..top] DO ps[i] _ s.time+width; ENDLOOP; }; SetVoiceOffset: PROC[vs: REF VoiceOffset, s: SyncPTR] = { d: INTEGER; v: NAT; FOR i: NAT IN [0..s.length) DO IF s.note[i] = NIL THEN EXIT; v _ s.note[i].voice; d _ value[s.note[i].value]+(IF s.note[i].value = whole THEN 10 ELSE 8); IF s.note[i].dotted AND d < 12 THEN d _ d+4; IF vs[v] > s.time THEN vs[v] _ MIN[vs[v], s.time+d] ELSE vs[v] _ s.time+d; ENDLOOP; }; value: ARRAY NoteValue OF NAT _ [32, 16, 8, 4, 2, 1, 1, 1]; measure: ARRAY MeasureType OF NAT _ [6, 12, 12, 12, 8, 6]; Index: PROC[height: INTEGER] RETURNS[NAT] = {RETURN[MAX[70+height/4, 0]]}; off: NAT = 100; OffsetState: TYPE = ARRAY [0..off) OF Time; VoiceOffset: TYPE = ARRAY[0..10) OF Time; test: BOOLEAN _ FALSE; END. PSpacingImpl.mesa Copyright (C) 1983, 1984 Xerox Corporation. All rights reserved. Last Edited by: Maxwell, November 18, 1983 3:45 pm Last Edited by: Doug Wyatt, June 14, 1984 8:54:53 pm PDT ***test for special case: physical notes in logical score **************************************************************************** justification of the score **************************************************************************** ENABLE Piece.Overflow => IF score = old THEN score _ new; begin _ select1; end _ select2; 'delete' hidden syncs (if any) score[j].time _ unjustifiedTime+5; so it won't get drawn we've hit the end of a line, try to justify. stretch the measures in [ML1..ML2] over the area [lineBegin..lineEnd] shift everything else over to the right set up selection set up sheet layout the selected section move the rest of the score to the right minimum distance based on voices interaction with graphical objects IF Note.Delta[n] < 0 THEN time _ MAX[time, a.time+4-Note.Delta[n]]; find interactions with the note head find interactions with the accidental not handled above find interactions with the ledger lines find interactions with the stem handle note events fill in for the note head fill in for ledger lines fill in for stems and flags handle all non-note events {top _ bottom _ Index[Sheet.Height[s.time, , 0]+44]; width _ 20} ÊŸ˜šœ™J™@Jšœ2™2Jšœ8™8—J˜šÏk ˜ JšœœR˜]J˜ Jšœœ'˜1Jšœœ˜Jšœœ˜Jšœœ(˜3Jšœ œ ˜Jšœœ(˜3Jšœœ7˜BJ˜—Jšœ œœ˜JšœD˜KJšœ˜ Jšœœœ ˜J˜Jšœœ˜J˜šÏn œœœœ˜;J˜J˜Jšœœœ˜J˜J˜šœœœ˜"Jšœ œœœ˜Jšœœœœ˜PJ˜Jš œœœœœ˜Bš œœœœœœ˜4Jšœœœœ˜ Jšœœœ˜(Jšœœœ˜#J˜%Jšœœ˜1Jšœœ˜+Jšœœ˜—Jšœœ˜Jšœ˜—Jšœœœ˜ Jšœ œ%˜Kš œœ œœ˜/Jšœœœ˜šœœ#Ïc˜]Jšœ!˜%—Jšœ˜ —Jšœ˜J˜—šžœœœ'˜EJšœœ˜&J˜:Jšœ œ˜J˜ J˜J˜ Jš œœœœœ˜9J˜)šœœœ˜"Jšœ˜Jšœœœ˜ Jšœœœ˜šœœ˜J˜-˜J˜*Jšœ œœ ˜9šœœœœ˜ Jšœ œœ˜-—Jšœ9™9J˜šœœœ˜Jšœ œœ˜CJšœ˜—šœœŸ˜6J˜šœœœ˜!Jšœœœœ˜&Jšœœ ˜Jšœ œ˜%Jšœ˜—JšœŸ!˜4šœœœœ˜ Jšœ œ˜*Jšœ˜—Jšœ˜—šœœœ˜!Jšœœœœ˜&Jšœ œ˜$Jšœœ,˜EJ˜Jšœ˜—J˜—Jšœ˜—Jšœ˜—Jšœ˜J˜—š žœœ)œœœ˜TJšœœ˜ J˜Jšœœœ˜.šœ ˜Jšœœœ˜#J˜"Jšœœ+˜2Jšœ˜—Jšœ ˜Jšœ˜J˜—J˜JšœL™LJšœ™JšœL™LJ˜šžœœœ'˜;Jšœœ œ ™9Jšœœ˜Jšœœ˜Jšœœ˜Jšœ œœ˜J˜5Jšœœ˜#Jšœ™Jšœ™Jšœ œœœ˜Jšœœœœ˜2J˜6J˜>Jšœ7Ÿ˜JJšœœ˜1J˜/J˜SJ˜$J˜&J˜š œ œ œœŸ*˜Pšœ œŸ ˜!Jšœ™J˜ š œœ œœœœ˜QJš œœœ œœŸ˜`J˜$šœœ œ˜5Jšœ œœ˜Jšœ-œœ˜:J˜(Jšœœ œ˜Jšœ:™:—Jšœ˜—Jšœ&œœŸ˜P—Jšœœ(˜LJšœœœœ˜#šœœœŸ%˜7Jšœ œ˜J˜J˜"Jšœ?œ˜EJ˜=Jšœ˜ —Jšœ,™,šœ œœŸ˜LJ˜ šœœœ˜$J˜$Jšœ˜—J˜Jšœ Ÿ4˜=Jšœ˜—šœ œŸ-˜@Jšœ(œœ ˜;Jšœ˜—JšœE™EJšœ#œœ˜/J˜DJš œœœœœœ˜dJšœœŸ˜(šœœœ ˜J˜LJšœ˜—šœ ˜ JšœH˜LJšœ@˜D—J˜J˜ Jšœ Ÿ4˜=Jšœ˜—Jšœ'™'J˜+šœœœ˜'J˜$Jšœ˜—Jšœ™J˜J˜FJšœ˜J˜—šžœœ œ œ˜LJšœœ˜J˜J˜ J˜"š œœ œœ˜"Jšœœœœ˜#Jšœœ ˜+Jšœœœ˜—Jšœ œŸ˜=šœœœ˜"Jšœœœœ˜#Jšœœœ˜!Jšœœ&œ˜8Jšœœ˜—J˜J˜"š œœ œœ˜"Jšœœœœ˜#Jšœœœ˜!Jšœœ˜)Jšœœœ˜—šœœœ˜"Jšœœœœ˜#Jšœœ&œ˜8Jšœœ˜—Jšœ œ Ÿ ˜&Jšœ˜J˜—šž œœœ)œ˜NJšœœ˜&Jšœœ˜J˜J˜J˜J˜ J˜Jšœœ œ˜Jšœ œ˜?Jšœœ˜9J˜ Jšœœ˜)J˜ J˜J˜+Jšœ ™ J˜9J˜šœœœ˜"J˜Jšœ˜—Jšœ™J˜J˜+šœœœ˜(J˜šœœ˜Jšœ+˜+Jšœ˜—J˜šœœ"˜:Jšœ˜šœ˜Jšœ0˜0Jšœ.˜.Jšœ˜——šœœ˜Jšœ5˜5šœ˜Jšœ˜Jšœ)˜)J˜%J˜—Jšœ˜—Jšœ˜—Jšœ'™'J˜(šœœœ˜*J˜&Jšœ˜—š œœœœœ˜/Jšœ!œœ˜.Jšœ˜—Jšœ˜J˜—J˜Jšœœœ˜'Jšœœœ˜'J˜šžœœ6œ ˜UJ˜ Jšœœ˜ J˜Jšœ œœ˜J˜J˜ Jšœœ˜ Jšœ ™ Jšœ!œ˜(JšœœœŸ#˜fšœœœ˜Jšœœ˜&Jšœœ œ œ˜6Jšœ˜—Jšœœœ œ˜7J˜šœœ œ˜Jšœœ˜Jšœ œ˜Jšœ œ œ œ˜,Jšœ˜—š œœ œœœœ˜3Jšœœ œœ˜Jšœœœ˜J˜J˜Jšœ˜—Jšœ œ˜šœœœ œ˜8Jšœœ˜JšœœD˜UJ˜7J˜6J˜5J˜5J˜4Jšœ'˜.—J˜Jšœ"™"Jšœœœœ ˜7š œœœœœ˜@Jšœœœœ˜/J˜Dšœœœ˜(šœœ'˜6J˜J˜Jšœ ˜——Jšœ!œ/˜VJšœC™CJšœ$™$š œ œœœ ˜;J˜J˜J˜ J˜#Jšœ˜—Jšœœ˜Jšœœ˜šœœœ ˜Jšœœ˜Jšœ˜—Jšœœœ˜Jšœ7™7šœœœ˜.š œœœœœœ˜IJšœœœœ˜'Jšœœ˜Jšœ˜—˜š œœœœœ˜;Jšœœ˜Jšœ˜——Jšœ˜ —Jšœ'™'J˜!šœœœ<˜KJšœœ˜Jšœ˜—šœœœ;˜JJšœœ˜Jšœ˜—Jšœ™Jšœ ˜ š œœœœ œ˜2Jšœœ˜"—š œœœœœ˜0Jšœœœ˜!—Jšœ˜—šœœ˜šœ˜Jš œœœ œœœ˜;Jš œœœœœœ˜Cšœ˜šœœ˜Jšœ˜Jšœ/˜3—Jšœ˜—Jšœ˜—Jšœœ˜šœŸ˜.Jš œœœ œœœ˜;J˜Jšœ˜—šœ˜ Jš œœœ œœœ˜;Jšœ˜——Jšœ œ œ˜4šœœœŸ&˜SJšœ$œ œœ ˜^—Jšœœ˜Jšœ˜J˜—šž œœœ˜IJ˜ J˜Jšœœ˜ J˜Jšœœ˜+Jšœ œ˜Jšœ™š œœœœœ˜@Jšœœœœ˜/Jšœ!œ,˜SJ˜DJšœ™J˜Jšœœ œœ ˜=Jšœ œ˜!Jšœ œ˜)Jšœœœ˜Jšœ™J˜šœœœ<˜KJšœœ˜Jšœ˜—šœœœ;˜JJšœœ˜Jšœ˜—Jšœ™Jšœœœœ˜2šœ œ˜J˜Jš œœ œœœœ ˜MJšœ œ œ ˜+š œœœ œœ˜.Jšœœ˜ Jšœ˜——šœ˜š œœ œœœ˜=Jšœ œ ˜—Jšœ œ œ ˜)š œœœœœ˜,Jšœœ˜ Jšœ˜ ——Jšœ˜—Jšœœœ˜Jšœ™J˜J˜7šœœ˜šœœ˜Jšœ@™@—J˜#Jšœ!œ˜*Jšœ.˜.šœœœ œ˜;J˜>J˜J˜—Jšœœ˜—Jšœœ ˜Jšœ œ˜Jš œœœœœ˜=Jšœ˜J˜—šžœœœ˜9Jšœœ˜ Jšœœ˜šœœœ˜Jšœ œœœ˜J˜Jšœœœœ˜GJšœœœ ˜,šœœ œ˜3Jšœ˜—Jšœ˜—Jšœ˜J˜—Jšœœ œœ˜;J˜Jšœ œ œœ˜:J˜Jšžœœ œœœœœ˜JJšœœ˜Jšœ œœ œ˜+Jšœ œœœ˜)J˜Jšœœœ˜J˜Jšœ˜—…—=ŠXy