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