DIRECTORY

LongString USING [AppendChar, AppendString, AppendDecimal],
Rope USING [Fetch, ROPE, Size],
RopeEdit USING [AlphaNumericChar, BlankChar, Concat, Substr],
RopeReader USING [Create, Get, GetIndex, Backwards, ReadOffEnd, Ref, SetPosition],
TextEdit USING [DeleteText, FetchChar, FetchLooks, InsertChar, InsertRope, Offset, Ref, RefTextNode, ReplaceByChar, InsertString, Size],
TextLooks USING [Look, Looks, noLooks],
TextNode USING [Backward, FirstChild, LastLocWithin, Location, NarrowToTextNode, NodeItself, Offset, Parent, Ref, RefTextNode, StepForward, StepBackward, TypeName],
TEditDocument USING [BeforeAfter, Selection, SelectionPoint],
TEditInput USING [CloseEvent, currentEvent],
TEditInputOps,
TEditOps,
TEditRefresh USING [ScrollToEndOfSel],
TEditSelection USING [CaretVisible, Copy, Deselect, InsertionPoint, LockSel, MakePointSelection, MakeSelection, pSel, SetSelLooks, UnlockSel],
Time USING [Current, Unpack, Unpacked],
TreeFind USING [Finder, CreateFromRope, Try, TryBackwards],
ViewerClasses USING [Viewer],
ViewerTools USING [SetSelection];

TEditMiscOpsImpl: CEDAR PROGRAM

IMPORTS LongString, Rope, RopeEdit, RopeReader, TextEdit, TextNode, TEditInput, TEditInputOps, TEditOps, TEditRefresh, TEditSelection, Time, TreeFind, ViewerTools
EXPORTS TEditInputOps = BEGIN
OPEN TEditDocument, TEditSelection, TEditOps, TEditInputOps;

InsertChar: PUBLIC PROC [char: CHARACTER] = {
DoInsertChar: PROC [root: TextEdit.Ref, tSel: Selection] = {
pos: TextNode.Location;
looks: TextLooks.Looks _ tSel.looks;
IF tSel.pendingDelete THEN {
DoPendingDelete[];
TEditSelection.Copy[source: pSel, dest: tSel] };
pos _ InsertionPoint[pSel]; -- need to get insertion point after pending delete
Deselect[primary];
[] _ TextEdit.InsertChar[root: root,
dest: TextNode.NarrowToTextNode[pos.node],
char: char, destLoc: pos.where,
inherit: FALSE, looks: looks,
event: TEditInput.currentEvent];
pos.where _ pos.where+1;
MakePointSelection[tSel, pos];
IF CaretVisible[] THEN TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE] };
CallWithLocks[DoInsertChar] };

InsertRope: PUBLIC PROC [rope: Rope.ROPE] = {
DoInsertRope: PROC [root: TextEdit.Ref, tSel: Selection] = {
pos: TextNode.Location;
len: TextNode.Offset _ Rope.Size[rope];
looks: TextLooks.Looks;
IF tSel.pendingDelete THEN {
DoPendingDelete[];
TEditSelection.Copy[source: pSel, dest: tSel] };
pos _ InsertionPoint[pSel]; -- need to get insertion point after pending delete
looks _ tSel.looks;
Deselect[primary];
[] _ TextEdit.InsertRope[root: root,
dest: TextNode.NarrowToTextNode[pos.node],
rope: rope, destLoc: pos.where,
inherit: FALSE, looks: looks,
event: TEditInput.currentEvent];
pos.where _ pos.where+len;
MakePointSelection[tSel, pos];
IF CaretVisible[] THEN TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE] };
CallWithLocks[DoInsertRope] };

InsertLineBreak: PUBLIC PROC = { -- copy leading blanks from previous line
DoInsertLineBreak: PROC [root: TextEdit.Ref, tSel: Selection] = {
pos: TextNode.Location;
node: TextNode.RefTextNode;	
start, end: TextNode.Offset;
rope: Rope.ROPE;
IF tSel.pendingDelete THEN {
DoPendingDelete[];
TEditSelection.Copy[source: pSel, dest: tSel] };
pos _ InsertionPoint[pSel]; -- need to get insertion point after pending delete
IF (node _ TextNode.NarrowToTextNode[pos.node]) = NIL THEN { EditFailed[]; RETURN };
rope _ node.rope;
start _ MAX[0, pos.where];
start _ MIN[start, Rope.Size[rope]];
WHILE start > 0 AND Rope.Fetch[rope,start-1] # 15C DO start _ start-1; ENDLOOP;
end _ start;
WHILE end < pos.where AND RopeEdit.BlankChar[Rope.Fetch[rope,end]] DO
end _ end+1; ENDLOOP;
InsertRope[RopeEdit.Concat["\n",RopeEdit.Substr[rope,start,end-start]]] };
CallWithLocks[DoInsertLineBreak] };

