DIRECTORY
IO,
Commander USING [ CommandProc, Register ],
Convert USING [ IntFromRope ],
Lark USING [ bStar, bThorp, CommandEvent, CommandEvents, CommandEventSequence, Device, disabled, DTMFEvent, enabled, endNum, Event, Passel, reset, StatusEvent, StatusEvents, SHHH ],
LarkRpcControl,
LarkSmarts,
Nice,
RPC USING [ CallFailed ], 
Rope USING [ Concat, FromChar, Length, ROPE ],
Process USING [ Detach, MsecToTicks, SetTimeout, Ticks ],
ThPartyPrivate USING [ SmartsData ],
ThSmartsPrivate USING [
click, EnterLarkSt, flushMarker, GetSmartsInfo, HookState, indexMarkerEnd, LarkInfo, LarkProseQueue, LarkState, maxClientMarker, ProseControlDone, proseFailure, ReportProseDone, RingDetState, SmartsInfo, stopAndFlushEnd, TerminalType, TonesDone ],
Thrush USING[ H, pERROR, ProseSpec, ROPE, SHHH, SmartsHandle, ThHandle ],
ThNet USING [ pd ],
VoiceUtils USING [ Problem, Report ]
;

LarkInImpl: CEDAR MONITOR LOCKS info USING info: LarkInfo
IMPORTS
LarkRpcControl, Commander, Convert, IO, Nice, Process, Rope, RPC, ThNet, Thrush, ThSmartsPrivate, VoiceUtils
EXPORTS LarkSmarts, ThSmartsPrivate= {
OPEN IO;

H: PROC[r: REF] RETURNS[Thrush.ThHandle] = INLINE {RETURN[Thrush.H[r]]; };
HookState: TYPE = ThSmartsPrivate.HookState;
LarkInfo: TYPE = ThSmartsPrivate.LarkInfo;
RingDetState: TYPE = ThSmartsPrivate.RingDetState;
SmartsData: TYPE = ThPartyPrivate.SmartsData;
SmartsInfo: TYPE = ThSmartsPrivate.SmartsInfo;
SmartsHandle: TYPE = Thrush.SmartsHandle;
TerminalType: TYPE = ThSmartsPrivate.TerminalType;
ROPE: TYPE = Thrush.ROPE;
bStar: Lark.Event = Lark.bStar;
bThorp: Lark.Event = Lark.bThorp;
enabled: Lark.Event = Lark.enabled;
endNum: Lark.Event = Lark.endNum;
disabled: Lark.Event = Lark.disabled;
reset: Lark.Event = Lark.reset;

PD: TYPE = RECORD [
callTimeoutOK: BOOL_FALSE -- set to keep Thrush alive when debugging a Lark.
];
pd: REF PD _ NEW[PD_[]];



DebEvent: PROC[info: SmartsInfo, ev: Lark.StatusEvent] = INLINE {
s: IO.STREAM=IO.ROS[];
s.PutF["[%3B, %3B, ",
card[LONG[
IF info#NIL THEN LOOPHOLE[info.larkInfo.netAddress.host,CARDINAL]
ELSE LOOPHOLE[777B, CARDINAL]]],
card[LONG[LOOPHOLE[ev.device, CARDINAL]]]]; 
IF ev.event<='z THEN s.PutF["%g]  ",char[ev.event]]
ELSE s.PutF["<%3B>]  ", card[LONG[LOOPHOLE[ev.event, CARDINAL]]]];
VoiceUtils.Report[s.RopeFromROS[], $LarkDetailed, info.larkInfo];
};

crowbar: BOOL_FALSE; -- TRUE to check basic RPC performance from Lark.
RecordEvent: PUBLIC PROC[shh: Thrush.SHHH, smartsID: Thrush.SmartsHandle, whatHappened: Lark.StatusEvents]
RETURNS [ success: BOOL_TRUE ]
= {
smartsInfo: SmartsInfo = ThSmartsPrivate.GetSmartsInfo[smartsID: smartsID];
parseInfo: SmartsInfo _ smartsInfo;
info: LarkInfo;
parseSmarts: SmartsData;
IF smartsInfo=NIL OR (info _ smartsInfo.larkInfo)=NIL THEN RETURN[FALSE];
parseSmarts _ smartsInfo.smarts;
FOR i: Lark.Passel IN [0 .. whatHappened.length) DO
sEvent: Lark.StatusEvent _ whatHappened[i];
IF ThNet.pd.debug THEN DebEvent[smartsInfo, sEvent];
IF crowbar OR info.larkState=failed OR info.larkState=recovering THEN LOOP;
SELECT sEvent.device FROM
ringDetect => {
parseSmarts _ smartsInfo.otherSmarts;
parseInfo _ ThSmartsPrivate.GetSmartsInfo[smarts: parseSmarts]; };
tones => {
ThSmartsPrivate.TonesDone[smartsInfo.larkInfo, sEvent, smartsInfo];
LOOP;
};
ENDCASE;
SELECT sEvent.device FROM
speakerSwitch => sEvent _ InterpretSpeakerSwitch[info, sEvent];
ringDetect => sEvent _ InterpretRingDetect[info, H[parseSmarts], parseInfo, sEvent];
touchPad => {
IF sEvent.event=disabled THEN sEvent.event _ smartsInfo.lastTouchpadChar
ELSE {
smartsInfo.lastTouchpadChar _ sEvent.event; LOOP; -- down transitions of DTMF pad.
};
IF sEvent.event='\000 THEN LOOP;
};
keyboard => {
IF info.textToSpeech THEN HandleAndReport[info, sEvent, smartsInfo];
LOOP;
};
hookSwitch => NULL;
ENDCASE => Thrush.pERROR;
IF sEvent.device=nothing THEN LOOP;
parseInfo.ParseEvent[ smartsInfo: parseInfo, sEvent: sEvent ];
ENDLOOP; };

EventRope: PUBLIC PROC[
shh: Thrush.SHHH, smartsID: SmartsHandle, time: CARDINAL, device: Lark.Device, events: ROPE]
RETURNS[success: BOOL] = {
NULL;
};

HandleProseOutput: ENTRY PROC[info: LarkInfo, commandEvent: Lark.StatusEvent, sInfo: SmartsInfo] RETURNS [pS: Thrush.ProseSpec _ NIL] = {
c: CHAR _ commandEvent.event;
SELECT c FROM
IO.BEL => NULL; -- take some error action?
IO.ESC, ';, '\\ => info.proseResponse _ ""; -- start of some response
'[ => NULL;  -- peel this character off
ThSmartsPrivate.stopAndFlushEnd => {
ThSmartsPrivate.ProseControlDone[info, ThSmartsPrivate.flushMarker, sInfo];
info.flushJustFinished _ TRUE;
};
ThSmartsPrivate.indexMarkerEnd => {
marker: INT;
IF Rope.Length[info.proseResponse]=0 THEN RETURN;
marker _ Convert.IntFromRope[info.proseResponse];
IF marker > ThSmartsPrivate.maxClientMarker THEN
ThSmartsPrivate.ProseControlDone[info, marker, sInfo]
ELSE {
pQ: ThSmartsPrivate.LarkProseQueue _ info.proseQueue;
IF pQ=NIL THEN Thrush.pERROR;
IF info.flushJustFinished THEN {
FOR pSkip: ThSmartsPrivate.LarkProseQueue _ pQ, pSkip.rest WHILE pSkip#NIL DO
IF pSkip.first.proseMarker = marker THEN pQ _ pSkip;
ENDLOOP;
info.flushJustFinished _ FALSE;
};
IF pQ.first.proseMarker = marker THEN {
pS _ pQ.first.proseSpec;
info.proseQueue _ pQ.rest;  -- Flush any skipped items.
IF info.proseQueue=NIL THEN info.pTail _ NIL;
}
ELSE
ThSmartsPrivate.ProseControlDone[info, ThSmartsPrivate.proseFailure, sInfo]; -- fail!!!
};
};
ENDCASE => info.proseResponse _ Rope.Concat[info.proseResponse, Rope.FromChar[c]];
};

HandleAndReport: PROC [info: LarkInfo, commandEvent: Lark.StatusEvent, sInfo: SmartsInfo] ~ {
pS: Thrush.ProseSpec _ HandleProseOutput[info, commandEvent, sInfo];
IF pS#NIL THEN ThSmartsPrivate.ReportProseDone[sInfo, pS];
};

InterpretSpeakerSwitch: PROC[info: LarkInfo, sEvent: Lark.StatusEvent]
RETURNS [ processedEvent: Lark.StatusEvent] = --<<INLINE>>-- {
interval: INTEGER = LOOPHOLE[sEvent.time-info.swOnTime];
processedEvent _ sEvent;
SELECT sEvent.event FROM
enabled => info.swOnTime _ sEvent.time;
disabled => NULL;
ENDCASE => ERROR Thrush.pERROR;
IF interval < 0 OR interval > spClickInterval THEN RETURN;
processedEvent.event _ ThSmartsPrivate.click; };

spClickInterval: INTEGER _ 500;

InterpretRingDetect: ENTRY PROC[info: LarkInfo, smartsID: SmartsHandle, smartsInfo: SmartsInfo, sEvent: Lark.StatusEvent]
RETURNS [ processedEvent: Lark.StatusEvent _ [ 0, nothing, Lark.reset ] ] = --<<INLINE>>-- {
ENABLE UNWIND=>NULL;
interval: INTEGER = LOOPHOLE[sEvent.time-info.ringChangeTime];
event: Lark.Event = sEvent.event;
info.ringChangeTime _ sEvent.time;
SELECT event FROM 
enabled => SELECT info.ringDetState FROM idle, between=>NULL; ENDCASE=>RETURN;
disabled => SELECT info.ringDetState FROM idle, between=>RETURN; ENDCASE;
ENDCASE=>RETURN;
SELECT info.ringDetState FROM
idle => TRUSTED { -- known enabled --
info.ringDetState _ maybe;
info.ringDetWaitState_idle;
info.ringDetInstance _ info.ringDetInstance+1;
Process.Detach[FORK RingDetProc[smartsID, smartsInfo, info.ringDetInstance]]; };
maybe =>  { -- known disabled --
IF interval<debounceInterval THEN info.ringDetState_idle ELSE {
info.ringDetState _ between; 
processedEvent _ sEvent; processedEvent.event _ enabled; }; };
ring1 => {  -- known disabled -- 
info.ringDetState _ between; };
ring => { -- known disabled --
info.ringDetState _ IF interval > ringInterval THEN between ELSE idle; };
between => { -- known enabled --
info.ringDetState _ IF interval < breakInterval THEN ring ELSE idle; };
ENDCASE;
IF info.ringDetState#info.ringDetWaitState THEN NOTIFY info.ringDetCondition; };

debounceInterval: INTEGER _ 300; -- ms.
ringInterval: INTEGER = 1700; -- ms., 2 sec. nominal, 300 ms. benefit of doubt
breakInterval: INTEGER = 4500; -- ms., 4 sec. nominal, 500 ms. benefit of doubt
debounceIntTicks: Process.Ticks = Process.MsecToTicks[debounceInterval];
ringIntTicks: Process.Ticks = Process.MsecToTicks[ringInterval];
breakIntTicks: Process.Ticks = Process.MsecToTicks[breakInterval];


RingDetProc: PROC[smartsID: SmartsHandle, smartsInfo: SmartsInfo, instance: CARDINAL] = {
info: LarkInfo = smartsInfo.larkInfo;
event: Lark.Event;
RingDetProcEntry: ENTRY PROC[info: LarkInfo] RETURNS[stillRunning: BOOL]	 = --INLINE-- {
ENABLE UNWIND=>NULL;
newState: RingDetState = IF info.ringDetInstance#instance THEN idle ELSE info.ringDetState;
event _ reset;
IF newState#idle AND newState=info.ringDetWaitState THEN -- timed out
SELECT info.ringDetState FROM
idle => RETURN[FALSE];--??--
maybe => { info.ringDetState _ ring1; event _ enabled; RETURN[TRUE]; };
ring1, between => info.ringDetState _ idle;
ring => info.ringDetState _ between; --??--
ENDCASE;
info.ringDetWaitState _ info.ringDetState;
TRUSTED { SELECT info.ringDetState FROM
idle => { event _ disabled; RETURN[FALSE]; };
maybe => Process.SetTimeout[@info.ringDetCondition, debounceIntTicks];
ring1 => Process.SetTimeout[@info.ringDetCondition, ringIntTicks+breakIntTicks];
ring => Process.SetTimeout[@info.ringDetCondition, ringIntTicks];
between => Process.SetTimeout[@info.ringDetCondition, breakIntTicks];
ENDCASE;
};
WAIT info.ringDetCondition;
RETURN[ TRUE ]; };
DO
stillRunning:BOOL_ RingDetProcEntry[info];
IF event#reset THEN
smartsInfo.ParseEvent[smartsInfo, [info.ringChangeTime, ringDetect, event ] ];
IF ~stillRunning THEN RETURN; ENDLOOP; };

InterpretHookState: PUBLIC ENTRY PROC
[ info: LarkInfo, rawEvent: Lark.StatusEvent, sInfo: SmartsInfo ]
RETURNS [ processedEvent: Lark.StatusEvent ] = {
ENABLE UNWIND=>NULL;
event: Lark.Event = rawEvent.event;
ev: EvType;
newState: HookState;
oldType: TerminalType_info.terminalType;
processedEvent.device _ nothing;
ev _ SELECT rawEvent.device FROM
hookSwitch => SELECT event FROM
Lark.enabled => IF info.monitor THEN spMon ELSE tsOn, Lark.disabled => tsOff,
ThSmartsPrivate.click => spClick, ENDCASE=> spNone,
speakerSwitch => SELECT event FROM
Lark.enabled => spOn, Lark.disabled => spOff,
ThSmartsPrivate.click => spClick, ENDCASE => spNone,
ENDCASE => spNone;
processedEvent _ rawEvent;
IF ev = spNone THEN {
processedEvent.event _ SELECT rawEvent.device FROM
keyboard => SELECT event FROM
'[ => enabled,
'] => disabled,
'\n => endNum,
ENDCASE => event,
touchPad => SELECT event FROM
bThorp => endNum,
bStar => '*,
IN Lark.DTMFEvent => event - (FIRST[Lark.DTMFEvent]-'0),
ENDCASE=>event,
ENDCASE => event;
RETURN;
};

newState _ newStates[info.hookState][ev];
processedEvent.device _ IF newState=onhook OR info.hookState=onhook
THEN hookSwitch ELSE nothing;
IF event=ThSmartsPrivate.click THEN processedEvent.event_disabled;
info.hookState _ newState;
info.terminalType _ std;
SELECT newState FROM
onhook => NULL;
telset, both, bOth => IF info.radio THEN info.terminalType _  radio;
spkr, sPkr, spKr => info.terminalType _ IF info.radio THEN radio ELSE spkr;
monitor => info.terminalType _ monitor;
ENDCASE=> VoiceUtils.Problem[, $Lark, info];
IF oldType#info.terminalType THEN
ThSmartsPrivate.EnterLarkSt[info, info.larkState, sInfo];
};


CheckHookState: PUBLIC ENTRY PROC
[info: LarkInfo ] RETURNS [ onHook: BOOL_TRUE ] = {
ENABLE RPC.CallFailed => IF pd.callTimeoutOK THEN RESUME ELSE GOTO Failed;
reverted, wasReverted: BOOL_FALSE;
which: CARDINAL;
DO
which_0;
reverted _ FALSE;
DO
events: Lark.StatusEvents;
[which, events] _ info.interface.WhatIsStatus[info.shh, which];
FOR i: NAT IN [0..events.length) DO
SELECT events[i].event FROM
enabled => SELECT events[i].device FROM
hookSwitch => {
onHook_FALSE;
info.interface.Commands[shh: info.shh, events: assertARelay];
};
revertHookswitch => IF ~wasReverted THEN reverted _ wasReverted _ TRUE;
ENDCASE;
ENDCASE;
ENDLOOP;
IF which=0 THEN EXIT;
ENDLOOP;
IF reverted THEN {
info.interface.Commands[shh: info.shh, events: unRevHS];
LOOP;
};
EXIT;
ENDLOOP;
EXITS
Failed => onHook_FALSE;
};

EvType: TYPE = { tsOn, tsOff, spOn, spOff, spClick, spMon, spNone };

newStates: ARRAY HookState OF ARRAY EvType OF HookState _ [
[ telset, onhook, sPkr, onhook, onhook, monitor, onhook ], -- onhook
[ telset, onhook, bOth, telset, telset, monitor, onhook ],   -- telset
[ telset, spkr, spKr, onhook, onhook, monitor, onhook ],  -- spkr (speakerphone mode but switch in middle)
[ bOth, sPkr, sPkr, onhook, spkr, bOth, onhook ],     -- sPkr (speaker switch is up)
[ bOth, sPkr, sPkr, onhook, onhook, bOth, onhook ],  -- spKr (sPkr, but click turns off - speaker switch in middle or up.)  Scenario goes like this: we were in spkr mode and we saw an spOn.  Next we might see an spClick, in which case this is a click off (=down+up) so we go onhook.  However, it might also be a click on (=up), in which case this situation could persist and has to be considered the same as sPkr.
[ both, spkr, both, telset, telset, both, onhook ],       -- both (handset offhook, speaker switch in middle or up; click reverts to telset)
[ bOth, sPkr, bOth, telset, both, bOth, onhook ],       -- bOth (handset offhook, speaker switch up)
[ monitor, onhook, bOth, sPkr, monitor, monitor, onhook ] ]; -- monitor


ViewCmd: Commander.CommandProc = TRUSTED {
Nice.View[pd, "Lark In PD"];
};

unRevHS: Lark.CommandEvents _ NEW[Lark.CommandEventSequence[1]];
assertARelay: Lark.CommandEvents _ NEW[Lark.CommandEventSequence[1]];
unRevHS[0] _ [revertHookswitch, disabled];
assertARelay[0] _ [aRelay, enabled];

Commander.Register["VuLarkIn", ViewCmd, "Program Management variables for Lark Input"];
}.
���
~��LarkInImpl.mesa 
Copyright c 1985, 1986 by Xerox Corporation.  All rights reserved.
Last modified by D. Swinehart, May 17, 1986 4:16:22 pm PDT
Polle Zellweger (PTZ) July 18, 1986 11:06:56 am PDT
*****************  External  Procedures  ********************
Handles smarts-independent filtering, events that need timing.
Interpret event, possibly filter some out.
React to upstrokes, not downstrokes.  0-key Rollover is a side-effect.  Try it.
Only pass on index marker notifications.  Swallow or handle all others.
Assume Prose XON / XOFF disabled.
Assume only get the following responses:
	On pReset:	pResetConfirmOK							if everything's okay
				cmdLeader <0-16> pResetConfirmEnd		otherwise
	Index marker response: 
	Undetermined problem: BEL
For now, we'll assume that this was a successful dictionary entry response.
It's okay to skip ahead in the queue.  Except for 1st item in a conversation, which follows an initial RESET, should be to some entry with queueIt=FALSE.  Don't report skipped entries as finished; FinchSmarts will take care of skipping ahead in its queue. (May want to add a proseSpec.type = flushed?)
ThSmartsPrivate.pResetConfirmEnd => {  -- this case is now the same as stopAndFlushEnd
IF Convert.IntFromRope[info.proseResponse] # 0 THEN
ThSmartsPrivate.ProseControlDone[info, ThSmartsPrivate.proseFailure, sInfo] -- fail!!!;
ELSE {
ThSmartsPrivate.ProseControlDone[info, ThSmartsPrivate.flushMarker, sInfo];
info.flushJustFinished _ TRUE;
};
};
Avoid deadlock - shouldn't call Smarts-level entry procs while holding the LarkIn/Out lock.
newly entered state
Filters only events whose device codes are hookswitch and speakerSwitch
Implements another state machine via SELECT
Translate characters from various devices into common set
Determine if either of telset or speakerphone is activated.
Assert aRelay and unrevert hookswitch
spOn is transition away from middle on speaker switch
spOff is transition to middle if it's been more than a few hundred milliseconds
spClick is transition to middle if it's been less than a few hundred milliseconds -- spClick is always preceded by spOn.
Note: spNone transitions are never taken.
Swinehart, August 6, 1985 12:10:40 pm PDT
Incorporate PTZ changes
changes to: DIRECTORY, LarkInImpl, RecordEvent, HandleProseOutput, InterpretSpeakerSwitch
Polle Zellweger (PTZ) August 7, 1985 6:36:35 pm PDT
Comments only.
changes to: EvType, newStates
Polle Zellweger (PTZ) August 22, 1985 5:20:05 pm PDT
Handle Prose flushing; remove deadlock from HandleProseOutput.
changes to: DIRECTORY, RecordEvent, HandleProseOutput, HandleAndReport
Polle Zellweger (PTZ) August 23, 1985 2:10:02 pm PDT
Input events from the Prose Lark are being interpreted as smarts-level parseable events.  Raise error for odd devices.
changes to: RecordEvent
Polle Zellweger (PTZ) August 23, 1985 2:34:28 pm PDT
changes to: RecordEvent, HandleProseOutput
Polle Zellweger (PTZ) August 27, 1985 8:57:45 pm PDT
Allow for Prose Reset command.
changes to: DIRECTORY, HandleProseOutput
Polle Zellweger (PTZ) August 29, 1985 5:46:33 pm PDT
changes to: HandleProseOutput
Polle Zellweger (PTZ) December 11, 1985 11:50:38 pm PST
changes to: HandleProseOutput
Swinehart, May 16, 1986 4:14:03 pm PDT
Cedar 6.1
changes to: DIRECTORY, LarkInImpl, DebEvent, InterpretHookState
Polle Zellweger (PTZ) July 17, 1986 6:26:10 pm PDT
changes to: HandleProseOutput
Polle Zellweger (PTZ) July 18, 1986 11:06:56 am PDT
changes to: DIRECTORY

�Êï��˜�šœ™Icodešœ
Ïmœ7™BJšœ:™:K™3—J˜�šÏk	˜	Jšžœ˜Jšœ
žœ˜*Jšœžœ˜Jšœžœ¤žœ˜µJ˜J˜J˜Jšžœžœ˜Jšœžœžœ˜.Jšœžœ,˜9Jšœžœ˜$šœžœ˜Jšœ÷˜÷—Jš	œžœžœžœžœ˜IJšœžœ˜Jšœžœ˜$J˜J˜�—šœž
œžœžœ˜9šž˜Jšœ$žœžœ,˜l—Jšžœ˜&—Jšžœžœ˜J˜�Jšžœžœžœžœžœžœžœ˜JJšœžœ˜,Jšœ
žœ˜*J˜2Jšœžœ˜-Jšœžœ˜.Jšœžœ˜)Jšœžœ ˜2Jšžœžœ
žœ˜J˜J˜!Jšœ#˜#J˜!Jšœ%˜%J˜J˜�šžœžœžœ˜JšœžœžœÏc2˜LJ˜—Jš	œžœžœžœžœ˜J˜�Jšœ=™=J˜�J˜�šÏnœžœ+žœ˜AJš	œžœžœžœžœ˜šœ˜šœžœ˜
Jš
žœžœžœžœžœ˜AJšžœžœžœ˜ —Jšœžœžœžœ˜,—Jšžœžœ˜3Jšžœžœžœžœ˜BJšœA˜AJšœ˜—J˜�Jšœ	žœžœŸ1˜Fš œžœžœžœA˜jJšžœž	œ˜J™>Jšœ˜JšœK˜KJ˜#Jšœ˜J˜Jšžœžœžœžœžœžœžœ˜IJ˜ šžœžœž˜3J˜+Jšžœžœ˜4Jš
žœ	žœžœžœžœ˜KJ™*šžœž˜šœž˜J˜%J˜B—šœ
˜
JšœC˜CJšžœ˜J˜—Jšžœ˜—šžœž˜J˜?Jšœ1žœ"˜Tšœ
˜
J™OJšžœžœ+˜Hšžœ˜Jšœ,žœŸ ˜RJ˜—Jšžœžœžœ˜ J˜—šœ
˜
Kšžœžœ+˜DKšžœ˜K˜—Jšœžœ˜Jšžœ˜—Jšžœžœžœ˜#Jšœ>˜>Jšžœ˜——J˜�š 	œžœ˜Jšœžœ žœžœ˜\Jšžœ
žœ˜Jšžœ˜Jšœ˜—J˜�Jšœ«ž™®š
 œžœžœDžœžœ˜‰Jšœžœ˜šžœž˜
JšžœžœŸ˜*Jšžœžœ&Ÿ˜EJšœžœŸ˜'šœ$˜$JšœK˜KJšœžœ˜J˜—šœ#˜#Jšœžœ˜šžœ#žœžœ˜1KšœK™K—Kšœ1˜1šžœ*ž˜0Jšœ5˜5—šžœ˜Kšœ5˜5Kšžœžœžœ˜šžœžœ˜ Kšœ­™­šžœ8žœžœž˜MKšžœ!žœ˜4Kšžœ˜—Kšœžœ˜K˜—šžœžœ˜'Kšœ˜KšœŸ˜7Jšžœžœžœžœ˜-J˜—šž˜JšœMŸ
˜W—J˜—J˜—šœV™Všžœ,ž™3JšœLŸ
œ™W—šžœ™JšœK™KJšœžœ™J™—J™—JšžœK˜R—Jšœ˜—J˜�š œžœH˜]J™[KšœD˜DKšžœžœžœ,˜:K˜J˜�—š œžœ*˜FJšžœ'Ÿœ˜>Jšœ
žœžœ˜8J˜šžœž˜J˜'Jšœžœ˜Jšžœžœ˜—Jšžœžœžœžœ˜:J˜0J˜�—Jšœžœ˜J˜�š œžœžœZ˜yJšžœEŸœ˜\Jšžœžœžœ˜Jšœ
žœžœ"˜>J˜!J˜"šžœžœ˜Jšœžœžœžœžœžœ˜NJš	œžœžœžœžœ˜IJšžœžœ˜—šžœž˜šœžœŸ˜%J˜J˜J˜.Jšœžœ=˜P—šœŸ˜ šžœžœžœ˜?J˜J˜>——šœŸœ˜!J˜—šœ
Ÿ˜Jšœžœžœ	žœ	˜I—šœ
Ÿ˜ Jšœžœžœžœ	˜G—Jšžœ˜—Jšžœ)žœžœ˜PJ˜�—JšœžœŸ˜'Jšœžœ	Ÿ0˜NJšœžœ	Ÿ0˜OJ˜HJ˜@J˜BJ˜�J˜�š œžœ;žœ˜YJ˜%J˜š œžœžœžœžœŸ
œ˜XJšžœžœžœ˜Jšœžœžœžœ˜[J˜šžœžœ žœŸ˜Ešžœž˜JšœžœžœŸ˜Jšœ7žœžœ˜GJšœ+˜+Jšœ%Ÿ˜+Jšžœ˜——Jšœ™Jšœ*˜*šžœžœž˜'Jšœžœžœ˜-JšœF˜FJšœP˜PJšœA˜AJšœE˜EJšžœ˜J˜—Jšžœ˜Jšžœžœ˜—šž˜Jšœ
žœ˜*šžœ
ž˜JšœN˜N—Jšžœžœžœžœ˜)—J˜�—š œžœžœž˜%šœA˜AJšžœ)˜0—Jšœ+Ïb
œ¡
™GJšœ%¡™+Jšžœžœžœ˜J˜#J˜J˜J˜(J˜ šœžœž˜ šœžœž˜Jšœžœžœžœ˜MJšœ"žœ
˜3—šœžœž˜"Jšœ-˜-Jšœ"žœ˜4—Jšžœ˜—J˜šžœ
žœ˜J™9šœžœž˜2šœžœž˜J˜J˜J˜Jšžœ
˜—šœžœž˜J˜J˜Jšžœžœ˜8Jšžœ˜—Jšžœ
˜—Jšžœ˜šœ˜J˜�——Jšœ)˜)šœžœžœ˜CJšžœžœ	˜—Jšžœžœ˜BJ˜Jšœ˜šžœ
ž˜Jšœ
žœ˜Jšœžœžœ˜DJšœ(žœžœžœ˜KJšœ'˜'Jšžœ%˜,—šžœž˜!Jšœ9˜9—Jšœ˜—J˜�J˜�š œžœžœž˜!Jšœžœžœžœ˜3J™;Jšžœžœžœžœžœžœžœ˜JJšœžœžœ˜"Jšœžœ˜šž˜J˜Jšœžœ˜šž˜J˜J˜?šžœžœžœž˜#šžœž˜šœžœž˜'šœ˜Jšœžœ˜
Jšœ=˜=J˜—Jšœžœžœžœ˜GJšžœ˜—Jšžœ˜—Jšžœ˜—Jšžœ	žœžœ˜Jšžœ˜—šžœ
žœ˜J™%Jšœ8˜8Jšžœ˜J˜—Jšžœ˜Jšžœ˜—šž˜Jšœžœ˜—J˜J˜�—šœžœ8˜DJ™5J™OJ™xJ™)—J˜�š	œžœžœžœžœ˜;Jšœ;Ÿ	˜DJšœ=Ÿ	˜FJšœ:Ÿ0˜jJšœ6Ÿ˜TJšœ5Ÿè˜Jšœ:ŸR˜ŒJšœ8Ÿ,˜dJšœ=Ÿ
˜GJ˜�—J˜�šœ!žœ˜*J˜Jšœ˜J˜�—Jšœžœ˜@Jšœ#žœ˜EJšœ*˜*Jšœ$˜$J˜�JšœW˜WJ˜™)K™KšœÏrM™Y—™3K™Kšœ¢™—™4Kšœ>™>Kšœ¢:™F—™4K™vKšœ¢™—™4Kšœ¢™*—™4K™Kšœ¢™(—™4Kšœ¢™—™7Kšœ¢™—™&K™	Kšœ¢3™?—™2Kšœ¢™—™3Kšœ¢	™—K™�—�…—����3Ð��P=��