DIRECTORY BasicTime USING [GetGMT, GMT, nullNetworkAddress, Now], BootSwitch USING [promptForInitializationParameters, Set], ControlMessages USING [Key], DecomposerControl USING [Expunge, Init, ModifyTraceLevel, NoticeNewFonts, NotifyProc, SetBannerMode], FaxStatus USING [TransmissionRetryReason], FontDirectory USING [Init], ForwardingControl USING [Init, ModifyTraceLevel, SetTargetPrintService], MarkerControl USING [ClientProcsHandle], MarkerInit USING [Init, MarkerInitParams], MergeControl USING [Init, ModifyTraceLevel, NotifyProc], MiscUtilities USING [CalcPagesForBandBuffers, CalcRMPagesForMarker, pagesPerBandBuffer], PaperTypes USING [nullDimensions, PaperMMDimension, PaperSize], PrincOps USING [PageCount], PrintingTypes USING [Option, RavenBuild], PrintQueue USING [FaxLocalPrintStatus, FaxMitStatus, Initialize, Next, nilQueueObjectHandle, ObjectStatus, QueueObjectHandle, QueueStage, ReleaseAsTestPattern, Requeue, ReserveForTestPattern], Process USING [Detach, priorityBackground, priorityNormal], PSAssignedTypes USING [tBackup, tPSCommandStableData, tSpooled, tTestPatterns], PSCommand USING [GetPrintServiceStatus, ResetStatistics], PSCommandInternal USING [BansheeStatusWatcher, D1StatusWatcher, DocumentCompleted, FaxStatusWatcher, FinishedMarking, FX3500StatusWatcher, MarkingEngineFailure, ProblemDuringDecomposition, ProblemDuringMerge, PutAsyncMsgFromKey, RavenStatusWatcher, ReadyToMark, RepairModeWatcher, RotateFonts90, WritableStateHandle], PSInit USING [calculateDefaultBBAllocation, calculateDefaultRMAllocation, Error, ErrorType, OptionalParms, RequiredParms, unlimitedPrintingCutOffMemSize], PSKMessages USING [GetHandle], PSState USING [maxStopReasonLength, maxUserNameLength, ServiceState, State, TraceLevel], PSVolume USING [GetDefaultSession, OpenDirectory], PSVolumeExtras USING [DeleteAll], QueueControl USING [CompletionProc, Init], QueueFile USING [Delete], Space USING [ForceOut, Interval, nullInterval, PagesFromWords, Unmap], SpecialSpace USING [realMemorySize], SpoolControl USING [Init, ModifyTraceLevel], StableData USING [DataProcessor, Enumerate, NotFound], TargetPS USING [Error, GetPrinterProperties, GetPrinterStatus], TargetPSStatus USING [Current, Properties], TestPattern USING [Init], VM USING [Interval, nullInterval], XMessage USING [Handle, MsgKey]; PSCommandInitImpl: CEDAR PROGRAM IMPORTS BasicTime, BootSwitch, DecomposerControl, FontDirectory, ForwardingControl, MarkerInit, MergeControl, MiscUtilities, NSFile, NSSegment, NSString, PrintQueue, Process, PSCommand, PSCommandInternal, PSInit, PSKMessages, PSVolume, PSVolumeExtras, QueueControl, QueueFile, Space, SpecialSpace, SpoolControl, StableData, TargetPS, TestPattern EXPORTS PSInit, PSCommandInternal = BEGIN blank: BYTE = LOOPHOLE[' ]; state: PUBLIC PSCommandInternal.WritableStateHandle _ NIL; currentCondition: PUBLIC PSState.ServiceState _ notInitialized; markerProcs: PUBLIC MarkerControl.ClientProcsHandle _ NIL; --Record containing all procs returned by marker at init. testPatternsNoticed: PUBLIC BOOLEAN _ TRUE; fontsNoticed: PUBLIC BOOLEAN _ TRUE; Error: PUBLIC ERROR [problem: PSInit.ErrorType] = CODE; developmentMode: BOOLEAN _ TRUE; controlMsgs: XMessage.Handle _ PSKMessages.GetHandle[control]; InitializeState: PUBLIC PROCEDURE = BEGIN OPEN S: NSString; nsBackingStore: ROPE = "PrinterState17.BackingStore"; backupDir: ROPE _ "///BackUp/"; stateBackingFile: FS.OpenFile _ FS.nullOpenFile; newBackingFile: BOOLEAN _ FALSE; CreateBackingFile: SAFE PROCEDURE = BEGIN stateBackingFile _ FS.Create[name: nsBackingStore, setPages: TRUE, pages: (SIZE[PSState.State]/PrincOps.wordsPerPage)+1, wDir: backupDir] END; -- CreateBackingFile InitializeSpace: SAFE PROCEDURE = BEGIN currentTime: BasicTime.GMT _ Time.Now[]; state _ NEW[PSState.State _ [ mode: [notStarted, notStarted], clientControl: [spooler: enabled, formatterEnabled: TRUE, markerEnabled: TRUE], internalControl: [spooler: disabled, formatterEnabled: FALSE, markerEnabled: FALSE], networkAddress: XNS.unknownAddress, statisticsReset: currentTime, lastInstallation: currentTime, lastBoot: currentTime, lastActivity: currentTime, nBoots: 0, docsPrinted: [total:0, grandTotal:0], docsAborted: [total:0, grandTotal:0], testPatternsPrinted: [total:0, grandTotal:0], docsRetried: [total:0, grandTotal:0], docsPurged: [total:0, grandTotal:0], commErrors: [total:0, grandTotal:0], stopPrintingReasonBody: ALL[blank], stopPrintingUserBody: ALL[blank], startPrintingUserBody: ALL[blank], stopQueuingReasonBody: ALL[blank], stopQueuingUserBody: ALL[blank], startQueuingUserBody: ALL[blank], decomposeWhileMarking: TRUE, spoolWhileMarking: TRUE, formatterPriority: Process.priorityNormal, markerPriority: Process.priorityNormal, spoolerTrace: none, formatterTrace: none, markerTrace: none, decomposerRMPagesForMarker: 256, **Will be calculated below. decomposerVMPages: 6000, markerRMPagesForBands: 48, printOrder: lastPageOutFirst, stapling: FALSE, twoSidedCopy: FALSE, unused1: 0, unused2: 0, unused3: 0, unused4: 0, printingOptionSpecific: unknown[] ]]; state.decomposerRMPagesForMarker _256; -- Not really used state.lastStopPrintingReason _ NEW[TEXT[PSState.maxStopReasonLength]], state.lastUserToStopPrinting _ NEW[TEXT[PSState.maxUserNameLength]], state.lastUserToStartPrinting _ NEW[TEXT[PSState.maxUserNameLength]], state.lastStopQueuingReason _ NEW[TEXT[PSState.maxStopReasonLength]], state.lastUserToStopQueuing _ NEW[TEXT[PSState.maxUserNameLength]], state.lastUserToStartQueuing _ NEW[TEXT[PSState.maxUserNameLength]], END; -- InitializeSpace UpdateState: SAFE PROCEDURE = BEGIN OPEN state; mode _ [notStarted, notStarted]; lastBoot _ Time.Now[]; nBoots _ nBoots + 1; docsPrinted.grandTotal _ docsPrinted.grandTotal + docsPrinted.total; docsPrinted.total _ 0; docsAborted.grandTotal _ docsAborted.grandTotal + docsAborted.total; docsAborted.total _ 0; testPatternsPrinted.grandTotal _ testPatternsPrinted.grandTotal + testPatternsPrinted.total; testPatternsPrinted.total _ 0; docsRetried.grandTotal _ docsRetried.grandTotal + docsRetried.total; docsRetried.total _ 0; docsPurged.grandTotal _ docsPurged.grandTotal + docsPurged.total; docsPurged.total _ 0; commErrors.grandTotal _ commErrors.grandTotal + commErrors.total; commErrors.total _ 0; lastStopPrintingReason.bytes _ LOOPHOLE[@state.stopPrintingReasonBody]; lastUserToStopPrinting.bytes _ LOOPHOLE[@state.stopPrintingUserBody]; lastUserToStartPrinting.bytes _ LOOPHOLE[@state.startPrintingUserBody]; lastStopQueuingReason.bytes _ LOOPHOLE[@state.stopQueuingReasonBody]; lastUserToStopQueuing.bytes _ LOOPHOLE[@state.stopQueuingUserBody]; lastUserToStartQueuing.bytes _ LOOPHOLE[@state.startQueuingUserBody]; WITH s: state SELECT FROM fax495 => BEGIN s.docsTransmitted.grandTotal _ s.docsTransmitted.grandTotal + s.docsTransmitted.total; s.docsTransmitted.total _ 0; END; feps9700 => BEGIN s.targetPSName.record.org.bytes _ LOOPHOLE[@s.targetPSName.org]; s.targetPSName.record.domain.bytes _ LOOPHOLE[@s.targetPSName.domain]; s.targetPSName.record.local.bytes _ LOOPHOLE[@s.targetPSName.local]; END; ENDCASE; END; -- UpdateState BEGIN stateBackingFile _ FS.Open[name: backupDir, wDir: nsBackingStore ! FS.Error => GOTO fileNotFound]; EXITS fileNotFound => {CreateBackingFile[]; newBackingFile _ TRUE}; END; BEGIN -- Create space for state record and map it to backing store. origin: NSSegment.Origin _ [file: stateBackingFile, base: 0, count: Space.PagesFromWords [SIZE[PSState.State]]]; stateSpace _ NSSegment.Map[origin: origin, access: NSFile.fullAccess, session: session]; state _ stateSpace.pointer; END; IF newBackingFile THEN BEGIN END ELSE UpdateState[]; --update old 10.0 backing file Space.ForceOut[stateSpace]; END; --InitializeState InitializePrintService: PUBLIC PROCEDURE [normal: BOOLEAN, serviceName: CHName.Name, required: PSInit.RequiredParms, optional: PSInit.OptionalParms _ [printingOptionParms: unknown[]]] = BEGIN --Exported by PSInit spoolDir, backupDir, fontDir: NSFile.Handle _ NSFile.nullHandle; defaultServiceName: NSString.String _ NSString.MakeString[z: commandHeap, bytes: 0]; --null string used when RegisterService doesn't return service name IF currentCondition # notInitialized THEN ERROR PSInit.Error[alreadyInitialized]; SELECT required.printingOption FROM bansheeDl, d1, fax295, fax495, feps9700, fx3500, raven => NULL; ENDCASE => ERROR PSInit.Error[printingOptionNotSupported]; IF state = NIL THEN InitializeState[]; backupDir _ PSVolume.OpenDirectory[PSAssignedTypes.tBackup]; spoolDir _ PSVolume.OpenDirectory[PSAssignedTypes.tSpooled]; [] _ PSVolume.OpenDirectory[PSAssignedTypes.tTestPatterns]; FinalizeState[required, optional]; --Apply user specified parameters to state record. fontDir _ FontDirectory.Init[state.option, session, optional.deleteIncompatibleFontsandTPs]; TestPattern.Init[printingOption: state.option, deleteIncompatibleTPs: optional.deleteIncompatibleFontsandTPs]; [] _ PrintQueue.Initialize[backupDir, 40, state.option]; DeleteObsoleteEngineLogs[backupDir]; --NOTE: Remove this in a later release. state.formatterPriority _ IF state.decomposeWhileMarking THEN Process.priorityBackground ELSE Process.priorityNormal; ClearQueues[]; --Clear the intermediate queues IF state.option # feps9700 THEN BEGIN engineSpecMarkerInitParms: MarkerInit.MarkerInitParams _ [ bufferSize: state.markerRMPagesForBands, engineFailure: PSCommandInternal.MarkingEngineFailure, finishedMarking: PSCommandInternal.FinishedMarking, readyToMark: PSCommandInternal.ReadyToMark, device: unknown[] --Compiler won't accept select stmt (below) here. **AJ 12/20/83 ]; WITH s: state SELECT FROM bansheeDl => BEGIN IF (NOT s.spoolWhileMarking) AND s.decomposeWhileMarking THEN BEGIN engineSpecMarkerInitParms.waitBetweenJobs _ TRUE; engineSpecMarkerInitParms.betweenJobWaitTime _ 15; --seconds END; engineSpecMarkerInitParms.device _ bansheeDl[enableUnlimitedPrinting: IF SpecialSpace.realMemorySize > PSInit.unlimitedPrintingCutOffMemSize THEN s.enableUnlimitedPrinting ELSE FALSE]; END; d1 => engineSpecMarkerInitParms.device _ d1[ reenteringRepairMode: s.mode.current = repair]; fax295 => BEGIN IF (NOT s.spoolWhileMarking) AND s.decomposeWhileMarking THEN BEGIN engineSpecMarkerInitParms.waitBetweenJobs _ TRUE; engineSpecMarkerInitParms.betweenJobWaitTime _ 35; --seconds END; engineSpecMarkerInitParms.device _ fax295[]; END; fax495 => BEGIN IF (NOT s.spoolWhileMarking) AND s.decomposeWhileMarking THEN BEGIN engineSpecMarkerInitParms.waitBetweenJobs _ TRUE; engineSpecMarkerInitParms.betweenJobWaitTime _ 35; --seconds END; engineSpecMarkerInitParms.device _ fax495[]; END; fx3500 => engineSpecMarkerInitParms.device _ fx3500[ reenteringRepairMode: s.mode.current = repair]; raven => BEGIN IF (NOT s.spoolWhileMarking) AND s.decomposeWhileMarking THEN BEGIN engineSpecMarkerInitParms.waitBetweenJobs _ TRUE; engineSpecMarkerInitParms.betweenJobWaitTime _ 15; --seconds END; engineSpecMarkerInitParms.device _ raven[ enableUnlimitedPrinting: IF SpecialSpace.realMemorySize > PSInit.unlimitedPrintingCutOffMemSize THEN s.enableUnlimitedPrinting ELSE FALSE]; END; ENDCASE => ERROR; markerProcs _ MarkerInit.Init[ priority: state.markerPriority, putAsyncMsgFromKey: PSCommandInternal.PutAsyncMsgFromKey, z: Heap.systemZone, deviceParams: engineSpecMarkerInitParms]; markerProcs.modifyTraceLevel[LOOPHOLE[state.markerTrace]]; markerProcs.setPrintOrder[state.printOrder]; END; WITH s: state SELECT FROM bansheeDl => WITH m: markerProcs SELECT FROM bansheeDl => BEGIN m.setBanner[s.banner]; Process.Detach[FORK PSCommandInternal.BansheeStatusWatcher[]]; END; ENDCASE => ERROR; --Procs returned by marker reflect different printing option than state record. d1 => WITH m: markerProcs SELECT FROM d1 => BEGIN m.setBanner[s.banner]; m.setRegistration[s.registration]; Process.Detach[FORK PSCommandInternal.D1StatusWatcher[]]; END; ENDCASE => ERROR; --Procs returned by marker reflect different printing option than state record. fax295 => WITH m: markerProcs SELECT FROM fax295 => BEGIN m.setBanner[s.banner]; m.setPaper[s.paperWidth]; Process.Detach[FORK PSCommandInternal.FaxStatusWatcher[]]; END; ENDCASE => ERROR; --Procs returned by marker reflect different printing option than state record. fax495 => WITH m: markerProcs SELECT FROM fax495 => BEGIN m.setBanner[s.banner]; m.setPaper[s.paperWidth]; m.setTransmissionResolution[s.fineResolutionSupported]; m.setMultipleCopies[ s.multLocalCopiesAllowed, s.multRemoteCopiesAllowed]; FOR r: FaxStatus.TransmissionRetryReason IN [noConnection..transmitError] DO m.setTransmissionRetries[r, s.retries[r].count, s.retries[r].delayInSecs]; ENDLOOP; Process.Detach[FORK PSCommandInternal.FaxStatusWatcher[]]; END; ENDCASE => ERROR; --Procs returned by marker reflect different printing option than state record. feps9700 => BEGIN MergeControl.Init[ currentOption: feps9700, priority: Process.priorityNormal, notifyProc: PSCommandInternal.ProblemDuringMerge, putAsyncMsgFromKey: PSCommandInternal.PutAsyncMsgFromKey]; MergeControl.ModifyTraceLevel[LOOPHOLE[state.markerTrace]]; ForwardingControl.Init[ currentOption: feps9700, priority: Process.priorityNormal, putAsyncMsgFromKey: PSCommandInternal.PutAsyncMsgFromKey]; IF s.targetPSAddress # Space.nullNetworkAddress THEN ForwardingControl.SetTargetPrintService[s.targetPSAddress]; ForwardingControl.ModifyTraceLevel[LOOPHOLE[state.markerTrace]]; END; fx3500 => WITH m: markerProcs SELECT FROM fx3500 => BEGIN m.setFeeding[s.paperFeed]; m.setBanner[s.banner]; m.setRegistration[s.registration]; Process.Detach[FORK PSCommandInternal.FX3500StatusWatcher[]]; END; ENDCASE => ERROR; --Procs returned by marker reflect different printing option than state record. raven => WITH m: markerProcs SELECT FROM raven => BEGIN m.setEngineBuild[s.engineBuild]; m.setFeeding[s.paperFeed]; m.setPaper[s.paperSupply]; m.setBanner[s.banner]; m.setRegistration[s.registration]; m.setStacking[s.paperStacking]; Process.Detach[FORK PSCommandInternal.RavenStatusWatcher[]]; END; ENDCASE => ERROR; --Procs returned by marker reflect different printing option than state record. ENDCASE => ERROR; --unknown printing option? state.networkAddress _ SpoolControl.Init[ maxConnections: 1, markerProcs: markerProcs, putAsyncMsgFromKey: PSCommandInternal.PutAsyncMsgFromKey]; SpoolControl.ModifyTraceLevel[LOOPHOLE[state.spoolerTrace]]; DecomposerControl.Init[ currentOption: state.option, priority: state.formatterPriority, fontDirectory: fontDir, maxVMPages: state.decomposerVMPages, maxRMPagesForMarker: state.decomposerRMPagesForMarker, maxDecomposeHandles: -- no decomposing while merging for feps9700 IF state.decomposeWhileMarking AND state.option # feps9700 THEN 3 ELSE 1, psName: IF serviceName # NIL THEN serviceName.local ELSE defaultServiceName, notifyProc: PSCommandInternal.ProblemDuringDecomposition, putAsyncMsgFromKey: PSCommandInternal.PutAsyncMsgFromKey]; WITH s: state SELECT FROM bansheeDl => DecomposerControl.SetBannerMode[s.banner # suppressed]; d1 => DecomposerControl.SetBannerMode[s.banner # suppressed]; fax295 => DecomposerControl.SetBannerMode[s.banner # suppressed]; fax495 => DecomposerControl.SetBannerMode[ s.banner.local # suppressed OR s.banner.remote # suppressed]; feps9700 => DecomposerControl.SetBannerMode[enableBanner: FALSE]; fx3500 => DecomposerControl.SetBannerMode[s.banner # suppressed]; raven => DecomposerControl.SetBannerMode[s.banner # suppressed]; ENDCASE => ERROR; DecomposerControl.ModifyTraceLevel[LOOPHOLE[state.formatterTrace]]; QueueControl.Init[ printingOption: state.option, documentCompleted: PSCommandInternal.DocumentCompleted, putAsyncMsgFromKey: PSCommandInternal.PutAsyncMsgFromKey, trace: LOOPHOLE[state.markerTrace]]; ReserveTestPattern[]; MakeInternalStateConsistent[]; IF state.option = raven OR state.option = fx3500 OR state.option = bansheeDl OR state.option = d1 THEN Process.Detach[FORK PSCommandInternal.RepairModeWatcher[]]; --will put us back into Repair mode if appropriate currentCondition _ stopped; IF required.catalogFontsAtInit THEN BEGIN IF state.option = bansheeDl THEN PSCommandInternal.RotateFonts90[]; DecomposerControl.NoticeNewFonts[]; END ELSE fontsNoticed _ FALSE; --setting this flag will force fonts to be cataloged/rotated when StartPrinting is called [] _ PSCommand.GetPrintServiceStatus[]; --Calls markerProcs to get paperSupply for fx3500 if necessary. Space.ForceOut[stateSpace]; END; --InitializePrintService ExpungePrintService: PUBLIC PROCEDURE [deleteFonts: BOOLEAN] = BEGIN IF state = NIL AND currentCondition = notInitialized THEN BEGIN DecomposerControl.Expunge[]; IF deleteFonts THEN PSVolumeExtras.DeleteAll[includingFonts: TRUE] ELSE PSVolumeExtras.DeleteAll[includingFonts: FALSE]; END ELSE ERROR PSInit.Error[alreadyInitialized]; END; --ExpungePrintService FinalizeState: PROCEDURE [required: PSInit.RequiredParms, optional: PSInit.OptionalParms] = BEGIN BansheeInit: PROCEDURE [enableUnlimited: BOOLEAN] = BEGIN state.printingOptionSpecific _ bansheeDl[ enableUnlimitedPrinting: enableUnlimited]; WITH s: state SELECT FROM bansheeDl => s.printOrder _ IF s.invertingTrayAttached THEN firstPageOutFirst ELSE lastPageOutFirst; ENDCASE => ERROR; state.decomposeWhileMarking _ state.spoolWhileMarking _ TRUE; state.decomposerVMPages _ 6000; END; --BansheeInit D1Init: PROCEDURE [] = BEGIN state.printingOptionSpecific _ d1[ ]; state.printOrder _ lastPageOutFirst; state.decomposeWhileMarking _ state.spoolWhileMarking _ TRUE; state.decomposerVMPages _ 6000; END; --D1Init Fax295Init: PROCEDURE [paperWidth: CARDINAL] = BEGIN state.printingOptionSpecific _ fax295[ banner: oncePerJob, paperWidth: paperWidth ]; state.printOrder _ firstPageOutFirst; state.decomposeWhileMarking _ state.spoolWhileMarking _ TRUE; state.decomposerVMPages _ 6000; END; --Fax295Init Fax495Init: PROCEDURE [ paperWidth: CARDINAL, supportFineResolution: BOOLEAN] = BEGIN state.printingOptionSpecific _ fax495[ paperWidth: paperWidth, fineResolutionSupported: supportFineResolution, retries: [count: 6, delayInSecs: 300], --in case of no connection [count: 3, delayInSecs: 180]; --in case of transmit error state.printOrder _ firstPageOutFirst; state.decomposeWhileMarking _ state.spoolWhileMarking _ TRUE; state.decomposerVMPages _ 6000; END; --Fax495Init FEPS9700Init: PROCEDURE = BEGIN state.printingOptionSpecific _ feps9700[ ]; WITH s: state SELECT FROM feps9700 => BEGIN s.targetPSName.record.org _ [ bytes: LOOPHOLE[@s.targetPSName.org], length: 0, maxlength: NSName.maxOrgLength]; s.targetPSName.record.domain _ [ bytes: LOOPHOLE[@s.targetPSName.domain], length: 0, maxlength: NSName.maxDomainLength]; s.targetPSName.record.local _ [ bytes: LOOPHOLE[@s.targetPSName.local], length: 0, maxlength: NSName.maxLocalLength]; END; ENDCASE => ERROR; state.printOrder _ firstPageOutFirst; state.decomposeWhileMarking _ state.spoolWhileMarking _ TRUE; --not really applicable to feps9700 state.markerRMPagesForBands _ MiscUtilities.pagesPerBandBuffer; --feps9700 always uses only one band buffer state.decomposerVMPages _ 6000; END; --FEPS9700Init FX3500Init: PROCEDURE [] = BEGIN state.printingOptionSpecific _ fx3500[ ]; state.printOrder _ lastPageOutFirst; state.decomposeWhileMarking _ state.spoolWhileMarking _ TRUE; state.decomposerVMPages _ 6000; END; --FX3500Init RavenInit: PROCEDURE [ version: PrintingTypes.RavenBuild, enableUnlimited: BOOLEAN] = BEGIN state.printingOptionSpecific _ raven[ engineBuild: version, enableUnlimitedPrinting: enableUnlimited]; WITH s: state SELECT FROM raven => SELECT version FROM b1 => {s.printOrder _ lastPageOutFirst; s.paperStacking _ aligned}; ENDCASE => {s.printOrder _ firstPageOutFirst; s.paperStacking _ jobOffset}; ENDCASE => ERROR; state.decomposeWhileMarking _ state.spoolWhileMarking _ TRUE; state.decomposerVMPages _ 6000; END; --RavenInit SetBansheeRequiredParms: PROCEDURE [enableUnlimited: BOOLEAN] = BEGIN --Assume previous printing option was bansheeDl WITH s: state SELECT FROM bansheeDl => s.enableUnlimitedPrinting _ enableUnlimited; ENDCASE; END; -- of SetBansheeRequiredParms SetFax295RequiredParms: PROCEDURE [paperWidth: CARDINAL] = BEGIN --Assume previous printing option was fax295 WITH s: state SELECT FROM fax295 => s.paperWidth _ paperWidth; ENDCASE => ERROR; END; --SetFax295RequiredParms SetFax495RequiredParms: PROCEDURE [ paperWidth: CARDINAL, supportFineResolution: BOOLEAN] = BEGIN --Assume previous printing option was fax495 WITH s: state SELECT FROM fax495 => BEGIN s.paperWidth _ paperWidth; s.fineResolutionSupported _ supportFineResolution; END; ENDCASE => ERROR; END; --SetFax495RequiredParms SetRavenRequiredParms: PROCEDURE [ version: PrintingTypes.RavenBuild, enableUnlimited: BOOLEAN] = BEGIN --Assume previous printing option was raven. WITH s: state SELECT FROM raven => BEGIN s.engineBuild _ version; s.enableUnlimitedPrinting _ enableUnlimited; SELECT version FROM b1 => {s.printOrder _ lastPageOutFirst; s.paperStacking _ aligned}; ENDCASE => {s.printOrder _ firstPageOutFirst; s.paperStacking _ jobOffset}; END; ENDCASE => ERROR; END; --SetRavenRequiredParms SetVariantOptionalParms: PROCEDURE [ spoolWhileMarking, decomposeWhileMarking: BOOLEAN] = BEGIN state.spoolWhileMarking _ spoolWhileMarking; state.decomposeWhileMarking _ decomposeWhileMarking; END; --SetVariantOptionalParms IF state.option = required.printingOption THEN BEGIN --same printing option as before IF required.newParametersSpecified THEN WITH r: required SELECT FROM bansheeDl => SetBansheeRequiredParms[r.enableUnlimitedPrinting]; d1 => NULL; fax295 => SetFax295RequiredParms[r.paperWidth]; fax495 => SetFax495RequiredParms[ r.paperWidth, r.supportFineResolution]; feps9700 => NULL; fx3500 => NULL; raven => SetRavenRequiredParms[r.version, r.enableUnlimitedPrinting]; ENDCASE => ERROR; END ELSE BEGIN --initialize a new printing option WITH r: required SELECT FROM bansheeDl => BansheeInit[r.enableUnlimitedPrinting]; d1 => D1Init[]; fax295 => Fax295Init[r.paperWidth]; fax495 => Fax495Init[r.paperWidth, r.supportFineResolution]; feps9700 => FEPS9700Init[]; fx3500 => FX3500Init[]; raven => RavenInit[r.version, r.enableUnlimitedPrinting]; ENDCASE => ERROR; PSCommand.ResetStatistics[]; --reset counts of docs printed, docs transmitted, etc. END; IF optional.printingOption # unknown THEN BEGIN WITH o: optional SELECT FROM bansheeDl => SetVariantOptionalParms[o.spoolWhileMarking, o.decomposeWhileMarking]; d1 => SetVariantOptionalParms[o.spoolWhileMarking, o.decomposeWhileMarking]; fax295 => SetVariantOptionalParms[o.spoolWhileMarking, o.decomposeWhileMarking]; fax495 => SetVariantOptionalParms[o.spoolWhileMarking, o.decomposeWhileMarking]; feps9700 => NULL; --no feps9700 optional parms fx3500 => SetVariantOptionalParms[o.spoolWhileMarking, o.decomposeWhileMarking]; raven => SetVariantOptionalParms[o.spoolWhileMarking, o.decomposeWhileMarking]; ENDCASE => ERROR; state.decomposerVMPages _ optional.vmPagesForDecomposer; WITH s: state SELECT FROM bansheeDl => s.markerRMPagesForBands _ --banshee may have unlimited printing enabled IF optional.bandBufferPages = PSInit.calculateDefaultBBAllocation THEN MiscUtilities.CalcPagesForBandBuffers[bansheeDl, s.enableUnlimitedPrinting] ELSE optional.bandBufferPages; raven => s.markerRMPagesForBands _ --raven may have unlimited printing enabled IF optional.bandBufferPages = PSInit.calculateDefaultBBAllocation THEN MiscUtilities.CalcPagesForBandBuffers[raven, s.enableUnlimitedPrinting] ELSE optional.bandBufferPages; ENDCASE => s.markerRMPagesForBands _ IF optional.bandBufferPages = PSInit.calculateDefaultBBAllocation THEN MiscUtilities.CalcPagesForBandBuffers[s.option] ELSE optional.bandBufferPages; state.decomposerRMPagesForMarker _ IF optional.decomposerRMPageLimit = PSInit.calculateDefaultRMAllocation THEN MiscUtilities.CalcRMPagesForMarker[state.markerRMPagesForBands] ELSE optional.decomposerRMPageLimit; END ELSE BEGIN WITH s: state SELECT FROM bansheeDl => s.markerRMPagesForBands _ MiscUtilities.CalcPagesForBandBuffers[bansheeDl, s.enableUnlimitedPrinting]; raven => s.markerRMPagesForBands _ MiscUtilities.CalcPagesForBandBuffers[raven, s.enableUnlimitedPrinting]; ENDCASE => s.markerRMPagesForBands _ MiscUtilities.CalcPagesForBandBuffers[s.option]; state.decomposerRMPagesForMarker _ MiscUtilities.CalcRMPagesForMarker[state.markerRMPagesForBands]; END; WITH s: state SELECT FROM feps9700 => IF s.targetPSAddress # BasicTime.nullNetworkAddress THEN BEGIN remoteStatus: TargetPSStatus.Current _ TargetPS.GetPrinterStatus[s.targetPSAddress ! TargetPS.Error => GOTO CantReachTarget]; remoteProperties: TargetPSStatus.Properties _ TargetPS.GetPrinterProperties[s.targetPSAddress ! TargetPS.Error => GOTO CantReachTarget]; s.paperSupply _ remoteStatus.paperSupply; s.stapling _ remoteProperties.staple; s.twoSidedCopy _ remoteProperties.twoSided; EXITS CantReachTarget => PSCommandInternal.PutAsyncMsgFromKey[ [domain: controlMsgs, key: XKey[mSetTargetWarning]]]; END; ENDCASE; Space.ForceOut[stateSpace]; END; --FinalizeState ClearQueues: PROCEDURE = BEGIN Dispose[fromQueue: spooling, disposeQ: aborted, statusOtherwise: sysRestartInSpooler]; Dispose[fromQueue: decomposing, retryQ: spooledNormal, disposeQ: aborted, statusIfRetried: restart, statusOtherwise: sysRestartInDecomposer]; Dispose[fromQueue: decomposed, retryQ: spooledNormal, disposeQ: aborted, statusIfRetried: restart, statusOtherwise: sysRestartInQueue]; Dispose[fromQueue: merging, retryQ: spooledNormal, disposeQ: aborted, statusIfRetried: restart, statusOtherwise: sysRestartInMerger]; Dispose[fromQueue: marking, retryQ: spooledNormal, disposeQ: aborted, statusIfRetried: restart, statusOtherwise: sysRestartInMarker]; Dispose[fromQueue: forwarding, retryQ: merged, disposeQ: aborted, statusIfRetried: merged, statusOtherwise: sysRestartInForwarder]; Dispose[fromQueue: retransmit, retryQ: spooledNormal, disposeQ: aborted, statusIfRetried: restart, statusOtherwise: sysRestartInQueue]; Dispose[fromQueue: temp, retryQ: spooledNormal, disposeQ: marked, statusIfRetried: restart, statusOtherwise: sysRestartInQueue]; Dispose[fromQueue: tpSpooled, disposeQ: aborted, statusOtherwise: sysRestartInQueue]; Dispose[fromQueue: tpDecomposed, disposeQ: aborted, statusOtherwise: sysRestartInQueue]; Dispose[fromQueue: tpMerged, disposeQ: aborted, statusOtherwise: sysRestartInQueue]; END; --ClearQueues DeleteObsoleteEngineLogs: PROCEDURE [dir: NSFile.Handle] = BEGIN ravenLog: NSString.String = Str["Raven.log"L]; bansheeLog: NSString.String = Str["Banshee.log"L]; NSFile.DeleteByName[dir, ravenLog, session ! NSFile.Error => CONTINUE]; NSFile.DeleteByName[dir, bansheeLog, session ! NSFile.Error => CONTINUE]; END; -- of DeleteObsoleteEngineLogs Dispose: PROCEDURE [ fromQueue: PrintQueue.QueueStage, retryQ, disposeQ: PrintQueue.QueueStage _ inactive, statusIfRetried: PrintQueue.ObjectStatus _ null, statusOtherwise: PrintQueue.ObjectStatus] = BEGIN qOH: PrintQueue.QueueObjectHandle _ PrintQueue.Next[qOH: PrintQueue.nilQueueObjectHandle, fromQueue: fromQueue]; UNTIL qOH = PrintQueue.nilQueueObjectHandle DO qOH.printObjectHandle _ NIL; -- Bands List and Font Load were temp files IF qOH.priorStatus = null AND statusIfRetried # PrintQueue.ObjectStatus[null] AND qOH.deleteInactiveFile = TRUE --not a test pattern-- THEN BEGIN qOH.priorStatus _ statusOtherwise; qOH.currentStatus _ statusIfRetried; WITH q: qOH SELECT FROM fax495 => SELECT fromQueue FROM marking, retransmit, temp => UpdateFaxStatuses[qOH: qOH, localStatus: queued, remoteStatus: queued, willRetry: TRUE]; ENDCASE; feps9700 => IF fromQueue = merging THEN IF q.ivFileID # NSFile.nullID THEN q.ivFileID _ QueueFile.Delete[q.ivFileID]; --returns nullID ENDCASE; qOH _ PrintQueue.Requeue[ --returns next qOH from fromQueue qOH: qOH, fromQueue: fromQueue, toQueue: retryQ, position: front]; state.docsRetried.total _ state.docsRetried.total + 1; END ELSE BEGIN qOH.currentStatus _ statusOtherwise; WITH q: qOH SELECT FROM fax495 => SELECT fromQueue FROM marking, retransmit, temp => UpdateFaxStatuses[qOH: qOH, localStatus: purgedAtSysRestart, remoteStatus: purgedAtSysRestart, willRetry: FALSE]; ENDCASE; ENDCASE; qOH _ PrintQueue.Requeue[ --returns next qOH from fromQueue qOH: qOH, fromQueue: fromQueue, toQueue: disposeQ]; state.docsPurged.total _ state.docsPurged.total + 1; END; ENDLOOP; END; -- Dispose MakeInternalStateConsistent: PROCEDURE = BEGIN -- Sort out the control state... SELECT state.mode.current FROM repair => NULL; --should return to repair mode. ENDCASE => BEGIN state.internalControl.spooler _ disabled; state.internalControl.formatterEnabled _ FALSE; state.internalControl.markerEnabled _ FALSE; IF state.mode.current # normal AND state.mode.current # notStarted THEN --diagnostic, fileWrite, fileDelete, and shutDown modes don't survive across boots state.mode.current _ state.mode.returnTo _ normal; END; END; --MakeInternalStateConsistent ReserveTestPattern: PROCEDURE = BEGIN qOH: PrintQueue.QueueObjectHandle _ PrintQueue.Next[qOH:, fromQueue: tpInactive]; IF qOH = PrintQueue.nilQueueObjectHandle THEN BEGIN -- none installed qOH _ PrintQueue.ReserveForTestPattern[qOH:, fromQueue: inactive, toQueue: tpInactive]; END ELSE BEGIN -- ensure there's only one installed tpQOH: PrintQueue.QueueObjectHandle _ PrintQueue.Next[qOH: qOH, fromQueue: tpInactive]; UNTIL tpQOH = PrintQueue.nilQueueObjectHandle DO PrintQueue.ReleaseAsTestPattern[qOH: tpQOH, fromQueue: tpInactive, toQueue: inactive]; tpQOH _ PrintQueue.Next[qOH: qOH, fromQueue: tpInactive]; ENDLOOP; END; END; -- ReserveTestPattern UpdateFaxStatuses: PROCEDURE [qOH: PrintQueue.QueueObjectHandle, localStatus: PrintQueue.FaxLocalPrintStatus, remoteStatus: PrintQueue.FaxMitStatus, willRetry: BOOLEAN] = BEGIN WITH q: qOH SELECT FROM fax495 => BEGIN IF q.localPrintStatus # printed AND q.localPrintStatus # null THEN BEGIN q.localPrintStatus _ localStatus; q.localPrintCompletionDate _ IF willRetry THEN NSFile.nullTime ELSE BasicTime.GetGreenwichMeanTime[]; END; FOR i: CARDINAL IN [0..q.phoneNoCount) DO q.transmitData[i].completionDate _ IF willRetry THEN NSFile.nullTime ELSE BasicTime.GetGreenwichMeanTime[]; q.transmitData[i].queuedForRetry _ FALSE; SELECT q.transmitData[i].status FROM IN [busy..transmitError], localFaxFailure => IF willRetry THEN q.transmitData[i].queuedForRetry _ TRUE; transmitted => NULL; ENDCASE => q.transmitData[i].status _ remoteStatus; ENDLOOP; END; ENDCASE => ERROR; END; --UpdateFaxStatuses XKey: PROCEDURE [key: ControlMessages.Key] RETURNS [xKey: XMessage.MsgKey] = {RETURN[ORD[key]]}; Str: PROCEDURE [s: LONG STRING] RETURNS [ns: NSString.String] = INLINE {RETURN[NSString.StringFromMesaString[s]]}; END. -- of PSCommandInitImpl LOG when/who/what ****EARLIER LOG ENTRIES DELETED. See archived version from 8.0. 12-Jul-84 14:42:09 - Jacks - Reset stacking to aligned with Raven B1 initialized. 17-Aug-84 13:42:31 - Jacks - Removed all reference to aps phototypesetter option. ****SPLIT OFF FROM PSCommandCImpl 20-Sep-84 13:31:14 - Jacks - Updated to 9.0 PS interfaces: PrintQueue, MarkerControl, MarkerInit, DecomposerControl, PSState, PSCommand. 2-Oct-84 15:01:25 - Jacks - Moved all operator interface prompts to PSExecInitImpl; redefined the Initialize proc as in PSInit interface; moved engine status watcher procs to PSCommandCImpl. 19-Oct-84 13:35:57 - Jacks - Moved CalcRMPagesForMarker into new MiscUtilitiesImpl module; added code for feps9700; added code to CopyOldStateData. 29-Oct-84 17:40:10 - Jacks - Put code in InitializeState to initialize ps80State strings before copying them. 16-Nov-84 13:42:07 - Jacks - Updated to second round 9.0 interface changes; moved noResources error msg from DecomposerControlImpl.Exception to ProblemDuringDecomposition; consolidated all QueueControl Init procs into DocumentCompleted; added RegisterAccountProc for new PrintServiceAccounting interface. 20-Nov-84 10:39:32 - Jacks - Added call to ForwardingControl.SetTargetPrintService to init. 27-Nov-84 13:57:11 - Jacks - Moved callback procs used as init parms and RegisterAccountProc to PSCommandCImpl (now import them from PSCommandInternal). 6-Dec-84 16:00:52 - Jacks - Replaced fontsNoticed with fontsInstalled and fontsDeleted; changed around DeleteOldFonts. 13-Dec-84 14:01:19 - Jacks - Changed call to TargetPS.GetPrinterStatus in FinalizeState. 16-Jan-85 15:49:11 - Jacks - Added "ps" prefix to all new msg keys for 9.0. 18-Jan-85 15:55:07 - Jacks - Updated product factoring for feps9700. 24-Jan-85 14:14:35 - Jacks - Commented back in deletion of pre 9.0 state information after 9.0 initialization. 6-Feb-85 17:19:03 - Jacks - Converted to new version of PSInit; added call to calculate RM for decomposer in default init case; call TestPattern.Init during initialization. 28-Feb-85 10:15:44 - Jacks - Now fork RepairModeWatcher for banshee; fontsInstalled and fontsDeleted were replaced by fontsNoticed. 18-Jun-85 14:55:27 - Jacks - Added copyright notice; updated to PS Euclid interfaces. 27-Jun-85 15:58:34 - Jacks - Added code for d1 engine. 1-Jul-85 16:45:10 - Jacks - Updated UpdateFaxStatuses. 24-Jul-85 11:14:51 - Jacks - Updated to Services Euclid interfaces, including XMessage; took out product factoring, leaving it up to PSExecInitImpl. 7-Aug-85 12:24:09 - Jacks - Rewrote DeleteOldFonts; now open all font directories; added MoveBansheeFontsIfNecessary; removed reenteringRepairMode from MarkerInit for raven; updated to new CalcRMPagesForMarker and CalcPagesForBandBuffers; added MoveD1Fonts; changed Adjust90State to Copy90State. 29-Aug-85 14:30:17 - Jacks - Added Expunge; unmap 8.0 and 9.0 state spaces; changed initialize size of commandHeap to 3 pages. 6-Sep-85 15:56:35 - Jacks - Created InitializeFontDirectory proc; improved DeleteIncompatibleFontDirs (used to be DeleteOldFonts), DeleteObsoleteEngineLogs and MoveBansheeFontsIfNecessary; always one band buffer for feps. 9-Sep-85 14:08:45 - Jacks - Changed fax retry defaults in Fax495Init; increased commandHeap to 5 pages. 11-Sep-85 11:30:07 - Jacks - Font directories reworked: moved the functionality to a new module FontDirectoryImpl, deleted InitializeFontDirectory, DeleteIncompatibleFontDirs, MoveD1Fonts and oveBansheeFontsIfNecessary. 25-Sep-85 12:30:56 - Jacks - Updated to new PSState, PSInit and MarkerInit with enableUnlimitedPrinting and betweenJobWaitTime options. 27-Sep-85 12:42:21 - Jacks - Don't enable unlimited printing unless mem size is big enough. 8-Oct-85 13:47:39 - Jacks - Updated to new CalcPagesForBandBuffers and changes to PSInit; fork RepairModeWatcher for d1; set spoolWhileMarking to TRUE for US printers. 15-Oct-85 9:38:02 - Jacks - New state backing store again. 6-Nov-85 10:43:33 - Jacks - Added call to DecomposerControl to Expunge; get msg handle from PSKMessages; added signal FontsNotCataloged. 7-Nov-85 11:23:22 - Jacks - Removed FontsNotCataloged; clear tpSpooled queue in ClearQueues. 13-Nov-85 10:30:04 - Jacks - Default spoolWhileMarking and decomposeWhileMarking to TRUE for FX printers. 27-Nov-85 17:07:05 - Jacks - Set decomposer vm pages to 6000 in various Init procs in FinalizeState. 26-Feb-86 17:25:46 - Jacks - Limit decompose handles to 1 for feps9700. 14-May-86 16:12:38 - Jacks - Moved InitializeState from mainline code to public proc; ExpungePrintService no longer needs to close backup directory. 20-May-86 15:27:32 - Jacks - Only catalog fonts if init parm indicates. ¦PSCommandInitImpl.mesa Copyright (C) Xerox Corporation 1983, 1984, 1985, 1986. All rights reserved. Last edited by Jacks: 20-May-86 15:27:46 Ruseli Binsol: October 15, 1986 3:14:16 pm PDT Tim Diebert: December 15, 1986 2:59:37 pm PST <> Heap USING [Create, systemZone], NSAssignedTypes USING [FileType], NSFile USING [Attribute, Close, Create, Delete, DeleteByName, Error, fullAccess, GetReference, Handle, OpenByName, nullHandle, nullID, nullTime, Reference, Session], NSName USING [maxDomainLength, maxLocalLength, maxOrgLength, Name, NameRecord, nullNameRecord], NSSegment USING [Map, Origin], NSString USING [AppendString, MakeString, nullString, String, StringFromMesaString], PS80State USING [PaperSize, RavenBuild, State, StateHandle], PS90State USING [PaperSize, RavenBuild, State, StateHandle], TYPEs PUBLIC variables exported by PSCommandInternal: This flag is set to TRUE if test patterns have not been cataloged or may have been installed or deleted, so that when StartPrinting is called the current test patterns will be enumerated: This flag is set to FALSE when fonts are installed or deleted, because the decomposer closes all the font files at that time. When StartPrinting is called the current fonts will be cataloged by the decomposer and rotated if necessary for banshee: PUBLIC ERRORs and SIGNALs exported by PSInit: Private variables: Message domain handle: ============================================================================= PRINT SERVICE INITIALIZATION AND EXPUNGE PROCS (exported by PSInit): ============================================================================ <> backupDir: NSFile.Handle _ PSVolume.OpenDirectory[PSAssignedTypes.tBackup]; ===================================== attrList: ARRAY [0..3) OF NSFile.Attribute _ [[dataSize[2*SIZE[PSState.State]]], [name[nsBackingStore]], [type[PSAssignedTypes.tBackup]]]; ===================================== Current Status-- Systems Statistics-- Systems Parameters-- Option Independent Paper Handling-- Reserved for emergency future use: Option Specific Information-- Option information is initialized durint PromptForStartupOptions. ===================================== ======================================= ****** Initialize/update state record and print queue ******* ******* Marker Initialization ****** Marker must be initialized before spooler and decomposer because markerProcs is passed to both. <> Set engine independent marker parameters... Set engine specific marker parameters and merger/forwarder parameters for feps9700... ****** Spooler initialization ****** ****** Decomposer initialization ****** ****** QueueControl initialization ****** This proc will check to make sure all the fonts have been rotated for banshee... ================================= STATE RECORD INITIALIZATION: ================================= invertingTrayAttached: FALSE, banner: oncePerJob, paper: [knownSize: letter, otherSize: PaperTypes.nullDimensions], banner: oncePerJob, paperSize: a4, trayEmpty: FALSE, registration: [15, 15] NOTE: Check these assumptions: docsTransmitted: [total: 0, grandTotal: 0], banner: [local: oncePerJob, remote: suppressed], multLocalCopiesAllowed: TRUE, multRemoteCopiesAllowed: FALSE, paperSupply: [letter, letter], targetPSAddress: BasicTime.nullNetworkAddress, targetPSName: [record: NSName.nullNameRecord, org: ALL[blank], domain: ALL[blank], local: ALL[blank]] Initialize target name record: banner: oncePerJob, paperSupply: [a4, a4], topPaperTrayEmpty: FALSE, bottomPaperTrayEmpty: FALSE, paperFeed: fromBottomOrTop, registration: [long: 15, short: 15] banner: oncePerJob, paperSupply: [letter, letter], paperFeed: fromBottomOrTop, paperStacking: aligned, registration: [long: 23, short: 8], ============================================== If printingOption = unknown then optional parameters aren't specified. Set optional parameters from variant part of parm record... Set optional parameters from shared part of parm record... <> <> For feps9700 make remote procedure call to target (if known) to get paper size and properties... display warning message that target can't be reached =============================================== SUPPORT ROUTINES: =============================================== Clear the intermediate queues <> statusIfRetried=PrintQueue.ObjectStatus[null] means: Just move job to disposeQ. There's a timing consideration that we must check for. If a document is found on the merging queue it is possible that the merged file has already been made permanent (i.e. we crashed just before moving the doc to merged queue). QueueFile.Delete will not raise any error if the file isn't found... The state.clientControl stays as is. Spooler, formatter and marker are disabled initially. They get enabled by the start proc: StartPrintService (PSCommandAImpl). IF qOH=PrintQueue.nilQueueObjectHandle THEN ???? Straighten out local print and phone number statuses. Κ˜codešœe™eKšœ(™(K™.K™-—K˜K™6K˜šΟk ˜ Kšœ œ œ˜7Kšœ œ*˜:Kšœœ˜KšœœN˜eKšœ œ˜*Kšœœ˜Kšœœ1˜HKšœœ™ Kšœœ˜(Kšœ œ˜*Kšœ œ&˜8KšœœE˜XKšœœ ™!Kšœœ™™₯KšœœS™_Kšœ œ™Kšœ œF™TKšœ œ/˜?Kšœ œ ˜Kšœœ˜)Kšœ œ°˜ΐKšœœ.˜;Kšœ œ-™˜K˜—KšœM™MKšœD™DšœL™LK˜—š œœ œ˜#K™DK™'K˜Kšœœœœœœœœœ œœ™EKš  œœœœœ™DK™K˜Kšœœ œ ˜Kšœœ!˜5K™KKšœ œ˜Kšœœ œ˜0Kšœœœ˜ K˜Kšœ%™%K˜š œœ œ˜)Kšœ œœ!œL™ŠK•StartOfExpansion[name: ROPE, setPages: BOOL _ TRUE, pages: INT _ 0, setKeep: BOOL _ FALSE, keep: CARDINAL _ 1B (1), wDir: ROPE _ NIL]šœœ(œ œ:˜‰KšœŸ˜—Kšœ%™%K˜š œœ œ˜'Kšœœ˜(šœœ˜KšœŸ™Kšœ˜Kšœ4œœ˜OKšœ7œœ˜TK˜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šœ˜—KšœœŸO˜a——˜šœœ˜šœ˜ K˜K˜"K˜Kšœœ&˜9Kšœ˜—KšœœŸO˜a——˜ šœœ˜šœ ˜K˜˜K˜—Kšœœ'˜:Kšœ˜—KšœœŸO˜a——˜ šœœ˜šœ ˜K˜K˜K˜7˜K˜5—šœ&œ˜LK˜JKšœ˜K˜—Kšœœ'˜:Kšœ˜—KšœœŸO˜a——šœ ˜˜K˜:K˜1K˜:—Kšœœ˜;K˜˜K˜:K˜:—šœ.˜4K˜;—Kšœ#œ˜@Kšœ˜—˜ šœœ˜šœ ˜K˜K˜K˜"K˜Kšœœ*˜=Kšœ˜—KšœœŸO˜a——˜ šœœ˜šœ ˜K˜ K˜K˜K˜K˜"K˜K˜Kšœœ)˜KšœŸ,˜2šœ œ˜šœ ˜K˜K˜,šœ ˜K˜CKšœD˜K—Kšœ˜—Kšœœ˜—KšœŸ˜K˜—š œ œ˜$Kšœ*œ˜:K˜,K˜4KšœŸ˜K˜—Kšœ.™.K˜šœ(œœŸ ˜Ušœ!˜'šœ œ˜K˜@Kšœœ˜ K˜/˜!K˜'—Kšœ œ˜Kšœ œ˜K˜EKšœœ˜——Kš˜—šœœŸ"˜-šœ œ˜K˜4K˜K˜#K˜—˜EK˜?—˜EK˜?—˜AK˜A—˜HK˜>—˜AK˜>—˜0K˜$—˜3K˜$—˜/K˜$—KšœŸ ˜——˜Kš œ œ˜@šœaœ2™˜K˜.K˜2Kšœ=œ˜GKšœ?œ˜IKšœŸ˜#K˜—š œ œ˜K˜!K˜3K˜0Kšœ+˜1KšœO™OK˜pšœ'˜.KšœœŸ+˜Hšœ˜Kšœ0˜3š œœŸœœ˜CK˜"K˜$šœœ˜šœ œ ˜˜8Kšœ6œ˜<—Kšœ˜—šœ œ˜'Kšœ6™6Kšœ:™:Kšœ4™4Kšœ=™=K˜Kšœ,™,Kšœ™šœœ˜#Kšœ+Ÿ˜;——Kšœ˜—šœŸ!˜;K˜B—K˜6Kš˜——šœ˜ K˜$šœœ˜šœ œ ˜˜8KšœNœ˜U—Kšœ˜—Kšœ˜—šœŸ!˜;K˜3—K˜4Kšœ˜—Kšœ˜—KšœŸ ˜K˜—š œ œœŸ ˜PKšœ[™[KšœG™Gšœ˜Kšœ œŸ˜0šœ˜K˜)Kšœ)œ˜/Kšœ&œ˜,šœœ!œŸR˜šK˜2—Kšœ˜——KšœŸ˜#K˜—š œ œ˜%K˜Qšœ'œœŸ˜FK˜WKšœ0™0Kš˜—šœœŸ$˜0šœWœ)˜ˆ˜BK˜—K˜9Kšœ˜—Kšœ˜—šœŸ˜K˜——š œ œ%˜AK˜,Kšœ2œ˜BKšœ5™5šœœ˜šœ ˜šœœœ˜HK˜!šœœ œ˜>Kšœ"˜&—Kšœ˜—šœœœ˜)šœ#œ œ˜DKšœ"˜&—Kšœ#œ˜)šœ˜$šœ*˜,Kšœ œ$œ˜:—Kšœœ˜Kšœ,˜3—Kšœ˜—Kšœ˜—Kšœœ˜—KšœŸ˜K˜—š œ œœ˜LKšœœœ˜K˜—š  œ œœœœ˜FKšœœ$˜+——K˜KšœŸ˜K˜—Kšœ˜Kš œœœœœ!˜@K˜QK˜QKšœœœœ˜!šœ,œZ˜ˆK˜Ύ—K˜“K˜mK˜°K˜[˜˜K˜v—K˜YK˜KK˜D˜nKšœXœR˜¬—K˜ƒKšœ@œ˜U˜6K˜6—˜”K˜§—˜~K˜έK˜g—K˜άK˜‡˜[Kšœ’œœ ˜§—˜;K˜ˆK˜\—KšœTœœ ˜iK˜dK˜GK˜”K˜G—…—Š4ΐξ