DIRECTORY Atom USING [DottedPairNode, GetPName, MakeAtom, PropList], Basics USING [BoundsCheckHighHalf, DoubleShiftLeft, NonNegative], IO USING [atom, int, PutFR], List USING [Length, Sort], MessageWindow USING [Append, Blink], RefTab USING [Create, Fetch, Ref, Store], Rope USING [Concat, Equal, Fetch, FromChar, FromRefText, IsEmpty, ROPE, Size, Substr], Rosary USING [FromProcProc, MapRuns, ROSARY, Size], Tioga USING [MapPropsAction, Node, PropCopier, PropReader, Props, PropsBody, PropWriter]; NodePropsImpl: CEDAR MONITOR IMPORTS Atom, Basics, IO, List, MessageWindow, RefTab, Rope, Rosary EXPORTS Tioga ~ BEGIN ROSARY: TYPE = Rosary.ROSARY; ROPE: TYPE = Rope.ROPE; Node: TYPE = Tioga.Node; Prop, Props: TYPE = Tioga.Props; PropsBody: TYPE = Tioga.PropsBody; MapPropsAction: TYPE = Tioga.MapPropsAction; PropReader: TYPE = Tioga.PropReader; PropWriter: TYPE = Tioga.PropWriter; PropCopier: TYPE = Tioga.PropCopier; commentAtom: ATOM = $Comment; formatAtom: ATOM = $Format; styleDefAtom: ATOM = $StyleDef; prefixAtom: ATOM = $Prefix; postfixAtom: ATOM = $Postfix; charpropsAtom: ATOM = $CharProps; charsetsAtom: ATOM = $CharSets; artworkAtom: ATOM = $Artwork; refBool: ARRAY BOOL OF REF BOOL _ [FALSE: NEW[BOOL _ FALSE], TRUE: NEW[BOOL _ TRUE]]; RefBool: PUBLIC PROC [b: BOOL] RETURNS [REF BOOL] ~ { RETURN[refBool[b]] }; ReadComment: PropReader ~ { comment: BOOL ~ Rope.Equal[specs, "TRUE", FALSE]; RETURN [refBool[comment]]; }; WriteComment: PropWriter ~ { comment: BOOL _ FALSE; WITH value SELECT FROM x: REF BOOL => comment _ x^; ENDCASE => NULL; RETURN [IF comment THEN "TRUE" ELSE "FALSE"]; }; ReadFormat: PropReader ~ { RETURN[IF Rope.IsEmpty[specs] THEN NIL ELSE Atom.MakeAtom[specs]]; }; WriteFormat: PropWriter ~ { IF value=NIL THEN RETURN[""]; WITH value SELECT FROM atom: ATOM => RETURN[Atom.GetPName[atom]]; ENDCASE => RETURN[NIL]; }; ReadCharSets: PropReader ~ { p: PROC [q: PROC [REF, INT]] ~ { i: INT _ 0; size: INT _ Rope.Size[specs]; GetByte: PROC RETURNS [b: [0..256)] ~ {b _ Rope.Fetch[specs, i]-'\000; i _ i + 1}; Combine: PROC [a: INT, b: [0..128)] RETURNS [INT] ~ { bnd: NAT ~ LAST[NAT]/128+1; RETURN [Basics.DoubleShiftLeft[[li[Basics.BoundsCheckHighHalf[a, bnd]]], 7].li + b]; }; GetInt: PROC RETURNS [int: INT _ 0] ~ { b: [0..256) _ GetByte[]; WHILE b > 127 DO int _ Combine[int, b-128]; b _ GetByte[]; ENDLOOP; int _ Combine[int, b]; }; UNTIL i = size DO repeat: INT ~ GetInt[]; charSet: [0..256) ~ GetByte[]; IF charSet=0 THEN q[NIL, repeat] ELSE q[NEW[[0..256) _ charSet], repeat]; ENDLOOP; }; RETURN [Rosary.FromProcProc[p]]; }; WriteCharSets: PropWriter ~ { text: REF TEXT ~ NEW[TEXT[48]]; Fold: PROC ~ {specs _ Rope.Concat[specs, Rope.FromRefText[text]]; text.length _ 0}; PutByte: PROC [b: [0..256)] ~ { IF text.length = text.maxLength THEN Fold[]; text[text.length] _ VAL[b]; text.length _ text.length + 1; }; PutInt: PROC [int: INT, more: BOOLEAN _ FALSE] ~ { IF int > 127 THEN {PutInt[int/128, TRUE]; int _ int MOD 128}; IF more THEN int _ int + 128; PutByte[int]; }; charSet: [0..256) _ 0; charSetRepeat: INT _ 0; FlushRun: PROC ~ { IF charSetRepeat > 0 THEN {PutInt[charSetRepeat]; PutByte[charSet]; charSetRepeat _ 0}; }; Action: PROC [item: REF, repeat: INT] RETURNS [quit: BOOL _ FALSE] ~ { new: [0..256) _ WITH item SELECT FROM r: REF [0..256) => r^, ENDCASE => 0; IF charSetRepeat > 0 AND new#charSet THEN FlushRun[]; charSet _ new; charSetRepeat _ charSetRepeat + repeat; }; specs _ NIL; [] _ Rosary.MapRuns[[NARROW[value]], Action]; FlushRun[]; Fold[]; IF specs#NIL AND Rope.Size[specs]=0 THEN specs _ NIL; }; ReadCharProps: PropReader ~ { p: PROC [q: PROC [REF, INT]] ~ { i: INT _ 0; size: INT _ Rope.Size[specs]; GetByte: PROC RETURNS [b: [0..256)] ~ {b _ Rope.Fetch[specs, i]-'\000; i _ i + 1}; Combine: PROC [a: INT, b: [0..128)] RETURNS [INT] ~ { bnd: NAT ~ LAST[NAT]/128+1; RETURN [Basics.DoubleShiftLeft[[li[Basics.BoundsCheckHighHalf[a, bnd]]], 7].li + b]; }; GetInt: PROC RETURNS [int: INT _ 0] ~ { b: [0..256) _ GetByte[]; WHILE b > 127 DO int _ Combine[int, b-128]; b _ GetByte[]; ENDLOOP; int _ Combine[int, b]; }; GetRope: PROC RETURNS [rope: ROPE _ NIL] ~ { len: INT ~ GetInt[]; rope _ Rope.Substr[specs, i, len]; i _ i + len; [] _ Basics.NonNegative[size-i]; }; UNTIL i = size DO repeatCount: INT ~ GetInt[]; propsCount: INT ~ GetInt[]; propList: Atom.PropList _ NIL; THROUGH [0..propsCount) DO atom: ATOM ~ Atom.MakeAtom[GetRope[]]; valueSpecs: ROPE ~ GetRope[]; value: REF ~ ReadProp[atom, valueSpecs]; propList _ CONS[NEW[Atom.DottedPairNode _ [key: atom, val: value]], propList]; ENDLOOP; q[propList, repeatCount]; ENDLOOP; }; RETURN [Rosary.FromProcProc[p]]; }; WriteCharProps: PropWriter ~ { curRope: ROPE _ NIL; Grab: PROC RETURNS [rope: ROPE] ~ {rope _ curRope; curRope _ NIL}; PutByte: PROC [b: [0..256)] ~ {curRope _ Rope.Concat[curRope, Rope.FromChar[VAL[b]]]}; PutRope: PROC [rope: ROPE] ~ {curRope _ Rope.Concat[curRope, rope]}; PutInt: PROC [int: INT, more: BOOLEAN _ FALSE] ~ { IF int > 127 THEN {PutInt[int/128, TRUE]; int _ int MOD 128}; IF more THEN int _ int + 128; PutByte[int]; }; rept: INT _ 0; itemSpecs: ROPE _ NIL; FlushRun: PROC ~ { IF rept > 0 THEN {PutInt[rept]; 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: Atom.PropList] RETURNS [s: LIST OF REF _ NIL] ~ { FOR p: Atom.PropList _ propList, p.rest UNTIL p = NIL DO atom: ATOM ~ NARROW[p.first.key]; v: ROPE ~ WriteProp[atom, p.first.val]; IF v # NIL THEN { a: ROPE ~ Atom.GetPName[atom]; PutInt[Rope.Size[a]]; PutRope[a]; PutInt[Rope.Size[v]]; PutRope[v]; s _ CONS[Grab[], s]; }; ENDLOOP; }; specList: LIST OF REF _ List.Sort[SpecsList[NARROW[item]]]; newItemSpecs: ROPE; PutInt[List.Length[specList]]; 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 specs#NIL AND Rope.Size[specs]=0 THEN specs _ NIL; }; FindName: PROC [n: Node, name: ATOM, remove: BOOL] RETURNS [prop: Prop] ~ { lst, prev: Props; IF n=NIL THEN RETURN [NIL]; lst _ n.props; prop _ NIL; prev _ NIL; WHILE lst#NIL DO IF lst.name = name THEN { prop _ lst; EXIT }; prev _ lst; lst _ lst.next; ENDLOOP; IF prop#NIL AND remove THEN { IF prev#NIL THEN prev.next _ prop.next ELSE n.props _ prop.next; }; }; PutProp: PUBLIC PROC [n: Node, name: ATOM, value: REF] ~ { prop: Prop _ FindName[n, name, FALSE]; IF name = charpropsAtom OR name = charsetsAtom THEN { value _ CheckRosarySize[NARROW[value], n, name]; }; IF value = NIL THEN { IF prop#NIL THEN prop.value _ NIL; SELECT name FROM styleDefAtom => n.hasstyledef _ FALSE; prefixAtom => n.hasprefix _ FALSE; postfixAtom => n.haspostfix _ FALSE; formatAtom => n.formatName _ NIL; commentAtom => n.comment _ FALSE; charpropsAtom => n.hascharprops _ FALSE; charsetsAtom => n.hascharsets _ FALSE; artworkAtom => n.hasartwork _ FALSE; ENDCASE; RETURN }; SELECT name FROM styleDefAtom => n.hasstyledef _ TRUE; prefixAtom => n.hasprefix _ TRUE; postfixAtom => n.haspostfix _ TRUE; formatAtom => { n.formatName _ NARROW[value]; RETURN; }; commentAtom => { -- simply set the bit in the node n.comment _ NARROW[value, REF BOOL]^; RETURN; }; charpropsAtom => n.hascharprops _ TRUE; charsetsAtom => n.hascharsets _ TRUE; artworkAtom => n.hasartwork _ TRUE; ENDCASE; IF prop#NIL THEN prop.value _ value ELSE n.props _ NEW[PropsBody _ [name: name, value: value, next: n.props]]; }; CheckRosarySize: PROC [rosary: ROSARY, n: Node, what: ATOM] RETURNS [ROSARY] ~ { IF rosary # NIL THEN { rosarySize: INT ~ Rosary.Size[rosary]; ropeSize: INT ~ Rope.Size[n.rope]; IF rosarySize # ropeSize THEN { msg: ROPE ~ IO.PutFR["NodePropsImpl: %g property discarded because its size (%g) differed from rope size (%g).", IO.atom[what], IO.int[rosarySize], IO.int[ropeSize]]; MessageWindow.Append[msg, TRUE]; MessageWindow.Blink[]; RETURN [NIL]; }; }; RETURN [rosary]; }; GetProp: PUBLIC PROC [node: Node, name: ATOM] RETURNS [value: REF _ NIL] ~ { IF node#NIL THEN { prop: Prop ~ FindName[node, name, FALSE]; IF prop#NIL THEN value _ prop.value ELSE SELECT name FROM commentAtom => value _ refBool[node.comment]; formatAtom => IF node.formatName#NIL THEN value _ node.formatName; ENDCASE; }; }; RemProp: PUBLIC PROC [n: Node, name: ATOM] ~ { [] _ FindName[n, name, TRUE]; -- removes the value SELECT name FROM styleDefAtom => n.hasstyledef _ FALSE; prefixAtom => n.hasprefix _ FALSE; postfixAtom => n.haspostfix _ FALSE; formatAtom => n.formatName _ NIL; commentAtom => n.comment _ FALSE; charpropsAtom => n.hascharprops _ FALSE; charsetsAtom => n.hascharsets _ FALSE; artworkAtom => n.hasartwork _ FALSE; ENDCASE; }; MapProps: PUBLIC PROC [node: Node, action: MapPropsAction, formatFlag, commentFlag: BOOL _ TRUE] RETURNS [quit: BOOL] ~ { IF node#NIL THEN { props: Props _ node.props; IF formatFlag AND node.formatName#NIL AND action[formatAtom, node.formatName] THEN RETURN [TRUE]; IF commentFlag AND action[commentAtom, refBool[node.comment]] THEN RETURN [TRUE]; UNTIL props=NIL DO next: Props ~ props.next; -- get it now in case action deletes current prop IF props.value#NIL AND action[props.name, props.value] THEN RETURN [TRUE]; props _ next; ENDLOOP; }; RETURN [FALSE] }; PropProcs: TYPE ~ REF PropProcsRep; PropProcsRep: TYPE ~ RECORD [reader: PropReader, writer: PropWriter, copier: PropCopier]; propProcsTable: RefTab.Ref _ RefTab.Create[]; RegisterProp: PUBLIC PROC [name: ATOM, reader: PropReader, writer: PropWriter, copier: PropCopier] ~ { IF name#NIL THEN { procs: PropProcs ~ NEW[PropProcsRep _ [reader: reader, writer: writer, copier: copier]]; [] _ RefTab.Store[propProcsTable, name, procs]; }; }; NullRead: PUBLIC PropReader ~ { RETURN [NIL] }; NullWrite: PUBLIC PropWriter ~ { RETURN [NIL] }; NullCopy: PUBLIC PropCopier ~ { RETURN [NIL] }; ReadProp: PUBLIC PropReader ~ { reader: PropReader _ NIL; WITH RefTab.Fetch[propProcsTable, name].val SELECT FROM procs: PropProcs => reader _ procs.reader; ENDCASE; IF reader#NIL THEN RETURN[reader[name, specs]] ELSE RETURN[specs]; }; WriteProp: PUBLIC PropWriter ~ { writer: PropWriter _ NIL; WITH RefTab.Fetch[propProcsTable, name].val SELECT FROM procs: PropProcs => writer _ procs.writer; ENDCASE; IF writer#NIL THEN RETURN[writer[name, value]] ELSE WITH value SELECT FROM rope: ROPE => RETURN[rope]; ENDCASE => RETURN[NIL]; }; CopyProp: PUBLIC PropCopier ~ { copier: PropCopier _ NIL; WITH RefTab.Fetch[propProcsTable, name].val SELECT FROM procs: PropProcs => copier _ procs.copier; ENDCASE; IF copier#NIL THEN RETURN[copier[name, value]] ELSE RETURN[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]; RegisterProp[formatAtom, ReadFormat, WriteFormat, NIL]; SetPropertyAttributes[formatAtom, visAndInherit]; RegisterProp[commentAtom, ReadComment, WriteComment, NIL]; SetPropertyAttributes[commentAtom, visAndInherit]; RegisterProp[$CharSets, ReadCharSets, WriteCharSets, NIL]; SetPropertyAttributes[$CharSets, visAndClient]; RegisterProp[$CharProps, ReadCharProps, WriteCharProps, NIL]; SetPropertyAttributes[$CharProps, visAndClient]; SetPropertyAttributes[prefixAtom, visAndInherit]; SetPropertyAttributes[postfixAtom, visAndInherit]; SetPropertyAttributes[$StyleDef, visAndInherit]; SetPropertyAttributes[$Artwork, visible]; SetPropertyAttributes[$Interpress, visible]; SetPropertyAttributes[$Bounds, visible]; }; Init[]; END. ˆNodePropsImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. written by Paxton. January 1981 Michael Plass, May 28, 1986 3:38:28 pm PDT Rick Beach, March 28, 1985 9:57:47 am PST Russ Atkinson (RRA) August 19, 1985 4:17:41 pm PDT Doug Wyatt, September 12, 1986 7:08:21 pm PDT Raises a bounds fault if invalid specs are provided. Encoding is ()*, where is encoded with the variable-length integer encoding scheme described in FileOps, 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 in FileOps. 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 Κ ˜codešœ™Kšœ Οmœ7™BKšœ ™ Kšœ*™*K™)K™2Kšœ-™-K™—šΟk ˜ Kšœžœ0˜:Kšœžœ5˜AKšžœžœ˜Kšœžœ˜Kšœžœ˜$Kšœžœ˜)Kšœžœ8žœ˜VKšœžœžœ˜3JšœžœN˜Y—K˜KšΠbl œžœž˜Kšžœ<˜CKšžœ˜ šœž˜K˜Kšžœžœ žœ˜Kšžœžœžœ˜Kšœžœ˜Kšœ žœ˜ Kšœ žœ˜"K˜Kšœžœ˜,Kšœ žœ˜$Kšœ žœ˜$Kšœ žœ˜$K˜Kšœ žœ ˜Kšœ žœ ˜Kšœžœ ˜Kšœ žœ ˜Kšœ žœ ˜Kšœžœ˜!Kšœžœ ˜Kšœ žœ ˜K˜Kšœ žœžœžœžœžœžœžœžœžœžœžœžœžœ˜UKšΟnœžœžœžœžœžœžœžœ˜KK˜š  œ˜Kšœ žœžœ˜1Kšžœ˜K˜K˜—š  œ˜Kšœ žœžœ˜šžœžœž˜Kšœžœžœ˜Kšžœžœ˜—Kšžœžœ žœžœ ˜-K˜K˜—K˜š  œ˜Kš žœžœžœžœžœ˜BK˜K˜—š  œ˜Kšžœžœžœžœ˜šžœžœž˜Kšœžœžœ˜*Kšžœžœžœ˜—K˜K˜—K˜š  œ˜Kšœ4™4Kšœ΅™΅š œžœžœžœžœ˜ Kšœžœ˜ Kšœžœ˜Kš œžœžœ=˜Rš  œžœžœžœžœ˜5Kšœžœžœžœ˜KšžœN˜TK˜—š œžœžœžœ ˜'K˜šžœ ž˜K˜K˜Kšžœ˜—K˜K˜—šžœ ž˜Kšœžœ ˜K˜Kš žœ žœžœ žœžœ˜IKšžœ˜—K˜—Kšžœ˜ K˜K˜—š  œ˜Kš œžœžœžœžœ˜Kš œžœI˜Sš œžœ˜Kšžœžœ˜,Kšœžœ˜K˜K˜—š  œžœžœžœžœ˜2Kšžœ žœžœ žœ˜=Kšžœžœ˜K˜ K˜—K˜Kšœžœ˜š œžœ˜Kšžœžœ>˜WK˜—š œžœžœ žœžœžœžœ˜Fšœžœžœž˜%Kšœžœ˜Kšžœ˜ —Kšžœžœ žœ ˜5K˜K˜'K˜—Kšœžœ˜ Kšœžœ˜-K˜ K˜Kš žœžœžœžœ žœ˜5K˜K˜—K˜š  œ˜Kšœ4™4šœ ™ KšœJ™J—Kšœo™oš œžœžœžœžœ˜ Kšœžœ˜ Kšœžœ˜Kš œžœžœ=˜Rš  œžœžœžœžœ˜5Kšœžœžœžœ˜KšžœN˜TK˜—š œžœžœžœ ˜'K˜šžœ ž˜K˜K˜Kšžœ˜—K˜K˜—š  œžœžœžœžœ˜,Kšœžœ ˜Kšœ"˜"K˜ Kšœ ˜ K˜—šžœ ž˜Kšœ žœ ˜Kšœ žœ ˜Kšœžœ˜šžœž˜Kšœžœ˜&Kšœ žœ ˜Kšœžœ˜(Kšœ žœžœ;˜NKšžœ˜—Kšœ˜Kšžœ˜—K˜—Kšžœ˜ K˜K˜—š œ˜Kšœ žœžœ˜Kš  œžœžœžœžœ˜BKš œžœ?žœ˜VKš œžœžœ+˜Dš  œžœžœžœžœ˜2Kšžœ žœžœ žœ˜=Kšžœžœ˜K˜ K˜—Kšœžœ˜Kšœ žœžœ˜Kš œžœžœ žœ0˜Sš œžœžœ žœ˜3Kšžœžœ%žœ ˜;Kšœ˜Kšœ˜Kšœ˜—š œžœžœ žœžœžœžœ˜FKšœžœ ˜š  œžœžœžœžœžœžœ˜Lšžœ%žœžœž˜8Kšœžœžœ˜!Kšœžœ ˜'šžœžœžœ˜Kšœžœ˜KšœC˜CKšœžœ ˜Kšœ˜—Kšžœ˜—Kšœ˜—Kš œ žœžœžœžœ ˜;Kšœžœ˜Kšœ˜šžœ žœž˜Kšœžœžœžœ ˜Kšœžœ ˜Kšœ˜Kšœ žœ˜ Kšžœ˜—Kšœ˜Kšœ˜Kšœ˜K˜—Kšœžœ˜-K˜ Kšœ˜Kš žœžœžœžœ žœ˜5K˜K˜—K˜š  œžœžœ žœžœ˜KK˜Kš žœžœžœžœžœ˜K˜Kšœžœ žœ˜šžœžœž˜Kšžœžœžœ˜-K˜Kšžœ˜—šžœžœžœžœ˜Kšžœžœžœ˜&Kšžœ˜K˜—K˜—K˜š  œžœžœžœ žœ˜:Kšœžœ˜&šžœžœžœ˜5Kšœžœ˜0Kšœ˜—šžœ žœžœ˜Kšžœžœžœžœ˜"šžœž˜Kšœ žœ˜&Kšœžœ˜"Kšœžœ˜$Kšœžœ˜!Kšœžœ˜!Kšœ"žœ˜(Kšœ žœ˜&Kšœžœ˜$Kšžœ˜—Kšžœ˜K˜—šžœž˜Kšœ žœ˜%Kšœžœ˜!Kšœžœ˜#˜Kšœžœ˜Kšžœ˜K˜—šœΟc!˜2Kšœ žœžœžœ˜%Kšžœ˜K˜—Kšœ"žœ˜'Kšœ žœ˜%Kšœžœ˜#Kšžœ˜—Kšžœžœžœ˜#Kšžœ žœ8˜JK˜—K˜š  œžœ žœžœžœžœ˜Pšžœ žœžœ˜Kšœ žœ˜&Kšœ žœ˜"šžœžœ˜Kš œžœžœcžœ žœžœ˜¦Kšœžœ˜ Kšœ˜Kšžœžœ˜ Kšœ˜—Kšœ˜—Kšžœ ˜Kšœ˜K˜—š œžœžœžœžœ žœžœ˜Lšžœžœžœ˜Kšœ"žœ˜)Kšžœžœžœ˜#šžœžœž˜Kšœ-˜-Kšœžœžœžœ˜BKšžœ˜—K˜—K˜—K˜š œžœžœžœ˜.Kšœžœ‘˜2šžœž˜Kšœ žœ˜&Kšœžœ˜"Kšœžœ˜$Kšœžœ˜!Kšœžœ˜!Kšœ"žœ˜(Kšœ žœ˜&Kšœžœ˜$Kšžœ˜—K˜—K˜š œžœžœ?žœžœžœžœ˜yKšœ7™7Kšœ+™+šžœžœžœ˜Kšœ˜Kšžœ žœžœžœ%žœžœžœ˜aKš žœ žœ,žœžœžœ˜Qšžœžœž˜Kšœ‘1˜KKš žœ žœžœ!žœžœžœ˜JK˜ Kšžœ˜—Jšœ˜—Kšžœžœ˜K˜K˜——headšœ™Kšœ žœžœ˜#šœžœžœ>˜YK˜—˜-K˜—š  œžœžœžœA˜fKšœ.™.Kšœ7™7šžœžœžœ˜KšœžœB˜XKšœ/˜/K˜—K˜—K˜Kš œžœžœžœ˜/Kš  œžœžœžœ˜0Kš œžœžœžœ˜/K˜š œžœ˜Kšœ™Kšœ2™2Kšœ(™(Kšœžœ˜šžœ(žœž˜7Kšœ*˜*Kšžœ˜—Kšžœžœžœžœ˜.Kšžœžœ˜K˜K˜—š  œžœ˜ Kšœ™Kšœ2™2KšœH™HKšœžœ˜šžœ(žœž˜7Kšœ*˜*Kšžœ˜—Kšžœžœžœžœ˜.Kšžœžœžœžœžœžœžœžœžœ˜OK˜K˜—š œžœ˜Kšœ™Kšœ2™2Kšœ)™)Kšœžœ˜šžœ(žœž˜7Kšœ*˜*Kšžœ˜—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˜—šœ2žœ˜7Kšœ1˜1K˜—šœ5žœ˜:Kšœ2˜2K˜—šœ5žœ˜:Kšœ/˜/K˜—šœ8žœ˜=Kšœ0˜0K˜—Kšœ1˜1Kšœ2˜2Kšœ0˜0Kšœ)˜)Kšœ,˜,Kšœ(˜(Kšœ˜K˜—K˜—K˜Kšžœ˜K˜—…—3(NΊ