DIRECTORY DBCommon; DBStoragePage: CEDAR DEFINITIONS IMPORTS DBCommon = BEGIN MaxWordsPerPage: CARDINAL = 512; RestOfWord: CARDINAL = 128; LengthField: TYPE = CARDINAL [0..MaxWordsPerPage); SlotIndexField: TYPE = CARDINAL [0..RestOfWord); SlotTypeField: TYPE = CARDINAL [0..RestOfWord); VecPage: TYPE = PRIVATE MACHINE DEPENDENT RECORD[ tag: CARDINAL [0..377B], unused: CARDINAL [0..1] _ NULL, highSlot: SlotIndexField, nFreeSlots: SlotIndexField, nWordsInFreeVecs: LengthField ];--VecPage Slot: TYPE = PRIVATE MACHINE DEPENDENT RECORD[ type: SlotTypeField, vecOffset: LengthField ];--Slot FreeType: SlotTypeField = 0; UnFreeType: SlotTypeField = 177B; MaxTuplesetPerPage: SlotTypeField = 171B; IndTupleType: SlotTypeField = 172B; LStringType: SlotTypeField = 173B; EStringType: SlotTypeField = 174B; NonlocalStringExtensonType: SlotTypeField = 175B; TSDictType: SlotTypeField = 176B; VecHeader: TYPE = PRIVATE MACHINE DEPENDENT RECORD[ slotIndex: SlotIndexField, length: PUBLIC LengthField ];--VecHeader TupleBody: TYPE = MACHINE DEPENDENT RECORD[ header: VecHeader, groupOffset: CARDINAL, fields: ARRAY[0..0) OF CARDINAL ];--TupleBody SizeOfNullTuple: CARDINAL = SIZE[TupleBody]; PageHeader: TYPE = MACHINE DEPENDENT RECORD[ pageTag: CARDINAL [0..256), dontCare: CARDINAL [0..256) ]; -- PageHeader Unused: CARDINAL = 0; -- unused page, obtained by extending Juniper file Free: CARDINAL = 1; -- page on segment or local free list AMap: CARDINAL = 2; -- page used to store segment address-map values Tuple: CARDINAL = 3; -- page used to store tuples SystemTuple: CARDINAL = 4; -- page used to store system tuples OverflowTuple: CARDINAL = 5; -- page used to store overflow tuples & long strings BTree: CARDINAL = 6; -- page used to store part of a B-tree IString: TYPE = MACHINE DEPENDENT RECORD[ bytesInString: LengthField, slotOfExtension: SlotIndexField, rest: SELECT OVERLAID * FROM word => [words: ARRAY [0..0) OF WORD _ NULL], text => [text: PACKED ARRAY [0..0) OF CHARACTER _ NULL], ENDCASE ];--IString SizeOfNullIString: CARDINAL = SIZE[IString]; LString: TYPE = MACHINE DEPENDENT RECORD[ header: VecHeader, bytesInRemString: CARDINAL, eStringID: DBCommon.TID ];--LString SizeOfNullLString: CARDINAL = SIZE[LString]; EString: TYPE = MACHINE DEPENDENT RECORD[ header: VecHeader, eStringID: DBCommon.TID, rest: SELECT OVERLAID * FROM word => [words: ARRAY [0..0) OF WORD _ NULL], text => [text: PACKED ARRAY [0..0) OF CHARACTER _ NULL], ENDCASE ];--EString SizeOfNullEString: CARDINAL = SIZE[EString]; TSDictSlotIndex: SlotIndexField = 1; TSDict: TYPE = MACHINE DEPENDENT RECORD[ header: VecHeader, allocLink: DBCommon.DBPage, seq: ARRAY [1..1) OF TSDictEntry ];--TSDict TSDictEntry: TYPE = MACHINE DEPENDENT RECORD[ tuplesetID: DBCommon.TID, next: DBCommon.DBPage, prev: DBCommon.DBPage ];--TSDictEntry TuplesetObject: TYPE = MACHINE DEPENDENT RECORD[ wordsForTupleFields: CARDINAL [0..377B] _ 0, nVarFields: CARDINAL [0..377B] _ 0, searchList: TSDictEntry, allocList: DBCommon.DBPage _ DBCommon.NullDBPage, pageAllocator: PageAllocator ];--TuplesetObject PageAllocator: TYPE = MACHINE DEPENDENT RECORD[ segmentID: DBCommon.DBPage, firstPageInBlock: DBCommon.DBPage _ DBCommon.NullDBPage, nPagesInBlock: CARDINAL _ 0, nFreePagesInBlock: CARDINAL _ 0, nPagesPerExtent: CARDINAL _ 0, freeList: DBCommon.DBPage _ DBCommon.NullDBPage, nPagesOnFreeList: CARDINAL _ 0 ];--PageAllocator SizeOfInitialTSDict: CARDINAL = SIZE[TSDict] + SIZE[TSDictEntry]; SizeOfNullTSDict: CARDINAL = SIZE[TSDict]; InitializeVecPage: PROC[p: LONG POINTER TO VecPage, pageTag: CARDINAL]; TagOfPage: PROC[p: LONG POINTER TO VecPage] RETURNS[--pageTag-- CARDINAL] = TRUSTED INLINE BEGIN RETURN[p.tag]; END;--TagOfPage AllocVec: PROC[p: LONG POINTER TO VecPage, nWords: CARDINAL] RETURNS[--slotIndex-- CARDINAL, --success-- BOOLEAN]; WordsInLargestAllocableVec: PROC[p: LONG POINTER TO VecPage] RETURNS[CARDINAL]; FreeVec: PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL]; ModifyVec: PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL, deltaWords: INTEGER, preserveContents: BOOLEAN] RETURNS[--success-- BOOLEAN]; VecOfSlot: PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL] RETURNS[LONG POINTER TO VecHeader] = TRUSTED INLINE BEGIN IF slotIndex=0 OR slotIndex>HighSlotIndexOfPage[p] THEN ERROR DBCommon.InternalError -- BadSlotIndex --; RETURN[LOOPHOLE[p + LOOPHOLE[p + (DBCommon.WordsPerPage - SIZE[Slot]) - slotIndex*SIZE[Slot], LONG POINTER TO Slot].vecOffset, LONG POINTER TO VecHeader]]; END;--VecOfSlot LengthOfVec: PROC[v: LONG POINTER TO VecHeader] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN RETURN[v.length]; END;--LengthOfVec TypeOfSlot: PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN IF slotIndex=0 OR slotIndex>HighSlotIndexOfPage[p] THEN ERROR DBCommon.InternalError -- BadSlotIndex --; RETURN[LOOPHOLE[p + (DBCommon.WordsPerPage - SIZE[Slot]) - slotIndex*SIZE[Slot], LONG POINTER TO Slot].type]; END;--TypeOfSlot SetTypeOfSlot: PROC[ p: LONG POINTER TO VecPage, slotIndex: CARDINAL, newType: CARDINAL] = TRUSTED INLINE BEGIN IF slotIndex=0 OR slotIndex>HighSlotIndexOfPage[p] THEN ERROR DBCommon.InternalError -- BadSlotIndex --; LOOPHOLE[p + (DBCommon.WordsPerPage - SIZE[Slot]) - slotIndex*SIZE[Slot], LONG POINTER TO Slot].type _ newType; END;--SetTypeOfSlot WordsLeftOnPage: PROC[p: LONG POINTER TO VecPage] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN RETURN[p.nWordsInFreeVecs - SIZE[VecHeader]]; END;--WordsLeftOnPage HighSlotIndexOfPage: PROC[p: LONG POINTER TO VecPage] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN RETURN[p.highSlot]; END;--HighSlotIndexOfPage CheckVecPage: PROC[p: LONG POINTER TO VecPage, pageTag: CARDINAL]; IndexToSlot: PRIVATE PROC[p: LONG POINTER TO VecPage, slotIndex: CARDINAL] RETURNS[LONG POINTER TO Slot] = TRUSTED INLINE BEGIN RETURN[LOOPHOLE[p + (DBCommon.WordsPerPage - SIZE[Slot]) - slotIndex*SIZE[Slot], LONG POINTER TO Slot]]; END;--IndexToSlot IndexToOffset: PRIVATE PROC[slotIndex: CARDINAL] RETURNS[CARDINAL] = TRUSTED INLINE BEGIN RETURN[DBCommon.WordsPerPage - SIZE[Slot] - slotIndex*SIZE[Slot]]; END;--IndexToOffset AssertVecIsLString: PROC[pagePtr: LONG POINTER TO VecPage, slotIndex: CARDINAL] = TRUSTED INLINE { SELECT TypeOfSlot[pagePtr, slotIndex] FROM LStringType => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadVecTag };--AssertVecIsLString AssertVecIsEString: PROC[pagePtr: LONG POINTER TO VecPage, slotIndex: CARDINAL] = TRUSTED INLINE { SELECT TypeOfSlot[pagePtr, slotIndex] FROM EStringType => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadVecTag };--AssertVecIsEString AssertVecIsTSDict: PROC[ pagePtr: LONG POINTER TO VecPage, slotIndex: CARDINAL] = TRUSTED INLINE { SELECT TypeOfSlot[pagePtr, slotIndex] FROM TSDictType => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadVecTag };--AssertVecIsTSDict AssertPageIsTuplePage: PROC[p: LONG POINTER] = TRUSTED INLINE { SELECT LOOPHOLE[p,LONG POINTER TO PageHeader].pageTag FROM Tuple => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadPageTag }; -- AssertPageIsTuplePage AssertPageIsSystemTuplePage: PROC[p: LONG POINTER] = TRUSTED INLINE { SELECT LOOPHOLE[p,LONG POINTER TO PageHeader].pageTag FROM SystemTuple => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadPageTag }; -- AssertPageIsSystemTuplePage AssertPageIsAnyTuplePage: PROC[p: LONG POINTER] = TRUSTED INLINE { SELECT LOOPHOLE[p,LONG POINTER TO PageHeader].pageTag FROM Tuple, SystemTuple => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadPageTag }; -- AssertPageIsAnyTuplePage AssertPageIsOverflowTuplePage: PROC[p: LONG POINTER] = TRUSTED INLINE { SELECT LOOPHOLE[p,LONG POINTER TO PageHeader].pageTag FROM OverflowTuple => {}; ENDCASE => ERROR DBCommon.InternalError; -- BadPageTag }; -- AssertPageIsOverflowTuplePage NEntries: PROC[LONG POINTER TO TSDict] RETURNS[CARDINAL]; GetIndex: PROC[--p--LONG POINTER TO VecPage, --tsID--DBCommon.TID] RETURNS[--index--CARDINAL, --found it--BOOLEAN]; GetEntry: PROC[--p--LONG POINTER TO VecPage, --tsID--DBCommon.TID] RETURNS[LONG POINTER TO TSDictEntry]; EntryFromIndex: PROC[--p--LONG POINTER TO VecPage, --index--CARDINAL] RETURNS[LONG POINTER TO TSDictEntry]; END. -- DBStoragePage Created by MBrown on February 15, 1980 2:47 PM Changed by MBrown on February 15, 1980 10:31 PM Changed by MBrown on February 17, 1980 6:46 PM Changed by MBrown on February 17, 1980 8:22 PM Changed by MBrown on February 17, 1980 10:21 PM Changed by MBrown on February 24, 1980 11:37 AM --to VecPage, and "LONG POINTER --TO Page--" to "LONG POINTER TO VecPage", to gain Changed by MBrown on February 24, 1980 1:01 PM Changed by MBrown on August 22, 1980 4:21 PM Changed by MBrown on September 26, 1980 11:21 AM Changed by Willie-Sue on February 15, 1985 "όFile DBStoragePage.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by: MBrown on September 26, 1980 11:18 AM Cattell on January 14, 1983 2:10 pm Willie-Sue, February 15, 1985 11:15:44 am PST Widom, July 16, 1985 3:34:11 pm PDT Donahue, May 23, 1986 9:27:04 am PDT This interface contains types and procedures relating to the structure of pages (tuple pages and overflow pages). Most of the types are PRIVATE; clients are expected to use a purely procedural interface. Types There seems to be no advantage in having these vary with the true pagesize. These structures will need to be re-thought for 1024 word pages (which may be too large for our expected applications). Page type, on all pages in the system. Largest slot index that is valid on this page. Number of slots in [1..highSlot] that are unused. Number of words in free vecs on this page. Header of a page that is formatted to hold vecs. There are three possible values for tag: DBStoragePagetags.Tuple, .SystemTuple, and .OverflowTuple. "Type" of object stored in vec. Page-relative pointer to a vec. A Slot is a typed pointer to a vec. The types are irrelevant inside of this interface, with the following exceptions: The slot is free; ignore vecOffset. The slot is not free. This is the type given to newly-created slots by AllocVec. Slots with types IN [1..MaxTuplesetPerPage] point to tuples. The slot points to an indirect tuple **unimplemented. The slot points to a local string extension. The slot points to an external string extension. The slot points to a nonlocal string extension **unimplemented. The slot points to a tupleset dictionary vec. Slot index of slot that points here, or FreeSlotIndex for free vecs. Number of words in vec, including vec header. Information located at the beginning of each vec. A pointer to a vec points to the header, so the header length must be added to get the first word of data. TupleBody is stored in a vec, so prefix is a VecHeader offset from TupleBody of 1st GroupEntry words for tuple fields (fixed length), uninterpreted at this level This is the layout of the "body" of a tuple, consisting of the fixed-length representations of the fields, plus the variable-length representation of pointers to the groups of which this tuple is head. This is limited in length to the maximum vec length; tuple bodies do not cross page boundaries. Variable-length fields are represented by a fixed-length portion, at a fixed offset in the tuple body, and a variable-length portion, which lies outside of the tuple body (maybe on another page). First word of a page. Page tag values. in future: HashTable, BitVector, etc... length, in bytes, of string stored in text portion of InlineString. zero means no extension (whole string fits into text field) nonzero is slot number of an LString. This is the portion of a variable length field (VarByte or VarWord) that is stored in the tuple body. The text portion allows space to be reserved in the tuple body for the "expected" length of the field. The actual amount of space for text in an IString is not represented anywhere in the tuple body, but is kept in the field handle that is used for all accesses to this field. LString is stored in a vec, so prefix is a VecHeader length of string represented by this LString (so storage allocation can be done all at once). ID of a "tuple" on another page; this tuple holds the first chars from remainder of string. Can't be null. EString is stored in a vec, so prefix is a VecHeader ID of a "tuple" on another page; this tuple holds the first chars from remainder of string. Null => this tuple holds tail of string. Reserved slot index on tuple pages: This slot points to the tupleset dictionary vec. TSDict is stored in a vec, so prefix is a VecHeader TSDict is stored in a vec, so prefix is a VecHeader sequence of TSDictEntry, length implicit in header.length indices in this array are used as slot types; NOTE 1-origin links in a doubly-linked list of pages that contain tuples from this tupleset length of fixed-length data for the fields of a tuple in this set, in words. number of VarByte or VarWord fields in a tuple in this set. includes tuplesetID, next, prev. Head of doubly-linked list of all pages containing tuples from this TS. Pointers to front and back allow all types of scans. a list of part-full pages that contain at least one tuple from this tupleset, and may be used for creating new tuples in this tupleset. a part-full page is located on exactly one tupleset's allocList, despite the fact that it may contain tuples from many different tuplesets. a source of fresh pages for tuples in this tupleset This cannot be longer than DBStorage.TupleSetObjectSize name of the segment containing this tupleset (the source for new pages) block is the initial allocation for this tupleset. free pages are at end of block. Number of pages to allocate from segment when allocator is empty. singly-linked list of free blocks or pages (freed by deletions from this TS) purpose is to allow pages to be freed gracefully to segment, if TS shrinks. In addition to serving as a method of assigning short names to tuple types, the tupleset dictionary is used to link together all pages that contain tuples of a given type. This allows a tupleset to be scanned without looking at all pages in the segment. There is a corresponding cost when tuples are created and destroyed. Procedures Creates an empty page in page p of the cache, ready to store vecs using the procedures below. The new page has tag = pageTag. Returns the page tag of page p. We intend that a page's tag be checked before any of the procedures below are called on that page. Makes a new vec of total length nWords (including vec header), a slot to hold it, and returns the index of the slot. If ~success, then the call failed for lack of space, and slotIndex is garbage. Returns the largest value nWords such that AllocVec[p, nWords] is guaranteed to succeed. Frees the vec held in the slot at slotIndex, and the slot also. Changes the length of the vec at slotIndex by deltaWords. If deltaWords<0, the final deltaWords words of data in the vec are lost forever. If deltaWords>0 and preserveContents, then the old contents of the vec will be found in the initial words of the new vec; the new words are not initialized. If ~success, then the call failed for lack of space. (The call cannot fail if deltaWords<0). Returns a LONG POINTER to the VecHeader of the vec stored in the slotIndex-th slot of page p. The pointer may be used for data retrieval from the vec, and to find the vec's length (below). When retrieving data, the header must be skipped explicitly. Returns the number of words in vec v, including the header. Returns the type code of the slotIndex-th slot of page p. Makes the type code of the slotIndex-th slot of page p be newType. Partially obsoleted by WordsInLargestAllocableVec. Returns the number of words available on the page for vec allocation. Note that slots are also allocated from this space, so the total number of words required to construct a vec of nWords words may be nWords + SIZE[Slot]. Returns the highest slot index valid on this page. This is to be used for iterations that wish to look at each slot on a page. Such an iteration runs through [1..HighSlotIndexOfPage[p]], and must ignore all slots with type = FreeType. Verifies that the internal structure of the page is consistent, and that it has tag = pageTag. Returns the number of TSDictEntries in the seq of a TSDict. This can be computed from the VecHeader. Returns index of the TSDictEntry on page p that contains tsID as its tuplesetID field. Second result is TRUE iff entry was actually found; otherwise we return 1+number of entries in the TSDict, and FALSE. Returns ptr to the TSDictEntry on page p that contains tsID as its tuplesetID field. ERRORs InternalBug if no such entry exists. Returns ptr to the index-th TSDictEntry on page p. ERRORs InternalBug if no such entry exists. Module History Reduced the size of the interface by a factor of 2 (hiding more structure inside). Added CheckVecPage to interface. (This can't be written without SHARING the interface). Fixed bug in slotIndex -> slot computation; added PRIVATE IndexToSlot to localize this information. Renamed HighSlotOFPage -> HighSlotIndexOfPage. Added PRIVATE IndexToOffset for use in CompactPage. Made length field of VecHeader PUBLIC. Added WordsLeftOnPage, and stopped having AllocVec, FreeVec, and ModifyVec return the number of words left. Changed VecPageHeader more type checking. Compiler had fatal error (no intelligible message) while compiling StorageVecImpl. Fix was to make TypeOfSlot and other inlines NOT call IndexToSlot, instead manually substituting the body. This apparently saves space in pass 5. Added WordsInLargestAllocableVec to interface. Used exception BadSlotIndex from new DBException. made Cedar, added tioga formatting Κ˜šœ™Jšœ Οmœ1™<—šœ™Jšœ&™&Jšœ#™#—Jšœ-™-™#Icode™$—J˜J˜šΟk œ ˜J˜J˜—šœžœž œžœ ž˜9JšœΜ™ΜJ˜Jšœ™J˜Jšœžœ˜ Jšœ žœ˜Jšœ žœžœ˜2Jšœžœžœ˜0šœžœžœ˜/JšœΓ™ΓJ˜J˜—š œ žœžœžœž œžœ˜1šœžœ ˜Jšœ&™&—Jšœžœ žœ˜˜Jšœ.™.—˜Jšœ1™1—˜Jšœ*™*—šœΟc ˜ Jšœ•™•——J˜J˜š œžœžœžœž œžœ˜.˜Jšœ™—˜Jšœ™—šœŸ˜Jšœv™vJ˜——˜Jšœ#™#—˜!JšœQ™QJ˜—˜)Jšœ<™<—˜#Jšœ5™5—˜"Jšœ,™,—˜"Jšœ0™0—˜1Jšœ?™?—˜!Jšœ-™-—J˜š œ žœžœžœž œžœ˜3˜JšœD™D—šœžœ ˜Jšœ-™-—šœŸ ˜ Jšœ™——J˜š œ žœžœž œžœ˜+˜Jšœ6™6—šœ žœ˜Jšœ'™'—šœžœžœž˜JšœB™B—JšœŸ ˜ —J™Jšœο™οJ˜Jšœžœžœ ˜,J˜š œ žœžœž œžœ˜,Jšœ žœ ˜Jšœ žœ ˜JšœŸ˜Jšœ™J˜J˜—Jšœ™J˜JšœžœŸ2˜PJšœžœŸ%˜CJšœžœŸ0˜NJšœžœŸ˜:Jšœ žœ Ÿ#˜AJšœžœŸ4˜RJšœžœŸ&˜DJ˜Jšœ'™'J˜š œ žœžœž œžœ˜)˜JšœC™C—˜ Jšœ;™;Jšœ%™%—šœžœžœž˜Jš œžœžœžœžœ˜-Jš œžœžœžœž œžœ˜8Jšž˜—JšœŸ ˜ —J™Jšœό™όJ˜Jšœžœžœ ˜,J˜š œ žœžœž œžœ˜)˜Jšœ4™4—šœžœ˜Jšœ]™]—šœ ž ˜Jšœj™j—JšœŸ ˜ —J˜Jšœžœžœ ˜,J˜š œ žœžœž œžœ˜)˜Jšœ4™4—šœ ž œ˜Jšœ„™„—šœžœžœž˜Jš œžœžœžœžœ˜-Jš œžœžœžœž œžœ˜8Jšž˜—JšœŸ ˜ —J˜Jšœžœžœ ˜,J™Jšœ#™#˜$Jšœ0™0J˜—š œžœžœž œžœ˜(˜Jšœ3™3—˜Jšœ3™3—šœžœžœ ˜ Jšœu™u—JšœŸ˜ —J˜š œ žœžœž œžœ˜-Jšœ˜J˜˜JšœM™M—JšœŸ ˜—J˜š œžœžœž œžœ˜0šœžœ˜,JšœL™L—šœ žœ˜#Jšœ;™;—˜JšœŸ™Ÿ—˜1Jšœ”™”—˜Jšœ3™3—JšœŸ˜J™Jšœ7™7—J˜š œžœžœž œžœ˜0˜JšœG™G—˜8Jšœ2™2—Jšœžœ˜šœžœ˜ Jšœ™—šœžœ˜JšœA™A—˜0JšœL™L—šœžœ˜JšœK™K—JšœŸ˜—J˜JšœΔ™ΔJ˜Jšœžœžœ žœ˜AJšœžœžœ ˜*Ihead1šœ ™ J˜š Οnœžœžœžœžœžœ˜GJšœ~™~J˜—š  œžœžœžœžœ žœŸ œžœžœžœž˜`šœ„™„Jšžœ˜—JšžœŸ ˜—J˜š œžœžœžœžœžœžœŸ œžœŸ œžœ˜ršœΔ™ΔJ˜——š œžœžœžœžœ žœžœ˜OšœX™XJ˜——š  œžœžœžœžœžœ˜?Jšœ?™?J˜—š  œžœžœžœžœžœžœžœžœŸ œžœ˜Žšœˆ™ˆJ˜——š  œžœžœžœžœžœžœžœžœžœžœžœž˜zšœϋ™ϋšžœ žœ"ž˜7JšžœŸœ˜0—š žœžœžœžœžœ˜]Jš žœžœžœžœžœžœ ˜=——JšžœŸ ˜—J˜š  œžœžœžœžœ žœžœžœžœž˜XJšœ;™;Jšžœ ˜JšžœŸ ˜—J˜š  œžœžœžœžœžœžœžœžœžœž˜jšœ9™9šžœ žœ"ž˜7JšžœŸœ˜0—šžœžœžœžœ˜PJšžœžœžœ ˜——JšžœŸ ˜—J˜š  œžœžœžœžœžœ žœžœžœž˜ošœB™Bšžœ žœ"ž˜7JšžœŸœ˜0—šžœžœžœ˜IJšžœžœžœ˜%——JšžœŸ˜—J˜š œžœžœžœžœ žœžœžœžœž˜Zšœ’™’Jšžœžœ ˜-—JšžœŸ˜—J˜š œžœžœžœžœ žœžœžœžœžœ˜_šœμ™μJšžœ ˜—JšžœŸ˜—J˜š   œžœžœžœžœžœ˜BJšœ^™^J˜—š  œžœžœžœžœžœžœžœžœžœžœ žœžœž˜šžœžœžœžœ˜PJšžœžœžœ˜—JšžœŸ ˜—J˜š  œžœžœ žœžœžœžœžœž˜YJšžœžœžœ˜BJšžœŸ˜—J˜š œžœ žœžœžœžœžœžœ˜bšžœ ž˜*J˜JšžœžœžœŸ ˜5——JšœŸ˜J˜š œžœ žœžœžœžœžœžœ˜bšžœ ž˜*J˜JšžœžœžœŸ ˜5——JšœŸ˜J˜š œžœ žœžœžœžœžœžœ˜bšžœ ž˜*J˜JšžœžœžœŸ ˜5——JšœŸ˜J˜š  œžœžœžœžœ˜?š žœžœžœžœžœž˜:J˜ —JšžœžœŸ ˜6JšœŸ˜J˜—š  œžœžœžœžœ˜Eš žœžœžœžœžœž˜:J˜—JšžœžœŸ ˜6JšœŸ ˜"J˜—š  œžœžœžœžœ˜Cš žœžœžœžœžœž˜:J˜—JšžœžœŸ ˜6JšœŸ˜J˜—š  œžœžœžœžœ˜Gš žœžœžœžœžœž˜:J˜—JšžœžœŸ ˜6JšœŸ"˜$—J˜š œžœžœžœžœ žœžœ˜9Jšœe™eJ˜—š œžœŸžœžœžœ ŸœžœŸ žœŸ žœ˜tšœΜ™ΜJ˜——š œžœŸžœžœžœ Ÿœžœžœžœžœ˜išœT™TJšœ+™+J˜——š œžœŸžœžœžœ Ÿ žœžœžœžœžœ˜lšœ2™2Jšœ+™+———JšžœŸ˜J˜J˜Jšœ™J˜Jšœ-ž˜/J˜Jšœ.ž˜0JšœR™RJ˜Jšœ-ž˜/JšœX™XJ˜Jšœ-ž˜/JšœV™VJšœ ™ J˜Jšœ.ž˜0JšœK™KJšœ™J˜Jšœ.ž˜0JšœQ™QJšœX™XJšŸ"žœŸ)˜RJšœ™J˜Jšœ-ž˜/JšœW™WJšœ\™\Jšœ1™1J˜Jšœ+ž˜-Jšœ.™.J˜Jšœ/ž˜1Jšœ1™1J™Jšœ*˜*J™"J˜J˜—…—"œU΅