DIRECTORY Atom USING [GetPName, MakeAtom], Basics USING [NonNegative], List USING [Length, Sort], NodeProps USING [CopyInfoProc, MapPropsAction, ReadSpecsProc, WriteSpecsProc], Prop USING [PropList, Get, Put, MapAction, Map], RefTab USING [Create, Fetch, Ref, Store], Rope USING [Concat, Equal, Fetch, FromChar, FromRefText, IsEmpty, ROPE, Size, Substr], Rosary USING [ROSARY, FromRuns, MapRuns], TextEdit USING [ItemFromCharSet], Tioga USING [Node, CharSet]; NodePropsImpl: CEDAR MONITOR IMPORTS Atom, Basics, List, Prop, RefTab, Rope, Rosary, TextEdit EXPORTS NodeProps ~ BEGIN ROSARY: TYPE = Rosary.ROSARY; ROPE: TYPE = Rope.ROPE; PropList: TYPE = Prop.PropList; CharSet: TYPE = Tioga.CharSet; CopyInfoProc: TYPE = NodeProps.CopyInfoProc; MapPropsAction: TYPE = NodeProps.MapPropsAction; ReadSpecsProc: TYPE = NodeProps.ReadSpecsProc; WriteSpecsProc: TYPE = NodeProps.WriteSpecsProc; nameFormat: PUBLIC ATOM ฌ $Format; nameComment: PUBLIC ATOM ฌ $Comment; nameCharSets: PUBLIC ATOM ฌ $CharSets; nameCharProps: PUBLIC ATOM ฌ $CharProps; nameStyleDef: PUBLIC ATOM ฌ $StyleDef; namePrefix: PUBLIC ATOM ฌ $Prefix; namePostfix: PUBLIC ATOM ฌ $Postfix; nameArtwork: PUBLIC ATOM ฌ $Artwork; nameActive: PUBLIC ATOM ฌ $Active; ReadComment: PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] ~ { RETURN [ValueFromBool[Rope.Equal[specs, "TRUE", FALSE]]]; }; WriteComment: PROC [name: ATOM, value: REF] RETURNS [specs: ROPE] ~ { comment: BOOL ~ BoolFromValue[value]; specs ฌ IF comment THEN "TRUE" ELSE "FALSE"; }; ReadFormat: PROC [name: ATOM, specs: ROPE] RETURNS [value: REF ฌ NIL] ~ { IF NOT Rope.IsEmpty[specs] THEN value ฌ Atom.MakeAtom[specs]; }; WriteFormat: PROC [name: ATOM, value: REF] RETURNS [specs: ROPE ฌ NIL] ~ { WITH value SELECT FROM atom: ATOM => specs ฌ Atom.GetPName[NARROW[atom]]; ENDCASE => IF value = NIL THEN specs ฌ ""; }; ReadPfix: PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] ~ { RETURN [specs] }; WritePfix: PROC [name: ATOM, value: REF] RETURNS [specs: ROPE ฌ NIL] ~ { WITH value SELECT FROM rope: ROPE => specs ฌ rope; ENDCASE; }; IntByte: TYPE ~ MACHINE DEPENDENT RECORD [more: BOOL, data: [0..128)]; GetInt: PROC [get: PROC RETURNS [BYTE]] RETURNS [int: INT ฌ 0] ~ { DO byte: IntByte ~ LOOPHOLE[get[]]; int ฌ int*128+byte.data; IF NOT byte.more THEN EXIT; ENDLOOP; }; PutInt: PROC [int: INT, put: PROC [BYTE], more: BOOL ฌ FALSE] ~ { byte: IntByte ~ [more: more, data: int MOD 128]; IF int>=128 THEN PutInt[int/128, put, TRUE]; put[LOOPHOLE[byte]]; }; ReadCharSets: PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] ~ { p: PROC [q: PROC [REF, INT]] ~ { size: INT ~ Rope.Size[specs]; i: INT ฌ 0; GetByte: PROC RETURNS [b: BYTE] ~ {b ฌ ORD[Rope.Fetch[specs, i]]; i ฌ i + 1}; UNTIL i = size DO repeat: INT ~ GetInt[GetByte]; charSet: BYTE ~ GetByte[]; q[TextEdit.ItemFromCharSet[charSet], repeat]; ENDLOOP; }; RETURN [Rosary.FromRuns[p]]; }; WriteCharSets: PROC [name: ATOM, value: REF] RETURNS [specs: ROPE ฌ NIL] ~ { text: REF TEXT ~ NEW[TEXT[48]]; Fold: PROC ~ {specs ฌ Rope.Concat[specs, Rope.FromRefText[text]]; text.length ฌ 0}; PutByte: PROC [b: BYTE] ~ { IF text.length = text.maxLength THEN Fold[]; text[text.length] ฌ VAL[b]; text.length ฌ text.length + 1; }; charSet: CharSet ฌ 0; rept: INT ฌ 0; FlushRun: PROC ~ {IF rept>0 THEN { PutInt[rept, PutByte]; PutByte[charSet]; rept ฌ 0 }}; Action: PROC [item: REF, repeat: INT] RETURNS [quit: BOOL ฌ FALSE] ~ { new: CharSet ฌ WITH item SELECT FROM r: REF CharSet => rญ, ENDCASE => 0; IF rept > 0 AND new#charSet THEN FlushRun[]; charSet ฌ new; rept ฌ rept + repeat; }; [] ฌ Rosary.MapRuns[[NARROW[value]], Action]; FlushRun[]; Fold[]; IF Rope.Size[specs] = 0 THEN specs ฌ NIL; }; ReadCharProps: PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] ~ { p: PROC [q: PROC [REF, INT]] ~ { i: INT ฌ 0; size: INT ฌ Rope.Size[specs]; GetByte: PROC RETURNS [b: BYTE] ~ {b ฌ ORD[Rope.Fetch[specs, i]]; i ฌ i + 1}; GetRope: PROC RETURNS [rope: ROPE ฌ NIL] ~ { len: INT ~ GetInt[GetByte]; rope ฌ Rope.Substr[specs, i, len]; i ฌ i + len; [] ฌ Basics.NonNegative[size-i]; }; UNTIL i = size DO repeatCount: INT ~ GetInt[GetByte]; propsCount: INT ~ GetInt[GetByte]; head, tail: Prop.PropList ฌ NIL; THROUGH [0..propsCount) DO atom: ATOM ~ Atom.MakeAtom[GetRope[]]; valueSpecs: ROPE ~ GetRope[]; value: REF ~ DoSpecs[atom, valueSpecs]; new: Prop.PropList ~ CONS[[key: atom, val: value], NIL]; IF head=NIL THEN head ฌ new ELSE tail.rest ฌ new; tail ฌ new; ENDLOOP; q[head, repeatCount]; ENDLOOP; }; RETURN [Rosary.FromRuns[p]]; }; WriteCharProps: PROC [name: ATOM, value: REF] RETURNS [specs: ROPE ฌ NIL] ~ { curRope: ROPE ฌ NIL; Grab: PROC RETURNS [rope: ROPE] ~ {rope ฌ curRope; curRope ฌ NIL}; PutByte: PROC [b: BYTE] ~ {curRope ฌ Rope.Concat[curRope, Rope.FromChar[VAL[b]]]}; PutRope: PROC [rope: ROPE] ~ {curRope ฌ Rope.Concat[curRope, rope]}; rept: INT ฌ 0; itemSpecs: ROPE ฌ NIL; FlushRun: PROC ~ {IF rept>0 THEN {PutInt[rept, PutByte]; PutRope[itemSpecs]; rept ฌ 0}}; PutItem: PROC [newItemSpecs: ROPE, repeat: INT] ~ { IF NOT Rope.Equal[newItemSpecs, itemSpecs] THEN FlushRun[]; itemSpecs ฌ newItemSpecs; rept ฌ rept + repeat; }; Action: PROC [item: REF, repeat: INT] RETURNS [quit: BOOL ฌ FALSE] ~ { save: ROPE ~ Grab[]; SpecsList: PROC [propList: Prop.PropList] RETURNS [s: LIST OF REF ฌ NIL] ~ { FOR p: Prop.PropList ฌ propList, p.rest UNTIL p = NIL DO atom: ATOM ~ NARROW[p.first.key]; v: ROPE ~ GetSpecs[atom, p.first.val]; IF v # NIL THEN { a: ROPE ~ Atom.GetPName[atom]; PutInt[Rope.Size[a], PutByte]; PutRope[a]; PutInt[Rope.Size[v], PutByte]; PutRope[v]; s ฌ CONS[Grab[], s]; }; ENDLOOP; }; specList: LIST OF REF ฌ List.Sort[SpecsList[NARROW[item]]]; newItemSpecs: ROPE; PutInt[List.Length[specList], PutByte]; UNTIL specList = NIL DO t: LIST OF REF ฌ specList; PutRope[NARROW[t.first]]; specList ฌ t.rest; t.rest ฌ NIL; ENDLOOP; newItemSpecs ฌ Grab[]; curRope ฌ save; PutItem[newItemSpecs, repeat]; }; [] ฌ Rosary.MapRuns[[NARROW[value]], Action]; FlushRun[]; specs ฌ Grab[]; IF Rope.Size[specs] = 0 THEN specs ฌ NIL; }; emptyAtom: ATOM ~ Atom.MakeAtom[NIL]; AtomFromValue: PUBLIC PROC [value: REF] RETURNS [ATOM] ~ { WITH value SELECT FROM atom: ATOM => RETURN[atom]; ENDCASE => RETURN[NIL]; }; ValueFromAtom: PUBLIC PROC [atom: ATOM] RETURNS [REF] ~ { RETURN[IF atom=emptyAtom THEN NIL ELSE atom]; }; refBoolFromBool: ARRAY BOOL OF REF BOOL ~ [ FALSE: NEW[BOOL ฌ FALSE], TRUE: NEW[BOOL ฌ TRUE] ]; BoolFromValue: PUBLIC PROC [value: REF] RETURNS [BOOL] ~ { WITH value SELECT FROM refBool: REF BOOL => RETURN[refBoolญ]; ENDCASE => RETURN[FALSE]; }; ValueFromBool: PUBLIC PROC [bool: BOOL] RETURNS [REF] ~ { RETURN[refBoolFromBool[bool]]; }; PutProp: PUBLIC PROC [n: Tioga.Node, name: ATOM, value: REF] ~ { SELECT name FROM nameFormat => n.format ฌ AtomFromValue[value]; nameComment => n.comment ฌ BoolFromValue[value]; nameCharSets, nameCharProps => ERROR; ENDCASE => { oldList: PropList ~ n.nodeProps; newList: PropList ~ Prop.Put[oldList, name, value]; IF newList#oldList THEN { hasProp: BOOL ~ (value#NIL); SELECT name FROM nameStyleDef => n.hasStyleDef ฌ hasProp; namePrefix => n.hasPrefix ฌ hasProp; namePostfix => n.hasPostfix ฌ hasProp; nameArtwork => n.hasArtwork ฌ hasProp; nameActive => n.hasActive ฌ hasProp; ENDCASE; n.nodeProps ฌ newList; }; }; }; GetProp: PUBLIC PROC [n: Tioga.Node, name: ATOM] RETURNS [value: REF] ~ { SELECT name FROM nameFormat => RETURN[ValueFromAtom[n.format]]; nameComment => RETURN[ValueFromBool[n.comment]]; ENDCASE => RETURN[Prop.Get[n.nodeProps, name]]; }; MapProps: PUBLIC PROC [n: Tioga.Node, action: MapPropsAction, formatFlag, commentFlag: BOOL ฌ TRUE] RETURNS [quit: BOOL] ~ { IF n#NIL THEN { IF formatFlag AND n.format#NIL THEN { IF action[nameFormat, ValueFromAtom[n.format]] THEN RETURN [TRUE]; }; IF commentFlag THEN { IF action[nameComment, ValueFromBool[n.comment]] THEN RETURN [TRUE]; }; { -- properties other than $Format and $Comment propAction: Prop.MapAction ~ { RETURN[action[NARROW[key], val]] }; RETURN[Prop.Map[n.nodeProps, propAction]]; }; }; RETURN [FALSE]; }; ReaderProcRef: TYPE = REF ReaderProcRec; ReaderProcRec: TYPE = RECORD [proc: ReadSpecsProc]; WriterProcRef: TYPE = REF WriterProcRec; WriterProcRec: TYPE = RECORD [proc: WriteSpecsProc]; CopierProcRef: TYPE = REF CopierProcRec; CopierProcRec: TYPE = RECORD [proc: CopyInfoProc]; readerTable: RefTab.Ref ฌ RefTab.Create[]; writerTable: RefTab.Ref ฌ RefTab.Create[]; copierTable: RefTab.Ref ฌ RefTab.Create[]; Register: PUBLIC PROC [name: ATOM, reader: ReadSpecsProc, writer: WriteSpecsProc, copier: CopyInfoProc] ~ { IF name=NIL THEN RETURN; [] ฌ RefTab.Store[readerTable, name, NEW[ReaderProcRec ฌ [reader]]]; [] ฌ RefTab.Store[writerTable, name, NEW[WriterProcRec ฌ [writer]]]; [] ฌ RefTab.Store[copierTable, name, NEW[CopierProcRec ฌ [copier]]] }; NullRead: PUBLIC PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] ~ { RETURN [NIL] }; NullWrite: PUBLIC PROC [name: ATOM, value: REF] RETURNS [specs: ROPE] ~ { RETURN [NIL] }; NullCopy: PUBLIC PROC [name: ATOM, value: REF] RETURNS [new: REF] ~ { RETURN [NIL] }; RefCopy: PUBLIC PROC [name: ATOM, value: REF] RETURNS [new: REF] ~ { RETURN [value] }; DoSpecs: PUBLIC PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] ~ { procRef: ReaderProcRef; proc: ReadSpecsProc; value ฌ ( IF name=NIL OR (procRef ฌ NARROW[RefTab.Fetch[readerTable, name].val])=NIL OR (proc ฌ procRef.proc)=NIL THEN specs ELSE proc[name,specs] ); }; GetSpecs: PUBLIC PROC [name: ATOM, value: REF] RETURNS [specs: ROPE] ~ { procRef: WriterProcRef; proc: WriteSpecsProc; IF name=NIL OR (procRef ฌ NARROW[RefTab.Fetch[writerTable, name].val])=NIL OR (proc ฌ procRef.proc)=NIL THEN { IF value=NIL THEN specs ฌ NIL ELSE { WITH value SELECT FROM rope: ROPE => specs ฌ rope; ENDCASE => specs ฌ NIL; }; } ELSE specs ฌ proc[name, value]; }; CopyInfo: PUBLIC PROC [name: ATOM, value: REF] RETURNS [new: REF] ~ { procRef: CopierProcRef; proc: CopyInfoProc; new ฌ IF name=NIL OR (procRef ฌ NARROW[RefTab.Fetch[copierTable, name].val])=NIL OR (proc ฌ procRef.proc)=NIL THEN value ELSE proc[name, value] }; attributeTable: LIST OF LIST OF ATOM ฌ NIL; DeclarePropertyAttribute: PUBLIC ENTRY PROC [name: ATOM, attribute: ATOM] ~ { FOR a: LIST OF LIST OF ATOM ฌ attributeTable, a.rest UNTIL a=NIL DO IF a.first.first = name THEN { FOR p: LIST OF ATOM ฌ a.first.rest, p.rest UNTIL p=NIL DO IF p.first = attribute THEN RETURN; ENDLOOP; a.first.rest ฌ CONS[attribute, a.first.rest]; RETURN; }; ENDLOOP; attributeTable ฌ CONS[LIST[name, attribute], attributeTable]; }; Is: PUBLIC ENTRY PROC [name: ATOM, attribute: ATOM] RETURNS [BOOL] ~ { FOR a: LIST OF LIST OF ATOM ฌ attributeTable, a.rest UNTIL a=NIL DO IF a.first.first = name THEN { FOR p: LIST OF ATOM ฌ a.first.rest, p.rest UNTIL p=NIL DO IF p.first = attribute THEN RETURN [TRUE]; ENDLOOP; RETURN [FALSE]; }; ENDLOOP; RETURN [FALSE]; }; GetPropertyAttributes: PUBLIC ENTRY PROC [name: ATOM] RETURNS [LIST OF ATOM] ~ { FOR a: LIST OF LIST OF ATOM ฌ attributeTable, a.rest UNTIL a=NIL DO IF a.first.first = name THEN RETURN [a.first.rest]; ENDLOOP; RETURN [NIL]; }; SetPropertyAttributes: PUBLIC ENTRY PROC [name: ATOM, attributes: LIST OF ATOM] ~ { FOR a: LIST OF LIST OF ATOM ฌ attributeTable, a.rest UNTIL a=NIL DO IF a.first.first = name THEN {a.first.rest ฌ attributes; RETURN}; ENDLOOP; attributeTable ฌ CONS[CONS[name, attributes], attributeTable]; }; Init: PROC ~ { visible: LIST OF ATOM ~ LIST[$Visible]; visAndInherit: LIST OF ATOM ~ CONS[$Inheritable, visible]; visAndClient: LIST OF ATOM ~ CONS[$ClientOnly, visible]; Register[namePrefix, ReadPfix, WritePfix, RefCopy]; SetPropertyAttributes[namePrefix, visAndInherit]; Register[namePostfix, ReadPfix, WritePfix, RefCopy]; SetPropertyAttributes[namePostfix, visAndInherit]; Register[nameFormat, ReadFormat, WriteFormat, RefCopy]; SetPropertyAttributes[nameFormat, visAndInherit]; Register[nameComment, ReadComment, WriteComment, RefCopy]; SetPropertyAttributes[nameComment, visAndInherit]; Register[nameCharSets, ReadCharSets, WriteCharSets, RefCopy]; SetPropertyAttributes[nameCharSets, visAndClient]; Register[nameCharProps, ReadCharProps, WriteCharProps, RefCopy]; SetPropertyAttributes[nameCharProps, visAndClient]; SetPropertyAttributes[nameStyleDef, visAndInherit]; SetPropertyAttributes[nameArtwork, visible]; SetPropertyAttributes[$NewlineDelimiter, visible]; SetPropertyAttributes[$FileExtension, visible]; SetPropertyAttributes[$Interpress, CONS[$ClientOnly, visible]]; SetPropertyAttributes[$Bounds, visible]; }; Init[]; END. ฎ NodePropsImpl.mesa Copyright ำ 1985, 1986, 1987, 1988, 1990, 1991, 1992, 1993 by Xerox Corporation. All rights reserved. written by Paxton. January 1981 Michael Plass, September 27, 1991 1:52 pm PDT Rick Beach, March 28, 1985 9:57:47 am PST Russ Atkinson (RRA) August 19, 1985 4:17:41 pm PDT Spreitze, July 9, 1990 4:56 pm PDT Doug Wyatt, February 9, 1993 1:42 pm PST NOTE: the variable-length integers in this encoding are stored high-order byte first, whereas variable-length integers elsewhere in Tioga files are stored low-order byte first! (DKW discovered this while porting Tioga to PCedar.) Raises a bounds fault if invalid specs are provided. Encoding is ()*, where is encoded with the variable-length integer encoding scheme described above, and is just encoded as a byte. Raises a bounds fault if invalid specs are provided. Encoding is (()*)*, where the counts and lengths are encoded with the variable-length integer encoding scheme described above. apply the action to each name & value pair for the node returns true if&when an action returns true Read, Write, Copy Props registers these procs for this variety of node they will be called by DoSpecs, GetSpecs, and CopyInfo used when reading files calls the registered reader for this property name returns specs if no reader is registered used when writing files calls the registered writer for this property name if no writer is registered, returns value if it is a rope, NIL otherwise used when copying nodes calls the registered copier for this property name if no copier is registered, returns value Property Attributes Property Attribute Documentation $Visible says whether property affects appearance $Inheritable says whether property may be inherited when a new node is inserted $ClientOnly asserts EditTool interface should not change the value Initialization สณ–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ฯeœ[™fKšœ ™ Kšœ-™-K™)K™2K™"K™(K™—šฯk ˜ Kšœžœ˜ Kšœžœ˜Kšœžœ˜Kšœ žœ?˜NKšœžœ&˜0Kšœžœ˜)Kšœžœ8žœ˜VKšœžœžœ˜)Kšœ žœ˜!Kšœžœ˜—K˜Kšฯn œžœž˜Kšžœ9˜@Kšžœ ˜šœž˜K˜Kšžœžœ žœ˜Kšžœžœžœ˜Kšœ žœ˜Kšœ žœ˜K˜Kšœžœ˜,Kšœžœ˜0Kšœžœ˜.šœžœ˜0K˜—Kšœ žœžœ ˜"Kšœ žœžœ ˜$Kšœžœžœ ˜&Kšœžœžœ˜(Kšœžœžœ ˜&Kšœ žœžœ ˜"Kšœ žœžœ ˜$Kšœ žœžœ ˜$šœ žœžœ ˜"K˜—š Ÿ œžœžœ žœžœ žœ˜DKšžœ*žœ˜9K˜—K˜š Ÿ œžœžœ žœžœ žœ˜EKšœ žœ˜%Kšœžœ žœžœ ˜,K˜—K˜šŸ œžœžœ žœžœ žœžœ˜IKšžœžœžœ˜=K˜—K˜šŸ œžœžœ žœžœ žœžœ˜Jšžœžœž˜Kšœžœžœ˜2Kšžœžœ žœžœ ˜*—K˜K˜—š Ÿœžœžœ žœžœ žœ˜AKšžœ ˜K˜—K˜šŸ œžœžœ žœžœ žœžœ˜Hšžœžœž˜Kšœžœ˜Kšžœ˜—K˜K˜—K˜š œ žœžœž œžœžœ˜FKšœๆ™ๆK˜—šŸœžœžœžœžœžœžœ ˜Bšžœžœ˜#K˜Kšžœžœ žœžœ˜Kšžœ˜—K˜K˜—šŸœžœžœžœžœ žœžœ˜AKšœ'žœ˜0Kšžœ žœžœ˜,Kšœžœ˜K˜K˜—K˜š Ÿ œžœžœ žœžœ žœ˜EKšœ4™4Kšœฐ™ฐš œžœžœžœžœ˜ Kšœžœ˜Kšœžœ˜ Kš Ÿœžœžœžœ žœ#˜Mšžœ ž˜Kšœžœ˜Kšœ žœ ˜K˜-Kšžœ˜—K˜—Kšžœ˜K˜—K˜šŸ œžœžœ žœžœ žœžœ˜LKš œžœžœžœžœ˜KšŸœžœI˜SšŸœžœžœ˜Kšžœžœ˜,Kšœžœ˜K˜K˜—Kšœ˜Kšœžœ˜KšŸœžœžœžœ8˜XšŸœžœžœ žœžœžœžœ˜Fšœžœžœž˜$Kšœžœ˜Kšžœ˜ —Kšžœ žœ žœ ˜,K˜K˜K˜—Kšœžœ˜-K˜ K˜Kšžœžœ žœ˜)K˜—K˜š Ÿ œžœžœ žœžœ žœ˜FšœA™AKšœJ™J—Kšœj™jš œžœžœžœžœ˜ Kšœžœ˜ Kšœžœ˜Kš Ÿœžœžœžœ žœ#˜Mš Ÿœžœžœžœžœ˜,Kšœžœ˜Kšœ"˜"K˜ Kšœ ˜ K˜—šžœ ž˜Kšœ žœ˜#Kšœ žœ˜"Kšœžœ˜ šžœž˜Kšœžœ˜&Kšœ žœ ˜Kšœžœ˜'Kšœžœžœ˜8Kšžœžœžœ žœ˜1K˜ Kšžœ˜—Kšœ˜Kšžœ˜—K˜—Kšžœ˜K˜K˜—šŸœžœžœ žœžœ žœžœ˜MKšœ žœžœ˜Kš Ÿœžœžœžœžœ˜BKšŸœžœžœ2žœ˜RKšŸœžœžœ+˜DKšœžœ˜Kšœ žœžœ˜KšŸœžœžœžœ8˜XšŸœžœžœ žœ˜3Kšžœžœ%žœ ˜;Kšœ˜Kšœ˜Kšœ˜—šŸœžœžœ žœžœžœžœ˜FKšœžœ ˜šŸ œžœžœžœžœžœžœ˜Lšžœ%žœžœž˜8Kšœžœžœ˜!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˜K˜—šœ žœžœ˜%K˜—š Ÿ œžœžœ žœžœžœ˜:šžœžœž˜Kšœžœžœ˜Kšžœžœžœ˜—Kšœ˜K˜—š Ÿ œžœžœžœžœžœ˜9Kš žœžœžœžœžœ˜-Kšœ˜K˜—š œžœžœžœžœžœ˜+Kšžœžœžœžœžœžœžœžœ˜0Kšœ˜K˜—š Ÿ œžœžœ žœžœžœ˜:šžœžœž˜Kšœ žœžœžœ ˜&Kšžœžœžœ˜—Kšœ˜K˜—š Ÿ œžœžœžœžœžœ˜9Kšžœ˜Kšœ˜K˜—š Ÿœžœžœžœ žœ˜@šžœž˜K˜.K˜0Kšœžœ˜%šžœ˜ K˜ K˜3šžœžœ˜Kšœ žœ žœ˜šžœž˜Kšœ(˜(Kšœ$˜$Kšœ&˜&Kšœ&˜&Kšœ$˜$Kšžœ˜—K˜K˜—K˜——K˜K™—š Ÿœžœžœžœžœ žœ˜Išžœž˜Kšœžœ˜.Kšœžœ˜0Kšžœžœ˜/—K˜K™—šŸœžœžœBžœžœžœžœ˜|Kšœ7™7Kšœ+™+šžœžœžœ˜šžœ žœ žœžœ˜%Kšžœ-žœžœžœ˜BK˜—šžœ žœ˜Kšžœ/žœžœžœ˜DK˜—šœฯc-˜/Kšœžœžœ˜BKšžœ$˜*K˜—Kšœ˜—Kšžœžœ˜K˜K˜——headšœ™Kšœžœžœ˜(Kšœžœžœ˜3Kšœžœžœ˜(Kšœžœžœ˜4Kšœžœžœ˜(Kšœžœžœ˜2K˜*K˜*˜*K˜—šŸœžœžœžœJ˜kKšœ.™.Kšœ7™7Kšžœžœžœžœ˜Kšœ$žœ˜DKšœ$žœ˜DKšœ$žœ˜DK˜—K˜šŸœžœžœžœ žœžœ žœ˜HKšžœžœ˜ K˜—K˜šŸ œžœžœžœ žœžœ žœ˜IKšžœžœ˜ K˜—K˜šŸœžœžœžœ žœžœžœ˜EKšžœžœ˜ K˜—K˜šŸœžœžœžœ žœžœžœ˜DKšžœ ˜K˜—K˜šŸœžœžœžœ žœžœ žœ˜GKšœ™Kšœ2™2Kšœ(™(K˜K˜šœ ˜ Kšžœž˜ Kšžœ žœ'ž˜>Kšžœž˜Kšžœ˜ Kšžœ˜Kšœ˜—K˜—K˜šŸœžœžœžœ žœžœ žœ˜HKšœ™Kšœ2™2KšœH™HK˜K˜Kšžœž˜ Kšžœ žœ'ž˜>Kšžœž˜šžœ˜Kšžœžœžœ ž˜šžœ˜šžœžœž˜Kšœžœ˜Kšžœ žœ˜—Kšœ˜—Kšœ˜—Kšžœ˜K˜—K˜šŸœžœžœžœ žœžœžœ˜EKšœ™Kšœ2™2Kšœ)™)K˜K˜Kšœžœžœžœ žœ'žœžœžœžœ˜K˜——™K˜Kš œžœžœžœžœžœžœ˜+š Ÿœžœžœžœžœ žœ˜Mšžœžœžœžœžœžœžœžœž˜Cšžœžœ˜š žœžœžœžœžœžœž˜9Kšžœžœžœ˜#Kšžœ˜—Kšœžœ˜-Kšžœ˜Kšœ˜—Kšžœ˜—Kšœžœžœ#˜=Kšœ˜K˜—šŸœžœžœžœžœ žœžœžœ˜Fšžœžœžœžœžœžœžœžœž˜Cšžœžœ˜š žœžœžœžœžœžœž˜9Kšžœžœžœžœ˜*Kšžœ˜—Kšžœžœ˜Kšœ˜—Kšžœ˜—Kšžœžœ˜Kšœ˜K˜—šŸœžœžœžœžœžœžœžœžœ˜Pšžœžœžœžœžœžœžœžœž˜CKšžœžœžœ˜3Kšžœ˜—Kšžœžœ˜ Kšœ˜K˜—šŸœžœžœžœžœžœžœžœ˜Sšžœžœžœžœžœžœžœžœž˜CKšžœžœžœ˜AKšžœ˜—Kšœžœžœ$˜>Kšœ˜—K˜—™ K™4KšœO™OKšœB™B—šœ™šŸœžœ˜Kš œ žœžœžœžœ ˜'Kš œžœžœžœžœ˜:š œžœžœžœžœ˜8K˜—šœ3˜3Kšœ1˜1K˜—šœ4˜4Kšœ2˜2K˜—šœ7˜7Kšœ1˜1K˜—šœ:˜:Kšœ2˜2K˜—šœ=˜=Kšœ2˜2K˜—šœ@˜@Kšœ3˜3K˜—Kšœ3˜3Kšœ,˜,Kšฯz2˜2Kšก/˜/Kšœ#žœ˜?Kšœ(˜(Kšœ˜K˜—K˜—K˜Kšžœ˜K˜—…—0๐MQ