9|P^GW" (kI ' p  tqCvCopyright 1993 Unisys Corporation. All rights reserved.Ver R12.3.1 Linker R12.3.1OBPP P_0op/ ?@` oP46O< CD? pKVYp` doopqp  МO_/00O0 O`_@O p?@ OOPo"#?0'p'P(0*0/P01P2?`:<O?G`I`JpJKO`OQPRoST0U?W@fijk?pll_@mOn/n q?qrtu/pwx_ 0OPКМ_Н00@oPp_ `?P / OP?O`O 0_ __@o? `_p/@_ o   /@ p_O@ / ?PO_`?O0!!O"O"/ #P#p&?P'_ '2O 4=?_0@E FFJN0OO0Sf@jl mmn o}~@_Ѐ0?@?`*G'(" )#+7* 8F% /N!) _    W   s +zh*T<99998$88 C\S SWAW !)19A\M /FX)<_F0 {p  F   G _ y 3!r!7!H!0(!C(!c(!(! 3!C3!W3!w3!3!3!3!3!33!S3!3!3!P!P!P!lP!P!P!P!vP!P!P!P!P!P!P!+P!B P!{ P! P!! P!T P! P! P!k P! P! P!1 P!g P! P! P! P!P!D"&D"aD"D"D"D"D" D"~""-"h"'""j"""D#i##y#/(#(#.8#8#(j#j#j#j#j#j#+$F$f$$$%%%w%%((,(Y*,J,W,,X,g,t,<,X,,Y. Y.SY.AY.dY.`Y.fY.Y.DY.7Y. Y.B/z////)/>/K//F/y///[// /=/l//(/>/,B0O0UO0O0O0O0O0O0008141A1]1v111 1 1S 1 111R1H2;H2H2H2H22=2P2 3T3g33Y4j444 42J4`J4J4J4J4J4J4J4 ] c p  / G f %@*Kz) /: J#(9$: $8_k SWe] v !!(!3!P!D"~""""""""""#(#8#W#j#$$$$$%J%Z%u%%%%%%%% &&%&,&:&Y&g&&F'e'i'''''(((((((1)6)>)****$*a*|****6+A+G+I+Q+T+\+,,,,,,,,,--!-2-J-N-X-e-q-v---------. ...G.U.Y./)////90B0O00001H2222222333334444J4i4i4  $ : B Y q {      ; W w     X      3 a     J      > q   I      F      " < B ^ u { e x _   7 F K [ `  ] c +c 3p p p Hp p p ap p p ?p `p p p p qp p p p !p 6p Fp bp sp p p p p :p dp p p p " , 5 E n  8 + 3 > m v  0 N  3 C L f s            * : P ] r         / +/ ,G sG G G G G G G G G &G kG G G G G G &  =    # Y i }    6 O c   '  3  5 I e n y  R h v    2 ? _     7 ^ .f f f 7f Uf f f f >f rf f f f  +  J!N!R!V!Z! =      &        A M       , 7 G Z h      / = [ h     K }     ;   # _      ( f  # ; g  N      /   T    1   ^  1 N [ h %N%S%\%e%~%%%%%%%%5%@-@:@J@\@h@t@@@@1@k@ @F@@@@/@B@U@@@@@2@M@@@@@A@[@l@@@@@@@@@ cpv ek}JPX|;A( $*06:?He=$*06<BHNTZ`flr ***"*=*P*h********!*=*I******%*u********/*n****1*l*********1*B*[**** &,}:% %Eh#7>[ 0 > C j    s     KK&K7KXKgKyKKKK!K2KEKsKKKKKKBKPK1zSzzz7zXzzzzzzzz-zYzmzzzzzzkzzpzzzzzzzzzzzz zz9zTzvz{zzzzzzzzz&z3zPzbzozvz{zzzzz +J] AtZo)Kem )t)))))))5)~))))[))$))))4)]))))))0)\)c)j)q)))))))U)n)))))))))4)w))))))%)4)<)V)i)))))) )# )0 ): )[ )e )x ) ) ) ) ) ) ) ) ) )% )@ )H )X )n )u ){ ) ) ) ) ) ) ) ) ) ) (8ahov:VZH`H8>Md[lZx%l'@SYh -@E[o}!(=KS[bnsTp{  & ? Y a q ~           # 3 @ V a v           1 > T p                 2 9 @ ` k v          $) pRe 3 C L U a g m s y       3EJYaiy!+>HNX^dn/N/j/}//:7:Z:j:::::::5:?:}::::::O:u::::A:Y::::: ::1:8:?:H:^:w::::g:q:::3:}:::::':=:Q:l::::::: : := : : : :D :n :z : : : : : : :/ :X : : : : :Km"(Kkqag2E`u|\bp 1J`hMR9H",6PZkp W m       + V s        3CJ1u q (27<AINX`o 0P^co}2\  ; M U _ d w }          Ykp{6LV\bhnx~!2\xtJJJJJ J.JAJcJxJJJJ JJ#J8JDJYJeJ{JJJJJJJ JiJJJJJJJ-J@JJJJJ J=J_JrJJJJdJJJJJJMJVJkJJJJ Je Jp J J J J J" J- J} J J J J J J' J2 J J J J J J" J> JN Jj Jz J J J J J J J; JK Jg Jw J J J J J J J J JJ#JMJ`JxJJJ2JFJcJJJJJJJJJ"J{JJJJJJ J(J6JSJJJJJJJ'J1J;JEJLJ[JJJJJJJ8JCJ 9Ht,BJ^nq{!<DTZlrx~0Yf:GRIfuAd!*F`|&Vh.Kjqx@~,Wm0EcV3u'pfjnrvz~9?xhFs3Qh>Zv8U%/Gdr AVm 4 k  k         @          ? Q ~    U_u\fuvax3$*06<BHNTZ`fl>Nh+HYi #3#E#***((R(](f(v(((((((999999 9#9+9P9j9r9999989@9j9~99999999979t999 969m999999/9W99999999 9( 9W 9,M;>Og $4E+$x$$$,::: : ::;:t:::x:::::p::::::0:A:j::4:L:\:m:Gh Banw   $3$C$L$[$c$n$y$$$$$$$$$$$$$$$ $$$$%$/$  8)8X8l8888%8v88,8@8L8r888888888838A8Z8n8848F8Y8f8888888Q8k8u88888 8 6]p8n3:?G^vcq*m{`gn6c): ____#_)_/_5_;_A_K_f_l_r_x_~_______ kk6kHkkkkkk k kBkYkfkkkk#k9kMkjkkkkkkkk=kOkqkkkk kkk kDkMk]kkk9&3>LYfs -Bsdq{j(;     " ( . 4 : @ J U ^ `We=ekeee'e/#e7Qe?eJNRVZ_cgkotx|  $(,159=AFJNRV[_cgkouz#Q ~}sJ d 8Tr3in!5AmIl*Pt os6v Cv \v v v v  Q `   b % N   I  a!!(!;P!P!P!A P! P! P!D"D"D"D"D"D"""""`"g"9#Z#08#3W#W#W# W#0j#j#j#j#j#j#j#j#j#9j#j#gj#j# j# j#W j# j#. j#h j# j# j#7 j#6 j# j# j#j#Rj#vj#j#j#j#Fj#j#j#j#3j#j#j#$$$>$|$$$,$S$i$$$$3$z$$9$k$F$$@%%3%n%%% %:%%J%Z%[Z%Z%Z%FZ%oZ%Z%u%4%u%%%m%%<%%3%z%%%E%%<%%'%%3%z%%%c%t &D%&,&e,&O:&:&<Y&uY&Y&Jg&g&g&g&g&Kg&g&5g&eg&{g&&+&A&F&pF'F'rF'F')%3%i' i'i'i'i'(i'i'i'i'i'i'i'Zi'i'i'i'i'i'-'\''C'i'''']'k'''''''2''''X 'v((((('(Z(j(E(w(/(B((((O(u(((((!(F>)>)>)>)u>)>)>)>)>)d>)>)F >)L*R*******M**3$*$*$*$*$*_$*$*Z$*  ba*a*a*$a*V|***4**N*y*****   5*I***I*\*n*s*****.*7*?*J*R*W*`**S*x*******Y*^*h************** 6+6A+VA+ G+G+ T+T+T+T+"T+JT+"\+/\+9\+>\+H\+W\+\+!\+&\+8\+B\+Q\+V\+c\+h\+u\+\+\+\+\+\+\+\+\+\+<\+F\+P\+U\+_\+i\+x\+}\+\+\+\+\+\+\+\+\+\+\+ \+\+\+)\+.\+8\+\+\+\+?\+N\+S\+b\+g\+t\+B\+\+\+\+d\+\+J\+6 \+pI tI ,,,,a,,!,,,,,0,L,u, ,,!,,,,,,,,,/,,,,",U,- -%-.-8-=-F-Y-^-!----!-4 !-!-!-!-!-J-J-%J-:J-VN-eN-N-X-X-%X-e-$e-Ge-Le-Qe-Ze-|e-e-t ---- --(-=--!--8-F-K-U-.".1. .% .: .Z >)s >) >).+. ..(.......4.?... U.U.'Y.Y.Y.Y.Y.!Y.@Y.NY.{Y.Y.Y.Y.Y.Y.Y.Y.Y."Y.nY.Y.LY. Y.z Y.//h/")/t)/)/)/)/)/)/)/:)/I)/i)/)/)/)/)//)/O)/t)/)/)/)/)/)/)/)/!)/3)/A)/g)/u)/)/)/)/)/)/b)/y)/)/)/)/)/ )/)/1)/)/)/ )/|/////&/N//c////K/Q////E/t///0/F/O0RO0000!000000 11p11`11I1`111Q111Q1111\ 1 1 1 1 1 1% 1 1 1 19 1 1 11111B1111,1y11111+1H2yH2H2H2H2,H2bH22|22 2c2222Y222222e222222q222& 2 2 2{ 2 2t 2 2Q 2 2333?334#4J4MetaWare High C Run-time Library Copyright (C) 1983-1988 MetaWare Incorporated..[KBD][VID][]}[!Scr]]$$.Tmp}[!Scr][!Scr][scr]<$>BsFilter.tmpVNVFpII010E02        ~  *?*?*?{}MASTERSERVERLOCAL{}[]{}[]<>^{}[]mfd.sys<>[]DATAABCDEFGHIJKLMNOPQRSTUVWXYZ)abcdefghijklmnopqrstuvwxyz)Yes)No)Binary  CharacterdFlagB[sys]LptConfig.Sys&YesNo`abcdefghijklmnopqrstuvwxyz{|}~`abcdefghijklmnopqrstuvwxyError 2624: msg= %0N maxlen= %1N^YesNo Press NEXT PAGE or SCROLL UP to continue*(Press NEXT PAGE to continue*!a?!*a**2Q=\zCKACTION BACK SPACEBOUNDCANCELCODECOPYDELETEFINISHGOHELPLOCKMARKMOVENEXT NEXT PAGE OVER TYPE PREV PAGERETURN SCROLL DOWN SCROLL UPSHIFTTAB#+17?GKQW]citTD aAdDhHmMnNoOsStTwWyYgG!oo!/!0d!/!0y! !hh!:!0m!!2AA!!*o!/!0d!/!0y! !*h!:!0m!!2*A!"!Nnn! !dd!, !yyyy! !hh!:!0m! !2AA!"!Nnn! !*d!, !yyyy! !*h!:!0m! !2*A!(!Www! !Nnn! !dd!, !yyyy! !hh!:!0m! !2AA!(!Www! !Nnn! !*d!, !yyyy! !*h!:!0m! !2*A! !0t!:!0m! !*t!:!0m!!hh!:!0m! !2AA!!*h!:!0m! !2*A!!0o!/!0d!/!0y!!*o!/!*d!/!0y!!0h!:!0m!:!0s!!0t!:!0m!:!0s!.tmp!W*w! !N*n! !*d!, !*y!!N*n! !*d!, !*y!"!0o!/!0d!/!0y!-!0h!:!0m!:!0s!!2*A!!Nnn! !*d!, !yyyy!Invalid Template Index$Cb %6FVfzTN00sundaymondaytuesday wednesdaythursdayfridaysaturdayjanuaryfebruarymarchaprilmayjunejulyaugust septemberoctobernovemberdecemberampmnoonmidnight05 invalid namesunmontuewedthufrisatjanfebmaraprmayjunjulaugsepoctnovdecampmnm05 %0:BLU_fmrx~ #(-27;?BEI{R12.3.1F^mDChord position index,5If the chord toggles, enter "y", otherwise enter "n". =If the chord key has an LED on it, enter "y", else enter "n".9If chord key has an LED on it, enter bit position of that / LED in OS LED word (a number less than 8).DB@C@C@B@ChordIDToggleLED BitPosition0 CHORDS  @ @  @@ @  @@ @  @@ @  @@ @  @@ @  @ @ @  @ @ @  @  @  @   @  @  @   @  @  @   @ @  @   @ @  @   @@ @  @@ @  @@ @  @ ChordKeysHyphen iChordKeyOIMMMMMMMMMMMMMMMMM=GGGGGIW]DG]]@G]]@G]]@G]]@G]]@f]U m]Ut]U{]U!]U(]U/]U9]U@]UG]Uf]U m]Ut]U]{]U!]U(]U/]U9]U@]UG]UTitleTextF1F2F3F4F5F6F7F8F9F10RespSGcr E555E @5  @< @ @5& @</ @8 @5A @<J @Example1FldName1DataFld1Example2FldName2DataFld2Example3FldName3DataFld38   4444446 ̀4  @4  @4  @4  @4  @4  @TitleTextF>MF1. To select a keyboard data file, move the cursor (ie., highlight) to'the file's name and press the "F7" key.FC2. To see more data (if message says it exists) press the "F8" key.FA3. To change the directory being searched, press the "F3" key to Bstart editing the "Directory Searched" field and the "F4" key whenthe editing is done./FF DIRECTORY SEARCHED-FFF3KEYBOARD DATA FILE NAMES (with ".kbd_data" removed) F }@@@0@@@0@@@0 @ @ @0 @ @@0@@@0@ DirSearched KbdDataFileo31(Enter IDs of chords that affect this key+(Use chord IDs in highlighted fields above)(1@@@ @ @&@,@2@8@>@ E@#L@&S@)Z@,a@/h@Chrd1Chrd2Chrd3Chrd4Chrd5Chrd6Chrd7Chrd8Chrd9Chrd10Chrd11Chrd12Chrd13Chrd14Chrd15Chrd16>FD No repeat  Slow repeat  Fast repeat  D4A valid set of entries in the above fields has a "y" 6in one field and a "n" or a blank in the other fields. D(.@&..@:6.@NoRptSlowRptFastRptT6&440ENTER CHORD KEY IDS IN SETS OF EQUIVALENT CHORDS0All chords in one set should have same effect on*at least some of the keys on the keyboard.441st Set2nd Set3rd Set      ANDAND      4/To enter a chord use number from table on left.44 @$  $E $E $E $E 4E 4E 4E 4E( DE+ DE. DE1 DE $E $E $E $E 4E 4E 4E 4E( DE+ DE. DE1 DE$ E$ E $ E $ E4 E4 E4 E4 E(D E+D E.D E1D EConditionNumberSelect Conditions1 Conditions2 Conditions3 K ?I*******I?D*@-@*@-@*@-@*@-@*@-@*@-@*@-@TitleField1AField1B(          D @ @ @ @ @ @ @TitleText[Kbd]l[Vid] ,[Lpt][Nul]t[Debug]D[SysIn][SysOut]>! #d>%), *]7u8$$al]y\]yB.\B\B.\tZt]y $OyD]y ]y {y2$<;<4d >>P>XPUU       01234567890ABCDEFabcdef}SpclNodetectedwarningerror%s %s %cC%c%c%c%c%cEF%cC%c%c%cS%c%cU %s %ss %s 1 %s %s %3d %ss %s %s %ss %s 1 %s %s mainutils.cmainutils.cmainutils.cmainutils.c%cC%c%cHelp not implemented%cC%c%c B/                  Xchorddataarrayobj.cchorddataarrayobj.cchorddataarrayobj.cchorddataarrayobj.cchorddataarrayobj.cchorddataarrayobj.cchorddataarrayobj.cchorddataarrayobj.cchorddataarrayobj.c{} ,chorddataarrayobj.cchorddataarrayobj.c , %s %d ; Number of Chords %2.2X %2.2X %c %c %2.2X %c %c %s ZZ[[ ChordIDToggleLEDBitPositionchorddataobj.c:[ D[L[ ChordKeysHypheniChordKey\[-conditiondataarrayobj.cconditiondataarrayobj.cconditiondataarrayobj.cconditiondataarrayobj.cconditiondataarrayobj.c %s %X ; Number of conditions %u %s %s j\ConditionNumberConditions1 BFEconditiondataobj.ccreateunxlate.ccreateunxlate.ccreateunxlate.cdiacritarrayobj.cdiacritarrayobj.cdiacritarrayobj.cdiacritarrayobj.c %s %u %2.2X %2.2X %2.2X %2.2X %8X %4X %4x %c %s diacriticobj.c Kbd TablesKbd_Nls_Table.objCT Kbd Customizing Tool createdKCT Ver lbrb|bbbIdSegIdSegEndDataSegKMemoryKbdGroupemitobjectmodule.cemitobjectmodule.cemitobjectmodule.cwemitobjectmodule.cwemitobjectmodule.cemitobjectmodule.cemitobjectmodule.cemitobjectmodule.cemitobjectmodule.cemitobjectmodule.cemitobjectmodule.cemitobjectmodule.c%fnkeyformobj.cCharacter.formsobj.cformsobj.cformsobj.cformsobj.cformsobj.cformsobj.cformsobj.cformsobj.cmmmmmmmn nExample1Example2Example3FldName1FldName2FldName3DataFld1DataFld2DataFld3"n nnnnnnnnnnnnnnnn handlealldstdata.chandlealldstdata.chandlealldstdata.chandlealldstdata.chandlealldstdata.c %s %s%s; %2.2X %s potoxo|ooo handlechorddata.c%Xhandlechorddata.chandlechorddata.chandlechorddata.c%Xhandlechorddata.chandlechorddata.chandlechorddata.chandlechorddata.c%4s%2s%2s%2s%2s%2s%2shandlechorddata.chandlechorddata.chandlechorddata.chandlechorddata.c%Xhandlechorddata.chandlechorddata.c %s %2d ; <<< Number of chords %2.2X %s handlecntrlchorddata.chandlecntrlchorddata.chandlecntrlchorddata.chandlecntrlchorddata.c %s %d ; Number control chords %X %s {}; handleconditiondata.chandleconditiondata.chandleconditiondata.chandleconditiondata.chandleconditiondata.chandleconditiondata.chandleconditiondata.chandleconditiondata.chandlediacriticdata.chandlediacriticdata.c%X%X%X%X%lX%1s%X%X%X%X%X%X%1shandlediacriticdata.chandlediacriticdata.chandlediacriticdata.chandlediacriticdata.chandlediacriticdata.chandlediacriticdata.c|handlediacriticsobj.chandlediacriticsobj.chandlediacriticsobj.chandlediacriticsobj.c%4.2X%4.2X%4.2X%4.2X%2c%2c%8.8X%8.8Xhandlediacriticsobj.chandlediacriticsobj.chandlediacriticsobj.chandlediacriticsobj.chandlediacriticsobj.cobjtblkbd_datattField1AField1Bhandlefiledatamenuobj.chandlefiledatamenuobj.chandlefiledatamenuobj.chandlefiledatamenuobj.chandlefiledatamenuobj.chandlefiledatamenuobj.chandlefiledatamenuobj.chandlefiledatamenuobj.chandlefiledatamenuobj.chandlefiledatamenuobj.chandlehotkeystbl.chandlehotkeystbl.chandlehotkeystbl.chandlehotkeystbl.c ,&} :handlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.c{handlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.chandlemultibytestrings.cxxx %d %dhandlerptattrdata.chandlerptattrdata.chandlerptattrdata.chandlerptattrdata.chandlerptattrdata.chandlerptattrdata.chandlerptattrdata.chandlerptattrdata.chandlerptattrdata.c %s %s%9d%9d %s%9d%9d handlerptattrdata.c||||| %s %s %s Unknown %s %s ; %2X handlerptattrdata.c %s lstlsthandleselkbdmenu.cwhandleselkbdmenu.chandleselkbdmenu.chandleselkbdmenu.cKeyBoardDataKbdTables.objhandleexistingformats.chandleexistingformats.crhandleexistingformats.chandleexistingformats.chandleexistingformats.chandleexistingformats.chandleexistingformats.chandleexistingformats.chandleexistingformats.cwDebug.res %3d. Ptr %p to %5d bytes allocated in module %s at line %uwDebug.res %3d. Ptr %p to %5d bytes reallocated to return %p in module %s at line %uwDebug.res > %3d. Ptr %p freed in module %s at line %u*}0}TextTitlekbddatafileobj.ckbddatafileobj.ckbddatafileobj.crkbddatafileobj.ckbddatafileobj.ckbddatafileobj.ckbddatafileobj.ckbddatafileobj.ckbddatafileobj.ckbddatafileobj.c ;kbddatafileobj.ckbddatafileobj.ckbddatafileobj.ckbddatafileobj.ckbddatafileobj.ckbddatanamesobj.ckbddatanamesobj.ckbddatanamesobj.ckbddatanamesobj.c**kbddatanamesobj.ckbddatanamesobj.cKey0000dEFBBULLK1K2K3K4K5K5PS2kbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.c%d%d kbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.c%X%X%X%X%X%X%skbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.ckbdformobj.c %s %s %s %d %s %s %u %u %u %3X %3X %3X %3X %3X %2X %s 06<BHNTZ`fnv~Chrd1Chrd2Chrd3Chrd4Chrd5Chrd6Chrd7Chrd7Chrd9Chrd10Chrd11Chrd12Chrd13Chrd14Chrd15Chrd16‚ȂЂNoRptSlowRptFastRptP[sys]KCTmsg.binBinary nationalization file "%s" is required. Binary nationalization file "%s" is empty.Could not allocate memory for message file. Error initializing message file at msg # %d. Could not re-allocate memory for message file. Invalid message index %d. Invalid message index %d. | msghandlerobj.cmsghandlerobj.cmsghandlerobj.cmsghandlerobj.cmsghandlerobj.cmsghandlerobj.cmultibytearrayobj.cmultibytearrayobj.cmultibytearrayobj.cmultibytearrayobj.cmultibytearrayobj.cmultibytearrayobj.c %s %u { %2.2X:%2.2X, } %s multibytestrobj.cmultibytestrobj.cmultibytestrobj.cperkeytablearrayobj.cperkeytablearrayobj.cperkeytablearrayobj.cperkeytablearrayobj.c SD: SM: SC: SU: %2.2X %2.2X %2.2lX%4.4X:%2.2X %s ; TABLE NUMBER %X WIDTH %X %s%s; %3.2X %s perkeytableobj.cperkeytableobj.cperkeytableobj.cperkeytableobj.cperkeytableobj.cperkeytableobj.cperkeytableobj.cpX DirSearchedKbdDataFileselkbddatamenuobj.cselkbddatamenuobj.cspecialdatahandler.cspecialdatahandler.cspecialdatahandler.cspecialdatahandler.c%X %X %X %X%X %X %X %X %Xspecialdatahandler.cspecialdatahandler.cspecialdatahandler.cspecialdatahandler.c %s ; Number Keys IBus Id KeyUp Mask cTables Target Translation Table %9X%14X%10X%11X 04 %d ; Number special keys %X %s specialdatahandler.cspecialdatahandler.cspecialdatahandler.cspecialdatahandler.cspecialdatahandler.cspecialdatahandler.cspecialdatahandler.c %s %d %X %s :; tablesobj.ctablesobj.ctablesobj.ctablesobj.c%lxtablesobj.c%xtablesobj.c%xtablesobj.ctablesobj.ctablesobj.c1234tablesobj.ctablesobj.ctablesobj.ctablesobj.cupdatebasefile.cupdatebasefile.cw %s ; <<<<<<<<<<<<< %s ; <<<<<<<<<<<<< -New-Oldupdatebasefile.cw%cC%c%cWriting to file "%s" ... done.updatebasefile.cupdatebasefile.cFFFFFFFFFFFF %s not standard hex number of form "0X..." or "0x..." 0000000000 ((((( AAAAAABBBBBB   VNVFPOOtmwmmmB?Ǫ0mC <@@@ @ @4@p+ŝi@զIx@ߌGA~QC‘F uuvHM]=];Zw R`%uU vvFPP(F@PFVvvvRPv^&ƒ UR/*FȾ/~BFPvvhW|hjjjjhhW|j2<˚=<#tj hjhhjhhW|UvvDFvvDFFUF#~)~| FFHFF;F~ F~FF+hjUFP#tIFvvjIG,RP|W Wt"vvjIG,RP6W6W| U>WtIhG,FVv vvRP| WW#u#tv vvvvRP|UF FuW#tt"<hWhWhWhXvv|:hWhWhXvv|hWhW6WhXvv|~ u hWhWhWh,Xvv|hWhWh8Xvv|vvUvvv v vj6W6WF=t #tP( j LUvvvvv v vj6W6WF=t #tP( j LU=vvvv v vj6W6WrF=t #tP( j LUvG,FVND}6J4QRPN|WW#u#tBvvvRP| -vv|WW#u#tvvRP|~t Wvv v ZU vG,FV+~uA+~uA+փ VhhDXRFV ND}v vJ4QvvRPRtv vvvvvRt vv|WW#u#tvvRP|~ t-vvvh$hPXvveU vG,FV+~uA+vh4h\XVFV ND}vJ4QvvRPRt vvvvvRt vv|WW#u#tvvRP|~ t\Wvvv hFhhXvvUvv|WW#u#tvvRP|~ tWvvv OWUvFV uv v vjjh8 FVUF Fuvv v jjh vvUF Fuvvv jjh v vvGFV uvvv jjh FVUv v vvz| t~Pvv+~uA+RPPPhmm~Rhx#udžxˍ~P~tvvvjvvj hN1vvxj G,RP|x( z|UP N v&^Yu`YUPvDŽlYvva|vnYhYPTvDŽxYUvxYu vWv~F ĴhY&UvxYu+v~ĴhY&UPvnYlYFĴhY~UPvDŽYDŽYY҉VhhYRev|Y~YUvYY~DŽYvY҉VhhYRv~Y|Yvv|Y~YUvYu vE-vY%#}-++F#u v[v^ۋYĴ|Y^&&PWvYYUvF;Y|hhYjjh˚ v~Ĵ|Y&0~ UvF;Y|hhYjjh˚ v~Ĵ|Y&0vF^&D YhhYVF@F vF;Y}%vĴ|Y&&H&P&HF͋v~Ĵ|Y&@&@vYWUvF;Y|hhYjjh˚ v~Ĵ|Y&0vF&DF^!Yv ~v &D YWUvYu+ vYUvF;Y|hh Zjjh˚ v~Ĵ|Y&p&0UvF;Y|h+h Zjjh˚ v~Ĵ|Y&p&0UvF;Y|h7h4Zjjh˚ v~Ĵ|Y&p&0UPvYt-FvF;Y}vP;FuFFظUPvYuLS#u@vF#YF#u-FvF;Y}vP(;FuFFظUv &hHZv vFV #u#u&<}uhJZVFV uvFhLZv v FV u~v&*ȝtBVdHF#|C;F}Pvbv & +hhPZjj&h˚ hhdZjj% hxZjjFV uU joG,RPh|Zvv|v YhZvv|Fv F;Y|v Ĵ|Y&0vFj&tFv&|uFTF*Pvv&D*PhZvv|jv&tFv&|uFTFv*PhZvv|"v&|tFTF*PhZvv|v&| tFTF*PhZvv|FjnG,RPhZvv|jjjjh/<ZZ ˃>Zu6Z<<Z6Z_<Uv vjFZV6Z<Uv vjFZV6Z <UPv% TjF@ hTh hZjjv 8F= uvvT_FUjh[j evV+󫖃UF v&DWUF v&WUF v&DWUF v&DWUF v&DWUF v&DWUv&D*Uv&*Uv&DUv&D*Uv&D*Uv&Djjjjh1<"[$[ U6WF FV FVFF;F|F F FP6WFP ^&FvVvV+‹uA+ى^FPvh([6"[<hV[vh.[6"[<3҃~ }BVj jBPvFFVFFPvh4[6"[<2˃>$[u6"[<<&[˃>&[t6"[_<&[&[h^[h/ ,`[b[d[˃>d[u6b[6`[J4j6`[xV;4jjg ˡf[U f[ FP6WF@~5v6WgFFvTvvvF hRjK,Ff[FU FP6WF@AFT6WFvvPF= t"v6WqhRjL,FFU FP6WF@~ v6WgFv6WqhRjM,hhh9hhWhGhh9hh9hhhh9j &UPvDŽl[vva|vn[h[PTvDŽz[Uvz[u vv~F Ĵh[&Uvz[u+v~Ĵh[&UPvz[u+'vl[n[FĴh[~Uv~[ujjvNvDŽ~[UPv~[u vv vLFN Fvv vx[Uv vFNV!Vvv vx[ˡx[UPvDŽ[DŽ[[FjKh[Pev[[Uv[[FjZh[Pv[[vv[[ uj[h[jj3h˚ UPv[u vKv[#u vmv^ۋ[Ĵ[^&&PWv[[Uv~Ĵ[&0~ Uv~vv ^ğ[~&9WUPhh[v~Ĵ[&p&0F@F vF;[}%vĴ[&&H&P&HF͋v~Ĵ[&@&@v[WUv[UFvF;[}(vĴ[&0vF&T;VtFʸUv~Ĵ[&0vF&DUv~Ĵ[&0vF~ &U.vFhh[PeF։VF F;F}Pvgv^&FjwG,RPh\v v|v[h\v v|FvF;[|vĴ[&0vҌF&th2\v v|F F=}S^&8uFv^&Fvvvv܍FPLFPh:\v v|Fރh@\v v|FHjvG,RPhB\v v|jjjjhV\u6T\6R\J46W6R\xV;46N\<< 6N\_<Uv&=$|&,$v&#}&$v& ++1L\z\&4\v &UF~$|b\FPVRh^\vhX\6N\ <6^\&b\tO6L\z\*-1F^&8u&6b\ƄF\hF\dHP6WgFv^& F`U6WF+FFF=|V;V|VvvFFF;F~zFF;F}P6Wg#FF#uF܃~~QFFPVRahX\6N\~<FPh^\vh^\vhX\6N\<"F{F?Ub\hd\6N\~<FPh^\vh^\jhd\6N\<FF=|{^&#~ PR\F@FFPVRF\nG\ob\h^\FFPhX\6N\<G\eh^\vhX\6N\< Fz6N\<UFFPVR-vhX\6N\<Fv.$$$$$$$$$$$F 딃n FN넸 7 2FFF= |F- F] P9HUjh\jevV󫖃Uv F ^& WUv F ^&!WUv ^&UF v&DUv ^&@h\h/ ,\\\˃>\u6\6\J4U"jFjFFF;F}VRPj F;FtF+FFF=}B#t=tFFFFHFF;F}YFBFF;F};VRPj&FFtFv^&F `v ^&FFN럋FU v&*PFPFPFv ^ F#~ ȍv~ >\\F v&D\v &F v&D `6\^ &F F#~ ȍv~ >\\F v&D*PFPFP]Fv ^ F#~ ȍv~ >\\F v&D\v &F v&D `6\^ &F F#~ ȍv~ >\\F F U> auZvLFFF;F}?PvLH~+hh h\F=u+ aaF+UvFa&U>au+ va&˃>au&aahaTjjaUP>auvFN FvvtUP\+^Pa|F\h?haPe\\j|`aaF UvvjLFVF*F=r\ta\V ҃^Ѓ2V;\r&\heh&aR6\6\\\ F #~"v >a>\\aF6\a&a `a&aF #~"v>a>\\aU j#uJ>at jvFPVRDFVRVRPvvvv!U">au> at ajLFj##t>at F ja|Fj FFF;F}AVRPj` F*F\ua\PRFPVaFFF;F}DPFPFPOFF F;F}VRVRvPvFF˸U+FFF=}^VFFU>at>FF FFF=} v~F^VF؋F+U>atK+FFF=}6^#t&ȉv6\^\~FFF‹F+U>at>auFF FFF=} v~F^VFFF=}6^#t&ȉv6\^\~FFF‹F+UFaˡaUvv=KUt:jFFh`h6aPe6`a+Nvv-^F~}vvv+F\FF\\FV~|vvDFv^FF;F}%vvDv&~uFFFӃ~u vjv~uF8ktvvFUja|FF.Tk.8k:k..Fj|*r.k,kHSF0kV6k2kD|4kFUvvF쾾j~F8jF6Zk~FjF#~?v&FjFy#tFvjFPFPU y#t6jvv$FFPvvvvivvvv&D4&T6y#tvvsFF#~PjFP;jS|Fj|N~FFFF;jsvvPj&F Fvv\\vFF;jsvvPj FFݡjFH|:vvjFFF;F}vvPj` F Fރ~~vvj<FwH|vvjFvvjFvv}dFF F;js6VRPjBLFnFv~FFUja|FF8jjj8jLFj8Fj%4Fj#tVjF+jjy#tFjFFjF jFj~t j4FjS|FVjjFjF#tVjVjFj\FVjjFjF#tVjFjFjj j#t"VjVVVjV+jj~tFjFFjwH|FjFFFjFFFjFFjLFFhh^kPeFVZk\kF F;FsEPjLFvjLFF=uv&DF&FfFFFj|*pjjHTFjVjjUFVFVja|Fj~F6ЉV&kj+ЉVFF;ksv~FVVFܡkF#~.v&FkFvjFPFPG FPvvvvivvvv&D2&T4F#~PjFPejS|Fj|N~FFFF;ksvvPj&FF ݋F=}b~FF FF;ksvvPj FFݡkFH|:vvjFFF;F}vvPj` F Fރ~~vvj<Fvv>|F vvjFFF+N~VVF F;ks9VRPjBLFЉVv~VFU ja|FF6 k6jLk6Fj%4Fk#t$VkFF&kj4FF&k+kkFkjS|kFjFkFkFjF#tV kF kFkj k#t"VkVVVkV+kk~tFkFFQ|"kF$kF FkFFVkFFЉV&kFj|*qjD|jjHEFjV kjUPFjj=~:$F6b6bjPhbF)jjƸbb UF6jbjvjbjjjUjFFFF;j}b*FFF6jbjAUQ FV+buA+v^&W։VRhOj6jFb+^&?uA+ыA^&7jbv&TjbuA+ыAbjbvjU +.buA+щVRh6jDŽbj+.buA+ыA.bjbv j+NbuA+щV/*NF/^уRh 6jDŽbj+NbuA+ыANbjbvvvFV6jƸbVvljU+FFF=})+ļXbuA+ыvRBVFϋF@PhhFF=}]jjRb+~ĽXbuA+ыA~vĵXbbvBjFjj$Ujh^ttj6jƄbHj6jƄbX j6jƄbhvjbjj6jFbj6jƄbj6jƄbjjUFFPh<j6jƄbFF=!j6jƄbj6jVbFjj'UK FV~u++WuA+ђFv&TЃRhj6j+bj6jƄbj6j^&WVb;Ft NWjbFjv&L&4jbv&Djj6jƄbj6jƄbj6jƄbjj&UPjhFVĈbVbbbbbjbPWjUPF =~F)F Ph~j6jF bvjbjNvjbFjFFjjV~ ~{˾bjbjUFPv&t&4&tjjjhrmF=t-~u0v P(hh h\F=u$+ hhrkjv&t&4j h˚Uvvl#t(h hkjhkv&t&43bb bb3ҡb btBUvv#t!hhkjhkv&t&43+U+j;jt AFPjjjvj >jt Fjv U +jjj6jjFjFFD|FjjjFPjLjjjhbhMhk6je$FVRPjj6jvv^hRhkvvU +,k*jjj60k.kF0kFFD|FjjjFPjjjjhbhlhk60ke$FVRPPjj60kvvhqhkvvU +jjjj6j:jFjFFFjjjFPXjjjjhbDhhl6je$FVRPjj6jvvhhlvvU+j+jjF$FjjjPyjFjFFFFjjjFPj;jFjFFFD|FFPjjFP^jjjjhbG j;jvFjFhh*lveFV+N~Fvv[vjvvv+N~FFvvvj6jvv$hh>lvv'6b6bj6jhb6b6b6b6bUjeG,FV+VNRlTluA+6VlXl˃>Xlu+hRl˚XUPFvvxr#t t uF F9~t^ FUv vvG,RPUvvG,RP8PRtv v 8P[Uv vvG,RP8PRtvv 8P!UFv&4&*ȝt v&4&, FZlufZlj hhtl,fljjjjh6<`lhlP~<blhl6`l~< dlhhhl5,hhnl5, 6`l<<^l6`l_<^lUvjFtlV6`lv^<vjvv6`l<UPFv &+D-F#|+F N~FFv &Dv &t&t&4vvVF U`Fv&&TFV&DFhl&t&4Fv&;DsFF llHF6blFPFP.F ~tsFFFV +ļhluA+ыAvĴhl~{vllFv&D+FP&4vVvBP FFVFFFPjhl6`l<U >^luF~|F V@FPtlV6`lv^<F^&xt FFSvvv6`l< FEF= } PvFsˡflUF= YjtlV6`lv^<jvv6`l<jEjvv6`l<jEjvv6`l<$U~ Tv vvjF tlV6`lv^<vVjvv6`l<v jFUPjhl6`l<F@hXhljj4h˚ FU>\luHWFFF;F PFhl6`l<F;F ~ hl6`l~<Fv&;DrC6dlVFPgFV|~v&DF|Pv hl6`l<hl6`lr<Fhl6`l<F V ;V~+V)Vvvv&tFPFP&t&4,FFF FF;F}@^&W&Z|~RV|Rvhl6`l<FF hl6`l~<hl6`l<Uv vvhl6`l<Uvvhl6`l<Uvhl6`l<jAvhl6`l<UF\lU ^,hG,FV+~uA+vQFjFPF wg.-GNSX]bglqv{GF G^?^ :^5^0^+^&^ !^$^(v =9F~ u *F;FuF~cjFP4^,Ohh"mjHem m+mmmUFm mFVF;m})v&| thh.m&t&4 FF hh:m6 m6mU>mthm;mMmmVhhFmR6 m6mm m uhhRmjj3h˚ mmމ^FFV&&WF &GF &GF&GF&G mmˡmUFmމ^F&w&7&w&w&wP(mU&Fmމ^F&w&7v&t&4&tjFPj"P(FU&Fmމ^F&w&7v&t&4&tjFPj"P(~t F+F@U&Fmމ^F&w&7v&t&4&tv FPj"P(FU&Fmމ^F&w&7v&t&4&tjFPj"P(~tFU&Fmމ^F&w&7v&t&4&tjFPj"P(~uFUv vvKFVmމ^F&w&7v&t&4&tv v&t&4PVhlP(UFm mމ^Fv vvFv&T;vVv&t&4v&t&4&tv v&t&4vhlP(UFFmމ^F&w&7v&t&4&tv FPFPP(vUFm&p&0P(mUFmމ^F&w&7v&t&4&tv vP(UFmމ^F&w&7VP(UFmމ^F&w&7v&t&4&tv )P(U +~uA+щVNQvvRPPPhrmF#thh^mjvvj PvjFPjP(F FhhjmPeFV+~ uA+vvv v VvvvF#thhvmjv v jPv P(FVUFmˡmjjjjh:<mn ˃>ntm,>nujF@ 6m<<nm˃>nt6m_<nUPFƄmV6m~<Fv&;Ds&Dv vjFƄmV6m <Uv vjFƄmV6m<UFmUvG,FV+~uA+vVRjvG,FVFPjvF V FV+~ uA+vFPjJUjuG,RPjtP,6Wa|FF F;F|FVjghnRP9, v&<;uj{VFV ujmhnjvj#h˚hj}vv ujphnjvj#h˚hFPvv6WVvv6W:FHjvhoRP,UPFF;n}&nVvoFU v6Wqn6WF+FFF;FsTVĴ&n& FP6WgF#nF#tjFF nVv뤋FFF;FsDŽ*nFFn˚bjjg :UFĜ&n& DŽ*n&nVvoU nFnnFVv&FF;F}-v&F< t<9w<0shjF,DFF6WF6n6ndv&;F|hvjG,+UP~},v6Wg#nF#thjH,+U~uTe~uX nhnvF n;*nu5#t+6 nF(n&n6n6n4 #uF> ntFFPF#tzNvF#ufv6WgF nnJF(n&nvdFP6WgF!n+v*nĴ&n&n~tF&nVvoF n*n6 n6n6nF(n&nF U +FFF=}aDŽ*nĜ&n^F& &nSvvv*nt!(n&ndHFP6Wg FFvv6W:U+FV^&@{Fv&@ ;Fu Fv&@0lFF;F _v &VtK= ~Fv^&@1FvF 0^&P~ &!F~tFv^&@,FF Fv^&@ Fv&@}Fv&@U,va|FvFhjhoPeF։VF F;F}Pvgv^&FjuG,RPh*ov v|FF;F}`PvqFPvvvލFP+~uA+у VvjWPFPh0ov v|"FjtG,RPh@ov v|U~ F ĜLo&&GDŽPoa~ }"FF0ĜLo&GĴLo& (FF 0ĜLo&W0ĴLo&FDŽPojj6oP_jj6oPFˀ>ouny6Ro&Voˀ>ouny6Xo&\oˀ>otFT6Xo&\oU^wA.'5AG;]aMS&f y;Pe~UF*ȝt F*䖃 YtF*ȝt F*䖃 Tt+*6Ro&Po6Xo&PoU+Fv&;DtJv&D= v FPv&t&4VRvBFPVRN+h^oohLooUP6do&FF*ȝt F*䖃 YtF*ȝt F*䖃 TuooUP6jo&FF*ȝt F*䖃 YtF*ȝt F*䖃 TuooU^wZ.I"(.)?93&-r' p\>otoUPF~}!FLoVvKFUhov6W&jsjF@ UFF=}&VR6W@uFoF+ooojZUv&4vF&<u'v&$&FFjjVhDqvv" #tv&<tN+ q qFF빃>q }q j^h\qRP,ˡqU~}q FqUjqG,RPhtqvv|6qhzqvv|Fp^FF;q}!v&4hqvv|FF jpG,RPhqvv|UHj|F܉VjF=F+N~FF;F|VRPj&F*v&;Dt&;DuF FĊF*v&;Dt&;D uF FF*v&;DuFFjK #ujK #tF*v&;DuF FFgFVFVFFVFp^FFFF;q}:qqVu Nu^v^&v&fVFFU FFF;F|~uhqv v lFV&<{u[hqDRPlvV&<}u'&Fv F v^F~&&ELFhhqjjFv&<}uhhqjjh˚ v^&&@F0F;F} F;F}L^&&@Fhqv v lvV&<{uhhqjj7 Uv&*ȝt4VdF#|;F |hhrjj,h˚ Fqhhrjj-h˚ jvvFPRF F=}<RJ#u#tưqVQR6WV vDŽqFU jwG,RPjvP,Fjhh.rFP#thFF;F}[~tU+qFVhhDrRP9,vvv6WqhqP6W4FhhZrRP,˃>qu>qu q#t'qqqq>quq#t qq˸qhqUPF;Ft~t~tF#FF;Ft;Fu+UFF=}BF6WFFF;F|hqP6W +FFFF=|~u+҉VqFVF=|xqFvP+#tYFF;F}B;Ft;FuFdFރ~d}!FvFBFvFBF~|F}FQF"+#u3>qu6Wq6WqhqP6W4 hq6q6W4q˚\6WH|!hq6q6W hq6q˚k˚@6W#t6Wq;qq6W#tq>q}6WHqUPqqiF= ugUPiF= uD6q6WRqUP6W#u 9Rhh\F=u86q6Wj6WF;qHq\j P(UF6q6WRF@~6WL;F9T@j6qg 4#t t uF F9F#t= t!FU jyG,RPjxP,jjPh~rFP#ujFF;F|ZFVjThrRP9,pr󫪃 ~u-FPhtrhsrhrrhqrhprhrvv  /FPhvrhtrhsrhrrhqrhprhrvv $>prt>qrt>rrt>srujnhrjj/h˚ pr*;F|jshrjjj.h˚hrr*;F|jxhrjjj.h˚h^*Ft)Tt fttuxrhh sjj xrhpr6W P6W Fhh"sRP,U v&v &jLFFF;F}WPjLFFF;F}7PvjLFVF:FuFv&Fv &+ FF롸Uj%xrvvFFhh8sPeFVFF;F}vvDv^&FFF;F|v&F"u&TVvvDFhqrhprvF@~`hsrhrrvF @~HF*䙣trvrhprj Pj qr*Ppr*Pj_vvDFFNjj Pj Uvzrujjv:vDŽzrUPvzru vv vqFN Fvv v:Uv vqFNV!Vvv v:U~}F~uhrsjr4v&t&tv&|uFTPv&D*P&D*P&D*P&*P6Ts6Rs6Xs6VsRtVsXsFV+>VsuA+vFPvr4U"hlsh/ ,nspsxshG,FV+~uA+vP4FFjZh~sPeFVj[hsj eFVNNj]hsQe VsXs ~F-+FFv&F~}Rh|svvFPvvvv<vFvvFBvvvvv<F먺+~uA+BVjmhsNRe6NsPs+~uA+ًAv>Ns6Ns6rstsVvsVҋ~F-+Pvvvv+~uA+ѾsuA+As~F~}evBB+FPvvvv<+~uA+ѾsuA+As~F 땋FF+FPvvvv<+~uA+ѾsuA+As~FFF+FPvvvv<+~uA+ѾsuA+As~F~uA+BVhhtRe6RsTs+~uA+ًAv>Rshhtvv&hh.tvvxsUT>zsthhDt6^s6\s zs+~󫪊`sV6bs  F6W FFZsF;F}Zs6fs\s^sމ^FFa4FZsJ;hs~ZhG,FV+~uA+vP4PFPVR4FFFVFPvr4nNfsFFF;F|F;hs%FPv&46W` FPv v4FFFFhG,FV+~uA+vj4FPjr4 ˃>xsu6ps6nsJ46W6nsxV;4j6jsg 6bs] jF@ 8>Zs~`UPZs#t fsdsB;9Rfsdshs;|fshshs;Zsuhs'%dsFjAFP4jFv4ds+UP>Zst>dsu,>fsu9Chs;Zs~hshsfs%dsFjANP4jFv4ds+U >Zsu9fsdsF\s&06W >Zsu= FF҉Vv6WqF#FPv6W: ZsHhs;uhsfs#~fsZs+U>Zsu 9+6ds>fs\s&FVRP6W` F*PF*P] a4FF F;FP4FFPjj4jF*Pg FPF= t=uFPv6W j4FUa4FFF;FP4F+~󫪚F FFFPF= t=u^ FFVv6WqF FPv6W:FP6W P6W [FU`s bs6`s6W jsfsdsj4hhhhh9hhhh9ho hhhhj 40F>Zs~jAdsP4a4FFF;FP4F6`sj6jsg j4Fhxth/ ,zt|trt6|t6ztJ4j6ztxV;4W%Ht vtu+*~t #tj4j4j4j 4˃>rtuy U+pt;Ft ptpt~t ptpt ~ t ptpt@Qjjjjjj˃>~tt9 jjjjjj˃>~tt9 jjje˃>~tt9 jjjI˃>~tt9 jjj-UPFvtpth|hLhh9h0hhhh9hhhj 4*F= tpt#~ P jjjjhJ<thth/ ,tttjjht,P(U  vVj.&t&4FVFV#u#t+~uA+^&G+v&DFv&T Vhh uReuuvv&t&4RP+6u^&>uuA+ѾWuA+AW>uu;Vu;Ft:>uuA+Ѿ~uA+Av>u+>uuA+щuuUn^#t t t hhhG,FVvv6t&tz&txFPRtFFV+~uA+JVBjFP;4U6t6tJ4veW%3=uBtW%3=uAt#t#u">tt j4>tt j4U>tu v|U vV&&Ttt&Dt~u"K vV&&Ttt&D +tttQ vV&&Ttt&Dt~t4y#u+tv^TttDtUht6t<t=}hh"ujj3h˚ jhht,vtU^#t ttF FF~tttډFVFt؉vFFFF;F}.V;t%vvFRvv6t<FF UjvYUjvKU>tt v6t<<vvvUPFFFQUlFFVFdFPjht6t <FP  F=uP~u&FdFPjht6t <FP  FdFPjht6t <FP3 FdFPjht6t <jjFPFPP(3Ҁ~uBRnvU~tF^#t ttF FFhhtvj6t8F= u ve~ u vF˚U>tu9< RP$#uF@#y#tj5$5$FURP$#uF@-j|#uj|Pj|$5$FU>tu9a RP$#uF@Hjj|#uj|Pj|$5$W%=u vJFU>tu>tu9ny#tjj|#uj|Pj| RP$#t$$5$W%=u vFF@Ujht tj4F v.xxxxxk jFbvvFE>tt>tt v>tt v>ttvPF9F;Ft= tIFj79/U >tu9 RPX$FV uF@xy#t7jj4$Fhah:uPeFVRP3$vvvjvvvv hghRuvvF U  RPX$FV uF@hj|F$Fh{hjuPeFVRP_$vvvjvvvvhhuvvF U >tu9 RPX$FV uF@jXj|#uj|Pj|j4 $FhhuPeFVRP$$vvvjvvvvhhuvv W%=u vFU >tu>tu9 RPX$FV uF@y#tjmj|#uj|Pj|j4$F $FhhuF;F}FPeFVRP3$vvvjvv+N~vv$$vvvjvvvvhhuvvW%=u vsFUjht tjlj44F v.  % 3 < K  jNFbvHv{FE>tt>tt v5>tt v>ttv>F9F;Ft= tBFj09(U>tu9S RPFV uF@4j_j4vvvvvvFU>tu9S RPFV uF@4jj4vvvvvvFU>tu9^ RPFV uF@?jj4vvvvvvvvFUjht tj2j44F v.AY_mvY jFbvEvFE>tt>tt v>tt v>ttvhF9F;Ft= tBFj09(UF%FF+FFF;F}M~}G^#^t t@t(j9Wj-{ j!FfFUPja|FujEhvPeuuF Uv&F*ȝuVvu6Tv6RvJ4j6RvxV;4jjg ˚ hhhhh9hhhh9hh9hh9hhhhhhh9j4*hXvh/ ,Zv\v^v˃>^vu6\v6ZvJ46W6ZvxV;4( U DFF FPv6WLFVjj FPvFPhhDhh6jDRPjjv8&F= uSFFVF FPjqDv^&jFPvvFVFPvv6WLWDjvg F˸hhh9h5hth7 hh9hPhh9hhhh9j  &Uvlvujjv:<vDŽlvUPvlvu vv vq<FN Fvv v:<Uv vq<FNV!Vvv v:<UhWvvFV#u#tFVj:vvFV uhhvjv j(h˚hj:vFVFV thhvjj9 FVU vvvYFVhvvRPFV uhhvjvj(h˚hvvvvhvvjjFV uhhvjvj(h˚hv\PSvvv&Fv&DVu#ЉV&FFFF;F}B~tF^ &;@u'F&;uFv^ &@&@&&@F붃~tv^ &@&@Nv&DF&FFFF;F}(~t"F^ &;@u F&;uFFЃ~t5~ |hhvjjh˚ vF^ &@F&FF*v&UFhwvvlFV#u#uhqvRPlFV#u#uh"hwjRPjh˚j:vvFV uh&hwjj8 -+~ 󫺐Vh-h8wReFVFFFFF~u3hWvvlFV uh:hRwjvvjh˚v&<}uhpvVlFV#u#uhHhlwjRPjh˚v&<&uFv&<}uFv&FF;F}#Fh^hwvvvFV F@Pv v^SFPFPvv_~t'FVhghwvv9,F FFFv6Wr4vVNv~FP6Wr4FVF6W|F F;F}"V*J;t  N ^&FfFP6W4P6Wp4hhwvv⚡U j{G,RPjzP,6W|FjhhwFP#t;FF;F}.FVhhwRP9,vvvFhhxRP,U>zvtj+zvFFF=}Ft|vFnFFF F=}$Ft~vFFFFԋFF%=u|v!FF% = u~v!FFUjFj|FF"FFFFF;F}Y~tSPjFV*;u7FvjgFV*#VN;u v&! Fv& F럃~uv&4v &FU$Fv &DFFhh"xPeFVFVv &D*FPeFFFFF F;F}HvvDFVRNQP#tF*v&DF&FnFF밋FFPjr4vVNv~j4FVRPjp4h.h .hWvvFVhWjjFV+UjOd>xtjsG,RPjrP,ja|FFF F;F|FVh?hTyRP9, ~t&vvFVhDhhyRP9,FhWvvFVhWjjFV+~uA+щVF6xvF&;Tu6PPvv&t&4RVR4P(~uvdF6xvF~tAF&;Du8jjvv&t&4PFP4P(~uvdF6x vF~tAF&;Du8jjvv&t&4PFP4P(~uvOdF~tGvv=,#thqh|yvv9, hshyjvj>vOdvvvFhzhyRP,UPF~}!FxVv|$FUPFF=sĴx& Fvad#t Xtpt FF FFF=sĴx&yVjjg D$BUFĜx& DŽxxVv|$U+FFF=}hF@VFĴx&*ȝtFĴx&*- YuhFjX,FvcFF됋FUFFDŽxxVvv^$hFvvL,F#uFFĴx&*ȝtFĴx&*- Yu vFFUPFF=|DŽxxVv$FĴx&*ȝtFĴx&*- Yu2^#ttu!vdvdvOdFeU,ja|FjsG,RPhyvv|GdF%FދV؁`VPRhG,RPhyvv| KdF%FދVځ`VPRhG,RPhyvv|hG,FV+~uA+vh hyVevV+~uA+ًAv~hyvv"FVhyjjFVhyjjFVhyjjFVhyjj FVhyvv|FF;F|FPadF$Fԃ#uvvhyvv|F ~t%F;Fuvvhzvv|F ~t%F;Fuvvhzvv|F ~thzvv|FF%=uvvhzvv| F%=uvvh zvv| vh&zvv|F hPh.zvvjrG,RPhBzvv|hHzh/ ,JzLzNz˃>Nzu6Lz6JzJ4j6JzxV;4j 4 U +FVډVV~t vvv jF^ Sv<Fvv^F= u~u ~tFp^w`..$..).....$)$  ..  FHF@+FF ~ VI  95UPF =~vvvv PvvFjvv v<F^w4.  9UfF_FPj_FPvv +~uA+ѾTzuA+APz{j_hXzPhlzFP3WWU+WWv&;Tu!&;uVtvvtvv Ft,hG,RP#tuhG,RP|hG,RP6W6W|Wj|FjT\ULvd&vjlvWhhnzjh hG,RP#uhG,RP|hG,RP6W6W|WWj|FU|jTLvd&vjlvTW Whhzjh Wuuhhzjj1j W%,j >Wuj1G,RP|j LFUbFFFjjFV+~uA+FVFV+~uA+Av~/*Vʾ/~BjPjdjdPP(jjjvv+~uA+RP(j+~uA+BRjFPF@PP(t+t tFwh.j Lt렍FP~vt녚9}hzh/ ,zzzUP+F;zu6z6zJ46W6zxV;4vjvg (UPWhhhhh9hh9hhhh9hhhh9hhhh9j4*FWhzh/ ,zzhG,zz+>zuA+6zz˃>zu6z6zJ46W6zxV;4(hzjthzh/ ,zzhG,zz+>zuA+6zzUP+F;zu6z6zJ46W6zxV;4(6Whz;4˰zzzz˰zzUPzhhh9hh9hh9hhhh9h9hhhh9j  &F=u zFUPhhhhh9hhhhhhhEh9h/hh9j 4*FUDF>WuhzhzjDhh6jDRPjjv8F= t=u@FFVF FPjqDv^&jFPvvzzWDFUPv&*䣲z&D*䣴zzhChhhh9hhhhhh9hhhhh9j 4*Fz~{ˡ{ˡ{ˡ {ˡ {ˡ{UF$FF~}.F:Fu*{ F:Fu,{v&Fv &FUv6{jLFVv6{jLFVFFVV *%=uiF({~F FPv6{jL UF %3=uBVF %3=uBVFFFFFFFFjOdjjL{jjL{jjL{jjL {~tjjL {jjL{~t;jjL{jjL{>({~jjL{FFF~|vvDFvvDF~tvvDFvvDF~ttfF6{^&ptSdFXt vdvOd~udF%=u~u~t+FVFV~t7FPv6 {jL F#tNꀍFPv6{jL ~ujF*䨀t6{6"{vj:~t%~tvjq  {FPvj: FPv6{jLFPv6{jLF#tNNFPv6{jLFPv6 {jLFG~t$F~}6{^&PSFUvvFF %3=uBVFF;F|vvDFvvDFvvDFF$F FuF#+FVNQv6{PLF F$FFu'FFFPv6{jLF FFPv6{jLFPv6{jL6{vj:F+FЉVjRPvvTF UF%؉FP|FuIevg.IPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP;PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPBBBBBBBBBB--BBBBP--BBBB4444444PB444444444P4-44-4----------4P--P-F8}t} >6}u6}<<8}}˃>8}t6}_<8}˚4UbFVFV+~uA+vh}6}~<Fh}6}r<Fh}6}<FF=~FvPvFPFPvv,$FFFFF;F}<B#~*^VZ̉^VFFPvh}6}< FF뼋FUh}6}r<FFFF;F}vh}6}<FFUXv&DF};sH+V ʍ~vv&t&4BPFFVFF }Fv&&TFVFPjh$}6}<UjOhJ}heB}D}jPh\}v&D@Pe>}@}v&t&t&4RPv&\>>}&vvjUhn}jh}6@}6>}3:}<}F}H}j^h}6D}6B}j_h}6@}6>}6<}6:}F}H}jjj6<}6:}T+>B}УF}H} Uv&<;t H}u>F}tBRjh˚ U7FVvv v RP9, v&<0r<9wVdv&vvv v vv$+ UFVvv v RP9, v&<0r<9vv&}@}v&&TU>H}u >F}u+F}H}v&&Tb~jZh~h ed~f~d`~j^h~Re~~UF~ }=vd~f~#u#t'jih~RPvvDŽd~DŽf~F 뽡~~#u#tjnh~RP U6v&&D&T&jfG,+ľuA+~uA+ыA~ľuA+ѾľuA+AĶľuA+щxPh ;P(~~6b~d~f~dž^~Pn =uP(Ķ&D ~_b~>b~ }>h 6b~d~f~+ɉ;u&;u"hh~Qj5 hh~jj6h ^~`~;^~}$`~d`~҉R~~Ķ&t&t&4Ğ&7&G&W ˡ^~ˡ~~UFF=}4jjfdv&t&4&tFP4P(F@+U3ҡ;FuBUvdfUFV uhhjj h˚ FVFVvv##tFv&FVUhh+~uA+BRevV+~uA+ًAv~v6~uA+щ Uhh+~uA+BRevV+~uA+ًAv~v6"$uA+щ&Uhh+~uA+BRevV+~uA+ًAv~v6(*~uA+щ,h(UhG,FV+~uA+vVvvvv4F #uhhjj0h˚ hG,FV+~uA+vVvvvv4F #uhhjj0h˚ UyFVRP8vv_FVRPvvEFVRPvvU#FV+~uA+Av~FV+~uA+Av~ U>duBFV#u#tRPfvvdhihjj h˚ UFUFV uhhjj h˚ vvv v hvv Uhv v F V F~} F F th jjF V Fh$jjF V thv &*䖉vȝuF v &, Fj]G,N&: tj^G,N&: ujv v vv< U46FFhh(PeDFFVhh6veHJFމVhhDveLNFډVhhRve PRF։Vhh`veTVF҉Vhhnve@BFΉVЋFFhh|Pe8:FVhhFPe <>FV+FF̋F;F|FV uhhjj h˚ FPvFVvփFVvFVvރFVvڃFVv΃FVhvv $vvFPFv&F+~uA+ыAv~~~uA+BVFUFj jhvj vWUFV uhhjj h˚ vvd6WUv& v &vuvT&0<v&&T+&.02 + .hh6F6Dhh6J6Hhh 6N6Lhh6R6Phh&6:68hh46B6@hhB6V6ThhP6>6<U6WF6F@BFVFF;F}qP6WF8:FVFF;F}Bv&:Vu/VRVR^SPjFjhv<FFFUBP6WF@~`>4tPF~}Nv66WyF=t%v6WgFtv`*P)FjF>4tP  P* *PUv@&8U&~tv6WRFFFFP6W ~|6WL;F96F@BFV8:FVv6WLFNFFF;F|VRVRvvPRv&*Pv6WLFVhv~<FF;F~FFލFFڌV܍FPjhv<&v&*PvFFFi@BFV6WFFF=|P66WyF=uwFF;F}jP6WgFtSv6WPF*;F}5VRVR^SP?v`*Pjhv<FF\UPFF;} R<<F~u47b4vv2UP>2t(FF;} R_<F2ˡ68&*U8:FVFF;6sv&*;Vt FFU6vjh  P<UP6*;t*jh  P<FwO.6H"6P6D 6L&뀡FˡTVˡ<>U68^&*ˡ6U v@&F* FvFV FV+~uA+vhv~<FF;FvFFFPjhv<UhG,FV+~uA+vQF+ F~t^(jFP4F_F we..38=BGLQY`m^!^ ^^^ ^^ ^$F#v #9F~ u F;FtOF˸UNv&D;FrFHFPv&t&4v v v ^&j.VFV#u#tNQRPv v i v ^&.F^&Fv&UF Pv vvh]F v &˸"˸(Uv &Dv&;Dvhh^@Pev&&Tv &t&t&4^&w&7v &\~&5&v &Dv&DUlFPjdVRNv vvFP<FFVFF FFPhLUvvh9Uvvh"&Uvvh(U&6*6(hlvv|66hrvv|6$6"hxvv|$6h~vv|F F;}]6.&t&thvv|6.&t&4hvv|6.&t&t hvv|$. F뚃>u6FPhvv|DFFVHJFVLNFVPRFV8:FV@BF܉VޡTVFV<>FVF F;F}lv&Vڋ^NQS^&*Rv&4^&7v&4^&7v&4hvv|FFFFFFFFjjjjh@<Ɓhāh/ ,́΁ʁj6΁6́\4j6́ V\4 U >ȁu[6WFFF;F}9FP6WP Fj jVRvFPv" ȁU>ȁtm6WF FV FVFF;F}5FP6WP F^&VvVP"  ȁ˃>ʁu6Ɓ<<Ɓ6Ɓ_<Uv vjFЁV6Ɓ<Uv vjFЁV6Ɓ <UPjF@ hLhhЁjjv8F= u vzLjFhh/ ,˃>u66J46W6xV;4 jjjjhB<hG,+>uA+6˃>ujh;46<<6_<Uv vjFưV6<Uv vjFưV6 <UPjF@ hh hjjv8F= u vjFUؐF2^+~uA+щVNQvvRPPPhrmF#tc=t=u;F(^+~uA+щVNQvvRPPPhrmF#tvvh>h|v( FFvjFPjP(F Fuh(hnh|j( v P(FFPFV uhh|h(vvvjjjh؆hh؊hCF#tvvh>h|v( +FFF=~^V^Ph؂hFPvF#u9Fv+ׂv؂uA+ыA؂^ĿvhȔ|v(FmvvvGFV uhh|h(UP>ؐtF >}=hWvv6ڐܐ tF Ft FFhh|Peꐉ쐃hh66ꐚ U+~uA+щV;~(hhR66ꐚꐉ쐋F vvv66ꐚ+6ꐋ^&FF F;}b~t\hW~t+ꐋRPFV uF&jvܐڐvv4@F F땃~thh66򐚡 FUjFV6vNQVhRP|vvhvv6W6W|hFVWQFVRPvv6W6W|vvvv|UPv vZF;F u~t@vLRP|v~ u'h3RP|h%RP6W6W|FUF Fuvv v jj h˚ vv#tvv v jjhh˚ UF Fuvv v jj h˚ vv#uG}Kvv v jgkFVRP|vv6W6W|`'h:RP|h,RP6W6W|Uj|vv&hqhReFVv&4vRP=FVUPvDŽDŽFjthPev̕ΕUj}h hevԕ֕+vDŽܕDŽUvFhh PvΕ̕vv̕Ε uhh4jj3h˚ UPvu vv;u voDv^ۋĴ̕^&&PvUv~Ĵ̕&0~ Uv~Ĵ̕&0vF^ۋ;F~&#~ &D)앋v~vv ^ğ̕~&9v^ &&G앀WUv~Ĵ̕&0vF^&&D)hhHVFF vF;} F FF FFWUvu vvFVܕ;}W+ȉN+ܕV+һdFiFhh\Pvevԕ֕F+FvܕFvԕ֕FUvUvUj{G,RPhpv v|vhvv v|FvF;|vĴ̕&0vF&++F&D&TFVh|v v|FF;F}?v&t&4hv v|F F;F}hv v|Fhv v|FBjzG,RPhv v|UPvDŽvva|vPTvDŽUvu vv~F Ĵ&WUvu+v~Ĵ&UPvu+'vFĴ~Ujhj evV+&&D&D&T&D&T ƒU+~uA+*v &v&;Lu &;ujh–Rev&&T(j hԖv &4v&t&4v&&T v &4vvv&t&4Uv v vvvVXUv&D&T^ &&Wv&v &DUv v vDRPVUv&D&T ^ &&Wv&Dv &DUPvDŽDŽFjThPev斉+UvF~DŽvFjihPv斉v^斉薋~+‰~Uvu v)v;u v\j|h&jeFVva|v&DF&DVTFvF;}!vĴ斋&&H tFыv~FVĴ斋&&PvFUv~Ĵ斋&&PFVv RPKTUv~Ĵ斋&0vF&DUv~Ĵ斋&0vF&DUv~Ĵ斋&&PFVvv v RPTW UhhhjBhjGhvev&&TjKh,jj2h˚ v&&T ujOh>jj3h˚ +Nv&u+6~6|J4ht˚XUPvvxrF=t =t= u ^ F9Uv vvG,RPUvvG,RP8P v v 8Pmja|hTUFUFˡˡU>u6^&WUP>u6^&*FfF FF&WU6vU6vU>u-F6^&WUjvUhvUjvU>uF6^& WUjvUhvUjvU>u+ 6^&*UP.F6~hh/ ,˃>u66J4j6xV;4jjg U FD$Fvvv$U F:Fv-Lvvhhh9hh9hhh9hRhh9hhhh9j &0j4hhh9hh9hhh9hh9hh9hhhh9j &UjnhƘje6&D jfG,FV+~uA+&wPPjjh<<6&FPh/ ,6&D&TF&DFP&Djyhژve$6&D&Th&4<6&DU`FPj_P(+v&D&<(:FtQv&\&<&{v&DF*PFP&\&<PF*v&D&\&<&}v&D v&\&<&[v&DF*PFP&\&<PF*v&D&\&<&]v&D&\&<&v&DU>t>u 6&D&D&D &D 6&t&tJ4j6&txV;46&4<<6Vm6DRPjh&4<6V Fh6&4<F;F| j4˃>t6&4_<@4UhG,FV+~uA+vFPjh6&4<jHjh6&4<6&4<6DRPjh&4<jAjh6&4<Uv&4&FF<[t <{t<6&D =}1+ЉV&DJVFV&D+ 6&D FUPvF6&T &+T &T &D UFh6&4<F;F|^vx.5wWw6&|u&D 6&D-6&|tH6&DF6&|t0FF6&|u~|6&D;F|~~96&DFFF@FF;F} 6&+DFFF6&+DF#uV&T#~O&L ;|:HVF‰F;F}B&T hFH6&D F&T ^F6&)D Q^6&+D ;F}3&DH&D HVVVB&T FF&D F6&D UP6&t h&4<Fw(.    j jjj뵋FU v G,FV+~uA+vjchVeFVvvN J4QvvRPRtjfhjvv$jgh™vvUjjG,RPjiP,FVhhؙRP9,vF>Wu+FPSSPhvv 2hFPvPPPhvv vtt t~uhh jjh˚ jhh vƐVv^F v&<vjjvRv&#v}jjvv.vDŽkv:v^+FvF;} jhh6vv"FF hhLRP,F ˡUFUvUvUvFUvUvFUkv:Ukv:UvUvFUjjG,RPhbv v|hhv v|~uhv v|vhv vv|vLPvhv v|~uhʚv v|hޚv v|vhv v|kv:؉vFFvF;}!v&4hv v|FF v&4h v v|jiG,RPh v v|U@XVuNUP+:vv4vv6vv8vv:vvvv@vv BvvDvvFvvHvvJvvLvvNvvXPR@TV 4JLNjjj vvT&vvDF~uPjvj+ U+:vvFF^FF;F}vvv&FFۋF=}t t t@ ~FjjGjj?ˡUjlG,RPjkP,jhhh#u>jG,FV+~uA+vhh(VeFVj6vvRPRthh>jvv"vvFF~t*~}$jhhTvnV"FF Ѓ~t'F;}jhhjVR"FF :FF~t*~}$jhhvnV"FF hhRP,UPjlG,RPhvv|6hvv|F~} vnhvv|F jkG,RPhvv|Un~UPWhhhhhh9hhKhlhhh9hhhh9hhhh9j4*FWUPWhhhhhh9hhKhlhhh9hhhh9hhhh9j4*FWUFVj`hʛRP9,FV U6W%4Fhƛv vvV &WuFPhv v  hěv vFV uhhjjj+h˚hFPh vv hějjFV uhhjjj+h˚hFPhvv  ~uFFPv v6WL ^*UwUuCuDt%MtfcudtmtQuuFFF FFP6W @hhjj; ov v6WlDF#t;Fwv v6W+'hh*jvj:> )v v6W>Wuv vFUAFVjjRPv&t&4&tFP4P(>Wt~thh6jj!FhBvvlFV uhhHjjj>F-vvdF=uFhhTjPj> FV(F~uhh`jj _FV 6Wa|Fv6WLFFF;F}(FPvvvCF;F} FVUj}G,RPj|P,hG,FV+~uA+v6Wql6WW#u PFF;F}VR=Fh!hlRP,U+~ uA+Ѿ~uA+^&wjhhxFVev&&T+~ uA+Av v&Mt=t P  L]U~u]UFPFP",V^&?{t@&?[uT6M:aOt. FPQSVSVQ^[Y=Xt ],N~] t&<&Pu$PP u>&Pt$P&G(P*P>*Pu]ð]UQQ2PP$ 2PFP@PP uJF62PP u8HP=u0,PP u!F62PP u4P=t=!t3]^ &G :}OuSvv^ &G :aNtWSvvnLN^ &G ^ SvvFNs=u8^ SFP ~u#aN^ &G ^ &dt@Fs7N률aN^ &G F,^ &G :HOr^ &G :7Ntw&G 9Fu9Fu^ &G&WFV^ &G&W;Vu;Fw3&G^ &O^ &O^ &O&W;Vu;Ns+^ &r &G&;Gwe^ &G &W"N~;u;wL&wщFVN;u;s&+O &"N։~؋F^ &G-sSF u^ &G-sG<PFPF^ &G-FVFVF%Ff^ &G^ &G^ &GNV^ &O &W"^ SPFPFPF u4F^ &G^ &G :LNt :Nt^ SjF t^ &G&G &W"FV&9Wu&9Gw&G&W9Fu9Fu^ &G&WFV^ &G&9G*s&G*^ &FF^ &G@1&@FތFF^ FV&9W"u&9G v&G*H1Fܺ&G &W"N~;u;r_F&+O &"N։~؋F։F&O,r&9G*sSlF tF^ &G^ &G*&;G(uF&G(F^ &G* ^ F&9G*s&G*^ F&9G(v&G(Fr^ Sj$$F u^ SlF uy^ &G ts&w8&SP^ &w"&w G<P^ &w: F t@^ &G-^ &G &W"&G4&W6^ &G&G.^ &F&G0Z&W2~Yt^ &G@1&W^ &w&@F&Z&W^ &GN^ &O^ &OF~+&G &"^ &G&G(^ &G&G*^ &G,^ &Yti&w8&Sh^ &w"&w FP#Fu^ &?^ &G,(~t^ &G&GF^ &G :Nt ^&FF^&G &W"&O*&;Wu&;GrI1&G^&G*1 uSj$$F u`^&G@1&@FF^&G*1&G &W"FV&w8^SQRPFP#FtK uX^&G*1V+^0^~&}*9^Y^&G*H13^Sj$F u/v&|*&L+^9 ^&G*&G^&G,^ &G :}OuS^SzO^ &G :aNt S^S<6^ &du7NLN^ &G ^ S^SFaN^ &G FU^&G :HOr^&G :LNt:Nu^&G&G &W"^&&Wc^&G :7NuX&r&G&;Gv &G&W^&G&G &W"^&&W^&G s7&G s/^&/&_!^&G :Nu^&&G ]^&^ &&W^&G :7Nt ^SF uk^&G;s]@1V&G&G &"F~&w8&XSv^&pWPG<P^&w:F t@^&G-F^&GFrF@1V^&G&G &W"FV&G-sG<PFPF^&G-3^&w8v&XSv^&pvvFP#FNVF׉NV~u t%^&9Wu&9Or&O&WFF t ^&Gv^&@F&Z&W^&GFV^&G &W"^&G&W;Vu;FYvF&GF^&G8^&G^&G&W&+G &W"FVF&G^&uFF^&G :aNt SvW6^&du7NLN^&G ^SvWFaN^&G F^&G :LNt:Nt :aNt^&G&G &W"FV&9Wu&9Gw&G&W^&G&9G*s&G*FP&t@"FP$$F u^&uSlF t^&w8&S^&w&w"&w G<P^&w: F t@^&G-^&G &W"&G4&W6^&G&G.^&F&G0Z&W2^Sv$$F Yu,^&w8jGPj ^&G :7Nu ^&G :LNt@&& tA"F&G :aNuC&du7N ^&duLN&G ^&G-sS&G :7Nu0G<PFP1^&G :LNt:7Nt:Nt ^G<PFPFF^&w:FPD u ~u~uߊFs^&w8jGPj FF^&w8 F^&w:)F^&G F u F uFF :r10^&Fr^&0FFF 10^v&F@ vvFPF^SvhF^&:F@F^Pvj]FF^&:F@F^Pvj6FF(FFF^SvRQPNQNQP,F u$F t^ SNQvNQPjF~uVFF^S*(PvFP<F u2~t,^S+(PvFP<F u~tF;Fv4N+NA^v0^ ~9^YFF+F@^&^&<{t<[tF FF^&^&?{uFS,(PvFP<F uoF sdt_NAv~^YF@^&^v&48-( ^& ^S8(PvFP<F u ~uFHN;v9@N+^vp^~&=9^YF@N+^&CFPF u^&O@wA^~&=9^Y^&G@^&^v&489(^&v&4^P^&wg&we^&^v&48;(^&"^vFF^&F^&G^vNFY^&Gw^ &Gj^&GyF^&^vNFYFPF uQ^&G@^&^&O@wA^^Y^&Ƈ^&Ƈ^PF uN^ GkP^ &PFPFPjF u#FPvhjj^Sh?(Pj Ⱦ^&G F =wmt =amt^SvFPFPjFF uݍFPvjjFPQ؍GPQF!t=u~^&Gi^GePF9FvF^kvN@YF^&^S^Sv^SFPF tF~u;^SvRPPRPF=u^v&xF^&Gi뾃~t<džCFEGv@CPEP}FF7^SFPvRQjv PvF u N^&G )s ^&G8^&G8Fvj^ Sj7F t^&F^GkPC(P^&PFP<F uFt @^&F^& ^ &Ow~&=^ 9^NOY^ &G^&F t$@^wk~ ^Y^ vxD(O(~ B^&G :Nt LN^&G ^SFPFPPF u^SrF u}^&FFvN^S^SvmF tJ^G8P^SvRPjhmmF u"^&w8F t^&w8 FFU^&G :Nt ~v F^&Gj]Uv&D ~&] ~&] Y]^ &dtZSFP^& uV^ &du&G-sG<P^S^&^ Shwmvv|^& uLN^ &G ^&^ &Gd<tN<uSh^& uH^ SFP^& u/^ Shrmvv|^& u7N^ &G ^&U].`P]U#U$VWQ^S4Y_^F^OGG w 3GGG؉GGGFG F GFGFGFGFGPS]UU^ SG PPFP\[#uMG~&wr/^ F%;u^ ^ FF;tX F ;FuX] ^&^SP$$F t^&G t~&w8&SP^&w"&w G<P^&w: F t@^&G-^&G &W"&G4&W6^&G&G.^&F&G0Z&W2~Yt^&GFu^&G@1V&G&G &W"F^&Gv^&@F&Z&Wv^&@&G^&G*^&G(^&G^&G, ^&G :LNt :Nt F^&G-rG<PFPF^&G-^&G0FF^F&G4&W6Ft.H^&O.+N^v0^9^Y^&O.N^F&)G.^v^&G0Z&W2F^&.uF tuSv$F tF^&G0FF^&w8^S^&w.&w6&w4FP$FFt.H^&O.+N^v0^9^Y^&O.N^F&G4&W6^F&)G.^v^&G0Z&W2F t ^&.u%FsFr^Sh$F u^&G :LNt :Nt ^&G&WFV&O&O &"N~;u;wN~Fs FF%Pu!PFPF u ~ rPP PujjPP/F t^&GFP&8G wFPX ^Fv&DF&GF&GF&GF^&GF&GF&GF&GF&G F&8G uANsNQPPF t FF^&#tF ;Fv F&O#F ;Fw FrF9F w~^ &FF^&O&@^&G^&w6 FA:r hQu `Qu bQu dQuFQuFs}^`Q tSpS`QFbQ tS^pSbQFdQ tS^pSdQFT^pSfQFfQF:QXQ&_)pS\Q&&_Q&Ƈ~s) ~NbQt>`Qu XQ&GR>bQtq>dQuj>fQucFQFsH^Sv XQGPXQ&GP^Sv6F=c=t=V=t=W=t !ttFQ~t>`Qu>bQu>dQtFXQ&G)P>TQjQQDQQjiPSQ6`QSQ6bQSQ6dQTQ6fQP=P>TQjQQDQQjiPSQ6`QSQ6bQSQ6dQTQ6fQh2TQ6hQPP FQ>FQtFQ u4FQ uiFQ ufQuxFQ u&FQ uQ؍XQZQF\Q^QXQGSQ؍XQZQF\Q^QXQGSjF~uv&<tF~to~tEv&<u<^&?TtTTTT~tf)Pj^Svg)Pjh)Pj^Svi)Pjxj)Pj nTPTS6T^Sv hrmF ul6Tj^ShF tFJFTT6T^ShPRPFP#F^TTOTTNT.T TuNTFF>Ts T&?uJT@T6TTShPRPFP#F t^FUT^GTTTG^ &Z&WT&^&T@T#@^TT6T FT ^SvFPFPjF u5FPF PFPjXF uF;F vdS~ vHv)~^vNFY^vxw)FF^&F F t~u5^&~u^S^Sv^ Sv<FFUFF F u4vvvjjFPj j{j}jF#t F#t)Fv^@‰FVvvvjjFPj j[j]jF#tF#t)Fv^@‰FV~t~u v&<jF#ukF#t)Fv^@‰FVvvvvv v vj2jj^jF#u$v&<uvvvj2vv VF~uFF^SvFPFPj[j]F u5FPF PFPj[j]XF uF;F vdS~ vHx)~^vNFY^vxy)FF^&F F t~u5^&~u^S^Sv^ SvLFF F FuFFPFPFPjj^XF uF F;FvdbF F2vRF t$N t~^Y^vFFv~N ^YFFF ^&F Ft~uF F t~u=^&~u'^S^Sv^Sv^ SvTFFUFF F uRvvvjjFPj j{j}jF#t)F#t)Fv^@‰FVvvvjjFPj j[j]jF#tF#t)Fv^@‰FVvvvjjFPj jjF#tF#t)Fv^@‰FVvvvjjFPj2jj^jF#uWF;Fs v&8^uFF#t)FF~tv~vvvj vv v vF~uFFU+FЉFVFv&F< t< t< t< tF<+t<-u3v&<-uBVFv&F<_u>MF<_t)+R RvvN*+0NvFv&FF<0r<9v~_t~t V^VFV]Uvv-]Uvv]UFVFV+~uA+v~ uA+щVVv&~ uA+;VuFFVvNv+|͋FVvNv+}FV+]USN v^6F 6GY]U.vvv v v&]UFPv v vv ]USv6t6tv Pvv N +;u;t v6D-Y]UP.vvv v fFY]Uv v vv66 ]UF Pvv66 ]UFPv v vvx ]U+FЉFVFv&F< t< t< t< tF<+t<-u3v&<-uBVF~u5v&<0u%Fv&F(t v&L F(F] U vvF&D u (&L Hv&D t vvv&L F n FV"| ++}(F Fu+dv&D tP+PP&D P,vvvvv+~ Fv&D t!vvYYP+PPv&D P,F]UP#F ;rVRvvF)F ~ wY]UP=t0V;v)+‰Ft uPvPY]US6&F<*t<1r<9v~u6&<0t6&F<0r<<9w8FF 6&*Ѓ0V6&F<0ra<9v[6&<*uQ6О&<} ~PuF6О&؉F 6О&FО~PuFFF]USFV+F6&:ue6&<%t8ڞ%uA+щV66Ԟ֞؞)ڞ0P^ ^뚡➉FVF6&* wL.-BB4BBBBBBB&BBB;  F~t+PFP6&<.u46&<-u6&F<0r<9vPPP6&uF Fu +P4>u;r=t ;vFFFF"tu uk#tP P~t uD=t;v+‰FPPU>uF Fu P6V~t]USPBF%FVV= s0v6|tF7 FWv^6@N~w]US00~F:F+҉FV#u#v PvsF+҉FV#u#v PvT FPFP]U+~uA+щڞF V ОҞUPvv_]US ^*%u0tzE3v..&M M M M M M M M M PM M M M M M M M M M M M M M M M M M M M M M |PM M M M M ؞P6֞6Ԟ>u6О&&TܞޞО*Fu'v6О&t&t&t&t&4 О v6ОΚ)О6О&&TܞޞО3ɀ~PuAQRP^6О&&ОF%uPPVRuP}6О&FО6О&&TFVО#u#tZ6+~uA+v;rv6uVvvvtv(]UvvF&D u (Fv&D tv&|t&D t+v&D u&||x&D tP+PP&D P,v&+DP&t&t&D PvFv&+T;uF(Fv&L v&D&T&&T&DFF]U +FvV+ӹvV+}|++VN}lv&;D tcvF&D t>&D t VFYY v&D t8v&D u&D u&t&tYYv&D Plv&D (FF]UPFvt;u;tPYYF=sF66YYY]VW&& _^QR˃݃ՃUv ]init T+P9˄.ػ(ЋTT.TX+@U"t3U>U&U?>U?u>>UUu...Uٛ>UUtU.<t%U%U $;w+jhhlInsufficient stack for argv[]+SS+UP>Ut7>ͫu/;u&.6.66666#U6!UZ>UtV>ͫuN.6.6.6.6P6#U6!UZ.6.6P P- P80387$AOı=@r-@ =r-UFTFT]UV+V %UF+F ]UvvF&d ڌ;u#;u&D PF<t <tv&L ;Vu(;Fu#v&D P<u v&d v&L ;Vu ;Fuv&d v&D t6Pv&D&TY u&d v&D&T&&T&Dv&D]U]U]UF ▸P;*t;(tFOP PPFPZFF *(FPPFPF#tOP$RRVRZFF<tG<tC<u$~tOPFPPFPZFOPFPPFPZF^*uu F#tNFv^&F<t^< tZF;F wM+FF 0t(1F *(v vv FPF=tP F]UPF *(v vv FPZP F;F s >(u(FY]UF *(FPF#t+]U>6u_6:68D420YY2< t< t< t< tI@6<&tA+щV<+)@BF06<&F< t< t< t< t]U>6u26<&]U0>6u6:68D42YY <6<&]U>6u6:6864\#<@B0]UF2*4]UP>6u6:68؈FYY36<&<uBVFY]USv6D+6D0>6u>6u6:68D42YYY]USv6|u6D v6D6Dn[USnEUSY]US>6u6:68D42YY<.@B0Y]USPDv6t6t&F<0rJ<9wFD%D v6t6\&*Ѓ0D6Dv6t6t&F<0r<9v‹]USP+v6DD6D6t&:uKv6t&F< t< t< t < t Xv6Dv6\&F< t< t< t< t "t^F< t< t< t < t^iv6\&?%t5"t^e>v6\&:u 6D1^i'v6D6\&?*u 6D6Dv6\&?hu6D&v6\&?lu6Dv6\&?Lu 6D6Dv6t&DuDv6\&P^^v6D]USPF*䗃0~ v.F<0r<9v#FDvXF<+t<-uI3<-uBv6T6\.v6D$v6D"*#tt덋]US+FЉFV/"t^xF*PKP^"uF*P6D^FV~tFV+ʋFV]USFFFFFH|ao"t^PP^="u"FVv6L+Nv^F;F}F럋FV]USP^cFV"t^qJ<:t ^^FV]USP^FV]US"t*^"!v6|u v&F^AD>Dvc"tY]US(F>Du FF D+҉FډV("t v6\F< tV< tR< tN< tJ"uBF=uPFP^^FFFv؈B݋^6_n^F Fuv؍FP^^]USv6|u"uUP)v& UPY]USN v^6F 6GY]USY]US$+~v&&&?^u Fv&Fv&&<]u& v&&*䖋jv&v&4&<]u"t^MFb F3*䖋jtBV:Vu'Fv6|u v&F^8D~u^>DvI"tv6|uv&]U^v&&TFVFvFFU; PmfFfF]US^*%uyE3v.^  1  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  1 1 1 1 1 1 1    1 1 1 1 1 ] 1 1  1 1 1 v6|u@6|uv,v6|uvv6t&4&&T3v^|v^v6|uVPVP6t6t6tvPvP+PPPtv6|u5v6\&&_Ë&v6t&4&^t^ 0v6\&?&6DrS"t^<%t ^R^Jv6\&w&7x5v6\&w&7c v6\&w&7DP(v6|uFFPk]U+6VN8:У<>F PB]U68:FV<>F P]_mwARGput_parmUS6VXZ&7&G~6M6u>Vv6tF6V6V&DZY]scan_args U+PPVR~tPF@RTFFH|ZvHFF@~9vvFP~t<PF@RTF;F}FNjF;F}F릋]count_args UPR+PP+P8PRF%t+VFY]set_up_args Uv6Z\6VXPVP6Z&&DT]U^ F㑋Fʖf ֒]U+~uA+щVVB~"v^&:F uƌF#~N+]0U (F+(Fv&v&Fv vF&Vv&^*+tfat"bumrtEtuiutVwt~~tuFv&3ҊF(t~t-+(v&<tPvv0 +Pvv F>(t v&F(F]UFv惼t F~v~v(FFv捄F^FV]UvvFF &D ~ u&D ~ u v&D  v&D ~tv&L ~tv&L @v F<t<uF~tv&L ~tP+PPv ,]U 34tBVVFPVRVRVRVRv v vv?F~t FF FVF Ft'vvvvvvvv&L &DFV]USFv6DF ꖁ(v^DP$v&&TP$v&D&T& &t t u(n]UfHFV;*F ▋(* uvcF;F}F֡f=2}ffHP@(fF]UF *(vVS $v.,S $vDŽ(DŽ*]UF=u[=tV=tQF=t= u QF=r=v=F=t5=) t0~u+F=t= u~u ~t+Pl]Uv&<[uC&DF(uF *(vv+~uA+SPPP6b.,RDFP~tF *(FP~tF *(vv+~uA+SPPP6d.,QvVDF#tQv*(vv+~uA+RPPP6b.,RDFP~tvF]Uv vv]U+~uA+уrvv1"t+F>(uw~ uF ▀0F F *(vv+~uA+SPPP^ *`.,RDFP,~tvF]U+~uA+уrvvu"t+7F>(u~ uF ▀0F ~ u3F *(vv+~uA+SPPP.6:7F *(vv+~uA+SPPP^ *`.,PDFP7~tvF]UPFPvv+~uA+RPPP6dPvPY]tmU+~uA+щVBF ~uA+щV;Vw FVF+]UFVFV+~uA+v~ uA+щVVv&~ uA+;VtFFVvNv+|͋FV+FV]HEAPCODEoffsetUF+҉FVF +FV++FV}vvPFFFV]sub_ptrUF+҉FVF +)FV~}vvPFFFV]each_chunk U vxPv&+RPV"uvvP9v&D&TFVV^ ^vFvFFVFVF Fu]each_item_in_chunkU PvvXv&tVFV&^&;Gt$SPvv^^ vv^^ "vv^^ FVFVv&|u] each_allocated_itemUFFU PFV#u#tRP^ ^]USU+Pvv]USv&|Du6v6t6D6T#u#t RP6\ 6\FVv6t6D6T]each_free_itemU rtFVFFvvF&|Ut VPv&D;Fu &D ;FtvvPFFSv&tVv&L&;tvvPvv^ ^FVFVv&D&T FVF FtV]remove_from_free_chainUv&|rY&D &T u&D&T rtv&D&T &t &D&T v&\&D #u#t&T &L&W &O]US]insert_into_free_chainUv&tVvV&|t&|UuVEv&Dv&D?v&#t^PVFV&|UuGVv&Dv&DvF&tVvV^&G&vvZJv&|r@rt^F&\&D #u#t Ž&w &Wv&D &D6rt]search_free_chainUU0PtFFfFV]USv&D^6;Gr 6w6Gʋ]normalize_relativeUFVFVN v NvN;Nt RP PFV]insert_chunk U+v&D&Tvx&L&\;xu;vtv&w&GFVvxv &DU~tvvVRF V v v ]add_new_chunk UF+FV+VQRPԊ*҉FV++}FV-} FFvvFV uvvFF&&D&D&D&D vF&&DDFV-&D&D&tVvV^&G&&D&Dvvvvj]malloc2U >jtFsF~v+ FvxFV uvv`FVF Fuvvv&D+FF=w &DFFFv&D-&DD|&DF&DPV FVRP^^ vvvFVN& ~v?F&D&DU&D|&TPVN& vv FF>jttFV] zU]hmallocU+PRvvvV>lt%#u#t#vkFV]mallocUv6n]possibly_free_chunkU]errUSv6t6tPnfreeUF FuFFVFV>jtsv&|Du#v&DFPvvq&F;Ft~v&DUV5vvV>jtf]check_heap_integrityUU PU% Py]US]US]HEAPCODEbefore_freeingUS AFv6T ;vVNv~v6D;Fu 6D;Ftfv6D F6T;vV~sFnv6D6TNvFVNFvv~]reallocUvvFF^&G*F^F&WVv~zvvS $+zAUI Pvv V$FV>Au9>@t2UI PvvV$FV>AuBBFF B>lt6vF#u#t(&D-FV;v+ʠkFV]creallocU@v v&t&4v&&TBF@]U^ *#t ttZF *(=F *(FPvVP v*(FVFV v v`F *(PPvVP v*(FPP v*(FV+FV FV RPP FV ]U+~uA+BV~ uA+BVF;rV;rPv v vv]U+~uA+щVv~ uA+vv ^9vv^&‹]UPvvPPFPjd #uF*Y]UvvYY]U66YY]UvvF(F(FV FV&D tVv&D tv&|u&Dv&D ud&|ul&D @t&vvPPv vjdF #tPPv&t&t&D Pv&D&D&T&&T&D&|uv&D @u&D=t&D&T&+&T|&|u;vvPPv vjdF #uv&< u~tN Fv&|u&Dv&|u&|tv&DH#v&&T&+D&TFV&D+FVN ++ً|։Fgv&|u<P&t&t&D Pv&D&D&T&&T&D&|uv&T &(u F(F(Fv&d F]U vFvFR+QQ&D P,FVv&D tC&|t<&D t&D t&D uv&D)FVv&D++NvFVFV]U+PPPvve v&d ]U~u (FFvvF&D u (v&D t&D tv&L v vv&D u (mv&D#t@u v&D&D&T-&&Tv&D&T&+&T}#& &DFv&&v&d FFFF]U(F+(vvF&D uFv&D @u&|ui&|ub>Ȟu[&D tRʞ&\&Pv&D&TRP&D P@v&DHucv&D&T&&T&Dv&|uV&D tHv&D uP&t&t&D Pv&Dv&|uv&D&T&&T&Dv&|&D=t&D&T&+&T|v&Tʞ&Ȟuk>v&D&&T&LA&\+ىFVʞ~uA+Cv&\v&DH&T;~&&T–&:˞uv&D&;Du&D3v&DH&;Du>Ȟu&Dv&&T&+D&T&Dv&|uv&|u$>Ȟu&DN ++}v&DHxv&&T&+D&TFV&D+FVFF V;sEv&4^~9v^& BV)V FȞv&)D~>Ȟ&@u~ vv&L >(t v&L F(] U vvF&D u (&L Uv&D t vvv&d &|u&DF n FV"| ++}(F Fu+vvvvv@+~ F]UF#t(]U~v0F**(#tPv ]UF*P ]U>FDFFF~v'<+t<-uFFЈF3<-uBVNF+FFFњ"t~t vϚ ^^ FF<0r <9wFX~.tR~t vϚ ^^7F<_t%~s~u<0tFFЋvBFFNFЃ~vF<0r<9v~_tF#w~.tNF<0r<9vK~uE"u.P ~t vϚ "t ^^ ^^~_tN5F<_t#~s~u<0tFFЋvBFNNFЃ~vF<0r<9v~_tF FuFF+~ FFFH|;vʊB,0Fƀ~uFƊFƋvBv~tFȋF=~NŃ~u,~FPFP~wFޣ>UuH6ޣvF&D%&D #t&d v&& D& D& D@&D #t&D ]U6ޣ~>Uu6ޣ&| t&| uv&L ޣ]UFfFV++|"}+lkv$FVl]Uv vv $]UvvS $]Uv$]UFVFV+~uA+v~ uA+щVVv&~ uA+;VuFFVvNv+|͋FV+FV]UVWv~ N+rt@H_^] UA&<M$@POl]UF;B~B]U>Dt @POlDB#~ V;|F@]US&v6D*6T+ЉVRFPv\S|FP|FPq|FPFPv~v6DFFvBFVs*$FFv6LF06\6@FrFF=} F뵋v6Dv6\6x0t+F@;}6D]US Fv6;D|vV|.6: .68 l|uvFPFP|.6> .6< lv\S|v\Sq|v\S|.6B .6@ l|r@v6D#t-\S|D P|v\Sq|v6D]U6FPFPv~v&<tFPF#}*@F#t.PFPFP|FP|FPq|FP|.6B .6@ l|sFP|D P|FPq|FF**F#t0PFPFP|FP|FPq|FP|D P||s+FP|.6P .6N lFPq|NF^*Et Gt"etftgt"FF+ F@P FV;|Rnx00~GG FvB^~&AFF~~Fv&]UvFP Sq|] US=tx;vR4tY]US=t =rY]USvvV|.6: .68 l|s&vV|FdvVq|p-tp+ tp vlY]USPFFNF;FvN0tF+ҋN+;u;uu vO.uNFHv6DF+F)x]USuu v6\v#tPpPu>tu v6\Y]USP>z>tP.v6D#unv6Tz;}A+;rЉVʋz|QBv6TF)6|t<R@@P.v6|t$u>t xu v6D^v6Dz;|R|Pv6Dz;~ +RPv6D#tPPP#u/v6|t"z#}أz#t5;~'v6tV|.6: .68 l|uFv6|t$ux^9PR x@@x^PT uz)v6T;rЉVʾ|P)v6T6|t PPd^PT P6zPv6tPPv6|u#t PP]US F|O>t FƄO.F#u~v6T;rЉVʾ}^OV)FHv6D6|t Pv^v6tPPv6|u,#t%PP^FHPPPz#F-#}@zF+zFF"z #}у0vOzNF>z׋F=|ϊVvO^6WN@@PNV]USF>uFF^*Et=Gtet3ftXguX>tQuFzH=|;~nD(Ffz#~;r) z]USz#}؉FFF FF~c렏@*@@F]U.W>u>uFFFPv6vvv v vvVRvzF#tP4vFP>u uFFF碏^*Et0Gt2et&ftgt#z;|*+$>ux`zH=|;~ HxBz#~*H3;uAʉx*+z@x>uxxtv>tu] ??? A00.UFVFV~tAV+~ uA+щVv ~N;s+~FV]U~P PFPF>u>u #u+]UPPF#t 0F^+Fv&TR*;t FƄ{v&LR*S^v&DR*F#t FvƄ}v&D*#t FvƄ[v&L*^v&D*F#t FvƄ]v&D*#t FvƄFv&L)**v&D)*F+v]UNv>+6^&vFv&&T>uA+Ѱ^>uA+Ѿ+>uA+V;tFv&@v&&Dv&<uv&<{t<[t<6vFuA+Ѱ>>uA+B+uA+ыA>v&<\t>66V+uA+Ѿ~uA+Av>uA+ы6vF+>uA+щVFN#t6^&8/u&\v&"u<.t&|.t}&|\tsvF6@;FrlFv&<\tN;u;uߺ+~uA+ыAvF~FNeF_v &&T+]U F#tyvvvFPFP%F#u[vvvv+~uA+RvvFV#u#t+~uA++Vv v vv]U YF#tpvvvFPFPF#uRvvvv+~uA+RvvFV#u#t+~uA++Vv]UF#tvvv FPFPF#tFPvv+~uA+RvvFV#u#t+~uA++VmmPF#tv vvFPFPF#uSvvv+~uA+RvvFV#u#t+~uA++VF#t v Fv ] SwFpEmulatorU>UuN #u3N F+؋F+}fFf+fv fff]^ VF"tĊ*ߊ*r #uP+RPv v Yv^;wu ;vI^ v ++ґ]Uv v vv֋]U>UudV V#}+ҋF V RPRv V1V#}+ҋFVRPRvFt+ʋFt+΋]fFff~ fff]Uv v vv#}^ v ֋]Uv v vv֓]U>Ut66ޣ6ޣ V@D}6ޣ\^FvF3&L&;OsBV#t^FvFvF^Fv&Dv&+DF=@&| t#~u6ޣ>ޣ ޣF#t Pvvv&D ^&:G u2PSvv"tkPvvv&L&DNv&| tPvvVDPvvvv"v&D v&| t PVhޣ~uv>ޣ66ޣK ]UPv v |,%GFA ~v F% F^wV.Cafaf{{v&&DNA&DN~v&Y]Uv&&T& D& T u+ v&D-?]Uv v |vv]Uv v vvq|]UnnormalInfinityDenormalUFFv vPPVR HtFFFF]UPv vvF]UP66vF]UF Fu+N+~uA+щVv v RPvvF N+;u;tFFF]UP66vvF66PPRHtFFY]Ud]U>Ut66ޣ6ޣ VgDK36ޣ&D &:DtB&T6ޣ&| t ޣ 6ޣ&D>ޣ6ޣ&|tޣ6ޣ V6ޣ&L6ޣ&|r66ޣ6ޣ&L6ޣ&|rV\PSPSt+6ޣ&L+&t++>@+v~ޣ#}6|FP66ޣ6ޣ&D>ޣ F6ޣ&D66ޣK ]UPv&D tFFFY]UPv&D tFFFY]Uv&d ] CDOS_ALLOC sysallocU>$t-"++FV|v6$"PF#t%$v"PF#t +$"F$FFV]sysfreeUvvF++ɾ+Q]allocated U]least_free_memoryU]UF0FdPFP6*~PP9]U츌P]HEAPMGMT - heap error # Aborting...)*** Cheap-heap linked in => no heap dump.U*>Ut66ޣ6ޣ VbDޣ6ޣ~6ޣ vF~u&| tޣ>ޣޣ3ҊFv&:D tBVF-?&D@FVFPFP\FNNFPZ~s~wv~~݀r'FFFFPFPFPv>ޣ66ޣK ]UP46*P9]Uޣࣹң+|ޣ ]Uޣ]UvvF&& D& D& Du+&D&D &D hv&|r &D~Hv&|s>VFv&L++| F&)DFv&+DPVv&D]#***Floating point stack overflow***Uv~ 3ۋN&CC] Uv~ 3ۋN&CC] Uv~ 3ۋN&CC] UvN 3ۋCC]U~3ɋE]u=u Ëދ3҃sArE]u]U~%UUU]U~m]]]U~N BE]ur֋3ss 3ɃE]u]U~%UUUUU U U]U! >UtvvD66ޣDvv66ޣL]U4t6&d 6&d 6&L @6&L @4t 6&d 6&L @]U/66 6vF&D &T VYY uȋ]U>Ut66ޣD-DFDB;u ;ޣuFAd6ޣ~FF~tN@=~u vuNN~uND ~rN%V* Љ⣒F]Uv&4FFVPv6̞ΞPPv]UAvvPM$@POl]U츢P]U6*P9]ː***Program aborted.******STACK/HEAP OVERFLOW***UBDFVNvB6D]˸;Du;Bt BBD>JJ% ãH.HÛ>FPF%A=@t=XÛÛÛ.2636&-6&-.:Л&=۾֋6&-6&-uܛ6G6GT6GV.TLLNˋܛ6G6_&6_&6_&?6_&/3tr@HÛ˻ >L.JLN˻>FFˋ6_&76_&'U~ UM]~tctgE ?uƀtE E Պϊ܊2҃t΀UM]]E E U~ ]MUu?||qĊߊ͊ցst F&E t΀ ~UM]]3333pxU.>v .>v.3ۋˋp#tx#tʡp#tz#t ڃr#tx#t ڃt#tx#t r#tz#t p#t|#t VQS3΋ޡv#tx#t t#tz#t r#t|#t p#t~#t v#tz#t t#t|#t r#t~#t v#t|#t ʃt#t~#t ʃv#t~#tWU.~EEEEu M ]] U 6ޣ ~6ޣޣv>ޣ]U>Ut 6ޣ&t 6ޣ&| u&t ]U]U>Ut 6ޣ&t 6ޣ&| u&t ]U>Ut 6ޣ&d  6ޣ&D ]U! 6ޣ >ޣ]U! >UtvvD66ޣDvv66ޣ]Uv .>v+؋U&.>u>u>u >u;.w rB;wr:>;>w0r >;>w$>)>>>. u*uu>u>tUL&r~&r&;.w rP;wrH>;>w>r >;>w2$u Ë3u L&&]+~& &]&E&u] ;.wr;r+. u uuvr;.wr;rPLrU>Ut66ޣ6ޣ VlD6ޣ&| t&|u6ޣ>ޣ  u+[6ޣ&D F&TV:u5 ~P66ޣFP"3:FtBVFFF*@]UPFFޣY]UF@FF;F}F]UFz~F s3F ꖍFPv|v򍄰P|FPq|n F~ uv~]?U>Ut66ޣDޣD66ޣmFVޣFV]U>Ut66ޣDޣvvD66ޣvvLޣ]Uv&4FFVPv]U6̞ΞPPv]U ! >UtvvHD66ޣDF3v&| vBV䣍~䣍~FFrv^&$v^&FFPv~FPFPPFPFPFFPFPFPF#vNoF>@v>ޣ66ޣK ]U.>Ut66ޣDvv:D6ޣ~F-?F~t v&D v&D ~?~FFFFv^&@ sFF#}Z=?~R?+RFPv~F Fu~ u~wFFFԈFF~t1F FuFV FҋF+VًF+҉FVF Fu F FuFFFvFڋV+ҋJ+ ؉Nډ^ u +FىB+vFڋVܹ B+PQvvښFډV܈FًF#vN럍v~FrF*䖊F^&F*䖊Fٱ^&F<sFޣ]UF V 2~tDtHE ?]ƀtE E Ԋ2t΀UE3E]E E U~EU]?|I=Ċ֊t€t C2E t΀ ]333UP]&Cheap stack dump linked in => no dump.U^ &GF&GFv FPFPF ue~uF:FwSF*F1F~uF:Fw2F*F1FFFFNNN8Fr8Nsw ^ &GFFFF:FsFFF8Fw^ v^F&N&WVv PFPQRFFt4v FPFP^GPFPFFN+v FPFP^&wFPFF@FF u9FFGFt,F ^ &GF^ &GF^ &G^ SV] U^&ux^&GF&GF&ON&GF&GF&GFNF:FsFFF8Fw^v^F&N&ONVRPFPPQFFPFPFPPFPF u;FtFNF@FFFnFtS^&G]UQ^S^SvvF^SP^Sv^ S^S]UQ^S^SvvF^SP^ Sv ^S]UQ^S^ SvvF^SPy] UQQ^&G FFF;Fs^SPyP(F]UQ^S^ Sv vF^SPvW]UQ^S^Svv F^SP^SvA]U^&G FFF;Fst^&G FF&|^AFFv&t^&FN;u.^ S^SQu^&G t &G;FuFF넸] U~uy&F^&G FF^&ux^&GF&Ov& N^&W&TV&_^PQRfPSP(f&UNt+Ju0^&Gu%&O N^v&t 0fdfPFP^Sv^ S^SPl ]U~uy&F^&G FF^&ux^&GF&Gv&F^&G&DF&GFbQP^ SF PFP^SPl F uHNF;v+ȋb&UFPFPFPbPFPP(]U ~uy&F^&G FF^&ux^&GF&Ov& N^&W&TV&GF&Gt1&G FFPQR&t ^PFPP(FFPNFȵQNQ6&UN*ȵQP(]U~uy&F^ &G FF^ &ux^ &GF&Gv&F^ &G&DF&GFFA;rQrFa;r qs)N7FStsu^&G%FUtuu ^&G%FFPFPFPvFP]U~ uyF ^&G XZ\ĞX&\&G^&G`&G% u@b&G%@ u@d&G% u@f&Wꉖh&Ojs*&wVF^_&ƉV&l&@nĞX&G z&O ^ĶX&t 0|P\~N] U~.u+JVt2~:Nu+JVuFF)F^^&?tdF@NFN&^;uQP~WStNF;v.^PR@+QFPPFPP F tpF^&FNFNFsFNFN^Sv^Sv^ Sv^&S^&FNFN!z]U~ t{~&UNt+JVuFFFF9Fv8^&:&Ut*0rJ9wEF ^v&0FFN+N^v8&Ut+JVt|F^&^&]UFPFPLF uq~ r-FPvv ^SvRPPFF t=>FF9Fv.NQNQN Q^PF uFʸ] UFPFPLF u~ sUPPFP/F um^&G :Fw\F^X ^F&G^ &^&G(FPFPFPGF uF^ &F^&] U~u8vv vlPvF uvv vlPvF] UvFPN Q{)RPQ^SvB(U u^&;Fvv]U(UNdždždžP(Uu^PF8Fu]UQ^ PPF^ v&>(UuP^SFPsFFѰ]U^ PDFFFF:Fw>(Ut^ PDFNs N^;st^&V*uF&>)F)u+JVt )&F>)F)u+JVt )&FF:FtFFLFFF^;s^&8*u& Fs F^F]UQQF>(UuV^ PP^ PD:F u3^ PF^ PD:Fu^ PD:FuFF룰]U>(Ut^PF(UuP^SFPF^PFNr"^PDF뷀~u(Utn] UQQ>(Uus^PF(UuPDFVN;w^ ;v +ʋ^ &FË] U^ G F^GWFVvFPFPFPFP^ PFYFVRP^ PDFF~%sg^v&8u &%tT1^v&ÉFPv!s^F@F؋]FFFF%;r)N듋FFFN;w)NGU^FNFFFFF~tP^ F^ NV´3ЉVVŠ^3ӉVV3ӉVV3‰FNFN몋F16*U^ F%1^F16*U^ F1^^ ?u^?u] U^ G^ GN~+^ O]UQQ^^:t^FFuȈF^@>))u+JVtS)&[@^F@>))u+JVtS)&[@^FH^:Hun]UQ>(UtT^tP ^G ^PDF^P^G~u^P ^GF]U>(Ut}^G FGF;r>OW^7G PQwwFP#(Uu(Uu^GF^vFFv^w^O^FG F]UQ^PDF^PDFF]UQ^t>(Uu PDFz)s^G t >(Uu(Uu]U)&>))u+J,U)&>))u+J.U>,Uu)&>))u+J,U>.Uu)&>))u+J.U0U]UQQ0Ur~&UNt+JVt_^v&F)&8t%)&:Ft8)6,UF&8t )&8uF$)6.UF&8t )&8uF|F~N F ^&]U^&s)FF) )FF)FF;FsFv~N^YF^&]UQFFN ;sNv~N^YN F;v+^8&U~&UN OuIA^&]UQF FN;sNv~N^YF^&]UQ^S^SvvF^SP^ S^Sc]U4FFP5F u ~u]U~uy&F^&G FF^&ux^&GF&Ov& N^&W&TV&GF&_^FPQRSFPP(^ &NFNNFRQPFP F u^&?v&GDQP7P(Q$u@RƆOFPFPFPF tFPFȴPFPFF uNP5F tƆMRP PFPF u^슆N&@ NEPN:DuOrƆOPOr PvƆOF:FrKRr^FPFȴPFPLPP(L tFPFPFPNQN*ɵQAP(FPFPFPNPP(FNNF@tJ:NrEƆN^&GNu F:Fs}NuF:FsFjNuFF[NuWFPFPFPSPFPP(S NOuIFAN:NuNNu#F:FrFȈF犎RrۊNQNucFF:FwFPFPPFPN*NɵQAP(FPFȴPFP PPP(8NUt'~tv &*U v &*U&4v &^&~tv &UPfs ^&4] U^ &u ^&2^S^ ScUP\U ucUs ^&^&] ^&FFFF^&GHN;rZ^&F< uF?Fs8F^ S^&S^vP^&wFPF~uFu FV;TUu;RUt^SsF tebUr@JUGFFFFF9Fw Nr^PFP8FFuVN+;sVFFF;FvFsFs@^v&`*طS^ &*ط^!*[:!*uFF FF)FF^v&^ &:u~u ^PFFFFF)F^S^v&Z[&S^ &[&:uFFFs ^&F^S^ Sv^&bU^SjJUPF=4t=4uF~t@bUFVRUTUU^&?u"^&G<`rU@UBU*DUFUHU^Sj FPF=4t=4uFF~u0^&GBUO>U@U^&HHU@DUFUFVNUPUUdUPj<]~F^ &^S}*PvFP<F uFt^ &FFF~NuV~u ^&P ~u^&7UP^ S~u8^&w&7UP^ SUF^~Hu2Ft tuS^SvUP^ SUF^~Du_~uFPF~u^&&WFV, PRPvvvUPj ^ STFUF^^S^ &7^Svv^SFUdUPjFF@^&*^+vN FYF ^&7^&:^&8^S~<s 9Fw9Fw 9Fw9F vF~t:^&Ƈ{^v NFY^v&ƀ}FFF~tC^v&ƀ[^vvNFYvv^&ƀ]FFF^v&ƀFF@^&*^+vN FYF ^&7^&:^&8^S^&8&8uSoF tb^&8F&^ &^v@^&Z&WF^ &@F^0~^YF^&8^&8rM^P^&*P+P^&7P&:SF u^&LJ8^&:FU^SvP]ULFs+PPFP/F u,^&!t@FF^ &FP$ F usFFFFFNNFF @FF^F FsFs PFP  FPF~u[vFPF tF;FtFF u$ 8FvFF^ &ȍvF!uFFFΈFψFбNѴFҋVVԉFF.F FڌF܋FFލFF^NFsFs PFP  FPF~uGvFPF u6F;Ft )F։F u F^ &~!t FtFF] LIBRARY: ctos.lib VERSION: R12.3.1 (friday november 12, 1993, 15:10) LIBRARY: ctostoolkit.lib VERSION: R12.3.0 (friday october 15, 1993, 17:26) LIBRARY: hcbe.lib VERSION: 1.0 (Wednesday November 2, 1988, 16:31) LIBRARY: forms.lib VERSION: s9.1.2 (Freitag Februar 2, 1990, 16:44) LIBRARY: enls.lib VERSION: R12.3.0 (friday october 15, 1993, 17:28) LIBRARY: Kct.lib VERSION: R12.3.1 (friday november 12, 1993, 16:48) COPYRIGHT (C) 1980, 1993 CONVERGENT TECHNOLOGIES, INC. ALL RIGHTS RESERVED. COPYRIGHT (C) 1980, 1993 UNISYS CORPORATION. ALL RIGHTS RESERVED. THIS SOFTWARE IS PROPRIETARY TO CONVERGENT TECHNOLOGIES, INC. AND UNISYS CORPORATION AND IS NOT TO BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS CORPORATION. THIS PROGRAM IS FURNISHED UNDER A LICENSE RESTRICTING ITS USE SOLELY FOR THE OPERATION OF A DESIGNATED COMPUTER FOR A PARTICULAR PURPOSE. TITLE TO AND OWNERSHIP OF THE PROGRAM, INCLUDING ITS SOURCE CODE, SHALL AT ALL TIMES REMAIN IN THE NAMES OF UNISYS CORPORATION AND CONVERGENT TECHNOLOGIES, INCORPORATED. VERSION: R12.3.1 (friday november 12, 1993, 16:47)mJ<xB~A(0DJKm h ,j 9 E C 3W + G   4 .C Cq < M O= M Ij"qsmp? j!A"E#j $zv%~&in'(G)s*KI+H,B--.LK/A0H16 2=V3-4H56678B9:H;d<7=8>9?:@;A<B=C>D?E!@F7aGJH3IEJ7ZKuLAM<GNOaPPvQzR@SDT4 U}9 V W07!Xg!YK!ZB"[ #\#]#^#_#`24#a2f#bB#c#d$e$f $gi$hB%iG%jW%ki%l%m3%n%o%p%q%r&s#&t8&uP&vj&wx&x&y&z&{&| &} &~&&''/,' [' f']o'K'[(Ar([(f)|t)p)#`*k*d*cR+k+s ,,g+-x-y ../`/7/*"0-L0y000+1-11E2)U2+~22"[38}3#3+3 4;42J4|4356585V5-t55.6 777 97F7'T7){7'7V7!88&86^888888888888Select ERROR %5u: Bad "Default Condition" format: missing a "}". ERROR %5u: Bad "Default Condition" format: missing a"{". ERROR %5u: Multibyte string did not have a pair terminator or did not have a pair where expected in string at %s. ERROR %5u: End of file reached. ERROR %5u: Occured during read of file. ERROR %5u: Abnormal end of %s data ERROR %5u: Invalid "Repeat Attribute" in entry %2Xh; used "None". ERROR %5u: Error reading translation table widths - processing cannot continue. ERROR %5u: Value is out of range; it must be between 0h and 0Fh inclusive. ERROR %5u: The %s type was missing. ERROR %5u: End of file encountered unexpectedly. ERROR %5u: End of file encountered while reading forms data. ERROR %5u: Error encountered while trying to open file %s. ERROR %5u: Could not allocate data buffer. ERROR %5u: Could not load form %s. ERROR %5u: Nonumeric data found when looking for numeric data. ERROR %5u: Data read specifies %d entries which is too much; the maximum value allowed %d was used instead. ERROR %5u: Data read specifies %d entries which is too small; the minimum value allowed %d was used instead. ERROR %5u: Bad table signature encountered. ERROR %5u: Main table does not exist. ERROR %5u: Bad IBus ID read from sys.keys file; it was %X. ERROR %5u: Must enter file name in command form!!!! ERROR %5u: Internal error, call to \"malloc\" returned NULL pointer. ERROR %5u: Internal error, call to \"realloc\" passed in NULL pointer. ERROR %5u: First line of special keys short of data; it needs FOUR (or FIVE for emulation) entries which are: Number of keys, IBus ID, Key up mask, Number of translation or emulation tables specified and, for emulation, the target keyboard. ERROR %5u: Too many keys up in multibyte (or key up mask bogus). ERROR %5u: Hardware iKey for a chord is too large or invalid; entry ignored. ERROR %5u: Chord bit Mask out of range (must be between 0h and 0fh); entry ignored. ERROR %5u: Data field that requires a "T" or a "F" had some other entry; "F" assumed. ERROR %5u: Internal error, attempting to access a nonexistent chord data block. ERROR %5u: Bad trans table width encountered; used %d. ERROR %5u: No width should be specified for emulation tables; width ignored. ERROR %5u: Trans table width entry missing, used 1 byte. ERROR %5u: Repeat delay and rate codes must be 0, 1, 2 or 3. ERROR %5u: Allowed states entry # %2Xh not enclosed in brackets as required. ERROR %5u: Non-recognizable string in bit set fields of repeat attribute # %2Xh; no bit set. ERROR %5u: Non-numeric string encountered while converting data within brackets; string ignored. ERROR %5u: At least one of the chord numbers in the brackets is too large. ERROR %5u: Invalid format in translation/emulation table; the format should be "Sz:nn" with no white space before or after the colon. ERROR %5u: Multibyte string pair # %d not formatted correctly. ERROR %5u: Entry in translation or emulation table missing; what is there is "Sz: ". ERROR %5u: Entry in translation or emulation table is not numeric. ERROR %5u: Entry in emulation table invalid; missing part # %d. ERROR %5u: Table ID in condition definition out of range. ERROR %5u: No Table ID in condition. ERROR %5u: Table ID in diacritic definition pair # %d out of range. ERROR %5u: Data in diacritic definition pair is invalid. ERROR %5u: Missing Keyboard name, obj file name or PUBLIC name. ERROR %5u: No valid data found in input file. ERROR %5u: Internal error, bad table size specified. ERROR %5u: Null pointer encountered. ERROR %5u: Unrecognisable action or funtion key value returned. ERROR %5u: \"Malloc\" returned null pointer while trying to allocate more area for wild card routine file name buffer. ERROR %5u: Too many file names in directory. ERROR %5u: Condition definition has more than three OR-States (ie. the data enclosed in braces); only the first three are used. ERROR %5u: Empty multibyte string encountered (ie. "{}"). ERROR %5u: Multibyte state/key pair with extra data (ie. x:y:z rather than x:y the correct format). ERROR %5u: Index into multibyte table in translation/emulation table has a value of %d which is out of range. ERROR %5u: Entry for diacritic does not match any diacritic specified. ERROR: There is NO directory %s!! ERROR: A NUMBER must be entered in this field. ERROR: Chord ID too large; it must be LESS than or EQUAL to %2Xh. ERROR: Chord ID same as one already shown. When processing input file line %lu (decimal). ERROR: A number MUST be entered in this field. ERROR: This is NOT a chord so you cannot modify it; to make it a chord press the \"Add Chord\" function key. ERROR: This key alreadt IS a chord so you cannot add it. ERROR: This is NOT a chord so you cannot delete it. ERROR: The only acceptable entries in the highlighted field are \"y\" (or \"Y\"), \"n\" (or \"N\") or blank which is equivalent to \"n\". ERROR: This chord position index is already used in the chord whose hardware iKey is %d.Multibyte string specifies push down or up of key already\n\t\tin that position.Multibyte string pair specifies the pushing down or releasing\n\t\tof a key already pushed down or released, respectively.1A \"y\" entered in more than one repeat attribute field. Do you want the repeat attribute CHANGED to reflect this latest entry?0Character entered is invalid; it must be either a \"y\" or a \"n\".0Character entered is invalid; it must be a numeral.0There is no chord coresponding to the number just entered; use a number from the right hand column in the table on the left.0Need to get more data before exiting menu. Try pressing \"F6\" rather than \"F4\" once you get back to the menu under this one.Your keyboard not supported by this application.Only one of these fields can have a \"y\" (or a \"Y\") in it. Delete the \"Y\" in the other field before entering a \"y\" in the current field.\nCannot create untranslation table for tables greater than 2 bytes wide.\nCannot create emulation table because count of emulation chord keys does not match the count of translation chord keys. Press "F8" to create only the translation table, "F3" to skip creating any table. RtLeftRightLeftMAKE & MULTI BYTE STRINGASSIGN REPEAT & ALLOWED STATES ATTRIBUTES TO A KEYIDENTIFY SETS OF CHORD KEYS THAT SELECT THIS TABLEIDENTIFY SETS OF CHORD KEYS THAT SELECT SECOND PART OF DIACRITICALMove the cursor to the key that is to be the second of the diacritic pair. Then press \"F7\" to display the menu that will allow you to select the chords for this second key.QueryError.kbd_data Extra data present; processing CAN continue; extra data will be ignored. Too little data; processing can NOT safely continue.END SPECIAL KEYSSTART SPECIAL KEYSEND LED EMULATION DATASTART LED EMULATION DATACount of LED data entries is %s, an invalid number.END CHORDS KEYSSTART CHORDS KEYSEND CONTROL CHORDSSTART CONTROL CHORDSEND RPT ATTRS TABLESTART RPT ATTRS TABLEEND ALLOWED STATES TABLESTART ALLOWED STATES TABLEEND CONDITIONSSTART CONDITIONSEND DIACRITICSSTART DIACRITICSEND MULTIBYTESSTART MULTIBYTESEND TABLESSTART TABLESEND HOT KEYS TABLESTART HOT KEYS TABLEEMULATION DATA EXISTSTRANSLATION DATA EXISTSF1|F2|F3|F4|F5|F6|F7|F8|F9|F10|Title|Text|Resp|TRANSLATIONEMULATION Exit||Change|Confirm|||Select| More||||| Dir| Dir||| File|Files|||SELECT KEYBOARD DATA FILE|Finish|| Show|| Trans|||Chose|| Save|||Values||Tables|||Chords|||MAIN MENU|Finish|| Exit|||Delete|Modify| Add|| Save||| Menu|||Chord|Chord|Chord|||SELECT A CHORD KEY|Finish||Return|||Return|||| Save|||NoSave||| Save|||||ENTER DATA|Finish|| Exit|| Prev|| Next||| Save||| Menu||Table||Table||||SHOW TRANSLATION TABLE VALUES|Finish|Delete| Exit||Modify||Modify|Modify|| Save||Table| Menu||Cond's||Attrs|Tables|||MODIFY % TABLE|Finish|Delete| Exit|Modify| Add|| Next| Prev| Show| Save||Cond'n| Menu|Cond'n|Cond'n||Cond'n|Cond'n| Kbd||VIEW % CONDITIONS|Finish|| Exit||Modify||Allowd||| Save||| Menu||Repeat||States||||SELECT A KEY TO HAVE ITS ATTRIBUTE(S) MODIFIED|SELECT ONE OF THE REPEAT ATTRIBUTESFinish|| Exit|Modify| Add|Resize| Next| Prev|| Save||| Menu|Table|Table|Table|Table|Table|||SELECT % TABLE|Finish|| Exit||Modify||Start|Start|| Save||| Menu||Return||Diacrt|MultBy|||MODIFY TRANSLATION TABLE|Finish||Return|Select| Copy|Return|Enter||| Save|||NoSave|Cond'n|Shown| Save|Values||||ADD % TABLE|Finish||Return|||Return|Select|Select|Start| Save|||NoSave||| Save| Pair|Output| Over||HANDLE % DIACRITICS|Finish|Delete| Exit|Modify| Add|| Next| Prev|| Save||Diacrt| Menu|Diacrt|Diacrt||Diacrt|Diacrt|||VIEW % DIACRITICS|Finish||Return|Start|Select|Return| Next| Prev|| Save|||NoSave| Over|Key| Save|Table|Table|||SELECT TABLE IN WHICH SECOND KEY OF % DIACRITIC PAIR FOUND|Finish||Return||Specfy|Return||Start|| Save|||NoSave|| Data| Save||MultBy|||SPECIFY % DIACRITIC OUTPUT|Finish|| Exit|Modify| Add|| Next| Prev|| Save||| Menu|MultBy|MultBy|||MultBy|MultBy||VIEW EXISTING % MULTI BYTE STRINGS|Finish| Undo|Return|Delete||Return|Create|Rewrap| Save| Save||| NoSave| Pair|| Save| Pair|| Edit||EDIT MULTI BYTE STRING|Finish| Undo|Return|Delete|Cancel|Return|Create|Rewrap| Save| Save||| NoSave| Pair|Shown| Save| Pair|| Edit||ADD % MULTI BYTE STRING| None| .obj| .tbl|Update||.obj +|.tbl +|.obj +||All|| Only| Only| Only|| .tbl|Update|Update||Files|TYPE(S) OF FILES TO BE PRODUCED| Exit|| Edit|| Only|| Only|| All||NoSave||Above||Trans||Emultn|| Data||TYPE OF DATA TO GO IN %s|||Cont-|||||||||| inue||||||||ENTER OBJECT MODULE NAME|Finish||Cont-||||||| Save||| inue|||||||||||Cancel|||||Confrm|||||Action|||||Action||||Chord|Numbrs|Chord|Names|<>WARNING: If you delete this condition, the table it points to will also be deleted as well as all diacritics and multibyte strings that contain references to that table.\nTo confirm that you wish to delete this condition press \"F7\"; to deny press \"F2\".Current return value for this key (in hex):Enter new return value for this key (in hex):PRESS A FUNCTION KEY.MOVE CURSOR (ie. HIGHLIGHT) TO THE KEY WHOSE DATA YOU WISH TO MODIFY.Current number of bytes in a table entry:Enter new number of bytes in a table entry:If the requested reduction in the number of bytes in each table entry occurs, some data will be truncated. To confirm that this should occur press \"F7\"; to deny press \"F2\". Table being shown is number %dSELECT TABLE IN WHICH SECOND KEY OF DIACRITIC PAIR FOUNDSELECT SECOND KEY OF DIACRITIC PAIREnter hex value to by returned by diacriticOther|Chords The highlighted key is not the start of any diacritics.Table #1|Key #1|Table #2|Key #2|MultiByte?|Output|Output file name|Type keyboard modified|Include Untranslate Table ?|PUBLIC in object module|Create object module|Create raw table|Update base text file|DEFAULTS FOR OBJECT MODULE FILEyesnoAttribute Characteristics FastAttribute Characteristics SlowFast|Slow|None|SetUserBit|DosAltBit|Set_nBit|The file to which you wish to write already exists. Press "F8" to confirm that this file should be overwritten, "F3" to prevent overwriting.Some or all of the translation tables have entries greater than one byte. This data will be truncated if the untranslation table is created. Press "F8" to create the untranslation table anyway, "F3" to omit this table.done.in %s table data Processing of %s . . .OBJECT MODULERAW TABLE FILE File %s: line %d\n\n ==== Translation Table Data ==== ==== Emulation Table Data ==== NOTE: Following string had only partial match, "%s". WIDTH NOTIFICATION: No translation data found. NOTIFICATION: No emulation data found. TEXT TABLE FILEText File Name Index, %d, out of range COPYRIGHT (C) 1980, 1993 CONVERGENT TECHNOLOGIES, INC. ALL RIGHTS RESERVED. COPYRIGHT (C) 1980, 1993 UNISYS CORPORATION. ALL RIGHTS RESERVED. THIS SOFTWARE IS PROPRIETARY TO CONVERGENT TECHNOLOGIES, INC. AND UNISYS CORPORATION AND IS NOT TO BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS CORPORATION. THIS PROGRAM IS FURNISHED UNDER A LICENSE RESTRICTING ITS USE SOLELY FOR THE OPERATION OF A DESIGNATED COMPUTER FOR A PARTICULAR PURPOSE. TITLE TO AND OWNERSHIP OF THE PROGRAM, INCLUDING ITS SOURCE CODE, SHALL AT ALL TIMES REMAIN IN THE NAMES OF UNISYS CORPORATION AND CONVERGENT TECHNOLOGIES, INCORPORATED. VERSION: x12.3.0/Beta-I (tuesday july 6, 1993, 13:48)/***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* K1.kbd_data */ /* */ /* This file contains the K1 translation table. */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION */ /* */ /* 08/24/93 12.3.E.02 S. Ahn / reverse the changes in 122SDV.04, to */ /* accommodate CODE-SHIFT-Alpha. */ /* Shift key should not affect non-Alpha */ /* keys. */ /* 09/23/92 12.3.A.01 V. Miller / Actually put 122SDV.4 in. */ /* */ /* 06/29/92 122SDV.04 V. Miller / now included with both */ /* shift keys in orState in condition */ /* with code keys instead of being */ /* handled separately to more closely */ /* emulate the conditions before CTOS II */ /* 3.3. */ /* 03/20/92 12.2.G.03 V. Miller / Changed so second (from the */ /* SG-102-K keyboard) is passed through. */ /* Meant adding a second alt key which */ /* I called as iKey "55h". Had */ /* to update Allowed State Table. */ /* Changed Conditions Table so */ /* selects same table as . */ /* 03/17/92 12.2.G.02 V. Miller / Added comments and change number of */ /* of emulated LEDs from 3 to 16. */ /* 02/17/92 12.2.F.01 V. Miller / Changed so is passed through */ /* Meant adding an alt key, , as */ /* iKey "53h" to match value on the K5 */ /* keyboard. Updated Allowed State Table */ /* and changed Conditions Table so */ /* selects same table as . */ /* Val Miller / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; ; This is the data file for the K1 Keyboard that is used by the "Create ; Keyboard Table" Application. The format is translation tables for a ; K1 keyboard. ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; ; Changes: ; ; 11/14/91 vjm Removed emulation of to be for XVT ; All allowed states with {..,3,4..} changed to {..,3,4..,6}. ; Two new conditions added "{6} {} {}" and ; "{6} {1,2,3,4,5} {}" which select table 3 the same ; table selected by {1,2} {3.4} {}, the CODE-SHIFT ; condition. ; Keyboard name K1 ; Output file name K1KbdTables.obj ; Name of PUBLIC in object module at start of table KeyBoardData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ; TRANSLATION DATA ; ; TRANSLATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if translation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of translation tables in decimal ; | | | | ; 80 04 80 4 ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have at least 19 and at most 29entries and they MUST ; be in the order shown. 22 ; Number special keys in decimal 61 ; a 62 ; b 7F ; 44 ; 4C ; 4D ; 04 ; 43 ; 45 ; 48 ; 49 ; 64 ; Mouse Disable 65 ; Mouse Enable 53 ; 00 ; c 1B ; 40 ; iKey not valid 20 ; Diacritic Escape 00 ; Sys Key If there is no key use an iKey that is ; not produced by the keyboard in question OR 00 ; NOTE that the help key can not be used as the ; system key since it is '00' 00 ; OS1 00 ; OS2 00 ; OS3 END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for a translation table. ; 7 ; Number of entries ; ; !!! ALL NUMBERS IN THE FOLLOWING TABLE MUST BE IN HEX ; ; key bMask* fToggle fLed LED mask** ; number bit bit fExclus- ; position position ionary ; (hex) (hex) (hex) ; 48 0 F F 0 F ; Chord #1 49 1 F F 0 F ; Chord #2 4C 2 F F 0 F ; Chord #3 4D 3 F F 0 F ; Chord #4 45 4 T T 6 F ; Chord #5 53 5 F F 0 F ; Chord #6 55 6 F F 0 F ; Chord #7 ; * NOTES: bMask bit position ; ; 1. The number of the bit set (to 1) in the bMask word for this ; chord where "0" means the least significant bit and "15" ; means the most significant bit. ; ; 2. The values for bMask are NOT required to be consecutive. ; ; ** NOTE: there MUST be an entry for "LED mask bit position" even if the ; "fLED" entry is "F"; it can be zero. END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START CONTROL CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. 8 ; Number of entries 00 ; escState 00 ; escState2 00 ; noDiacrit 00 ; noRepeat 0C ; status4 00 ; status2 03 ; status1 10 ; altStatus1 END CONTROL CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START RPT ATTRS TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; The following entries for FAST and SLOW attribute characteristics are ; optional. You can have both none or one of them. The allowable codes ; are: ; ; Delay until repeating starts codes: 1 - 0.2 seconds ; 2 - 0.4 seconds ; 3 - 0.7 seconds ; ; Frequency of repetition codes: 0 - 1 character / second ; 1 - 10 character / second ; 2 - 20 character / second ; 3 - 30 character / second ; ; If no entry is made a default will be shown. The dafaults are: ; ; Delay Until Frequency Of ; Repeating Repeating ; Starts Code Code ; ; Attribute Characteristics Fast 2 3 ; ; Attribute Characteristics Slow 3 2 ; ; ENTRIES ; ---------------------------------------------------- ; Repeat iKey Key ; Attribute Number Name ; --------- ------ --------- None ; 000 help Fast ; 001 up-arrow None ; 002 mark None ; 003 bound None ; 004 finish None ; 005 prev page Slow ; 006 1/2-1/4 None ; 007 cancel Slow ; 008 backspace None ; 009 tab Slow ; 00A return Fast ; 00B down-arrow None ; 00C next page Slow ; 00D next Fast ; 00E left-arrow Fast ; 00F right-arrow None ; 010 SH-L Slow ; 011 scroll-up None ; 012 move Slow ; 013 scroll-down None ; 014 copy None ; 015 f1 None ; 016 f2 None ; 017 f3 None ; 018 f4 None ; 019 f5 None ; 01A f6 None ; 01B GO None ; 01C f7 None ; 01D f8 None ; 01E f9 None ; 01F f10 Slow ; 020 space Slow ; 021 9 9 None ; 022 SH-R None ; 023 0 None ; 024 NEXT None ; 025 None ; 026 Slow ; 027 ' " None ; 028 None ; 029 None ; 02A Slow ; 02B + = Slow ; 02C , , Slow ; 02D - _ Slow ; 02E . . Slow ; 02F / ? Slow ; 030 0 right parens Slow ; 031 1 ! Slow ; 032 2 @ Slow ; 033 3 # Slow ; 034 4 $ Slow ; 035 5 percent Slow ; 036 6 cent Slow ; 037 7 & Slow ; 038 8 * Slow ; 039 9 left parens None ; 03A Slow ; 03B None ; 03C None ; 03D None ; 03E None ; 03F iKeyInvalid None ; 040 iKeyNoKeys Slow ; 041 6 6 Slow ; 042 - - None ; 043 reset None ; 044 overtype None ; 045 lock Slow ; 046 2 2 Slow ; 047 3 3 None ; 048 shift-r None ; 049 shift-l Slow ; 04A 0 0 Slow ; 04B . . None ; 04C code-r None ; 04D code-l None ; 04E None ; 04F None ; 050 None ; 051 None ; 052 sys None ; 053 alt None ; 054 None ; 055 None ; 056 None ; 057 None ; 058 None ; 059 None ; 05A Slow ; 05B [ < Slow ; 05C 7 | Slow ; 05D ] > Slow ; 05E ^ ~ None ; 05F Slow ; 060 1 ` Slow ; 061 a A Slow ; 062 b B Slow ; 063 c C Slow ; 064 d D Slow ; 065 e E Slow ; 066 f F Slow ; 067 g G Slow ; 068 h H Slow ; 069 i I Slow ; 06A j J Slow ; 06B k K Slow ; 06C l L Slow ; 06D m M Slow ; 06E n N Slow ; 06F o O Slow ; 070 p P Slow ; 071 q Q Slow ; 072 r R Slow ; 073 s S Slow ; 074 t T Slow ; 075 u U Slow ; 076 v V Slow ; 077 w W Slow ; 078 x X Slow ; 079 y Y Slow ; 07A z Z Slow ; 07B 4 { Slow ; 07C 8 backslash Slow ; 07D 5 } None ; 07E Slow ; 07F del END RPT ATTRS TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; ------------------ ------ --------- { 1,2,3,4,6,7 } ; 000 help { 1,2,3,4,6,7 } ; 001 up-arrow { 1,2,3,4,6,7 } ; 002 mark { 1,2,3,4,6,7 } ; 003 bound { 1,2,3,4,6,7 } ; 004 finish { 1,2,3,4,6,7 } ; 005 prev page { 1,2,3,4,6,7 } ; 006 1/2-1/4 { 1,2,3,4,6,7 } ; 007 cancel { 1,2,3,4,6,7 } ; 008 backspace { 1,2,3,4,6,7 } ; 009 tab { 1,2,3,4,6,7 } ; 00A return { 1,2,3,4,6,7 } ; 00B down-arrow { 1,2,3,4,6,7 } ; 00C next page { 1,2,3,4,6,7 } ; 00D next { 1,2,3,4,6,7 } ; 00E left-arrow { 1,2,3,4,6,7 } ; 00F right-arrow { 0 } ; 010 SH-L { 1,2,3,4,6,7 } ; 011 scroll-up { 1,2,3,4,6,7 } ; 012 move { 1,2,3,4,6,7 } ; 013 scroll-down { 1,2,3,4,6,7 } ; 014 copy { 1,2,3,4,6,7 } ; 015 f1 { 1,2,3,4,6,7 } ; 016 f2 { 1,2,3,4,6,7 } ; 017 f3 { 1,2,3,4,6,7 } ; 018 f4 { 1,2,3,4,6,7 } ; 019 f5 { 1,2,3,4,6,7 } ; 01A f6 { 1,2,3,4,6,7 } ; 01B GO { 1,2,3,4,6,7 } ; 01C f7 { 1,2,3,4,6,7 } ; 01D f8 { 1,2,3,4,6,7 } ; 01E f9 { 1,2,3,4,6,7 } ; 01F f10 { 1,2,3,4,6,7 } ; 020 space { 1,2,3,4,6,7 } ; 021 9 9 { 0 } ; 022 SH-R { 0 } ; 023 0 { 0 } ; 024 NEXT { 0 } ; 025 { 0 } ; 026 { 1,2,3,4,6,7 } ; 027 ' " { 0 } ; 028 { 0 } ; 029 { 0 } ; 02A { 1,2,3,4,6,7 } ; 02B + = { 1,2,3,4,6,7 } ; 02C , , { 1,2,3,4,6,7 } ; 02D - _ { 1,2,3,4,6,7 } ; 02E . . { 1,2,3,4,6,7 } ; 02F / ? { 1,2,3,4,6,7 } ; 030 0 right parens { 1,2,3,4,6,7 } ; 031 1 ! { 1,2,3,4,6,7 } ; 032 2 @ { 1,2,3,4,6,7 } ; 033 3 # { 1,2,3,4,6,7 } ; 034 4 $ { 1,2,3,4,6,7 } ; 035 5 percent { 1,2,3,4,6,7 } ; 036 6 cent { 1,2,3,4,6,7 } ; 037 7 & { 1,2,3,4,6,7 } ; 038 8 * { 1,2,3,4,6,7 } ; 039 9 left parens { 0 } ; 03A { 1,2,3,4,6,7 } ; 03B { 0 } ; 03C { 0 } ; 03D { 0 } ; 03E { 0 } ; 03F iKeyInvalid { 0 } ; 040 iKeyNoKeys { 1,2,3,4,6,7 } ; 041 6 6 { 1,2,3,4,6,7 } ; 042 - - { 0 } ; 043 reset { 1,2,3,4,6,7 } ; 044 overtype { 5 } ; 045 lock { 1,2,3,4,6,7 } ; 046 2 2 { 1,2,3,4,6,7 } ; 047 3 3 { 1 } ; 048 shift-r { 2 } ; 049 shift-l { 1,2,3,4,6,7 } ; 04A 0 0 { 1,2,3,4,6,7 } ; 04B . . { 3 } ; 04C code-r { 4 } ; 04D code-l { 0 } ; 04E { 0 } ; 04F { 0 } ; 050 { 0 } ; 051 { 0 } ; 052 { 6 } ; 053 { 0 } ; 054 { 7 } ; 055 { 0 } ; 056 { 0 } ; 057 { 0 } ; 058 { 0 } ; 059 { 0 } ; 05A { 1,2,3,4,6,7 } ; 05B [ < { 1,2,3,4,6,7 } ; 05C 7 | { 1,2,3,4,6,7 } ; 05D ] > { 1,2,3,4,6,7 } ; 05E ^ ~ { 0 } ; 05F { 1,2,3,4,6,7 } ; 060 1 ` { 1,2,3,4,5,6,7 } ; 061 a A { 1,2,3,4,5,6,7 } ; 062 b B { 1,2,3,4,5,6,7 } ; 063 c C { 1,2,3,4,5,6,7 } ; 064 d D { 1,2,3,4,5,6,7 } ; 065 e E { 1,2,3,4,5,6,7 } ; 066 f F { 1,2,3,4,5,6,7 } ; 067 g G { 1,2,3,4,5,6,7 } ; 068 h H { 1,2,3,4,5,6,7 } ; 069 i I { 1,2,3,4,5,6,7 } ; 06A j J { 1,2,3,4,5,6,7 } ; 06B k K { 1,2,3,4,5,6,7 } ; 06C l L { 1,2,3,4,5,6,7 } ; 06D m M { 1,2,3,4,5,6,7 } ; 06E n N { 1,2,3,4,5,6,7 } ; 06F o O { 1,2,3,4,5,6,7 } ; 070 p P { 1,2,3,4,5,6,7 } ; 071 q Q { 1,2,3,4,5,6,7 } ; 072 r R { 1,2,3,4,5,6,7 } ; 073 s S { 1,2,3,4,5,6,7 } ; 074 t T { 1,2,3,4,5,6,7 } ; 075 u U { 1,2,3,4,5,6,7 } ; 076 v V { 1,2,3,4,5,6,7 } ; 077 w W { 1,2,3,4,5,6,7 } ; 078 x X { 1,2,3,4,5,6,7 } ; 079 y Y { 1,2,3,4,5,6,7 } ; 07A z Z { 1,2,3,4,6,7 } ; 07B 4 { { 1,2,3,4,6,7 } ; 07C 8 backslash { 1,2,3,4,6,7 } ; 07D 5 } { 0 } ; 07E { 1,2,3,4,6,7 } ; 07F del END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 8 ; Number of conditions (does not have to match number tables) 123E.02 6 ; Conditions that point to a given table ; ; Table Conditions Comments ; ID -------------------------------- ; orState 1 orState 2 orState 3 ; ----- --------- --------- --------- ----------------------------------- 0 { } { } { } ; No chord keys down 1 { 1,2,5 } ; Shift-lock OR either Shift key ; down; one "orState" 2 { 3,4 } ; Either Code key down; one ; "orState" ; 3 { 1,2,5 } { 3,4 } ; Either Shift key OR the Caps Lock ; key down AND either Code key ; down; two "orStates" ; 06/29/92 VJM above condition replaces the following three conditions ; which are commented out. ; 123E.02 change above back to following three lines 3 { 1,2 } { 3,4 } ; Either Shift key down AND either ; Code key down; two "orStates" 2 { 5 } { 3,4 } ; Shift-lock key down AND either ; Code key down; two "orStates" 3 { 1,2 } { 3,4 } { 5 } ; Shift-lock AND either Shift key ; down AND either Code key ; down; three "orStates". ; --------------------- New additions --------------------- 3 { 6,7 } { } ; Alt key down; one "orState" 3 { 6,7 } {1,2,3,4,5} ; Alt key and one or more other ; chord keys down; two ; "orStates" END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 0 ; Number of multibyte strings ; String : each entry is a "state:hardware ikey" pair ; ; As an example, the following string would display "Hi there" as shown. ; Note the upstroke for the last key is present; this is okay the ; tool will add any necessary upstrokes. ; ; The "&" means continue. ; ; shft-h shft-h i i space space t t h h ; down up down up down up down up down up ; { 01:68, 01:E8, 00:69, 00:E9, 00:20, 00:A0, 00:74, 00:F4, 00:68, 00:E8 & ; 00:65, 00:E5, 00:72, 00:F2, 00:65 } ; e e r r e ; down up down up down ; ; The following string would display ".00" . ; ; { 00:2E, 00:AE, 00:30, 00:B0, 00:30, 00:B0 } ; END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Translation Tables Info ; ; Table #0, for case where no chord keys held down. ; WIDTH 1 ; 00 ; 000 help 01 ; 001 up-arrow 02 ; 002 mark 0D ; 003 bound 04 ; 004 finish 05 ; 005 prev page 06 ; 006 1/2-1/4 07 ; 007 cancel 08 ; 008 backspace 09 ; 009 tab 0A ; 00A return 0B ; 00B down-arrow 0C ; 00C next page 0A ; 00D next 0E ; 00E left-arrow 12 ; 00F right-arrow EA ; 010 SH-L K2, K3, K5 & K6 "JUMP" 11 ; 011 scroll-up 0F ; 012 move 13 ; 013 scroll-down 14 ; 014 copy 15 ; 015 f1 16 ; 016 f2 17 ; 017 f3 18 ; 018 f4 19 ; 019 f5 1A ; 01A f6 1B ; 01B GO 1C ; 01C f7 1D ; 01D f8 1E ; 01E f9 1F ; 01F f10 20 ; 020 space 39 ; 021 9 (from 9 9 keypad key) BA ; 022 SH-R K2, K3, K5 & K6 "DEL CHAR" 00 ; 023 0 00 ; 024 NEXT 00 ; 025 FE ; 026 K2, K3, K5 & K6 "COLUMN" key 27 ; 027 ' (from ' " keypad key) FB ; 028 K2, K3, K5 & K6 "PAGE" key E0 ; 029 K2, K3, K5 & K6 "PARAGRAPH" key BF ; 02A K2, K3, K5 & K6 "SENTENCE" key 3D ; 02B = 2C ; 02C , (from , , keypad key) 2D ; 02D - (from - _ keypad key) 2E ; 02E . (from . . keypad key) 2F ; 02F / 30 ; 030 0 (from 0 ) keypad key) 31 ; 031 1 (from 1 ! keypad key) 32 ; 032 2 (from 2 @ keypad key) 33 ; 033 3 (from 3 # keypad key) 34 ; 034 4 (from 4 $ keypad key) 35 ; 035 5 (from 5 % keypad key) 36 ; 036 6 (from 6  keypad key) 37 ; 037 7 (from 7 & keypad key) 38 ; 038 8 (from 8 * keypad key) 39 ; 039 9 (from 9 ( keypad key) 00 ; 03A 3B ; 03B ; BE ; 03C K2, K3, K5 & K6 "WORD" key FD ; 03D K2, K3, K5 & K6 "LINE" key 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys 36 ; 041 6 (from 6 6 keypad key) 2D ; 042 - (from - - keypad key) 00 ; 043 reset D0 ; 044 overtype 00 ; 045 lock 32 ; 046 2 (from 2 2 keypad key) 33 ; 047 3 (from 3 3 keypad key) 00 ; 048 shift 00 ; 049 shift 30 ; 04A 0 (from 0 0 keypad key) 2E ; 04B . (from . . keypad key) 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 sys 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A 5B ; 05B [ 37 ; 05C 7 (from 7 | keypad key) 5D ; 05D ] 5E ; 05E ^ 00 ; 05F 31 ; 060 1 (from 1 ` keypad key) 61 ; 061 a 62 ; 062 b 63 ; 063 c 64 ; 064 d 65 ; 065 e 66 ; 066 f 67 ; 067 g 68 ; 068 h 69 ; 069 i 6A ; 06A j 6B ; 06B k 6C ; 06C l 6D ; 06D m 6E ; 06E n 6F ; 06F o 70 ; 070 p 71 ; 071 q 72 ; 072 r 73 ; 073 s 74 ; 074 t 75 ; 075 u 76 ; 076 v 77 ; 077 w 78 ; 078 x 79 ; 079 y 7A ; 07A z 34 ; 07B 4 (from 4 { keypad key) 38 ; 07C 8 (from 8 \ keypad key) 35 ; 07D 5 (from 5 } keypad key) 00 ; 07E 7F ; 07F del ; ; Table #1, for case where either chord key held down. ; WIDTH 1 C0 ; 000 help C1 ; 001 up-arrow C2 ; 002 mark C3 ; 003 bound C4 ; 004 finish C5 ; 005 prev page 10 ; 006 1/2-1/4 C7 ; 007 cancel 08 ; 008 backspace 09 ; 009 tab 0A ; 00A return CB ; 00B down-arrow CC ; 00C next page 0A ; 00D next CE ; 00E left-arrow D2 ; 00F right-arrow 00 ; 010 SH-L D1 ; 011 scroll-up CF ; 012 move D3 ; 013 scroll-down D4 ; 014 copy D5 ; 015 f1 D6 ; 016 f2 D7 ; 017 f3 D8 ; 018 f4 D9 ; 019 f5 DA ; 01A f6 C9 ; 01B GO DC ; 01C f7 CD ; 01D f8 CA ; 01E f9 DF ; 01F f10 20 ; 020 space 39 ; 021 9 (from 9 9 keypad key) BA ; 022 SH-R K2, K3, K5 & K6 "DEL CHAR" 00 ; 023 0 00 ; 024 NEXT 00 ; 025 FE ; 026 K2, K3, K5 & K6 "COLUMN" 22 ; 027 " (from ' " keypad key) FB ; 028 K2, K3, K5 & K6 "PAGE" key E0 ; 029 K2, K3, K5 & K6 "PARAGRAPH" key BF ; 02A K2, K3, K5 & K6 "SENTENCE" key 2B ; 02B + 2C ; 02C , (from , , keypad key) 5F ; 02D _ (from - _ keypad key) 2E ; 02E . (from . . keypad key) 3F ; 02F ? 29 ; 030 ) (from 0 ) keypad key) 21 ; 031 ! (from 1 ! keypad key) 40 ; 032 @ (from 2 @ keypad key) 23 ; 033 # (from 3 # keypad key) 24 ; 034 $ (from 4 $ keypad key) 25 ; 035 % (from 5 % keypad key) 03 ; 036  (from 6  keypad key) 26 ; 037 & (from 7 & keypad key) 2A ; 038 * (from 8 * keypad key) 28 ; 039 ( (from 9 ( keypad key) 00 ; 03A 3A ; 03B : BE ; 03C K2, K3, K5 & K6 "WORD" key FD ; 03D K2, K3, K5 & K6 "LINE" key 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys 36 ; 041 6 (from 6 6 keypad key) 2D ; 042 - (from - - keypad key) 00 ; 043 reset D0 ; 044 overtype 00 ; 045 lock 32 ; 046 2 (from 2 2 keypad key) 33 ; 047 3 (from 3 3 keypad key) 00 ; 048 shift 00 ; 049 shift 30 ; 04A 0 (from 0 0 keypad key) 2E ; 04B . (from . . keypad key) 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A 3C ; 05B < 7C ; 05C | (from 7 | keypad key) 3E ; 05D > 7E ; 05E ~ 00 ; 05F 60 ; 060 ` (from 1 ` keypad key) 41 ; 061 A 42 ; 062 B 43 ; 063 C 44 ; 064 D 45 ; 065 E 46 ; 066 F 47 ; 067 G 48 ; 068 H 49 ; 069 I 4A ; 06A J 4B ; 06B K 4C ; 06C L 4D ; 06D M 4E ; 06E N 4F ; 06F O 50 ; 070 P 51 ; 071 Q 52 ; 072 R 53 ; 073 S 54 ; 074 T 55 ; 075 U 56 ; 076 V 57 ; 077 W 58 ; 078 X 59 ; 079 Y 5A ; 07A Z 7B ; 07B { (from 4 { keypad key) 5C ; 07C \ (from 8 \ keypad key) 7D ; 07D } (from 5 } keypad key) 00 ; 07E C8 ; 07F del ; ; Table #2, for case where either chord key held down. ; WIDTH 1 80 ; 000 help 81 ; 001 up-arrow 82 ; 002 mark 8D ; 003 bound 84 ; 004 finish 85 ; 005 prev page 86 ; 006 1/2-1/4 87 ; 007 cancel 88 ; 008 backspace 89 ; 009 tab 8A ; 00A return 8B ; 00B down-arrow 8C ; 00C next page 8A ; 00D next 8E ; 00E left-arrow 92 ; 00F right-arrow 00 ; 010 SH-L 91 ; 011 scroll-up 8F ; 012 move 93 ; 013 scroll-down 94 ; 014 copy 95 ; 015 f1 96 ; 016 f2 97 ; 017 f3 98 ; 018 f4 99 ; 019 f5 9A ; 01A f6 9B ; 01B GO 9C ; 01C f7 9D ; 01D f8 9E ; 01E f9 9F ; 01F f10 A0 ; 020 space B9 ; 021 9 9 00 ; 022 SH-R 00 ; 023 0 00 ; 024 NEXT 00 ; 025 00 ; 026 A7 ; 027 ' " 00 ; 028 00 ; 029 00 ; 02A BD ; 02B + = AC ; 02C , , AD ; 02D - _ AE ; 02E . . AF ; 02F / ? B0 ; 030 0 right parens B1 ; 031 1 ! B2 ; 032 2 @ B3 ; 033 3 # B4 ; 034 4 $ B5 ; 035 5 percent B6 ; 036 6 cent B7 ; 037 7 & B8 ; 038 8 * B9 ; 039 9 left parens 00 ; 03A BB ; 03B ; : 00 ; 03C 00 ; 03D 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys B6 ; 041 6 6 AD ; 042 - - 00 ; 043 reset 00 ; 044 overtype 00 ; 045 lock B2 ; 046 2 2 B3 ; 047 3 3 00 ; 048 shift 00 ; 049 shift B0 ; 04A 0 0 AE ; 04B . . 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A DB ; 05B [ < B7 ; 05C 7 | DD ; 05D ] > DE ; 05E ^ ~ 00 ; 05F B1 ; 060 1 ` E1 ; 061 a A E2 ; 062 b B E3 ; 063 c C E4 ; 064 d D E5 ; 065 e E E6 ; 066 f F E7 ; 067 g G E8 ; 068 h H E9 ; 069 i I EA ; 06A j J EB ; 06B k K EC ; 06C l L ED ; 06D m M EE ; 06E n N EF ; 06F o O F0 ; 070 p P F1 ; 071 q Q F2 ; 072 r R F3 ; 073 s S F4 ; 074 t T F5 ; 075 u U F6 ; 076 v V F7 ; 077 w W F8 ; 078 x X F9 ; 079 y Y FA ; 07A z Z B4 ; 07B 4 { B8 ; 07C 8 backslash B5 ; 07D 5 } 00 ; 07E FF ; 07F del ; ; Table #3, for case where one of the chord keys and one of the ; chord keys held down simultaneously. ; WIDTH 1 C0 ; 000 help C1 ; 001 up-arrow C2 ; 002 mark C3 ; 003 bound C4 ; 004 finish C5 ; 005 prev page 90 ; 006 1/2-1/4 C7 ; 007 cancel 88 ; 008 backspace 89 ; 009 tab 8A ; 00A return CB ; 00B down-arrow CC ; 00C next page 8A ; 00D next CE ; 00E left-arrow D2 ; 00F right-arrow 00 ; 010 SH-L D3 ; 011 scroll-up CF ; 012 move D3 ; 013 scroll-down D4 ; 014 copy D5 ; 015 f1 D6 ; 016 f2 D7 ; 017 f3 D8 ; 018 f4 D9 ; 019 f5 DA ; 01A f6 C9 ; 01B GO DC ; 01C f7 CD ; 01D f8 CA ; 01E f9 DF ; 01F f10 A0 ; 020 space B9 ; 021 9 9 00 ; 022 SH-R 00 ; 023 0 00 ; 024 NEXT 00 ; 025 00 ; 026 A2 ; 027 ' " 00 ; 028 00 ; 029 00 ; 02A AB ; 02B + = AC ; 02C , , DF ; 02D - _ AE ; 02E . . BF ; 02F / ? A9 ; 030 0 right parens A1 ; 031 1 ! C0 ; 032 2 @ A3 ; 033 3 # A4 ; 034 4 $ A5 ; 035 5 percent 83 ; 036 6 cent A6 ; 037 7 & AA ; 038 8 * A8 ; 039 9 left parens 00 ; 03A BA ; 03B ; : 00 ; 03C 00 ; 03D 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys B6 ; 041 6 6 AD ; 042 - - 00 ; 043 reset 00 ; 044 overtype 00 ; 045 lock B2 ; 046 2 2 B3 ; 047 3 3 00 ; 048 shift 00 ; 049 shift B0 ; 04A 0 0 AE ; 04B . . 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A BC ; 05B [ < FC ; 05C 7 | BE ; 05D ] > FE ; 05E ^ ~ 00 ; 05F E0 ; 060 1 ` C1 ; 061 a A C2 ; 062 b B C3 ; 063 c C C4 ; 064 d D C5 ; 065 e E C6 ; 066 f F C7 ; 067 g G C8 ; 068 h H C9 ; 069 i I CA ; 06A j J CB ; 06B k K CC ; 06C l L CD ; 06D m M CE ; 06E n N CF ; 06F o O D0 ; 070 p P D1 ; 071 q Q D2 ; 072 r R D3 ; 073 s S D4 ; 074 t T D5 ; 075 u U D6 ; 076 v V D7 ; 077 w W D8 ; 078 x X D9 ; 079 y Y DA ; 07A z Z FB ; 07B 4 { DC ; 07C 8 backslash FD ; 07D 5 } 00 ; 07E C8 ; 07F del END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. /***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* 21.kbd_data */ /* */ /* This file contains the text version of the table that causes a K2 */ /* keyboard to emulate a K1 keyboard for the OS version of "NlsKbd.sys". */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION */ /* */ /* 03/20/92 122G.01 V. Miller / Added comments documenting how the */ /* emulated LEDs table should work. */ /* V. Miller & K. Hampton / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; ; This is the data file for the K2 Keyboard that is used by the "Create ; Keyboard Table" Application. The format is translation tables for a ; K1 keyboard followed by emulation tables that convert K2 iKeys to the ; K1 iKey values that produce the same effect. ; ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; Keyboard name K2 ; Output file name K2KbdTables.obj ; Name of PUBLIC in object module at start of table K2KeyBoardData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ==================================================================== ; ; EMULATION DATA ; ; What follows is the data that enables the keyboard process to emulate ; the K2 keyboard as a K1 keyboard. This means that K2 state/hardware iKey ; combinations are replaced by the state/hardware iKey for the K1 keyboard ; that give the same result. ; EMULATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if emulation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of emulation tables in hex ; | | | | ; | | | | :-- Target translation table in hex ; | | | | | ; 80 FF 80 2 04 ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have at least 22 and at most 29 entries and they MUST ; be in the order shown. 22 ; Number special keys 61 ; a 62 ; b 7F ; 44 ; 4C ; 4D ; 04 ; 43 ; 45 ; 48 ; 49 ; 64 ; Mouse Disable 65 ; Mouse Enable 40 ; 00 ; c 1B ; 40 ; iKey not valid 20 ; Diacritic Escape 00 ; Sys Key 00 ; OS1 00 ; OS2 00 ; OS3 END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; If the i-th entry in this table is non-zero (say it is"j" instead), ; it means that when the user of the actual keyboard asks for the ; "i-th" LED to be turned on the "j-th" LED is turned on instead. ; 8 ; Number of LEDs on keyboard (NOT number of entries in table). This ; number must be 16 or less. ; The table below is used to specify what LED is turned on when a key that ; affects an LED is pressed. The table MUST have 16 entries. ; Enter the number of the LED to be actually be turned on when the code ; specifies the particular LED number. For example, the entry ; ; "03 ; 7" ; ; means that when an application specifies that LED 7 be turned on, ; actually turn on LED 03 (where both 3 and 7 are base 10). ; ; Other possible values ; ; ~ 0 means don't remap (or map to itself). For example, the entry ; ; "00 ; 8" ; ; means thet when an application specifies that LED 8 be turned on, ; don't change (or remap) what is to be turned on; actually turn on ; LED 08. ; ; ~ FF (or actually any number greater than 16) means not supported. ; For example, the entry ; ; "FF ; 9" ; ; means thet when an application specifies that LED 9 be turned on, ; nothing is turned on. ; ; When we say LED "x" is set, we mean that the current LED state is OR-ed ; with the "x-th" entry in the following array. ; ; "1h,2h,4h,8h,10h,20h,40h,80h" ; ; LEDs >8 on the Kx style keyboards are handled according to the ; rquirement described in the hardware spec. ; 00 ; 1 f10 00 ; 2 f9 00 ; 3 f8 00 ; 4 f3 00 ; 5 f2 00 ; 6 f1 00 ; 7 LOCK 00 ; 8 Overtype 00 ; 9 Comm1 Not used on this keyboard 00 ; 10 Comm2 Not used on this keyboard 00 ; 11 Comm3 Not used on this keyboard 00 ; 12 Comm4 Not used on this keyboard 00 ; 13 Comm5 Not used on this keyboard 00 ; 14 'Numlock' Not used on this keyboard 00 ; 15 'Scroll Lock' Not used on this keyboard 00 ; 16 Not used on this keyboard END LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for a translation table. ; ; 5 ; Number of entries ; ; !!! ALL NUMBERS IN THE FOLLOWING TABLE MUST BE IN HEX ; ; key bMask* fToggle fLed LED mask** ; number bit bit fExclus- ; position position ionary ; (hex) (hex) (hex) ; 48 0 F F 0 F ; Chord #1 49 1 F F 0 F ; Chord #2 4C 2 F F 0 F ; Chord #3 4D 3 F F 0 F ; Chord #4 45 4 T T 6 F ; Chord #5 END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; numbers are decimal ; ------------------ ------ --------- { 1,2 } ; 00 { 1,2 } ; 01 { 1,2 } ; 02 { 1,2 } ; 03 { 1,2 } ; 04 { 1,2 } ; 05 { 1,2 } ; 06 { 1,2 } ; 07 { 1,2 } ; 08 { 1,2 } ; 09 { 1,2 } ; 0A { 1,2 } ; 0B { 1,2 } ; 0C { 1,2 } ; 0D { 1,2 } ; 0E { 1,2 } ; 0F { 1,2 } ; 10 { 1,2 } ; 11 { 1,2 } ; 12 { 1,2 } ; 13 { 1,2 } ; 14 { 1,2 } ; 15 { 1,2 } ; 16 { 1,2 } ; 17 { 1,2 } ; 18 { 1,2 } ; 19 { 1,2 } ; 1A { 1,2 } ; 1B { 1,2 } ; 1C { 1,2 } ; 1D { 1,2 } ; 1E { 1,2 } ; 1F { 1,2 } ; 20 { 1,2 } ; 21 { 1,2 } ; 22 { 1,2 } ; 23 { 1,2 } ; 24 { 1,2 } ; 25 { 1,2 } ; 26 { 1,2 } ; 27 { 1,2 } ; 28 { 1,2 } ; 29 { 1,2 } ; 2A { 1,2 } ; 2B { 1,2 } ; 2C { 1,2 } ; 2D { 1,2 } ; 2E { 1,2 } ; 2F { 1,2 } ; 30 { 1,2 } ; 31 { 1,2 } ; 32 { 1,2 } ; 33 { 1,2 } ; 34 { 1,2 } ; 35 { 1,2 } ; 36 { 1,2 } ; 37 { 1,2 } ; 38 { 1,2 } ; 39 { 1,2 } ; 3A { 1,2 } ; 3B { 1,2 } ; 3C { 1,2 } ; 3D { 1,2 } ; 3E { 0 } ; 3F { 0 } ; 40 { 1,2 } ; 41 { 1,2 } ; 42 { 0 } ; 43 { 1,2 } ; 44 { 5 } ; 45 { 1,2 } ; 46 { 1,2 } ; 47 { 1 } ; 48 { 2 } ; 49 { 1,2 } ; 4A { 1,2 } ; 4B { 3 } ; 4C { 4 } ; 4D { 0 } ; 4E { 0 } ; 4F { 0 } ; 50 { 0 } ; 51 { 0 } ; 52 { 0 } ; 53 { 1,2 } ; 54 { 0 } ; 55 { 0 } ; 56 { 0 } ; 57 { 0 } ; 58 { 1,2 } ; 59 { 0 } ; 5A { 1,2 } ; 5B { 1,2 } ; 5C { 1,2 } ; 5D { 1,2 } ; 5E { 0 } ; 5F { 1,2 } ; 60 { 1,2,5 } ; 61 { 1,2,5 } ; 62 { 1,2,5 } ; 63 { 1,2,5 } ; 64 { 1,2,5 } ; 65 { 1,2,5 } ; 66 { 1,2,5 } ; 67 { 1,2,5 } ; 68 { 1,2,5 } ; 69 { 1,2,5 } ; 6A { 1,2,5 } ; 6B { 1,2,5 } ; 6C { 1,2,5 } ; 6D { 1,2,5 } ; 6E { 1,2,5 } ; 6F { 1,2,5 } ; 70 { 1,2,5 } ; 71 { 1,2,5 } ; 72 { 1,2,5 } ; 73 { 1,2,5 } ; 74 { 1,2,5 } ; 75 { 1,2,5 } ; 76 { 1,2,5 } ; 77 { 1,2,5 } ; 78 { 1,2,5 } ; 79 { 1,2,5 } ; 7A { 1,2 } ; 7B { 1,2 } ; 7C { 1,2 } ; 7D { 0 } ; 7E { 1,2 } ; 7F END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 2 ; Number of conditions ; Conditions that point to a given table ; ; NOTE: Numbers in orStates are decimal ; ; Table Conditions Comments ; ID ---------------------------- ; orState1 orState2 orState3 ; ----- -------- -------- -------- ------------------------------------- 0 { } { 0 } { 0 } ; No chord keys down 1 { 1,2,5 } ; Shift-lock OR either Shift key down; ; one "orState" END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 1 ; Number of multibyte strings ; String { 00:30, 00:B0, 00:30, 00:B0 } END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Emulation Tables Info ; Number of emulation tables specified in special keys section. ; ; Table for case where no chord keys held down. ; ; NOTE: FFFF:xx means use existing state. ; ; ; Table #0, for case where no chord keys held down. ; FFFF:00 ; 00 FFFF:01 ; 01 FFFF:02 ; 02 FFFF:03 ; 03 FFFF:04 ; 04 FFFF:05 ; 05 FFFF:06 ; 06 FFFF:07 ; 07 FFFF:08 ; 08 FFFF:09 ; 09 FFFF:0A ; 0A FFFF:0B ; 0B FFFF:0C ; 0C FFFF:0D ; 0D FFFF:0E ; 0E FFFF:0F ; 0F FFFF:10 ; 10 FFFF:11 ; 11 FFFF:12 ; 12 FFFF:13 ; 13 FFFF:14 ; 14 FFFF:15 ; 15 FFFF:16 ; 16 FFFF:17 ; 17 FFFF:18 ; 18 FFFF:19 ; 19 FFFF:1A ; 1A FFFF:1B ; 1B FFFF:1C ; 1C FFFF:1D ; 1D FFFF:1E ; 1E FFFF:1F ; 1F FFFF:20 ; 20 FFFF:21 ; 21 FFFF:22 ; 22 08:04 ; 23 ; Replace K2 value (unshifted 24) with 01:38 ; 24 >>>> K1 value ( 38) because asterix ; is also on this key on the K2 ; keyboard. FFFF:2F ; 25 FFFF:26 ; 26 FFFF:27 ; 27 FFFF:28 ; 28 FFFF:29 ; 29 FFFF:2A ; 2A FFFF:2B ; 2B FFFF:2C ; 2C FFFF:2D ; 2D FFFF:2E ; 2E FFFF:2F ; 2F FFFF:30 ; 30 FFFF:31 ; 31 FFFF:32 ; 32 FFFF:33 ; 33 FFFF:34 ; 34 FFFF:35 ; 35 FFFF:36 ; 36 FFFF:37 ; 37 FFFF:38 ; 38 FFFF:39 ; 39 FFFF:2B ; 3A FFFF:3B ; 3B FFFF:3C ; 3C FFFF:3D ; 3D 01:35 ; 3E FFFF:FF ; 3F FFFF:FF ; 40 FFFF:41 ; 41 FFFF:42 ; 42 FFFF:43 ; 43 FFFF:44 ; 44 FFFF:45 ; 45 FFFF:46 ; 46 FFFF:47 ; 47 FFFF:48 ; 48 FFFF:49 ; 49 FFFF:4A ; 4A FFFF:4B ; 4B FFFF:4C ; 4C FFFF:4D ; 4D FFFF:FF ; 4E FFFF:FF ; 4F FFFF:FF ; 50 FFFF:FF ; 51 FFFF:FF ; 52 Since there is no key on K2 keyboard FFFF:FF ; 53 Since there is no key on K2 keyboard 01:2B ; 54 FFFF:FF ; 55 FFFF:FF ; 56 FFFF:FF ; 57 FFFF:58 ; 58 SM:01:4A ; 059 Numeric 00 MUST BE MULTIBYTE FFFF:FF ; 5A FFFF:5B ; 5B FFFF:5C ; 5C FFFF:5D ; 5D FFFF:FF ; 5E FFFF:FF ; 5F FFFF:60 ; 60 FFFF:61 ; 61 FFFF:62 ; 62 FFFF:63 ; 63 FFFF:64 ; 64 FFFF:65 ; 65 FFFF:66 ; 66 FFFF:67 ; 67 FFFF:68 ; 68 FFFF:69 ; 69 FFFF:6A ; 6A FFFF:6B ; 6B FFFF:6C ; 6C FFFF:6D ; 6D FFFF:6E ; 6E FFFF:6F ; 6F FFFF:70 ; 70 FFFF:71 ; 71 FFFF:72 ; 72 FFFF:73 ; 73 FFFF:74 ; 74 FFFF:75 ; 75 FFFF:76 ; 76 FFFF:77 ; 77 FFFF:78 ; 78 FFFF:79 ; 79 FFFF:7A ; 7A FFFF:7B ; 7B FFFF:7C ; 7C FFFF:7D ; 7D FFFF:FF ; 7E FFFF:7F ; 7F ; ; Table #1, for case where or key held down. ; FFFF:00 ; 00 FFFF:01 ; 01 FFFF:02 ; 02 FFFF:03 ; 03 FFFF:04 ; 04 FFFF:05 ; 05 FFFF:06 ; 06 FFFF:07 ; 07 FFFF:08 ; 08 FFFF:09 ; 09 FFFF:0A ; 0A FFFF:0B ; 0B FFFF:0C ; 0C FFFF:0D ; 0D FFFF:0E ; 0E FFFF:0F ; 0F FFFF:10 ; 10 FFFF:11 ; 11 FFFF:12 ; 12 FFFF:13 ; 13 FFFF:14 ; 14 FFFF:15 ; 15 FFFF:16 ; 16 FFFF:17 ; 17 FFFF:18 ; 18 FFFF:19 ; 19 FFFF:1A ; 1A FFFF:1B ; 1B FFFF:1C ; 1C FFFF:1D ; 1D FFFF:1E ; 1E FFFF:1F ; 1F FFFF:20 ; 20 00:5E ; 21 caret (from 9 pad key) FFFF:22 ; 22 08:05 ; 23 FFFF:38 ; 24 00:2F ; 25 FFFF:26 ; 26 FFFF:27 ; 27 FFFF:28 ; 28 FFFF:29 ; 29 FFFF:2A ; 2A FFFF:2B ; 2B FFFF:2C ; 2C FFFF:2D ; 2D FFFF:2E ; 2E FFFF:2F ; 2F FFFF:30 ; 30 FFFF:31 ; 31 FFFF:32 ; 32 FFFF:33 ; 33 FFFF:34 ; 34 FFFF:35 ; 35 FFFF:36 ; 36 FFFF:37 ; 37 FFFF:38 ; 38 FFFF:39 ; 39 00:2B ; 3A FFFF:3B ; 3B FFFF:3C ; 3C FFFF:3D ; 3D FFFF:35 ; 3E FFFF:FF ; 3F FFFF:FF ; 40 FFFF:5E ; 41 FFFF:42 ; 42 FFFF:43 ; 43 FFFF:44 ; 44 FFFF:45 ; 45 00:06 ; 46 FFFF:06 ; 47 FFFF:48 ; 48 FFFF:49 ; 49 FFFF:4A ; 4A FFFF:4B ; 4B FFFF:4C ; 4C FFFF:4D ; 4D FFFF:FF ; 4E FFFF:FF ; 4F FFFF:FF ; 50 FFFF:FF ; 51 FFFF:FF ; 52 FFFF:FF ; 53 FFFF:2B ; 54 FFFF:FF ; 55 FFFF:FF ; 56 FFFF:FF ; 57 FFFF:58 ; 58 SM:01:4A ; 059 Numeric 00 FFFF:FF ; 5A FFFF:5B ; 5B FFFF:5C ; 5C FFFF:5D ; 5D FFFF:FF ; 5E FFFF:FF ; 5F FFFF:60 ; 60 FFFF:61 ; 61 FFFF:62 ; 62 FFFF:63 ; 63 FFFF:64 ; 64 FFFF:65 ; 65 FFFF:66 ; 66 FFFF:67 ; 67 FFFF:68 ; 68 FFFF:69 ; 69 FFFF:6A ; 6A FFFF:6B ; 6B FFFF:6C ; 6C FFFF:6D ; 6D FFFF:6E ; 6E FFFF:6F ; 6F FFFF:70 ; 70 FFFF:71 ; 71 FFFF:72 ; 72 FFFF:73 ; 73 FFFF:74 ; 74 FFFF:75 ; 75 FFFF:76 ; 76 FFFF:77 ; 77 FFFF:78 ; 78 FFFF:79 ; 79 FFFF:7A ; 7A FFFF:7B ; 7B FFFF:7C ; 7C FFFF:7D ; 7D FFFF:FF ; 7E FFFF:7F ; 7F END TABLES /***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* 41.kbd_data */ /* */ /* This file contains the text version of the K4 keyboard data block. */ /* To properly do this (i.e. to make HELP and a few things like that */ /* work) both an emulation and a translation table are needed. */ /* */ /* */ /* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV */ /* >>> <<< */ /* >>> NOTE!!! This table is designed for the FSA version of the K4. <<< */ /* >>> Other versions of the K4 keyboard will not work <<< */ /* >>> with this table. The FSA version of the table was <<< */ /* >>> chosen as the standard one because most users of the <<< */ /* >>> K4 keyboard use primarily all FSA applications. <<< */ /* >>> <<< */ /* >>> This table is generated and tested at the FSA <<< */ /* >>> development site. <<< */ /* >>> <<< */ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION */ /* */ /* 11/10/93 D. Thakurdesai/ Changes to make CODE-NEXT work as */ /* CODE-TAB (Finesse UCF# 49036434). */ /* 03/18/92 122G.03 V. Miller / Added comment. */ /* 02/24/92 122G.02 D. Hall / Received from David Hall, Unisys */ /* Atlanta on February 24, 1992. */ /* 02/15/92 122G.01 V.Miller / Made changes to make the following */ /* keys work correctly if is */ /* on: , , , . They */ /* should give, respectively, "P", "Z", */ /* delete functionality and copy */ /* functionality. */ /* D. Hall / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; ; This is the data file for the K4 Keyboard that is used by the "Create ; Keyboard Table" Application. The format is translation tables for a ; K4 keyboard. ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; Keyboard name K4 ; Output file name K4KbdTables.obj ; Name of PUBLIC in object module at start of table K4KeyBoardData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ; TRANSLATION DATA ; ; TRANSLATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if translation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of translation tables in decimal ; | | | | ; 80 90 80 4 ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K4 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have at least 19 and at most 29entries and they MUST ; be in the order shown. 22 ; Number special keys in decimal 05 ;A 39 ;B 13 ;DELETE CANCEL - 7 44 ;OVERTYPE 04 ;LEFT CODE 04 ;RIGHT CODE 7F ;FINISH 43 ;ACTION 2B ;LOCK ( Shift - Lock 2-13-92 ) 14 ;LEFT SHIFT 14 ;RIGHT SHIFT FFFF ;RESERVED Mouse Disable FFFF ;RESERVED Mouse Enable FFFF ;RESERVED 0C ;HELP 08 ;GO - 1B 40 ;NULL 20 ;DIACRITIC ESCAPE 0 ;SYS KEY If there is no key use an iKey that is ; not produced by the keyboard in question OR 00 ; NOTE that the help key can not be used as the ; system key since it is '00' 00 ; OS1 00 ; OS2 00 ; OS3 END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for a translation table. ; 3 ; Number of entries ; ; !!! ALL NUMBERS IN THE FOLLOWING TABLE MUST BE IN HEX ; ; key bMask* fToggle fLed LED mask** ; number bit bit fExclus- ; position position ionary ; (hex) (hex) (hex) ; 14 0 F F 0 F ; Chord #1 04 1 F F 0 F ; Chord #2 2B 2 T T 1 F ; Chord #3 ; * NOTES: bMask bit position ; ; 1. The number of the bit set (to 1) in the bMask word for this ; chord where "0" means the least significant bit and "15" ; means the most significant bit. ; ; 2. The values for bMask are NOT required to be consecutive. ; ; ** NOTE: there MUST be an entry for "LED mask bit position" even if the ; "fLED" entry is "F"; it can be zero. END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START CONTROL CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. 8 ; Number of entries 01 ; AllShiftsMask 00 ; BullShiftMask 02 ; noDiacrit 02 ; noRepeat 02 ; CodeKeyMask 00 ; AltCodeKeyMask 01 ; K4ShiftMask 04 ; LockKeyMask END CONTROL CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START RPT ATTRS TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; The following entries for FAST and SLOW attribute characteristics are ; optional. You can have both none or one of them. The allowable codes ; are: ; ; Delay until repeating starts codes: 1 - 0.2 seconds ; 2 - 0.4 seconds ; 3 - 0.7 seconds ; ; Frequency of repetition codes: 0 - 1 character / second ; 1 - 10 character / second ; 2 - 20 character / second ; 3 - 30 character / second ; ; If no entry is made a default will be shown. The dafaults are: ; ; Delay Until Frequency Of ; Repeating Repeating ; Starts Code Code ; ; Attribute Characteristics Fast 2 3 ; ; Attribute Characteristics Slow 3 2 ; ; ENTRIES ; ---------------------------------------------------- ; Repeat iKey Key ; Attribute Number Name ; --------- ------ --------- None ; 0 Fast ; 1 None ; 2 Fast ; 3 None ; 4 None ; 5 None ; 6 Slow ; 7 None ; 8 None ; 9 None ; A Fast ; B None ; C Slow ; D Fast ; E Fast ; F None ; 10 None ; 11 None ; 12 None ; 13 None ; 14 None ; 15 None ; 16 None ; 17 None ; 18 None ; 19 None ; 1A None ; 1B None ; 1C None ; 1D None ; 1E None ; 1F None ; 20 Slow ; 21 None ; 22 None ; 23 None ; 24 None ; 25 None ; 26 None ; 27 None ; 28 None ; 29 None ; 2A None ; 2B None ; 2C None ; 2D Slow ; 2E None ; 2F None ; 30 None ; 31 Slow ; 32 Slow ; 33 None ; 34 None ; 35 None ; 36 None ; 37 None ; 38 None ; 39 Slow ; 3A None ; 3B None ; 3C None ; 3D None ; 3E None ; 3F None ; 40 Slow ; 41 None ; 42 None ; 43 None ; 44 None ; 45 Slow ; 46 Slow ; 47 None ; 48 None ; 49 Slow ; 4A None ; 4B None ; 4C None ; 4D None ; 4E None ; 4F None ; 50 None ; 51 None ; 52 None ; 53 Fast ; 54 None ; 55 None ; 56 None ; 57 None ; 58 None ; 59 None ; 5A None ; 5B Slow ; 5C None ; 5D None ; 5E None ; 5F Slow ; 60 None ; 61 None ; 62 None ; 63 None ; 64 None ; 65 None ; 66 None ; 67 None ; 68 None ; 69 None ; 6A None ; 6B None ; 6C None ; 6D None ; 6E None ; 6F None ; 70 None ; 71 None ; 72 None ; 73 None ; 74 None ; 75 None ; 76 None ; 77 None ; 78 None ; 79 None ; 7A Slow ; 7B Slow ; 7C Slow ; 7D None ; 7E None ; 7F END RPT ATTRS TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; ------------------ ------ --------- { 1,2,3 } ; 00 HELP or Z { 1,2 } ; 01 { 1,2 } ; 02 { 1,2 } ; 03 { 2 } ; 04 { 1,2,3 } ; 05 EC or A { 1,2 } ; 06 { 1,2 } ; 07 { 1,2 } ; 08 { 1,2 } ; 09 { 1,2 } ; 0A { 1,2 } ; 0B { 1,2,3 } ; 0C { 1,2 } ; 0D { 1,2 } ; 0E { 1,2 } ; 0F { 1,2 } ; 10 { 1,2,3 } ; 11 RV or S { 1,2,3 } ; 12 DEL CHAR or C { 1,2,3 } ; 13 CANCEL or X { 1,2 } ; 14 { 1,2,3 } ; 15 F1 or Q { 1,2,3 } ; 16 F2 or W { 1,2,3 } ; 17 F3 or E { 1,2,3 } ; 18 F4 or R { 1,2,3 } ; 19 F5 or T { 1,2,3 } ; 1A F6 or Y { 1,2 } ; 1B { 1,2,3 } ; 1C F7 or U { 1,2,3 } ; 1D F8 or I { 1,2,3 } ; 1E F9 or O { 1,2,3 } ; 1F F10 or P { 1,2 } ; 20 { 1,2 } ; 21 { 1,2 } ; 22 { 1,2 } ; 23 { 1,2 } ; 24 { 1,2 } ; 25 { 1,2 } ; 26 { 1,2 } ; 27 { 1,2 } ; 28 { 1,2 } ; 29 { 1,2 } ; 2A { 3 } ; 2B ( Shift - Lock 2-13-92 ) { 1,2 } ; 2C { 1,2,3 } ; 2D - or M { 1,2 } ; 2E { 1,2 } ; 2F { 1,2,3 } ; 30 / or N { 1,2,3 } ; 31 PREV PAGE or F { 1,2,3 } ; 32 SCROLL UP or G { 1,2,3 } ; 33 SCROLL DOWN or H { 1,2,3 } ; 34 MARK or J { 1,2,3 } ; 35 BOUND or K { 1,2,3 } ; 36 TLR A or L { 1,2 } ; 37 { 1,2,3 } ; 38 % or V { 1,2,3 } ; 39 * or B { 1,2 } ; 3A { 1,2 } ; 3B { 1,2 } ; 3C { 1,2 } ; 3D { 1,2 } ; 3E { 1,2 } ; 3F { 1,2 } ; 40 { 1,2 } ; 41 { 1,2 } ; 42 { 1,2 } ; 43 { 1,2 } ; 44 { 3 } ; 45 { 1,2 } ; 46 { 1,2 } ; 47 { 1,2 } ; 48 { 1,2 } ; 49 { 1,2 } ; 4A { 1,2 } ; 4B { 1,2 } ; 4C { 1,2 } ; 4D { 1,2 } ; 4E { 1,2 } ; 4F { 1,2 } ; 50 { 1,2 } ; 51 { 1,2 } ; 52 { 1,2 } ; 53 { 1,2 } ; 54 { 1,2 } ; 55 { 1,2 } ; 56 { 1,2 } ; 57 { 1,2 } ; 58 { 1,2 } ; 59 { 1,2 } ; 5A { 1,2 } ; 5B { 1,2 } ; 5C { 1,2 } ; 5D { 1,2,3 } ; 5E NEXT PAGE or D { 1,2 } ; 5F { 1,2 } ; 60 { 1,2 } ; 61 { 1,2 } ; 62 { 1,2 } ; 63 { 1,2 } ; 64 { 1,2 } ; 65 { 1,2 } ; 66 { 1,2 } ; 67 { 1,2 } ; 68 { 1,2 } ; 69 { 1,2 } ; 6A { 1,2 } ; 6B { 1,2 } ; 6C { 1,2 } ; 6D { 1,2 } ; 6E { 1,2 } ; 6F { 1,2 } ; 70 { 1,2 } ; 71 { 1,2 } ; 72 { 1,2 } ; 73 { 1,2 } ; 74 { 1,2 } ; 75 { 1,2 } ; 76 { 1,2 } ; 77 { 1,2 } ; 78 { 1,2 } ; 79 { 1,2 } ; 7A { 1,2 } ; 7B { 1,2 } ; 7C { 1,2 } ; 7D { 1,2 } ; 7E { 1,2 } ; 7F END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 5 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; Table Conditions Comments ; ID ---------------------------- ; orState1 orState2 orState3 ; ----- -------- -------- -------- ------------------------------------- 0 { } { } { } ; NO CHORD 1 { 1,3 } { } { } ; SHIFT or LOCK one "orState" 2 { 2 } { } { } ; CODE one "orState" 3 { 1 } { 2 } { } ; SHIFT AND CODE two "orStates" 2 { 3 } { 2 } { } ; LOCK AND CODE two "orStates" END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 1 ; Number of multibyte strings ; String : each entry is a "state:hardware ikey" pair ; ; As an example, the following string would display "Hi there" as shown. ; Note the upstroke for the last key is present; this is okay the ; tool will add any necessary upstrokes. ; ; The "&" means continue. ; ; shft-h shft-h i i space space t t h h ; down up down up down up down up down up ; { 01:68, 01:E8, 00:69, 00:E9, 00:20, 00:A0, 00:74, 00:F4, 00:68, 00:E8 & ; 00:65, 00:E5, 00:72, 00:F2, 00:65 } ; e e r r e ; down up down up down ; ; The following string would display ".00" . ; ; { 00:2E, 00:AE, 00:30, 00:B0, 00:30, 00:B0 } ; { 00:4A, 00:CA, 00:4A, 00:CA } END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Translation Tables Info ; ; Table #0, for case where no chord keys held down. WIDTH 1 ; Finesse iKey ; iKey - Standard Key - Finesse Key 00 ; 00 HELP HELP 0B ; from 1F VJM ; 01 SCROLL UP DOWN ARROW from 01 DMH 5C ; 02 NOT ON K4 BACKSLASH for BEM 12 ; from 37 VJM ; 03 BOUND RIGHT ARROW 00 ; 04 FINISH CODE ( SPECIAL KEYS ) D9 ; 05 I EC ( SHIFT - F5 ) 5F ; 06 NOT ON K4 UNDERSCORE for BEM 7F ; 07 CANCEL DELETE 1B ; 08 X GO 09 ; 09 NOT ON K4 TAB for MEM and BEM DC ; 0A Y SPD ( SHIFT - F7 ) 01 ; from 01 VJM ; 0B NEXT PAGE UP ARROW from 0B DMH 14 ; 0C Q COPY 0A ; 0D NEXT NEXT 20 ; 0E CODE SPACE 7E ; 0F SHIFT OVERLAY 80 ; 10 NOT ON K4 CODE HELP DA ; 11 J RV ( SHIFT - F6 ) BA ; 12 MOVE DEL CHAR 07 ; 13 R CANCEL 00 ; 14 COPY SHIFT 00 15 ; 15 A F1 16 ; 16 B F2 17 ; 17 C F3 18 ; 18 D F4 19 ; 19 E F5 1A ; 1A F F6 2B ; 1B TAB + 1C ; 1C G F7 1D ; 1D H F8 1E ; 1E UP ARROW F9 1F ; 1F DOWN ARROW F10 5F ; 20 NOT ON K4 UNDERSCORE for BEM 39 ; 21 9 9 82 ; 22 NOT ON K4 CODE-MARK 84 ; 23 NOT ON K4 CODE-FINISH 86 ; 24 NOT ON K4 CODE-1/2 08 ; 25 NOT ON K4 BACKSPACE FOR BEM 00 ; 26 NOT ON K4 00 ; 27 NOT ON K4 00 ; 28 NOT ON K4 00 ; 29 NOT ON K4 00 ; 2A NOT ON K4 00 ; 2B W ( SHIFT - LOCK 2-13-92 ) 00 ; 2C NOT ON K4 2D ; 2D V - 2E ; 2E . . 00 ; 2F NOT ON K4 - 2F ; 30 U / 05 ; 31 L PREVIOUS PAGE 11 ; 32 M SCROLL UP 13 ; 33 N SCROLL DOWN 02 ; 34 O MARK 03 ; 35 P BOUND CA ; 36 LEFT ARROW TLR A ( SHIFT - F9 ) DF ; 37 RIGHT ARROW TLR B ( SHIFT - F10 ) 25 ; 38 S % 2A ; 39 T * SM:01 ; 3A 00 00 00 ; 3B NOT ON K4 00 ; 3C NOT ON K4 00 ; 3D NOT ON K4 00 ; 3E NOT ON K4 00 ; 3F NOT ON K4 00 ; 40 NOT ON K4 36 ; 41 6 6 3D ; 42 SPACE = 00 ; 43 ACTION ACTION D0 ; 44 OVERTYPE OVERTYPE 00 ; 45 NOT ON K4 32 ; 46 2 2 33 ; 47 3 3 BE ; 48 GO STAT ( SHIFT - F8 ) 00 ; 49 NOT ON K4 30 ; 4A 0 0 00 ; 4B NOT ON K4 00 ; 4C NOT ON K4 00 ; 4D NOT ON K4 00 ; 4E NOT ON K4 00 ; 4F NOT ON K4 00 ; 50 NOT ON K4 00 ; 51 NOT ON K4 00 ; 52 NOT ON K4 00 ; 53 NOT ON K4 0E ; 54 MARK LEFT ARROW 00 ; 55 NOT ON K4 00 ; 56 NOT ON K4 00 ; 57 NOT ON K4 00 ; 58 NOT ON K4 00 ; 59 NOT ON K4 00 ; 5A NOT ON K4 00 ; 5B NOT ON K4 37 ; 5C 7 7 00 ; 5D NOT ON K4 0C ; 5E K NEXT PAGE 00 ; 5F NOT ON K4 31 ; 60 1 1 00 ; 61 NOT ON K4 00 ; 62 NOT ON K4 00 ; 63 NOT ON K4 00 ; 64 NOT ON K4 00 ; 65 NOT ON K4 00 ; 66 NOT ON K4 00 ; 67 NOT ON K4 00 ; 68 NOT ON K4 00 ; 69 NOT ON K4 00 ; 6A NOT ON K4 00 ; 6B NOT ON K4 00 ; 6C NOT ON K4 00 ; 6D NOT ON K4 00 ; 6E NOT ON K4 00 ; 6F NOT ON K4 00 ; 70 NOT ON K4 00 ; 71 NOT ON K4 00 ; 72 NOT ON K4 00 ; 73 NOT ON K4 00 ; 74 NOT ON K4 00 ; 75 NOT ON K4 00 ; 76 NOT ON K4 00 ; 77 NOT ON K4 00 ; 78 NOT ON K4 00 ; 79 NOT ON K4 00 ; 7A NOT ON K4 34 ; 7B 4 4 38 ; 7C 8 8 35 ; 7D 5 5 00 ; 7E NOT ON K4 04 ; 7F DELETE FINISH ; TABLE NUMBER 2 - SHIFT or LOCK CHORD WIDTH 1 ; Finesse iKey ; iKey - Standard Key - Finesse Key 3E ; 00 NOT ON K4 > CB ; 01 SCROLL DOWN SHIFT DOWN ARROW 00 ; 02 NOT ON K4 D2 ; 03 NOT ON K4 SHIFT RIGHT ARROW 00 ; 04 NOT ON K4 41 ; 05 F6 A 00 ; 06 NOT ON K4 3C ; 07 NOT ON K4 - < 1B ; 08 NOT ON K4 - GO 00 ; 09 NOT ON K4 - 2C ; 0A Z , C1 ; 0B PREV PAGE SHIFT UP ARROW 5A ; 0C ? Z 0A ; 0D NEXT NEXT 20 ; 0E NOT ON K4 SPACE 22 ; 0F NOT ON K4 " 81 ; 10 NOT ON K4 CODE UP ARROW 53 ; 11 F7 S 43 ; 12 NOT ON K4 C 58 ; 13 : X 00 ; 14 NOT ON K4 51 ; 15 F1 Q 57 ; 16 F2 W 45 ; 17 F3 E 52 ; 18 F4 R 54 ; 19 F5 T 59 ; 1A < Y 5B ; 1B BACKSPACE [ 55 ; 1C > U 49 ; 1D ' I 4F ; 1E NOT ON K4 O 50 ; 1F NOT ON K4 P 00 ; 20 NOT ON K4 28 ; 21 ) ( 83 ; 22 NOT ON K4 SHIFT-R' 85 ; 23 NOT ON K4 SHIFT-0' 87 ; 24 NOT ON K4 SHIFT-NEXT' 00 ; 25 NOT ON K4 00 ; 26 NOT ON K4 00 ; 27 NOT ON K4 00 ; 28 NOT ON K4 00 ; 29 NOT ON K4 00 ; 2A NOT ON K4 00 ; 2B = . ( Shift-Lock 2-13-92 ) 00 ; 2C NOT ON K4 4D ; 2D / M 27 ; 2E NOT ON K4 - ' 00 ; 2F NOT ON K4 4E ; 30 - N 46 ; 31 F9 F 47 ; 32 F10 G 48 ; 33 [ H 4A ; 34 ] J 4B ; 35 ; K 4C ; 36 NOT ON K4 L 3B ; 37 NOT ON K4 ; 56 ; 38 * V 42 ; 39 + B 3A ; 3A NOT ON K4 : 00 ; 3B NOT ON K4 00 ; 3C NOT ON K4 00 ; 3D NOT ON K4 00 ; 3E NOT ON K4 00 ; 3F NOT ON K4 00 ; 40 NOT ON K4 03 ; 41 &  ( SHIFT - 6 ) 5D ; 42 NOT ON K4 ] 00 ; 43 NOT ON K4 D0 ; 44 NOT ON K4 OVERTYPE 00 ; 45 NOT ON K4 40 ; 46 " @ ( SHIFT - 2 ) 23 ; 47 # # ( SHIFT - 3 ) 3F ; 48 NOT ON K4 ? 00 ; 49 NOT ON K4 29 ; 4A NOT ON K4 ) 00 ; 4B NOT ON K4 00 ; 4C NOT ON K4 00 ; 4D NOT ON K4 00 ; 4E NOT ON K4 00 ; 4F NOT ON K4 00 ; 50 NOT ON K4 00 ; 51 NOT ON K4 00 ; 52 NOT ON K4 00 ; 53 NOT ON K4 CE ; 54 NOT ON K4 SHIFT-LEFT ARROW 00 ; 55 NOT ON K4 00 ; 56 NOT ON K4 00 ; 57 NOT ON K4 00 ; 58 NOT ON K4 00 ; 59 NOT ON K4 00 ; 5A NOT ON K4 00 ; 5B NOT ON K4 26 ; 5C ' & 00 ; 5D NOT ON K4 44 ; 5E F8 D 00 ; 5F NOT ON K4 21 ; 60 ! ! ( SHIFT - 1 ) 00 ; 61 NOT ON K4 00 ; 62 NOT ON K4 00 ; 63 NOT ON K4 00 ; 64 NOT ON K4 00 ; 65 NOT ON K4 00 ; 66 NOT ON K4 00 ; 67 NOT ON K4 00 ; 68 NOT ON K4 00 ; 69 NOT ON K4 00 ; 6A NOT ON K4 00 ; 6B NOT ON K4 00 ; 6C NOT ON K4 00 ; 6D NOT ON K4 00 ; 6E NOT ON K4 00 ; 6F NOT ON K4 00 ; 70 NOT ON K4 00 ; 71 NOT ON K4 00 ; 72 NOT ON K4 00 ; 73 NOT ON K4 00 ; 74 NOT ON K4 00 ; 75 NOT ON K4 00 ; 76 NOT ON K4 00 ; 77 NOT ON K4 00 ; 78 NOT ON K4 00 ; 79 NOT ON K4 00 ; 7A NOT ON K4 24 ; 7B $ $ ( SHIFT - 4 ) 2A ; 7C ( * ( SHIFT - 8 ) 25 ; 7D % % ( SHIFT - 5 ) 00 ; 7E NOT ON K4 C4 ; 7F NOT ON K4 ( SHIFT - FINISH ) ; TABLE NUMBER 3 - CODE CHORD WIDTH 1 ; Finesse iKey ; iKey - Standard Key - Finesse Key BE ; 00 NOT ON K4 CODE-SHIFT-[ 8B ; 01 NOT ON K4 CODE-DOWN ARROW 80 ; 02 NOT ON K4 CODE-HELP 92 ; 03 NOT ON K4 CODE-RIGHT ARROW 00 ; 04 NOT ON K4 CODE-CODE(SPECIAL KEYS) C1 ; 05 NOT ON K4 CODE-SHIFT-A 80 ; 06 NOT ON K4 CODE-HELP FF ; 07 NOT ON K4 CODE-DELETE 9B ; 08 NOT ON K4 CODE-GO 89 ; 09 NOT ON K4 CODE-TAB !49036434 AC ; 0A NOT ON K4 CODE-- 81 ; 0B NOT ON K4 CODE-UP ARROW 80 ; 0C NOT ON K4 CODE-HELP 8A ; 0D NOT ON K4 CODE-NEXT 20 ; 0E NOT ON K4 SPACE A2 ; 0F NOT ON K4 CODE-SHIFT-' 00 ; 10 NOT ON K4 HELP D3 ; 11 NOT ON K4 CODE-SHIFT-S C3 ; 12 NOT ON K4 CODE-SHIFT-C 87 ; 13 NOT ON K4 CODE-CANCEL 94 ; 14 NOT ON K4 CODE-COPY 95 ; 15 NOT ON K4 CODE-F1 96 ; 16 NOT ON K4 CODE-F2 97 ; 17 NOT ON K4 CODE-F3 98 ; 18 NOT ON K4 CODE-F4 99 ; 19 NOT ON K4 CODE-F5 9A ; 1A NOT ON K4 CODE-F6 AB ; 1B NOT ON K4 CODE-SHIFT-= ( CODE-+) 9C ; 1C NOT ON K4 CODE-F7 9D ; 1D NOT ON K4 CODE-F8 9E ; 1E NOT ON K4 CODE-F9 9F ; 1F NOT ON K4 CODE-F10 80 ; 20 NOT ON K4 CODE-HELP A8 ; 21 NOT ON K4 CODE-SHIFT-9 00 ; 22 NOT ON K4 00 ; 23 NOT ON K4 00 ; 24 NOT ON K4 00 ; 25 NOT ON K4 00 ; 26 NOT ON K4 80 ; 27 NOT ON K4 00 ; 28 NOT ON K4 00 ; 29 NOT ON K4 00 ; 2A NOT ON K4 00 ; 2B NOT ON K4 CODE-. (Shift-Lock) 80 ; 2C NOT ON K4 AD ; 2D NOT ON K4 CODE-- A7 ; 2E NOT ON K4 CODE-' 80 ; 2F NOT ON K4 AF ; 30 NOT ON K4 CODE-/ 85 ; 31 NOT ON K4 CODE-PREV PAGE 91 ; 32 NOT ON K4 CODE-SCROLL UP 93 ; 33 NOT ON K4 CODE-SCROLL DOWN 82 ; 34 NOT ON K4 CODE-MARK 8D ; 35 NOT ON K4 CODE-BOUND CC ; 36 NOT ON K4 CODE-SHIFT-L BB ; 37 NOT ON K4 CODE-; D6 ; 38 NOT ON K4 CODE-SHIFT-V C2 ; 39 NOT ON K4 CODE-SHIFT-B 00 ; 3A NOT ON K4 80 ; 3B NOT ON K4 00 ; 3C NOT ON K4 00 ; 3D NOT ON K4 00 ; 3E NOT ON K4 80 ; 3F NOT ON K4 80 ; 40 NOT ON K4 83 ; 41 NOT ON K4 CODE-SHIFT-6 BD ; 42 NOT ON K4 CODE-= 80 ; 43 NOT ON K4 D0 ; 44 NOT ON K4 80 ; 45 NOT ON K4 CD ; 46 NOT ON K4 SHIFT-F8 for API A3 ; 47 NOT ON K4 CODE-SHIFT-3 BF ; 48 NOT ON K4 CODE-SHIFT-/ 80 ; 49 NOT ON K4 A9 ; 4A NOT ON K4 CODE-SHIFT-0 80 ; 4B NOT ON K4 80 ; 4C NOT ON K4 80 ; 4D NOT ON K4 80 ; 4E NOT ON K4 80 ; 4F NOT ON K4 80 ; 50 NOT ON K4 80 ; 51 NOT ON K4 80 ; 52 NOT ON K4 80 ; 53 NOT ON K4 8E ; 54 NOT ON K4 CODE-LEFT ARROW 80 ; 55 NOT ON K4 80 ; 56 NOT ON K4 80 ; 57 NOT ON K4 80 ; 58 NOT ON K4 00 ; 59 NOT ON K4 80 ; 5A NOT ON K4 80 ; 5B NOT ON K4 A6 ; 5C NOT ON K4 CODE-SHIFT-7 80 ; 5D NOT ON K4 8C ; 5E NOT ON K4 CODE-NEXT PAGE 80 ; 5F NOT ON K4 D8 ; 60 NOT ON K4 SHIFT-F4 for API 80 ; 61 NOT ON K4 80 ; 62 NOT ON K4 80 ; 63 NOT ON K4 80 ; 64 NOT ON K4 80 ; 65 NOT ON K4 80 ; 66 NOT ON K4 80 ; 67 NOT ON K4 80 ; 68 NOT ON K4 80 ; 69 NOT ON K4 80 ; 6A NOT ON K4 80 ; 6B NOT ON K4 80 ; 6C NOT ON K4 80 ; 6D NOT ON K4 80 ; 6E NOT ON K4 80 ; 6F NOT ON K4 80 ; 70 NOT ON K4 80 ; 71 NOT ON K4 80 ; 72 NOT ON K4 80 ; 73 NOT ON K4 80 ; 74 NOT ON K4 80 ; 75 NOT ON K4 80 ; 76 NOT ON K4 80 ; 77 NOT ON K4 80 ; 78 NOT ON K4 80 ; 79 NOT ON K4 80 ; 7A NOT ON K4 A4 ; 7B NOT ON K4 CODE-SHIFT-4 AA ; 7C NOT ON K4 CODE-SHIFT-8 A5 ; 7D NOT ON K4 CODE-SHIFT-5 80 ; 7E NOT ON K4 84 ; 7F NOT ON K4 CODE-FINISH ; TABLE NUMBER 4 - SHIFT AND CODE CHORD WIDTH 1 ; Finesse iKey ; iKey - Standard Key - Finesse Key 94 ; 00 C1 ; 01 80 ; 02 92 ; 03 00 ; 04 E1 ; 05 NOT ON K4 CODE-a 80 ; 06 FF ; 07 9B ; 08 80 ; 09 FD ; 0A CB ; 0B FA ; 0C NOT ON K4 CODE-z 8A ; 0D A0 ; 0E FE ; 0F 00 ; 10 F3 ; 11 NOT ON K4 CODE-s E3 ; 12 NOT ON K4 CODE-c F8 ; 13 NOT ON K4 CODE-x 00 ; 14 F1 ; 15 NOT ON K4 CODE-q F7 ; 16 NOT ON K4 CODE-w E5 ; 17 NOT ON K4 CODE-e F2 ; 18 NOT ON K4 CODE-r F4 ; 19 NOT ON K4 CODE-t F9 ; 1A NOT ON K4 CODE-y AB ; 1B F5 ; 1C NOT ON K4 CODE-u E9 ; 1D NOT ON K4 CODE-i EF ; 1E NOT ON K4 CODE-o F0 ; 1F NOT ON K4 CODE-p 80 ; 20 B9 ; 21 00 ; 22 00 ; 23 00 ; 24 00 ; 25 00 ; 26 80 ; 27 00 ; 28 00 ; 29 00 ; 2A 00 ; 2B ( Shift - Lock 2-13-92 ) 80 ; 2C ED ; 2D NOT ON K4 CODE-m AE ; 2E 80 ; 2F EE ; 30 NOT ON K4 CODE-n E6 ; 31 NOT ON K4 CODE-f E7 ; 32 NOT ON K4 CODE-g E8 ; 33 NOT ON K4 CODE-h EA ; 34 NOT ON K4 CODE-j EB ; 35 NOT ON K4 CODE-k EC ; 36 NOT ON K4 CODE-l FB ; 37 F6 ; 38 NOT ON K4 CODE-v E2 ; 39 NOT ON K4 CODE-b 00 ; 3A 80 ; 3B 00 ; 3C 00 ; 3D 00 ; 3E 80 ; 3F 80 ; 40 B6 ; 41 BD ; 42 80 ; 43 D0 ; 44 80 ; 45 B2 ; 46 B3 ; 47 BE ; 48 80 ; 49 B0 ; 4A 80 ; 4B 80 ; 4C 80 ; 4D 80 ; 4E 80 ; 4F 80 ; 50 80 ; 51 80 ; 52 80 ; 53 00 ; 54 80 ; 55 80 ; 56 80 ; 57 80 ; 58 00 ; 59 80 ; 5A 80 ; 5B B7 ; 5C 80 ; 5D E4 ; 5E NOT ON K4 CODE-d 80 ; 5F B1 ; 60 80 ; 61 80 ; 62 80 ; 63 80 ; 64 80 ; 65 80 ; 66 80 ; 67 80 ; 68 80 ; 69 80 ; 6A 80 ; 6B 80 ; 6C 80 ; 6D 80 ; 6E 80 ; 6F 80 ; 70 80 ; 71 80 ; 72 80 ; 73 80 ; 74 80 ; 75 80 ; 76 80 ; 77 80 ; 78 80 ; 79 80 ; 7A B4 ; 7B B8 ; 7C B5 ; 7D 80 ; 7E 84 ; 7F END TABLES EMULATION DATA EXISTS ; <<<<<<<<<<<<< START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ K1 Keyboard IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of emulation tables in hex ; | | | | ; | | | | :-- Target translation table in hex ; | | | | | ; 80 90 80 4 90 ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K4 keyboard. For example the "delete" key returns "7F h". For the K4 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have at least 19 and at most 29 entries and they MUST ; be in the order shown. 22 ; Number special keys 05 ;A 39 ;B 13 ;CANCEL - 7 44 ;OVERTYPE 04 ;LEFT CODE 04 ;RIGHT CODE 7F ;FINISH 43 ;ACTION 2B ;LOCK ( Shift - Lock 2-13-92 ) 14 ;LEFT SHIFT 14 ;RIGHT SHIFT FFFF ;RESERVED Mouse Disable FFFF ;RESERVED Mouse Enable FFFF ;RESERVED Alt Key 0C ;HELP 08 ;GO - 1B 40 ;NULL 20 ;DIACRITIC ESCAPE 0 ;SYS KEY 00;OS1 00;OS2 00;OS3 END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default LEDs is included. 13 ; Number of LEDs on keyboard ;0 means don't remap. FF means not supported. Valid non-zero value is the 1- ;based LED numberthat will be converted to a command valid for the new target ;hardware as follows: 1h,2h,4h,8h,10h,20h,40h,80h; LEDs >8 on the Kx style ;keyboards are handled according to the rquirement described in the hardware ;spec. 00 ; CTOS LED 1 - f10 00 ; 2 - f9 00 ; 3 - f8 00 ; 4 - f3 00 ; 5 - f2 00 ; 6 - f1 00 ; 7 - LOCK 00 ; 8 - Overtype 00 ; 9 - Comm1 00 ; 10 - Comm2 00 ; 11 - Comm3 00 ; 12 - Comm4 00 ; 13 - Comm5 99 ; 14 - 'Numlock' 99 ; 15 - 'Scroll Lock' 99 ; END LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for Emulation table ; ; 3 ; Number of entries ; ; !!! ALL NUMBERS IN THE FOLLOWING TABLE MUST BE IN HEX ; ; key bMask* fToggle fLed LED mask** ; number bit bit fExclus- ; position position ionary ; (hex) (hex) (hex) ; 14 0 F F 0 F ; Chord #1 04 1 F F 0 F ; Chord #2 2B 2 T T 1 F ; Chord #3 2-13 END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; ------------------ ------ --------- { 1,2 } ; 00 { 1,2 } ; 01 { 1,2 } ; 02 { 1,2 } ; 03 { 2 } ; 04 { 1,2,3 } ; 05 EC or A { 1,2 } ; 06 { 1,2 } ; 07 { 1,2 } ; 08 { 1,2 } ; 09 { 1,2 } ; 0A { 1,2 } ; 0B { 1,2,3 } ; 0C COPY or Z { 1,2 } ; 0D { 1,2 } ; 0E { 1,2 } ; 0F { 1,2 } ; 10 { 1,2,3 } ; 11 RV or S { 1,2,3 } ; 12 DEL CHAR or C { 1,2,3 } ; 13 CANCEL or X { 1,2 } ; 14 { 1,2,3 } ; 15 F1 or Q { 1,2,3 } ; 16 F2 or W { 1,2,3 } ; 17 F3 or E { 1,2,3 } ; 18 F4 or R { 1,2,3 } ; 19 F5 or T { 1,2,3 } ; 1A F6 or Y { 1,2 } ; 1B { 1,2,3 } ; 1C F7 or U { 1,2,3 } ; 1D F8 or I { 1,2,3 } ; 1E F9 or O { 1,2,3 } ; 1F F10 or P { 1,2 } ; 20 { 1,2 } ; 21 { 1,2 } ; 22 { 1,2 } ; 23 { 1,2 } ; 24 { 1,2 } ; 25 { 1,2 } ; 26 { 1,2 } ; 27 { 1,2 } ; 28 { 1,2 } ; 29 { 1,2 } ; 2A { 3 } ; 2B ( Shift - Lock 2-13-92 ) { 1,2 } ; 2C { 1,2,3 } ; 2D - or M { 1,2 } ; 2E { 1,2 } ; 2F { 1,2,3 } ; 30 / or N { 1,2,3 } ; 31 PREV PAGE or F { 1,2,3 } ; 32 SCROLL UP or G { 1,2,3 } ; 33 SCROLL DOWN or H { 1,2,3 } ; 34 MARK or J { 1,2,3 } ; 35 BOUND or K { 1,2,3 } ; 36 TLR A or L { 1,2 } ; 37 { 1,2,3 } ; 38 % or V { 1,2,3 } ; 39 * or B { 1,2 } ; 3A { 1,2 } ; 3B { 1,2 } ; 3C { 1,2 } ; 3D { 1,2 } ; 3E { 1,2 } ; 3F { 1,2 } ; 40 { 1,2 } ; 41 { 1,2 } ; 42 { 1,2 } ; 43 { 1,2 } ; 44 { 3 } ; 45 { 1,2 } ; 46 { 1,2 } ; 47 { 1,2 } ; 48 { 1,2 } ; 49 { 1,2 } ; 4A { 1,2 } ; 4B { 1,2 } ; 4C { 1,2 } ; 4D { 1,2 } ; 4E { 1,2 } ; 4F { 1,2 } ; 50 { 1,2 } ; 51 { 1,2 } ; 52 { 1,2 } ; 53 { 1,2 } ; 54 { 1,2 } ; 55 { 1,2 } ; 56 { 1,2 } ; 57 { 1,2 } ; 58 { 1,2 } ; 59 { 1,2 } ; 5A { 1,2 } ; 5B { 1,2 } ; 5C { 1,2 } ; 5D { 1,2,3 } ; 5E NEXT PAGE or D { 1,2 } ; 5F { 1,2 } ; 60 { 1,2 } ; 61 { 1,2 } ; 62 { 1,2 } ; 63 { 1,2 } ; 64 { 1,2 } ; 65 { 1,2 } ; 66 { 1,2 } ; 67 { 1,2 } ; 68 { 1,2 } ; 69 { 1,2 } ; 6A { 1,2 } ; 6B { 1,2 } ; 6C { 1,2 } ; 6D { 1,2 } ; 6E { 1,2 } ; 6F { 1,2 } ; 70 { 1,2 } ; 71 { 1,2 } ; 72 { 1,2 } ; 73 { 1,2 } ; 74 { 1,2 } ; 75 { 1,2 } ; 76 { 1,2 } ; 77 { 1,2 } ; 78 { 1,2 } ; 79 { 1,2 } ; 7A { 1,2 } ; 7B { 1,2 } ; 7C { 1,2 } ; 7D { 1,2 } ; 7E { 1,2 } ; 7F END ALLOWED STATES TABLE START CONDITIONS 5 ; Number of conditions 0 { 0 } { 0 } { 0 } 1 { 1,3 } { 0 } { 0 } 2 { 2 } { 0 } { 0 } 3 { 1 } { 2 } { 0 } 2 { 3 } { 2 } { 0 } END CONDITIONS START MULTIBYTES 1 { 00:4A, 00:CA, 00:4A, 00:CA } END MULTIBYTES START DIACRITICS 0 END DIACRITICS START TABLES ; TABLE NUMBER 1 - NO CHORD ; Finesse iKey ; iKey - Standard Key - Finesse Key FF:0C ; 00 HELP COPY FF:01 ; 01 SCROLL UP DOWN ARROW FF:02 ; 02 NOT ON K4 FF:03 ; 03 BOUND RIGHT ARROW FF:04 ; 04 FINISH CODE ( SPECIAL KEYS ) FF:05 ; 05 I EC ( SHIFT - F5 ) FF:06 ; 06 NOT ON K4 FF:07 ; 07 CANCEL DELETE FF:08 ; 08 X GO FF:09 ; 09 NOT ON K4 FF:0A ; 0A Y SPD ( SHIFT - F7 ) FF:0B ; 0B NEXT PAGE UP ARROW FF:00 ; 0C Q HELP FF:0D ; 0D NEXT NEXT FF:0E ; 0E CODE SPACE FF:0F ; 0F SHIFT OVERLAY FF:10 ; 10 NOT ON K4 CODE HELP FF:11 ; 11 J RV ( SHIFT - F6 ) FF:12 ; 12 MOVE DEL CHAR FF:13 ; 13 R CANCEL FF:14 ; 14 COPY SHIFT 00 FF:15 ; 15 A F1 FF:16 ; 16 B F2 FF:17 ; 17 C F3 FF:18 ; 18 D F4 FF:19 ; 19 E F5 FF:1A ; 1A F F6 FF:1B ; 1B TAB + FF:1C ; 1C G F7 FF:1D ; 1D H F8 FF:1E ; 1E UP ARROW F9 FF:1F ; 1F DOWN ARROW F10 FF:20 ; 20 NOT ON K4 FF:21 ; 21 9 9 FF:22 ; 22 NOT ON K4 CODE-MARK FF:23 ; 23 NOT ON K4 CODE-FINISH FF:24 ; 24 NOT ON K4 CODE-1/2 FF:25 ; 25 NOT ON K4 FF:26 ; 26 NOT ON K4 FF:27 ; 27 NOT ON K4 FF:28 ; 28 NOT ON K4 FF:29 ; 29 NOT ON K4 FF:2A ; 2A NOT ON K4 FF:2B ; 2B W (SHIFT-LOCK 2-13-92) FF:2C ; 2C NOT ON K4 FF:2D ; 2D V - FF:2E ; 2E . . FF:2F ; 2F NOT ON K4 - FF:30 ; 30 U / FF:31 ; 31 L PREVIOUS PAGE FF:32 ; 32 M SCROLL UP FF:33 ; 33 N SCROLL DOWN FF:34 ; 34 O MARK FF:35 ; 35 P BOUND FF:36 ; 36 LEFT ARROW TLR A ( SHIFT - F9 ) FF:37 ; 37 RIGHT ARROW TLR B ( SHIFT - F10 ) FF:38 ; 38 S % FF:39 ; 39 T * FF:3A ; 3A 00 00 FF:3B ; 3B NOT ON K4 FF:3C ; 3C NOT ON K4 FF:3D ; 3D NOT ON K4 FF:3E ; 3E NOT ON K4 FF:3F ; 3F NOT ON K4 FF:40 ; 40 NOT ON K4 FF:41 ; 41 6 6 FF:42 ; 42 SPACE = FF:43 ; 43 ACTION ACTION FF:44 ; 44 OVERTYPE OVERTYPE FF:45 ; 45 NOT ON K4 FF:46 ; 46 2 2 FF:47 ; 47 3 3 FF:48 ; 48 GO STAT ( SHIFT - F8 ) FF:49 ; 49 NOT ON K4 FF:4A ; 4A 0 0 FF:4B ; 4B NOT ON K4 FF:4C ; 4C NOT ON K4 FF:4D ; 4D NOT ON K4 FF:4E ; 4E NOT ON K4 FF:4F ; 4F NOT ON K4 FF:50 ; 50 NOT ON K4 FF:51 ; 51 NOT ON K4 FF:52 ; 52 NOT ON K4 FF:53 ; 53 NOT ON K4 FF:54 ; 54 NOT ON K4 FF:55 ; 55 NOT ON K4 FF:56 ; 56 NOT ON K4 FF:57 ; 57 NOT ON K4 FF:58 ; 58 NOT ON K4 FF:59 ; 59 NOT ON K4 FF:5A ; 5A NOT ON K4 FF:5B ; 5B NOT ON K4 FF:5C ; 5C 7 7 FF:5D ; 5D NOT ON K4 FF:5E ; 5E K NEXT PAGE FF:5F ; 5F NOT ON K4 FF:60 ; 60 1 1 FF:61 ; 61 NOT ON K4 FF:62 ; 62 NOT ON K4 FF:63 ; 63 NOT ON K4 FF:63 ; 64 NOT ON K4 FF:65 ; 65 NOT ON K4 FF:66 ; 66 NOT ON K4 FF:67 ; 67 NOT ON K4 FF:68 ; 68 NOT ON K4 FF:69 ; 69 NOT ON K4 FF:6A ; 6A NOT ON K4 FF:6B ; 6B NOT ON K4 FF:6C ; 6C NOT ON K4 FF:6D ; 6D NOT ON K4 FF:6E ; 6E NOT ON K4 FF:6F ; 6F NOT ON K4 FF:70 ; 70 NOT ON K4 FF:71 ; 71 NOT ON K4 FF:72 ; 72 NOT ON K4 FF:73 ; 73 NOT ON K4 FF:74 ; 74 NOT ON K4 FF:75 ; 75 NOT ON K4 FF:76 ; 76 NOT ON K4 FF:77 ; 77 NOT ON K4 FF:78 ; 78 NOT ON K4 FF:79 ; 79 NOT ON K4 FF:7A ; 7A NOT ON K4 FF:7B ; 7B 4 4 FF:7C ; 7C 8 8 FF:7D ; 7D 5 5 FF:7E ; 7E NOT ON K4 FF:7F ; 7F DELETE FINISH ; TABLE NUMBER 2 - SHIFT or LOCK CHORD ; Finesse iKey ; iKey - Standard Key - Finesse Key FF:00 ; 00 NOT ON K4 > FF:01 ; 01 SCROLL DOWN SHIFT DOWN ARROW FF:02 ; 02 NOT ON K4 FF:03 ; 03 NOT ON K4 SHIFT RIGHT ARROW FF:04 ; 04 NOT ON K4 FF:05 ; 05 F6 A FF:06 ; 06 NOT ON K4 FF:07 ; 07 NOT ON K4 - < FF:08 ; 08 NOT ON K4 - GO FF:09 ; 09 NOT ON K4 - FF:0A ; 0A Z , FF:0B ; 0B PREV PAGE SHIFT UP ARROW FF:0C ; 0C ? Z FF:0D ; 0D NEXT NEXT FF:0E ; 0E NOT ON K4 SPACE FF:0F ; 0F NOT ON K4 " FF:10 ; 10 NOT ON K4 CODE UP ARROW FF:11 ; 11 F7 S FF:12 ; 12 NOT ON K4 C FF:13 ; 13 : X FF:14 ; 14 NOT ON K4 FF:15 ; 15 F1 Q FF:16 ; 16 F2 W FF:17 ; 17 F3 E FF:18 ; 18 F4 R FF:19 ; 19 F5 T FF:1A ; 1A < Y FF:1B ; 1B BACKSPACE [ FF:1C ; 1C > U FF:1D ; 1D ' I FF:1E ; 1E NOT ON K4 O FF:1F ; 1F NOT ON K4 P FF:20 ; 20 NOT ON K4 FF:21 ; 21 ) ( FF:22 ; 22 NOT ON K4 SHIFT-R' FF:23 ; 23 NOT ON K4 SHIFT-0' FF:24 ; 24 NOT ON K4 SHIFT-NEXT' FF:25 ; 25 NOT ON K4 FF:26 ; 26 NOT ON K4 FF:27 ; 27 NOT ON K4 FF:28 ; 28 NOT ON K4 FF:29 ; 29 NOT ON K4 FF:2A ; 2A NOT ON K4 FF:2B ; 2B = . FF:2C ; 2C NOT ON K4 FF:2D ; 2D / M FF:2E ; 2E NOT ON K4 - ' FF:2F ; 2F NOT ON K4 FF:30 ; 30 - N FF:31 ; 31 F9 F FF:32 ; 32 F10 G FF:33 ; 33 [ H FF:34 ; 34 ] J FF:35 ; 35 ; K FF:36 ; 36 NOT ON K4 L FF:37 ; 37 NOT ON K4 ; FF:38 ; 38 * V FF:39 ; 39 + B FF:3A ; 3A NOT ON K4 : FF:3B ; 3B NOT ON K4 FF:3C ; 3C NOT ON K4 FF:3D ; 3D NOT ON K4 FF:3E ; 3E NOT ON K4 FF:3F ; 3F NOT ON K4 FF:40 ; 40 NOT ON K4 FF:41 ; 41 &  ( SHIFT - 6 ) FF:42 ; 42 NOT ON K4 ] FF:43 ; 43 NOT ON K4 FF:44 ; 44 NOT ON K4 OVERTYPE FF:45 ; 45 NOT ON K4 FF:46 ; 46 " @ ( SHIFT - 2 ) FF:47 ; 47 # # ( SHIFT - 3 ) FF:48 ; 48 NOT ON K4 ? FF:49 ; 49 NOT ON K4 FF:4A ; 4A NOT ON K4 ) FF:4B ; 4B NOT ON K4 FF:4C ; 4C NOT ON K4 FF:4D ; 4D NOT ON K4 FF:4E ; 4E NOT ON K4 FF:4F ; 4F NOT ON K4 FF:50 ; 50 NOT ON K4 FF:51 ; 51 NOT ON K4 FF:52 ; 52 NOT ON K4 FF:53 ; 53 NOT ON K4 FF:54 ; 54 NOT ON K4 FF:55 ; 55 NOT ON K4 FF:56 ; 56 NOT ON K4 FF:57 ; 57 NOT ON K4 FF:58 ; 58 NOT ON K4 FF:59 ; 59 NOT ON K4 FF:5A ; 5A NOT ON K4 FF:5B ; 5B NOT ON K4 FF:5C ; 5C ' & FF:5D ; 5D NOT ON K4 FF:5E ; 5E F8 D FF:5F ; 5F NOT ON K4 FF:60 ; 60 ! ! ( SHIFT - 1 ) FF:61 ; 61 NOT ON K4 FF:62 ; 62 NOT ON K4 FF:63 ; 63 NOT ON K4 FF:64 ; 64 NOT ON K4 FF:65 ; 65 NOT ON K4 FF:66 ; 66 NOT ON K4 FF:67 ; 67 NOT ON K4 FF:68 ; 68 NOT ON K4 FF:69 ; 69 NOT ON K4 FF:6A ; 6A NOT ON K4 FF:6B ; 6B NOT ON K4 FF:6C ; 6C NOT ON K4 FF:6D ; 6D NOT ON K4 FF:6E ; 6E NOT ON K4 FF:6F ; 6F NOT ON K4 FF:70 ; 70 NOT ON K4 FF:71 ; 71 NOT ON K4 FF:72 ; 72 NOT ON K4 FF:73 ; 73 NOT ON K4 FF:74 ; 74 NOT ON K4 FF:75 ; 75 NOT ON K4 FF:76 ; 76 NOT ON K4 FF:77 ; 77 NOT ON K4 FF:78 ; 78 NOT ON K4 FF:79 ; 79 NOT ON K4 FF:7A ; 7A NOT ON K4 FF:7B ; 7B $ $ ( SHIFT - 4 ) FF:7C ; 7C ( * ( SHIFT - 8 ) FF:7D ; 7D % % ( SHIFT - 5 ) FF:7E ; 7E NOT ON K4 FF:7F ; 7F NOT ON K4 ( SHIFT - FINISH ) ; TABLE NUMBER 3 - CODE CHORD ; Finesse iKey ; iKey - Standard Key - Finesse Key FF:00 ; 00 NOT ON K4 CODE-SHIFT-[ FF:01 ; 01 NOT ON K4 CODE-DOWN ARROW FF:02 ; 02 NOT ON K4 CODE-HELP FF:03 ; 03 NOT ON K4 CODE-RIGHT ARROW FF:04 ; 04 NOT ON K4 CODE-CODE(SPECIAL KEYS) FF:05 ; 05 NOT ON K4 CODE-SHIFT-A FF:06 ; 06 NOT ON K4 CODE-HELP FF:07 ; 07 NOT ON K4 CODE-DELETE FF:08 ; 08 NOT ON K4 CODE-GO FF:09 ; 09 NOT ON K4 CODE-HELP FF:0A ; 0A NOT ON K4 CODE-- FF:0B ; 0B NOT ON K4 CODE-UP ARROW FF:0C ; 0C NOT ON K4 CODE-HELP FF:0D ; 0D NOT ON K4 CODE-NEXT FF:0E ; 0E NOT ON K4 SPACE FF:0F ; 0F NOT ON K4 CODE-SHIFT-' FF:10 ; 10 NOT ON K4 HELP FF:11 ; 11 NOT ON K4 CODE-SHIFT-S FF:12 ; 12 NOT ON K4 CODE-SHIFT-C FF:13 ; 13 NOT ON K4 CODE-CANCEL FF:14 ; 14 NOT ON K4 CODE-COPY FF:15 ; 15 NOT ON K4 CODE-F1 FF:16 ; 16 NOT ON K4 CODE-F2 FF:17 ; 17 NOT ON K4 CODE-F3 FF:18 ; 18 NOT ON K4 CODE-F4 FF:19 ; 19 NOT ON K4 CODE-F5 FF:1A ; 1A NOT ON K4 CODE-F6 FF:1B ; 1B NOT ON K4 CODE-SHIFT-= ( CODE-+) FF:1C ; 1C NOT ON K4 CODE-F7 FF:1D ; 1D NOT ON K4 CODE-F8 FF:1E ; 1E NOT ON K4 CODE-F9 FF:1F ; 1F NOT ON K4 CODE-F10 FF:20 ; 20 NOT ON K4 CODE-HELP FF:21 ; 21 NOT ON K4 CODE-SHIFT-9 FF:22 ; 22 NOT ON K4 FF:23 ; 23 NOT ON K4 FF:24 ; 24 NOT ON K4 FF:25 ; 25 NOT ON K4 FF:26 ; 26 NOT ON K4 FF:27 ; 27 NOT ON K4 FF:28 ; 28 NOT ON K4 FF:29 ; 29 NOT ON K4 FF:2A ; 2A NOT ON K4 FF:2B ; 2B NOT ON K4 CODE-. FF:2C ; 2C NOT ON K4 FF:2D ; 2D NOT ON K4 CODE-- FF:2E ; 2E NOT ON K4 CODE-' FF:2F ; 2F NOT ON K4 FF:30 ; 30 NOT ON K4 CODE-/ FF:31 ; 31 NOT ON K4 CODE-PREV PAGE FF:32 ; 32 NOT ON K4 CODE-SCROLL UP FF:33 ; 33 NOT ON K4 CODE-SCROLL DOWN FF:34 ; 34 NOT ON K4 CODE-MARK FF:35 ; 35 NOT ON K4 CODE-BOUND FF:36 ; 36 NOT ON K4 CODE-SHIFT-L FF:37 ; 37 NOT ON K4 CODE-; FF:38 ; 38 NOT ON K4 CODE-SHIFT-V FF:39 ; 39 NOT ON K4 CODE-SHIFT-B FF:3A ; 3A NOT ON K4 FF:3B ; 3B NOT ON K4 FF:3C ; 3C NOT ON K4 FF:3D ; 3D NOT ON K4 FF:3E ; 3E NOT ON K4 FF:3F ; 3F NOT ON K4 FF:40 ; 40 NOT ON K4 FF:41 ; 41 NOT ON K4 CODE-SHIFT-6 FF:42 ; 42 NOT ON K4 CODE-= FF:43 ; 43 NOT ON K4 FF:44 ; 44 NOT ON K4 FF:45 ; 45 NOT ON K4 FF:46 ; 46 NOT ON K4 CODE-SHIFT-2 FF:47 ; 47 NOT ON K4 CODE-SHIFT-3 FF:48 ; 48 NOT ON K4 CODE-SHIFT-/ FF:49 ; 49 NOT ON K4 FF:4A ; 4A NOT ON K4 CODE-SHIFT-0 FF:4B ; 4B NOT ON K4 FF:4C ; 4C NOT ON K4 FF:4D ; 4D NOT ON K4 FF:4E ; 4E NOT ON K4 FF:4F ; 4F NOT ON K4 FF:50 ; 50 NOT ON K4 FF:51 ; 51 NOT ON K4 FF:52 ; 52 NOT ON K4 FF:53 ; 53 NOT ON K4 FF:54 ; 54 NOT ON K4 FF:55 ; 55 NOT ON K4 FF:56 ; 56 NOT ON K4 FF:57 ; 57 NOT ON K4 FF:58 ; 58 NOT ON K4 FF:59 ; 59 NOT ON K4 FF:5A ; 5A NOT ON K4 FF:5B ; 5B NOT ON K4 FF:5C ; 5C NOT ON K4 CODE-SHIFT-7 FF:5D ; 5D NOT ON K4 FF:5E ; 5E NOT ON K4 CODE-NEXT PAGE FF:5F ; 5F NOT ON K4 FF:60 ; 60 NOT ON K4 CODE-SHIFT-1 FF:61 ; 61 NOT ON K4 FF:62 ; 62 NOT ON K4 FF:63 ; 63 NOT ON K4 FF:64 ; 64 NOT ON K4 FF:65 ; 65 NOT ON K4 FF:66 ; 66 NOT ON K4 FF:67 ; 67 NOT ON K4 FF:68 ; 68 NOT ON K4 FF:69 ; 69 NOT ON K4 FF:6A ; 6A NOT ON K4 FF:6B ; 6B NOT ON K4 FF:6C ; 6C NOT ON K4 FF:6D ; 6D NOT ON K4 FF:6E ; 6E NOT ON K4 FF:6F ; 6F NOT ON K4 FF:70 ; 70 NOT ON K4 FF:71 ; 71 NOT ON K4 FF:72 ; 72 NOT ON K4 FF:73 ; 73 NOT ON K4 FF:74 ; 74 NOT ON K4 FF:75 ; 75 NOT ON K4 FF:76 ; 76 NOT ON K4 FF:77 ; 77 NOT ON K4 FF:78 ; 78 NOT ON K4 FF:79 ; 79 NOT ON K4 FF:7A ; 7A NOT ON K4 FF:7B ; 7B NOT ON K4 CODE-SHIFT-4 FF:7C ; 7C NOT ON K4 CODE-SHIFT-8 FF:7D ; 7D NOT ON K4 CODE-SHIFT-5 FF:7E ; 7E NOT ON K4 FF:7F ; 7F NOT ON K4 CODE-FINISH ; TABLE NUMBER 4 - SHIFT AND CODE CHORD ( NOT IMPLEMENTED ) FF:00 ; 00 FF:01 ; 01 FF:02 ; 02 FF:03 ; 03 FF:04 ; 04 FF:05 ; 05 FF:06 ; 06 FF:07 ; 07 FF:08 ; 08 FF:09 ; 09 FF:0A ; 0A FF:0B ; 0B FF:0C ; 0C FF:0D ; 0D FF:0E ; 0E FF:0F ; 0F FF:10 ; 10 FF:11 ; 11 FF:12 ; 12 FF:13 ; 13 FF:14 ; 14 FF:15 ; 15 FF:16 ; 16 FF:17 ; 17 FF:18 ; 18 FF:19 ; 19 FF:1A ; 1A FF:1B ; 1B FF:1C ; 1C FF:1D ; 1D FF:1E ; 1E FF:1F ; 1F FF:20 ; 20 FF:21 ; 21 FF:22 ; 22 FF:23 ; 23 FF:24 ; 24 FF:25 ; 25 FF:26 ; 26 FF:27 ; 27 FF:28 ; 28 FF:29 ; 29 FF:2A ; 2A FF:2B ; 2B FF:2C ; 2C FF:2D ; 2D FF:2E ; 2E FF:2F ; 2F FF:30 ; 30 FF:31 ; 31 FF:32 ; 32 FF:33 ; 33 FF:34 ; 34 FF:35 ; 35 FF:36 ; 36 FF:37 ; 37 FF:38 ; 38 FF:39 ; 39 FF:3A ; 3A FF:3B ; 3B FF:3C ; 3C FF:3D ; 3D FF:3E ; 3E FF:3F ; 3F FF:40 ; 40 FF:41 ; 41 FF:42 ; 42 FF:43 ; 43 FF:44 ; 44 FF:45 ; 45 FF:46 ; 46 FF:47 ; 47 FF:48 ; 48 FF:49 ; 49 FF:4A ; 4A FF:4B ; 4B FF:4C ; 4C FF:4D ; 4D FF:4E ; 4E FF:4F ; 4F FF:50 ; 50 FF:51 ; 51 FF:52 ; 52 FF:53 ; 53 FF:54 ; 54 FF:55 ; 55 FF:56 ; 56 FF:57 ; 57 FF:58 ; 58 FF:59 ; 59 FF:5A ; 5A FF:5B ; 5B FF:5C ; 5C FF:5D ; 5D FF:5E ; 5E FF:5F ; 5F FF:60 ; 60 FF:61 ; 61 FF:62 ; 62 FF:63 ; 63 FF:64 ; 64 FF:65 ; 65 FF:66 ; 66 FF:67 ; 67 FF:68 ; 68 FF:69 ; 69 FF:6A ; 6A FF:6B ; 6B FF:6C ; 6C FF:6D ; 6D FF:6E ; 6E FF:6F ; 6F FF:70 ; 70 FF:71 ; 71 FF:72 ; 72 FF:73 ; 73 FF:74 ; 74 FF:75 ; 75 FF:76 ; 76 FF:77 ; 77 FF:78 ; 78 FF:79 ; 79 FF:7A ; 7A FF:7B ; 7B FF:7C ; 7C FF:7D ; 7D FF:7E ; 7E FF:7F ; 7F END TABLES /***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* 51.kbd_data */ /* */ /* This file contains the text version of the table that causes a K3 or */ /* a K5 keyboard to emulate a K1 keyboard for the OS version of */ /* "NlsKbd.sys". */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION */ /* */ /* 09/29/92 12.3.A.01 V. Miller / iKey 23 returns FFFF:FF. */ /* */ /* 03/20/92 12.2.G.01 V. Miller / Added comments documenting how the */ /* emulated LEDs table should work. */ /* V. Miller & K. Hampton / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; ; This is the data file for the K5 Keyboard that is used by the "Create ; Keyboard Table" Application. The format is translation tables for a ; K1 keyboard followed by emulation tables that convert K5 iKeys to the ; K1 iKey values that produce the same effect. ; ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; ; Changes: ; ; 11/14/91 vjm Removed emulation of to be for XVT ; All instances of "0009:" in the LAST emulation table ; replaced by "FFFF:" so if state has ALT key in it, ; the ALT key is passed through instead of being ; emulated. ; Keyboard name K5 ; Output file name K5KbdTables.obj ; Name of PUBLIC in object module at start of table K5KeyBoardData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ==================================================================== ; ; EMULATION DATA ; ; What follows is the data for having the PS2 keyboard emulate the K1 ; keyboard. That is given a PS2 state and key what K1 state and key ; would have to be pushed to give the same result ; EMULATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if emulation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ PS2 Keyboard IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of emulation tables in hex ; | | | | ; | | | | :-- Target translation table in hex ; | | | | | ; 80 EF 80 3 04 ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have at least 19 and at most 29 entries and they MUST ; be in the order shown. 22 ; Number special keys 61 ; a 62 ; b 7F ; 44 ; 4C ; 4D ; 04 ; 43 ; 45 ; 48 ; 49 ; 64 ; Mouse Disable 65 ; Mouse Enable 53 ; Alt Key 00 ; c 1B ; 40 ; iKey not valid 20 ; Diacritic Escape 52 ; Sys Key 00;OS1 00;OS2 00;OS3 END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default LEDs is included. 13 (NOT number of entries in table). This ; number must be 16 or less. ; The table below is used to specify what LED is turned on when a key that ; affects an LED is pressed. The table MUST have 16 entries. ; Enter the number of the LED to be actually be turned on when the code ; specifies the particular LED number. For example, the entry ; ; "03 ; 7" ; ; means that when an application specifies that LED 7 be turned on, ; actually turn on LED 03 (where both 3 and 7 are base 10). ; ; Other possible values ; ; ~ 0 means don't remap (or map to itself). For example, the entry ; ; "00 ; 8" ; ; means thet when an application specifies that LED 8 be turned on, ; don't change (or remap) what is to be turned on; actually turn on ; LED 08. ; ; ~ FF (or actually any number greater than 16) means not supported. ; For example, the entry ; ; "FF ; 9" ; ; means thet when an application specifies that LED 9 be turned on, ; nothing is turned on. ; ; When we say LED "x" is set, we mean that the current LED state is OR-ed ; with the "x-th" entry in the following array. ; ; "1h,2h,4h,8h,10h,20h,40h,80h" ; ; LEDs >8 on the Kx style keyboards are handled according to the ; rquirement described in the hardware spec. ; ; LED LED Key LED ; Actually Application Is On ; Turned Specifies ; On Be Turned On ; 00 ; 1 f10 00 ; 2 f9 00 ; 3 f8 00 ; 4 f3 00 ; 5 f2 00 ; 6 f1 00 ; 7 LOCK 00 ; 8 Overtype 00 ; 9 Comm1 00 ; 10 Comm2 00 ; 11 Comm3 00 ; 12 Comm4 00 ; 13 Comm5 99 ; 14 'Numlock' Not used on this keyboard 99 ; 15 'Scroll Lock' Not used on this keyboard 99 ; 16 Not used on this keyboard END LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for Emulation table ; ; 6 ; Number of entries ; ; !!! ALL NUMBERS IN THE FOLLOWING TABLE MUST BE IN HEX ; ; key bMask* fToggle fLed LED mask** ; number bit bit fExclus- ; position position ionary ; (hex) (hex) (hex) ; 48 0 F F 0 F ; Chord #1 49 1 F F 0 F ; Chord #2 4C 2 F F 0 F ; Chord #3 4D 3 F F 0 F ; Chord #4 45 4 T T 6 F ; Chord #5 53 5 F F 0 F ; Chord #6 END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; numbers are decimal ; ------------------ ------ --------- { 1,2,6 } ; 000 help { 1,2,6 } ; 001 up-arrow { 1,2,6 } ; 002 mark { 1,2,6 } ; 003 bound { 1,2,6 } ; 004 finish { 1,2,6 } ; 005 prev page { 1,2,6 } ; 006 1/2-1/4 { 1,2,6 } ; 007 cancel { 1,2,6 } ; 008 backspace { 1,2,6 } ; 009 tab { 1,2,6 } ; 00A return { 1,2,6 } ; 00B down-arrow { 1,2,6 } ; 00C next page { 1,2,6 } ; 00D next { 1,2,6 } ; 00E left-arrow { 1,2,6 } ; 00F right-arrow { 1,2,6 } ; 010 JUMP { 1,2,6 } ; 011 scroll-up { 1,2,6 } ; 012 move { 1,2,6 } ; 013 scroll-down { 1,2,6 } ; 014 copy { 1,2,6 } ; 015 f1 { 1,2,6 } ; 016 f2 { 1,2,6 } ; 017 f3 { 1,2,6 } ; 018 f4 { 1,2,6 } ; 019 f5 { 1,2,6 } ; 01A f6 { 1,2,6 } ; 01B GO { 1,2,6 } ; 01C f7 { 1,2,6 } ; 01D f8 { 1,2,6 } ; 01E f9 { 1,2,6 } ; 01F f10 { 1,2,6 } ; 020 space { 1,2,6 } ; 021 9 9 { 1,2,6 } ; 022 Delete char { 1,2,6 } ; 023 0 0 { 1,2,6 } ; 024 Numeric * { 1,2,6 } ; 025 Numeric / { 1,2,6 } ; 026 Column { 1,2,6 } ; 027 quotes { 1,2,6 } ; 028 PAGE { 1,2,6 } ; 029 PARAGRAPH { 1,2,6 } ; 02A SENTENCE { 1,2,6 } ; 02B plus equals { 1,2,6 } ; 02C commas { 1,2,6 } ; 02D - _ { 1,2,6 } ; 02E periods { 1,2,6 } ; 02F slash question mark { 1,2,6 } ; 030 0 right parens { 1,2,6 } ; 031 1 exclam mark { 1,2,6 } ; 032 2 at sign { 1,2,6 } ; 033 3 hash { 1,2,6 } ; 034 4 $ { 1,2,6 } ; 035 5 percent { 1,2,6 } ; 036 6 cent { 1,2,6 } ; 037 7 & { 1,2,6 } ; 038 8 * { 1,2,6 } ; 039 9 left parens { 1,2,6 } ; 03A Numeric = { 1,2,6 } ; 03B ; : { 1,2,6 } ; 03C WORD { 1,2,6 } ; 03D LINE { 1,2,6 } ; 03E Numeric Percent { 0 } ; 03F iKeyInvalid { 0 } ; 040 iKeyNoKeys { 1,2,6 } ; 041 6 6 { 1,2,6 } ; 042 - - { 0 } ; 043 reset { 1,2,6 } ; 044 overtype { 5 } ; 045 lock { 1,2,6 } ; 046 2 2 { 1,2,6 } ; 047 3 3 { 1 } ; 048 shift-r { 2 } ; 049 shift-l { 1,2,6 } ; 04A 0 0 { 1,2,6 } ; 04B . . { 3 } ; 04C code-r { 4 } ; 04D code-l { 0 } ; 04E { 0 } ; 04F { 0 } ; 050 { 0 } ; 051 { 0 } ; 052 { 6 } ; 053 alt { 1,2,6 } ; 054 Numeric + { 0 } ; 055 { 0 } ; 056 { 0 } ; 057 { 0 } ; 058 { 1,2,6 } ; 059 Numeric 00 { 0 } ; 05A { 1,2,6 } ; 05B [ < { 1,2,6 } ; 05C 7 | { 1,2,6 } ; 05D ] > { 1,2,6 } ; 05E ^ ~ { 0 } ; 05F { 1,2,6 } ; 060 1 single quote { 1,2,5,6 } ; 061 a A { 1,2,5,6 } ; 062 b B { 1,2,5,6 } ; 063 c C { 1,2,5,6 } ; 064 d D { 1,2,5,6 } ; 065 e E { 1,2,5,6 } ; 066 f F { 1,2,5,6 } ; 067 g G { 1,2,5,6 } ; 068 h H { 1,2,5,6 } ; 069 i I { 1,2,5,6 } ; 06A j J { 1,2,5,6 } ; 06B k K { 1,2,5,6 } ; 06C l L { 1,2,5,6 } ; 06D m M { 1,2,5,6 } ; 06E n N { 1,2,5,6 } ; 06F o O { 1,2,5,6 } ; 070 p P { 1,2,5,6 } ; 071 q Q { 1,2,5,6 } ; 072 r R { 1,2,5,6 } ; 073 s S { 1,2,5,6 } ; 074 t T { 1,2,5,6 } ; 075 u U { 1,2,5,6 } ; 076 v V { 1,2,5,6 } ; 077 w W { 1,2,5,6 } ; 078 x X { 1,2,5,6 } ; 079 y Y { 1,2,5,6 } ; 07A z Z { 1,2,6 } ; 07B 4 { { 1,2,6 } ; 07C 8 backslash { 1,2,6 } ; 07D 5 } { 0 } ; 07E { 1,2,6 } ; 07F del END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 4 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; NOTE: Numbers in orStates are decimal ; ; Table Conditions Comments ; ID ---------------------------- ; orState1 orState2 orState3 ; ----- ------- ------- ------- ------------------------------------- 0 { } { } { } ; No chord keys down 1 { 1,2,5 } ; Shift-lock OR either Shift key down; ; one "orState" 2 { 6 } ; ALT 2 { 6 } {1,2,3,4,5} ; ALT and anything else END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 1 ; Number of multibyte strings ; String { 00:30, 00:B0, 00:30, 00:B0 } END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; ; 01 27 00 65 00000016 F ; 00 4B 01 65 00010034 F ; 01 4B 01 63 00000001 T ; ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Emulation Tables Info ; ; In what follows entries are of the form xx:yy where ; ; xx = the state (FF means "Use existing state; do not emulate as ; anything new") ; yy = the K1 iKey; if this is an FF it means do not pass anything ; through to type ahead buffer. ; ; Table #0, for case where no chord keys held down. ; FFFF:00 ; 000 help FFFF:01 ; 001 up-arrow FFFF:02 ; 002 mark FFFF:03 ; 003 bound FFFF:04 ; 004 finish FFFF:05 ; 005 prev page FFFF:06 ; 006 1/2-1/4 FFFF:07 ; 007 cancel FFFF:08 ; 008 backspace FFFF:09 ; 009 tab FFFF:0A ; 00A return FFFF:0B ; 00B down-arrow FFFF:0C ; 00C next page FFFF:0D ; 00D next FFFF:0E ; 00E left-arrow FFFF:0F ; 00F right-arrow FFFF:10 ; 010 JUMP FFFF:11 ; 011 scroll-up FFFF:12 ; 012 move FFFF:13 ; 013 scroll-down FFFF:14 ; 014 copy FFFF:15 ; 015 f1 FFFF:16 ; 016 f2 FFFF:17 ; 017 f3 FFFF:18 ; 018 f4 FFFF:19 ; 019 f5 FFFF:1A ; 01A f6 FFFF:1B ; 01B GO FFFF:1C ; 01C f7 FFFF:1D ; 01D f8 FFFF:1E ; 01E f9 FFFF:1F ; 01F f10 FFFF:20 ; 020 space FFFF:21 ; 021 9 (from 9 9 keypad key) FFFF:22 ; 022 DELETE CHAR FFFF:FF ; 023 0 01:38 ; 024 Numeric * FFFF:2F ; 025 Numeric / FFFF:26 ; 026 COLUMN FFFF:27 ; 027 ' (from ' " keypad key) FFFF:28 ; 028 PAGE FFFF:29 ; 029 PARAGRAPH FFFF:2A ; 02A SENTENCE FFFF:2B ; 02B = FFFF:2C ; 02C , (from , , keypad key) FFFF:2D ; 02D - (from - _ keypad key) FFFF:2E ; 02E . (from . . keypad key) FFFF:2F ; 02F / FFFF:30 ; 030 0 (from 0 ) keypad key) FFFF:31 ; 031 1 (from 1 ! keypad key) FFFF:32 ; 032 2 (from 2 @ keypad key) FFFF:33 ; 033 3 (from 3 # keypad key) FFFF:34 ; 034 4 (from 4 $ keypad key) FFFF:35 ; 035 5 (from 5 % keypad key) FFFF:36 ; 036 6 (from 6  keypad key) FFFF:37 ; 037 7 (from 7 & keypad key) FFFF:38 ; 038 8 (from 8 * keypad key) FFFF:39 ; 039 9 (from 9 ( keypad key) FFFF:2B ; 03A Numeric = FFFF:3B ; 03B ; : FFFF:3C ; 03C WORD FFFF:3D ; 03D LINE 01:35 ; 03E Numeric Percent FFFF:FF ; 03F 3F = iKeyInvalid FFFF:FF ; 040 40 = iKeyNoKeys FFFF:41 ; 041 6 (from 6 6 keypad key) FFFF:42 ; 042 - (from - - keypad key) FFFF:43 ; 043 reset FFFF:44 ; 044 overtype FFFF:45 ; 045 lock FFFF:46 ; 046 2 (from 2 2 keypad key) FFFF:47 ; 047 3 (from 3 3 keypad key) FFFF:48 ; 048 shift FFFF:49 ; 049 shift FFFF:4A ; 04A 0 (from 0 0 keypad key) FFFF:4B ; 04B . (from . . keypad key) FFFF:4C ; 04C code FFFF:4D ; 04D code FFFF:FF ; 04E FFFF:FF ; 04F FFFF:FF ; 050 FFFF:FF ; 051 FFFF:52 ; 052 SYS FFFF:53 ; 053 ALT 01:2B ; 054 Numeric + FFFF:FF ; 055 FFFF:FF ; 056 FFFF:FF ; 057 FFFF:58 ; 058 SM:01:4A ; 059 Numeric 00 MUST BE MULTIBYTE FFFF:FF ; 05A FFFF:5B ; 05B [ FFFF:5C ; 05C 7 (from 7 | keypad key) FFFF:5D ; 05D ] FFFF:FF ; 05E ^ FFFF:FF ; 05F FFFF:60 ; 060 1 (from 1 ` keypad key) FFFF:61 ; 061 a FFFF:62 ; 062 b FFFF:63 ; 063 c FFFF:64 ; 064 d FFFF:65 ; 065 e FFFF:66 ; 066 f FFFF:67 ; 067 g FFFF:68 ; 068 h FFFF:69 ; 069 i FFFF:6A ; 06A j FFFF:6B ; 06B k FFFF:6C ; 06C l FFFF:6D ; 06D m FFFF:6E ; 06E n FFFF:6F ; 06F o FFFF:70 ; 070 p FFFF:71 ; 071 q FFFF:72 ; 072 r FFFF:73 ; 073 s FFFF:74 ; 074 t FFFF:75 ; 075 u FFFF:76 ; 076 v FFFF:77 ; 077 w FFFF:78 ; 078 x FFFF:79 ; 079 y FFFF:7A ; 07A z FFFF:7B ; 07B 4 (from 4 { keypad key) FFFF:7C ; 07C 8 (from 8 \ keypad key) FFFF:7D ; 07D 5 (from 5 } keypad key) FFFF:FF ; 07E FFFF:7F ; 07F del ; ; Table #1, for case where either chord key held down. ; FFFF:00 ; 000 help FFFF:01 ; 001 up-arrow FFFF:02 ; 002 mark FFFF:03 ; 003 bound FFFF:04 ; 004 finish FFFF:05 ; 005 prev page FFFF:06 ; 006 1/2-1/4 FFFF:07 ; 007 cancel FFFF:08 ; 008 backspace FFFF:09 ; 009 tab FFFF:0A ; 00A return FFFF:0B ; 00B down-arrow FFFF:0C ; 00C next page FFFF:0D ; 00D next FFFF:0E ; 00E left-arrow FFFF:0F ; 00F right-arrow FFFF:10 ; 010 JUMP FFFF:11 ; 011 scroll-up FFFF:12 ; 012 move FFFF:13 ; 013 scroll-down FFFF:14 ; 014 copy FFFF:15 ; 015 f1 FFFF:16 ; 016 f2 FFFF:17 ; 017 f3 FFFF:18 ; 018 f4 FFFF:19 ; 019 f5 FFFF:1A ; 01A f6 FFFF:1B ; 01B GO FFFF:1C ; 01C f7 FFFF:1D ; 01D f8 FFFF:1E ; 01E f9 FFFF:1F ; 01F f10 FFFF:20 ; 020 space 00:5E ; 021 caret (from 9 pad key) FFFF:22 ; 022 Delete Char FFFF:FF ; 023 0 FFFF:38 ; 024 Numeric * 00:2F ; 025 Numeric / FFFF:26 ; 026 Column FFFF:27 ; 027 " (from quotes keypad key) FFFF:28 ; 028 PAGE FFFF:29 ; 029 PARAGRAPH FFFF:2A ; 02A SENTENCE FFFF:2B ; 02B + FFFF:2C ; 02C , (from , , keypad key) FFFF:2D ; 02D _ (from - _ keypad key) FFFF:2E ; 02E . (from . . keypad key) FFFF:2F ; 02F ? FFFF:30 ; 030 ) (from 0 ) keypad key) FFFF:31 ; 031 ! (from 1 ! keypad key) FFFF:32 ; 032 @ (from 2 @ keypad key) FFFF:33 ; 033 # (from 3 # keypad key) FFFF:34 ; 034 $ (from 4 $ keypad key) FFFF:35 ; 035 % (from 5 % keypad key) FFFF:36 ; 036  (from 6  keypad key) FFFF:37 ; 037 & (from 7 & keypad key) FFFF:38 ; 038 * (from 8 * keypad key) FFFF:39 ; 039 ( (from 9 ( keypad key) 00:2B ; 03A Numeric = FFFF:3B ; 03B ; : FFFF:3C ; 03C WORD FFFF:3D ; 03D LINE FFFF:35 ; 03E Numeric Percent FFFF:FF ; 03F 3F = iKeyInvalid FFFF:FF ; 040 40 = iKeyNoKeys FFFF:5E ; 041 6 (from 6 ~ keypad key) FFFF:42 ; 042 - (from - - keypad key) FFFF:43 ; 043 reset FFFF:44 ; 044 overtype FFFF:45 ; 045 lock 00:06 ; 046 2 (from 2  keypad key) FFFF:06 ; 047 3 (from 3  keypad key) FFFF:48 ; 048 shift FFFF:49 ; 049 shift FFFF:4A ; 04A 0 (from 0 0 keypad key) FFFF:4B ; 04B . (from . . keypad key) FFFF:4C ; 04C code FFFF:4D ; 04D code FFFF:FF ; 04E FFFF:FF ; 04F FFFF:FF ; 050 FFFF:FF ; 051 FFFF:52 ; 052 SYS FFFF:53 ; 053 ALT FFFF:2B ; 054 Numeric + FFFF:FF ; 055 FFFF:FF ; 056 FFFF:FF ; 057 FFFF:58 ; 058 SM:01:4A ; 059 Numeric 00 FFFF:FF ; 05A FFFF:5B ; 05B < FFFF:5C ; 05C | (from 7 | keypad key) FFFF:5D ; 05D > FFFF:FF ; 05E ~ ??? FFFF:FF ; 05F FFFF:60 ; 060 left quote (from 1 keypad key) FFFF:61 ; 061 A FFFF:62 ; 062 B FFFF:63 ; 063 C FFFF:64 ; 064 D FFFF:65 ; 065 E FFFF:66 ; 066 F FFFF:67 ; 067 G FFFF:68 ; 068 H FFFF:69 ; 069 I FFFF:6A ; 06A J FFFF:6B ; 06B K FFFF:6C ; 06C L FFFF:6D ; 06D M FFFF:6E ; 06E N FFFF:6F ; 06F O FFFF:70 ; 070 P FFFF:71 ; 071 Q FFFF:72 ; 072 R FFFF:73 ; 073 S FFFF:74 ; 074 T FFFF:75 ; 075 U FFFF:76 ; 076 V FFFF:77 ; 077 W FFFF:78 ; 078 X FFFF:79 ; 079 Y FFFF:7A ; 07A Z FFFF:7B ; 07B { (from 4 { keypad key) FFFF:7C ; 07C \ (from 8 \ keypad key) FFFF:7D ; 07D } (from 5 } keypad key) FFFF:FF ; 07E FFFF:7F ; 07F del ; ; Table #2, for case where chord key held down. ; FFFF:00 ; 000 help FFFF:01 ; 001 up-arrow FFFF:02 ; 002 mark FFFF:03 ; 003 bound FFFF:04 ; 004 finish FFFF:05 ; 005 prev page FFFF:06 ; 006 1/2-1/4 FFFF:07 ; 007 cancel FFFF:08 ; 008 backspace FFFF:09 ; 009 tab FFFF:0A ; 00A return FFFF:0B ; 00B down-arrow FFFF:0C ; 00C next page FFFF:0D ; 00D next FFFF:0E ; 00E left-arrow FFFF:0F ; 00F right-arrow FFFF:10 ; 010 JUMP FFFF:11 ; 011 scroll-up FFFF:12 ; 012 move FFFF:13 ; 013 scroll-down FFFF:14 ; 014 copy FFFF:15 ; 015 f1 FFFF:16 ; 016 f2 FFFF:17 ; 017 f3 FFFF:18 ; 018 f4 FFFF:19 ; 019 f5 FFFF:1A ; 01A f6 FFFF:1B ; 01B GO FFFF:1C ; 01C f7 FFFF:1D ; 01D f8 FFFF:1E ; 01E f9 FFFF:1F ; 01F f10 FFFF:20 ; 020 space 00:5E ; 021 caret (from 9 pad key) FFFF:22 ; 022 Delete Char FFFF:FF ; 023 0 FFFF:38 ; 024 Numeric * 00:2F ; 025 Numeric / FFFF:26 ; 026 Column FFFF:27 ; 027 " (from quotes keypad key) FFFF:28 ; 028 PAGE FFFF:29 ; 029 PARAGRAPH FFFF:2A ; 02A SENTENCE FFFF:2B ; 02B + FFFF:2C ; 02C , (from , , keypad key) FFFF:2D ; 02D _ (from - _ keypad key) FFFF:2E ; 02E . (from . . keypad key) FFFF:2F ; 02F ? FFFF:30 ; 030 ) (from 0 ) keypad key) FFFF:31 ; 031 ! (from 1 ! keypad key) FFFF:32 ; 032 @ (from 2 @ keypad key) FFFF:33 ; 033 # (from 3 # keypad key) FFFF:34 ; 034 $ (from 4 $ keypad key) FFFF:35 ; 035 % (from 5 % keypad key) FFFF:36 ; 036  (from 6  keypad key) FFFF:37 ; 037 & (from 7 & keypad key) FFFF:38 ; 038 * (from 8 * keypad key) FFFF:39 ; 039 ( (from 9 ( keypad key) 00:2B ; 03A Numeric = FFFF:3B ; 03B ; : FFFF:3C ; 03C WORD FFFF:3D ; 03D LINE FFFF:35 ; 03E Numeric Percent FFFF:FF ; 03F 3F = iKeyInvalid FFFF:FF ; 040 40 = iKeyNoKeys FFFF:5E ; 041 6 (from 6 ~ keypad key) FFFF:42 ; 042 - (from - - keypad key) FFFF:43 ; 043 reset FFFF:44 ; 044 overtype FFFF:45 ; 045 lock 00:06 ; 046 2 (from 2  keypad key) FFFF:06 ; 047 3 (from 3  keypad key) FFFF:48 ; 048 shift FFFF:49 ; 049 shift FFFF:4A ; 04A 0 (from 0 0 keypad key) FFFF:4B ; 04B . (from . . keypad key) FFFF:4C ; 04C code FFFF:4D ; 04D code FFFF:FF ; 04E FFFF:FF ; 04F FFFF:FF ; 050 FFFF:FF ; 051 00:52 ; 052 SYS FFFF:53 ; 053 ALT FFFF:2B ; 054 Numeric + FFFF:FF ; 055 FFFF:FF ; 056 FFFF:FF ; 057 FFFF:58 ; 058 ? SM:01:4A ; 059 Numeric 00 FFFF:FF ; 05A FFFF:5B ; 05B < FFFF:5C ; 05C | (from 7 | keypad key) FFFF:5D ; 05D > FFFF:FF ; 05E ~ ??? FFFF:FF ; 05F FFFF:60 ; 060 left quote (from 1 keypad key) FFFF:61 ; 061 A FFFF:62 ; 062 B FFFF:63 ; 063 C FFFF:64 ; 064 D FFFF:65 ; 065 E FFFF:66 ; 066 F FFFF:67 ; 067 G FFFF:68 ; 068 H FFFF:69 ; 069 I FFFF:6A ; 06A J FFFF:6B ; 06B K FFFF:6C ; 06C L FFFF:6D ; 06D M FFFF:6E ; 06E N FFFF:6F ; 06F O FFFF:70 ; 070 P FFFF:71 ; 071 Q FFFF:72 ; 072 R FFFF:73 ; 073 S FFFF:74 ; 074 T FFFF:75 ; 075 U FFFF:76 ; 076 V FFFF:77 ; 077 W FFFF:78 ; 078 X FFFF:79 ; 079 Y FFFF:7A ; 07A Z FFFF:7B ; 07B { (from 4 { keypad key) FFFF:7C ; 07C \ (from 8 \ keypad key) FFFF:7D ; 07D } (from 5 } keypad key) FFFF:FF ; 07E FFFF:7F ; 07F del END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. /***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* 51.kbd_data */ /* */ /* This file contains the text version of the table that causes a K3 or */ /* a K5 keyboard to emulate a K1 keyboard for the OS version of */ /* "NlsKbd.sys". */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION */ /* */ /* 09/29/92 12.3.A.01 V. Miller / iKey 23 returns FFFF:FF. */ /* */ /* 03/20/92 12.2.G.01 V. Miller / Changed number of emulated LEDs back */ /* to 13 from 16 and added documentation */ /* regarding how the emulated LEDs table */ /* should work. */ /* V. Miller & K. Hampton / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; ; This is the data file for the K6 Keyboard that is used by the "Create ; Keyboard Table" Application. The format is translation tables for a ; K1 keyboard followed by emulation tables that convert K6 iKeys to the ; K1 iKey values that produce the same effect. ; ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; ; Changes: ; ; 11/14/91 vjm Removed emulation of to be for XVT ; All instances of "0009:" in the LAST emulation table ; replaced by "FFFF:" so if state has ALT key in it, ; the ALT key is passed through instead of being ; emulated. ; Keyboard name K6 ; Output file name K6KbdTables.obj ; Name of PUBLIC in object module at start of table K6KeyboardData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ==================================================================== ; ; EMULATION DATA ; ; What follows is the data for having the PS2 keyboard emulate the K1 ; keyboard. That is given a PS2 state and key what K1 state and key ; would have to be pushed to give the same result ; EMULATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if emulation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ K6 Keyboard IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of translation tables in hex ; | | | | ; | | | | :-- Target translation table in hex ; | | | | | ; 80 21 80 3 04 ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have 19 entries and they MUST be in the order shown. 22 ; Number of special keys 61 ; a 62 ; b 7F ; 44 ; 4C ; 4D ; 04 ; 43 ; 45 ; 48 ; 49 ; 64 ; Mouse Disable 65 ; Mouse Enable 53 ; Alt Key 00 ; c 1B ; 40 ; iKey not valid 20 ; Diacritic Escape 52 ; Sys Key 00 ; OS1 00 ; OS2 00 ; OS3 END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default LEDs is included. 13 (NOT number of entries in table). This ; number must be 16 or less. ; The table below is used to specify what LED is turned on when a key that ; affects an LED is pressed. The table MUST have 16 entries. ; Enter the number of the LED to be actually be turned on when the code ; specifies the particular LED number. For example, the entry ; ; "03 ; 7" ; ; means that when an application specifies that LED 7 be turned on, ; actually turn on LED 03 (where both 3 and 7 are base 10). ; ; Other possible values ; ; ~ 0 means don't remap (or map to itself). For example, the entry ; ; "00 ; 8" ; ; means thet when an application specifies that LED 8 be turned on, ; don't change (or remap) what is to be turned on; actually turn on ; LED 08. ; ; ~ FF (or actually any number greater than 16) means not supported. ; For example, the entry ; ; "FF ; 9" ; ; means thet when an application specifies that LED 9 be turned on, ; nothing is turned on. ; ; When we say LED "x" is set, we mean that the current LED state is OR-ed ; with the "x-th" entry in the following array. ; ; "1h,2h,4h,8h,10h,20h,40h,80h" ; ; LEDs >8 on the Kx style keyboards are handled according to the ; rquirement described in the hardware spec. ; ; LED LED Key LED ; Actually Application Is On ; Turned Specifies ; On Be Turned On ; 00 ; 1 f10 00 ; 2 f9 00 ; 3 f8 00 ; 4 f3 00 ; 5 f2 00 ; 6 f1 00 ; 7 LOCK 00 ; 8 Overtype 00 ; 9 Comm1 00 ; 10 Comm2 00 ; 11 Comm3 00 ; 12 Comm4 00 ; 13 Comm5 99 ; 14 'Numlock' Not used on this keyboard 99 ; 15 'Scroll Lock' Not used on this keyboard 99 ; 16 Not used on this keyboard END LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for Emulation table ; ; ; Number of entries should be the same as in translation table in this file 6 ; Number of entries ; key bMask* fToggle fLed LED mask** ; number bit bit fExclusionary ; position position ; (hex) (hex) (hex) ; 48 0 F F 0 F ; Chord #1 49 1 F F 0 F ; Chord #2 4C 2 F F 0 F ; Chord #3 4D 3 F F 0 F ; Chord #4 45 4 T T 6 F ; Chord #5 53 5 F F 0 F ; Chord #6 END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; numbers are decimal ; ------------------ ------ --------- { 1,2,6 } ; 000 help { 1,2,6 } ; 001 up-arrow { 1,2,6 } ; 002 mark { 1,2,6 } ; 003 bound { 1,2,6 } ; 004 finish { 1,2,6 } ; 005 prev page { 1,2,6 } ; 006 ` ~ { 1,2,6 } ; 007 cancel { 1,2,6 } ; 008 backspace { 1,2,6 } ; 009 tab { 1,2,6 } ; 00A return { 1,2,6 } ; 00B down-arrow { 1,2,6 } ; 00C next page { 1,2,6 } ; 00D next { 1,2,6 } ; 00E left-arrow { 1,2,6 } ; 00F right-arrow { 1,2,6 } ; 010 JUMP { 1,2,6 } ; 011 scroll-up { 1,2,6 } ; 012 move { 1,2,6 } ; 013 scroll-down { 1,2,6 } ; 014 copy { 1,2,6 } ; 015 f1 { 1,2,6 } ; 016 f2 { 1,2,6 } ; 017 f3 { 1,2,6 } ; 018 f4 { 1,2,6 } ; 019 f5 { 1,2,6 } ; 01A f6 { 1,2,6 } ; 01B GO { 1,2,6 } ; 01C f7 { 1,2,6 } ; 01D f8 { 1,2,6 } ; 01E f9 { 1,2,6 } ; 01F f10 { 1,2,6 } ; 020 space { 1,2,6 } ; 021 9 9 { 1,2,6 } ; 022 Delete char { 1,2,6 } ; 023 0 0 { 1,2,6 } ; 024 Numeric * { 1,2,6 } ; 025 Numeric / { 1,2,6 } ; 026 Column { 1,2,6 } ; 027 quotes { 1,2,6 } ; 028 PAGE { 1,2,6 } ; 029 PARAGRAPH { 1,2,6 } ; 02A SENTENCE { 1,2,6 } ; 02B plus equals { 1,2,6 } ; 02C commas { 1,2,6 } ; 02D - _ { 1,2,6 } ; 02E .\ { 1,2,6 } ; 02F slash question mark { 1,2,6 } ; 030 0 right parens { 1,2,6 } ; 031 1 exclam mark { 1,2,6 } ; 032 2 at sign { 1,2,6 } ; 033 3 hash { 1,2,6 } ; 034 4 $ { 1,2,6 } ; 035 5 percent { 1,2,6 } ; 036 6 cent { 1,2,6 } ; 037 7 & { 1,2,6 } ; 038 8 * { 1,2,6 } ; 039 9 left parens { 1,2,6 } ; 03A Numeric = { 1,2,6 } ; 03B ; : { 1,2,6 } ; 03C WORD { 1,2,6 } ; 03D LINE { 1,2,6 } ; 03E Numeric Percent { 0 } ; 03F iKeyInvalid { 0 } ; 040 iKeyNoKeys { 1,2,6 } ; 041 6 6 { 1,2,6 } ; 042 - - { 0 } ; 043 reset { 1,2,6 } ; 044 overtype { 5 } ; 045 lock { 1,2,6 } ; 046 2 2 { 1,2,6 } ; 047 3 3 { 1 } ; 048 shift-r { 2 } ; 049 shift-l { 1,2,6 } ; 04A 0 0 { 1,2,6 } ; 04B . . { 3 } ; 04C code-r { 4 } ; 04D code-l { 0 } ; 04E { 0 } ; 04F { 0 } ; 050 { 0 } ; 051 { 0 } ; 052 { 6 } ; 053 alt { 1,2,6 } ; 054 Numeric + { 0 } ; 055 { 0 } ; 056 { 0 } ; 057 { 0 } ; 058 { 1,2,6 } ; 059 Numeric 00 { 0 } ; 05A { 1,2,6 } ; 05B [ < { 1,2,6 } ; 05C 7 | { 1,2,6 } ; 05D ] > { 1,2,6 } ; 05E ^ ~ { 0 } ; 05F { 1,2,6 } ; 060 1 single quote { 1,2,5,6 } ; 061 a A { 1,2,5,6 } ; 062 b B { 1,2,5,6 } ; 063 c C { 1,2,5,6 } ; 064 d D { 1,2,5,6 } ; 065 e E { 1,2,5,6 } ; 066 f F { 1,2,5,6 } ; 067 g G { 1,2,5,6 } ; 068 h H { 1,2,5,6 } ; 069 i I { 1,2,5,6 } ; 06A j J { 1,2,5,6 } ; 06B k K { 1,2,5,6 } ; 06C l L { 1,2,5,6 } ; 06D m M { 1,2,5,6 } ; 06E n N { 1,2,5,6 } ; 06F o O { 1,2,5,6 } ; 070 p P { 1,2,5,6 } ; 071 q Q { 1,2,5,6 } ; 072 r R { 1,2,5,6 } ; 073 s S { 1,2,5,6 } ; 074 t T { 1,2,5,6 } ; 075 u U { 1,2,5,6 } ; 076 v V { 1,2,5,6 } ; 077 w W { 1,2,5,6 } ; 078 x X { 1,2,5,6 } ; 079 y Y { 1,2,5,6 } ; 07A z Z { 1,2,6 } ; 07B 4 { { 1,2,6 } ; 07C 8 backslash { 1,2,6 } ; 07D 5 } { 0 } ; 07E { 1,2,6 } ; 07F del END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 4 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; NOTE: Numbers in orStates are decimal ; ; Table Conditions Comments ; ID ---------------------------- ; orState1 orState2 orState3 ; ----- -------- -------- -------- ------------------------------------- 0 { } { } { } ; No chord keys down 1 {1,2,5 } ; Shift-lock OR either Shift key down; ; one "orState" 2 {6} ; ALT 2 {6} {1,2,3,4,5} ; ALT and anything else END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 1 ; Number of multibyte strings ; String { 00:30, 00:B0, 00:30, 00:B0 } END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 01 27 00 65 00000016 F ; 00 4B 01 65 00010034 F ; 01 4B 01 63 00000001 T ; ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Emulation Tables Info ; ; In what follows entries are of the form xx:yy where ; ; xx = the state (FF or FFFF means "Do not emulate as a different state") ; yy = the K1 iKey ; Number of emulation tables in special keys table ; ; Table for case where no chord keys held down. ; FFFF:00 ; 000 help FFFF:01 ; 001 up-arrow FFFF:02 ; 002 mark FFFF:03 ; 003 bound FFFF:04 ; 004 finish FFFF:05 ; 005 prev page 01:60 ; 006 ` FFFF:07 ; 007 cancel FFFF:08 ; 008 backspace FFFF:09 ; 009 tab FFFF:0A ; 00A return FFFF:0B ; 00B down-arrow FFFF:0C ; 00C next page FFFF:0D ; 00D next FFFF:0E ; 00E left-arrow FFFF:0F ; 00F right-arrow FFFF:10 ; 010 JUMP FFFF:11 ; 011 scroll-up FFFF:12 ; 012 move FFFF:13 ; 013 scroll-down FFFF:14 ; 014 copy FFFF:15 ; 015 f1 FFFF:16 ; 016 f2 FFFF:17 ; 017 f3 FFFF:18 ; 018 f4 FFFF:19 ; 019 f5 FFFF:1A ; 01A f6 FFFF:1B ; 01B GO FFFF:1C ; 01C f7 FFFF:1D ; 01D f8 FFFF:1E ; 01E f9 FFFF:1F ; 01F f10 FFFF:20 ; 020 space FFFF:21 ; 021 9 (from 9 9 keypad key) FFFF:22 ; 022 DELETE CHAR FFFF:FF ; 023 0 01:38 ; 024 Numeric * FFFF:2F ; 025 Numeric / FFFF:26 ; 026 COLUMN FFFF:27 ; 027 ' (from ' " keypad key) FFFF:28 ; 028 PAGE FFFF:29 ; 029 PARAGRAPH FFFF:2A ; 02A SENTENCE FFFF:2B ; 02B = FFFF:2C ; 02C , (from , , key) FFFF:2D ; 02D - (from - _ key) FFFF:2E ; 02E . (from . \ key) FFFF:2F ; 02F / FFFF:30 ; 030 0 (from 0 ) key) FFFF:31 ; 031 1 (from 1 ! key) FFFF:32 ; 032 2 (from 2 @ key) FFFF:33 ; 033 3 (from 3 # key) FFFF:34 ; 034 4 (from 4 $ key) FFFF:35 ; 035 5 (from 5 % key) FFFF:36 ; 036 6 (from 6  key) FFFF:37 ; 037 7 (from 7 & key) FFFF:38 ; 038 8 (from 8 * key) FFFF:39 ; 039 9 (from 9 ( key) FFFF:2B ; 03A Numeric = FFFF:3B ; 03B ; : FFFF:3C ; 03C WORD FFFF:3D ; 03D LINE 01:35 ; 03E Numeric Percent FFFF:FF ; 03F 3F = iKeyInvalid FFFF:FF ; 040 40 = iKeyNoKeys FFFF:41 ; 041 6 (from 6 6 keypad key) FFFF:42 ; 042 - (from - - keypad key) FFFF:43 ; 043 reset FFFF:44 ; 044 overtype FFFF:45 ; 045 lock FFFF:46 ; 046 2 (from 2 2 keypad key) FFFF:47 ; 047 3 (from 3 3 keypad key) FFFF:48 ; 048 shift FFFF:49 ; 049 shift FFFF:4A ; 04A 0 (from 0 0 keypad key) FFFF:4B ; 04B . (from . . keypad key) FFFF:4C ; 04C code FFFF:4D ; 04D code FFFF:FF ; 04E FFFF:FF ; 04F FFFF:FF ; 050 FFFF:FF ; 051 FFFF:52 ; 052 SYS FFFF:53 ; 053 ALT 01:2B ; 054 Numeric + FFFF:FF ; 055 FFFF:FF ; 056 FFFF:FF ; 057 FFFF:58 ; 058 SM:01:4A ; 059 Numeric 00 MUST BE MULTIBYTE FFFF:FF ; 05A FFFF:5B ; 05B [ FFFF:5C ; 05C 7 (from 7 | keypad key) FFFF:5D ; 05D ] FFFF:FF ; 05E ^ FFFF:FF ; 05F FFFF:60 ; 060 1 (from 1 ` keypad key) FFFF:61 ; 061 a FFFF:62 ; 062 b FFFF:63 ; 063 c FFFF:64 ; 064 d FFFF:65 ; 065 e FFFF:66 ; 066 f FFFF:67 ; 067 g FFFF:68 ; 068 h FFFF:69 ; 069 i FFFF:6A ; 06A j FFFF:6B ; 06B k FFFF:6C ; 06C l FFFF:6D ; 06D m FFFF:6E ; 06E n FFFF:6F ; 06F o FFFF:70 ; 070 p FFFF:71 ; 071 q FFFF:72 ; 072 r FFFF:73 ; 073 s FFFF:74 ; 074 t FFFF:75 ; 075 u FFFF:76 ; 076 v FFFF:77 ; 077 w FFFF:78 ; 078 x FFFF:79 ; 079 y FFFF:7A ; 07A z FFFF:7B ; 07B 4 (from 4 { keypad key) FFFF:7C ; 07C 8 (from 8 \ keypad key) FFFF:7D ; 07D 5 (from 5 } keypad key) FFFF:FF ; 07E FFFF:7F ; 07F del ; ; Table for case where either chord key held down. ; FFFF:00 ; 000 help FFFF:01 ; 001 up-arrow FFFF:02 ; 002 mark FFFF:03 ; 003 bound FFFF:04 ; 004 finish FFFF:05 ; 005 prev page FFFF:5E ; 006 ~ FFFF:07 ; 007 cancel FFFF:08 ; 008 backspace FFFF:09 ; 009 tab FFFF:0A ; 00A return FFFF:0B ; 00B down-arrow FFFF:0C ; 00C next page FFFF:0D ; 00D next FFFF:0E ; 00E left-arrow FFFF:0F ; 00F right-arrow FFFF:10 ; 010 JUMP FFFF:11 ; 011 scroll-up FFFF:12 ; 012 move FFFF:13 ; 013 scroll-down FFFF:14 ; 014 copy FFFF:15 ; 015 f1 FFFF:16 ; 016 f2 FFFF:17 ; 017 f3 FFFF:18 ; 018 f4 FFFF:19 ; 019 f5 FFFF:1A ; 01A f6 FFFF:1B ; 01B GO FFFF:1C ; 01C f7 FFFF:1D ; 01D f8 FFFF:1E ; 01E f9 FFFF:1F ; 01F f10 FFFF:20 ; 020 space 00:5E ; 021 caret (from 9 pad key) FFFF:22 ; 022 Delete Char FFFF:FF ; 023 0 FFFF:38 ; 024 Numeric * 00:2F ; 025 Numeric / FFFF:26 ; 026 Column FFFF:27 ; 027 " (from quotes keypad key) 09:7B ; 026 PAGE FFFF:29 ; 029 PARAGRAPH FFFF:2A ; 02A SENTENCE FFFF:2B ; 02B + FFFF:2C ; 02C , (from , , key) FFFF:2D ; 02D _ (from - _ key) FFFF:7C ; 02E \ (from . \ key) FFFF:2F ; 02F ? FFFF:30 ; 030 ) (from 0 ) key) FFFF:31 ; 031 ! (from 1 ! key) FFFF:32 ; 032 @ (from 2 @ key) FFFF:33 ; 033 # (from 3 # key) FFFF:34 ; 034 $ (from 4 $ key) FFFF:35 ; 035 % (from 5 % key) FFFF:36 ; 036  (from 6  key) FFFF:37 ; 037 & (from 7 & key) FFFF:38 ; 038 * (from 8 * key) FFFF:39 ; 039 ( (from 9 ( key) 00:2B ; 03A Numeric = FFFF:3B ; 03B ; : FFFF:3C ; 03C WORD FFFF:3D ; 03D LINE FFFF:35 ; 03E Numeric Percent FFFF:FF ; 03F 3F = iKeyInvalid FFFF:FF ; 040 40 = iKeyNoKeys FFFF:5E ; 041 6 (from 6 ~ keypad key) FFFF:42 ; 042 - (from - - keypad key) FFFF:43 ; 043 reset FFFF:44 ; 044 overtype FFFF:45 ; 045 lock 00:06 ; 046 2 (from 2  keypad key) FFFF:06 ; 047 3 (from 3  keypad key) FFFF:48 ; 048 shift FFFF:49 ; 049 shift FFFF:4A ; 04A 0 (from 0 0 keypad key) FFFF:4B ; 04B . (from . . keypad key) FFFF:4C ; 04C code FFFF:4D ; 04D code FFFF:FF ; 04E FFFF:FF ; 04F FFFF:FF ; 050 FFFF:FF ; 051 FFFF:52 ; 052 SYS FFFF:53 ; 053 ALT FFFF:2B ; 054 Numeric + FFFF:FF ; 055 FFFF:FF ; 056 FFFF:FF ; 057 FFFF:58 ; 058 SM:01:4A ; 059 Numeric 00 FFFF:FF ; 05A FFFF:5B ; 05B < FFFF:5C ; 05C | (from 7 | keypad key) FFFF:5D ; 05D > FFFF:FF ; 05E ~ ??? FFFF:FF ; 05F FFFF:60 ; 060 left quote (from 1 keypad key) FFFF:61 ; 061 A FFFF:62 ; 062 B FFFF:63 ; 063 C FFFF:64 ; 064 D FFFF:65 ; 065 E FFFF:66 ; 066 F FFFF:67 ; 067 G FFFF:68 ; 068 H FFFF:69 ; 069 I FFFF:6A ; 06A J FFFF:6B ; 06B K FFFF:6C ; 06C L FFFF:6D ; 06D M FFFF:6E ; 06E N FFFF:6F ; 06F O FFFF:70 ; 070 P FFFF:71 ; 071 Q FFFF:72 ; 072 R FFFF:73 ; 073 S FFFF:74 ; 074 T FFFF:75 ; 075 U FFFF:76 ; 076 V FFFF:77 ; 077 W FFFF:78 ; 078 X FFFF:79 ; 079 Y FFFF:7A ; 07A Z FFFF:7B ; 07B { (from 4 { keypad key) FFFF:7C ; 07C \ (from 8 \ keypad key) FFFF:7D ; 07D } (from 5 } keypad key) FFFF:FF ; 07E FFFF:7F ; 07F del ; ; Table for case where chord key held down. ; FFFF:00 ; 000 help FFFF:01 ; 001 up-arrow FFFF:02 ; 002 mark FFFF:03 ; 003 bound FFFF:04 ; 004 finish FFFF:05 ; 005 prev page FFFF:5E ; 006 `~ FFFF:07 ; 007 cancel FFFF:08 ; 008 backspace FFFF:09 ; 009 tab FFFF:0A ; 00A return FFFF:0B ; 00B down-arrow FFFF:0C ; 00C next page FFFF:0D ; 00D next FFFF:0E ; 00E left-arrow FFFF:0F ; 00F right-arrow FFFF:10 ; 010 JUMP FFFF:11 ; 011 scroll-up FFFF:12 ; 012 move FFFF:13 ; 013 scroll-down FFFF:14 ; 014 copy FFFF:15 ; 015 f1 FFFF:16 ; 016 f2 FFFF:17 ; 017 f3 FFFF:18 ; 018 f4 FFFF:19 ; 019 f5 FFFF:1A ; 01A f6 FFFF:1B ; 01B GO FFFF:1C ; 01C f7 FFFF:1D ; 01D f8 FFFF:1E ; 01E f9 FFFF:1F ; 01F f10 FFFF:20 ; 020 space 00:5E ; 021 caret (from 9 pad key) FFFF:22 ; 022 Delete Char FFFF:FF ; 023 0 FFFF:38 ; 024 Numeric * 00:2F ; 025 Numeric / FFFF:26 ; 026 Column FFFF:27 ; 027 " (from quotes keypad key) FFFF:28 ; 028 PAGE FFFF:29 ; 029 PARAGRAPH FFFF:2A ; 02A SENTENCE FFFF:2B ; 02B + FFFF:2C ; 02C , (from , , key) FFFF:2D ; 02D _ (from - _ key) FFFF:7C ; 02E . (from . \ key) FFFF:2F ; 02F ? FFFF:30 ; 030 ) (from 0 ) key) FFFF:31 ; 031 ! (from 1 ! key) FFFF:32 ; 032 @ (from 2 @ key) FFFF:33 ; 033 # (from 3 # key) FFFF:34 ; 034 $ (from 4 $ key) FFFF:35 ; 035 % (from 5 % key) FFFF:36 ; 036  (from 6  key) FFFF:37 ; 037 & (from 7 & key) FFFF:38 ; 038 * (from 8 * key) FFFF:39 ; 039 ( (from 9 ( key) 00:2B ; 03A Numeric = FFFF:3B ; 03B ; : FFFF:3C ; 03C WORD FFFF:3D ; 03D LINE FFFF:35 ; 03E Numeric Percent FFFF:FF ; 03F 3F = iKeyInvalid FFFF:FF ; 040 40 = iKeyNoKeys FFFF:5E ; 041 6 (from 6 ~ keypad key) FFFF:42 ; 042 - (from - - keypad key) FFFF:43 ; 043 reset FFFF:44 ; 044 overtype FFFF:45 ; 045 lock 00:06 ; 046 2 (from 2  keypad key) FFFF:06 ; 047 3 (from 3  keypad key) FFFF:48 ; 048 shift FFFF:49 ; 049 shift FFFF:4A ; 04A 0 (from 0 0 keypad key) FFFF:4B ; 04B . (from . . keypad key) FFFF:4C ; 04C code FFFF:4D ; 04D code FFFF:FF ; 04E FFFF:FF ; 04F FFFF:FF ; 050 FFFF:FF ; 051 00:52 ; 052 SYS FFFF:53 ; 053 ALT FFFF:2B ; 054 Numeric + FFFF:FF ; 055 FFFF:FF ; 056 FFFF:FF ; 057 FFFF:58 ; 058 ? SM:01:4A ; 059 Numeric 00 FFFF:FF ; 05A FFFF:5B ; 05B < FFFF:5C ; 05C | (from 7 | keypad key) FFFF:5D ; 05D > FFFF:FF ; 05E ~ ??? FFFF:FF ; 05F FFFF:60 ; 060 left quote (from 1 keypad key) FFFF:61 ; 061 A FFFF:62 ; 062 B FFFF:63 ; 063 C FFFF:64 ; 064 D FFFF:65 ; 065 E FFFF:66 ; 066 F FFFF:67 ; 067 G FFFF:68 ; 068 H FFFF:69 ; 069 I FFFF:6A ; 06A J FFFF:6B ; 06B K FFFF:6C ; 06C L FFFF:6D ; 06D M FFFF:6E ; 06E N FFFF:6F ; 06F O FFFF:70 ; 070 P FFFF:71 ; 071 Q FFFF:72 ; 072 R FFFF:73 ; 073 S FFFF:74 ; 074 T FFFF:75 ; 075 U FFFF:76 ; 076 V FFFF:77 ; 077 W FFFF:78 ; 078 X FFFF:79 ; 079 Y FFFF:7A ; 07A Z FFFF:7B ; 07B { (from 4 { keypad key) FFFF:7C ; 07C \ (from 8 \ keypad key) FFFF:7D ; 07D } (from 5 } keypad key) FFFF:FF ; 07E FFFF:7F ; 07F del END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. /***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* ssK1.kbd_data */ /* */ /* This file contains the text version of the table that causes a */ /* SG-102-K (SuperSet) keyboard to emulate a K1 keyboard for the OS */ /* version of "NlsKbd.sys". */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VV.V.V/MM PROGRAMMER / DESCRIPTION */ /* */ /* 09/29/92 12.3.A.01 V. Miller / Add 5d as doing same as ikey 5c for */ /* Unisys PC keyboard. */ /* */ /* 07/10/92 122FSF.05 K. Hampton / Added Numlock+scrolllock condition */ /* 06/24/92 12.2.J.04 K. Hampton / Added Hot Keys Table. */ /* 03/20/92 12.2.G.03 V. Miller / Made emulate to key 53 not */ /* 54 because 53 is in K1 keyboard */ /* data block. Means all instances of */ /* "FFFF:54" changed to "FFFF:53". */ /* Also, change number of emulated LEDs */ /* back to 3 from 16 and added document- */ /* ation regarding emulated LEDs. */ /* 03/18/92 12.2.G.02 V. Miller / Made special key table entry no */ /* be iKey of key; make it */ /* 30h instead, a non-used key. Make */ /* special key table entry the key */ /* entry and put 53h in it. When doing */ /* emulate as 0000:00 to make */ /* help appear; make sure the Alt does */ /* not get through because Left Alt is */ /* emulated as . */ /* 03/17/92 12.2.G.01 V. Miller / Added comments and change number of */ /* emulated LEDs from 3 to 16. */ /* Val Miller / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; This is the data file for a PS2 or superset keyboard that is to be ; emulated as a K1 Keyboard; this file is suitable for use by the ; "Create Keyboard Table" command ; ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; Keyboard name SS1 ; Output file name SS1EmulTables.obj ; Name of PUBLIC in object module at start of table SS1EmulData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ==================================================================== ; ; EMULATION DATA ; ; What follows is the data for having the PS2 keyboard emulate the K1 ; keyboard. That is given a PS2 state and key what K1 state and key ; would have to be pushed to give the same result ; EMULATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if emulation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ PS2 Keyboard IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of emulation tables in hex ; | | | | ; 85 65 80 5 04 -- target translation table in hex ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have 19 entries and they MUST be in the order shown. 22 ; Number of special keys 1C ; a * 32 ; b * 64 ; * 67 ; * 11 ; * 58 ; * 07 ; * 30 ; Space for ; put not used key 14 ; * 12 ; * 59 ; * 40 ; 40 ; 53 ; 00 ; c 79 ; 40 ; iKey not valid 29 ; Diacritic Escape 57 ; System Key 00 ; reserved for future use 00 ; reserved for future use 00 ; reserved for future use END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. 3 ; Number of LEDs on keyboard (NOT number of entries in table). This ; number must be 16 or less. ; The table below is used to specify what LED is turned on when a key that ; affects an LED is pressed. The table MUST have 16 entries. ; Enter the number of the LED to be actually be turned on when the code ; specifies the particular LED number. For example, the entry ; ; "03 ; 7" ; ; means that when an application specifies that LED 7 be turned on, ; actually turn on LED 03 (where both 3 and 7 are base 10). ; ; Other possible values ; ; ~ 0 means don't remap (or map to itself). For example, the entry ; ; "00 ; 8" ; ; means thet when an application specifies that LED 8 be turned on, ; don't change (or remap) what is to be turned on; actually turn on ; LED 08. ; ; ~ FF (or actually any number greater than 16) means not supported. ; For example, the entry ; ; "FF ; 9" ; ; means thet when an application specifies that LED 9 be turned on, ; nothing is turned on. ; ; When we say LED "x" is set, we mean that the current LED state is OR-ed ; with the "x-th" entry in the following array. ; ; "1h,2h,4h,8h,10h,20h,40h,80h" ; ; LEDs >8 on the Kx style keyboards are handled according to the ; rquirement described in the hardware spec. ; ; LED LED Key LED ; Actually Application Is On ; Turned Specifies ; On Be Turned On ; 04 ; 1 f10 NOT SUPPORTED ON SUPERSET KEYBOARD 05 ; 2 f9 NOT SUPPORTED ON SUPERSET KEYBOARD 06 ; 3 f8 NOT SUPPORTED ON SUPERSET KEYBOARD 07 ; 4 f3 NOT SUPPORTED ON SUPERSET KEYBOARD 08 ; 5 f2 NOT SUPPORTED ON SUPERSET KEYBOARD 09 ; 6 f1 NOT SUPPORTED ON SUPERSET KEYBOARD 03 ; 7 LOCK 0A ; 8 Overtype NOT SUPPORTED ON SUPERSET KEYBOARD 0B ; 9 Comm1 NOT SUPPORTED ON SUPERSET KEYBOARD 0C ; 10 Comm2 NOT SUPPORTED ON SUPERSET KEYBOARD 0D ; 11 Comm3 NOT SUPPORTED ON SUPERSET KEYBOARD 0E ; 12 Comm4 NOT SUPPORTED ON SUPERSET KEYBOARD 0F ; 13 Comm5 NOT SUPPORTED ON SUPERSET KEYBOARD 02 ; 14 'Numlock' 01 ; 15 'Scroll Lock' FF ; ; ; NOTE THE "OVERTYPE" KEY IS NOT SUPPORTED ON SUPERSET KEYBOARD ; END LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for Emulation table ; ; 9 ; Number of entries ; Hw bMask* Toggle Led LED** Exclus- Turn Chord Chord ; iKey bit mask ionary On For Number Name ;(hex) position bit Chord Init ; position ; 12 0 F F 0 F F ; 1 59 1 F F 0 F F ; 2 11 2 F F 0 F F ; 3 58 3 F F 0 F F ; 4 14 4 T T 2 F F ; 5 19 5 F F 0 F F ; 6 (K1 nop) 39 6 F F 0 F F ; 7 (K1 nop) 76 7 T T 1 F F ; 8 (K1 nop) 5F 8 T T 0 F T ; 9 (K1 nop) ; ; Field Definitions ; ; Hw iKey ; ; This is the raw hardware iKey value returned when this key is ; pressed. ; ; ; bMask bit position ; ; The OS needs a way to keep track of which which of these chord keys ; is currently down. This is done with a "chord state" word where ; each bit in the word corresponds to a chord; this chord state word ; is what is returned in the "State" field if a "ReadKbdInfo" request ; is made by an application. This entry is where you can specify ; which bit is set for a given chord key. Several things need to ; be noted: ; ; 1. Values are in hex (A is not acceptable, 0A must be used). ; Allowed values range from 0 to 0F where 0 refers to the least ; significant bit in the state word and 0Fh refers to the most ; significant. For example, if you specify a bMask value of 4, ; then if this chord is down the state word looks as follows: ; ; 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 = 0010h ; ^ ^ ^ ; | | | ; '-- Position 0Fh Position 4h --' Position 0h ; ; ; 2. These values do NOT have to be in order as they are above and ; they do NOT have to be assigned to the chords they way they ; are in this table. The order and assignment in this table ; was chosen simply to maintain historical continuity with the ; defaults use in earlier CTOS and BTOS OS's. ; ; ; Toggle ; ; If the effect of the chord is to toggle (like normally ; does) then a "T" should be entered here; otherwise an "F" should be ; entered. ; ; ; LED ; ; If the state of this chord (i.e. whether it is in effect or not) ; affects an LED then a "T" should be entered here; otherwise an ; "F" should be entered. ; ; ; LED mask bit position ; ; If a "T" is entered for the LED field then this entry is used to ; specify which bit in the "LED state" word governs the LED that is ; turned on when this chord comes into effect and off when this ; chord stops being in effect. ; ; ; Exclusionary Chord ; ; The OS WILL NOT ALLOW two exclusionary chords to be in force at ; the same time. If an exclusionary chord key is being held down ; and another exclusionary chord is pressed, then the upstoke of ; the first key is put in the typeahead buffer to terminate its ; effect. If an exclusionary toggle chord key is in effrect and ; another exclusionary chord is pressed, then the downstroke and ; upstoke necessary to turn off the toggle key is put in the ; typeahead buffer. To make a chord an exclusionary chord enter ; a "T" ; otherwise an "F" should be entered. ; ; NOTE: The effect of non-exclusionary chords is NOT changed when ; an exclusionary chord is pressed; only the effect of other ; exclusionary chords. ; ; ; Turn On For Init ; ; If a "T" is entered in this field, then when a partition is created ; the effect of this chord is set to be on. If there is an LED ; associated with the chord , it also is set on. If the chord is ; desired to be off when partitions initialize, then enter "F". ; ; NOTE: This is an optional field in 12.1.x versions of Standard ; Software. ; ; ; Chord Number ; ; This is actually part of the comments. Chord numbers are assigned ; by the Keyboard Customizing Tool based on the order in which the ; chords actually appear in the file. This data in this field is ; shown in the table and described here because the chord numbers ; are used in the allowed states and conditions table. The chord ; numbers are used as follows: ; ; In the allowed states and conditions table there are entries ; with the form: ; ; { x,y,z } where the x, y and z are chord numbers ; ; For example, the following entry "{ 1,2,4 } would refer to ; the chords in the above table with chord numbers 1, 2 and 4 ; (i.e. the , and chords). ; ; ; Chord Name ; ; This is name of the key that must be pressed to cause the chord ; to bee in effect. ; ; NOTES: ; ; 1. If possible, dummy entries should be added to the emulated ; keyboard table so there are the same number of entries in ; both emulated and emulating keyboard data blocks. ; ; 2. The order of the chords in the emulating and emulated keyboard ; data blocks must be the same. This means chords in the emulating ; keyboard data block that are not in the emulated keyboard data ; block must come in the chords table after chords that are ; present on both emulated and emulating keyboard data blocks. ; ; 3. The "(K1 NOP)" notation are for chords that cannot be cause by ; any key on the emulated keyboard but can be caused by pressing ; keys on the emulating keyboard. These chords MUST always ; FOLLOW in the chords table those chords that are present on ; both emulated and emulating keyboard data blocks. ; END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; numbers are decimal ; ------------------ ------ --------- { 0 } ; 000 { 0 } ; 001 { 0 } ; 002 { 0 } ; 003 { 0 } ; 004 { 0 } ; 005 { 0 } ; 006 { 6,7 } ; 007 F1 (l alt,r alt) { 0 } ; 008 Escape { 0 } ; 009 { 0 } ; 00A { 0 } ; 00B { 0 } ; 00C { 0 } ; 00D Tab { 1,2 } ; 00E ` ~ { 0 } ; 00F F2 { 0 } ; 010 { 3,4 } ; 011 Left Control { 1,2 } ; 012 Left Shift { 0 } ; 013 { 5 } ; 014 Lock { 1,2,5 } ; 015 q Q { 1,2 } ; 016 1 ! { 0 } ; 017 f3 { 0 } ; 018 { 6,7 } ; 019 Left Alt { 1,2,5 } ; 01A z Z { 1,2,5 } ; 01B s S { 1,2,5 } ; 01C a A { 1,2,5 } ; 01D w W { 1,2 } ; 01E 2 @ { 0 } ; 01F f4 { 0 } ; 020 { 1,2,5 } ; 021 c C { 1,2,5 } ; 022 x X { 1,2,5 } ; 023 d D { 1,2,5 } ; 024 e E { 1,2 } ; 025 4 $ { 1,2 } ; 026 3 # { 0 } ; 027 f5 { 0 } ; 028 { 0 } ; 029 space { 1,2,5 } ; 02A v V { 1,2,5 } ; 02B f F { 1,2,5 } ; 02C t T { 1,2,5 } ; 02D k K { 1,2 } ; 02E 5 % { 0 } ; 02F f6 { 0 } ; 030 { 1,2,5 } ; 031 n N { 1,2,5 } ; 032 b B { 1,2,5 } ; 033 h H { 1,2,5 } ; 034 g G { 1,2,5 } ; 035 y Y { 1,2 } ; 036 6 ^ { 0 } ; 037 F7 { 0 } ; 038 { 6,7 } ; 039 Right Alt { 1,2,5 } ; 03A m M { 1,2,5 } ; 03B j J { 1,2,5 } ; 03C u U { 1,2 } ; 03D 7 & { 1,2 } ; 03E 8 * { 0 } ; 03F f8 { 0 } ; 040 { 1,2 } ; 041 , < { 1,2,5 } ; 042 k K { 1,2,5 } ; 043 i I { 1,2,5 } ; 044 o O { 1,2 } ; 045 0 ) { 1,2 } ; 046 9 ( { 0 } ; 047 f9 { 0 } ; 048 { 1,2 } ; 049 . > { 1,2 } ; 04A / ? { 1,2,5 } ; 04B l L { 1,2 } ; 04C ; : { 1,2,5 } ; 04D p P { 1,2 } ; 04E - _ { 0 } ; 04F f10 { 0 } ; 050 { 0 } ; 051 { 1,2 } ; 052 ' " { 0 } ; 053 { 1,2 } ; 054 [ { { 1,2 } ; 055 = + { 0 } ; 056 f11 { 0 } ; 057 Print Screen { 3,4 } ; 058 Right Control { 1,2 } ; 059 Right Shift { 0 } ; 05A Return { 1,2 } ; 05B ] } { 1,2 } ; 05C \ | { 1,2 } ; 05D \ | on the Unisys PC kbd vjm 12.3.A.01 { 0 } ; 05E f12 { 9 } ; 05F CTOS (Scroll) Lock { 0 } ; 060 Down Arrow { 0 } ; 061 Left Arrow { 0 } ; 062 Pause { 0 } ; 063 Up Arrow { 0 } ; 064 Delete { 0 } ; 065 End { 0 } ; 066 Bacspace { 0 } ; 067 Insert { 0 } ; 068 { 1,2,8,9 } ; 069 1 pad { 0 } ; 06A Right Arrow { 1,2,8,9 } ; 06B 4 pad { 1,2,8,9 } ; 06C 7 pad { 0 } ; 06D pg dn { 0 } ; 06E home { 0 } ; 06F pg up { 1,2,8,9 } ; 070 0 pad { 1,2,8,9 } ; 071 . pad { 1,2,8,9 } ; 072 2 pad { 1,2,8,9 } ; 073 5 pad { 1,2,8,9 } ; 074 6 pad { 1,2,8,9 } ; 075 8 pad { 8 } ; 076 numlock { 1,2 } ; 077 / pad { 0 } ; 078 { 0 } ; 079 enter (GO) { 1,2,8,9 } ; 07A 3 pad { 0 } ; 07B { 0 } ; 07C + pad { 1,2,8,9 } ; 07D 9 pad { 0 } ; 07E * pad { 0 } ; 07F { 0 } ; 080 { 0 } ; 081 { 0 } ; 082 { 0 } ; 083 { 0 } ; 084 - pad END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 9 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; NOTE: Numbers in orStates are decimal ; ; Table Conditions Comments ; ID ---------------------------- ; orState1 orState2 orState3 ; ----- -------- -------- -------- ------------------------------------- 0 { } { } { } ; No chord keys down 1 { 1,2 } ; either Shift key down; 4 { 8 } ; numlock down 4 { 8 } { 9 } ; numlock and CTOS lock 3 { 9 } ; CTOS lock down 3 { 9 } {1,2,3,4,5} ; CTOS lk and (shifts/codes) 0 { 8 } { 1,2 } ; numlock and either shift key 2 { 6,7 } ; either alt (for f1) 2 { 6,7 } {1,2,3,4,5} ; either alt and (shifts/codes)(for f1) ; to facilitate shift+help or code+help ; to facilitate shift+help or code+help END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 0 ; Number of multibyte strings ; String ; { 01:68, 01:E8, 00:69, 00:E9, 00:20, 00:A0, 02:74, 02:F4, 00:68, 00:E8& ; 00:65, 00:E5, 00:72, 00:F2, 00:65 } ; { 00:2E, 00:AE, 00:30, 00:B0, 00:30, 00:B0 } ; The "&" means continue. END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 00 27 00 65 00000016 F ; 01 5E 01 65 00010034 F ; 01 5E 01 63 00000001 T ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Emulation Tables Info ; ; In what follows entries are of the form xx:yy where ; ; xx = the state ; yy = the K1 iKey ; FF:FF means "Do not emulate as anything" ; FF:xx means "Do not change the state, emulate the key" (ikey -> xx) ; Number of emulation tables specified in special keys table. ; ; Table for case where no chord keys held down. ; FF:FF ; 000 FF:FF ; 001 FF:FF ; 002 FF:FF ; 003 FF:FF ; 004 FF:FF ; 005 FF:FF ; 006 FF:15 ; 007 f1 FF:07 ; 008 esc FF:FF ; 009 FF:FF ; 00A FF:FF ; 00B FF:FF ; 00C FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:16 ; 00F f2 FF:FF ; 010 FF:4C ; 011 l ctrl -> l code FF:48 ; 012 l shift FF:FF ; 013 FF:45 ; 014 lock -> capslock FF:71 ; 015 q FF:31 ; 016 1 FF:17 ; 017 f3 FF:FF ; 018 FF:53 ; 019 l alt FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:18 ; 01F f4 FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:19 ; 027 f5 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:1A ; 02F f6 FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:1C ; 037 f7 FF:FF ; 038 FF:55 ; 039 r alt FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:1D ; 03F f8 FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:1E ; 047 f9 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:1F ; 04F f10 FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 f11 FF:57 ; 057 prt screen /sys rq -> SYS FF:4D ; 058 r ctrl FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] 01:7C ; 05C \ (8 \) ; FF:FF ; 05D 01:7C ; 05D \ (8 \) \ | on the Unisys PC kbd vjm 12.3.A.01 FF:FF ; 05E f12 FF:5F ; 05F scroll lock FF:0B ; 060 down arrow FF:0E ; 061 left arrow FF:1B ; 062 pause FF:01 ; 063 up arrow FF:7F ; 064 delete 08:65 ; 065 CODE E end FF:08 ; 066 backspace FF:44 ; 067 insert -> overtype FF:FF ; 068 08:65 ; 069 END lc 1 pad FF:0F ; 06A right arrow FF:0E ; 06B l arrow lc 4 pad 08:62 ; 06C HOME lc 7 pad FF:0C ; 06D PAGE NXT page down (NEXT PAGE) 08:62 ; 06E CODE-B home FF:05 ; 06F PAGE PRV page up (PREV PAGE) FF:44 ; 070 INSERT lc 0 pad FF:7F ; 071 DEL lc . pad FF:0B ; 072 DOWN ARR lc 2 pad (SCROLL UP) 00:7D ; 073 5 pad SCR LK meaningless to CTOS FF:0F ; 074 RT ARR lc 6 pad FF:01 ; 075 UP ARR lc 8 pad (SCROLL DN) FF:56 ; 076 numlock FF:2F ; 077 / pad FF:FF ; 078 FF:1B ; 079 enter -> GO FF:0C ; 07A PG DN lc 3 pad FF:FF ; 07B 01:2B ; 07C + pad FF:05 ; 07D PG UP lc 9 pad 01:38 ; 07E * pad FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:FF ; 083 FF:42 ; 084 - pad ; ; Table for case where shift keys held down. ; FF:FF ; 000 FF:FF ; 001 FF:FF ; 002 FF:FF ; 003 FF:FF ; 004 FF:FF ; 005 FF:FF ; 006 FF:15 ; 007 f1 FF:07 ; 008 esc FF:FF ; 009 FF:FF ; 00A FF:FF ; 00B FF:FF ; 00C FF:09 ; 00D tab FF:5E ; 00E ~ FF:16 ; 00F f2 FF:FF ; 010 FF:4C ; 011 l ctrl -> l code FF:48 ; 012 l shift FF:FF ; 013 FF:45 ; 014 lock -> capslock FF:71 ; 015 q FF:31 ; 016 ! FF:17 ; 017 f3 FF:FF ; 018 FF:53 ; 019 l alt FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E @ FF:18 ; 01F f4 FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 $ FF:33 ; 026 # FF:19 ; 027 f5 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E % FF:1A ; 02F f6 FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y 00:5E ; 036 ^ FF:1C ; 037 f7 FF:FF ; 038 FF:55 ; 039 r alt FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D & FF:38 ; 03E * FF:1D ; 03F f8 FF:FF ; 040 FF:5B ; 041 < FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 ) FF:39 ; 046 ( FF:1E ; 047 f9 FF:FF ; 048 FF:5D ; 049 > FF:2F ; 04A ? FF:6C ; 04B l FF:3B ; 04C : FF:70 ; 04D p FF:2D ; 04E _ FF:1F ; 04F f10 FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 " FF:FF ; 053 FF:7B ; 054 { FF:2B ; 055 = FF:FF ; 056 f11 FF:57 ; 057 prt screen /sys rq -> SYS FF:4D ; 058 r ctrl FF:49 ; 059 r shift FF:0A ; 05A return FF:7D ; 05B } FF:5C ; 05C | (7 |) ; FF:FF ; 05D FF:5C ; 05D | (7 |) \ | on the Unisys PC kbd vjm 12.3.A.01 FF:FF ; 05E f12 01:44 ; 05F scroll lock -> overtype FF:0B ; 060 down arrow FF:0E ; 061 left arrow FF:FF ; 062 pause FF:01 ; 063 up arrow FF:7F ; 064 delete FF:11 ; 065 end -> scroll up FF:08 ; 066 backspace FF:44 ; 067 insert -> overtype FF:FF ; 068 00:60 ; 069 1 pad FF:0F ; 06A right arrow 00:7B ; 06B 4 pad 00:5C ; 06C 7 pad FF:0C ; 06D pg down FF:13 ; 06E home FF:05 ; 06F page up 00:4A ; 070 0 pad 00:4B ; 071 . pad 00:46 ; 072 2 pad 00:7D ; 073 5 pad 00:41 ; 074 6 pad 00:7C ; 075 8 pad FF:56 ; 076 numlock 00:2F ; 077 / pad FF:FF ; 078 FF:1B ; 079 enter -> GO 00:47 ; 07A 3 pad FF:FF ; 07B FF:2B ; 07C + pad 00:21 ; 07D 9 pad FF:38 ; 07E * pad FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:FF ; 083 FF:42 ; 084 - pad ; Table for case where ALT keys held down. ; only gets used for keys that have alt in their allowed states - F1 ; therefore all other keys are NOP and look like unshifted keys FF:FF ; 000 FF:FF ; 001 FF:FF ; 002 FF:FF ; 003 FF:FF ; 004 FF:FF ; 005 FF:FF ; 006 00:00 ; 007 f1 NOTE ALT+F1 = HELP (K1 ikey 00) ; MUST emulate to 0000:00 because Left Alt emulates ; to and ; beeps in the Exec. the 0000: kills the ALT ; and prevents this. FF:07 ; 008 esc FF:FF ; 009 FF:FF ; 00A FF:FF ; 00B FF:FF ; 00C FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:16 ; 00F f2 FF:FF ; 010 FF:4C ; 011 l ctrl -> l code FF:48 ; 012 l shift FF:FF ; 013 FF:45 ; 014 lock -> capslock FF:71 ; 015 q FF:31 ; 016 1 FF:17 ; 017 f3 FF:FF ; 018 FF:53 ; 019 l alt FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:18 ; 01F f4 FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:19 ; 027 f5 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:1A ; 02F f6 FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:1C ; 037 f7 FF:FF ; 038 FF:55 ; 039 r alt FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:1D ; 03F f8 FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:1E ; 047 f9 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:1F ; 04F f10 FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 f11 FF:57 ; 057 prt screen /sys rq -> SYS FF:4D ; 058 r ctrl FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] 01:7C ; 05C \ (8 \) ; FF:FF ; 05D 01:7C ; 05C \ (8 \) \ | on the Unisys PC kbd vjm 12.3.A.01 FF:FF ; 05E f12 01:44 ; 05F scroll lock -> overtype FF:0B ; 060 down arrow FF:0E ; 061 left arrow FF:FF ; 062 pause FF:01 ; 063 up arrow FF:7F ; 064 delete FF:11 ; 065 end -> scroll up FF:08 ; 066 backspace FF:44 ; 067 insert -> overtype FF:FF ; 068 FF:12 ; 069 MOVE lc 1 pad FF:0F ; 06A right arrow FF:0E ; 06B l arrow lc 4 pad FF:43 ; 06C ACTION lc 7 pad FF:0C ; 06D pg down FF:13 ; 06E home FF:05 ; 06F page up FF:02 ; 070 MARK lc 0 pad FF:03 ; 071 BOUND lc . pad FF:11 ; 072 SCRL NXT lc 2 pad (SCROLL UP) FF:7D ; 073 5 pad FF:0D ; 074 NEXT lc 6 pad FF:13 ; 075 SCRL PRV lc 8 pad (SCROLL DN) FF:56 ; 076 numlock FF:2F ; 077 / pad FF:FF ; 078 FF:1B ; 079 enter -> GO FF:14 ; 07A COPY lc 3 pad FF:FF ; 07B 01:2B ; 07C + pad FF:04 ; 07D FINISH lc 9 pad 01:38 ; 07E * pad FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:FF ; 083 FF:42 ; 084 - pad ; ; Table for case where CTOS Lock is on. ;do we need ctos lock and shift? probably not if ctos lock ;is only allowed for selected keys ; FF:FF ; 000 FF:FF ; 001 FF:FF ; 002 FF:FF ; 003 FF:FF ; 004 FF:FF ; 005 FF:FF ; 006 FF:15 ; 007 f1 FF:07 ; 008 esc FF:FF ; 009 FF:FF ; 00A FF:FF ; 00B FF:FF ; 00C FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:16 ; 00F f2 FF:FF ; 010 FF:4C ; 011 l ctrl -> l code FF:48 ; 012 l shift FF:FF ; 013 FF:45 ; 014 lock -> capslock FF:71 ; 015 q FF:31 ; 016 1 FF:17 ; 017 f3 FF:FF ; 018 FF:53 ; 019 l alt FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:18 ; 01F f4 FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:19 ; 027 f5 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:1A ; 02F f6 FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:1C ; 037 f7 FF:FF ; 038 FF:55 ; 039 r alt FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:1D ; 03F f8 FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:1E ; 047 f9 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:1F ; 04F f10 FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 f11 FF:57 ; 057 prt screen /sys rq -> SYS FF:4D ; 058 r ctrl FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] 01:7C ; 05C \ (8 \) ; FF:FF ; 05D 01:7C ; 05D \ (8 \) \ | on the Unisys PC kbd vjm 12.3.A.01 FF:FF ; 05E f12 FF:5F ; 05F scroll lock FF:0B ; 060 down arrow FF:0E ; 061 left arrow FF:FF ; 062 pause FF:01 ; 063 up arrow FF:7F ; 064 delete 08:65 ; 065 CODE E end FF:08 ; 066 backspace FF:44 ; 067 insert -> overtype FF:FF ; 068 FF:12 ; 069 MOVE lc 1 pad FF:0F ; 06A right arrow FF:0E ; 06B l arrow lc 4 pad FF:43 ; 06C ACTION lc 7 pad FF:0C ; 06D PAGE NXT page down (NEXT PAGE) 08:62 ; 06E CODE-B home FF:05 ; 06F PAGE PRV page up (PREV PAGE) FF:02 ; 070 MARK lc 0 pad FF:03 ; 071 BOUND lc . pad FF:11 ; 072 SCRL NXT lc 2 pad (SCROLL UP) FF:FF ; 073 5 pad meaningless if CTOS Lock is on FF:0D ; 074 NEXT lc 6 pad FF:13 ; 075 SCRL PRV lc 8 pad (SCROLL DN) FF:56 ; 076 numlock FF:2F ; 077 / pad FF:FF ; 078 FF:1B ; 079 enter -> GO FF:14 ; 07A COPY lc 3 pad FF:FF ; 07B 01:2B ; 07C + pad FF:04 ; 07D FINISH lc 9 pad 01:38 ; 07E * pad FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:FF ; 083 FF:42 ; 084 - pad ; ; Table for case where numlock key held down. ; FF:FF ; 000 FF:FF ; 001 FF:FF ; 002 FF:FF ; 003 FF:FF ; 004 FF:FF ; 005 FF:FF ; 006 FF:15 ; 007 f1 FF:07 ; 008 esc FF:FF ; 009 FF:FF ; 00A FF:FF ; 00B FF:FF ; 00C FF:09 ; 00D tab FF:5E ; 00E ~ FF:16 ; 00F f2 FF:FF ; 010 FF:4C ; 011 l ctrl -> l code FF:48 ; 012 l shift FF:FF ; 013 FF:45 ; 014 lock -> capslock FF:71 ; 015 q FF:31 ; 016 ! FF:17 ; 017 f3 FF:FF ; 018 FF:53 ; 019 l alt FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E @ FF:18 ; 01F f4 FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 $ FF:33 ; 026 # FF:19 ; 027 f5 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E % FF:1A ; 02F f6 FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y 00:5E ; 036 ^ FF:1C ; 037 f7 FF:FF ; 038 FF:55 ; 039 r alt FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D & FF:38 ; 03E * FF:1D ; 03F f8 FF:FF ; 040 FF:5B ; 041 < FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 ) FF:39 ; 046 ( FF:1E ; 047 f9 FF:FF ; 048 FF:5D ; 049 > FF:2F ; 04A ? FF:6C ; 04B l FF:3B ; 04C : FF:70 ; 04D p FF:2D ; 04E _ FF:1F ; 04F f10 FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 " FF:FF ; 053 FF:7B ; 054 { FF:2B ; 055 = FF:FF ; 056 f11 FF:57 ; 057 prt screen /sys rq -> SYS FF:4D ; 058 r ctrl FF:49 ; 059 r shift FF:0A ; 05A return FF:7D ; 05B } FF:5C ; 05C | (7 |) ; FF:FF ; 05D FF:5C ; 05C | (7 |) \ | on the Unisys PC kbd vjm 12.3.A.01 FF:FF ; 05E f12 01:44 ; 05F scroll lock -> overtype FF:0B ; 060 down arrow FF:0E ; 061 left arrow FF:FF ; 062 pause FF:01 ; 063 up arrow FF:7F ; 064 delete FF:11 ; 065 end -> scroll up FF:08 ; 066 backspace FF:44 ; 067 insert -> overtype FF:FF ; 068 FF:60 ; 069 1 pad FF:0F ; 06A right arrow FF:7B ; 06B 4 pad FF:5C ; 06C 7 pad FF:0C ; 06D pg down FF:13 ; 06E home FF:05 ; 06F page up FF:4A ; 070 0 pad FF:4B ; 071 . pad FF:46 ; 072 2 pad FF:7D ; 073 5 pad FF:41 ; 074 6 pad FF:7C ; 075 8 pad FF:56 ; 076 numlock FF:2F ; 077 / pad FF:FF ; 078 FF:1B ; 079 enter -> GO FF:47 ; 07A 3 pad FF:FF ; 07B FF:2B ; 07C + pad FF:21 ; 07D 9 pad FF:38 ; 07E * pad FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:FF ; 083 FF:42 ; 084 - pad END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START HOT KEYS TABLE 0 { 0 } { 0 } { 0 } ; 000 0 { 0 } { 0 } { 0 } ; 001 f9 0 { 0 } { 0 } { 0 } ; 002 FAKE GO KEY 0 { 0 } { 0 } { 0 } ; 003 f5 0 { 0 } { 0 } { 0 } ; 004 f3 0 { 0 } { 0 } { 0 } ; 005 f1 0 { 0 } { 0 } { 0 } ; 006 f2 0 { 0 } { 0 } { 0 } ; 007 f12 BOUND 0 { 0 } { 0 } { 0 } ; 008 0 { 0 } { 0 } { 0 } ; 009 f10 0 { 0 } { 0 } { 0 } ; 00A f8 0 { 0 } { 0 } { 0 } ; 00B f6 0 { 0 } { 0 } { 0 } ; 00C f4 0 { 0 } { 0 } { 0 } ; 00D tab 0 { 0 } { 0 } { 0 } ; 00E l quote (1 `) 0 { 0 } { 0 } { 0 } ; 00F 0 { 0 } { 0 } { 0 } ; 010 0 { 0 } { 0 } { 0 } ; 011 l alt 0 { 0 } { 0 } { 0 } ; 012 l shift 0 { 0 } { 0 } { 0 } ; 013 0 { 0 } { 0 } { 0 } ; 014 l ctrl -> l code 0 { 0 } { 0 } { 0 } ; 015 q 31 { 0 } { 0 } { 0 } ; 016 1 0 { 0 } { 0 } { 0 } ; 017 0 { 0 } { 0 } { 0 } ; 018 0 { 0 } { 0 } { 0 } ; 019 7a { 6 } { 0 } { 0 } ; 01A z 0 { 0 } { 0 } { 0 } ; 01B s 61 { 1,2 } { 0 } { 0 } ; 01C a 0 { 0 } { 0 } { 0 } ; 01D w 0 { 0 } { 0 } { 0 } ; 01E 2 0 { 0 } { 0 } { 0 } ; 01F 0 { 0 } { 0 } { 0 } ; 020 0 { 0 } { 0 } { 0 } ; 021 c 0 { 0 } { 0 } { 0 } ; 022 x 0 { 0 } { 0 } { 0 } ; 023 d 0 { 0 } { 0 } { 0 } ; 024 e 0 { 0 } { 0 } { 0 } ; 025 4 0 { 0 } { 0 } { 0 } ; 026 3 0 { 0 } { 0 } { 0 } ; 027 0 { 0 } { 0 } { 0 } ; 028 0 { 0 } { 0 } { 0 } ; 029 space 0 { 0 } { 0 } { 0 } ; 02A v 0 { 0 } { 0 } { 0 } ; 02B f 0 { 0 } { 0 } { 0 } ; 02C t 0 { 0 } { 0 } { 0 } ; 02D r 0 { 0 } { 0 } { 0 } ; 02E 5 0 { 0 } { 0 } { 0 } ; 02F 0 { 0 } { 0 } { 0 } ; 030 0 { 0 } { 0 } { 0 } ; 031 n 0 { 0 } { 0 } { 0 } ; 032 b 0 { 0 } { 0 } { 0 } ; 033 h 0 { 0 } { 0 } { 0 } ; 034 g 0 { 0 } { 0 } { 0 } ; 035 y 0 { 0 } { 0 } { 0 } ; 036 6 0 { 0 } { 0 } { 0 } ; 037 0 { 0 } { 0 } { 0 } ; 038 0 { 0 } { 0 } { 0 } ; 039 0 { 0 } { 0 } { 0 } ; 03A m 0 { 0 } { 0 } { 0 } ; 03B j 0 { 0 } { 0 } { 0 } ; 03C u 0 { 0 } { 0 } { 0 } ; 03D 7 0 { 0 } { 0 } { 0 } ; 03E 8 0 { 0 } { 0 } { 0 } ; 03F 0 { 0 } { 0 } { 0 } ; 040 0 { 0 } { 0 } { 0 } ; 041 , 0 { 0 } { 0 } { 0 } ; 042 k 0 { 0 } { 0 } { 0 } ; 043 i 0 { 0 } { 0 } { 0 } ; 044 o 0 { 0 } { 0 } { 0 } ; 045 0 0 { 0 } { 0 } { 0 } ; 046 9 0 { 0 } { 0 } { 0 } ; 047 0 { 0 } { 0 } { 0 } ; 048 0 { 0 } { 0 } { 0 } ; 049 . 0 { 0 } { 0 } { 0 } ; 04A / 0 { 0 } { 0 } { 0 } ; 04B l 0 { 0 } { 0 } { 0 } ; 04C ; 0 { 0 } { 0 } { 0 } ; 04D p 0 { 0 } { 0 } { 0 } ; 04E - 0 { 0 } { 0 } { 0 } ; 04F 0 { 0 } { 0 } { 0 } ; 050 0 { 0 } { 0 } { 0 } ; 051 0 { 0 } { 0 } { 0 } ; 052 ' 0 { 0 } { 0 } { 0 } ; 053 0 { 0 } { 0 } { 0 } ; 054 [ 0 { 0 } { 0 } { 0 } ; 055 = 0 { 0 } { 0 } { 0 } ; 056 0 { 0 } { 0 } { 0 } ; 057 0 { 0 } { 0 } { 0 } ; 058 lock -> capslock 0 { 0 } { 0 } { 0 } ; 059 r shift 0 { 0 } { 0 } { 0 } ; 05A return 0 { 0 } { 0 } { 0 } ; 05B ] 0 { 0 } { 0 } { 0 } ; 05C \ (8 \) 0 { 0 } { 0 } { 0 } ; 05D 102 key keyboard only 0 { 0 } { 0 } { 0 } ; 05E 0 { 0 } { 0 } { 0 } ; 05F borrowed for pause 0 { 0 } { 0 } { 0 } ; 060 0 { 0 } { 0 } { 0 } ; 061 102 key keyboard only 0 { 0 } { 0 } { 0 } ; 062 0 { 0 } { 0 } { 0 } ; 063 0 { 0 } { 0 } { 0 } ; 064 0 { 0 } { 0 } { 0 } ; 065 0 { 0 } { 0 } { 0 } ; 066 0 { 0 } { 0 } { 0 } ; 067 0 { 0 } { 0 } { 0 } ; 068 0 { 0 } { 0 } { 0 } ; 069 END FINISH 0 { 0 } { 0 } { 0 } ; 06A 0 { 0 } { 0 } { 0 } ; 06B l arrow 0 { 0 } { 0 } { 0 } ; 06C HOME ACTION 0 { 0 } { 0 } { 0 } ; 06D 0 { 0 } { 0 } { 0 } ; 06E 0 { 0 } { 0 } { 0 } ; 06F 0 { 0 } { 0 } { 0 } ; 070 INSERT 0 { 0 } { 0 } { 0 } ; 071 DEL 0 { 0 } { 0 } { 0 } ; 072 DOWN ARR 0 { 0 } { 0 } { 0 } ; 073 (only get 73 with numlock on) 0 { 0 } { 0 } { 0 } ; 074 RT ARR 0 { 0 } { 0 } { 0 } ; 075 UP ARR 0 { 0 } { 0 } { 0 } ; 076 escape/cancel 0 { 0 } { 0 } { 0 } ; 077 numlock 0 { 0 } { 0 } { 0 } ; 078 f11 MARK 0 { 0 } { 0 } { 0 } ; 079 numpad + 0 { 0 } { 0 } { 0 } ; 07A PG DN lc 3 pad 0 { 0 } { 0 } { 0 } ; 07B numpad - 0 { 0 } { 0 } { 0 } ; 07C numpad * 0 { 0 } { 0 } { 0 } ; 07D PG UP lc 9 pad 0 { 0 } { 0 } { 0 } ; 07E scroll lock->OVERTYPE (INSERT) 0 { 0 } { 0 } { 0 } ; 07F 0 { 0 } { 0 } { 0 } ; 080 0 { 0 } { 0 } { 0 } ; 081 0 { 0 } { 0 } { 0 } ; 082 0 { 0 } { 0 } { 0 } ; 083 f7 0 { 0 } { 0 } { 0 } ; 084 alt+print screen = sysrq on PC kbd SYSTEM key END HOT KEYS TABLE /***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* K1.kbd_data */ /* */ /* This file contains the K1' translation table for Power Port */ /* NOTE: iKey = 66h. */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION */ /* 04/20/92 KH / DisAllow ALTs for PowerPort. */ /* 03/20/92 122G.03 V. Miller / Changed so second (from the */ /* SG-102-K keyboard) is passed through. */ /* Meant adding a second alt key which */ /* I called as iKey "55h". Had */ /* to update Allowed State Table. */ /* Changed Conditions Table so */ /* selects same table as . */ /* 03/17/92 122G.02 V. Miller / Added comments and change number of */ /* of emulated LEDs from 3 to 16. */ /* 02/17/92 122F.01 V. Miller / Changed so is passed through */ /* Meant adding an alt key, , as */ /* iKey "53h" to match value on the K5 */ /* keyboard. Updated Allowed State Table */ /* and changed Conditions Table so */ /* selects same table as . */ /* Val Miller / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; ; This is the data file for the K1 Keyboard that is used by the "Create ; Keyboard Table" Application. The format is translation tables for a ; K1 keyboard. ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; ; Changes: ; ; 11/14/91 vjm Removed emulation of to be for XVT ; All allowed states with {..,3,4..} changed to {..,3,4..,6}. ; Two new conditions added "{6} {} {}" and ; "{6} {1,2,3,4,5} {}" which select table 3 the same ; table selected by {1,2} {3.4} {}, the CODE-SHIFT ; condition. ; Keyboard name K0 ; Output file name K0KbdTables.obj ; Name of PUBLIC in object module at start of table K0KeyBoardData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ; TRANSLATION DATA ; ; TRANSLATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if translation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of translation tables in decimal ; | | | | ; 80 66 80 4 ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have at least 19 and at most 29entries and they MUST ; be in the order shown. 22 ; Number special keys in decimal 61 ; a 62 ; b 7F ; 44 ; 4C ; 4D ; 04 ; 43 ; 45 ; 48 ; 49 ; 64 ; Mouse Disable 65 ; Mouse Enable 53 ; 00 ; c 1B ; 40 ; iKey not valid 20 ; Diacritic Escape 00 ; Sys Key If there is no key use an iKey that is ; not produced by the keyboard in question OR 00 ; NOTE that the help key can not be used as the ; system key since it is '00' 00 ; OS1 00 ; OS2 00 ; OS3 END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for a translation table. ; 7 ; Number of entries ; ; !!! ALL NUMBERS IN THE FOLLOWING TABLE MUST BE IN HEX ; ; key bMask* fToggle fLed LED mask** ; number bit bit fExclus- ; position position ionary ; (hex) (hex) (hex) ; 48 0 F F 0 F ; Chord #1 49 1 F F 0 F ; Chord #2 4C 2 F F 0 F ; Chord #3 4D 3 F F 0 F ; Chord #4 45 4 T T 6 F ; Chord #5 53 5 F F 0 F ; Chord #6 55 6 F F 0 F ; Chord #7 ; * NOTES: bMask bit position ; ; 1. The number of the bit set (to 1) in the bMask word for this ; chord where "0" means the least significant bit and "15" ; means the most significant bit. ; ; 2. The values for bMask are NOT required to be consecutive. ; ; ** NOTE: there MUST be an entry for "LED mask bit position" even if the ; "fLED" entry is "F"; it can be zero. END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START CONTROL CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. 8 ; Number of entries 00 ; escState 00 ; escState2 00 ; noDiacrit 00 ; noRepeat 0C ; status4 00 ; status2 03 ; status1 10 ; altStatus1 END CONTROL CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START RPT ATTRS TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; The following entries for FAST and SLOW attribute characteristics are ; optional. You can have both none or one of them. The allowable codes ; are: ; ; Delay until repeating starts codes: 1 - 0.2 seconds ; 2 - 0.4 seconds ; 3 - 0.7 seconds ; ; Frequency of repetition codes: 0 - 1 character / second ; 1 - 10 character / second ; 2 - 20 character / second ; 3 - 30 character / second ; ; If no entry is made a default will be shown. The dafaults are: ; ; Delay Until Frequency Of ; Repeating Repeating ; Starts Code Code ; ; Attribute Characteristics Fast 2 3 ; ; Attribute Characteristics Slow 3 2 ; ; ENTRIES ; ---------------------------------------------------- ; Repeat iKey Key ; Attribute Number Name ; --------- ------ --------- None ; 000 help Fast ; 001 up-arrow None ; 002 mark None ; 003 bound None ; 004 finish None ; 005 prev page Slow ; 006 1/2-1/4 None ; 007 cancel Slow ; 008 backspace None ; 009 tab Slow ; 00A return Fast ; 00B down-arrow None ; 00C next page Slow ; 00D next Fast ; 00E left-arrow Fast ; 00F right-arrow None ; 010 SH-L Slow ; 011 scroll-up None ; 012 move Slow ; 013 scroll-down None ; 014 copy None ; 015 f1 None ; 016 f2 None ; 017 f3 None ; 018 f4 None ; 019 f5 None ; 01A f6 None ; 01B GO None ; 01C f7 None ; 01D f8 None ; 01E f9 None ; 01F f10 Slow ; 020 space Slow ; 021 9 9 None ; 022 SH-R None ; 023 0 None ; 024 NEXT None ; 025 None ; 026 Slow ; 027 ' " None ; 028 None ; 029 None ; 02A Slow ; 02B + = Slow ; 02C , , Slow ; 02D - _ Slow ; 02E . . Slow ; 02F / ? Slow ; 030 0 right parens Slow ; 031 1 ! Slow ; 032 2 @ Slow ; 033 3 # Slow ; 034 4 $ Slow ; 035 5 percent Slow ; 036 6 cent Slow ; 037 7 & Slow ; 038 8 * Slow ; 039 9 left parens None ; 03A Slow ; 03B None ; 03C None ; 03D None ; 03E None ; 03F iKeyInvalid None ; 040 iKeyNoKeys Slow ; 041 6 6 Slow ; 042 - - None ; 043 reset None ; 044 overtype None ; 045 lock Slow ; 046 2 2 Slow ; 047 3 3 None ; 048 shift-r None ; 049 shift-l Slow ; 04A 0 0 Slow ; 04B . . None ; 04C code-r None ; 04D code-l None ; 04E None ; 04F None ; 050 None ; 051 None ; 052 sys None ; 053 alt None ; 054 None ; 055 None ; 056 None ; 057 None ; 058 None ; 059 None ; 05A Slow ; 05B [ < Slow ; 05C 7 | Slow ; 05D ] > Slow ; 05E ^ ~ None ; 05F Slow ; 060 1 ` Slow ; 061 a A Slow ; 062 b B Slow ; 063 c C Slow ; 064 d D Slow ; 065 e E Slow ; 066 f F Slow ; 067 g G Slow ; 068 h H Slow ; 069 i I Slow ; 06A j J Slow ; 06B k K Slow ; 06C l L Slow ; 06D m M Slow ; 06E n N Slow ; 06F o O Slow ; 070 p P Slow ; 071 q Q Slow ; 072 r R Slow ; 073 s S Slow ; 074 t T Slow ; 075 u U Slow ; 076 v V Slow ; 077 w W Slow ; 078 x X Slow ; 079 y Y Slow ; 07A z Z Slow ; 07B 4 { Slow ; 07C 8 backslash Slow ; 07D 5 } None ; 07E Slow ; 07F del END RPT ATTRS TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; ------------------ ------ --------- { 1,2,3,4 } ; 000 help { 1,2,3,4 } ; 001 up-arrow { 1,2,3,4 } ; 002 mark { 1,2,3,4 } ; 003 bound { 1,2,3,4 } ; 004 finish { 1,2,3,4 } ; 005 prev page { 1,2,3,4 } ; 006 1/2-1/4 { 1,2,3,4 } ; 007 cancel { 1,2,3,4 } ; 008 backspace { 1,2,3,4 } ; 009 tab { 1,2,3,4 } ; 00A return { 1,2,3,4 } ; 00B down-arrow { 1,2,3,4 } ; 00C next page { 1,2,3,4 } ; 00D next { 1,2,3,4 } ; 00E left-arrow { 1,2,3,4 } ; 00F right-arrow { 0 } ; 010 SH-L { 1,2,3,4 } ; 011 scroll-up { 1,2,3,4 } ; 012 move { 1,2,3,4 } ; 013 scroll-down { 1,2,3,4 } ; 014 copy { 1,2,3,4 } ; 015 f1 { 1,2,3,4 } ; 016 f2 { 1,2,3,4 } ; 017 f3 { 1,2,3,4 } ; 018 f4 { 1,2,3,4 } ; 019 f5 { 1,2,3,4 } ; 01A f6 { 1,2,3,4 } ; 01B GO { 1,2,3,4 } ; 01C f7 { 1,2,3,4 } ; 01D f8 { 1,2,3,4 } ; 01E f9 { 1,2,3,4 } ; 01F f10 { 1,2,3,4 } ; 020 space { 1,2,3,4,6,7 } ; 021 9 9 { 0 } ; 022 SH-R { 0 } ; 023 0 { 0 } ; 024 NEXT { 0 } ; 025 { 0 } ; 026 { 1,2,3,4,6,7 } ; 027 ' " { 0 } ; 028 { 0 } ; 029 { 0 } ; 02A { 1,2,3,4,6,7 } ; 02B + = { 1,2,3,4,6,7 } ; 02C , , { 1,2,3,4,6,7 } ; 02D - _ { 1,2,3,4,6,7 } ; 02E . . { 1,2,3,4,6,7 } ; 02F / ? { 1,2,3,4,6,7 } ; 030 0 right parens { 1,2,3,4,6,7 } ; 031 1 ! { 1,2,3,4,6,7 } ; 032 2 @ { 1,2,3,4,6,7 } ; 033 3 # { 1,2,3,4,6,7 } ; 034 4 $ { 1,2,3,4,6,7 } ; 035 5 percent { 1,2,3,4,6,7 } ; 036 6 cent { 1,2,3,4,6,7 } ; 037 7 & { 1,2,3,4,6,7 } ; 038 8 * { 1,2,3,4,6,7 } ; 039 9 left parens { 0 } ; 03A { 1,2,3,4,6,7 } ; 03B { 0 } ; 03C { 0 } ; 03D { 0 } ; 03E { 0 } ; 03F iKeyInvalid { 0 } ; 040 iKeyNoKeys { 1,2,3,4,6,7 } ; 041 6 6 { 1,2,3,4,6,7 } ; 042 - - { 0 } ; 043 reset { 1,2,3,4 } ; 044 overtype { 5 } ; 045 lock { 1,2,3,4,6,7 } ; 046 2 2 { 1,2,3,4,6,7 } ; 047 3 3 { 1 } ; 048 shift-r { 2 } ; 049 shift-l { 1,2,3,4,6,7 } ; 04A 0 0 { 1,2,3,4,6,7 } ; 04B . . { 3 } ; 04C code-r { 4 } ; 04D code-l { 0 } ; 04E { 0 } ; 04F { 0 } ; 050 { 0 } ; 051 { 0 } ; 052 { 0 } ; 053 { 0 } ; 054 { 0 } ; 055 { 0 } ; 056 { 0 } ; 057 { 0 } ; 058 { 0 } ; 059 { 0 } ; 05A { 1,2,3,4,6,7 } ; 05B [ < { 1,2,3,4,6,7 } ; 05C 7 | { 1,2,3,4,6,7 } ; 05D ] > { 1,2,3,4,6,7 } ; 05E ^ ~ { 0 } ; 05F { 1,2,3,4,6,7 } ; 060 1 ` { 1,2,3,4,5,6,7 } ; 061 a A { 1,2,3,4,5,6,7 } ; 062 b B { 1,2,3,4,5,6,7 } ; 063 c C { 1,2,3,4,5,6,7 } ; 064 d D { 1,2,3,4,5,6,7 } ; 065 e E { 1,2,3,4,5,6,7 } ; 066 f F { 1,2,3,4,5,6,7 } ; 067 g G { 1,2,3,4,5,6,7 } ; 068 h H { 1,2,3,4,5,6,7 } ; 069 i I { 1,2,3,4,5,6,7 } ; 06A j J { 1,2,3,4,5,6,7 } ; 06B k K { 1,2,3,4,5,6,7 } ; 06C l L { 1,2,3,4,5,6,7 } ; 06D m M { 1,2,3,4,5,6,7 } ; 06E n N { 1,2,3,4,5,6,7 } ; 06F o O { 1,2,3,4,5,6,7 } ; 070 p P { 1,2,3,4,5,6,7 } ; 071 q Q { 1,2,3,4,5,6,7 } ; 072 r R { 1,2,3,4,5,6,7 } ; 073 s S { 1,2,3,4,5,6,7 } ; 074 t T { 1,2,3,4,5,6,7 } ; 075 u U { 1,2,3,4,5,6,7 } ; 076 v V { 1,2,3,4,5,6,7 } ; 077 w W { 1,2,3,4,5,6,7 } ; 078 x X { 1,2,3,4,5,6,7 } ; 079 y Y { 1,2,3,4,5,6,7 } ; 07A z Z { 1,2,3,4,6,7 } ; 07B 4 { { 1,2,3,4,6,7 } ; 07C 8 backslash { 1,2,3,4,6,7 } ; 07D 5 } { 0 } ; 07E { 1,2,3,4 } ; 07F del END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 8 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; Table Conditions Comments ; ID -------------------------------- ; orState 1 orState 2 orState 3 ; ----- --------- --------- --------- ----------------------------------- 0 { } { } { } ; No chord keys down 1 { 1,2,5 } ; Shift-lock OR either Shift key ; down; one "orState" 2 { 3,4 } ; Either Code key down; one ; "orState" 3 { 1,2 } { 3,4 } ; Either Shift key down AND either ; Code key down; two "orStates" 2 { 5 } { 3,4 } ; Shift-lock key down AND either ; Code key down; two "orStates" 3 { 1,2 } { 3,4 } { 5 } ; Shift-lock AND either Shift key ; down AND either Code key ; down; three "orStates". ; --------------------- New additions --------------------- 3 { 6,7 } { } ; Alt key down; one "orState" 3 { 6,7 } {1,2,3,4,5} ; Alt key and one or more other ; chord keys down; two ; "orStates" END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 0 ; Number of multibyte strings ; String : each entry is a "state:hardware ikey" pair ; ; As an example, the following string would display "Hi there" as shown. ; Note the upstroke for the last key is present; this is okay the ; tool will add any necessary upstrokes. ; ; The "&" means continue. ; ; shft-h shft-h i i space space t t h h ; down up down up down up down up down up ; { 01:68, 01:E8, 00:69, 00:E9, 00:20, 00:A0, 00:74, 00:F4, 00:68, 00:E8 & ; 00:65, 00:E5, 00:72, 00:F2, 00:65 } ; e e r r e ; down up down up down ; ; The following string would display ".00" . ; ; { 00:2E, 00:AE, 00:30, 00:B0, 00:30, 00:B0 } ; END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Translation Tables Info ; ; Table #0, for case where no chord keys held down. ; WIDTH 1 ; 00 ; 000 help 01 ; 001 up-arrow 02 ; 002 mark 0D ; 003 bound 04 ; 004 finish 05 ; 005 prev page 06 ; 006 1/2-1/4 07 ; 007 cancel 08 ; 008 backspace 09 ; 009 tab 0A ; 00A return 0B ; 00B down-arrow 0C ; 00C next page 0A ; 00D next 0E ; 00E left-arrow 12 ; 00F right-arrow EA ; 010 SH-L K2, K3, K5 & K6 "JUMP" 11 ; 011 scroll-up 0F ; 012 move 13 ; 013 scroll-down 14 ; 014 copy 15 ; 015 f1 16 ; 016 f2 17 ; 017 f3 18 ; 018 f4 19 ; 019 f5 1A ; 01A f6 1B ; 01B GO 1C ; 01C f7 1D ; 01D f8 1E ; 01E f9 1F ; 01F f10 20 ; 020 space 39 ; 021 9 (from 9 9 keypad key) BA ; 022 SH-R K2, K3, K5 & K6 "DEL CHAR" 00 ; 023 0 00 ; 024 NEXT 00 ; 025 FE ; 026 K2, K3, K5 & K6 "COLUMN" key 27 ; 027 ' (from ' " keypad key) FB ; 028 K2, K3, K5 & K6 "PAGE" key E0 ; 029 K2, K3, K5 & K6 "PARAGRAPH" key BF ; 02A K2, K3, K5 & K6 "SENTENCE" key 3D ; 02B = 2C ; 02C , (from , , keypad key) 2D ; 02D - (from - _ keypad key) 2E ; 02E . (from . . keypad key) 2F ; 02F / 30 ; 030 0 (from 0 ) keypad key) 31 ; 031 1 (from 1 ! keypad key) 32 ; 032 2 (from 2 @ keypad key) 33 ; 033 3 (from 3 # keypad key) 34 ; 034 4 (from 4 $ keypad key) 35 ; 035 5 (from 5 % keypad key) 36 ; 036 6 (from 6  keypad key) 37 ; 037 7 (from 7 & keypad key) 38 ; 038 8 (from 8 * keypad key) 39 ; 039 9 (from 9 ( keypad key) 00 ; 03A 3B ; 03B ; BE ; 03C K2, K3, K5 & K6 "WORD" key FD ; 03D K2, K3, K5 & K6 "LINE" key 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys 36 ; 041 6 (from 6 6 keypad key) 2D ; 042 - (from - - keypad key) 00 ; 043 reset D0 ; 044 overtype 00 ; 045 lock 32 ; 046 2 (from 2 2 keypad key) 33 ; 047 3 (from 3 3 keypad key) 00 ; 048 shift 00 ; 049 shift 30 ; 04A 0 (from 0 0 keypad key) 2E ; 04B . (from . . keypad key) 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 sys 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A 5B ; 05B [ 37 ; 05C 7 (from 7 | keypad key) 5D ; 05D ] 5E ; 05E ^ 00 ; 05F 31 ; 060 1 (from 1 ` keypad key) 61 ; 061 a 62 ; 062 b 63 ; 063 c 64 ; 064 d 65 ; 065 e 66 ; 066 f 67 ; 067 g 68 ; 068 h 69 ; 069 i 6A ; 06A j 6B ; 06B k 6C ; 06C l 6D ; 06D m 6E ; 06E n 6F ; 06F o 70 ; 070 p 71 ; 071 q 72 ; 072 r 73 ; 073 s 74 ; 074 t 75 ; 075 u 76 ; 076 v 77 ; 077 w 78 ; 078 x 79 ; 079 y 7A ; 07A z 34 ; 07B 4 (from 4 { keypad key) 38 ; 07C 8 (from 8 \ keypad key) 35 ; 07D 5 (from 5 } keypad key) 00 ; 07E 7F ; 07F del ; ; Table #1, for case where either chord key held down. ; WIDTH 1 C0 ; 000 help C1 ; 001 up-arrow C2 ; 002 mark C3 ; 003 bound C4 ; 004 finish C5 ; 005 prev page 10 ; 006 1/2-1/4 C7 ; 007 cancel 08 ; 008 backspace 09 ; 009 tab 0A ; 00A return CB ; 00B down-arrow CC ; 00C next page 0A ; 00D next CE ; 00E left-arrow D2 ; 00F right-arrow 00 ; 010 SH-L D1 ; 011 scroll-up CF ; 012 move D3 ; 013 scroll-down D4 ; 014 copy D5 ; 015 f1 D6 ; 016 f2 D7 ; 017 f3 D8 ; 018 f4 D9 ; 019 f5 DA ; 01A f6 C9 ; 01B GO DC ; 01C f7 CD ; 01D f8 CA ; 01E f9 DF ; 01F f10 20 ; 020 space 39 ; 021 9 (from 9 9 keypad key) BA ; 022 SH-R K2, K3, K5 & K6 "DEL CHAR" 00 ; 023 0 00 ; 024 NEXT 00 ; 025 FE ; 026 K2, K3, K5 & K6 "COLUMN" 22 ; 027 " (from ' " keypad key) FB ; 028 K2, K3, K5 & K6 "PAGE" key E0 ; 029 K2, K3, K5 & K6 "PARAGRAPH" key BF ; 02A K2, K3, K5 & K6 "SENTENCE" key 2B ; 02B + 2C ; 02C , (from , , keypad key) 5F ; 02D _ (from - _ keypad key) 2E ; 02E . (from . . keypad key) 3F ; 02F ? 29 ; 030 ) (from 0 ) keypad key) 21 ; 031 ! (from 1 ! keypad key) 40 ; 032 @ (from 2 @ keypad key) 23 ; 033 # (from 3 # keypad key) 24 ; 034 $ (from 4 $ keypad key) 25 ; 035 % (from 5 % keypad key) 03 ; 036  (from 6  keypad key) 26 ; 037 & (from 7 & keypad key) 2A ; 038 * (from 8 * keypad key) 28 ; 039 ( (from 9 ( keypad key) 00 ; 03A 3A ; 03B : BE ; 03C K2, K3, K5 & K6 "WORD" key FD ; 03D K2, K3, K5 & K6 "LINE" key 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys 36 ; 041 6 (from 6 6 keypad key) 2D ; 042 - (from - - keypad key) 00 ; 043 reset D0 ; 044 overtype 00 ; 045 lock 32 ; 046 2 (from 2 2 keypad key) 33 ; 047 3 (from 3 3 keypad key) 00 ; 048 shift 00 ; 049 shift 30 ; 04A 0 (from 0 0 keypad key) 2E ; 04B . (from . . keypad key) 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A 3C ; 05B < 7C ; 05C | (from 7 | keypad key) 3E ; 05D > 7E ; 05E ~ 00 ; 05F 60 ; 060 ` (from 1 ` keypad key) 41 ; 061 A 42 ; 062 B 43 ; 063 C 44 ; 064 D 45 ; 065 E 46 ; 066 F 47 ; 067 G 48 ; 068 H 49 ; 069 I 4A ; 06A J 4B ; 06B K 4C ; 06C L 4D ; 06D M 4E ; 06E N 4F ; 06F O 50 ; 070 P 51 ; 071 Q 52 ; 072 R 53 ; 073 S 54 ; 074 T 55 ; 075 U 56 ; 076 V 57 ; 077 W 58 ; 078 X 59 ; 079 Y 5A ; 07A Z 7B ; 07B { (from 4 { keypad key) 5C ; 07C \ (from 8 \ keypad key) 7D ; 07D } (from 5 } keypad key) 00 ; 07E C8 ; 07F del ; ; Table #2, for case where either chord key held down. ; WIDTH 1 80 ; 000 help 81 ; 001 up-arrow 82 ; 002 mark 8D ; 003 bound 84 ; 004 finish 85 ; 005 prev page 86 ; 006 1/2-1/4 87 ; 007 cancel 88 ; 008 backspace 89 ; 009 tab 8A ; 00A return 8B ; 00B down-arrow 8C ; 00C next page 8A ; 00D next 8E ; 00E left-arrow 92 ; 00F right-arrow 00 ; 010 SH-L 91 ; 011 scroll-up 8F ; 012 move 93 ; 013 scroll-down 94 ; 014 copy 95 ; 015 f1 96 ; 016 f2 97 ; 017 f3 98 ; 018 f4 99 ; 019 f5 9A ; 01A f6 9B ; 01B GO 9C ; 01C f7 9D ; 01D f8 9E ; 01E f9 9F ; 01F f10 A0 ; 020 space B9 ; 021 9 9 00 ; 022 SH-R 00 ; 023 0 00 ; 024 NEXT 00 ; 025 00 ; 026 A7 ; 027 ' " 00 ; 028 00 ; 029 00 ; 02A BD ; 02B + = AC ; 02C , , AD ; 02D - _ AE ; 02E . . AF ; 02F / ? B0 ; 030 0 right parens B1 ; 031 1 ! B2 ; 032 2 @ B3 ; 033 3 # B4 ; 034 4 $ B5 ; 035 5 percent B6 ; 036 6 cent B7 ; 037 7 & B8 ; 038 8 * B9 ; 039 9 left parens 00 ; 03A BB ; 03B ; : 00 ; 03C 00 ; 03D 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys B6 ; 041 6 6 AD ; 042 - - 00 ; 043 reset 00 ; 044 overtype 00 ; 045 lock B2 ; 046 2 2 B3 ; 047 3 3 00 ; 048 shift 00 ; 049 shift B0 ; 04A 0 0 AE ; 04B . . 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A DB ; 05B [ < B7 ; 05C 7 | DD ; 05D ] > DE ; 05E ^ ~ 00 ; 05F B1 ; 060 1 ` E1 ; 061 a A E2 ; 062 b B E3 ; 063 c C E4 ; 064 d D E5 ; 065 e E E6 ; 066 f F E7 ; 067 g G E8 ; 068 h H E9 ; 069 i I EA ; 06A j J EB ; 06B k K EC ; 06C l L ED ; 06D m M EE ; 06E n N EF ; 06F o O F0 ; 070 p P F1 ; 071 q Q F2 ; 072 r R F3 ; 073 s S F4 ; 074 t T F5 ; 075 u U F6 ; 076 v V F7 ; 077 w W F8 ; 078 x X F9 ; 079 y Y FA ; 07A z Z B4 ; 07B 4 { B8 ; 07C 8 backslash B5 ; 07D 5 } 00 ; 07E FF ; 07F del ; ; Table #3, for case where one of the chord keys and one of the ; chord keys held down simultaneously. ; WIDTH 1 C0 ; 000 help C1 ; 001 up-arrow C2 ; 002 mark C3 ; 003 bound C4 ; 004 finish C5 ; 005 prev page 90 ; 006 1/2-1/4 C7 ; 007 cancel 88 ; 008 backspace 89 ; 009 tab 8A ; 00A return CB ; 00B down-arrow CC ; 00C next page 8A ; 00D next CE ; 00E left-arrow D2 ; 00F right-arrow 00 ; 010 SH-L D3 ; 011 scroll-up CF ; 012 move D3 ; 013 scroll-down D4 ; 014 copy D5 ; 015 f1 D6 ; 016 f2 D7 ; 017 f3 D8 ; 018 f4 D9 ; 019 f5 DA ; 01A f6 C9 ; 01B GO DC ; 01C f7 CD ; 01D f8 CA ; 01E f9 DF ; 01F f10 A0 ; 020 space B9 ; 021 9 9 00 ; 022 SH-R 00 ; 023 0 00 ; 024 NEXT 00 ; 025 00 ; 026 A2 ; 027 ' " 00 ; 028 00 ; 029 00 ; 02A AB ; 02B + = AC ; 02C , , DF ; 02D - _ AE ; 02E . . BF ; 02F / ? A9 ; 030 0 right parens A1 ; 031 1 ! C0 ; 032 2 @ A3 ; 033 3 # A4 ; 034 4 $ A5 ; 035 5 percent 83 ; 036 6 cent A6 ; 037 7 & AA ; 038 8 * A8 ; 039 9 left parens 00 ; 03A BA ; 03B ; : 00 ; 03C 00 ; 03D 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys B6 ; 041 6 6 AD ; 042 - - 00 ; 043 reset 00 ; 044 overtype 00 ; 045 lock B2 ; 046 2 2 B3 ; 047 3 3 00 ; 048 shift 00 ; 049 shift B0 ; 04A 0 0 AE ; 04B . . 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A BC ; 05B [ < FC ; 05C 7 | BE ; 05D ] > FE ; 05E ^ ~ 00 ; 05F E0 ; 060 1 ` C1 ; 061 a A C2 ; 062 b B C3 ; 063 c C C4 ; 064 d D C5 ; 065 e E C6 ; 066 f F C7 ; 067 g G C8 ; 068 h H C9 ; 069 i I CA ; 06A j J CB ; 06B k K CC ; 06C l L CD ; 06D m M CE ; 06E n N CF ; 06F o O D0 ; 070 p P D1 ; 071 q Q D2 ; 072 r R D3 ; 073 s S D4 ; 074 t T D5 ; 075 u U D6 ; 076 v V D7 ; 077 w W D8 ; 078 x X D9 ; 079 y Y DA ; 07A z Z FB ; 07B 4 { DC ; 07C 8 backslash FD ; 07D 5 } 00 ; 07E C8 ; 07F del END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. K4 K4NonFinKbdTables.obj K4NonFinKeyBoardData 0 TRANSLATION DATA EXISTS ; <<<<<<<<<<<<< START SPECIAL KEYS ; Number Keys IBus Id KeyUp Mask cTables 80 03 80 4 19 ; Number special keys 61 62 7F 44 E E 4 43 45 F F 0 0 40 0 48 40 20 40 END SPECIAL KEYS START CHORDS KEYS 3 ; Number of Chords 0F 00 F F 00 F F 0E 01 F F 00 F F 45 02 T T 06 F F END CHORDS KEYS START CONTROL CHORDS 11 ; Number control chords 0 0 0 0 0 0 0 0 0 0 0 END CONTROL CHORDS START RPT ATTRS TABLE Attribute Characteristics Fast 2 3 Attribute Characteristics Slow 3 2 None ; 0 Slow ; 1 None ; 2 None ; 3 None ; 4 Slow ; 5 None ; 6 None ; 7 Slow ; 8 None ; 9 Slow ; A Slow ; B Slow ; C Slow ; D None ; E None ; F None ; 10 Slow ; 11 None ; 12 Slow ; 13 None ; 14 Slow ; 15 Slow ; 16 Slow ; 17 Slow ; 18 Slow ; 19 Slow ; 1A Slow ; 1B Slow ; 1C Slow ; 1D Slow ; 1E Slow ; 1F None ; 20 Slow ; 21 None ; 22 None ; 23 None ; 24 None ; 25 None ; 26 None ; 27 None ; 28 None ; 29 None ; 2A Slow ; 2B None ; 2C Slow ; 2D Slow ; 2E None ; 2F Slow ; 30 Slow ; 31 Slow ; 32 Slow ; 33 Slow ; 34 Slow ; 35 Slow ; 36 Slow ; 37 Slow ; 38 Slow ; 39 Slow ; 3A None ; 3B None ; 3C None ; 3D None ; 3E None ; 3F None ; 40 Slow ; 41 Slow ; 42 None ; 43 None ; 44 None ; 45 Slow ; 46 Slow ; 47 None ; 48 None ; 49 Slow ; 4A None ; 4B None ; 4C None ; 4D None ; 4E None ; 4F None ; 50 None ; 51 None ; 52 None ; 53 None ; 54 None ; 55 None ; 56 None ; 57 None ; 58 None ; 59 None ; 5A None ; 5B Slow ; 5C None ; 5D Slow ; 5E None ; 5F Slow ; 60 None ; 61 None ; 62 None ; 63 None ; 64 None ; 65 None ; 66 None ; 67 None ; 68 None ; 69 None ; 6A None ; 6B None ; 6C None ; 6D None ; 6E None ; 6F None ; 70 None ; 71 None ; 72 None ; 73 None ; 74 None ; 75 None ; 76 None ; 77 None ; 78 None ; 79 None ; 7A Slow ; 7B Slow ; 7C Slow ; 7D None ; 7E None ; 7F END RPT ATTRS TABLE START ALLOWED STATES TABLE { 0 } ; 00 { 1,2,3 } ; 01 { 0 } ; 02 { 1,2 } ; 03 { 1,2 } ; 04 { 1,2,3 } ; 05 { 0 } ; 06 { 1,2 } ; 07 { 1,2,3 } ; 08 { 0 } ; 09 { 1,2,3 } ; 0A { 1,2,3 } ; 0B { 1,2,3 } ; 0C { 1,2 } ; 0D { 2 } ; 0E { 1 } ; 0F { 0 } ; 10 { 1,2,3 } ; 11 { 1,2 } ; 12 { 1,2,3 } ; 13 { 1,2 } ; 14 { 1,2,3 } ; 15 { 1,2,3 } ; 16 { 1,2,3 } ; 17 { 1,2,3 } ; 18 { 1,2,3 } ; 19 { 1,2,3 } ; 1A { 1,2 } ; 1B { 1,2,3 } ; 1C { 1,2,3 } ; 1D { 1,2 } ; 1E { 1,2 } ; 1F { 0 } ; 20 { 1,2 } ; 21 { 0 } ; 22 { 0 } ; 23 { 0 } ; 24 { 0 } ; 25 { 0 } ; 26 { 0 } ; 27 { 0 } ; 28 { 0 } ; 29 { 0 } ; 2A { 1,2,3 } ; 2B { 0 } ; 2C { 1,2,3 } ; 2D { 1,2 } ; 2E { 0 } ; 2F { 1,2,3 } ; 30 { 1,2,3 } ; 31 { 1,2,3 } ; 32 { 1,2,3 } ; 33 { 1,2,3 } ; 34 { 1,2,3 } ; 35 { 1,2 } ; 36 { 1,2 } ; 37 { 1,2,3 } ; 38 { 1,2,3 } ; 39 { 1,2 } ; 3A { 0 } ; 3B { 0 } ; 3C { 0 } ; 3D { 0 } ; 3E { 0 } ; 3F { 0 } ; 40 { 1,2 } ; 41 { 1,2 } ; 42 { 0 } ; 43 { 1,2 } ; 44 { 3 } ; 45 { 1,2 } ; 46 { 1,2 } ; 47 { 1,2 } ; 48 { 0 } ; 49 { 1,2 } ; 4A { 0 } ; 4B { 0 } ; 4C { 0 } ; 4D { 0 } ; 4E { 0 } ; 4F { 0 } ; 50 { 0 } ; 51 { 0 } ; 52 { 0 } ; 53 { 1,2 } ; 54 { 0 } ; 55 { 0 } ; 56 { 0 } ; 57 { 0 } ; 58 { 0 } ; 59 { 0 } ; 5A { 0 } ; 5B { 1,2 } ; 5C { 0 } ; 5D { 1,2,3 } ; 5E { 0 } ; 5F { 1,2 } ; 60 { 0 } ; 61 { 0 } ; 62 { 0 } ; 63 { 0 } ; 64 { 0 } ; 65 { 0 } ; 66 { 0 } ; 67 { 0 } ; 68 { 0 } ; 69 { 0 } ; 6A { 0 } ; 6B { 0 } ; 6C { 0 } ; 6D { 0 } ; 6E { 0 } ; 6F { 0 } ; 70 { 0 } ; 71 { 0 } ; 72 { 0 } ; 73 { 0 } ; 74 { 0 } ; 75 { 0 } ; 76 { 0 } ; 77 { 0 } ; 78 { 0 } ; 79 { 0 } ; 7A { 1,2 } ; 7B { 1,2 } ; 7C { 1,2 } ; 7D { 0 } ; 7E { 1,2 } ; 7F END ALLOWED STATES TABLE START CONDITIONS 6 ; Number of conditions 0 { 0 } { 0 } { 0 } 1 { 1,3 } { 0 } { 0 } 2 { 2 } { 0 } { 0 } 3 { 1 } { 2 } { 0 } 2 { 3 } { 2 } { 0 } 3 { 1 } { 2 } { 3 } END CONDITIONS START MULTIBYTES 1 { 00:4A, 00:CA, 00:4A, 00:CA } END MULTIBYTES START DIACRITICS 0 END DIACRITICS START TABLES ; TABLE NUMBER 0 WIDTH 1 00 ; 00 HELP 11 ; 01 M 00 ; 02 0D ; 03 04 ; 04 49 ; 05 00 ; 06 07 ; 07 58 ; 08 00 ; 09 59 ; 0A 0C ; 0B 51 ; 0C 0A ; 0D 00 ; 0E 00 ; 0F 00 ; 10 4A ; 11 0F ; 12 52 ; 13 14 ; 14 41 ; 15 42 ; 16 43 ; 17 44 ; 18 45 ; 19 46 ; 1A 09 ; 1B 47 ; 1C 48 ; 1D 01 ; 1E 0B ; 1F 00 ; 20 39 ; 21 00 ; 22 00 ; 23 00 ; 24 00 ; 25 00 ; 26 00 ; 27 00 ; 28 00 ; 29 00 ; 2A 57 ; 2B 00 ; 2C 56 ; 2D 2E ; 2E 00 ; 2F 55 ; 30 4C ; 31 4D ; 32 4E ; 33 4F ; 34 50 ; 35 0E ; 36 12 ; 37 53 ; 38 54 ; 39 SM:01 ; 3A 00 ; 3B 00 ; 3C 00 ; 3D 00 ; 3E 00 ; 3F 00 ; 40 36 ; 41 20 ; 42 00 ; 43 D0 ; 44 00 ; 45 32 ; 46 33 ; 47 1B ; 48 00 ; 49 30 ; 4A 00 ; 4B 00 ; 4C 00 ; 4D 00 ; 4E 00 ; 4F 00 ; 50 00 ; 51 00 ; 52 00 ; 53 02 ; 54 00 ; 55 00 ; 56 00 ; 57 00 ; 58 00 ; 59 00 ; 5A 00 ; 5B 37 ; 5C 00 ; 5D 4B ; 5E 00 ; 5F 31 ; 60 00 ; 61 00 ; 62 00 ; 63 00 ; 64 00 ; 65 00 ; 66 00 ; 67 00 ; 68 00 ; 69 00 ; 6A 00 ; 6B 00 ; 6C 00 ; 6D 00 ; 6E 00 ; 6F 00 ; 70 00 ; 71 00 ; 72 00 ; 73 00 ; 74 00 ; 75 00 ; 76 00 ; 77 00 ; 78 00 ; 79 00 ; 7A 34 ; 7B 38 ; 7C 35 ; 7D 00 ; 7E 7F ; 7F ; TABLE NUMBER 1 WIDTH 1 00 ; 00 13 ; 01 00 ; 02 0D ; 03 04 ; 04 1A ; 05 00 ; 06 07 ; 07 5F ; 08 00 ; 09 5A ; 0A 05 ; 0B 3F ; 0C 0A ; 0D 00 ; 0E 00 ; 0F 00 ; 10 1C ; 11 0F ; 12 3A ; 13 14 ; 14 15 ; 15 16 ; 16 17 ; 17 18 ; 18 19 ; 19 3C ; 1A 08 ; 1B 3E ; 1C 2C ; 1D 01 ; 1E 0B ; 1F 00 ; 20 29 ; 21 00 ; 22 00 ; 23 00 ; 24 00 ; 25 00 ; 26 00 ; 27 00 ; 28 00 ; 29 00 ; 2A 3D ; 2B 00 ; 2C 2F ; 2D 2E ; 2E 00 ; 2F 2D ; 30 1E ; 31 1F ; 32 5B ; 33 5D ; 34 3B ; 35 0E ; 36 12 ; 37 2A ; 38 2B ; 39 SM:01 ; 3A 00 ; 3B 00 ; 3C 00 ; 3D 00 ; 3E 00 ; 3F 00 ; 40 26 ; 41 20 ; 42 00 ; 43 D0 ; 44 00 ; 45 22 ; 46 23 ; 47 1B ; 48 00 ; 49 30 ; 4A 00 ; 4B 00 ; 4C 00 ; 4D 00 ; 4E 00 ; 4F 00 ; 50 00 ; 51 00 ; 52 00 ; 53 02 ; 54 00 ; 55 00 ; 56 00 ; 57 00 ; 58 00 ; 59 00 ; 5A 00 ; 5B 27 ; 5C 00 ; 5D 1D ; 5E 00 ; 5F 21 ; 60 00 ; 61 00 ; 62 00 ; 63 00 ; 64 00 ; 65 00 ; 66 00 ; 67 00 ; 68 00 ; 69 00 ; 6A 00 ; 6B 00 ; 6C 00 ; 6D 00 ; 6E 00 ; 6F 00 ; 70 00 ; 71 00 ; 72 00 ; 73 00 ; 74 00 ; 75 00 ; 76 00 ; 77 00 ; 78 00 ; 79 00 ; 7A 24 ; 7B 28 ; 7C 25 ; 7D 00 ; 7E 7F ; 7F ; TABLE NUMBER 2 WIDTH 1 00 ; 00 91 ; 01 00 ; 02 8D ; 03 84 ; 04 C9 ; 05 00 ; 06 87 ; 07 D8 ; 08 00 ; 09 D9 ; 0A 8C ; 0B D1 ; 0C 8A ; 0D 00 ; 0E 00 ; 0F 00 ; 10 CA ; 11 8F ; 12 D2 ; 13 94 ; 14 C1 ; 15 C2 ; 16 C3 ; 17 C4 ; 18 C5 ; 19 C6 ; 1A 89 ; 1B C7 ; 1C C8 ; 1D 81 ; 1E 8B ; 1F 00 ; 20 B9 ; 21 00 ; 22 00 ; 23 00 ; 24 00 ; 25 00 ; 26 00 ; 27 00 ; 28 00 ; 29 00 ; 2A D7 ; 2B 00 ; 2C D6 ; 2D AE ; 2E 00 ; 2F D5 ; 30 CC ; 31 CD ; 32 CE ; 33 CF ; 34 D0 ; 35 8E ; 36 92 ; 37 D3 ; 38 D4 ; 39 BA ; 3A 00 ; 3B 00 ; 3C 00 ; 3D 00 ; 3E 00 ; 3F 00 ; 40 B6 ; 41 A0 ; 42 00 ; 43 D0 ; 44 00 ; 45 B2 ; 46 B3 ; 47 9B ; 48 00 ; 49 B0 ; 4A 00 ; 4B 00 ; 4C 00 ; 4D 00 ; 4E 00 ; 4F 00 ; 50 00 ; 51 00 ; 52 00 ; 53 82 ; 54 00 ; 55 00 ; 56 00 ; 57 00 ; 58 00 ; 59 00 ; 5A 00 ; 5B B7 ; 5C 00 ; 5D CB ; 5E 00 ; 5F B1 ; 60 00 ; 61 00 ; 62 00 ; 63 00 ; 64 00 ; 65 00 ; 66 00 ; 67 00 ; 68 00 ; 69 00 ; 6A 00 ; 6B 00 ; 6C 00 ; 6D 00 ; 6E 00 ; 6F 00 ; 70 00 ; 71 00 ; 72 00 ; 73 00 ; 74 00 ; 75 00 ; 76 00 ; 77 00 ; 78 00 ; 79 00 ; 7A B4 ; 7B B8 ; 7C B5 ; 7D 00 ; 7E FF ; 7F ; TABLE NUMBER 3 WIDTH 1 00 ; 00 93 ; 01 00 ; 02 8D ; 03 84 ; 04 9A ; 05 00 ; 06 87 ; 07 DF ; 08 00 ; 09 DA ; 0A 85 ; 0B BF ; 0C 8A ; 0D 00 ; 0E 00 ; 0F 00 ; 10 9C ; 11 8F ; 12 BA ; 13 94 ; 14 95 ; 15 96 ; 16 97 ; 17 98 ; 18 99 ; 19 BC ; 1A 88 ; 1B BE ; 1C AC ; 1D 81 ; 1E 8B ; 1F 00 ; 20 A9 ; 21 00 ; 22 00 ; 23 00 ; 24 00 ; 25 00 ; 26 00 ; 27 00 ; 28 00 ; 29 00 ; 2A BD ; 2B 00 ; 2C AF ; 2D AE ; 2E 00 ; 2F AD ; 30 9E ; 31 9F ; 32 DB ; 33 DD ; 34 BB ; 35 8E ; 36 92 ; 37 AA ; 38 AB ; 39 BA ; 3A 00 ; 3B 00 ; 3C 00 ; 3D 00 ; 3E 00 ; 3F 00 ; 40 A6 ; 41 A0 ; 42 00 ; 43 D0 ; 44 00 ; 45 A2 ; 46 A3 ; 47 9B ; 48 00 ; 49 B0 ; 4A 00 ; 4B 00 ; 4C 00 ; 4D 00 ; 4E 00 ; 4F 00 ; 50 00 ; 51 00 ; 52 00 ; 53 82 ; 54 00 ; 55 00 ; 56 00 ; 57 00 ; 58 00 ; 59 00 ; 5A 00 ; 5B A7 ; 5C 00 ; 5D 9D ; 5E 00 ; 5F A1 ; 60 00 ; 61 00 ; 62 00 ; 63 00 ; 64 00 ; 65 00 ; 66 00 ; 67 00 ; 68 00 ; 69 00 ; 6A 00 ; 6B 00 ; 6C 00 ; 6D 00 ; 6E 00 ; 6F 00 ; 70 00 ; 71 00 ; 72 00 ; 73 00 ; 74 00 ; 75 00 ; 76 00 ; 77 00 ; 78 00 ; 79 00 ; 7A A4 ; 7B A8 ; 7C A5 ; 7D 00 ; 7E FF ; 7F END TABLES /***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* pcK1.kbd_data */ /* */ /* This file contains the text version of the table that causes a */ /* PC keyboard using scan set 2 (such as the Portable on board key- */ /* board) to emulate a K1 keyboard. */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION */ /* */ /* 03/18/92 122G.00 K. Hampton / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; This is the data file for a PS2 or superset keyboard that is to be ; emulated as a K1 Keyboard; this file is suitable for use by the ; "Create Keyboard Table" command ; ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; Keyboard name PC1 ; Output file name PC1EmulTables.obj ; Name of PUBLIC in object module at start of table PC1EmulData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ==================================================================== ; ; EMULATION DATA ; ; What follows is the data for having the PS2 keyboard emulate the K1 ; keyboard. That is given a PS2 state and key what K1 state and key ; would have to be pushed to give the same result ; EMULATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if emulation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ PS2 Keyboard IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of emulation tables in hex ; | | | | ; 85 66 80 5 04 -- target translation table in hex ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have 19 entries and they MUST be in the order shown. 22 ; Number of special keys 1C ; a * 32 ; b * 171 ; * 71h + hi-order bit for 'E0' extension 170 ; * 70h + hi-order bit for 'E0' extension 14 ; * 114 ; * 14h + hi-order bit for 'E0' extension 76 ; * 11 ; * 58 ; * 12 ; * 59 ; * 40 ; 40 ; 40 ; 00 ; c 15A ; * 5Ah + hi-order bit for 'E0' extension 00 ; iKey not valid 29 ; Diacritic Escape 17C ; System Key * 7Ch + hi-order bit for 'E0' extension 00 ; reserved for future use 5F ; map pause key 00 ; reserved for future use ;;; "L ALT", "NUM LOCK" ???? END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. 3 ; Number of LEDs on keyboard ;0 means don't remap. FF means not supported. Valid non-zero value is the 1- ;based LED numberthat will be converted to a command valid for the new target ;hardware as follows: 1h,2h,4h,8h,10h,20h,40h,80h; LEDs >8 on the Kx style ;keyboards are handled according to the rquirement described in the hardware ;spec. 99 ; CTOS LED 1 - f10 99 ; 2 - f9 99 ; 3 - f8 99 ; 4 - f3 99 ; 5 - f2 99 ; 6 - f1 03 ; 7 - LOCK 99 ; 8 - Overtype NOT SUPPORTED 99 ; 9 - Comm1 99 ; 10 - Comm2 99 ; 11 - Comm3 99 ; 12 - Comm4 99 ; 13 - Comm5 02 ; 14 - 'Numlock' 01 ; 15 - 'Scroll Lock' 99 ; END LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for Emulation table ; ; ; Number of entries should be the same as in translation table in this file 10 ; Number of entries ; key bMask* fToggle fLed LED mask** ; number bit bit ; (hex) position position ; 12 0 F F 0 F ; Chord #1 59 1 F F 0 F ; Chord #2 14 2 F F 0 F ; Chord #4 94 3 F F 8 F ; Chord #5 58 4 T T 2 F ; Chord #3 11 5 F F 0 F ; Chord #6 (K1 NOP) 91 6 F F 8 F ; Chord #7 (K1 NOP) 77 7 T T 1 F ; Chord #8 (K1 NOP) 7E 8 T T 0 F T; Chord #8 (K1 NOP) 0E0 9 F F 9 F ; Chord #9 (K1 NOP) END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; numbers are decimal ; ------------------ ------ --------- { 0 } ; 000 { 0 } ; 001 f9 { 0 } ; 002 { 0 } ; 003 f5 { 0 } ; 004 f3 { 6,7 } ; 005 f1 (l alt,r alt) { 0 } ; 006 f2 { 0 } ; 007 f12 { 0 } ; 008 { 0 } ; 009 f10 { 0 } ; 00A f8 { 0 } ; 00B f6 { 0 } ; 00C f4 { 0 } ; 00D Tab { 1,2 } ; 00E ` ~ { 0 } ; 00F { 0 } ; 010 { 6,7,10 } ; 011 Left alt 6 (rt alt = 7+10) { 1,2,10 } ; 012 Left Shift { 0 } ; 013 { 3,4,10 } ; 014 Left code 3 (rt code = 4+10) { 1,2,5 } ; 015 q Q { 1,2 } ; 016 1 ! { 0 } ; 017 { 0 } ; 018 { 0 } ; 019 Left Alt { 1,2,5 } ; 01A z Z { 1,2,5 } ; 01B s S { 1,2,5 } ; 01C a A { 1,2,5 } ; 01D w W { 1,2 } ; 01E 2 @ { 0 } ; 01F { 0 } ; 020 { 1,2,5 } ; 021 c C { 1,2,5 } ; 022 x X { 1,2,5 } ; 023 d D { 1,2,5 } ; 024 e E { 1,2 } ; 025 4 $ { 1,2 } ; 026 3 # { 0 } ; 027 { 0 } ; 028 { 0 } ; 029 space { 1,2,5 } ; 02A v V { 1,2,5 } ; 02B f F { 1,2,5 } ; 02C t T { 1,2,5 } ; 02D r R { 1,2 } ; 02E 5 % { 0 } ; 02F { 0 } ; 030 { 1,2,5 } ; 031 n N { 1,2,5 } ; 032 b B { 1,2,5 } ; 033 h H { 1,2,5 } ; 034 g G { 1,2,5 } ; 035 y Y { 1,2 } ; 036 6 ^ { 0 } ; 037 { 0 } ; 038 { 0 } ; { 1,2,5 } ; 03A m M { 1,2,5 } ; 03B j J { 1,2,5 } ; 03C u U { 1,2 } ; 03D 7 & { 1,2 } ; 03E 8 * { 0 } ; 03F { 0 } ; 040 { 1,2 } ; 041 , < { 1,2,5 } ; 042 k K { 1,2,5 } ; 043 i I { 1,2,5 } ; 044 o O { 1,2 } ; 045 0 ) { 1,2 } ; 046 9 ( { 0 } ; 047 { 0 } ; 048 { 1,2 } ; 049 . > { 1,2,10 } ; 04A / ? E0 4A = numpad / { 1,2,5 } ; 04B l L { 1,2 } ; 04C ; : { 1,2,5 } ; 04D p P { 1,2 } ; 04E - _ { 0 } ; 04F { 0 } ; 050 { 0 } ; 051 { 1,2 } ; 052 ' " { 0 } ; 053 { 1,2 } ; 054 [ { { 1,2 } ; 055 = + { 0 } ; 056 { 0 } ; 057 { 5 } ; 058 Capslock { 1,2,10 } ; 059 R Shift E0 59 = Extended shift, absorb { 10 } ; 05A Return E0 5A = GO { 1,2 } ; 05B ] } { 1,2 } ; 05C \ | { 0 } ; 05D { 0 } ; 05E { 0 } ; 05F { 0 } ; 060 { 0 } ; 061 { 0 } ; 062 { 0 } ; 063 { 0 } ; 064 { 0 } ; 065 { 0 } ; 066 { 0 } ; 067 { 0 } ; 068 { 1,2,8,9,10 } ; 069 1 pad E0 69 = END { 0 } ; 06A { 1,2,8,9,10 } ; 06B 4 pad E0 6B = l arrow { 1,2,8,9,10 } ; 06C 7 pad E0 6C = HOME { 0 } ; 06D { 0 } ; 06E { 0 } ; 06F { 1,2,8,9,10 } ; 070 0 pad E0 70 = Insert/Overtype { 1,2,8,9,10 } ; 071 . pad E0 71 = DELETE { 1,2,8,9,10 } ; 072 2 pad E0 72 = Scroll UP { 1,2,8,9 } ; 073 5 pad { 1,2,8,9,10 } ; 074 6 pad E0 74 = RT Arrow { 1,2,8,9,10 } ; 075 8 pad E0 75 = Scroll DN { 0 } ; 076 escape/cancel { 8 } ; 077 numlock { 0 } ; 078 { 0 } ; 079 numpad + { 1,2,8,9,10 } ; 07A 3 pad E0 7A = Page DN { 0 } ; 07B { 10 } ; 07C * pad { 1,2,8,9,10 } ; 07D 9 pad E0 7D = Page UP { 9 } ; 07E CTOS mode/Scroll Lock { 0 } ; 07F { 0 } ; 080 { 0 } ; 081 { 0 } ; 082 { 0 } ; 083 f7 { 0 } ; 084 - pad END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 11 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; NOTE: Numbers in orStates are decimal ; ; Table Conditions Comments ; ID ---------------------------- ; orState1 orState2 orState3 ; ----- -------- -------- -------- ------------------------------------- 0 { } { } { } ; No chord keys down 1 {1,2 } ; either Shift key down; 1 { 8 } ; numlock down 1 { 8 } { 9 } ; numlock and CTOS lock 3 { 9 } ; CTOS lock down 3 { 9 } {1,2,3,4,5} ; CTOS lk and (shifts/codes) 0 { 8 } { 1,2 } ; numlock and either shift key 2 { 6,7 } ; either alt (for f1) 2 { 6,7 } {1,2,3,4,5} ; either alt and (shifts/codes)(for f1) ; to facilitate shift+help or code+help ; to facilitate shift+help or code+help 4 { 10 } { } { } ; E0 4 { 10 } {1,2,3,4,5,6,7,8,9} { } ; E0 END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 0 ; Number of multibyte strings ; String ; { 01:68, 01:E8, 00:69, 00:E9, 00:20, 00:A0, 02:74, 02:F4, 00:68, 00:E8& ; 00:65, 00:E5, 00:72, 00:F2, 00:65 } ; { 00:2E, 00:AE, 00:30, 00:B0, 00:30, 00:B0 } ; The "&" means continue. END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 00 27 00 65 00000016 F ; 01 5E 01 65 00010034 F ; 01 5E 01 63 00000001 T ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Emulation Tables Info ; ; In what follows entries are of the form xx:yy where ; ; xx = the state ; yy = the K1 iKey ; FF:FF means "Do not emulate as anything" ; FF:xx means "Do not change the state, emulate the key" (ikey -> xx) ; Number of emulation tables specified in special keys table. ; ; Table for case where no chord keys held down. ; FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:FF ; 007 f12 FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:54 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] 01:7C ; 05C \ (8 \) FF:FF ; 05D 102 key keyboard only FF:FF ; 05E FF:57 ; 05F borrowed for pause FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:08 ; 066 FF:FF ; 067 FF:FF ; 068 08:65 ; 069 END lc 1 pad FF:FF ; 06A FF:0E ; 06B l arrow lc 4 pad 08:62 ; 06C HOME lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:44 ; 070 INSERT lc 0 pad FF:7F ; 071 DEL lc . pad FF:0B ; 072 DOWN ARR lc 2 pad (SCROLL UP) 00:7D ; 073 5 pad SCR LK meaningless to CTOS FF:0F ; 074 RT ARR lc 6 pad FF:01 ; 075 UP ARR lc 8 pad (SCROLL DN) FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:FF ; 078 f11 01:2B ; 079 numpad + FF:0C ; 07A PG DN lc 3 pad FF:42 ; 07B numpad - 01:38 ; 07C numpad * FF:05 ; 07D PG UP lc 9 pad FF:5F ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; ; Table for case where shift keys held down. ; FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:FF ; 007 f12 FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E ~ FF:FF ; 00F FF:FF ; 010 FF:54 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 ! FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E @ FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 $ FF:33 ; 026 # FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E % FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y 00:5E ; 036 ^ FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D & FF:38 ; 03E * FF:FF ; 03F FF:FF ; 040 FF:5B ; 041 < FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 ) FF:39 ; 046 ( FF:FF ; 047 FF:FF ; 048 FF:5D ; 049 > FF:2F ; 04A ? FF:6C ; 04B l FF:3B ; 04C : FF:70 ; 04D p FF:2D ; 04E _ FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 " FF:FF ; 053 FF:7B ; 054 { FF:2B ; 055 + =+ FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:7D ; 05B } FF:5C ; 05C | FF:FF ; 05D FF:FF ; 05E FF:FF ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:08 ; 066 FF:FF ; 067 FF:FF ; 068 00:60 ; 069 lc 1 pad FF:FF ; 06A 00:7B ; 06B lc 4 pad 00:5C ; 06C lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F 00:4A ; 070 lc 0 pad 00:4B ; 071 lc . pad 00:46 ; 072 lc 2 pad (SCROLL UP) 00:7D ; 073 lc 5 pad 00:41 ; 074 lc 6 pad 00:7C ; 075 lc 8 pad (SCROLL DN) FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:FF ; 078 f11 FF:2B ; 079 numpad + 00:47 ; 07A lc 3 pad FF:42 ; 07B numpad - FF:38 ; 07C numpad * 00:21 ; 07D lc 9 pad FF:5F ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; Table for case where ALT keys held down. ; only gets used for keys that have alt in their allowed states - F1 ; therefore all other keys are NOP and look like unshifted keys FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:00 ; 005 f1 NOTE ALT+F1 = HELP (K1 ikey 00) FF:16 ; 006 f2 FF:FF ; 007 f12 FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:54 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] 01:7C ; 05C \ (8 \) FF:FF ; 05D 102 key keyboard only FF:FF ; 05E FF:5F ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 FF:FF ; 067 FF:FF ; 068 08:65 ; 069 END lc 1 pad FF:FF ; 06A FF:0E ; 06B l arrow lc 4 pad 08:62 ; 06C HOME lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:44 ; 070 INSERT lc 0 pad FF:7F ; 071 DEL lc . pad FF:0B ; 072 DOWN ARR lc 2 pad (SCROLL UP) 00:7D ; 073 5 pad SCR LK meaningless to CTOS FF:0F ; 074 RT ARR lc 6 pad FF:01 ; 075 UP ARR lc 8 pad (SCROLL DN) FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:FF ; 078 f11 01:2B ; 079 numpad + FF:0C ; 07A PG DN lc 3 pad FF:42 ; 07B numpad - 01:38 ; 07C numpad * FF:05 ; 07D PG UP lc 9 pad FF:5F ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; ; Table for case where CTOS Lock is on. ;do we need ctos lock and shift? probably not if ctos lock ;is only allowed for selected keys ; FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:FF ; 007 f12 FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:54 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] 01:7C ; 05C \ (8 \) FF:FF ; 05D 102 key keyboard only FF:FF ; 05E FF:5F ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 FF:FF ; 067 FF:FF ; 068 FF:12 ; 069 MOVE lc 1 pad FF:FF ; 06A FF:0E ; 06B l arrow lc 4 pad FF:43 ; 06C ACTION lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:02 ; 070 MARK lc 0 pad FF:03 ; 071 BOUND lc . pad FF:11 ; 072 SCRL NEXT lc 2 pad (SCROLL UP) FF:FF ; 073 5 pad SCR LK meaningless to CTOS FF:0D ; 074 NEXT lc 6 pad FF:13 ; 075 SCRL PREV lc 8 pad (SCROLL DN) FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:FF ; 078 f11 01:2B ; 079 numpad + FF:14 ; 07A COPY lc 3 pad FF:42 ; 07B numpad - 01:38 ; 07C numpad * FF:04 ; 07D FINISH lc 9 pad FF:5F ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; ; Table for case where E0 is held down. ; FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:FF ; 007 f12 FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:55 ; 011 NOTE: RIGHT ALT FF:FF ; 012 l shift NOTE: ABSORB IF EXTENDED FF:FF ; 013 FF:4D ; 014 NOTE: RIGHT CODE FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A NOTE: numpad / if extended FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:FF ; 059 r shift NOTE: ABSORB IF EXTENDED FF:1B ; 05A enter NOTE: GO if extended FF:5D ; 05B ] 01:7C ; 05C \ (8 \) FF:FF ; 05D 102 key keyboard only FF:FF ; 05E FF:5F ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 FF:FF ; 067 FF:FF ; 068 08:65 ; 069 END NOTE: END FF:FF ; 06A FF:0E ; 06B NOTE: LEFT ARROW 08:62 ; 06C NOTE: HOME FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:44 ; 070 NOTE: OVERTYPE FF:7F ; 071 NOTE: DELETE FF:0B ; 072 NOTE: DN ARROW 00:7D ; 073 5 pad SCR LK meaningless to CTOS FF:0F ; 074 NOTE: RT ARROW FF:01 ; 075 NOTE: UP ARROW FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:FF ; 078 f11 01:2B ; 079 numpad + FF:0C ; 07A NOTE: PAGE NEXT FF:42 ; 07B numpad - FF:57 ; 07C NOTE: SYSTEM FF:05 ; 07D NOTE: PAGE PREV FF:5F ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; This is the data file for a PORTABLE Internal keyboard that is to be ; emulated as a K1 Keyboard; this file is suitable for use by the ; "Create Keyboard Table" command ; ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; Keyboard name PI ; Output file name PIEmulTables.obj ; Name of PUBLIC in object module at start of table PIEmulData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ==================================================================== ; ; EMULATION DATA ; ; What follows is the data for having the PS2 keyboard emulate the K1 ; keyboard. That is given a PS2 state and key what K1 state and key ; would have to be pushed to give the same result ; EMULATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if emulation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ Keyboard ID of a standard PowerPort internal kbd ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of emulation tables in hex ; | | | | ; 85 66 80 5 66 -- target translation table in hex ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have 19 entries and they MUST be in the order shown. 22 ; Number of special keys 1C ; a * 32 ; b * 171 ; * 71h + hi-order bit for 'E0' extension 170 ; * 70h + hi-order bit for 'E0' extension 14 ; * 114 ; * 14h + hi-order bit for 'E0' extension 76 ; * 11 ; * 58 ; * 12 ; * 59 ; * 40 ; 40 ; 40 ; 00 ; c 15A ; * 5Ah + hi-order bit for 'E0' extension 00 ; iKey not valid 29 ; Diacritic Escape 17C ; System Key * 7Ch + hi-order bit for 'E0' extension 15A ; 02 ; map pause key 00 ; reserved for future use ;;; "L ALT", "NUM LOCK" ???? END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. 3 ; Number of LEDs on keyboard ;0 means don't remap. FF means not supported. Valid non-zero value is the 1- ;based LED numberthat will be converted to a command valid for the new target ;hardware as follows: 1h,2h,4h,8h,10h,20h,40h,80h; LEDs >8 on the Kx style ;keyboards are handled according to the rquirement described in the hardware ;spec. 99 ; CTOS LED 1 - f10 99 ; 2 - f9 99 ; 3 - f8 99 ; 4 - f3 99 ; 5 - f2 99 ; 6 - f1 03 ; 7 - LOCK 01 ; 8 - Overtype SHARES SCROLL LOCK 99 ; 9 - Comm1 99 ; 10 - Comm2 99 ; 11 - Comm3 99 ; 12 - Comm4 99 ; 13 - Comm5 02 ; 14 - 'Numlock' 99 ; 15 - 'Scroll Lock' 99 ; END LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for Emulation table ; ; ; Number of entries should be the same as in translation table in this file 9 ; Number of entries ; key bMask* fToggle fLed LED mask** ; number bit bit ; (hex) position position ; 12 0 F F 0 F ; Chord #1 59 1 F F 0 F ; Chord #2 14 2 F F 0 F ; Chord #3 94 3 F F 0 F ; Chord #4 58 4 T T 2 F ; Chord #5 11 5 F F 0 F ; Chord #6 (K1 NOP) 91 6 F F 0 F ; Chord #7 (K1 NOP) 77 7 T T 1 F ; Chord #8 (K1 NOP) E0 8 F F 0 F ; Chord #9 (K1 NOP) END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; numbers are decimal ; ------------------ ------ --------- { 0 } ; 000 { 0 } ; 001 f9 { 0 } ; 002 FAKE GO KEY (Remapped from scanset2 PAUSE key) { 0 } ; 003 f5 { 0 } ; 004 f3 { 6,7 } ; 005 f1 (l alt,r alt) { 0 } ; 006 f2 { 6,7 } ; 007 f12 BOUND alt+f12 = COPY { 0 } ; 008 { 0 } ; 009 f10 { 0 } ; 00A f8 { 0 } ; 00B f6 { 0 } ; 00C f4 { 6,7 } ; 00D Tab ALT+Tab = NEXT { 1,2 } ; 00E ` ~ { 0 } ; 00F { 0 } ; 010 { 6,7,9 } ; 011 Left alt 6 (rt alt = 7+9) { 1,2,9 } ; 012 Left Shift (E0 12 is absorbed) { 0 } ; 013 { 3,4,9 } ; 014 Left code 3 (rt code = 4+9) { 1,2,5 } ; 015 q Q { 1,2 } ; 016 1 ! { 0 } ; 017 { 0 } ; 018 { 0 } ; 019 { 1,2,5,} ; 01A z Z { 1,2,5 } ; 01B s S { 1,2,5 } ; 01C a A { 1,2,5 } ; 01D w W { 1,2 } ; 01E 2 @ { 0 } ; 01F { 0 } ; 020 { 1,2,5 } ; 021 c C { 1,2,5 } ; 022 x X { 1,2,5 } ; 023 d D { 1,2,5 } ; 024 e E { 1,2 } ; 025 4 $ { 1,2 } ; 026 3 # { 0 } ; 027 { 0 } ; 028 { 0 } ; 029 space { 1,2,5 } ; 02A v V { 1,2,5 } ; 02B f F { 1,2,5 } ; 02C t T { 1,2,5 } ; 02D r R { 1,2 } ; 02E 5 % { 0 } ; 02F { 0 } ; 030 { 1,2,5 } ; 031 n N { 1,2,5 } ; 032 b B { 1,2,5 } ; 033 h H { 1,2,5 } ; 034 g G { 1,2,5 } ; 035 y Y { 1,2 } ; 036 6 ^ { 0 } ; 037 { 0 } ; 038 { 0 } ; { 1,2,5 } ; 03A m M { 1,2,5 } ; 03B j J { 1,2,5 } ; 03C u U { 1,2 } ; 03D 7 & { 1,2 } ; 03E 8 * { 0 } ; 03F { 0 } ; 040 { 1,2 } ; 041 , < { 1,2,5 } ; 042 k K { 1,2,5 } ; 043 i I { 1,2,5 } ; 044 o O { 1,2 } ; 045 0 ) { 1,2 } ; 046 9 ( { 0 } ; 047 { 0 } ; 048 { 1,2 } ; 049 . > { 1,2 } ; 04A / ? E0 4A = numpad / { 1,2,5 } ; 04B l L { 1,2 } ; 04C ; : { 1,2,5 } ; 04D p P { 1,2 } ; 04E - _ { 0 } ; 04F { 0 } ; 050 { 0 } ; 051 { 1,2 } ; 052 ' " { 0 } ; 053 { 1,2 } ; 054 [ { { 1,2 } ; 055 = + { 0 } ; 056 { 0 } ; 057 { 5 } ; 058 Capslock { 1,2,9 } ; 059 R Shift E0 59 = Extended shift, absorb { 8,9 } ; 05A Return E0 5A = GO { 1,2 } ; 05B ] } { 0 } ; 05C { 1,2 } ; 05D \ | { 0 } ; 05E { 0 } ; 05F { 0 } ; 060 { 0 } ; 061 { 0 } ; 062 { 0 } ; 063 { 0 } ; 064 { 0 } ; 065 { 0 } ; 066 { 0 } ; 067 { 0 } ; 068 { 8,9 } ; 069 FINISH NUMLOCK+69=1 pad 69,E0 69 = END { 0 } ; 06A { 8,9 } ; 06B NUMLOCK+6b =4 pad E0 6B = l arrow { 8,9 } ; 06C ACTION 6C = HOME NUMLOCK+6C = 7 pad { 0 } ; 06D { 0 } ; 06E { 0 } ; 06F { 8,9 } ; 070 NUMLOCK+ 70 = 0 pad 70/E0 70 = Insert/Overtype { 8,9 } ; 071 . pad E0 71 = DELETE { 8,9 } ; 072 2 pad ALT+ E0 72 = Scroll UP { 8 } ; 073 5 pad { 8,9 } ; 074 6 pad E0 74 = RT Arrow { 8,9 } ; 075 8 pad ALT+ E0 75 = Scroll DN { 0 } ; 076 escape/cancel { 8 } ; 077 numlock { 6,7 } ; 078 f11 { 8,9 } ; 079 numpad + { 6,7,8,9 } ; 07A 3 pad E0 7A = Page DN { 8 } ; 07B { 8,9 } ; 07C * pad E0 7C = Prt Screen / System KEY { 6,7,8,9 } ; 07D 9 pad E0 7D = Page UP { 9 } ; 07E CTOS mode/Scroll Lock OR CODE+PAUSE=E0 7E { 0 } ; 07F { 0 } ; 080 { 0 } ; 081 { 0 } ; 082 { 0 } ; 083 f7 { 0 } ; 084 - pad END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 10 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; NOTE: Numbers in orStates are decimal ; ; Table Conditions Comments ; ID ---------------------------- ; orState1 orState2 orState3 ; ----- -------- -------- -------- ------------------------------------- 0 { } { } { } ; No chord keys down 1 {1,2 } ; either Shift key down; 3 { 8 } ; numlock down 3 { 8 } { 1,2 } ; numlock and either shift key 0 { 8 } { 9 } ; numlock and E0 2 { 6,7 } ; either alt (for f1,f11,f12) 2 { 6,7 } {1,2,3,4,5} ; either alt and (shifts/codes)(for f1) ; to facilitate shift+help or code+help ; to facilitate shift+help or code+help 4 { 9 } { } { } ; E0 4 { 9 } {1,2,3,4,5,6,7 } { } ; E0 2 { 9 } {1,2,3,4,5,6,7 } { 8 } ; E0 ALT+Pg Dn,Pg Up END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 0 ; Number of multibyte strings ; String ; { 01:68, 01:E8, 00:69, 00:E9, 00:20, 00:A0, 02:74, 02:F4, 00:68, 00:E8& ; 00:65, 00:E5, 00:72, 00:F2, 00:65 } ; { 00:2E, 00:AE, 00:30, 00:B0, 00:30, 00:B0 } ; The "&" means continue. END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 00 27 00 65 00000016 F ; 01 5E 01 65 00010034 F ; 01 5E 01 63 00000001 T ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Emulation Tables Info ; ; In what follows entries are of the form xx:yy where ; ; xx = the state ; yy = the K1 iKey ; FF:FF means "Do not emulate as anything" ; FF:xx means "Do not change the state, emulate the key" (ikey -> xx) ; Number of emulation tables specified in special keys table. ; ; Table for case where no chord keys held down. ; FF:FF ; 000 FF:1E ; 001 f9 FF:1B ; 002 FAKE GO KEY FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:03 ; 007 f12 BOUND FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:53 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] FF:FF ; 05C 01:7C ; 05D \ FF:FF ; 05E FF:57 ; 05F borrowed for pause FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:08 ; 066 FF:FF ; 067 FF:FF ; 068 FF:04 ; 069 END FINISH FF:FF ; 06A FF:0E ; 06B l arrow FF:43 ; 06C HOME ACTION FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:44 ; 070 INSERT FF:7F ; 071 DEL FF:0B ; 072 DOWN ARR FF:FF ; 073 (only get 73 with numlock on) FF:0F ; 074 RT ARR FF:01 ; 075 UP ARR FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:02 ; 078 f11 MARK 01:2B ; 079 numpad + FF:0C ; 07A PG DN lc 3 pad FF:42 ; 07B numpad - 01:38 ; 07C numpad * FF:05 ; 07D PG UP lc 9 pad FF:44 ; 07E scroll lock->OVERTYPE (INSERT) FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; ; Table for case where shift keys held down. ; FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:03 ; 007 f12 BOUND FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E ~ FF:FF ; 00F FF:FF ; 010 FF:54 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 ! FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E @ FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 $ FF:33 ; 026 # FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E % FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y 00:5E ; 036 ^ FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D & FF:38 ; 03E * FF:FF ; 03F FF:FF ; 040 FF:5B ; 041 < FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 ) FF:39 ; 046 ( FF:FF ; 047 FF:FF ; 048 FF:5D ; 049 > FF:2F ; 04A ? FF:6C ; 04B l FF:3B ; 04C : FF:70 ; 04D p FF:2D ; 04E _ FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 " FF:FF ; 053 FF:7B ; 054 { FF:2B ; 055 + =+ FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:7D ; 05B } FF:FF ; 05C FF:5C ; 05D | FF:FF ; 05E FF:FF ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:08 ; 066 FF:FF ; 067 FF:FF ; 068 00:60 ; 069 lc 1 pad FF:FF ; 06A 00:7B ; 06B lc 4 pad 00:5C ; 06C lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F 00:4A ; 070 lc 0 pad 00:4B ; 071 lc . pad 00:46 ; 072 lc 2 pad (SCROLL UP) 00:7D ; 073 lc 5 pad 00:41 ; 074 lc 6 pad 00:7C ; 075 lc 8 pad (SCROLL DN) FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:FF ; 078 f11 FF:2B ; 079 numpad + 00:47 ; 07A lc 3 pad FF:42 ; 07B numpad - FF:38 ; 07C numpad * 00:21 ; 07D lc 9 pad FF:5F ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; Table for case where ALT keys held down. FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:00 ; 005 f1 NOTE ALT+F1 = HELP (K1 ikey 00) FF:16 ; 006 f2 FF:14 ; 007 f12 ALT+f12 = COPY FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:0D ; 00D ALT+TAB= NEXT 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:53 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] FF:FF ; 05C 01:7C ; 05D \ (8 \) FF:FF ; 05E FF:5F ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 FF:FF ; 067 FF:FF ; 068 08:65 ; 069 END lc 1 pad FF:FF ; 06A FF:0E ; 06B l arrow lc 4 pad 08:62 ; 06C HOME lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:44 ; 070 INSERT lc 0 pad FF:7F ; 071 DEL lc . pad FF:11 ; 072 00:7D ; 073 5 pad FF:0F ; 074 RT ARR lc 6 pad FF:13 ; 075 FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:12 ; 078 f11 ALT+f11 = MOVE 01:2B ; 079 numpad + FF:13 ; 07A SCROLL DN lc 3 pad FF:42 ; 07B numpad - 01:38 ; 07C numpad * FF:11 ; 07D SCROLL UP FF:5F ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; ; Table for case where NumLock is on. FF:FF ; 000 FF:1E ; 001 f9 FF:1B ; 002 FAKE GO KEY FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:FF ; 007 f12 FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:54 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] FF:FF ; 05C 01:7C ; 05D \ (8 \) FF:FF ; 05E FF:5F ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 FF:FF ; 067 FF:FF ; 068 FF:60 ; 069 lc 1 pad FF:FF ; 06A FF:7B ; 06B lc 4 pad FF:5C ; 06C lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:4A ; 070 lc 0 pad FF:4B ; 071 lc . pad FF:46 ; 072 lc 2 pad FF:7D ; 073 lc 5 pad FF:41 ; 074 lc 6 pad FF:7C ; 075 lc 8 pad FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:FF ; 078 f11 81:2B ; 079 numpad + FF:47 ; 07A lc 3 pad FF:42 ; 07B numpad - 81:38 ; 07C numpad * FF:21 ; 07D lc 9 pad FF:5F ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; ; Table for case where E0 is held down. ; FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:FF ; 007 f12 FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:55 ; 011 NOTE: RIGHT ALT FF:FF ; 012 l shift NOTE: ABSORB IF EXTENDED FF:FF ; 013 FF:4D ; 014 NOTE: RIGHT CODE FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A NOTE: numpad / if extended FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:FF ; 059 r shift NOTE: ABSORB IF EXTENDED FF:1B ; 05A enter NOTE: GO if extended FF:5D ; 05B ] FF:FF ; 05C 102 key keyboard only 01:7C ; 05D \ (8 \) FF:FF ; 05E FF:5F ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 FF:FF ; 067 FF:FF ; 068 08:65 ; 069 FINISH FF:04 NOTE: END FF:FF ; 06A FF:0E ; 06B NOTE: LEFT ARROW FF:43 ; 06C ACTION NOTE: HOME FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:44 ; 070 NOTE: OVERTYPE FF:7F ; 071 NOTE: DELETE FF:0B ; 072 NOTE: DN ARROW 00:7D ; 073 5 pad SCR LK meaningless to CTOS FF:0F ; 074 NOTE: RT ARROW FF:01 ; 075 NOTE: UP ARROW FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:FF ; 078 f11 01:2B ; 079 numpad + FF:0C ; 07A NOTE: PAGE NEXT FF:42 ; 07B numpad - FF:57 ; 07C NOTE: SYSTEM FF:05 ; 07D NOTE: PAGE PREV FF:1B ; 07E CODE+PAUSE = CODE-GO FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; emulation tables are included. START HOT KEYS TABLE 0 { 0 } { 0 } { 0 } ; 000 0 { 0 } { 0 } { 0 } ; 001 f9 0 { 0 } { 0 } { 0 } ; 002 FAKE GO KEY 0 { 0 } { 0 } { 0 } ; 003 f5 0 { 0 } { 0 } { 0 } ; 004 f3 0 { 0 } { 0 } { 0 } ; 005 f1 0 { 0 } { 0 } { 0 } ; 006 f2 0 { 0 } { 0 } { 0 } ; 007 f12 BOUND 0 { 0 } { 0 } { 0 } ; 008 0 { 0 } { 0 } { 0 } ; 009 f10 0 { 0 } { 0 } { 0 } ; 00A f8 0 { 0 } { 0 } { 0 } ; 00B f6 0 { 0 } { 0 } { 0 } ; 00C f4 0 { 0 } { 0 } { 0 } ; 00D tab 0 { 0 } { 0 } { 0 } ; 00E l quote (1 `) 0 { 0 } { 0 } { 0 } ; 00F 0 { 0 } { 0 } { 0 } ; 010 0 { 0 } { 0 } { 0 } ; 011 l alt 0 { 0 } { 0 } { 0 } ; 012 l shift 0 { 0 } { 0 } { 0 } ; 013 0 { 0 } { 0 } { 0 } ; 014 l ctrl -> l code 0 { 0 } { 0 } { 0 } ; 015 q 0 { 0 } { 0 } { 0 } ; 016 1 0 { 0 } { 0 } { 0 } ; 017 0 { 0 } { 0 } { 0 } ; 018 0 { 0 } { 0 } { 0 } ; 019 7A { 3,4 } { 6,7 } { 0 } ; 01A z 73 { 3,4 } { 6,7 } { 0 } ; 01B s 0 { 0 } { 0 } { 0 } ; 01C a 0 { 0 } { 0 } { 0 } ; 01D w 0 { 0 } { 0 } { 0 } ; 01E 2 0 { 0 } { 0 } { 0 } ; 01F 0 { 0 } { 0 } { 0 } ; 020 0 { 0 } { 0 } { 0 } ; 021 c 0 { 0 } { 0 } { 0 } ; 022 x 0 { 0 } { 0 } { 0 } ; 023 d 65 { 3,4 } { 6,7 } { 0 } ; 024 e 0 { 0 } { 0 } { 0 } ; 025 4 0 { 0 } { 0 } { 0 } ; 026 3 0 { 0 } { 0 } { 0 } ; 027 0 { 0 } { 0 } { 0 } ; 028 0 { 0 } { 0 } { 0 } ; 029 space 76 { 3,4 } { 6,7 } { 0 } ; 02A v 0 { 0 } { 0 } { 0 } ; 02B f 0 { 0 } { 0 } { 0 } ; 02C t 72 { 3,4 } { 6,7 } { 0 } ; 02D r 0 { 0 } { 0 } { 0 } ; 02E 5 0 { 0 } { 0 } { 0 } ; 02F 0 { 0 } { 0 } { 0 } ; 030 0 { 0 } { 0 } { 0 } ; 031 n 62 { 3,4 } { 6,7 } { 0 } ; 032 b 0 { 0 } { 0 } { 0 } ; 033 h 0 { 0 } { 0 } { 0 } ; 034 g 0 { 0 } { 0 } { 0 } ; 035 y 0 { 0 } { 0 } { 0 } ; 036 6 0 { 0 } { 0 } { 0 } ; 037 0 { 0 } { 0 } { 0 } ; 038 0 { 0 } { 0 } { 0 } ; 039 6D { 3,4 } { 6,7 } { 0 } ; 03A m 0 { 0 } { 0 } { 0 } ; 03B j 0 { 0 } { 0 } { 0 } ; 03C u 0 { 0 } { 0 } { 0 } ; 03D 7 0 { 0 } { 0 } { 0 } ; 03E 8 0 { 0 } { 0 } { 0 } ; 03F 0 { 0 } { 0 } { 0 } ; 040 0 { 0 } { 0 } { 0 } ; 041 , 0 { 0 } { 0 } { 0 } ; 042 k 0 { 0 } { 0 } { 0 } ; 043 i 0 { 0 } { 0 } { 0 } ; 044 o 0 { 0 } { 0 } { 0 } ; 045 0 0 { 0 } { 0 } { 0 } ; 046 9 0 { 0 } { 0 } { 0 } ; 047 0 { 0 } { 0 } { 0 } ; 048 0 { 0 } { 0 } { 0 } ; 049 . 0 { 0 } { 0 } { 0 } ; 04A / 0 { 0 } { 0 } { 0 } ; 04B l 0 { 0 } { 0 } { 0 } ; 04C ; 0 { 0 } { 0 } { 0 } ; 04D p 0 { 0 } { 0 } { 0 } ; 04E - 0 { 0 } { 0 } { 0 } ; 04F 0 { 0 } { 0 } { 0 } ; 050 0 { 0 } { 0 } { 0 } ; 051 0 { 0 } { 0 } { 0 } ; 052 ' 0 { 0 } { 0 } { 0 } ; 053 0 { 0 } { 0 } { 0 } ; 054 [ 0 { 0 } { 0 } { 0 } ; 055 = 0 { 0 } { 0 } { 0 } ; 056 0 { 0 } { 0 } { 0 } ; 057 0 { 0 } { 0 } { 0 } ; 058 lock -> capslock 0 { 0 } { 0 } { 0 } ; 059 r shift 0 { 0 } { 0 } { 0 } ; 05A return 0 { 0 } { 0 } { 0 } ; 05B ] 0 { 0 } { 0 } { 0 } ; 05C 0 { 0 } { 0 } { 0 } ; 05D \ 0 { 0 } { 0 } { 0 } ; 05E 0 { 0 } { 0 } { 0 } ; 05F borrowed for pause 0 { 0 } { 0 } { 0 } ; 060 0 { 0 } { 0 } { 0 } ; 061 102 key keyboard only 0 { 0 } { 0 } { 0 } ; 062 0 { 0 } { 0 } { 0 } ; 063 0 { 0 } { 0 } { 0 } ; 064 0 { 0 } { 0 } { 0 } ; 065 0 { 0 } { 0 } { 0 } ; 066 0 { 0 } { 0 } { 0 } ; 067 0 { 0 } { 0 } { 0 } ; 068 0 { 0 } { 0 } { 0 } ; 069 END FINISH 0 { 0 } { 0 } { 0 } ; 06A 0 { 0 } { 0 } { 0 } ; 06B l arrow 0 { 0 } { 0 } { 0 } ; 06C HOME ACTION 0 { 0 } { 0 } { 0 } ; 06D 0 { 0 } { 0 } { 0 } ; 06E 0 { 0 } { 0 } { 0 } ; 06F 0 { 0 } { 0 } { 0 } ; 070 INSERT 0 { 0 } { 0 } { 0 } ; 071 DEL 0 { 0 } { 0 } { 0 } ; 072 DOWN ARR 0 { 0 } { 0 } { 0 } ; 073 (only get 73 with numlock on) 0 { 0 } { 0 } { 0 } ; 074 RT ARR 0 { 0 } { 0 } { 0 } ; 075 UP ARR 0 { 0 } { 0 } { 0 } ; 076 escape/cancel 0 { 0 } { 0 } { 0 } ; 077 numlock 0 { 0 } { 0 } { 0 } ; 078 f11 MARK 0 { 0 } { 0 } { 0 } ; 079 numpad + 0 { 0 } { 0 } { 0 } ; 07A PG DN lc 3 pad 0 { 0 } { 0 } { 0 } ; 07B numpad - 0 { 0 } { 0 } { 0 } ; 07C numpad * 0 { 0 } { 0 } { 0 } ; 07D PG UP lc 9 pad 0 { 0 } { 0 } { 0 } ; 07E scroll lock->OVERTYPE (INSERT) 0 { 0 } { 0 } { 0 } ; 07F 0 { 0 } { 0 } { 0 } ; 080 0 { 0 } { 0 } { 0 } ; 081 0 { 0 } { 0 } { 0 } ; 082 0 { 0 } { 0 } { 0 } ; 083 f7 0 { 0 } { 0 } { 0 } ; 084 alt+print screen = sysrq on PC kbd SYSTEM key END HOT KEYS TABLE /***************************** MODULE HEADER *******************************/ /* */ /* */ /* MACHINE: LANGUAGE: OS: CTOS */ /* */ /* SG1kTrans_data */ /* */ /* This file contains the K1 translation table. */ /* */ /* */ /* HISTORY: */ /* -------- */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION */ /* 10/20/92 xxxxxxx KH / Restore system key for SG1000 /* 07/26/92 xxxxxxx FW / Modify for the SG1000 internal Kbd */ /* 06/26/92 xxxxxxx FW/KH / Change spec keys GO to COPY for */ /* / Nationwide Action-Copy program */ /* 04/20/92 KH / DisAllow ALTs for PowerPort. */ /* 03/20/92 122G.03 V. Miller / Changed so second (from the */ /* SG-102-K keyboard) is passed through. */ /* Meant adding a second alt key which */ /* I called as iKey "55h". Had */ /* to update Allowed State Table. */ /* Changed Conditions Table so */ /* selects same table as . */ /* 03/17/92 122G.02 V. Miller / Added comments and change number of */ /* of emulated LEDs from 3 to 16. */ /* 02/17/92 122F.01 V. Miller / Changed so is passed through */ /* Meant adding an alt key, , as */ /* iKey "53h" to match value on the K5 */ /* keyboard. Updated Allowed State Table */ /* and changed Conditions Table so */ /* selects same table as . */ /* Val Miller / Created. */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO */ /* BE REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM */ /* LICENSE OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF */ /* UNISYS CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1990 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* */ /*****************************************************************************/ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE */ /* AND RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS */ /* OF PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /************************** END OF MODULE HEADER ***************************/ ; ; This is the data file for the K1 Keyboard that is used by the "Create ; Keyboard Table" Application. The format is translation tables for a ; K1 keyboard. ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; ; Changes: ; ; 11/14/91 vjm Removed emulation of to be for XVT ; All allowed states with {..,3,4..} changed to {..,3,4..,6}. ; Two new conditions added "{6} {} {}" and ; "{6} {1,2,3,4,5} {}" which select table 3 the same ; table selected by {1,2} {3.4} {}, the CODE-SHIFT ; condition. ; Keyboard name SG1K ; Output file name SG1KTransTables.obj ; Name of PUBLIC in object module at start of table SG1KKeyBoardData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ; TRANSLATION DATA ; ; TRANSLATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if translation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ IBus ID in hex. ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of translation tables in decimal ; | | | | ; 80 67 80 4 ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "7F h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have at least 19 and at most 29entries and they MUST ; be in the order shown. 22 ; Number special keys in decimal 61 ; a 62 ; b 7F ; 44 ; 4C ; 4D ; 04 ; 43 ; 45 ; 48 ; 49 ; 64 ; Mouse Disable 65 ; Mouse Enable 53 ; 00 ; c 1B ; - For Action-GO via the Prt Screen key (System key) 40 ; iKey not valid 20 ; Diacritic Escape 57 ; Sys Key If there is no key use an iKey that is ; not produced by the keyboard in question OR 00 ; NOTE that the help key can not be used as the ; system key since it is '00' 00 ; OS1 00 ; OS2 00 ; OS3 END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for a translation table. ; 7 ; Number of entries ; ; !!! ALL NUMBERS IN THE FOLLOWING TABLE MUST BE IN HEX ; ; key bMask* fToggle fLed LED mask** ; number bit bit fExclus- ; position position ionary ; (hex) (hex) (hex) ; 48 0 F F 0 F ; Chord #1 49 1 F F 0 F ; Chord #2 4C 2 F F 0 F ; Chord #3 4D 3 F F 0 F ; Chord #4 45 4 T T 6 F ; Chord #5 53 5 F F 0 F ; Chord #6 55 6 F F 0 F ; Chord #7 ; * NOTES: bMask bit position ; ; 1. The number of the bit set (to 1) in the bMask word for this ; chord where "0" means the least significant bit and "15" ; means the most significant bit. ; ; 2. The values for bMask are NOT required to be consecutive. ; ; ** NOTE: there MUST be an entry for "LED mask bit position" even if the ; "fLED" entry is "F"; it can be zero. END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START CONTROL CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. 8 ; Number of entries 00 ; escState 00 ; escState2 00 ; noDiacrit 00 ; noRepeat 0C ; status4 00 ; status2 03 ; status1 10 ; altStatus1 END CONTROL CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START RPT ATTRS TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; The following entries for FAST and SLOW attribute characteristics are ; optional. You can have both none or one of them. The allowable codes ; are: ; ; Delay until repeating starts codes: 1 - 0.2 seconds ; 2 - 0.4 seconds ; 3 - 0.7 seconds ; ; Frequency of repetition codes: 0 - 1 character / second ; 1 - 10 character / second ; 2 - 20 character / second ; 3 - 30 character / second ; ; If no entry is made a default will be shown. The dafaults are: ; ; Delay Until Frequency Of ; Repeating Repeating ; Starts Code Code ; ; Attribute Characteristics Fast 2 3 ; ; Attribute Characteristics Slow 3 2 ; ; ENTRIES ; ---------------------------------------------------- ; Repeat iKey Key ; Attribute Number Name ; --------- ------ --------- None ; 000 help Fast ; 001 up-arrow None ; 002 mark None ; 003 bound None ; 004 finish None ; 005 prev page Slow ; 006 1/2-1/4 None ; 007 cancel Slow ; 008 backspace None ; 009 tab Slow ; 00A return Fast ; 00B down-arrow None ; 00C next page Slow ; 00D next Fast ; 00E left-arrow Fast ; 00F right-arrow None ; 010 SH-L Slow ; 011 scroll-up None ; 012 move Slow ; 013 scroll-down None ; 014 copy None ; 015 f1 None ; 016 f2 None ; 017 f3 None ; 018 f4 None ; 019 f5 None ; 01A f6 None ; 01B GO None ; 01C f7 None ; 01D f8 None ; 01E f9 None ; 01F f10 Slow ; 020 space Slow ; 021 9 9 None ; 022 SH-R None ; 023 0 None ; 024 NEXT None ; 025 None ; 026 Slow ; 027 ' " None ; 028 None ; 029 None ; 02A Slow ; 02B + = Slow ; 02C , , Slow ; 02D - _ Slow ; 02E . . Slow ; 02F / ? Slow ; 030 0 right parens Slow ; 031 1 ! Slow ; 032 2 @ Slow ; 033 3 # Slow ; 034 4 $ Slow ; 035 5 percent Slow ; 036 6 cent Slow ; 037 7 & Slow ; 038 8 * Slow ; 039 9 left parens None ; 03A Slow ; 03B None ; 03C None ; 03D None ; 03E None ; 03F iKeyInvalid None ; 040 iKeyNoKeys Slow ; 041 6 6 Slow ; 042 - - None ; 043 reset None ; 044 overtype None ; 045 lock Slow ; 046 2 2 Slow ; 047 3 3 None ; 048 shift-r None ; 049 shift-l Slow ; 04A 0 0 Slow ; 04B . . None ; 04C code-r None ; 04D code-l None ; 04E None ; 04F None ; 050 None ; 051 None ; 052 sys None ; 053 alt None ; 054 None ; 055 None ; 056 None ; 057 None ; 058 None ; 059 None ; 05A Slow ; 05B [ < Slow ; 05C 7 | Slow ; 05D ] > Slow ; 05E ^ ~ None ; 05F Slow ; 060 1 ` Slow ; 061 a A Slow ; 062 b B Slow ; 063 c C Slow ; 064 d D Slow ; 065 e E Slow ; 066 f F Slow ; 067 g G Slow ; 068 h H Slow ; 069 i I Slow ; 06A j J Slow ; 06B k K Slow ; 06C l L Slow ; 06D m M Slow ; 06E n N Slow ; 06F o O Slow ; 070 p P Slow ; 071 q Q Slow ; 072 r R Slow ; 073 s S Slow ; 074 t T Slow ; 075 u U Slow ; 076 v V Slow ; 077 w W Slow ; 078 x X Slow ; 079 y Y Slow ; 07A z Z Slow ; 07B 4 { Slow ; 07C 8 backslash Slow ; 07D 5 } None ; 07E Slow ; 07F del END RPT ATTRS TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; ------------------ ------ --------- { 1,2,3,4 } ; 000 help { 1,2,3,4 } ; 001 up-arrow { 1,2,3,4 } ; 002 mark { 1,2,3,4 } ; 003 bound { 1,2,3,4 } ; 004 finish { 1,2,3,4 } ; 005 prev page { 1,2,3,4 } ; 006 1/2-1/4 { 1,2,3,4 } ; 007 cancel { 1,2,3,4 } ; 008 backspace { 1,2,3,4 } ; 009 tab { 1,2,3,4 } ; 00A return { 1,2,3,4 } ; 00B down-arrow { 1,2,3,4 } ; 00C next page { 1,2,3,4 } ; 00D next { 1,2,3,4 } ; 00E left-arrow { 1,2,3,4 } ; 00F right-arrow { 0 } ; 010 SH-L { 1,2,3,4 } ; 011 scroll-up { 1,2,3,4 } ; 012 move { 1,2,3,4 } ; 013 scroll-down { 1,2,3,4 } ; 014 copy { 1,2,3,4 } ; 015 f1 { 1,2,3,4 } ; 016 f2 { 1,2,3,4 } ; 017 f3 { 1,2,3,4 } ; 018 f4 { 1,2,3,4 } ; 019 f5 { 1,2,3,4 } ; 01A f6 { 1,2,3,4 } ; 01B GO { 1,2,3,4 } ; 01C f7 { 1,2,3,4 } ; 01D f8 { 1,2,3,4 } ; 01E f9 { 1,2,3,4 } ; 01F f10 { 1,2,3,4 } ; 020 space { 1,2,3,4,6,7 } ; 021 9 9 { 0 } ; 022 SH-R { 0 } ; 023 0 { 0 } ; 024 NEXT { 0 } ; 025 { 0 } ; 026 { 1,2,3,4,6,7 } ; 027 ' " { 0 } ; 028 { 0 } ; 029 { 0 } ; 02A { 1,2,3,4,6,7 } ; 02B + = { 1,2,3,4,6,7 } ; 02C , , { 1,2,3,4,6,7 } ; 02D - _ { 1,2,3,4,6,7 } ; 02E . . { 1,2,3,4,6,7 } ; 02F / ? { 1,2,3,4,6,7 } ; 030 0 right parens { 1,2,3,4,6,7 } ; 031 1 ! { 1,2,3,4,6,7 } ; 032 2 @ { 1,2,3,4,6,7 } ; 033 3 # { 1,2,3,4,6,7 } ; 034 4 $ { 1,2,3,4,6,7 } ; 035 5 percent { 1,2,3,4,6,7 } ; 036 6 cent { 1,2,3,4,6,7 } ; 037 7 & { 1,2,3,4,6,7 } ; 038 8 * { 1,2,3,4,6,7 } ; 039 9 left parens { 0 } ; 03A { 1,2,3,4,6,7 } ; 03B { 0 } ; 03C { 0 } ; 03D { 0 } ; 03E { 0 } ; 03F iKeyInvalid { 0 } ; 040 iKeyNoKeys { 1,2,3,4,6,7 } ; 041 6 6 { 1,2,3,4,6,7 } ; 042 - - { 0 } ; 043 reset { 1,2,3,4 } ; 044 overtype { 5 } ; 045 lock { 1,2,3,4,6,7 } ; 046 2 2 { 1,2,3,4,6,7 } ; 047 3 3 { 1 } ; 048 shift-r { 2 } ; 049 shift-l { 1,2,3,4,6,7 } ; 04A 0 0 { 1,2,3,4,6,7 } ; 04B . . { 3 } ; 04C code-r { 4 } ; 04D code-l { 0 } ; 04E { 0 } ; 04F { 0 } ; 050 { 0 } ; 051 { 0 } ; 052 { 0 } ; 053 { 0 } ; 054 { 0 } ; 055 { 0 } ; 056 { 0 } ; 057 { 0 } ; 058 { 0 } ; 059 { 0 } ; 05A { 1,2,3,4,6,7 } ; 05B [ < { 1,2,3,4,6,7 } ; 05C 7 | { 1,2,3,4,6,7 } ; 05D ] > { 1,2,3,4,6,7 } ; 05E ^ ~ { 0 } ; 05F { 1,2,3,4,6,7 } ; 060 1 ` { 1,2,3,4,5,6,7 } ; 061 a A { 1,2,3,4,5,6,7 } ; 062 b B { 1,2,3,4,5,6,7 } ; 063 c C { 1,2,3,4,5,6,7 } ; 064 d D { 1,2,3,4,5,6,7 } ; 065 e E { 1,2,3,4,5,6,7 } ; 066 f F { 1,2,3,4,5,6,7 } ; 067 g G { 1,2,3,4,5,6,7 } ; 068 h H { 1,2,3,4,5,6,7 } ; 069 i I { 1,2,3,4,5,6,7 } ; 06A j J { 1,2,3,4,5,6,7 } ; 06B k K { 1,2,3,4,5,6,7 } ; 06C l L { 1,2,3,4,5,6,7 } ; 06D m M { 1,2,3,4,5,6,7 } ; 06E n N { 1,2,3,4,5,6,7 } ; 06F o O { 1,2,3,4,5,6,7 } ; 070 p P { 1,2,3,4,5,6,7 } ; 071 q Q { 1,2,3,4,5,6,7 } ; 072 r R { 1,2,3,4,5,6,7 } ; 073 s S { 1,2,3,4,5,6,7 } ; 074 t T { 1,2,3,4,5,6,7 } ; 075 u U { 1,2,3,4,5,6,7 } ; 076 v V { 1,2,3,4,5,6,7 } ; 077 w W { 1,2,3,4,5,6,7 } ; 078 x X { 1,2,3,4,5,6,7 } ; 079 y Y { 1,2,3,4,5,6,7 } ; 07A z Z { 1,2,3,4,6,7 } ; 07B 4 { { 1,2,3,4,6,7 } ; 07C 8 backslash { 1,2,3,4,6,7 } ; 07D 5 } { 0 } ; 07E { 1,2,3,4 } ; 07F del END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 8 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; Table Conditions Comments ; ID -------------------------------- ; orState 1 orState 2 orState 3 ; ----- --------- --------- --------- ----------------------------------- 0 { } { } { } ; No chord keys down 1 { 1,2,5 } ; Shift-lock OR either Shift key ; down; one "orState" 2 { 3,4 } ; Either Code key down; one ; "orState" 3 { 1,2 } { 3,4 } ; Either Shift key down AND either ; Code key down; two "orStates" 2 { 5 } { 3,4 } ; Shift-lock key down AND either ; Code key down; two "orStates" 3 { 1,2 } { 3,4 } { 5 } ; Shift-lock AND either Shift key ; down AND either Code key ; down; three "orStates". ; --------------------- New additions --------------------- 3 { 6,7 } { } ; Alt key down; one "orState" 3 { 6,7 } {1,2,3,4,5} ; Alt key and one or more other ; chord keys down; two ; "orStates" END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 0 ; Number of multibyte strings ; String : each entry is a "state:hardware ikey" pair ; ; As an example, the following string would display "Hi there" as shown. ; Note the upstroke for the last key is present; this is okay the ; tool will add any necessary upstrokes. ; ; The "&" means continue. ; ; shft-h shft-h i i space space t t h h ; down up down up down up down up down up ; { 01:68, 01:E8, 00:69, 00:E9, 00:20, 00:A0, 00:74, 00:F4, 00:68, 00:E8 & ; 00:65, 00:E5, 00:72, 00:F2, 00:65 } ; e e r r e ; down up down up down ; ; The following string would display ".00" . ; ; { 00:2E, 00:AE, 00:30, 00:B0, 00:30, 00:B0 } ; END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Translation Tables Info ; ; Table #0, for case where no chord keys held down. ; WIDTH 1 ; 00 ; 000 help 01 ; 001 up-arrow 02 ; 002 mark 0D ; 003 bound 04 ; 004 finish 05 ; 005 prev page 06 ; 006 1/2-1/4 07 ; 007 cancel 08 ; 008 backspace 09 ; 009 tab 0A ; 00A return 0B ; 00B down-arrow 0C ; 00C next page 0A ; 00D next 0E ; 00E left-arrow 12 ; 00F right-arrow EA ; 010 SH-L K2, K3, K5 & K6 "JUMP" 11 ; 011 scroll-up 0F ; 012 move 13 ; 013 scroll-down 14 ; 014 copy 15 ; 015 f1 16 ; 016 f2 17 ; 017 f3 18 ; 018 f4 19 ; 019 f5 1A ; 01A f6 1B ; 01B GO 1C ; 01C f7 1D ; 01D f8 1E ; 01E f9 1F ; 01F f10 20 ; 020 space 39 ; 021 9 (from 9 9 keypad key) BA ; 022 SH-R K2, K3, K5 & K6 "DEL CHAR" 00 ; 023 0 00 ; 024 NEXT 00 ; 025 FE ; 026 K2, K3, K5 & K6 "COLUMN" key 27 ; 027 ' (from ' " key) FB ; 028 K2, K3, K5 & K6 "PAGE" key E0 ; 029 K2, K3, K5 & K6 "PARAGRAPH" key BF ; 02A K2, K3, K5 & K6 "SENTENCE" key 3D ; 02B = 2C ; 02C , (from , , key) 2D ; 02D - (from - _ key) 2E ; 02E . (from . . key) 2F ; 02F / 30 ; 030 0 (from 0 ) key) 31 ; 031 1 (from 1 ! key) 32 ; 032 2 (from 2 @ key) 33 ; 033 3 (from 3 # key) 34 ; 034 4 (from 4 $ key) 35 ; 035 5 (from 5 % key) 36 ; 036 6 (from 6  key) 37 ; 037 7 (from 7 & key) 38 ; 038 8 (from 8 * key) 39 ; 039 9 (from 9 ( key) 00 ; 03A 3B ; 03B ; BE ; 03C K2, K3, K5 & K6 "WORD" key FD ; 03D K2, K3, K5 & K6 "LINE" key 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys 36 ; 041 6 (from 6 6 keypad key) 2D ; 042 - (from - - keypad key) 00 ; 043 reset D0 ; 044 overtype 00 ; 045 lock 32 ; 046 2 (from 2 2 keypad key) 33 ; 047 3 (from 3 3 keypad key) 00 ; 048 shift 00 ; 049 shift 30 ; 04A 0 (from 0 0 keypad key) 2E ; 04B . (from . . keypad key) 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 sys 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A 5B ; 05B [ 37 ; 05C 7 (from 7 | keypad key) 5D ; 05D ] 5E ; 05E ^ 00 ; 05F 31 ; 060 1 (from 1 ` keypad key) 61 ; 061 a 62 ; 062 b 63 ; 063 c 64 ; 064 d 65 ; 065 e 66 ; 066 f 67 ; 067 g 68 ; 068 h 69 ; 069 i 6A ; 06A j 6B ; 06B k 6C ; 06C l 6D ; 06D m 6E ; 06E n 6F ; 06F o 70 ; 070 p 71 ; 071 q 72 ; 072 r 73 ; 073 s 74 ; 074 t 75 ; 075 u 76 ; 076 v 77 ; 077 w 78 ; 078 x 79 ; 079 y 7A ; 07A z 34 ; 07B 4 (from 4 { keypad key) 38 ; 07C 8 (from 8 \ keypad key) 35 ; 07D 5 (from 5 } keypad key) 00 ; 07E 7F ; 07F del ; ; Table #1, for case where either chord key held down. ; WIDTH 1 C0 ; 000 help C1 ; 001 up-arrow C2 ; 002 mark C3 ; 003 bound C4 ; 004 finish C5 ; 005 prev page 10 ; 006 1/2-1/4 C7 ; 007 cancel 08 ; 008 backspace 09 ; 009 tab 0A ; 00A return CB ; 00B down-arrow CC ; 00C next page 0A ; 00D next CE ; 00E left-arrow D2 ; 00F right-arrow 00 ; 010 SH-L D1 ; 011 scroll-up CF ; 012 move D3 ; 013 scroll-down D4 ; 014 copy D5 ; 015 f1 D6 ; 016 f2 D7 ; 017 f3 D8 ; 018 f4 D9 ; 019 f5 DA ; 01A f6 C9 ; 01B GO DC ; 01C f7 CD ; 01D f8 CA ; 01E f9 DF ; 01F f10 20 ; 020 space 39 ; 021 9 (from 9 9 keypad key) BA ; 022 SH-R K2, K3, K5 & K6 "DEL CHAR" 00 ; 023 0 00 ; 024 NEXT 00 ; 025 FE ; 026 K2, K3, K5 & K6 "COLUMN" 22 ; 027 " (from ' " keypad key) FB ; 028 K2, K3, K5 & K6 "PAGE" key E0 ; 029 K2, K3, K5 & K6 "PARAGRAPH" key BF ; 02A K2, K3, K5 & K6 "SENTENCE" key 2B ; 02B + 2C ; 02C , (from , , keypad key) 5F ; 02D _ (from - _ keypad key) 2E ; 02E . (from . . keypad key) 3F ; 02F ? 29 ; 030 ) (from 0 ) keypad key) 21 ; 031 ! (from 1 ! keypad key) 40 ; 032 @ (from 2 @ keypad key) 23 ; 033 # (from 3 # keypad key) 24 ; 034 $ (from 4 $ keypad key) 25 ; 035 % (from 5 % keypad key) 03 ; 036  (from 6  keypad key) 26 ; 037 & (from 7 & keypad key) 2A ; 038 * (from 8 * keypad key) 28 ; 039 ( (from 9 ( keypad key) 00 ; 03A 3A ; 03B : BE ; 03C K2, K3, K5 & K6 "WORD" key FD ; 03D K2, K3, K5 & K6 "LINE" key 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys 36 ; 041 6 (from 6 6 keypad key) 2D ; 042 - (from - - keypad key) 00 ; 043 reset D0 ; 044 overtype 00 ; 045 lock 32 ; 046 2 (from 2 2 keypad key) 33 ; 047 3 (from 3 3 keypad key) 00 ; 048 shift 00 ; 049 shift 30 ; 04A 0 (from 0 0 keypad key) 2E ; 04B . (from . . keypad key) 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A 3C ; 05B < 7C ; 05C | (from 7 | keypad key) 3E ; 05D > 7E ; 05E ~ 00 ; 05F 60 ; 060 ` (from 1 ` keypad key) 41 ; 061 A 42 ; 062 B 43 ; 063 C 44 ; 064 D 45 ; 065 E 46 ; 066 F 47 ; 067 G 48 ; 068 H 49 ; 069 I 4A ; 06A J 4B ; 06B K 4C ; 06C L 4D ; 06D M 4E ; 06E N 4F ; 06F O 50 ; 070 P 51 ; 071 Q 52 ; 072 R 53 ; 073 S 54 ; 074 T 55 ; 075 U 56 ; 076 V 57 ; 077 W 58 ; 078 X 59 ; 079 Y 5A ; 07A Z 7B ; 07B { (from 4 { keypad key) 5C ; 07C \ (from 8 \ keypad key) 7D ; 07D } (from 5 } keypad key) 00 ; 07E C8 ; 07F del ; ; Table #2, for case where either chord key held down. ; WIDTH 1 80 ; 000 help 81 ; 001 up-arrow 82 ; 002 mark 8D ; 003 bound 84 ; 004 finish 85 ; 005 prev page 86 ; 006 1/2-1/4 87 ; 007 cancel 88 ; 008 backspace 89 ; 009 tab 8A ; 00A return 8B ; 00B down-arrow 8C ; 00C next page 8A ; 00D next 8E ; 00E left-arrow 92 ; 00F right-arrow 00 ; 010 SH-L 91 ; 011 scroll-up 8F ; 012 move 93 ; 013 scroll-down 94 ; 014 copy 95 ; 015 f1 96 ; 016 f2 97 ; 017 f3 98 ; 018 f4 99 ; 019 f5 9A ; 01A f6 9B ; 01B GO 9C ; 01C f7 9D ; 01D f8 9E ; 01E f9 9F ; 01F f10 A0 ; 020 space B9 ; 021 9 9 00 ; 022 SH-R 00 ; 023 0 00 ; 024 NEXT 00 ; 025 00 ; 026 A7 ; 027 ' " 00 ; 028 00 ; 029 00 ; 02A BD ; 02B + = AC ; 02C , , AD ; 02D - _ AE ; 02E . . AF ; 02F / ? B0 ; 030 0 right parens B1 ; 031 1 ! B2 ; 032 2 @ B3 ; 033 3 # B4 ; 034 4 $ B5 ; 035 5 percent B6 ; 036 6 cent B7 ; 037 7 & B8 ; 038 8 * B9 ; 039 9 left parens 00 ; 03A BB ; 03B ; : 00 ; 03C 00 ; 03D 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys B6 ; 041 6 6 AD ; 042 - - 00 ; 043 reset 00 ; 044 overtype 00 ; 045 lock B2 ; 046 2 2 B3 ; 047 3 3 00 ; 048 shift 00 ; 049 shift B0 ; 04A 0 0 AE ; 04B . . 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A DB ; 05B [ < B7 ; 05C 7 | DD ; 05D ] > DE ; 05E ^ ~ 00 ; 05F B1 ; 060 1 ` E1 ; 061 a A E2 ; 062 b B E3 ; 063 c C E4 ; 064 d D E5 ; 065 e E E6 ; 066 f F E7 ; 067 g G E8 ; 068 h H E9 ; 069 i I EA ; 06A j J EB ; 06B k K EC ; 06C l L ED ; 06D m M EE ; 06E n N EF ; 06F o O F0 ; 070 p P F1 ; 071 q Q F2 ; 072 r R F3 ; 073 s S F4 ; 074 t T F5 ; 075 u U F6 ; 076 v V F7 ; 077 w W F8 ; 078 x X F9 ; 079 y Y FA ; 07A z Z B4 ; 07B 4 { B8 ; 07C 8 backslash B5 ; 07D 5 } 00 ; 07E FF ; 07F del ; ; Table #3, for case where one of the chord keys and one of the ; chord keys held down simultaneously. ; WIDTH 1 C0 ; 000 help C1 ; 001 up-arrow C2 ; 002 mark C3 ; 003 bound C4 ; 004 finish C5 ; 005 prev page 90 ; 006 1/2-1/4 C7 ; 007 cancel 88 ; 008 backspace 89 ; 009 tab 8A ; 00A return CB ; 00B down-arrow CC ; 00C next page 8A ; 00D next CE ; 00E left-arrow D2 ; 00F right-arrow 00 ; 010 SH-L D3 ; 011 scroll-up CF ; 012 move D3 ; 013 scroll-down D4 ; 014 copy D5 ; 015 f1 D6 ; 016 f2 D7 ; 017 f3 D8 ; 018 f4 D9 ; 019 f5 DA ; 01A f6 C9 ; 01B GO DC ; 01C f7 CD ; 01D f8 CA ; 01E f9 DF ; 01F f10 A0 ; 020 space B9 ; 021 9 9 00 ; 022 SH-R 00 ; 023 0 00 ; 024 NEXT 00 ; 025 00 ; 026 A2 ; 027 ' " 00 ; 028 00 ; 029 00 ; 02A AB ; 02B + = AC ; 02C , , DF ; 02D - _ AE ; 02E . . BF ; 02F / ? A9 ; 030 0 right parens A1 ; 031 1 ! C0 ; 032 2 @ A3 ; 033 3 # A4 ; 034 4 $ A5 ; 035 5 percent 83 ; 036 6 cent A6 ; 037 7 & AA ; 038 8 * A8 ; 039 9 left parens 00 ; 03A BA ; 03B ; : 00 ; 03C 00 ; 03D 00 ; 03E 00 ; 03F 3F = iKeyInvalid 00 ; 040 40 = iKeyNoKeys B6 ; 041 6 6 AD ; 042 - - 00 ; 043 reset 00 ; 044 overtype 00 ; 045 lock B2 ; 046 2 2 B3 ; 047 3 3 00 ; 048 shift 00 ; 049 shift B0 ; 04A 0 0 AE ; 04B . . 00 ; 04C code 00 ; 04D code 00 ; 04E 00 ; 04F 00 ; 050 00 ; 051 00 ; 052 00 ; 053 alt 00 ; 054 00 ; 055 00 ; 056 00 ; 057 00 ; 058 00 ; 059 00 ; 05A BC ; 05B [ < FC ; 05C 7 | BE ; 05D ] > FE ; 05E ^ ~ 00 ; 05F E0 ; 060 1 ` C1 ; 061 a A C2 ; 062 b B C3 ; 063 c C C4 ; 064 d D C5 ; 065 e E C6 ; 066 f F C7 ; 067 g G C8 ; 068 h H C9 ; 069 i I CA ; 06A j J CB ; 06B k K CC ; 06C l L CD ; 06D m M CE ; 06E n N CF ; 06F o O D0 ; 070 p P D1 ; 071 q Q D2 ; 072 r R D3 ; 073 s S D4 ; 074 t T D5 ; 075 u U D6 ; 076 v V D7 ; 077 w W D8 ; 078 x X D9 ; 079 y Y DA ; 07A z Z FB ; 07B 4 { DC ; 07C 8 backslash FD ; 07D 5 } 00 ; 07E C8 ; 07F del END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm CrashDump.sys0Development Utilities Diskette 3 of 3 (B25U22-3) Install.ctrlSortMergeExamples>Install.ctrl DLLMediator>Install.jcl!DLLMediator>Install.ctrl"Fileheaders.sysMfd.sys SysImage.sysKeyboardTool>Install.jclKeyboardTool>Install.ctrl!AsynchronousExamples>Install.ctrlBootRecord.sysLog.sys BadBlk.sysKeyboardTool>Install.cmdsKeyboardTables>Install.jclKeyboardTables>Install.ctrl AsynchronousExamples>Install.jclSortMergeExamples>Install.jclC@ B25U22-3/3@ wwB @ D ZP >  89|P^Sys8 KCT Async SM Mediator KbdTbl 9|Fileheaders.sysSys: ΟwΟwΟwD (BootRecord.sysSys< ΟwΟwΟwzMfd.sysSys: ϟwϟwϟwB vLog.sysSys< ПwПwПw@  SysImage.sysSys: ПwПwПw(] BadBlk.sysSys< џwџwџw7 CrashDump.sysSys8 ҟwҟwҟw@ S0Development Utilities Diskette 3 of 3 (B25U22-3)cinchSys8 www9 KCT.runcinchKCT  wCvRv KCTMsg.bincinchKCT  w#uZQv;< k1.kbd_datacinchKbdTbl  wcvPv! 21.kbd_datacinchKbdTbl  w sPvji~j9 41.kbd_datacinchKbdTbl  w/vPvkWX4 51.kbd_datacinchKbdTbl wsQv`@ 61.kbd_datacinchKbdTbl wsQv ssk1.kbd_datacinchKbdTbl wsQvF k0.kbd_datacinchKbdTbl #w!sPv\DWk4nonfin.kbd_datacinchKbdTbl (wᜦs@QvKL. pck1.kbd_datacinchKbdTbl +w s'Qv  pik1.kbd_datacinchKbdTbl 0wNt6Qvܝ 9sg1ktrans.kbd_datacinchKbdTbl 5wǥ$tVQv&@ 3sg1kemul.kbd_datacinchKbdTbl 9wInstall.jclcinchSys: Jwww A\KeyboardTool>Install.ctrlcinchSys: Mwww (KeyboardTool>Install.cmdscinchSys< OwRrw KeyboardTables>Install.jclcinchSys< Vwww KeyboardTables>Install.ctrlcinchSys< Xwww ܑ AsynchronousExamples>Install.jclcinchSys< _www 1!AsynchronousExamples>Install.ctrlcinchSys: awwwi >SortMergeExamples>Install.jclcinchSys< hwww & SortMergeExamples>Install.ctrlcinchSys 8 jwww 6!DLLMediator>Install.jclcinchSys!8 qwww` "DLLMediator>Install.ctrlcinchSys"8 swwĞw &E#Async.hcinchAsync# {w sGQv J9$AsyncService.ccinchAsync$ ~wIsJQv5 6˿% DeInstall.ccinchAsync% w@LsLQvH & Example.ccinchAsync& wLsOQvC^ D'ExDef.hcinchAsync' w sQQvb (ExFunc.hcinchAsync( w sSQv ۭ) ExRqblk.hcinchAsync) w sUQvS !* ExRqlabl.asmcinchAsync* wMsWQv  )+LinkDeinstall.flscinchAsync+ w s2 LinkStop.subcinchAsync2 wovB=v# 3ReadMecinchAsync3 w% stQv Y4 RequestEx.txtcinchAsync4 wFortran86ChkErc.fort86cinchSM> ǠwsQv?Fortran86ChkSts.fort86cinchSM? ʠwsQv  4@Fortran86Link.flscinchSM@ ̠wsQvN{AFortran86SortExample.fort86cinchSMA Πw sQvVBFortran86SortExample.subcinchSMB ѠwsQv  ȏCFortranSortExample.forcinchSMC ԠwsQvÊDFortranSortExample.subcinchSMD ֠w sQv  EMrkDatacinchSME ؠwsQv&(tFMultiRecordKeySct.subcinchSMF ۠wsQv)G NewRecordscinchSMG ݠwsQvU]H OldMastercinchSMH ޠwsQv7 IPascalSortExample.pascinchSMI wsQv&&JPascalSortExample.subcinchSMJ wsQv 6 TKSortMergeSct.subcinchSMK w sQvQ@ۜLMediatorFirst.asmcinchMediatorL wWcvQv6D(M mediator.asmcinchMediatorM w)v)vX(N mediator.defcinchMediatorN wPZvQvjO mediator.mdfcinchMediatorO wQZvQv(|*PQ)QR(RS'ST&TU%UV$VW#WX"XY{Y KCTMsg.bin KCT.run ExDef.h' ExRqblk.h) ExRqlabl.asm*LinkDeinstall.fls+LinkExample.sub. LinkStart.sub0 Example.c&ExFunc.h(LinkDeinstall.sub, LinkStop.fls1ReadMe3Start.c5Stop.c6Async.h#AsyncService.c$ DeInstall.c%LinkExample.fls- LinkStart.fls/ LinkStop.sub2 RequestEx.txt4BasicSortExample.sub8Fortran86ChkSts.fort86?Fortran86SortExample.fort86AFortran86SortExample.subBFortranSortExample.subDMrkDataEMultiRecordKeySct.subF NewRecordsG OldMasterHPascalSortExample.subJFiles.in< FntUtl.idf=Fortran86ChkErc.fort86>Fortran86Link.fls@FortranSortExample.forCPascalSortExample.pasIBasicSortExample.bas7CSortExample.c9CSortExample.sub:DataFile;SortMergeSct.subKMediatorFirst.asmL mediator.mdfO mediator.asmM mediator.defN ssk1.kbd_data k0.kbd_data pck1.kbd_data k1.kbd_data 21.kbd_data 41.kbd_data 51.kbd_data 61.kbd_datak4nonfin.kbd_data pik1.kbd_datasg1ktrans.kbd_datasg1kemul.kbd_data; ; ; This is the data file for a PORTABLE Internal keyboard that is to be ; emulated as a K1 Keyboard; this file is suitable for use by the ; "Create Keyboard Table" command ; ; In what follows semicolons, ";", or the slash-asterix pair "/*" start ; comments. The newline character ends comments. Also lines consisting ; of only the new line character are ignored. ; ;CHANGE LOG: ;10/01/92 KH added E0 to allowed state for 7C for system key ;10/13/92 KH changes to make 'pad' keys work; removed numlock tables ;10/14/92 reverse scrolling so that alt-pg down moves you further into the file ; (just like pg-dn does) ;10/15/92 KH removed shifts from allowed states for alpha keys, and used ; 'shifts' table for ALT E0 7A/7D, the only ALT+E0 keys (scrolling) ; therefore eliminating the ALT+E0 table and conditions ;10/21/92 KH another attempt to get consistency: E0 7D = ikey for PG UP/NEXT PG ; and (with ALT) SCROLL UP, all of which move you toward the end; ; this change from the previous use of the SG1K pg up key and was ; made because pg xx and scroll xx have to be the same since they ; share a key, and scroll xx should mean the same thing as the IBUS ; keys by the same name. ;11/03/92 KH fix shift+E0 keys problem. Introduce the shift+E0 condition which ; ONLY affects the extended shift keys E0 12/59 (or E0 F0 12/59) ; generated by the firmware when the shift key is down follwed by ; arrow, page, home/end, insert and delete keys. Note that these ; extended shifts need to be absorbed as we don't want to see them. ;11/05/92 KH Hopefully the end of this Pageup/dn business; put directions back ; to the 10/14 way. Page up moves you to the beginning, no matter ; what you are doing (paging/scrolling in CTOS,PM,DOS,Windows apps ; ;05/15/93 KH Removed {6,7} {1,2,3,4,5} case since none of the allowed states ; would let this happen. Added {6,7} {1,2} case (using table 3) for ; 5D to change the \ | key to GO, ALT 5D to \ and SHIFT ALT 5D to ; |. Put ALTs in the allowed states for 5D. Changed the tables as ; follows: Table 0 = 1B (GO). 'Shift table' Table 1 = 1B (GO). ; 'ALT table' Table 2 = 01:7C (this was the original table 0 value). ; 'E0 table ' Table 3 is used for the ALT SHIFT 5D case, as 5D had ; no entry in this table and is not impacted by E0. So, ; Table 3 = 01:7D. Note that this is the only key for which ALTs ; and SHIFTs are both significant. ; ALSO: Renamed Tables in comment from Tables 1-4 to Tables 0-3 to make ; this comment non-ambiguous. ; ALSO: Fixed the ACTION/FINISH definitions in the special keys table, ; which is significant to raw-mode programs. ; Keyboard name SG1K ; Output file name SG1KEmulTables.obj ; Name of PUBLIC in object module at start of table SG1KEmulData ;Number of forms files needed to display keyboard. 0 ; ==================================================================== ; ==================================================================== ; ; EMULATION DATA ; ; What follows is the data for having the SG-1000 internal keyboard ; keyboard emulate the standard CTOS (K1) ; keyboard. That is given a HW state and key produce the K1 state and key(s) ; needed to give the same result ; EMULATION DATA EXISTS ; The preceeding string is NOT a comment. It ; must be in the file if emulation data ; is present in the file. START SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. ; ; :----------------------- Number of entries in per key tables in hex ; | ; | :------------------ Keyboard ID of a SG-1000 portable ; | | ; | | :------------ "Key up" mask in hex. ; | | | ; | | | :-------- Number of emulation tables in hex ; | | | | ; 85 67 80 4 67 -- target translation table in hex ; ; Special keys. ; ; The first column is the hardware "iKey" returned by the special key (in ; hex). The second column (the comments) is the value of that key on the ; K1 keyboard. For example the "delete" key returns "71 h". For the K1 ; keyboard this data is in Tables B-1 or C-1 in the CTOS Concepts manual. ; This table MUST have at least 19 entries and all MUST be in the order shown. ;Values > FFh represent a two-byte scanset2 key 22 ; Number of special keys. ; SG-1000 Kbd key CTOS Function 1C ; a ACTION-A for debugger 32 ; b ACTION-B for debugger 171 ; ACTION-DELETE for keyboard cleanup 170 ; ACTION-OVERTYPE for screen saver (blent) 14 ; LEFT CODE 114 ; RIGHT CODE 169 ; FINISH 16C ; ACTION 58 ; CAPS LOCK 12 ; LEFT SHIFT 59 ; RIGHT SHIFT 40 ; 40 ; 40 ; 00 ; c ACTION-C 15A ; GO 00 ; iKey not valid 29 ; Diacritic Escape 17C ; SYSTEM KEY (ACTION-GO) 15A ; 00 ; Map PAUSE key 00 ; reserved for future use ;;; "L ALT", "NUM LOCK" ???? END SPECIAL KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. 3 ; Number of LEDs on keyboard ;0 means don't remap. >16 means not supported. Valid non-zero value is the 1- ;based LED numberthat will be converted to a command valid for the new target ;hardware as follows: 1h,2h,4h,8h,10h,20h,40h,80h; LEDs >8 on the Kx style ;keyboards are handled according to the rquirement described in the hardware ;spec. ;for non-ibus keyboards, values > number of LEDs but <= 16 will be supported ;as phantom or virtual LEDs 99 ; CTOS LED 1 - f10 99 ; 2 - f9 99 ; 3 - f8 99 ; 4 - f3 99 ; 5 - f2 99 ; 6 - f1 03 ; 7 - LOCK 01 ; 8 - Overtype SHARES SCROLL LOCK 99 ; 9 - Comm1 99 ; 10 - Comm2 99 ; 11 - Comm3 99 ; 12 - Comm4 99 ; 13 - Comm5 02 ; 14 - 'Numlock' 99 ; 15 - 'Scroll Lock' 99 ; END LED EMULATION DATA ; The preceeding string is NOT a comment. It ; must be in the file even if no special ; keys list is included. START CHORDS KEYS ; The preceeding string is NOT a comment. It ; must be in the file even if no list of ; default chords is included. ; ; Default Chords for Emulation table ; ; ; Number of entries should be the same as in translation table in this file 9 ; Number of entries ; key bMask* fToggle fLed LED mask** ; number bit bit ; (hex) position position ; 12 0 F F 0 F ; Chord #1 59 1 F F 0 F ; Chord #2 14 2 F F 0 F ; Chord #3 94 3 F F 0 F ; Chord #4 58 4 T T 2 F ; Chord #5 11 5 F F 0 F ; Chord #6 (K1 NOP) 91 6 F F 0 F ; Chord #7 (K1 NOP) 77 7 T T 1 F ; Chord #8 E0 8 F F 0 F ; Chord #9 END CHORDS KEYS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; list of default chords is included. START ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. ; ENTRIES ; ---------------------------------------------------- ; Chords that affect iKey Key ; this "iKey" Number Name ; numbers are decimal ; ------------------ ------ --------- { 0 } ; 000 { 0 } ; 001 f9 { 0 } ; 002 { 0 } ; 003 f5 { 0 } ; 004 f3 { 6,7 } ; 005 f1 (l alt,r alt) { 0 } ; 006 f2 { 6,7 } ; 007 f12 BOUND alt+f12 = COPY { 0 } ; 008 { 0 } ; 009 f10 { 0 } ; 00A f8 { 0 } ; 00B f6 { 0 } ; 00C f4 { 6,7 } ; 00D Tab ALT+Tab = NEXT { 1,2 } ; 00E ` ~ { 0 } ; 00F { 0 } ; 010 { 6,7,9 } ; 011 ALT { 1,2,9 } ; 012 Left Shift (E0 12 is absorbed) { 0 } ; 013 { 3,4,9 } ; 014 CODE { 0 } ; 015 q Q { 1,2 } ; 016 1 ! { 0 } ; 017 { 0 } ; 018 { 0 } ; 019 { 0 } ; 01A z Z { 0 } ; 01B s S { 0 } ; 01C a A { 0 } ; 01D w W { 1,2 } ; 01E 2 @ { 0 } ; 01F { 0 } ; 020 { 0 } ; 021 c C { 0 } ; 022 x X { 0 } ; 023 d D { 0 } ; 024 e E { 1,2 } ; 025 4 $ { 1,2 } ; 026 3 # { 0 } ; 027 { 0 } ; 028 { 0 } ; 029 space { 0 } ; 02A v V { 0 } ; 02B f F { 0 } ; 02C t T { 0 } ; 02D r R { 1,2 } ; 02E 5 % { 0 } ; 02F { 0 } ; 030 { 0 } ; 031 n N { 0 } ; 032 b B { 0 } ; 033 h H { 0 } ; 034 g G { 0 } ; 035 y Y { 1,2 } ; 036 6 ^ { 0 } ; 037 { 0 } ; 038 { 0 } ; 039 { 0 } ; 03A m M { 0 } ; 03B j J { 0 } ; 03C u U { 1,2 } ; 03D 7 & { 1,2 } ; 03E 8 * { 0 } ; 03F { 0 } ; 040 { 1,2 } ; 041 , < { 0 } ; 042 k K { 0 } ; 043 i I { 0 } ; 044 o O { 1,2 } ; 045 0 ) { 1,2 } ; 046 9 ( { 0 } ; 047 { 0 } ; 048 { 1,2 } ; 049 . > { 1,2 } ; 04A / ? E0 4A = pad / but CTOS doesn't care { 0 } ; 04B l L { 1,2 } ; 04C ; : { 0 } ; 04D p P { 1,2 } ; 04E - _ { 0 } ; 04F { 0 } ; 050 { 0 } ; 051 { 1,2 } ; 052 ' " { 0 } ; 053 { 1,2 } ; 054 [ { { 1,2 } ; 055 = + { 0 } ; 056 { 0 } ; 057 { 5 } ; 058 Capslock { 1,2,9 } ; 059 R Shift E0 59 = Extended shift, absorb { 6,7 } ; 05A Return ALT-Enter is GO,So is ALT E0 5A { 1,2 } ; 05B ] } { 0 } ; 05C { 1,2,6,7 } ; 05D \ | 5/93 KH LET 5D = GO, USE ALT FOR CHARS { 0 } ; 05E { 0 } ; 05F { 0 } ; 060 { 0 } ; 061 { 0 } ; 062 { 0 } ; 063 { 0 } ; 064 { 0 } ; 065 { 0 } ; 066 Backspace { 0 } ; 067 { 0 } ; 068 { 9 } ; 069 + E0 = FINISH (END) 69 = 1 pad { 0 } ; 06A { 9 } ; 06B 4 pad + E0 = left arrow { 9 } ; 06C 7 pad + E0 = ACTION (HOME) { 0 } ; 06D { 0 } ; 06E { 0 } ; 06F { 9 } ; 070 0 pad + E0 = overtype (insert) { 9 } ; 071 . pad + E0 = delete { 9 } ; 072 2 pad + E0 = down arrow { 0 } ; 073 5 pad { 9 } ; 074 6 pad + E0 = right arrow { 9 } ; 075 8 pad + E0 = up arrow { 0 } ; 076 escape/cancel { 8 } ; 077 numlock { 6,7 } ; 078 f11 { 0 } ; 079 numpad + { 6,7,9 } ; 07A 3 pad + E0 = PgDn +ALT E0 = scrll dn { 0 } ; 07B { 9 } ; 07C * pad + E0 = System key { 6,7,9 } ; 07D 9 pad + E0 = PgUp +ALT E0 = scrll up { 0 } ; 07E { 0 } ; 07F { 0 } ; 080 { 0 } ; 081 { 0 } ; 082 { 0 } ; 083 f7 { 0 } ; 084 ALT SYSRQ END ALLOWED STATES TABLE ; The preceeding string is NOT a comment. ; It must be in the file even if no ; repeat attributes table is included. START CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Conditions info 8 ; Number of conditions (does not have to match number tables) ; Conditions that point to a given table ; ; NOTE: Numbers in orStates are decimal ; ; Table Conditions Comments ; ID ---------------------------- ; orState1 orState2 orState3 ; ----- -------- -------- -------- ------------------------------------- 0 { } { } { } ; No chord keys down 1 {1,2 } ; either Shift key down; 2 { 6,7 } ; alt (for f1,f11,f12,tab,enter) 3 { 6,7 } {1,2} ; alt and shifts (for 5D to produce \|) 3 { 9 } { } { } ; E0 only 1 { 9 } {6,7} { } ; E0 and ALT only - share shift table 2 { 9 } {1,2} { } ; E0 and SHIFTS only - share ALT table 3 { 9 } {3,4,5,8 } ; E0 and anything else ; ; NOTE ONLY ALT + PG UP/DN have ALT + E0 case and since shifts aren't allowed ; for 7D and 7A they can share the shift table - saves a whole table for just ; 2 keys ; ; ALSO: ONLY the SHIFT keys (12 and 59) have a SHIFT + E0 case allowed. THESE ; must be ABSORBED. Since ALT is of no significance, use the ALT table with ; FF:FF for 12 and 59. Again, this saves a whole table for just 2 keys ; ;5/15 KH Removed: ; 2 { 6,7 } {1,2,3,4,5} ; alt and (shifts/code)(for f1) ; ; to facilitate shift+help or code+help ; ; to facilitate shift+help or code+help ;And added: ; 3 { 6,7 } {1,2} ; alt and shifts (for 5D to produce \|) ; ; END CONDITIONS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. START MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. ; ; Default Multibyte Tables 0 ; Number of multibyte strings ; String ; { 01:68, 01:E8, 00:69, 00:E9, 00:20, 00:A0, 02:74, 02:F4, 00:68, 00:E8& ; 00:65, 00:E5, 00:72, 00:F2, 00:65 } ; { 00:2E, 00:AE, 00:30, 00:B0, 00:30, 00:B0 } ; The "&" means continue. END MULTIBYTES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation multi byte strings are ; included. START DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. ; ; Default Diacritic Tables 0 ; Number of diacritic pairs ; Condition 1/ Condition 1/ Condition 1/2/ MultiByte ; Number Number Number Flag ; Of First First Of Second Second Of Result Result ; Character Character Character Character Character Character ; 00 27 00 65 00000016 F ; 01 5E 01 65 00010034 F ; 01 5E 01 63 00000001 T ; 1/ Condition number is the same as table number in the conditions table ; 2/ Usually zero. END DIACRITICS ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation diacritics are included. START TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; translation table are included. ; ; Default Emulation Tables Info ; ; In what follows entries are of the form xx:yy where ; ; xx = the state ; yy = the K1 iKey ; FF:FF means "Do not emulate as anything" ; FF:xx means "Do not change the state, emulate the key" (ikey -> xx) ; Number of emulation tables specified in special keys table. ; ; Table 0: for case where no chord keys held down. ; FF:FF ; 000 FF:1E ; 001 f9 FF:FF ; 002 FF:19 ; 003 f5 FF:17 ; 004 f3 FF:15 ; 005 f1 FF:16 ; 006 f2 FF:03 ; 007 f12 BOUND FF:FF ; 008 FF:1F ; 009 f10 FF:1D ; 00A f8 FF:1A ; 00B f6 FF:18 ; 00C f4 FF:09 ; 00D tab 01:60 ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:53 ; 011 l alt FF:48 ; 012 l shift FF:FF ; 013 FF:4C ; 014 l ctrl -> l code FF:71 ; 015 q FF:31 ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:7A ; 01A z FF:73 ; 01B s FF:61 ; 01C a FF:77 ; 01D w FF:32 ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:63 ; 021 c FF:78 ; 022 x FF:64 ; 023 d FF:65 ; 024 e FF:34 ; 025 4 FF:33 ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:20 ; 029 space FF:76 ; 02A v FF:66 ; 02B f FF:74 ; 02C t FF:72 ; 02D r FF:35 ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:6E ; 031 n FF:62 ; 032 b FF:68 ; 033 h FF:67 ; 034 g FF:79 ; 035 y FF:36 ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:6D ; 03A m FF:6A ; 03B j FF:75 ; 03C u FF:37 ; 03D 7 FF:38 ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:2C ; 041 , FF:6B ; 042 k FF:69 ; 043 i FF:6F ; 044 o FF:30 ; 045 0 FF:39 ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:2E ; 049 . FF:2F ; 04A / FF:6C ; 04B l FF:3B ; 04C ; FF:70 ; 04D p FF:2D ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 ' FF:FF ; 053 FF:5B ; 054 [ FF:2B ; 055 = FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift FF:0A ; 05A return FF:5D ; 05B ] FF:FF ; 05C 102 key keyboard only FF:1B ; 05D GO (WAS 01:7C) \ (K1 8 \) FF:FF ; 05E FF:57 ; 05F borrowed for pause FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:08 ; 066 FF:FF ; 067 FF:FF ; 068 FF:60 ; 069 1 pad FF:FF ; 06A FF:7B ; 06B 4 pad FF:5C ; 06C 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:4A ; 070 pad 0 FF:4B ; 071 pad . FF:46 ; 072 pad 2 FF:7D ; 073 pad 5 FF:41 ; 074 pad 6 FF:7C ; 075 pad 8 FF:07 ; 076 escape/cancel FF:56 ; 077 numlock FF:02 ; 078 f11 MARK 01:2B ; 079 pad + FF:47 ; 07A pad 3 FF:42 ; 07B pad - 01:38 ; 07C pad * FF:21 ; 07D pad 9 FF:44 ; 07E scroll lock->OVERTYPE (INSERT) FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:1C ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; ; Table 1: for case where shift keys held down. ; FF:FF ; 000 FF:FF ; 001 f9 FF:FF ; 002 FF:FF ; 003 f5 FF:FF ; 004 f3 FF:FF ; 005 f1 FF:FF ; 006 f2 FF:FF ; 007 f12 BOUND FF:FF ; 008 FF:FF ; 009 f10 FF:FF ; 00A f8 FF:FF ; 00B f6 FF:FF ; 00C f4 FF:FF ; 00D tab FF:5E ; 00E ~ * FF:FF ; 00F FF:FF ; 010 FF:FF ; 011 l alt FF:48 ; 012 l shift * FF:FF ; 013 FF:FF ; 014 l ctrl -> l code FF:FF ; 015 q FF:31 ; 016 ! * FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:FF ; 01A z FF:FF ; 01B s FF:FF ; 01C a FF:FF ; 01D w FF:32 ; 01E @ * FF:FF ; 01F FF:FF ; 020 FF:FF ; 021 c FF:FF ; 022 x FF:FF ; 023 d FF:FF ; 024 e FF:34 ; 025 $ * FF:33 ; 026 # * FF:FF ; 027 FF:FF ; 028 FF:FF ; 029 space FF:FF ; 02A v FF:FF ; 02B f FF:FF ; 02C t FF:FF ; 02D r FF:35 ; 02E % * FF:FF ; 02F FF:FF ; 030 FF:FF ; 031 n FF:FF ; 032 b FF:FF ; 033 h FF:FF ; 034 g FF:FF ; 035 y 00:5E ; 036 ^ * FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:FF ; 03A m FF:FF ; 03B j FF:FF ; 03C u FF:37 ; 03D & * FF:38 ; 03E * * FF:FF ; 03F FF:FF ; 040 FF:5B ; 041 < * FF:FF ; 042 k FF:FF ; 043 i FF:FF ; 044 o FF:30 ; 045 ) * FF:39 ; 046 ( * FF:FF ; 047 FF:FF ; 048 FF:5D ; 049 > * FF:2F ; 04A ? * FF:FF ; 04B l FF:3B ; 04C : * FF:FF ; 04D p FF:2D ; 04E _ * FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:27 ; 052 " * FF:FF ; 053 FF:7B ; 054 { * FF:2B ; 055 + * FF:FF ; 056 FF:FF ; 057 FF:45 ; 058 lock -> capslock FF:49 ; 059 r shift * FF:FF ; 05A return FF:7D ; 05B } * FF:FF ; 05C FF:1B ; 05D GO | * (KH WAS | FF:5C) FF:FF ; 05E FF:FF ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 BACKSPACE FF:FF ; 067 FF:FF ; 068 FF:FF ; 069 lc 1 pad FF:FF ; 06A FF:FF ; 06B lc 4 pad FF:FF ; 06C lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:FF ; 070 lc 0 pad FF:FF ; 071 lc . pad FF:FF ; 072 lc 2 pad FF:FF ; 073 lc 5 pad FF:FF ; 074 lc 6 pad FF:FF ; 075 lc 8 pad FF:FF ; 076 escape/cancel FF:FF ; 077 numlock FF:FF ; 078 f11 FF:FF ; 079 numpad + FF:11 ; 07A lc 3 pad ALT+Pg dn **** ALT + E0 7A = scrl dn FF:FF ; 07B numpad - FF:FF ; 07C numpad * FF:13 ; 07D lc 9 pad ALT+Pg up **** ALT + E0 7D = scrl up FF:FF ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:FF ; 083 f7 FF:FF ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; Table 2: for case where ALT keys held down. FF:FF ; 000 FF:FF ; 001 f9 FF:FF ; 002 FF:FF ; 003 f5 FF:FF ; 004 f3 FF:00 ; 005 f1 NOTE ALT+F1 = HELP (K1 ikey 00) * FF:FF ; 006 f2 FF:14 ; 007 f12 ALT+f12 = COPY * FF:FF ; 008 FF:FF ; 009 f10 FF:FF ; 00A f8 FF:FF ; 00B f6 FF:FF ; 00C f4 FF:0D ; 00D ALT+TAB= NEXT * FF:FF ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:53 ; 011 l alt * FF:FF ; 012 l shift E0 + 12 * ABSORB FF:FF ; 013 FF:FF ; 014 l ctrl -> l code FF:FF ; 015 q FF:FF ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:FF ; 01A z FF:FF ; 01B s FF:FF ; 01C a FF:FF ; 01D w FF:FF ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:FF ; 021 c FF:FF ; 022 x FF:FF ; 023 d FF:FF ; 024 e FF:FF ; 025 4 FF:FF ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:FF ; 029 space FF:FF ; 02A v FF:FF ; 02B f FF:FF ; 02C t FF:FF ; 02D r FF:FF ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:FF ; 031 n FF:FF ; 032 b FF:FF ; 033 h FF:FF ; 034 g FF:FF ; 035 y FF:FF ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:FF ; 03A m FF:FF ; 03B j FF:FF ; 03C u FF:FF ; 03D 7 FF:FF ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:FF ; 041 , FF:FF ; 042 k FF:FF ; 043 i FF:FF ; 044 o FF:FF ; 045 0 FF:FF ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:FF ; 049 . FF:FF ; 04A / FF:FF ; 04B l FF:FF ; 04C ; FF:FF ; 04D p FF:FF ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:FF ; 052 ' FF:FF ; 053 FF:FF ; 054 [ FF:FF ; 055 = FF:FF ; 056 FF:FF ; 057 FF:FF ; 058 lock -> capslock FF:FF ; 059 r shift E0 + 59 * ABSORB FF:1B ; 05A ALT-Enter is GO * FF:FF ; 05B ] FF:FF ; 05C 102 key keyboard only 01:7C ; 05D \ (8 \) * ADDED 5/15/93 FF:FF ; 05E FF:FF ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 FF:FF ; 067 FF:FF ; 068 FF:FF ; 069 END lc 1 pad FF:FF ; 06A FF:FF ; 06B l arrow lc 4 pad FF:FF ; 06C HOME lc 7 pad FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:FF ; 070 INSERT lc 0 pad FF:FF ; 071 DEL lc . pad FF:FF ; 072 FF:FF ; 073 5 pad FF:FF ; 074 RT ARR lc 6 pad FF:FF ; 075 FF:FF ; 076 escape/cancel FF:FF ; 077 numlock FF:12 ; 078 f11 ALT+f11 = MOVE * FF:FF ; 079 numpad + FF:47 ; 07A 3 pad * FF:FF ; 07B numpad - FF:FF ; 07C numpad * FF:21 ; 07D 9 pad * FF:FF ; 07E scroll lock/ CTOS mode FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:FF ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key ; ; Table 3: for case where E0 is held down. ; FF:FF ; 000 FF:FF ; 001 f9 FF:FF ; 002 FF:FF ; 003 f5 FF:FF ; 004 f3 FF:FF ; 005 f1 FF:FF ; 006 f2 FF:FF ; 007 f12 FF:FF ; 008 FF:FF ; 009 f10 FF:FF ; 00A f8 FF:FF ; 00B f6 FF:FF ; 00C f4 FF:FF ; 00D tab FF:FF ; 00E l quote (1 `) FF:FF ; 00F FF:FF ; 010 FF:55 ; 011 NOTE: RIGHT ALT * FF:FF ; 012 l shift NOTE: ABSORB IF EXTENDED * FF:FF ; 013 FF:4D ; 014 NOTE: RIGHT CODE * FF:FF ; 015 q FF:FF ; 016 1 FF:FF ; 017 FF:FF ; 018 FF:FF ; 019 FF:FF ; 01A z FF:FF ; 01B s FF:FF ; 01C a FF:FF ; 01D w FF:FF ; 01E 2 FF:FF ; 01F FF:FF ; 020 FF:FF ; 021 c FF:FF ; 022 x FF:FF ; 023 d FF:FF ; 024 e FF:FF ; 025 4 FF:FF ; 026 3 FF:FF ; 027 FF:FF ; 028 FF:FF ; 029 space FF:FF ; 02A v FF:FF ; 02B f FF:FF ; 02C t FF:FF ; 02D r FF:FF ; 02E 5 FF:FF ; 02F FF:FF ; 030 FF:FF ; 031 n FF:FF ; 032 b FF:FF ; 033 h FF:FF ; 034 g FF:FF ; 035 y FF:FF ; 036 6 FF:FF ; 037 FF:FF ; 038 FF:FF ; 039 FF:FF ; 03A m FF:FF ; 03B j FF:FF ; 03C u FF:FF ; 03D 7 FF:FF ; 03E 8 FF:FF ; 03F FF:FF ; 040 FF:FF ; 041 , FF:FF ; 042 k FF:FF ; 043 i FF:FF ; 044 o FF:FF ; 045 0 FF:FF ; 046 9 FF:FF ; 047 FF:FF ; 048 FF:FF ; 049 . FF:FF ; 04A NOTE: numpad / if extended FF:FF ; 04B l FF:FF ; 04C ; FF:FF ; 04D p FF:FF ; 04E - FF:FF ; 04F FF:FF ; 050 FF:FF ; 051 FF:FF ; 052 ' FF:FF ; 053 FF:FF ; 054 [ FF:FF ; 055 = FF:FF ; 056 FF:FF ; 057 FF:FF ; 058 lock -> capslock FF:FF ; 059 r shift NOTE: ABSORB IF EXTENDED * FF:FF ; 05A enter FF:FF ; 05B ] FF:FF ; 05C 102 key keyboard only 01:5C ; 05D | SHIFT+ALT+ \| ADDED 5/15/93 * FF:FF ; 05E FF:5F ; 05F FF:FF ; 060 FF:FF ; 061 102 key keyboard only FF:FF ; 062 FF:FF ; 063 FF:FF ; 064 FF:FF ; 065 FF:FF ; 066 FF:FF ; 067 FF:FF ; 068 FF:04 ; 069 FINISH FF:04 NOTE: END * FF:FF ; 06A FF:0E ; 06B NOTE: LEFT ARROW * FF:43 ; 06C ACTION NOTE: HOME * FF:FF ; 06D FF:FF ; 06E FF:FF ; 06F FF:44 ; 070 NOTE: OVERTYPE * FF:7F ; 071 NOTE: DELETE * FF:0B ; 072 NOTE: DN ARROW * FF:FF ; 073 5 pad FF:0F ; 074 NOTE: RT ARROW * FF:01 ; 075 NOTE: UP ARROW * FF:FF ; 076 escape/cancel FF:FF ; 077 numlock FF:FF ; 078 f11 FF:FF ; 079 numpad + FF:0C ; 07A NOTE: PG DN / NEXT PAGE * FF:FF ; 07B numpad - FF:57 ; 07C NOTE: SYSTEM * FF:05 ; 07D NOTE: PG UP / PREV PAGE * FF:FF ; 07E FF:FF ; 07F FF:FF ; 080 FF:FF ; 081 FF:FF ; 082 FF:FF ; 083 f7 FF:57 ; 084 alt+print screen = sysrq on PC kbd SYSTEM key END TABLES ; The preceeding string is NOT a comment. ; It must be in the file even if no ; emulation tables are included. START HOT KEYS TABLE 0 { 0 } { 0 } { 0 } ; 000 0 { 0 } { 0 } { 0 } ; 001 f9 0 { 0 } { 0 } { 0 } ; 002 FAKE GO KEY 0 { 0 } { 0 } { 0 } ; 003 f5 0 { 0 } { 0 } { 0 } ; 004 f3 0 { 0 } { 0 } { 0 } ; 005 f1 0 { 0 } { 0 } { 0 } ; 006 f2 0 { 0 } { 0 } { 0 } ; 007 f12 BOUND 0 { 0 } { 0 } { 0 } ; 008 0 { 0 } { 0 } { 0 } ; 009 f10 0 { 0 } { 0 } { 0 } ; 00A f8 0 { 0 } { 0 } { 0 } ; 00B f6 0 { 0 } { 0 } { 0 } ; 00C f4 0 { 0 } { 0 } { 0 } ; 00D tab 0 { 0 } { 0 } { 0 } ; 00E l quote (1 `) 0 { 0 } { 0 } { 0 } ; 00F 0 { 0 } { 0 } { 0 } ; 010 0 { 0 } { 0 } { 0 } ; 011 l alt 0 { 0 } { 0 } { 0 } ; 012 l shift 0 { 0 } { 0 } { 0 } ; 013 0 { 0 } { 0 } { 0 } ; 014 l ctrl -> l code 0 { 0 } { 0 } { 0 } ; 015 q 0 { 0 } { 0 } { 0 } ; 016 1 0 { 0 } { 0 } { 0 } ; 017 0 { 0 } { 0 } { 0 } ; 018 0 { 0 } { 0 } { 0 } ; 019 0 { 0 } { 0 } { 0 } ; 01A z 0 { 0 } { 0 } { 0 } ; 01B s 0 { 0 } { 0 } { 0 } ; 01C a 0 { 0 } { 0 } { 0 } ; 01D w 0 { 0 } { 0 } { 0 } ; 01E 2 0 { 0 } { 0 } { 0 } ; 01F 0 { 0 } { 0 } { 0 } ; 020 0 { 0 } { 0 } { 0 } ; 021 c 0 { 0 } { 0 } { 0 } ; 022 x 0 { 0 } { 0 } { 0 } ; 023 d 0 { 0 } { 0 } { 0 } ; 024 e 0 { 0 } { 0 } { 0 } ; 025 4 0 { 0 } { 0 } { 0 } ; 026 3 0 { 0 } { 0 } { 0 } ; 027 0 { 0 } { 0 } { 0 } ; 028 0 { 0 } { 0 } { 0 } ; 029 space 0 { 0 } { 0 } { 0 } ; 02A v 0 { 0 } { 0 } { 0 } ; 02B f 0 { 0 } { 0 } { 0 } ; 02C t 0 { 0 } { 0 } { 0 } ; 02D r 0 { 0 } { 0 } { 0 } ; 02E 5 0 { 0 } { 0 } { 0 } ; 02F 0 { 0 } { 0 } { 0 } ; 030 0 { 0 } { 0 } { 0 } ; 031 n 0 { 0 } { 0 } { 0 } ; 032 b 0 { 0 } { 0 } { 0 } ; 033 h 0 { 0 } { 0 } { 0 } ; 034 g 0 { 0 } { 0 } { 0 } ; 035 y 0 { 0 } { 0 } { 0 } ; 036 6 0 { 0 } { 0 } { 0 } ; 037 0 { 0 } { 0 } { 0 } ; 038 0 { 0 } { 0 } { 0 } ; 039 0 { 0 } { 0 } { 0 } ; 03A m 0 { 0 } { 0 } { 0 } ; 03B j 0 { 0 } { 0 } { 0 } ; 03C u 0 { 0 } { 0 } { 0 } ; 03D 7 0 { 0 } { 0 } { 0 } ; 03E 8 0 { 0 } { 0 } { 0 } ; 03F 0 { 0 } { 0 } { 0 } ; 040 0 { 0 } { 0 } { 0 } ; 041 , 0 { 0 } { 0 } { 0 } ; 042 k 0 { 0 } { 0 } { 0 } ; 043 i 0 { 0 } { 0 } { 0 } ; 044 o 0 { 0 } { 0 } { 0 } ; 045 0 0 { 0 } { 0 } { 0 } ; 046 9 0 { 0 } { 0 } { 0 } ; 047 0 { 0 } { 0 } { 0 } ; 048 0 { 0 } { 0 } { 0 } ; 049 . 0 { 0 } { 0 } { 0 } ; 04A / 0 { 0 } { 0 } { 0 } ; 04B l 0 { 0 } { 0 } { 0 } ; 04C ; 0 { 0 } { 0 } { 0 } ; 04D p 0 { 0 } { 0 } { 0 } ; 04E - 0 { 0 } { 0 } { 0 } ; 04F 0 { 0 } { 0 } { 0 } ; 050 0 { 0 } { 0 } { 0 } ; 051 0 { 0 } { 0 } { 0 } ; 052 ' 0 { 0 } { 0 } { 0 } ; 053 0 { 0 } { 0 } { 0 } ; 054 [ 0 { 0 } { 0 } { 0 } ; 055 = 0 { 0 } { 0 } { 0 } ; 056 0 { 0 } { 0 } { 0 } ; 057 0 { 0 } { 0 } { 0 } ; 058 lock -> capslock 0 { 0 } { 0 } { 0 } ; 059 r shift 0 { 0 } { 0 } { 0 } ; 05A return 0 { 0 } { 0 } { 0 } ; 05B ] 0 { 0 } { 0 } { 0 } ; 05C 102 key keyboard only 0 { 0 } { 0 } { 0 } ; 05D \ (8 \) 0 { 0 } { 0 } { 0 } ; 05E 0 { 0 } { 0 } { 0 } ; 05F borrowed for pause 0 { 0 } { 0 } { 0 } ; 060 0 { 0 } { 0 } { 0 } ; 061 102 key keyboard only 0 { 0 } { 0 } { 0 } ; 062 0 { 0 } { 0 } { 0 } ; 063 0 { 0 } { 0 } { 0 } ; 064 0 { 0 } { 0 } { 0 } ; 065 0 { 0 } { 0 } { 0 } ; 066 0 { 0 } { 0 } { 0 } ; 067 0 { 0 } { 0 } { 0 } ; 068 0 { 0 } { 0 } { 0 } ; 069 END FINISH 0 { 0 } { 0 } { 0 } ; 06A 0 { 0 } { 0 } { 0 } ; 06B l arrow 0 { 0 } { 0 } { 0 } ; 06C HOME ACTION 0 { 0 } { 0 } { 0 } ; 06D 0 { 0 } { 0 } { 0 } ; 06E 0 { 0 } { 0 } { 0 } ; 06F 0 { 0 } { 0 } { 0 } ; 070 INSERT 0 { 0 } { 0 } { 0 } ; 071 DEL 0 { 0 } { 0 } { 0 } ; 072 DOWN ARR 0 { 0 } { 0 } { 0 } ; 073 (only get 73 with numlock on) 0 { 0 } { 0 } { 0 } ; 074 RT ARR 0 { 0 } { 0 } { 0 } ; 075 UP ARR 0 { 0 } { 0 } { 0 } ; 076 escape/cancel 0 { 0 } { 0 } { 0 } ; 077 numlock 0 { 0 } { 0 } { 0 } ; 078 f11 MARK 0 { 0 } { 0 } { 0 } ; 079 numpad + 0 { 0 } { 0 } { 0 } ; 07A PG DN lc 3 pad 0 { 0 } { 0 } { 0 } ; 07B numpad - 0 { 0 } { 0 } { 0 } ; 07C numpad * 0 { 0 } { 0 } { 0 } ; 07D PG UP lc 9 pad 0 { 0 } { 0 } { 0 } ; 07E scroll lock->OVERTYPE (INSERT) 0 { 0 } { 0 } { 0 } ; 07F 0 { 0 } { 0 } { 0 } ; 080 0 { 0 } { 0 } { 0 } ; 081 0 { 0 } { 0 } { 0 } ; 082 0 { 0 } { 0 } { 0 } ; 083 f7 0 { 0 } { 0 } { 0 } ; 084 alt+print screen = sysrq on PC kbd SYSTEM key END HOT KEYS TABLE :MultiPkgName:Keyboard Tool :MultiPkgName:Keyboard Tables :MultiPkgName:Asynchronous Examples :MultiPkgName:SortMerge Examples :MultiPkgName:DLL Mediator xamples :MultiPkgName:SortMerge Examples :MultiPkgName:DLL Mediator irstDisk = 'Development Utilities Diskette 3 of 3 (B25DUX-3)' FromFloppy = 0 FromServer = 2 ScrSpec = '[Scr]<$>' FloppySpec = ConcatStrings(DeviceFrom, '') ToSpec = ConcatStrings(VolumeTo, DirectoryTo) FromSpec = ConcatStrings(FloppySpec, '*') If Install; KeyboardTool>Install.jcl ; Install the Keyboard Tool subpackage ; Except for yes/no strings, these two messages are the only nationalizable ; strings in this file. ErrorMsg = 'Cannot access message file' FirstDisk = 'Development Utilities Diskette 3 of 3 (B25U22-3)' FromFloppy = 0 FromServer = 2 SysVolume = '[Sys]' SysCmds = '[!Sys]sys.cmds' FloppySpec = ConcatStrings(DeviceFrom, '') ToSpec = ConcatStrings(VolumeTo, DirectoryTo) FromSpec = ConcatStrings(FloppySpec, '*') If InstallType = FromFloppy NextFloppy(FirstDisk) EndIf If Public Command Merge Command Files ,& CmdFileFrom ,& SysCmds ,& Yes ,& SysVolume EndIf Command Merge Command Files ,& CmdFileFrom ,& CmdFileTo ,& Yes ,& VolumeTo If InstallType = FromServer Command LCopy ,& ,& @[Scr]<$>InstallOverwriteOkFrom.fls ,& @[Scr]<$>InstallOverwriteOkTo.fls ,& ,& Yes ,& No ,& No GoTo EndIt Endif Command LCopy ,& FromSpec ,& ,& ToSpec ,& ,& Yes ,& No ,& No RestartLabel EndIt: End ,& SubFromSpec ,& ,& ToSys ,& :l No ,& :PackageName:Keyboard Tool :Version:12.3.1 :RequiredDiskSpace:481 :Directory: :Verify: :Commands: 'Convert Nls.sys' 'Convert Sys.keys' 'Create Keyboard Data Block' :ProductFiles: Kct.run KctMsg.bin Make' 'Resource Librarian' 'Sort Public Procedure Names' 'Wrap' 'Convert Public Case' :ProductFiles:Assembler.run Async.lib Ctos.lib CtosToolKit.lib Enls.lib German_Nls.asm Histogram.run HistogramMsg.bin Librarian.run Linker.run LinkerConfig.sys MakeNls.sub ModuleDefinition.run ModuleDefinitionMsg.bin Mous> Convert Nls.sys Convert Sys.keysCreate Keyboard Data Block22Q@[Sys]Kct.runCreates a new style keyboard table from data in an nls.sys file.Nls.sys file name 11I8[Sys]Kct.runCreates a new style keyboard table from a sys.keys file.Sys.keys file name 00SNB[Sys]Kct.runCreate a new style keyboard table from data in an ASCII text file.[Keyboard datafile name][Output is object module?][Output is binary table?] ; KeyboardTables>Install.jcl ; Install the Keyboard Table Source subpackage ; Except for yes/no strings, these two messages are the only nationalizable ; strings in this file. ErrorMsg = 'Cannot access message file' FirstDisk = 'Development Utilities Diskette 3 of 3 (B25U22-3)' FromFloppy = 0 FromServer = 2 ScrSpec = '[Scr]<$>' FloppySpec = ConcatStrings(DeviceFrom, '') ToSpec = ConcatStrings(VolumeTo, DirectoryTo) FromSpec = ConcatStrings(FloppySpec, '*') If InstallType = FromFloppy NextFloppy(FirstDisk) EndIf If InstallType = FromServer Command LCopy ,& ,& @[Scr]<$>InstallOverwriteOkFrom.fls ,& @[Scr]<$>InstallOverwriteOkTo.fls ,& ,& Yes ,& No ,& No GoTo EndIt Endif Command LCopy ,& FromSpec ,& ,& ToSpec ,& ,& Yes ,& No ,& No RestartLabel EndIt: End GoTo EndIt Endif Command LCopy ,& FromSpec :PackageName:Keyboard Tables :Version:12.3.1 :RequiredDiskSpace:450 :Directory: :Verify: :ProductFiles: k1.kbd_data 21.kbd_data 41.kbd_data 51.kbd_data 61.kbd_data ssk1.kbd_data k0.kbd_data k4nonfin.kbd_data pck1.kbd_data pik1.kbd_data sg1kemul.kbd_data sg1ktrans.kbd_data blic Case' :ProductFiles:Assembler.run Async.lib Ctos.lib CtosToolKit.lib Enls.lib German_Nls.asm Histogram.run HistogramMsg.bin Librarian.run Linker.run LinkerConfig.sys MakeNls.sub ModuleDefinition.run ModuleDefinitionMsg.bin Mous; AsynchronousExamples>Install.jcl ; Install the Asynchronous Examples subpackage ; Except for yes/no strings, these two messages are the only nationalizable ; strings in this file. ErrorMsg = 'Cannot access message file' FirstDisk = 'Development Utilities Diskette 3 of 3 (B25U22-3)' FromFloppy = 0 FromServer = 2 FloppySpec = ConcatStrings(DeviceFrom, '') ToSpec = ConcatStrings(VolumeTo, DirectoryTo) FromSpec = ConcatStrings(FloppySpec, '*') If InstallType = FromFloppy NextFloppy(FirstDisk) EndIf Command Create Directory ,& ToSpec If InstallType = FromServer Command LCopy ,& ,& @[Scr]<$>InstallOverwriteOkFrom.fls ,& @[Scr]<$>InstallOverwriteOkTo.fls ,& ,& Yes ,& No ,& No GoTo EndIt Endif Command LCopy ,& FromSpec ,& ,& ToSpec ,& ,& Yes ,& No ,& No EndIt: End GoTo EndIt Endif Command LCopy ,& FromSpec :PackageName:Asynchronous Examples :Version:12.3.1 :RequiredDiskSpace:361 :Directory: :Verify: :ProductFiles: Async.h AsyncService.c DeInstall.c Example.c ExDef.h ExFunc.h ExRqblk.h ExRqlabl.asm LinkDeinstall.fls LinkDeinstall.sub LinkExample.fls LinkExample.sub LinkStart.fls LinkStart.sub LinkStop.fls LinkStop.sub ReadMe RequestEx.txt Start.c Stop.c FortranSortExample.sub MrkData MultiRecordKeySct.sub NewRecords OldMaster PascalSortExample.pas PascalSortExample.sub SortMergeSct.sub ionMsg.bin Mous; SortMergeExamples>Install.jcl ; Install the SortMerge Examples subpackage ; Except for yes/no strings, this message is the only nationalizable string ; in this file. ErrorMsg = 'Cannot access message file' FirstDisk = 'Development Utilities Diskette 3 of 3 (B25U22-3)' FromFloppy = 0 FromServer = 2 FloppySpec = ConcatStrings(DeviceFrom, '') ToSpec = ConcatStrings(VolumeTo, DirectoryTo) FromSpec = ConcatStrings(FloppySpec, '*') If InstallType = FromFloppy NextFloppy(FirstDisk) EndIf Command Create Directory ,& ToSpec If InstallType = FromServer Command LCopy ,& ,& @[Scr]<$>InstallOverwriteOkFrom.fls ,& @[Scr]<$>InstallOverwriteOkTo.fls ,& ,& Yes ,& No ,& No GoTo EndIt Endif Command LCopy ,& FromSpec ,& ,& ToSpec ,& ,& Yes ,& No ,& No EndIt: End EndIt: End GoTo EndIt Endif Command LCopy ,& FromSpec :PackageName:SortMerge Examples :Version:12.3.1 :RequiredDiskSpace:298 :Directory: :Verify: :ProductFiles: BasicSortExample.bas BasicSortExample.sub CSortExample.c CSortExample.sub DataFile Files.in FntUtl.idf Fortran86ChkErc.fort86 Fortran86ChkSts.fort86 Fortran86Link.fls Fortran86SortExample.fort86 Fortran86SortExample.sub FortranSortExample.for FortranSortExample.sub MrkData MultiRecordKeySct.sub NewRecords OldMaster PascalSortExample.pas PascalSortExample.sub SortMergeSct.sub ionMsg.bin Mous; DLLMediator>Install.jcl ; Install the DLL Mediator subpackage ; Except for yes/no strings, these two messages are the only nationalizable ; strings in this file. FirstDisk = 'Development Utilities Diskette 3 of 3 (B25U22-3)' FromFloppy = 0 FromServer = 2 FloppySpec = ConcatStrings(DeviceFrom, '') ToSpec = ConcatStrings(VolumeTo, DirectoryTo) FromSpec = ConcatStrings(FloppySpec, '*') If InstallType = FromFloppy NextFloppy(FirstDisk) EndIf Command Create Directory ,& ToSpec If InstallType = FromServer Command LCopy ,& ,& @[Scr]<$>InstallOverwriteOkFrom.fls ,& @[Scr]<$>InstallOverwriteOkTo.fls ,& ,& Yes ,& No ,& No GoTo EndIt Endif Command LCopy ,& FromSpec ,& ,& ToSpec ,& ,& Yes ,& No ,& No EndIt: End 'Memory Required','[Abbreviation]','[Function Key]','[Command Case]','[Volume]','[Directory]','[Prefix]','[Password]','[Node]','[Autostart ordering]','[Needs In:PackageName:DLL Mediator :Version:12.3.1 :RequiredDiskSpace:50 :Directory: :Verify: :ProductFiles:MediatorFirst.asm mediator.asm mediator.def mediator.mdf ata ssk1.kbd_data k0.kbd_data k4nonfin.kbd_data pck1.kbd_data pik1.kbd_data sg1kemul.kbd_data sg1ktrans.kbd_data blic Case' :ProductFiles:Assembler.run Async.lib Ctos.lib CtosToolKit.lib Enls.lib German_Nls.asm Histogram.run HistogramMsg.bin Librarian.run Linker.run LinkerConfig.sys MakeNls.sub ModuleDefinition.run ModuleDefinitionMsg.bin Mous/****************************** INCLUDE HEADER (.H)***************************/ /* */ /* INCLUDE FILE: Async.h */ /* */ /* MACHINE: B20 LANGUAGE: METAWARE C V1.0 OS: BTOS */ /* */ /* DESCRIPTION: Header file for Async.Lib procedures. */ /* */ /* */ /* HISTORY: */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) */ /* */ /* 12/03/89 120E/02 S. Emmons / Removed headers for example functions. */ /* 12/02/89 120E/01 S. Emmons / Changed C typing to CTOS Typing. */ /* */ /* TITLE: BTOS SYSTEM SOFTWARE */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE */ /* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE */ /* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS */ /* CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* */ /* COPYRIGHT (C) 1980, 1989 CONVERGENT INCORPROATED. ALL RIGHTS RESERVED */ /* COPYRIGHT (C) 1980, 1989 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* ************************************************************************* */ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND */ /* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF */ /* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /* */ /*************************** END OF MODULE HEADER ****************************/ pragma Off(List); #c_include pragma Calling_convention(CTOS_CALLING_CONVENTIONS); #if defined(AllocMemoryInit) || defined(All) #undef AllocMemoryInit extern ErcType AllocMemoryInit (Word cb, Pointer ppMemoryRet, FlagType fInit); #endif #if defined(AsyncRequest) || defined(All) #undef AsyncRequest extern ErcType AsyncRequest (Pointer pRq); #endif #if defined(AsyncRequestDirect) || defined(All) #undef AsyncRequestDirect extern ErcType AsyncRequestDirect (Pointer pRq); #endif #if defined(BuildAsyncRequest) || defined(All) #undef BuildAsyncRequest extern ErcType BuildAsyncRequest (); #endif #if defined(BuildAsyncRequestDirect) || defined(All) #undef BuildAsyncRequestDirect extern ErcType BuildAsyncRequestDirect (); #endif #if defined(CheckContextStack) || defined(All) #undef CheckContextStack extern ErcType CheckContextStack (void); #endif #if defined(CreateContext) || defined(All) #undef CreateContext extern ErcType CreateContext (Word sStack, Word userNum); #endif #if defined(DebugTrap) || defined(All) #undef DebugTrap extern void DebugTrap (void); #endif #if defined(HeapAlloc) || defined(All) #undef HeapAlloc extern ErcType HeapAlloc (Word cBytes, Pointer ppMemoryRet); #endif #if defined(HeapFree) || defined(All) #undef HeapFree extern ErcType HeapFree (Pointer pbFree); #endif #if defined(HeapInit) || defined(All) #undef HeapInit extern ErcType HeapInit (Word cb, Pointer pbHeap); #endif #if defined(LogMsgIn) || defined(All) #undef LogMsgIn extern ErcType LogMsgIn (void); #endif #if defined(LogRequest) || defined(All) #undef LogRequest extern ErcType LogRequest (Pointer pRq); #endif #if defined(LogRespond) || defined(All) #undef LogRespond extern ErcType LogRespond (RqHeaderType *pRq); #endif #if defined(ResumeContext) || defined(All) #undef ResumeContext extern ErcType ResumeContext (void); #endif #if defined(SwapContextUser) || defined(All) #undef SwapContextUser extern ErcType SwapContextUser (Word userNum); #endif #if defined(TerminateAllOtherContexts) || defined(All) #undef TerminateAllOtherContexts extern ErcType TerminateAllOtherContexts (Word erc); #endif #if defined(TerminateContext) || defined(All) #undef TerminateContext extern ErcType TerminateContext (void); #endif #if defined(TerminateContextUser) || defined(All) #undef TerminateContextUser extern ErcType TerminateContextUser (Word userNum, Word erc); #endif #undef All pragma Calling_convention(); pragma Pop(List); /******************************* MODULE HEADER *******************************/ /* */ /* FILE: AsyncService.c */ /* */ /* MACHINE: SGen/NGen LANGUAGE: METAWARE C V1.0 OS: CTOS */ /* */ /* DESCRIPTION: Main program of CTOS Asynchronous Service Model */ /* */ /* Uses AsyncService library procedures. */ /* */ /* HISTORY: */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) */ /* */ /* 09/16/92 12.3/00 S. Ahn / Added attribute information */ /* 12/03/89 120E/02 S. Emmons / Moved rgwRqs[], rqwOldExch, and nRqCodes */ /* into this module; Add check, in */ /* HandleRequest (), so that we don't respond*/ /* on forwarded requests. */ /* 12/02/89 120E/01 S. Emmons / Fixed NULL pointer to AllocMemoryInit (); */ /* changed from c typing to CTOS-based naming*/ /* and typing conventions; Changed references*/ /* from server to service; Gratuitous */ /* reformatting. */ /* 2/3/89 TAB Used CTOS_CALLING_CONVENTIONS */ /* 10Nov88 PBC Set PLM calling conventions to _default */ /* 16Sep88 Ken Burgett: change offset parameters to pointer to make */ /* compatible with calling sequence standards for both */ /* PL/M and High-C */ /* 28Jul88 Ken Burgett: built from Jim Frandeen PL/M prototype. */ /* */ /* */ /* Attributes exhibited by this software: (See SSAttributes.doc) */ /* Use attribute levels 0, E, A, S, F, I and 1...9 as decribed. */ /* */ /* VID:~ 0 */ /* FIL:~ 0 */ /* KBD:~ 0 */ /* CLS:~ 0 */ /* KNL:~ 0 */ /* MEM:~ 0 */ /* COM:~ 0 */ /* TIM:~ 0 */ /* PFM:~ 0 */ /* HDW:~ 0 */ /* DSK:~ 0 */ /* DEV:~ 0 */ /* NLS:~ 0 */ /* */ /* TITLE: CTOS SYSTEM SOFTWARE */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE */ /* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE */ /* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS */ /* CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1980, 1989 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED */ /* COPYRIGHT (C) 1980, 1989 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* ************************************************************************* */ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND */ /* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF */ /* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /* */ /*************************** END OF MODULE HEADER ****************************/ /* External Definitions */ #define Syslit #define RqHeaderType #include #define AllocExch #define ChangePriority #define Check #define CheckErc #define ConvertToSys #define ErrorExit #define FatalError #define GetPartitionHandle #define GetUserNumber #define QueryRequestInfo #define ResetStack #define Respond #define ServeRq #define SetPartitionLock #define SetPartitionName #define ShrinkAreaSL #define Wait #include #define FsErc #define RqErc #include #include /* Async.lib Definitions */ #define AllocMemoryInit #define CreateContext #define HeapInit #define LogMsgIn #define LogRespond #define ResumeContext #define TerminateAllOtherContexts #define TerminateContext #include "async.h" #include "exdef.h" pragma Calling_convention(CTOS_CALLING_CONVENTIONS,_DEFAULT); /* External variables provided by async.lib */ extern Pointer pToDeallocate; /* set up by InitAlloc */ extern Word cbFree; /* set up by InitAlloc */ /* External functions, provided by user. */ extern void InitializeServer (void); extern ErcType ServeRequest (void); extern void HandleTimer (void); extern void InitializeTimer (void); /* External Variables, provided by user. */ extern Word cbHeap; /* size of service heap */ extern Word defaultStackSize; /* size of stack allocated per context */ extern Word wOSRel; extern FlagType fConvertToSys; extern FlagType fRespond; extern Word priorityServ; /* process priority of service */ extern char rgbPartitionName[]; /* name of partition */ /* PUBLIC Variables required by the AsyncService procedures: */ Word rgwRqs[10] = { /* request codes served by this service */ rcAbortExample, rcChangeUserNumExample, rcDeinstallExample, rcOpenFile, rcOpenFileLL, rcStartRecord, rcStopRecord, rcSwapExample, rcTerminateExample, rcReOpenFile}; Word nRqCodes = 10; /* number of request codes served */ Word rgwOldExch[10]; /* temp. storage of old exchange values */ ErcType ercAsync; /* The erc from BuildAsyncRequest or BuildAsyncRequestDirect is returned here. */ ExchType exchServ; /* This is the exchange where the service waits in its WaitLoop. This variable is stored in the exchResp field of the Request block that is built by BuildAsyncRequest or BuildAsyncRequestDirect. */ RqHeaderType *pRq; /* pRq points to the current client request. It is set by the service in its WaitLoop by the call to Wait: erc = Wait(exchServ, &pRq); It is saved in the current Context Control Block by BuildAsyncRequest. It is restored by ResumeContext. */ Pointer pZero = 0; Word saveSpBp[2] = {0, 0}; /* storage locations for sp & bp */ Word *pSave; Pointer *pbHeap; /* pointer to allocated heap storage */ void FatalServerError (ErcType erc) { FatalError (erc) /* Kill the system service */; } ErcType DeinstallServer (void) { /* This function is invoked as a result of deinstall request. */ typedef struct { RqHeaderType rqhdr; Word *pPhRet } DeinstallType; ErcType erc; Word i; DeinstallType *prx; RqHeaderType *pRqBlk; prx = (DeinstallType*) pRq; /* Unserve all requests by serving them to the exchange previously served. */ for (i = 0; i < nRqCodes; i++) { erc = ServeRq (rgwRqs[i], rgwOldExch[i]); if (erc != ercOK) FatalServerError (erc); } /* Terminate all contexts except for the current context. */ erc = TerminateAllOtherContexts (ercOK); if (erc != ercOK) FatalServerError (erc); /* Reject all further incoming requests to service's exchange. */ while (erc == ercOK) { erc = Check (exchServ, &pRqBlk); if (erc == ercOK) { pRqBlk->ercRet = ercServiceNotAvail; LogRespond (pRqBlk); erc = Respond (pRqBlk); if (erc != ercOK) FatalServerError(erc); } } /* Return partition handle to calling program so that the calling program can vacate the partition and remove it. */ ercAsync = SetPartitionLock (FALSE); return GetPartitionHandle (&rgbPartitionName, strlen(rgbPartitionName), prx->pPhRet); } /* HandleRequest: The request pointed to by pRq is a new Request or a TRB. Given a request code, call the routine which processes the request. NOTE that this procedure is NOT REENTRANT. After the call to CreateContext, its stack pointer has changed, so it cannot access any local variables on the stack. */ void HandleRequest (void) { if (pRq->rqCode == 0) { /* rqCode = 0 indicates a timer request block */ HandleTimer (); return; } ercAsync = CreateContext (defaultStackSize, pRq->userNum); if (ercAsync == ercOK) { /* Process request in user-supplied function */ pRq->ercRet = ServeRequest (); } else { /* Context could not be started because no heap space */; pRq->ercRet = ercAsync; } if (fRespond) { LogRespond (pRq); ercAsync = Respond (pRq); } fRespond = TRUE; ercAsync = TerminateContext (); /* Only returns if error -- normally calls WaitLoop */ FatalServerError (ercAsync); } void Initialize(void) { /* This function is called to initialize the service. */ Word i; Word userNumServ; pSave = &saveSpBp[0]; /* establish pointer to sp/bp save area */ /* Allocate exchange for service. */ CheckErc (AllocExch (&exchServ)); /* Set process priority of service. */ CheckErc (ChangePriority (priorityServ)); /* Test Requests; */ if (wOSRel < 10) nRqCodes--; for (i = 0; i < nRqCodes; i++) /* Test each request enumerated in rgwRqs[] to verify that it also exists in the Request.sys file read at boot time. */ CheckErc (QueryRequestInfo (rgwRqs[i], &rgwOldExch[i], 2)); /* Allocate memory from DS space to be used for the heap. */ CheckErc (AllocMemoryInit (cbHeap, &pbHeap, FALSE)); CheckErc (HeapInit (cbHeap, pbHeap)); /* Allocate any other memory required for tables, etc from DS space. */ if (cbFree != 0) /* Free leftover memory used by the initialization code. */ CheckErc (ShrinkAreaSL (pToDeallocate, cbFree)); /* Service specific initialization. */ InitializeServer (); /* Initialize Timer Request Block as necessary. */ InitializeTimer (); if (fConvertToSys) CheckErc (ConvertToSys ()); /* Serve Requests */ for (i = 0; i < nRqCodes; i++) { /* Save the exchange previously served for this request so that it can be restored when the service is deinstalled. */ CheckErc (QueryRequestInfo (rgwRqs[i], &rgwOldExch[i], 2)); /* Serve each request code enumerated for this service. */ CheckErc (ServeRq (rgwRqs[i], exchServ)); } /* Call ErrorExit (ercOK) to 'become' part of OS. */ ErrorExit (ercOK); ercAsync = GetUserNumber (&userNumServ); /* SetPartitionName must come after ConvertToSys. */ ercAsync = SetPartitionName ((userNumServ & 0xFF), &rgbPartitionName, strlen (rgbPartitionName)); } /* WaitLoop: Main process loop. It waits for a request or a response to come in. */ void WaitLoop (void) { ErcType erc; erc = ResetStack (offsetof (pSave)); FOREVER { erc = Wait (exchServ, &pRq); LogMsgIn (); if (erc == ercOK) { /* If the response exchange in the request block equals this service's service exchange, then the request was sent by this service. If the request code is 0, then the request is a timer request block. */ if ((pRq->exchResp == exchServ) && (pRq->rqCode != 0)) /* The request in rq is a response to an asynchronous request that we created and sent out. Handle the response. */ erc = ResumeContext (); /* Only returns if error was detected. */ else /* We have a new Request or a Timer Request Block. */ HandleRequest (); } if (erc != ercOK) FatalServerError (erc); } } void AsyncServer (void) { Initialize (); WaitLoop (); } /******************************* MODULE HEADER *******************************/ /* */ /* FILE: DeInstall.c */ /* */ /* MACHINE: NGen/Sgen LANGUAGE: METAWARE C V1.0 OS: CTOS */ /* */ /* DESCRIPTION: Deinstalls example service. */ /* */ /* */ /* HISTORY: */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) */ /* */ /* 09/16/92 12.3/00 S. Ahn / Added attributes information */ /* 12/03/89 120E/01 S. Emmons / Changed server to service. */ /* */ /* */ /* Attributes exhibited by this software: (See SSAttributes.doc) */ /* Use attribute levels 0, E, A, S, F, I and 1...9 as decribed. */ /* */ /* VID:~ 0 */ /* FIL:~ 0 */ /* KBD:~ 0 */ /* CLS:~ 0 */ /* KNL:~ 0 */ /* MEM:~ 0 */ /* COM:~ 0 */ /* TIM:~ 0 */ /* PFM:~ 0 */ /* HDW:~ 0 */ /* DSK:~ 0 */ /* DEV:~ 0 */ /* NLS:~ 0 */ /* */ /* TITLE: CTOS SYSTEM SOFTWARE */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE */ /* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE */ /* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS */ /* CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1980, 1989 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED */ /* COPYRIGHT (C) 1980, 1989 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* ************************************************************************* */ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND */ /* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF */ /* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /* */ /*************************** END OF MODULE HEADER ****************************/ #define Syslit #include #define CheckErc #define RemovePartition #define VacatePartition #include #define DeinstallExample #include "ExFunc.h" #include /* Program used to remove File Access Recorder service from memory. */ void main (void) { Word PartitionHandle; CheckErc (DeinstallExample (&PartitionHandle)); CheckErc (VacatePartition (PartitionHandle)); CheckErc (RemovePartition (PartitionHandle)); printf ("\nFile Access Recorder removed.\n"); }/******************************* MODULE HEADER *******************************/ /* */ /* FILE: Example.c */ /* */ /* MACHINE: SGen/NGen LANGUAGE: METAWARE C V1.0 OS: CTOS */ /* */ /* DESCRIPTION: */ /* */ /* This service filters File System open requests and records the filenames */ /* and access times in a recording file. The requests are then forwarded */ /* for normal processing. */ /* */ /* The recording file is normally closed and is only opened and written */ /* when an internal buffer fills. */ /* */ /* This is done so that another context can examine the recording file at */ /* any time. */ /* */ /* When a StartRecord request is seen, the recording operation is started. */ /* When a StopRecord request is seen, the recording operation is suspended. */ /* When a DeinstallExample request is seen, this service exits. */ /* */ /* HISTORY: */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) */ /* */ /* 09/16/92 12.3/00 S. Ahn / Added attribute information */ /* 12/03/89 120E/02 S. Emmons / Moved rgwRqs[], rqwOldExch, and nRqCodes */ /* into AsyncService.c; Set protection level */ /* of log file to 15, to override default */ /* protection level of password protected */ /* systems; Gratuitous reformatting. */ /* 12/02/89 120E/01 S. Emmons / Changed c typing to CTOS-based naming and */ /* typing conventions; Changed references */ /* from server to service. */ /* */ /* */ /* Attributes exhibited by this software: (See SSAttributes.doc) */ /* Use attribute levels 0, E, A, S, F, I and 1...9 as decribed. */ /* */ /* VID:~ 0 */ /* FIL:~ 0 */ /* KBD:~ 0 */ /* CLS:~ 0 */ /* KNL:~ 0 */ /* MEM:~ 0 */ /* COM:~ 0 */ /* TIM:~ 0 */ /* PFM:~ 0 */ /* HDW:~ 0 */ /* DSK:~ 0 */ /* DEV:~ 0 */ /* NLS:~ 0 */ /* */ /* TITLE: CTOS SYSTEM SOFTWARE */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE */ /* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE */ /* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS */ /* CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1980, 1989 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED */ /* COPYRIGHT (C) 1980, 1989 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* ************************************************************************* */ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND */ /* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF */ /* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /* */ /*************************** END OF MODULE HEADER ****************************/ /* External definitions. */ #define RqHeaderType #define Syslit #define sdType #define Sublit #define TRBType #include #define ChangeFileLength #define CheckErc #define CloseFile #define CreateFile #define CurrentOsVersion #define ForwardRequest #define GetDateTime #define GetUserNumber #define NlsStdFormatDateTime #define OpenFile #define QueryRequestInfo #define RgParam #define SetFileStatus #include #define FsErc #define RqErc #include #define BuildAsyncRequest #define BuildAsyncRequestDirect #define CheckContextStack #define CreateContext #define DebugTrap #define HeapAlloc #define HeapFree #define SwapContextUser #define TerminateContext #define TerminateContextUser #include "Async.h" #include #include #include #include "ExDef.h" #define All #include "ExRqBlk.h" /* External functions provided by user. */ extern void AsyncServer (void); extern ErcType DeinstallServer (void); extern void FatalServerError (ErcType erc); /* Constants */ #define NDATESIZE 19 #define LF 0x0A #define rcChangeFileLength 13 #define rcGetFileStatus 8 #define rcWrite 36 /* External variables. */ extern RqHeaderType *pRq; extern ErcType ercAsync; extern Pointer pZero; /* Public variables. */ char rgbPartitionName[] = "Example"; char rgbPad[] = " \n"; char rgbMissedFiles[] = "Could not open recording file, records discarded.\n"; Byte bReadWritePro = 15; /* Protection = R/W without password */ FlagType fConvertToSys = TRUE; /* Set to FALSE for debugging */ FlagType fDebug = FALSE; FlagType fRespond = TRUE; Word wOSRel, wOSRev; TRBType TimeRq; /* Timer Request Block */ /* The following variables must be set before main () calls AsyncServer (). If any of these values need to be computed at runtime, do it in InitializeBeforeAsync (). */ Word cbHeap = 6000; /* Total size of heap */ Word defaultStackSize = 1200; /* Stack space for each context */ Word priorityServ = 0x20; /* Process priority of service */ /* Module variables. */ char rgbRecordFile[255]; Word cbRecordFile; char zDefaultRecordFile[] = "[sys]OpenFile.log\0"; Pointer pbBuffer[2]; /* 2 buffer pointers for double buffering */ char Buffer1[1024], Buffer2[1024]; /* buffers for I/O */ Word iActive = 0; /* index of active buffer */ Word iBuf = 0; /* buffer data pointer in active buffer */ char *pWork; /* pointer to data in active buffer */ FlagType fRecording = TRUE; /* recording boolean */ ExchType exchOpenFile, exchOpenFileLL, exchReOpenFile; ErcType AddToBuffer (sdType *pSd) { /* This function is invoked for each open file request seen by this service. The file name and the date/time it was referenced is placed in the current buffer. If there is insufficient space in the buffer, DumpBuffer() is invoked to write the buffer to the recording file. */ ErcType erc; Word len; DWord dateTime; extern ErcType DumpBuffer (void); if (fRecording) { /* If not enough space is left in the buffer for this entry, dump the buffer to the file. */ if (iBuf + pSd->cb + NDATESIZE + 2 > sizeof (Buffer1)) { erc = DumpBuffer (); if (erc != ercOK) { /* Could not open file, try to record event. */ strcpy (pWork, &rgbMissedFiles); pWork += strlen (rgbMissedFiles); iBuf += strlen (rgbMissedFiles); } } /* Get date and time of reference */ erc = GetDateTime (&dateTime); if (erc != ercOK) return (erc); /* Expand it to human-readable form */ erc = NlsStdFormatDateTime (NULL, 16, dateTime, pWork, sizeof (Buffer1) - iBuf, &len); if (erc != ercOK) return (erc); /* Put date stamp and filename in buffer */ pWork += len; iBuf += len; *pWork++ = ' '; iBuf += 1; strncpy (pWork, pSd->pb, pSd->cb); pWork += pSd->cb; iBuf += pSd->cb; *pWork++ = LF; /* add line feed to filename/timestamp */ iBuf += 1; } if (CheckContextStack () != ercOK) { /* defaultStackSize is too small!! */ DebugTrap (); } } ErcType DumpBuffer (void) { /* This function is invoked whenever (1) a buffer fills, (2) recording is turned off, (3) the service is deinstalled. */ Word len; FhType fh; ErcType erc; DWord lfa; Pointer p; /* Space fill between last data and end of buffer */ while (iBuf < sizeof (Buffer1)) { len = sizeof (rgbPad); if (len > (sizeof (Buffer1) - iBuf)) len = sizeof (Buffer1) - iBuf; strncpy (pWork, rgbPad, len); pWork += len; iBuf += len; } --pWork; *pWork++ = LF; /* Assign a new buffer for output. */ p = pbBuffer[iActive]; iActive = (iActive + 1) & 1; pWork = pbBuffer[iActive]; iBuf = 0; /* Open the file in mode modify */ erc = BuildAsyncRequestDirect (&fh, &rgbRecordFile, cbRecordFile, (DWord)0, 0, modeModify, rcOpenFileLL, exchOpenFileLL); if (erc == ercOK) { /* Change the file length */ erc = BuildAsyncRequest (fh, 0, &lfa, 4, rcGetFileStatus); if (erc != ercOK) return (erc); erc = BuildAsyncRequest (fh, lfa + sizeof (Buffer1), rcChangeFileLength); if (erc != ercOK) return (erc); /* Write the data */ erc = BuildAsyncRequest (fh, p, sizeof (Buffer1), lfa, &len, rcWrite); if (erc != ercOK) return (erc); /* Close the file */ erc = BuildAsyncRequest (fh, rcCloseFile); } if (CheckContextStack () != ercOK) { /* defaultStackSize is too small!! */ DebugTrap (); } return (erc); } /* HandleTimer: The request in pRq is a Timer Request Block NOTE that this procedure is NOT REENTRANT. After the call to CreateContext, its stack pointer has changed, so it cannot access any local variables on the stack. */ void HandleTimer (void) { /* The timer is not used in this example. This function is provided only to resolve the external reference made in the Asynchronous Service code. */ ercAsync = CreateContext (defaultStackSize, 0); if (ercAsync != ercOK) { /* Context could not be started because no heap space */ TimeRq.cEvents = 0; /* Re-enable timer */ } else { /* Context started OK. Insert timer processing code here. */ ercAsync = TerminateContext (); /* Only returns if error -- normally calls WaitLoop */ FatalServerError (ercAsync); } } /* Early service initialization, service heap not yet initialized. */ void InitializeBeforeAsync (void) { ErcType erc; FhType fh; sdType sd; /* Process '[Recording file]' parameter */ strcpy (rgbRecordFile, zDefaultRecordFile); cbRecordFile = strlen (zDefaultRecordFile); erc = RgParam (1, 0, &sd) /* log file name */; if (erc == ercOK) { strncpy (&rgbRecordFile[0], sd.pb, sd.cb); cbRecordFile = sd.cb; rgbRecordFile[sd.cb] = 0; } erc = CreateFile (&rgbRecordFile, cbRecordFile, pZero, 0, 1024); CheckErc (OpenFile (&fh, &rgbRecordFile, cbRecordFile, pZero, 0, modeModify)); CheckErc (ChangeFileLength (fh, 0)); CheckErc (SetFileStatus (fh, 2, &bReadWritePro, 1)); CheckErc (CloseFile (fh)); /* Establish array of buffer pointers for double buffering. */ pbBuffer[0] = &Buffer1[0]; pbBuffer[1] = &Buffer2[0]; pWork = pbBuffer[iActive = 0]; /* Get OS Version; ReOpenFile request does not exist on real mode Workstation OS's. */ CheckErc (CurrentOsVersion (&wOSRel, &wOSRev)); /* Save exchange values for forwarding; */ CheckErc (QueryRequestInfo (rcOpenFile, &exchOpenFile, 2)); CheckErc (QueryRequestInfo (rcOpenFileLL, &exchOpenFileLL, 2)); if (wOSRel >= 10) CheckErc (QueryRequestInfo (rcReOpenFile, &exchReOpenFile, 2)); /* Output sign-on message */ printf ("\nFile Access Recorder installed.\n"); } /* Service-specific initialization, called before ConvertToSys. The Service Heap is initialized. */ void InitializeServer (void) { /* No additional initialization is required by this example. */ } /* Timer initialization, called before ConvertToSys. The Service Heap is initialized. */ void InitializeTimer (void) { /* Timer unused in this example. This function is provided to satisfy external reference made by the Asynchronous Service code. */ } /* Service-specific request processing procedure. */ ErcType ServeRequest (void) { ErcType erc, ercDiscard; sdType sd; switch (pRq->rqCode) { case rcAbortExample: { AbortExampleType *prx; prx = (AbortExampleType *) pRq; erc = TerminateContextUser (prx->rqhdr.userNum, ercOK); break; } case rcChangeUserNumExample: { ChangeUserNumExampleType *prx; prx = (ChangeUserNumExampleType *) pRq; break; } case rcDeinstallExample: { DeinstallExampleType *prx; prx = (DeinstallExampleType *) pRq; erc = DumpBuffer (); fRecording = FALSE; DeinstallServer (); break; } case rcOpenFile: { OpenFileType *prx; prx = (OpenFileType *) pRq; sd.cb = prx->cbFileSpec; erc = HeapAlloc (sd.cb, &sd.pb); if (erc == ercOK) strncpy (sd.pb, prx->pbFileSpec, sd.cb); ercDiscard = ForwardRequest (exchOpenFile, pRq); if (erc == ercOK) { ercDiscard = AddToBuffer (&sd); ercDiscard = HeapFree (sd.pb); } fRespond = FALSE; break; } case rcOpenFileLL: { OpenFileLLType *prx; prx = (OpenFileLLType *) pRq; sd.cb = prx->cbFileSpec; erc = HeapAlloc (sd.cb, &sd.pb); if (erc == ercOK) strncpy(sd.pb, prx->pbFileSpec, sd.cb); ercDiscard = ForwardRequest (exchOpenFileLL, pRq); if (erc == ercOK) { ercDiscard = AddToBuffer (&sd); ercDiscard = HeapFree (sd.pb); } fRespond = FALSE; break; } case rcReOpenFile: { ReOpenFileType *prx; prx = (ReOpenFileType *) pRq; sd.cb = prx->cbFileSpec; erc = HeapAlloc (sd.cb, &sd.pb); if (erc == ercOK) strncpy (sd.pb, prx->pbFileSpec, sd.cb); ercDiscard = ForwardRequest (exchReOpenFile, pRq); if (erc == ercOK) { ercDiscard = AddToBuffer (&sd); ercDiscard = HeapFree (sd.pb); } fRespond = FALSE; break; } case rcStartRecord: { StartRecordType *prx; prx = (StartRecordType *) pRq; fRecording = TRUE; break; } case rcStopRecord: { StopRecordType *prx; prx = (StopRecordType *) pRq; erc = DumpBuffer (); fRecording = FALSE; break; } case rcSwapExample: { SwapExampleType *prx; prx = (SwapExampleType *) pRq; erc = SwapContextUser (prx->rqhdr.userNum); break; } case rcTerminateExample: { TerminateExampleType *prx; prx = (TerminateExampleType *) pRq; erc = TerminateContextUser (prx->rqhdr.userNum, ercOK); break; } DEFAULT: { /* unrecognized request code */ return (ercNoSuchRc); } } return (ercOK); } /* Main program. */ void main (void) { InitializeBeforeAsync (); AsyncServer (); } /* File exdef.h, Oct 13, 1988, 12:34:03 */ #define rcAbortExample 16898 #define rcChangeUserNumExample 16899 #define rcDeinstallExample 16897 #define rcStopRecord 16896 #define rcOpenFile 4 #define rcCloseFile 10 #define rcOpenFileLL 97 #define rcReOpenFile 294 #define rcStartRecord 16902 #define rcSwapExample 16900 #define rcTerminateExample 16901 /****************************** INCLUDE HEADER (.H)***************************/ /* */ /* INCLUDE FILE: Name.h */ /* */ /* MACHINE: B20 LANGUAGE: METAWARE C V1.0 OS: BTOS */ /* */ /* DESCRIPTION: Header for example functions. */ /* */ /* HISTORY: */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) */ /* */ /* 12/03/89 120E/01 S. Emmons / Changed C typing to CTOS-based typing. */ /* */ /* */ /* TITLE: BTOS SYSTEM SOFTWARE */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE */ /* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE */ /* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS */ /* CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* */ /* COPYRIGHT (C) 1980, 1989 CONVERGENT INCORPROATED. ALL RIGHTS RESERVED */ /* COPYRIGHT (C) 1980, 1989 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* ************************************************************************* */ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND */ /* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF */ /* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /* */ /*************************** END OF MODULE HEADER ****************************/ pragma Off(List); #c_include pragma Calling_convention(CTOS_CALLING_CONVENTIONS); #if defined(AbortExample) || defined(All) #undef AbortExample extern ErcType AbortExample (Word wErc); #endif #if defined(ChangeUserNumExample) || defined(All) #undef ChangeUserNumExample extern ErcType ChangeUserNumExample (Word wOldUserNum); #endif #if defined(DeinstallExample) || defined(All) #undef DeinstallExample extern ErcType DeinstallExample (Word *pPhRet); #endif #if defined(StartRecord) || defined(All) #undef StartRecord extern ErcType StartRecord (void); #endif #if defined(StopRecord) || defined(All) #undef StopRecord extern ErcType StopRecord (void); #endif #if defined(SwapExample) || defined(All) #undef SwapExample extern ErcType SwapExample (Word wErc); #endif #if defined(TerminateExample) || defined(All) #undef TerminateExample extern ErcType TerminateExample (Word wErc); #endif #undef All pragma Calling_convention(); pragma Pop(List); /****************************** INCLUDE HEADER (.H)***************************/ /* */ /* INCLUDE FILE: ExRqBlk.h */ /* */ /* MACHINE: B20 LANGUAGE: METAWARE C V1.0 OS: BTOS */ /* */ /* DESCRIPTION: Header for procedural interface definitions of example Rqs. */ /* */ /* */ /* HISTORY: */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) */ /* */ /* 12/03/89 120E/01 S. Emmons / Changed C typing to CTOS-based typing. */ /* */ /* */ /* TITLE: BTOS SYSTEM SOFTWARE */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE */ /* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE */ /* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS */ /* CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* */ /* COPYRIGHT (C) 1980, 1989 CONVERGENT INCORPROATED. ALL RIGHTS RESERVED */ /* COPYRIGHT (C) 1980, 1989 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* ************************************************************************* */ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND */ /* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF */ /* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /* */ /*************************** END OF MODULE HEADER ****************************/ #if defined(AbortExampleType) || defined(All) #undef AbortExampleType typedef struct { RqHeaderType rqhdr; Word wErc } AbortExampleType; #endif #if defined(ChangeUserNumExampleType) || defined(All) #undef ChangeUserNumExampleType typedef struct { RqHeaderType rqhdr; Word wOldUserNum } ChangeUserNumExampleType; #endif #if defined(DeinstallExampleType) || defined(All) #undef DeinstallExampleType typedef struct { RqHeaderType rqhdr; Word *pPhRet; Word sPhMax } DeinstallExampleType; #endif #if defined(OpenFileType) || defined(All) #undef OpenFileType typedef struct { RqHeaderType rqhdr; Byte res12[2]; Word mode; Byte res16[2]; Pointer pbFileSpec; Word cbFileSpec; Pointer pbPassword; Word cbPassword; Pointer pFhRet; Word sFhMax } OpenFileType; #endif #if defined(OpenFileLLType) || defined(All) #undef OpenFileLLType typedef struct { RqHeaderType rqhdr; Byte res12[2]; Word mode; Byte res16[2]; Pointer pbFileSpec; Word cbFileSpec; Pointer pbPassword; Word cbPassword; Pointer pFhRet; Word sFhMax } OpenFileLLType; #endif #if defined(ReOpenFileType) || defined(All) #undef ReOpenFileType typedef struct { RqHeaderType rqhdr; Byte res12[2]; Word mode; Byte res16[2]; Pointer pbFileSpec; Word cbFileSpec; Pointer pbPassword; Word cbPassword; Pointer pFhRet; Word sFhMax } ReOpenFileType; #endif #if defined(StartRecordType) || defined(All) #undef StartRecordType typedef struct { RqHeaderType rqhdr } StartRecordType; #endif #if defined(StopRecordType) || defined(All) #undef StopRecordType typedef struct { RqHeaderType rqhdr } StopRecordType; #endif #if defined(SwapExampleType) || defined(All) #undef SwapExampleType typedef struct { RqHeaderType rqhdr; Word wErc } SwapExampleType; #endif #if defined(TerminateExampleType) || defined(All) #undef TerminateExampleType typedef struct { RqHeaderType rqhdr; Word wErc } TerminateExampleType; #endif #undef All ;******************************* MODULE HEADER *******************************; ;* *; ;* FILE: ExRqLabl.asm *; ;* *; ;* MACHINE: NGen/SGen LANGUAGE: ASSEMBLER OS: CTOS *; ;* *; ;* DESCRIPTION: *; ;* *; ;* examples of request codes *; ;* *; ;* *; ;* *; ;* HISTORY: *; ;* *; ;* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) *; ;* *; ;* 09/16/92 123A00 S. Ahn / Added header and attribution information *; ;* *; ;* *; ;* Attributes exhibited by this software: (See SSAttributes.doc) *; ;* Use attribute levels 0, E, A, S, F, I and 1...9 as decribed. *; ;* *; ;* VID:~ 0 *; ;* FIL:~ 0 *; ;* KBD:~ 0 *; ;* CLS:~ 0 *; ;* KNL:~ 0 *; ;* MEM:~ 0 *; ;* COM:~ 0 *; ;* TIM:~ 0 *; ;* PFM:~ 0 *; ;* HDW:~ 0 *; ;* DSK:~ 0 *; ;* DEV:~ 0 *; ;* NLS:~ 0 *; ;* *; ;* TITLE: CTOS SYSTEM SOFTWARE *; ;* *; ;* PROPRIETARY PROGRAM MATERIAL *; ;* *; ;* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE *; ;* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE *; ;* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS *; ;* CORPORATION, DETROIT, MICHIGAN 48232, USA. *; ;* *; ;* COPYRIGHT (C) 1980, 1993 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED *; ;* COPYRIGHT (C) 1980, 1993 UNISYS CORPORATION. ALL RIGHTS RESERVED *; ;* ************************************************************************* *; ;* *; ;* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND *; ;* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, *; ;* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY *; ;* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF *; ;* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO *; ;* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. *; ;* *; ;* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE *; ;* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE *; ;* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. *; ;* *; ;* *; ;*************************** END OF MODULE HEADER ****************************; $INCLUDE([sys]RqLabl.mdf) %RqName(4202H, "AbortExample") %RqName(4203H, "ChangeUserNumExample") %RqName(4201H, "DeinstallExample") %RqName(4200H, "StopRecord") %RqName(4206H, "StartRecord") %RqName(4204H, "SwapExample") %RqName(4205H, "TerminateExample") END Deinstall.obj ExRqLabl.obj [Sys]Ctos.lib(OsSub)Link V6 %'Object modules ' @linkDeinstall.fls %'Run file ' Deinstall.run %'[Map file] ' %'[Publics?] ' %'[Line numbers?] ' %'[Stack size] ' %'[Max array, data, code]' 0 0 %'[Min array, data, code]' 0 0 %'[Run file mode] ' Protected %'[Version] ' %0 %'[Libraries] ' [sys]hcbe.lib @[Sys]ENLSLib.fls %'[DS allocation?] ' yes %'[Symbol file] ' %'[Copyright notice?] ' Yes %'[File to append] ' legalese %'[Linker config file] 'ys]Async.lib(InitAlloc LogAsync) Asyncservice.obj Example.obj [Sys]Ctos.lib(OsSub) %' Copy %' '[Kbd] %' '[Sys]<$>LinkExampleLib.fls %' 'Yes ys]hcbe.lib [Sys]Async.lib Append %' '[Sys]ENLSLib.fls %' '[Sys]<$>LinkExampleLib.fls Link V6 %'Object modules ' @LinkExample.fls %'Run file ' Example.run %'[Map file] ' %'[Publics?] ' %'[Line numbers?] ' %'[Stack size] ' %'[Max array, data, code]' 0 0 %'[Min array, data, code]' 0 0 %'[Run file mode] ' Protected %'[Version] ' '%0' %'[Libraries] ' @[Sys]<$>LinkExampleLib.fls %'[DS allocation?] ' yes %'[Symbol file] ' %'[Copyright notice?] ' Yes %'[File to append] ' legalese %'[Linker config file] 'Start.obj ExRqLabl.obj [Sys]Ctos.lib(OsSub)Link V6 %'Object modules ' @linkStart.fls %'Run file ' Start.run %'[Map file] ' %'[Publics?] ' %'[Line numbers?] ' %'[Stack size] ' %'[Max array, data, code]' 0 0 %'[Min array, data, code]' 0 0 %'[Run file mode] ' Protected %'[Version] ' %0 %'[Libraries] ' [Sys]hcbe.lib @[Sys]ENLSLib.fls %'[DS allocation?] ' yes %'[Symbol file] ' %'[Copyright notice?] ' Yes %'[File to append] ' legalese %'[Linker config file] 'Stop.obj ExRqLabl.obj [Sys]Ctos.lib(OsSub)Link V6 %'Object modules ' @linkStop.fls %'Run file ' Stop.run %'[Map file] ' %'[Publics?] ' %'[Line numbers?] ' %'[Stack size] ' %'[Max array, data, code]' 0 0 %'[Min array, data, code]' 0 0 %'[Run file mode] ' Protected %'[Version] ' %0 %'[Libraries] ' [Sys]hcbe.lib @[Sys]ENLSLib.fls %'[DS allocation?] ' yes %'[Symbol file] ' %'[Copyright notice?] ' Yes %'[File to append] ' legalese %'[Linker config file] ' A Model for Asynchronous Request Processing and Dynamic Memory Management for CTOS System Services Jim Frandeen date Introduction 3 Synchronous Versus Asynchronous 3 The Synchronous Server Model 3 The Asynchronous Server Model 4 The Asynchronous Request Interface 4 BuildAsyncRequest 5 BuildAsyncRequestDirect 5 Passing a Variable Length Parameter List in PL/M 5 Asynchronous Request Error Conditions 7 AsyncRequest 7 AsyncRequestDirect 7 Contexts 8 CreateContext 8 ResumeContext 9 TerminateContext 9 WaitLoop 10 CheckContextStack 10 Other Ways to Use Contexts 10 Handling System Requests 11 Termination and Abort Requests 11 SwapContextUser 12 Deinstallation 14 Memory Management 14 DS Allocation 14 COED Modules 15 AllocMemoryInit 16 Freeing Leftover Memory 16 HeapInit 17 HeapAlloc 17 HeapFree 18 Other Ways to Use the Heap Procedures 18 Using the AsyncServer Library Procedures 18 Debugging Aids 18 Contents of the AsyncServer Release Diskette 19 Restrictions 20 System Software Compatibility 20 Resource Requirements 20 AsyncServer Statistics 21 Error Code Summary 22 Server Program Example 23 Introduction You have probably experienced the following kind of frustration while waiting your turn at a supermarket checkout counter. The person in front of you is writing a check, and you think the wait will be short. But the clerk must call the manager to approve the check. The manager is busy with another customer. Since you are only buying a pint of ice cream, you wish the clerk would use this idle time to handle your purchase. The clerk explains that he can only process one transaction at a time. The minutes drag by. The clerk idly jingles change in the cash drawer. The manager seems to be on hold. As your ice cream begins to melt, you wonder if there isn't a better way. Unfortunately, most servers are designed along the lines of the supermarket checkout counter. The clerk (server) in this example is blocked at his default response exchange waiting for a synchronous request. This paper presents an alternative model for supermarkets and CTOS servers. In this model the server uses a new request interface to send asynchronous requests. When the server is not working, it is waiting at its service exchange, either for a new request or for a response to a request that it sent out. Synchronous Versus Asynchronous We conisder two models of execution. In the synchronous model, the server blocks each time it sends a request. In the asynchronous model, the server does not wait for a request to come back. The Synchronous Server Model The usual model of execution for a system service is the following: DO FOREVER; erc = Wait(exchServ, @pRq); erc = ProcessRequest; rq.ErcRet = erc; erc = Respond(pRq); END; In this model the server waits for a request at its exchange. When it receives a request, it processes it, responds to the client, and goes back to the top of the loop to wait for the next request. All the work is done by the procedure called ProcessRequest. In some cases, there is very little work to be done, and the server can respond to the client immediately. In other cases, the server may need to send requests of its own. In a simple example, the server may need to send a Read request to the operating system. In a more complicated example, the server may need to send an entire document to a device driver. In either case, when the server is waiting for a synchronous request, it cannot process new requests that arrive at its service exchange. The problem is that the server spends time waiting for synchronous requests at its default response exchange when it could be doing useful work. This is the problem we wish to solve with a different model of execution.} {The Asynchronous Server Model In the asynchronous server model, the server rarely if ever sends synchronous requests. When the server sends a request, it always goes back to the top of its wait loop to wait for either a new request or a response to a request that it sent out. DO FOREVER; erc = Wait(exchServ, @pRq); IF rq.exchResp = exchServ THEN CALL ProcessResponse; ELSE DO; erc = ProcessRequest; rq.ercRet = erc; erc = Respond(pRq); END; END;} {The Asynchronous Request Interface This section describes a set of library procedures that make it easy to create an asynchronous server or even to convert an existing synchronous server to the new model. The beauty of the synchronous procedural interface is that it is easy to use. The user invokes the procedural interface by coding a procedure call of the form: erc = RequestName(arg0, arg1,...,argn-1); The procedural interface builds a request block on the stack using the parameters passed and a set of tables in the OS addressed by the name of the request. The procedural interface then sends the request, waits for a response at the default response exchange, removes the request block from the stack, and continues program execution. Ideally, we would like for the asynchronous procedural interface to be as easy to use. The following are desiderata for the library routines to be defined. 1. We need an easy way to build a request block, send it to the OS to be processed, and jump to the top of our wait loop. 2. When a response to a request comes back, we need an easy way to continue execution where we left off when the asynchronous request was sent.} {BuildAsyncRequest The procedure BuildAsyncRequest works very much like the synchronous procedural interface. It builds a request block on the stack using the arguments passed by the user. It uses tables in the OS necessary to build the request block. When the request block has been built, it is sent to the operating system via the Request primitive. This is where the similarity ends. Instead of waiting at the user's default response exchange for the request to come back, the asynchronous procedural interface saves the state of the context that is running so that it can be restored later, and then jumps to the top of the user's wait loop to wait for the next request or a response to an asynchronous request that was sent out. The details of starting and resuming a context are discussed later. In C, the user invokes the asynchronous procedural interface by coding a procedure call of the form: erc = BuildAsyncRequest(arg0, arg1,...,argn-1, rcRequestName); where the last parameter is the request code. The other parameters are the same as in the synchronous procedural interface. Passing a variable length parameter list in PL/M will be described below.} {BuildAsyncRequestDirect Servers often need to send a request to a specified exchange. The procedure BuildAsyncRequestDirect works just like BuildAsyncRequest, but it takes one more parameter -- the target exchange. For example: erc = BuildAsyncRequestDirect(arg0, arg1,...,argn-1, rcRequestName, exchTarget);} {Passing a Variable Length Parameter List in PL/M In PL/M, there is only one way to call a procedure and pass a variable number of parameters -- by using an indirect procedure call through a POINTER variable: DECLARE procBuildAsyncRequest POINTER EXTERNAL; DECLARE ercAsync ErcType EXTERNAL; CALL procBuildAsyncRequest(arg0, arg1,...,argn-1, rcRequestName); erc = ercAsync; In PL/M, a procedure called indirectly may not return a value. For this reason, the erc is returned in the global variable ercAsync.} {There is another problem with using an indirect procedure call -- the compiler does not perform any type conversion of parameters. The problem occurs when literals appear in the parameter list because the compiler does not know how to convert them. Consider the following example of a call to OpenFile. To use the synchronous procedural interface, the user might code: erc = OpenFile(@fh, @rgbFileName, cbFileName, 0, 0, modeRead); In this example, the first 0 represents a pointer value (pbPassword), and the second 0 represents a word value (cbPassword). The compiler knows this because the procedure OpenFile has been explicitly declared. To use the asynchronous procedural interface, the user might code (erroneously): CALL procBuildAsyncRequest(@fh, @rgbFileName, cbFileName, 0, 0, modeRead, rcOpenFile); erc = ercAsync; In this case, the compiler does not know how to convert the 0 values, so it pushes a byte value in each case. Needless to say, this will not work. There are several ways around this problem.} {WORD values The easiest way to explicitly call for a word value is to use the INT function. INT(0) will cause a word value to be pushed on the stack. Note that the last parameter passed to BuildAsyncRequest (the request code) must be a word value. For example: DECLARE rcOpenFile LITERALLY 'INT(4)'; POINTER values The easiest way to generate a zero pointer value is to declare a pointer variable with a value of zero and use it everywhere: DECLARE pZero POINTER INITIAL(0); CALL procBuildAsyncRequest(@fh, @rgbFileName, cbFileName, pZero, INT(0), modeRead, rcOpenFile); erc = ercAsync; The problem of passing a zero pointer occurs in C as well as in PL/M. The importance of carefully checking the validity of the variable length parameter list cannot be overemphasized. If the number and type of arguments passed is not correct, the calling program will die a horrible death.} {Asynchronous Request Error Conditions The asynchronous request interface has two interesting error codes. 1. ercStackOverflow (4531) is returned if the the stack has overflowed or if the request block to be built would cause the stack to overflow. The global oCCB always points to the Context Control Block, and the stack starts at the bottom of the CCB, so it is a simple matter to test for stack overflow. When the test is made to assure that the request block will fit, all the overhead is included in the calculation, including 64 bytes that would be used to handle an interrupt. The problem of stack overflow can be avoided by allocating more stack space to a context (see the section of Context creation). 2. ercNoSuchRc (31) is returned if the request code passed as the last parameter cannot be found in the OS tables. This is a serious problem because the asynchronous request interface does not know how many words to remove from the stack before it returns. Control is returned to the caller, but program execution is rather unpredictable at this point since the state of the stack pointer is not valid.} {AsyncRequest Two more procedures are provided for users who wish to build their own request blocks. The procedure AsyncRequest uses the Request primitive to send a request block and then jumps to the user's wait loop. When the request block comes back, the Resume operation will cause execution to continue at the next statement. erc = AsyncRequest(exch, pRq); AsyncRequestDirect The procedure AsyncRequest uses the RequestDirect primitive to send a request block to a specified exchange and then jumps to the user's wait loop. When the request block comes back, the Resume operation will cause execution to continue at the next statement. erc = AsyncRequestDirect(exch, pRq);} {Contexts This section describes how contexts are used with the asynchronous server. We define a context as an instance of program execution along with all its local variables. Local variables are variables allocated on the stack. In this sense, a context is very much like a CTOS process. The difference is that a context may be created and terminated easily. When the server receives a request, a context will be created to handle the request. When the server finishes processing the request, the context will be terminated, and any memory allocated to the context will be returned to the heap. When a server sends a request of its own, the state of the context will be saved so that it can be restored when the request comes back. CreateContext The procedure CreateContext allocates stack space for a context from a heap. The heap will be described later. The user codes: erc = CreateContext(stackSize, userNum); stackSize is the number of bytes to allocate for the stack of the context to be created. userNum is the user number to associated with the context. The user number is used by the abort/termination procedures described below. If the context is not to be associated with a client request, (e.g., it's a context to handle a Timer Request Block), the user number should be zero. If no memory is available from the heap, ercHeapMemoryNotAvail (4533) will be returned. In general, it is a good idea to keep the stack size of a context small -- 300 bytes is a good size. Large blocks of data used by a procedure should be allocated from the heap when a procedure begins and freed when the procedure has finished. If one procedure that is rarely called uses a large amount of stack space for local variables, it causes all the stack sizes to be inflated, and this wastes memory. The heap allocation procedures are defined below.} {When control returns from CreateContext with erc = ercOK, the stack pointer has been changed. This means the calling procedure must not use any local variables, because they will not be addressable when control returns from the call. CreateContext allocates a Context Control Block from the heap and sets a global oCCB to point to it. The CCB has two parts to it -- the header and the stack. The header contains the following information, which is accessed only by the AsyncServer library procedures: pointers to a doubly linked list of active CCBs. a list of heap blocks allocated to the context. When the context is terminated, any heap blocks that still belong to the context are freed. a pointer to the client request being served by this context. CreateContext saves the global pRq in the CCB header so that it can be restored when the context is resumed. the total size of the CCB. a seal which is used to check the CCB to assure that it does not get overwritten. The stack portion of the CCB starts at the end of the CCB and grows towards the header.} {ResumeContext The procedure ResumeContext continues execution of a context where it left off the last time it called (Build)AsyncRequest(Direct). If a request was built on the stack, it is removed and the erc returned in the request block is stored in the global ercAsync. In any case, the program continues execution where it left off the last time execution was suspended. The user codes: erc = ResumeContext; ResumeContext does not take any arguments. It uses the global pRq to find the context to resume. Control does not return from ResumeContext unless an error is detected. If pRq does not point to a request sent out by (Build)AsyncRequest(Direct), ercContextNotFound (4532) is returned.} {TerminateContext The procedure TerminateContext is used to terminate a context and return its stack space to the heap. The user codes: erc = TerminateContext; TerminateContext does not take any arguments. It uses the global oCCB that points to the current Context Control Block. Any heap space that is still owned by the context is returned to the heap at this time. An erc is returned only if oCCB does not point to a valid context. TerminateContext jumps to the user's wait loop.} {WaitLoop This document has often referred to the user's wait loop. The user is required to have a procedure called WaitLoop. The format of the WaitLoop procedure is illustrated in the sample program at the end of this document.} {CheckContextStack All of the async request procedures check to be sure the context stack has not overflowed. If a user's procedure does not call any of the async request procedures, a stack overflow could go undetected. The procedure CheckContextStack is provided so that the user can validate the context stack. erc = CheckContextStack;} {Other Ways to Use Contexts The program "AsyncServer" at the end of this document illustrates how the AsyncServer library procedures can be used by a server. In this example, a context is created by the procedure HandleRequest each time a request is received. In general, a context is associated with a request that is being processed, but this need not be the case. A context can also be created to service a timeout when a Timer Request Block is received. The WaitLoop procedure can create a context whenever it receives a message of any kind. The message need not be a request, and the pointer to the message need not be unique. The timeout procedure could send N messages to the server exchange to cause N contexts to be created. When a context is created, the value of pRq (the pointer to the last message received) is saved in the new Context Control Block, and the value is restored whenever a context is resumed.} {Handling System Requests The handling of abort requests, termination requests and swapping requests requires special consideration. The handling of system requests is often the most difficult and bug-prone part of a system service. Two procedures are provided by the AsyncServer library to make the handling of system requests easier. Termination and Abort Requests The OS issues a termination or abort request for two reasons: 1. To guarantee that no requests will be returned to the program after it has been terminated. 2. To guarantee that no outstanding requests will access memory that belongs to the program that is terminating. When a system service receives one of these requests, it is required to Respond to all requests with the same user number and then to Respond to the abort/termination request. If the server does not have any contexts active for the user that is terminating, it can simply respond to the abort/termination request.} {If the server has active context(s) for the user that is terminating, then the server has one outstanding client request for each context. There is also one asynchronous server request outstanding for each context. The asynchronous request was issued by the server on behalf of the client. The system service should respond to the client request as soon as possible so that it can respond to the abort/termination request. An important question to consider is the following? Can the server respond to the outstanding client request before the outstanding asynchronous server request has finished? The answer depends on requirement (2) above. Suppose for example, that the outstanding asynchronous request is reading to or from memory of the program that is terminating. If we responded to the abort/termination request before the outstanding server request had finished, it could cause memory that belongs to some other program to be corrupted. We can thus answer the above question with a simple rule: If all the pb/cb pairs in the outstanding asynchronous server request point to data in the server's memory, then the request is "safe". The server can respond to the client request before the asynchronous server request has finished.} {The procedure TerminateContextUser responds to all client requests for a given user. It waits for all outstanding asynchronous server requests to return in a way that is transparent to the caller. The user codes: erc = TerminateContextUser(userNum, erc) The algorithm used by TerminateContextUser is as follows: 1. If there are no active contexts for that user, control is simply returned to the caller. 2. If the user has outstanding context(s), it sets the terminated flag in the Context Control Block of each context to be terminated. For each context, it responds to the client request immediately if possible (if all the pb/cb pairs point to server data). If it can respond to all the outstanding client requests immediately, it returns to the caller. 3. If it must wait for one or more asynchronous server requests to finish, it jumps to the user's wait loop instead of returning to the caller. The context that called TerminateContextUser is now in a suspended state. The client request of this context is the abort/termination request. 4. Each time an asynchronous request returns, its context is resumed. When a context that has been flagged terminated is resumed, the ResumeContext procedure calls TerminateContext instead of resuming it. It then responds to the client request if it is still outstanding. If this is the last outstanding client request, it resumes the context that called TerminateContextUser.} {SwapContextUser The procedure SwapContextUser is designed to be used by procedures that handle swap requests. The OS issues a swap request for two reasons similar to abort/termination requests: 1. To guarantee that no requests will be returned to the program after it has been swapped out. 2. To guarantee that no outstanding requests will access memory that belongs to the program that is swapped out. When a system service receives a swap request it is required to Respond to all requests with the same user number and then to Respond to the swap request. The procedure SwapContextUser works very much like TerminateContextUser. The user codes: erc = SwapContextUser(userNum)} {The difference is that with SwapContextUser, the server is not finished with the client request. When the user is swapped back in, the context must pick up where it left off. This is handled by the Context procedures as follows. 1. The procedure SwapContextUser reponds to each client request with error code 37 (service not completed). This causes the OS to re-issue the request when the program is swapped back into memory, transparently to the application program which originally issued the request. 2. When the server sees a new request, it calls CreateContext. CreateContext checks to see if the user specified by the userNum parameter of CreateContext has a context that is waiting to be swapped back in. 3. When the user has a context waiting to be swapped back in, the request can only be a request that is being re-issued by the OS. The CreateContext procedure finds the context for that user that has the same request code as the request that just came in and resumes that context instead of creating a new context. There is one important consideration about the way swap requests are handled. When control returns to a context after an asynchronous request returns, the client request being handled may not be the same client request the context started with. The request could have been re-issued by the OS when the client program was swapped back in. In this case, the pointers in the client request block may not be the same as they were the first time the request was received. If the request came over the cluster, the request block was most likely received in a different buffer, and the pointers were constructed to point to data in a different buffer. This means that the server must not save away any pointers from the client request between asynchronous requests.} {Deinstallation The server receives a request when it is time to deinstall the server. The sample program illustrates the steps required to deinstall the server: 1. Unserve all requests. When the server was installed, it should have saved the exchange currently serving each request. Each request code should be served to restore it to the previous exchange. 2. Each active context must be terminated. The user codes: erc = TerminateAllOtherContexts(erc); This procedure terminates all contexts except for the calling context. The effect of this procedure is to call TerminateContextUser for every active user, including the server. This causes any contexts that belong to the server to be shut down as well as client contexts. An example of a context that belongs to the server is a context that is handling a Timer Request Block. 3. Any further incoming requests must be rejected. 4. The deinstall request must be handled. Usually, this requires returning the partition handle to the calling program so that the calling program can vacate the partition and remove it.} {Memory Management This section describes how memory is managed by the AsyncServer library procedures. The creation and termination of contexts depends on the use of a heap. When a context is created, a Context Control Block is allocated from the heap. The memory is returned to the heap when the context is terminated. The heap is allocated out of DS space. The AsyncServer library procedures were designed so that DS and SS are the same. This has a number of advantages. It means all pointers can be short pointers, code size is smaller and faster, and debugging is easier. DS Allocation A server that uses the AsyncServer library procedures must use the DS allocation feature when the program is linked, i.e., [DS allocation?] yes The result is that the program is loaded into the high end of memory. Space below the program code can be used as a dynamically allocatable area containing data relative to DS.} {COED Modules The memory allocation procedures are designed to use the "COED Hack" if desired. In order to conserve memory space, code that is used only once for initialization can be either returned to the operating system or used for data space when the code is no longer needed. Object modules that are used in this fashion must be processed by the COED program: Command coed Coed File list The Coed program takes a list of object modules and changes every segment of class CODE to class COED. When the program is linked, all of the modules of class COED are placed at the bottom of memory so that they can be reallocated for data.} {AllocMemoryInit The procedure AllocMemoryInit is used to allocate memory out of DS space. This means that space is allocated from memory below the last CODE segment. Memory is allocated from three areas in the following order: 1. A memory array in the module InitAlloc. 2. When the memory array has been used, memory is allocated from any COED modules. The procedure AllocMemoryInit is in a COED module called InitAlloc, so there will always be at least one COED module. 3. When no more COED space is available, additional memory is allocated from the OS by means of ExpandAreaSL. In any case, the memory allocated will be addressable by a short pointer. The user codes: erc = AllocMemoryInit(cBytes, ppMemoryRet, fInit); where cBytes is the count of bytes to be allocated. ppMemoryRet is a pointer to a 4-byte memory address into which the pointer of the DS space allocated is returned. fInit should be TRUE if the call is being made from a COED module and the data allocated will be initialized or used before all COED modules have finished execution. The purpose of this is to prevent the user from writing over code that will be executed. AllocMemoryInit will return an erc if fInit is TRUE and the next space to allocate is code space. The user can avoid this problem by allocating memory after all COED modules have finished execution. When the user's program is linked, the module InitAlloc MUST be the first module in the list of modules. This causes the COED modules (including InitAlloc) to be placed in memory in the proper order.} {Freeing Leftover Memory Note that all memory must be allocated before the program makes the call to ConvertToSys. Before the call to ConvertToSys, the program may wish to deallocate any unused memory. This only occurs when the size of the COED modules is greater than the size of memory allocated from DS space. The sample program illustrates how to free unused memory by calling ShrinkAreaSL.} {The Heap This section describes the heap procedures. The heap is a linked list of free blocks of memory in DS space. Initially, the list contains only one large block of memory. When a request for heap space is made, the free list is searched until a block big enough to fulfill the request is found. If the block is exactly the size requested, it is unchained from the free list and returned to the caller. If the block is bigger than the amount requested, it is split into two parts. One part is returned to the caller and the other is returned to the free list. The free list is kept in order of increasing addresses so that blocks can be merged with adjacent blocks when they are returned to the free list. HeapInit The procedure HeapInit initializes the heap. The user must call HeapInit before any of the AsyncServer library procedures are used. The heap is initialized with a fixed amount of memory. Once allocated, the heap may not be deallocated, and its size may not change. This is not a disadvantage for servers, since they may not allocate any more memory once they have called ConvertToSys. The user codes: erc = HeapInit(cBytes, pbHeap); where cBytes is the number of bytes to be used for the heap. pbHeap is the pointer to the first byte of heap space. This is usually memory that has been allocated by AllocMemoryInit.} {HeapAlloc The procedure HeapAlloc allocates memory from the heap. The user codes: erc = HeapAlloc(cBytes, ppMemoryRet); where cBytes is the number of bytes to allocate. ppMemoryRet is a pointer to a 4-byte memory address into which the pointer of the DS space allocated is returned. An erc is returned (ercNoHeapMemoryAvail = 4533) if there is not enough contiguous memory available in the heap to satisfy the request.} {HeapFree The procedure HeapFree returns memory to the heap. The user codes: erc = HeapFree(pbMemory); where pbMemory is the pointer to the block that was previously allocated from the heap. An erc is returned (ercInvalidHeapBlock = 4534) if the offset passed to HeapFree is not the address of a valid heap block.} {Other Ways to Use the Heap Procedures The heap procedures are used by the AsyncServer library procedures described above to allocate a Context Control Block (i.e., stack space) each time a context is created. The user may also use the Heap procedures for allocating and freeing blocks of memory during program execution. Rather than storing all variables in the stack, it is more efficient to allocate storage for large blocks of data as needed.} {Using the AsyncServer Library Procedures Debugging Aids The AsyncServer library includes procedures to log requests in a trace buffer as they are received and responded to. LogMsgIn: PROCEDURE EXTERNAL; This procedure logs the message pointed to by the global pRq. This procedure is designed to be used by the server when it receives a message at its exchange. LogRespond(pRq): PROCEDURE EXTERNAL; This procedure logs the response to the request pointed to by the parameter pRq. This procedure is designed to be used by the server before it responds to a client request. It is also used by the library procedures SwapContextUser and TerminateContextUser before responding to outstanding client requests. LogRequest(pRq): PROCEDURE EXTERNAL; This procedure logs the Request pointed to by the parameter pRq. This procedure is called by (Build)AsyncRequest(Direct) before the Request(Direct) primitive is called.} {The server may wish to use these procedures while debugging and eliminate them at a later time. The library Async.lib has two modules: LogAsync contains procedures and a trace buffer. LogAsyncDmy contains dummy procedures that do nothing. They are required to link the AsyncServer library procedures with the using server.} {The trace buffer has the following format: rgLog is an array of 50 entries. Each 9-word entry has the following format: code offset 0: This one-word entry has the following meaning: AAAA means message received at server exchange. This entry occurs when LogMsgIn is called. BBBB means request was sent by (Build)AsyncRequest(Direct). This entry occurs when LogRequest is called. CCCC means a response to an async request was received at the server exchange. This entry occurs when LogMsgIn is called. FFFF means we responded to a client request. This entry occurs when LogRespond is called. pRq offset 2: This two-word entry is the pointer to the message. rq offset 6: This six-word entry is the contents of the request block header. rgLog is a ring buffer. It starts filling from the last entry and fills towards the top of the buffer. This makes it more convenient to look at the buffer with the debugger. The pointer pLog points to the last entry used in the buffer. The convenient way to look at the log is to type pLog CODE Right Arrow then down arrow 8 times to see the last entry. To see the previous entry, type down arrow 9 more times, and so forth.} {Contents of the AsyncServer Release Diskette The AsyncServer release diskette contains the following files on the directory: Async.lib contains the object modules to be linked with applications that use the AsyncServer library procedures. Async.edf contains definitions to be used to compile PL/M applications that use the AsyncServer library procedures. Async.doc contains this document. AsyncServer.plm contains the sample server program illustrated at the end of this document.} LogAsync.plm contains the trace log program as described in the section on debugging so that it can be easily modified to suit the user. {Restrictions The AsyncServer library procedures are not designed to be used with programs that use more than one process. The use of global variables (pRq, ercAsync, oCCB, and others) precludes use by more than one process. This should not be considered as a disadvantage. The AsyncServer procedures are designed to replace processes and eliminate the problems inherent with applications designed to use more than one process -- synchronization and access to shared data. The AsyncServer procedures do not preclude the use of synchronous requests or the standard procedural interface. The user may want to use synchronous requests in some cases. System Software Compatibility The AsyncServer procedures will run on NGENs with CTOS 9.1 or later. The AsyncServer procedures depend on the use of GetpStructure to access the necessary tables in the OS to build request blocks. Resource Requirements The AsyncServer procedures described in this document use about 1700 decimal bytes of memory total.} {AsyncServer Statistics The AsyncServer library procedures maintain statistics that are helpful when debugging and tuning servers that use these procedures. The global label AsyncStats is a label to look at while in the debugger or when looking at a dump. It is followed by the following statistics: nStackOverflow is the number of times stack overflow was detected by BuildAsyncRequest or BuildAsyncRequestDirect. nCreateContextError is the number of times CreateContext returned an erc because there was no heap space available to create a context. nResumeContextError is the number of times ResumeContext returned an erc because pRq did not point to a request that belonged to an active context. minStackFree is the minimum number of bytes free on the stack after building a request block. This is after leaving room for all request overhead and 64 bytes to handle an interrupt. minHeapFree is the minimum number of bytes free in the heap. nBytesHeap is the number of bytes allocated to the heap. nBytesHeapFree is the number of bytes currently free in the heap. nCcbActive is the number of contexts currently active. nCcbActiveMax is the maximum number of contexts that were active at any one time.} Error Code Summary Decimal Value Meaning 26 Returned by AllocMemoryInit if fInit is TRUE and the next space to be allocated is COED space. If the memory were allocated out of COED space, code could be written over. See the section on AllocMemoryInit. 31 No such request code. Returned by BuildAsyncRequest or BuildAsyncRequestDirect if the request code is not recognized. The stack pointer is not valid when this erc is returned because the procedure does not know how many words to remove from the stack. 4531 Stack Overflow. Returned by BuildAsyncRequest or BuildAsyncRequestDirect if the request block to be built would overflow the stack. The context should be created with a bigger stack. 4532 Context Not Found. Returned by ResumeContext if the request block pointed to by pRq does not belong to a context that is waiting for a request. 4533 No Heap Memory Available. Returned by HeapAlloc if there is not enough contiguous memory available in the heap to satisfy the allocation request. The heap should be allocated more space initially. 4534 Invalid Heap Block. Returned by HeapFree if the pointer to the block to free is not valid. Either the address is out of range or the header of the heap block has been corrupted. For example, a user might have overwritten one heap block into the next. 4550 Can't find OS Tables. This occurs if the AsyncServer procedures can't access the tables in the OS to get the tables it needs to build request blocks. The OS may be too old to work with the AsyncServer procedures. {Server Program Example $MEDIUM OPTIMIZE(3) AsyncServer: DO; /* Title: Template of Server that uses AsyncServer library procedures History: 08-Apr-87 Jim Frandeen: created */ /* External Definitions */ $SET(SysLit,rqHeader,TrbType) $INCLUDE(:f0:Ctostypes.edf) $SET(AllocExch, ChangePriority, CheckErc, ConvertToSys, QueryRequestInfo) $SET(Exit, FatalError, GetUserNumber, OpenRTClock, ResetStack, Respond) $SET(SetPartitionName, ShrinkAreaSL, Wait, GetPartitionHandle, ServeRq, Check) $INCLUDE(:f0:CtosLib.edf) $SET(FsErc,RqErc) $INCLUDE(:f0:Erc.edf) /* Library AsyncServer Definitions */ $SET(All) $INCLUDE(:f1:Async.edf) /* PUBLIC Variables */ DECLARE cbHeap WORD PUBLIC INITIAL(2000) ,cDevices WORD INITIAL(3) ,defaultStackSize WORD PUBLIC INITIAL(300) ,fDebug FLAGTYPE PUBLIC INITIAL(TRUE) ,nRqCodes LITERALLY '2' /* number of rqCodes we serve */ ,priorityServ WORD PUBLIC INITIAL(20h) ,pZero POINTER PUBLIC INITIAL(0) ,rgbPartitionName(*) BYTE DATA('AsyncServer') ,saveSpBp (2) WORD PUBLIC ,pbHeap WORD PUBLIC ,rcOpenFileLL LITERALLY '97' ,rcRead LITERALLY '35' ,rgFileSpec(*) BYTE DATA('FileName') ,rgwOldExch(nRqCodes) WORD PUBLIC ,rgwRqs(nRqCodes) WORD PUBLIC INITIAL ( /* list of request codes served by this server. */ 0) ,TimeRq TrbType PUBLIC ; DECLARE pToDeallocate POINTER /* set up by InitAlloc */ EXTERNAL ,cbFree WORD /* set up by InitAlloc */ EXTERNAL ; /* PUBLIC Variables required by the AsyncServer procedures: */ DECLARE ercAsync ErcType PUBLIC; /* The erc from BuildAsyncRequest or BuildAsyncRequestDirect is returned here. */ DECLARE exchServ ExchType PUBLIC; /* This is the exchange where the server waits in its WaitLoop. This variable is stored in the exchResp field of the Request block that is build by BuildAsyncRequest or BuildAsyncRequestDirect. */ DECLARE pRq POINTER PUBLIC; /* pRq points to the current client request. It is set by the server in its WaitLoop by the call to Wait: erc = Wait(exchServ, @pRq); It is saved in the current Context Control Block by BuildAsyncRequest. It is restored by ResumeContext. */ DeinstallServer: PROCEDURE ErcType PUBLIC REENTRANT; DECLARE erc ErcType ,ercDiscard ErcType ,i WORD ,pRqBlk POINTER ,rqBlk BASED pRqBlk STRUCTURE(rqHeader) ,rq BASED pRq STRUCTURE( rqHeader ,pPhRet POINTER) ; /* Unserve all requests by serving them to the exchange previously served. */ DO i = 0 to nRqCodes - 1; erc = ServeRq(rgwRqs(i), rgwOldExch(i)); IF erc <> ercOK THEN CALL FatalServerError(erc); i = i + 1; END; /* Terminate all contexts except for the current context. */ erc = TerminateAllOtherContexts(ercOk); IF erc <> ercOK THEN CALL FatalServerError(erc); /* Reject all further incoming requests to server's exchange. */ DO WHILE erc = ercOk; erc = Check(exchServ, @pRqBlk); IF erc = ercOk THEN DO; rqBlk.ercRet = ercServiceNotAvail; CALL LogRespond(pRqBlk); erc = Respond(pRqBlk); IF erc <> ercOK THEN CALL FatalServerError(erc); END; END; /* Return partition handle to calling program so that the calling program can vacate the partition and remove it. */ erc = GetPartitionHandle(@rgbPartitionName, SIZE(rgbPartitionName), rq.pPhRet); RETURN erc; END DeinstallServer; FatalServerError: PROCEDURE(erc) PUBLIC REENTRANT; DECLARE erc ERCTYPE ; IF fDebug THEN CAUSE$INTERRUPT(3) /* Call the Debugger */; CALL FatalError(erc) /* Kill the system service */; END FatalServerError; /* HandleRequest: The request pointed to by rq is a new Request or a TRB. Given a request code, call the routine which processes the request. NOTE that this procedure is NOT REENTRANT. After the call to CreateContext, its stack pointer has changed, so it cannot access any local variables on the stack. */ HandleRequest: PROCEDURE PUBLIC; DECLARE erc ERCTYPE ,i WORD ,rq BASED pRq STRUCTURE(rqHeader) ; IF rq.rqCode = 0 THEN DO; CALL HandleTimer; RETURN; END /* of Timer Request */; i = FINDW(@rgwRqs(0), rq.rqCode, LENGTH(rgwRqs)); IF i = 0FFFFh THEN DO; rq.ercRet = ercNoSuchRc; CALL LogRespond(pRq); erc = Respond(pRq); RETURN; END; erc = CreateContext(defaultStackSize, rq.userNum); IF erc <> ercOk THEN DO /* Context could not be started because no heap space */; rq.ercRet = erc; CALL LogRespond(pRq); erc = Respond(pRq); RETURN; END /* of context could not be started */; DO CASE i; /* Call procedure to handle Request depending on Request code */ erc = DeinstallServer /* CASE 0 */; erc = ProcessRequest /* CASE 1 */; END /* CASE */; rq.ercRet = erc; CALL LogRespond(pRq); erc = Respond(pRq); erc = TerminateContext; /* Only returns if error -- normally calls WaitLoop */ CALL FatalServerError(erc); END HandleRequest; /* HandleTimer: The request in rq is a Timer Request Block NOTE that this procedure is NOT REENTRANT. After the call to CreateContext, its stack pointer has changed, so it cannot access any local variables on the stack. */ HandleTimer: PROCEDURE PUBLIC; DECLARE erc ERCTYPE ; erc = CreateContext(defaultStackSize, 0); IF erc <> ercOk THEN DO /* Context could not be started because no heap space */; TimeRq.cEvents = 0 /* Re-enable timer */; END /* of context could not be started */; ELSE DO /* Context started OK */; /* Handle Timer */ erc = TerminateContext; /* Only returns if error -- normally calls WaitLoop */ CALL FatalServerError(erc); END /* of context started OK */; END HandleTimer; Initialize: PROCEDURE PUBLIC REENTRANT; DECLARE i WORD ,erc ErcType ,userNumServ WORD ; /* Allocate exchange for server. */ CALL CheckErc (AllocExch(@exchServ)); CALL CheckErc (ChangePriority(priorityServ)); /* Serve Requests */ DO i = 0 to nRqCodes - 1; /* Save the exchange previously served for this request so that it can be restored when the server is desinstalled. */ CALL CheckErc(QueryRequestInfo(rgwRqs(i), @rgwOldExch(i), 2)); CALL CheckErc(ServeRq(rgwRqs(i), exchServ)); i = i + 1; END; /* Allocate memory from DS space to be used for the heap. */ CALL CheckErc(AllocMemoryInit(cbHeap, @pbHeap, FALSE)); CALL CheckErc(HeapInit(cbHeap, pbHeap)); /* Initialize Timer Request Block, if necessary. */ TimeRq.counter = 30; TimeRq.counterReload = 30; TimeRq.cEvents = 0; TimeRq.ExchResp = exchServ; TimeRq.rqCode = 0; CALL CheckErc(OpenRTClock(@TimeRq)); /* Allocate any other memory required for tables, etc from DS space. */ IF cbFree <> 0 THEN /* Free leftover memory used by the initialization code. */ CALL CheckErc(ShrinkAreaSL(pToDeallocate, cbFree)); CALL CheckErc(ConvertToSys); CALL Exit; /* CALL Exit must immediately follow ConvertToSys. SetPartitionName must come after ConvertToSys. */ erc = GetUserNumber(@userNumServ); erc = SetPartitionName((userNumServ AND 0FFh), @rgbPartitionName, SIZE(rgbPartitionName)); END Initialize; /* This is a sample procedure to begin handling a request. Its stack is allocated when the context is created. Each time it sends an asynchronous Request, its stack pointer and the global pRq are saved in the Context Control Block, and control is passed back to WaitLoop. When the context is Resumed, the stack pointer and pRq are restored. */ ProcessRequest: PROCEDURE ERCTYPE PUBLIC REENTRANT; DECLARE fh FHTYPE ,rq BASED pRq STRUCTURE(rqHeader) ,oData WORD ,rgData BASED oData (1024) BYTE ,(dFileSize, lfa) DWORD ,(dataRet, cCopyReset) WORD ,(erc, ercHeap) ERCTYPE ; /* Allocate buffer from the heap so we don't waste stack space. */ erc = HeapAlloc(SIZE(rgData), @oData); IF erc = ercOK THEN DO; lfa = 0; /* Send asynchronous Request to open file. */ CALL procBuildAsyncRequest(@fh, @rgFileSpec, INT(SIZE(rgFileSpec)), pZero, INT(0), modeRead, INT(rcOpenFileLL)); /* ResumeContext causes control to continue here when Request comes back. The stack and pRq are as before we sent the Request. */ erc = ercAsync; DO WHILE ((erc = ercOK) AND (lfa < dFileSize)); CALL procBuildAsyncRequest(fh, @rgData, SIZE(rgData), lfa, @dataRet, INT(rcRead)); erc = ercAsync; IF ((erc = ercOK) OR (erc = ercEOM)) THEN DO; IF (lfa + dataRet) > dFileSize THEN dataRet = dFileSize - lfa; END; END /* of DO WHILE */; /* Free heap space allocated for buffer. */ ercHeap = HeapFree(oData); IF ercHeap <> ercOK THEN CALL FatalServerError(ercHeap); END /* of heap allocated */; RETURN (erc); END ProcessRequest; /* TimeOut: when the timer issues a request, lets do whatever polling that is necessary. */ TimeOut: PROCEDURE PUBLIC REENTRANT; DECLARE i WORD ,erc ERCTYPE ; DO i = 0 TO cDevices - 1; ; END; TimeRq.cEvents = 0; END TimeOut; /* WaitLoop: Main process loop. It waits for a request or a response to come in. */ WaitLoop: PROCEDURE PUBLIC REENTRANT; DECLARE erc ErcType ,rq BASED pRq STRUCTURE(rqHeader) ; erc = ResetStack(.saveSpBp); DO FOREVER; erc = Wait(exchServ, @pRq); CALL LogMsgIn; IF erc = ercOK THEN DO; IF (rq.exchResp = exchServ) AND (rq.rqCode <> 0) THEN /* The request in rq is a response to an asynchronous request that we created and sent out. Handle the response. */ erc = ResumeContext; /* Only returns if error was detected. */ ELSE /* We have a new Request or a Timer Request Block. */ CALL HandleRequest; END /* of erc = ercOk */; IF erc <> ercOK THEN CALL FatalServerError(erc); END /* of DO FOREVER */; END WaitLoop; /* Main program */ DO; CALL Initialize; CALL WaitLoop; END; END AsyncServer; EOF 2 - # - Asynchronous Request Processing and Dynamic Memory Management 1.0 Async Server Page # of 30 Jim Frandeen date rvyz-KdqvwxyɛGH@ 2=H@  @  H/G H@  @,G H"#$ABCabcՆʈ՚ʜմ#BbЇ GH GH GH GH@ 2= GHGH@ 2=H GH345[\]jkĺ׊4\kҀ`@ 2=  GH  GH  GH GHGH@ 2=H GH !"345>@ASUVq!4@Us GH GH GH GH  GHGH@ 2=H  GH >@AQSTce@Sfe GH GH GH@ 2= GHGH@ 2=H GH%'(578HJKcefo'7Jeqɵ GH GH GH GH@ 2= GHGH@ 2= &*,H BDEnpqՀʃհDpЂвF !GH  GH@ 2= GH GH GHGH@ 2=H GH134JLMdfgz|3Lf|– 'GH &GH %GH $GH #GHGH@ 2=H "GHI GH$&(*,GH (GHGH@ 2=H . GHGH )GH@5 0H`x 8Ph= GHƤ! GH@3 @ 0H`x 8PhGH }GHGH@2 0H`x 8Ph= GHƿ] GH@3 @ 0H`x 8PhGHžGHGH@2 0H`x 8Ph= GHDƀDw@.  0H`x 8PhGH@3 @ 0H`x 8PhGH!` GH@5 0H`x 8Ph= GH$&(*,GHGH\GH@3 @ 0H`x 8PhGHGHƷ޸H GHH@. @ 0H`x 8PhGH$$GHGH GH@5 0H`x 8Ph= GHKuKul@.  0H`x 8PhGH@1 @ 0H`x 8PhGHf@6   0H`x 8Ph@3 @ 0H`x 8PhGH GH@5 0H`x 8Ph= GH$&(*,GHGHv{Ov|@.  0H`x 8PhGH@3 @ 0H`x 8PhGH6GHGH GH@5 0H`x 8Ph= GHGH@.  0H`x 8PhGH@3 @ 0H`x 8PhGH33GHGH GH@2 0H`x 8Ph= GHHƟEE@.  0H`x 8PhGH@3 @ 0H`x 8PhGHuuvGH@3 @ 0H`x 8Ph$&(*,GHGHGH?b?b@3 @ 0H`x 8PhGH@.  0H`x 8PhGHwGH GH@3 @ 0H`x 8PhGHGH  i@.  0H`x 8PhGH@3  0H`x 8PhGHIGH@3 @ 0H`x 8PhGH~~:@.  0H`x 8PhGH@3  0H`x 8PhGHuuš@3  0H`x 8PhGH@.  0H`x 8PhGH* @5 0H`x 8Ph=  GH$&(*,GHGHGH&φ&j@3 @ 0H`x 8PhGHGH GHDX@3 @ 0H`x 8Ph@3  0H`x 8PhGH"¨GHGH GH@5 0H`x 8Ph=  GHGH"=\=\™@.  0H`x 8PhGH@3 @ 0H`x 8PhGH"=GHGH@5 0H`x 8Ph=  GH")+*@.  0H`x 8PhGH@3 @ 0H`x 8PhGH"  7 GH@5 0H`x 8Ph=  GH$&(*,GHH"_+  GH@3 @ 0H`x 8PhGHWGHGH@5 0H`x 8Ph=  GH)I@.  0H`x 8PhGH@3 @ 0H`x 8PhGH)Ơ]~¡@3 @ 0H`x 8Ph@6  @0H`x 8PhGH)@3 @ 0H`x 8PhGH$&(*, GHGH)012߿k߆1 GHGH@3  0H`x 8PhGHžGHGH GH@5 0H`x 8Ph= GH.yƪy@.  0H`x 8PhGH@3 @ 0H`x 8PhGH.GHGH GH@5 @ 0H`x 8Ph= GHGH.vv@.  0H`x 8PhGH@3 @ 0H`x 8PhGH.   GH@5 0H`x 8Ph= GH$&(*, GHGH. GHGH@3 @ 0H`x 8PhGHGHGH GH@5 0H`x 8Ph= GH4'@'A@.  0H`x 8PhGH@3 @ 0H`x 8PhGH4žGHGH GH@5 0H`x 8Ph= GHH4Ɓ GH$&(*, GHGH@3 @ 0H`x 8PhGH4GHGH GH@5 0H`x 8Ph= GH66w GH@3 @ 0H`x 8PhGH9AGHGH@5 0H`x 8Ph= GH9I>J"@6   0H`x 8Ph@3 @ 0H`x 8PhGH9FGH@3 @ 0H`x 8PhGHGH9zzGH@1  0H`x 8PhFGH9Ɓ‚@3  0H`x 8Ph@3 @ 0H`x 8PhGH9;GH@3 @ 0H`x 8PhGH$&(*, GHGH9)c)cc@3 @ 0H`x 8PhGH@.  0H`x 8PhGHVWX]X GHGH@6   0H`x 8PhGHA¨GHGH GH@5 0H`x 8Ph= GHAww—@6   0H`x 8Ph@3 @ 0H`x 8PhGHA !! GH$&(*, GHH@.  0H`x 8PhGHAGH@3 @ 0H`x 8PhGH@3 @ 0H`x 8Ph@6   0H`x 8PhGHF@5 0H`x 8Ph= GH$&(*,GHGHGHFϡ@3 @ 0H`x 8PhGHGH GH&&"@.  0H`x 8PhGH@6   0H`x 8PhGHIgyh@6   0H`x 8Ph@3  0H`x 8PhGHI•GHGH GH@5 0H`x 8Ph= GHGHI/./ GH@3 @ 0H`x 8PhGHIRGHGH@5 0H`x 8Ph= GHICDE{ED GH$&(*,GHGH@3 @ 0H`x 8PhGHIGHGH GH@5 0H`x 8Ph= GHƌ`@3  0H`x 8Ph@3 @ 0H`x 8PhGHPԞGH GH@ = GH$&(*,GHHPĐ6ߐ@6   0H`x 8Ph@3 @ 0H`x 8PhGH3939@3 @ 0H`x 8PhGH@.  0H`x 8PhGHS50m6@3 @ 0H`x 8Ph@6  @0H`x 8PhGHSGHGH GH@ = GHGHSrstts\$&(*,GHGH@3 @ 0H`x 8PhGHS GH GH@3 0H`x 8PhGHƾ GH@3 @ 0H`x 8PhGHX GHGH@5 0H`x 8Ph= GHXƑƷ@.  0H`x 8PhGH@3 @ 0H`x 8PhGHXƵ9` GHGH@6  @0H`x 8PhGHX ªGHGH GH@5 0H`x 8Ph= GHXHntHntŸ@.  0H`x 8PhGH@3 @ 0H`x 8PhGHX*-,+@3 @ 0H`x 8Ph@6  @0H`x 8PhGHX   GH@2 0H`x 8Ph= GH$&(*,GHGHXC]cC]c@.  0H`x 8PhGH@3 @ 0H`x 8PhGHTj@3 @ 0H`x 8Ph@6  @0H`x 8PhGHa((›GHGH GH@5 0H`x 8Ph= GHGHaƘs  GHGH@3 @ 0H`x 8PhGHa** !GHGH GH@5 0H`x 8Ph=  GHa°GHGH@5 0H`x 8Ph= !GHav2WƉWv2WX¡@.  0H`x 8PhGH@3 @ 0H`x 8PhGHaˉJ@3 @ 0H`x 8PhGHGHa3$&(*,GH@6  @0H`x 8PhGHay,yGH@3 @ 0H`x 8PhGH@¡@6 @  0H`x 8Ph@6   0H`x 8PhGHjưC@3 @ 0H`x 8Ph@6 @  0H`x 8PhGHjƌ@3 @ 0H`x 8Ph@3  0H`x 8PhGHj//†GHGH@5 0H`x 8Ph= "GHGHjUCiW@6  0H`x 8Ph@3 @ 0H`x 8PhGHjˎŽt #GH$&(*,GH@6  0H`x 8PhGHGHjGHGH GH@5 0H`x 8Ph= #GHyy $GH@3 @ 0H`x 8PhGHq^GHGH@5 0H`x 8Ph= $GHq@ %GH@3 @ 0H`x 8PhGHq{GHGH@5 0H`x 8Ph= %GHqdeffe> &GH$&(*,GHGH@3 @ 0H`x 8PhGHqGHGH GH@5 0H`x 8Ph= &GH ƿj.i@6  0H`x 8Ph@3 @ 0H`x 8PhGHw GH@5 0H`x 8Ph= 'GH$&(*,GHGHwGH@3 0H`x 8PhGH/V (GH$&(*,H@6  0H`x 8PhGHzyGHGH GH@5 0H`x 8Ph= (GH&Ɵ>a{*KƔ!:S_9b` a $&(*,$&(*,FGH@6 '9K]o#5GYk}GH|4H@ɸ)AXvɐyΏɐ D U Ξ ɷ Y Ι έ ɮ Ź 2 j Ƀ Θ ɢ  ɉ Υ ɸ   $&(*,@6 '9K]o#5GYk}$&(*,FGHGHGH# fؒ'ب2sķ !h;01?,v } K ] b ؕ 2 3 2 @6 '9K]o#5GYk}$&(*,FGHGH$&(*,GH^_fNOWm CNı%:wxy$z{ *GHGHFGH@6 '9K]o#5GYk}$&(*,GH@ @,@X  $-6?HQZclu~ )2;DMV_hH+H DE\]acqu@EuDu/GH *GHGH@!GH,GH, FGH FGH   */=!F@@@@@@@@ Courier 72Times(TimesTimesTimes!TimesTimesTimesTimesCourier Courier?"\\lElluD Xzzllzlp?p'?gzggXp]XXp]upplrrr~~:p pJXX?gzgppJ2pJOgzO]]uOOlzzzzzzzzzzOOlTlXpXXuOuullJpu<Ez<uz]XEpgplgu@u]JJJuNNNZZuuzzpllllzlOluuEuTTgpgppJ2pJOOp@XXlOOXppppppppppOJlTgOXOOu@zzlpOlz@@z@zzX]Jupzlgp<pTJJJuNNNZZzzzulpppupTOppp2p<<ppuzT7uTOpObbOOlOOb]l]]OzuuOzEOEl]TuzuuJbXXTZZZffzzuuuupOJTT]gz~~~]~ggE-gpEEJg<OOgJETggggggggggEJlTbz@T@El<gugugJbu<@u<uuuuTXEpggb]l<lO@@ElNNNNNggupggggpgEEggg2l77gugppJ2puJJbuJ]]uJJXuuuuuuuuuuJJu]glXlOu@uzlgOpE@z@zuzX]@gulbJpTJJJuNNNZZuuzzlggguTOlzzEzJE]gz~~~]~glE-glEEOg@OOl@ETggggggggggEElOXzpbTgEl@ppbz]Egu<@p<pullOT@u]gb]p<lJJJElNNNNNppuuub]]]pgJJllg2pEE]lz~~~]~ggE-lEEglETTlEE]llllllllllEEbTlzT]TOlEpzgugElu<Op<uzXbEuggbbl<lTTTElNNNNNppzuuggggzlbEbzzEzEE?~<}Ti^vGyG m\>9Imagen2.2;6 6Q^ " ~Nrm !!}"$$$v(())+)+- ..S2K4|6659H9;%;<<T=q=@ ACBbBDFGI[JJO'OQQRXX_YZ\]/_=_``c/cee-iGijjmmCoopxpqqrrsttt1xx|yy{}~ :RequestCode:4202H :RequestName:AbortExample (wErc): ErcType :Version:3 :LclSvcCode:0000H :ServiceExch:exchInstalledMastr :sCntInfo:2 :nReqPbCb:0 :nRespPbCb:0 :Params:w(12) :NetRouting:NoRouting :SrpRouting:rRemote :WsAbortRq:4202H :RequestCode:4203H :RequestName:ChangeUserNumExample (wOldUserNum): ErcType :Version:3 :LclSvcCode:0000H :ServiceExch:exchInstalledMastr :sCntInfo:2 :nReqPbCb:0 :nRespPbCb:0 :Params:w(12) :NetRouting:NoRouting :SrpRouting:rRemote :ChgUserNumRq:4203H :RequestCode:4201H :RequestName:DeinstallExample (pPhRet): ErcType :Version:0 :LclSvcCode:0000H :ServiceExch:exchInstalledMastr :sCntInfo:0 :nReqPbCb:0 :nRespPbCb:1 :Params:p(12),c(2,16) :NetRouting:NoRouting :SrpRouting:rRemote :RequestCode:4200H :RequestName:StopRecord: ErcType :Version:0 :LclSvcCode:0000H :ServiceExch:exchInstalledMastr :sCntInfo:0 :nReqPbCb:0 :nRespPbCb:0 :Params:none :NetRouting:NoRouting :SrpRouting:rRemote :RequestCode:4206H :RequestName:StartRecord: ErcType :Version:0 :LclSvcCode:0000H :ServiceExch:exchInstalledMastr :sCntInfo:0 :nReqPbCb:0 :nRespPbCb:0 :Params:none :NetRouting:NoRouting :SrpRouting:rRemote :RequestCode:4204H :RequestName:SwapExample (wErc): ErcType :Version:3 :LclSvcCode:0000H :ServiceExch:exchInstalledMastr :sCntInfo:2 :nReqPbCb:0 :nRespPbCb:0 :Params:w(12) :NetRouting:NoRouting :SrpRouting:rRemote :SwappingRq:4204H :RequestCode:4205H :RequestName:TerminateExample (wErc): ErcType :Version:3 :LclSvcCode:0000H :ServiceExch:exchInstalledMastr :sCntInfo:2 :nReqPbCb:0 :nRespPbCb:0 :Params:w(12) :NetRouting:NoRouting :SrpRouting:rRemote :TerminationRq:4205H /******************************* MODULE HEADER *******************************/ /* */ /* FILE: Start.c */ /* */ /* MACHINE: SGen/NGen LANGUAGE: METAWARE C V1.0 OS: CTOS */ /* */ /* DESCRIPTION: Starts recording of open requests in example service. */ /* */ /* */ /* HISTORY: */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) */ /* */ /* 09/16/92 123A/00 S. Ahn / Added attribute information */ /* 12/03/89 120E/01 S. Emmons / Changed server to service. */ /* */ /* */ /* */ /* Attributes exhibited by this software: (See SSAttributes.doc) */ /* Use attribute levels 0, E, A, S, F, I and 1...9 as decribed. */ /* */ /* VID:~ 0 */ /* FIL:~ 0 */ /* KBD:~ 0 */ /* CLS:~ 0 */ /* KNL:~ 0 */ /* MEM:~ 0 */ /* COM:~ 0 */ /* TIM:~ 0 */ /* PFM:~ 0 */ /* HDW:~ 0 */ /* DSK:~ 0 */ /* DEV:~ 0 */ /* NLS:~ 0 */ /* */ /* TITLE: BTOS SYSTEM SOFTWARE */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE */ /* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE */ /* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS */ /* CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1980, 1989 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED */ /* COPYRIGHT (C) 1980, 1989 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* ************************************************************************* */ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND */ /* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF */ /* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /* */ /*************************** END OF MODULE HEADER ****************************/ #define Syslit #include #define CheckErc #include #define StartRecord #include "ExFunc.h" /* Program used to enable file open recording of File Access Recorder service. */ void main (void) { CheckErc (StartRecord ()); }/******************************* MODULE HEADER *******************************/ /* */ /* FILE: Stop.c */ /* */ /* MACHINE: SGen/NGen LANGUAGE: METAWARE C V1.0 OS: CTOS */ /* */ /* DESCRIPTION: Disables file recording feature of example service. */ /* */ /* HISTORY: */ /* */ /* MM/DD/YY VVVV/MM PROGRAMMER / DESCRIPTION OF CHANGE (Most recent first) */ /* */ /* 09/16/92 123A/00 S. Ahn / Added attribute information */ /* 12/03/89 120E/01 S. Emmons / Changed server to service. */ /* */ /* */ /* Attributes exhibited by this software: (See SSAttributes.doc) */ /* Use attribute levels 0, E, A, S, F, I and 1...9 as decribed. */ /* */ /* VID:~ 0 */ /* FIL:~ 0 */ /* KBD:~ 0 */ /* CLS:~ 0 */ /* KNL:~ 0 */ /* MEM:~ 0 */ /* COM:~ 0 */ /* TIM:~ 0 */ /* PFM:~ 0 */ /* HDW:~ 0 */ /* DSK:~ 0 */ /* DEV:~ 0 */ /* NLS:~ 0 */ /* */ /* */ /* TITLE: CTOS SYSTEM SOFTWARE */ /* */ /* PROPRIETARY PROGRAM MATERIAL */ /* */ /* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE */ /* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE */ /* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS */ /* CORPORATION, DETROIT, MICHIGAN 48232, USA. */ /* */ /* COPYRIGHT (C) 1980, 1989 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED */ /* COPYRIGHT (C) 1980, 1989 UNISYS CORPORATION. ALL RIGHTS RESERVED */ /* ************************************************************************* */ /* */ /* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND */ /* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, */ /* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY */ /* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF */ /* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO */ /* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. */ /* */ /* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE */ /* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE */ /* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. */ /* */ /* */ /*************************** END OF MODULE HEADER ****************************/ #define Syslit #include #define CheckErc #include #define StopRecord #include "ExFunc.h" /* Program used to disable file open recording of File Access Recorder service. */ void main (void) { CheckErc (StopRecord ()); } 1 ' *********************************************************** 2 ' This program illustrates how to call the Sort/Merge object  modules from BASIC. The records to be sorted are read  from the SAM file Files.In, contained on the distribution  3 ' diskette. The sorted records are written to the SAM file  Files.Out.  4 ' Files.In contains a sequence of 65-byte records  terminated by line feeds. All the records must be  exactly 65-bytes long (including the line feed), or the  sort will not work.  5 ' Two 6-byte keys are used for the sort, both of type  character. The first is located 6 bytes from the  beginning of the record, and the second 26 bytes from the  6 ' beginning. Both are sorted in ascending order.   10 '************************************************************ 11 ' Declarations  20 ' Function to extend an integer (2-byte) to a quad (4-byte  integer). The quad is stored as a single-precision (4-  byte) real number.  21 DEF fnQuadFromInt(w%) = CVS(MKI$(w%) + MKI$(0))   30 ' Array definitions.  31 DIM rgwStatusBlock%[2] 32 DIM rgwPrepSort%[112] 33 DIM rgwKeyDesc%[9]   40 ' Constants  41 qsWFCreate = fnQuadFromInt(1024) 42 sWFIncr% = 512 43 sBufferIn% = 1024 44 sBufferOut% = 1024 45 sRecordMax% = 65 46 sRecordMin% = 32   50 ' File Names  51 wf1$ = "[Sys]<$>Sort1.Temp" 52 wf2$ = "[Sys]<$>Sort2.Temp"   200 ' *********************************************************** 201 ' Initialize key descriptor (2 keys, 2 + 2*8 = 18 bytes)  205 PRINT "Initializing key descriptor" 210 ' 2 keys are used. 211 rgwKeyDesc%[0] = 2 220 ' The first key is of type character, is 6 bytes long, has  an offset of 6 bytes from the beginning of the record,  and is sorted in ascending order.  221 rgwKeyDesc%[1] = 6 222 rgwKeyDesc%[2] = 6 223 rgwKeyDesc%[3] = 2 224 rgwKeyDesc%[4] = &hFFFF  230 ' The second key is of type character, is 6 bytes long,  has an offset of 26 bytes from the beginning of the  record, and is sorted in ascending order.  231 rgwKeyDesc%[5] = 26 232 rgwKeyDesc%[6] = 6 233 rgwKeyDesc%[7] = 2 234 rgwKeyDesc%[8] = &hFFFF   300 ' *********************************************************** 301 ' Open input and output files.  305 PRINT "Opening files" 310 OPEN "I", #1, "Files.In"  320 OPEN "O", #2, "Files.Out"   400 ' *********************************************************** 401 ' Initialize Sort/Merge.  405 PRINT "Preparing for sort" 410 erc% = BasicPrepareKeySort(  PTR(rgwPrepSort%[0]), wf1$, "", wf2$, "",  qsWFCreate, sWFIncr%, fnQuadFromInt(0), sRecordMax%, 0, PTR(rgwKeyDesc%[0]), MAKEPOINTER(0,0),  PTR(rgwStatusBlock%[0])) 411 IF erc% <> 0 THEN GOTO 940   500 ' *********************************************************** 501 ' Read records from Files.In and release them to Sort/Merge.  510 PRINT "Release Records"  520 IF EOF(1) THEN GOTO 600  530 LINE INPUT #1, record$ 531 IF LEN(record$) > sRecordMax% THEN  record$ = LEFT$(record$, sRecordMax%) 532 IF LEN(record$) < sRecordMin% THEN  record$ = record$ + SPACE$(sRecordMin% - LEN(record$)) 533 sRecord% = LEN(record$) 540 erc% = ReleaseRecord(  PTR(sRecord%), PTR(record$), PTR(rgwStatusBlock%[0])):  IF erc% <> 0 THEN GOTO 940  550 PRINT record$ 551 GOTO 520   600 ' *********************************************************** 601 ' Sort the records.  610 PRINT "Do Sort"  620 erc% = DoSort(PTR(rgwStatusBlock%[0])) :  IF erc% <> 0 THEN GOTO 940   700 ' *********************************************************** 701 ' Get the sorted records back, displaying and writing them  to Files.Out.  710 PRINT "Return Records"  720 record$ = SPACE$(sRecordMax%) 721 erc% = ReturnRecord(  PTR(sRecord%), PTR(record$), PTR(rgwStatusBlock%[0])):  IF erc% <> 0 THEN GOTO 760 722 record$ = LEFT$(record$, sRecord%)  730 PRINT #2, record$ 740 PRINT record$  750 GOTO 720   760 ' Check to be sure that the "error" was "no more records". 761 IF erc% <> 3404 THEN GOTO 940   800 ' *********************************************************** 801 ' Termination logic.  810 erc% = ConcludeSort(PTR(rgwStatusBlock%[0])) :  IF erc% <> 0 THEN GOTO 940  820 PRINT "Sort Concluded Successfully" 821 PRINT  830 PRINT "Press any key to exit" 831 x$ = INPUT$(1) 832 SYSTEM  840 END   900 ' *********************************************************** 901 ' Error logic: Display status and quit.  910 ' Terminate with a status status code in erc%  920 PRINT "Error" 921 PRINT "Status code = "; erc%  930 ' Note that TerminateSort can be called even if no sort is  pending. 931 erc% = TerminateSort(PTR(rgwStatusBlock%[0])) 932 STOP   940 ' Terminate with a status code in erc% and a status block  in rgwStatusBlock%  950 ' Make sure the status block is valid. 951 IF erc% <> rgwStatusBlock%[0] THEN GOTO 910  960 PRINT "Error" 961 PRINT "Status code = "; erc% 962 IF rgwStatusBlock%[1] <> 0 THEN  PRINT "Detailed status code = "; rgwStatusBlock%[1]  970 erc% = TerminateSort(PTR(rgwStatusBlock%[0])) 971 STOP 2 ӷѮv ё ]OTѵ@Ƶ@0` P  , j^(` @` @` )P x0xxxx Courier 72G  "10.3%' File: BASICCompilerSortExample.Sub %' Version: 8.1 %' Revised: 2/2/84 %' %' Copyright (c) 1984 by Convergent Technologies %' %' %' Ref: Sort/Merge Manual, Appendix B, "Programming Examples" %' %' This submit file is used to compile and link the Sort/Merge %' example BASIC programs: %' %' Submit %' File list BASICCompilerSortExample.Sub %' ... %' BASIC Compile BASICSortExample.Bas BasGen.Obj Yes Yes %' Link BASICSortExample.Obj BASICSortExample.Run Protected [Sys]SortMerge.Lib %' 2¥+-+@-+-   ((()P xxxx Courier 72G B-+"10.3 /**************************************************************** * * CSortExample.C * * This program illustrates how to call the Sort/Merge object * modules from C. The records to be sorted are read from * the SAM file Files.In, contained on the distribution diskette. * The sorted records are written to the SAM file Files.Out. * * Files.In contains a sequence of 65-byte records terminated by * line feeds. All the records must be exactly 65-bytes long * (including the line feed), or the sort will not work. * * Two 6-byte keys are used for the sort, both of type character. * The first is located 6 bytes from the beginning of the record, * and the second 26 bytes from the beginning. Both are sorted in * ascending order. * *****************************************************************/ /* CTOS and SAM Types and Constants */ #define ercOk 0 #define ercEof 1 #define ercInternalError 8 #define modeRead 0x6D72 #define modeWrite 0x6D77 #define pageSize 512 #define NULL ((char *) 0) typedef int ErcType; /* Sort/Merge Types and Constants */ #define ercNoMoreRecords 3404 #define charType 2 typedef struct { ErcType erc; ErcType ercDetail; } StatusBlockType; typedef struct { char cbWorkFile1; /* offset 0 */ char rgbWorkFile1[91]; /* 1 */ char cbPwWorkFile1; /* 92 */ char rgbPwWorkFile1[12]; /* 93 */ char cbWorkFile2; /* 105 */ char rgbWorkFile2[91]; /* 106 */ char cbPwWorkFile2; /* 197 */ char rgbPwWorkFile2[12]; /* 198 */ long qsSortWorkFileCreate; /* 210 */ int sWorkFileIncrement; /* 214 */ long qsSortWorkArea; /* 216 */ int sRecordMax; /* 220 */ int fStableSort; /* 222 */ } PrepareSortBlockType; typedef struct { int rbKey; int cbKey; int typ; int fAscending; } KeyComponentType; typedef struct { int cKeyComponents; KeyComponentType keyComponentDescriptor1; KeyComponentType keyComponentDescriptor2; } KeyDescriptorType; /* CTOS and SAM Procedures */ extern void CheckErc( /* erc */ ); extern void FatalError( /* erc */ ); extern ErcType OpenByteStream( /* pBs, pbFile, cbFile, pbPW, cbPW, mode : modeType; pBuffer, cbBuffer */ ); extern ErcType ReadBsRecord( /* pBs, pBufferRet, sBuffer, psDataRet */ ); extern ErcType CloseByteStream( /* pBs */ ); extern ErcType WriteBsRecord( /* pBs, pb, cb, pcbRet */ ); /* Sort/Merge Procedures */ extern ErcType ConcludeSort ( /* pStatusBlockRet */ ); extern ErcType DoSort ( /* pStatusBlockRet */ ); extern ErcType PrepareKeySort ( /* pPrepareSortBlock, pKeyDescriptor, pSortWorkArea, pStatusBlockRet */ ); extern ErcType PrepareSort ( /* pPrepareSortBlock, psKey, pSortWorkArea, pStatusBlockRet */ ); extern ErcType ReleaseRecord ( /* psRecord, pRecord, pStatusBlockRet */ ); extern ErcType ReleaseRecordAndKey ( /* psRecord, pRecord, psKey, pKey, pStatusBlockRet */ ); extern ErcType ReturnRecord ( /* psRecordRet, pRecordRet, pStatusBlockRet */ ); extern ErcType ReturnRecordAndKey ( /* psRecordRet, pRecordRet, psKeyRet, pKeyRet, pStatusBlockRet */ ); extern ErcType TerminateSort ( /* pStatusBlockRet */ ); /* C library procedure to copy n bytes from s2 to s1, return s1 */ extern char *memcpy( /* s1, s2, n */ ); /* Global Variables */ char bsIn[130]; char bsOut[130]; char rgbBufferIn[1024]; char rgbBufferOut[1024]; char rgbWorkArea[8192]; PrepareSortBlockType prepareSortBlock; KeyDescriptorType keyDescriptor; StatusBlockType statusBlock; char rgbRecord[66]; int sRecord; char zbInFileName[] = "Files.In"; char zbOutFileName[] = "Files.Out"; char zbWorkFile1[] = "[Sys]<$>WorkFile1.Tmp"; char zbWorkFile2[] = "[Sys]<$>WorkFile2.Tmp"; /* Procedure to check status blocks, returning on ercOk */ void CheckStatus( erc, pStatusBlock ) ErcType erc; StatusBlockType *pStatusBlock; { if (erc != pStatusBlock->erc) FatalError(ercInternalError); if (erc == ercOk) return; printf("\nSort Error\n Status code %d\n", erc); if (pStatusBlock->ercDetail != ercOk) printf(" Detail status code %d\n", pStatusBlock->ercDetail); (void) TerminateSort(pStatusBlock); FatalError(erc); } /* Main Program */ main() { ErcType erc; int wRet; int cb; /* Open input file */ CheckErc(OpenByteStream(bsIn, zbInFileName, sizeof(zbInFileName) - 1, NULL, 0, modeRead, rgbBufferIn, sizeof(rgbBufferIn))); /* Open output file */ CheckErc(OpenByteStream(bsOut, zbOutFileName, sizeof(zbOutFileName) - 1, NULL, 0, modeWrite, rgbBufferOut, sizeof(rgbBufferOut))); /* Initialize prepareSortBlock */ prepareSortBlock.cbWorkFile1 = cb = sizeof(zbWorkFile1) - 1; (void)memcpy(prepareSortBlock.rgbWorkFile1, zbWorkFile1, cb); prepareSortBlock.cbPwWorkFile1 = 0; prepareSortBlock.cbWorkFile2 = cb = sizeof(zbWorkFile2) - 1; (void)memcpy(prepareSortBlock.rgbWorkFile2, zbWorkFile2, cb); prepareSortBlock.cbPwWorkFile2 = 0; prepareSortBlock.qsSortWorkFileCreate = 1024; prepareSortBlock.sWorkFileIncrement = 512; prepareSortBlock.qsSortWorkArea = sizeof(rgbWorkArea); prepareSortBlock.sRecordMax = 65; prepareSortBlock.fStableSort = 0; /* Initialize key descriptor */ /* 2 keys are used. */ /* The first key is of type character, is 6 bytes long, has an */ /* offset of 6 bytes from the beginning of the record, and is */ /* sorted in ascending order. */ keyDescriptor.cKeyComponents = 2; keyDescriptor.keyComponentDescriptor1.rbKey = 6; keyDescriptor.keyComponentDescriptor1.cbKey = 6; keyDescriptor.keyComponentDescriptor1.typ = charType; keyDescriptor.keyComponentDescriptor1.fAscending = 0xFF; /* The second key is of type character, is 6 bytes long, has an */ /* offset of 26 bytes from the beginning of the record, and is */ /* sorted in ascending order. */ keyDescriptor.keyComponentDescriptor2.rbKey = 26; keyDescriptor.keyComponentDescriptor2.cbKey = 6; keyDescriptor.keyComponentDescriptor2.typ = charType; keyDescriptor.keyComponentDescriptor2.fAscending = 0xFF; /* Initialize Sort */ CheckStatus( PrepareKeySort( &prepareSortBlock, &keyDescriptor, rgbWorkArea, &statusBlock), &statusBlock); /* Release records */ printf("\nRelease Records\n"); erc = ercOk; sRecord = 65; while (erc == ercOk) { erc = ReadBsRecord(bsIn, rgbRecord, sRecord, &wRet); if (erc == ercOk) { /* null-terminate string for printing, leave line feed in record */ rgbRecord[sRecord] = '\0'; printf("%s", rgbRecord); CheckStatus( ReleaseRecord(&sRecord, rgbRecord, &statusBlock), &statusBlock); } } if (erc != ercEof) FatalError(erc); /* Do Sort */ printf("Do Sort\n"); CheckStatus(DoSort(&statusBlock), &statusBlock); /* Retrieve records */ printf("Return Records\n"); erc = ercOk; while (erc == ercOk) { erc = ReturnRecord(&sRecord, rgbRecord, &statusBlock); if (erc == ercOk) { if (sRecord != 65) FatalError(ercInternalError); CheckErc(WriteBsRecord( bsOut, rgbRecord, sRecord, &wRet)); printf("%s", rgbRecord); } } if (erc != ercNoMoreRecords) CheckStatus(erc, &statusBlock); /* Close files and end sort */ CheckStatus(ConcludeSort(&statusBlock), &statusBlock); CheckErc(CloseByteStream(bsIn)); CheckErc(CloseByteStream(bsOut)); printf("Sort concluded successfully\n"); } %' File: CSortExample.Sub %' Version: 9.0 %' Revised: 9/27/88 %' %' Copyright (c) 1988 by Convergent Technologies %' %' %' Ref: Sort/Merge Manual, Appendix B, "Programming Examples" %' %' This submit file is used to compile and link the Sort/Merge %' example C program: %' %' Submit %' File list CSortExample.Sub %' ... %' CC86 CSortExample.C medium %' Link CSortExample.Obj CSortExample.Run Protected [Sys]SortMerge.Lib @[sys]mclib.fls %' 2am??c?aim1 ttyhf Tue Nov 4 13:05 - 13:13 (00:07) ??aim1 ttyhf Tue Nov 4 11:51 - 11:53 (00:02) ~?amnon ttyhc Tue Nov 4 09:04 - 09:06 (00:02) ?amnon ttyhd Tue Nov 4 13:08 - 13:09 (00:00) ?anne ttyhe Tue Nov 4 11:33 - 12:21 (00:47) ;?anne ttyi8 Tue Nov 4 12:16 - 13:15 (00:58) z?baden ttyhd Tue Nov 4 11:02 - 11:06 (00:03) ?bart ttyh3 Tue Nov 4 10:29 - 11:12 (00:43) ?ber ttyd7 Tue Nov 4 01:23 - 01:25 (00:01) 7?berlek ttyd0 Tue Nov 4 11:55 - 12:25 (00:29) v?berlek ttyd0 Tue Nov 4 08:22 - 08:23 (00:00) ?cabrera ttyhe Tue Nov 4 10:45 - 10:48 (00:02) ?cary ttyd0 Tue Nov 4 02:41 - 02:45 (00:04) 3?cary ttyd0 Tue Nov 4 01:35 - 02:37 (01:01) r?cary ttyie Tue Nov 4 09:15 - 09:18 (00:03) ?cary ttyie Tue Nov 4 08:48 - 09:13 (00:24) ?chin ttyh6 Tue Nov 4 09:18 - 09:19 (00:00) /?chs ttyd0 Tue Nov 4 12:58 - 13:04 (00:05) n?chs ttyd0 Tue Nov 4 12:32 - 12:57 (00:25) ?chs ttyd0 Tue Nov 4 12:30 - 12:31 (00:00) ?chs ttyd0 Tue Nov 4 07:09 - 08:00 (00:51) +?chs ttyd1 Tue Nov 4 12:19 - 12:30 (00:10) j?chs ttyd1 Tue Nov 4 12:08 - 12:18 (00:10) ?chs ttyd1 Tue Nov 4 12:02 - 12:07 (00:05) ?chs ttyd2 Tue Nov 4 12:00 - 12:01 (00:00) '?cindy ttyd1 Tue Nov 4 11:40 - 12:00 (00:20) f?deering ttyie Tue Nov 4 11:09 - 12:28 (01:19) ?demmel ttyhd Tue Nov 4 11:42 - 11:45 (00:02) ?demmel ttyi8 Tue Nov 4 12:08 - 12:15 (00:06) # ?devel tty7 Tue Nov 4 08:09 - 08:10 (00:00) b ?devel tty7 Tue Nov 4 08:07 - 08:09 (00:01)  ?devel tty7 Tue Nov 4 08:06 - 08:07 (00:01)  ?devel tty7 Tue Nov 4 08:04 - 08:05 (00:01)  ?devel ttyi5 Tue Nov 4 07:27 - 08:09 (00:42) ^ ?dmu tty30 Tue Nov 4 11:02 - 11:04 (00:01)  ?doucette ttyd0 Tue Nov 4 08:25 - 09:01 (00:35)  ?doucette ttyi3 Tue Nov 4 10:52 - 10:58 (00:06)  ?douglas ttyd7 Tue Nov 4 09:05 - 09:14 (00:08) Z ?drb ttyhe Tue Nov 4 13:04 - 13:28 (00:24)  ?drb ttyi8 Tue Nov 4 08:02 - 11:43 (03:41)  ?earl ttyd0 Tue Nov 4 11:22 - 11:48 (00:26)  ?earl ttyd0 Tue Nov 4 09:06 - 09:18 (00:11) V ?earl ttyd1 Tue Nov 4 10:34 - 10:42 (00:07)  ?eric ttyd6 Tue Nov 4 09:46 - 09:54 (00:07)  ?eric ttyd6 Tue Nov 4 09:25 - 09:39 (00:14)  ?eric ttyd6 Tue Nov 4 09:21 - 09:25 (00:04) R ?eric ttyd6 Tue Nov 4 08:18 - 09:20 (01:02)  ?erics ttyd6 Tue Nov 4 11:23 - 11:25 (00:02)  ?erics ttyd6 Tue Nov 4 11:19 - 11:21 (00:01) ?fateman ttyd6 Tue Nov 4 07:05 - 07:21 (00:16) N?fitz ttyh5 Tue Nov 4 09:55 - 09:59 (00:03) ?fitz ttyh5 Tue Nov 4 09:50 - 09:55 (00:05) ?fkunze ttyd3 Tue Nov 4 12:04 - 12:07 (00:02)  ?gaede ttyd0 Tue Nov 4 10:00 - 10:01 (00:00) J?gaede ttyd0 Tue Nov 4 09:25 - 09:39 (00:13) ?gaede ttyd0 Tue Nov 4 09:21 - 09:25 (00:04) ?gaede ttyd0 Tue Nov 4 09:20 - 09:20 (00:00) ?gaede ttyd1 Tue Nov 4 11:30 - 11:31 (00:00) F?ghg ttyd7 Tue Nov 4 09:16 - 09:20 (00:03) ?ghg ttyd8 Tue Nov 4 09:25 - 09:37 (00:11) ?god ttyd6 Tue Nov 4 13:04 - 13:06 (00:01) ?goodman ttyd6 Tue Nov 4 06:28 - 06:30 (00:01) B?goodman ttyd6 Tue Nov 4 06:27 - 06:27 (00:00) ?hamachi ttyh3 Tue Nov 4 11:42 - 12:37 (00:54) ?harald ttyhc Tue Nov 4 12:18 - 12:39 (00:21) ?harald ttyhc Tue Nov 4 09:10 - 11:55 (02:45) >?harrison tty4 Tue Nov 4 11:26 - 12:31 (01:05) }?harrison ttyd0 Tue Nov 4 06:29 - 06:36 (00:06) ?harrison ttyhe Tue Nov 4 11:19 - 11:23 (00:03) ?henry ttyh1 Tue Nov 4 09:41 - 12:49 (03:08) :?hofmann tty27 Tue Nov 4 11:09 - 11:10 (00:01) y?hyerle ttyhe Tue Nov 4 12:22 - 12:48 (00:25) ?ingres ttyhe Tue Nov 4 11:25 - 11:28 (00:03) ?ip ttyd0 Tue Nov 4 11:15 - 11:16 (00:00) 6?jimbo tty27 Tue Nov 4 12:28 - 13:04 (00:36) u?jkf ttyd9 Tue Nov 4 09:04 - 09:14 (00:09) ?jkf ttyh5 Tue Nov 4 10:04 - 12:50 (02:46) ?joe ttyi3 Tue Nov 4 08:45 - 09:02 (00:17) 2?jonf ttyd0 Tue Nov 4 04:32 - 04:49 (00:16) q?jonf ttyd0 Tue Nov 4 04:12 - 04:28 (00:16) ?kateveni ttyhc Tue Nov 4 12:41 - 12:43 (00:02) ?larry ttyha Tue Nov 4 09:00 - 09:16 (00:15) .?laura tty29 Tue Nov 4 11:16 - 11:20 (00:03) m?laura tty29 Tue Nov 4 10:24 - 11:16 (00:52) ?laura tty29 Tue Nov 4 09:36 - 10:24 (00:47) ?lhl ttyd7 Tue Nov 4 05:49 - 05:50 (00:00) *?lin ttyhc Tue Nov 4 12:14 - 12:17 (00:03) i?lock ttyhd Tue Nov 4 12:30 - 12:45 (00:15) ?lock ttyhe Tue Nov 4 12:52 - 12:55 (00:02) ?novy ttyhd Tue Nov 4 08:26 - 10:50 (02:23) &?ouster ttyh2 Tue Nov 4 11:02 - 12:31 (01:29) e?parker ttyhc Tue Nov 4 08:43 - 08:51 (00:08) ?parker ttyhe Tue Nov 4 09:05 - 09:08 (00:03) ?patlee ttyhe Tue Nov 4 09:39 - 10:20 (00:41) "?patt ttyhb Tue Nov 4 09:08 - 09:09 (00:01) a?patt ttyhb Tue Nov 4 07:41 - 07:43 (00:02) ?pattrsn ttyd7 Tue Nov 4 08:21 - 08:48 (00:27) ?peter ttyd1 Tue Nov 4 08:52 - 09:10 (00:17) ?pjw ttyd6 Tue Nov 4 04:23 - 04:25 (00:02) ]?porcarj ttyd1 Tue Nov 4 08:31 - 08:43 (00:11) ?porcarj ttyd7 Tue Nov 4 10:52 - 11:03 (00:11) ?powell ttyd6 Tue Nov 4 11:48 - 12:52 (01:03) ?powell ttyd6 Tue Nov 4 10:50 - 11:03 (00:13) Y?presotto ttyhd Tue Nov 4 12:03 - 12:24 (00:21) ?root console Tue Nov 4 09:31 - 12:50 (03:19) ?schmidt ttyd0 Tue Nov 4 09:42 - 09:46 (00:03) ?shafi ttyhe Tue Nov 4 10:21 - 10:29 (00:07) U?shafi ttyhe Tue Nov 4 09:33 - 09:34 (00:00) ?shen ttyh6 Tue Nov 4 09:11 - 09:12 (00:00) ?shivaji ttyh6 Tue Nov 4 10:06 - 12:53 (02:47) ?sif ttyd6 Tue Nov 4 06:52 - 06:52 (00:00) Q?sif ttyh9 Tue Nov 4 08:20 - 08:22 (00:01) ?simon ttyhc Tue Nov 4 12:03 - 12:03 (00:00) ?simon ttyhd Tue Nov 4 11:20 - 11:23 (00:03) ?simon ttyhd Tue Nov 4 11:14 - 11:19 (00:04) M?siyan ttyh6 Tue Nov 4 12:54 - 13:13 (00:19) ?sklower ttyd6 Tue Nov 4 11:26 - 11:43 (00:16) ?sklower ttyd7 Tue Nov 4 11:50 - 11:52 (00:01)  ?sklower ttyd7 Tue Nov 4 09:25 - 09:37 (00:11) I?sklower ttyd7 Tue Nov 4 09:21 - 09:25 (00:03) ?sklower ttyd8 Tue Nov 4 08:35 - 09:20 (00:44) ?thompson ttyhd Tue Nov 4 10:59 - 11:00 (00:00)  ?tomisawa ttyh2 Tue Nov 4 10:10 - 10:16 (00:05) E ?tygar ttyd1 Tue Nov 4 09:30 - 09:39 (00:09)  ?ucsd ttyd1 Tue Nov 4 07:57 - 08:03 (00:05)  ?upstill ttyhf Tue Nov 4 11:39 - 11:40 (00:01) !?usg ttyd6 Tue Nov 4 05:05 - 05:18 (00:12) A!?uucp ttyd0 Tue Nov 4 10:15 - 11:03 (00:47) !?uucp ttyd0 Tue Nov 4 07:07 - 07:07 (00:00) !?uucp ttyd0 Tue Nov 4 03:11 - 03:12 (00:00) !?uucp ttyd0 Tue Nov 4 03:05 - 03:09 (00:04) ="?uucp ttyd4 Tue Nov 4 08:28 - 08:34 (00:06) |"?uucp ttyd6 Tue Nov 4 07:40 - 07:42 (00:01) "?uucp ttyd6 Tue Nov 4 06:00 - 06:01 (00:00) "?uucp ttyd7 Tue Nov 4 04:24 - 04:24 (00:00) 9#?uucp ttyd7 Tue Nov 4 03:11 - 03:11 (00:00) x#?uucp ttyd7 Tue Nov 4 02:04 - 02:08 (00:03) #?uucp ttyd7 Tue Nov 4 02:01 - 02:03 (00:01) #?uucp ttyd7 Tue Nov 4 01:18 - 01:21 (00:02) 5$?w ttyi8 Tue Nov 4 12:07 - 12:07 (00:00) t$?w ttyi8 Tue Nov 4 12:06 - 12:07 (00:00) $?w ttyi8 Tue Nov 4 07:56 - 07:56 (00:00) $?who tty7 Tue Nov 4 08:07 - 08:07 (00:00) 1%?who ttyd6 Tue Nov 4 11:13 - 11:13 (00:00) p%?who ttyd7 Tue Nov 4 11:28 - 11:28 (00:00) %?wildbill ttyhe Tue Nov 4 09:15 - 09:19 (00:03) %?william ttyd9 Tue Nov 4 12:39 - 12:59 (00:19) -&?william ttyda Tue Nov 4 09:12 - 09:20 (00:08) l&?ying ttyhf Tue Nov 4 11:56 - 13:02 (01:06) &?ying ttyhf Tue Nov 4 08:12 - 11:22 (03:10)  Larrus Frank V Oreglia Augustine Wylie Dovie Zzunk K D C Zeisser Henry Blodgett John T Davis Don Higgs Rye E Blodgett Cynthia M Martin Bell Marrion E L Randolph Ted /* IsUtil.idf Internal interfaces used in the ISAM utilities. Last edited 12/09/80 KRD Created. */ $SAVE NOLIST /*CONSTANTS*/ $IF IsuErc $RESTORE DECLARE ercInstallError LITERALLY '1000' ,ercCreateError LITERALLY '1010' ,ercCreateSucceeded LITERALLY '1011' ,ercBadIndexParam LITERALLY '1020' ,ercBadNumericParam LITERALLY '1021' ,ercBadFlagParam LITERALLY '1022' ,ercMissingParam LITERALLY '1023' ,ercNotSingleParam LITERALLY '1024' ,ercConfirm LITERALLY '1030' ,ercConfirmed LITERALLY '1031' ,ercOkToDelete LITERALLY '1032' ,ercIOErrorMsg LITERALLY '1033' ,ercDenied LITERALLY '1034' ,ercIsamError LITERALLY '1040' ,ercIsamDetail LITERALLY '1041' ,ercOpenError LITERALLY '1050' ,ercCloseError LITERALLY '1051' ,ercLoadError LITERALLY '1052' ,ercLoadSucceeded LITERALLY '1053' ; $SAVE NOLIST $ENDIF /*PROCEDURES*/ $IF GetSingleParam $RESTORE /* Read a string parameter from a subsys parameter. * There must be only one parameter on the line. * If fRequired is false, then there may be none (returns null string). * If anything goes wrong, this displays a message and sets fBadParam. */ GetSingleParam: PROCEDURE (iParam, fRequired, pSdRet) EXTERNAL; DECLARE iParam WORD ,fRequired FlagType ,pSdRet POINTER ; END GetSingleParam; $SAVE NOLIST $ENDIF $IF GetWordParam $RESTORE /* Read a word parameter from a subsys parameter. * There must be only one parameter on the line. * If wDefault is ONES, then there must be a parameter. * If anything goes wrong, this displays a message and sets fBadParam. */ GetWordParam: PROCEDURE (iParam, wDefault, pWRet) EXTERNAL; DECLARE iParam WORD ,wDefault WORD ,pWRet POINTER ; END GetWordParam; $SAVE NOLIST $ENDIF $IF GetQuadParam $RESTORE /* Read a 4-byte integer parameter from a subsys parameter. * There must be only one parameter on the line. * If qDefault.low is ONES, then a parameter must be supplied. * If anything goes wrong, this displays a message and sets fBadParam. */ GetQuadParam: PROCEDURE (iParam, qDefault, pQRet) EXTERNAL; DECLARE iParam WORD ,qDefault QUAD ,pQRet POINTER ; END GetQuadParam; $SAVE NOLIST $ENDIF $IF GetFlagParam $RESTORE /* Read a flag parameter from a subsys parameter. * There must be only one parameter on the line. * Default is FALSE. * If anything goes wrong, this displays a message and sets fBadParam. */ GetFlagParam: PROCEDURE (iParam, pFRet) EXTERNAL; DECLARE iParam WORD ,pFRet POINTER ; END GetFlagParam; $SAVE NOLIST $ENDIF $IF GetIndexParams $RESTORE /* Read a set of index key specs from a subsys parameter. * There must be isamDesc.cIndexes parameters on the line. * If anything goes wrong, this displays a message and sets fBadParam. */ GetIndexParams: PROCEDURE (iParam, pIsamDesc) EXTERNAL; DECLARE iParam WORD ,pIsamDesc POINTER ; END GetIndexParams; $SAVE NOLIST $ENDIF /* Error message procs */ $IF Display0 $RESTORE Display0: PROCEDURE (erc) EXTERNAL; DECLARE erc ErcType ; END Display0; $SAVE NOLIST $ENDIF $IF Display1 $RESTORE Display1: PROCEDURE (erc, pArg0) EXTERNAL; DECLARE erc ErcType ,pArg0 POINTER ; END Display1; $SAVE NOLIST $ENDIF $IF Display2 $RESTORE Display2: PROCEDURE (erc, pArg0, pArg1) EXTERNAL; DECLARE erc ErcType ,pArg0 POINTER ,pArg1 POINTER ; END Display2; $SAVE NOLIST $ENDIF $IF DisplayIOError $RESTORE DisplayIOError: PROCEDURE (erc, pbFSpec, cbFSpec) EXTERNAL; DECLARE erc ErcType ,pbFSpec POINTER ,cbFSpec WORD ; END DisplayIOError; $SAVE NOLIST $ENDIF $IF DisplayISAMError $RESTORE DisplayISAMError: PROCEDURE (erc, oIsb) EXTERNAL; DECLARE erc ErcType ,oIsb OFFSET ; END DisplayISAMError; $SAVE NOLIST $ENDIF $IF MapErcSd $RESTORE MapErcSd: PROCEDURE (erc,pSdRet) EXTERNAL; /* make pSdRet^ refer to a message decoding the erc */ DECLARE erc ErcType ,pSdRet POINTER ; END MapErcSd; $SAVE NOLIST $ENDIF $IF GetConfirmation $RESTORE /*Get a confirm/deny response */ GetConfirmation: PROCEDURE FlagType EXTERNAL; END GetConfirmation; $SAVE NOLIST $ENDIF /* Misc procs */ $IF CheckDelete $RESTORE /* Delete a file, possibly asking for user confirmation. */ CheckDelete: PROCEDURE (pbFSpec, cbFSpec, pbPw, cbPw, fNoConfirm) EXTERNAL; DECLARE pbFSpec POINTER ,cbFSpec WORD ,pbPw POINTER ,cbPw WORD ,fNoConfirm FlagType ; END CheckDelete; $SAVE NOLIST $ENDIF $RESTORE /*END IsUtil.idf*/ ***************************************************************** * * Subroutine to check for unexpected status codes. Used by the * example FORTRAN-86 Sort/Merge program. Subroutine ChkErc(iErc) if (iErc .eq. 0) return write(*, '( / 1x, a)') 'Error encountered' write(*, '(1x, a, i5)') ' Status code', iErc stop end2OQO@QOQ@ ((8,  ()P xxxx Courier 72G@QO 8.4 ***************************************************************** * * Subroutine to check for unexpected Sort/Merge errors. Used by * the example FORTRAN-86 Sort/Merge program. Subroutine ChkSts(iErc, irgSts) dimension irgSts(2) if (iErc .ne. irgSts(1)) call ChkErc(8) if (iErc .eq. 0) return write(*, '( / 1x, a)') 'Sort Error' write(*, '(1x, a, i5)') ' Status code', iErc if (irgSts(2) .ne. 0) write(*, '(1x, a, i5)') . ' Detail status code', irgSts(2) iErc = ISMTST(irgSts) stop end2   @   @ ((8,  ()P xxxx Courier 72G@   8.4FORTRAN86SortExample.Obj FORTRAN86ChkErc.Obj FORTRAN86ChkSts.Obj Fort86Gen.Obj ***************************************************************** * * This program illustrates how to call the Sort/Merge object * modules from FORTRAN-86. The records to be sorted are read * from the SAM file Files.In, contained on the distribution * diskette. The sorted records are written to the SAM file * Files.Out. * * Files.In contains a sequence of 65-byte records terminated by * line feeds. All the records must be exactly 65-bytes long * (including the line feed), or the sort will not work. * * Two 6-byte keys are used for the sort, both of type character. * The first is located 6 bytes from the beginning of the record, * and the second 26 bytes from the beginning. Both are sorted in * ascending order. * ***************************************************************** * See FORTRAN86ChkErc.Fort86 and FORTRAN86ChkSts.Fort86 for the * definitions of the subroutines ChkErc and ChkSts, respectively. ***************************************************************** * Main Program Program SortEx * Variables implicit integer (f) implicit integer (s) implicit integer (b) * Miscellaneous integer*2 iErc integer*2 iStsBk(2) integer*2 wRet * Record buffer and size integer*1 iRecrd(65) integer*2 sRecrd * Work areas and buffers dimension iRgbIn(512), iRgbOu(512), iBsIn(65), iBsOut(65) dimension iRgbWk(4096), iPrpSB(112) * Sort/Merge key descriptor integer*2 iKeyDs(9) data iKeyDs / * 2 keys: . 2, * 1st: located 6 bytes from the beginning of the record, 6 * bytes long, type character (2), and sorted in ascending * order (255): . 6, 6, 2, 255, * 2nd: located 26 bytes from the beginning of the record, * 6 bytes long, type character (2), and sorted in * ascending order (255): . 26, 6, 2, 255/ * Long-integer constants to be used in Sort/Merge and SAM * procedure calls. integer*4 qsWFCr, qsWrkA data qsWFCr, qsWrkA /1024, 8192/ * Character strings to be used in Sort/Merge and SAM procedure * calls. integer*1 filin(8) character*8 chflin data chflin /'Files.In'/ equivalence (filin, chflin) integer*1 filout(9) character*9 chflou data chflou /'Files.Out'/ equivalence (filout, chflou) integer*1 pswd(1) character*1 chpswd data chpswd /' '/ equivalence (pswd, chpswd) integer*1 nWf1(21) character*21 chWf1 data chWf1 /'[Sys]<$>WorkFile1.Tmp'/ equivalence (nWf1, chWf1) integer*1 nWf2(21) character*21 chWf2 data chWf2 /'[Sys]<$>WorkFile2.Tmp'/ equivalence (nWf2, chWf2) integer*2 iModeR, iModeW character*2 modeR, modeW data modeR, modeW /'rm', 'wm'/ equivalence (iModeR, modeR), (iModeW, modeW) * Open input file call ChkErc(IBSOPN( . iBsIn, filin, 8, pswd, 0, iModeR, iRgbIn, 1024)) * Open output file call ChkErc(IBSOPN( . iBsOut, filout, 9, pswd, 0, iModeW, iRgbOu, 1024)) * Initialize sort call ChkSts(ISMBPK( . iPrpSB, nWf1, 21, nWf1, 0, nWf2, 21, nWf2, 0, . qsWFCr, 512, qsWrkA, 65, 0, iKeyDs, iRgbWk, . iStsBk), . iStsBk) * Release records sRecrd = 65 write(*, '(1x / 1x, a)') 'Release Records' 10 iErc = IBSRRC(iBsIn, iRecrd, 65, wRet) IF (iErc.ne.0) goto 20 call ChkSts(ISMRLC(sRecrd, iRecrd, iStsBk), iStsBk) write(*, '(1x, 64a1)') (iRecrd(i), i=1, 64) goto 10 20 IF (iErc.ne.1) CALL ChkErc(iErc) * Do sort write(*, '(1x, a)') 'Do Sort' call ChkSts(ISMDST(iStsBk), iStsBk) * Retrieve records write(*, '(1x, a)') 'Return Records' 30 iErc = ISMRTC(sRecrd, iRecrd, iStsBk) IF (iErc.ne.0) goto 40 call ChkErc(IBSWRC(iBsOut, iRecrd, sRecrd, wRet)) write(*, '(1x, 64a1)') (iRecrd(i), i=1, 64) goto 30 40 IF (iErc.ne.3404) CALL ChkSts(iErc, iStsBk) * Close files and end sort CALL ChkSts(ISMCST(iStsBk), iStsBk) CALL ChkErc(IBSCLS(iBsIn)) CALL ChkErc(IBSCLS(iBsOut)) write(*, '(1x, a)') 'Sort concluded successfully' end2@@ ((8,  ()P xxxx Courier 72G@  8.4%' File: FORTRAN86SortExample.Sub %' Version: 8.1 %' Revised: 1/17/84 %' %' Copyright (c) 1984 by Convergent Technologies %' %' %' Ref: Sort/Merge Manual, Appendix B, "Programming Examples" %' %' This submit file is used to compile and link the Sort/Merge %' example FORTRAN-86 programs: %' %' Submit %' File list FORTRAN86SortExample.Sub %' ... %' Fort86 FORTRAN86SortExample.Fort86 FORTRAN86SortExample.Obj FORTRAN86SortExample.Lst %' Fort86 FORTRAN86ChkErc.Fort86 FORTRAN86ChkErc.Obj FORTRAN86ChkErc.Lst %' Fort86 FORTRAN86ChkSts.Fort86 FORTRAN86ChkSts.Obj FORTRAN86ChkSts.Lst %' Link @FORTRAN86Link.Fls FORTRAN86SortExample.Run [Sys]SortMerge.Lib @[Sys]87Null.Fls %' 2¢@   ()P xxxx Courier 72G@ 8.4 $STORAGE: 2 ***************************************************************** * * This program illustrates how to call the Sort/Merge object * modules from FORTRAN. The records to be sorted are read from * the SAM file Files.In, contained on the distribution diskette. * The sorted records are written to the SAM file Files.Out. * * Files.In contains a sequence of 65-byte records terminated by * line feeds. All the records must be exactly 65-bytes long * (including the line feed), or the sort will not work. * * Two 6-byte keys are used for the sort, both of type character. * The first is located 6 bytes from the beginning of the record, * and the second 26 bytes from the beginning. Both are sorted in * ascending order. * ***************************************************************** * Subroutine to check for unexpected status codes. Subroutine ChkErc(iErc) if (iErc.eq.0) return write(*,'( / 1x,17hError encountered)') write(*,'(1x,15h Status code,I5)') iErc stop end * Subroutine to check for unexpected Sort/Merge errors. Subroutine ChkSts(iErc, irgSts) dimension irgSts(2) if (iErc.ne.irgSts(1)) call ChkErc(8) if (iErc.eq.0) return write(*,'( / 1x,10hSort Error)') write(*,'(1x,15h Status code,I5)') iErc if (irgSts(2).ne.0) . write(*, . '(1x,22h Detail status code,I5)') irgSts(2) iErc = SMTRST(irgSts) stop end * Main Program Program SortEx * Variables implicit integer (f) implicit integer (s) implicit integer (b) character*65 chRecrd character*8 filin character*9 filout character*1 pswd character*21 nWf1 character*21 nWf2 character*2 modeR character*2 modeW character LF integer*4 q0 integer*4 qsWFCr integer*4 qsWrkA integer*2 iErc integer*2 wRet integer*2 sRecrd dimension iRgbIn(512),iRgbOu(512),iBsIn(65),iBsOut(65) dimension iRgbWk(4096),iPrpSB(112),iKeyDs(9),iStsBk(2) data filin/'Files.In'/,filout/'Files.Out'/,pswd/' '/ data modeR/'rm'/,modeW/'wm'/ data nWf1/'[Sys]<$>WorkFile1.Tmp'/ data nWf2/'[Sys]<$>WorkFile2.Tmp'/ q0 = 0 lf = char(10) * Open input file call ChkErc(BSOPEN(iBsIn,filin,8,pswd,0,modeR,iRgbIn,1024)) * Open output file call ChkErc(BSOPEN( . iBsOut,filout,9,pswd,0,modeW,iRgbOu,1024)) * Initialize prepare sort block variables qsWFCr = 1024 qsWrkA = 8192 * Initialize key descriptor * 2 keys are used. * The first key is of type character, is 6 bytes long, has an * offset of 6 bytes from the beginning of the record, and is * sorted in ascending order. iKeyDs(1) = 2 iKeyDs(2) = 6 iKeyDs(3) = 6 iKeyDs(4) = 2 iKeyDs(5) = 255 * The second key is of type character, is 6 bytes long, has an * offset of 26 bytes from the beginning of the record, and is * sorted in ascending order. iKeyDs(6) = 26 iKeyDs(7) = 6 iKeyDs(8) = 2 iKeyDs(9) = 255 * Initialize sort call ChkSts(SMBPKS(iPrpSB,nWf1,21,nWf1,0,nWf2,21,nWf2,0, . qsWFCr,512,qsWrkA,65,0,iKeyDs,iRgbWk,iStsBk), . iStsBk) * Release records sRecrd = 65 write(*, 9) 9 format(1x / ' Release Records') 10 iErc = BSRDRC(iBsIn,chRecrd,65,wRet) IF (iErc.ne.0) goto 20 call ChkSts(SMRLRC(sRecrd,chRecrd,iStsBk), iStsBk) write(*, '(1x,a64)') chRecrd goto 10 20 IF (iErc.ne.1) CALL ChkErc(iErc) * Do sort write(*,'(1x,7hDo Sort,1a)') LF call ChkSts(SMDOST(iStsBk), iStsBk) * Retrieve records write(*,'(1x,14hReturn Records,1a)') LF 30 iErc = SMRTRC(sRecrd,chRecrd,iStsBk) IF (iErc.ne.0) goto 40 call ChkErc(BSWRRC(iBsOut,chRecrd,sRecrd,wRet)) write(*, '(1x,a64)') chRecrd goto 30 40 IF (iErc.ne.3404) CALL ChkSts(iErc, iStsBk) * Close files and end sort CALL ChkSts(SMCDST(iStsBk), iStsBk) CALL ChkErc(BSCLOS(iBsIn)) CALL ChkErc(BSCLOS(iBsOut)) write(*,'(1x,27hSort concluded successfully,1a)') LF end2@@ ((8,  ()P xxxx Courier 72G@  8.4%' File: FORTRANSortExample.Sub %' Version: 8.1 %' Revised: 1/15/84 %' %' Copyright (c) 1984 by Convergent Technologies %' %' %' Ref: Sort/Merge Manual, Appendix B, "Programming Examples" %' %' This submit file is used to compile and link the Sort/Merge %' example FORTRAN programs: %' %' Submit %' File list FORTRANSortExample.Sub %' ... %' FORTRAN FORTRANSortExample.For %' Link FORTRANSortExample.Obj ForGen.Obj FORTRANSortExample.Run [Sys]SortMerge.Lib %' 2  @     ()P xxxx Courier 72G@  8.42am?c?aim1 ttyhf Tue Nov 4 13:05 - 13:13 (00:07) ?aim1 O/ Tue Nov 4 11:51 - 11:53 (00:02) ~?amnon ttyhc Tue Nov 4 09:04 - 09:06 (00:02) ?amnon ttyhd Tue Nov 4 13:08 - 13:09 (00:00) ?anne ttyhe Tue Nov 4 11:33 - 12:21 (00:47) ;?anne ttyi8 Tue Nov 4 12:16 - 13:15 (00:58) z?baden ttyhd Tue Nov 4 11:02 - 11:06 (00:03) ?bart ttyh3 Tue Nov 4 10:29 - 11:12 (00:43) ?ber ttyd7 Tue Nov 4 01:23 - 01:25 (00:01) 7?berlek ttyd0 Tue Nov 4 11:55 - 12:25 (00:29) v?berlek ttyd0 Tue Nov 4 08:22 - 08:23 (00:00) ?cabrera ttyhe Tue Nov 4 10:45 - 10:48 (00:02) ?cary ttyd0 Tue Nov 4 02:41 - 02:45 (00:04) 3?cary ttyd0 Tue Nov 4 01:35 - 02:37 (01:01) r?cary ttyie Tue Nov 4 09:15 - 09:18 (00:03) ?cary ttyie Tue Nov 4 08:48 - 09:13 (00:24) ?chin ttyh6 Tue Nov 4 09:18 - 09:19 (00:00) /?chs ttyd0 Tue Nov 4 12:58 - 13:04 (00:05) n?chs ttyd0 Tue Nov 4 12:32 - 12:57 (00:25) ?chs ttyd0 Tue Nov 4 12:30 - 12:31 (00:00) ?chs ttyd0 Tue Nov 4 07:09 - 08:00 (00:51) +?chs ttyd1 Tue Nov 4 12:19 - 12:30 (00:10) j?chs ttyd1 Tue Nov 4 12:08 - 12:18 (00:10) ?chs ttyd1 Tue Nov 4 12:02 - 12:07 (00:05) ?chs ttyd2 Tue Nov 4 12:00 - 12:01 (00:00) '?cindy ttyd1 Tue Nov 4 11:40 - 12:00 (00:20) f?deering ttyie Tue Nov 4 11:09 - 12:28 (01:19) ?demmel ttyhd Tue Nov 4 11:42 - 11:45 (00:02) ?demmel ttyi8 Tue Nov 4 12:08 - 12:15 (00:06) # ?devel tty7 Tue Nov 4 08:09 - 08:10 (00:00) b ?devel tty7 Tue Nov 4 08:07 - 08:09 (00:01)  ?devel tty7 Tue Nov 4 08:06 - 08:07 (00:01)  ?devel tty7 Tue Nov 4 08:04 - 08:05 (00:01)  ?devel ttyi5 Tue Nov 4 07:27 - 08:09 (00:42) ^ ?dmu tty30 Tue Nov 4 11:02 - 11:04 (00:01)  ?doucette ttyd0 Tue Nov 4 08:25 - 09:01 (00:35)  ?doucette ttyi3 Tue Nov 4 10:52 - 10:58 (00:06)  ?douglas ttyd7 Tue Nov 4 09:05 - 09:14 (00:08) Z ?drb ttyhe Tue Nov 4 13:04 - 13:28 (00:24)  ?drb ttyi8 Tue Nov 4 08:02 - 11:43 (03:41)  ?earl ttyd0 Tue Nov 4 11:22 - 11:48 (00:26)  ?earl ttyd0 Tue Nov 4 09:06 - 09:18 (00:11) V ?earl ttyd1 Tue Nov 4 10:34 - 10:42 (00:07)  ?eric ttyd6 Tue Nov 4 09:46 - 09:54 (00:07)  ?eric ttyd6 Tue Nov 4 09:25 - 09:39 (00:14)  ?eric ttyd6 Tue Nov 4 09:21 - 09:25 (00:04) R ?eric ttyd6 Tue Nov 4 08:18 - 09:20 (01:02)  ?erics ttyd6 Tue Nov 4 11:23 - 11:25 (00:02)  ?erics ttyd6 Tue Nov 4 11:19 - 11:21 (00:01) ?fateman ttyd6 Tue Nov 4 07:05 - 07:21 (00:16) N?fitz ttyh5 Tue Nov 4 09:55 - 09:59 (00:03) ?fitz ttyh5 Tue Nov 4 09:50 - 09:55 (00:05) ?fkunze ttyd3 Tue Nov 4 12:04 - 12:07 (00:02)  ?gaede ttyd0 Tue Nov 4 10:00 - 10:01 (00:00) J?gaede ttyd0 Tue Nov 4 09:25 - 09:39 (00:13) ?gaede ttyd0 Tue Nov 4 09:21 - 09:25 (00:04) ?gaede ttyd0 Tue Nov 4 09:20 - 09:20 (00:00) ?gaede ttyd1 Tue Nov 4 11:30 - 11:31 (00:00) F?ghg ttyd7 Tue Nov 4 09:16 - 09:20 (00:03) ?ghg ttyd8 Tue Nov 4 09:25 - 09:37 (00:11) ?god ttyd6 Tue Nov 4 13:04 - 13:06 (00:01) ?goodman ttyd6 Tue Nov 4 06:28 - 06:30 (00:01) B?goodman ttyd6 Tue Nov 4 06:27 - 06:27 (00:00) ?hamachi ttyh3 Tue Nov 4 11:42 - 12:37 (00:54) ?harald ttyhc Tue Nov 4 12:18 - 12:39 (00:21) ?harald ttyhc Tue Nov 4 09:10 - 11:55 (02:45) >?harrison tty4 Tue Nov 4 11:26 - 12:31 (01:05) }?harrison ttyd0 Tue Nov 4 06:29 - 06:36 (00:06) ?harrison ttyhe Tue Nov 4 11:19 - 11:23 (00:03) ?henry ttyh1 Tue Nov 4 09:41 - 12:49 (03:08) :?hofmann tty27 Tue Nov 4 11:09 - 11:10 (00:01) y?hyerle ttyhe Tue Nov 4 12:22 - 12:48 (00:25) ?ingres ttyhe Tue Nov 4 11:25 - 11:28 (00:03) ?ip ttyd0 Tue Nov 4 11:15 - 11:16 (00:00) 6?jimbo tty27 Tue Nov 4 12:28 - 13:04 (00:36) u?jkf ttyd9 Tue Nov 4 09:04 - 09:14 (00:09) ?jkf ttyh5 Tue Nov 4 10:04 - 12:50 (02:46) ?joe ttyi3 Tue Nov 4 08:45 - 09:02 (00:17) 2?jonf ttyd0 Tue Nov 4 04:32 - 04:49 (00:16) q?jonf ttyd0 Tue Nov 4 04:12 - 04:28 (00:16) ?kateveni ttyhc Tue Nov 4 12:41 - 12:43 (00:02) ?larry ttyha Tue Nov 4 09:00 - 09:16 (00:15) .?laura tty29 Tue Nov 4 11:16 - 11:20 (00:03) m?laura tty29 Tue Nov 4 10:24 - 11:16 (00:52) ?laura tty29 Tue Nov 4 09:36 - 10:24 (00:47) ?lhl ttyd7 Tue Nov 4 05:49 - 05:50 (00:00) *?lin ttyhc Tue Nov 4 12:14 - 12:17 (00:03) i?lock ttyhd Tue Nov 4 12:30 - 12:45 (00:15) ?lock ttyhe Tue Nov 4 12:52 - 12:55 (00:02) ?novy ttyhd Tue Nov 4 08:26 - 10:50 (02:23) &?ouster ttyh2 Tue Nov 4 11:02 - 12:31 (01:29) e?parker ttyhc Tue Nov 4 08:43 - 08:51 (00:08) ?parker ttyhe Tue Nov 4 09:05 - 09:08 (00:03) ?patlee ttyhe Tue Nov 4 09:39 - 10:20 (00:41) "?patt ttyhb Tue Nov 4 09:08 - 09:09 (00:01) a?patt ttyhb Tue Nov 4 07:41 - 07:43 (00:02) ?pattrsn ttyd7 Tue Nov 4 08:21 - 08:48 (00:27) ?peter ttyd1 Tue Nov 4 08:52 - 09:10 (00:17) ?pjw ttyd6 Tue Nov 4 04:23 - 04:25 (00:02) ]?porcarj ttyd1 Tue Nov 4 08:31 - 08:43 (00:11) ?porcarj ttyd7 Tue Nov 4 10:52 - 11:03 (00:11) ?powell ttyd6 Tue Nov 4 11:48 - 12:52 (01:03) ?powell ttyd6 Tue Nov 4 10:50 - 11:03 (00:13) Y?presotto ttyhd Tue Nov 4 12:03 - 12:24 (00:21) ?root console Tue Nov 4 09:31 - 12:50 (03:19) ?schmidt ttyd0 Tue Nov 4 09:42 - 09:46 (00:03) ?shafi ttyhe Tue Nov 4 10:21 - 10:29 (00:07) U?shafi ttyhe Tue Nov 4 09:33 - 09:34 (00:00) ?shen ttyh6 Tue Nov 4 09:11 - 09:12 (00:00) ?shivaji ttyh6 Tue Nov 4 10:06 - 12:53 (02:47) ?sif ttyd6 Tue Nov 4 06:52 - 06:52 (00:00) Q?sif ttyh9 Tue Nov 4 08:20 - 08:22 (00:01) ?simon ttyhc Tue Nov 4 12:03 - 12:03 (00:00) ?simon ttyhd Tue Nov 4 11:20 - 11:23 (00:03) ?simon ttyhd Tue Nov 4 11:14 - 11:19 (00:04) M?siyan ttyh6 Tue Nov 4 12:54 - 13:13 (00:19) ?sklower ttyd6 Tue Nov 4 11:26 - 11:43 (00:16) ?sklower ttyd7 Tue Nov 4 11:50 - 11:52 (00:01)  ?sklower ttyd7 Tue Nov 4 09:25 - 09:37 (00:11) I?sklower ttyd7 Tue Nov 4 09:21 - 09:25 (00:03) ?sklower ttyd8 Tue Nov 4 08:35 - 09:20 (00:44) ?thompson ttyhd Tue Nov 4 10:59 - 11:00 (00:00)  ?tomisawa ttyh2 Tue Nov 4 10:10 - 10:16 (00:05) E ?tygar ttyd1 Tue Nov 4 09:30 - 09:39 (00:09)  ?ucsd ttyd1 Tue Nov 4 07:57 - 08:03 (00:05)  ?upstill ttyhf Tue Nov 4 11:39 - 11:40 (00:01) !?usg ttyd6 Tue Nov 4 05:05 - 05:18 (00:12) A!?uucp ttyd0 Tue Nov 4 10:15 - 11:03 (00:47) !?uucp ttyd0 Tue Nov 4 07:07 - 07:07 (00:00) !?uucp ttyd0 Tue Nov 4 03:11 - 03:12 (00:00) !?uucp ttyd0 Tue Nov 4 03:05 - 03:09 (00:04) ="?uucp ttyd4 Tue Nov 4 08:28 - 08:34 (00:06) |"?uucp ttyd6 Tue Nov 4 07:40 - 07:42 (00:01) "?uucp ttyd6 Tue Nov 4 06:00 - 06:01 (00:00) "?uucp ttyd7 Tue Nov 4 04:24 - 04:24 (00:00) 9#?uucp ttyd7 Tue Nov 4 03:11 - 03:11 (00:00) x#?uucp ttyd7 Tue Nov 4 02:04 - 02:08 (00:03) #?uucp ttyd7 Tue Nov 4 02:01 - 02:03 (00:01) #?uucp ttyd7 Tue Nov 4 01:18 - 01:21 (00:02) 5$?w ttyi8 Tue Nov 4 12:07 - 12:07 (00:00) t$?w ttyi8 Tue Nov 4 12:06 - 12:07 (00:00) $?w ttyi8 Tue Nov 4 07:56 - 07:56 (00:00) $?who tty7 Tue Nov 4 08:07 - 08:07 (00:00) 1%?who ttyd6 Tue Nov 4 11:13 - 11:13 (00:00) p%?who ttyd7 Tue Nov 4 11:28 - 11:28 (00:00) %?wildbill ttyhe Tue Nov 4 09:15 - 09:19 (00:03) %?william ttyd9 Tue Nov 4 12:39 - 12:59 (00:19) -&?william ttyda Tue Nov 4 09:12 - 09:20 (00:08) l&?ying ttyhf Tue Nov 4 11:56 - 13:02 (01:06) &?ying ttyhf Tue Nov 4 08:12 - 11:22 (03:10)  sort MRKdata junk ch:6.6.a junklog 2am cSalt Lake City Logan#Tooele1 Ogden>South Salt Lake2am cBrighamMurray Price* Provo PROGRAM PascalSortExample(INPUT, OUTPUT); !**************************************************************** ! ! This program illustrates how to call the Sort/Merge object ! modules from Pascal. The records to be sorted are read from ! the SAM file Files.In, contained on the distribution diskette. ! The sorted records are written to the SAM file Files.Out. ! ! Files.In contains a sequence of 65-byte records terminated by ! line feeds. All the records must be exactly 65-bytes long ! (including the line feed), or the sort will not work. ! ! Two 6-byte keys are used for the sort, both of type character. ! The first is located 6 bytes from the beginning of the record, ! and the second 26 bytes from the beginning. Both are sorted in ! ascending order. ! !**************************************************************** { CTOS and SAM Types and Constants } CONST ercOk = 0; ercEof = 1; ercInternalError = 8; { note: RETYPE to word bug in Pascal 8.0 } modeAppend = 28001 {RETYPE(WORD, 'ma')}; modeModify = 28013 {RETYPE(WORD, 'mm')}; modeRead = 28018 {RETYPE(WORD, 'mr')}; modeWrite = 28023 {RETYPE(WORD, 'mw')}; pageSize = 512; TYPE ErcType = WORD; FlagType = BOOLEAN; FhType = WORD; LfaType = INTEGER4; ModeType = WORD; POINTER = ADS OF WORD; PbType = ADS OF WORD; QUAD = INTEGER4; { Sort/Merge Types and Constants } CONST ercNoMoreRecords = 3404; charType = 2; TYPE StatusBlockType = PACKED RECORD erc : ErcType; ercDetail : ErcType; END; TYPE PrepareSortBlockType = RECORD lstrWorkFile1 [000] : LSTRING(91); lstrPwWorkFile1 [092] : LSTRING(12); lstrWorkFile2 [105] : LSTRING(91); lstrPwWorkFile2 [197] : LSTRING(12); qsSortWorkfileCreate [210] : QUAD; sWorkFileIncrement [214] : WORD; qsSortWorkArea [216] : QUAD; sRecordMax [220] : WORD; fStableSort [222] : WORD; END; TYPE KeyComponentType = PACKED RECORD rbKey : WORD; cbKey : WORD; typ : WORD; fAscending : WORD; END; TYPE KeyDescriptorType = PACKED RECORD cKeyComponents : WORD; keyComponentDescriptor1 : KeyComponentType; keyComponentDescriptor2 : KeyComponentType; END; { CTOS and SAM Procedures } PROCEDURE CheckErc(erc : ErcType) ; EXTERN; PROCEDURE Exit ; EXTERN; PROCEDURE FatalError(erc : ErcType) ; EXTERN; FUNCTION OpenByteStream( pBs : POINTER; pbFile : POINTER; cbFile : WORD; pbPW : POINTER; cbPW : WORD; mode : modeType; pBuffer : POINTER; cbBuffer : WORD) : ErcType ; EXTERN; FUNCTION ReadBsRecord( pBs : POINTER; pBufferRet : POINTER; sBuffer : WORD; psDataRet : POINTER) : ErcType ; EXTERN; FUNCTION CloseByteStream(pBs : POINTER) : ErcType ; EXTERN; FUNCTION WriteBsRecord( pBs : POINTER; pb : POINTER; cb : WORD; pcbRet : POINTER) : ErcType ; EXTERN; { Sort/Merge Procedures } FUNCTION ConcludeSort ( pStatusBlockRet : POINTER) : ErcType ; EXTERN; FUNCTION DoSort (pStatusBlockRet : POINTER) : ErcType ; EXTERN; FUNCTION PrepareKeySort ( pPrepareSortBlock : POINTER; pKeyDescriptor : POINTER; pSortWorkArea : POINTER; pStatusBlockRet : POINTER) : ErcType ; EXTERN; FUNCTION PrepareSort ( pPrepareSortBlock : POINTER; psKey : POINTER; pSortWorkArea : POINTER; pStatusBlockRet : POINTER) : ErcType ; EXTERN; FUNCTION ReleaseRecord ( psRecord : POINTER; pRecord : POINTER; pStatusBlockRet : POINTER) : ErcType ; EXTERN; FUNCTION ReleaseRecordAndKey ( psRecord : POINTER; pRecord : POINTER; psKey : POINTER; pKey : POINTER; pStatusBlockRet : POINTER) : ErcType ; EXTERN; FUNCTION ReturnRecord ( psRecordRet : POINTER; pRecordRet : POINTER; pStatusBlockRet : POINTER) : ErcType ; EXTERN; FUNCTION ReturnRecordAndKey ( psRecordRet : POINTER; pRecordRet : POINTER; psKeyRet : POINTER; pKeyRet : POINTER; pStatusBlockRet : POINTER) : ErcType ; EXTERN; FUNCTION TerminateSort ( pStatusBlockRet : POINTER) : ErcType ; EXTERN; { Global Variables } VAR [PUBLIC] bsIn : ARRAY [0..129] OF BYTE; bsOut : ARRAY [0..129] OF BYTE; rgbBufferIn : ARRAY [0..1023] OF BYTE; rgbBufferOut : ARRAY [0..1023] OF BYTE; rgbWorkArea : ARRAY [0..8191] OF BYTE; prepareSortBlock : PrepareSortBlockType; keyDescriptor : KeyDescriptorType; statusBlock : StatusBlockType; lstrRecord : LSTRING(66); sRecord : WORD; lstrInFileName : LSTRING(10); lstrOutFileName : LSTRING(10); lstrPw : LSTRING(10); VAR i : INTEGER; j : INTEGER; cbJunk : WORD; erc : WORD; ercJunk : WORD; wRet : WORD; { Procedure to check status blocks, returning for ercOk } PROCEDURE CheckStatus( erc : ErcType; CONST statusBlock : StatusBlockType); BEGIN IF erc <> statusBlock.erc THEN FatalError(ercInternalError); IF erc = ercOk THEN RETURN; WRITELN; WRITELN('Sort Error'); WRITELN(' Status code ', erc); IF statusBlock.ercDetail <> ercOk THEN BEGIN WRITELN(' Detail status code ', statusBlock.ercDetail); END; ercJunk := TerminateSort(ADS statusBlock); Exit; END; { Main Program } BEGIN { Open input file } lstrInFileName := 'Files.In'; lstrPw := NULL; CheckErc(OpenByteStream( ADS bsIn, ADS(lstrInFileName[1]), lstrInFileName.LEN, ADS(lstrPw[1]), lstrPw.LEN, modeRead, ADS rgbBufferIn, SIZEOF(rgbBufferIn))); { Open output file } lstrOutFileName := 'Files.Out'; lstrPw := NULL; CheckErc(OpenByteStream( ADS bsOut, ADS(lstrOutFileName[1]), lstrOutFileName.LEN, ADS(lstrPw[1]), lstrPw.LEN, modeWrite, ADS rgbBufferOut, SIZEOF(rgbBufferOut))); { Initialize prepareSortBlock } prepareSortBlock.lstrWorkFile1 := '[Sys]<$>WorkFile1.Tmp'; prepareSortBlock.lstrPwWorkFile1 := NULL; prepareSortBlock.lstrWorkFile2 := '[Sys]<$>WorkFile2.Tmp'; prepareSortBlock.lstrPwWorkFile2 := NULL; prepareSortBlock.qsSortWorkFileCreate := 1024; prepareSortBlock.sWorkFileIncrement := 512; prepareSortBlock.qsSortWorkArea := SIZEOF(rgbWorkArea); prepareSortBlock.sRecordMax := 65; prepareSortBlock.fStableSort := 0; { Initialize key descriptor } { 2 keys are used. } { The first key is of type character, is 6 bytes long, has an } { offset of 6 bytes from the beginning of the record, and is } { sorted in ascending order. } keyDescriptor.cKeyComponents := 2; keyDescriptor.keyComponentDescriptor1.rbKey := 6; keyDescriptor.keyComponentDescriptor1.cbKey := 6; keyDescriptor.keyComponentDescriptor1.typ := charType; keyDescriptor.keyComponentDescriptor1.fAscending := #0FF; { The second key is of type character, is 6 bytes long, has an } { offset of 26 bytes from the beginning of the record, and is } { sorted in ascending order. } keyDescriptor.keyComponentDescriptor2.rbKey := 26; keyDescriptor.keyComponentDescriptor2.cbKey := 6; keyDescriptor.keyComponentDescriptor2.typ := charType; keyDescriptor.keyComponentDescriptor2.fAscending := #0FF; { Initialize Sort } CheckStatus( PrepareKeySort( ADS prepareSortBlock, ADS keyDescriptor, ADS rgbWorkArea, ADS statusBlock), statusBlock); { Release records } WRITELN; WRITELN('Release Records'); erc := ercOk; sRecord := 65; WHILE erc = ercOk DO BEGIN erc := ReadBsRecord( ADS bsIn, ADS lstrRecord[1], sRecord, ADS wRet); IF erc = ercOk THEN BEGIN lstrRecord.LEN := sRecord-1; { strip off the line feed } WRITELN(lstrRecord); CheckStatus( ReleaseRecord( ADS sRecord, ADS lstrRecord[1], ADS statusBlock), statusBlock); END; END; IF erc <> ercEOF THEN FatalError(erc); { Do Sort } WRITELN('Do Sort'); CheckStatus(DoSort(ADS statusBlock), statusBlock); { Retrieve records } WRITELN('Return Records'); erc := ercOk; WHILE erc = ercOk DO BEGIN erc := ReturnRecord( ADS sRecord, ADS lstrRecord[1], ADS statusBlock); IF erc = ercOk THEN BEGIN IF sRecord <> 65 THEN FatalError(ercInternalError); CheckErc(WriteBsRecord( ADS bsOut, ADS lstrRecord[1], sRecord, ADS cbJunk)); lstrRecord.LEN := sRecord-1; { strip off line feed } WRITELN(lstrRecord); END; END; IF erc <> ercNoMoreRecords THEN CheckStatus(erc, statusBlock); { Close files and end sort } CheckStatus(ConcludeSort(ADS statusBlock), statusBlock); CheckErc(CloseByteStream(ADS bsIn)); CheckErc(CloseByteStream(ADS bsOut)); WRITELN('Sort concluded successfully'); Exit; END.2Ԣ@2| X  ,  ,@&0H`x 8Ph j^(` @` @` )P x0xxxx Courier 72G "10.3%' File: PascalSortExample.Sub %' Version: 8.1 %' Revised: 1/15/84 %' %' Copyright (c) 1984 by Convergent Technologies %' %' %' Ref: Sort/Merge Manual, Appendix B, "Programming Examples" %' %' This submit file is used to compile and link the Sort/Merge %' example Pascal programs: %' %' Submit %' File list PascalSortExample.Sub %' ... %' Pascal PascalSortExample.Pas %' Link PascalSortExample.Obj PascalSortExample.Run Protected [Sys]SortMerge.Lib %' 2Ÿ@   ((()P xxxx Courier 72G B"10.3 Delete in* out*  Copy Datafile insortdata1  Sort datafile outsort1d character:10.0.d y  Copy outsort1d outsort1cd  merge datafile insortdata1 outmerge1a character:10.0.a  merge outsort1d outsort1cd outmerge1d character:10.0.d  sort outmerge1a outsort2d character:10.0.d y  dump outmerge1d outsort2d  sort outmerge1d outsort2a character:10.0.a y  dump outmerge1a outsort2a  merge datafile insortdata1 outmerge1a outmerge2a character:10.0.a  merge outsort2d outsort1d outsort1cd outmerge2d character:10.0.d  sort outmerge2a outsort3d character:10.0.d y  dump outmerge2d outsort3d ;******************************* MODULE HEADER *******************************; ;* *; ;* FILE: MediatorFirst.asm *; ;* *; ;* MACHINE: NGen/SGen LANGUAGE: ASSEMBLER OS: CTOS *; ;* *; ;* DESCRIPTION: *; ;* *; ;* Segment ordering for DLLs that use the mediator (call non-large model *; ;* object module routines.) *; ;* *; ;* TITLE: CTOS SYSTEM SOFTWARE *; ;* *; ;* PROPRIETARY PROGRAM MATERIAL *; ;* *; ;* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE *; ;* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE *; ;* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS *; ;* CORPORATION, DETROIT, MICHIGAN 48232, USA. *; ;* *; ;* COPYRIGHT (C) 1980, 1993 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED *; ;* COPYRIGHT (C) 1980, 1993 UNISYS CORPORATION. ALL RIGHTS RESERVED *; ;* ************************************************************************* *; ;* *; ;* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND *; ;* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, *; ;* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY *; ;* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF *; ;* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO *; ;* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. *; ;* *; ;* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE *; ;* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE *; ;* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. *; ;* *; ;* *; ;*************************** END OF MODULE HEADER ****************************; $MOD386 MediatorTbl SEGMENT WORD PUBLIC 'MediatorTbl' MediatorTbl ENDS ; DGroup segments, with data being first. DGroup GROUP DATA, MEMORY, CONST, STACK, ___STACK Data SEGMENT WORD PUBLIC 'Data' Data ENDS Memory SEGMENT WORD MEMORY 'Memory' Memory ENDS Const SEGMENT WORD PUBLIC 'Const' Const ENDS Stack SEGMENT WORD STACK 'Stack' PUBLIC stackBottom stackBottom LABEL WORD Stack ENDS ___STACK SEGMENT WORD PUBLIC 'Stack' PUBLIC _end_Stack _end_Stack LABEL BYTE ___STACK ENDS ; Init proc used to open semaphore PUBLIC InitMediator PUBLIC ExitMediator EXTRN CheckErc : FAR EXTRN SemClose : FAR EXTRN semMediator : DWORD EXTRN SemOpen : FAR EXTRN SetExitList : FAR MediatorCode SEGMENT WORD PUBLIC 'Code' ASSUME CS:MediatorCode, DS:DGroup InitMediator PROC FAR PUSH DS MOV AX, DGroup MOV DS, AX ; check if previously invoked MOV EAX, DS:WORD PTR [semMediator] CMP EAX, 0 JNZ Finished ; open semaphore MOV EAX, 0 ; no semaphore name PUSH EAX PUSH AX PUSH 4 ; normal, terminatable, user-exclusive semaphore LEA AX, DS:WORD PTR [semMediator] PUSH DS PUSH AX CALL SemOpen PUSH AX CALL CheckErc ; set exit proc ; Set exit proc priority to 0F0; this DLL's exit proc ; should probably run before CtosLib.dll and System.dll (PM users) PUSH 0F001h ; add pProc LEA AX, CS:WORD PTR [ExitMediator] PUSH CS PUSH AX CALL SetExitList PUSH AX CALL CheckErc Finished: POP DS MOV AX, 0 RET InitMediator ENDP ExitMediator PROC FAR PUSH DS MOV AX, DGroup MOV DS, AX ; close our semaphore MOV EAX, DS:DWORD PTR [semMediator] PUSH EAX CALL SemClose POP DS RET ExitMediator ENDP MediatorCode ENDS END ;******************************* MODULE HEADER *******************************; ;* *; ;* FILE: Mediator.asm *; ;* *; ;* MACHINE: NGen/SGen LANGUAGE: ASSEMBLER OS: CTOS *; ;* *; ;* DESCRIPTION: *; ;* *; ;* Stack swapper for calling medium model object module routines from *; ;* large model programs. This swapping is required when linking medium *; ;* model object modules from Unisys libraries into mediated DLLs. *; ;* *; ;* To add a mediated call, create a Mediate macro entry. The two parameters *; ;* are the name of the routine written in non-large model and the number of *; ;* bytes in the parameter list. *; ;* *; ;* For example: To mediate calls to CloseByteStream, the macro would look *; ;* like the following line without the leading and trailing semicolon *; ;* -asterisk, which denotes comment. *; ;* *; ;* Mediate(ProcedureName,N) *; ;* where *; ;* N is the total number of bytes in the parameter list for the procedure. *; ;* Parameters that are described as a byte should be counted as two(2) bytes *; ;* becuase parameters are always pushed onto the stack with word-allignment. *; ;* N should never be an odd value. *; ;* *; ;* TITLE: CTOS SYSTEM SOFTWARE *; ;* *; ;* PROPRIETARY PROGRAM MATERIAL *; ;* *; ;* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE *; ;* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE *; ;* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS *; ;* CORPORATION, DETROIT, MICHIGAN 48232, USA. *; ;* *; ;* COPYRIGHT (C) 1980, 1993 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED *; ;* COPYRIGHT (C) 1980, 1993 UNISYS CORPORATION. ALL RIGHTS RESERVED *; ;* ************************************************************************* *; ;* *; ;* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND *; ;* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, *; ;* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY *; ;* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF *; ;* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO *; ;* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. *; ;* *; ;* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE *; ;* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE *; ;* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. *; ;* *; ;* *; ;*************************** END OF MODULE HEADER ****************************; $INCLUDE(:f1:Mediator.mdf) ; Add mediated calls here %Mediate(CloseByteStream,4) END tP6PGPF tP6PGPF tP6PGPF ueP6GFt8P6XPGPF@uP6PGPF t> P6P PGPFtP6PGPFuP6PGPFt@nP6P;************************* MODULE DEFINITION FILE ****************************; ;* *; ;* FILE: Mediator.def *; ;* *; ;* MACHINE: NGen/SGen LANGUAGE: MODULE DEFINITION OS: CTOS *; ;* *; ;* DESCRIPTION: *; ;* *; ;* Module Definition File for Mediated procedures. *; ;* *; ;* To add a mediated call, equate the ProcName of the call with l_ProcName. *; ;* For example, to add CloseByteStream, place the following line (without *; ;* the leading semicolon-asterisk) in the EXPORTS section after the *; ;* InitMediator entry below. *; ;* *; ;* CloseByteStream = l_CloseByteStream *; ;* *; ;* This causes calls to CloseByteStream to be routed to l_CloseByteStream, *; ;* which is the mediated call defined in Mediator.obj. *; ;* *; ;* An example using CloseByteStream has been provided, which may be deleted. *; ;* *; ;* TITLE: CTOS SYSTEM SOFTWARE *; ;* *; ;* PROPRIETARY PROGRAM MATERIAL *; ;* *; ;* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE *; ;* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE *; ;* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS *; ;* CORPORATION, DETROIT, MICHIGAN 48232, USA. *; ;* *; ;* COPYRIGHT (C) 1980, 1993 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED *; ;* COPYRIGHT (C) 1980, 1993 UNISYS CORPORATION. ALL RIGHTS RESERVED *; ;* ************************************************************************* *; ;* *; ;* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND *; ;* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, *; ;* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY *; ;* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF *; ;* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO *; ;* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. *; ;* *; ;* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE *; ;* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE *; ;* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. *; ;* *; ;* *; ;*************************** END OF MODULE HEADER ****************************; LIBRARY MediatedDll INITINSTANCE InitMediator DESCRIPTION 'Mediator for medium model object modules' STACKSIZE 4096 DATA MULTIPLE SEGMENTS MediatorTbl CLASS 'MediatorTbl' READONLY EXPORTS InitMediator ; Add mediated calls here CloseByteStream = l_CloseByteStream ;****************************** INCLUDE HEADER (.MDF) ************************; ;* *; ;* INCLUDE FILE: Mediator.mdf *; ;* *; ;* MACHINE: NGen/SGen LANGUAGE: ASSEMBLER OS: CTOS *; ;* *; ;* DESCRIPTION: *; ;* *; ;* Macros for Mediator.asm. *; ;* *; ;* TITLE: CTOS SYSTEM SOFTWARE *; ;* *; ;* PROPRIETARY PROGRAM MATERIAL *; ;* *; ;* THIS MATERIAL IS PROPRIETARY TO UNISYS CORPORATION AND IS NOT TO BE *; ;* REPRODUCED, USED OR DISCLOSED EXCEPT IN ACCORDANCE WITH PROGRAM LICENSE *; ;* OR UPON WRITTEN AUTHORIZATION OF THE PATENT DIVISION OF UNISYS *; ;* CORPORATION, DETROIT, MICHIGAN 48232, USA. *; ;* *; ;* *; ;* COPYRIGHT (C) 1980, 1993 CONVERGENT INCORPORATED. ALL RIGHTS RESERVED *; ;* COPYRIGHT (C) 1980, 1993 UNISYS CORPORATION. ALL RIGHTS RESERVED *; ;* ************************************************************************* *; ;* *; ;* UNISYS BELIEVES THAT THE SOFTWARE FURNISHED HEREWITH IS ACCURATE AND *; ;* RELIABLE, AND MUCH CARE HAS BEEN TAKEN IN ITS PREPARATION. HOWEVER, *; ;* NO RESPONSIBILITY, FINANCIAL OR OTHERWISE, CAN BE ACCEPTED FOR ANY *; ;* CONSEQUENCES ARISING OUT OF THE USE OF THIS MATERIAL, INCLUDING LOSS OF *; ;* PROFIT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES, THERE ARE NO *; ;* WARRANTIES WHICH EXTEND BEYOND THE PROGRAM SPECIFICATION. *; ;* *; ;* THE CUSTOMER SHOULD EXERCISE CARE TO ASSURE THAT USE OF THE SOFTWARE *; ;* WILL BE IN FULL COMPLIANCE WITH LAWS, RULES AND REGULATIONS OF THE *; ;* JURISDICTIONS WITH RESPECT TO WHICH IT IS USED. *; ;* *; ;* *; ;*************************** END OF MODULE HEADER ****************************; $MOD386 PUBLIC Mediator PUBLIC MediatorTable PUBLIC semMediator EXTRN _end_Stack : WORD EXTRN SemLock : FAR EXTRN SemClear : FAR MediatorTbl SEGMENT WORD PUBLIC 'MediatorTbl' MediatorTable LABEL BYTE MediatorTbl ENDS Data SEGMENT WORD PUBLIC 'Data' semMediator DD 0 Data ENDS DGroup GROUP Data MediatorCode SEGMENT WORD PUBLIC 'Code' ASSUME CS:MediatorCode, DS:NOTHING oArgs EQU WORD PTR [BP+16] ; 1st word after arguments pProc EQU WORD PTR [BP+6] ; pProc to call sParms EQU WORD PTR [BP+4] ; number of bytes passed to function Mediator PROC NEAR PUSH BP MOV BP, SP PUSH DS MOV AX, DGroup MOV DS, AX ; lock data group from other processes (1 lock per user) MOV EAX, DS:DWORD PTR [semMediator] PUSH EAX MOV AX, 0FFFFh ; wait indefinitely PUSH AX CALL SemLock ; set ES:DI to point to first word of DLL stack PUSH DS POP ES LEA DI, ES:WORD PTR [_end_Stack] SUB DI, 2 ; setup new stack as follows (backwards): ; current SS ; current SP ; function's parameters MOV ES:WORD PTR [DI], SS MOV ES:WORD PTR [DI-2], SP SUB DI, 4 PUSH SS POP DS LEA SI, oArgs ; point to word right after arguments MOV CX, sParms ADD SI, CX ; point to first word of arguments STD ; backwards for stack copying SHR CX, 1 REP MOVSW CLD ; Microsoft C string routines don't clear ADD DI, 2 ; point to last word moved ; set SI to stack address of cs:ip of function to call LEA SI, pProc ; set DS for medium model PUSH ES POP DS ; save current SS:SP MOV CX, SP MOV DX, SS ; switch stacks and store old one CLI MOV AX, ES MOV SS, AX MOV SP, DI STI ; call procedure MOV ES, DX ; DX holds old SS CALL DWORD PTR ES:[SI] ; restore old stack POP CX POP DX CLI MOV SS, DX MOV SP, CX STI PUSH AX ; save call proc's return value ; unlock semaphore MOV EAX, DS:DWORD PTR [semMediator] PUSH EAX CALL SemClear POP AX POP DS POP BP RET 6 Mediator ENDP MediatorCode ENDS %*define(Mediate(Name, sParms)) ( EXTRN %Name : FAR %' store procedure address in table PUBLIC p_%Name MediatorTbl SEGMENT p_%Name DD %Name MediatorTbl ENDS %' create stub call to Mediator() MediatorCode SEGMENT ASSUME CS:MediatorCode PUBLIC l_%Name l_%Name PROC FAR PUSH SI PUSH DI MOV AX, MediatorTbl MOV ES, AX LES BX, ES:DWORD PTR [p_%Name] PUSH ES PUSH BX PUSH %sParms CALL Mediator POP DI POP SI RET %sParms l_%Name ENDP MediatorCode ENDS ) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm