DIRECTORY BasicTime USING [GetClockPulses, GMT, Now, nullGMT, PulsesToMicroseconds], Basics USING [UnsafeBlock], CrRPC USING [BulkDataSink, BulkDataSource, BulkDataValueProc, CreateClientHandle, DestroyClientHandle, Handle, ReadBulkDataStream], FilingP10V5, FilingAttributesP10V5 USING [Attribute, AttributeSequence, AttributeSequenceObject, AttributeValue, FileID, InterpretedAttributeType, Version], IO USING [EndOf, PutFR, rope, UnsafeGetBlock, UnsafePutBlock], QuickFilingP10V5 USING [QuickGetAttributes], PFS USING [Error, UniqueID], PFSNames USING [PATH], RefText USING [ReleaseScratch], Rope USING [Fetch, FromRefText, ROPE, Substr], RuntimeError USING [ ], UserCredentials USING [GetIdentity], XNS USING [Address, unknownAddress], XNSAuth USING [Conversation, Credentials, GetCredentials, GetNextVerifier, Identity, Initiate, Refresh, SetRecipientHostNumber, Verifier], XNSCH USING [LookupAddressFromRope], XNSCHName USING [Name, RopeFromName], XNSFilingAttributes USING [BuildAttribute, BuildScope, EncapsulateFileID, Interpreted, nullAttributes, nullControls], XNSFilingFileMgr USING [OpenFile, OpenFileObject], XNSFilingNames USING [ParseName, UnparseName], XNSFilingOps USING [EnumProc, Info, Op, ServerData, ServerDataObject], XNSFilingPrivate USING [ConvertFSNameToXNS, InfoFromAttributeStream]; XNSFilingOpsImpl: CEDAR MONITOR IMPORTS BasicTime, CrRPC, FilingP10V5, IO, PFS, QuickFilingP10V5, RefText, Rope, UserCredentials, XNSAuth, XNSCH, XNSCHName, XNSFilingAttributes, XNSFilingNames, XNSFilingPrivate EXPORTS XNSFilingFileMgr, XNSFilingOps ~ { OPEN FilingP10V5, FilingAttributesP10V5, XNSFilingAttributes, XNSFilingFileMgr, XNSFilingOps, XNSFilingPrivate; ROPE: TYPE ~ Rope.ROPE; BangStarFile: PROC [file: ROPE] RETURNS [pattern: PFSNames.PATH _ NIL] ~ { NULL }; ConvertToPattern: PROC [pattern: PFSNames.PATH, op: Op] RETURNS [pat: PFSNames.PATH] ~ { }; BuildPath: PROC [mnt: ServerData, rope: ROPE, isDir: BOOL] RETURNS [pathy: PFSNames.PATH] ~ { format: ROPE ~ IF ( isDir ) THEN "/%g/" ELSE "/%g"; rope _ IO.PutFR[format, IO.rope[rope] ]; pathy _ XNSFilingNames.ParseName[rope]; }; RemoveLeadingSlash: PROC [withSlash: ROPE] RETURNS [matcher: ROPE] ~ { matcher _ IF ( withSlash.Fetch[0] # '/ ) THEN withSlash ELSE withSlash.Substr[1]; }; OpenInternal: ENTRY PROC [mnt: XNSFilingOps.ServerData] ~ { ENABLE UNWIND => { NULL }; mnt.admin.files _ mnt.admin.files.SUCC; }; CloseInternal: ENTRY PROC [mnt: XNSFilingOps.ServerData] ~ { ENABLE UNWIND => { NULL }; mnt.admin.files _ mnt.admin.files.PRED; }; ReadFileOp: PUBLIC PROC [mnt: ServerData, xnsFile: OpenFile, filePosition, nBytes: CARD, to: POINTER] RETURNS [bytesRead: INT _ 0] ~ { range: FilingP10V5.ByteRange ~ [filePosition, nBytes]; Sink: CrRPC.BulkDataSink ~ TRUSTED { block: Basics.UnsafeBlock ~ [to, 0, nBytes]; abort _ checkAbort[h]; bytesRead _ s.UnsafeGetBlock[block]; }; RetrieveBytesOp[mnt, xnsFile.fileH, range, Sink]; }; WriteFileOp: PUBLIC PROC [mnt: ServerData, xnsFile: OpenFile, filePosition, nBytes: CARD, from: POINTER] RETURNS [bytesWritten: INT _ 0] ~ { range: FilingP10V5.ByteRange ~ [filePosition, nBytes]; Source: CrRPC.BulkDataSource ~ TRUSTED { block: Basics.UnsafeBlock ~ [from, 0, nBytes]; abort _ checkAbort[h]; s.UnsafePutBlock[block]; bytesWritten _ nBytes; }; ReplaceBytesOp[mnt, xnsFile.fileH, range, Source]; }; CloseFileOp: PUBLIC PROC [mnt: ServerData, xnsFile: OpenFile] ~ { IF ( mnt.session # NIL ) THEN CloseOp[mnt, xnsFile.fileH]; CloseInternal[mnt]; }; OpenFileOp: PUBLIC PROC [mnt: ServerData, fullFName: PFSNames.PATH] RETURNS [xnsFile: OpenFile _ NIL] ~ { withSlash: ROPE ~ XNSFilingNames.UnparseName[fullFName]; newFile: ROPE ~ RemoveLeadingSlash[withSlash]; attributes: AttributeSequence ~ BuildAttribute[newFile, Interpreted.pathname.ORD]; fileH: FilingP10V5.Handle ~ OpenOp[mnt, attributes]; now: BasicTime.GMT ~ BasicTime.Now[]; xfile: OpenFile ~ NEW[OpenFileObject _ [fileH, now]]; OpenInternal[mnt]; xnsFile _ xfile; }; EnumerateOp: PUBLIC PROC [mnt: ServerData, pattern: PFSNames.PATH, proc: EnumProc, op: Op] ~ { Listing: CrRPC.BulkDataSink ~ { EachElement: CrRPC.BulkDataValueProc ~ { info: Info ~ InfoFromAttributeStream[s]; { nonEmpty: BOOL ~ ( ( info.isDir ) AND ( info.numKids # 0 ) ); pathy: PFSNames.PATH ~ BuildPath[mnt, info.pathName, info.isDir]; IF ( pathy = NIL ) THEN { abort _ FALSE; RETURN }; abort _ NOT proc[pattern, info, pathy]; }; }; IF ( s.EndOf[] ) THEN { abort _ FALSE; RETURN }; -- "Services" feature workaround abort _ CrRPC.ReadBulkDataStream[h, s, checkAbort, EachElement]; }; root: FilingP10V5.Handle ~ mnt.root; types: AttributeTypeSequence ~ GetCedarATS[op]; withSlash: ROPE ~ XNSFilingNames.UnparseName[pattern]; matcher: ROPE ~ RemoveLeadingSlash[withSlash]; scope: FilingP10V5.ScopeSequence ~ BuildScope[$matches, matcher, InterpretedAttributeType.pathname.ORD]; ListOp[mnt, root, types, scope, Listing]; }; LogonOp: PUBLIC PROC [server: ROPE] RETURNS [mnt: ServerData _ NIL] ~ { qualified: XNSCHName.Name; add: XNS.Address; LogonOpInner: PROC ~ { name: ROPE ~ XNSCHName.RopeFromName[qualified]; address: REF XNS.Address ~ NEW[XNS.Address _ add]; crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, address]; realId: XNSAuth.Identity ~ UserCredentials.GetIdentity[]; conversation: XNSAuth.Conversation ~ XNSAuth.Initiate[realId, qualified]; credentials: XNSAuth.Credentials ~ XNSAuth.GetCredentials[conversation]; verifier: XNSAuth.Verifier; session: REF FilingP10V5.Session; timeToLive: CARD32; XNSAuth.SetRecipientHostNumber[conversation, address.host]; verifier _ XNSAuth.GetNextVerifier[conversation]; session _ NEW[Session _ FilingP10V5.Logon[crH, qualified, credentials, verifier]]; session.verifier _ XNSAuth.GetNextVerifier[conversation]; timeToLive _ FilingP10V5.Continue[crH, session^]; XNSAuth.Refresh[conversation, timeToLive]; CrRPC.DestroyClientHandle[crH]; mnt _ NEW[ServerDataObject _ [name, qualified, address, conversation, session, timeToLive, FilingP10V5.nullHandle, ]]; }; [qualified, add] _ XNSCH.LookupAddressFromRope[server]; IF ( add = XNS.unknownAddress ) THEN GOTO NoCanDo; LogonOpInner[]; EXITS NoCanDo => { ERROR }; }; MountRootOp: PUBLIC PROC [mnt: ServerData] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; mnt.session.verifier _ XNSAuth.GetNextVerifier[mnt.tkt]; mnt.root _ FilingP10V5.Open[crH, nullAttributes, FilingP10V5.nullHandle, nullControls, mnt.session^]; CrRPC.DestroyClientHandle[crH]; }; ContinueOp: PUBLIC PROC [mnt: ServerData] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; mnt.session.verifier _ XNSAuth.GetNextVerifier[mnt.tkt]; mnt.admin.trTTL _ mnt.timeToLive _ FilingP10V5.Continue[crH, mnt.session^]; XNSAuth.Refresh[conversation: mnt.tkt, seconds: mnt.admin.trTTL]; CrRPC.DestroyClientHandle[crH]; }; OpenOp: PUBLIC PROC [mnt: ServerData, attributes: AttributeSequence] RETURNS [fileH: FilingP10V5.Handle] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; fileH _ FilingP10V5.Open[h: crH, attributes: attributes, directory: mnt.root, controls: nullControls, session: mnt.session^]; CrRPC.DestroyClientHandle[crH]; }; OpenFIDOp: PUBLIC PROC [mnt: ServerData, fid: FileID] RETURNS [fileH: FilingP10V5.Handle] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; attributes: AttributeSequence _ NEW[AttributeSequenceObject[1]]; attributes[0] _ [type: InterpretedAttributeType.fileID.ORD, value: EncapsulateFileID[fid]]; mnt.session.verifier _ XNSAuth.GetNextVerifier[mnt.tkt]; fileH _ FilingP10V5.Open[h: crH, attributes: attributes, directory: FilingP10V5.nullHandle, controls: nullControls, session: mnt.session^]; CrRPC.DestroyClientHandle[crH]; }; ListOp: PUBLIC PROC [mnt: ServerData, fileH: FilingP10V5.Handle, types: AttributeTypeSequence, scope: ScopeSequence, listing: CrRPC.BulkDataSink] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; mnt.session.verifier _ XNSAuth.GetNextVerifier[mnt.tkt]; FilingP10V5.List[crH, fileH, types, scope, listing, mnt.session^]; CrRPC.DestroyClientHandle[crH]; }; QuickInfoOp: PUBLIC PROC [mnt: ServerData, fileH: FilingP10V5.Handle, types: AttributeTypeSequence] RETURNS [info: Info] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; text: REF TEXT; mnt.session.verifier _ XNSAuth.GetNextVerifier[mnt.tkt]; [info.version, info.bytes, info.created, info.fileType, text, info.fID, info.isDir, info.numKids] _ QuickFilingP10V5.QuickGetAttributes[crH, fileH, types, mnt.session^]; info.pathName _ Rope.FromRefText[text]; RefText.ReleaseScratch[text]; CrRPC.DestroyClientHandle[crH]; }; DeleteOp: PUBLIC PROC [mnt: ServerData, fileH: FilingP10V5.Handle] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; mnt.session.verifier _ XNSAuth.GetNextVerifier[mnt.tkt]; FilingP10V5.Delete[h: crH, file: fileH, session: mnt.session^]; CrRPC.DestroyClientHandle[crH]; }; CloseOp: PUBLIC PROC [mnt: ServerData, fileH: FilingP10V5.Handle] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; FilingP10V5.Close[h: crH, file: fileH, session: mnt.session^]; CrRPC.DestroyClientHandle[crH]; }; RetrieveBytesOp: PUBLIC PROC [mnt: ServerData, file: FilingP10V5.Handle, range: FilingP10V5.ByteRange, sink: CrRPC.BulkDataSink] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; FilingP10V5.RetrieveBytes[crH, file, range, sink, mnt.session^]; CrRPC.DestroyClientHandle[crH]; }; ReplaceBytesOp: PUBLIC PROC [mnt: ServerData, file: FilingP10V5.Handle, range: ByteRange, source: CrRPC.BulkDataSource] ~ { crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address]; FilingP10V5.ReplaceBytes[crH, file, range, source, mnt.session^]; CrRPC.DestroyClientHandle[crH]; }; LogoffOp: PUBLIC PROC [mnt: ServerData] ~ { ENABLE PFS.Error => { GOTO GiveUp }; IF ( mnt.session = NIL ) THEN RETURN; { session: REF Session ~ mnt.session; address: REF XNS.Address ~ mnt.address; crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, address]; FilingP10V5.Logoff[h: crH, session: session^]; CrRPC.DestroyClientHandle[crH]; }; mnt.session _ NIL; EXITS GiveUp => { NULL }; }; XNSDelete: PUBLIC PROC [mnt: ServerData, file: ROPE, wantedUniqueID: PFS.UniqueID] ~ { fileH: FilingP10V5.Handle; info: Info; withKids: BOOL; [fileH, info, withKids] _ FindFile[mnt, file, wantedUniqueID.egmt.time, $delete]; }; XNSEnumerateForInfo: PUBLIC PROC ~ { << P: PROC [file: ROPE, bytes: INT, created: BasicTime.GMT, fileType: FileType, version: Version, fID: FileID, isDir: BOOL, withKids: BOOL, pathName: REF TEXT] RETURNS [continue: BOOL] = { continue _ proc[file, bytes, created, fileType]; }; EnumerateOp[h, pattern, P, $enumerate]; >> }; openTime: CARD; startO, endO: CARD; FindFile: PROC [mnt: ServerData, file: ROPE, wantedTime: BasicTime.GMT, op: Op] RETURNS [fileH: FilingP10V5.Handle _ FilingP10V5.nullHandle, info: Info, withKids: BOOL] = { Note: EnumProc ~ { IF ( wantedTime # eInfo.created ) THEN RETURN; fileH _ OpenFIDOp[mnt, eInfo.fID]; info _ eInfo; continue _ FALSE; }; timeSearch: BOOL ~ ( wantedTime # BasicTime.nullGMT ); newFile: ROPE _ ConvertFSNameToXNS[file, op]; attributes: AttributeSequence _ BuildAttribute[newFile, Interpreted.pathname.ORD]; startO _ BasicTime.GetClockPulses[]; fileH _ OpenOp[mnt, attributes]; IF ( fileH # FilingP10V5.nullHandle ) THEN { endO _ BasicTime.GetClockPulses[]; openTime _ BasicTime.PulsesToMicroseconds[endO] - BasicTime.PulsesToMicroseconds[startO]; info _ InfoFromOpenFile[mnt, fileH, op]; withKids _ ( ( info.isDir ) AND ( info.numKids # 0 ) ); IF ( ( NOT timeSearch ) OR ( wantedTime = info.created ) ) THEN { RETURN }; }; CloseOp[mnt, fileH]; fileH _ FilingP10V5.nullHandle; IF ( timeSearch ) THEN { pattern: PFSNames.PATH ~ ConvertToPattern[BangStarFile[file], $enumerate]; EnumerateOp[mnt, pattern, Note, op]; endO _ BasicTime.GetClockPulses[]; openTime _ BasicTime.PulsesToMicroseconds[endO] - BasicTime.PulsesToMicroseconds[startO]; IF ( fileH # FilingP10V5.nullHandle ) THEN RETURN; }; ERROR; }; infoTime: CARD; startE, endE: CARD; InfoFromOpenFile: PROC [mnt: ServerData, fileH: FilingP10V5.Handle, op: Op] RETURNS [info: Info] = { types: AttributeTypeSequence ~ GetCedarATS[op]; startE _ BasicTime.GetClockPulses[]; info _ QuickInfoOp[mnt, fileH, types]; endE _ BasicTime.GetClockPulses[]; infoTime _ BasicTime.PulsesToMicroseconds[endE] - BasicTime.PulsesToMicroseconds[startE]; }; deleteATS: AttributeTypeSequence; enumerateATS: AttributeTypeSequence; enumerateNamesATS: AttributeTypeSequence; retrieveATS: AttributeTypeSequence; storeATS: AttributeTypeSequence; GetCedarATS: PROC [op: Op] RETURNS [attributes: AttributeTypeSequence] = { attributes _ SELECT op FROM delete => deleteATS, enumerate => enumerateATS, enumerateNames => enumerateNamesATS, rename => enumerateATS, retrieve => retrieveATS, store => storeATS, ENDCASE => ERROR; }; MakeCedarATS: PROC RETURNS [delete, enumerate, enumerateNames, retrieve, store: AttributeTypeSequence] ~ { CardAT: PROC [iat: InterpretedAttributeType] RETURNS [card: CARD32] ~ INLINE { card _ iat.ORD }; delete _ NEW[AttributeTypeSequenceObject[6]]; enumerate _ NEW[AttributeTypeSequenceObject[8]]; enumerateNames _ NEW[AttributeTypeSequenceObject[2]]; retrieve _ NEW[AttributeTypeSequenceObject[5]]; store _ NEW[AttributeTypeSequenceObject[1]]; delete[0] _ CardAT[createdOn]; delete[1] _ CardAT[fileID]; delete[2] _ CardAT[isDirectory]; delete[3] _ CardAT[numberOfChildren]; delete[4] _ CardAT[version]; delete[5] _ CardAT[pathname]; enumerate[0] _ CardAT[createdOn]; enumerate[1] _ CardAT[dataSize]; enumerate[2] _ CardAT[name]; enumerate[3] _ CardAT[pathname]; enumerate[4] _ CardAT[type]; enumerate[5] _ CardAT[isDirectory]; enumerate[6] _ CardAT[version]; enumerate[7] _ CardAT[fileID]; enumerateNames[0] _ CardAT[pathname]; enumerateNames[1] _ CardAT[isDirectory]; retrieve[0] _ CardAT[createdOn]; retrieve[1] _ CardAT[dataSize]; retrieve[2] _ CardAT[version]; retrieve[3] _ CardAT[pathname]; retrieve[4] _ CardAT[fileID]; store[0] _ CardAT[version]; }; Init: PROC = { [deleteATS, enumerateATS, enumerateNamesATS, retrieveATS, storeATS] _ MakeCedarATS[]; }; Init[]; }. 6XNSFilingOpsImpl.mesa Copyright Σ 1988, 1989, 1990 by Xerox Corporation. All rights reserved. Tim Diebert: September 14, 1988 11:11:57 am PDT Willie-Sue, August 30, 1989 7:00:59 pm PDT Bill Jackson (bj), May 30, 1990 2:34 pm PDT Junk format: ROPE ~ IF ( isDir ) THEN "/%g/%g/" ELSE "/%g/%g"; rope _ IO.PutFR[format, IO.rope[mnt.serverName], IO.rope[rope] ]; matcher _ "BJackson/bridge.tar.Z!+"; Reference Counting Files Open/Close FileMgr Operations we don't have to close files after a logout! newFile: ROPE ~ PFS.RopeFromPath[fullFName]; ??? XNSFilingOpsImpl.FindFile ??? Composite Operations the server has given us a file that has a bad character in it so go around Remote Operations Strong Authentication logic CrRPC.Error, AuthenticationError, SessionError, ServiceError, XNSAuth.AuthenticationError, XNSAuth.CallError SessionError, AuthenticationError, CrRPC.Error PFS Access Routines IF ( withKids ) THEN { ENABLE UNWIND => { CloseOp[mnt, fileH] }; xx: ROPE ~ IO.PutFR["Directory %g has children", IO.rope[file] ]; PFSBackdoor.ProduceError[accessDenied, xx] }; { delete: BOOL _ IF ( proc = NIL ) THEN TRUE ELSE proc[fullName, uniqueID]; IF ( delete ) THEN { DeleteOp[fileH] }; }; Filing Utils check if this is (not) the one Any file found didn't meet the create time requested. So, we need to do an enumerate to find a file matching it since it is a timeSearch we need to do an enumerate attributes: AttributeSequence ~ FilingP10V5.GetAttributes[crH, fileH, types, mnt.session^]; [...] _ InfoFromAttributeSequence[attributes]; AttributeTypeSequences (fixed) Initialization Κt•NewlineDelimiter ˜codešœ™K™HK™/K™*K™+K˜—šΟk ˜ Kšœ œœ&˜JKšœœ˜Kšœœx˜ƒKšœ ˜ Kšœœt˜Kšœœ6˜>Kšœœ˜,Kšœœ˜Kšœ œœ˜Kšœœ˜Kšœœœ ˜.Kšœ œ˜Kšœœ˜$Kšœœ˜$Kšœœ}˜ŠKšœœ˜$Kšœ œ˜%Kšœœ\˜uKšœœ˜2Kšœœ˜.Kšœ œ4˜FKšœœ/˜EK˜—šΟnœœ˜Kšœ œœ=œB˜²Kšœ#˜*Kšœk˜oKšœœœ˜headšΟz™Kšž œœœœœœœ˜RK˜š žœœœ œœ˜XKšœ˜K˜—š ž œœœ œœœ˜]Kš œœœ œ œ ™9Kšœœœœ™AKš œœœ œœ˜3Kšœœœ˜(Kšœ'˜'K˜K˜—š žœœ œœ œ˜FKšœ œœ œ˜QKšœ$™$Kšœ˜——šŸ#™#šž œœœ#˜;Kšœœœ˜Kšœ"œ˜'K˜K˜—šž œœœ#˜˜>Kšœ˜Kšœ˜K˜—šžœœœh˜„KšœA˜AKšœ@˜@Kšœ˜Kšœ˜K˜—šžœœœ`˜{KšœA˜AKšœA˜AKšœ˜Kšœ˜K˜—šžœœœ˜+šœœ œ ˜$Kšœ.™.—K–3[h: CrRPC.Handle, session: FilingP10V5.Session]šœœœœ˜%šœ˜Kšœ œ˜#Kšœ œœ˜'Kšœ=˜=Kšœ.˜.Kšœ˜Kšœ˜—Kšœœ˜Kšœ œ˜Kšœ˜K˜——šŸ™š ž œœœœœ˜VKšœ1œ˜6KšœQ˜Qšœœ™Kšœœ™)Kšœœœ$œ™AJšœ*™*K™—šœ™Icode2–O[h: CrRPC.Handle, file: FilingP10V5.Handle, session: FilingP10V5.Session]š œœœ œœœœ™IMšœ œ™'M™—K˜K˜—šžœœœ˜$Kšœ˜šžœœœ œœ<œ œ œœœ œ˜ΉKšœ0˜0Kšœ˜—Mšœ'˜'Mšœ˜K˜K˜——šŸ ™ Kšœ œ˜Kšœœ˜š žœœœœ œLœ˜¬šžœ˜šœ œœ˜.Kšœ™—Kšœ"˜"Kšœ ˜ Kšœ œ˜Kšœ˜—Kšœ œ&˜6Kšœ œ ˜-KšœMœ˜RKšœ$˜$Kšœ ˜ šœ$œ˜,Kšœ"˜"KšœY˜YKšœ(˜(Kšœœ˜7Kš œœœ!œœ˜KKšœ˜K˜—Kšœo™oK™Kšœ˜šœ˜K™—šœœ˜Kšœ3™3Kšœœ4˜JK–&[problem: FilingP10V5.AccessProblem]šœ$˜$Kšœ"˜"KšœY˜YKšœ$œœ˜2Kšœ˜K˜—K–Z[r1: ROPE _ NIL, r2: ROPE _ NIL, r3: ROPE _ NIL, r4: ROPE _ NIL, r5: ROPE _ NIL]šœ˜Kšœ˜—K˜Kšœ œ˜Kšœœ˜šžœœ6œ˜dKšΟbœ*˜/K–{[h: CrRPC.Handle, file: FilingP10V5.Handle, types: FilingP10V5.AttributeTypeSequence, session: FilingP10V5.Session]šœ[™[Kšœ.™.Kšœ$˜$Kšœ‘œ˜&Kšœ"˜"KšœY˜YKšœ˜——šŸ™Kšœ!˜!Kšœ$˜$Kšœ)˜)Kšœ#˜#Kšœ ˜ K˜šž œœ œ(˜Jšœ œ˜Kšœ˜Kšœ˜Kšœ$˜$Kšœ˜Kšœ˜Kšœ˜Kšœœ˜—Kšœ˜—K˜šž œœœP˜jKš žœœ!œœœœ˜`Kšœ œ!˜-Kšœ œ!˜0Kšœœ!˜5Kšœ œ!˜/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šœU˜UKšœ˜K˜———K˜Kšœ˜—…—7Mΐ