DeleteNextChar: PUBLIC PROC [count: INT _ 1] = {
DoDeleteNextChar: PROC [root: TextEdit.Ref, tSel: Selection] = {
flush: TextNode.Location _ InsertionPoint[tSel];
node: TextNode.RefTextNode;
IF (node _ TextNode.NarrowToTextNode[flush.node]) = NIL THEN GOTO Bad;
IF flush.where=TextNode.NodeItself THEN GOTO Bad;
IF (count _ MIN[count,TextEdit.Size[node]-flush.where]) <= 0 THEN GOTO Bad;
Deselect[primary];
TextEdit.DeleteText[root, node, flush.where, count, TEditInput.currentEvent];
MakePointSelection[tSel,flush];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE];
EXITS Bad => EditFailed[] };
IF count > 0 THEN CallWithLocks[DoDeleteNextChar] };

GoToNextChar: PUBLIC PROC [count: INT _ 1] = {
DoGoToNextChar: PROC [root: TextEdit.Ref, tSel: Selection] = {
loc: TextNode.Location _ InsertionPoint[tSel];
node: TextNode.RefTextNode;
IF (node _ TextNode.NarrowToTextNode[loc.node]) = NIL OR
loc.where=TextNode.NodeItself OR
(count _ MIN[count,TextEdit.Size[node]-loc.where]) <= 0 THEN { -- try next node
GoToNextNode; RETURN };
MakePointSelection[tSel,[node,loc.where+count]];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE] };
IF count > 0 THEN CallWithLocks[DoGoToNextChar, read] };

GoToPreviousChar: PUBLIC PROC [count: INT _ 1] = {
DoGoToPreviousChar: PROC [root: TextEdit.Ref, tSel: Selection] = {
loc: TextNode.Location _ InsertionPoint[tSel];
node: TextNode.RefTextNode;
IF (node _ TextNode.NarrowToTextNode[loc.node]) = NIL OR
loc.where=TextNode.NodeItself OR loc.where < count 
THEN { GoToPreviousNode; RETURN }; -- try previous node
MakePointSelection[tSel,[node,loc.where-count]];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE] };
IF count > 0 THEN CallWithLocks[DoGoToPreviousChar, read] };

FindNextWord: PUBLIC PROC [node: TextNode.RefTextNode, start: TextNode.Offset]
RETURNS [nChars: CARDINAL] = {
offset: TextNode.Offset _ start;
size: TextNode.Offset _ TextEdit.Size[node];
nChars _ 1;
WHILE offset<size AND ~RopeEdit.AlphaNumericChar[TextEdit.FetchChar[node, offset]] DO
offset _ offset + 1;
nChars _ nChars + 1;
ENDLOOP;
WHILE offset<size AND RopeEdit.AlphaNumericChar[TextEdit.FetchChar[node, offset]] DO
offset _ offset + 1;
nChars _ nChars + 1;
ENDLOOP;
nChars _ nChars - 1;	-- correction: loops overshoot by 1
};

DeleteNextWord: PUBLIC PROC [count: INT _ 1] = {
DoDeleteNextWord: PROC [root: TextEdit.Ref, tSel: Selection] = {
pos: TextNode.Location _ InsertionPoint[tSel];
node: TextNode.RefTextNode;
nChars, start, next: TextEdit.Offset;
IF (start _ pos.where) = TextNode.NodeItself THEN GOTO Bad;
IF (node _ TextNode.NarrowToTextNode[pos.node])=NIL THEN GOTO Bad;
next _ start;
FOR garbage:INT IN [0..count) DO next _ next+FindNextWord[node,next]; ENDLOOP;
nChars _ next-start;
Deselect[primary];
TextEdit.DeleteText[root, node, start, nChars, TEditInput.currentEvent];
MakePointSelection[tSel,pos];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE];
EXITS Bad => EditFailed[] };
IF count > 0 THEN CallWithLocks[DoDeleteNextWord] };

GoToNextWord: PUBLIC PROC [count: INT _ 1] = {
DoGoToNextWord: PROC [root: TextEdit.Ref, tSel: Selection] = {
pos: TextNode.Location _ InsertionPoint[tSel];
node: TextNode.RefTextNode;
size, next: TextEdit.Offset;
IF (node _ TextNode.NarrowToTextNode[pos.node])=NIL OR
(next _ pos.where)=TextNode.NodeItself THEN { -- try next node
GoToNextNode; RETURN };
size _ TextEdit.Size[node];
FOR garbage:INT IN [0..count) DO
IF next >= size THEN { GoToNextNode; RETURN };
next _ next+FindNextWord[node,next];
ENDLOOP;
MakePointSelection[tSel,[node,next]];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE] };
IF count > 0 THEN CallWithLocks[DoGoToNextWord, read] };

GoToNextNode: PUBLIC PROC [count: INT _ 1] = {
DoGoToNextNode: PROC [root: TextEdit.Ref, tSel: Selection] = {
pos: TextNode.Location _ InsertionPoint[tSel];
node: TextNode.Ref _ pos.node;
FOR garbage:INT IN [0..count) DO
IF (node _ TextNode.StepForward[node])=NIL THEN { EditFailed[]; RETURN };
ENDLOOP;
MakePointSelection[tSel,[node,0]];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE] };
IF count > 0 THEN CallWithLocks[DoGoToNextNode, read] };

GoToPreviousNode: PUBLIC PROC [count: INT _ 1] = {
DoGoToPreviousNode: PROC [root: TextEdit.Ref, tSel: Selection] = {
text: TextNode.RefTextNode;
pos: TextNode.Location _ InsertionPoint[tSel];
node: TextNode.Ref _ pos.node;
FOR garbage:INT IN [0..count) DO
IF (node _ TextNode.StepBackward[node])=NIL OR
TextNode.Parent[node]=NIL THEN GOTO Bad;
ENDLOOP;
IF (text _ TextNode.NarrowToTextNode[node])=NIL THEN GOTO Bad;
MakePointSelection[tSel,[text,TextEdit.Size[text]]];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, TRUE];
EXITS Bad => EditFailed[] };
IF count > 0 THEN CallWithLocks[DoGoToPreviousNode, read] };

