DIRECTORY Basics: TYPE USING [BITXOR, bytesPerWord, LongMult, LowHalf, RawBytes], BcdDefs: TYPE USING [Base, BcdBase, FTIndex, FTNull, FTRecord, --PageSize,-- SGIndex, VersionStamp], BcdLiterals: TYPE USING [], IO: TYPE USING [STREAM, UnsafePutBlock], PrincOpsUtils: TYPE USING [LongCopy], RCMapOps: TYPE USING [RCMT, MapMap, Create, Destroy, FindMapMapEntry, GetSpan, Include], RTBcd: TYPE USING [AnyStamp, RefLitIndex, RefLitItem, RefLitList, RTBase, RTHeader, StampIndex, StampList, TypeIndex, TypeItem, TypeList, UTInfo, VersionID], UnsafeStorage: TYPE USING [GetSystemUZone], VM: TYPE USING [AddressForPageNumber, Allocate, Free, Interval, nullInterval, wordsPerPage]; BcdLiteralsImpl: MONITOR IMPORTS Basics, IO, PrincOpsUtils, RCMapOps, UnsafeStorage, VM EXPORTS BcdLiterals = { OPEN BcdDefs; TypeMap: TYPE ~ RECORD[SEQUENCE length: NAT OF RTBcd.TypeIndex]; LitMap: TYPE ~ RECORD[SEQUENCE length: CARDINAL OF RTBcd.RefLitIndex]; Relation: TYPE ~ {ls, gr, eq}; Branch: TYPE ~ CARDINAL --[0..NAT.LAST+1]--; nullBranch: Branch ~ NAT.LAST+1; Nodes: TYPE ~ RECORD[SEQUENCE length: NAT OF RECORD [l, r: Branch]]; AdjustNodes: PROC[tree: REF Nodes, newLimit: NAT] RETURNS[newTree: REF Nodes] ~ { oldLimit: NAT ~ IF tree = NIL THEN 0 ELSE tree.length; newTree _ NEW[Nodes[newLimit]]; IF tree # NIL THEN { FOR i: NAT IN [0 .. MIN[oldLimit, newLimit]) DO newTree[i] _ tree[i] ENDLOOP; }; }; Scramble: PROC[n: CARDINAL] RETURNS[WORD] ~ INLINE { -- see Knuth, v 3, p. 509-511 RETURN[Basics.LowHalf[Basics.LongMult[n, 44451]]]}; HVIndex: TYPE ~ [0 .. 251); HTIndex: TYPE ~ CARDINAL; HTNull: HTIndex ~ HTIndex.LAST; HashNode: TYPE ~ RECORD [offset: CARDINAL, link: HTIndex]; HashSeq: TYPE ~ RECORD [SEQUENCE length: CARDINAL OF HashNode]; LiteralState: TYPE ~ REF LiteralStateInfo; LiteralStateInfo: PUBLIC TYPE~RECORD[ typeMap: REF TypeMap_NIL, litMap: REF LitMap_NIL, typeList: REF RTBcd.TypeList_NIL, nextType: NAT_0, typeTree: REF Nodes_NIL, litList: REF RTBcd.RefLitList_NIL, nextLit: NAT_0, litTree: REF Nodes_NIL, rcmt: RCMapOps.RCMT_NIL, textSpace: VM.Interval_VM.nullInterval, textBase: LONG POINTER_NIL, textOffset, textLimit: CARDINAL_0, textPages: CARDINAL_0, hashVec: REF ARRAY HVIndex OF HTIndex_NIL, ht: REF HashSeq_NIL, nextHti: HTIndex_0, stampList: REF RTBcd.StampList_NIL, nextStamp: NAT_1 ]; Copy: PROC[from: LONG POINTER, nwords: CARDINAL, to: LONG POINTER] ~ PrincOpsUtils.LongCopy; zone: UNCOUNTED ZONE = UnsafeStorage.GetSystemUZone[]; Load: PUBLIC PROC[ ls: LiteralState, bcdBase: BcdDefs.BcdBase, MapFile: PROC[FTIndex] RETURNS[FTIndex], MapSegment: PROC[SGIndex] RETURNS[SGIndex]] RETURNS[success: BOOL _ TRUE] ~ { IF bcdBase.rtPages.pages # 0 THEN { ftb: BcdDefs.Base ~ LOOPHOLE[bcdBase, BcdDefs.Base] + bcdBase.ftOffset; ftLimit: FTIndex ~ bcdBase.ftLimit; VersionToFile: PROC[i: RTBcd.StampIndex] RETURNS[fti: BcdDefs.FTIndex] ~ INLINE { FOR fti _ FTIndex.FIRST, fti + FTRecord.SIZE UNTIL fti = ftLimit DO IF ls.stampList[i] = ftb[fti].version THEN RETURN; ENDLOOP; RETURN[FTNull]}; rcmMap: RCMapOps.MapMap; MapTypeItem: PROC[old: RTBcd.TypeItem, name: LONG POINTER TO TEXT] RETURNS[RTBcd.TypeItem] ~ { stamp: RTBcd.StampIndex ~ IF old.ut.version = RTBcd.AnyStamp THEN RTBcd.AnyStamp ELSE EnterStamp[rtHeader[rtHeader.stampTable][old.ut.version]]; IF ~old.canonical AND stamp # RTBcd.AnyStamp THEN [] _ MapFile[VersionToFile[stamp]]; -- force file entry RETURN[[ table~MapSegment[old.table], sei~old.sei, canonical~old.canonical, ct~[EnterText[name]], ut~[version: stamp, sei: old.ut.sei], rcMap~rcmMap.FindMapMapEntry[old.rcMap]]]}; MapLitItem: PROC[old: RTBcd.RefLitItem, lit: LONG POINTER TO TEXT] RETURNS[RTBcd.RefLitItem] ~ { RETURN[[ referentType~MapType[ls, old.referentType], offset~EnterText[lit], length~old.length]]}; EnterType: PROC[item: RTBcd.TypeItem] RETURNS[index: RTBcd.TypeIndex] ~ { i: Branch _ 0; InsertType: PROC[item: RTBcd.TypeItem] RETURNS[index: Branch] ~ { IF ls.typeList = NIL OR ls.nextType >= ls.typeList.length THEN { oldLimit: NAT ~ IF ls.typeList = NIL THEN 0 ELSE ls.typeList.length; newLimit: NAT ~ oldLimit + MAX[MIN[oldLimit/2, 500], 50]; AdjustTypeList[ls, newLimit]; ls.typeTree _ AdjustNodes[ls.typeTree, newLimit]}; index _ ls.nextType; ls.nextType _ ls.nextType + 1; ls.typeList[index] _ item; ls.typeTree[index] _ [l~nullBranch, r~nullBranch]; RETURN}; IF ls.nextType = 0 THEN [] _ InsertType[item]; DO SELECT CompareTypes[item, ls.typeList[i]] FROM $ls => { IF ls.typeTree[i].l = nullBranch THEN ls.typeTree[i].l _ InsertType[item]; i _ ls.typeTree[i].l}; $gr => { IF ls.typeTree[i].r = nullBranch THEN ls.typeTree[i].r _ InsertType[item]; i _ ls.typeTree[i].r}; ENDCASE => RETURN[[i]] ENDLOOP}; EnterRefLit: PROC[item: RTBcd.RefLitItem] RETURNS[RTBcd.RefLitIndex] ~ { i: Branch _ 0; InsertRefLit: PROC[item: RTBcd.RefLitItem] RETURNS[index: Branch] ~ { IF ls.litList = NIL OR ls.nextLit >= ls.litList.length THEN { oldLimit: NAT ~ IF ls.litList = NIL THEN 0 ELSE ls.litList.length; newLimit: NAT ~ oldLimit + MAX[MIN[oldLimit/2, 500], 50]; AdjustLitList[ls, newLimit]; ls.litTree _ AdjustNodes[ls.litTree, newLimit]}; index _ ls.nextLit; ls.nextLit _ ls.nextLit + 1; ls.litList[index] _ item; ls.litTree[index] _ [l~nullBranch, r~nullBranch]; RETURN}; IF ls.nextLit = 0 THEN [] _ InsertRefLit[item]; DO SELECT CompareLits[item, ls.litList[i]] FROM $ls => { IF ls.litTree[i].l = nullBranch THEN ls.litTree[i].l _ InsertRefLit[item]; i _ ls.litTree[i].l}; $gr => { IF ls.litTree[i].r = nullBranch THEN ls.litTree[i].r _ InsertRefLit[item]; i _ ls.litTree[i].r}; ENDCASE => RETURN[[i]] ENDLOOP}; LitText: PROC[offset: CARDINAL] RETURNS[LONG POINTER TO TEXT] ~ INLINE { RETURN[ls.textBase + offset]}; EnterText: PROC[s: LONG POINTER TO TEXT] RETURNS[offset: CARDINAL] ~ { HashValue: PROC[s: LONG POINTER TO TEXT] RETURNS[HVIndex] ~ INLINE { n: CARDINAL ~ s.length; v: WORD ~ (IF n = 0 THEN 0 ELSE (s[0]-0c)*177b + (s[n-1]-0c)); RETURN[Basics.BITXOR[v, n*17b] MOD ls.hashVec^.LENGTH]}; hvi: HVIndex ~ HashValue[s]; hti: HTIndex; nw: CARDINAL; ExpandTextSpace: PROC ~ INLINE { newPages: CARDINAL ~ ls.textPages + MAX[MIN[ls.textPages/2, 16], 4]; newSpace: VM.Interval ~ VM.Allocate[count~newPages]; newBase: LONG POINTER ~ VM.AddressForPageNumber[newSpace.page]; IF ls.textSpace # VM.nullInterval THEN { Copy[from~ls.textBase, to~newBase, nwords~ls.textOffset]; VM.Free[ls.textSpace]}; ls.textSpace _ newSpace; ls.textBase _ newBase; ls.textPages _ newPages; ls.textLimit _ newPages*VM.wordsPerPage}; FOR hti _ ls.hashVec[hvi], ls.ht[hti].link UNTIL hti = HTNull DO t: LONG POINTER TO TEXT ~ LitText[ls.ht[hti].offset]; IF EqText[s, t] THEN RETURN[ls.ht[hti].offset]; ENDLOOP; nw _ TEXT[s.length].SIZE; WHILE ls.textOffset + nw > ls.textLimit DO ExpandTextSpace[] ENDLOOP; offset _ ls.textOffset; Copy[from~s, to~ls.textBase+ls.textOffset, nwords~nw]; ls.textOffset _ ls.textOffset + nw; hti _ AllocateHash[]; ls.ht[hti] _ [link~ls.hashVec[hvi], offset~offset]; ls.hashVec[hvi] _ hti; RETURN}; AllocateHash: PROC RETURNS[hti: HTIndex] ~ { ExpandHashSpace: PROC ~ { oldLength: CARDINAL ~ IF ls.ht = NIL THEN 0 ELSE ls.ht.length; newLength: CARDINAL ~ oldLength + MAX[MIN[oldLength/2, 1024], 256]; newHt: REF HashSeq ~ NEW[HashSeq[newLength]]; IF ls.ht # NIL THEN FOR i: NAT IN [0 .. ls.ht.length) DO newHt[i] _ ls.ht[i] ENDLOOP; ls.ht _ newHt}; IF ls.ht = NIL OR ls.nextHti >= ls.ht.length THEN ExpandHashSpace[]; hti _ ls.nextHti; ls.nextHti _ ls.nextHti + 1; RETURN}; EnterStamp: PROC[stamp: BcdDefs.VersionStamp] RETURNS[index: RTBcd.StampIndex] ~ { ExpandStampList: PROC ~ INLINE { oldSize: NAT ~ IF ls.stampList = NIL THEN 0 ELSE ls.stampList.limit-1; AdjustStampList[ls, oldSize + MAX[MIN[oldSize/2, 256], 64]]}; FOR i: NAT IN [1 .. ls.nextStamp) DO IF stamp = ls.stampList[i] THEN RETURN[[i]]; ENDLOOP; IF ls.stampList = NIL OR ls.nextStamp >= ls.stampList.limit THEN ExpandStampList[]; index _ [ls.nextStamp]; ls.stampList[ls.nextStamp] _ stamp; ls.nextStamp _ ls.nextStamp + 1; RETURN}; rtHeader: RTBcd.RTBase ~ LOOPHOLE[bcdBase + bcdBase.rtPages.relPageBase*VM.wordsPerPage--BcdDefs.PageSize--]; nTypes, nLits: NAT; IF rtHeader.versionIdent # RTBcd.VersionID THEN GO TO badFormat; nTypes _ rtHeader[rtHeader.typeTable].length; IF nTypes # 0 THEN { rcmMap _ ls.rcmt.Include[ rcmb~@rtHeader[rtHeader.rcMapBase], size~rtHeader.rcMapLength, zone~zone]; ls.typeMap _ NEW[TypeMap[nTypes]]; FOR i: NAT IN [0 .. nTypes) DO typeString: LONG POINTER TO TEXT ~ @rtHeader[rtHeader.litBase] + rtHeader[rtHeader.typeTable][i].ct; ls.typeMap[i] _ EnterType[MapTypeItem[rtHeader[rtHeader.typeTable][i], typeString]]; ENDLOOP; IF rcmMap # NIL THEN zone.FREE[@rcmMap]}; nLits _ rtHeader[rtHeader.refLitTable].length; IF nLits # 0 THEN { ls.litMap _ NEW[LitMap[nLits]]; FOR i: NAT IN [0 .. rtHeader[rtHeader.refLitTable].length) DO pName: LONG POINTER TO TEXT ~ @rtHeader[rtHeader.litBase] + rtHeader[rtHeader.refLitTable][i].offset; ls.litMap[i] _ EnterRefLit[MapLitItem[rtHeader[rtHeader.refLitTable][i], pName]]; ENDLOOP}; EXITS badFormat => success _ FALSE; }; RETURN}; MapLitLink: PUBLIC PROC[ls: LiteralState, old: RTBcd.RefLitIndex] RETURNS[RTBcd.RefLitIndex] ~ { RETURN[IF ls.litMap = NIL THEN ERROR ELSE MapLit[ls, old]]}; MapTypeLink: PUBLIC PROC[ls: LiteralState, old: RTBcd.TypeIndex] RETURNS[RTBcd.TypeIndex] ~ { RETURN[IF ls.typeMap = NIL THEN ERROR ELSE MapType[ls, old]]}; Unload: PUBLIC PROC[ls: LiteralState] ~ { ls.typeMap _ NIL; ls.litMap _ NIL}; MapType: PROC[ls: LiteralState, old: RTBcd.TypeIndex] RETURNS[RTBcd.TypeIndex] ~ INLINE { RETURN[ls.typeMap[old]]}; CompareTypes: PROC[l, r: RTBcd.TypeItem] RETURNS[Relation] ~ { sl: WORD ~ Scramble[l.ct]; sr: WORD ~ Scramble[r.ct]; RETURN[ SELECT sl FROM < sr => $ls, > sr => $gr, ENDCASE => SELECT TRUE FROM l.canonical AND ~r.canonical => $ls, ~l.canonical AND r.canonical => $gr, ENDCASE => -- l.canonical = r.canonical IF l.canonical THEN $eq ELSE CompareUTFs[l.ut, r.ut]] }; CompareUTFs: PROC[l, r: RTBcd.UTInfo] RETURNS[Relation] ~ { UTWords: TYPE ~ ARRAY [0..RTBcd.UTInfo.SIZE) OF WORD; FOR i: NAT IN [0..RTBcd.UTInfo.SIZE) DO SELECT LOOPHOLE[l, UTWords][i] FROM < LOOPHOLE[r, UTWords][i] => RETURN[$ls]; > LOOPHOLE[r, UTWords][i] => RETURN[$gr]; ENDCASE; ENDLOOP; RETURN[$eq]}; AdjustTypeList: PROC[ls: LiteralState, newLimit: NAT] ~ { oldLimit: NAT ~ IF ls.typeList = NIL THEN 0 ELSE ls.typeList.length; newList: REF RTBcd.TypeList ~ NEW[RTBcd.TypeList[newLimit]]; IF ls.typeList # NIL THEN { FOR i: NAT IN [0 .. MIN[oldLimit, newLimit]) DO newList[i] _ ls.typeList[i] ENDLOOP; ls.typeList _ NIL}; ls.typeList _ newList}; MapLit: PROC[ls: LiteralState, old: RTBcd.RefLitIndex] RETURNS[RTBcd.RefLitIndex] ~ INLINE { RETURN[ls.litMap[old]]}; CompareLits: PROC[l, r: RTBcd.RefLitItem] RETURNS[Relation] ~ { sl: WORD ~ Scramble[l.offset]; sr: WORD ~ Scramble[r.offset]; RETURN[SELECT sl FROM < sr => $ls, > sr => $gr, ENDCASE => SELECT l.length FROM = r.length => SELECT l.referentType - r.referentType FROM = 0 => $eq, > 0 => $gr, ENDCASE => $ls, < r.length => $ls, ENDCASE => $gr] }; AdjustLitList: PROC[ls: LiteralState, newLimit: NAT] ~ { oldLimit: NAT ~ IF ls.litList = NIL THEN 0 ELSE ls.litList.length; newList: REF RTBcd.RefLitList ~ NEW[RTBcd.RefLitList[newLimit]]; IF ls.litList # NIL THEN { FOR i: NAT IN [0 .. MIN[oldLimit, newLimit]) DO newList[i] _ ls.litList[i] ENDLOOP; ls.litList _ NIL}; ls.litList _ newList}; OpenRCMap: PROC[ls: LiteralState] ~ { IF ls.rcmt = NIL THEN ls.rcmt _ RCMapOps.Create[zone~zone, nPages~0, ptr~NIL, expansionOK~TRUE]; }; CloseRCMap: PROC[ls: LiteralState] ~ { IF ls.rcmt # NIL THEN ls.rcmt _ RCMapOps.Destroy[ls.rcmt]; }; EqText: PROC[t1, t2: LONG POINTER TO TEXT] RETURNS [BOOL] ~ INLINE { IF t1.length # t2.length THEN RETURN[FALSE]; FOR i: NAT IN [0..t1.length) DO IF t1[i] # t2[i] THEN RETURN[FALSE] ENDLOOP; RETURN[TRUE]}; AdjustStampList: PROC[ls: LiteralState, newSize: NAT] ~ { oldSize: NAT ~ IF ls.stampList = NIL THEN 0 ELSE ls.stampList.limit-1; newList: REF RTBcd.StampList ~ NEW[RTBcd.StampList[newSize]]; FOR i: NAT IN [1 .. MIN[oldSize, newSize]] DO newList[i] _ ls.stampList[i] ENDLOOP; ls.stampList _ newList}; EnterVersionFiles: PUBLIC PROC[ ls: LiteralState, ftb: BcdDefs.Base, ftLimit: BcdDefs.FTIndex, MapFile: PROC[BcdDefs.FTIndex] RETURNS[BcdDefs.FTIndex]] ~ { VersionToFile: PROC[i: RTBcd.StampIndex] RETURNS[fti: BcdDefs.FTIndex] ~ { FOR fti _ FTIndex.FIRST, fti + FTRecord.SIZE UNTIL fti = ftLimit DO IF ls.stampList[i] = ftb[fti].version THEN RETURN; ENDLOOP; RETURN[FTNull]}; FOR i: NAT IN [0 .. ls.nextType) DO IF ~ls.typeList[i].canonical AND ls.typeList[i].ut.version # RTBcd.AnyStamp THEN [] _ MapFile[VersionToFile[ls.typeList[i].ut.version]]; ENDLOOP }; RTHeaderSize: CARDINAL ~ RTBcd.RTHeader.SIZE; SegmentSize: PUBLIC PROC[ls: LiteralState] RETURNS[nWords: CARDINAL] ~ { RETURN[IF ls.litList = NIL AND ls.typeList = NIL THEN 0 ELSE RTHeaderSize + RTBcd.RefLitList[ls.nextLit].SIZE + ls.textOffset + RTBcd.TypeList[ls.nextType].SIZE + RTBcd.StampList[ls.nextStamp-1].SIZE + ls.rcmt.GetSpan[].size] }; UpdateSegments: PUBLIC PROC[ls: LiteralState, MapSegment: PROC[SGIndex] RETURNS[SGIndex]] ~ { FOR i: NAT IN [0 .. ls.nextType) DO ls.typeList[i].table _ MapSegment[ls.typeList[i].table] ENDLOOP }; SealLiterals: PUBLIC PROC[ls: LiteralState] ~ { ls.hashVec _ NIL; ls.ht _ NIL; ls.litTree _ NIL; ls.typeTree _ NIL}; Write: PUBLIC PROC[ls: LiteralState, stream: IO.STREAM] ~ { IF ls.litList # NIL OR ls.typeList # NIL THEN { bytesPerWord: CARDINAL ~ Basics.bytesPerWord; litSize: CARDINAL ~ RTBcd.RefLitList[ls.nextLit].SIZE; typeSize: CARDINAL ~ RTBcd.TypeList[ls.nextType].SIZE; stampSize: CARDINAL ~ RTBcd.StampList[ls.nextStamp-1].SIZE; rcmSize: CARDINAL ~ ls.rcmt.GetSpan[].size; header: RTBcd.RTHeader _ [ refLitTable~LOOPHOLE[RTHeaderSize], litBase~LOOPHOLE[RTHeaderSize + litSize], litLength~ls.textOffset, rcMapBase~LOOPHOLE[(RTHeaderSize + litSize + ls.textOffset).LONG], rcMapLength~rcmSize, stampTable~LOOPHOLE[RTHeaderSize + litSize + ls.textOffset + rcmSize], typeTable~LOOPHOLE[RTHeaderSize + litSize + ls.textOffset + rcmSize + stampSize]]; stream.UnsafePutBlock[[LOOPHOLE[(@header).LONG, LONG POINTER TO Basics.RawBytes], 0, RTHeaderSize*bytesPerWord]]; AdjustLitList[ls, ls.nextLit]; stream.UnsafePutBlock [[LOOPHOLE[ls.litList, LONG POINTER TO Basics.RawBytes], 0, litSize*bytesPerWord]]; ls.litList _ NIL; IF ls.textSpace # VM.nullInterval THEN { stream.UnsafePutBlock[[ls.textBase, 0, ls.textOffset*bytesPerWord]]; VM.Free[ls.textSpace]}; IF rcmSize # 0 THEN stream.UnsafePutBlock[[ls.rcmt.GetSpan[].base, 0, rcmSize*bytesPerWord]]; AdjustStampList[ls, ls.nextStamp-1]; stream.UnsafePutBlock [[LOOPHOLE[ls.stampList, LONG POINTER TO Basics.RawBytes], 0, stampSize*bytesPerWord]]; ls.stampList _ NIL; AdjustTypeList[ls, ls.nextType]; stream.UnsafePutBlock [[LOOPHOLE[ls.typeList, LONG POINTER TO Basics.RawBytes], 0, typeSize*bytesPerWord]]; ls.typeList _ NIL} }; Create: PUBLIC PROC RETURNS[ls: LiteralState] ~ { ls _ NEW[LiteralStateInfo_[]]; ls.hashVec _ NEW[ARRAY HVIndex OF HTIndex _ ALL[HTNull]]; OpenRCMap[ls]; RETURN}; Finalize: PUBLIC PROC[ls: LiteralState] ~ { CloseRCMap[ls]; ls.hashVec _ NIL}; }. τBcdLiteralsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Satterthwaite, April 24, 1986 4:23:19 pm PST Maxwell, August 11, 1983 2:23 pm Paul Rovner, September 22, 1983 11:43 am Russ Atkinson (RRA) March 7, 1985 0:59:00 am PST input data structures data structures for auxiliary tree structures data structures for literal values state record input type mapping ATOM and ROPE literal mapping RC map table literal values version stamps utilities input routines called after LoadLiterals, before UnloadLiterals called after LoadLiterals, before UnloadLiterals type mapping operations atoms and REFs to literals RC maps literal value manipulation version stamp manipulation output called if output packing has produced new sgis Κ^˜codešœ™Kšœ Οmœ1™˜XKšœžœžœŒ˜Kšœžœžœ˜+KšžœžœžœN˜\K˜—šœž˜Kšž œ žœ,˜@Kšž œ˜Kšžœ ˜ K˜—šœ™K˜Kš œ žœžœžœ žœžœ˜@Kš œžœžœžœ žœžœ˜FK˜—Kšœ-™-˜Kšœ žœ˜KšœžœžœΟcœ˜,Kšœžœžœ˜ Kš œžœžœžœ žœžœžœ˜DK˜š Οn œžœžœžœžœ žœ ˜QKš œ žœžœžœžœžœ ˜6Kšœ žœ˜šžœžœžœ˜Kš žœžœžœžœžœžœ˜MKšœ˜—K˜K˜—š  œžœžœžœžœžœŸ˜SKšžœ-˜3K˜—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˜—K™šœ ™ K˜š œžœžœžœ žœžœžœ˜DK˜K˜—Kšœž œžœ"˜6K˜—K™™š œžœžœ˜K˜K˜Kšœ œžœ žœ ˜,Kšœ  œžœ žœ ˜0Kšž œ žœžœ˜#Kšžœžœ˜#˜Kšœžœ+˜GK˜#K˜š  œžœžœžœ˜Qš žœžœžœžœž˜CKšžœ$žœžœ˜2Kšžœ˜—Kšžœ ˜K˜—K˜K˜š   œžœžœžœžœžœ˜BKšžœ˜šœžœ ˜Kšžœžœ žœ žœ˜8K˜—K˜K˜ Kšœžœ˜ K˜š œžœžœ˜ Kšœ žœžœžœ˜DKšœ žœ žœ˜4Kšœ žœžœžœ%˜?šžœžœžœ˜(K˜9Kšžœ˜—K˜0Kšœ2žœ˜CK˜—šžœ(žœž˜@Kš œžœžœžœžœ˜5Kšžœžœžœ˜/Kšžœ˜—Kšœžœ žœ˜Kšžœ#žœžœ˜EK˜K˜6K˜#K˜K˜KKšžœ˜—K˜š  œžœžœ˜,K˜š œžœ˜Kš œ žœžœ žœžœžœ˜>Kšœ žœžœžœ˜CKšœžœ žœ˜-Kšžœ žœžœžœžœžœžœžœ˜UK˜K˜—Kšžœ žœžœžœ˜DK˜/Kšžœ˜K˜—š  œžœžœ˜RK˜š œžœžœ˜ Kš œ žœžœžœžœžœ˜FKšœžœžœ˜=K˜—šžœžœžœž˜$Kšžœžœžœ˜,Kšžœ˜ —Kšžœžœžœ$žœ˜SKšœ<˜K˜K˜——š œžœžœ˜)Kšœ žœ˜Kšœ žœ˜K˜K˜——Kšœ™˜š œžœ)žœžœ˜YKšžœ˜K˜—š  œžœžœ˜>Kšœžœ˜Kšœžœ˜šžœ˜šžœž˜K˜šžœ˜ šžœžœž˜Kšœ žœ˜$Kšœ žœ˜$šžœŸ˜'Kšžœ žœžœ˜5—————šœ˜K˜——š  œžœžœ˜;Kš œ žœžœžœžœžœ˜5š žœžœžœžœž˜'šžœžœž˜#Kšœžœžœ˜)Kšœžœžœ˜)Kšžœ˜—Kšžœ˜—Kšžœ˜ K˜—š œžœžœ˜9Kš œ žœžœžœžœžœ˜DKšœ žœžœ˜<šžœžœžœ˜Kš žœžœžœžœžœžœ˜TKšœ˜—Kšœ˜K˜K˜——Kšœ™˜š œžœ+žœžœ˜\Kšžœ˜K˜—š  œžœžœ˜?Kšœžœ˜Kšœžœ˜šžœžœž˜K˜ K˜ šžœžœ ž˜˜ šžœ!ž˜+Kšœžœ˜'——K˜Kšžœ˜——šœ˜K˜——š  œžœžœ˜8Kš œ žœžœžœžœžœ˜BKšœ žœžœ˜@šžœžœžœ˜Kš žœžœžœžœžœžœ˜SKšœ žœ˜—K˜K˜K˜——Kšœ™˜š  œžœ˜%šžœ žœž˜Kšœ3žœžœ˜J—šœ˜K˜——š  œžœ˜&šžœ žœž˜Kšœ$˜$—Kšœ˜K˜K˜——Kšœ™˜š œžœ žœžœžœžœžœžœžœ˜DKšžœžœžœžœ˜,šžœžœžœž˜Kš žœžœžœžœžœ˜,—Kšžœžœ˜K˜K˜——Kšœ™˜š œžœžœ˜9Kš œ žœžœžœžœžœ˜FKšœ žœžœ˜=Kš žœžœžœžœžœžœ˜SK˜K˜K˜——šœ™K˜š œžœžœ˜K˜K˜,Kš œžœžœ˜——šœ˜K˜——š  œžœžœ  œžœ žœ˜]Kšœ.™.šžœžœžœž˜#Kšœ8ž˜?—šœ˜K˜——š  œžœžœ˜/Kšœ žœ˜Kšœžœ˜ Kšœ žœ˜Kšœžœ˜K˜—š  œžœžœžœžœ˜;š žœžœžœžœžœ˜/Kšœžœ˜-Kšœ žœ žœ˜6Kšœ žœžœ˜6Kšœ žœ#žœ˜;Kšœ žœ˜+˜Kšœ žœ˜#Kšœžœ˜)K˜Kšœ žœ*žœ˜BK˜Kšœ žœ3˜FKšœ žœ@˜R—Kš œžœ žœžœžœžœ2˜qKšœ˜šœ˜Kš œžœ žœžœžœ-˜S—Kšœ˜šžœžœžœ˜(KšœD˜DKšžœ˜—šžœ ž˜KšœI˜I—K˜$šœ˜Kš œžœžœžœžœ/˜W—Kšœžœ˜Kšœ ˜ šœ˜Kš œžœžœžœžœ.˜U—Kšœžœ˜—šœ˜K˜K˜——š œžœžœžœ˜1Kšœžœ˜Kš œ žœžœ žœ žœ ˜9K˜Kšžœ˜K˜—š œžœžœ˜+K˜Kšœ žœ˜K˜—K˜K˜——…—;œSξ