DIRECTORY BcdDefs USING [Base], BcdOps USING [BcdBase, FPHandle, MTHandle, SPHandle], BootFile USING [MemorySizeToFileSize], Environment USING [bitsPerWord, wordsPerPage], Inline USING [LongCOPY], MB USING [ BHandle, BIndex, BitArray, DumpSegs, EnumerateBCDs, EnumerateCode, EnumerateFramePacks, EnumerateGlobalFrames, EnumerateSpaces, Handle, nullIndex, VirtualGlobalFrame, Zero], MBStorage USING [FreeMDSPages, FreePages, FreeWords, MDSPages, PagesForWords, Words], MBVM USING [ AllocMDSData, Base, CodeSeg, CopyWrite, DataSeg, FileSeg, MDS, Pages, PointerFromSeg, Seg, SortSegs], PrincOps USING [GlobalFrameHandle], StartList USING [ BackingLocation, Entry, Header, Index, NullSpaceIndex, NullSwapUnitIndex, SpaceIndex, SpaceType, StartIndex, SwapUnitIndex, SwapUnitInfo, SwapUnitState, Base, VersionID]; MBScript: PROGRAM IMPORTS BootFile, Inline, MB, MBStorage, MBVM EXPORTS MB = BEGIN OPEN StartList; PageSize: CARDINAL = Environment.wordsPerPage; PageState: TYPE = RECORD [busy, resident, in, readOnly, mds, first64K: BOOL]; data: MB.Handle _ NIL; segs: LONG DESCRIPTOR FOR ARRAY OF MBVM.Seg; residentTable, resDescTable, inTable, readOnlyTable: MB.BitArray _ NIL; suIndex: SwapUnitIndex; scriptIndex: Index; tablePages: CARDINAL; scriptBase: StartList.Base; header: LONG POINTER TO Header; InitScript: PUBLIC PROC [h: MB.Handle] = { data _ h; header _ data.zone.NEW[Header]; MB.Zero[header, SIZE[Header]]; data.header _ header; header.version _ VersionID; scriptIndex _ StartList.StartIndex; tablePages _ 0; scriptBase _ NIL; }; FinishScript: PUBLIC PROC = { OPEN MBStorage; IF residentTable ~= NIL THEN {FreeWords[BASE[residentTable]]; residentTable _ NIL}; IF resDescTable ~= NIL THEN {FreeWords[BASE[resDescTable]]; resDescTable _ NIL}; IF inTable ~= NIL THEN {FreeWords[BASE[inTable]]; inTable _ NIL}; IF readOnlyTable ~= NIL THEN {FreeWords[BASE[readOnlyTable]]; readOnlyTable _ NIL}; IF header ~= NIL THEN data.zone.FREE[@header]; IF scriptBase ~= NIL THEN {FreeMDSPages[scriptBase]; scriptBase _ NIL}; data _ NIL; }; InitBitTables: PROC [length: CARDINAL] = { OPEN MBStorage; wordsForTable: CARDINAL = (length+Environment.bitsPerWord-1)/Environment.bitsPerWord; residentTable _ DESCRIPTOR[Words[wordsForTable], length]; MB.Zero[BASE[residentTable], wordsForTable]; resDescTable _ DESCRIPTOR[Words[wordsForTable], length]; MB.Zero[BASE[resDescTable], wordsForTable]; inTable _ DESCRIPTOR[Words[wordsForTable], length]; MB.Zero[BASE[inTable], wordsForTable]; readOnlyTable _ DESCRIPTOR[Words[wordsForTable], length]; MB.Zero[BASE[readOnlyTable], wordsForTable]; }; MakeScript: PUBLIC PROC = { r: stop Entry _ Entry[stop[]]; nSpaces: CARDINAL _ 0; state: PageState _ [FALSE, FALSE, FALSE, FALSE, FALSE, FALSE]; inMDS, inFirst64K: BOOL; mdsBase: CARDINAL = data.mdsBase; newState: PageState; i, nwords, start: CARDINAL; tableSeg: MBVM.DataSeg; segs _ MBVM.SortSegs[]; InitBitTables[LENGTH[data.vmMap]]; FOR i IN [0..LENGTH[segs]) DO AddToBitTables[segs[i]] ENDLOOP; ClassifyPages[]; FOR i IN [0..data.lastVMPage] DO inMDS _ (i IN [mdsBase..mdsBase+255]); inFirst64K _ (i IN [0..255]); newState _ [ busy: data.vmMap[i], resident: residentTable[i], in: inTable[i], readOnly: readOnlyTable[i], mds: inMDS, first64K: inFirst64K ]; IF newState # state THEN {state _ newState; nSpaces _ nSpaces + 1}; ENDLOOP; nwords _ 0; FOR i IN [0..LENGTH[segs]) DO WITH seg: segs[i] SELECT FROM data => nwords _ nwords + SIZE[swapUnit Entry]; code => nwords _ nwords + (IF seg.sph # NIL THEN seg.sph.length*SIZE[swapUnit Entry] ELSE SIZE[swapUnit Entry]); file => IF seg.bIndex = MB.nullIndex THEN nwords _ nwords + SIZE[swapUnit Entry] ELSE { loadee: MB.BHandle = data.inputBCDs.bcds[seg.bIndex]; IF loadee.bcd.rtPages.pages ~= 0 THEN nwords _ nwords + 2*SIZE[swapUnit Entry] ELSE nwords _ nwords + SIZE[swapUnit Entry]; }; ENDCASE; ENDLOOP; nwords _ (nwords + SIZE[Header] + 16 + nSpaces*SIZE[space Entry]); AddScriptWords[nwords]; tableSeg _ MBVM.AllocMDSData[base: MBVM.MDS, pages: tablePages]; -- this won't expand vmMap tableSeg.bootLoaded _ TRUE; tableSeg.info _ [readOnly: FALSE, state: swappable]; AddToBitTables[tableSeg]; header.table _ MBVM.PointerFromSeg[tableSeg]; MBStorage.FreePages[BASE[segs]]; segs _ MBVM.SortSegs[]; FOR i IN [0..LENGTH[segs]) DO EnterSegment[segs[i]] ENDLOOP; IF data.debug THEN MB.DumpSegs[segs, "SCRIPT CONSTRUCTION"L]; state _ [ busy: data.vmMap[0], resident: residentTable[0], in: inTable[0], readOnly: readOnlyTable[0], mds: mdsBase = 0, first64K: TRUE ]; start _ 0; suIndex _ LOOPHOLE[StartIndex]; FOR i IN [1..data.lastVMPage] DO inMDS _ i IN [mdsBase..mdsBase+255]; inFirst64K _ i IN [0..255]; newState _ [ busy: data.vmMap[i], resident: residentTable[i], in: inTable[i], readOnly: readOnlyTable[i], mds: inMDS, first64K: inFirst64K ]; IF newState # state THEN {AddSpace[state, start, i-1]; start _ i; state _ newState}; ENDLOOP; AddSpace[state, start, data.lastVMPage]; AppendBootWords[@r, SIZE[stop Entry]]; [lastBootedPage: header.lastBootLoadedPage, nBootPages: data.nBootPages, nFilePages: data.nFilePages] _ PreScanSegs[segs]; MBStorage.FreePages[BASE[segs]]; header.mdsBase _ data.mdsBase; header.pdaPages _ data.pdaPages; header.loadState _ NullSwapUnitIndex; header.initLoadState _ data.lsseg.index; header.lastVMPage _ data.lastVMPage; header.stateVectorCounts _ data.stateVectorCounts; header.stateVectorSize _ data.svSize; header.nProcesses _ data.nProcesses; scriptBase^ _ header^; MBVM.CopyWrite[from: scriptBase, to: header.table, nwords: PageSize*tablePages]; }; AddToBitTables: PROC [seg: MBVM.Seg] = { resDesc: BOOL = (seg.info.state = residentDescriptor); resident: BOOL = (seg.info.state = resident); FOR i: CARDINAL IN [seg.base..seg.base+seg.pages) DO readOnlyTable[i] _ seg.info.readOnly; inTable[i] _ seg.bootLoaded; resDescTable[i] _ resDesc; residentTable[i] _ resident; ENDLOOP; }; ClassifyPages: PROC = { MB.EnumerateCode[in, BootLoadCode]; MB.EnumerateSpaces[in, BootLoadSpaces]; MB.EnumerateFramePacks[in, BootLoadFramePacks]; MB.EnumerateGlobalFrames[in, BootLoadGlobalFrames]; MB.EnumerateBCDs[in, BootLoadBCDs]; MB.EnumerateCode[resDesc, ResDescCode]; MB.EnumerateSpaces[resDesc, ResDescSpaces]; MB.EnumerateFramePacks[resDesc, ResDescFramePacks]; MB.EnumerateGlobalFrames[resDesc, ResDescGlobalFrames]; MB.EnumerateBCDs[resDesc, ResDescBCDs]; MB.EnumerateCode[resident, ResidentCode]; MB.EnumerateSpaces[resident, ResidentSpaces]; -- resident FramePacks and GlobalFrames were done during loading-- MB.EnumerateBCDs[resident, ResidentBCDs]; }; BootLoadCode: PROC [bh: MB.BHandle, mth: BcdOps.MTHandle] RETURNS [BOOL] = { cseg: MBVM.CodeSeg = bh.mt[mth.gfi].code; MarkSegPages[cseg, @inTable]; RETURN[FALSE] }; BootLoadSpaces: PROC [bh: MB.BHandle, sph: BcdOps.SPHandle, index: CARDINAL] RETURNS [BOOL] = { MarkSpacePages[sph, index, @inTable]; RETURN[FALSE] }; BootLoadFramePacks: PROC [bh: MB.BHandle, fph: BcdOps.FPHandle] RETURNS [BOOL] = { mtb: BcdDefs.Base = LOOPHOLE[bh.bcd + bh.bcd.mtOffset]; RETURN[BootLoadGlobalFrames[bh, @mtb[fph.modules[0]]]] }; BootLoadGlobalFrames: PROC [bh: MB.BHandle, mth: BcdOps.MTHandle] RETURNS [BOOL] = { frame: PrincOps.GlobalFrameHandle = bh.mt[mth.gfi].frame; IF ~MB.VirtualGlobalFrame[frame].alloced THEN MarkSegPages[SegForBase[PageFromAddress[frame] + data.mdsBase], @inTable]; RETURN[FALSE] }; BootLoadBCDs: PROC [bh: MB.BHandle] RETURNS [BOOL] = { bcdSeg: MBVM.FileSeg = bh.bcdSeg; MarkSegPages[bcdSeg, @inTable]; RETURN[FALSE] }; ResDescCode: PROC [bh: MB.BHandle, mth: BcdOps.MTHandle] RETURNS [BOOL] = { cseg: MBVM.CodeSeg = bh.mt[mth.gfi].code; cseg.info.state _ residentDescriptor; MarkSegPages[cseg, @resDescTable]; RETURN[FALSE] }; ResDescSpaces: PROC [bh: MB.BHandle, sph: BcdOps.SPHandle, index: CARDINAL] RETURNS [BOOL] = { MarkSpacePages[sph, index, @resDescTable]; RETURN[FALSE] }; ResDescFramePacks: PROC [bh: MB.BHandle, fph: BcdOps.FPHandle] RETURNS [BOOL] = { mtb: BcdDefs.Base = LOOPHOLE[bh.bcd + bh.bcd.mtOffset]; RETURN[ResDescGlobalFrames[bh, @mtb[fph.modules[0]]]]}; ResDescGlobalFrames: PROC [bh: MB.BHandle, mth: BcdOps.MTHandle] RETURNS [BOOL] = { frame: PrincOps.GlobalFrameHandle = bh.mt[mth.gfi].frame; IF ~MB.VirtualGlobalFrame[frame].alloced THEN MarkSegPages[SegForBase[PageFromAddress[frame] + data.mdsBase], @resDescTable]; RETURN[FALSE] }; ResDescBCDs: PROC [bh: MB.BHandle] RETURNS [BOOL] = { bcdSeg: MBVM.FileSeg = bh.bcdSeg; bcdSeg.info.state _ residentDescriptor; MarkSegPages[bcdSeg, @resDescTable]; RETURN[FALSE] }; ResidentCode: PROC [bh: MB.BHandle, mth: BcdOps.MTHandle] RETURNS [BOOL] = { cseg: MBVM.CodeSeg = bh.mt[mth.gfi].code; cseg.info.state _ resident; MarkSegPages[cseg, @residentTable]; MarkSegPages[cseg, @inTable]; RETURN[FALSE] }; ResidentSpaces: PROC [bh: MB.BHandle, sph: BcdOps.SPHandle, index: CARDINAL] RETURNS [BOOL] = { cseg: MBVM.CodeSeg = SegForSpace[sph]; first: CARDINAL = cseg.base+sph.spaces[index].offset; count: CARDINAL = sph.spaces[index].pages; MarkTablePages[@residentTable, first, count]; MarkTablePages[@inTable, first, count]; RETURN[FALSE] }; ResidentBCDs: PROC [bh: MB.BHandle] RETURNS [BOOL] = { bcdSeg: MBVM.FileSeg = bh.bcdSeg; bcdSeg.info.state _ resident; MarkSegPages[bcdSeg, @residentTable]; MarkSegPages[bcdSeg, @inTable]; RETURN[FALSE] }; MarkSegPages: PROC [seg: MBVM.Seg, table: POINTER TO MB.BitArray] = INLINE { MarkTablePages[table, seg.base, seg.pages]}; MarkSpacePages: PROC [ sph: BcdOps.SPHandle, index: CARDINAL, table: POINTER TO MB.BitArray] = { cseg: MBVM.CodeSeg = SegForSpace[sph]; MarkTablePages[table, cseg.base + sph.spaces[index].offset, sph.spaces[index].pages] }; MarkTablePages: PROC [table: POINTER TO MB.BitArray, first, count: CARDINAL] = { FOR i: CARDINAL IN [first..first+count) DO table^[i] _ TRUE; ENDLOOP; }; SegForBase: PROC [base: CARDINAL] RETURNS [seg: MBVM.Seg] = { FOR i: CARDINAL IN [0..LENGTH[segs]) DO seg _ segs[i]; IF base IN [seg.base..seg.base+seg.pages) THEN EXIT; REPEAT FINISHED => ERROR; ENDLOOP; }; SegForSpace: PROC [sph: BcdOps.SPHandle] RETURNS [cseg: MBVM.CodeSeg] = { FOR i: CARDINAL IN [0..LENGTH[segs]) DO WITH s: segs[i] SELECT FROM code => IF s.sph = sph THEN {cseg _ @s; EXIT}; ENDCASE; REPEAT FINISHED => ERROR; ENDLOOP; }; AddScriptWords: PROC [nwords: CARDINAL] = { newPages: CARDINAL _ (tablePages + MBStorage.PagesForWords[nwords]); newbase: POINTER _ MBStorage.MDSPages[newPages]; IF scriptBase # NIL THEN { Inline.LongCOPY[from: scriptBase, to: newbase, nwords: tablePages*PageSize]; MBStorage.FreeMDSPages[scriptBase]; }; tablePages _ newPages; data.scriptBase _ scriptBase _ newbase; }; EnterSegment: PROC [seg: MBVM.Seg] = { WITH s: seg SELECT FROM data => EnterSimpleSegment[seg]; code => IF s.sph = NIL THEN EnterSimpleSegment[seg] ELSE { r: swapUnit Entry; first: BOOL _ TRUE; s.bootLoaded _ FALSE; FOR i: CARDINAL IN [0..s.sph.length) DO base: CARDINAL = s.base+s.sph.spaces[i].offset; state: SwapUnitState = SELECT TRUE FROM residentTable[base] => resident, resDescTable[base] => residentDescriptor, ENDCASE => swappable; IF residentTable[base] OR inTable[base] THEN s.bootLoaded _ TRUE; r _ Entry[swapUnit[info: [s.info.readOnly, state], pages: s.sph.spaces[i].pages, base: s.sph.spaces[i].offset, parent: NullSpaceIndex] ]; IF first THEN {first _ FALSE; s.index _ LOOPHOLE[scriptIndex]}; AppendBootWords[@r, SIZE[swapUnit Entry]]; ENDLOOP; }; file => IF s.bIndex = MB.nullIndex THEN EnterSimpleSegment[seg] ELSE { bcd: BcdOps.BcdBase = data.inputBCDs.bcds[s.bIndex].bcd; r: swapUnit Entry _ Entry[swapUnit[ info: GetSegmentInfo[seg], pages: seg.pages, base: 0, parent: NullSpaceIndex]]; seg.index _ LOOPHOLE[scriptIndex]; IF r.info.state = resident OR bcd.rtPages.pages = 0 THEN AppendBootWords[@r, SIZE[swapUnit Entry]] ELSE { s.nUnits _ 2; r.pages _ bcd.nPages - bcd.rtPages.pages; AppendBootWords[@r, SIZE[swapUnit Entry]]; r.pages _ bcd.rtPages.pages; r.base _ bcd.rtPages.relPageBase; AppendBootWords[@r, SIZE[swapUnit Entry]]; }; }; ENDCASE; }; EnterSimpleSegment: PROC [seg: MBVM.Seg] = { r: swapUnit Entry _ Entry[swapUnit[ info: GetSegmentInfo[seg], pages: seg.pages, base: 0, parent: NullSpaceIndex]]; seg.index _ LOOPHOLE[scriptIndex]; AppendBootWords[@r, SIZE[swapUnit Entry]]; }; GetSegmentInfo: PROC [seg: MBVM.Seg] RETURNS [info: SwapUnitInfo] = { state: SwapUnitState = IF seg.info.state = resident THEN resident ELSE SELECT TRUE FROM residentTable[seg.base] => resident, resDescTable[seg.base] => residentDescriptor, ENDCASE => swappable; seg.bootLoaded _ residentTable[seg.base] OR inTable[seg.base]; RETURN[[seg.info.readOnly, state]] }; AppendBootWords: PROC [addr: POINTER, count: CARDINAL] = { IF LOOPHOLE[scriptIndex,CARDINAL]+count > tablePages*PageSize OR count = 0 THEN ERROR; Inline.LongCOPY[from: addr, to: @scriptBase[scriptIndex], nwords: count]; scriptIndex _ scriptIndex + count; }; AddSpace: PROC [state: PageState, start, end: CARDINAL] = { r: space Entry; single: BOOL _ TRUE; resident: BOOL _ residentTable[start]; anyResDesc, anyReadOnly: BOOL _ FALSE; allResDesc, allReadOnly: BOOL _ TRUE; offset: CARDINAL; pages: CARDINAL = end-start+1; space: SpaceIndex _ LOOPHOLE[scriptIndex]; IF ~state.busy THEN {AddEmptySpace[start, pages]; RETURN}; r _ Entry[space[ readOnly: state.readOnly, bootLoaded: (state.resident OR state.in), handle:, type:, pages: pages, vmpage: start, backingPage: 0, backingStore: (IF state.resident THEN null ELSE self)] ]; AppendBootWords[@r, SIZE[space Entry]]; FOR i: CARDINAL IN [start..end] DO anyResDesc _ anyResDesc OR resDescTable[i]; allResDesc _ allResDesc AND resDescTable[i]; anyReadOnly _ anyReadOnly OR readOnlyTable[i]; allReadOnly _ allReadOnly AND readOnlyTable[i]; ENDLOOP; offset _ 0; DO scriptBase[suIndex].parent _ space; scriptBase[suIndex].base _ offset; offset _ scriptBase[suIndex].pages + offset; IF offset >= pages THEN EXIT; suIndex _ suIndex + SIZE[swapUnit Entry]; single _ FALSE; ENDLOOP; scriptBase[space].type _ IF ~single THEN [family[ anyResidentChildren: resident, anyResidentDescriptorChildren: anyResDesc, anySwappableChildren: ~resident, allResidentChildren: resident, allResidentDescriptorChildren: allResDesc, allSwappableChildren: ~resident]] ELSE [unitary[suIndex]]; suIndex _ suIndex + SIZE[swapUnit Entry]; }; AddEmptySpace: PROC [start, pages: CARDINAL] = { r: space Entry; space: SpaceIndex _ LOOPHOLE[scriptIndex]; r _ Entry[space[bootLoaded: FALSE, backingStore: null, type: [empty[]], readOnly: FALSE, pages: pages, vmpage: start, handle:, backingPage: 0] ]; AppendBootWords[@r, SIZE[space Entry]]; }; PageFromAddress: PROC [p: POINTER] RETURNS [CARDINAL] = { RETURN[LOOPHOLE[p, CARDINAL]/256]}; PreScanSegs: PROC [ segs: LONG DESCRIPTOR FOR ARRAY OF MBVM.Seg] RETURNS [lastBootedPage, nBootPages, nFilePages: CARDINAL] = { i: CARDINAL; seg: MBVM.Seg; nBootPages _ 0; FOR i IN [0..LENGTH[segs]) DO seg _ segs[i]; IF ~seg.bootLoaded THEN LOOP; WITH s: seg SELECT FROM data => IF seg.base # 376B THEN { lastBootedPage _ s.base + s.pages - 1; nBootPages _ nBootPages + s.pages; }; code => [lastBootedPage, nBootPages] _ ScanBootedCodeSeg[@s, nBootPages]; file => { lastBootedPage _ s.base + s.pages - 1; nBootPages _ nBootPages + s.pages; }; ENDCASE; ENDLOOP; nFilePages _ BootFile.MemorySizeToFileSize[nBootPages]; FOR i IN [0..LENGTH[segs]) DO info: StartList.SwapUnitInfo; seg _ segs[i]; info _ scriptBase[seg.index].info; WITH s: seg SELECT FROM data => IF info.state # resident THEN { IF scriptBase[scriptBase[seg.index].parent].backingPage = 0 THEN scriptBase[scriptBase[seg.index].parent].backingPage _ nFilePages; nFilePages _ nFilePages + s.pages; }; code => nFilePages _ ScanCodeSeg[@s, nFilePages]; file => IF info.state # resident THEN { IF scriptBase[scriptBase[seg.index].parent].backingPage = 0 THEN scriptBase[scriptBase[seg.index].parent].backingPage _ nFilePages; nFilePages _ nFilePages + s.pages; }; ENDCASE; ENDLOOP; }; ScanBootedCodeSeg: PROC [seg: MBVM.CodeSeg, nBootPages: CARDINAL] RETURNS [lastPage, pages: CARDINAL] = { i, page: CARDINAL; nUnits: CARDINAL _ IF seg.sph = NIL THEN 1 ELSE seg.sph.length; index: SwapUnitIndex _ seg.index; page _ seg.base; pages _ 0; FOR i IN [0..nUnits) DO IF scriptBase[scriptBase[index].parent].bootLoaded THEN { lastPage _ page + scriptBase[index].pages - 1; pages _ pages + scriptBase[index].pages; }; page _ page + scriptBase[index].pages; index _ index + SIZE[swapUnit Entry]; ENDLOOP; RETURN[lastPage, nBootPages + pages] }; ScanCodeSeg: PROC [seg: MBVM.CodeSeg, nFilePages: CARDINAL] RETURNS [CARDINAL] = { nUnits: CARDINAL _ IF seg.sph = NIL THEN 1 ELSE seg.sph.length; index: SwapUnitIndex _ seg.index; su: POINTER TO swapUnit Entry; FOR i: CARDINAL IN [0..nUnits) DO su _ @scriptBase[index]; IF scriptBase[su.parent].backingPage = 0 THEN scriptBase[su.parent].backingPage _ nFilePages; IF su.info.state # resident THEN nFilePages _ nFilePages + su.pages; index _ index + SIZE[swapUnit Entry]; ENDLOOP; RETURN[nFilePages] }; END. ÔMBScript.mesa Edited by Sandman on 6-Aug-81 15:42:29 Edited by Lewis on 17-Sep-81 16:15:24 Edited by Levin on April 5, 1983 3:42 pm Wart Script Management Beyond this point it is assumed that the vmMap won't grow. Since the initial vmMap includes the MDS, the following can't cause it to grow therefore, our bit tables won't need to grow any bigger. Trinity or later... anyReadOnlyChildren: anyReadOnly, Trinity or later... allReadOnlyChildren: allReadOnly, ʾ˜Jšœ™Jšœ&™&Jšœ%™%Jšœ(™(J˜šÏk ˜ Jšœœ˜Jšœœ)˜5Jšœ œ˜&Jšœ œ˜.Jšœœ ˜šœœ˜ J˜­—Jšœ œF˜Ušœœ˜ Jšœ:œ(˜e—Jšœ œ˜#šœ œ˜J˜ªJ˜——šœ ˜Jšœœ ˜-Jšœœ˜ J˜—Jš˜J˜Jšœ ˜J˜Jšœ œ˜.J˜Jšœ œœ/œ˜MJ˜Jšœœ œ˜Jš œœ œœœœœ˜,Jšœ5œ œ˜GJ˜J˜Jšœ™J˜Jšœ œ˜J˜Jšœœœœ˜J˜šÏn œœœœ ˜*J˜ Jšœœ ˜Jšœœ ˜J˜J˜J˜#J˜Jšœ ˜Jšœ˜J˜—šž œœœ˜Jšœ ˜Jš œœœ œ"œ˜SJš œœœ œ œ˜PJš œ œœ œœ˜AJš œœœ œ"œ˜SJšœ œœ œ ˜.Jšœœœ)œ˜GJšœ˜ Jšœ˜J˜—šž œœ œ˜*Jšœ ˜Jšœœ>˜UJšœ œ˜9Jšœœ ˜,Jšœ œ˜8Jšœœ˜+Jšœ œ˜3Jšœœ˜&Jšœ œ˜9Jšœœ ˜,J˜J˜—šž œœœ˜J˜Jšœ œ˜Jš œœœœœœœ˜>Jšœœ˜Jšœ œ˜!J˜Jšœœ˜Jšœ œ ˜Jšœœ ˜Jšœœ˜"Jšœ:™:Jš œœœœœ˜>J˜šœœ˜ Jšœ œ˜&Jšœœ ˜˜ J˜@J˜˜VJšœ˜—J˜(Jšœœ˜&˜eJ˜—Jšœœ˜ J˜J˜ J˜%J˜(J˜$J˜2J˜%J˜$J˜JšœL˜PJšœ˜J˜—šžœœœ ˜(Jšœ œ)˜6Jšœ œ˜-šœœœ ˜4J˜%J˜J˜J˜Jš˜—šœ˜J˜——šž œœ˜Jšœ!˜#Jšœ%˜'Jšœ-˜/Jšœ1˜3Jšœ!˜#Jšœ%˜'Jšœ)˜+Jšœ1˜3Jšœ5˜7Jšœ%˜'Jšœ'˜)Jšœ+˜-JšŸB˜BJšœ'˜)Jšœ˜J˜—š ž œœœ œœ˜LJšœœ˜)J˜Jšœœ˜ Jšœ˜J˜—šžœœœ'œ˜LJšœœ˜J˜%Jšœœ˜ Jšœ˜J˜—š žœœœ œœ˜RJšœœ˜7Jšœ0˜6Jšœ˜J˜—š žœœœ œœ˜TJ˜9šœœ#˜-J˜J—Jšœœ˜ Jšœ˜J˜—š ž œœœ œœ˜6Jšœœ˜!J˜Jšœœ˜ Jšœ˜J˜—š ž œœœ œœ˜KJšœœ˜)J˜%J˜"Jšœœ˜ Jšœ˜J˜—šž œœœ'œ˜KJšœœ˜J˜*Jšœœ˜ Jšœ˜J˜—š žœœœ œœ˜QJšœœ˜7Jšœ1˜7J˜—š žœœœ œœ˜SJ˜9šœœ#˜-J˜O—Jšœœ˜ Jšœ˜J˜—š ž œœœ œœ˜5Jšœœ˜!J˜'J˜$Jšœœ˜ Jšœ˜J˜—š ž œœœ œœ˜LJšœœ˜)J˜J˜#J˜Jšœœ˜ Jšœ˜J˜—šžœœœ'œ˜LJšœœ˜Jšœœ˜&Jšœœ&˜5Jšœœ˜*J˜-J˜'Jšœœ˜ Jšœ˜J˜—š ž œœœ œœ˜6Jšœœ˜!J˜J˜%J˜Jšœœ˜ Jšœ˜J˜—šž œœœ œœœœ˜MJ˜,J˜—šžœœ˜Jš œœ œœœ˜IJšœœ˜&J˜TJ˜J˜—š žœœ œœœœ˜Pšœœœ˜*Jšœ œ˜Jš˜—šœ˜J˜——š ž œœœœœ ˜=š œœœœ˜'J˜Jšœœ œœ˜4š˜Jšœœ˜—Jš˜—šœ˜J˜——šž œœœœ ˜Iš œœœœ˜'šœ œ˜Jšœœ œœ˜/Jšœ˜—š˜Jšœœ˜—Jš˜—šœ˜J˜——šžœœ œ˜+Jšœ œ2˜DJšœ œ ˜0šœœœ˜J˜LJ˜#J˜—J˜J˜'J˜J˜—šž œœœ ˜&šœœ˜J˜ ˜Jšœ œœ˜+šœ˜J˜Jšœœœ˜Jšœœ˜šœœœ˜'Jšœœ!˜/šœœœ˜'J˜ J˜)Jšœ˜—Jšœœœœ˜A˜2J˜;J˜J˜—Jšœœ œ œ˜?Jšœœ˜*Jš˜—Jšœ˜——˜Jšœ œ œ˜7šœ˜J˜8˜#J˜O—Jšœ œ˜"šœœ˜8Jšœœ˜)—šœ˜J˜ J˜)Jšœœ˜*J˜>Jšœœ˜*Jšœ˜—Jšœ˜——Jš˜—šœ˜J˜——šžœœœ ˜,˜#J˜O—Jšœ œ˜"Jšœœ˜*Jšœ˜J˜—šžœœœœ˜E˜šœœ ˜/šœœ˜J˜$J˜-Jšœ˜———Jšœ)œ˜>Jšœ˜"Jšœ˜J˜—šžœœœ œ˜:Jš œœ œœ œœ˜VJ˜IJ˜"J˜J˜—šžœœ œ˜;J˜Jšœœœ˜Jšœ œ˜&Jšœœœ˜&Jšœœœ˜%Jšœœ˜Jšœœ˜Jšœœ˜*Jšœ œœ˜:˜J˜Jšœœ˜9J˜,Jšœœœœ˜6Jšœ˜—Jšœœ˜'šœœœ˜"Jšœœ˜+Jšœœ˜,Jšœœ˜.Jšœœ˜/Jšœ˜—J˜ š˜J˜#J˜"J˜,Jšœœœ˜Jšœœ˜)Jšœ œ˜Jšœ˜—šœœ˜(šœ˜Jšœ6™6J˜J˜+J˜!Jšœ5™5J˜J˜+J˜!—Jšœ˜—Jšœœ˜)Jšœ˜J˜—šž œœœ˜0J˜Jšœœ˜*šœœ&˜GJšœ œ7˜FJšœ˜—Jšœœ˜'Jšœ˜J˜—š žœœœœœ˜9Jšœœœ˜#J˜—šž œœ˜Jš œœ œœœœœ˜,Jšœ*œ˜>Jšœœ˜ Jšœœ˜J˜šœœœ˜J˜Jšœœœ˜šœœ˜šœœœ˜!J˜'J˜"J˜—J˜I˜ J˜'J˜"J˜—Jšœ˜—Jšœ˜—J˜7šœœœ˜J˜J˜J˜"šœœ˜šœ˜šœœ˜šœ:˜@J˜B—J˜"J˜——J˜1šœ˜šœœ˜šœ:˜@J˜B—J˜"J˜——Jšœ˜—Jš˜—šœ˜J˜——šžœœœœ˜BJšœœ˜'Jšœ œ˜Jš œœœ œœœ˜?J˜!J˜J˜ šœœ ˜šœ1œ˜9J˜/J˜(J˜—J˜&Jšœœ˜%Jšœ˜—Jšœ˜$Jšœ˜J˜—š ž œœœœœœ˜RJš œœœ œœœ˜?J˜!Jšœœœ˜šœœœ ˜!J˜šœ'˜-J˜/—Jšœœ$˜DJšœœ˜%Jšœ˜—Jšœ ˜Jšœ˜J˜—Jšœ˜J˜J˜—…—B0WÂ