DIRECTORY Atom USING [GetPName, GetPropFromList, PropList, PutPropOnList, RemPropFromList], Basics USING [FWORD, HWORD, CopyBytes, RawBytes, UnsafeBlock], IO, IOErrorFormatting, IOUtils USING [], PreDebug USING [Explainer, Raise, RegisterErrorExplainer], RefText USING [InlineAppendChar, New], Rope USING [Cat, Concat, Length, ROPE], RuntimeError USING [BoundsFault]; IOCommonImpl: CEDAR PROGRAM IMPORTS Basics, IO, Atom, PreDebug, RefText, Rope, RuntimeError EXPORTS IO, IOErrorFormatting, IOUtils SHARES IO --for representation of StreamProcs = BEGIN OPEN IO; ROPE: TYPE = Rope.ROPE; RawBytes: TYPE = Basics.RawBytes; UnsafeBlock: TYPE = Basics.UnsafeBlock; Error: PUBLIC ERROR [ec: IO.ErrorCode, stream: STREAM, details: LIST OF REF ¬ NIL, msg: ROPE ¬ NIL] = CODE; EndOfStream: PUBLIC ERROR [stream: STREAM] = CODE; Rubout: PUBLIC ERROR [stream: STREAM] = CODE; Timeout: PUBLIC SIGNAL [which: REF, codes: LIST OF ATOM, msg: ROPE] = CODE; AtomFromErrorCode: PUBLIC PROC [ec: ErrorCode] RETURNS [ATOM] ~ { SELECT ec FROM Null => RETURN[$Null]; NotImplementedForThisStream => RETURN[$NotImplementedForThisStream]; StreamClosed => RETURN[$StreamClosed]; Failure => RETURN[$Failure]; IllegalBackup => RETURN[$IllegalBackup]; BufferOverflow => RETURN[$BufferOverflow]; BadIndex => RETURN[$BadIndex]; SyntaxError => RETURN[$SyntaxError]; PFInvalidCode => RETURN[$PFInvalidCode]; PFInvalidPFProcs => RETURN[$PFInvalidPFProcs]; PFCantBindConversionProc => RETURN[$PFCantBindConversionProc]; PFFormatSyntaxError => RETURN[$PFFormatSyntaxError]; PFUnprintableValue => RETURN[$PFUnprintableValue]; ENDCASE => RETURN[NIL]; }; ErrorCodeFromAtom: PUBLIC PROC [atom: ATOM] RETURNS [ErrorCode] ~ { SELECT atom FROM $Null => RETURN[Null]; $NotImplementedForThisStream => RETURN[NotImplementedForThisStream]; $StreamClosed => RETURN[StreamClosed]; $Failure => RETURN[Failure]; $IllegalBackup => RETURN[IllegalBackup]; $BufferOverflow => RETURN[BufferOverflow]; $BadIndex => RETURN[BadIndex]; $SyntaxError => RETURN[SyntaxError]; $PFInvalidCode => RETURN[PFInvalidCode]; $PFInvalidPFProcs => RETURN[PFInvalidPFProcs]; $PFCantBindConversionProc => RETURN[PFCantBindConversionProc]; $PFFormatSyntaxError => RETURN[PFFormatSyntaxError]; $PFUnprintableValue => RETURN[PFUnprintableValue]; ENDCASE => RETURN[ErrorCode.LAST]; }; RopeFromErrorCode: PUBLIC PROC [ec: ErrorCode] RETURNS [ROPE] ~ { a: ATOM ~ AtomFromErrorCode[ec]; IF a=NIL THEN RETURN IO.PutFR1["code %g", [cardinal[ec.ORD]] ] ELSE RETURN [Atom.GetPName[a]]}; FormatError: PUBLIC PROC [ec: ErrorCode, details: LIST OF REF ¬ NIL, msg: ROPE ¬ NIL] RETURNS [rope: ROPE] ~ { rope ¬ Rope.Concat["IO.Error[", RopeFromErrorCode[ec]]; IF msg.Length[]>0 THEN rope ¬ rope.Cat[": ", msg]; IF details#NIL THEN { rope ¬ IO.PutFR["%g (%g", [rope[rope]], [refAny[details.first]] ]; FOR details ¬ details.rest, details.rest WHILE details#NIL DO rope ¬ rope.Cat["/", IO.PutR1[[refAny[details.first]]]]; ENDLOOP; rope ¬ rope.Concat[")]"]} ELSE rope ¬ rope.Concat["]"]; RETURN}; ExplainIOError: PreDebug.Explainer = { message: ROPE ¬ "IO.Error"; IF args#NIL THEN PreDebug.Raise[signalOrError, args ! Error => { message ¬ IO.PutFR["%g (ec: %g) %g", IO.rope[message], IO.card[ORD[ec]], IO.rope[msg]]; CONTINUE }]; RETURN [message] }; ExplainEndOfStream: PreDebug.Explainer = { RETURN["EndOfStream"]; }; ExplainRubout: PreDebug.Explainer = { RETURN["Rubout"]; }; CreateStreamProcs: PUBLIC PROC [ variety: IO.StreamVariety, class: ATOM, getChar: GetCharProc ¬ NIL, getBlock: GetBlockProc ¬ NIL, unsafeGetBlock: UnsafeGetBlockProc ¬ NIL, endOf: EndOfProc ¬ NIL, charsAvail: CharsAvailProc ¬ NIL, backup: BackupProc ¬ NIL, putChar: PutCharProc ¬ NIL, putBlock: PutBlockProc ¬ NIL, unsafePutBlock: UnsafePutBlockProc ¬ NIL, flush: FlushProc ¬ NIL, reset: ResetProc ¬ NIL, close: CloseProc ¬ NIL, getIndex: GetIndexProc ¬ NIL, setIndex: SetIndexProc ¬ NIL, getLength: GetLengthProc ¬ NIL, setLength: SetLengthProc ¬ NIL, eraseChar: EraseCharProc ¬ NIL ] RETURNS [REF StreamProcs] = { streamProcs: REF StreamProcs ¬ NEW[StreamProcs ¬ [ variety: variety, class: class, getChar: IF getChar # NIL THEN getChar ELSE IF unsafeGetBlock # NIL THEN GetCharViaUnsafeGetBlock ELSE DefaultGetChar, getBlock: IF getBlock # NIL THEN getBlock ELSE IF unsafeGetBlock # NIL THEN GetBlockViaUnsafeGetBlock ELSE GetBlockViaGetChar, unsafeGetBlock: IF unsafeGetBlock # NIL THEN unsafeGetBlock ELSE UnsafeGetBlockViaGetChar, endOf: IF endOf = NIL THEN DefaultEndOf ELSE endOf, charsAvail: IF charsAvail = NIL THEN DefaultCharsAvail ELSE charsAvail, backup: IF backup = NIL THEN DefaultBackup ELSE backup, putChar: IF putChar # NIL THEN putChar ELSE IF unsafePutBlock # NIL THEN PutCharViaUnsafePutBlock ELSE DefaultPutChar, putBlock: IF putBlock # NIL THEN putBlock ELSE IF unsafePutBlock # NIL THEN PutBlockViaUnsafePutBlock ELSE PutBlockViaPutChar, unsafePutBlock: IF unsafePutBlock # NIL THEN unsafePutBlock ELSE UnsafePutBlockViaPutChar, flush: IF flush = NIL THEN DefaultFlush ELSE flush, reset: IF reset = NIL THEN DefaultReset ELSE reset, close: IF close = NIL THEN DefaultClose ELSE close, getIndex: IF getIndex = NIL THEN DefaultGetIndex ELSE getIndex, setIndex: IF setIndex = NIL THEN DefaultSetIndex ELSE setIndex, getLength: IF getLength = NIL THEN DefaultGetLength ELSE getLength, setLength: IF setLength = NIL THEN DefaultSetLength ELSE setLength, eraseChar: IF eraseChar = NIL THEN DefaultEraseChar ELSE eraseChar, propList: NIL]]; RETURN[streamProcs]; }; CreateStream: PUBLIC PROC [streamProcs: REF StreamProcs, streamData: REF ANY, backingStream: STREAM ¬ NIL] RETURNS [stream: STREAM] = { stream ¬ NEW[IO.STREAMRecord ¬ [streamProcs: streamProcs, streamData: streamData, backingStream: backingStream]]; }; TextPtr: PROC [text: REF READONLY TEXT] RETURNS [POINTER TO RawBytes] ~ INLINE { RETURN[LOOPHOLE[text, POINTER TO RawBytes]+SIZE[TEXT[0]]]; }; GetBlockViaGetChar: PUBLIC PROC [self: STREAM, block: REF TEXT, startIndex: NAT, count: NAT] RETURNS [nBytesRead: NAT] = { rem: NAT ~ block.maxLength-startIndex; -- BoundsFault if startIndex>block.maxLength index: NAT ¬ startIndex; { ENABLE EndOfStream => CONTINUE; THROUGH [0..MIN[count, rem]) DO block[index] ¬ IO.InlineGetChar[self]; index ¬ index+1; ENDLOOP; }; block.length ¬ index; RETURN[index-startIndex]; }; UnsafeGetBlockViaGetChar: PUBLIC UNSAFE PROC [self: STREAM, block: UnsafeBlock] RETURNS [nBytesRead: INT] = { startIndex: CARD ~ block.startIndex; -- BoundsFault if block.startIndex<0 count: CARD ~ block.count; -- BoundsFault if block.count<0 index: CARD ¬ startIndex; { ENABLE EndOfStream => CONTINUE; THROUGH [0..count) DO TRUSTED { block.base[index] ¬ ORD[IO.InlineGetChar[self]] }; -- UNSAFE! index ¬ index+1; ENDLOOP; }; RETURN[index-startIndex]; }; GetCharViaUnsafeGetBlock: PUBLIC PROC [self: STREAM] RETURNS [CHAR] = TRUSTED { buff: ARRAY [0..BYTES[WORD]) OF BYTE; base: POINTER TO RawBytes ~ LOOPHOLE[@buff]; IF self.streamProcs.unsafeGetBlock[self, [base: base, startIndex: 0, count: 1]] = 1 THEN RETURN[VAL[base[0]]] ELSE ERROR EndOfStream[self]; }; GetBlockViaUnsafeGetBlock: PUBLIC PROC [self: IO.STREAM, block: REF TEXT, startIndex: NAT, count: NAT] RETURNS [nBytesRead: NAT] = { rem: NAT ~ block.maxLength-startIndex; -- BoundsFault if startIndex>block.maxLength TRUSTED { nBytesRead ¬ self.streamProcs.unsafeGetBlock[self, [base: TextPtr[block], startIndex: startIndex, count: MIN[count, rem]]] }; block.length ¬ startIndex+nBytesRead; }; PutBlockViaPutChar: PUBLIC PROC [self: STREAM, block: REF READONLY TEXT, startIndex: NAT, count: NAT] = { rem: NAT ~ block.maxLength-startIndex; -- BoundsFault if startIndex>block.maxLength len: NAT ~ IF count>rem THEN MIN[rem, block.length-startIndex] ELSE count; FOR i: NAT IN [startIndex..startIndex+len) DO IO.InlinePutChar[self, IO.QFetch[block, i]]; ENDLOOP; }; UnsafePutBlockViaPutChar: PUBLIC PROC [self: STREAM, block: UnsafeBlock] = { startIndex: CARD ~ block.startIndex; -- BoundsFault if block.startIndex<0 count: CARD ~ block.count; -- BoundsFault if block.count<0 FOR i: CARD IN [startIndex..startIndex+count) DO TRUSTED { IO.InlinePutChar[self, VAL[block.base[i]]] }; ENDLOOP; }; PutCharViaUnsafePutBlock: PUBLIC PROC [self: STREAM, char: CHAR] = TRUSTED { buff: ARRAY [0..BYTES[WORD]) OF BYTE; base: POINTER TO RawBytes ~ LOOPHOLE[@buff]; base[0] ¬ ORD[char]; self.streamProcs.unsafePutBlock[self, [base: base, startIndex: 0, count: 1]]; }; PutBlockViaUnsafePutBlock: PUBLIC PROC [self: STREAM, block: REF READONLY TEXT, startIndex: NAT, count: NAT] = { rem: NAT ~ block.maxLength-startIndex; -- BoundsFault if startIndex>block.maxLength len: NAT ~ IF count>rem THEN MIN[rem, block.length-startIndex] ELSE count; self.streamProcs.unsafePutBlock[self, [base: TextPtr[block], startIndex: startIndex, count: len]]; }; DefaultGetChar: PROC [self: STREAM] RETURNS [CHAR] = { IF self.backingStream#NIL THEN RETURN[IO.InlineGetChar[self.backingStream]] ELSE ERROR Error[$NotImplementedForThisStream, self]; }; DefaultEndOf: PROC [self: STREAM] RETURNS [BOOL] = { IF self.backingStream#NIL THEN RETURN IO.InlineEndOf[self.backingStream] ELSE ERROR IO.Error[$NotImplementedForThisStream, self]; }; DefaultCharsAvail: PROC [self: STREAM, wait: BOOL] RETURNS [INT] = { IF self.backingStream#NIL THEN RETURN IO.CharsAvail[self.backingStream, wait] ELSE RETURN[INT.LAST]; }; DefaultPutChar: PROC [self: STREAM, char: CHAR] = { IF self.backingStream#NIL THEN IO.InlinePutChar[self.backingStream, char] ELSE ERROR IO.Error[$NotImplementedForThisStream, self]; }; DefaultFlush: PROC [self: STREAM] = { IF self.backingStream#NIL THEN IO.Flush[self.backingStream]; }; DefaultReset: PROC [self: STREAM] = { IF self.backingStream#NIL THEN IO.Reset[self.backingStream]; }; DefaultClose: PROC [self: STREAM, abort: BOOL ¬ FALSE] = { IF abort THEN self.streamProcs.reset[self] ELSE self.streamProcs.flush[self]; IF self.backingStream#NIL THEN IO.Close[self.backingStream, abort]; self­ ¬ [streamProcs: closedStreamProcs]; }; DefaultGetIndex: PROC [self: STREAM] RETURNS [index: INT] = { IF self.backingStream#NIL THEN RETURN IO.GetIndex[self.backingStream] ELSE ERROR IO.Error[$NotImplementedForThisStream, self]; }; DefaultSetIndex: PROC [self: STREAM, index: INT] = { IF self.backingStream#NIL THEN IO.SetIndex[self.backingStream, index] ELSE ERROR IO.Error[$NotImplementedForThisStream, self]; }; DefaultGetLength: PROC [self: STREAM] RETURNS [length: INT] = { IF self.backingStream#NIL THEN RETURN IO.GetLength[self.backingStream] ELSE ERROR IO.Error[$NotImplementedForThisStream, self]; }; DefaultSetLength: PROC [self: STREAM, length: INT] = { IF self.backingStream#NIL THEN IO.SetLength[self.backingStream, length] ELSE ERROR IO.Error[$NotImplementedForThisStream, self]; }; DefaultEraseChar: PROC [self: STREAM, char: CHAR] = { IF self.backingStream#NIL THEN IO.EraseChar[self.backingStream, char] ELSE { IO.PutChar[self, '\\]; IO.PutChar[self, char] }; }; closedStreamProcs: PUBLIC REF StreamProcs ¬ NEW[StreamProcs ¬ [ variety: $inputOutput, class: $Closed, getChar: ClosedGetChar, getBlock: ClosedGetBlock, unsafeGetBlock: ClosedUnsafeGetBlock, endOf: ClosedEndOf, charsAvail: ClosedCharsAvail, backup: ClosedBackup, putChar: ClosedPutChar, putBlock: ClosedPutBlock, unsafePutBlock: ClosedUnsafePutBlock, flush: ClosedFlush, reset: ClosedReset, close: ClosedClose, getIndex: ClosedGetIndex, setIndex: ClosedSetIndex, getLength: ClosedGetLength, setLength: ClosedSetLength, eraseChar: ClosedEraseChar, propList: NIL]]; ClosedGetChar: GetCharProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedGetBlock: GetBlockProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedUnsafeGetBlock: UnsafeGetBlockProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedEndOf: EndOfProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedCharsAvail: CharsAvailProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedBackup: BackupProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedPutChar: PutCharProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedPutBlock: PutBlockProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedUnsafePutBlock: UnsafePutBlockProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedFlush: FlushProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedReset: ResetProc = { -- *noop* -- }; ClosedClose: CloseProc = { -- *noop* -- }; ClosedGetIndex: GetIndexProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedSetIndex: SetIndexProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedGetLength: GetLengthProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedSetLength: SetLengthProc = { ERROR IO.Error[$StreamClosed, self] }; ClosedEraseChar: EraseCharProc = { ERROR IO.Error[$StreamClosed, self] }; GetInfo: PUBLIC PROC [stream: STREAM] RETURNS [variety: StreamVariety, class: ATOM] = { RETURN [stream.streamProcs.variety, stream.streamProcs.class]; }; GetChar: PUBLIC PROC [self: STREAM] RETURNS [CHAR] = { i: NAT ~ self.bufferIndex; IF i < self.bufferInputLength THEN { self.bufferIndex ¬ i+1; RETURN[IO.QFetch[self.buffer, i]] } ELSE RETURN[self.streamProcs.getChar[self]]; }; GetBlock: PUBLIC PROC [self: STREAM, block: REF TEXT, startIndex: NAT ¬ 0, count: NAT ¬ NAT.LAST] RETURNS [nBytesRead: NAT] = { rem: NAT ~ block.maxLength-startIndex; -- BoundsFault if startIndex>block.maxLength len: NAT ~ MIN[count, rem]; i: NAT ~ self.bufferIndex; IF i= self.bufferInputLength) AND self.streamProcs.endOf[self]]; }; CharsAvail: PUBLIC PROC [self: STREAM, wait: BOOL ¬ FALSE] RETURNS [INT] = { RETURN[self.streamProcs.charsAvail[self, wait]]; }; Backup: PUBLIC PROC [self: STREAM, char: CHAR] = { i: NAT ~ self.bufferIndex; IF i > 0 AND i <= self.bufferInputLength THEN { k: NAT ~ i-1; IF self.buffer[k]=char THEN self.bufferIndex ¬ k ELSE ERROR IO.Error[$IllegalBackup, self]; } ELSE self.streamProcs.backup[self, char]; }; PeekChar: PUBLIC PROC [self: STREAM] RETURNS [char: CHAR] = { i: NAT ~ self.bufferIndex; IF i < self.bufferInputLength THEN RETURN[IO.QFetch[self.buffer, i]] ELSE Backup[self, (char ¬ self.streamProcs.getChar[self])]; }; PutChar: PUBLIC PROC [self: STREAM, char: CHAR] = { i: NAT ~ self.bufferIndex; IF i < self.bufferOutputLength THEN { self.bufferIndex ¬ i+1; self.buffer[i] ¬ char } ELSE self.streamProcs.putChar[self, char]; }; PutBlock: PUBLIC PROC [self: STREAM, block: REF READONLY TEXT, startIndex: NAT ¬ 0, count: NAT ¬ NAT.LAST] = { rem: NAT ~ block.maxLength-startIndex; -- BoundsFault if startIndex>block.maxLength len: NAT ~ IF count>rem THEN MIN[rem, block.length-startIndex] ELSE count; bufferOutputLength: NAT ~ IF self.buffer=NIL THEN 0 ELSE MIN[self.buffer.maxLength, self.bufferOutputLength]; i: NAT ~ self.bufferIndex; IF i ERROR IO.Error[BufferOverflow, self]]; }; BackupGetChar: PROC [self: STREAM] RETURNS [char: CHAR] = { data: BackupData = NARROW[self.streamData]; char ¬ data.buffer[data.buffer.length - 1]; data.buffer.length ¬ data.buffer.length - 1; IF data.buffer.length = 0 THEN UnAmbushStream[self]; RETURN[char]; }; BackupEndOf: PROC [self: STREAM] RETURNS [BOOL] = { RETURN[FALSE]; }; BackupCharsAvail: PROC [self: STREAM, wait: BOOL] RETURNS [INT] = { data: BackupData = NARROW[self.streamData]; IF data.buffer.length > 0 THEN RETURN [data.buffer.length]; RETURN[self.backingStream.CharsAvail[wait]]; }; BackupReset: PROC [self: STREAM] = { data: BackupData = NARROW[self.streamData]; data.buffer.length ¬ 0; UnAmbushStream[self]; self.Reset[]; }; PreDebug.RegisterErrorExplainer[Error, ExplainIOError]; PreDebug.RegisterErrorExplainer[EndOfStream, ExplainEndOfStream]; PreDebug.RegisterErrorExplainer[Rubout, ExplainRubout]; END. 4IOCommonImpl.mesa Copyright Σ 1985, 1986, 1987, 1989, 1991, 1992 by Xerox Corporation. All rights reserved. MBrown on January 13, 1984 2:15 pm Paul Rovner on May 26, 1983 2:00 pm Teitelman on April 20, 1983 2:52 pm Russ Atkinson (RRA) November 14, 1989 4:56:53 pm PST JKF August 26, 1988 3:24:36 pm PDT Willie-Sue Orr/ Alan Demers, November 13, 1989 6:45:56 pm PST Christian Jacobi, July 25, 1990 8:18 pm PDT Michael Plass, August 9, 1991 9:58 am PDT Willie-s, February 4, 1992 5:02 pm PST Last tweaked by Mike Spreitzer March 26, 1992 4:59 pm PST Doug Wyatt, April 10, 1992 6:12 pm PDT Types Errors Creating streams Default Procedures: Get/Put Char/Block Default Procedures: others Closed Stream Procedures General information Input operations Output Operations (defined for output and inputOutput streams) Control Operations (defined for all streams) Other Get/Put Operations Special Control Operations (defined for file-like streams) Ambush / UnAmbush Stream Property list manipulation Default Backup implementation This is the implementation of Backup supplied by CreateStreamProcs when the client does not supply its own. This implementation ambushes the stream self. The stream created by the ambushing is saved so that it can be reused if the stream enters the backed-up state often. -- first time for this particular stream this is the implementation of Backup when a stream is in the backed-up state from a call to BackupFirstChar. Change Log Changed by MBrown on October 25, 1983 1:18 pm Added "IF NOT debugClose THEN self.streamProcs ¬ closedStreamProcs;" to DefaultClose (default is debugClose = TRUE because compiler and binder break otherwise ...) Changed by MBrown on November 15, 1983 5:25 pm Fixed off-by-one error in BackupGetChar. Michael Plass, Doug Wyatt, August 6, 1991 Cedar10.0 conversion Κ~•NewlineDelimiter –"cedarcode" style˜codešœ™Kšœ ΟeœO™ZKšœ Οc™"Kšœž™#Kšž œž™#J™4K™#K™=K™,K™)K™&K™9K™&—K˜šΟk ˜ KšœŸœG˜QKšœŸœŸœŸœ$˜>KšŸœ˜K˜KšœŸœ˜Kšœ Ÿœ,˜:KšœŸœ˜&KšœŸœŸœ˜'Kšœ Ÿœ˜!—K˜šΟn œŸœŸœ˜KšŸœ Ÿœ-˜?KšŸœŸœ˜&KšŸœŸœž#˜-KšœŸœŸœŸœ˜—K˜head™KšŸœŸœŸœ˜Kšœ Ÿœ˜!Kšœ Ÿœ˜'—šœ™Kš œŸœŸœŸœ ŸœŸœŸœŸœŸœŸœŸœ˜kKš   œŸœŸœ ŸœŸœ˜2Kš  œŸœŸœ ŸœŸœ˜-š œŸœŸœ Ÿœ ŸœŸœŸœŸœŸœ˜KK˜—š  œŸœŸœŸœŸœ˜AšŸœŸ˜KšœŸœ˜KšœŸœ˜DKšœŸœ˜&Kšœ Ÿœ ˜KšœŸœ˜(KšœŸœ˜*Kšœ Ÿœ ˜KšœŸœ˜$KšœŸœ˜(KšœŸœ˜.KšœŸœ˜>KšœŸœ˜4KšœŸœ˜2KšŸœŸœŸœ˜—K˜K˜—š  œŸœŸœŸœŸœ˜CšŸœŸ˜Kšœ Ÿœ˜Kšœ Ÿœ˜DKšœŸœ˜&Kšœ Ÿœ ˜KšœŸœ˜(KšœŸœ˜*Kšœ Ÿœ ˜KšœŸœ˜$KšœŸœ˜(KšœŸœ˜.KšœŸœ˜>KšœŸœ˜4KšœŸœ˜2KšŸœŸœ Ÿœ˜"—K˜K˜—š  œŸœŸœŸœŸœ˜AKšœŸœ˜ Kš ŸœŸœŸœŸœŸœ Ÿœ˜>KšŸœŸœ˜ K˜—š  œŸœŸœŸœŸœŸœŸœŸœŸœŸœŸœ˜nK˜7KšŸœŸœ˜2šŸœ ŸœŸœ˜KšœŸœ9˜BšŸœ&Ÿœ ŸœŸ˜=KšœŸœ!˜8KšŸœ˜—K˜—KšŸœ˜KšŸœ˜—K˜š œ˜&Kšœ Ÿœ˜šŸœŸœŸœ0˜@Kš œ ŸœŸœŸœŸœŸœ ˜WKšŸ˜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šŸœŸœ˜šœ ŸœŸœ˜2Kšœ˜K˜ šœ Ÿœ ŸœŸœ˜&KšŸœŸœŸœŸœ˜:KšŸœ˜—šœ Ÿœ ŸœŸœ ˜)KšŸœŸœŸœŸœ˜;KšŸœ˜—šœŸœŸœŸœ˜;KšŸœ˜—Kš œŸœ ŸœŸœŸœ˜4Kš œ ŸœŸœŸœŸœ˜KKš œŸœ ŸœŸœŸœ˜7šœ Ÿœ ŸœŸœ˜&KšŸœŸœŸœŸœ˜:KšŸœ˜—šœ Ÿœ ŸœŸœ ˜)KšŸœŸœŸœŸœ˜;KšŸœ˜—šœŸœŸœŸœ˜;KšŸœ˜—Kš œŸœ ŸœŸœŸœ˜4Kš œŸœ ŸœŸœŸœ˜4Kš œŸœ ŸœŸœŸœ˜4Kš œ Ÿœ ŸœŸœŸœ ˜?Kš œ Ÿœ ŸœŸœŸœ ˜?Kš œ Ÿœ ŸœŸœŸœ ˜CKš œ Ÿœ ŸœŸœŸœ ˜CKš œ Ÿœ ŸœŸœŸœ ˜CKšœ Ÿœ˜—KšŸœ˜Kšœ˜K˜—š  œŸœŸœŸœŸœŸœŸœŸœŸœ Ÿœ˜‡Kšœ ŸœŸœb˜qKšœ˜K˜——šœ&™&š œŸœŸœŸœŸœŸœŸœŸœ Ÿœ˜PKš ŸœŸœŸœŸœ ŸœŸœ˜:Kšœ˜K˜—š œŸ œŸœ ŸœŸœŸœ ŸœŸ œ Ÿœ˜zKšœŸœΟrœ ž,˜SKšœŸœ˜šœŸœŸœ˜!šŸœŸœŸ˜Kš‘Ÿœ‘˜&Kšœ˜KšŸœ˜—K˜—Kš‘˜KšΠkr‘˜K˜K˜—š œŸœŸœŸœŸœŸœŸœ˜mKšœ Ÿœž$˜IKšœŸœž˜:KšœŸœ˜šœŸœŸœ˜!šŸœ Ÿ˜KšŸœŸœŸœž ˜GKšœ˜KšŸœ˜—K˜—Kš’‘˜Kšœ˜K˜—š œŸœŸœŸœŸœŸœŸœ˜OKš œŸœŸœŸœŸœŸœ˜%KšœŸœŸœ Ÿœ˜,šŸœQ˜SKšŸœŸœŸœ ˜KšŸœŸœ˜—K˜K˜—š œŸœŸœŸœŸœ ŸœŸœŸœ ŸœŸ œ Ÿœ˜„KšœŸœ‘œ ž,˜SKšŸœlŸœ˜‡Kš‘œ ˜%Kšœ˜K™—š œŸœŸœŸœ ŸœŸœŸœŸœ Ÿœ˜iKšœŸœ‘œ ž,˜SKš œŸœŸœ ŸœŸœŸœ˜Jš ’‘’‘’‘œ‘’˜-Kš’‘œ’‘˜,Kš’‘˜—K˜K˜—š œŸœŸœŸœ˜LKšœ Ÿœž$˜IKšœŸœž˜:š ’‘Ÿ‘’‘œ‘’˜0Kš ’‘œ’‘œ‘’‘˜7Kš’‘˜—K˜K˜—š  œŸœŸœŸœŸœŸœ˜LKš œŸœŸœŸœŸœŸœ˜%KšœŸœŸœ Ÿœ˜,Kšœ Ÿœ˜KšœM˜MK˜K˜—š œŸœŸœŸœ ŸœŸœŸœŸœ Ÿœ˜pKšœŸœ‘œ ž,˜SKš œŸœŸœ ŸœŸœŸœ˜JKšœb˜bK˜K™——šœ™š  œŸœŸœŸœŸœ˜6Kš ŸœŸœŸœŸœŸœ#˜KKšŸœŸœ+˜5K˜K˜—š   œŸœŸœŸœŸœ˜4Kš ŸœŸœŸœŸœŸœ ˜HKšŸœŸœŸœ+˜8K˜K˜—š  œŸœŸœŸœŸœŸœ˜DKš ŸœŸœŸœŸœŸœ%˜MKšŸœŸœŸœŸœ˜K˜K˜—š œŸœŸœŸœ˜3KšŸœŸœŸœŸœ(˜IKšŸœŸœŸœ+˜8K˜K˜—š  œŸœŸœ˜%KšŸœŸœŸœŸœ˜K˜K˜——™š  œŸœŸœŸœŸœŸœ˜6KšœŸœ˜šŸœ˜KšŸœŸœŸœ˜BKšŸœŸœ!˜,—Kšœ˜K˜—š œŸœŸœŸœ ŸœŸœŸœ ŸœŸœŸœŸœŸœ˜KšœŸœ‘œ ž,˜SKšœŸœŸœ ˜KšœŸœ˜šŸœŸœŸœ˜BšŸœ˜KšŸœ€˜‡Kšœ˜Kšœ˜KšŸœ˜ K˜—KšŸœŸœ:˜E—Kšœ˜K˜—š œŸœŸœŸœŸœŸœŸœ˜cKšœ Ÿœž$˜IKšœŸœž˜8KšœŸœ˜šŸœŸœŸœ˜CšŸœ˜KšŸœ}ž#˜§Kšœ˜KšŸœ˜ Kšœ˜—KšŸœŸœŸœ2ž ˜Q—Kšœ˜K˜—š  œŸœŸœŸœŸœŸœ˜4KšŸœ.Ÿœ˜VKšœ˜K˜—š  œŸœŸœŸœŸœŸœŸœŸœ˜LKšŸœ*˜0Kšœ˜K˜—š  œŸœŸœŸœŸœ˜2KšœŸœ˜šŸœŸœ˜(šŸœ˜KšœŸœ˜ šŸœ˜KšŸœ˜KšŸœŸœŸœ˜*—K˜—KšŸœ%˜)—Kšœ˜K™—š  œŸœŸœŸœŸœŸœ˜=KšœŸœ˜šŸœ˜KšŸœŸœŸœ˜&KšŸœ7˜;—Kšœ˜K˜——šœ>™>š  œŸœŸœŸœŸœ˜3KšœŸœ˜šŸœ˜KšŸœ2˜6KšŸœ&˜*—Kšœ˜K˜—š œŸœŸœŸœ ŸœŸœŸœŸœ ŸœŸœŸœ˜nKšœŸœ‘œ ž,˜SKš œŸœŸœ ŸœŸœŸœ˜JKš œŸœŸœ ŸœŸœŸœŸœ1˜nKšœŸœ˜šŸœŸœŸœ˜:šŸœ˜KšŸœ€˜‡Kšœ˜Kšœ˜—KšŸœ9˜=—Kšœ˜K˜—š œŸœŸœŸœ˜BKšœ Ÿœž$˜IKšœŸœž˜8Kš œŸœŸœ ŸœŸœŸœŸœ1˜nKšœŸœ˜šŸœŸœŸœ˜;šŸœ˜KšŸœ|˜ƒKšœ˜Kšœ˜—KšŸœ.˜2—Kšœ˜K˜—š œŸœŸœŸœ˜%Kšœ˜Kšœ˜K™—š   œŸœŸœŸœŸœ˜5Kšœ'˜'Kšœ˜K˜——šœ,™,š œŸœŸœŸœ˜%Kšœ˜Kšœ˜K™—š  œŸœŸœŸœ ŸœŸœ˜:Kšœ$˜$Kšœ˜K™——šœ™š œŸœŸœŸœŸœ ŸœŸœŸœŸœŸœŸœ˜bKšŸœŸœŸœŸœ˜JKšŸœ3ŸœŸœ˜RK˜K˜—š œŸœŸœŸœŸœŸœŸœ˜=KšŸœŸœŸœ ˜-Kšœ˜K˜—š œŸœŸœŸ œŸœŸœŸœ˜QKšœŸœŸœ˜"KšœŸœŸœ˜"KšŸœ ž ˜2K˜K˜—š  œŸœŸœŸ œŸœŸœ˜HKšŸœ˜!KšŸœ˜!K˜K˜—š œŸœŸœŸ œŸœŸœŸœ˜QKšœŸœŸœ˜#KšœŸœŸœ˜#KšœŸœŸœ˜#KšœŸœŸœ˜#KšŸœ˜!K˜K˜—š  œŸœŸœŸ œŸœŸœ˜HK˜K˜Kšœ˜K™——šœ:™:š  œŸœŸœŸœŸœ Ÿœ˜=KšŸœ!˜'Kšœ˜K˜—š  œŸœŸœŸœ Ÿœ˜4Kšœ&˜&Kšœ˜K˜—š   œŸœŸœŸœŸœ Ÿœ˜?KšŸœ"˜(Kšœ˜K™—š   œŸœŸœŸœ Ÿœ˜6Kšœ(˜(Kšœ˜K˜——šœ™š   œŸœŸœŸœŸœ ˜FKš œ ŸœŸœ ŸœŸœ˜/š Ÿœ ŸœŸœž*œŸ˜RKš œ ŸœŸœŸœŸœ˜E—K˜K˜oKšœŸœž#˜;Kšœ˜K™—š œŸœŸœŸœ˜.K˜)KšŸœŸœŸœŸœ˜(K˜Kš ŸœŸœŸœŸœž6˜YKšœ˜Kšœ˜K˜——™š   œŸ œŸœŸœŸœŸœ˜CKšœ‘œ-˜=Kšœ˜K˜—š  œŸ œŸœŸœŸœŸœŸœŸœ˜GKšŸœ+˜1Kšœ˜K˜—š  œŸ œŸœŸœ˜5Kšœ‘œ)˜9Kšœ˜K˜—š   œŸ œ ŸœŸœ ŸœŸœ˜PKšœ‘œ1˜BKšœ˜K˜—š  œŸ œŸœŸœŸœ ŸœŸœŸœ˜PKšŸœ7˜=Kšœ˜K™——™Kšœ ŸœŸœ˜$Kš œŸœŸœ Ÿœ ŸœŸœ˜>šœ ŸœŸœ˜4K˜(K˜K˜K˜K˜K˜K˜K™—š  œŸœŸœŸœ˜2Kšœ•‘œx™‘KšœŸœ˜5šŸœŸœŸœ˜Kšž'œ™(šœŸœ˜KšœŸœŸœ˜<—Kšœ2˜2—šŸœŸœŸœ˜