InsertTime: PUBLIC PROC = {
dateLen: TextEdit.Offset;
TimeString: PROC RETURNS [time: REF TEXT] = TRUSTED BEGIN OPEN LongString;
s: LONG STRING;	-- for convenience;
now: Time.Unpacked = Time.Unpack[Time.Current[]];
time _ NEW[TEXT[30]];
s _ LOOPHOLE[time];
AppendString[s, SELECT now.month FROM
0 => "January"L,
1 => "February"L,
2 => "March"L,
3 => "April"L,
4 => "May"L,
5 => "June"L,
6 => "July"L,
7 => "August"L,
8 => "September"L,
9 => "October"L,
10 => "November"L,
ENDCASE => "December"L];
AppendChar[s, ' ];
AppendDecimal[s, now.day];
AppendString[s , ", "];
AppendDecimal[s, now.year];
dateLen _ s.length;	-- remember length of date for selection
AppendChar[s, ' ];
AppendDecimal[s, ((now.hour+11) MOD 12)+1];
AppendChar[s, ':];
AppendDecimal[s, now.minute/10];
AppendDecimal[s, now.minute MOD 10];
AppendString[s, IF now.hour<12 THEN " am" ELSE " pm"];
END;
DoInsertTime: PROC [root: TextEdit.Ref, tSel: Selection] = {
resLen: TextEdit.Offset;
caret: TextNode.Location;
dest: TextNode.RefTextNode;
looks: TextLooks.Looks;
looks _ pSel.looks;
IF pSel.pendingDelete THEN DoPendingDelete[];
caret _ InsertionPoint[pSel];
IF (dest _ TextNode.NarrowToTextNode[caret.node])=NIL THEN GOTO Bad;
Deselect[primary];
[----, resLen] _ TextEdit.InsertString[root: root, dest: dest, string: TimeString[],
destLoc: caret.where, inherit: FALSE, looks: looks, event: TEditInput.currentEvent];
tSel.end.pos.node _ tSel.start.pos.node _ caret.node;
tSel.end.pos.where _ caret.where+resLen-1;
tSel.start.pos.where _ caret.where+dateLen;
tSel.insertion _ after;
tSel.granularity _ char;
tSel.pendingDelete _ FALSE;
MakeSelection[selection: primary, new: tSel];
EXITS Bad => EditFailed[] };
CallWithLocks[DoInsertTime] };

InsertBrackets: PUBLIC PROC [left, right: CHAR] = {
DoInsertBrackets: PROC [root: TextEdit.Ref, tSel: Selection] = {
leftEnd, rightEnd: TextNode.Location;
leftNode, rightNode: TextNode.RefTextNode;
l, r: TextNode.Offset;
leftEnd _ tSel.start.pos;
rightEnd _ tSel.end.pos;
IF (leftNode _ TextNode.NarrowToTextNode[leftEnd.node])=NIL THEN GOTO Bad;
IF (rightNode _ TextNode.NarrowToTextNode[rightEnd.node])=NIL THEN GOTO Bad; 
IF (r _ rightEnd.where) = TextNode.NodeItself THEN r _ TextEdit.Size[rightNode]
ELSE IF tSel.granularity # point THEN r _ r+1;
IF (l _ leftEnd.where) = TextNode.NodeItself THEN l _ 0;
Deselect[primary];
[----, ----] _ TextEdit.InsertChar[
root: root,
dest: rightNode,
char: right,
destLoc: r,
inherit: FALSE, looks: tSel.looks,
event: TEditInput.currentEvent];
[----, ----] _ TextEdit.InsertChar[
root: root,
dest: leftNode,
char: left,
destLoc: l,
inherit: FALSE, looks: tSel.looks,
event: TEditInput.currentEvent];
tSel.start.pos.where _ l+1;
IF tSel.granularity = point THEN tSel.end.pos.where _ l+1
ELSE {
tSel.granularity _ char;
IF leftNode=rightNode THEN tSel.end.pos.where _ r};
tSel.pendingDelete _ FALSE;
MakeSelection[selection: primary, new: tSel];
EXITS Bad => EditFailed[] };
CallWithLocks[DoInsertBrackets] };

End: ERROR = CODE; -- private; for use in SelectMatchingBrackets

SelectMatchingBrackets: PUBLIC PROC [left, right: CHAR] = {
IF ~DoSelectMatchingBrackets[left, right] THEN EditFailed["No match."] };

DoSelectMatchingBrackets: PUBLIC PROC [left, right: CHAR] RETURNS [found: BOOL] = {
rdr: RopeReader.Ref _ RopeReader.Create[];
ref, parent: TextNode.Ref;
node: TextNode.RefTextNode;

GetPreviousNode: PROC RETURNS [n: TextNode.RefTextNode] = {
DO -- search for previous text node
[ref,parent,] _ TextNode.Backward[ref,parent];
IF ref=NIL THEN ERROR End;
IF (n _ TextNode.NarrowToTextNode[ref]) # NIL THEN RETURN [n];
ENDLOOP };

GetLeftChar: PROC RETURNS [CHAR] = {
RETURN [RopeReader.Backwards[rdr ! RopeReader.ReadOffEnd => {
node _ GetPreviousNode[];
RopeReader.SetPosition[rdr, node.rope, Rope.Size[node.rope]];
RETRY }]] };

GetNextNode: PROC RETURNS [n: TextNode.RefTextNode] = {
DO -- search for next text node
IF (ref _ TextNode.StepForward[ref])=NIL THEN ERROR End;
IF (n _ TextNode.NarrowToTextNode[ref]) # NIL THEN RETURN [n];
ENDLOOP };

GetRightChar: PROC RETURNS [CHAR] = {
RETURN [RopeReader.Get[rdr ! RopeReader.ReadOffEnd => {
node _ GetNextNode[];
RopeReader.SetPosition[rdr, node.rope];
RETRY }]] };

DoSelect: PROC [root: TextEdit.Ref, tSel: Selection] = {
leftEnd, rightEnd: TextNode.Location;
nest: CARDINAL _ 0;
loc: TextNode.Offset;

leftEnd _ tSel.start.pos;
rightEnd _ tSel.end.pos;

ref _ leftEnd.node;
IF (node _ TextNode.NarrowToTextNode[ref])=NIL THEN {
IF (node _ GetPreviousNode[])=NIL THEN GOTO NoMatch;
loc _ Rope.Size[node.rope] }
ELSE IF (loc _ leftEnd.where) = TextNode.NodeItself THEN loc _ 0;
RopeReader.SetPosition[rdr, node.rope, loc];
DO	-- left end
SELECT GetLeftChar[ ! End => GOTO NoMatch] FROM
left => IF nest=0 THEN EXIT ELSE nest _ nest-1;
right => nest _ nest+1;
ENDCASE;
ENDLOOP;
leftEnd.node _ node;
leftEnd.where _ RopeReader.GetIndex[rdr];

ref _ rightEnd.node;
IF (node _ TextNode.NarrowToTextNode[ref])=NIL THEN {
IF (node _ GetNextNode[])=NIL THEN GOTO NoMatch;
loc _ 0 }
ELSE IF (loc _ rightEnd.where) = TextNode.NodeItself THEN loc _ Rope.Size[node.rope]
ELSE IF pSel.granularity # point THEN loc _ loc+1;
RopeReader.SetPosition[rdr, node.rope, loc];
DO	-- right end
SELECT GetRightChar[ ! End => GOTO NoMatch] FROM
right => IF nest=0 THEN EXIT ELSE nest _ nest-1;
left => nest _ nest+1;
ENDCASE;
ENDLOOP;
rightEnd.node _ node;
rightEnd.where _ RopeReader.GetIndex[rdr]-1;

tSel.start.pos _ leftEnd;
tSel.end.pos _ rightEnd;
tSel.granularity _ char;
SetSelLooks[tSel];
MakeSelection[selection: primary, new: tSel];
found _ TRUE;
EXITS NoMatch => found _ FALSE };

CallWithLocks[DoSelect, read] };

NextViewer: PUBLIC PROC [forward: BOOLEAN] = BEGIN
IF ~DoNextViewer[forward] THEN EditFailed["No next viewer."] END;

DoNextViewer: PUBLIC PROC [forward: BOOLEAN] RETURNS [found: BOOL] = BEGIN
OPEN ViewerClasses;
Enumerate: PROC [enum: PROC [Viewer]] = BEGIN
FOR v: Viewer _ pSel.viewer.parent.child, v.sibling UNTIL v=NIL DO
enum[v];
ENDLOOP;
END;
thisViewer: Viewer = pSel.viewer;
nextViewer: Viewer _ NIL;
ConvergeForward: PROC [v: Viewer] = BEGIN
IF v.class.flavor=$Text AND (v.cy > thisViewer.cy
OR (v.cy = thisViewer.cy AND v.cx > thisViewer.cx)) THEN BEGIN
IF nextViewer=NIL OR v.cy < nextViewer.cy THEN {nextViewer _ v; RETURN};
IF v.cy > nextViewer.cy THEN RETURN;
IF (v.cy > thisViewer.cy OR v.cx > thisViewer.cx) AND v.cx < nextViewer.cx THEN
nextViewer _ v;	
END;
END;
ConvergeBackward: PROC [v: Viewer] = BEGIN
IF v.class.flavor=$Text AND (v.cy < thisViewer.cy
OR (v.cy = thisViewer.cy AND v.cx < thisViewer.cx)) THEN BEGIN
IF nextViewer=NIL OR v.cy > nextViewer.cy THEN {nextViewer _ v; RETURN};
IF v.cy < nextViewer.cy THEN RETURN;
IF (v.cy < thisViewer.cy OR v.cx < thisViewer.cx) AND v.cx > nextViewer.cx THEN
nextViewer _ v;	
END;
END;
LockSel[primary, "DoNextViewer"];
{ ENABLE UNWIND => UnlockSel[primary];
IF pSel.viewer=NIL OR pSel.viewer.parent=NIL THEN {
UnlockSel[primary]; EditFailed[]; RETURN [FALSE] };
Enumerate[IF forward THEN ConvergeForward ELSE ConvergeBackward];
IF nextViewer # NIL THEN ViewerTools.SetSelection[nextViewer, NIL];
}; UnlockSel[primary];
RETURN [nextViewer # NIL];
END;

FindPlaceholders: PUBLIC PROCEDURE [next: BOOLEAN] = {
found, wenttoend: BOOL;
[found, wenttoend] _ DoFindPlaceholders[next, TRUE];
IF ~found AND ~wenttoend THEN NextViewer[next] };

DoFindPlaceholders: PUBLIC PROCEDURE [next, gotoend: BOOL,
startBoundaryNode, endBoundaryNode: TextNode.Ref _ NIL,
startBoundaryOffset: TextNode.Offset _ 0,
endBoundaryOffset: TextNode.Offset _ LAST[TextNode.Offset]]
RETURNS [found, wenttoend: BOOL] = {
DoFind: PROC [root: TextEdit.Ref, tSel: Selection] = {
finder: TreeFind.Finder _ TreeFind.CreateFromRope[IF next THEN "" ELSE ""];
from: TextNode.Location;
where: TextNode.RefTextNode;
at, atEnd, start: TextNode.Offset;
Failed: PROC = {
IF gotoend THEN {
loc: TextNode.Location = IF next THEN TextNode.LastLocWithin[root]
ELSE [TextNode.FirstChild[root],0];
IF loc # from OR tSel.granularity # point THEN {
wenttoend _ TRUE;
RememberCurrentPosition[tSel.viewer];
MakePointSelection[tSel, loc];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, FALSE] }};
};
from _ InsertionPoint[tSel];
start _ from.where;
IF next AND tSel.insertion=before AND tSel.granularity#point THEN start _ start+1
ELSE IF ~next AND tSel.insertion=after THEN start _ MAX[start-1,0];
[found,where,at,atEnd,,] _ IF next THEN
TreeFind.Try[finder: finder, first: from.node, start: start,
last: endBoundaryNode, lastLen: endBoundaryOffset]
ELSE TreeFind.TryBackwards[finder: finder, first: from.node, len: start,
last: startBoundaryNode, lastStart: startBoundaryOffset];
wenttoend _ FALSE;
IF ~found THEN { Failed[]; RETURN };
MakePointSelection[tSel, [where,IF next THEN at+1 ELSE MAX[at,0]]];
IF ~DoSelectMatchingBrackets[','] THEN { Failed[]; RETURN };
TEditSelection.Copy[source: pSel, dest: tSel];
tSel.insertion _ before;
tSel.pendingDelete _ TRUE;
RememberCurrentPosition[tSel.viewer];
tSel.looks _ TextEdit.FetchLooks[ -- take looks from first char after the 
TextNode.NarrowToTextNode[tSel.start.pos.node], tSel.start.pos.where+1];
MakeSelection[tSel, primary];
TEditInput.CloseEvent[];
TEditRefresh.ScrollToEndOfSel[tSel.viewer, FALSE];
};
CallWithLocks[DoFind, read] };

END.

�����-- TEditMiscOpsImpl.mesa Edited by Paxton on June 6, 1983 4:09 pm
Last Edited by: Maxwell, January 6, 1983 11:33 am
-- insert left char at start of selection, right char after selection
-- extend selection until includes matching left and right brackets
Ê´��˜�JšÏcA™AJšÏk1™1Jšž	˜	˜�Jšœžœ+˜;Jšœžœ	žœ˜Jšœ	žœ/˜=JšœžœB˜RJšœ	žœz˜ˆJšœ
žœ˜'Jšœ	žœ–˜¤Jšœžœ*˜=Jšœžœ˜,J˜J˜	Jšœ
žœ˜&Jšœžœz˜ŽJšœžœ˜'Jšœ	žœ-˜;Jšœžœ
˜Jšœžœ˜!J˜�—Jšœž
˜J˜�Jšžœ›˜¢Jšžœž˜Jšžœ8˜<J˜�šÏn
œžœžœž	œ˜-šŸœžœ*˜<J˜Jšœ$˜$šžœžœ˜Jšœ˜J˜0—Jšœ3˜OJ˜˜$J˜*J˜Jšœ	žœ˜J˜ —J˜Jšœ˜Jšžœžœ,žœ˜J—Jšœ˜J˜�—šŸ
œžœžœ
žœ˜-šŸœžœ*˜<J˜J˜'J˜šžœžœ˜Jšœ˜J˜0—Jšœ3˜OJšœ˜J˜˜$J˜*J˜Jšœ	žœ˜J˜ —J˜Jšœ˜Jšžœžœ,žœ˜J—Jšœ˜J˜�—šŸœžœžœ)˜JšŸœžœ*˜AJ˜J˜J˜Jšœžœ˜šžœžœ˜Jšœ˜J˜0—Jšœ3˜OJšžœ0žœžœžœ˜TJ˜Jšœžœ˜Jšœžœ˜$Jšžœžœ žœžœ˜OJ˜šžœžœ*ž˜EJšœ
žœ˜—J˜J—šœ#˜#J˜�——šŸœžœžœ	žœ	˜0šŸœžœ*˜@Jšœ0˜0J˜Jšžœ2žœžœžœ˜FJšžœ!žœžœ˜1Jšžœ
žœ.žœžœ˜KJ˜J˜MJšœ˜Jšœ+žœ˜1Jšžœ˜—Jšžœžœ#˜4J˜�—šŸœžœžœ	žœ	˜.šŸœžœ*˜>Jšœ.˜.J˜šžœ0žœž˜8Jšœž˜ Jšœ	žœ,žœ˜OJšœžœ˜—Jšœ0˜0Jšœ+žœ˜3—Jšžœžœ'˜8J˜�—šŸœžœžœ	žœ	˜2šŸœžœ*˜BJšœ.˜.J˜šžœ0žœž˜8Jšœžœ˜3Jšžœžœ˜7—Jšœ0˜0Jšœ+žœ˜3—Jšžœžœ+˜<J˜�—šŸœžœžœ5˜NJšžœ
žœ˜J˜ J˜,J˜šžœ
žœ>ž˜UJ˜J˜Jšžœ˜—šžœ
žœ=ž˜TJ˜J˜Jšžœ˜—Jšœ#˜8J˜J˜�—šŸœžœžœ	žœ	˜0šŸœžœ*˜@Jšœ.˜.J˜J˜%Jšžœ+žœžœ˜;Jšžœ.žœžœžœ˜BJ˜
Jš
žœ	žœžœžœ&žœ˜NJ˜J˜JšœH˜HJšœ˜Jšœ+žœ˜1Jšžœ˜—Jšžœžœ#˜4J˜�—šŸœžœžœ	žœ	˜.šŸœžœ*˜>Jšœ.˜.J˜J˜šžœ.žœž˜6Jšœ'žœ˜>Jšœžœ˜—J˜šžœ	žœžœž˜ Jšžœžœžœ˜.J˜$Jšžœ˜—Jšœ%˜%Jšœ+žœ˜3—Jšžœžœ'˜8J˜�—šŸœžœžœ	žœ	˜.šŸœžœ*˜>Jšœ.˜.J˜šžœ	žœžœž˜ Jšžœ%žœžœžœ˜IJšžœ˜—Jšœ"˜"Jšœ+žœ˜3—Jšžœžœ'˜8J˜�—šŸœžœžœ	žœ	˜2šŸœžœ*˜BJ˜Jšœ.˜.J˜šžœ	žœžœž˜ šžœ&žœž˜.Jšœžœžœžœ˜(—Jšžœ˜—Jšžœ*žœžœžœ˜>Jšœ4˜4Jšœ+žœ˜1Jšžœ˜—Jšžœžœ+˜<J˜�—šŸ
œžœžœ˜J˜šŸ
œžœžœžœžœžœžœžœ˜JJšœžœžœ˜#J˜1Jšœžœžœ˜Jšœžœ˜šœžœž˜%J˜J˜J˜J˜J˜J˜
J˜
J˜J˜J˜J˜Jšžœ˜—J˜J˜J˜J˜Jšœ(˜<J˜Jšœ žœ˜+J˜J˜ Jšœžœ˜$Jšœžœ
žœžœ˜6Jšžœ˜—šŸœžœ*˜<J˜J˜J˜J˜J˜Jšžœžœ˜-J˜Jšžœ0žœžœžœ˜DJ˜šœœO˜TJšœžœ0˜T—J˜5J˜*J˜+J˜J˜Jšœžœ˜J˜-Jšžœ˜—Jšœ˜J˜�—šŸœžœžœžœ˜3JšE™EšŸœžœ*˜@J˜%J˜*J˜Jšœ˜Jšœ˜Jšžœ6žœžœžœ˜JJšžœ8žœžœžœ˜MJšžœ,žœ˜OJšžœžœžœ	˜.Jšžœ+žœ˜8J˜šœœœ˜#J˜J˜J˜J˜Jšœ	žœ˜"J˜ —šœœœ˜#J˜J˜J˜J˜Jšœ	žœ˜"J˜ —J˜Jšžœžœ˜9šžœ˜J˜Jšžœžœ˜3—Jšœžœ˜J˜-Jšžœ˜—šœ"˜"J˜�——Jšœžœžœ-˜@J˜�šŸœžœžœžœ˜;Jšžœ(žœ˜IJ˜�—šŸœžœžœžœžœ	žœ˜SJšC™CJ˜*J˜J˜J˜�šŸœžœžœ˜;Jšžœ ˜#J˜.Jšžœžœžœžœ˜Jšžœ(žœžœžœ˜>Jšžœ˜
J˜�—šŸœžœžœžœ˜$šžœ7˜=J˜J˜=Jšžœ˜J˜�——šŸœžœžœ˜7Jšžœ˜Jšžœ#žœžœžœ˜8Jšžœ(žœžœžœ˜>Jšžœ˜
J˜�—šŸœžœžœžœ˜%šžœ1˜7J˜J˜'Jšžœ˜J˜�——šŸœžœ*˜8J˜%Jšœžœ˜J˜J˜�Jšœ˜Jšœ˜J˜�J˜šžœ)žœžœ˜5Jšžœžœžœžœ	˜4J˜—Jšžœžœ-žœ	˜AJ˜,šžœ˜šžœžœ
ž˜/Jš	œžœžœžœžœ˜/J˜Jšžœ˜—Jšžœ˜—J˜J˜)J˜�J˜šžœ)žœžœ˜5Jšžœžœžœžœ	˜0J˜	—šžœžœ.žœ˜TJšžœžœžœ
˜2—J˜,šžœ˜šžœžœ
ž˜0Jš	œ	žœžœžœžœ˜0J˜Jšžœ˜—Jšžœ˜—J˜J˜,J˜�J˜J˜J˜J˜J˜-Jšœžœ˜
Jšžœžœ˜!—J˜�Jšœ ˜ J˜�—š	Ÿ
œžœžœžœž˜2Jšžœžœžœ˜AJ˜�—š
Ÿœžœžœžœžœ	žœž˜JJšžœ˜šŸ	œžœžœ
ž˜-šžœ1žœžœž˜BJ˜Jšžœ˜—Jšžœ˜—J˜!Jšœžœ˜šŸœžœž˜)Jšžœžœ˜1šžœžœžœž˜>Jš
žœžœžœžœžœ˜HJšžœžœžœ˜$šžœžœžœž˜OJ˜—Jšžœ˜—Jšžœ˜—šŸœžœž˜*Jšžœžœ˜1šžœžœžœž˜>Jš
žœžœžœžœžœ˜HJšžœžœžœ˜$šžœžœžœž˜OJ˜—Jšžœ˜—Jšžœ˜—Jšœ!˜!Jšœžœžœ˜&š
žœ
žœžœžœžœ˜3Jšœ"žœžœ˜3—Jšœ
žœ	žœžœ˜AJšžœžœžœ&žœ˜CJšœ˜Jšžœžœ˜Jšžœ˜—J˜�šŸœžœž	œžœ˜6Jšœžœ˜Jšœ.žœ˜4šžœžœžœ˜1J˜�——šŸœžœž	œžœ˜:Jšœ3žœ˜7Iprocšœ)˜)Kšœ%žœ˜;Jšžœžœ˜$šŸœžœ*˜6Jšœ2žœžœžœ˜MJ˜J˜J˜"šŸœžœ˜šžœ	žœ˜šœžœžœ˜BJšžœ˜#—šžœžœžœ˜0Jšœžœ˜Jšœ%˜%J˜Jšœ+žœ˜5——Jšœ˜—Jšœ˜J˜Jšžœžœžœžœ˜QJš
žœžœžœžœ	žœ˜Cšœžœž˜'šœ<˜<Jšœ2˜2—šžœD˜HJšœ9˜9——Jšœžœ˜Jšžœžœ
žœ˜$Jš	œ žœžœžœžœ	˜CJšžœ"žœ
žœ˜>J˜.J˜Jšœžœ˜Jšœ%˜%šœ")˜KJšœH˜H—J˜J˜Jšœ+žœ˜2Jšœ˜—J˜J˜�—Jšžœ˜J˜�—�…—����DÈ��W€��