DIRECTORY Basics USING [BITAND, BITSHIFT, HighByte, LongNumber, LowByte, LowHalf], IO USING [card, int, PutF, STREAM], Process USING [MsecToTicks, SetTimeout], PupDefs USING [GetFreePupBuffer, MsToTocks, PupAddressLookup, PupAddressToRope, PupBuffer, PupPackageMake, PupPackageDestroy, PupRouterSendThis, PupSocket, PupSocketID, PupSocketDestroy, PupSocketMake, ReturnFreePupBuffer, SetPupContentsWords, UniqueLocalPupAddress], PupTypes USING [fillInHostID, fillInNetID, fillInPupAddress, Pair, PupAddress, PupType], PupStream USING [GetPupAddress, PupNameTrouble], Rope USING [ROPE], TeleLoad; TeleLoadImpl: MONITOR IMPORTS Basics, IO, Process, PupDefs, PupStream EXPORTS TeleLoad = BEGIN OPEN TeleLoad; BitOp: TYPE = PROC [a, b: UNSPECIFIED] RETURNS [UNSPECIFIED]; And: BitOp = INLINE { RETURN[Basics.BITAND[a,b]]; }; Shift: BitOp = INLINE { RETURN[Basics.BITSHIFT[a,b]]; }; locMaxByte: PUBLIC NAT _ 150; NameToAddress: PUBLIC SAFE PROC [name: Rope.ROPE] RETURNS [address: PupTypes.PupAddress, ok: BOOL _ TRUE] = TRUSTED { address _ PupStream.GetPupAddress[teleSwatSocket, name ! PupStream.PupNameTrouble => {ok _ FALSE; CONTINUE; }]; }; AddressToName: PUBLIC SAFE PROC [address: PupTypes.PupAddress] RETURNS [nameRope, addressRope: Rope.ROPE] = TRUSTED { nameRope _ PupDefs.PupAddressLookup[address]; addressRope _ PupDefs.PupAddressToRope[address]; }; Start: PUBLIC SAFE PROC [host: Rope.ROPE, log: IO.STREAM] RETURNS [h: Handle] = TRUSTED { sendHim: PupTypes.PupAddress; allok: BOOL; [sendHim, allok] _ NameToAddress[host]; sendHim.socket _ TeleLoad.teleSwatSocket; IF NOT allok THEN RETURN[NIL]; h _ NEW[TLObject _ [ host: host, address: sendHim, cacheSize: locMaxByte, log: log]]; RETURN[h]; }; Stop: PUBLIC SAFE PROC [h: Handle] = TRUSTED { IF h=NIL THEN RETURN; h.host _ NIL; h.log _ NIL; }; Store: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GStore[h: h, requestcb: cb, type: coreStoreRequest, tries: tries]; }; Fetch: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GFetch[h: h, requestcb: cb, type: coreFetchRequest, tries: tries]; }; SlaveStore: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GStore[h: h, requestcb: cb, type: slaveStoreRequest, tries: tries]; }; SlaveFetch: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GFetch[h: h, requestcb: cb, type: slaveFetchRequest, tries: tries]; }; Call: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GExchange[h: h, requestcb: cb, type: callRequest, tries: tries]; }; Go: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GStore[h: h, requestcb: cb, type: goRequest, tries: 1]; }; GoFromBreak: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GStore[h: h, requestcb: cb, type: goFromBreakRequest, tries: 1]; }; SingleStep: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GStore[h: h, requestcb: cb, type: singleStepRequest, tries: 1]; }; FetchState: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; [ok, attempts] _ GFetch[h: h, requestcb: cb, type: stateFetchRequest, tries: tries]; }; GoToDebugger: PUBLIC ENTRY TeleLoadProc = TRUSTED { ENABLE UNWIND => NULL; b: PupDefs.PupBuffer _ PupDefs.GetFreePupBuffer[]; replycb: CorePkt; replycb _ LOOPHOLE[@b.pupBody]; replycb.advice _ cb.advice; replycb.address _ cb.address; replycb.count _ cb.count; FOR j: CARDINAL IN [0..cb.count) DO replycb.data[j] _ cb.data[j]; ENDLOOP; PupDefs.SetPupContentsWords[b, SIZE[CorePktObject]+((cb.count+1)/2)]; b.pupID _ NewPupID[]; b.pupType _ debugRequest; KingSend[b, h.address]; }; eventServerUseCount: INT _ 0; eventServerActive: BOOL _ FALSE; eventServerProcess: PROCESS; eventServerPollingInterval: NAT _ 500; eventSocket: PupDefs.PupSocket _ NIL; eventClientProcedure: EventProc; eventClientData: REF ANY; StartEventServer: PUBLIC ENTRY SAFE PROC [proc: EventProc, clientData: REF ANY] = TRUSTED { eventServerUseCount _ eventServerUseCount + 1; IF eventServerUseCount > 1 THEN RETURN; IF eventServerActive THEN RETURN; eventClientProcedure _ proc; eventClientData _ clientData; eventServerActive _ TRUE; eventServerProcess _ FORK TeleloadEventServer[]; }; StopEventServer: PUBLIC ENTRY SAFE PROC = TRUSTED { eventServerUseCount _ MAX[0, eventServerUseCount - 1]; IF eventServerUseCount > 0 THEN RETURN; eventServerActive _ FALSE; JOIN eventServerProcess; }; TeleloadEventServer: PROC = { b: PupDefs.PupBuffer _ NIL; er: EventRecord; cp: CorePkt; PupDefs.PupPackageMake[]; eventSocket _ PupDefs.PupSocketMake[local: teleSwatSocket, remote: [PupTypes.fillInNetID, PupTypes.fillInHostID, teleSwatSocket], ticks: PupDefs.MsToTocks[eventServerPollingInterval]]; DO b _ eventSocket.get[]; IF b # NIL THEN { cp _ LOOPHOLE[@b.pupBody]; er _ LOOPHOLE[@cp^.data]; eventClientProcedure[b.source, er^, eventClientData]; PupDefs.ReturnFreePupBuffer[b]; }; IF NOT eventServerActive THEN EXIT; ENDLOOP; eventClientData _ NIL; eventClientProcedure _ NIL; PupDefs.PupSocketDestroy[eventSocket]; PupDefs.PupPackageDestroy[]; }; GStore: INTERNAL PROC [h: Handle, requestcb: CoreBlock, type: PupTypes.PupType, tries: NAT] RETURNS [a: BOOL _ TRUE, actualAttempts: NAT] = { b: PupDefs.PupBuffer _ NIL; id: PupTypes.Pair _ NewPupID[]; replycb: CorePkt; IF h=NIL THEN RETURN[FALSE, 0]; FOR actualAttempts IN [1..tries] DO IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; b _ PupDefs.GetFreePupBuffer[]; replycb _ LOOPHOLE[@b.pupBody]; replycb.advice _ requestcb.advice; replycb.address _ requestcb.address; replycb.count _ requestcb.count; FOR j: CARDINAL IN [0..requestcb.count) DO replycb.data[j] _ requestcb.data[j]; ENDLOOP; PupDefs.SetPupContentsWords[b, SIZE[CorePktObject]+((requestcb.count+1)/2)]; b _ Exchange[h, b, type, id]; IF b=NIL THEN LOOP; replycb _ LOOPHOLE[@b.pupBody]; IF NOT Check[requestcb, replycb] THEN LOOP; requestcb.advice _ replycb.advice; EXIT; REPEAT FINISHED => a _ FALSE; ENDLOOP; IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; }; GFetch: INTERNAL PROC [h: Handle, requestcb: CoreBlock, type: PupTypes.PupType, tries: CARDINAL] RETURNS [a: BOOL _ TRUE, actualAttempts: NAT] = { b: PupDefs.PupBuffer _ NIL; id: PupTypes.Pair _ NewPupID[]; replycb: CorePkt; IF h=NIL THEN RETURN[FALSE, 0]; FOR actualAttempts IN [1..tries] DO IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; b _ PupDefs.GetFreePupBuffer[]; replycb _ LOOPHOLE[@b.pupBody]; replycb.advice _ requestcb.advice; replycb.address _ requestcb.address; replycb.count _ requestcb.count; PupDefs.SetPupContentsWords[b, SIZE[CorePktObject]]; b _ Exchange[h, b, type, id]; IF b=NIL THEN LOOP; replycb _ LOOPHOLE[@b.pupBody]; IF replycb.address # requestcb.address THEN LOOP; IF replycb.count # requestcb.count THEN LOOP; FOR j: CARDINAL IN [0..requestcb.count) DO requestcb.data[j] _ replycb.data[j]; ENDLOOP; requestcb.advice _ replycb.advice; EXIT; REPEAT FINISHED => a _ FALSE; ENDLOOP; IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; }; GExchange: INTERNAL PROC [h: Handle, requestcb: CoreBlock, type: PupTypes.PupType, tries: CARDINAL] RETURNS [a: BOOL _ TRUE, actualAttempts: NAT] = { b: PupDefs.PupBuffer _ NIL; id: PupTypes.Pair _ NewPupID[]; replycb: CorePkt; IF h=NIL THEN RETURN[FALSE, 0]; FOR actualAttempts IN [1..tries] DO IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; b _ PupDefs.GetFreePupBuffer[]; replycb _ LOOPHOLE[@b.pupBody]; replycb.advice _ requestcb.advice; replycb.address _ requestcb.address; replycb.count _ requestcb.count; FOR j: CARDINAL IN [0..requestcb.count) DO replycb.data[j] _ requestcb.data[j]; ENDLOOP; PupDefs.SetPupContentsWords[b, SIZE[CorePktObject]+((requestcb.count+1)/2)]; b.pupID _ id; b _ Exchange[h, b, type, id]; IF b=NIL THEN LOOP; replycb _ LOOPHOLE[@b.pupBody]; IF replycb.address # requestcb.address THEN LOOP; IF replycb.count # requestcb.count THEN LOOP; FOR j: CARDINAL IN [0..requestcb.count) DO requestcb.data[j] _ replycb.data[j]; ENDLOOP; requestcb.advice _ replycb.advice; EXIT; REPEAT FINISHED => a _ FALSE; ENDLOOP; IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; }; Exchange: INTERNAL PROC [h: Handle, request: PupDefs.PupBuffer, type: PupTypes.PupType, id: PupTypes.Pair] RETURNS[PupDefs.PupBuffer] = { reply: PupDefs.PupBuffer _ NIL; request.pupID _ id; request.pupType _ type; KingSend[request, h.address]; DO IF reply#NIL THEN PupDefs.ReturnFreePupBuffer[reply]; reply _ KingGet[h.address]; IF reply = NIL THEN RETURN[NIL]; IF reply.pupType # LOOPHOLE[LOOPHOLE[type, CARDINAL]+1] THEN LOOP; IF reply.pupID # id THEN LOOP; RETURN[reply]; ENDLOOP; }; Check: INTERNAL PROC [a: CoreBlock, b: CorePkt] RETURNS [BOOL] = { IF a.address # b.address THEN RETURN[FALSE]; IF a.count # b.count THEN RETURN[FALSE]; FOR i: CARDINAL IN [0..a.count) DO IF a.data[i] # b.data[i] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; }; Failed: PUBLIC ERROR = CODE; GetCoreBlock: PUBLIC ENTRY SAFE PROC[h: Handle, addr: CoreAddress, count: CARDINAL, addressSpace: AddressSpace _ main] RETURNS [cb: CoreBlock] = TRUSTED { ENABLE UNWIND => NULL; RETURN [GetCoreBlockInternal[h, addr, count, addressSpace]]; }; GetCoreBlockInternal: INTERNAL PROC[h: Handle, addr: CoreAddress, count: CARDINAL, addressSpace: AddressSpace] RETURNS [cb: CoreBlock] = { ok: BOOLEAN; tries: NAT; cb _ NEW[CoreBlockObject[count]]; cb.address _ addr; cb.advice _ [FALSE, FALSE, 0]; [ok, tries] _ GFetch[h, cb, IF addressSpace = main THEN coreFetchRequest ELSE slaveFetchRequest, 5]; IF NOT ok THEN { IF h.log # NIL THEN h.log.PutF[" ... %d byte read from %08x failed, (%d tries).\n", IO.card[count], IO.card[cb.address], IO.int[tries]]; cb_NIL; ERROR Failed; }; }; ReadWord: PUBLIC ENTRY SAFE PROC [h: Handle, addr: CoreAddress, addressSpace: AddressSpace _ main] RETURNS [v: CARDINAL] = TRUSTED { ENABLE UNWIND => NULL; RETURN [ReadInternal[h, addr, addressSpace] + (Shift[ReadInternal[h, addr+1, addressSpace], 8])]; }; Read: PUBLIC ENTRY SAFE PROC [h: Handle, addr: CoreAddress, addressSpace: AddressSpace _ main] RETURNS [v: CARDINAL] = TRUSTED { ENABLE UNWIND => NULL; RETURN[ReadInternal[h, addr, addressSpace]]; }; ReadInternal: INTERNAL PROC [h: Handle, addr: CoreAddress, addressSpace: AddressSpace] RETURNS [v: CARDINAL] = { temp: Basics.LongNumber; blockAddr: CoreAddress; count: NAT _ h.cacheSize; IF h.cacheSize = 0 THEN h.cacheSize _ locMaxByte; h.cacheSize _ MAX[1, MIN[h.cacheSize, locMaxByte]]; temp.lc _ addr; temp.lc _ temp.lc - (temp.lc MOD h.cacheSize); blockAddr _ temp.lc; IF h.cacheCB = NIL THEN { h.cacheCB _ GetCoreBlockInternal[h: h, addr: blockAddr, count: h.cacheSize, addressSpace: addressSpace]; h.addressSpace _ addressSpace; }; IF h.cacheCB.address # blockAddr OR h.addressSpace # addressSpace THEN { FlushWritesInternal[h]; h.cacheCB _ GetCoreBlockInternal[h: h, addr: blockAddr, count: h.cacheSize, addressSpace: addressSpace]; h.addressSpace _ addressSpace; }; RETURN[h.cacheCB.data[Basics.LowHalf[addr-blockAddr]]]; }; WriteWord: PUBLIC ENTRY SAFE PROC [h: Handle, addr: CoreAddress, value: CARDINAL, addressSpace: AddressSpace _ main] = TRUSTED { ENABLE UNWIND => NULL; WriteInternal[h, addr, And[value, 377B], addressSpace]; WriteInternal[h, addr + 1, Shift[value, -8], addressSpace]; }; Write: PUBLIC ENTRY SAFE PROC [h: Handle, addr: CoreAddress, value: CARDINAL, addressSpace: AddressSpace _ main] = TRUSTED { ENABLE UNWIND => NULL; WriteInternal[h, addr, value, addressSpace]; }; WriteInternal: INTERNAL PROC [h: Handle, addr: CoreAddress, value: CARDINAL, addressSpace: AddressSpace] = { temp: Basics.LongNumber; blockAddr: CoreAddress; [] _ ReadInternal[h, addr, addressSpace]; temp.lc _ addr; temp.lc _ temp.lc - (temp.lc MOD h.cacheSize); blockAddr _ temp.lc; h.cacheCB.data[Basics.LowHalf[addr-blockAddr]] _ value; h.dirty _ TRUE; }; FlushWrites: PUBLIC ENTRY SAFE PROC [h: Handle] = TRUSTED { ENABLE UNWIND => NULL; FlushWritesInternal[h]; }; FlushWritesInternal: INTERNAL PROC [h: Handle] = { IF h.dirty THEN { ok: BOOL; tries: NAT; [ok, tries] _ GStore[h, h.cacheCB, IF h.addressSpace = main THEN coreStoreRequest ELSE slaveStoreRequest, 5]; h.dirty _ FALSE; IF NOT ok THEN { IF h.log # NIL THEN h.log.PutF[" Write to %08x failed (%d tries), cache reset anyway.\n", IO.card[h.cacheCB.address], IO.int[tries]]; ERROR Failed; }; }; }; ResetCache: PUBLIC ENTRY SAFE PROC [h: Handle] = TRUSTED { ENABLE UNWIND => NULL; FlushWritesInternal[h]; h.cacheCB _ NIL; }; SetCacheSize: PUBLIC ENTRY SAFE PROC [h: Handle, bytes: NAT] = TRUSTED { ENABLE UNWIND => NULL; FlushWritesInternal[h]; h.cacheCB _ NIL; h.cacheSize _ IF bytes = 0 THEN locMaxByte ELSE MAX[1, MIN[locMaxByte, bytes]]; }; Swab: PUBLIC SAFE PROC [a: CARDINAL] RETURNS [b: CARDINAL] = TRUSTED { b _ Basics.BITSHIFT[Basics.LowByte[a], 8] + Basics.HighByte[a]; }; SwabState: PUBLIC SAFE PROC [state: State8086Object] RETURNS [State8086Object] = TRUSTED { FOR i: Registers8086 IN [AX..FL] DO state.Regs[i] _ Swab[state.Regs[i]]; ENDLOOP; RETURN[state]; }; SwabEvent: PUBLIC SAFE PROC [state: EventRecordObject] RETURNS [EventRecordObject] = TRUSTED { state.regs _ SwabState[state.regs]; state.reason _ Swab[state.reason]; state.clockLow _ Swab[state.clockLow]; state.clockHigh _ Swab[state.clockHigh]; state.bootSwitches _ Swab[state.bootSwitches]; state.advice _ Swab[state.advice]; state.monRelays _ Swab[state.monRelays]; state.tlNet _ Swab[state.tlNet]; state.tlHost _ Swab[state.tlHost]; state.tlImHost _ Swab[state.tlImHost]; state.localNet _ Swab[state.localNet]; RETURN[state]; }; kingUseCount: INT _ 0; kingWait: CONDITION; lastPacket: PupDefs.PupBuffer; pleaseStopKing: BOOL _ TRUE; myID: PupTypes.Pair _ [1711, 1]; king: PupDefs.PupSocket; kingProcess: PROCESS; KingGet: INTERNAL PROC [from: PupTypes.PupAddress] RETURNS [PupDefs.PupBuffer] = { b: PupDefs.PupBuffer; IF lastPacket # NIL AND lastPacket.source.net = from.net AND lastPacket.source.host = from.host THEN { b _ lastPacket; lastPacket _ NIL; RETURN[b]; }; WAIT kingWait; IF lastPacket # NIL AND lastPacket.source.net = from.net AND lastPacket.source.host = from.host THEN { b _ lastPacket; lastPacket _ NIL; RETURN[b]; }; RETURN[NIL]; }; NewPupID: INTERNAL PROC RETURNS [PupTypes.Pair] = { myID.b _ myID.b + 1; RETURN [myID]; }; KingSend: INTERNAL PROC [b: PupDefs.PupBuffer _ NIL, to: PupTypes.PupAddress] = { IF king = NIL THEN { PupDefs.ReturnFreePupBuffer[b]; RETURN; }; b.dest _ to; b.source _ king.getLocalAddress[]; PupDefs.PupRouterSendThis[b]; }; KingDaemon: PROC = { us: PupTypes.PupAddress _ PupDefs.UniqueLocalPupAddress[PupTypes.fillInPupAddress]; b: PupDefs.PupBuffer; SetKingPacket: ENTRY PROC [b: PupDefs.PupBuffer] = { IF lastPacket # NIL THEN PupDefs.ReturnFreePupBuffer[lastPacket]; lastPacket _ b; NOTIFY kingWait; }; king _ PupDefs.PupSocketMake[local: us.socket, remote: us, ticks: PupDefs.MsToTocks[500]]; DO IF pleaseStopKing THEN EXIT; b _ king.get[]; IF b # NIL THEN SetKingPacket[b]; ENDLOOP; PupDefs.PupSocketDestroy[king]; king _ NIL; SetKingPacket[NIL]; }; StartKing: PUBLIC ENTRY SAFE PROC = TRUSTED { kingUseCount _ kingUseCount + 1; IF kingUseCount > 1 THEN RETURN; IF NOT pleaseStopKing THEN RETURN; pleaseStopKing _ FALSE; kingProcess _ FORK KingDaemon[]; }; StopKing: PUBLIC SAFE PROC = TRUSTED { giveUp: BOOL _ FALSE; GetLock: ENTRY PROC = { kingUseCount _ MAX[0, kingUseCount - 1]; IF kingUseCount > 0 THEN giveUp _ TRUE; IF pleaseStopKing THEN giveUp _ TRUE; pleaseStopKing _ TRUE; }; GetLock[]; IF NOT giveUp THEN JOIN kingProcess; }; StopHimProbing: PUBLIC ENTRY SAFE PROC [h: Handle, setPointers: BOOL] = TRUSTED { replycb: CorePkt; b: PupDefs.PupBuffer _ NIL; IF h = NIL THEN RETURN; b _ PupDefs.GetFreePupBuffer[]; replycb _ LOOPHOLE[@b.pupBody]; replycb.advice _ [setPointers, FALSE, 0]; replycb.address _ 0; replycb.count _ 10; PupDefs.SetPupContentsWords[b, SIZE[CorePktObject]]; b.pupID _ NewPupID[]; b.pupType _ coreFetchRequest; KingSend[b, h.address]; }; GetEventData: PUBLIC SAFE PROC [h: Handle, setPointers: BOOL] RETURNS [event: EventRecordObject, ok: BOOL] = TRUSTED { deleteOnReturn: BOOL _ FALSE; er: EventRecord; cb: CoreBlock; IF h = NIL THEN RETURN [event: event, ok: FALSE]; cb _ NEW[CoreBlockObject[SIZE[EventRecordObject] * 2]]; cb.address _ 0DA00H; cb.advice _ [setPointers, FALSE, 0]; ok _ Fetch[h, cb, 1].ok; IF NOT ok THEN RETURN [event: event, ok: FALSE]; er _ LOOPHOLE[BASE[DESCRIPTOR[cb.data]], EventRecord]; event _ SwabEvent[er^]; RETURN [event: event, ok: TRUE]; }; Process.SetTimeout[condition: @kingWait, ticks: Process.MsecToTicks[500]]; END. December 30, 1981 3:14 PM, Stewart, created from AudioSocket.mesa December 22, 1982 3:17 pm, Stewart, modifications to TeleLoad April 25, 1983 11:22 am, LCS, new Event interface and locMaxByte May 28, 1983 5:47 pm, LCS, cacheSize added, in order to make alteration of running program safe! December 26, 1983 2:40 pm, LCS, patchup addresses with StripChar `TeleLoadImpl.mesa Last Edited by: Stewart, December 26, 1983 4:11 pm Fires up a process to watch for unsolicited news items from debugees Communication stuff more conveniently arranged Here lives the single king socket. These variables are only touched by procedures in the monitor These variables are handled outside the monitor Mainline code ÊŒ˜Jšœ™Jšœ2™2J˜šÏk ˜ Jšœœœœ*˜HJšœœœ˜#Jšœœ˜(Jšœœþ˜‹Jšœ œJ˜XJšœ œ!˜0Jšœœœ˜J˜ J˜—šœ˜Jšœ œ˜/Jšœ ˜Jšœœ ˜J˜Jš Ïnœœœ œœ œ˜=J˜Jšœ œœœ ˜4Jšœœœœ ˜8J˜Jšœ œœ˜J˜šž œœœœ œœ$œœœ˜ušœ8˜8Jšœ"œœ˜6—J˜J˜—šž œœœœ œœœ˜uJšœ-˜-Jšœ0˜0J˜J˜—šžœœœœ œœœœœ˜YJ˜Jšœœ˜ J˜'J˜)Jš œœœœœ˜šœœ ˜Jšœ ˜ Jšœ˜J˜Jšœ ˜ —Jšœ˜ J˜J˜—š žœœœœœ˜.Jšœœœœ˜Jšœ œ˜ Jšœœ˜ J˜J˜—šœœœœ˜,Jšœœœ˜J˜SJ˜J˜—šœœœœ˜,Jšœœœ˜JšœS˜SJ˜J˜—šœ œœœ˜1Jšœœœ˜JšœT˜TJ˜J˜—šœ œœœ˜1Jšœœœ˜JšœT˜TJ˜J˜—šœœœœ˜+Jšœœœ˜JšœQ˜QJ˜—J˜šœœœœ˜)Jšœœœ˜J˜HJ˜J˜—šœ œœœ˜2Jšœœœ˜J˜QJ˜J˜—šœ œœœ˜1Jšœœœ˜J˜PJ˜J˜—šœ œœœ˜1Jšœœœ˜J˜TJ˜J˜—šœœœœ˜3Jšœœœ˜J˜2J˜Jšœ œ ˜J˜J˜J˜šœœœ˜#J˜Jšœ˜—Jšœœ"˜EJ˜J˜J˜J˜J˜——JšœD™D˜Jšœœ˜Jšœœœ˜ Jšœœ˜Jšœœ˜&Jšœ!œ˜%Jšœ ˜ Jšœœœ˜J˜šžœœœœœœœœ˜[J˜.Jšœœœ˜'Jšœœœ˜!J˜Jšœ˜Jšœœ˜Jšœœ˜0J˜J˜—š žœœœœœœ˜3Jšœœ˜6Jšœœœ˜'Jšœœ˜Jšœ˜J˜J˜—šžœœ˜Jšœœ˜J˜J˜ J˜J˜¸š˜J˜šœœœ˜Jšœœ ˜Jšœœ ˜Jšœ5˜5J˜J˜—Jšœœœœ˜#Jšœ˜—Jšœœ˜Jšœœ˜J˜&J˜J˜J˜—šžœœœBœœœœœ˜Jšœœ˜J˜J˜Jš œœœœœ˜šœœ ˜#Jšœœœ ˜-J˜Jšœ œ ˜J˜"J˜$J˜ šœœœ˜*J˜$Jšœ˜—Jšœœ)˜LJ˜Jšœœœœ˜Jšœ œ ˜Jšœœœœ˜+J˜"Jšœ˜Jš˜Jšœœ˜Jšœ˜—Jšœœœ ˜-J˜J˜—šžœœœBœœœœœ˜’Jšœœ˜J˜J˜Jš œœœœœ˜šœœ ˜#Jšœœœ ˜-J˜Jšœ œ ˜J˜"J˜$J˜ Jšœœ˜4J˜Jšœœœœ˜Jšœ œ ˜Jšœ%œœ˜1Jšœ!œœ˜-šœœœ˜*J˜$Jšœ˜—J˜"Jšœ˜Jš˜Jšœœ˜Jšœ˜—Jšœœœ ˜-J˜J˜—šž œœœBœœœœœ˜•Jšœœ˜J˜J˜Jš œœœœœ˜šœœ ˜#Jšœœœ ˜-J˜Jšœ œ ˜J˜"J˜$J˜ šœœœ˜*J˜$Jšœ˜—Jšœœ)˜LJ˜ J˜Jšœœœœ˜Jšœ œ ˜Jšœ%œœ˜1Jšœ!œœ˜-šœœœ˜*J˜$Jšœ˜—J˜"Jšœ˜Jš˜Jšœœ˜Jšœ˜—Jšœœœ ˜-J˜—J˜šžœœœTœ˜‰Jšœœ˜Jšœ˜J˜J˜š˜Jšœœœ$˜5J˜Jš œ œœœœ˜ Jš œœœœœœ˜BJšœœœ˜Jšœ˜Jšœ˜—J˜J˜—š žœœœœœ˜BJšœœœœ˜,Jšœœœœ˜(šœœœ˜"Jšœœœœ˜,Jšœ˜—Jšœœ˜ J˜—J˜J™.J˜Jšœœœœ˜J™šž œœœœœ&œ%œœ˜šJšœœœ˜Jšœ6˜