DIRECTORY AtomButtons, Basics, Feedback, GGCoreOps, GGCoreTypes, Imager, ImagerColor, ImagerTransformation, Rope; GGCoreOpsImpl: CEDAR PROGRAM IMPORTS Feedback, Imager, ImagerColor, ImagerTransformation, Rope EXPORTS GGCoreOps = BEGIN Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = Feedback.Problem; EachEventProc: TYPE = GGCoreOps.EachEventProc; EachRopeProc: TYPE = PROC [thisRope: Rope.ROPE] RETURNS [done: BOOL ¬ FALSE]; EventListt: TYPE = REF EventListtObj; -- spelled with two t's to indicate a "List and a Tail pointer" EventListtObj: TYPE = GGCoreTypes.EventListtObj; Event: TYPE = GGCoreTypes.Event; RopeListt: TYPE = REF RopeListtObj; RopeListtObj: TYPE = GGCoreTypes.RopeListtObj; ScalarButton: TYPE = AtomButtons.ScalarButton; NewEventListt: PUBLIC PROC [] RETURNS [listt: EventListt] = { listt ¬ NEW[EventListtObj ¬ [NIL, NIL]]; }; FlushEventListt: PUBLIC PROC [listt: EventListt] = { listt.list ¬ NIL; listt.tail ¬ NIL; }; AppendEvent: PUBLIC PROC [event: Event, listt: EventListt] = { IF listt.tail = NIL THEN { IF NOT listt.list = NIL THEN ERROR; listt.tail ¬ listt.list ¬ LIST[event]; } ELSE { listt.tail.rest ¬ LIST[event]; listt.tail ¬ listt.tail.rest; }; }; GetEventList: PUBLIC PROC [listt: EventListt] RETURNS [list: LIST OF Event] = { list ¬ listt.list; }; NoEvents: PUBLIC PROC [listt: EventListt] RETURNS [BOOL] = { RETURN[listt.list = NIL]; }; ForEachEvent: PUBLIC PROC [listt: EventListt, eachEventProc: EachEventProc] = { done: BOOL ¬ FALSE; FOR list: LIST OF Event ¬ listt.list, list.rest UNTIL list = NIL DO done ¬ eachEventProc[list.first]; IF done THEN RETURN; ENDLOOP; }; NewRopeListt: PUBLIC PROC [] RETURNS [listt: RopeListt] = { listt ¬ NEW[RopeListtObj ¬ [NIL, NIL]]; }; FlushRopeListt: PUBLIC PROC [listt: RopeListt] = { listt.list ¬ NIL; listt.tail ¬ NIL; }; AppendRope: PUBLIC PROC [rope: Rope.ROPE, listt: RopeListt] = { IF listt.tail = NIL THEN { IF NOT listt.list = NIL THEN ERROR; listt.tail ¬ listt.list ¬ LIST[rope]; } ELSE { listt.tail.rest ¬ LIST[rope]; listt.tail ¬ listt.tail.rest; }; }; NoRopes: PUBLIC PROC [listt: RopeListt] RETURNS [BOOL] = { RETURN[listt.list = NIL]; }; ForEachRope: PUBLIC PROC [listt: RopeListt, eachRopeProc: EachRopeProc] = { done: BOOL ¬ FALSE; FOR list: LIST OF Rope.ROPE ¬ listt.list, list.rest UNTIL list = NIL DO done ¬ eachRopeProc[list.first]; IF done THEN RETURN; ENDLOOP; }; StartList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF REF ANY] = { ptr ¬ entityList ¬ NIL; }; AddEntity: PUBLIC PROC [entity: REF ANY, entityList, ptr: LIST OF REF ANY] RETURNS [newList, newPtr: LIST OF REF ANY] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr ¬ newList ¬ CONS[entity, NIL]; RETURN; } ELSE { newList ¬ entityList; ptr.rest ¬ CONS[entity, NIL]; newPtr ¬ ptr.rest; }; }; List: PUBLIC PROC [ref1, ref2, ref3: REF ANY ¬ NIL] RETURNS [LIST OF REF ANY] = { RETURN[ SELECT TRUE FROM ref2=NIL => LIST[ref1], ref3=NIL => LIST[ref1, ref2], ENDCASE => LIST[ref1, ref2, ref3] ]; }; StartRealList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF REAL] = { ptr ¬ entityList ¬ NIL; }; AddReal: PUBLIC PROC [entity: REAL, entityList, ptr: LIST OF REAL] RETURNS [newList, newPtr: LIST OF REAL] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr ¬ newList ¬ CONS[entity, NIL]; RETURN; } ELSE { newList ¬ entityList; ptr.rest ¬ CONS[entity, NIL]; newPtr ¬ ptr.rest; }; }; AppendRealList: PUBLIC PROC [list1, list2: LIST OF REAL] RETURNS [result: LIST OF REAL] = { pos: LIST OF REAL; newCell: LIST OF REAL; IF list1 = NIL THEN RETURN[list2]; result ¬ CONS[list1.first, NIL]; pos ¬ result; FOR l: LIST OF REAL ¬ list1.rest, l.rest UNTIL l = NIL DO newCell ¬ CONS[l.first, NIL]; pos.rest ¬ newCell; pos ¬ newCell; ENDLOOP; pos.rest ¬ list2; }; RealCompareProc: TYPE = PROC[r1: REAL, r2: REAL] RETURNS [Basics.Comparison]; SortRealList: PUBLIC PROC [list: LIST OF REAL, ascending: BOOL ¬ TRUE] RETURNS [sortedList: LIST OF REAL] = { CompareAscending: RealCompareProc = { IF r1 < r2 THEN RETURN[less]; IF r1 > r2 THEN RETURN[greater] ELSE RETURN[equal]; }; CompareDescending: RealCompareProc = { IF r1 > r2 THEN RETURN[less]; IF r1 < r2 THEN RETURN[greater] ELSE RETURN[equal]; }; IF ascending THEN sortedList ¬ UniqueSortRealList[list, CompareAscending] ELSE sortedList ¬ UniqueSortRealList[list, CompareDescending]; }; SortRealListAux: PUBLIC PROC [list: LIST OF REAL, compareProc: RealCompareProc] RETURNS [LIST OF REAL] = { InnerSort: PROC [head: LIST OF REAL, max: NAT] RETURNS [new, next: LIST OF REAL] = { mid: LIST OF REAL ¬ (new ¬ head).rest; IF mid = NIL THEN RETURN; next ¬ mid.rest; IF compareProc[new.first, mid.first] = greater THEN { mid.rest ¬ new; new ¬ mid; mid ¬ head; }; mid.rest ¬ NIL; IF next = NIL THEN RETURN; next ¬ (mid ¬ next).rest; IF next # NIL THEN { temp: LIST OF REAL ¬ next; next ¬ temp.rest; temp.rest ¬ NIL; IF compareProc[mid.first, temp.first] = greater THEN { mid.rest ¬ NIL; temp.rest ¬ mid; mid ¬ temp} }; new ¬ MergeRealList[new, mid, compareProc]; IF next = NIL THEN RETURN; FOR depth: NAT IN [2..max) DO [mid, next] ¬ InnerSort[next, depth]; new ¬ MergeRealList[new, mid, compareProc]; IF next = NIL THEN RETURN; ENDLOOP; }; IF list = NIL OR list.rest = NIL THEN RETURN [list]; RETURN [InnerSort[list, 32].new]; }; MergeRealList: PUBLIC PROC [x,y: LIST OF REAL, compareProc: RealCompareProc] RETURNS [new: LIST OF REAL] = { tail: LIST OF REAL ¬ NIL; IF x = NIL THEN RETURN [y]; IF y = NIL THEN RETURN [x]; new ¬ x; IF compareProc[x.first, y.first] = greater THEN {new ¬ y; y ¬ x; x ¬ new}; DO DO tail ¬ x; x ¬ x.rest; IF x = NIL THEN {tail.rest ¬ y; RETURN}; IF compareProc[x.first, y.first] = greater THEN EXIT; ENDLOOP; tail.rest ¬ y; DO tail ¬ y; y ¬ y.rest; IF y = NIL THEN {tail.rest ¬ x; RETURN}; IF compareProc[x.first, y.first] = less THEN EXIT; ENDLOOP; tail.rest ¬ x; ENDLOOP; }; UniqueSortRealList: PUBLIC PROC [list: LIST OF REAL, compareProc: RealCompareProc] RETURNS[LIST OF REAL] = { lag: LIST OF REAL ¬ list ¬ SortRealListAux[list, compareProc]; WHILE lag # NIL DO rest: LIST OF REAL ¬ lag.rest; IF rest = NIL THEN EXIT; IF compareProc[lag.first, rest.first] = equal THEN lag.rest ¬ rest.rest ELSE lag ¬ rest; ENDLOOP; RETURN[list]; }; StartBoolList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF BOOL] = { ptr ¬ entityList ¬ NIL; }; AddBool: PUBLIC PROC [entity: BOOL, entityList, ptr: LIST OF BOOL] RETURNS [newList, newPtr: LIST OF BOOL] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr ¬ newList ¬ CONS[entity, NIL]; RETURN; } ELSE { newList ¬ entityList; ptr.rest ¬ CONS[entity, NIL]; newPtr ¬ ptr.rest; }; }; AppendBoolList: PUBLIC PROC [list1, list2: LIST OF BOOL] RETURNS [result: LIST OF BOOL] = { pos: LIST OF BOOL; newCell: LIST OF BOOL; IF list1 = NIL THEN RETURN[list2]; result ¬ CONS[list1.first, NIL]; pos ¬ result; FOR l: LIST OF BOOL ¬ list1.rest, l.rest UNTIL l = NIL DO newCell ¬ CONS[l.first, NIL]; pos.rest ¬ newCell; pos ¬ newCell; ENDLOOP; pos.rest ¬ list2; }; StartNATList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF NAT] = { ptr ¬ entityList ¬ NIL; }; AddNAT: PUBLIC PROC [entity: NAT, entityList, ptr: LIST OF NAT] RETURNS [newList, newPtr: LIST OF NAT] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr ¬ newList ¬ CONS[entity, NIL]; RETURN; } ELSE { newList ¬ entityList; ptr.rest ¬ CONS[entity, NIL]; newPtr ¬ ptr.rest; }; }; AppendNATs: PUBLIC PROC [list1, list2: LIST OF NAT] RETURNS [result: LIST OF NAT] = { pos: LIST OF NAT; newCell: LIST OF NAT; IF list1 = NIL THEN RETURN[list2]; result ¬ CONS[list1.first, NIL]; pos ¬ result; FOR l: LIST OF NAT ¬ list1.rest, l.rest UNTIL l = NIL DO newCell ¬ CONS[l.first, NIL]; pos.rest ¬ newCell; pos ¬ newCell; ENDLOOP; pos.rest ¬ list2; }; StartScalarButtonList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF ScalarButton] = { ptr ¬ entityList ¬ NIL; }; AddScalarButton: PUBLIC PROC [entity: ScalarButton, entityList, ptr: LIST OF ScalarButton] RETURNS [newList, newPtr: LIST OF ScalarButton] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr ¬ newList ¬ CONS[entity, NIL]; RETURN; } ELSE { newList ¬ entityList; ptr.rest ¬ CONS[entity, NIL]; newPtr ¬ ptr.rest; }; }; AppendScalarButtons: PUBLIC PROC [list1, list2: LIST OF ScalarButton] RETURNS [result: LIST OF ScalarButton] = { pos: LIST OF ScalarButton; newCell: LIST OF ScalarButton; IF list1 = NIL THEN RETURN[list2]; result ¬ CONS[list1.first, NIL]; pos ¬ result; FOR l: LIST OF ScalarButton ¬ list1.rest, l.rest UNTIL l = NIL DO newCell ¬ CONS[l.first, NIL]; pos.rest ¬ newCell; pos ¬ newCell; ENDLOOP; pos.rest ¬ list2; }; PUChoiceList: PUBLIC PROC [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19: AtomButtons.PopUpChoice ¬ [] ] RETURNS [list: AtomButtons.PopUpChoices] = { OPEN AtomButtons; InnerCons: PROC[r: PopUpChoice] = {rList ¬ CONS[r, rList]; }; rList: PopUpChoices; IF r0.action#NIL THEN InnerCons[r0]; IF r1.action#NIL THEN InnerCons[r1]; IF r2.action#NIL THEN InnerCons[r2]; IF r3.action#NIL THEN InnerCons[r3]; IF r4.action#NIL THEN InnerCons[r4]; IF r5.action#NIL THEN InnerCons[r5]; IF r6.action#NIL THEN InnerCons[r6]; IF r7.action#NIL THEN InnerCons[r7]; IF r8.action#NIL THEN InnerCons[r8]; IF r9.action#NIL THEN InnerCons[r9]; IF r10.action#NIL THEN InnerCons[r10]; IF r11.action#NIL THEN InnerCons[r11]; IF r12.action#NIL THEN InnerCons[r12]; IF r13.action#NIL THEN InnerCons[r13]; IF r14.action#NIL THEN InnerCons[r14]; IF r15.action#NIL THEN InnerCons[r15]; IF r16.action#NIL THEN InnerCons[r16]; IF r17.action#NIL THEN InnerCons[r17]; IF r18.action#NIL THEN InnerCons[r18]; IF r19.action#NIL THEN InnerCons[r19]; FOR dummy: PopUpChoices ¬ rList, dummy.rest UNTIL dummy=NIL DO list ¬ CONS[dummy.first, list]; ENDLOOP; }; BreakIntervalMOD: PUBLIC PROC [start, end, mod: NAT] RETURNS [s1, e1, s2, e2: INT] = { IF start >= mod OR end >= mod THEN ERROR; IF start <= end THEN RETURN[start, end, -1, -1]; RETURN[0, end, start, mod-1]; }; BreakIntervalMODLen: PUBLIC PROC [start, len, mod: NAT] RETURNS [s1, len1, s2, len2: INT] = { IF start >= mod OR len > mod + 1 THEN ERROR; IF start + len -1 < mod THEN RETURN[start, len, -1, -1]; RETURN[0, start+len-mod, start, mod-start]; }; InMODRegion: PUBLIC PROC [test: NAT, start, end, mod: NAT] RETURNS [BOOL] = { IF start = end THEN RETURN [test = start]; IF start < end THEN RETURN [test IN [start..end]]; RETURN [test IN [start..mod) OR test IN [0..end]]; }; ExtractRGB: PUBLIC PROC [color: ImagerColor.ConstantColor] RETURNS [r,g,b: REAL] = { [[R: r, G: g, B: b]] ¬ ImagerColor.RGBFromColor[ImagerColor.NarrowToOpConstantColor[color]]; }; EquivalentColors: PUBLIC PROC [color1, color2: Imager.Color] RETURNS [equal: BOOL ¬ FALSE] = { r1, g1, b1, r2, g2, b2: REAL; epsilon: REAL ¬ 1.0E-2; success: BOOL ¬ TRUE; IF color1=color2 THEN RETURN[TRUE]; IF color1=NIL OR color2=NIL THEN RETURN[FALSE]; WITH color1 SELECT FROM color1Constant: ImagerColor.ConstantColor => { WITH color2 SELECT FROM color2Constant: ImagerColor.ConstantColor => { [r1, g1, b1] ¬ ExtractRGB[color1Constant]; [r2, g2, b2] ¬ ExtractRGB[color2Constant]; equal ¬ (r1=r2 AND g1=g2 AND b1=b2) OR (ABS[r1-r2] equal ¬ FALSE; }; color1SampledBlack: ImagerColor.SampledBlack => { WITH color2 SELECT FROM color2SampledBlack: ImagerColor.SampledBlack => { equal ¬ color1SampledBlack.pa = color2SampledBlack.pa AND color1SampledBlack.clear = color2SampledBlack.clear }; ENDCASE => equal ¬ FALSE; }; color1SampledColor: ImagerColor.SampledColor => { WITH color2 SELECT FROM color2SampledColor: ImagerColor.SampledColor => { equal ¬ color1SampledColor.pa = color2SampledColor.pa AND color1SampledColor.colorOperator = color2SampledColor.colorOperator }; ENDCASE => equal ¬ FALSE; }; ENDCASE => equal ¬ FALSE; }; SetColor: PUBLIC PROC [dc: Imager.Context, color: Imager.Color, m: Imager.Transformation ¬ NIL] = { IF color = NIL THEN RETURN; WITH color SELECT FROM sampledBlack: ImagerColor.SampledBlack => { IF m # NIL THEN Imager.SetSampledBlack[dc, sampledBlack.pa, ImagerTransformation.Concat[sampledBlack.um, m], sampledBlack.clear] ELSE Imager.SetSampledBlack[dc, sampledBlack.pa, sampledBlack.um, sampledBlack.clear]; }; sampledColor: ImagerColor.SampledColor => { IF m # NIL THEN Imager.SetSampledColor[dc, sampledColor.pa, ImagerTransformation.Concat[sampledColor.um, m], sampledColor.colorOperator] ELSE Imager.SetSampledColor[dc, sampledColor.pa, sampledColor.um, sampledColor.colorOperator]; } ENDCASE => Imager.SetColor[dc, color]; }; TransformColor: PUBLIC PROC [color: Imager.Color, viewView: ImagerTransformation.Transformation] RETURNS [newColor: Imager.Color] = { WITH color SELECT FROM sampledBlack: ImagerColor.SampledBlack => { sampledBlack.um ¬ ImagerTransformation.Concat[sampledBlack.um, viewView]; }; sampledColor: ImagerColor.SampledColor => { sampledColor.um ¬ ImagerTransformation.Concat[sampledColor.um, viewView]; } ENDCASE => {}; newColor ¬ color; }; CopyColor: PUBLIC PROC [color: Imager.Color] RETURNS [copy: Imager.Color] = { WITH color SELECT FROM sampledBlack: ImagerColor.SampledBlack => { copy ¬ ImagerColor.MakeSampledBlack[sampledBlack.pa, ImagerTransformation.Copy[sampledBlack.um], sampledBlack.clear]; }; sampledColor: ImagerColor.SampledColor => { copy ¬ ImagerColor.MakeSampledColor[sampledColor.pa, ImagerTransformation.Copy[sampledColor.um], sampledColor.colorOperator]; } ENDCASE => copy ¬ color; }; BoolToRope: PUBLIC PROC [bool: BOOL] RETURNS [rope: Rope.ROPE] = { rope ¬ IF bool THEN "T" ELSE "F"; }; RopeToBool: PUBLIC PROC [rope: Rope.ROPE] RETURNS [bool: BOOL] = { SELECT TRUE FROM Rope.Equal[rope, "F", FALSE] => bool ¬ FALSE; Rope.Equal[rope, "T", FALSE] => bool ¬ TRUE; ENDCASE => ERROR; }; END. € GGCoreOpsImpl.mesa Copyright Σ 1986, 1992 by Xerox Corporation. All rights reserved. Contents: Utility routines extracted from GGUtility and SVUtility and other places. Bier, January 6, 1992 5:14 pm PST Pier, October 22, 1987 2:09:53 pm PDT Doug Wyatt, April 9, 1992 4:30 pm PDT Operations on LIST OF REF ANY Operations on LIST OF REAL Non-destructive (copies the first list). Sorts the list of REAL using the MergeSort algorithm from ListImpl. ... destructively sorts the given list in increasing order according to compareProc. The sort is not stable, so order of equal elements is not preserved. swap them, leaving mid pointing at the greater. Second, grab the second pair of elements off the list. There is at least one. There are two elements for the second pair, so we need to put them in order. The first two nodes are in the wrong order, so swap them. Third, merge the two lead lists. If this exhausts the original list, then return. Finally, build up the tree by progressively building small lists and merging them into larger lists. The size doubles at each level. We start with new holding onto a list of 4 elements, and next holding onto the remainder of the list. ... destructively merges two lists according to compareProc. If the input lists are sorted in increasing order, then the output list will be sorted in increasing order. Implementation notes: RC assignments are limited by preserving runs of elements in order. Test for empty lists Start from y, which we do by swapping x and y. We first assume that we have just appended from x, but need to advance x to the next element and check for emptiness. Once this is done we try to stay within x as long as the predicate allows. By doing this we reduce the amount of RC assignments of the form "tail.rest _ ...", which speeds things up considerably. We have just appended from y, so append to the list from y as long as reasonable. Operations on LIST OF BOOL Non-destructive (copies the first list). Operations on LIST OF NAT Non-destructive (copies the first list). Operations on LIST OF ScalarButton Non-destructive (copies the first list). Modular Arithmetic Example: BreakIntervalMODLen[6, 4, 7] => [0, 3, 6, 1]. BreakIntervalMODLen[2, 5, 7] => [2, 5, -1, -1]. BreakIntervalMODLen[6, 8, 7] => [0, 7, 6, 1]. -- repeats 6 twice Colors Does not yet work properly for sampled colors. Ignores transformation for now (must be ignored for Imager.Object caching). Ignores transformation for now (must be ignored for Imager.Object caching). Calls Imager.SetColor, Imager.SetSampledColor, or Imager.SetSampledBlack as appropriate. Gargoyle stores the transformation colorView in the sampled color (instead of colorDevice as the Imager would). m is considered to be a transformation from View to View. um in a transformation is a colorView transformation. Conversions Returns "T" or "F". Takes "T" or "F". Raises an Error if rope is anything else. ΚC–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ Οeœ6™BKšΟnœL™TK™!K™%K™%K™—šΟk ˜ K˜g—K˜šž œŸœŸ˜KšŸœ:˜AKšŸœŸ˜—K˜K˜KšžœŸœŸœ Ÿœ˜;K˜KšœŸœ˜.Kš œŸœŸœŸœŸœŸœŸœ˜MKš œ ŸœŸœΟc'Πcz ‘  ˜eKšœŸœ˜0KšœŸœ˜ Kšœ ŸœŸœ˜#KšœŸœ˜.KšœŸœ˜.K˜šž œŸœŸœŸœ˜=KšœŸœŸœŸœ˜(K˜K˜—šžœŸœŸœ˜4Kšœ Ÿœ˜Kšœ Ÿœ˜K˜K˜—šž œŸœŸœ&˜>šŸœŸœŸœ˜Kš ŸœŸœŸœŸœŸœ˜#KšœŸœ˜&K˜—šŸœ˜KšœŸœ˜K˜K˜—K˜K˜—š ž œŸœŸœŸœŸœŸœ ˜OK˜K˜K˜—š žœŸœŸœŸœŸœ˜K˜—K™šžœŸ œŸœŸœŸœ ŸœŸœŸœŸœ˜jKšœš™ššž œŸœŸœŸœŸœŸœŸœ ŸœŸœŸœ˜TKšœŸœŸœŸœ˜&KšŸœŸœŸœŸœ˜K˜šŸœ-Ÿœ˜5Kšœ/™/K˜&Kšœ˜—Kšœ Ÿœ˜KšŸœŸœŸœŸœ˜K˜KšœN™NK˜šŸœŸœŸœ˜KšœL™LKšœŸœŸœŸœ˜K˜Kšœ Ÿœ˜šŸœ.Ÿœ˜6Kšœ9™9Kšœ Ÿœ˜,—K˜K˜—K™RK˜+KšŸœŸœŸœŸœ˜Kšœμ™μšŸœŸœŸœ Ÿ˜K˜%K˜+KšŸœŸœŸœŸœ˜KšŸœ˜—K˜—Kš ŸœŸœŸœ ŸœŸœŸœ˜4KšŸœ˜!K˜K˜—šž œŸœŸœŸœŸœŸœ ŸœŸœŸœŸœ˜lJšœ©™©™J™C—Kš œŸœŸœŸœŸœ˜K˜Jšœ™KšŸœŸœŸœŸœ˜KšŸœŸœŸœŸœ˜K˜K˜šŸœ)Ÿœ˜LJšœ.™.K˜—šŸ˜Jš œ«™ΊšŸ˜K˜KšŸœŸœŸœŸœ˜(KšŸœ)ŸœŸœ˜5KšŸœ˜—K˜K˜JšœQ™QšŸ˜K˜KšŸœŸœŸœŸœ˜(KšŸœ&ŸœŸœ˜2KšŸœ˜—K˜KšŸœ˜—K˜K˜—šžœŸœŸœŸœŸœŸœ ŸœŸœŸœŸœ˜lKšœŸœŸœŸœ-˜>šŸœŸœŸ˜KšœŸœŸœŸœ ˜KšŸœŸœŸœŸœ˜KšŸœ,ŸœŸœ ˜XKšŸœ˜—KšŸœ˜ K˜—K™šœŸœ™K™—šž œŸœŸœŸœŸœŸœŸœ˜IKšœŸœ˜K˜K˜—šžœŸœŸœ ŸœŸœŸœŸœŸœŸœŸœŸœ˜nšŸœŸœŸœ˜Kš ŸœŸœŸœŸœŸœ˜#KšœŸœ Ÿœ˜%KšŸœ˜K˜—šŸœ˜K˜Kšœ Ÿœ Ÿœ˜K˜K˜—K˜K˜—šžœŸœŸœŸœŸœŸœŸœ ŸœŸœŸœ˜[KšœŸœŸœŸœ˜Kšœ ŸœŸœŸœ˜K™(KšŸœ ŸœŸœŸœ˜"Kšœ ŸœŸœ˜ K˜ š ŸœŸœŸœŸœŸœŸœŸ˜9Kšœ Ÿœ Ÿœ˜K˜K˜—KšŸœ˜K˜Kšœ˜K˜—K™šœŸœ™K™—šž œŸœŸœŸœŸœŸœŸœ˜GKšœŸœ˜K˜K˜—šžœŸœŸœ ŸœŸœŸœŸœŸœŸœŸœŸœ˜jšŸœŸœŸœ˜Kš ŸœŸœŸœŸœŸœ˜#KšœŸœ Ÿœ˜%KšŸœ˜K˜—šŸœ˜K˜Kšœ Ÿœ Ÿœ˜K˜K˜—K˜K˜—šž œŸœŸœŸœŸœŸœŸœ ŸœŸœŸœ˜UKšœŸœŸœŸœ˜Kšœ ŸœŸœŸœ˜K™(KšŸœ ŸœŸœŸœ˜"Kšœ ŸœŸœ˜ K˜ š ŸœŸœŸœŸœŸœŸœŸ˜8Kšœ Ÿœ Ÿœ˜K˜K˜—KšŸœ˜K˜Kšœ˜—K™šœŸœŸœ ™"K™—š žœŸœŸœŸœŸœŸœ˜YKšœŸœ˜K˜K˜—šžœŸœŸœ)ŸœŸœŸœŸœŸœ˜ŽšŸœŸœŸœ˜Kš ŸœŸœŸœŸœŸœ˜#KšœŸœ Ÿœ˜%KšŸœ˜K˜—šŸœ˜K˜Kšœ Ÿœ Ÿœ˜K˜K˜—K˜K˜—šžœŸœŸœŸœŸœŸœ ŸœŸœ˜pKšœŸœŸœ˜Kšœ ŸœŸœ˜K™(KšŸœ ŸœŸœŸœ˜"Kšœ ŸœŸœ˜ K˜ š ŸœŸœŸœ#ŸœŸœŸ˜AKšœ Ÿœ Ÿœ˜K˜K˜—KšŸœ˜K˜K˜—K˜šž œŸ œ{Ÿœ%˜ΐKšŸœ ˜Kšž œŸœŸœ˜=K˜Kšœ˜KšŸœ ŸœŸœ˜$Kš ŸœΟtœŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜$Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&Kš Ÿœ’œŸœŸœ ’œ˜&K˜šŸœ)ŸœŸœŸ˜>KšœŸœ˜KšŸœ˜—K˜K˜—K™šœ™K™—š žœŸœŸœŸœŸœŸœ˜VKšŸœŸœ ŸœŸœ˜)KšŸœŸœŸœ˜0KšŸœ˜K˜K˜—š žœŸœŸœŸœŸœŸœ˜]Kšžœ/™6Kšœ/™/Kšœ. ™@KšŸœŸœŸœŸœ˜,KšŸœŸœŸœ˜8KšŸœ%˜+K˜K˜—šž œŸœŸœŸœŸœŸœŸœ˜NKšŸœ ŸœŸœ˜*KšŸœ ŸœŸœŸœ˜2KšŸœŸœŸœŸœ ˜2Kšœ˜—K™™K˜—š ž œŸœŸœ$Ÿœ Ÿœ˜TK˜\K˜K˜—š žœŸœŸœ Ÿœ ŸœŸœ˜^K™.KšœŸœ˜Kšœ Ÿœ ˜Kšœ ŸœŸœ˜KšŸœŸœŸœŸœ˜#KšŸœŸœŸœŸœŸœŸœŸœ˜/šŸœŸœŸ˜šœ.˜.šŸœŸœŸ˜šœ.˜.K˜*K˜*šœŸœŸœŸ˜&Kš œŸœŸœŸœŸœŸœ˜C—K˜—KšŸœ Ÿœ˜—K˜—šœ1˜1šŸœŸœŸ˜šœ1˜1šœ6Ÿ˜9Kšœ3˜3—K™KK˜—KšŸœ Ÿœ˜—K˜—šœ1˜1šŸœŸœŸ˜šœ1˜1šœ6Ÿ˜9KšœC˜C—K™KK˜—KšŸœ Ÿœ˜—K˜—KšŸœ Ÿœ˜—K˜—K˜procšžœŸœŸœFŸœ˜cLšœ‚Οuœ'£œQ™„KšŸœ ŸœŸœŸœ˜šŸœŸœŸ˜šœ+˜+LšŸœŸ˜ šŸœ,˜0LšœD˜D—LšŸœR˜VL˜—šœ+˜+LšŸœŸ˜ šŸœ,˜0LšœL˜L—LšŸœZ˜^Lšœ˜—LšŸœ˜&—L˜L˜—šžœŸ œ£œ'Ÿœ˜…Kšœ!£œ™5šŸœŸœŸ˜šœ+˜+LšœC£œ˜IL˜—šœ+˜+LšœC£œ˜ILšœ˜—LšŸœ˜—L˜K˜K˜—šž œŸ œŸœ˜MšŸœŸœŸ˜šœ+˜+L˜uL˜—šœ+˜+L˜}Lšœ˜—LšŸœ˜—K˜—K˜™ L˜—š ž œŸœŸœŸœŸœ Ÿœ˜BL™LšœŸœŸœŸœ˜!L˜L˜—š ž œŸœŸœ ŸœŸœŸœ˜BL™<šŸœŸœŸ˜LšœŸœ Ÿœ˜-LšœŸœ Ÿœ˜,LšŸœŸœ˜—L˜—L˜KšŸœ˜—…—5άYŸ