DIRECTORY Basics USING [FWORD, HWORD, LongNumber, Word16], IO USING [GetChar, GetFWord, GetHWord, PutChar, STREAM], Rope USING [ROPE]; CrRPC: CEDAR DEFINITIONS IMPORTS IO ~ { HWORD: TYPE ~ Basics.HWORD; FWORD: TYPE ~ Basics.FWORD; ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; Handle: TYPE ~ REF Object; RefAddress: TYPE ~ REF; HandleClass: TYPE ~ ATOM; HandleKind: TYPE ~ { client, server }; CreateClientHandle: PROC [class: HandleClass, remote: RefAddress] RETURNS [Handle]; DestroyProc: TYPE ~ PROC [h: Handle]; DestroyClientHandle: DestroyProc ~ INLINE { h.procs.destroy[h] }; SetParametersProc: TYPE ~ PROC [h: Handle, op: ATOM, argument: REF] RETURNS [hNew: Handle, result: REF]; SetParameters: SetParametersProc ~ INLINE { [hNew, result] ¬ h.procs.setParameters[h, op, argument] }; PutArgsProc: TYPE ~ PROC [h: Handle, s: STREAM]; GetResultsProc: TYPE ~ PROC [h: Handle, s: STREAM]; GetErrorProc: TYPE ~ PROC [h: Handle, s: STREAM, errNum: CARDINAL]; CallProc: TYPE ~ PROC [ h: Handle, remotePgm: CARD32, remotePgmVersion: CARD16, remoteProc: CARD16, putArgs: PutArgsProc ¬ NIL, getResults: GetResultsProc ¬ NIL, getError: GetErrorProc ¬ NIL]; Call: CallProc ~ INLINE { h.procs.call[h, remotePgm, remotePgmVersion, remoteProc, putArgs, getResults, getError] }; ServerProc: TYPE ~ PROC [ h: Handle, s: STREAM, pgm: CARD32, pgmVersion: CARD16, proc: CARD16, beginReturn: BeginReturnProc, beginError: BeginErrorProc, beginReject: BeginRejectProc ]; BeginReturnProc: TYPE ~ PROC [h: Handle]; BeginErrorProc: TYPE ~ PROC [h: Handle, errNum: CARDINAL]; BeginRejectProc: TYPE ~ PROC [h: Handle, rejectReason: CARDINAL ¬ noSuchProcedure]; noSuchProgram: CARD16 ~ 0; noSuchVersion: CARD16 ~ 1; noSuchProcedure: CARD16 ~ 2; invalidArgument: CARD16 ~ 3; unspecifiedReject: CARD16 ~ CARD16.LAST; StopServerQueryProc: TYPE ~ PROC [h: Handle] RETURNS [pleaseStop: BOOL]; RegisterServerProcs: PROC [ pgm: CARD32, pgmLoVersion: CARD16, pgmHiVersion: CARD16, serverProc: ServerProc, stopServerQueryProc: StopServerQueryProc ¬ NIL ]; StartServerInstance: PROC [ pgm: CARD32, pgmVersion: CARD16, class: HandleClass ¬ NIL, local: RefAddress ¬ NIL]; EnsureListener: PROC [ class: HandleClass, local: RefAddress ¬ NIL]; GetByte: PROC [s: STREAM] RETURNS [BYTE] ~ INLINE { RETURN [LOOPHOLE[IO.GetChar[s]]] }; GetChar: PROC [s: STREAM] RETURNS [CHAR] ~ INLINE { RETURN [IO.GetChar[s]] }; GetHWord: PROC [s: STREAM] RETURNS [hWord: HWORD] ~ INLINE { RETURN[IO.GetHWord[s]] }; GetCard16: PROC [s: STREAM] RETURNS [CARD16] ~ INLINE { buf: Basics.Word16; buf.hi ¬ ORD[IO.GetChar[s]]; buf.lo ¬ ORD[IO.GetChar[s]]; RETURN [buf.card] }; GetInt16: PROC [s: STREAM] RETURNS [INT16] ~ INLINE { buf: Basics.Word16; buf.hi ¬ ORD[IO.GetChar[s]]; buf.lo ¬ ORD[IO.GetChar[s]]; RETURN [buf.int] }; GetBool: PROC [s: STREAM] RETURNS [BOOL] ~ INLINE { [] ¬ IO.GetChar[s]; RETURN [ORD[IO.GetChar[s]] # 0] }; GetFWord: PROC [s: STREAM] RETURNS [fWord: FWORD] ~ INLINE { RETURN[IO.GetFWord[s]] }; GetCard32: PROC [s: STREAM] RETURNS [CARD32] ~ INLINE { buf: Basics.LongNumber; buf.hh ¬ ORD[IO.GetChar[s]]; buf.hl ¬ ORD[IO.GetChar[s]]; buf.lh ¬ ORD[IO.GetChar[s]]; buf.ll ¬ ORD[IO.GetChar[s]]; RETURN [buf.lc] }; GetInt32: PROC [s: STREAM] RETURNS [INT32] ~ INLINE { buf: Basics.LongNumber; buf.hh ¬ ORD[IO.GetChar[s]]; buf.hl ¬ ORD[IO.GetChar[s]]; buf.lh ¬ ORD[IO.GetChar[s]]; buf.ll ¬ ORD[IO.GetChar[s]]; RETURN [buf.li] }; PutByte: PROC [s: STREAM, byte: BYTE] ~ INLINE { IO.PutChar[s, LOOPHOLE[byte]] }; PutChar: PROC [s: STREAM, char: CHAR] ~ INLINE { IO.PutChar[s, char] }; PutHWord: PROC [s: STREAM, hWord: HWORD] ~ INLINE { IO.PutChar[s, VAL[hWord.hi]]; IO.PutChar[s, VAL[hWord.lo]] }; PutCard16: PROC [s: STREAM, card16: CARD16] ~ INLINE { buf: Basics.Word16; buf.card ¬ card16; IO.PutChar[s, VAL[buf.hi]]; IO.PutChar[s, VAL[buf.lo]] }; PutInt16: PROC [s: STREAM, int16: INT16] ~ INLINE { buf: Basics.Word16; buf.int ¬ int16; IO.PutChar[s, VAL[buf.hi]]; IO.PutChar[s, VAL[buf.lo]] }; PutBool: PROC [s: STREAM, bool: BOOL] ~ INLINE { IO.PutChar[s, VAL[0]]; IO.PutChar[s, IF bool THEN VAL[1] ELSE VAL[0]] }; PutFWord: PROC [s: STREAM, fWord: FWORD] ~ INLINE { IO.PutChar[s, VAL[fWord.hi.hi]]; IO.PutChar[s, VAL[fWord.hi.lo]]; IO.PutChar[s, VAL[fWord.lo.hi]]; IO.PutChar[s, VAL[fWord.lo.lo]] }; PutCard32: PROC [s: STREAM, card32: CARD32] ~ INLINE { buf: Basics.LongNumber; buf.lc ¬ card32; IO.PutChar[s, VAL[buf.hh]]; IO.PutChar[s, VAL[buf.hl]]; IO.PutChar[s, VAL[buf.lh]]; IO.PutChar[s, VAL[buf.ll]] }; PutInt32: PROC [s: STREAM, int32: INT32] ~ INLINE { buf: Basics.LongNumber; buf.li ¬ int32; IO.PutChar[s, VAL[buf.hh]]; IO.PutChar[s, VAL[buf.hl]]; IO.PutChar[s, VAL[buf.lh]]; IO.PutChar[s, VAL[buf.ll]] }; SeqHWord: TYPE ~ REF SeqHWordObject; SeqHWordObject: TYPE ~ MACHINE DEPENDENT RECORD [ body: PACKED SEQUENCE length: CARD16 OF HWORD ]; GetSeqHWord: PROC [s: STREAM] RETURNS [seqHWord: SeqHWord]; PutSeqHWord: PROC [s: STREAM, seqHWord: SeqHWord]; SkipSeqHWord: PROC [s: STREAM]; SeqCard16: TYPE ~ REF SeqCard16Object; SeqCard16Object: TYPE ~ MACHINE DEPENDENT RECORD [ body: PACKED SEQUENCE length: CARD16 OF CARD16 ]; GetSeqCard16: PROC [s: STREAM] RETURNS [seqCard16: SeqCard16]; PutSeqCard16: PROC [s: STREAM, seqCard16: SeqCard16]; SkipSeqCard16: PROC [s: STREAM]; GetRope: PROC [s: STREAM] RETURNS [rope: ROPE]; PutRope: PROC [s: STREAM, rope: ROPE]; SkipRope: PROC [s: STREAM]; MarshalledRopeHWords: PROC [rope: ROPE] RETURNS [hWords: CARDINAL]; BulkDataCheckAbortProc: TYPE ~ PROC [h: Handle] RETURNS [abort: BOOL]; BulkDataXferProc: TYPE ~ PROC [h: Handle, s: STREAM, checkAbort: BulkDataCheckAbortProc] RETURNS [abort: BOOL]; BulkDataSource: TYPE ~ BulkDataXferProc; BulkDataSink: TYPE ~ BulkDataXferProc; GetBulkDataXferProcProc: TYPE ~ PROC [h: Handle, s: STREAM] RETURNS [BulkDataXferProc]; GetBulkDataSource: GetBulkDataXferProcProc; GetBulkDataSink: GetBulkDataXferProcProc; PutBulkDataXferProcProc: TYPE ~ PROC [h: Handle, s: STREAM, proc: BulkDataXferProc]; PutBulkDataSource: PutBulkDataXferProcProc ~ INLINE { h.procs.putBulkDataSource[h, s, proc] }; PutBulkDataSink: PutBulkDataXferProcProc ~ INLINE { h.procs.putBulkDataSink[h, s, proc] }; BulkDataValueProc: TYPE ~ PROC [s: STREAM] RETURNS [abort: BOOL ¬ FALSE]; ReadBulkDataStreamProc: TYPE ~ PROC [h: Handle, s: STREAM, checkAbort: BulkDataCheckAbortProc, readValue: BulkDataValueProc] RETURNS [abort: BOOL]; ReadBulkDataStream: ReadBulkDataStreamProc ~ INLINE { RETURN [h.procs.readBulkDataStream[h, s, checkAbort, readValue]] }; WriteBulkDataSegmentProc: TYPE ~ PROC [h: Handle, s: STREAM, checkAbort: BulkDataCheckAbortProc, writeValue: BulkDataValueProc, n: CARDINAL ¬ 1] RETURNS [abort: BOOL, heAborted: BOOL]; WriteBulkDataSegment: WriteBulkDataSegmentProc ~ INLINE { [abort, heAborted] ¬ h.procs.writeBulkDataSegment[h, s, checkAbort, writeValue, n] }; ContinuationProc: TYPE ~ PROC [s: STREAM, clientData: REF] RETURNS [STREAM]; CallContinuationProc: TYPE ~ PROC [h: Handle, proc: ContinuationProc, clientData: REF]; CallContinuation: CallContinuationProc ~ INLINE { h.procs.callContinuation[h, proc, clientData] }; SetContinuationProc: TYPE ~ PROC [h: Handle, proc: ContinuationProc, clientData: REF]; SetContinuation: SetContinuationProc ~ INLINE { h.procs.setContinuation[h, proc, clientData] }; Error: ERROR [h: Handle, errorReason: ErrorReason, text: ROPE]; ErrorReason: TYPE ~ { unknown, unknownClass, courierVersionMismatch, rejectedNoSuchProgram, rejectedNoSuchVersion, rejectedNoSuchProcedure, rejectedInvalidArgument, rejectedUnspecified, remoteError, cantConnectToRemote, argsError, resultsError, bulkDataError, protocolError, remoteClose, communicationFailure, notImplemented, unknownOperation, notServerHandle, notClientHandle, addressInappropriateForClass, other }; Object: TYPE ~ RECORD [ class: HandleClass, kind: HandleKind, procs: REF ProcsObject, data: REF, -- private, for use by implementor clientData: REF -- public, for use by client ]; ProcsObject: TYPE ~ RECORD [ destroy: DestroyProc, setParameters: SetParametersProc, call: CallProc, getBulkDataSource: GetBulkDataXferProcProc, getBulkDataSink: GetBulkDataXferProcProc, putBulkDataSource: PutBulkDataXferProcProc, putBulkDataSink: PutBulkDataXferProcProc, readBulkDataStream: ReadBulkDataStreamProc, writeBulkDataSegment: WriteBulkDataSegmentProc, callContinuation: CallContinuationProc, setContinuation: SetContinuationProc, finalize: PROC [Handle] RETURNS[renewHandle: BOOL] -- true if want to reuse handle ]; }. "fCrRPC.mesa Copyright Σ 1986, 1991 by Xerox Corporation. All rights reserved. Demers, November 13, 1989 6:47:37 pm PST Willie-Sue Orr, November 13, 1989 10:53:26 pm PST Willie-s, December 9, 1991 1:57 pm PST Introduction Courier client / server interface. Primarily for Sirocco-generated stubs. The "class" stuff determines what kind of transport is used  currently: $SPP gets you "official" Courier. This uses SPP streams for its transport and supports bulk data transfer, but does not allow broadcast calls. Other classes could be implemented  see the CrRPCBackdoor interface. For client stubs: It is the client stub's responsibility to ensure that only one call is outstanding on a handle at any time. Sirocco takes care of this. Copied Types Types See below for Object. A pointer to a network address. Network address format is class-specific. The class of a handle tells what kind of transport it uses. Create / Set Parameters / Destroy for Client Handles Create a client handle of the specified class directed at the specified remote address. For restrictions on remote see SetRemote[...] below. Class-specific. It will return a handle with the desired parameter values. This handle is not guaranteed to the same as the original argument handle. Calling a Remote Procedure Called to put arguments to STREAM s using STREAM operations from IO or the PutXXX procs defined below. A PutArgsProc may propagate errors raised from underlying transport mechanism (e.g. XNSStream.ConnectionClosed[...]), in which case it will eventually be unwound by the invoking CallProc. Called to get results from STREAM s using STREAM operations from IO or the GetXXX operations defined below. A GetResultsProc may propagate errors raised from underlying transport mechanism (e.g. XNSStream.ConnectionClosed[...], IO.EndOfStream[...]), in which case it will eventually be unwound by the invoking CallProc. Called to get arguments to a remote ERROR from handle using GetBYTE, ..., defined below. A GetErrorProc may propagate errors raised from underlying transport mechanism (e.g. XNSStream.ConnectionClosed[...], IO.EndOfStream[...]), in which case it will eventually be unwound by the invoking CallProc. ! Error[Handle, errorReason, text] A handle's CallProc invokes a remote procedure. It works by: (1) call putArgs to stuff the arguments. (2) send the call message. (3) get the reply; if it's a normal return then call getResults, otherwise ERROR Error[...]. Network and stream errors raised by putArgs and getResults will be caught, unwound and converted to Error[...]. Unwinding after Error[...] cleans up correctly. It is reasonable for getResults to do substantial processing, but (obviously) it can't do another remote procedure call using the same handle. Servers for Remote Calls Server for all procedures of a version of a remote program. Notifies Courier that we're about to construct the return record. Notifies Courier that we're about to construct an abort record. Notifies Courier that we're about to construct a reject record. Use of noSuchVersion or noSuchProgram as the rejectReason here would be questionable, since these errors are caught before the server proc is called. Reject Reasons Server process calls this periodically to determine whether to quit. Register ServerProc-StopServerQueryProc pair for given program and version range. Start a single server thread. Multiple server instances may exist with same class. Default for stopServerQueryProc means server runs forever. Defaults for class and local are Courier on XNS transport. Ensure that there's a listener for the given transport class listening at the specified local address. This is in some sense a CROCK  there should be (something analogous to) a Courier well-known socket for each transport class, but they didn't design it that way. For transport with a well-known socket (e.g. SPP) the default is to use it; for transport without a well-known socket, the default will raise Error[notImplemented]. In any case, an explicitly-specified socket might make sense for debugging ... Marshalling Primitives Bulk Data Immediate and null Bulk Data transfers are supported; third-party transfers are not. Think of this as a callback proc passed from client to server. The server calls the BulkDataXferProc, passing a STREAM, for the data, and the checkAbort proc, which will be polled to determine whether the server wants to abort the transfer. The result of the BulkDataXferProc indicates whether the client aborted the transfer. Bulk Data Marshalling and Unmarshalling procs require the Handle as well as the STREAM as arguments; marshalling a Source or Sink changes the state of the Handle. NOTE (Nov 1986): GetBulkDataSource, GetBulkDataSink should be INLINE, but can't be for now because of a compiler error in pass 4. ~ INLINE { RETURN [h.procs.getBulkDataSource[h, s] }; ~ INLINE { RETURN [h.procs.getBulkDataSink[h, s] }; Supplying NIL for proc results in a null bulk data transfer. Bulk Data Streams A stylized way to use the Bulk Data Transfer facility. Assumes the data to be transferred comprises a single value of the recursively-defined type StreamOfT (cf. XSIS 038112 Add. 1a, Sec. F.4.1). This is the case for most "official" XNS protocols. A callback to read/write a single data value from/to a bulk data stream. IO.Error[...] and transport-specific ERRORs raised here will be caught by the CrRPC package. Return TRUE if this side wants to abort the transfer. Note that the marshalling/unmarshalling procs declared above  GetByte, ..., PutByte, ...  can be used to build a BulkDataValueProc. ! Error Reads a bulk data stream (a value of type StreamOfT), calling readValue to read each T value in the stream. Returns TRUE iff this side wants to abort the transfer (i.e. a call to readValue returned TRUE). Example: ReadStreamOfShortInteger: BulkDataXferProc ~ { EachShortIntegerInStream: BulkDataValueProc ~ { x: INT16 _ GetInt16[s]; ... RETURN [doIWantToAbort] }; Return [ReadBulkDataStream[h, s, checkAbort, EachShortIntegerInStream]] }; ! Error If n > 0: first writes the header of a streamOfT element of type nextSegment with count n; then calls the BulkDataValueProc n times to fill in the data. If n=0: writes a streamOfT element of type lastSegment and length 0. Example: WriteStreamOfShortInteger: BulkDataXferProc ~ { WHILE not done DO WriteTheShortInteger: BulkDataValueProc ~ { theShortInteger: INT16 _ ... ; PutInt16[s, theShortInteger]; done _ ... ; RETURN [doIWantToAbort] }; [heAborts, abort] _ WriteBulkDataSegment[h, s, checkAbort, WriteTheShortInteger]; IF heAborts OR abort THEN RETURN --[abort]-- ; ENDLOOP; WriteBulkDataSegment[h, s, NIL, NIL, 0]; }; Continuations This mechanism is used primarily for GAP (the Gateway Access Protocol). GAP uses a call and return to communicate setup parameters; the actual terminal emulation is done by ContinuationProcs using the Courier transport stream. CallContinuation[...] can also be used (with a trivial ContinuationProc) by clients to force a handle's underlying transport to be closed immediately. This is useful for dealing with feeble-minded servers that can't maintain multiple transport streams simultaneously. GAP terminal emulation is done by a ContinuationProc on each side. The properties of the stream  e.g. how out-of-band data is transferred  are class-specific. Class specific ERRORs  e.g. XNSStream.ConnectionClosed[...]  will be caught by the CrRPC package if they are not caught in the ContinuationProc. A ContinuationProc should either dispose of stream s (using IO.Close) and return NIL, or leave s in a reasonable state for another RPC ("reasonable" here is class-specific, sigh) and return s. Allowed only on client handles. Call proc[s, clientData], where s is the transport stream associated with h. The properties of s are of course class-specific. The stream returned by proc replaces h's transport stream. It should be either s itself (in a state acceptable for the next Courier call) or NIL. ERRORS: CrRPC.Error[...]. Allosed only on server handles. The ServerProc calls SetContinuation[...] before returning; after the ServerProc returns, the CrRPC package calls proc[s, clientData], where s is the handle's transport stream. The properties of the stream are of course class-specific. The stream returned by proc replaces the handle's transport stream. It should be either s itself (in a state acceptable for the next Courier call) or NIL (in which case this server instance disappears immediately). SetContinuation[h, NIL, NIL] undoes the effect of a previous SetContinuation call. Signals / Errors Shouldn't be seen by anybody ... Seen only by clients ... Seen by clients or servers ... Client / Server mixups ... Address format mixups ... Catch-all Representation Details Κφ•NewlineDelimiter –(cedarcode) style˜šœ ™ Icodešœ Οeœ6™BK™(K™1K™&K™—šΟk ˜ Kšœžœžœžœ˜0Kšžœžœ(žœ˜8Kšœžœžœ˜K˜—šΡblnœžœž ˜Kšžœž˜ Kšœ˜head™ ™JK™—™HK™—™EK™—K™›—™ Kšžœžœ žœ˜Kšžœžœ žœ˜Kšžœžœžœ˜Kšžœžœžœžœ˜—™šœžœžœ˜K™—K˜šœ žœžœ˜K™J—K˜šœ žœžœ˜K™;K˜—šœ žœ˜&K˜——™4šΟnœžœ*žœ ˜SK™WK™4K˜—Kš  œžœžœ ˜%š œžœ˜AK˜—Kš œžœžœžœ žœœžœžœ˜hš  œžœ˜+K˜:K™———™š  œžœžœžœ˜0Kšœžœ žœžœ#™fK™»—K˜š œžœžœžœ˜3Kšœžœ žœžœ(™kK™Σ—K˜š   œžœžœžœ žœ˜CK™XK™Ρ—K˜š œžœžœ˜K˜ Kšœ žœ˜Kšœžœ˜Kšœ žœ˜Kšœžœ˜Kšœžœ˜!Kšœžœ˜K™"šœ=™=Kšœ(™(K™K™\—K™ KšœŽ™Ž—K˜Kš œ žœ]˜t—™š  œžœžœ˜K˜ Kšœžœ˜ Kšœžœ˜ Kšœ žœ˜Kšœžœ˜ Kšœ˜K˜K˜K˜K™;K˜—š œžœžœ ˜)K™AK˜—š œžœžœžœ˜:K™?K˜—š œžœžœžœ˜SK™ΦK˜—™Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœžœžœ˜(K˜—š  œžœžœ žœžœ˜HK™DK˜—š œžœ˜Kšœžœ˜ Kšœžœ˜Kšœžœ˜K˜Kšœ+ž˜.Kšœ˜KšœQ™QK˜—š œžœ˜Kšœžœ˜ Kšœ žœ˜Kšœžœ˜Kšœžœ˜KšœΛ™ΛK˜—š œžœ˜Kšœ˜Kšœžœ˜K™€K˜——™š  œžœžœžœžœžœ˜3Kšžœžœžœ˜#—š  œžœžœžœžœžœ˜3Kšžœžœ˜—Kš œžœžœžœ žœžœžœžœ˜Vš   œžœžœžœžœžœ˜7K˜Kšœ žœžœ ˜Kšœ žœžœ ˜Kšžœ˜—š  œžœžœžœžœžœ˜5K˜Kšœ žœžœ ˜Kšœ žœžœ ˜Kšžœ ˜—š  œžœžœžœžœžœ˜3Kš œžœ žœžœžœ˜6—Kš œžœžœžœ žœžœžœžœ˜Vš   œžœžœžœžœžœ˜7K˜Kš œ žœžœžœžœ ˜:Kš œ žœžœžœžœ ˜:Kšžœ ˜—š  œžœžœžœžœžœ˜5K˜Kš œ žœžœžœžœ ˜:Kš œ žœžœžœžœ ˜:Kšžœ ˜—K˜š  œžœžœžœžœ˜0Kšžœ žœ ˜ —š  œžœžœžœžœ˜0Kšžœ˜—š  œžœžœ žœžœ˜3Kšžœ žœžœ žœ˜>—š   œžœžœ žœžœ˜6K˜K˜Kšžœ žœ žœ žœ ˜:—š  œžœžœ žœžœ˜3K˜K˜Kšžœ žœ žœ žœ ˜:—š  œžœžœžœžœ˜0Kšžœ žœžœ žœžœžœžœžœ˜I—š  œžœžœ žœžœ˜3Kšžœ žœžœ žœ˜BKšžœ žœžœ žœ˜D—š   œžœžœ žœžœ˜6K˜K˜Kšžœ žœ žœ žœ ˜8Kšžœ žœ žœ žœ ˜:—š  œžœžœ žœžœ˜3K˜K˜Kšžœ žœ žœ žœ ˜8Kšžœ žœ žœ žœ ˜:K˜—Kšœ žœžœ˜$š œžœžœž œžœ˜1Kš œžœžœ žœžœžœ˜0K˜—Kš  œžœžœžœ˜;Kš  œžœžœ˜2š  œžœžœ˜K˜—Kšœ žœžœ˜&š œžœžœž œžœ˜2Kš œžœžœ žœžœžœ˜1K˜—Kš  œžœžœžœ˜>Kš  œžœžœ˜5š  œžœžœ˜ K˜—Kš  œžœžœžœžœ˜/Kš œžœžœžœ˜&Kš œžœžœ˜Kš  œžœžœžœ žœ˜C—™ K™TK™Kš  œžœžœ žœ žœ˜Fš  œžœžœžœ&žœ žœ˜oKšœΘ™ΘK˜—Kš œžœ˜(š  œžœ˜&K˜—K™’K™K™K˜Kš  œžœžœžœžœ˜Wš œ˜+Kšœžœžœ$™5—š œ˜)Kšœžœžœ"™3K˜—Kš œžœžœžœ˜Tš œžœ˜5Kšœ(˜(—š œžœ˜3Kšœ&˜&K™<——™K™ωK˜š œžœžœžœžœ žœžœ˜IKšœožœ2™¦K™5Kšœ…™…—K˜Kš  œžœžœžœDžœ žœ˜“š œžœ˜5Kšžœ=˜CK™K™kKšœžœNžœ™`K™™š œ™.š œ™/K™K™Kšžœ™—KšœG™GK™———K˜Kš œžœžœžœHžœžœ žœ žœ˜Έš œžœ˜9K˜UKšœ™Kšœ˜™˜KšœD™DK™™š œ™/šžœ ž™š œ™+K™K™K™ Kšžœ™—JšœQ™QJšžœ žœžœžœ™.Kšžœ™—Kšœžœžœ™(K™————™ Kšœγ™γK™KšœŒ™ŒK˜š œžœžœžœžœžœžœ˜LKšœ΅™΅K™ΐ—K˜Kš œžœžœ1žœ˜Wš œžœ˜1Kšœ0˜0Kšœ™Kšœ“™“K™K™K˜—Kš œžœžœ1žœ˜Vš œžœ˜/Kšœ/˜/K™KšœΕ™ΕKšœR™R——™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šœžœΟc"˜-Kšœ žœ‘˜,K˜K˜—šœ žœžœ˜K˜K˜!K˜K˜+K˜)K˜+K˜)K˜+K˜/Kšœ'˜'K˜%Kšœ žœ žœžœ‘˜SK˜K˜——K˜—K˜K˜—…—!BRž