DIRECTORY FileIO, Inline, IO, IOExtras, Rope, RPCPkt, TeleDebOps, TeleLoad; TDX: PROGRAM IMPORTS FileIO, IO, IOExtras, Rope, TeleDebOps EXPORTS TeleDebOps = { host: PUBLIC TeleDebOps.TeleDebugData; CoreWordBlock: TYPE = LONG POINTER TO RECORD [ advice: TeleLoad.Advice, address: TeleLoad.CoreAddress, data: SEQUENCE count: CARDINAL OF CARDINAL ]; headerSize: CARDINAL = SIZE[RPCPkt.Header]*2; PBIRecord: TYPE = RECORD [ link: ShortCoreAddress, -- Queue word queue: ShortCoreAddress, -- where to put after transmission clientWord: WORD, -- give client a value in each PBI pup: ShortCoreAddress -- The pup ]; PBI: TYPE = LONG POINTER TO PBIRecord; ShortCoreAddress: TYPE = TeleDebOps.ShortCoreAddress; RPCCtx: TYPE = RECORD [ link: ShortCoreAddress, -- Queue word stack: ShortCoreAddress, -- Saved stack top value when context inactive stackMin: ShortCoreAddress, -- Limit initialPC: ShortCoreAddress, -- Procedure forked by CreateNContext name: ShortCoreAddress, -- C string describing context maxrun: CARDINAL, caller: ShortCoreAddress, -- caller of Block after maxrun extra: ARRAY [0..6) OF UNSPECIFIED, myPSB: CARDINAL, -- if a context that uses RPC, its PSB. sigVec: ShortCoreAddress, -- where the signal vector is for this context. stackArea: ARRAY [0..0) OF UNSPECIFIED -- the stack -- ]; SetHost: PROC [hostName: Rope.ROPE] RETURNS [BOOL] = { host _ TeleDebOps.FindByNameOrAddress[hostName]; RETURN[host#NIL]; }; DspCtxQ: PROC [ctx: TeleLoad.CoreAddress _ 0, ctxRunning: TeleLoad.CoreAddress _ 0 ] = { ENABLE TeleDebOps.Failed => CONTINUE; CheckHost[]; IF ctx=0 THEN { ctxItem: TeleDebOps.STObject; found: BOOL; [item: ctxItem, found: found] _ TeleDebOps.FindVariable[host.program, "ctxQ"]; IF found THEN ctx _ TeleDebOps.ReadWord[host, ctxItem.addr] ELSE { host.out.PutF["can't get symbol ctxQ\n"]; RETURN; }; }; IF ctxRunning = 0 THEN { cxtxRunningItem: TeleDebOps.STObject; found: BOOL; [item: cxtxRunningItem, found: found] _ TeleDebOps.FindVariable[TeleDebOps.Monitor[host], "CtxRunning"]; IF found THEN ctxRunning _ TeleDebOps.ReadWord[host, cxtxRunningItem.addr]; }; IF ctxRunning#0 THEN DspCtx[ctxRunning, TRUE]; WHILE ctx#0 DO IF ctx#ctxRunning THEN DspCtx[ctx, FALSE]; ctx _ TeleDebOps.ReadWord[host, ctx]; ENDLOOP; }; ClrCtxStats: PROC [ ctx: TeleLoad.CoreAddress _ 0 ] = { ENABLE TeleDebOps.Failed => CONTINUE; CheckHost[]; IF ctx = 0 THEN { ctxItem: TeleDebOps.STObject; found: BOOL; [item: ctxItem, found: found] _ TeleDebOps.FindVariable[host.program, "ctxQ"]; IF found THEN ctx _ TeleDebOps.ReadWord[host, ctxItem.addr] ELSE { host.out.PutF["can't get symbol ctxQ\n"]; RETURN; }; }; WHILE ctx # 0 DO TeleDebOps.WriteWord[host: host, addr: ctx+offsetMaxrun*2, value: 0]; ctx _ TeleDebOps.ReadWord[host, ctx]; ENDLOOP; TeleDebOps.FlushWrites[host]; }; PrintFixed: PROC = { ENABLE TeleDebOps.Failed => CONTINUE; end: TeleDebOps.STObject; found: BOOL; fobp: TeleLoad.CoreAddress; fob: FOB; caller, caller2: TeleDebOps.STObject; CheckHost[]; [item: end, found: found] _ TeleDebOps.FindVariable[host.program, "end"]; IF NOT found THEN { host.out.PutF["can't get symbol end\n"]; RETURN; }; fobp _ end.addr; IF (fobp MOD 2) # 0 THEN fobp _ fobp + 1; DO fob _ ReadFob[host: host, fobAddr: fobp]; IF fob.length = 0 THEN EXIT; caller _ TeleDebOps.ProcedureEnclosing[host.program, fob.owner]; caller2 _ TeleDebOps.ProcedureEnclosing[host.program, fob.owner2]; host.out.PutF["adr: %04xH, len: %5d ", IO.card[fobp + 6], IO.card[fob.length]]; host.out.PutF["own: %g+%x ", IO.rope[caller.id], IO.card[fob.owner - caller.addr]]; host.out.PutF["own2: %g+%x\n", IO.rope[caller2.id], IO.card[fob.owner2 - caller2.addr]]; fobp _ fobp + (fob.length * 2) + 6; ENDLOOP; }; PrintCtxStats: PROC = { ENABLE TeleDebOps.Failed => CONTINUE; ctxStats: TeleDebOps.STObject; found: BOOL; val: Inline.LongNumber; CheckHost[]; [item: ctxStats, found: found] _ TeleDebOps.FindVariable[host.program, "ctxListTime"]; IF NOT found THEN { host.out.PutF[". . cannot find symbol ctxListTime\n"]; RETURN; }; host.out.PutRope["Context list histogram:\n"]; FOR i: NAT IN [0..20) DO val.lowbits _ TeleDebOps.ReadWord[host, ctxStats.addr + (4*i)]; val.highbits _ TeleDebOps.ReadWord[host, ctxStats.addr + (4*i) + 2]; host.out.PutF["[%2d..%2d): %8d\n", IO.card[i], IO.card[i+1], IO.card[val.lc]]; ENDLOOP; val.lowbits _ TeleDebOps.ReadWord[host, ctxStats.addr + (4*20)]; val.highbits _ TeleDebOps.ReadWord[host, ctxStats.addr + (4*20) + 2]; host.out.PutF["ov: %8d\n", IO.card[val.lc]]; }; ResetCtxStats: PROC = { ENABLE TeleDebOps.Failed => CONTINUE; ctxStats: TeleDebOps.STObject; found: BOOL; CheckHost[]; [item: ctxStats, found: found] _ TeleDebOps.FindVariable[host.program, "ctxListTime"]; IF NOT found THEN { host.out.PutF[". . cannot find symbol ctxListTime\n"]; RETURN; }; FOR i: NAT IN [0..21) DO TeleDebOps.WriteWord[host, ctxStats.addr + (4*i), 0]; TeleDebOps.WriteWord[host, ctxStats.addr + (4*i) + 2, 0]; ENDLOOP; TeleDebOps.FlushWrites[host]; }; PrintV: PROC [name: Rope.ROPE, words: NAT _ 1] = { ENABLE TeleDebOps.Failed => CONTINUE; CheckHost[]; TeleDebOps.PrintVariable[host, name, words]; }; SetVal: PROC [name: Rope.ROPE, value: CARDINAL, offset: NAT _ 0] = { ENABLE TeleDebOps.Failed => CONTINUE; CheckHost[]; [] _ TeleDebOps.SetValue[host: host, name:name, value: value, offset: offset]; }; SetBlock: PROC [low, high: CARDINAL, value: CARDINAL] = { ENABLE TeleDebOps.Failed => CONTINUE; addr: TeleLoad.CoreAddress _ low; CheckHost[]; IF high <= low THEN RETURN; IF ((high - low) MOD 2) # 0 THEN high _ high - 1 ELSE high _ high - 2; DO TeleDebOps.WriteWord[host: host, addr: addr, value: value]; addr _ addr + 2; IF addr > high THEN EXIT; ENDLOOP; }; CheckBlock: PROC [low, high: CARDINAL, value: CARDINAL, ignore: NAT _ 1] = { ENABLE TeleDebOps.Failed => CONTINUE; addr: TeleLoad.CoreAddress _ low; newValue: CARDINAL; start, stop: TeleLoad.CoreAddress _ 0; inside: {out, in, leaving}; CheckHost[]; IF high <= low THEN RETURN; IF ((high - low) MOD 2) # 0 THEN high _ high - 1 ELSE high _ high - 2; ignore _ ignore * 2; DO newValue _ TeleDebOps.ReadWord[host: host, addr: addr]; SELECT inside FROM out => { IF (newValue # value) THEN { start _ addr; inside _ in; }; }; in => { IF (newValue = value) THEN { stop _ addr; inside _ leaving; }; }; leaving => { IF (newValue = value) THEN { IF addr - stop = ignore THEN { inside _ out; host.out.PutF["[%04xH..%04xH] bad\n", IO.card[start], IO.card[stop]]; }; IF (addr - stop) > ignore THEN ERROR; } ELSE { -- newValue # value IF (addr - stop) < ignore THEN inside _ in; IF (addr - stop) = ignore THEN { host.out.PutF["[%04xH..%04xH] bad\n", IO.card[start], IO.card[stop]]; start _ addr; inside _ in; }; IF (addr - stop) > ignore THEN ERROR; }; }; ENDCASE => ERROR; IF host.in.CharsAvail[] THEN EXIT; addr _ addr + 2; IF addr > high THEN EXIT; ENDLOOP; }; CheckHost: PROC = { IF host = NIL THEN ERROR TeleDebOps.Failed; }; SetHostByRef: PUBLIC PROC [h: TeleDebOps.TeleDebugData] = { host _ h; }; DspQ: PROC[addr: TeleLoad.CoreAddress] = { ENABLE TeleDebOps.Failed => CONTINUE; host.out.PutF["--------------\rQueue at %4X:\r", IO.card[addr]]; WHILE (addr _ TeleDebOps.ReadWord[host, addr])#0 DO host.out.PutF[" %4X\r", IO.card[addr]]; ENDLOOP; host.out.PutRope["----\r\r"]; }; DspStack: PROC[bp: TeleLoad.CoreAddress, initPC: TeleLoad.CoreAddress] = { ENABLE TeleDebOps.Failed => CONTINUE; FOR i: NAT IN [0..15) DO -- limit depth IF bp = 0 THEN EXIT; host.out.PutF[" BP, IP = (%4X, %4X) [...", IO.card[bp], IO.card[initPC]]; host.out.PutF["%4X, %4X, %4X, %4X]", IO.card[TeleDebOps.ReadWord[host, bp-4]], IO.card[TeleDebOps.ReadWord[host, bp-2]], IO.card[TeleDebOps.ReadWord[host, bp+4]], IO.card[TeleDebOps.ReadWord[host, bp+6]]]; host.out.PutF[" (in %g)\n", IO.rope[TeleDebOps.ProcedureEnclosing[host.program, initPC].id]]; initPC _ TeleDebOps.ReadWord[host, bp+2]; bp _ TeleDebOps.ReadWord[host, bp]; IF bp = 0 THEN EXIT; ENDLOOP; host.out.PutChar['\n]; }; zbCtx: LONG POINTER TO RPCCtx = LOOPHOLE[LONG[0]]; offsetSigVec: LONG CARDINAL = LOOPHOLE[@zbCtx.sigVec]; offsetMaxrun: LONG CARDINAL = LOOPHOLE[@zbCtx.maxrun]; ReadCoreBlock: PROC [addr: TeleLoad.CoreAddress, count: CARDINAL] RETURNS [cb: TeleLoad.CoreBlock] = { cb _ NEW[TeleLoad.CoreBlockObject[count]]; FOR i: NAT IN [0..cb.count) DO cb.data[i] _ TeleDebOps.Read[host, addr+i]; ENDLOOP; }; DspCtx: PROC [addr: TeleLoad.CoreAddress, running: BOOLEAN_FALSE ] = { ENABLE TeleDebOps.Failed => CONTINUE; cb: TeleLoad.CoreBlock _ ReadCoreBlock[addr, SIZE[RPCCtx] * 2]; ctx: LONG POINTER TO RPCCtx = LOOPHOLE[@(LOOPHOLE[cb, CoreWordBlock]).data[0]]; bp, ip: ShortCoreAddress; hwm: ShortCoreAddress; host.out.PutRope["Ctx: "]; DspCString[host, TeleDebOps.Swab[ctx.name]]; host.out.PutF["(%2x)%g at %4x, limit %4x", IO.card[TeleDebOps.Swab[ctx.myPSB]], IO.char[IF running THEN '@ ELSE '\040], IO.card[addr], IO.card[TeleDebOps.Swab[ctx.stackMin]]]; host.out.PutF[", sigVec at %4X\n", IO.card[LOOPHOLE[addr+offsetSigVec*2]]]; hwm _ HighWaterMark[TeleDebOps.Swab[ctx.stackMin]]; host.out.PutF[" max run %4d(10) due to %4x, high water mark at %4x\n", IO.card[TeleDebOps.Swab[ctx.maxrun]], IO.card[TeleDebOps.Swab[ctx.caller]], IO.card[hwm]]; IF running THEN { TeleDebOps.FetchState[host]; bp _ host.larkState[BP]; ip _ host.larkState[IP]; } ELSE { cbw: CoreWordBlock; cb _ TeleDebOps.GetCoreBlock[host, TeleDebOps.Swab[ctx.stack], 4]; cbw _ LOOPHOLE[cb]; bp _ TeleDebOps.Swab[cbw[0]]; ip _ TeleDebOps.Swab[cbw[1]]; }; DspStack[bp, ip]; }; SB: TYPE = RECORD [ length: CARDINAL, user: CARDINAL, pSbNext: CARDINAL, pSbPrevious: CARDINAL ]; ZN: TYPE = RECORD [ anchor: SB, rover: CARDINAL, minAdr: CARDINAL, maxAdr: CARDINAL ]; ReadZN: PROC [a: TeleLoad.CoreAddress] RETURNS [z: ZN] = { z.anchor _ ReadSB[a]; z.rover _ TeleDebOps.ReadWord[host, a+8]; z.minAdr _ TeleDebOps.ReadWord[host, a+10]; z.maxAdr _ TeleDebOps.ReadWord[host, a+12]; }; ReadSB: PROC [a: TeleLoad.CoreAddress] RETURNS [s: SB] = { s.length _ TeleDebOps.ReadWord[host, a]; s.user _ TeleDebOps.ReadWord[host, a+2]; s.pSbNext _ TeleDebOps.ReadWord[host, a+4]; s.pSbPrevious _ TeleDebOps.ReadWord[host, a+6]; }; PrintZone: PROC = { ENABLE TeleDebOps.Failed => CONTINUE; sysZone: TeleDebOps.STObject; zone: TeleLoad.CoreAddress; ia: CARDINAL; addit: INTEGER; z: ZN; s: SB; as: CARDINAL; found: BOOL; [item: sysZone, found: found] _ TeleDebOps.FindVariable[host.program, "sysZone"]; IF NOT found THEN { host.out.PutF["can't get sysZone\n"]; RETURN; }; zone _ TeleDebOps.ReadWord[host, sysZone.addr]; z _ ReadZN[zone]; IF TeleDebOps.ReadWord[host, z.maxAdr] # 177777B THEN { host.out.PutF["CallSwat(ecAllocate+7)\n"]; RETURN; }; ia _ z.minAdr; as _ ia; s _ ReadSB[as]; DO IF z.maxAdr <= as THEN EXIT; addit _ LOOPHOLE[s.length]; IF addit >= 0 THEN { host.out.PutF["adr: %04xH, len: %5d, prev: %04xH next: %04xH\n", IO.card[as], IO.card[addit], IO.card[s.pSbPrevious], IO.card[s.pSbNext]]; } ELSE { item: TeleDebOps.STObject _ TeleDebOps.ProcedureEnclosing[host.program, s.user]; addit _ -addit; host.out.PutF["adr: %04xH, len: %5d, usedby: %g+%x\n", IO.card[as], IO.card[addit], IO.rope[item.id], IO.card[s.user-item.addr]]; }; ia _ ia + addit; IF as > LOOPHOLE[ia, CARDINAL] THEN { host.out.PutF["CallSwat(ecAllocate+8)\n"]; RETURN; }; as _ ia; s _ ReadSB[as]; ENDLOOP; }; FOB: TYPE = RECORD [ owner: CARDINAL, owner2: CARDINAL, length: CARDINAL ]; ReadFob: PROC [host: TeleDebOps.TeleDebugData, fobAddr: TeleLoad.CoreAddress] RETURNS [f: FOB] = { f.owner _ TeleDebOps.ReadWord[host, fobAddr]; f.owner2 _ TeleDebOps.ReadWord[host, fobAddr + 2]; f.length _ TeleDebOps.ReadWord[host, fobAddr + 4]; }; HighWaterMark: PROC [stackLim: TeleLoad.CoreAddress] RETURNS [hwm: TeleLoad.CoreAddress] = { ENABLE TeleDebOps.Failed => CONTINUE; addr: TeleLoad.CoreAddress _ stackLim; DO IF TeleDebOps.ReadWord[host, addr]#0 THEN RETURN[addr+1]; addr _ addr+2; ENDLOOP; }; DspCString: PROC[host: TeleDebOps.TeleDebugData, addr: ShortCoreAddress ] = { ENABLE TeleDebOps.Failed => CONTINUE; FOR i: NAT IN [0..20) DO c: CHAR _ LOOPHOLE[TeleDebOps.Read[host, addr+i]]; IF c = '\000 THEN RETURN; host.out.PutChar[c]; ENDLOOP; }; DspPkt: PROC[addr: TeleLoad.CoreAddress] = { ENABLE TeleDebOps.Failed => CONTINUE; cb: TeleLoad.CoreBlock _ ReadCoreBlock[addr, RPCPkt.pktLengthOverhead*2]; header: LONG POINTER TO RPCPkt.Header; typ: Rope.ROPE _ PktType[header.type]; offset: NAT _ IF typ.Length[]=0 THEN 0 ELSE headerSize; IF cb=NIL THEN RETURN; header _ LOOPHOLE[@(LOOPHOLE[cb, CoreWordBlock]).data[0]]; host.out.PutF["--------------\r%d byte packet at %4X:\r%s (%3B) ", IO.card[header.length*2], IO.card[addr], IO.rope[typ], IO.card[cb.data[3]]]; host.out.PutF["[%2B#%3B#%2B](%4X)", IO.card[header.destHost.net], IO.card[header.destHost.host], IO.card[header.destSoc.b], IO.card[header.destPSB]]; host.out.PutF[" _ [%2B#%3B#%2B](%4X)\r", IO.card[header.srceHost.net], IO.card[header.srceHost.host], IO.card[header.srceSoc.b], IO.card[header.srcePSB]]; host.out.PutF["conv: %8Xx, id: [act: %4X, count: %8Xx, seq: %4X]\r", MesaDbl[@header.conv], IO.card[header.pktID.activity], MesaDbl[@header.pktID.callSeq], IO.card[header.pktID.pktSeq]]; host.out.PutF["disp: [mds: %4X, id: %8X, hint: %4X]\r", IO.card[header.dispatcher.mds], MesaDbl[@header.dispatcher.dispatcherID], IO.card[header.dispatcher.dispatcherHint]]; host.out.PutRope["Data:\r"]; IF header.length>0 AND header.length<105 THEN { TeleDebOps.Show[host, addr+offset, header.length*2-offset]; }; }; DspPBI: PROC[addr: TeleLoad.CoreAddress] = { ENABLE TeleDebOps.Failed => CONTINUE; cb: TeleLoad.CoreBlock _ ReadCoreBlock[addr, SIZE[PBIRecord]*2]; pbi: PBI; IF cb=NIL THEN RETURN; pbi _ LOOPHOLE[@(LOOPHOLE[cb, CoreWordBlock]).data[0]]; host.out.PutF["--------------\rPBI at %4X:\r", IO.card[addr]]; host.out.PutF["link: %4X\r queue: %4X, clientWord: %4X, pup: %4X\r", IO.card[TeleDebOps.Swab[pbi.link]], IO.card[TeleDebOps.Swab[pbi.queue]], IO.card[TeleDebOps.Swab[pbi.clientWord]], IO.card[TeleDebOps.Swab[pbi.pup]]]; DspPkt[TeleDebOps.Swab[pbi.pup]]; }; MesaDbl: PROC[addr: LONG POINTER] RETURNS [IO.Value] = { ln: Inline.LongNumber _ LOOPHOLE[addr, LONG POINTER TO Inline.LongNumber]^; ln.lowbits _ TeleDebOps.Swab[ln.lowbits]; ln.highbits _ TeleDebOps.Swab[ln.highbits]; RETURN[IO.card[ln.lc]]; }; PktType: PROC[type: RPCPkt.PktType] RETURNS [Rope.ROPE] = { t: Rope.ROPE_NIL; IF type.subType#rpc THEN RETURN[NIL]; IF type.eom=notEnd THEN t_"notEnd-"; IF type.ack=pleaseAck AND type.class=ack THEN RETURN[t.Concat["Ping"]]; t_t.Concat[SELECT type.class FROM call=>"Call", data=>"Data", ack=>"Ack", rfa=>"Rfa", ENDCASE=>"??"]; IF type.ack=pleaseAck THEN t_t.Concat["/Ack"]; RETURN[t]; }; PrintVariable: PUBLIC PROC [host: TeleDebOps.TeleDebugData, name: Rope.ROPE, words: NAT _ 1] = { ENABLE TeleDebOps.Failed => CONTINUE; ob: TeleDebOps.STObject; address: TeleLoad.CoreAddress; found: BOOL; [item: ob, found: found] _ TeleDebOps.FindVariable[host.program, name]; IF NOT found THEN { host.out.PutF[" %g: not found\n", IO.rope[name]]; } ELSE { -- fetch data and print it address _ ob.addr; host.out.PutF[" %g (%04xH^): ", IO.rope[name], IO.int[address]]; FOR i: NAT IN [0..words) DO host.out.PutF[" %04xH", IO.card[TeleDebOps.ReadWord[host, address + (i * 2)]]]; ENDLOOP; host.out.PutChar['\n]; }; }; SetValue: PUBLIC PROC [host: TeleDebOps.TeleDebugData, name: Rope.ROPE, value: CARDINAL, offset: NAT _ 0] RETURNS [BOOL] = {{ ENABLE TeleDebOps.Failed => CONTINUE; ob: TeleDebOps.STObject; address: TeleLoad.CoreAddress; found: BOOL; oldValue: CARDINAL; [item: ob, found: found] _ TeleDebOps.FindVariable[host.program, name]; IF NOT found THEN { host.out.PutF[" %g: not found\n", IO.rope[name]]; RETURN[FALSE]; } ELSE { -- fetch data and print it address _ ob.addr; host.out.PutF[" %g + %04xH (%04xH^): ", IO.rope[name], IO.card[offset], IO.card[address]]; oldValue _ TeleDebOps.ReadWord[host, address + offset]; IF ob.type = variable THEN { TeleDebOps.WriteWord[host: host, addr: address + offset, value: value]; TeleDebOps.FlushWrites[host]; host.out.PutF["%04xH _ %04xH\n", IO.card[oldValue], IO.card[value]]; } ELSE { host.out.PutF["%04xH . . . not a variable\n", IO.card[oldValue]]; RETURN[FALSE]; }; }; }; RETURN[TRUE]; }; }. >TDX.mesa Teledeb extra stuff Last modified by Stewart, April 4, 1983 8:06 pm RPCSystem substructure RPCUser substructure Procedures intended to be called from the interpreter addr is address of first context, not of context queue. PrintZone, if there is a zone! changes the word at offset from an identifier, use for patch decks internal procedures Linear search in symbol table lookup address changes the word at offset from an identifier, use for patch decks Linear search in symbol table lookup address Last modified by Swinehart, November 13, 1982 4:45 pm Last modified by Stewart, November 19, 1982 4:43 pm Last modified by Stewart, December 18, 1982 4:54 pm, better symtab stuff Last modified by Stewart, December 20, 1982 12:46 pm, PUBLICs Last modified by Stewart, February 16, 1983 9:52 pm, Binary search bug Ê›˜Jšœ™Jšœ™Jšœ/™/J˜šÏk ˜ J˜J˜Jšœ˜J˜ J˜J˜J˜ J˜ J˜—Jšœ˜ Jšœ œ˜.Jšœ˜J˜Jšœœ˜&J˜š œœœœœœ˜.J˜J˜Jšœœœœ˜*J˜J˜—Jšœ œœ˜-J˜šœ œœ˜JšœÏc ˜%Jšœž"˜;Jšœ œž"˜4Jšœž ˜ J˜J˜—Jš œœœœœ ˜&J˜Jšœœ˜5J˜šœœœ˜Jšœž ˜%Jšœž.˜GJšœž˜$Jšœž%˜BJšœž˜6J˜Jšœ™Jšœœ˜Jšœž˜9Jšœœœ œ˜#J˜Jšœ™Jšœœž'˜9Jšœž/˜IJ˜Jš œ œœ œžœ˜9—J™6J˜š Ïnœœœœœ˜6J˜0Jšœœ˜J˜J˜—šŸœœK˜XJšœœ˜%J˜ Jšœ7™7šœœ˜J˜Jšœœ˜ J˜NJšœœ.˜;šœ˜J˜)Jšœ˜J˜—J˜—šœœ˜J˜%Jšœœ˜ J˜hJšœœ>˜KJ˜—Jšœœœ˜.šœ˜Jšœœ œ˜*J˜%Jšœ˜—J˜J˜šŸ œœ&˜7Jšœœ˜%J˜ šœ œ˜J˜Jšœœ˜ J˜NJšœœ.˜;šœ˜J˜)Jšœ˜J˜—J˜—šœ ˜J˜EJ˜%Jšœ˜—J˜J˜J˜—J™J™—J˜šŸ œœ˜Jšœœ˜%J˜Jšœœ˜ J˜Jšœœ˜ J˜%J˜ J˜Išœœœ˜J˜(Jšœ˜J˜—J˜Jšœœœ˜)š˜J˜)Jšœœœ˜J˜@J˜BJšœ'œœ˜OJšœœœ ˜SJšœœœ"˜XJ˜#Jšœ˜—J˜J˜—šŸ œœ˜Jšœœ˜%J˜Jšœœ˜ J˜J˜ J˜Všœœœ˜J˜6Jšœ˜J˜—J˜.šœœœ ˜J˜?J˜DJšœ#œ œ œ˜NJšœ˜J˜@J˜E—Jšœœ˜,J˜J˜—šŸ œœ˜Jšœœ˜%J˜Jšœœ˜ J˜ J˜Všœœœ˜J˜6Jšœ˜J˜—šœœœ ˜J˜5J˜9Jšœ˜—J˜J˜J˜—šŸœœ œ œ ˜2Jšœœ˜%J˜ J˜,J˜J™—JšœB™Bš Ÿœœ œ œ œ ˜DJšœœ˜%J˜ J˜NJ˜J˜—šŸœœ œ œ˜9Jšœœ˜%J˜!J˜ Jšœ œœ˜Jšœœœ˜0Jšœ˜š˜J˜;J˜Jšœ œœ˜Jšœ˜—J˜J˜—š Ÿ œœ œ œ œ ˜LJšœœ˜%J˜!Jšœ œ˜J˜&J˜J˜ Jšœ œœ˜Jšœœœ˜0Jšœ˜J˜š˜J˜7šœ˜˜šœœ˜J˜ J˜ J˜—J˜—˜šœœ˜J˜ J˜J˜—J˜—˜ šœœ˜šœœ˜J˜ Jšœ&œœ ˜EJ˜—Jšœœœ˜%J˜—šœž˜Jšœœ ˜+šœœ˜ Jšœ&œœ ˜EJ˜ J˜ J˜—Jšœœœ˜%J˜—J˜—Jšœœ˜—Jšœœœ˜"J˜Jšœ œœ˜Jšœ˜—J˜J˜—J™J™šŸ œœ˜Jšœœœœ˜+J˜J˜—J™šŸ œœœ"˜;J˜ J˜J˜—šŸœœ ˜*Jšœœ˜%Jšœ1œ ˜@šœ,˜3Jšœœ ˜(Jšœ˜—J˜J˜J˜—šŸœœ<˜JJšœœ˜%š œœœ œž˜'Jšœœœ˜Jšœ-œ œ˜K˜$Jšœ(œ(œ(œ(˜¨—Jšœœ?˜]J˜)J˜#Jšœœœ˜Jšœ˜—J˜J˜J˜—Jš œœœœ œœ˜2Jšœœœœ˜6Jšœœœœ˜6J˜šŸ œœ%œœ˜fJšœœ"˜*Jš œœœœ-œ˜SJ˜J˜—šŸœœ'œœ˜FJšœœ˜%Jšœ-œ˜?Jš œœœœ œœ˜OJ˜J˜J˜J˜,˜*Jš œ#œœ œœ˜LJšœ œ&˜7—Jšœ#œœ˜KJ˜3˜FJšœ$œ$œ ˜Z—šœ œ˜J˜Jšœœ˜Jšœœ˜—šœ˜J˜J˜BJšœœ˜J˜J˜J˜—J˜J˜J˜—šœœœ˜Jšœœ˜Jšœœ˜Jšœ œ˜Jšœ ˜J˜J˜—šœœœ˜Jšœœ˜ Jšœœ˜Jšœœ˜Jšœ˜J˜J˜—šŸœœœœ˜:J˜J˜)J˜+J˜+J˜J˜—šŸœœœœ˜:J˜(J˜(J˜+J˜/J˜J˜—šŸ œœ˜Jšœœ˜%J˜J˜Jšœœ˜ Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜ Jšœœ˜ J˜Qšœœœ˜J˜%Jšœ˜J˜—J˜/J˜šœ/œ˜7J˜*Jšœ˜J˜—J˜J˜J˜š˜Jšœœœ˜Jšœœ ˜šœ œ˜Jš œAœ œœœ˜ŠJ˜—šœ˜J˜PJ˜Jš œ7œ œœœ˜J˜—J˜šœœœœ˜%J˜*Jšœ˜J˜—J˜J˜Jšœ˜—J˜J˜—šœœœ˜Jšœœ˜Jšœœ˜Jšœ˜J˜J˜—šŸœœAœœ˜bJ˜-J˜2J˜2J˜J˜—šŸ œœ"œ ˜\Jšœœ˜%J˜&š˜Jšœ#œœ ˜9J˜Jšœ˜—J˜J˜—šŸ œœ>˜NJšœœ˜%šœœœ ˜Jšœœœ ˜2Jšœ œœ˜J˜Jšœ˜—J˜J˜—šŸœœ ˜,Jšœœ˜%J˜IJšœœœœ˜&Jšœ œ˜&Jš œœœœœ ˜7Jšœœœœ˜Jšœ œœ˜:˜CJšœœ œ œ˜L—˜#Jšœœœ˜WJšœ˜—˜(Jšœœœ˜WJšœ˜—˜DJšœœ˜6Jšœ œ˜>—˜7JšœG˜IJšœ)˜+—J˜šœœœ˜/J˜;J˜—J˜J˜—šŸœœ ˜,Jšœœ˜%Jšœ-œ˜@Jšœœ˜ Jšœœœœ˜Jšœœœ˜7Jšœ/œ ˜>˜DJšœ"œ#œ'˜rJšœ!˜#—J˜!J˜J˜—šŸœœœœ˜!Jšœœ ˜Jš œœœœœ˜KJšœ)˜)Jšœ+˜+Jšœœ˜J˜—šŸœœœœ˜;Jšœœœ˜Jšœœœœ˜%Jšœœ ˜$Jšœœœœ˜Gšœ œ ˜!Jšœ4œ˜C—Jšœœ˜.Jšœ˜ J˜—š Ÿ œœœ-œ œ ˜`Jšœœ˜%J˜J˜Jšœœ˜ Jšœ™J˜GJšœ™šœœœ˜Jšœ#œ ˜2J˜—šœž˜!J˜Jšœ!œ œ˜Ašœœœ ˜Jšœœ5˜OJšœ˜—J˜J˜—J˜J˜—JšœB™BšŸœœœ-œ œ œœœ˜}Jšœœ˜%J˜J˜Jšœœ˜ Jšœ œ˜Jšœ™J˜GJšœ™šœœœ˜Jšœ#œ ˜2Jšœœ˜J˜—šœž˜!J˜Jšœ)œ œœ˜[J˜7šœœ˜J˜GJ˜Jšœ!œœ˜DJ˜—šœ˜Jšœ.œ˜AJšœœ˜J˜—J˜—J˜Jšœœ˜ J˜J˜—J˜Jšœ6™6Jšœ3™3JšœH™HJšœ=™=JšœF™F—…—?.U