summaryrefslogtreecommitdiff
path: root/appl/wm/minitel
diff options
context:
space:
mode:
Diffstat (limited to 'appl/wm/minitel')
-rw-r--r--appl/wm/minitel/README209
-rw-r--r--appl/wm/minitel/event.b19
-rw-r--r--appl/wm/minitel/event.m19
-rw-r--r--appl/wm/minitel/keyb.b367
-rw-r--r--appl/wm/minitel/mdisplay.b799
-rw-r--r--appl/wm/minitel/mdisplay.disbin0 -> 10304 bytes
-rw-r--r--appl/wm/minitel/mdisplay.m115
-rw-r--r--appl/wm/minitel/mdisplay.sbl1969
-rw-r--r--appl/wm/minitel/miniterm.b1187
-rw-r--r--appl/wm/minitel/miniterm.disbin0 -> 48192 bytes
-rw-r--r--appl/wm/minitel/miniterm.m120
-rw-r--r--appl/wm/minitel/miniterm.sbl6810
-rw-r--r--appl/wm/minitel/mkfile24
-rw-r--r--appl/wm/minitel/modem.b620
-rw-r--r--appl/wm/minitel/screen.b1610
-rw-r--r--appl/wm/minitel/socket.b49
-rw-r--r--appl/wm/minitel/swkeyb.b370
-rw-r--r--appl/wm/minitel/swkeyb.disbin0 -> 6496 bytes
-rw-r--r--appl/wm/minitel/swkeyb.m21
-rw-r--r--appl/wm/minitel/swkeyb.sbl724
20 files changed, 15032 insertions, 0 deletions
diff --git a/appl/wm/minitel/README b/appl/wm/minitel/README
new file mode 100644
index 00000000..82f3202e
--- /dev/null
+++ b/appl/wm/minitel/README
@@ -0,0 +1,209 @@
+Minitel Emulation for Inferno
+
+This directory contains the source of `miniterm', a minitel emulator
+for Inferno. Miniterm is written in Limbo. The main components are:
+
+ miniterm.m - common constants
+ miniterm.b - terminal emulator, messaging and Minitel `protocol`
+ event.[mb] - inter-module message format
+ keyb.b - Minitel keyboard module
+ modem.b - Minitel modem module
+ screen.b - Minitel screen module
+ socket.b - Minitel socket module
+ arg.m - basic command line argument handling
+ mdisplay.[mb] - Videotex display module
+ swkeyb.[mb] - Minitel aware software keyboard
+
+ fonts.tgz which expands into:
+
+ fonts/minitel - external and subfont directory (`bind -b' into /fonts)
+ fonts/minitel/f40x25 - 40 column external font
+ fonts/minitel/14x17
+ fonts/minitel/14x17xoe
+ fonts/minitel/14x17arrow
+ fonts/minitel/f40x25g1 - 40 column semigraphic external font
+ fonts/minitel/vid14x17
+ fonts/minitel/f40x25h - 40 column double height external font
+ fonts/minitel/14x34
+ fonts/minitel/14x34xoe
+ fonts/minitel/14x34arrow
+ fonts/minitel/f40x25w - 40 column double width external font
+ fonts/minitel/28x17
+ fonts/minitel/28x17xoe
+ fonts/minitel/28x17arrow
+ fonts/minitel/f40x25s - 40 column double size external font
+ fonts/minitel/28x34xoe
+ fonts/minitel/28x34arrow
+ fonts/minitel/f80x25 - 80 column external font
+ fonts/minitel/8x12
+ fonts/minitel/8x12xoe
+ fonts/minitel/8x12arrow
+
+The fonts subdirectory should be bound into /fonts:
+ bind -b fonts /fonts
+or the directory fonts/minitel copied to /fonts/minitel before invoking the emulator.
+The names of the external fonts are
+known to the Videotex display module. Similarly, the files:
+ /dev/modem
+ /dev/modemctl
+are known to the modem module, but you can ignore them if
+(as is almost certain) you are using the Internet-minitel gateway
+and you haven't got appropriate modem hardware anyway.
+
+To build
+ mkdir /usr/inferno/dis/wm/minitel
+ mk install
+
+The code models the structure outlined in the Minitel 1B specification
+provided by France Telecom. However, much more interpretation was
+required to display the majority of screens currently seen on Minitel.
+Additional information (although sketchy) was found on the Internet by
+searching for Minitel or Videotex and also by examination of the codes
+sent by minitel servers and experimenting with replies. There must be
+some more up to date information somewhere!
+
+We don't support downloadable fonts, but correctly filter them out.
+
+The file miniterm.b contains the code for the minitel `terminal' with
+which the other modules communicate. The keyboard, modem, socket,
+screen and terminal are run as separate threads which communicate by
+calling:
+ send(e: ref Event)
+The clue to the intermodule communication is in Terminal.run which
+does something like:
+ for(;;) {
+ ev =<- t.in =>
+ eva := protocol(ev);
+ while(len eva > 0) {
+ post(eva[0]);
+ eva = eva[1:];
+ }
+ # then deliver any `posted' messages (without blocking)
+ }
+An Event `ev' may typically be an Edata type (say from the modem) or
+an Eproto type for internal interpretation. In the call:
+ eva := protocol(ev)
+The function protocol() dissects Edata messages to produce an inline
+sequence of Edata and Eproto messages. The function post() queues
+messages for delivery to the appropriate modules. For example, data
+from the modem might be destined for the screen and the socket module.
+Messages are queued until they can be delivered. That way the line:
+ ev =<- t.in
+is executed in a timely way and the other modules can be written to
+make blocking writes (via send()) and to service reads when they are
+ready.
+
+In many places in the code lines appear with comments like:
+ if(p.skip < 1 || p.skip > 127) # 5.0
+These refer to sections of the Minitel specification which explain the
+code.
+
+The mdisplay code provides a Videotex display using Inferno
+primitives. The screen, keyboard and modem modules interpret data as
+described in the equivalent section of the Minitel specification. The
+socket module has not been implemented but currently performs a `null'
+function and could easily be added if required.
+
+
+- Namespace
+We always expect the fonts to appear in /fonts and the softmodem
+to appear as /dev/modem and /dev/modemctl.
+
+- Invocation
+If invoked with no argument, miniterm uses the France Telecom
+internet gateway by default (tcp!193.252.252.250!513).
+If the argument starts with `modem' then
+a direct connection through /dev/modem will be established.
+
+An argument beginning with anything other than `modem' will
+be assumed to be an address suitable for dial(). For example:
+
+ wm/minitel/miniterm tcp!193.252.252.250!513
+
+will connect to the current France Telecom internet server.
+
+For direct connections a modem `init' string and an optional
+phone number can follow the modem prefix, as in:
+
+ wm/minitel/miniterm modem!F3!3615
+
+or
+
+ wm/minitel/miniterm modem!F3!01133836431414
+
+The `F3' is the code which instructs the softmodem to enable V.23
+and needs to be passed when connecting to the FT servers.
+To use pulse dialing instead of tone dialing the phone number
+can be prefixed with a 'P' as in:
+
+ wm/minitel/miniterm modem!F3!P3614
+
+If the parameter specifies a network connection or a direct connection
+with a phone number the software will attempt to connect immediately.
+If Cx/Fin is used to disconnect and then re-connect it will use the
+same IP address for a network connection or prompt for a new
+phone number in the case of a direct connection. When prompting
+for a new number the top row of the screen is used to allow the user
+to edit the last used number. Simple editing is available, and the minitel
+keys do the obvious things.
+
+
+
+** Notes on the 15th December 1998 Release **
+
+- Software keyboard
+A version of the software keyboard which understands some of
+the minitel keyboard mappings is included. For example, hitting 'A' results
+in a capital 'A' on the screen in spite of the Videotex case mapping.
+
+- Minitel function keys
+The minitel keys are displayed on the right hand side of the screen
+in 40 column mode on a network connection
+and can be swapped to the left hand side by hitting the <- key.
+In direct dial mode and 80 column network mode the keys are
+displayed at the bottom of the screen.
+In network mode they are re-displayed as appropriate on 40 to 80
+column mode changes.
+
+
+Known Omission
+-------------
+- Error Correction (direct dial only)
+There is no screen button to enable error correction in the release.
+If a server asks for error correction it will be enabled. It looks as though
+we need to include a key to enable it. Without it direct dial screens are
+occasionally corrupted.
+
+- Software Keyboard Handling
+We need to add some code to update the software keyboard and
+bring it to the foreground on a mode change.
+
+- Full 80 column support
+I am aware of some screens which don't look correct in 80 column
+mode (and others that do). See `EMAIL' then choose USENET and
+press SUITE a few times. I believe it behaves as specified but as we
+have seen with the 40 column Videotex mode the specification
+is not sufficient to display most of the minitel screens correctly.
+80 column support needs just a little more work.
+It may be, too, that the 80 column font could be made much more
+readable by utilising a few more pixels on the screen now that we
+are able to cover the toolbar.
+
+- Full toolbar integration
+Experimentation will show whether there needs to be more
+integration with the toolbar.
+
+Known Bugs
+----------
+- Softmodem disconnection
+Often, the modem does not hangup correctly.
+
+- Choose `USA' from a network connection
+USA (from a network connection) gives an `iC' in bottom left hand
+corner of screen. Possibly a server issue. Doesn't occur when
+connecting directly. The server is really sending this sequence.
+Both the FT emulator and their explorer plug-in suffer from it too.
+
+
+John Bates
+Vita Nuova Limited
diff --git a/appl/wm/minitel/event.b b/appl/wm/minitel/event.b
new file mode 100644
index 00000000..f751f55b
--- /dev/null
+++ b/appl/wm/minitel/event.b
@@ -0,0 +1,19 @@
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+Event.str(ev: self ref Event) : string
+{
+ s := "?";
+ pick e := ev {
+ Edata =>
+ s = sprint("Edata %d = ", len e.data);
+ for(i:=0; i<len e.data; i++)
+ s += hex(int e.data[i], 2) + " ";
+ Equit =>
+ s = "Equit";
+ Eproto =>
+ s = sprint("Eproto %ux (%s)", e.cmd, e.s);
+ }
+ return s;
+}
diff --git a/appl/wm/minitel/event.m b/appl/wm/minitel/event.m
new file mode 100644
index 00000000..1b524363
--- /dev/null
+++ b/appl/wm/minitel/event.m
@@ -0,0 +1,19 @@
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+Event: adt {
+ path: int; # path for delivery
+ from: int; # sending module (for reply)
+ pick {
+ Edata =>
+ data: array of byte;
+ Eproto =>
+ cmd: int;
+ s: string;
+ a0, a1, a2: int; # parameters
+ Equit =>
+ }
+
+ str: fn(e: self ref Event) : string; # convert to readable form
+};
diff --git a/appl/wm/minitel/keyb.b b/appl/wm/minitel/keyb.b
new file mode 100644
index 00000000..aba5485d
--- /dev/null
+++ b/appl/wm/minitel/keyb.b
@@ -0,0 +1,367 @@
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+# special keyboard operations
+Extend, # enable cursor and editing keys and control chars
+C0keys, # cursor keys send BS,HT,LF and VT
+Invert # case inversion
+ : con 1 << iota;
+
+Keyb: adt {
+ m: ref Module; # common attributes
+ in: chan of ref Event;
+
+ cmd: chan of string; # from Tk (keypresses and focus)
+ spec: int; # special keyboard extensions
+
+ init: fn(k: self ref Keyb, toplevel: ref Tk->Toplevel);
+ reset: fn(k: self ref Keyb);
+ run: fn(k: self ref Keyb);
+ quit: fn(k: self ref Keyb);
+ map: fn(k: self ref Keyb, key:int): array of byte;
+};
+
+Keyb.init(k: self ref Keyb, toplevel: ref Tk->Toplevel)
+{
+ k.in = chan of ref Event;
+ k.cmd = chan of string;
+ tk->namechan(toplevel, k.cmd, "keyb"); # Tk -> keyboard
+ k.reset();
+}
+
+Keyb.reset(k: self ref Keyb)
+{
+ k.m = ref Module(Pmodem|Psocket, 0);
+}
+
+ask(in: chan of string, out: chan of string)
+{
+ keys: string;
+
+ T.mode = Videotex;
+ S.setmode(Videotex);
+# clear(S);
+ prompt: con "Numéroter: ";
+ number := M.lastdialstr;
+ S.msg(prompt);
+
+Input:
+ for(;;) {
+ n := len prompt + len number;
+ # guard length must be > len prompt
+ if (n > 30)
+ n -= 30;
+ else
+ n = 0;
+ S.msg(prompt + number[n:]);
+ keys = <- in;
+ if (keys == nil)
+ return;
+
+ keys = canoncmd(keys);
+
+ case keys {
+ "connect" or "send" =>
+ break Input;
+ "correct" =>
+ if(len number > 0)
+ number = number[0: len number -1];
+ "cancel" =>
+ number = "";
+ break Input;
+ "repeat" or "index" or "guide" or "next" or "previous" =>
+ ;
+ * =>
+ number += keys;
+ }
+ }
+
+ S.msg(nil);
+ for (;;) alt {
+ out <- = number =>
+ return;
+ keys = <- in =>
+ if (keys == nil)
+ return;
+ }
+}
+
+Keyb.run(k: self ref Keyb)
+{
+ dontask := chan of string;
+ askchan := dontask;
+ askkeys := chan of string;
+Runloop:
+ for(;;){
+ alt {
+ ev := <- k.in =>
+ pick e := ev {
+ Equit =>
+ break Runloop;
+ Eproto =>
+ case e.cmd {
+ Creset =>
+ k.reset();
+ Cproto =>
+ case e.a0 {
+ START =>
+ case e.a1 {
+ LOWERCASE =>
+ k.spec |= Invert;
+ }
+ STOP =>
+ case e.a1 {
+ LOWERCASE =>
+ k.spec &= ~Invert;
+ }
+ }
+ * => break;
+ }
+ }
+ cmd := <- k.cmd =>
+ if(debug['k'] > 0) {
+ fprint(stderr, "Tk %s\n", cmd);
+ }
+ (n, args) := sys->tokenize(cmd, " ");
+ if(n >0)
+ case hd args {
+ "key" =>
+ (key, nil) := toint(hd tl args, 16);
+ if(askchan != dontask) {
+ s := minikey(key);
+ if (s == nil)
+ s[0] = key;
+ askkeys <-= s;
+ break;
+ }
+ keys := k.map(key);
+ if(keys != nil) {
+ send(ref Event.Edata(k.m.path, Mkeyb, keys));
+ }
+ "skey" => # minitel key hit (soft key)
+ if(hd tl args == "Exit") {
+ if(askchan != dontask) {
+ askchan = dontask;
+ askkeys <-= nil;
+ }
+ if(T.state == Online || T.state == Connecting) {
+ seq := keyseq("connect");
+ if(seq != nil) {
+ send(ref Event.Edata(k.m.path, Mkeyb, seq));
+ send(ref Event.Edata(k.m.path, Mkeyb, seq));
+ }
+ send(ref Event.Eproto(Pmodem, Mkeyb, Cdisconnect, "", 0,0,0));
+ }
+ send(ref Event.Equit(0, 0));
+ break;
+ }
+ if(askchan != dontask) {
+ askkeys <-= hd tl args;
+ break;
+ }
+ case hd tl args {
+ "Connect" =>
+ case T.state {
+ Local =>
+ if(M.connect == Network)
+ send(ref Event.Eproto(Pmodem, Mkeyb, Cconnect, "", 0,0,0));
+ else {
+ askchan = chan of string;
+ spawn ask(askkeys, askchan);
+ }
+ Connecting =>
+ send(ref Event.Eproto(Pmodem, Mkeyb, Cdisconnect, "", 0,0,0));
+ Online =>
+ seq := keyseq("connect");
+ if(seq != nil)
+ send(ref Event.Edata(k.m.path, Mkeyb, seq));
+ }
+ * =>
+ seq := keyseq(hd tl args);
+ if(seq != nil)
+ send(ref Event.Edata(k.m.path, Mkeyb, seq));
+ }
+ "click" => # fetch a word from the display
+ x := int hd tl args;
+ y := int hd tl tl args;
+ word := disp->GetWord(Point(x, y));
+ if(word != nil) {
+ if (askchan != dontask) {
+ askkeys <- = word;
+ break;
+ }
+ if (T.state == Local) {
+ if (canoncmd(word) == "connect") {
+ if(M.connect == Network)
+ send(ref Event.Eproto(Pmodem, Mkeyb, Cconnect, "", 0,0,0));
+ else {
+ askchan = chan of string;
+ spawn ask(askkeys, askchan);
+ }
+ break;
+ }
+ }
+ seq := keyseq(word);
+ if(seq != nil)
+ send(ref Event.Edata(k.m.path, Mkeyb, seq));
+ else {
+ send(ref Event.Edata(k.m.path, Mkeyb, array of byte word ));
+ send(ref Event.Edata(k.m.path, Mkeyb, keyseq("send")));
+ }
+ }
+
+ }
+ dialstr := <-askchan =>
+ askchan = dontask;
+ if(dialstr != nil) {
+ M.dialstr = dialstr;
+ send(ref Event.Eproto(Pmodem, Mkeyb, Cconnect, "", 0,0,0));
+ }
+ }
+ }
+ send(nil);
+}
+
+
+# Perform mode specific key translation
+# returns nil on invalid keypress,
+Keyb.map(nil: self ref Keyb, key: int): array of byte
+{
+ # hardware to minitel keyboard mapping
+ cmd := minikey(key);
+ if (cmd != nil) {
+ seq := keyseq(cmd);
+ if(seq != nil)
+ return seq;
+ }
+
+ # alphabetic (with case mapping)
+ case T.mode {
+ Videotex =>
+ if(key >= 'A' && key <= 'Z')
+ return array [] of { byte ('a' + (key - 'A'))};
+ if(key >= 'a' && key <= 'z')
+ return array [] of {byte ('A' + (key - 'a'))};
+ Mixed or Ascii =>
+ if(key >= 'A' && key <= 'Z' || key >= 'a' && key <= 'z')
+ return array [] of {byte key};
+ };
+
+ # Numeric
+ if(key >= '0' && key <= '9')
+ return array [] of {byte key};
+
+ # Control-A -> Control-Z, Esc - columns 0 and 1
+ if(key >= 16r00 && key <=16r1f)
+ case T.mode {
+ Videotex =>
+ return nil;
+ Mixed or Ascii =>
+ return array [] of {byte key};
+ }
+
+ # miscellaneous key mapping
+ case key {
+ 16r20 => ; # space
+ 16ra3 => return array [] of { byte 16r19, byte 16r23 }; # pound
+ '!' or '"' or '#' or '$'
+ or '%' or '&' or '\'' or '(' or ')'
+ or '*' or '+' or ',' or '-'
+ or '.' or ':' or ';' or '<'
+ or '=' or '>' or '?' or '@' => ;
+ KF13 => # request for error correction - usually Fnct M + C
+ if((M.spec&Ecp) == 0 && T.state == Online && T.connect == Direct) {
+fprint(stderr, "requesting Ecp\n");
+ return array [] of { byte SEP, byte 16r4a };
+ }
+ return nil;
+ * => return nil;
+ }
+ return array [] of {byte key};
+}
+
+Keyb.quit(k: self ref Keyb)
+{
+ if(k==nil);
+}
+
+canoncmd(s : string) : string
+{
+ s = tolower(s);
+ case s {
+ "connect" or "cx/fin" or
+ "connexion" or "fin" => return "connect";
+ "send" or "envoi" => return "send";
+ "repeat" or "repetition" => return "repeat";
+ "index" or "sommaire" or "somm"
+ => return "index";
+ "guide" => return "guide";
+ "correct" or "correction" => return "correct";
+ "cancel" or "annulation" or "annul" or "annu"
+ => return "cancel";
+ "next" or "suite" => return "next";
+ "previous" or "retour" or "retou"
+ => return "previous";
+ }
+ return s;
+}
+
+# map softkey names to the appropriate byte sequences
+keyseq(skey: string): array of byte
+{
+ b2 := 0;
+ asterisk := 0;
+ if(skey == nil || len skey == 0)
+ return nil;
+ if(skey[0] == '*') {
+ asterisk = 1;
+ skey = skey[1:];
+ }
+ skey = canoncmd(skey);
+ case skey {
+ "connect" => b2 = 16r49;
+ "send" => b2 = 16r41;
+ "repeat" => b2 = 16r43;
+ "index" => b2 = 16r46;
+ "guide" => b2 = 16r44;
+ "correct" => b2 = 16r47;
+ "cancel" => b2 = 16r45;
+ "next" => b2 = 16r48;
+ "previous" => b2 = 16r42;
+ }
+ if(b2) {
+ if(asterisk)
+ return array [] of { byte '*', byte SEP, byte b2};
+ else
+ return array [] of { byte SEP, byte b2};
+ } else
+ return nil;
+}
+
+# map hardware or software keyboard presses to minitel functions
+minikey(key: int): string
+{
+ case key {
+ Kup or KupPC =>
+ return"previous";
+ Kdown or KdownPC =>
+ return "next";
+ Kenter =>
+ return "send";
+ Kback =>
+ return "correct";
+ Kesc =>
+ return "cancel";
+ KF1 =>
+ return "guide";
+ KF2 =>
+ return "connect";
+ KF3 =>
+ return "repeat";
+ KF4 =>
+ return "index";
+ * =>
+ return nil;
+ }
+} \ No newline at end of file
diff --git a/appl/wm/minitel/mdisplay.b b/appl/wm/minitel/mdisplay.b
new file mode 100644
index 00000000..b3c629f9
--- /dev/null
+++ b/appl/wm/minitel/mdisplay.b
@@ -0,0 +1,799 @@
+implement MDisplay;
+
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+# - best viewed with acme!
+
+include "sys.m";
+include "draw.m";
+include "mdisplay.m";
+
+sys : Sys;
+draw : Draw;
+
+Context, Point, Rect, Font, Image, Display, Screen : import draw;
+
+
+# len cell == number of lines
+# len cell[0] == number of cellmap cells per char
+# (x,y)*cellsize == font glyph clipr
+
+cellS := array [] of {array [] of {(0, 0)}};
+cellW := array [] of {array [] of {(0, 0), (1, 0)}};
+cellH := array [] of {array [] of {(0, 1)}, array [] of {(0, 0)}};
+cellWH := array [] of {array [] of {(0, 1), (1, 1)}, array [] of {(0, 0), (1, 0)}};
+
+Cellinfo : adt {
+ font : ref Font;
+ ch, attr : int;
+ clipmod : (int, int);
+};
+
+
+# current display attributes
+display : ref Display;
+window : ref Image;
+frames := array [2] of ref Image;
+update : chan of int;
+
+colours : array of ref Image;
+bright : ref Image;
+
+# current mode attributes
+cellmap : array of Cellinfo;
+nrows : int;
+ncols : int;
+ulheight : int;
+curpos : Point;
+winoff : Point;
+cellsize : Point;
+modeattr : con fgWhite | bgBlack;
+showC := 0;
+delims := 0;
+modbbox := Rect((0,0),(0,0));
+blankrow : array of Cellinfo;
+
+ctxt : ref Context;
+font : ref Font; # g0 videotex font - extended with unicode g2 syms
+fonth : ref Font; # double height version of font
+fontw : ref Font; # double width
+fonts : ref Font; # double size
+fontg1 : ref Font; # semigraphic videotex font (ch+128=separated)
+fontfr : ref Font; # french character set
+fontusa : ref Font; # american character set
+
+
+Init(c : ref Context) : string
+{
+ sys = load Sys Sys->PATH;
+ draw = load Draw Draw->PATH;
+
+ if (c == nil || c.display == nil)
+ return "no display context";
+
+ ctxt = c;
+ disp := ctxt.display;
+
+ black := disp.rgb2cmap(0, 0, 0);
+ blue := disp.rgb2cmap(0, 0, 255);
+ red := disp.rgb2cmap(255, 0, 0);
+ magenta := disp.rgb2cmap(255, 0, 255);
+ green := disp.rgb2cmap(0, 255, 0);
+ cyan := disp.rgb2cmap(0, 255, 255);
+ yellow := disp.rgb2cmap(255, 255, 0);
+ white := disp.rgb2cmap(240, 240, 240);
+
+ iblack := disp.color(black);
+ iblue := disp.color(blue);
+ ired := disp.color(red);
+ imagenta := disp.color(magenta);
+ igreen := disp.color(green);
+ icyan := disp.color(cyan);
+ iyellow := disp.color(yellow);
+ iwhite := disp.color(white);
+
+ colours = array [] of { iblack, iblue, ired, imagenta,
+ igreen, icyan, iyellow, iwhite};
+ bright = disp.color(disp.rgb2cmap(255, 255, 255));
+
+ update = chan of int;
+ spawn Update(update);
+ display = disp;
+ return nil;
+}
+
+Quit()
+{
+ if (update != nil)
+ update <- = QuitUpdate;
+ update = nil;
+ window = nil;
+ frames[0] = nil;
+ frames[1] = nil;
+ cellmap = nil;
+ display = nil;
+}
+
+Mode(r : Draw->Rect, w, h, ulh, d : int, fontpath : string) : (string, ref Draw->Image)
+{
+ if (display == nil)
+ # module not properly Init()'d
+ return ("not initialized", nil);
+
+ curpos = Point(-1, -1);
+ if (window != nil)
+ update <- = Pause;
+
+ cellmap = nil;
+ window = nil;
+ (dx, dy) := (r.dx(), r.dy());
+ if (dx == 0 || dy == 0) {
+ return (nil, nil);
+ }
+
+ black := display.rgb2cmap(0, 0, 0);
+ window = ctxt.screen.newwindow(r, Draw->Refbackup, black);
+ if (window == nil)
+ return ("cannot create window", nil);
+
+ window.origin(Point(0,0), r.min);
+ winr := Rect((0,0), (dx, dy));
+ frames[0] = display.newimage(winr, window.chans, 0, black);
+ frames[1] = display.newimage(winr, window.chans, 0, black);
+
+ if (window == nil || frames[0] == nil || frames[1] == nil) {
+ window = nil;
+ return ("cannot allocate display resources", nil);
+ }
+
+ ncols = w;
+ nrows = h;
+ ulheight = ulh;
+ delims = d;
+ showC = 0;
+
+ cellmap = array [ncols * nrows] of Cellinfo;
+
+ font = Font.open(display, fontpath);
+ fontw = Font.open(display, fontpath + "w");
+ fonth = Font.open(display, fontpath + "h");
+ fonts = Font.open(display, fontpath + "s");
+ fontg1 = Font.open(display, fontpath + "g1");
+ fontfr = Font.open(display, fontpath + "fr");
+ fontusa = Font.open(display, fontpath + "usa");
+
+ if (font != nil)
+ cellsize = Point(font.width(" "), font.height);
+ else
+ cellsize = Point(dx/ncols, dy / nrows);
+
+ winoff.x = (dx - (cellsize.x * ncols)) / 2;
+ winoff.y = (dy - (cellsize.y * nrows)) /2;
+ if (winoff.x < 0)
+ winoff.x = 0;
+ if (winoff.y < 0)
+ winoff.y = 0;
+
+ blankrow = array [ncols] of {* => Cellinfo(font, ' ', modeattr | fgWhite, (0,0))};
+ for (y := 0; y < nrows; y++) {
+ col0 := y * ncols;
+ cellmap[col0:] = blankrow;
+ }
+
+# frames[0].clipr = frames[0].r;
+# frames[1].clipr = frames[1].r;
+# frames[0].draw(frames[0].r, colours[0], nil, Point(0,0));
+# frames[1].draw(frames[1].r, colours[0], nil, Point(0,0));
+# window.draw(window.r, colours[0], nil, Point(0,0));
+ update <- = Continue;
+ return (nil, window);
+}
+
+Cursor(pt : Point)
+{
+ if (update == nil || cellmap == nil)
+ # update thread (cursor/character flashing) not running
+ return;
+
+ # normalize pt
+ pt.x--;
+
+ curpos = pt;
+ update <- = CursorSet;
+}
+
+Put(str : string, pt : Point, charset, attr, insert : int)
+{
+ if (cellmap == nil || str == nil)
+ # nothing to do
+ return;
+
+ # normalize pt
+ pt.x--;
+
+ f : ref Font;
+ cell := cellS;
+
+ case charset {
+ videotex =>
+ if (!(attr & attrD))
+ attr &= (fgMask | attrF | attrH | attrW | attrP);
+ if (attr & attrW && attr & attrH) {
+ cell = cellWH;
+ f = fonts;
+ } else if (attr & attrH) {
+ cell = cellH;
+ f = fonth;
+ } else if (attr & attrW) {
+ cell = cellW;
+ f = fontw;
+ } else {
+ f = font;
+ }
+
+ semigraphic =>
+ f = fontg1;
+ if (attr & attrL) {
+ # convert to "separated"
+ newstr := "";
+ for (ix := 0; ix < len str; ix++)
+ newstr[ix] = str[ix] + 16r80;
+ str = newstr;
+ }
+ # semigraphic charset does not support size / polarity attributes
+ # attrD always set later once field attr established
+ attr &= ~(attrD | attrH | attrW | attrP | attrL);
+
+ french => f = fontfr;
+ american => f = fontusa;
+ * => f = font;
+ }
+
+ update <- = Pause;
+
+ txty := pt.y - (len cell - 1);
+ for (cellix := len cell - 1; cellix >= 0; cellix--) {
+ y := pt.y - cellix;
+
+ if (y < 0)
+ continue;
+ if (y >= nrows)
+ break;
+
+ col0 := y * ncols;
+ colbase := pt.y * ncols;
+
+ if (delims && !(attr & attrD)) {
+ # seek back for a delimiter
+ mask : int;
+ delimattr := modeattr;
+
+ # semigraphics only inherit attrC from current field
+ if (charset == semigraphic)
+ mask = attrC;
+ else
+ mask = bgMask | attrC | attrL;
+
+ for (ix := pt.x-1; ix >= 0; ix--) {
+ cix := ix + col0;
+ if (cellmap[cix].attr & attrD) {
+ if (cellmap[cix].font == fontg1 && f != fontg1)
+ # don't carry over attrL from semigraphic field
+ mask &= ~attrL;
+
+ delimattr = cellmap[cix].attr;
+ break;
+ }
+ }
+ attr = (attr & ~mask) | (delimattr & mask);
+
+ # semigraphics validate background colour
+ if (charset == semigraphic)
+ attr |= attrD;
+ }
+
+ strlen := len cell[0] * len str;
+ gfxwidth := cellsize.x * strlen;
+ srco := Point(pt.x*cellsize.x, y*cellsize.y);
+
+ if (insert) {
+ # copy existing cells and display to new position
+ if (pt.x + strlen < ncols) {
+ for (destx := ncols -1; destx > pt.x; destx--) {
+ srcx := destx - strlen;
+ if (srcx < 0)
+ break;
+ cellmap[col0 + destx] = cellmap[col0 + srcx];
+ }
+
+ # let draw() do the clipping for us
+ dsto := Point(srco.x + gfxwidth, srco.y);
+ dstr := Rect((dsto.x, srco.y), (ncols * cellsize.x, srco.y + cellsize.y));
+
+ frames[0].clipr = frames[0].r;
+ frames[1].clipr = frames[1].r;
+ frames[0].draw(dstr, frames[0], nil, srco);
+ frames[1].draw(dstr, frames[1], nil, srco);
+ if (modbbox.dx() == 0)
+ modbbox = dstr;
+ else
+ modbbox = boundingrect(modbbox, dstr);
+ }
+ }
+
+ # copy-in new string
+ x := pt.x;
+ for (strix := 0; x < ncols && strix < len str; strix++) {
+ for (clipix := 0; clipix < len cell[cellix]; (x, clipix) = (x+1, clipix+1)) {
+ if (x < 0)
+ continue;
+ if (x >= ncols)
+ break;
+ cmix := col0 + x;
+ cellmap[cmix].font = f;
+ cellmap[cmix].ch = str[strix];
+ cellmap[cmix].attr = attr;
+ cellmap[cmix].clipmod = cell[cellix][clipix];
+ }
+ }
+
+ # render the new string
+ txto := Point(srco.x, txty * cellsize.y);
+ strr := Rect(srco, (srco.x + gfxwidth, srco.y + cellsize.y));
+ if (strr.max.x > ncols * cellsize.x)
+ strr.max.x = ncols * cellsize.x;
+
+ drawstr(str, f, strr, txto, attr);
+
+ # redraw remainder of line until find cell not needing redraw
+
+ # this could be optimised by
+ # spotting strings with same attrs, font and clipmod pairs
+ # and write out whole string rather than processing
+ # a char at a time
+
+ attr2 := attr;
+ mask := bgMask | attrC | attrL;
+ s := "";
+ for (; delims && x < ncols; x++) {
+ if (x < 0)
+ continue;
+ newattr := cellmap[col0 + x].attr;
+
+ if (cellmap[col0 + x].font == fontg1) {
+ # semigraphics act as bg colour delimiter
+ attr2 = (attr2 & ~bgMask) | (newattr & bgMask);
+ mask &= ~attrL;
+ } else
+ if (newattr & attrD)
+ break;
+
+ if ((attr2 & mask) == (newattr & mask))
+ break;
+ newattr = (newattr & ~mask) | (attr2 & mask);
+ cellmap[col0 + x].attr = newattr;
+ s[0] = cellmap[col0 + x].ch;
+ (cx, cy) := cellmap[col0 + x].clipmod;
+ f2 := cellmap[col0 + x].font;
+
+ cellpos := Point(x * cellsize.x, y * cellsize.y);
+ clipr := Rect(cellpos, cellpos.add(Point(cellsize.x, cellsize.y)));
+ drawpt := cellpos.sub(Point(cx*cellsize.x, cy*cellsize.y));
+ drawstr(s, f2, clipr, drawpt, newattr);
+ }
+ }
+ update <- = Continue;
+}
+
+Scroll(topline, nlines : int)
+{
+ if (cellmap == nil || nlines == 0)
+ return;
+
+ blankr : Rect;
+ scr := Rect((0,topline * cellsize.y), (ncols * cellsize.x, nrows * cellsize.y));
+
+ update <- = Pause;
+
+ frames[0].clipr = scr;
+ frames[1].clipr = scr;
+ dstr := scr.subpt(Point(0, nlines * cellsize.y));
+
+ frames[0].draw(dstr, frames[0], nil, frames[0].clipr.min);
+ frames[1].draw(dstr, frames[1], nil, frames[1].clipr.min);
+
+ if (nlines > 0) {
+ # scroll up - copy up from top
+ if (nlines > nrows - topline)
+ nlines = nrows - topline;
+ for (y := nlines + topline; y < nrows; y++) {
+ srccol0 := y * ncols;
+ dstcol0 := (y - nlines) * ncols;
+ cellmap[dstcol0:] = cellmap[srccol0:srccol0+ncols];
+ }
+ for (y = nrows - nlines; y < nrows; y++) {
+ col0 := y * ncols;
+ cellmap[col0:] = blankrow;
+ }
+ blankr = Rect(Point(0, scr.max.y - (nlines * cellsize.y)), scr.max);
+ } else {
+ # scroll down - copy down from bottom
+ nlines = -nlines;
+ if (nlines > nrows - topline)
+ nlines = nrows - topline;
+ for (y := (nrows - 1) - nlines; y >= topline; y--) {
+ srccol0 := y * ncols;
+ dstcol0 := (y + nlines) * ncols;
+ cellmap[dstcol0:] = cellmap[srccol0:srccol0+ncols];
+ }
+ for (y = topline; y < nlines; y++) {
+ col0 := y * ncols;
+ cellmap[col0:] = blankrow;
+ }
+ blankr = Rect(scr.min, (scr.max.x, scr.min.y + (nlines * cellsize.y)));
+ }
+ frames[0].draw(blankr, colours[0], nil, Point(0,0));
+ frames[1].draw(blankr, colours[0], nil, Point(0,0));
+ if (modbbox.dx() == 0)
+ modbbox = scr;
+ else
+ modbbox = boundingrect(modbbox, scr);
+ update <- = Continue;
+}
+
+Reveal(show : int)
+{
+ showC = show;
+ if (cellmap == nil)
+ return;
+
+ update <- = Pause;
+ for (y := 0; y < nrows; y++) {
+ col0 := y * ncols;
+ for (x := 0; x < ncols; x++) {
+ attr := cellmap[col0+x].attr;
+ if (!(attr & attrC))
+ continue;
+
+ s := "";
+ s[0] = cellmap[col0 + x].ch;
+ (cx, cy) := cellmap[col0 + x].clipmod;
+ f := cellmap[col0 + x].font;
+ cellpos := Point(x * cellsize.x, y * cellsize.y);
+ clipr := Rect(cellpos, cellpos.add(Point(cellsize.x, cellsize.y)));
+ drawpt := cellpos.sub(Point(cx*cellsize.x, cy*cellsize.y));
+
+ drawstr(s, f, clipr, drawpt, attr);
+ }
+ }
+ update <- = Continue;
+}
+
+# expects that pt.x already normalized
+wordchar(pt : Point) : int
+{
+ if (pt.x < 0 || pt.x >= ncols)
+ return 0;
+ if (pt.y < 0 || pt.y >= nrows)
+ return 0;
+
+ col0 := pt.y * ncols;
+ c := cellmap[col0 + pt.x];
+
+ if (c.attr & attrC && !showC)
+ # don't let clicking on screen 'reveal' concealed chars!
+ return 0;
+
+ if (c.font == fontg1)
+ return 0;
+
+ if (c.attr & attrW) {
+ # check for both parts of character
+ (modx, nil) := c.clipmod;
+ if (modx == 1) {
+ # rhs of char - check lhs is the same
+ if (pt.x <= 0)
+ return 0;
+ lhc := cellmap[col0 + pt.x-1];
+ (lhmodx, nil) := lhc.clipmod;
+ if (!((lhc.attr & attrW) && (lhc.font == c.font) && (lhc.ch == c.ch) && (lhmodx == 0)))
+ return 0;
+ } else {
+ # lhs of char - check rhs is the same
+ if (pt.x >= ncols - 1)
+ return 0;
+ rhc := cellmap[col0 + pt.x + 1];
+ (rhmodx, nil) := rhc.clipmod;
+ if (!((rhc.attr & attrW) && (rhc.font == c.font) && (rhc.ch == c.ch) && (rhmodx == 1)))
+ return 0;
+ }
+ }
+ if (c.ch >= 16r30 && c.ch <= 16r39)
+ # digits
+ return 1;
+ if (c.ch >= 16r41 && c.ch <= 16r5a)
+ # capitals
+ return 1;
+ if (c.ch >= 16r61 && c.ch <= 16r7a)
+ # lowercase
+ return 1;
+ if (c.ch == '*' || c.ch == '/')
+ return 1;
+ return 0;
+}
+
+GetWord(gfxpt : Point) : string
+{
+ if (cellmap == nil)
+ return nil;
+
+ scr := Rect((0,0), (ncols * cellsize.x, nrows * cellsize.y));
+ gfxpt = gfxpt.sub(winoff);
+
+ if (!gfxpt.in(scr))
+ return nil;
+
+ x := gfxpt.x / cellsize.x;
+ y := gfxpt.y / cellsize.y;
+ col0 := y * ncols;
+
+ s := "";
+
+ # seek back
+ for (sx := x; sx >= 0; sx--)
+ if (!wordchar(Point(sx, y)))
+ break;
+
+ if (sx++ == x)
+ return nil;
+
+ # seek forward, constructing s
+ for (; sx < ncols; sx++) {
+ if (!wordchar(Point(sx, y)))
+ break;
+ c := cellmap[col0 + sx];
+ s[len s] = c.ch;
+ if (c.attr & attrW)
+ sx++;
+ }
+ return s;
+}
+
+Refresh()
+{
+ if (window == nil || modbbox.dx() == 0)
+ return;
+
+ if (update != nil)
+ update <- = Redraw;
+}
+
+framecolours(attr : int) : (ref Image, ref Image, ref Image, ref Image)
+{
+ fg : ref Image;
+ fgcol := attr & fgMask;
+ if (fgcol == fgWhite && attr & attrB)
+ fg = bright;
+ else
+ fg = colours[fgcol / fgBase];
+
+ bg : ref Image;
+ bgcol := attr & bgMask;
+ if (bgcol == bgWhite && attr & attrB)
+ bg = bright;
+ else
+ bg = colours[bgcol / bgBase];
+
+ (fg0, fg1) := (fg, fg);
+ (bg0, bg1) := (bg, bg);
+
+ if (attr & attrP)
+ (fg0, bg0, fg1, bg1) = (bg1, fg1, bg0, fg0);
+
+ if (attr & attrF) {
+ fg0 = fg;
+ fg1 = bg;
+ }
+
+ if ((attr & attrC) && !showC)
+ (fg0, fg1) = (bg0, bg1);
+ return (fg0, bg0, fg1, bg1);
+}
+
+kill(pid : int)
+{
+ prog := "/prog/" + string pid + "/ctl";
+ fd := sys->open(prog, Sys->OWRITE);
+ if (fd != nil) {
+ cmd := array of byte "kill";
+ sys->write(fd, cmd, len cmd);
+ }
+}
+
+timer(ms : int, pc, tick : chan of int)
+{
+ pc <- = sys->pctl(0, nil);
+ for (;;) {
+ sys->sleep(ms);
+ tick <- = 1;
+ }
+}
+
+# Update() commands
+Redraw, Pause, Continue, CursorSet, QuitUpdate : con iota;
+
+Update(cmd : chan of int)
+{
+ flashtick := chan of int;
+ cursortick := chan of int;
+ pc := chan of int;
+ spawn timer(1000, pc, flashtick);
+ flashpid := <- pc;
+ spawn timer(500, pc, cursortick);
+ cursorpid := <- pc;
+
+ cursor : Point;
+ showcursor := 0;
+ cursoron := 0;
+ quit := 0;
+ nultick := chan of int;
+ flashchan := nultick;
+ pcount := 1;
+ fgframe := 0;
+
+ for (;!quit ;) alt {
+ c := <- cmd =>
+ case c {
+ Redraw =>
+ frames[0].clipr = frames[0].r;
+ frames[1].clipr = frames[1].r;
+ r := modbbox.addpt(winoff);
+ window.draw(r.addpt(window.r.min), frames[fgframe], nil, modbbox.min);
+ if (showcursor && cursoron)
+ drawcursor(cursor, fgframe, 1);
+ modbbox = Rect((0,0),(0,0));
+
+ Pause =>
+ if (pcount++ == 0)
+ flashchan = nultick;
+
+ Continue =>
+ pcount--;
+ if (pcount == 0)
+ flashchan = flashtick;
+
+ QuitUpdate =>
+ quit++;
+
+ CursorSet =>
+ frames[0].clipr = frames[0].r;
+ frames[1].clipr = frames[1].r;
+ if (showcursor && cursoron)
+ drawcursor(cursor, fgframe, 0);
+ cursoron = 0;
+ if (curpos.x < 0 || curpos.x >= ncols || curpos.y < 0 || curpos.y >= nrows)
+ showcursor = 0;
+ else {
+ cursor = curpos;
+ showcursor = 1;
+ drawcursor(cursor, fgframe, 1);
+ cursoron = 1;
+ }
+ }
+
+ <- flashchan =>
+ # flip displays...
+ fgframe = (fgframe + 1 ) % 2;
+ modbbox = Rect((0,0),(0,0));
+ frames[0].clipr = frames[0].r;
+ frames[1].clipr = frames[1].r;
+ window.draw(window.r.addpt(winoff), frames[fgframe], nil, Point(0,0));
+ if (showcursor && cursoron)
+ drawcursor(cursor, fgframe, 1);
+
+ <- cursortick =>
+ if (showcursor) {
+ cursoron = !cursoron;
+ drawcursor(cursor, fgframe, cursoron);
+ }
+ }
+ kill(flashpid);
+ kill(cursorpid);
+}
+
+
+drawstr(s : string, f : ref Font, clipr : Rect, drawpt : Point, attr : int)
+{
+ (fg0, bg0, fg1, bg1) := framecolours(attr);
+ frames[0].clipr = clipr;
+ frames[1].clipr = clipr;
+ frames[0].draw(clipr, bg0, nil, Point(0,0));
+ frames[1].draw(clipr, bg1, nil, Point(0,0));
+ ulrect : Rect;
+ ul := (attr & attrL) && ! (attr & attrD);
+
+ if (f != nil) {
+ if (ul)
+ ulrect = Rect((drawpt.x, drawpt.y + f.height - ulheight), (drawpt.x + clipr.dx(), drawpt.y + f.height));
+ if (fg0 != bg0) {
+ frames[0].text(drawpt, fg0, Point(0,0), f, s);
+ if (ul)
+ frames[0].draw(ulrect, fg0, nil, Point(0,0));
+ }
+ if (fg1 != bg1) {
+ frames[1].text(drawpt, fg1, Point(0,0), f, s);
+ if (ul)
+ frames[1].draw(ulrect, fg1, nil, Point(0,0));
+ }
+ }
+ if (modbbox.dx() == 0)
+ modbbox = clipr;
+ else
+ modbbox = boundingrect(modbbox, clipr);
+}
+
+boundingrect(r1, r2 : Rect) : Rect
+{
+ if (r2.min.x < r1.min.x)
+ r1.min.x = r2.min.x;
+ if (r2.min.y < r1.min.y)
+ r1.min.y = r2.min.y;
+ if (r2.max.x > r1.max.x)
+ r1.max.x = r2.max.x;
+ if (r2.max.y > r1.max.y)
+ r1.max.y = r2.max.y;
+ return r1;
+}
+
+drawcursor(pt : Point, srcix, show : int)
+{
+ col0 := pt.y * ncols;
+ c := cellmap[col0 + pt.x];
+ s := "";
+
+ s[0] = c.ch;
+ (cx, cy) := c.clipmod;
+ cellpos := Point(pt.x * cellsize.x, pt.y * cellsize.y);
+ clipr := Rect(cellpos, cellpos.add(Point(cellsize.x, cellsize.y)));
+ clipr = clipr.addpt(winoff);
+ clipr = clipr.addpt(window.r.min);
+
+ drawpt := cellpos.sub(Point(cx*cellsize.x, cy*cellsize.y));
+ drawpt = drawpt.add(winoff);
+ drawpt = drawpt.add(window.r.min);
+
+ if (!show) {
+ # copy from appropriate frame buffer
+ window.draw(clipr, frames[srcix], nil, cellpos);
+ return;
+ }
+
+ # invert colours
+ attr := c.attr ^ (fgMask | bgMask);
+
+ fg, bg : ref Image;
+ f := c.font;
+ if (srcix == 0)
+ (fg, bg, nil, nil) = framecolours(attr);
+ else
+ (nil, nil, fg, bg) = framecolours(attr);
+
+ prevclipr := window.clipr;
+ window.clipr = clipr;
+
+ window.draw(clipr, bg, nil, Point(0,0));
+ ulrect : Rect;
+ ul := (attr & attrL) && ! (attr & attrD);
+
+ if (f != nil) {
+ if (ul)
+ ulrect = Rect((drawpt.x, drawpt.y + f.height - ulheight), (drawpt.x + clipr.dx(), drawpt.y + f.height));
+ if (fg != bg) {
+ window.text(drawpt, fg, Point(0,0), f, s);
+ if (ul)
+ window.draw(ulrect, fg, nil, Point(0,0));
+ }
+ }
+ window.clipr = prevclipr;
+}
diff --git a/appl/wm/minitel/mdisplay.dis b/appl/wm/minitel/mdisplay.dis
new file mode 100644
index 00000000..fd193994
--- /dev/null
+++ b/appl/wm/minitel/mdisplay.dis
Binary files differ
diff --git a/appl/wm/minitel/mdisplay.m b/appl/wm/minitel/mdisplay.m
new file mode 100644
index 00000000..24d7173f
--- /dev/null
+++ b/appl/wm/minitel/mdisplay.m
@@ -0,0 +1,115 @@
+#
+# Minitel display handling module
+#
+# © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+MDisplay: module
+{
+
+ PATH: con "/dis/wm/minitel/mdisplay.dis";
+
+ # Available character sets
+ videotex, semigraphic, french, american : con iota;
+
+ # Fill() attributes bit mask
+ #
+ # DL CFPH WBbb bfff
+ #
+ # D = Delimiter (set "serial" attributes for rest of line)
+ # L = Lining (underlined text & "separated" graphics)
+ # C = Concealing
+ # F = Flashing
+ # P = polarity (1 = "inverse")
+ # H = double height
+ # W = double width (set H+W for double size)
+ # B = bright (0: fgwhite=lt.grey, 1: fgwhite=white)
+ # bbb = background colour
+ # fff = foreground colour
+
+ fgBase : con 8r001;
+ bgBase : con 8r010;
+ attrBase : con 8r100;
+
+ fgMask : con 8r007;
+ bgMask : con 8r070;
+ attrMask : con ~0 ^ (fgMask | bgMask);
+
+ fgBlack, fgBlue, fgRed, fgMagenta,
+ fgGreen, fgCyan, fgYellow, fgWhite : con iota * fgBase;
+
+ bgBlack, bgBlue, bgRed, bgMagenta,
+ bgGreen, bgCyan, bgYellow, bgWhite : con iota * bgBase;
+
+ attrB, attrW, attrH, attrP, attrF, attrC, attrL, attrD : con attrBase << iota;
+
+ #
+ # Init (ctxt) : string
+ # performs general module initialisation
+ # creates the display window of size/position r using the
+ # given display context.
+ # spawns refresh thread
+ # returns reason for error, or nil on success
+ #
+ # Mode(rect, width, height, ulheight, delims, fontpath) : (string, ref Draw->Image)
+ # set/reset display to given rectangle and character grid size
+ # ulheight == underline height from bottom of character cell
+ # if delims != 0 then "field" attrs for Put() are derived from
+ # preceding delimiter otherwise Put() attrs are taken as is
+ #
+ # load fonts:
+ # <fontpath> videotex
+ # <fontpath>w videotex double width
+ # <fontpath>h videotex double height
+ # <fontpath>s videotex double size
+ # <fontpath>g1 videotex semigraphics
+ # <fontpath>fr french character set
+ # <fontpath>usa american character set
+ # Note:
+ # charset g2 is not directly supported, instead the symbols
+ # of g2 that do not appear in g0 (standard videotex charset)
+ # are available in videotex font using unicode char codes.
+ # Therefore controlling s/w must map g2 codes to unicode.
+ #
+ # Cursor(pt)
+ # move cursor to given position
+ # row number (y) is 0 based
+ # column number (x) is 1 based
+ # move cursor off-screen to hide
+ #
+ # Put(str, pt, charset, attr, insert)
+ # render string str at position pt in the given character set
+ # using specified attributes.
+ # if insert is non-zero, all characters from given position to end
+ # of line are moved right by len str positions.
+ #
+ # Scroll(topline, nlines)
+ # move the whole displayby nlines (+ve = scroll up).
+ # exposed lines of display are set to spaces rendered with
+ # the current mode attribute flags.
+ # scroll region is from topline to bottom of display
+ #
+ # Reveal(reveal)
+ # reveal/hide all chars affected by Concealing attribute.
+ #
+ # Refresh()
+ # force screen update
+ #
+ # GetWord(pt) : string
+ # returns on-screen word at given graphics co-ords
+ # returns nil if blank or semigraphic charset at location
+ #
+ # Quit()
+ # undo Init()
+
+
+ Init : fn (ctxt : ref Draw->Context) : string;
+ Mode : fn (r : Draw->Rect, width, height, ulh, attr : int, fontpath : string) : (string, ref Draw->Image);
+ Cursor : fn (pt : Draw->Point);
+ Put : fn (str : string, pt : Draw->Point, chset, attr, insert : int);
+ Scroll : fn (topline, nlines : int);
+ Reveal : fn (reveal : int);
+ Refresh : fn ();
+ GetWord : fn (gfxpt : Draw->Point) : string;
+ Quit : fn ();
+};
diff --git a/appl/wm/minitel/mdisplay.sbl b/appl/wm/minitel/mdisplay.sbl
new file mode 100644
index 00000000..c97ec8e7
--- /dev/null
+++ b/appl/wm/minitel/mdisplay.sbl
@@ -0,0 +1,1969 @@
+limbo .sbl 2.1
+MDisplay
+4
+mdisplay.b
+sys.m
+draw.m
+mdisplay.m
+1460
+69.1,25 0
+70.1,28 1
+72.5,13 2
+17,33 2
+73.9,29 3
+2,29 3
+75.1,9 4
+76.1,21 5
+78.1,32 6
+10,14 6
+24,25 6
+27,28 6
+30,31 6
+1,32 6
+1,32 6
+79.1,34 7
+10,14 7
+24,25 7
+27,28 7
+30,33 7
+1,34 7
+1,34 7
+80.1,33 8
+9,13 8
+23,26 8
+28,29 8
+31,32 8
+1,33 8
+1,33 8
+81.1,38 9
+12,16 9
+26,29 9
+31,32 9
+34,37 9
+1,38 9
+1,38 9
+82.1,34 10
+10,14 10
+24,25 10
+27,30 10
+32,33 10
+1,34 10
+1,34 10
+83.1,36 11
+10,14 11
+24,25 11
+27,30 11
+32,35 11
+1,36 11
+1,36 11
+84.1,37 12
+11,15 12
+25,28 12
+30,33 12
+35,36 12
+1,37 12
+1,37 12
+85.1,38 13
+10,14 13
+24,27 13
+29,32 13
+34,37 13
+1,38 13
+1,38 13
+87.1,28 14
+11,15 14
+22,27 14
+1,28 14
+1,28 14
+88.1,27 15
+11,15 15
+22,26 15
+1,27 15
+1,27 15
+89.1,25 16
+10,14 16
+21,24 16
+1,25 16
+1,25 16
+90.1,32 17
+13,17 17
+24,31 17
+1,32 17
+1,32 17
+91.1,28 18
+11,15 18
+22,27 18
+1,28 18
+1,28 18
+92.1,26 19
+10,14 19
+21,25 19
+1,26 19
+1,26 19
+93.1,30 20
+12,16 20
+23,29 20
+1,30 20
+1,30 20
+94.1,28 21
+11,15 21
+22,27 21
+1,28 21
+1,28 21
+96.1,97.37 22
+96.25,31 22
+25,31 22
+33,38 22
+33,38 22
+40,44 22
+40,44 22
+46,54 22
+46,54 22
+97.6,12 22
+6,12 22
+14,19 22
+14,19 22
+21,28 22
+21,28 22
+30,36 22
+30,36 22
+98.21,49 23
+21,25 23
+35,38 23
+40,43 23
+45,48 23
+21,49 23
+21,49 23
+1,50 23
+10,14 23
+10,14 23
+1,50 23
+1,50 23
+100.1,21 24
+101.1,21 25
+14,20 25
+1,21 25
+102.1,15 26
+103.8,11 27
+1,11 27
+108.5,18 28
+109.2,24 29
+110.1,13 30
+111.1,13 31
+112.1,10 32
+1,16 32
+113.1,10 33
+1,16 33
+114.1,14 34
+115.1,14 35
+116.0,1 36
+120.5,19 37
+122.10,27 38
+29,32 38
+2,33 38
+124.16,18 39
+20,22 39
+125.5,18 40
+126.2,19 41
+128.1,14 42
+129.1,13 43
+130.14,20 44
+14,15 44
+14,20 44
+14,20 44
+22,28 44
+22,23 44
+22,28 44
+22,28 44
+131.5,12 45
+16,23 45
+132.10,13 46
+15,18 46
+2,19 46
+135.1,35 47
+10,17 47
+27,28 47
+30,31 47
+33,34 47
+1,35 47
+1,35 47
+136.1,58 48
+10,21 48
+32,33 48
+35,50 48
+52,57 48
+1,58 48
+1,58 48
+137.5,18 49
+138.10,32 50
+34,37 50
+2,38 50
+140.1,33 51
+1,7 51
+21,22 51
+23,24 51
+27,32 51
+1,33 51
+1,33 51
+141.15,16 52
+17,18 52
+21,29 52
+142.1,10 53
+1,59 53
+13,20 53
+30,34 53
+36,48 53
+50,51 53
+53,58 53
+1,59 53
+1,59 53
+143.1,10 54
+1,59 54
+13,20 54
+30,34 54
+36,48 54
+50,51 54
+53,58 54
+1,59 54
+1,59 54
+145.5,18 55
+22,31 55
+22,38 55
+42,51 55
+42,58 55
+146.2,14 56
+147.10,45 57
+47,50 57
+2,51 57
+150.1,10 58
+151.1,10 59
+152.1,15 60
+153.1,11 61
+154.1,10 62
+156.18,31 63
+1,44 63
+158.1,37 64
+19,26 64
+28,36 64
+1,37 64
+1,37 64
+159.1,43 65
+19,26 65
+28,42 65
+1,43 65
+1,43 65
+160.1,43 66
+19,26 66
+28,42 66
+1,43 66
+1,43 66
+161.1,44 67
+20,27 67
+29,43 67
+1,44 67
+1,44 67
+162.1,45 68
+20,27 68
+29,44 68
+1,45 68
+1,45 68
+163.1,45 69
+20,27 69
+29,44 69
+1,45 69
+1,45 69
+164.1,47 70
+21,28 70
+30,46 70
+1,47 70
+1,47 70
+166.5,16 71
+167.19,34 72
+19,23 72
+30,33 72
+19,34 72
+19,34 72
+36,47 72
+36,47 73
+169.19,27 74
+29,39 74
+171.18,38 75
+12,39 75
+1,43 75
+172.18,38 76
+12,39 76
+1,42 76
+173.5,17 77
+174.2,14 78
+175.5,17 79
+176.2,14 80
+178.1,82 81
+35,81 81
+35,81 81
+35,81 81
+44,48 81
+50,53 81
+55,73 81
+76,77 81
+78,79 81
+35,81 81
+35,81 81
+35,81 81
+179.6,12 82
+14,23 83
+180.2,19 84
+181.2,27 85
+179.25,28 86
+25,28 86
+189.1,21 87
+190.9,12 88
+14,20 88
+1,21 88
+195.5,18 89
+22,36 89
+197.2,8 90
+200.1,7 91
+202.1,12 92
+203.1,22 93
+204.0,1 94
+208.5,19 95
+23,33 95
+210.2,8 96
+213.1,7 97
+216.1,14 98
+218.6,13 99
+6,13 99
+6,13 99
+220.7,21 100
+7,21 100
+221.3,51 101
+222.6,18 102
+6,18 102
+22,34 102
+22,34 102
+223.3,16 103
+224.3,12 104
+3,12 105
+225.13,25 106
+13,25 106
+226.3,15 107
+227.3,12 108
+3,12 109
+228.13,25 110
+13,25 110
+229.3,15 111
+230.3,12 112
+3,12 113
+232.3,11 114
+3,11 99
+236.2,12 115
+237.6,18 116
+6,18 116
+239.3,15 117
+240.8,15 118
+22,29 119
+17,29 119
+241.17,24 120
+17,32 120
+4,32 120
+240.31,35 121
+31,35 121
+242.3,15 122
+3,15 123
+246.2,50 124
+2,50 99
+248.12,22 125
+12,22 99
+249.14,25 126
+14,25 99
+250.8,16 127
+8,16 99
+253.1,18 128
+255.17,25 129
+16,30 129
+1,30 129
+256.16,24 130
+6,28 130
+30,41 131
+257.2,20 132
+259.6,11 133
+6,11 134
+260.3,11 135
+261.6,16 136
+6,16 137
+262.3,8 138
+264.2,19 139
+265.2,25 140
+267.6,12 141
+17,31 141
+17,31 141
+270.3,24 142
+273.7,29 143
+274.4,16 144
+4,16 145
+276.4,34 146
+278.8,20 147
+22,29 148
+279.4,20 149
+280.8,20 150
+8,33 150
+8,33 150
+281.9,21 151
+9,36 151
+40,51 151
+283.6,20 152
+285.17,29 153
+5,34 153
+286.5,10 154
+278.31,35 155
+31,35 155
+289.18,23 156
+10,24 156
+27,45 156
+3,45 156
+292.7,29 157
+293.4,17 158
+296.16,23 159
+12,23 159
+26,33 159
+2,33 159
+297.2,33 160
+298.16,31 161
+33,45 161
+300.6,12 162
+302.7,20 163
+7,28 163
+303.9,26 164
+28,40 165
+304.5,27 166
+305.9,17 167
+306.6,11 168
+307.13,25 169
+5,26 169
+37,48 169
+29,49 169
+5,49 169
+303.42,49 170
+42,49 170
+311.18,35 171
+37,43 171
+312.18,24 172
+26,32 172
+36,54 172
+56,75 172
+314.4,13 173
+4,13 173
+22,31 173
+22,31 173
+4,33 173
+4,33 174
+4,33 175
+315.4,13 176
+4,13 176
+22,31 176
+22,31 176
+4,33 176
+4,33 177
+4,33 178
+316.4,46 179
+4,13 179
+4,13 179
+19,23 179
+25,34 179
+25,34 179
+36,39 179
+41,45 179
+4,46 179
+317.4,46 180
+4,13 180
+4,13 180
+19,23 180
+25,34 180
+25,34 180
+36,39 180
+41,45 180
+4,46 180
+318.8,20 181
+8,15 181
+8,20 181
+8,20 181
+8,25 181
+319.5,19 182
+5,19 183
+321.5,42 184
+28,35 184
+37,41 184
+5,42 184
+5,42 184
+326.2,11 185
+327.7,17 186
+19,28 187
+40,47 187
+32,47 187
+328.8,19 188
+34,46 189
+30,46 189
+21,46 189
+329.8,13 190
+330.5,13 191
+331.8,18 192
+332.5,10 193
+333.4,20 194
+334.4,17 195
+4,26 195
+335.4,17 196
+23,33 196
+336.4,17 197
+4,29 197
+337.4,17 198
+28,40 198
+28,48 198
+4,48 198
+328.63,66 199
+68,76 199
+49,50 199
+52,58 199
+52,58 199
+327.49,56 200
+49,56 200
+342.16,22 201
+24,41 201
+343.15,19 202
+22,39 202
+41,60 202
+344.19,37 203
+6,37 203
+345.3,34 204
+347.2,35 205
+10,13 205
+15,16 205
+18,22 205
+24,28 205
+30,34 205
+2,35 205
+356.2,15 206
+357.2,32 207
+358.2,9 208
+359.9,15 209
+19,28 209
+360.7,12 210
+7,12 211
+361.4,12 212
+362.22,30 213
+14,31 213
+3,36 213
+364.15,23 214
+7,24 214
+7,39 214
+366.12,29 215
+32,50 215
+4,50 215
+367.4,18 216
+4,18 217
+369.8,23 218
+8,23 218
+8,23 219
+370.5,10 220
+372.25,41 221
+7,21 221
+7,41 221
+7,41 222
+373.4,9 223
+374.24,29 224
+13,30 224
+33,47 224
+3,47 224
+375.11,19 225
+3,20 225
+3,35 225
+376.18,26 226
+10,27 226
+3,30 226
+377.23,31 227
+15,32 227
+15,40 227
+378.17,25 228
+9,26 228
+3,31 228
+380.20,34 229
+36,50 229
+381.17,24 230
+26,68 230
+26,33 230
+44,54 230
+56,66 230
+26,68 230
+26,68 230
+382.3,61 231
+13,20 231
+31,44 231
+46,59 231
+3,61 231
+3,61 231
+383.3,41 232
+11,12 232
+14,16 232
+18,23 232
+25,31 232
+33,40 232
+3,41 232
+3,41 233
+359.30,33 234
+30,33 234
+30,33 235
+256.43,51 236
+43,51 236
+386.1,21 237
+387.0,1 238
+391.5,19 239
+23,34 239
+392.2,8 240
+395.14,15 241
+16,36 241
+40,58 241
+60,78 241
+397.1,18 242
+399.1,10 243
+1,10 243
+1,22 243
+1,22 244
+400.1,10 245
+1,10 245
+1,22 245
+1,22 246
+401.1,49 247
+9,12 247
+25,26 247
+28,47 247
+1,49 247
+1,49 247
+403.1,58 248
+1,10 248
+1,10 248
+16,20 248
+22,31 248
+22,31 248
+33,36 248
+38,47 248
+38,47 248
+38,57 248
+38,57 249
+1,58 248
+404.1,58 250
+1,10 250
+1,10 250
+16,20 250
+22,31 250
+22,31 250
+33,36 250
+38,47 250
+38,47 250
+38,57 250
+38,57 251
+1,58 250
+406.5,15 252
+408.15,30 253
+6,30 253
+409.3,27 254
+410.7,28 255
+30,39 256
+411.3,23 257
+412.14,26 258
+3,34 258
+413.39,52 259
+23,30 259
+23,53 259
+3,53 259
+3,53 260
+410.41,44 261
+41,44 261
+415.7,25 262
+27,36 263
+416.3,20 264
+417.3,28 265
+415.38,41 266
+38,41 266
+419.22,23 267
+37,58 267
+25,58 267
+61,68 267
+61,68 268
+422.2,18 269
+423.15,30 270
+6,30 270
+424.3,27 271
+425.12,23 272
+7,32 272
+34,46 273
+426.3,23 274
+427.14,26 275
+3,34 275
+428.39,52 276
+23,30 276
+23,53 276
+3,53 276
+3,53 277
+425.48,51 278
+48,51 278
+430.7,18 279
+20,30 280
+431.3,20 281
+432.3,28 282
+430.32,35 283
+32,35 283
+434.16,23 284
+26,35 284
+49,70 284
+37,70 284
+436.1,52 285
+1,10 285
+1,10 285
+16,22 285
+24,34 285
+24,34 285
+36,39 285
+47,48 285
+49,50 285
+1,52 285
+437.1,52 286
+1,10 286
+1,10 286
+16,22 286
+24,34 286
+24,34 286
+36,39 286
+47,48 286
+49,50 286
+1,52 286
+438.5,17 287
+5,12 287
+5,17 287
+5,17 287
+5,23 287
+439.2,15 288
+2,15 289
+441.2,38 290
+25,32 290
+34,37 290
+2,38 290
+2,38 290
+442.1,21 291
+443.0,1 292
+447.1,13 293
+448.5,19 294
+449.2,8 295
+451.1,18 296
+452.6,12 297
+14,23 298
+453.2,19 299
+454.7,13 300
+15,24 301
+455.19,25 302
+11,26 302
+3,31 302
+456.8,22 303
+8,22 303
+8,22 304
+8,22 305
+457.4,12 306
+459.3,10 307
+460.18,26 308
+10,27 308
+3,30 308
+461.23,31 309
+15,32 309
+15,40 309
+462.16,24 310
+8,25 310
+3,30 310
+463.20,34 311
+36,50 311
+464.17,24 312
+26,68 312
+26,33 312
+44,54 312
+56,66 312
+26,68 312
+26,68 312
+465.3,61 313
+13,20 313
+31,44 313
+46,59 313
+3,61 313
+3,61 313
+467.3,37 314
+11,12 314
+14,15 314
+17,22 314
+24,30 314
+32,36 314
+3,37 314
+3,37 315
+3,37 316
+454.26,29 317
+26,29 317
+452.25,28 318
+25,28 318
+470.1,21 319
+471.0,1 320
+476.5,13 321
+17,30 321
+477.9,10 322
+2,10 322
+478.5,13 323
+17,30 323
+479.9,10 324
+2,10 324
+481.1,21 325
+482.14,25 326
+6,26 326
+1,26 326
+484.5,19 327
+5,19 327
+24,29 327
+486.9,10 328
+2,10 328
+488.5,21 329
+489.9,10 330
+2,10 330
+491.5,19 331
+5,19 331
+493.17,26 332
+3,7 332
+494.6,15 333
+496.7,16 334
+497.11,12 335
+4,12 335
+498.18,29 336
+18,31 336
+10,32 336
+3,32 336
+499.20,31 337
+4,10 337
+500.9,27 338
+9,27 338
+31,51 338
+55,71 338
+75,88 338
+501.11,12 339
+4,12 339
+4,12 340
+4,12 341
+504.15,24 342
+7,24 342
+505.11,12 343
+4,12 343
+506.18,29 344
+18,33 344
+10,34 344
+3,34 344
+507.20,31 345
+4,10 345
+508.9,27 346
+9,27 346
+31,51 346
+55,71 346
+75,88 346
+509.11,12 347
+4,12 347
+4,12 348
+512.5,18 349
+22,35 349
+514.9,10 350
+2,10 350
+515.5,18 351
+22,35 351
+517.9,10 352
+2,10 352
+518.5,18 353
+22,35 353
+520.9,10 354
+2,10 354
+521.5,16 355
+20,31 355
+522.9,10 356
+2,10 356
+523.8,9 357
+1,9 357
+528.5,19 358
+529.9,12 359
+2,12 359
+531.14,15 360
+16,17 360
+21,39 360
+41,59 360
+532.1,26 361
+9,14 361
+19,25 361
+1,26 361
+1,26 361
+534.6,19 362
+6,11 362
+15,18 362
+6,19 362
+6,19 362
+6,19 362
+535.9,12 363
+2,12 363
+537.1,26 364
+538.1,26 365
+539.1,18 366
+541.1,8 367
+544.6,13 368
+15,22 369
+545.7,29 370
+22,24 370
+26,27 370
+7,29 370
+7,29 370
+7,29 370
+546.3,8 371
+544.24,28 372
+24,28 372
+548.5,9 373
+5,9 373
+5,14 373
+549.9,12 374
+2,12 374
+552.8,18 375
+553.7,29 376
+22,24 376
+26,27 376
+7,29 376
+7,29 376
+7,29 376
+7,29 377
+554.3,8 378
+555.15,24 379
+7,25 379
+2,25 379
+556.4,9 380
+2,17 380
+557.6,20 381
+6,20 381
+558.3,7 382
+3,7 383
+552.20,24 384
+20,24 384
+560.8,9 385
+1,9 385
+565.5,18 386
+22,34 386
+22,29 386
+22,34 386
+22,34 386
+22,39 386
+566.2,8 387
+568.5,18 388
+569.2,20 389
+570.0,1 390
+575.1,23 391
+576.5,21 392
+25,37 392
+25,37 392
+577.2,13 393
+2,13 394
+579.7,30 395
+2,30 395
+582.1,23 396
+583.5,21 397
+25,37 397
+25,37 397
+584.2,13 398
+2,13 399
+586.15,29 400
+7,30 400
+2,30 400
+588.16,18 401
+20,22 401
+589.16,18 402
+20,22 402
+591.5,17 403
+5,17 403
+592.26,29 404
+31,34 404
+36,39 404
+41,44 404
+3,6 404
+8,11 404
+13,16 404
+18,21 404
+18,21 405
+18,21 406
+18,21 407
+18,21 408
+594.5,17 409
+5,17 409
+595.2,10 410
+596.2,10 411
+599.5,19 412
+5,19 412
+24,29 412
+600.15,25 413
+601.9,12 414
+14,17 414
+19,22 414
+24,27 414
+1,28 414
+606.20,30 415
+9,30 415
+1,39 415
+1,39 416
+607.1,35 417
+17,21 417
+23,34 417
+1,35 417
+1,35 417
+608.5,14 418
+609.2,29 419
+610.2,30 420
+13,15 420
+17,20 420
+22,29 420
+2,30 420
+2,30 420
+2,30 421
+612.0,1 422
+616.9,26 423
+19,20 423
+22,25 423
+9,26 423
+9,26 423
+1,26 423
+618.2,16 424
+13,15 424
+2,16 424
+2,16 424
+619.2,13 425
+2,13 425
+628.1,25 426
+629.1,26 427
+630.1,18 428
+631.1,33 429
+13,17 429
+19,21 429
+23,32 429
+1,33 429
+632.1,18 430
+633.1,33 431
+13,16 431
+18,20 431
+22,32 431
+1,33 431
+634.1,19 432
+637.1,16 433
+638.1,14 434
+639.1,11 435
+640.1,23 436
+641.1,21 437
+642.1,12 438
+643.1,13 439
+645.8,12 440
+646.9,12 441
+9,12 441
+685.4,13 441
+4,13 441
+695.4,14 441
+4,14 441
+645.16,22 441
+16,22 441
+16,22 441
+16,22 441
+647.7,8 442
+7,8 442
+7,8 442
+649.3,12 443
+3,12 443
+21,30 443
+21,30 443
+3,32 443
+3,32 444
+3,32 445
+650.3,12 446
+3,12 446
+21,30 446
+21,30 446
+3,32 446
+3,32 447
+3,32 448
+651.3,29 449
+8,15 449
+22,28 449
+3,29 449
+3,29 449
+652.15,36 450
+15,16 450
+23,35 450
+15,36 450
+15,36 450
+3,72 450
+3,9 450
+3,9 450
+38,53 450
+38,53 450
+55,58 450
+60,71 450
+3,72 450
+653.7,17 451
+21,29 451
+654.4,34 452
+15,21 452
+23,30 452
+32,33 452
+4,34 452
+655.19,20 453
+21,22 453
+25,26 453
+27,28 453
+27,28 442
+658.7,15 454
+7,15 454
+7,20 454
+659.4,23 455
+4,23 442
+662.3,11 456
+663.7,18 457
+664.4,25 458
+4,25 442
+667.3,9 459
+3,9 442
+670.3,12 460
+3,12 460
+21,30 460
+21,30 460
+3,32 460
+3,32 461
+3,32 462
+671.3,12 463
+3,12 463
+21,30 463
+21,30 463
+3,32 463
+3,32 464
+3,32 465
+672.7,17 466
+21,29 466
+673.4,34 467
+15,21 467
+23,30 467
+32,33 467
+4,34 467
+674.3,15 468
+675.7,19 469
+23,40 469
+44,56 469
+61,78 469
+676.4,18 470
+4,18 471
+678.4,19 472
+679.4,18 473
+680.4,34 474
+15,21 474
+23,30 474
+32,33 474
+4,34 474
+681.4,16 475
+4,16 442
+4,16 441
+687.12,26 476
+2,30 476
+688.18,19 477
+20,21 477
+24,25 477
+26,27 477
+689.2,11 478
+2,11 478
+20,29 478
+20,29 478
+2,31 478
+2,31 479
+2,31 480
+690.2,11 481
+2,11 481
+20,29 481
+20,29 481
+2,31 481
+2,31 482
+2,31 483
+691.14,36 484
+14,22 484
+29,35 484
+14,36 484
+14,36 484
+2,71 484
+2,8 484
+2,8 484
+38,53 484
+38,53 484
+55,58 484
+66,67 484
+68,69 484
+2,71 484
+692.6,16 485
+20,28 485
+693.3,33 486
+14,20 486
+22,29 486
+31,32 486
+3,33 486
+3,33 441
+696.6,16 487
+697.15,23 488
+3,23 488
+3,23 488
+3,23 488
+698.3,40 489
+14,20 489
+22,29 489
+31,39 489
+3,40 489
+3,40 441
+701.1,15 490
+6,14 490
+1,15 490
+702.1,16 491
+6,15 491
+1,16 491
+703.0,1 492
+708.25,43 493
+38,42 493
+25,43 493
+25,43 493
+709.1,10 494
+1,10 494
+1,24 494
+1,24 495
+710.1,10 496
+1,10 496
+1,24 496
+1,24 497
+711.1,44 498
+1,10 498
+1,10 498
+16,21 498
+23,26 498
+28,31 498
+39,40 498
+41,42 498
+1,44 498
+712.1,44 499
+1,10 499
+1,10 499
+16,21 499
+23,26 499
+28,31 499
+39,40 499
+41,42 499
+1,44 499
+714.7,21 500
+7,21 500
+27,41 500
+27,41 500
+1,41 500
+1,41 500
+1,41 500
+716.5,13 501
+717.6,8 502
+718.18,26 503
+28,47 503
+28,58 503
+73,83 503
+73,78 503
+73,83 503
+73,83 503
+62,83 503
+85,104 503
+719.6,16 504
+720.3,48 505
+3,12 505
+3,12 505
+18,24 505
+26,29 505
+37,38 505
+39,40 505
+43,44 505
+46,47 505
+3,48 505
+3,48 505
+721.7,9 506
+722.4,48 507
+4,13 507
+4,13 507
+19,25 507
+27,30 507
+32,35 507
+43,44 507
+45,46 507
+4,48 507
+724.6,16 508
+725.3,48 509
+3,12 509
+3,12 509
+18,24 509
+26,29 509
+37,38 509
+39,40 509
+43,44 509
+46,47 509
+3,48 509
+3,48 509
+726.7,9 510
+727.4,48 511
+4,13 511
+4,13 511
+19,25 511
+27,30 511
+32,35 511
+43,44 511
+45,46 511
+4,48 511
+730.5,17 512
+5,12 512
+5,17 512
+5,17 512
+5,22 512
+731.2,17 513
+734.0,1 514
+733.2,40 515
+25,32 515
+34,39 515
+2,40 515
+2,40 515
+734.0,1 514
+738.5,24 516
+739.2,21 517
+740.5,24 518
+741.2,21 519
+742.5,24 520
+743.2,21 521
+744.5,24 522
+745.2,21 523
+746.8,10 524
+1,10 524
+751.1,21 525
+752.14,25 526
+6,26 526
+1,26 526
+753.1,8 527
+755.1,12 528
+756.13,22 529
+757.18,35 530
+37,54 530
+758.15,22 531
+24,66 531
+24,31 531
+42,52 531
+54,64 531
+24,66 531
+24,66 531
+759.1,28 532
+9,14 532
+21,27 532
+1,28 532
+1,28 532
+760.1,34 533
+9,14 533
+21,33 533
+1,34 533
+1,34 533
+762.1,59 534
+11,18 534
+29,42 534
+44,57 534
+1,59 534
+1,59 534
+763.1,28 535
+10,16 535
+21,27 535
+1,28 535
+1,28 535
+764.1,34 536
+10,16 536
+21,33 536
+1,34 536
+1,34 536
+766.6,10 537
+768.2,49 538
+2,8 538
+14,19 538
+21,34 538
+21,34 538
+36,39 538
+41,48 538
+2,49 538
+769.2,8 539
+773.1,35 540
+776.1,12 541
+777.5,15 542
+778.23,41 543
+36,40 543
+23,41 543
+23,41 543
+3,5 543
+7,9 543
+7,9 544
+7,9 545
+7,9 546
+7,9 547
+7,9 548
+780.23,41 549
+36,40 549
+23,41 549
+23,41 549
+13,15 549
+17,19 549
+17,19 550
+17,19 551
+17,19 552
+17,19 553
+782.1,26 554
+783.1,21 555
+785.1,40 556
+1,7 556
+13,18 556
+20,22 556
+24,27 556
+35,36 556
+37,38 556
+1,40 556
+787.7,21 557
+7,21 557
+27,41 557
+27,41 557
+1,41 557
+1,41 557
+1,41 557
+789.5,13 558
+790.6,8 559
+791.18,26 560
+28,47 560
+28,58 560
+73,83 560
+73,78 560
+73,83 560
+73,83 560
+62,83 560
+85,104 560
+792.6,14 561
+793.3,44 562
+3,9 562
+15,21 562
+23,25 562
+33,34 562
+35,36 562
+39,40 562
+42,43 562
+3,44 562
+3,44 562
+794.7,9 563
+795.4,44 564
+4,10 564
+16,22 564
+24,26 564
+28,31 564
+39,40 564
+41,42 564
+4,44 564
+798.1,25 565
+799.0,1 566
+14
+aSys->Dir 1:26.1,39.2 64
+11
+0:name:28.2,6 s
+4:uid:29.2,5 s
+8:gid:30.2,5 s
+12:muid:31.2,6 s
+16:qid:32.2,5 @1
+
+32:mode:33.2,6 i
+36:atime:34.2,7 i
+40:mtime:35.2,7 i
+48:length:36.2,8 B
+56:dtype:37.2,7 i
+60:dev:38.2,5 i
+aSys->Qid 11.1,16.2 16
+3
+0:path:13.2,6 B
+8:vers:14.2,6 i
+12:qtype:15.2,7 i
+aDraw->Chans 2:70.1,82.2 4
+1
+0:desc:72.2,6 i
+aDraw->Image 142.1,198.2 56
+8
+0:r:146.2,3 @4
+
+16:clipr:147.2,7 @4
+
+32:depth:148.2,7 i
+36:chans:149.2,7 @2
+
+40:repl:150.2,6 i
+44:display:151.2,9 R@6
+
+48:screen:152.2,8 R@7
+
+52:iname:153.2,7 s
+aDraw->Rect 116.1,139.2 16
+2
+0:min:118.2,5 @5
+
+8:max:119.2,5 @5
+
+aDraw->Point 99.1,113.2 8
+2
+0:x:101.2,3 i
+4:y:102.2,3 i
+aDraw->Display 201.1,230.2 20
+5
+0:image:203.2,7 R@3
+
+4:white:204.2,7 R@3
+
+8:black:205.2,7 R@3
+
+12:opaque:206.2,8 R@3
+
+16:transparent:207.2,13 R@3
+
+aDraw->Screen 249.1,263.2 16
+4
+0:id:251.2,4 i
+4:image:252.2,7 R@3
+
+8:fill:253.2,6 R@3
+
+12:display:254.2,9 R@6
+
+aDraw->Context 274.1,279.2 12
+3
+0:display:276.2,9 R@6
+
+4:screen:277.2,8 R@7
+
+8:wm:278.2,4 Ct8.2
+0:t0:15,21 s
+4:t1:15,21 Ct8.2
+0:t0:32,38 s
+4:t1:32,38 R@9
+
+
+
+aDraw->Wmcontext 282.1,291.2 28
+7
+0:kbd:284.2,5 Ci
+4:ptr:285.2,5 CR@10
+
+8:ctl:286.2,5 Cs
+12:wctl:287.2,6 Cs
+16:images:288.2,8 CR@3
+
+20:connfd:289.2,8 R@11
+
+24:ctxt:290.2,6 R@8
+
+aDraw->Pointer 266.1,271.2 16
+3
+0:buttons:268.2,9 i
+4:xy:269.2,4 @5
+
+12:msec:270.2,6 i
+aSys->FD 1:45.1,48.2 4
+1
+0:fd:47.2,4 i
+aDraw->Font 2:233.1,246.2 16
+4
+0:name:235.2,6 s
+4:height:236.2,8 i
+8:ascent:237.2,8 i
+12:display:238.2,9 R@6
+
+aCellinfo 0:27.0,31.1 20
+4
+0:font:28.1,5 R@12
+
+4:ch:29.1,3 i
+8:attr:5,9 i
+12:clipmod:30.1,8 t8.2
+0:t0:12,15 i
+4:t1:12,15 i
+
+17
+0:Init
+1
+32:c:67.5,6 R@8
+
+17
+36:disp:76.1,5 R@6
+
+40:black:78.1,6 i
+44:blue:79.1,5 i
+48:cyan:83.1,5 i
+52:green:82.1,6 i
+56:iblack:87.1,7 R@3
+
+60:iblue:88.1,6 R@3
+
+64:icyan:92.1,6 R@3
+
+68:igreen:91.1,7 R@3
+
+72:imagenta:90.1,9 R@3
+
+76:ired:89.1,5 R@3
+
+80:iwhite:94.1,7 R@3
+
+84:iyellow:93.1,8 R@3
+
+88:magenta:81.1,8 i
+92:red:80.1,4 i
+96:white:85.1,6 i
+100:yellow:84.1,7 i
+s140:Quit
+0
+0
+n151:Mode
+6
+32:r:118.5,6 @4
+
+48:w:21,22 i
+52:h:24,25 i
+56:ulh:27,30 i
+60:d:32,33 i
+64:fontpath:41,49 s
+6
+68:dx:130.2,4 i
+72:dy:6,8 i
+76:black:135.1,6 i
+80:y:179.6,7 i
+84:col0:180.2,6 i
+96:winr:141.1,5 @4
+
+t8.2
+0:t0:118.63,69 s
+4:t1:63,69 R@3
+
+313:Cursor
+1
+32:pt:193.7,9 @5
+
+0
+n320:Put
+5
+32:str:206.4,7 s
+36:pt:18,20 @5
+
+44:charset:30,37 i
+48:attr:39,43 i
+52:insert:45,51 i
+36
+56:col0:264.2,6 i
+60:f:215.1,2 R@12
+
+64:cell:216.1,5 AAt8.2
+0:t0:22.37,38 i
+4:t1:40,41 i
+
+68:newattr:362.3,10 i
+72:cellix:256.6,12 i
+76:y:257.2,3 i
+80:clipix:328.8,14 i
+84:cmix:333.4,8 i
+88:ix:240.8,10 i
+92:mask:269.3,7 i
+96:cix:279.4,7 i
+100:ix:278.8,10 i
+104:delimattr:270.3,12 i
+108:newstr:239.3,9 s
+112:s:358.2,3 s
+116:cx:377.4,6 i
+120:cy:8,10 i
+124:f2:378.3,5 R@12
+
+144:colbase:265.2,9 i
+148:srco:298.2,6 @5
+
+156:dstr:312.4,8 @4
+
+172:cellpos:380.3,10 @5
+
+180:drawpt:382.3,9 @5
+
+188:dsto:311.4,8 @5
+
+196:clipr:381.3,8 @4
+
+104:x:326.2,3 i
+80:mask:357.2,6 i
+84:attr2:356.2,7 i
+104:destx:303.9,14 i
+100:strix:327.7,12 i
+96:strlen:296.2,8 i
+92:gfxwidth:297.2,10 i
+100:srcx:304.5,9 i
+88:txty:255.1,5 i
+156:strr:343.2,6 @4
+
+188:txto:342.2,6 @5
+
+n609:Scroll
+2
+32:topline:389.7,14 i
+36:nlines:16,22 i
+11
+40:y:410.7,8 i
+44:srccol0:411.3,10 i
+48:dstcol0:412.3,10 i
+64:scr:395.1,4 @4
+
+80:blankr:394.1,7 @4
+
+96:dstr:401.1,5 @4
+
+44:y:425.7,8 i
+48:srccol0:426.3,10 i
+44:col0:416.3,7 i
+48:col0:431.3,7 i
+40:dstcol0:427.3,10 i
+n743:Reveal
+1
+32:show:445.7,11 i
+11
+36:x:454.7,8 i
+40:col0:453.2,6 i
+44:y:452.6,7 i
+48:attr:455.3,7 i
+52:s:459.3,4 s
+56:cx:461.4,6 i
+60:cy:8,10 i
+64:f:462.3,4 R@12
+
+72:cellpos:463.3,10 @5
+
+80:drawpt:465.3,9 @5
+
+88:clipr:464.3,8 @4
+
+n800:wordchar
+1
+32:pt:474.9,11 @5
+
+7
+40:col0:481.1,5 i
+44:lhmodx:499.4,10 i
+48:modx:493.3,7 i
+56:c:482.1,2 @13
+
+76:lhc:498.3,6 @13
+
+96:rhc:506.3,6 @13
+
+44:rhmodx:507.4,10 i
+i879:GetWord
+1
+32:gfxpt:526.8,13 @5
+
+7
+40:sx:544.6,8 i
+44:s:541.1,2 s
+48:y:538.1,2 i
+52:x:537.1,2 i
+56:col0:539.1,5 i
+68:c:555.2,3 @13
+
+88:scr:531.1,4 @4
+
+s941:Refresh
+0
+0
+n951:framecolours
+1
+32:attr:572.13,17 i
+8
+36:fg0:588.2,5 R@3
+
+40:fg1:7,10 R@3
+
+44:bg:581.1,3 R@3
+
+48:bg0:589.2,5 R@3
+
+52:bg1:7,10 R@3
+
+56:fg:574.1,3 R@3
+
+60:bgcol:582.1,6 i
+64:fgcol:575.1,6 i
+t16.4
+0:t0:572.28,37 R@3
+
+4:t1:28,37 R@3
+
+8:t2:28,37 R@3
+
+12:t3:28,37 R@3
+
+999:kill
+1
+32:pid:604.5,8 i
+3
+36:cmd:609.2,5 Ab
+40:fd:607.1,3 R@11
+
+44:prog:606.1,5 s
+n1018:timer
+3
+32:ms:614.6,8 i
+36:pc:16,18 Ci
+40:tick:20,24 Ci
+0
+n1030:Update
+1
+32:cmd:626.7,10 Ci
+15
+36:fgframe:643.1,8 i
+40:cursoron:638.1,9 i
+44:showcursor:637.1,11 i
+48:pc:630.1,3 Ci
+52:flashchan:641.1,10 Ci
+56:pcount:642.1,7 i
+60:cursortick:629.1,11 Ci
+64:flashtick:628.1,10 Ci
+68:nultick:640.1,8 Ci
+72:quit:639.1,5 i
+76:c:646.1,2 i
+80:cursorpid:634.1,10 i
+84:flashpid:632.1,9 i
+104:cursor:636.1,7 @5
+
+128:r:651.3,4 @4
+
+n1219:drawstr
+5
+32:s:706.8,9 s
+36:f:20,21 R@12
+
+40:clipr:34,39 @4
+
+56:drawpt:48,54 @5
+
+64:attr:64,68 i
+6
+68:fg0:708.2,5 R@3
+
+72:bg0:7,10 R@3
+
+76:fg1:12,15 R@3
+
+80:bg1:17,20 R@3
+
+84:ul:714.1,3 i
+100:ulrect:713.1,7 @4
+
+n1324:boundingrect
+2
+32:r1:736.13,15 @4
+
+48:r2:17,19 @4
+
+0
+@4
+1334:drawcursor
+3
+32:pt:749.11,13 @5
+
+40:srcix:23,28 i
+44:show:30,34 i
+15
+48:attr:773.1,5 i
+52:f:776.1,2 R@12
+
+56:fg:775.1,3 R@3
+
+60:bg:5,7 R@3
+
+64:s:753.1,2 s
+68:ul:787.1,3 i
+72:col0:751.1,5 i
+76:cx:756.2,4 i
+80:cy:6,8 i
+92:drawpt:762.1,7 @5
+
+100:clipr:758.1,6 @4
+
+116:cellpos:757.1,8 @5
+
+124:c:752.1,2 @13
+
+160:prevclipr:782.1,10 @4
+
+176:ulrect:786.1,7 @4
+
+n31
+88:blankrow:55.0,8 A@13
+
+92:bright:41.0,6 R@3
+
+104:cellH:24.0,5 AAt8.2
+0:t0:37,38 i
+4:t1:40,41 i
+
+108:cellS:22.0,5 AAt8.2
+0:t0:37,38 i
+4:t1:40,41 i
+
+112:cellW:23.0,5 AAt8.2
+0:t0:36,37 i
+4:t1:39,40 i
+
+116:cellWH:25.0,6 AAt8.2
+0:t0:37,38 i
+4:t1:40,41 i
+
+120:cellmap:44.0,7 A@13
+
+124:cellsize:50.0,8 @5
+
+132:colours:40.0,7 AR@3
+
+136:ctxt:57.0,4 R@8
+
+140:curpos:48.0,6 @5
+
+148:delims:53.0,6 i
+152:display:35.0,7 R@6
+
+156:draw:13.0,4 mDraw
+2:1.0,298.1 0
+
+160:font:0:58.0,4 R@12
+
+164:fontfr:63.0,6 R@12
+
+168:fontg1:62.0,6 R@12
+
+172:fonth:59.0,5 R@12
+
+176:fonts:61.0,5 R@12
+
+180:fontusa:64.0,7 R@12
+
+184:fontw:60.0,5 R@12
+
+192:frames:37.0,6 AR@3
+
+208:modbbox:54.0,7 @4
+
+224:ncols:46.0,5 i
+240:nrows:45.0,5 i
+248:showC:52.0,5 i
+252:sys:12.0,3 mSys
+1:4.0,160.1 0
+
+256:ulheight:0:47.0,8 i
+260:update:38.0,6 Ci
+272:window:36.0,6 R@3
+
+276:winoff:49.0,6 @5
+
diff --git a/appl/wm/minitel/miniterm.b b/appl/wm/minitel/miniterm.b
new file mode 100644
index 00000000..1c6ff759
--- /dev/null
+++ b/appl/wm/minitel/miniterm.b
@@ -0,0 +1,1187 @@
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+implement Miniterm;
+
+include "sys.m";
+ sys: Sys;
+ print, fprint, sprint, read: import sys;
+include "draw.m";
+ draw: Draw;
+include "tk.m";
+ tk: Tk;
+include "tkclient.m";
+ tkclient: Tkclient;
+
+include "miniterm.m";
+
+Miniterm: module
+{
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+
+};
+
+pgrp: int = 0;
+debug: array of int = array[256] of {* => 0};
+stderr: ref Sys->FD;
+
+# Minitel terminal identification request - reply sequence
+TERMINALID1 := array [] of {
+ byte SOH,
+ byte 'S', byte 'X', byte '1', byte 'H', byte 'N',
+ byte EOT
+};
+TERMINALID2 := array [] of {
+ byte SOH,
+ byte 'C', byte 'g', byte '1',
+ byte EOT
+};
+
+# Minitel module identifiers
+Mscreen, Mmodem, Mkeyb, Msocket, Nmodule: con iota;
+Pscreen, Pmodem, Pkeyb, Psocket: con (1 << iota);
+Modname := array [Nmodule] of {
+ Mscreen => "S",
+ Mmodem => "M",
+ Mkeyb => "K",
+ Msocket => "C",
+ * => "?",
+};
+
+# attributes common to all modules
+Module: adt {
+ path: int; # bitset to connected modules
+ disabled: int;
+};
+
+# A BufChan queues events from the terminal to the modules
+BufChan: adt {
+ path: int; # id bit
+ ch: chan of ref Event; # set to `in' or `dummy' channel
+ ev: ref Event; # next event to send
+ in: chan of ref Event; # real channel for Events to the device
+ q: array of ref Event; # subsequent events to send
+};
+
+# holds state information for the minitel `protocol` (chapter 6)
+PState: adt {
+ state: int;
+ arg: array of int; # up to 3 arguments: X,Y,Z
+ nargs: int; # expected number of arguments
+ n: int; # progress
+ skip: int; # transparency; bytes to skip
+};
+PSstart, PSesc, PSarg: con iota; # states
+
+# Terminal display modes
+Videotex, Mixed, Ascii,
+
+# Connection methods
+Direct, Network,
+
+# Terminal connection states
+Local, Connecting, Online,
+
+# Special features
+Echo
+ : con (1 << iota);
+
+Terminal: adt {
+ in: chan of ref Event;
+ out: array of ref BufChan; # buffered output to the minitel modules
+
+ mode: int; # display mode
+ state: int; # connection state
+ spec: int; # special features
+ connect: int; # Direct, or Network
+ toplevel: ref Tk->Toplevel;
+ cmd: chan of string; # from Tk
+ proto: array of ref PState; # minitel protocol state
+ netaddr: string; # network address to dial
+ buttonsleft: int; # display buttons on the LHS (40 cols)
+ terminalid: array of byte; # ENQROM response
+ kbctl: chan of string; # softkeyboard control
+ kbmode: string; # softkeyboard mode
+
+ init: fn(t: self ref Terminal, toplevel: ref Tk->Toplevel, connect: int);
+ run: fn(t: self ref Terminal, done: chan of int);
+ reset: fn(t: self ref Terminal);
+ quit: fn(t: self ref Terminal);
+ layout: fn(t: self ref Terminal, cols: int);
+ setkbmode: fn(t: self ref Terminal, tmode: int);
+};
+
+include "arg.m";
+include "event.m";
+include "event.b";
+
+include "keyb.b";
+include "modem.b";
+include "socket.b";
+include "screen.b";
+
+K: ref Keyb;
+M: ref Modem;
+C: ref Socket;
+S: ref Screen;
+T: ref Terminal;
+Modules: array of ref Module;
+
+
+init(ctxt: ref Draw->Context, argv: list of string)
+{
+ s: string;
+ netaddr: string = nil;
+
+ sys = load Sys Sys->PATH;
+ tk = load Tk Tk->PATH;
+ tkclient = load Tkclient Tkclient->PATH;
+ tkclient->init();
+ draw = load Draw Draw->PATH;
+ stderr = sys->fildes(2);
+ pgrp = sys->pctl(Sys->NEWPGRP|Sys->FORKNS, nil);
+
+ arg := load Arg Arg->PATH;
+ arg->init(argv);
+ arg->setusage("miniterm [netaddr]");
+ while((c := arg->opt()) != 0){
+ case c {
+ 'D' =>
+ s = arg->earg();
+ for(i := 0; i < len s; i++){
+ c = s[i];
+ if(c < len debug)
+ debug[c] += 1;
+ }
+ * =>
+ arg->usage();
+ }
+ }
+ argv = arg->argv();
+ if(len argv > 0) {
+ netaddr = hd argv;
+ argv = tl argv;
+ }
+
+ if(argv != nil)
+ arg->usage();
+ arg = nil;
+
+ # usage: miniterm modem[!init[!number]]
+ # or miniterm tcp!a.b.c.d
+ connect: int;
+ initstr := dialstr := string nil;
+ if(netaddr == nil)
+ netaddr = "tcp!pdc.minitelfr.com!513"; # gateway
+ (nil, words) := sys->tokenize(netaddr, "!");
+ if(len words == 0) {
+ connect = Direct;
+ words = "modem" :: nil;
+ }
+ if(hd words == "modem") {
+ connect = Direct;
+ words = tl words;
+ if(words != nil) {
+ initstr = hd words;
+ words = tl words;
+ if(words != nil)
+ dialstr = hd words;
+ }
+ if(initstr == "*")
+ initstr = nil;
+ if(dialstr == "*")
+ dialstr = nil;
+ } else {
+ connect = Network;
+ dialstr = netaddr;
+ }
+
+ T = ref Terminal;
+ K = ref Keyb;
+ M = ref Modem;
+ C = ref Socket;
+ S = ref Screen;
+ Modules = array [Nmodule] of {
+ Mscreen => S.m,
+ Mmodem => M.m,
+ Mkeyb => K.m,
+ Msocket => C.m,
+ };
+
+ toplevel := tk->toplevel(ctxt.display, "");
+ inittk(toplevel, connect);
+
+ T.init(toplevel, connect);
+ K.init(toplevel);
+ M.init(connect, initstr, dialstr);
+ C.init();
+ case connect {
+ Direct =>
+ S.init(ctxt, Rect((0,0), (640,425)), Rect((0,0), (640,425)));
+ Network =>
+ S.init(ctxt, Rect((0,0), (596,440)), Rect((0,50), (640,350)));
+ }
+
+ done := chan of int;
+ spawn K.run();
+ spawn M.run();
+ spawn C.run();
+ spawn S.run();
+ spawn T.run(done);
+ <- done;
+
+ # now tidy up
+ K.quit();
+ M.quit();
+ C.quit();
+ S.quit();
+ T.quit();
+}
+
+# the keyboard module handles keypresses and focus
+BTN40x25: con "-height 24 -font {/fonts/lucidasans/unicode.6.font}";
+BTNCTL: con "-width 60 -height 20 -font {/fonts/lucidasans/unicode.7.font}";
+BTNMAIN: con "-width 80 -height 20 -font {/fonts/lucidasans/unicode.7.font}";
+
+tkinitbs := array[] of {
+ "button .cxfin -text {Cx/Fin} -command {send keyb skey Connect}",
+ "button .done -text {Quitter} -command {send keyb skey Exit}",
+ "button .hup -text {Raccr.} -command {send term hangup}",
+ "button .somm -text {Somm.} -command {send keyb skey Index}",
+ "button .guide -text {Guide} -command {send keyb skey Guide}",
+ "button .annul -text {Annul.} -command {send keyb skey Cancel}",
+ "button .corr -text {Corr.} -command {send keyb skey Correct}",
+ "button .retour -text {Retour} -command {send keyb skey Previous}",
+ "button .suite -text {Suite} -command {send keyb skey Next}",
+ "button .repet -text {Répét.} -command {send keyb skey Repeat}",
+ "button .envoi -text {Envoi} -command {send keyb skey Send}",
+ "button .play -text {P} -command {send term play}",
+# "button .db -text {D} -command {send term debug}" ,
+ "button .kb -text {Clavier} -command {send term keyboard}",
+ "button .move -text {<-} -command {send term buttonsleft} " + BTN40x25,
+};
+
+tkinitdirect := array [] of {
+ ". configure -background black -height 480 -width 640",
+
+ ".cxfin configure " + BTNCTL,
+ ".hup configure " + BTNCTL,
+ ".done configure " + BTNCTL,
+ ".somm configure " + BTNMAIN,
+ ".guide configure " + BTNMAIN,
+ ".annul configure " + BTNMAIN,
+ ".corr configure " + BTNMAIN,
+ ".retour configure " + BTNMAIN,
+ ".suite configure " + BTNMAIN,
+ ".repet configure " + BTNMAIN,
+ ".envoi configure " + BTNMAIN,
+# ".play configure " + BTNCTL,
+# ".db configure " + BTNCTL,
+ ".kb configure " + BTNCTL,
+
+ "canvas .c -height 425 -width 640 -background black",
+ "bind .c <Configure> {send term resize}",
+ "bind .c <Key> {send keyb key %K}",
+ "bind .c <FocusIn> {send keyb focusin}",
+ "bind .c <FocusOut> {send keyb focusout}",
+ "bind .c <ButtonRelease> {focus .c; send keyb click %x %y}",
+ "frame .k -height 55 -width 640 -background black",
+ "pack propagate .k no",
+ "frame .klhs -background black",
+ "frame .krhs -background black",
+ "frame .krows -background black",
+ "frame .k1 -background black",
+ "frame .k2 -background black",
+ "pack .cxfin -in .klhs -anchor w -pady 4",
+ "pack .hup -in .klhs -anchor w",
+ "pack .somm .annul .retour .repet -in .k1 -side left -padx 2",
+ "pack .guide .corr .suite .envoi -in .k2 -side left -padx 2",
+ "pack .kb -in .krhs -anchor e -pady 4",
+ "pack .done -in .krhs -anchor e",
+ "pack .k1 -in .krows -pady 4",
+ "pack .k2 -in .krows",
+ "pack .klhs .krows .krhs -in .k -side left -expand 1 -fill x",
+ "pack .c .k",
+ "focus .c",
+ "update",
+};
+
+tkinitip := array [] of {
+ ". configure -background black -height 440 -width 640",
+
+ # ip 40x25 mode support
+ "canvas .c40 -height 440 -width 596 -background black",
+ "bind .c40 <Configure> {send term resize}",
+ "bind .c40 <Key> {send keyb key %K}",
+ "bind .c40 <FocusIn> {send keyb focusin}",
+ "bind .c40 <FocusOut> {send keyb focusout}",
+ "bind .c40 <ButtonRelease> {focus .c40; send keyb click %x %y}",
+ "frame .k -height 427 -width 44 -background black",
+ "frame .gap1 -background black",
+ "frame .gap2 -background black",
+ "pack propagate .k no",
+
+ # ip 80x25 mode support
+ "frame .padtop -height 50",
+ "canvas .c80 -height 300 -width 640 -background black",
+ "bind .c80 <Configure> {send term resize}",
+ "bind .c80 <Key> {send keyb key %K}",
+ "bind .c80 <FocusIn> {send keyb focusin}",
+ "bind .c80 <FocusOut> {send keyb focusout}",
+ "bind .c80 <ButtonRelease> {focus .c80; send keyb click %x %y}",
+ "frame .k80 -height 90 -width 640 -background black",
+ "pack propagate .k80 no",
+ "frame .klhs -background black",
+ "frame .krows -background black",
+ "frame .krow1 -background black",
+ "frame .krow2 -background black",
+ "frame .krhs -background black",
+ "pack .krow1 .krow2 -in .krows -pady 2",
+ "pack .klhs -in .k80 -side left",
+ "pack .krows -in .k80 -side left -expand 1",
+ "pack .krhs -in .k80 -side left",
+};
+
+tkip40x25show := array [] of {
+ ".cxfin configure " + BTN40x25,
+ ".hup configure " + BTN40x25,
+ ".done configure " + BTN40x25,
+ ".somm configure " + BTN40x25,
+ ".guide configure " + BTN40x25,
+ ".annul configure " + BTN40x25,
+ ".corr configure " + BTN40x25,
+ ".retour configure " + BTN40x25,
+ ".suite configure " + BTN40x25,
+ ".repet configure " + BTN40x25,
+ ".envoi configure " + BTN40x25,
+ ".play configure " + BTN40x25,
+# ".db configure " + BTN40x25,
+ ".kb configure " + BTN40x25,
+ "pack .cxfin -in .k -side top -fill x",
+ "pack .gap1 -in .k -side top -expand 1",
+ "pack .guide .repet .somm .annul .corr .retour .suite .envoi -in .k -side top -fill x",
+ "pack .gap2 -in .k -side top -expand 1",
+ "pack .done .hup .kb .move -in .k -side bottom -pady 2 -fill x",
+# "pack .db -in .k -side bottom",
+};
+
+tkip40x25lhs := array [] of {
+ ".move configure -text {->} -command {send term buttonsright}",
+ "pack .k .c40 -side left",
+ "focus .c40",
+ "update",
+};
+
+tkip40x25rhs := array [] of {
+ ".move configure -text {<-} -command {send term buttonsleft}",
+ "pack .c40 .k -side left",
+ "focus .c40",
+ "update",
+};
+
+tkip40x25hide := array [] of {
+ "pack forget .k .c40",
+};
+
+tkip80x25show := array [] of {
+ ".cxfin configure " + BTNCTL,
+ ".hup configure " + BTNCTL,
+ ".done configure " + BTNCTL,
+ ".somm configure " + BTNMAIN,
+ ".guide configure " + BTNMAIN,
+ ".annul configure " + BTNMAIN,
+ ".corr configure " + BTNMAIN,
+ ".retour configure " + BTNMAIN,
+ ".suite configure " + BTNMAIN,
+ ".repet configure " + BTNMAIN,
+ ".envoi configure " + BTNMAIN,
+# ".play configure " + BTNCTL,
+# ".db configure " + BTNCTL,
+ ".kb configure " + BTNCTL,
+
+ "pack .cxfin .hup -in .klhs -anchor w -pady 2",
+ "pack .somm .annul .retour .repet -in .krow1 -side left -padx 2",
+ "pack .guide .corr .suite .envoi -in .krow2 -side left -padx 2",
+ "pack .done .kb -in .krhs -anchor e -pady 2",
+ "pack .padtop .c80 .k80 -side top",
+ "focus .c80",
+ "update",
+};
+
+tkip80x25hide := array [] of {
+ "pack forget .padtop .c80 .k80",
+};
+
+inittk(toplevel: ref Tk->Toplevel, connect: int)
+{
+ tkcmds(toplevel, tkinitbs);
+ if(connect == Direct)
+ tkcmds(toplevel, tkinitdirect);
+ else
+ tkcmds(toplevel, tkinitip);
+}
+
+Terminal.layout(t: self ref Terminal, cols: int)
+{
+ if(t.connect == Direct)
+ return;
+ if(cols == 80) {
+ tkcmds(t.toplevel, tkip40x25hide);
+ tkcmds(t.toplevel, tkip80x25show);
+ } else {
+ tkcmds(t.toplevel, tkip80x25hide);
+ tkcmds(t.toplevel, tkip40x25show);
+ if (t.buttonsleft)
+ tkcmds(t.toplevel, tkip40x25lhs);
+ else
+ tkcmds(t.toplevel, tkip40x25rhs);
+ }
+}
+
+Terminal.init(t: self ref Terminal, toplevel: ref Tk->Toplevel, connect: int)
+{
+ t.in = chan of ref Event;
+ t.proto = array [Nmodule] of {
+ Mscreen => ref PState(PSstart, array [] of {0,0,0}, 0, 0, 0),
+ Mmodem => ref PState(PSstart, array [] of {0,0,0}, 0, 0, 0),
+ Mkeyb => ref PState(PSstart, array [] of {0,0,0}, 0, 0, 0),
+ Msocket => ref PState(PSstart, array [] of {0,0,0}, 0, 0, 0),
+ };
+
+ t.toplevel = toplevel;
+ t.connect = connect;
+ if (t.connect == Direct)
+ t.spec = 0;
+ else
+ t.spec = Echo;
+ t.cmd = chan of string;
+ tk->namechan(t.toplevel, t.cmd, "term"); # Tk -> terminal
+ t.state = Local;
+ t.buttonsleft = 0;
+ t.kbctl = nil;
+ t.kbmode = "minitel";
+ t.reset();
+}
+
+Terminal.reset(t: self ref Terminal)
+{
+ t.mode = Videotex;
+}
+
+Terminal.run(t: self ref Terminal, done: chan of int)
+{
+ t.out = array [Nmodule] of {
+ Mscreen => ref BufChan(Pscreen, nil, nil, S.in, array [0] of ref Event),
+ Mmodem => ref BufChan(Pmodem, nil, nil, M.in, array [0] of ref Event),
+ Mkeyb => ref BufChan(Pkeyb, nil, nil, K.in, array [0] of ref Event),
+ Msocket => ref BufChan(Psocket, nil, nil, C.in, array [0] of ref Event),
+ };
+ modcount := Nmodule;
+ if(debug['P'])
+ post(ref Event.Eproto(Pmodem, 0, Cplay, "play", 0,0,0));
+Evloop:
+ for(;;) {
+ ev: ref Event = nil;
+ post(nil);
+ alt {
+ # recv message from one of the modules
+ ev =<- t.in =>
+ if(ev == nil) { # modules ack Equit with nil
+ if(--modcount == 0)
+ break Evloop;
+ continue;
+ }
+ pick e := ev {
+ Equit => # close modules down
+ post(ref Event.Equit(Pscreen|Pmodem|Pkeyb|Psocket,0));
+ continue;
+ }
+
+ eva := protocol(ev);
+ while(len eva > 0) {
+ post(eva[0]);
+ eva = eva[1:];
+ }
+
+ # send message to `plumbed' modules
+ t.out[Mscreen].ch <- = t.out[Mscreen].ev =>
+ t.out[Mscreen].ev = nil;
+ t.out[Mmodem].ch <- = t.out[Mmodem].ev =>
+ t.out[Mmodem].ev = nil;
+ t.out[Mkeyb].ch <- = t.out[Mkeyb].ev =>
+ t.out[Mkeyb].ev = nil;
+ t.out[Msocket].ch <- = t.out[Msocket].ev =>
+ t.out[Msocket].ev = nil;
+
+ # recv message from Tk
+ cmd := <- t.cmd =>
+ (n, word) := sys->tokenize(cmd, " ");
+ if(n >0)
+ case hd word {
+ "resize" => ;
+ "play" => # for testing only
+ post(ref Event.Eproto(Pmodem, Mmodem, Cplay, "play", 0,0,0));
+ "keyboard" =>
+ if (t.kbctl == nil) {
+ e: string;
+ (e, t.kbctl) = kb(t);
+ if (e != nil)
+ sys->print("cannot start keyboard: %s\n", e);
+ } else
+ t.kbctl <- = "click";
+ "hangup" =>
+ if(T.state == Online || T.state == Connecting)
+ post(ref Event.Eproto(Pmodem, 0, Cdisconnect, "",0,0,0));
+ "buttonsleft" =>
+ tkcmds(t.toplevel, tkip40x25lhs);
+ t.buttonsleft = 1;
+ if(S.image != nil)
+ draw->(S.image.origin)(Point(0,0), Point(44, 0));
+ if (t.kbctl != nil)
+ t.kbctl <- = "fg";
+ "buttonsright" =>
+ tkcmds(t.toplevel, tkip40x25rhs);
+ t.buttonsleft = 0;
+ if(S.image != nil)
+ draw->(S.image.origin)(Point(0,0), Point(0, 0));
+ if (t.kbctl != nil)
+ t.kbctl <- = "fg";
+ "debug" =>
+ debug['s'] ^= 1;
+ debug['m'] ^= 1;
+ }
+ }
+
+ }
+ if (t.kbctl != nil)
+ t.kbctl <- = "quit";
+ t.kbctl = nil;
+ done <-= 0;
+}
+
+kb(t: ref Terminal): (string, chan of string)
+{
+ s := chan of string;
+ spawn dokb(t, s);
+ e := <- s;
+ if (e != nil)
+ return (e, nil);
+ return (nil, s);
+}
+
+Terminal.setkbmode(t: self ref Terminal, tmode: int)
+{
+ case tmode {
+ Videotex =>
+ t.kbmode = "minitel";
+ Mixed or Ascii =>
+ t.kbmode = "standard";
+ }
+ if(t.kbctl != nil) {
+ t.kbctl <-= "mode";
+ t.kbctl <-= "fg";
+ }
+}
+
+include "swkeyb.m";
+dokb(t: ref Terminal, c: chan of string)
+{
+ keyboard := load Keyboard Keyboard->PATH;
+ if (keyboard == nil) {
+ c <- = "cannot load keyboard";
+ return;
+ }
+
+ kbctl := chan of string;
+ (top, m) := tkclient->toplevel(S.ctxt, "", "Keyboard", 0);
+ tk->cmd(top, "pack .Wm_t -fill x");
+ tk->cmd(top, "update");
+ keyboard->chaninit(top, S.ctxt, ".keys", kbctl);
+ tk->cmd(top, "pack .keys");
+
+ kbctl <-= t.kbmode ;
+
+ kbon := 1;
+ c <- = nil; # all ok, we are now ready to accept commands
+
+ for (;;) alt {
+ mcmd := <- m =>
+ if (mcmd == "exit") {
+ if (kbon) {
+ tk->cmd(top, ". unmap; update");
+ kbon = 0;
+ }
+ } else
+ tkclient->wmctl(top, mcmd);
+ kbcmd := <- c =>
+ case kbcmd {
+ "fg" =>
+ if (kbon)
+ tk->cmd(top, "raise .;update");
+ "click" =>
+ if (kbon) {
+ tk->cmd(top, ". unmap; update");
+ kbon = 0;
+ } else {
+ tk->cmd(top, ". map; raise .");
+ kbon = 1;
+ }
+ "mode" =>
+ kbctl <- = t.kbmode;
+ "quit" =>
+ kbctl <- = "kill";
+ top = nil;
+ # ensure tkclient not blocked on a send to us (probably overkill!)
+ alt {
+ <- m => ;
+ * => ;
+ }
+ return;
+ }
+ }
+}
+
+
+Terminal.quit(nil: self ref Terminal)
+{
+}
+
+# a minitel module sends an event to the terminal for routing
+send(e: ref Event)
+{
+ if(debug['e'] && e != nil)
+ fprint(stderr, "%s: -> %s\n", Modname[e.from], e.str());
+ T.in <- = e;
+}
+
+# post an event to one or more modules
+post(e: ref Event)
+{
+ i,l: int;
+ for(i=0; i<Nmodule; i++) {
+ # `ev' is cleared once sent, reload it from the front of `q'
+ b: ref BufChan = T.out[i];
+ l = len b.q;
+ if(b.ev == nil && l != 0) {
+ b.ev = b.q[0];
+ na := array [l-1] of ref Event;
+ na[0:] = b.q[1:];
+ b.q = na;
+ }
+ if (e != nil) {
+ if(e.path & b.path) {
+ if(debug['e'] > 0) {
+ pick de := e {
+ * =>
+ fprint(stderr, "[%s<-%s] %s\n", Modname[i], Modname[e.from], e.str());
+ }
+ }
+ if(b.ev == nil) # nothing queued
+ b.ev = e;
+ else { # enqueue it
+ l = len b.q;
+ na := array [l+1] of ref Event;
+ na[0:] = b.q[0:];
+ na[l] = e;
+ b.q = na;
+ }
+ }
+ }
+ # set a dummy channel if nothing to send
+ if(b.ev == nil)
+ b.ch = chan of ref Event;
+ else
+ b.ch = b.in;
+ }
+}
+
+# run the terminal protocol
+protocol(ev: ref Event): array of ref Event
+{
+ # Introduced by the following sequences, the minitel protocol can be
+ # embedded in any normal data sequence
+ # ESC,0x39,X
+ # ESC,0x3a,X,Y
+ # ESC,0x3b,X,Y,Z
+ # ESC,0x61 - cursor position request
+
+ ea := array [0] of ref Event; # resulting sequence of Events
+ changed := 0; # if set, results are found in `ea'
+
+ pick e := ev {
+ Edata =>
+ d0 := 0; # offset of start of last data sequence
+ p := T.proto[e.from];
+ for(i:=0; i<len e.data; i++) {
+ ch := int e.data[i];
+# if(debug['p'])
+# fprint(stderr, "protocol: [%s] %d %ux (%c)\n", Modname[e.from], p.state, ch, ch);
+ if(p.skip > 0) { # in transparency mode
+ if(ch == 0 && e.from == Mmodem) # 5.0
+ continue;
+ p.skip--;
+ continue;
+ }
+ case p.state {
+ PSstart =>
+ if(ch == ESC) {
+ p.state = PSesc;
+ changed = 1;
+ if(i > d0)
+ ea = eappend(ea, ref Event.Edata(e.path, e.from, e.data[d0:i]));
+ d0 = i+1;
+ }
+ PSesc =>
+ p.state = PSarg;
+ p.n = 0;
+ d0 = i+1;
+ changed = 1;
+ if(ch >= 16r39 && ch <= 16r3b) #PRO1,2,3
+ p.nargs = ch - 16r39 + 1;
+ else if(ch == 16r61) # cursor position request
+ p.nargs = 0;
+ else if(ch == ESC) {
+ ea = eappend(ea, ref Event.Edata(e.path, e.from, array [] of { byte ESC }));
+ p.state = PSesc;
+ } else {
+ # false alarm, restore as data
+ ea = eappend(ea, ref Event.Edata(e.path, e.from, array [] of { byte ESC, byte ch }));
+ p.state = PSstart;
+ }
+ PSarg => # expect `nargs' bytes
+ d0 = i+1;
+ changed =1;
+ if(p.n < p.nargs)
+ p.arg[p.n++] = ch;
+ if(p.n == p.nargs) {
+ # got complete protocol sequence
+ pe := proto(e.from, p);
+ if(pe != nil)
+ ea = eappend(ea, pe);
+ p.state = PSstart;
+ }
+ }
+ }
+ if(changed) { # some interpretation, results in `ea'
+ if(i > d0)
+ ea = eappend(ea, ref Event.Edata(e.path, e.from, e.data[d0:i]));
+ return ea;
+ }
+ ev = e;
+ return array [] of {ev};
+ }
+ return array [] of {ev};
+}
+
+# append to an Event array
+eappend(ea: array of ref Event, e: ref Event): array of ref Event
+{
+ l := len ea;
+ na := array [l+1] of ref Event;
+ na[0:] = ea[0:];
+ na[l] = e;
+ return na;
+}
+
+# act on a received protocol sequence
+# some sequences are handled here by the terminal and result in a posted reply
+# others are returned `inline' as Eproto events with the normal data stream.
+proto(from: int, p: ref PState): ref Event
+{
+ if(debug['p']) {
+ fprint(stderr, "PRO%d: %ux", p.nargs, p.arg[0]);
+ if(p.nargs > 1)
+ fprint(stderr, " %ux", p.arg[1]);
+ if(p.nargs > 2)
+ fprint(stderr, " %ux", p.arg[2]);
+ fprint(stderr, " (%s)\n", Modname[from]);
+ }
+ case p.nargs {
+ 0 => # cursor position request ESC 0x61
+ reply := array [] of { byte US, byte S.pos.y, byte S.pos.x };
+ post(ref Event.Edata(Pmodem, from, reply));
+ 1 =>
+ case p.arg[0] {
+ PROTOCOLSTATUS => ;
+ ENQROM => # identification request
+ post(ref Event.Edata(Pmodem, from, T.terminalid));
+ if(T.terminalid == TERMINALID1)
+ T.terminalid = TERMINALID2;
+ SETRAM1 or SETRAM2 => ;
+ FUNCTIONINGSTATUS => # 11.3
+ PRO2(Pmodem, from, REPFUNCTIONINGSTATUS, osb());
+ CONNECT => ;
+ DISCONNECT =>
+ return ref Event.Eproto(Pscreen, from, Cscreenoff, "",0,0,0);
+ RESET => # reset the minitel terminal
+ all := Pscreen|Pmodem|Pkeyb|Psocket;
+ post(ref Event.Eproto(all, from, Creset, "",0,0,0)); # check
+ T.reset();
+ reply := array [] of { byte SEP, byte 16r5E };
+ post(ref Event.Edata(Pmodem, from, reply));
+ }
+ 2 =>
+ case p.arg[0] {
+ TO => # request for module status
+ PRO3(Pmodem, from, FROM, p.arg[1], psb(p.arg[1]));
+ NOBROADCAST => ;
+ BROADCAST => ;
+ TRANSPARENCY => # transparency mode - skip bytes
+ p.skip = p.arg[1];
+ if(p.skip < 1 || p.skip > 127) # 5.0
+ p.skip = 0;
+ else {
+ reply := array [] of { byte SEP, byte 16r57 };
+ post(ref Event.Edata(Pmodem, from, reply));
+ }
+ KEYBOARDSTATUS =>
+ if(p.arg[1] == RxKeyb)
+ PRO3(Pmodem, from, REPKEYBOARDSTATUS, RxKeyb, kosb());
+ START =>
+ x := osb();
+ if(p.arg[1] == PROCEDURE)
+ x |= 16r04;
+ if(p.arg[1] == SCROLLING)
+ x |= 16r02;
+ PRO2(Pmodem, from, REPFUNCTIONINGSTATUS, x);
+ case p.arg[1] {
+ PROCEDURE => # activate error correction procedure
+ sys->print("activate error correction\n");
+ return ref Event.Eproto(Pmodem, from, Cstartecp, "",0,0,0);
+ SCROLLING => # set screen to scroll
+ return ref Event.Eproto(Pscreen, from, Cproto, "",START,SCROLLING,0);
+ LOWERCASE => # set keyb to invert case
+ return ref Event.Eproto(Pkeyb, from, Cproto, "",START,LOWERCASE,0);
+ }
+ STOP =>
+ x := osb();
+ if(p.arg[1] == SCROLLING)
+ x &= ~16r02;
+ PRO2(Pmodem, from, REPFUNCTIONINGSTATUS, osb());
+ case p.arg[1] {
+ PROCEDURE => # deactivate error correction procedure
+ sys->print("deactivate error correction\n");
+ return ref Event.Eproto(Pmodem, from, Cstopecp, "",0,0,0);
+ SCROLLING => # set screen to no scroll
+ return ref Event.Eproto(Pscreen, from, Cproto, "",STOP,SCROLLING,0);
+ LOWERCASE => # set keyb to not invert case
+ return ref Event.Eproto(Pkeyb, from, Cproto, "",STOP,LOWERCASE,0);
+ }
+ COPY => # copy screen to socket
+ # not implemented
+ ;
+ MIXED => # change video mode (12.1)
+ case p.arg[1] {
+ MIXED1 => # videotex -> mixed
+ reply := array [] of { byte SEP, byte 16r70 };
+ return ref Event.Eproto(Pscreen, from, Cproto, "",MIXED,MIXED1,0);
+ MIXED2 => # mixed -> videotex
+ reply := array [] of { byte SEP, byte 16r71 };
+ return ref Event.Eproto(Pscreen, from, Cproto, "",MIXED,MIXED2,0);
+ }
+ ASCII => # change video mode (12.2)
+ # TODO
+ ;
+ }
+ 3 =>
+ case p.arg[0] {
+ OFF or ON => # link, unlink, enable, disable
+ modcmd(p.arg[0], p.arg[1], p.arg[2]);
+ PRO3(Pmodem, from, FROM, p.arg[1], psb(TxCode(p.arg[1])));
+ START =>
+ case p.arg[1] {
+ RxKeyb => # keyboard mode
+ case p.arg[2] {
+ ETEN => # extended keyboard
+ K.spec |= Extend;
+ C0 => # cursor control key coding from col 0
+ K.spec |= C0keys;
+ }
+ PRO3(Pmodem, from, REPKEYBOARDSTATUS, RxKeyb, kosb());
+ }
+ STOP => # keyboard mode
+ case p.arg[1] {
+ RxKeyb => # keyboard mode
+ case p.arg[2] {
+ ETEN => # extended keyboard
+ K.spec &= ~Extend;
+ C0 => # cursor control key coding from col 0
+ K.spec &= ~C0keys;
+ }
+ PRO3(Pmodem, from, REPKEYBOARDSTATUS, RxKeyb, kosb());
+ }
+ }
+ }
+ return nil;
+}
+
+# post a PRO3 sequence to all modules on `path'
+PRO3(path, from, x, y, z: int)
+{
+ data := array [] of { byte ESC, byte 16r3b, byte x, byte y, byte z};
+ post(ref Event.Edata(path, from, data));
+}
+
+# post a PRO2 sequence to all modules on `path'
+PRO2(path, from, x, y: int)
+{
+ data := array [] of { byte ESC, byte 16r3a, byte x, byte y};
+ post(ref Event.Edata(path, from, data));
+}
+
+# post a PRO1 sequence to all modules on `path'
+PRO1(path, from, x: int)
+{
+ data := array [] of { byte ESC, byte 16r39, byte x};
+ post(ref Event.Edata(path, from, data));
+}
+
+# make or break links between modules, or enable and disable
+modcmd(cmd, from, targ: int)
+{
+ from = RxTx(from);
+ targ = RxTx(targ);
+ if(from == targ) # enable or disable module
+ if(cmd == ON)
+ Modules[from].disabled = 0;
+ else
+ Modules[from].disabled = 1;
+ else # modify path
+ if(cmd == ON)
+ Modules[from].path |= (1<<targ);
+ else
+ Modules[from].path &= ~(1<<targ);
+}
+
+# determine the path status byte (3.4)
+# if bit 3 of `code' is set then a receive path status byte is returned
+# otherwise a transmit path status byte
+psb(code: int): int
+{
+ this := RxTx(code);
+ b := 16r40; # bit 6 always set
+ if(code == RxCode(code)) { # want a receive path status byte
+ mask := (1<<this);
+ if(Modules[Mscreen].path & mask)
+ b |= 16r01;
+ if(Modules[Mkeyb].path & mask)
+ b |= 16r02;
+ if(Modules[Mmodem].path & mask)
+ b |= 16r04;
+ if(Modules[Msocket].path & mask)
+ b |= 16r08;
+ } else {
+ mod := Modules[this];
+ if(mod.path & Mscreen)
+ b |= 16r01;
+ if(mod.path & Mkeyb)
+ b |= 16r02;
+ if(mod.path & Mmodem)
+ b |= 16r04;
+ if(mod.path & Msocket)
+ b |= 16r08;
+ }
+# if(parity(b))
+# b ^= 16r80;
+ return b;
+}
+
+# convert `code' to a receive code by setting bit 3
+RxCode(code: int): int
+{
+ return (code | 16r08)&16rff;
+}
+
+# covert `code' to a send code by clearing bit 3
+TxCode(code: int): int
+{
+ return (code & ~16r08)&16rff;
+}
+
+# return 0 on even parity, 1 otherwise
+# only the bottom 8 bits are considered
+parity(b: int): int
+{
+ bits := 8;
+ p := 0;
+ while(bits-- > 0) {
+ if(b&1)
+ p ^= 1;
+ b >>= 1;
+ }
+ return p;
+}
+
+# convert Rx or Tx code to a module code
+RxTx(code: int): int
+{
+ rv := 0;
+ case code {
+ TxScreen or RxScreen => rv = Mscreen;
+ TxKeyb or RxKeyb => rv = Mkeyb;
+ TxModem or RxModem => rv = Mmodem;
+ TxSocket or RxSocket => rv = Msocket;
+ * =>
+ fatal("invalid module code");
+ }
+ return rv;
+}
+
+# generate an operating status byte (11.2)
+osb(): int
+{
+ b := 16r40;
+ if(S.cols == 80)
+ b |= 16r01;
+ if(S.spec & Scroll)
+ b |= 16r02;
+ if(M.spec & Ecp)
+ b |= 16r04;
+ if(K.spec & Invert)
+ b |= 16r08;
+# if(parity(b))
+# b ^= 16r80;
+ return b;
+}
+
+# generate a keyboard operating status byte (9.1.2)
+kosb(): int
+{
+ b := 16r40;
+ if(K.spec & Extend)
+ b |= 16r01;
+ if(K.spec & C0keys)
+ b |= 16r04;
+# if(parity(b))
+# b ^= 16r80;
+ return b;
+}
+
+hex(v, n: int): string
+{
+ return sprint("%.*ux", n, v);
+}
+
+tostr(ch: int): string
+{
+ str := "";
+ str[0] = ch;
+ return str;
+}
+
+toint(s: string, base: int): (int, string)
+{
+ if(base < 0 || base > 36)
+ return (0, s);
+
+ c := 0;
+ for(i := 0; i < len s; i++) {
+ c = s[i];
+ if(c != ' ' && c != '\t' && c != '\n')
+ break;
+ }
+
+ neg := 0;
+ if(c == '+' || c == '-') {
+ if(c == '-')
+ neg = 1;
+ i++;
+ }
+
+ ok := 0;
+ n := 0;
+ for(; i < len s; i++) {
+ c = s[i];
+ v := base;
+ case c {
+ 'a' to 'z' =>
+ v = c - 'a' + 10;
+ 'A' to 'Z' =>
+ v = c - 'A' + 10;
+ '0' to '9' =>
+ v = c - '0';
+ }
+ if(v >= base)
+ break;
+ ok = 1;
+ n = n * base + v;
+ }
+
+ if(!ok)
+ return (0, s);
+ if(neg)
+ n = -n;
+ return (n, s[i:]);
+}
+
+tolower(s: string): string
+{
+ r := s;
+ for(i := 0; i < len r; i++) {
+ c := r[i];
+ if(c >= int 'A' && c <= int 'Z')
+ r[i] = r[i] + (int 'a' - int 'A');
+ }
+ return r;
+}
+
+# duplicate `ch' exactly `n' times
+dup(ch, n: int): string
+{
+ str := "";
+ for(i:=0; i<n; i++)
+ str[i] = ch;
+ return str;
+}
+
+fatal(msg: string)
+{
+ fprint(stderr, "fatal: %s\n", msg);
+ exits(msg);
+}
+
+exits(s: string)
+{
+ if(s==nil);
+# raise "fail: miniterm " + s;
+ fd := sys->open("#p/" + string pgrp + "/ctl", sys->OWRITE);
+ if(fd != nil)
+ sys->fprint(fd, "killgrp");
+ exit;
+}
+
+# Minitel byte MSB and LSB classification (p.87)
+MSB(ch: int): int
+{
+ return (ch&16r70)>>4;
+}
+LSB(ch: int): int
+{
+ return (ch&16r0f);
+}
+
+# Minitel character set classification (p.92)
+ISC0(ch: int): int
+{
+ msb := (ch&16r70)>>4;
+ return msb == 0 || msb == 1;
+}
+
+ISC1(ch: int): int
+{
+ return ch >= 16r40 && ch <= 16r5f;
+}
+
+ISG0(ch: int): int
+{
+ # 0x20 (space) and 0x7f (DEL) are not in G0
+ return ch > 16r20 && ch < 16r7f;
+}
+
+tkcmds(t: ref Tk->Toplevel, cmds: array of string)
+{
+ n := len cmds;
+ for (ix := 0; ix < n; ix++)
+ tk->cmd(t, cmds[ix]);
+}
diff --git a/appl/wm/minitel/miniterm.dis b/appl/wm/minitel/miniterm.dis
new file mode 100644
index 00000000..39c6ba5e
--- /dev/null
+++ b/appl/wm/minitel/miniterm.dis
Binary files differ
diff --git a/appl/wm/minitel/miniterm.m b/appl/wm/minitel/miniterm.m
new file mode 100644
index 00000000..e0345f81
--- /dev/null
+++ b/appl/wm/minitel/miniterm.m
@@ -0,0 +1,120 @@
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+# Common control bytes
+NUL: con 16r00;
+SOH: con 16r01;
+EOT: con 16r04;
+ENQ: con 16r05;
+BEL: con 16r07;
+BS: con 16r08;
+HT: con 16r09;
+LF: con 16r0a;
+VT: con 16r0b;
+FF: con 16r0c;
+CR: con 16r0d;
+SO: con 16r0e;
+SI: con 16r0f;
+DLE: con 16r10;
+CON: con 16r11;
+XON: con 16r11;
+REP: con 16r12;
+SEP: con 16r13;
+XOFF: con 16r13;
+COFF: con 16r14;
+NACK: con 16r15;
+SYN: con 16r16;
+CAN: con 16r18;
+SS2: con 16r19;
+SUB: con 16r1a;
+ESC: con 16r1b;
+SS3: con 16r1d;
+RS: con 16r1e;
+US: con 16r1f;
+
+SP: con 16r20;
+DEL: con 16r7f;
+
+# Minitel Protocol - some are duplicated (chapter 6)
+ASCII: con 16r31;
+MIXED: con 16r32;
+ETEN: con 16r41;
+C0: con 16r43;
+SCROLLING: con 16r43;
+PROCEDURE: con 16r44;
+LOWERCASE: con 16r45;
+OFF: con 16r60;
+ON: con 16r61;
+TO: con 16r62;
+FROM: con 16r63;
+NOBROADCAST: con 16r64;
+BROADCAST: con 16r65;
+NONRETURN: con 16r64;
+RETURN: con 16r65;
+TRANSPARENCY: con 16r66;
+DISCONNECT: con 16r67;
+CONNECT: con 16r68;
+START: con 16r69;
+STOP: con 16r6a;
+KEYBOARDSTATUS: con 16r72;
+REPKEYBOARDSTATUS: con 16r73;
+FUNCTIONINGSTATUS: con 16r72;
+REPFUNCTIONINGSTATUS: con 16r73;
+EXCHANGERATESTATUS: con 16r74;
+REPEXCHANGERATESTATUS: con 16r75;
+PROTOCOLSTATUS: con 16r76;
+REPPROTOCOLSTATUS: con 16r77;
+SETRAM1: con 16r78;
+SETRAM2: con 16r79;
+ENQROM: con 16r7b;
+COPY: con 16r7c;
+ASCII1: con 16r7d;
+MIXED1: con 16r7d;
+MIXED2: con 16r7e;
+RESET: con 16r7f;
+
+# Module send and receive codes (chapter 6)
+TxScreen: con 16r50;
+TxKeyb: con 16r51;
+TxModem: con 16r52;
+TxSocket: con 16r53;
+RxScreen: con 16r58;
+RxKeyb: con 16r59;
+RxModem: con 16r5a;
+RxSocket: con 16r5b;
+
+# Internal Event.Eproto command constants
+Cplay, # for testing
+Cconnect, # e.s contains the address to dial
+Cdisconnect, #
+Crequestecp, # ask server to start ecp
+Creset, # reset module
+Cstartecp, # start error correction
+Cstopecp, # stop error correction
+Cproto, # minitel protocol
+Ccursor, # update screen cursor
+Cindicators, # update row 0 indicators
+
+# softmodem bug: Cscreenoff, Cscreenon
+Cscreenoff, # screen: ignore data
+Cscreenon, # screen: don't ignore data
+
+Clast
+ : con iota;
+
+# Special keys - hardware returned byte
+KupPC: con 16r0203; # pc emu
+KdownPC: con 16r0204; # pc emu
+Kup: con 16rE012;
+Kdown: con 16rE013;
+Kenter: con 16r000a;
+Kback: con 16r0008;
+Kesc: con 16r001b;
+KF1: con 16rE041;
+KF2: con 16rE042;
+KF3: con 16rE043;
+KF4: con 16rE044;
+KF13: con 16rE04D;
+
+
diff --git a/appl/wm/minitel/miniterm.sbl b/appl/wm/minitel/miniterm.sbl
new file mode 100644
index 00000000..a34fa8b1
--- /dev/null
+++ b/appl/wm/minitel/miniterm.sbl
@@ -0,0 +1,6810 @@
+limbo .sbl 2.1
+Miniterm
+15
+miniterm.b
+sys.m
+draw.m
+tk.m
+tkclient.m
+miniterm.m
+arg.m
+event.m
+event.b
+keyb.b
+modem.b
+socket.b
+screen.b
+mdisplay.m
+swkeyb.m
+5725
+8:7.1,9 0
+8.6,13 1
+6,13 1
+10.3,40 2
+14,27 2
+29,39 2
+3,40 2
+3,40 2
+11.7,11 3
+15,25 4
+13,25 4
+12.9,30 5
+9,30 5
+28,29 5
+17,26 5
+13,26 5
+9,30 5
+9,30 5
+9,36 5
+4,36 5
+4,36 6
+11.27,30 7
+27,30 7
+14.3,14 8
+3,14 1
+16.3,44 9
+14,31 9
+33,38 9
+40,43 9
+3,44 9
+3,44 9
+3,44 1
+18.8,9 10
+1,9 10
+9:27.1,25 11
+28.1,23 12
+29.1,38 13
+14,22 13
+24,29 13
+31,37 13
+1,38 13
+1,38 13
+1,38 14
+30.1,10 15
+1,2 15
+1,10 15
+31.0,1 16
+35.1,36 17
+18,32 17
+34,35 17
+1,36 17
+1,36 18
+36.0,1 19
+42.1,18 20
+43.1,20 21
+1,2 21
+11,19 21
+1,20 21
+46.1,24 22
+47.1,14 23
+1,2 23
+7,13 23
+1,14 23
+51.20,30 24
+2,30 24
+53.6,12 25
+54.3,10 26
+3,10 27
+56.3,8 28
+57.2,28 29
+2,3 29
+17,27 29
+17,23 29
+17,27 29
+8,27 29
+8,27 30
+2,28 29
+58.2,14 31
+59.6,17 32
+60.3,9 33
+62.2,23 34
+18,22 34
+2,23 34
+2,23 34
+64.7,11 35
+66.3,8 36
+68.6,16 37
+6,20 37
+69.23,33 38
+23,36 38
+4,37 38
+4,37 35
+71.3,14 39
+72.3,8 40
+73.2,21 35
+76.3,17 41
+3,17 35
+80.1,11 42
+1,2 42
+7,10 42
+1,11 42
+82.1,4 43
+1,4 43
+84.11,13 43
+11,13 43
+81.10,16 43
+10,16 43
+10,16 43
+10,16 43
+83.2,8 44
+85.6,17 45
+86.3,9 46
+92.1,26 47
+93.1,19 48
+94.1,26 49
+98.11,15 50
+11,15 50
+122.12,17 50
+12,17 50
+215.15,22 50
+15,22 50
+97.2,8 50
+2,8 50
+2,8 50
+2,8 50
+99.8,15 51
+8,15 51
+8,15 52
+101.4,9 53
+103.9,14 54
+9,14 54
+9,14 54
+9,14 54
+9,14 54
+105.5,14 55
+5,6 55
+5,14 55
+5,14 54
+107.10,14 56
+109.11,15 57
+111.7,23 58
+7,23 57
+7,23 56
+114.11,15 59
+116.7,24 60
+7,24 59
+7,24 56
+7,24 54
+119.9,14 61
+9,14 62
+9,14 50
+123.6,16 63
+6,20 63
+124.4,34 64
+11,17 64
+19,28 64
+30,33 64
+4,34 64
+4,34 64
+126.16,39 65
+30,33 65
+35,38 65
+16,39 65
+16,39 65
+4,5 65
+7,11 65
+7,11 66
+127.6,10 67
+128.9,16 68
+9,16 68
+130.19,40 69
+28,35 69
+25,35 69
+25,35 70
+37,39 69
+19,40 69
+19,40 69
+6,9 69
+6,9 71
+131.8,26 72
+132.6,23 73
+19,22 73
+6,23 73
+6,23 73
+133.10,18 74
+134.7,17 75
+135.6,19 76
+6,19 77
+6,19 78
+136.6,11 79
+138.5,23 80
+13,14 80
+19,22 80
+5,23 80
+5,23 80
+139.8,19 81
+140.6,50 82
+11,49 82
+15,49 82
+27,30 82
+27,35 82
+27,35 83
+37,42 82
+44,48 82
+11,49 82
+11,49 84
+6,50 82
+6,50 85
+6,50 68
+143.11,18 86
+8,18 86
+8,28 86
+8,28 87
+144.9,27 88
+145.7,24 89
+146.7,22 90
+148.9,26 91
+30,51 91
+149.7,31 92
+21,30 92
+7,31 92
+7,31 92
+150.10,20 93
+151.8,51 94
+13,50 94
+17,50 94
+29,32 94
+29,37 94
+29,37 95
+39,44 94
+46,49 94
+13,50 94
+13,50 96
+8,51 94
+152.8,51 97
+13,50 97
+17,50 97
+29,32 97
+29,37 97
+29,37 98
+39,44 97
+46,49 97
+13,50 97
+13,50 99
+8,51 97
+154.7,68 100
+12,67 100
+16,67 100
+29,35 100
+37,42 100
+44,55 100
+57,59 100
+61,62 100
+63,64 100
+65,66 100
+12,67 100
+12,67 101
+7,68 100
+7,68 102
+156.6,33 103
+11,32 103
+15,32 103
+27,28 103
+30,31 103
+11,32 103
+11,32 104
+6,33 103
+157.6,11 105
+159.8,26 106
+160.21,28 107
+18,28 107
+6,28 107
+6,28 108
+161.6,11 109
+163.13,20 110
+10,20 110
+10,20 110
+165.11,18 111
+167.10,30 112
+168.8,66 113
+13,65 113
+17,65 113
+30,36 113
+38,43 113
+45,53 113
+55,57 113
+59,60 113
+61,62 113
+63,64 113
+13,65 113
+13,65 114
+8,66 113
+8,66 115
+170.8,32 116
+171.8,35 117
+18,25 117
+27,34 117
+8,35 117
+8,35 111
+174.7,68 118
+12,67 118
+16,67 118
+29,35 118
+37,42 118
+44,55 118
+57,59 118
+61,62 118
+63,64 118
+65,66 118
+12,67 118
+12,67 119
+7,68 118
+7,68 111
+176.7,31 120
+21,30 120
+7,31 120
+7,31 120
+177.10,20 121
+178.8,51 122
+13,50 122
+17,50 122
+29,32 122
+29,37 122
+29,37 123
+39,44 122
+46,49 122
+13,50 122
+13,50 124
+8,51 122
+8,51 125
+8,51 111
+8,51 110
+181.6,31 126
+23,30 126
+20,30 126
+20,30 127
+6,31 126
+6,31 126
+182.9,19 128
+183.7,50 129
+12,49 129
+16,49 129
+28,31 129
+28,36 129
+28,36 130
+38,43 129
+45,48 129
+12,49 129
+12,49 131
+7,50 129
+7,50 132
+7,50 110
+186.17,24 133
+14,24 133
+5,24 133
+5,24 134
+187.20,27 135
+17,27 135
+14,27 135
+5,27 135
+5,27 136
+188.5,39 137
+33,34 137
+36,37 137
+5,39 137
+5,39 137
+189.8,19 138
+190.10,28 139
+191.7,24 140
+7,24 141
+7,24 142
+192.7,12 143
+194.10,26 144
+195.11,25 145
+20,24 145
+11,25 145
+11,25 145
+11,38 145
+11,38 146
+196.11,31 147
+197.9,67 148
+14,66 148
+18,66 148
+31,37 148
+39,44 148
+46,54 148
+56,58 148
+60,61 148
+62,63 148
+64,65 148
+14,66 148
+14,66 149
+9,67 148
+9,67 150
+199.9,33 151
+200.9,36 152
+19,26 152
+28,35 152
+9,36 152
+9,36 153
+9,36 154
+202.8,13 155
+205.6,25 156
+20,24 156
+6,25 156
+6,25 156
+206.9,19 157
+207.7,50 158
+12,49 158
+16,49 158
+28,31 158
+28,36 158
+28,36 159
+38,43 158
+45,48 158
+12,49 158
+12,49 160
+7,50 158
+7,50 161
+209.7,66 162
+12,65 162
+16,65 162
+28,31 162
+28,36 162
+28,36 163
+38,43 162
+45,63 162
+12,65 162
+12,65 164
+7,66 162
+210.12,60 165
+16,60 165
+28,31 165
+28,36 165
+28,36 166
+38,43 165
+45,59 165
+52,58 165
+45,59 165
+45,59 165
+7,61 165
+7,61 165
+7,61 167
+7,61 165
+7,61 168
+7,61 169
+7,61 68
+7,61 170
+7,61 171
+7,61 50
+216.3,20 172
+217.6,20 173
+218.4,23 174
+219.4,62 175
+9,61 175
+13,61 175
+26,32 175
+34,39 175
+41,49 175
+51,53 175
+55,56 175
+57,58 175
+59,60 175
+9,61 175
+9,61 176
+4,62 175
+4,62 177
+4,62 50
+223.1,10 178
+6,9 178
+1,10 178
+224.0,1 179
+232.1,20 180
+16,19 180
+1,20 180
+1,20 180
+233.5,15 181
+234.2,20 182
+16,19 182
+2,20 182
+2,20 182
+235.5,15 183
+236.10,13 184
+3,13 184
+3,13 185
+240.6,12 186
+6,12 186
+6,12 186
+6,12 186
+6,12 186
+242.5,15 187
+19,29 187
+243.10,49 188
+24,48 188
+36,47 188
+29,48 188
+24,48 188
+3,49 188
+244.5,15 189
+19,29 189
+245.10,48 190
+23,47 190
+35,46 190
+28,47 190
+23,47 190
+3,48 190
+247.5,15 191
+19,29 191
+33,43 191
+47,57 191
+248.10,32 192
+23,31 192
+23,31 192
+3,32 192
+252.4,14 193
+18,28 193
+253.9,31 194
+22,30 194
+22,30 194
+2,31 194
+256.4,16 195
+20,31 195
+257.7,13 196
+7,13 196
+7,13 196
+7,13 196
+7,13 196
+259.10,13 197
+3,13 197
+261.10,32 198
+23,31 198
+23,31 198
+3,32 198
+265.6,9 199
+266.1,6 199
+267.17,55 200
+31,41 200
+31,41 200
+43,53 200
+43,53 200
+10,55 200
+268.1,11 199
+274.5,17 201
+5,22 201
+26,43 201
+47,66 201
+275.0,34 202
+7,13 202
+15,33 202
+0,34 202
+0,34 202
+276.10,46 203
+24,32 203
+24,32 203
+34,44 203
+34,44 203
+3,46 203
+278.9,12 204
+2,12 204
+279.14,17 205
+7,17 205
+281.8,30 206
+21,29 206
+21,29 206
+1,30 206
+286.4,10 207
+287.0,1 208
+291.1,15 209
+13,14 209
+1,15 209
+1,15 209
+292.6,7 210
+294.33,42 211
+26,42 211
+295.31,37 212
+24,37 212
+296.36,44 213
+29,44 213
+298.16,23 214
+9,23 214
+299.22,29 215
+15,29 215
+300.37,46 216
+30,46 216
+302.16,24 217
+9,24 217
+303.30,36 218
+23,36 218
+305.16,26 219
+9,26 219
+307.8,9 220
+1,9 220
+313.1,8 221
+314.1,14 222
+315.4,15 223
+19,27 223
+19,32 223
+316.9,12 224
+2,12 224
+317.4,11 225
+4,18 225
+318.2,14 226
+319.2,17 227
+2,17 227
+321.1,22 228
+17,21 228
+1,22 228
+1,22 228
+322.6,10 229
+323.15,25 230
+15,25 229
+324.14,24 231
+14,24 229
+325.14,24 232
+14,24 229
+326.13,23 233
+13,23 229
+327.13,23 234
+13,23 229
+328.15,25 235
+15,25 229
+329.14,24 236
+14,24 229
+330.12,22 237
+12,22 229
+331.16,26 238
+16,26 229
+333.4,6 239
+334.5,13 240
+335.10,52 241
+24,32 241
+24,32 241
+34,42 241
+34,42 241
+44,51 241
+44,51 241
+3,52 241
+337.10,42 242
+24,32 242
+24,32 242
+34,41 242
+34,41 242
+3,42 242
+339.9,12 243
+2,12 243
+345.6,9 244
+347.8,18 245
+2,18 245
+349.9,15 246
+2,15 246
+351.9,15 247
+2,15 247
+353.9,18 248
+2,18 248
+355.9,17 249
+2,17 249
+357.9,16 250
+2,16 250
+359.9,18 251
+2,18 251
+361.9,17 252
+2,17 252
+363.9,16 253
+2,16 253
+365.9,12 254
+2,12 254
+10:51.1,28 255
+18,24 255
+26,27 255
+1,28 255
+1,28 255
+52.5,11 256
+13,18 257
+53.7,37 258
+19,26 258
+32,36 258
+28,36 258
+7,37 258
+7,37 258
+2,37 258
+2,37 259
+52.20,23 260
+20,23 260
+54.8,9 261
+1,9 261
+59.1,28 262
+60.5,11 263
+13,20 264
+61.5,14 265
+12,13 265
+5,14 265
+5,14 265
+5,14 265
+62.3,12 266
+20,31 266
+3,31 266
+3,31 267
+64.3,12 268
+3,21 268
+60.22,25 269
+22,25 269
+65.1,25 270
+66.1,20 271
+67.1,18 272
+68.1,20 273
+69.1,20 274
+70.1,10 275
+71.1,11 276
+72.1,10 277
+73.1,14 278
+74.1,15 279
+75.1,16 280
+76.1,27 281
+77.1,29 282
+78.1,10 283
+1,2 283
+1,10 283
+79.0,1 284
+83.1,29 285
+18,25 285
+27,28 285
+1,29 285
+1,29 286
+84.0,1 287
+88.4,20 288
+89.2,61 289
+7,60 289
+11,60 289
+24,30 289
+32,38 289
+40,48 289
+50,52 289
+54,55 289
+56,57 289
+58,59 289
+7,60 289
+7,60 290
+2,61 289
+93.11,15 291
+11,15 291
+192.10,14 291
+10,14 291
+92.2,8 291
+2,8 291
+2,8 291
+2,8 291
+94.8,15 292
+8,15 292
+8,15 293
+96.4,9 294
+98.7,17 295
+7,21 295
+99.37,44 296
+37,38 296
+37,44 296
+37,44 296
+5,45 296
+12,18 296
+20,35 296
+20,35 296
+20,35 297
+5,45 296
+5,45 296
+100.4,19 298
+4,5 298
+12,18 298
+4,19 298
+4,19 298
+101.7,23 299
+27,40 299
+27,40 299
+102.8,23 300
+103.6,64 301
+11,63 301
+15,63 301
+28,35 301
+37,42 301
+44,51 301
+53,55 301
+57,58 301
+59,60 301
+61,62 301
+11,63 301
+11,63 302
+6,64 301
+104.6,51 303
+11,50 303
+15,50 303
+27,34 303
+36,41 303
+43,49 303
+11,50 303
+11,50 304
+6,51 303
+6,51 292
+108.9,14 305
+9,14 305
+9,14 305
+110.5,14 306
+5,6 306
+5,14 306
+5,14 305
+112.8,18 307
+113.6,11 308
+114.5,20 309
+115.5,25 310
+116.5,67 311
+10,66 311
+14,66 311
+27,34 311
+36,42 311
+44,55 311
+57,59 311
+60,61 311
+62,63 311
+64,65 311
+10,66 311
+10,66 312
+5,67 311
+118.10,19 313
+120.6,38 314
+6,7 314
+12,30 314
+12,37 314
+12,37 315
+6,38 314
+121.6,25 316
+122.9,26 317
+19,20 317
+22,25 317
+9,26 317
+9,26 317
+9,30 317
+123.7,30 318
+7,8 318
+13,29 318
+7,30 318
+124.7,22 319
+125.7,69 320
+12,68 320
+16,68 320
+29,36 320
+38,44 320
+46,57 320
+59,61 320
+62,63 320
+64,65 320
+66,67 320
+12,68 320
+12,68 321
+7,69 320
+7,69 322
+126.7,12 323
+128.6,25 324
+129.6,18 325
+130.6,16 326
+14,15 326
+6,16 326
+131.6,32 327
+6,32 328
+6,32 313
+133.6,39 329
+6,7 329
+12,38 329
+6,39 329
+134.9,19 330
+9,23 330
+27,37 330
+27,41 330
+135.7,42 331
+18,30 331
+32,41 331
+7,42 331
+7,42 331
+136.18,42 332
+28,37 332
+39,41 332
+18,42 332
+18,42 332
+137.10,18 333
+138.7,37 334
+7,8 334
+13,36 334
+7,37 334
+139.7,22 335
+140.7,69 336
+12,68 336
+16,68 336
+29,36 336
+38,44 336
+46,57 336
+59,61 336
+62,63 336
+64,65 336
+66,67 336
+12,68 336
+12,68 337
+7,69 336
+141.10,20 338
+10,24 338
+142.8,52 339
+19,40 339
+42,51 339
+8,52 339
+8,52 339
+8,52 340
+8,52 341
+8,52 342
+8,52 343
+8,52 344
+8,52 345
+143.7,12 346
+145.6,52 347
+23,39 347
+41,51 347
+6,52 347
+6,52 347
+146.6,20 348
+147.9,22 349
+9,27 349
+31,40 349
+31,45 349
+31,54 349
+31,54 350
+148.7,22 351
+149.9,20 352
+150.7,17 353
+7,8 353
+13,16 353
+7,17 353
+151.7,28 354
+152.7,23 355
+153.7,69 356
+12,68 356
+16,68 356
+29,36 356
+38,44 356
+46,57 356
+59,61 356
+62,63 356
+64,65 356
+66,67 356
+12,68 356
+12,68 357
+7,69 356
+155.6,32 358
+6,32 359
+6,32 360
+6,32 361
+6,32 362
+6,32 363
+6,32 364
+6,32 313
+157.8,19 365
+158.6,25 366
+159.6,26 367
+12,13 367
+21,25 367
+6,26 367
+160.6,20 368
+6,20 369
+6,20 305
+163.8,18 370
+164.6,30 371
+6,7 371
+12,29 371
+6,30 371
+165.6,31 372
+167.8,27 373
+168.6,15 374
+13,14 374
+6,15 374
+6,15 375
+170.6,18 376
+16,17 376
+6,18 376
+6,18 305
+172.10,13 377
+174.6,15 378
+13,14 378
+6,15 378
+6,15 377
+6,15 305
+177.8,20 379
+8,20 379
+178.6,20 380
+179.6,11 381
+181.5,47 382
+5,6 382
+13,46 382
+25,33 382
+25,33 382
+35,45 382
+35,45 382
+5,47 382
+5,47 382
+182.0,39 383
+11,38 383
+0,39 383
+0,39 383
+0,39 305
+184.5,18 384
+185.5,14 385
+186.5,18 386
+5,18 305
+188.5,19 387
+5,19 305
+189.9,14 388
+9,14 389
+9,14 291
+193.6,16 390
+6,20 390
+194.36,49 391
+41,42 391
+43,48 391
+36,49 391
+36,49 391
+4,50 391
+11,17 391
+19,34 391
+19,34 391
+19,34 392
+4,50 391
+4,50 391
+196.6,14 393
+197.4,13 394
+198.9,16 395
+200.5,25 396
+5,6 396
+11,24 396
+5,25 396
+5,25 395
+202.5,15 397
+5,6 397
+11,14 397
+5,15 397
+5,15 395
+204.4,21 398
+205.4,19 399
+206.4,64 400
+9,63 400
+13,63 400
+26,33 400
+35,41 400
+43,52 400
+54,56 400
+57,58 400
+59,60 400
+61,62 400
+9,63 400
+9,63 401
+4,64 400
+207.4,66 402
+9,65 402
+13,65 402
+26,33 402
+35,41 402
+43,54 402
+56,58 402
+59,60 402
+61,62 402
+63,64 402
+9,65 402
+9,65 403
+4,66 402
+4,66 404
+208.4,9 405
+210.3,16 406
+3,4 406
+14,15 406
+3,16 406
+3,16 407
+3,16 291
+213.4,14 408
+214.2,13 409
+7,12 409
+2,13 409
+215.1,10 410
+6,9 410
+1,10 410
+216.0,1 411
+220.0,1 412
+224.4,14 413
+4,16 413
+225.42,62 414
+47,51 414
+53,61 414
+42,62 414
+42,62 414
+2,63 414
+13,31 414
+33,40 414
+33,40 414
+33,40 415
+2,63 414
+2,63 414
+226.6,13 416
+6,13 416
+6,13 416
+6,13 416
+6,13 416
+256.0,1 417
+229.6,10 418
+14,22 419
+12,22 419
+230.13,20 420
+3,20 420
+231.6,16 421
+20,30 421
+232.12,23 422
+4,29 422
+4,29 423
+233.4,12 424
+235.18,36 425
+28,35 425
+18,36 425
+18,36 425
+236.8,12 426
+8,12 426
+8,12 426
+237.3,14 426
+239.4,14 427
+4,5 427
+10,13 427
+4,14 427
+240.4,25 428
+241.4,20 429
+242.4,66 430
+9,65 430
+13,65 430
+26,33 430
+35,41 430
+43,54 430
+56,58 430
+59,60 430
+61,62 430
+63,64 430
+9,65 430
+9,65 431
+4,66 430
+4,66 426
+244.4,13 432
+11,12 432
+4,13 432
+245.4,14 433
+4,5 433
+10,13 433
+4,14 433
+246.4,21 434
+247.4,19 435
+248.4,66 436
+9,65 436
+13,65 436
+26,33 436
+35,41 436
+43,54 436
+56,58 436
+59,60 436
+61,62 436
+63,64 436
+9,65 436
+9,65 437
+4,66 436
+4,66 426
+250.3,15 438
+3,15 439
+3,15 440
+229.24,27 441
+24,27 441
+253.2,47 442
+7,46 442
+11,46 442
+23,26 442
+23,31 442
+23,31 443
+33,39 442
+41,45 442
+7,46 442
+7,46 444
+2,47 442
+256.0,1 417
+0,1 417
+0,1 417
+260.4,15 445
+261.9,11 446
+2,11 446
+262.4,12 447
+4,17 447
+263.9,10 448
+2,10 448
+264.4,15 449
+266.14,22 450
+2,31 450
+267.6,12 451
+16,24 452
+14,24 452
+268.3,8 453
+22,29 453
+18,29 453
+18,37 453
+11,38 453
+3,38 453
+267.26,29 454
+26,29 454
+269.2,11 455
+2,11 456
+271.4,14 457
+4,16 457
+272.27,47 458
+32,36 458
+38,46 458
+27,47 458
+27,47 458
+2,48 458
+13,25 458
+13,25 458
+13,25 459
+2,48 458
+2,48 458
+273.8,40 460
+19,23 460
+25,29 460
+31,39 460
+8,40 460
+8,40 460
+1,40 460
+292.1,27 461
+293.5,11 462
+13,20 463
+294.2,8 464
+295.2,10 465
+296.6,12 466
+14,19 467
+297.3,12 468
+298.6,13 469
+6,21 469
+6,21 469
+299.4,18 470
+300.3,10 471
+296.21,24 472
+21,24 472
+302.2,11 473
+14,22 473
+2,30 473
+293.22,25 474
+22,25 474
+304.0,1 475
+310.7,12 476
+311.5,9 477
+5,21 477
+312.3,8 478
+310.14,17 479
+14,17 479
+313.8,9 480
+1,9 480
+320.4,14 481
+4,16 481
+321.29,44 482
+34,35 482
+37,43 482
+29,44 482
+29,44 482
+2,45 482
+13,27 482
+13,27 482
+13,27 483
+2,45 482
+2,45 482
+322.1,12 484
+323.15,26 485
+1,26 485
+324.1,9 486
+325.1,8 487
+326.1,9 488
+327.5,9 489
+11,21 490
+328.11,15 491
+2,15 491
+329.2,17 492
+330.12,22 493
+8,22 493
+5,23 493
+5,31 493
+5,31 493
+331.3,11 494
+332.15,22 495
+8,23 495
+2,23 495
+334.6,9 496
+335.6,15 497
+19,22 497
+19,33 497
+336.4,11 498
+337.4,12 499
+339.6,15 500
+340.4,12 501
+342.2,9 502
+343.4,8 503
+4,8 503
+2,9 503
+2,19 503
+327.23,26 504
+23,26 504
+345.4,10 505
+346.5,15 506
+5,19 506
+347.3,29 507
+14,28 507
+3,29 507
+3,29 507
+348.9,12 508
+2,12 508
+350.7,15 509
+1,21 509
+351.8,19 510
+4,19 510
+4,29 510
+352.5,15 511
+5,19 511
+353.3,67 512
+14,41 512
+43,49 512
+55,66 512
+51,66 512
+3,67 512
+3,67 512
+354.9,12 513
+2,12 513
+356.1,23 514
+357.9,10 515
+9,16 515
+1,16 515
+1,16 516
+358.4,14 517
+4,18 517
+359.37,47 518
+42,43 518
+44,46 518
+37,47 518
+37,47 518
+2,61 518
+13,35 518
+13,35 518
+13,35 519
+49,52 518
+54,60 518
+2,61 518
+2,61 518
+360.8,9 520
+1,9 520
+365.10,27 521
+20,21 521
+23,26 521
+10,27 521
+10,27 521
+1,27 521
+366.4,17 522
+367.2,10 523
+2,10 523
+368.1,34 524
+369.1,11 525
+370.7,18 526
+371.8,49 527
+19,23 527
+25,34 527
+25,26 527
+25,34 527
+36,41 527
+36,47 527
+8,49 527
+8,49 527
+8,49 527
+8,53 527
+372.3,13 528
+373.3,12 529
+374.6,20 530
+6,25 530
+375.4,25 531
+376.8,14 532
+16,19 533
+377.5,9 534
+22,26 534
+18,26 534
+17,35 534
+5,35 534
+376.21,24 535
+21,24 535
+378.4,14 536
+4,14 537
+4,14 538
+381.4,10 539
+382.7,16 540
+383.5,43 541
+16,35 541
+37,42 541
+5,43 541
+5,43 541
+384.5,30 542
+385.5,15 543
+386.11,19 544
+387.9,13 545
+9,20 545
+26,29 545
+24,30 545
+24,37 545
+48,51 545
+46,52 545
+42,52 545
+41,59 545
+63,68 545
+41,68 545
+388.7,13 546
+389.7,20 547
+390.7,51 548
+18,38 548
+40,45 548
+47,50 548
+7,51 548
+7,51 548
+391.7,12 549
+386.21,24 550
+21,24 550
+394.4,19 551
+395.10,34 552
+25,26 552
+28,29 552
+31,32 552
+10,34 552
+10,34 552
+10,34 552
+10,41 552
+396.5,23 553
+17,22 553
+17,18 553
+17,22 553
+5,23 553
+5,23 553
+397.8,18 554
+22,30 554
+398.6,20 555
+399.6,26 556
+400.6,10 557
+6,22 557
+401.6,10 558
+18,33 558
+6,33 558
+402.6,37 559
+17,29 559
+31,36 559
+6,37 559
+6,37 559
+403.6,16 560
+6,7 560
+14,15 560
+6,16 560
+6,16 560
+404.6,19 561
+405.6,11 562
+6,11 563
+406.6,11 564
+408.13,22 565
+5,29 565
+409.5,15 566
+5,15 567
+395.43,54 568
+43,54 568
+411.7,12 569
+412.13,14 570
+13,19 570
+5,19 570
+5,19 571
+413.5,16 572
+5,16 572
+417.5,11 573
+418.3,8 574
+421.1,13 575
+422.0,1 576
+429.1,27 577
+431.1,7 578
+432.1,26 579
+433.1,13 580
+434.4,17 581
+435.2,47 582
+21,34 582
+36,46 582
+2,47 582
+2,47 582
+436.4,17 583
+437.2,8 584
+438.1,8 585
+439.1,13 586
+440.1,17 587
+441.1,9 588
+442.1,11 589
+445.2,38 590
+17,23 590
+25,28 590
+30,37 590
+2,38 590
+2,38 590
+446.5,11 591
+447.3,8 592
+448.6,10 593
+12,15 594
+449.13,19 595
+3,19 595
+450.6,8 596
+451.9,11 597
+452.11,22 598
+11,22 597
+453.11,22 599
+454.9,14 600
+455.7,23 601
+18,22 601
+7,23 601
+7,23 601
+7,23 597
+456.12,21 602
+12,21 597
+457.12,17 603
+459.6,16 604
+460.4,10 605
+4,10 606
+462.4,10 607
+463.6,13 608
+464.4,12 609
+465.7,12 610
+466.4,12 611
+467.6,22 612
+28,37 612
+41,50 612
+56,65 612
+69,78 612
+468.7,13 613
+4,19 613
+4,19 614
+469.11,20 615
+470.4,19 616
+471.16,29 617
+22,24 617
+26,28 617
+16,29 617
+16,29 617
+5,6 617
+5,6 618
+472.7,10 619
+7,10 619
+4,11 619
+4,20 619
+473.7,16 620
+474.5,48 621
+10,47 621
+14,47 621
+26,29 621
+26,34 621
+26,34 622
+36,42 621
+44,46 621
+10,47 621
+10,47 623
+5,48 621
+475.5,10 624
+476.5,29 625
+477.5,19 626
+16,18 626
+5,19 626
+5,19 626
+479.4,11 627
+4,11 628
+480.12,21 629
+481.4,19 630
+448.17,20 631
+17,20 631
+484.1,13 632
+486.0,1 633
+490.17,27 634
+9,27 634
+1,36 634
+1,36 635
+491.1,35 636
+17,21 636
+23,34 636
+1,35 636
+1,35 636
+492.5,14 637
+493.2,29 638
+494.2,30 639
+13,15 639
+17,20 639
+22,29 639
+2,30 639
+2,30 639
+2,30 640
+496.0,1 641
+526.1,21 642
+527.8,34 643
+19,23 643
+25,26 643
+28,33 643
+8,34 643
+8,34 643
+1,34 643
+535.1,10 644
+536.5,11 645
+17,22 646
+13,22 646
+537.7,11 647
+538.6,13 648
+2,18 648
+539.5,14 649
+24,29 649
+23,33 649
+18,33 649
+540.6,15 650
+541.8,15 651
+4,23 651
+542.6,19 652
+12,13 652
+15,18 652
+6,19 652
+6,19 652
+6,23 652
+543.11,18 653
+4,18 653
+544.3,11 654
+536.24,27 655
+24,27 655
+547.8,10 656
+1,10 656
+552.1,34 657
+18,21 657
+23,33 657
+1,34 657
+1,34 657
+553.1,41 658
+19,28 658
+30,40 658
+1,41 658
+1,41 658
+554.4,15 659
+19,31 659
+555.9,11 660
+2,11 660
+561.8,9 661
+1,9 661
+566.1,17 662
+12,16 662
+1,17 662
+1,17 662
+567.1,16 663
+7,8 663
+10,15 663
+1,16 663
+1,16 663
+568.1,17 664
+12,16 664
+1,17 664
+1,17 664
+569.1,17 665
+7,8 665
+10,16 665
+1,17 665
+1,17 665
+570.1,11 666
+572.1,40 667
+12,17 667
+19,36 667
+38,39 667
+1,40 667
+1,40 667
+573.1,12 668
+575.1,37 669
+11,23 669
+25,36 669
+1,37 669
+1,37 669
+1,37 670
+576.0,1 671
+580.1,11 672
+581.1,45 673
+12,17 673
+19,41 673
+43,44 673
+1,45 673
+1,45 673
+582.1,12 674
+583.0,1 675
+591.5,11 676
+17,25 677
+13,25 677
+592.18,25 678
+14,30 678
+5,10 678
+5,30 678
+59,66 678
+59,71 678
+42,49 678
+38,54 678
+34,35 678
+34,55 678
+34,71 678
+34,71 679
+34,71 680
+593.11,18 681
+11,23 681
+25,32 681
+25,38 681
+3,39 681
+591.27,30 682
+27,30 682
+595.9,14 683
+16,17 683
+1,18 683
+613.4,20 684
+614.2,26 685
+8,9 685
+11,25 685
+2,26 685
+2,26 685
+615.4,20 686
+616.2,27 687
+8,9 687
+11,26 687
+2,27 687
+2,27 687
+617.2,27 688
+618.2,17 689
+620.0,1 690
+11:17.1,25 691
+18.1,10 692
+1,2 692
+1,10 692
+19.0,1 693
+23.1,29 694
+18,25 694
+27,28 694
+1,29 694
+1,29 695
+24.0,1 696
+30.2,15 697
+31.7,14 698
+7,14 698
+7,14 699
+33.3,8 700
+35.8,13 701
+37.4,13 702
+4,5 702
+4,13 702
+4,13 701
+38.8,13 703
+40.2,7 698
+2,7 704
+2,7 704
+43.1,10 705
+6,9 705
+1,10 705
+44.0,1 706
+48.4,10 707
+49.0,1 708
+12:88.1,37 709
+89.4,15 710
+90.2,57 711
+8,56 711
+2,57 711
+92.1,23 712
+18,19 712
+21,22 712
+1,23 712
+1,23 713
+93.1,14 714
+94.1,16 715
+95.1,16 716
+96.1,16 717
+97.1,25 718
+98.1,19 719
+12,18 719
+1,19 719
+1,19 719
+1,19 720
+99.1,10 721
+1,2 721
+1,10 721
+100.15,16 722
+18,19 722
+1,20 722
+101.1,13 723
+102.1,13 724
+103.1,17 725
+104.1,19 726
+105.0,1 727
+109.1,18 728
+1,2 728
+11,17 728
+1,18 728
+110.1,14 729
+12,13 729
+1,14 729
+111.1,17 730
+112.0,1 731
+118.10,14 732
+10,14 732
+117.9,15 732
+9,15 732
+9,15 732
+9,15 732
+119.7,14 733
+7,14 733
+7,14 734
+121.3,8 735
+123.8,13 736
+8,13 736
+8,13 736
+8,13 736
+8,13 736
+125.4,13 737
+4,5 737
+4,13 737
+4,13 736
+127.9,13 738
+129.10,14 739
+131.6,22 740
+6,22 739
+6,22 738
+134.10,14 741
+136.6,23 742
+6,23 741
+6,23 738
+139.10,14 743
+141.9,24 744
+142.7,23 745
+7,8 745
+17,22 745
+7,23 745
+143.6,20 746
+6,20 743
+145.9,27 747
+146.7,26 748
+7,8 748
+17,25 748
+7,26 748
+147.6,23 749
+6,23 743
+6,23 738
+6,23 736
+151.4,16 750
+4,16 736
+153.4,17 751
+15,16 751
+4,17 751
+4,17 736
+155.4,20 752
+156.4,20 753
+4,20 736
+158.4,20 754
+4,20 736
+159.8,13 755
+162.6,18 756
+6,18 757
+6,18 758
+163.4,12 759
+164.3,18 760
+165.3,20 761
+166.3,26 762
+16,17 762
+19,25 762
+3,26 762
+3,26 762
+167.9,15 763
+9,19 763
+168.4,21 764
+4,5 764
+15,20 764
+15,20 764
+4,21 764
+169.4,15 765
+4,15 765
+4,15 765
+172.6,25 766
+29,48 766
+52,67 766
+68,84 766
+52,84 766
+52,84 766
+173.4,16 767
+174.6,14 768
+175.7,22 769
+7,22 769
+176.5,24 770
+18,23 770
+5,24 770
+5,24 771
+178.5,31 772
+24,26 772
+27,29 772
+5,31 772
+179.4,16 773
+180.4,13 774
+4,13 774
+4,13 775
+181.13,28 776
+182.4,13 777
+4,13 777
+4,13 778
+4,13 733
+4,13 779
+4,13 732
+185.1,10 780
+6,9 780
+1,10 780
+186.0,1 781
+194.1,24 782
+195.6,13 783
+197.2,10 784
+2,10 783
+199.2,10 785
+200.2,15 786
+2,15 783
+202.2,10 787
+2,10 783
+204.4,16 788
+205.2,10 789
+206.2,15 790
+2,15 791
+208.2,10 792
+209.1,48 793
+11,13 793
+21,24 793
+26,27 793
+30,38 793
+40,44 793
+46,47 793
+1,48 793
+210.0,1 794
+217.1,12 795
+218.1,11 796
+219.10,28 797
+1,28 797
+220.1,14 798
+221.27,29 799
+31,33 799
+9,34 799
+1,34 799
+222.1,13 800
+223.6,11 801
+6,11 801
+6,11 801
+6,11 801
+225.2,19 802
+226.2,13 803
+227.2,19 804
+228.2,12 805
+229.2,14 806
+230.16,17 807
+18,19 807
+2,20 807
+231.2,19 808
+2,19 801
+234.2,20 809
+235.2,13 810
+236.2,19 811
+237.2,12 812
+238.2,14 813
+239.2,18 814
+240.16,17 815
+19,20 815
+2,21 815
+2,21 801
+242.2,17 816
+243.2,13 817
+244.2,19 818
+245.2,12 819
+246.2,14 820
+2,14 801
+248.4,23 821
+249.19,61 822
+32,33 822
+34,35 822
+38,39 822
+40,41 822
+45,46 822
+48,49 822
+51,52 822
+54,55 822
+57,60 822
+19,61 822
+19,61 822
+8,15 822
+8,15 823
+8,15 824
+250.2,18 825
+2,3 825
+11,17 825
+2,18 825
+251.2,61 826
+21,44 826
+46,52 826
+54,60 826
+2,61 826
+2,61 826
+252.19,80 827
+30,35 827
+37,43 827
+45,51 827
+53,61 827
+63,69 827
+71,79 827
+19,80 827
+19,80 827
+8,15 827
+8,15 828
+8,15 829
+253.2,20 830
+2,3 830
+14,19 830
+2,20 830
+2,20 831
+255.1,16 832
+14,15 832
+1,16 832
+256.1,27 833
+20,22 833
+23,25 833
+1,27 833
+257.1,19 834
+258.0,1 835
+262.1,13 836
+1,13 836
+263.0,1 837
+267.7,15 838
+7,19 838
+268.7,13 839
+7,13 839
+7,13 839
+7,13 839
+7,13 839
+270.3,25 840
+17,18 840
+20,24 840
+3,25 840
+3,25 840
+3,25 839
+272.3,25 841
+17,18 841
+20,24 841
+3,25 841
+3,25 841
+3,25 839
+274.3,25 842
+3,25 839
+3,25 839
+276.0,1 843
+281.6,8 844
+6,8 844
+6,8 844
+286.2,16 845
+381.0,1 846
+288.2,16 847
+381.0,1 846
+290.2,16 848
+381.0,1 846
+292.2,22 849
+293.2,32 850
+294.2,18 851
+381.0,1 846
+296.2,19 852
+297.2,18 853
+298.2,32 854
+381.0,1 846
+300.2,17 855
+381.0,1 846
+302.5,17 856
+303.6,18 857
+381.0,1 846
+305.6,18 858
+306.14,20 859
+4,24 859
+4,24 860
+308.4,16 861
+309.3,19 862
+381.0,1 846
+311.3,15 863
+381.0,1 846
+313.16,22 864
+5,22 864
+314.6,18 865
+381.0,1 846
+316.17,23 866
+17,27 866
+6,13 866
+6,27 866
+317.4,15 867
+4,15 868
+319.4,16 869
+320.3,14 870
+381.0,1 846
+322.3,15 871
+381.0,1 846
+324.16,22 872
+16,26 872
+5,12 872
+5,26 872
+325.6,19 873
+6,19 873
+326.4,16 874
+11,12 874
+14,15 874
+4,16 874
+381.0,1 846
+328.4,15 875
+381.0,1 846
+329.10,22 876
+330.3,20 877
+331.3,22 878
+381.0,1 846
+333.3,15 879
+381.0,1 846
+335.5,17 880
+336.6,19 881
+6,19 881
+337.4,17 882
+11,12 882
+14,16 882
+4,17 882
+381.0,1 846
+339.14,20 883
+4,24 883
+381.0,1 846
+340.10,22 884
+381.0,1 846
+343.3,15 885
+381.0,1 846
+345.2,13 886
+381.0,1 846
+347.10,16 887
+10,26 887
+2,30 887
+348.12,26 888
+16,19 888
+21,25 888
+12,26 888
+12,26 888
+2,70 888
+2,70 888
+2,70 889
+34,41 888
+42,49 888
+52,58 888
+60,66 888
+68,69 888
+2,70 888
+381.0,1 846
+351.2,16 890
+381.0,1 846
+353.2,19 891
+354.2,16 892
+355.16,17 893
+18,19 893
+2,20 893
+356.2,19 894
+357.2,14 895
+358.2,10 896
+8,9 896
+2,10 896
+381.0,1 846
+360.2,19 897
+361.2,16 898
+362.16,17 899
+18,19 899
+2,20 899
+363.2,19 900
+364.2,14 901
+381.0,1 846
+366.2,18 902
+367.2,14 903
+381.0,1 846
+369.2,19 904
+370.2,14 905
+381.0,1 846
+373.2,19 906
+381.0,1 846
+0,1 846
+0,1 846
+0,1 846
+386.4,12 907
+9,11 907
+4,12 907
+4,12 907
+4,12 907
+387.2,18 908
+388.2,12 909
+6,7 909
+9,11 909
+2,12 909
+389.2,8 910
+391.4,15 911
+19,30 911
+392.5,16 912
+393.3,25 913
+3,25 914
+394.10,21 915
+395.3,21 916
+3,21 917
+397.3,21 918
+398.9,17 919
+2,17 919
+399.2,8 920
+402.7,15 921
+1,15 921
+403.6,8 922
+6,8 922
+6,8 922
+6,8 922
+407.2,17 923
+408.2,8 924
+411.9,17 925
+2,17 925
+412.5,16 926
+413.3,18 927
+414.2,8 928
+417.10,22 929
+10,22 922
+418.10,20 930
+10,20 922
+419.10,22 931
+10,22 922
+420.10,23 932
+10,23 922
+421.10,21 933
+10,21 922
+422.10,24 934
+10,24 922
+423.10,21 935
+10,21 922
+424.10,22 936
+10,22 922
+427.10,22 937
+10,22 922
+428.10,20 938
+10,20 922
+429.10,22 939
+10,22 922
+430.10,23 940
+10,23 922
+431.10,21 941
+10,21 922
+432.10,24 942
+10,24 922
+433.10,21 943
+10,21 922
+434.10,22 944
+10,22 922
+437.10,25 945
+10,25 922
+438.10,26 946
+10,26 922
+441.10,25 947
+442.3,16 948
+3,16 922
+443.10,26 949
+444.3,16 950
+3,16 922
+447.10,25 951
+448.3,16 952
+3,16 922
+449.10,26 953
+450.3,16 954
+3,16 922
+453.10,25 955
+10,25 922
+454.10,26 956
+10,26 922
+458.2,26 957
+2,26 922
+462.5,16 958
+463.3,8 959
+464.2,26 960
+465.2,17 961
+2,17 922
+469.5,16 962
+470.3,8 963
+471.2,26 964
+472.2,17 965
+2,17 922
+476.5,16 966
+477.3,8 967
+478.2,25 968
+2,25 922
+480.4,11 969
+481.2,19 970
+482.2,14 971
+484.4,11 972
+485.2,19 973
+486.2,14 974
+487.2,15 975
+489.1,17 976
+490.0,1 977
+496.4,12 978
+9,11 978
+4,12 978
+4,12 978
+4,12 978
+497.2,18 979
+498.2,12 980
+6,7 980
+9,11 980
+2,12 980
+499.2,8 981
+501.6,8 982
+507.2,11 983
+508.2,19 984
+509.2,8 985
+510.10,18 986
+10,18 982
+511.10,18 987
+10,18 982
+512.10,18 988
+10,18 982
+513.10,18 989
+10,18 982
+514.10,20 990
+10,20 982
+515.10,20 991
+10,20 982
+516.10,20 992
+10,20 982
+517.10,20 993
+10,20 982
+518.10,18 994
+10,18 982
+519.10,18 995
+10,18 982
+520.10,18 996
+10,18 982
+521.10,18 997
+10,18 982
+522.10,18 998
+10,18 982
+523.10,18 999
+10,18 982
+524.10,18 1000
+10,18 982
+525.10,18 1001
+10,18 982
+526.10,18 1002
+10,18 982
+528.7,16 1003
+13,15 1003
+7,16 1003
+7,16 1003
+1,17 1003
+1,2 1003
+1,2 1003
+1,2 1004
+1,17 1003
+529.1,14 1005
+530.1,17 1006
+531.0,1 1007
+536.6,13 1008
+538.7,9 1009
+541.3,18 1010
+542.6,17 1011
+543.4,15 1012
+4,15 1009
+547.3,18 1013
+548.17,23 1014
+6,23 1014
+549.14,20 1015
+4,24 1015
+4,24 1009
+553.3,18 1016
+554.16,22 1017
+6,22 1017
+555.4,20 1018
+4,20 1009
+559.3,18 1019
+560.6,17 1020
+561.4,15 1021
+4,15 1009
+565.3,18 1022
+566.3,9 1023
+569.8,12 1024
+8,12 1024
+8,12 1024
+572.4,38 1025
+13,20 1025
+22,29 1025
+31,37 1025
+4,38 1025
+573.8,20 1026
+22,30 1027
+574.5,27 1028
+14,15 1028
+17,18 1028
+20,26 1028
+5,27 1028
+573.32,35 1029
+32,35 1029
+577.8,12 1030
+14,23 1031
+578.5,27 1032
+14,15 1032
+17,18 1032
+20,26 1032
+5,27 1032
+577.25,28 1033
+25,28 1033
+579.4,33 1034
+13,20 1034
+22,23 1034
+25,32 1034
+4,33 1034
+4,33 1024
+582.4,12 1035
+10,11 1035
+4,12 1035
+4,12 1024
+4,12 1009
+586.8,12 1036
+8,12 1036
+8,12 1036
+588.8,42 1037
+17,24 1037
+26,33 1037
+35,41 1037
+8,42 1037
+8,42 1036
+591.8,37 1038
+17,24 1038
+26,27 1038
+29,36 1038
+8,37 1038
+8,37 1036
+594.8,36 1039
+17,24 1039
+26,27 1039
+29,35 1039
+8,36 1039
+8,36 1036
+8,36 1009
+599.3,45 1040
+12,19 1040
+21,28 1040
+30,37 1040
+30,42 1040
+30,44 1040
+3,45 1040
+3,45 1009
+603.13,27 1041
+17,20 1041
+22,26 1041
+13,27 1041
+13,27 1041
+3,71 1041
+3,71 1041
+3,71 1042
+35,42 1041
+43,50 1041
+53,59 1041
+61,67 1041
+69,70 1041
+3,71 1041
+3,71 1009
+607.6,15 1043
+608.4,20 1044
+4,20 1009
+611.6,15 1045
+612.4,21 1046
+4,21 1009
+616.3,24 1047
+10,17 1047
+19,23 1047
+3,24 1047
+3,24 1009
+620.3,27 1048
+10,17 1048
+19,26 1048
+3,27 1048
+3,27 1009
+622.2,18 1049
+632.0,1 1050
+624.7,9 1051
+627.6,14 1052
+25,31 1052
+18,31 1052
+35,43 1052
+55,61 1052
+47,61 1052
+628.18,22 1053
+24,28 1053
+4,29 1053
+4,29 1051
+630.2,18 1054
+632.0,1 1050
+0,1 1050
+638.5,10 1055
+16,24 1056
+12,24 1056
+639.12,19 1057
+2,19 1057
+641.5,15 1058
+5,15 1058
+642.3,9 1059
+643.6,22 1060
+24,32 1061
+24,32 1062
+39,45 1063
+644.3,120 1064
+10,16 1064
+18,64 1064
+66,73 1064
+75,77 1064
+79,81 1064
+83,89 1064
+91,97 1064
+99,101 1064
+103,110 1064
+112,119 1064
+3,120 1064
+3,120 1064
+3,120 1065
+646.7,14 1066
+7,14 1066
+7,14 1066
+648.6,14 1067
+6,14 1067
+18,26 1067
+649.4,10 1068
+650.4,13 1069
+651.14,22 1070
+10,22 1070
+652.14,21 1071
+5,21 1071
+653.8,16 1072
+8,16 1072
+20,28 1072
+654.10,13 1073
+10,13 1073
+26,29 1073
+26,29 1073
+21,30 1073
+17,30 1073
+6,30 1073
+6,30 1074
+656.6,9 1075
+657.6,11 1076
+660.7,12 1077
+661.8,18 1078
+8,18 1078
+662.6,46 1079
+13,19 1079
+21,40 1079
+42,45 1079
+6,46 1079
+6,46 1079
+663.5,15 1080
+5,6 1080
+11,14 1080
+5,15 1080
+664.20,23 1081
+16,24 1081
+16,24 1082
+16,24 1083
+666.13,21 1084
+18,20 1084
+13,21 1084
+13,21 1084
+13,21 1084
+667.4,14 1085
+8,9 1085
+11,13 1085
+4,14 1085
+4,14 1086
+668.11,20 1087
+669.7,28 1088
+670.5,15 1089
+671.10,19 1090
+16,18 1090
+10,19 1090
+10,19 1090
+4,20 1090
+4,5 1090
+4,5 1090
+4,5 1091
+4,20 1090
+672.4,17 1092
+4,17 1066
+675.6,15 1093
+676.4,12 1094
+677.6,27 1095
+678.4,12 1096
+679.3,14 1097
+8,9 1097
+11,13 1097
+3,14 1097
+3,14 1066
+681.6,15 1098
+682.4,12 1099
+683.3,13 1100
+7,8 1100
+10,12 1100
+3,13 1100
+3,13 1066
+687.6,15 1101
+688.4,12 1102
+689.6,14 1103
+11,13 1103
+6,14 1103
+6,14 1103
+6,14 1103
+690.4,20 1104
+691.4,14 1105
+8,9 1105
+11,13 1105
+4,14 1105
+692.4,9 1106
+694.6,17 1107
+21,32 1107
+695.10,35 1108
+14,22 1108
+24,34 1108
+10,35 1108
+10,35 1108
+4,36 1108
+4,5 1108
+4,5 1108
+4,5 1109
+4,36 1108
+696.3,19 1110
+3,19 1066
+698.8,12 1111
+8,12 1111
+8,12 1111
+8,12 1111
+8,12 1111
+700.9,11 1112
+701.11,19 1113
+11,19 1112
+702.11,19 1114
+11,19 1112
+703.11,19 1115
+11,19 1112
+11,19 1111
+706.9,11 1116
+707.11,19 1117
+11,19 1116
+11,19 1111
+710.9,11 1118
+711.11,19 1119
+11,19 1118
+712.11,19 1120
+11,19 1118
+713.12,20 1121
+12,20 1118
+714.11,19 1122
+11,19 1118
+715.11,19 1123
+11,19 1118
+11,19 1111
+718.9,11 1124
+719.11,19 1125
+11,19 1124
+720.11,19 1126
+11,19 1124
+721.12,20 1127
+12,20 1124
+722.11,19 1128
+11,19 1124
+723.11,19 1129
+11,19 1124
+11,19 1111
+726.9,11 1130
+727.11,19 1131
+11,19 1130
+11,19 1111
+730.9,18 1132
+15,17 1132
+9,18 1132
+9,18 1132
+3,19 1132
+3,4 1132
+3,4 1132
+3,4 1133
+3,19 1132
+731.3,16 1134
+732.3,19 1135
+3,19 1066
+734.6,17 1136
+21,32 1136
+735.4,14 1137
+736.12,24 1138
+4,24 1138
+4,24 1139
+737.14,25 1140
+29,40 1140
+46,57 1140
+61,72 1140
+738.4,12 1141
+739.4,22 1142
+4,22 1143
+741.4,15 1144
+9,10 1144
+12,14 1144
+4,15 1144
+4,15 1066
+743.6,17 1145
+21,32 1145
+744.4,14 1146
+745.12,24 1147
+4,24 1147
+4,24 1148
+747.4,15 1149
+9,10 1149
+12,14 1149
+4,15 1149
+4,15 1066
+749.6,17 1150
+750.4,19 1151
+751.4,12 1152
+752.4,9 1153
+754.6,17 1154
+21,31 1154
+755.4,23 1155
+4,23 1156
+756.11,22 1157
+26,37 1157
+757.4,23 1158
+4,23 1159
+759.4,13 1160
+760.3,17 1161
+3,17 1066
+762.6,17 1162
+21,31 1162
+763.4,23 1163
+4,23 1164
+764.11,22 1165
+26,37 1165
+765.4,23 1166
+766.11,18 1167
+21,25 1167
+4,25 1167
+767.4,12 1168
+4,12 1169
+769.4,13 1170
+771.6,15 1171
+26,32 1171
+19,32 1171
+36,44 1171
+56,62 1171
+48,62 1171
+772.7,16 1172
+20,31 1172
+773.5,22 1173
+774.5,24 1174
+776.18,22 1175
+24,28 1175
+4,29 1175
+777.4,17 1176
+778.4,18 1177
+779.4,21 1178
+781.3,19 1179
+3,19 1066
+784.3,19 1180
+785.6,14 1181
+11,13 1181
+6,14 1181
+6,14 1181
+6,14 1181
+786.4,14 1182
+8,9 1182
+11,13 1182
+4,14 1182
+4,14 1066
+789.6,16 1183
+790.4,20 1184
+4,20 1066
+795.6,15 1185
+796.4,12 1186
+797.6,14 1187
+11,13 1187
+6,14 1187
+6,14 1187
+6,14 1187
+798.4,20 1188
+799.4,14 1189
+8,9 1189
+11,13 1189
+4,14 1189
+800.4,9 1190
+802.3,9 1191
+803.6,15 1192
+804.7,18 1193
+22,33 1193
+805.5,10 1194
+807.7,16 1195
+20,31 1195
+35,46 1195
+808.5,21 1196
+809.5,10 1197
+811.3,19 1198
+812.9,19 1199
+15,18 1199
+9,19 1199
+9,19 1199
+3,20 1199
+3,4 1199
+3,4 1199
+3,4 1200
+3,20 1199
+3,20 1066
+817.6,14 1201
+11,13 1201
+6,14 1201
+6,14 1201
+6,14 1201
+818.4,20 1202
+819.4,14 1203
+8,9 1203
+11,13 1203
+4,14 1203
+820.4,9 1204
+822.6,17 1205
+21,32 1205
+823.5,10 1206
+824.6,17 1207
+21,32 1207
+825.4,20 1208
+826.4,9 1209
+828.3,19 1210
+829.9,19 1211
+15,18 1211
+9,19 1211
+9,19 1211
+3,20 1211
+3,4 1211
+3,4 1211
+3,4 1212
+3,20 1211
+3,20 1066
+834.3,837.4 1213
+835.5,38 1213
+5,38 1213
+19,22 1213
+19,22 1213
+24,29 1213
+24,29 1213
+31,36 1213
+31,36 1213
+836.5,38 1213
+5,38 1213
+19,22 1213
+19,22 1213
+24,29 1213
+24,29 1213
+31,36 1213
+31,36 1213
+838.6,15 1214
+839.11,19 1215
+4,19 1215
+4,19 1216
+840.4,9 1217
+842.12,20 1218
+12,26 1218
+6,26 1218
+843.4,10 1219
+4,10 1220
+845.4,12 1221
+846.12,20 1222
+12,26 1222
+6,26 1222
+847.4,10 1223
+4,10 1224
+849.4,12 1225
+850.6,15 1226
+19,28 1226
+851.4,20 1227
+4,20 1228
+4,20 1066
+853.6,14 1229
+854.4,10 1230
+855.7,16 1231
+856.5,21 1232
+857.5,10 1233
+859.13,21 1234
+860.4,18 1235
+4,18 1236
+861.11,22 1237
+862.4,12 1238
+4,12 1066
+869.8,12 1239
+871.7,18 1240
+22,33 1240
+872.5,14 1241
+5,14 1239
+874.9,11 1242
+876.5,20 1243
+18,19 1243
+5,20 1243
+877.5,20 1244
+5,20 1244
+5,20 1242
+879.5,20 1245
+18,19 1245
+5,20 1245
+880.5,20 1246
+5,20 1246
+5,20 1242
+882.4,20 1247
+4,20 1239
+884.4,20 1248
+4,20 1239
+4,20 1066
+638.26,29 1249
+26,29 1249
+888.9,17 1250
+5,17 1250
+889.9,17 1251
+9,13 1251
+9,17 1251
+2,17 1251
+891.9,12 1252
+2,12 1252
+899.5,10 1253
+16,24 1254
+12,24 1254
+900.12,19 1255
+2,19 1255
+902.5,15 1256
+5,15 1256
+903.3,9 1257
+904.6,22 1258
+24,32 1259
+24,32 1260
+39,45 1261
+905.3,122 1262
+10,16 1262
+18,64 1262
+66,73 1262
+75,77 1262
+79,81 1262
+83,89 1262
+91,99 1262
+101,103 1262
+105,112 1262
+114,121 1262
+3,122 1262
+3,122 1262
+3,122 1263
+907.7,14 1264
+7,14 1264
+7,14 1264
+909.6,14 1265
+6,14 1265
+18,26 1265
+910.4,10 1266
+911.4,13 1267
+912.14,22 1268
+10,22 1268
+913.14,21 1269
+5,21 1269
+914.8,16 1270
+8,16 1270
+20,28 1270
+915.10,13 1271
+10,13 1271
+26,29 1271
+26,29 1271
+21,30 1271
+17,30 1271
+6,30 1271
+6,30 1272
+917.6,9 1273
+918.6,11 1274
+921.7,12 1275
+922.8,18 1276
+8,18 1276
+923.6,46 1277
+13,19 1277
+21,40 1277
+42,45 1277
+6,46 1277
+6,46 1277
+924.5,15 1278
+5,6 1278
+11,14 1278
+5,15 1278
+925.20,23 1279
+16,24 1279
+16,24 1280
+16,24 1281
+927.13,21 1282
+18,20 1282
+13,21 1282
+13,21 1282
+13,21 1282
+928.4,14 1283
+8,9 1283
+11,13 1283
+4,14 1283
+4,14 1284
+929.11,20 1285
+930.7,28 1286
+931.5,15 1287
+932.10,19 1288
+16,18 1288
+10,19 1288
+10,19 1288
+4,20 1288
+4,5 1288
+4,5 1288
+4,5 1289
+4,20 1288
+933.4,17 1290
+4,17 1264
+936.6,15 1291
+937.4,12 1292
+938.3,13 1293
+7,8 1293
+10,12 1293
+3,13 1293
+3,13 1264
+940.6,17 1294
+21,32 1294
+941.4,14 1295
+942.12,24 1296
+4,24 1296
+4,24 1297
+943.13,22 1298
+944.4,14 1299
+4,14 1300
+946.4,15 1301
+9,10 1301
+12,14 1301
+4,15 1301
+947.6,21 1302
+948.4,9 1303
+950.6,17 1304
+21,32 1304
+951.4,14 1305
+952.12,24 1306
+4,24 1306
+4,24 1307
+954.4,15 1308
+9,10 1308
+12,14 1308
+4,15 1308
+4,15 1264
+956.6,17 1309
+21,31 1309
+957.4,23 1310
+4,23 1311
+958.11,22 1312
+26,37 1312
+959.4,23 1313
+4,23 1314
+961.4,13 1315
+962.3,17 1316
+3,17 1264
+964.6,17 1317
+21,31 1317
+965.4,23 1318
+4,23 1319
+966.11,22 1320
+26,37 1320
+967.4,23 1321
+968.11,18 1322
+21,25 1322
+4,25 1322
+969.4,12 1323
+4,12 1324
+971.4,13 1325
+973.6,15 1326
+26,32 1326
+19,32 1326
+36,44 1326
+56,62 1326
+48,62 1326
+974.7,16 1327
+20,31 1327
+975.5,22 1328
+976.5,24 1329
+978.18,22 1330
+24,28 1330
+4,29 1330
+979.4,17 1331
+980.4,18 1332
+981.4,21 1333
+983.3,19 1334
+3,19 1264
+988.6,14 1335
+11,13 1335
+6,14 1335
+6,14 1335
+6,14 1335
+989.4,20 1336
+990.4,14 1337
+8,9 1337
+11,13 1337
+4,14 1337
+991.4,9 1338
+993.6,17 1339
+21,32 1339
+994.5,10 1340
+995.6,17 1341
+21,32 1341
+996.4,20 1342
+997.4,9 1343
+999.3,19 1344
+1000.9,19 1345
+15,18 1345
+9,19 1345
+9,19 1345
+3,20 1345
+3,4 1345
+3,4 1345
+3,4 1346
+3,20 1345
+3,20 1264
+899.26,29 1347
+26,29 1347
+1003.9,17 1348
+5,17 1348
+1004.9,17 1349
+9,13 1349
+9,17 1349
+2,17 1349
+1006.9,12 1350
+2,12 1350
+1013.6,8 1351
+6,8 1351
+6,8 1351
+1015.2,16 1352
+1060.0,1 1353
+0,1 1353
+0,1 1353
+1023.5,16 1354
+1024.3,15 1355
+1060.0,1 1353
+1026.2,14 1356
+1027.15,21 1357
+5,21 1357
+1028.3,19 1358
+1060.0,1 1353
+1030.16,22 1359
+16,26 1359
+5,12 1359
+5,26 1359
+1031.6,19 1360
+6,19 1360
+1032.4,16 1361
+11,12 1361
+14,15 1361
+4,16 1361
+1060.0,1 1353
+1034.4,15 1362
+1060.0,1 1353
+1035.10,22 1363
+1036.6,14 1364
+1037.4,21 1365
+1038.4,23 1366
+1060.0,1 1353
+1041.3,15 1367
+1060.0,1 1353
+1043.2,13 1368
+1060.0,1 1353
+1045.12,25 1369
+16,21 1369
+23,24 1369
+12,25 1369
+12,25 1369
+2,69 1369
+2,69 1369
+2,69 1370
+33,40 1369
+41,48 1369
+51,57 1369
+59,65 1369
+67,68 1369
+2,69 1369
+1060.0,1 1353
+0,1 1353
+0,1 1353
+0,1 1353
+0,1 1353
+1058.2,16 1371
+1060.0,1 1353
+0,1 1353
+1065.4,12 1372
+9,11 1372
+4,12 1372
+4,12 1372
+4,12 1372
+1066.2,18 1373
+1067.2,12 1374
+6,7 1374
+9,11 1374
+2,12 1374
+1068.2,8 1375
+1070.6,8 1376
+1072.9,17 1377
+2,17 1377
+1073.5,16 1378
+1074.3,18 1379
+1075.2,8 1380
+1079.5,16 1381
+1080.3,14 1382
+1081.16,22 1383
+16,26 1383
+5,12 1383
+5,26 1383
+1082.6,19 1384
+6,19 1384
+1083.4,16 1385
+11,12 1385
+14,15 1385
+4,16 1385
+4,16 1386
+1085.4,15 1387
+4,15 1388
+1086.10,22 1389
+1087.3,20 1390
+1088.3,22 1391
+3,22 1392
+1090.3,15 1393
+3,15 1376
+1092.5,17 1394
+1093.6,19 1395
+6,19 1395
+1094.4,17 1396
+11,12 1396
+14,16 1396
+4,17 1396
+4,17 1397
+1096.14,20 1398
+4,24 1398
+4,24 1399
+1097.10,22 1400
+1098.3,8 1401
+1100.3,15 1402
+3,15 1376
+1102.1,17 1403
+1103.0,1 1404
+1109.6,13 1405
+1111.7,9 1406
+1114.6,15 1407
+1115.4,12 1408
+1116.3,18 1409
+1117.6,17 1410
+1118.4,15 1411
+4,15 1406
+1122.6,15 1412
+1123.4,12 1413
+1124.3,18 1414
+1125.17,23 1415
+6,23 1415
+1126.14,20 1416
+4,24 1416
+4,24 1406
+1130.6,15 1417
+1131.4,12 1418
+1132.3,18 1419
+1133.16,22 1420
+6,22 1420
+1134.4,20 1421
+4,20 1406
+1138.6,15 1422
+1139.4,12 1423
+1140.3,18 1424
+1141.6,17 1425
+1142.4,15 1426
+4,15 1406
+1146.3,18 1427
+1147.3,9 1428
+1150.8,12 1429
+8,12 1429
+8,12 1429
+1153.4,38 1430
+13,20 1430
+22,29 1430
+31,37 1430
+4,38 1430
+1154.8,20 1431
+22,30 1432
+1155.5,27 1433
+14,15 1433
+17,18 1433
+20,26 1433
+5,27 1433
+1154.32,35 1434
+32,35 1434
+1158.8,12 1435
+14,23 1436
+1159.5,27 1437
+14,15 1437
+17,18 1437
+20,26 1437
+5,27 1437
+1158.25,28 1438
+25,28 1438
+1160.4,33 1439
+13,20 1439
+22,23 1439
+25,32 1439
+4,33 1439
+4,33 1429
+1163.4,12 1440
+10,11 1440
+4,12 1440
+4,12 1429
+4,12 1406
+1167.8,12 1441
+8,12 1441
+8,12 1441
+1169.8,42 1442
+17,24 1442
+26,33 1442
+35,41 1442
+8,42 1442
+8,42 1441
+1172.8,37 1443
+17,24 1443
+26,27 1443
+29,36 1443
+8,37 1443
+8,37 1441
+1175.8,36 1444
+17,24 1444
+26,27 1444
+29,35 1444
+8,36 1444
+8,36 1441
+8,36 1406
+1180.13,27 1445
+17,20 1445
+22,26 1445
+13,27 1445
+13,27 1445
+3,71 1445
+3,71 1445
+3,71 1446
+35,42 1445
+43,50 1445
+53,59 1445
+61,67 1445
+69,70 1445
+3,71 1445
+3,71 1406
+1184.6,15 1447
+1185.4,20 1448
+4,20 1406
+1188.6,15 1449
+1189.4,21 1450
+4,21 1406
+1193.3,27 1451
+10,17 1451
+19,26 1451
+3,27 1451
+1194.3,14 1452
+3,14 1406
+1198.3,24 1453
+10,17 1453
+19,23 1453
+3,24 1453
+1199.3,14 1454
+3,14 1406
+1203.3,45 1455
+12,19 1455
+21,28 1455
+30,37 1455
+30,42 1455
+30,44 1455
+3,45 1455
+3,45 1406
+1207.6,17 1456
+1208.4,21 1457
+1209.4,21 1458
+4,5 1458
+14,20 1458
+4,21 1458
+4,21 1406
+1214.8,12 1459
+1215.9,45 1460
+9,45 1459
+1216.9,24 1461
+9,24 1459
+1217.9,24 1462
+9,24 1459
+1218.9,24 1463
+9,24 1459
+1219.9,24 1464
+9,24 1459
+1220.9,25 1465
+9,25 1459
+1221.9,25 1466
+9,25 1459
+1222.9,25 1467
+9,25 1459
+1223.9,25 1468
+9,25 1459
+9,25 1406
+1227.6,15 1469
+1228.4,12 1470
+1229.6,15 1471
+1230.4,12 1472
+1231.6,14 1473
+25,31 1473
+18,31 1473
+35,43 1473
+55,61 1473
+47,61 1473
+1232.18,22 1474
+24,28 1474
+4,29 1474
+4,29 1406
+1234.2,18 1475
+1248.0,1 1476
+1236.7,9 1477
+1239.6,15 1478
+1240.4,12 1479
+1241.6,15 1480
+1242.4,12 1481
+1243.6,14 1482
+25,31 1482
+18,31 1482
+35,43 1482
+55,61 1482
+47,61 1482
+1244.18,22 1483
+24,28 1483
+4,29 1483
+4,29 1477
+1246.2,18 1484
+1248.0,1 1476
+0,1 1476
+1260.7,21 1485
+7,21 1485
+7,25 1485
+1261.7,13 1486
+7,23 1486
+2,27 1486
+1262.5,19 1487
+5,19 1487
+1263.6,11 1488
+1264.4,10 1489
+1266.5,10 1490
+1267.3,8 1491
+1268.5,14 1492
+1269.7,11 1493
+13,16 1494
+1270.7,13 1495
+7,20 1495
+1271.5,10 1496
+1269.18,21 1497
+18,21 1497
+1272.6,11 1498
+1273.4,61 1499
+14,17 1499
+14,22 1499
+24,29 1499
+31,37 1499
+39,45 1499
+47,60 1499
+4,61 1499
+1274.4,16 1500
+11,12 1500
+14,15 1500
+4,16 1500
+1276.6,11 1501
+1277.7,17 1502
+7,17 1502
+1278.5,11 1503
+1279.8,24 1504
+26,34 1505
+26,34 1506
+41,47 1507
+1280.5,51 1508
+12,18 1508
+20,32 1508
+34,46 1508
+48,50 1508
+5,51 1508
+5,51 1508
+5,51 1509
+1282.14,27 1510
+20,26 1510
+14,27 1510
+14,27 1510
+4,72 1510
+4,72 1510
+4,72 1511
+29,34 1510
+36,42 1510
+44,56 1510
+58,71 1510
+4,72 1510
+1283.4,16 1512
+11,12 1512
+14,15 1512
+4,16 1512
+1284.4,17 1513
+1287.9,15 1514
+1289.5,29 1515
+5,29 1514
+1291.5,23 1516
+5,23 1514
+1294.10,13 1517
+6,13 1517
+1295.4,63 1518
+18,21 1518
+14,17 1518
+14,24 1518
+26,31 1518
+33,39 1518
+41,47 1518
+49,62 1518
+4,63 1518
+1296.4,22 1519
+11,12 1519
+16,21 1519
+14,21 1519
+4,22 1519
+4,22 1520
+1299.3,60 1521
+13,16 1521
+13,21 1521
+23,28 1521
+30,36 1521
+38,44 1521
+46,59 1521
+3,60 1521
+1300.3,15 1522
+10,11 1522
+13,14 1522
+3,15 1522
+1302.9,16 1523
+5,16 1523
+1303.3,16 1524
+3,16 1524
+3,16 1525
+1305.3,12 1526
+3,12 1526
+1309.0,1 1527
+1315.4,18 1528
+4,18 1528
+1316.13,16 1529
+2,16 1529
+2,16 1530
+1318.2,14 1531
+1319.14,20 1532
+4,20 1532
+1320.5,17 1533
+1321.3,19 1534
+1340.0,1 1535
+1323.3,14 1536
+1324.17,23 1537
+17,27 1537
+6,13 1537
+6,27 1537
+31,44 1537
+31,44 1537
+1325.7,21 1538
+7,21 1538
+1326.5,17 1539
+12,13 1539
+15,16 1539
+5,17 1539
+1340.0,1 1535
+1328.5,17 1540
+12,13 1540
+15,16 1540
+5,17 1540
+1329.5,33 1541
+14,21 1541
+23,24 1541
+26,32 1541
+5,33 1541
+1340.0,1 1535
+1332.7,21 1542
+7,21 1542
+1333.5,17 1543
+5,17 1544
+1335.5,17 1545
+1336.18,24 1546
+7,24 1546
+1337.17,23 1547
+16,26 1547
+5,26 1547
+1340.0,1 1535
+1346.11,35 1548
+15,20 1548
+22,32 1548
+22,34 1548
+11,35 1548
+11,35 1548
+1,77 1548
+1,77 1548
+1,77 1549
+43,48 1548
+49,50 1548
+53,64 1548
+66,73 1548
+75,76 1548
+1,77 1548
+1348.0,1 1550
+1352.5,9 1551
+11,19 1552
+1353.2,24 1553
+11,12 1553
+14,15 1553
+17,23 1553
+2,24 1553
+1352.21,24 1554
+21,24 1554
+1354.0,1 1555
+1359.1,16 1556
+1,16 1556
+1360.0,1 1557
+1365.1,30 1558
+14,21 1558
+23,29 1558
+1,30 1558
+1366.1,16 1559
+1,16 1559
+1367.0,1 1560
+1373.6,12 1561
+6,12 1561
+6,12 1561
+6,12 1561
+6,12 1561
+1375.9,25 1562
+17,18 1562
+20,24 1562
+9,25 1562
+9,25 1562
+2,25 1562
+1377.9,25 1563
+17,18 1563
+20,24 1563
+9,25 1563
+9,25 1563
+2,25 1563
+1379.9,25 1564
+9,25 1564
+20,24 1564
+2,25 1564
+1381.8,11 1565
+1,11 1565
+1387.1,33 1566
+1388.1,13 1567
+1390.1,8 1568
+1391.5,9 1569
+13,21 1570
+11,21 1570
+1392.12,19 1571
+2,19 1571
+1393.7,15 1572
+7,15 1572
+7,15 1572
+1395.6,15 1573
+1396.4,20 1574
+1397.4,15 1575
+1398.7,13 1576
+1399.5,33 1577
+18,20 1577
+22,26 1577
+22,32 1577
+5,33 1577
+5,33 1577
+1400.4,12 1578
+4,12 1572
+1403.3,11 1579
+1404.3,14 1580
+1405.6,15 1581
+1406.4,21 1582
+1407.4,32 1583
+1408.4,14 1584
+1412.4,14 1585
+4,14 1586
+1413.13,22 1587
+1414.4,46 1588
+17,19 1588
+21,45 1588
+35,43 1588
+35,43 1588
+4,46 1588
+4,46 1588
+1415.4,20 1589
+4,20 1590
+1418.4,55 1591
+17,19 1591
+21,54 1591
+35,43 1591
+35,43 1591
+45,52 1591
+45,52 1591
+4,55 1591
+4,55 1591
+1419.4,22 1592
+4,22 1572
+1422.3,11 1593
+1423.3,14 1594
+1424.6,17 1595
+21,32 1595
+1425.8,18 1596
+22,32 1596
+37,46 1596
+1426.5,15 1597
+1427.16,28 1598
+16,32 1598
+4,41 1598
+1428.12,24 1599
+12,20 1599
+12,24 1599
+4,24 1599
+4,24 1600
+1429.6,11 1601
+6,15 1601
+4,16 1601
+4,26 1601
+1430.4,16 1602
+4,16 1603
+4,16 1604
+1432.4,14 1605
+1433.10,12 1606
+1434.4,7 1606
+1435.4,7 1606
+1436.4,7 1606
+1437.4,7 1606
+1438.4,7 1606
+1439.4,7 1606
+1440.4,7 1606
+1441.4,7 1606
+1442.4,7 1606
+1443.4,7 1606
+1444.4,7 1606
+1445.4,7 1606
+1446.4,7 1606
+1448.5,14 1607
+5,14 1606
+1450.7,13 1608
+1451.5,14 1609
+1452.7,17 1610
+7,17 1610
+1453.5,69 1611
+12,18 1611
+20,40 1611
+42,47 1611
+49,64 1611
+66,68 1611
+5,69 1611
+5,69 1611
+1454.7,12 1612
+1455.5,57 1613
+18,20 1613
+22,56 1613
+36,44 1613
+36,44 1613
+46,54 1613
+46,54 1613
+5,57 1613
+5,57 1613
+1456.5,31 1614
+18,20 1614
+22,30 1614
+5,31 1614
+5,31 1614
+1457.5,47 1615
+18,20 1615
+22,45 1615
+36,43 1615
+36,43 1615
+5,47 1615
+5,47 1615
+1459.4,22 1616
+4,22 1572
+1461.2,8 1572
+1391.23,26 1617
+23,26 1617
+1464.4,11 1618
+1465.5,11 1619
+1466.3,31 1620
+16,18 1620
+20,24 1620
+20,30 1620
+3,31 1620
+3,31 1620
+1467.9,11 1621
+2,11 1621
+1469.8,28 1622
+22,26 1622
+22,26 1622
+1,28 1622
+1475.1,33 1623
+1476.1,13 1624
+1478.1,8 1625
+1479.5,9 1626
+13,21 1627
+11,21 1627
+1480.12,19 1628
+2,19 1628
+1481.7,15 1629
+7,15 1629
+7,15 1629
+1483.8,10 1630
+1485.4,20 1631
+1486.4,15 1632
+1487.7,13 1633
+1488.5,33 1634
+18,20 1634
+22,26 1634
+22,32 1634
+5,33 1634
+5,33 1634
+1489.4,12 1635
+4,12 1630
+1491.4,20 1636
+1492.4,15 1637
+1493.7,13 1638
+1494.5,33 1639
+18,20 1639
+22,26 1639
+22,32 1639
+5,33 1639
+5,33 1639
+1495.4,12 1640
+4,12 1630
+4,12 1629
+1498.3,11 1641
+1499.3,14 1642
+1500.6,15 1643
+1501.4,21 1644
+1502.4,32 1645
+1503.4,14 1646
+4,14 1647
+1504.13,22 1648
+1505.4,46 1649
+17,19 1649
+21,45 1649
+35,43 1649
+35,43 1649
+4,46 1649
+4,46 1649
+1506.4,20 1650
+4,20 1651
+1509.4,55 1652
+17,19 1652
+21,54 1652
+35,43 1652
+35,43 1652
+45,52 1652
+45,52 1652
+4,55 1652
+4,55 1652
+1510.4,22 1653
+4,22 1629
+1513.3,11 1654
+1514.3,14 1655
+1515.6,15 1656
+1516.4,46 1657
+17,19 1657
+21,45 1657
+35,43 1657
+35,43 1657
+4,46 1657
+4,46 1657
+1517.4,20 1658
+4,20 1659
+1518.13,22 1660
+1519.4,46 1661
+17,19 1661
+21,45 1661
+35,43 1661
+35,43 1661
+4,46 1661
+4,46 1661
+1520.4,20 1662
+4,20 1663
+1522.7,18 1664
+22,33 1664
+1523.5,57 1665
+18,20 1665
+22,56 1665
+36,44 1665
+36,44 1665
+47,54 1665
+47,54 1665
+5,57 1665
+5,57 1665
+1525.4,22 1666
+4,22 1629
+1528.3,11 1667
+1529.3,14 1668
+1530.6,17 1669
+21,32 1669
+1531.8,18 1670
+22,32 1670
+37,46 1670
+50,59 1670
+1532.5,15 1671
+1533.16,28 1672
+16,32 1672
+4,41 1672
+1534.12,24 1673
+12,20 1673
+12,24 1673
+4,24 1673
+4,24 1674
+1535.6,11 1675
+6,15 1675
+4,16 1675
+4,26 1675
+1536.4,16 1676
+4,16 1677
+4,16 1678
+1538.4,14 1679
+1539.10,12 1680
+1540.4,7 1680
+1541.4,7 1680
+1542.4,7 1680
+1543.4,7 1680
+1544.4,7 1680
+1545.4,7 1680
+1546.4,7 1680
+1547.4,7 1680
+1548.4,7 1680
+1549.4,7 1680
+1550.4,7 1680
+1551.4,7 1680
+1552.4,7 1680
+1553.4,7 1680
+1555.5,22 1681
+1556.8,14 1682
+27,30 1682
+18,31 1682
+18,43 1682
+1557.6,16 1683
+6,16 1680
+1559.5,14 1684
+5,14 1680
+1561.7,13 1685
+1562.5,14 1686
+1563.7,17 1687
+7,17 1687
+1564.5,69 1688
+12,18 1688
+20,40 1688
+42,47 1688
+49,64 1688
+66,68 1688
+5,69 1688
+5,69 1688
+1565.7,12 1689
+1566.5,57 1690
+18,20 1690
+22,56 1690
+36,44 1690
+36,44 1690
+46,54 1690
+46,54 1690
+5,57 1690
+5,57 1690
+1567.5,31 1691
+18,20 1691
+22,30 1691
+5,31 1691
+5,31 1691
+1568.5,47 1692
+18,20 1692
+22,45 1692
+36,43 1692
+36,43 1692
+5,47 1692
+5,47 1692
+1570.4,22 1693
+4,22 1629
+1572.2,8 1629
+1479.23,26 1694
+23,26 1694
+1575.4,11 1695
+1576.5,11 1696
+1577.3,31 1697
+16,18 1697
+20,24 1697
+20,30 1697
+3,31 1697
+3,31 1697
+1578.9,11 1698
+2,11 1698
+1580.8,28 1699
+22,26 1699
+22,26 1699
+1,28 1699
+1592.1,12 1700
+1593.14,17 1701
+1,35 1701
+1594.10,16 1702
+10,12 1702
+10,16 1702
+1,16 1702
+1,16 1703
+1595.1,6 1704
+1,10 1704
+1596.8,10 1705
+1,10 1705
+1602.24,30 1706
+24,33 1706
+17,53 1706
+44,52 1706
+44,52 1706
+44,52 1706
+44,52 1706
+44,52 1706
+44,52 1706
+1,53 1706
+1,53 1707
+1603.1,13 1708
+1604.8,14 1709
+8,18 1709
+4,18 1709
+1605.6,12 1710
+2,16 1710
+1606.1,46 1711
+11,16 1711
+24,25 1711
+27,28 1711
+31,39 1711
+41,42 1711
+44,45 1711
+1,46 1711
+1607.4,14 1712
+1608.2,62 1713
+12,15 1713
+12,20 1713
+28,29 1713
+31,32 1713
+35,43 1713
+45,58 1713
+60,61 1713
+2,62 1713
+1609.1,16 1714
+1,16 1714
+1610.0,1 1715
+0:135.19,22 1716
+137.1,25 1717
+138.1,22 1718
+139.1,40 1719
+140.1,17 1720
+1,17 1720
+141.1,28 1721
+142.1,24 1722
+22,23 1722
+1,24 1722
+1,24 1722
+143.1,48 1723
+18,42 1723
+44,47 1723
+1,48 1723
+1,48 1723
+145.1,26 1724
+146.1,16 1725
+11,15 1725
+1,16 1725
+147.1,36 1726
+15,35 1726
+1,36 1726
+148.7,24 1727
+7,24 1727
+7,24 1727
+7,24 1727
+7,29 1727
+149.7,8 1728
+151.3,18 1729
+3,18 1729
+3,18 1729
+152.7,13 1730
+19,24 1731
+15,24 1731
+153.8,12 1732
+154.11,20 1733
+7,20 1733
+155.5,13 1734
+5,18 1734
+152.26,29 1735
+26,29 1735
+158.3,15 1736
+3,15 1736
+3,15 1728
+161.1,19 1737
+1,19 1737
+1,19 1737
+162.4,12 1738
+4,16 1738
+163.2,19 1739
+164.2,16 1740
+167.4,15 1741
+168.2,14 1742
+2,14 1742
+169.1,10 1743
+174.12,33 1744
+1,33 1744
+175.4,18 1745
+176.2,39 1746
+177.17,44 1747
+31,38 1747
+40,43 1747
+17,44 1747
+17,44 1747
+7,12 1747
+7,12 1748
+178.4,13 1749
+4,18 1749
+179.2,18 1750
+180.21,24 1751
+2,24 1751
+2,24 1751
+2,24 1752
+182.4,12 1753
+4,23 1753
+4,23 1754
+183.2,18 1755
+184.2,18 1756
+185.5,17 1757
+186.3,21 1758
+187.3,19 1759
+188.6,18 1760
+189.4,22 1761
+191.5,19 1762
+192.3,16 1763
+193.5,19 1764
+194.3,16 1765
+3,16 1766
+196.2,19 1767
+197.2,19 1768
+200.1,17 1769
+201.1,13 1770
+202.1,14 1771
+203.1,15 1772
+204.1,15 1773
+205.1,210.2 1774
+206.2,9 1774
+13,16 1774
+207.2,8 1774
+12,15 1774
+208.2,7 1774
+12,15 1774
+209.2,9 1774
+13,16 1774
+212.1,43 1775
+26,38 1775
+40,42 1775
+1,43 1775
+1,43 1775
+213.1,26 1776
+8,16 1776
+18,25 1776
+1,26 1776
+215.1,26 1777
+1,2 1777
+8,16 1777
+18,25 1777
+1,26 1777
+216.1,17 1778
+1,2 1778
+8,16 1778
+1,17 1778
+217.1,34 1779
+1,2 1779
+8,15 1779
+17,24 1779
+26,33 1779
+1,34 1779
+218.1,9 1780
+1,2 1780
+1,9 1780
+219.6,13 1781
+221.2,62 1782
+2,3 1782
+9,13 1782
+21,22 1782
+23,24 1782
+28,31 1782
+32,35 1782
+45,46 1782
+47,48 1782
+52,55 1782
+56,59 1782
+2,62 1782
+2,62 1781
+223.2,63 1783
+2,3 1783
+9,13 1783
+21,22 1783
+23,24 1783
+28,31 1783
+32,35 1783
+45,46 1783
+47,49 1783
+53,56 1783
+57,60 1783
+2,63 1783
+2,63 1781
+226.1,20 1784
+227.1,14 1785
+7,8 1785
+1,14 1785
+228.1,14 1786
+7,8 1786
+1,14 1786
+229.1,14 1787
+7,8 1787
+1,14 1787
+230.1,14 1788
+7,8 1788
+1,14 1788
+231.1,18 1789
+7,8 1789
+13,17 1789
+1,18 1789
+232.1,8 1790
+235.1,9 1791
+1,2 1791
+1,9 1791
+236.1,9 1792
+1,2 1792
+1,9 1792
+237.1,9 1793
+1,2 1793
+1,9 1793
+238.1,9 1794
+1,2 1794
+1,9 1794
+239.1,9 1795
+1,2 1795
+1,9 1795
+240.0,1 1796
+418.1,27 1797
+8,16 1797
+18,26 1797
+1,27 1797
+419.4,21 1798
+420.2,32 1799
+9,17 1799
+19,31 1799
+2,32 1799
+423.0,1 1800
+422.2,28 1801
+9,17 1801
+19,27 1801
+2,28 1801
+423.0,1 1800
+427.4,23 1802
+428.2,8 1803
+429.4,14 1804
+430.2,35 1805
+9,19 1805
+21,34 1805
+2,35 1805
+431.2,35 1806
+9,19 1806
+21,34 1806
+2,35 1806
+440.0,1 1807
+433.2,35 1808
+9,19 1808
+21,34 1808
+2,35 1808
+434.2,35 1809
+9,19 1809
+21,34 1809
+2,35 1809
+435.6,19 1810
+436.3,35 1811
+10,20 1811
+22,34 1811
+3,35 1811
+440.0,1 1807
+438.3,35 1812
+10,20 1812
+22,34 1812
+3,35 1812
+440.0,1 1807
+444.1,25 1813
+445.1,450.2 1814
+446.2,9 1814
+13,62 1814
+24,31 1814
+33,52 1814
+46,47 1814
+46,47 1814
+48,49 1814
+48,49 1814
+50,51 1814
+50,51 1814
+54,55 1814
+57,58 1814
+60,61 1814
+13,62 1814
+13,62 1815
+447.2,8 1814
+12,61 1814
+23,30 1814
+32,51 1814
+45,46 1814
+45,46 1814
+47,48 1814
+47,48 1814
+49,50 1814
+49,50 1814
+53,54 1814
+56,57 1814
+59,60 1814
+12,61 1814
+12,61 1816
+448.2,7 1814
+11,60 1814
+22,29 1814
+31,50 1814
+44,45 1814
+44,45 1814
+46,47 1814
+46,47 1814
+48,49 1814
+48,49 1814
+52,53 1814
+55,56 1814
+58,59 1814
+11,60 1814
+11,60 1817
+449.2,9 1814
+13,62 1814
+24,31 1814
+33,52 1814
+46,47 1814
+46,47 1814
+48,49 1814
+48,49 1814
+50,51 1814
+50,51 1814
+54,55 1814
+57,58 1814
+60,61 1814
+13,62 1814
+13,62 1818
+452.1,22 1819
+453.1,20 1820
+454.5,24 1821
+455.2,12 1822
+2,12 1823
+457.2,15 1824
+458.1,23 1825
+459.1,40 1826
+14,24 1826
+26,31 1826
+33,39 1826
+1,40 1826
+1,40 1826
+1,40 1827
+460.1,16 1828
+461.1,18 1829
+462.1,14 1830
+463.1,21 1831
+464.1,10 1832
+1,2 1832
+1,10 1832
+465.0,1 1833
+469.1,18 1834
+470.0,1 1835
+474.1,479.2 1836
+475.2,9 1836
+13,73 1836
+25,32 1836
+34,37 1836
+39,42 1836
+44,48 1836
+50,72 1836
+13,73 1836
+13,73 1837
+476.2,8 1836
+12,71 1836
+24,30 1836
+32,35 1836
+37,40 1836
+42,46 1836
+48,70 1836
+12,71 1836
+12,71 1838
+477.2,7 1836
+12,70 1836
+24,29 1836
+31,34 1836
+36,39 1836
+41,45 1836
+47,69 1836
+12,70 1836
+12,70 1839
+478.2,9 1836
+13,73 1836
+25,32 1836
+34,37 1836
+39,42 1836
+44,48 1836
+50,72 1836
+13,73 1836
+13,73 1840
+480.1,20 1841
+481.4,14 1842
+4,14 1842
+482.2,57 1843
+7,56 1843
+11,56 1843
+24,30 1843
+32,33 1843
+35,40 1843
+42,48 1843
+50,51 1843
+52,53 1843
+54,55 1843
+7,56 1843
+7,56 1844
+2,57 1843
+485.18,21 1845
+486.2,11 1846
+7,10 1846
+2,11 1846
+489.9,13 1847
+9,13 1847
+508.2,16 1847
+2,16 1847
+2,19 1847
+2,19 1848
+25,39 1847
+25,39 1847
+25,42 1847
+2,19 1847
+510.2,15 1847
+2,15 1847
+2,18 1847
+2,18 1849
+24,37 1847
+24,37 1847
+24,40 1847
+2,18 1847
+512.2,14 1847
+2,14 1847
+2,17 1847
+2,17 1850
+24,36 1847
+24,36 1847
+24,39 1847
+2,17 1847
+514.2,16 1847
+2,16 1847
+2,19 1847
+2,19 1851
+25,39 1847
+25,39 1847
+25,42 1847
+2,19 1847
+518.12,17 1847
+12,17 1847
+487.2,8 1847
+2,8 1847
+2,8 1847
+2,8 1847
+490.6,15 1852
+491.7,17 1853
+7,17 1853
+7,22 1853
+7,22 1854
+7,22 1855
+492.5,10 1856
+5,10 1857
+5,10 1858
+493.4,12 1859
+495.8,15 1860
+8,15 1860
+497.4,57 1861
+9,56 1861
+13,56 1861
+25,53 1861
+54,55 1861
+9,56 1861
+9,56 1862
+4,57 1861
+4,57 1863
+4,57 1864
+498.4,12 1865
+501.3,22 1866
+19,21 1866
+3,22 1866
+3,22 1866
+502.9,16 1867
+9,20 1867
+503.4,16 1868
+9,15 1868
+9,15 1868
+4,16 1868
+504.4,17 1869
+4,17 1869
+4,17 1869
+4,17 1870
+4,17 1847
+4,17 1871
+509.3,17 1872
+3,17 1872
+3,26 1872
+3,26 1873
+3,26 1847
+3,26 1874
+511.3,16 1875
+3,16 1875
+3,25 1875
+3,25 1876
+3,25 1847
+3,25 1877
+513.3,15 1878
+3,15 1878
+3,24 1878
+3,24 1879
+3,24 1847
+3,24 1880
+515.3,17 1881
+3,17 1881
+3,26 1881
+3,26 1882
+3,26 1847
+519.16,39 1883
+30,33 1883
+35,38 1883
+16,39 1883
+16,39 1883
+4,5 1883
+7,11 1883
+7,11 1884
+520.6,10 1885
+521.9,16 1886
+9,16 1886
+522.4,12 1886
+524.5,65 1887
+10,64 1887
+14,64 1887
+27,33 1887
+35,41 1887
+43,48 1887
+50,56 1887
+58,59 1887
+60,61 1887
+62,63 1887
+10,64 1887
+10,64 1888
+5,65 1887
+5,65 1886
+526.9,23 1889
+528.21,26 1890
+24,25 1890
+21,26 1890
+21,26 1890
+7,8 1890
+10,17 1890
+10,17 1891
+10,17 1892
+529.10,18 1893
+530.7,51 1894
+18,47 1894
+49,50 1894
+7,51 1894
+7,51 1894
+7,51 1895
+7,51 1896
+532.6,26 1897
+6,26 1886
+534.8,25 1898
+29,50 1898
+535.6,62 1899
+11,61 1899
+15,61 1899
+28,34 1899
+36,37 1899
+39,50 1899
+52,54 1899
+55,56 1899
+57,58 1899
+59,60 1899
+11,61 1899
+11,61 1900
+6,62 1899
+6,62 1886
+537.5,37 1901
+12,22 1901
+24,36 1901
+5,37 1901
+538.5,22 1902
+539.8,22 1903
+540.6,54 1904
+13,20 1904
+35,36 1904
+37,38 1904
+47,49 1904
+51,52 1904
+6,54 1904
+6,54 1904
+541.9,23 1905
+542.6,23 1906
+6,23 1886
+544.5,37 1907
+12,22 1907
+24,36 1907
+5,37 1907
+545.5,22 1908
+546.8,22 1909
+547.6,53 1910
+13,20 1910
+35,36 1910
+37,38 1910
+47,48 1910
+50,51 1910
+6,53 1910
+6,53 1910
+548.9,23 1911
+549.6,23 1912
+6,23 1886
+551.5,15 1913
+5,20 1913
+552.5,15 1914
+5,20 1914
+5,20 1886
+5,20 1915
+5,20 1916
+5,20 1847
+5,20 1917
+5,20 1917
+557.5,19 1918
+558.2,21 1919
+559.1,14 1920
+560.1,11 1921
+561.0,1 1922
+565.1,20 1923
+566.1,17 1924
+12,13 1924
+15,16 1924
+1,17 1924
+567.1,10 1925
+568.5,13 1926
+569.10,11 1927
+13,16 1927
+2,17 1927
+570.9,12 1928
+14,15 1928
+1,16 1928
+575.6,11 1929
+6,11 1929
+6,11 1929
+6,11 1929
+577.2,22 1930
+2,22 1929
+579.2,23 1931
+2,23 1929
+581.4,18 1932
+582.2,20 1933
+583.2,18 1934
+585.0,1 1935
+590.1,41 1936
+591.5,20 1937
+592.2,31 1938
+593.2,8 1939
+596.1,24 1940
+597.13,58 1941
+32,38 1941
+40,42 1941
+44,54 1941
+56,57 1941
+13,58 1941
+13,58 1941
+598.1,35 1942
+9,12 1942
+14,34 1942
+1,35 1942
+1,35 1942
+1,35 1943
+599.1,23 1944
+9,12 1944
+14,22 1944
+1,23 1944
+1,23 1944
+1,23 1945
+600.1,48 1946
+20,23 1946
+25,31 1946
+33,40 1946
+42,47 1946
+1,48 1946
+1,48 1946
+1,48 1947
+601.1,27 1948
+9,12 1948
+14,26 1948
+1,27 1948
+1,27 1948
+1,27 1949
+603.1,19 1950
+605.1,10 1951
+606.1,11 1952
+609.12,13 1953
+12,13 1953
+617.13,14 1953
+13,14 1953
+608.10,16 1953
+10,16 1953
+10,16 1953
+10,16 1953
+610.6,20 1954
+611.7,11 1955
+612.4,35 1956
+12,15 1956
+17,34 1956
+4,35 1956
+4,35 1956
+4,35 1957
+613.4,12 1958
+4,12 1959
+616.3,29 1960
+19,22 1960
+24,28 1960
+3,29 1960
+3,29 1960
+3,29 1961
+3,29 1962
+3,29 1953
+618.7,12 1963
+620.7,11 1964
+621.4,34 1965
+12,15 1965
+17,33 1965
+4,34 1965
+4,34 1965
+4,34 1966
+4,34 1963
+623.7,11 1967
+624.4,35 1968
+12,15 1968
+17,34 1968
+4,35 1968
+4,35 1968
+4,35 1969
+625.4,12 1970
+4,12 1971
+627.4,34 1972
+12,15 1972
+17,33 1972
+4,34 1972
+4,34 1972
+4,34 1973
+628.4,12 1974
+4,12 1963
+631.3,22 1975
+3,22 1963
+633.3,20 1976
+634.3,12 1977
+637.7,8 1978
+7,8 1978
+636.3,9 1978
+3,9 1978
+3,9 1978
+3,9 1978
+3,9 1979
+640.3,9 1980
+3,9 1980
+3,9 1981
+3,9 1953
+648.0,1 1982
+653.4,14 1983
+4,14 1983
+18,26 1983
+654.49,56 1984
+49,50 1984
+49,56 1984
+49,56 1984
+2,57 1984
+9,15 1984
+17,30 1984
+32,47 1984
+32,47 1984
+32,47 1984
+32,47 1985
+2,57 1984
+2,57 1984
+655.1,12 1986
+656.0,1 1987
+662.5,8 1988
+10,19 1989
+664.19,27 1990
+19,27 1990
+665.2,13 1991
+666.5,16 1992
+20,26 1992
+667.10,16 1993
+3,16 1993
+668.16,19 1994
+3,33 1994
+669.12,19 1995
+12,15 1995
+12,19 1995
+3,19 1995
+3,19 1996
+670.3,11 1997
+3,11 1998
+672.6,14 1999
+673.6,12 2000
+6,21 2000
+6,21 2000
+674.7,17 2001
+7,21 2001
+675.10,17 2002
+10,17 2002
+677.67,74 2003
+67,68 2003
+67,74 2003
+67,74 2003
+6,75 2003
+13,19 2003
+21,36 2003
+38,48 2003
+38,48 2003
+50,65 2003
+50,65 2003
+50,65 2003
+50,65 2004
+6,75 2003
+6,75 2003
+6,75 2002
+680.7,18 2005
+681.5,13 2006
+5,13 2007
+683.5,16 2008
+684.18,21 2009
+5,35 2009
+685.14,21 2010
+14,17 2010
+14,21 2010
+5,21 2010
+5,21 2011
+686.5,10 2012
+5,14 2012
+687.5,13 2013
+5,13 2014
+692.5,16 2015
+693.3,27 2016
+3,27 2017
+695.3,14 2018
+3,14 2019
+662.21,24 2020
+21,24 2020
+697.0,1 2021
+709.1,29 2022
+710.1,13 2023
+712.6,13 2024
+6,13 2024
+714.2,9 2025
+715.7,22 2026
+2,22 2026
+716.6,10 2027
+14,24 2028
+12,24 2028
+717.13,22 2029
+3,22 2029
+720.6,16 2030
+721.7,14 2031
+18,34 2031
+722.5,13 2032
+723.4,12 2033
+724.4,12 2034
+726.8,15 2035
+8,15 2035
+8,15 2035
+728.7,16 2036
+729.5,20 2037
+730.5,16 2038
+731.8,14 2039
+732.6,69 2040
+19,21 2040
+23,68 2040
+27,68 2040
+39,45 2040
+47,53 2040
+55,61 2040
+55,67 2040
+23,68 2040
+23,68 2041
+6,69 2040
+6,69 2040
+733.5,13 2042
+5,13 2035
+736.4,19 2043
+737.4,11 2044
+738.4,12 2045
+739.4,15 2046
+740.7,18 2047
+22,33 2047
+741.15,25 2048
+5,29 2048
+5,29 2049
+742.12,23 2050
+743.5,16 2051
+5,16 2052
+744.12,21 2053
+745.5,80 2054
+18,20 2054
+22,79 2054
+26,79 2054
+38,44 2054
+46,52 2054
+54,78 2054
+68,76 2054
+68,76 2054
+22,79 2054
+22,79 2055
+5,80 2054
+5,80 2054
+746.5,20 2056
+5,20 2057
+749.5,89 2058
+18,20 2058
+22,88 2058
+26,88 2058
+38,44 2058
+46,52 2058
+54,87 2058
+68,76 2058
+68,76 2058
+78,85 2058
+78,85 2058
+22,88 2058
+22,88 2059
+5,89 2058
+5,89 2058
+750.5,22 2060
+5,22 2035
+753.4,12 2061
+754.4,14 2062
+755.13,20 2063
+7,20 2063
+756.11,16 2064
+11,16 2064
+5,17 2064
+5,22 2064
+757.14,21 2065
+7,21 2065
+759.5,27 2066
+17,23 2066
+25,26 2066
+5,27 2066
+5,27 2066
+760.8,17 2067
+761.6,26 2068
+19,21 2068
+23,25 2068
+6,26 2068
+6,26 2068
+762.5,22 2069
+5,22 2070
+5,22 2035
+716.26,29 2071
+26,29 2071
+766.5,12 2072
+767.6,12 2073
+768.4,67 2074
+17,19 2074
+21,66 2074
+25,66 2074
+37,43 2074
+45,51 2074
+53,59 2074
+53,65 2074
+21,66 2074
+21,66 2075
+4,67 2074
+4,67 2074
+769.10,12 2076
+3,12 2076
+771.2,8 2077
+772.9,25 2078
+22,24 2078
+22,24 2078
+2,25 2078
+774.8,24 2079
+21,23 2079
+21,23 2079
+1,24 2079
+780.1,12 2080
+781.14,17 2081
+1,31 2081
+782.10,16 2082
+10,12 2082
+10,16 2082
+1,16 2082
+1,16 2083
+783.1,6 2084
+1,10 2084
+784.8,10 2085
+1,10 2085
+792.4,14 2086
+4,14 2086
+793.2,49 2087
+9,15 2087
+17,29 2087
+31,38 2087
+40,48 2087
+40,48 2087
+2,49 2087
+2,49 2087
+794.5,16 2088
+795.3,35 2089
+10,16 2089
+18,24 2089
+26,34 2089
+26,34 2089
+3,35 2089
+3,35 2089
+796.5,16 2090
+797.3,35 2091
+10,16 2091
+18,24 2091
+26,34 2091
+26,34 2091
+3,35 2091
+3,35 2091
+798.2,42 2092
+9,15 2092
+17,26 2092
+28,41 2092
+28,41 2092
+2,42 2092
+2,42 2092
+800.6,13 2093
+6,13 2093
+6,13 2093
+802.2,62 2094
+25,32 2094
+25,32 2094
+34,46 2094
+34,46 2094
+48,60 2094
+48,60 2094
+803.2,44 2095
+7,43 2095
+11,43 2095
+23,29 2095
+31,35 2095
+37,42 2095
+7,43 2095
+7,43 2096
+2,44 2095
+2,44 2097
+2,44 2093
+805.7,15 2098
+7,15 2098
+806.2,16 2098
+808.3,52 2099
+8,51 2099
+12,51 2099
+24,30 2099
+32,36 2099
+38,50 2099
+8,51 2099
+8,51 2100
+3,52 2099
+809.6,33 2101
+810.4,30 2102
+4,30 2098
+811.2,20 2098
+813.44,49 2103
+44,49 2103
+44,49 2103
+3,50 2103
+8,14 2103
+16,20 2103
+22,42 2103
+22,42 2103
+3,50 2103
+3,50 2098
+814.2,9 2098
+816.10,63 2104
+14,63 2104
+27,34 2104
+36,40 2104
+42,52 2104
+54,56 2104
+57,58 2104
+59,60 2104
+61,62 2104
+10,63 2104
+10,63 2105
+3,63 2104
+818.3,38 2106
+819.3,54 2107
+8,53 2107
+12,53 2107
+25,28 2107
+30,34 2107
+36,42 2107
+44,46 2107
+47,48 2107
+49,50 2107
+51,52 2107
+8,53 2107
+8,53 2108
+3,54 2107
+820.3,12 2109
+3,4 2109
+3,12 2109
+821.3,48 2110
+26,34 2110
+26,34 2110
+36,46 2110
+36,46 2110
+822.3,45 2111
+8,44 2111
+12,44 2111
+24,30 2111
+32,36 2111
+38,43 2111
+8,44 2111
+8,44 2112
+3,45 2111
+3,45 2113
+3,45 2098
+3,45 2093
+825.7,15 2114
+7,15 2114
+827.38,51 2115
+42,50 2115
+42,50 2115
+38,51 2115
+38,51 2115
+3,52 2115
+8,14 2115
+16,20 2115
+22,26 2115
+28,36 2115
+28,36 2115
+28,36 2115
+3,52 2115
+3,52 2114
+828.2,13 2114
+829.2,11 2114
+831.12,20 2116
+3,20 2116
+832.6,16 2117
+20,32 2117
+833.4,14 2118
+4,14 2119
+835.4,49 2120
+27,35 2120
+27,35 2120
+37,47 2120
+37,47 2120
+836.4,46 2121
+9,45 2121
+13,45 2121
+25,31 2121
+33,37 2121
+39,44 2121
+9,45 2121
+9,45 2122
+4,46 2121
+4,46 2123
+4,46 2114
+839.6,14 2124
+6,24 2124
+840.50,56 2125
+50,56 2125
+50,56 2125
+4,57 2125
+9,15 2125
+17,21 2125
+23,40 2125
+42,48 2125
+42,48 2125
+4,57 2125
+4,57 2114
+842.3,13 2126
+3,13 2126
+3,13 2126
+843.6,14 2127
+6,27 2127
+844.4,14 2128
+845.6,14 2129
+6,27 2129
+846.4,14 2130
+847.3,46 2131
+8,14 2131
+16,20 2131
+22,42 2131
+44,45 2131
+3,46 2131
+848.8,16 2132
+8,16 2132
+8,16 2132
+8,16 2132
+8,16 2132
+8,16 2132
+850.4,45 2133
+15,44 2133
+4,45 2133
+4,45 2133
+851.11,62 2134
+15,62 2134
+28,34 2134
+36,40 2134
+42,51 2134
+53,55 2134
+56,57 2134
+58,59 2134
+60,61 2134
+11,62 2134
+11,62 2135
+4,62 2134
+853.11,72 2136
+15,72 2136
+28,35 2136
+37,41 2136
+43,49 2136
+51,53 2136
+54,59 2136
+60,69 2136
+70,71 2136
+11,72 2136
+11,72 2137
+4,72 2136
+855.11,70 2138
+15,70 2138
+28,33 2138
+35,39 2138
+41,47 2138
+49,51 2138
+52,57 2138
+58,67 2138
+68,69 2138
+11,70 2138
+11,70 2139
+4,70 2138
+4,70 2114
+858.3,13 2140
+3,13 2140
+3,13 2140
+859.6,14 2141
+6,27 2141
+860.4,15 2142
+861.44,49 2143
+44,49 2143
+44,49 2143
+3,50 2143
+8,14 2143
+16,20 2143
+22,42 2143
+22,42 2143
+3,50 2143
+862.8,16 2144
+8,16 2144
+8,16 2144
+8,16 2144
+8,16 2144
+8,16 2144
+864.4,47 2145
+15,46 2145
+4,47 2145
+4,47 2145
+865.11,61 2146
+15,61 2146
+28,34 2146
+36,40 2146
+42,50 2146
+52,54 2146
+55,56 2146
+57,58 2146
+59,60 2146
+11,61 2146
+11,61 2147
+4,61 2146
+867.11,71 2148
+15,71 2148
+28,35 2148
+37,41 2148
+43,49 2148
+51,53 2148
+54,58 2148
+59,68 2148
+69,70 2148
+11,71 2148
+11,71 2149
+4,71 2148
+869.11,69 2150
+15,69 2150
+28,33 2150
+35,39 2150
+41,47 2150
+49,51 2150
+52,56 2150
+57,66 2150
+67,68 2150
+11,69 2150
+11,69 2151
+4,69 2150
+4,69 2114
+871.2,6 2114
+875.8,16 2152
+8,16 2152
+877.4,49 2153
+27,35 2153
+27,35 2153
+37,47 2153
+37,47 2153
+878.11,69 2154
+15,69 2154
+28,35 2154
+37,41 2154
+43,49 2154
+51,53 2154
+54,59 2154
+60,66 2154
+67,68 2154
+11,69 2154
+11,69 2155
+4,69 2154
+880.4,49 2156
+27,35 2156
+27,35 2156
+37,47 2156
+37,47 2156
+881.11,69 2157
+15,69 2157
+28,35 2157
+37,41 2157
+43,49 2157
+51,53 2157
+54,59 2157
+60,66 2157
+67,68 2157
+11,69 2157
+11,69 2158
+4,69 2157
+4,69 2114
+883.2,7 2114
+2,7 2093
+888.7,15 2159
+7,15 2159
+890.3,39 2160
+10,18 2160
+10,18 2160
+20,28 2160
+20,28 2160
+30,38 2160
+30,38 2160
+3,39 2160
+891.38,59 2161
+49,57 2161
+42,58 2161
+38,59 2161
+38,59 2161
+3,60 2161
+8,14 2161
+16,20 2161
+22,26 2161
+28,36 2161
+28,36 2161
+28,36 2161
+3,60 2161
+3,60 2159
+893.8,16 2162
+8,16 2162
+895.9,17 2163
+9,17 2163
+9,17 2163
+9,17 2163
+9,17 2163
+9,17 2163
+897.5,21 2164
+5,21 2163
+899.5,21 2165
+5,21 2163
+901.50,56 2166
+50,56 2166
+50,56 2166
+4,57 2166
+9,15 2166
+17,21 2166
+23,40 2166
+42,48 2166
+42,48 2166
+4,57 2166
+4,57 2162
+4,57 2159
+904.8,16 2167
+8,16 2167
+906.9,17 2168
+9,17 2168
+9,17 2168
+9,17 2168
+9,17 2168
+9,17 2168
+908.5,22 2169
+5,22 2168
+910.5,22 2170
+5,22 2168
+912.50,56 2171
+50,56 2171
+50,56 2171
+4,57 2171
+9,15 2171
+17,21 2171
+23,40 2171
+42,48 2171
+42,48 2171
+4,57 2171
+4,57 2167
+4,57 2159
+4,57 2093
+916.8,11 2172
+1,11 2172
+922.1,68 2173
+23,31 2173
+23,31 2173
+33,43 2173
+33,43 2173
+45,51 2173
+45,51 2173
+53,59 2173
+53,59 2173
+61,67 2173
+61,67 2173
+923.1,40 2174
+6,39 2174
+10,39 2174
+22,26 2174
+28,32 2174
+34,38 2174
+6,39 2174
+6,39 2175
+1,40 2174
+924.0,1 2176
+929.1,60 2177
+23,31 2177
+23,31 2177
+33,43 2177
+33,43 2177
+45,51 2177
+45,51 2177
+53,59 2177
+53,59 2177
+930.1,40 2178
+6,39 2178
+10,39 2178
+22,26 2178
+28,32 2178
+34,38 2178
+6,39 2178
+6,39 2179
+1,40 2178
+931.0,1 2180
+943.1,18 2181
+13,17 2181
+1,18 2181
+1,18 2181
+944.1,18 2182
+13,17 2182
+1,18 2182
+1,18 2182
+945.4,16 2183
+946.5,14 2184
+947.3,16 2185
+3,16 2185
+3,29 2185
+3,29 2186
+955.0,1 2187
+949.3,16 2188
+3,16 2188
+3,29 2188
+3,29 2189
+955.0,1 2187
+951.5,14 2190
+952.3,16 2191
+3,16 2191
+25,34 2191
+3,34 2191
+3,34 2192
+955.0,1 2187
+954.3,16 2193
+3,16 2193
+26,35 2193
+25,35 2193
+3,35 2193
+3,35 2194
+955.0,1 2187
+962.1,19 2195
+14,18 2195
+1,19 2195
+1,19 2195
+963.1,11 2196
+964.12,24 2197
+12,24 2197
+4,24 2197
+965.2,19 2198
+966.5,21 2199
+5,21 2199
+5,33 2199
+5,33 2200
+5,33 2199
+967.3,13 2201
+968.5,19 2202
+5,19 2202
+5,31 2202
+5,31 2203
+5,31 2202
+969.3,13 2204
+970.5,20 2205
+5,20 2205
+5,32 2205
+5,32 2206
+5,32 2205
+971.3,13 2207
+972.5,21 2208
+5,21 2208
+5,33 2208
+5,33 2209
+5,33 2208
+973.3,13 2210
+3,13 2211
+975.9,22 2212
+2,22 2212
+976.5,23 2213
+5,23 2213
+977.3,13 2214
+978.5,21 2215
+5,21 2215
+979.3,13 2216
+980.5,22 2217
+5,22 2217
+981.3,13 2218
+982.5,23 2219
+5,23 2219
+983.3,13 2220
+3,13 2221
+987.8,9 2222
+1,9 2222
+1006.1,10 2223
+1007.1,7 2224
+1008.7,13 2225
+7,13 2225
+7,17 2225
+1009.5,8 2226
+5,8 2226
+1010.3,9 2227
+1011.2,9 2228
+2,9 2228
+1013.8,9 2229
+1,9 2229
+1019.1,8 2230
+1020.6,10 2231
+6,10 2231
+6,10 2231
+6,10 2231
+1021.25,37 2232
+25,37 2231
+1022.22,32 2233
+22,32 2231
+1023.23,34 2234
+23,34 2231
+1024.25,37 2235
+25,37 2231
+1026.2,30 2236
+8,29 2236
+2,30 2236
+2,30 2231
+1028.8,10 2237
+1,10 2237
+1034.1,11 2238
+1035.4,16 2239
+1036.2,12 2240
+1037.4,19 2241
+4,19 2241
+1038.2,12 2242
+1039.4,16 2243
+4,16 2243
+1040.2,12 2244
+1041.4,19 2245
+4,19 2245
+1042.2,12 2246
+1045.8,9 2247
+1,9 2247
+1051.1,11 2248
+1052.4,19 2249
+4,19 2249
+1053.2,12 2250
+1054.4,19 2251
+4,19 2251
+1055.2,12 2252
+1058.8,9 2253
+1,9 2253
+1068.1,10 2254
+1069.1,12 2255
+1070.8,11 2256
+1,11 2256
+1075.4,12 2257
+16,25 2257
+1076.10,11 2258
+13,14 2258
+2,15 2258
+1078.1,7 2259
+1079.5,11 2260
+17,22 2261
+13,22 2261
+1080.6,10 2262
+1081.5,13 2263
+17,26 2263
+30,39 2263
+1082.3,8 2264
+1079.24,27 2265
+24,27 2265
+1085.1,9 2266
+1086.4,12 2267
+16,24 2267
+1087.5,13 2268
+1088.3,10 2269
+1089.2,5 2270
+1092.1,8 2271
+1093.1,7 2272
+1094.11,16 2273
+7,16 2273
+1095.6,10 2274
+1096.2,11 2275
+1097.7,8 2276
+1099.7,14 2277
+3,19 2277
+3,19 2276
+1101.7,14 2278
+3,19 2278
+3,19 2276
+1103.3,14 2279
+3,14 2276
+1105.5,14 2280
+1106.3,8 2281
+1107.2,8 2282
+1108.6,14 2283
+2,18 2283
+1094.18,21 2284
+18,21 2284
+1111.5,7 2285
+1112.10,11 2286
+13,14 2286
+2,15 2286
+1113.4,7 2287
+1114.2,8 2288
+1115.9,10 2289
+12,17 2289
+12,13 2289
+12,17 2289
+1,18 2289
+1120.1,7 2290
+1121.5,11 2291
+17,22 2292
+13,22 2292
+1122.7,11 2293
+1123.5,17 2294
+21,33 2294
+1124.10,14 2295
+10,36 2295
+3,36 2295
+1121.24,27 2296
+24,27 2296
+1126.8,9 2297
+1,9 2297
+1132.1,10 2298
+1133.5,9 2299
+11,14 2300
+1134.2,13 2301
+1133.16,19 2302
+16,19 2302
+1135.8,11 2303
+1,11 2303
+1140.1,35 2304
+8,14 2304
+16,29 2304
+31,34 2304
+1,35 2304
+1,35 2304
+1141.1,11 2305
+7,10 2305
+1,11 2305
+1142.0,1 2306
+1146.4,10 2307
+1148.1,59 2308
+25,36 2308
+17,36 2308
+17,45 2308
+17,45 2309
+47,58 2308
+1,59 2308
+1,59 2308
+1149.4,13 2310
+1150.2,28 2311
+14,16 2311
+18,27 2311
+2,28 2311
+2,28 2311
+1151.1,5 2312
+1167.8,18 2313
+1,21 2313
+1168.8,16 2314
+20,28 2314
+8,28 2314
+1,28 2314
+8,28 2314
+1,28 2314
+1184.1,14 2315
+1185.6,13 2316
+15,21 2317
+1186.2,22 2318
+10,11 2318
+13,21 2318
+13,21 2318
+2,22 2318
+2,22 2318
+2,22 2319
+1185.23,27 2320
+23,27 2320
+1187.0,1 2321
+24
+aSys->Dir 1:26.1,39.2 64
+11
+0:name:28.2,6 s
+4:uid:29.2,5 s
+8:gid:30.2,5 s
+12:muid:31.2,6 s
+16:qid:32.2,5 @1
+
+32:mode:33.2,6 i
+36:atime:34.2,7 i
+40:mtime:35.2,7 i
+48:length:36.2,8 B
+56:dtype:37.2,7 i
+60:dev:38.2,5 i
+aSys->Qid 11.1,16.2 16
+3
+0:path:13.2,6 B
+8:vers:14.2,6 i
+12:qtype:15.2,7 i
+aDraw->Chans 2:70.1,82.2 4
+1
+0:desc:72.2,6 i
+pEvent 7:5.0,19.1 0
+2
+4:path:6.1,5 i
+8:from:7.1,5 i
+3
+Edata:9.2,7 16
+1
+12:data:10.3,7 Ab
+Eproto:11.2,8 32
+5
+12:cmd:12.3,6 i
+16:s:13.3,4 s
+20:a0:14.3,5 i
+24:a1:7,9 i
+28:a2:11,13 i
+Equit:15.2,7 12
+0
+aKeyb 9:11.0,23.1 16
+4
+0:m:12.1,2 R@5
+
+4:in:13.1,3 CR@3
+
+8:cmd:15.1,4 Cs
+12:spec:16.1,5 i
+aModule 0:53.0,56.1 8
+2
+0:path:54.1,5 i
+4:disabled:55.1,9 i
+aTk->Toplevel 3:5.1,12.2 32
+5
+0:display:7.2,9 R@7
+
+4:wreq:8.2,6 Cs
+8:image:9.2,7 R@8
+
+12:ctxt:10.2,6 R@12
+
+16:screenr:11.2,9 @9
+
+aDraw->Display 2:201.1,230.2 20
+5
+0:image:203.2,7 R@8
+
+4:white:204.2,7 R@8
+
+8:black:205.2,7 R@8
+
+12:opaque:206.2,8 R@8
+
+16:transparent:207.2,13 R@8
+
+aDraw->Image 142.1,198.2 56
+8
+0:r:146.2,3 @9
+
+16:clipr:147.2,7 @9
+
+32:depth:148.2,7 i
+36:chans:149.2,7 @2
+
+40:repl:150.2,6 i
+44:display:151.2,9 R@7
+
+48:screen:152.2,8 R@11
+
+52:iname:153.2,7 s
+aDraw->Rect 116.1,139.2 16
+2
+0:min:118.2,5 @10
+
+8:max:119.2,5 @10
+
+aDraw->Point 99.1,113.2 8
+2
+0:x:101.2,3 i
+4:y:102.2,3 i
+aDraw->Screen 249.1,263.2 16
+4
+0:id:251.2,4 i
+4:image:252.2,7 R@8
+
+8:fill:253.2,6 R@8
+
+12:display:254.2,9 R@7
+
+aDraw->Wmcontext 282.1,291.2 28
+7
+0:kbd:284.2,5 Ci
+4:ptr:285.2,5 CR@13
+
+8:ctl:286.2,5 Cs
+12:wctl:287.2,6 Cs
+16:images:288.2,8 CR@8
+
+20:connfd:289.2,8 R@14
+
+24:ctxt:290.2,6 R@15
+
+aDraw->Pointer 266.1,271.2 16
+3
+0:buttons:268.2,9 i
+4:xy:269.2,4 @10
+
+12:msec:270.2,6 i
+aSys->FD 1:45.1,48.2 4
+1
+0:fd:47.2,4 i
+aDraw->Context 2:274.1,279.2 12
+3
+0:display:276.2,9 R@7
+
+4:screen:277.2,8 R@11
+
+8:wm:278.2,4 Ct8.2
+0:t0:15,21 s
+4:t1:15,21 Ct8.2
+0:t0:32,38 s
+4:t1:32,38 R@12
+
+
+
+aModem 10:14.0,45.1 76
+19
+0:m:15.1,2 R@5
+
+4:in:16.1,3 CR@3
+
+8:connect:18.1,8 i
+12:state:19.1,6 i
+16:saved:20.1,6 s
+20:initstr:21.1,8 s
+24:dialstr:22.1,8 s
+28:lastdialstr:23.1,12 s
+32:spec:25.1,5 i
+36:fd:26.1,3 R@14
+
+40:cfd:27.1,4 R@14
+
+44:devpath:28.1,8 s
+48:avail:29.1,6 Ab
+52:rd:30.1,3 CAb
+56:pid:31.1,4 i
+60:seq:33.1,4 i
+64:waitsyn:34.1,8 i
+68:errforce:35.1,9 i
+72:addparity:36.1,10 i
+aMsg 508.0,512.1 12
+3
+0:text:509.1,5 s
+4:trans:510.1,6 s
+8:code:511.1,5 i
+aSocket 11:5.0,13.1 8
+2
+0:m:6.1,2 R@5
+
+4:in:7.1,3 CR@3
+
+aScreen 12:45.0,84.1 132
+25
+0:m:46.1,2 R@5
+
+4:ctxt:47.1,5 R@15
+
+8:in:48.1,3 CR@3
+
+12:image:50.1,6 R@8
+
+16:dispr40:51.1,8 @9
+
+32:dispr80:10,17 @9
+
+48:oldtmode:52.1,9 i
+52:rows:53.1,5 i
+56:cols:54.1,5 i
+60:cset:55.1,5 i
+64:pos:57.1,4 @10
+
+72:attr:58.1,5 i
+76:spec:59.1,5 i
+80:savepos:60.1,8 @10
+
+88:saveattr:61.1,9 i
+92:savech:62.1,7 i
+96:delimit:63.1,8 i
+100:cursor:64.1,7 i
+104:state:66.1,6 i
+108:a0:67.1,3 i
+112:a1:68.1,3 i
+116:fstate:70.1,7 i
+120:fsaved:71.1,7 Ab
+124:badp:72.1,5 i
+128:ignoredata:74.1,11 i
+aTerminal 0:90.0,113.1 56
+14
+0:in:91.1,3 CR@3
+
+4:out:92.1,4 AR@21
+
+8:mode:94.1,5 i
+12:state:95.1,6 i
+16:spec:96.1,5 i
+20:connect:97.1,8 i
+24:toplevel:98.1,9 R@6
+
+28:cmd:99.1,4 Cs
+32:proto:100.1,6 AR@22
+
+36:netaddr:101.1,8 s
+40:buttonsleft:102.1,12 i
+44:terminalid:103.1,11 Ab
+48:kbctl:104.1,6 Cs
+52:kbmode:105.1,7 s
+aBufChan 59.0,65.1 20
+5
+0:path:60.1,5 i
+4:ch:61.1,3 CR@3
+
+8:ev:62.1,3 R@3
+
+12:in:63.1,3 CR@3
+
+16:q:64.1,2 AR@3
+
+aPState 68.0,74.1 20
+5
+0:state:69.1,6 i
+4:arg:70.1,4 Ai
+8:nargs:71.1,6 i
+12:n:72.1,2 i
+16:skip:73.1,5 i
+aSys->Connection 1:52.1,57.2 12
+3
+0:dfd:54.2,5 R@14
+
+4:cfd:55.2,5 R@14
+
+8:dir:56.2,5 s
+92
+0:Event.str
+1
+32:ev:8:5.10,12 R@3
+
+3
+36:e:8.6,7 R@3
+
+40:s:7.1,2 s
+44:i:11.7,8 i
+s34:Keyb.init
+2
+32:k:9:25.10,11 R@4
+
+36:toplevel:28,36 R@6
+
+0
+n47:Keyb.reset
+1
+32:k:33.11,12 R@4
+
+0
+n53:ask
+2
+32:in:38.4,6 Cs
+36:out:24,27 Cs
+3
+40:number:46.1,7 s
+44:keys:40.1,5 s
+48:n:51.2,3 i
+n112:Keyb.run
+1
+32:k:90.9,10 R@4
+
+19
+36:askchan:93.1,8 Cs
+40:dontask:92.1,8 Cs
+44:askkeys:94.1,8 Cs
+48:e:99.8,9 R@3
+
+52:word:188.5,9 s
+56:key:130.6,9 i
+60:s:132.6,7 s
+64:seq:149.7,10 Ab
+68:cmd:122.2,5 s
+72:dialstr:215.2,9 s
+76:keys:138.5,9 Ab
+80:seq:176.7,10 Ab
+84:seq:181.6,9 Ab
+88:seq:205.6,9 Ab
+92:ev:98.2,4 R@3
+
+96:n:126.4,5 i
+100:args:7,11 Ls
+104:y:187.5,6 i
+56:x:186.5,6 i
+n472:Keyb.map
+1
+36:key:229.29,32 i
+2
+40:cmd:232.1,4 s
+44:seq:234.2,5 Ab
+Ab565:Keyb.quit
+1
+32:k:284.10,11 R@4
+
+0
+n567:canoncmd
+1
+32:s:289.9,10 s
+0
+s592:keyseq
+1
+32:skey:311.7,11 s
+2
+36:b2:313.1,3 i
+40:asterisk:314.1,9 i
+Ab645:minikey
+1
+32:key:343.8,11 i
+0
+s666:dump
+2
+32:a:10:49.5,6 Ab
+36:n:23,24 i
+2
+40:i:52.5,6 i
+44:s:51.1,2 s
+s685:Modem.init
+4
+32:m:57.11,12 R@16
+
+36:connect:30,37 i
+40:initstr:44,51 s
+44:dialstr:53,60 s
+1
+48:c:60.5,6 i
+n718:Modem.reset
+1
+32:m:81.12,13 R@16
+
+0
+n724:Modem.run
+1
+32:m:86.10,11 R@16
+
+7
+36:e:94.8,9 R@3
+
+40:b:192.2,3 Ab
+44:pidc:158.6,10 Ci
+48:dev:121.6,9 s
+52:ev:93.2,4 R@3
+
+56:ok:136.7,9 i
+60:cx:11,13 @23
+
+n1081:Modem.quit
+0
+0
+n1082:Modem.runstate
+2
+32:m:222.15,16 R@16
+
+36:data:34,38 Ab
+4
+40:ch:230.3,5 i
+44:i:229.6,7 i
+48:code:235.4,8 i
+52:str:10,13 s
+n1183:Modem.write
+2
+32:m:258.12,13 R@16
+
+36:data:31,35 Ab
+2
+40:i:267.6,7 i
+44:pa:266.2,4 Ab
+i1226:mktabs
+0
+4
+32:c:293.5,6 i
+36:crc:295.2,5 i
+40:i:296.6,7 i
+44:v:294.2,3 i
+n1247:nextblock
+3
+32:a:308.10,11 Ab
+36:i:28,29 i
+40:n:36,37 i
+0
+i1255:decode
+1
+32:a:318.7,8 Ab
+9
+36:crc:324.1,4 i
+40:i:327.5,6 i
+44:nc:329.2,4 i
+48:op:325.1,3 i
+52:b:356.1,2 Ab
+56:c:328.2,3 i
+60:dle:326.1,4 i
+64:oldcrc:323.1,7 i
+68:badpar:322.1,7 i
+Ab1350:Modem.reader
+2
+32:m:363.13,14 R@16
+
+36:pidc:32,36 Ci
+10
+40:syn:384.5,8 b
+44:n:371.9,10 i
+48:a:368.1,2 Ab
+52:b:396.5,6 Ab
+56:inbuf:369.1,6 i
+60:i:376.8,9 i
+64:b:375.4,5 Ab
+68:lim:385.5,8 i
+60:i:381.4,5 i
+68:lim:394.4,7 i
+n1477:replay
+1
+32:m:427.7,8 R@16
+
+12
+36:ch:449.3,5 i
+40:hs:441.1,3 s
+44:buf:429.1,4 Ab
+48:d:431.1,2 i
+52:da:432.1,3 Ab
+56:discard:439.1,8 i
+60:i:448.6,7 i
+64:nl:438.1,3 i
+68:start:442.1,6 i
+72:state:440.1,6 i
+76:n:445.2,3 i
+80:v:471.5,6 i
+n1575:kill
+1
+32:pid:488.5,8 i
+3
+36:cmd:493.2,5 Ab
+40:fd:491.1,3 R@14
+
+44:prog:490.1,5 s
+n1594:msend
+2
+32:m:524.6,7 R@16
+
+36:x:20,21 s
+1
+40:a:526.1,2 Ab
+i1602:apply
+2
+32:m:533.6,7 R@16
+
+36:s:20,21 s
+3
+40:buf:535.1,4 s
+44:i:536.5,6 i
+48:c:537.2,3 i
+i1629:openmodem
+2
+32:m:550.10,11 R@16
+
+36:dev:24,27 s
+0
+i1645:hangup
+1
+32:m:564.7,8 R@16
+
+0
+n1678:nethangup
+1
+32:m:578.10,11 R@16
+
+0
+n1687:seenreply
+1
+32:s:589.10,11 s
+1
+36:k:591.5,6 i
+t8.2
+0:t0:589.23,26 i
+4:t1:23,26 s
+1713:dialout
+1
+32:m:611.8,9 R@16
+
+0
+n1728:Socket.init
+1
+32:c:11:15.12,13 R@18
+
+0
+n1733:Socket.reset
+1
+32:c:21.13,14 R@18
+
+0
+n1739:Socket.run
+1
+32:c:26.11,12 R@18
+
+2
+36:e:31.7,8 R@3
+
+40:ev:30.2,4 R@3
+
+n1757:Socket.quit
+1
+32:c:46.12,13 R@18
+
+0
+n1759:Screen.init
+4
+32:s:12:86.12,13 R@19
+
+36:ctxt:32,36 R@15
+
+40:r40:57,60 @9
+
+56:r80:62,65 @9
+
+0
+n1790:Screen.reset
+1
+32:s:107.13,14 R@19
+
+0
+n1799:Screen.run
+1
+32:s:114.11,12 R@19
+
+5
+36:e:119.7,8 R@3
+
+40:da:166.3,5 AAb
+44:ev:118.1,3 R@3
+
+48:oldspec:165.3,10 i
+60:oldpos:164.3,9 @10
+
+n1910:indicators
+1
+32:s:189.11,12 R@19
+
+3
+36:attr:194.1,5 i
+40:ch:192.1,3 s
+44:col:191.1,4 i
+n1933:Screen.setmode
+2
+32:s:212.15,16 R@19
+
+36:tmode:35,40 i
+4
+40:delims:215.1,7 i
+44:ulheight:216.1,9 i
+48:fontpath:251.2,10 s
+56:dispr:214.1,6 @9
+
+n2025:Screen.quit
+0
+0
+n2028:Screen.runstate
+2
+32:s:265.16,17 R@19
+
+36:data:36,40 Ab
+0
+n2051:vc0
+2
+32:s:279.4,5 R@19
+
+36:ch:19,21 i
+1
+40:cols:347.2,6 i
+n2183:vc1
+2
+32:s:384.4,5 R@19
+
+36:ch:19,21 i
+2
+40:bg:402.7,9 i
+44:fg:1,3 i
+n2296:vss2
+2
+32:s:494.5,6 R@19
+
+36:ch:20,22 i
+0
+n2357:vcsi
+2
+32:s:534.5,6 R@19
+
+36:ch:20,22 i
+2
+40:r:573.8,9 i
+40:r:577.8,9 i
+n2494:vstate
+2
+32:s:635.7,8 R@19
+
+36:data:22,26 Ab
+6
+40:ch:639.2,4 i
+44:i:637.1,2 i
+48:str:650.4,7 s
+52:cs:642.3,5 s
+56:n:649.4,5 i
+60:match:834.3,8 AAi
+Ab2921:mstate
+2
+32:s:895.7,8 R@19
+
+36:data:22,26 Ab
+5
+40:ch:900.2,4 i
+44:i:897.1,2 i
+48:str:911.4,7 s
+52:cs:903.3,5 s
+56:n:910.4,5 i
+Ab3127:mc0
+2
+32:s:1011.4,5 R@19
+
+36:ch:19,21 i
+0
+n3186:mc1
+2
+32:s:1063.4,5 R@19
+
+36:ch:19,21 i
+0
+n3241:mcsi
+2
+32:s:1107.5,6 R@19
+
+36:ch:20,22 i
+2
+40:r:1154.8,9 i
+40:r:1158.8,9 i
+n3433:Screen.put
+2
+32:s:1258.11,12 R@19
+
+36:str:31,34 s
+4
+40:n:1261.2,3 i
+44:i:1269.7,8 i
+48:cs:1278.5,7 s
+52:l:1260.8,9 i
+n3541:incpos
+2
+32:s:1313.7,8 R@19
+
+36:n:22,23 i
+0
+n3587:rowclear
+3
+32:r:1343.9,10 i
+36:first:12,17 i
+40:last:19,23 i
+0
+n3603:clear
+1
+32:s:1350.6,7 R@19
+
+1
+36:r:1352.5,6 i
+n3613:refresh
+0
+0
+n3616:scroll
+2
+32:topline:1363.7,14 i
+36:nlines:16,22 i
+0
+n3623:filter
+2
+32:s:1371.7,8 R@19
+
+36:data:22,26 Ab
+0
+AAb3646:vfilter
+2
+32:s:1385.8,9 R@19
+
+36:data:23,27 Ab
+7
+40:ba:1387.1,3 AAb
+44:ch:1392.2,4 i
+48:i:1391.5,6 i
+52:d0:1390.1,3 i
+56:a:1427.4,5 Ab
+60:changed:1388.1,8 i
+64:valid:1432.4,9 i
+AAb3791:mfilter
+2
+32:s:1473.8,9 R@19
+
+36:data:23,27 Ab
+8
+40:ba:1475.1,3 AAb
+44:ch:1480.2,4 i
+48:i:1479.5,6 i
+52:d0:1478.1,3 i
+56:changed:1476.1,8 i
+60:a:1533.4,5 Ab
+64:valid:1538.4,9 i
+68:n:1555.5,6 i
+AAb3991:dappend
+2
+32:ba:1590.8,10 AAb
+36:b:36,37 Ab
+2
+40:na:1593.1,3 AAb
+44:l:1592.1,2 i
+AAb4003:Screen.msg
+2
+32:s:1600.11,12 R@19
+
+36:str:31,34 s
+2
+40:n:1603.1,2 i
+44:blank:1602.1,6 s
+n4041:init
+2
+32:ctxt:0:132.5,9 R@15
+
+36:argv:30,34 Ls
+11
+40:words:177.7,12 Ls
+44:arg:145.1,4 mArg
+6:1.0,14.1 0
+
+48:dialstr:0:174.12,19 s
+52:netaddr:135.1,8 s
+56:c:148.8,9 i
+60:initstr:174.1,8 s
+64:i:152.7,8 i
+68:toplevel:212.1,9 R@6
+
+72:done:226.1,5 Ci
+76:s:134.1,2 s
+64:connect:173.1,8 i
+n4234:inittk
+2
+32:toplevel:416.7,15 R@6
+
+36:connect:35,42 i
+0
+n4249:Terminal.layout
+2
+32:t:425.16,17 R@20
+
+36:cols:38,42 i
+0
+n4280:Terminal.init
+3
+32:t:442.14,15 R@20
+
+36:toplevel:36,44 R@6
+
+40:connect:64,71 i
+0
+n4364:Terminal.reset
+1
+32:t:467.15,16 R@20
+
+0
+n4366:Terminal.run
+2
+32:t:472.13,14 R@20
+
+36:done:35,39 Ci
+8
+40:ev:485.2,4 R@3
+
+44:eva:501.3,6 AR@3
+
+48:e:527.6,7 s
+52:cmd:518.2,5 s
+56:e:495.8,9 R@3
+
+60:modcount:480.1,9 i
+64:n:519.4,5 i
+68:word:7,11 Ls
+n4635:kb
+1
+32:t:563.3,4 R@20
+
+2
+36:s:565.1,2 Cs
+40:e:567.1,2 s
+t8.2
+0:t0:563.22,28 s
+4:t1:22,28 Cs
+4648:Terminal.setkbmode
+2
+32:t:573.19,20 R@20
+
+36:tmode:41,46 i
+0
+n4660:dokb
+2
+32:t:588.5,6 R@20
+
+36:c:22,23 Cs
+7
+40:top:597.2,5 R@6
+
+44:m:7,8 Cs
+48:kbon:605.1,5 i
+52:kbctl:596.1,6 Cs
+56:keyboard:590.1,9 mKeyboard
+14:13.0,21.1 0
+
+60:mcmd:0:609.1,5 s
+64:kbcmd:617.1,6 s
+n4768:Terminal.quit
+0
+0
+n4769:send
+1
+32:e:651.5,6 R@3
+
+0
+n4787:post
+1
+32:e:659.5,6 R@3
+
+6
+36:b:664.2,3 R@21
+
+40:l:661.3,4 i
+44:i:1,2 i
+48:na:684.5,7 AR@3
+
+52:na:668.3,5 AR@3
+
+56:de:675.10,12 R@3
+
+n4852:protocol
+1
+32:ev:700.9,11 R@3
+
+8
+36:p:715.2,3 R@22
+
+40:e:712.6,7 R@3
+
+44:ea:709.1,3 AR@3
+
+48:i:716.6,7 i
+52:ch:717.3,5 i
+56:d0:714.2,4 i
+60:changed:710.1,8 i
+64:pe:759.5,7 R@3
+
+AR@3
+4987:eappend
+2
+32:ea:778.8,10 AR@3
+
+36:e:32,33 R@3
+
+2
+40:na:781.1,3 AR@3
+
+44:l:780.1,2 i
+AR@3
+4999:proto
+2
+32:from:790.6,10 i
+36:p:17,18 R@22
+
+8
+40:all:818.3,6 i
+44:reply:802.2,7 Ab
+48:reply:821.3,8 Ab
+52:reply:835.4,9 Ab
+76:reply:877.4,9 Ab
+80:reply:880.4,9 Ab
+40:x:842.3,4 i
+40:x:858.3,4 i
+R@3
+5418:PRO3
+5
+32:path:920.5,9 i
+36:from:11,15 i
+40:x:17,18 i
+44:y:20,21 i
+48:z:23,24 i
+1
+52:data:922.1,5 Ab
+n5439:PRO2
+4
+32:path:927.5,9 i
+36:from:11,15 i
+40:x:17,18 i
+44:y:20,21 i
+1
+48:data:929.1,5 Ab
+n5458:modcmd
+3
+32:cmd:941.7,10 i
+36:from:12,16 i
+40:targ:18,22 i
+0
+n5492:psb
+1
+32:code:960.4,8 i
+4
+36:b:963.1,2 i
+40:mask:965.2,6 i
+44:mod:975.2,5 R@5
+
+48:this:962.1,5 i
+i5543:parity
+1
+32:b:1004.7,8 i
+2
+36:p:1007.1,2 i
+40:bits:1006.1,5 i
+i5555:RxTx
+1
+32:code:1017.5,9 i
+1
+36:rv:1019.1,3 i
+i5574:osb
+0
+1
+32:b:1034.1,2 i
+i5588:kosb
+0
+1
+32:b:1051.1,2 i
+i5597:tostr
+1
+32:ch:1066.6,8 i
+1
+36:str:1068.1,4 s
+s5601:toint
+2
+32:s:1073.6,7 s
+36:base:17,21 i
+6
+40:c:1078.1,2 i
+44:i:1079.5,6 i
+48:n:1093.1,2 i
+52:v:1096.2,3 i
+56:neg:1085.1,4 i
+60:ok:1092.1,3 i
+t8.2
+0:t0:1073.30,33 i
+4:t1:30,33 s
+5656:tolower
+1
+32:s:1118.8,9 s
+3
+36:i:1121.5,6 i
+40:r:1120.1,2 s
+44:c:1122.2,3 i
+s5670:dup
+2
+32:ch:1130.4,6 i
+36:n:8,9 i
+2
+40:i:1133.5,6 i
+44:str:1132.1,4 s
+s5678:fatal
+1
+32:msg:1138.6,9 s
+0
+n5688:exits
+1
+32:s:1144.6,7 s
+1
+36:fd:1148.1,3 R@14
+
+n5704:ISC0
+1
+32:ch:1165.5,7 i
+1
+36:msb:1167.1,4 i
+i5712:tkcmds
+2
+32:t:1182.7,8 R@6
+
+36:cmds:28,32 As
+2
+40:ix:1185.6,8 i
+44:n:1184.1,2 i
+n30
+5144:C:126.0,1 R@18
+
+5196:K:124.0,1 R@4
+
+5204:M:125.0,1 R@16
+
+5220:Modname:44.0,7 As
+5224:Modules:129.0,7 AR@5
+
+5244:S:127.0,1 R@19
+
+5248:T:128.0,1 R@20
+
+5252:TERMINALID1:30.0,11 Ab
+5256:TERMINALID2:35.0,11 Ab
+5320:crctab:10:285.0,6 Ai
+5332:debug:0:26.0,5 Ai
+5340:disp:12:10.0,4 mMDisplay
+13:7.0,115.1 0
+
+5344:draw:0:11.1,5 mDraw
+2:1.0,298.1 0
+
+5420:msgs:10:514.0,4 A@17
+
+5448:partab:47.0,6 Ab
+5452:pgrp:0:25.0,4 i
+5460:playfd:10:424.0,6 R@14
+
+5508:stderr:0:27.0,6 R@14
+
+5512:sys:8.1,4 mSys
+1:4.0,160.1 0
+
+5528:tk:0:13.1,3 mTk
+3:1.0,25.1 0
+
+5532:tkclient:0:15.1,9 mTkclient
+4:1.0,26.1 0
+
+5536:tkinitbs:0:247.0,8 As
+5540:tkinitdirect:265.0,12 As
+5544:tkinitip:310.0,8 As
+5548:tkip40x25hide:383.0,13 As
+5552:tkip40x25lhs:369.0,12 As
+5556:tkip40x25rhs:376.0,12 As
+5560:tkip40x25show:346.0,13 As
+5564:tkip80x25hide:412.0,13 As
+5568:tkip80x25show:387.0,13 As
diff --git a/appl/wm/minitel/mkfile b/appl/wm/minitel/mkfile
new file mode 100644
index 00000000..16f816a6
--- /dev/null
+++ b/appl/wm/minitel/mkfile
@@ -0,0 +1,24 @@
+<../../../mkconfig
+
+TARG=\
+ mdisplay.dis\
+ miniterm.dis\
+ swkeyb.dis\
+
+MODULES=\
+ mdisplay.m\
+ miniterm.m\
+ event.m\
+ swkeyb.m\
+
+SYSMODULES=\
+ arg.m\
+ sys.m\
+ debug.m\
+ draw.m\
+ tk.m\
+ wmlib.m\
+
+DISBIN=$ROOT/dis/wm/minitel
+
+<$ROOT/mkfiles/mkdis
diff --git a/appl/wm/minitel/modem.b b/appl/wm/minitel/modem.b
new file mode 100644
index 00000000..b7a21c1d
--- /dev/null
+++ b/appl/wm/minitel/modem.b
@@ -0,0 +1,620 @@
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+#modem states for direct connection
+MSstart, MSdialing, MSconnected, MSdisconnecting,
+
+# special features
+Ecp # error correction
+ : con (1 << iota);
+
+Ecplen: con 17; # error correction block length: data[15], crc, validation (=0)
+
+Modem: adt {
+ m: ref Module; # common attributes
+ in: chan of ref Event;
+
+ connect: int; # None, Direct, Network
+ state: int; # modem dialing state
+ saved: string; # response, so far (direct dial)
+ initstr: string; # softmodem init string (direct dial)
+ dialstr: string; # softmodem dial string (direct dial)
+ lastdialstr: string;
+
+ spec: int; # special features
+ fd: ref Sys->FD; # modem data file, if != nil
+ cfd: ref Sys->FD; # modem ctl file, if != nil (direct dial only)
+ devpath: string; # path to the modem;
+ avail: array of byte; # already read
+ rd: chan of array of byte; # reader -> rd
+ pid: int; # reader pid if != 0
+
+ seq: int; # ECP block sequence number
+ waitsyn: int; # awaiting restart SYN SYN ... sequence
+ errforce: int;
+ addparity: int; # must add parity to outgoing data
+
+ init: fn(m: self ref Modem, connect: int, initstr, dialstr: string);
+ reset: fn(m: self ref Modem);
+ run: fn(m: self ref Modem);
+ quit: fn(m: self ref Modem);
+ runstate: fn(m: self ref Modem, data: array of byte);
+ write: fn(m: self ref Modem, data: array of byte):int; # to network
+ reader: fn(m: self ref Modem, pidc: chan of int);
+};
+
+partab: array of byte;
+
+dump(a: array of byte, n: int): string
+{
+ s := sys->sprint("[%d]", n);
+ for(i := 0; i < n; i++)
+ s += sys->sprint(" %.2x", int a[i]);
+ return s;
+}
+
+Modem.init(m: self ref Modem, connect: int, initstr, dialstr: string)
+{
+ partab = array[128] of byte;
+ for(c := 0; c < 128; c++)
+ if(parity(c))
+ partab[c] = byte (c | 16r80);
+ else
+ partab[c] = byte c;
+ m.in = chan of ref Event;
+ m.connect = connect;
+ m.state = MSstart;
+ m.initstr = initstr;
+ m.dialstr = dialstr;
+ m.pid = 0;
+ m.spec = 0;
+ m.seq = 0;
+ m.waitsyn = 0;
+ m.errforce = 0;
+ m.addparity = 0;
+ m.avail = array[0] of byte;
+ m.rd = chan of array of byte;
+ m.reset();
+}
+
+Modem.reset(m: self ref Modem)
+{
+ m.m = ref Module(Pscreen, 0);
+}
+
+Modem.run(m: self ref Modem)
+{
+ if(m.dialstr != nil)
+ send(ref Event.Eproto(Pmodem, Mmodem, Cconnect, "", 0,0,0));
+Runloop:
+ for(;;){
+ alt {
+ ev := <- m.in =>
+ pick e := ev {
+ Equit =>
+ break Runloop;
+ Edata =>
+ if(debug['m'] > 0)
+ fprint(stderr, "Modem <- %s\n", e.str());
+ m.write(e.data);
+ if(T.state == Local || T.spec & Echo) { # loopback
+ if(e.from == Mkeyb) {
+ send(ref Event.Eproto(Pscreen, Mkeyb, Ccursor, "", 0,0,0));
+ send(ref Event.Edata(Pscreen, Mkeyb, e.data));
+ }
+ }
+ Eproto =>
+ case e.cmd {
+ Creset =>
+ m.reset();
+ Cconnect =>
+ if(m.pid != 0)
+ break;
+ m.addparity = 1;
+ T.state = Connecting;
+ send(ref Event.Eproto(Pscreen, Mmodem, Cindicators, "",0,0,0));
+
+ case m.connect {
+ Direct =>
+ S.msg("Appel "+m.dialstr+" ...");
+ dev := "/dev/modem";
+ if(openmodem(m, dev) < 0) {
+ S.msg("Modem non prêt");
+ T.state = Local;
+ send(ref Event.Eproto(Pscreen, Mmodem, Cindicators, "",0,0,0));
+ break;
+ }
+ m.state = MSdialing;
+ m.saved = "";
+ dialout(m);
+ T.terminalid = TERMINALID2;
+ Network =>
+ S.msg("Connexion au serveur ...");
+ if(debug['m'] > 0 || debug['M'] > 0)
+ sys->print("dial(%s)\n", m.dialstr);
+ (ok, cx) := sys->dial(m.dialstr, "");
+ if (ok == -1){
+ S.msg("Echec de la connexion");
+ T.state = Local;
+ send(ref Event.Eproto(Pscreen, Mmodem, Cindicators, "",0,0,0));
+ if(debug['m'] > 0)
+ sys->print("can't dial %s: %r\n", m.dialstr);
+ break;
+ }
+ m.fd = sys->open(cx.dir + "/data", Sys->ORDWR);
+ m.cfd = cx.cfd;
+ if(len m.dialstr >= 3 && m.dialstr[0:3] == "tcp")
+ m.addparity = 0; # Internet gateway apparently doesn't require parity
+ if(m.fd != nil) {
+ S.msg(nil);
+ m.state = MSconnected;
+ T.state = Online;
+ send(ref Event.Eproto(Pscreen, Mmodem, Cindicators, "",0,0,0));
+ }
+ T.terminalid = TERMINALID1;
+ }
+ if(m.fd != nil) {
+ pidc := chan of int;
+ spawn m.reader(pidc);
+ m.pid = <-pidc;
+ }
+ Cdisconnect =>
+ if(m.pid != 0) {
+ S.msg("Déconnexion ...");
+ m.state = MSdisconnecting;
+ }
+ if(m.connect == Direct)
+ hangup(m);
+ else
+ nethangup(m);
+ Cplay => # for testing
+ case e.s {
+ "play" =>
+ replay(m);
+ }
+ Crequestecp =>
+ if(m.spec & Ecp){ # for testing: if already active, force an error
+ m.errforce = 1;
+ break;
+ }
+ m.write(array[] of {byte SEP, byte 16r4A});
+sys->print("sending request for ecp\n");
+ Cstartecp =>
+ m.spec |= Ecp;
+ m.seq = 0; # not in spec
+ m.waitsyn = 0; # not in spec
+ Cstopecp =>
+ m.spec &= ~Ecp;
+ * => break;
+ }
+ }
+ b := <- m.rd =>
+ if(debug['m'] > 0){
+ fprint(stderr, "Modem -> %s\n", dump(b,len b));
+ }
+ if(b == nil) {
+ m.pid = 0;
+ case m.state {
+ MSdialing =>
+ S.msg("Echec appel");
+ MSdisconnecting =>
+ S.msg(nil);
+ }
+ m.state = MSstart;
+ T.state = Local;
+ send(ref Event.Eproto(Pscreen, Mmodem, Cscreenon, "",0,0,0));
+ send(ref Event.Eproto(Pscreen, Mmodem, Cindicators, "",0,0,0));
+ break;
+ }
+ m.runstate(b);
+ }
+ }
+ if(m.pid != 0)
+ kill(m.pid);
+ send(nil);
+}
+
+Modem.quit(nil: self ref Modem)
+{
+}
+
+Modem.runstate(m: self ref Modem, data: array of byte)
+{
+ if(debug['m']>0)
+ sys->print("runstate %d %s\n", m.state, dump(data, len data));
+ case m.state {
+ MSstart => ;
+ MSdialing =>
+ for(i:=0; i<len data; i++) {
+ ch := int data[i];
+ if(ch != '\n' && ch != '\r') {
+ m.saved[len m.saved] = ch;
+ continue;
+ }
+ (code, str) := seenreply(m.saved);
+ case code {
+ Noise or Ok => ;
+ Success =>
+ S.msg(nil);
+ m.state = MSconnected;
+ T.state = Online;
+ send(ref Event.Eproto(Pscreen, Mmodem, Cindicators, "",0,0,0));
+ Failure =>
+ hangup(m);
+ S.msg(str);
+ m.state = MSstart;
+ T.state = Local;
+ send(ref Event.Eproto(Pscreen, Mmodem, Cindicators, "",0,0,0));
+ }
+ m.saved = "";
+ }
+ MSconnected =>
+ send(ref Event.Edata(m.m.path, Mmodem, data));
+ MSdisconnecting => ;
+ }
+}
+
+Modem.write(m: self ref Modem, data: array of byte): int
+{
+ if(m.fd == nil)
+ return -1;
+ if(len data == 0)
+ return 0;
+ if(m.addparity){
+ # unfortunately must copy data to add parity for direct modem connection
+ pa := array[len data] of byte;
+ for(i := 0; i<len data; i++)
+ pa[i] = partab[int data[i] & 16r7F];
+ data = pa;
+ }
+ if(debug['m']>0)
+ sys->print("WRITE %s\n", dump(data, len data));
+ return sys->write(m.fd, data, len data);
+}
+
+#
+# minitel error correction protocol
+#
+# SYN, SYN, block number start of retransmission
+# NUL ignored
+# DLE escapes {DLE, SYN, NACK, NUL}
+# NACK, block restart request
+#
+
+crctab: array of int;
+Crcpoly: con 16r9; # crc7 = x^7+x^3+1
+
+# precalculate the CRC7 remainder for all bytes
+
+mktabs()
+{
+ crctab = array[256] of int;
+ for(c := 0; c < 256; c++){
+ v := c;
+ crc := 0;
+ for(i := 0; i < 8; i++){
+ crc <<= 1; # align remainder's MSB with value's
+ if((v^crc) & 16r80)
+ crc ^= Crcpoly;
+ v <<= 1;
+ }
+ crctab[c] = (crc<<1) & 16rFE; # pre-align the result to save <<1 later
+ }
+}
+
+# return the index of the first non-NUL character (the start of a block)
+
+nextblock(a: array of byte, i: int, n: int): int
+{
+ for(; i < n; i++)
+ if(a[i] != byte NUL)
+ break;
+ return i;
+}
+
+# return the data in the ecp block in a[0:Ecplen] (return nil for bad format)
+
+decode(a: array of byte): array of byte
+{
+ if(debug['M']>0)
+ sys->print("DECODE: %s\n", dump(a, Ecplen));
+ badpar := 0;
+ oldcrc := int a[Ecplen-2];
+ crc := 0;
+ op := 0;
+ dle := 0;
+ for(i:=0; i<Ecplen-2; i++){ # first byte is high-order byte of polynomial (MSB first)
+ c := int a[i];
+ nc := c & 16r7F; # strip parity
+ if((c^int partab[nc]) & 16r80)
+ badpar++;
+ crc = crctab[crc ^ c];
+ # collapse DLE sequences
+ if(!dle){
+ if(nc == DLE && i+1 < Ecplen-2){
+ dle = 1;
+ continue;
+ }
+ if(nc == NUL)
+ continue; # strip non-escaped NULs
+ }
+ dle = 0;
+ a[op++] = byte nc;
+ }
+ if(badpar){
+ if(debug['E'] > 0)
+ sys->print("bad parity\n");
+ return nil;
+ }
+ crc = (crc>>1)&16r7F;
+ if(int partab[crc] != oldcrc){
+ if(debug['E'] > 0)
+ sys->print("bad crc: in %ux got %ux\n", oldcrc, int partab[crc]);
+ return nil;
+ }
+ b := array[op] of byte;
+ b[0:] = a[0:op];
+ if(debug['M'] > 0)
+ sys->print("OUT: %s [%x :: %x]\n", dump(b,op), crc, oldcrc);
+ return b;
+}
+
+Modem.reader(m: self ref Modem, pidc: chan of int)
+{
+ pidc <-= sys->pctl(0, nil);
+ if(crctab == nil)
+ mktabs();
+ a := array[Sys->ATOMICIO] of byte;
+ inbuf := 0;
+ while(m.fd != nil) {
+ while((n := read(m.fd, a[inbuf:], len a-inbuf)) > 0){
+ n += inbuf;
+ inbuf = 0;
+ if((m.spec & Ecp) == 0){
+ b := array[n] of byte;
+ for(i := 0; i<n; i++)
+ b[i] = byte (int a[i] & 16r7F); # strip parity
+ m.rd <-= b;
+ }else{
+ #sys->print("IN: %s\n", dump(a,n));
+ i := 0;
+ if(m.waitsyn){
+ sys->print("seeking SYN #%x\n", m.seq);
+ syn := byte (SYN | 16r80);
+ lim := n-3;
+ for(; i <= lim; i++)
+ if(a[i] == syn && a[i+1] == syn && (int a[i+2]&16r0F) == m.seq){
+ i += 3;
+ m.waitsyn = 0;
+ sys->print("found SYN #%x@%d\n", m.seq, i-3);
+ break;
+ }
+ }
+ lim := n-Ecplen;
+ for(; (i = nextblock(a, i, n)) <= lim; i += Ecplen){
+ b := decode(a[i:]);
+ if(m.errforce || b == nil){
+ m.errforce = 0;
+ b = array[2] of byte;
+ b[0] = byte NACK;
+ b[1] = byte (m.seq | 16r40);
+ sys->print("NACK #%x\n", m.seq);
+ m.write(b);
+ m.waitsyn = 1;
+ i = n; # discard rest of block
+ break;
+ }
+ m.seq = (m.seq+1) & 16rF; # mod 16 counter
+ m.rd <-= b;
+ }
+ if(i < n){
+ a[0:] = a[i:n];
+ inbuf = n-i;
+ }
+ }
+ }
+ if(n <= 0)
+ break;
+ }
+# m.fd = nil;
+ m.rd <-= nil;
+}
+
+playfd: ref Sys->FD;
+in_code, in_char: con iota;
+
+replay(m: ref Modem)
+{
+ buf := array[8192] of byte;
+ DMAX: con 10;
+ d := 0;
+ da := array[DMAX] of byte;
+ playfd = nil;
+ if(playfd == nil)
+ playfd = sys->open("minitel.txt", Sys->OREAD);
+ if(playfd == nil)
+ return;
+ nl := 1;
+ discard := 1;
+ state := in_code;
+ hs := "";
+ start := 0;
+mainloop:
+ for(;;) {
+ n := sys->read(playfd, buf, len buf);
+ if(n <= 0)
+ break;
+ for(i:=0; i<n; i++) {
+ ch := int buf[i];
+ if(nl)
+ case ch {
+ '>' => discard = 0;
+ '<' => discard = 1;
+ if(start)
+ sys->sleep(1000);
+ '{' => start = 1;
+ '}' => break mainloop;
+ }
+ if(ch == '\n')
+ nl = 1;
+ else
+ nl = 0;
+ if(discard)
+ continue;
+ if(!start)
+ continue;
+ if(state == in_code && ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z')))
+ hs[len hs] = ch;
+ else if(ch == '(') {
+ state = in_char;
+ (v, nil) := toint(hs, 16);
+ da[d++] = byte v;
+ if(d == DMAX) {
+ send(ref Event.Edata(m.m.path, Mmodem, da));
+ d = 0;
+ da = array[DMAX] of byte;
+ sys->sleep(50);
+ }
+ hs = "";
+ }else if(ch == ')')
+ state = in_code;
+ }
+ }
+ playfd = nil;
+
+}
+
+kill(pid : int)
+{
+ prog := "#p/" + string pid + "/ctl";
+ fd := sys->open(prog, Sys->OWRITE);
+ if (fd != nil) {
+ cmd := array of byte "kill";
+ sys->write(fd, cmd, len cmd);
+ }
+}
+
+
+# Modem stuff
+
+
+# modem return codes
+Ok, Success, Failure, Noise, Found: con iota;
+
+#
+# modem return messages
+#
+Msg: adt {
+ text: string;
+ trans: string;
+ code: int;
+};
+
+msgs: array of Msg = array [] of {
+ ("OK", "Ok", Ok),
+ ("NO CARRIER", "No carrier", Failure),
+ ("ERROR", "Bad modem command", Failure),
+ ("NO DIALTONE", "No dial tone", Failure),
+ ("BUSY", "Busy tone", Failure),
+ ("NO ANSWER", "No answer", Failure),
+ ("CONNECT", "", Success),
+};
+
+msend(m: ref Modem, x: string): int
+{
+ a := array of byte x;
+ return sys->write(m.fd, a, len a);
+}
+
+#
+# apply a string of commands to modem
+#
+apply(m: ref Modem, s: string): int
+{
+ buf := "";
+ for(i := 0; i < len s; i++){
+ c := s[i];
+ buf[len buf] = c; # assume no Unicode
+ if(c == '\r' || i == (len s -1)){
+ if(c != '\r')
+ buf[len buf] = '\r';
+ if(msend(m, buf) < 0)
+ return Failure;
+ buf = "";
+ }
+ }
+ return Ok;
+}
+
+openmodem(m: ref Modem, dev: string): int
+{
+ m.fd = sys->open(dev, Sys->ORDWR);
+ m.cfd = sys->open(dev+"ctl", Sys->ORDWR);
+ if(m.fd == nil || m.cfd == nil)
+ return -1;
+# hangup(m);
+# m.fd = sys->open(dev, Sys->ORDWR);
+# m.cfd = sys->open(dev+"ctl", Sys->ORDWR);
+# if(m.fd == nil || m.cfd == nil)
+# return -1;
+ return 0;
+}
+
+hangup(m: ref Modem)
+{
+ sys->sleep(1020);
+ msend(m, "+++");
+ sys->sleep(1020);
+ apply(m, "ATH0");
+ m.fd = nil;
+# sys->write(m.cfd, array of byte "f", 1);
+ sys->write(m.cfd, array of byte "h", 1);
+ m.cfd = nil;
+ # HACK: shannon softmodem "off-hook" bug fix
+ sys->open("/dev/modem", Sys->OWRITE);
+}
+
+nethangup(m: ref Modem)
+{
+ m.fd = nil;
+ sys->write(m.cfd, array of byte "hangup", 6);
+ m.cfd = nil;
+}
+
+
+#
+# check `s' for a known reply or `substr'
+#
+seenreply(s: string): (int, string)
+{
+ for(k := 0; k < len msgs; k++)
+ if(len s >= len msgs[k].text && s[0:len msgs[k].text] == msgs[k].text) {
+ return (msgs[k].code, msgs[k].trans);
+ }
+ return (Noise, s);
+}
+
+contains(s, t: string): int
+{
+ if(t == nil)
+ return 1;
+ if(s == nil)
+ return 0;
+ n := len t;
+ for(i := 0; i+n <= len s; i++)
+ if(s[i:i+n] == t)
+ return 1;
+ return 0;
+}
+
+dialout(m: ref Modem)
+{
+ if(m.initstr != nil)
+ apply(m, "AT"+m.initstr);
+ if(m.dialstr != nil) {
+ apply(m, "ATD"+m.dialstr);
+ m.lastdialstr = m.dialstr;
+ m.dialstr = nil;
+ }
+}
diff --git a/appl/wm/minitel/screen.b b/appl/wm/minitel/screen.b
new file mode 100644
index 00000000..4313d48d
--- /dev/null
+++ b/appl/wm/minitel/screen.b
@@ -0,0 +1,1610 @@
+#
+# Occasional references are made to sections and tables in the
+# France Telecom Minitel specification
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+include "mdisplay.m";
+
+disp: MDisplay;
+
+Rect, Point : import Draw;
+
+# display character sets
+videotex, semigraphic, french, american :import MDisplay;
+
+# display foreground colour attributes
+fgBlack, fgBlue, fgRed, fgMagenta,
+fgGreen, fgCyan, fgYellow, fgWhite :import MDisplay;
+
+# display background colour attributes
+bgBlack, bgBlue, bgRed, bgMagenta,
+bgGreen, bgCyan, bgYellow, bgWhite :import MDisplay;
+
+fgMask, bgMask : import MDisplay;
+
+# display formatting attributes
+attrB, attrW, attrH, attrP, attrF, attrC, attrL, attrD :import MDisplay;
+
+# Initial attributes - white on black
+ATTR0: con fgWhite|bgBlack&~(attrB|attrW|attrH|attrP|attrF|attrC|attrL|attrD);
+
+# special features
+Cursor, Scroll, Insert
+ : con (1 << iota);
+
+# Screen states
+Sstart, Sss2, Sesc, Srepeat, Saccent, Scsi0, Scsi1, Sus0, Sus1, Sskip,
+Siso2022, Siso6429, Stransparent, Sdrcs, Sconceal, Swaitfor
+ : con iota;
+
+# Filter states
+FSstart, FSesc, FSsep, FS6429, FS2022: con iota;
+
+Screen: adt {
+ m: ref Module; # common attributes
+ ctxt: ref Draw->Context;
+ in: chan of ref Event; # from the terminal
+
+ image: ref Draw->Image; # Mdisplay image
+ dispr40, dispr80: Rect; # 40 and 80 column display region
+ oldtmode: int; # old terminal mode
+ rows: int; # number of screen rows (25 for minitel)
+ cols: int; # number of screen cols (40 or 80)
+ cset: int; # current display charset
+
+ pos: Point; # current writing position (x:1, y:0)
+ attr: int; # display attribute set
+ spec: int; # special features
+ savepos: Point; # `pos' before moving to row zero
+ saveattr: int; # `attr' before moving to row zero
+ savech: int; # last character `Put'
+ delimit: int; # attr changed, make next space a delimiter
+ cursor: int; # update cursor soon
+
+ state: int; # recogniser state
+ a0: int; # recogniser arg 0
+ a1: int; # recogniser arg 1
+
+ fstate: int; # filter state
+ fsaved: array of byte; # filter `chars so far'
+ badp: int; # filter because of bad parameter
+
+ ignoredata: int; # ignore data from
+
+ init: fn(s: self ref Screen, ctxt: ref Draw->Context, r40, r80: Rect);
+ reset: fn(s: self ref Screen);
+ run: fn(s: self ref Screen);
+ quit: fn(s: self ref Screen);
+ setmode: fn(s: self ref Screen, tmode: int);
+ runstate: fn(s: self ref Screen, data: array of byte);
+ put: fn(s: self ref Screen, str: string);
+ msg: fn(s: self ref Screen, str: string);
+};
+
+Screen.init(s: self ref Screen, ctxt: ref Draw->Context, r40, r80: Rect)
+{
+ disp = load MDisplay MDisplay->PATH;
+ if(disp == nil)
+ fatal("can't load the display module: "+MDisplay->PATH);
+
+ s.m = ref Module(0, 0);
+ s.ctxt = ctxt;
+ s.dispr40 = r40;
+ s.dispr80 = r80;
+ s.oldtmode = -1;
+ s.in = chan of ref Event;
+ disp->Init(s.ctxt);
+ s.reset();
+ s.pos = Point(1, 1);
+ s.savech = 0;
+ s.cursor = 1;
+ s.ignoredata = 0;
+ s.fstate = FSstart;
+}
+
+Screen.reset(s: self ref Screen)
+{
+ s.setmode(T.mode);
+ indicators(s);
+ s.state = Sstart;
+}
+
+Screen.run(s: self ref Screen)
+{
+Runloop:
+ for(;;) alt {
+ ev := <- s.in =>
+ pick e := ev {
+ Equit =>
+ break Runloop;
+ Eproto =>
+ case e.cmd {
+ Creset =>
+ s.reset();
+ Cproto =>
+ case e.a0 {
+ START =>
+ case e.a1 {
+ SCROLLING =>
+ s.spec |= Scroll;
+ }
+ STOP =>
+ case e.a1 {
+ SCROLLING =>
+ s.spec &= ~Scroll;
+ }
+ MIXED =>
+ case e.a1 {
+ MIXED1 => # videotex -> mixed
+ if(T.mode != Mixed)
+ s.setmode(Mixed);
+ T.mode = Mixed;
+ MIXED2 => # mixed -> videotex
+ if(T.mode != Videotex)
+ s.setmode(Videotex);
+ T.mode = Videotex;
+ }
+ }
+ Ccursor => # update the cursor soon
+ s.cursor = 1;
+ Cindicators =>
+ indicators(s);
+ Cscreenoff =>
+ s.ignoredata = 1;
+ s.state = Sstart;
+ Cscreenon =>
+ s.ignoredata = 0;
+ * => break;
+ }
+ Edata =>
+ if(s.ignoredata)
+ continue;
+ oldpos := s.pos;
+ oldspec := s.spec;
+ da := filter(s, e.data);
+ while(len da > 0) {
+ s.runstate(da[0]);
+ da = da[1:];
+ }
+
+ if(s.pos.x != oldpos.x || s.pos.y != oldpos.y || (s.spec&Cursor)^(oldspec&Cursor))
+ s.cursor = 1;
+ if(s.cursor) {
+ if(s.spec & Cursor)
+ disp->Cursor(s.pos);
+ else
+ disp->Cursor(Point(-1,-1));
+ s.cursor = 0;
+ refresh();
+ } else if(e.from == Mkeyb)
+ refresh();
+ }
+ }
+ send(nil);
+}
+
+# row0 indicators (1.2.2)
+indicators(s: ref Screen)
+{
+ col: int;
+ ch: string;
+
+ attr := fgWhite|bgBlack;
+ case T.state {
+ Local =>
+ ch = "F";
+ Connecting =>
+ ch = "C";
+ attr |= attrF;
+ Online =>
+ ch = "C";
+ }
+ if(s.cols == 40) {
+ col = 39;
+ attr |= attrP;
+ } else
+ col = 77;
+ disp->Put(ch, Point(col, 0), videotex, attr, 0);
+}
+
+Screen.setmode(s: self ref Screen, tmode: int)
+{
+ dispr: Rect;
+ delims: int;
+ ulheight: int;
+ s.rows = 25;
+ s.spec = 0;
+ s.attr = s.saveattr = ATTR0;
+ s.delimit = 0;
+ s.pos = s.savepos = Point(-1, -1);
+ s.cursor = 1;
+ case tmode {
+ Videotex =>
+ s.cset = videotex;
+ s.cols = 40;
+ dispr = s.dispr40;
+ delims = 1;
+ ulheight = 2;
+ s.pos = Point(1,1);
+ s.spec &= ~Cursor;
+ Mixed =>
+# s.cset = french;
+ s.cset = videotex;
+ s.cols = 80;
+ dispr = s.dispr80;
+ delims = 0;
+ ulheight = 1;
+ s.spec |= Scroll;
+ s.pos = Point(1, 1);
+ Ascii =>
+ s.cset = french;
+ s.cols = 80;
+ dispr = s.dispr80;
+ delims = 0;
+ ulheight = 1;
+ };
+ if(tmode != s.oldtmode) {
+ (nil, s.image) = disp->Mode(((0,0),(0,0)), 0, 0, 0, 0, nil);
+ T.layout(s.cols);
+ fontpath := sprint("/fonts/minitel/f%dx%d", s.cols, s.rows);
+ (nil, s.image) = disp->Mode(dispr, s.cols, s.rows, ulheight, delims, fontpath);
+ T.setkbmode(tmode);
+ }
+ disp->Reveal(0); # concealing enabled (1.2.2)
+ disp->Cursor(Point(-1,-1));
+ s.oldtmode = tmode;
+}
+
+Screen.quit(nil: self ref Screen)
+{
+ disp->Quit();
+}
+
+Screen.runstate(s: self ref Screen, data: array of byte)
+{
+ while(len data > 0)
+ case T.mode {
+ Videotex =>
+ data = vstate(s, data);
+ Mixed =>
+ data = mstate(s, data);
+ Ascii =>
+ data = astate(s, data);
+ };
+}
+
+# process a byte from set C0
+vc0(s: ref Screen, ch: int)
+{
+ case ch {
+# SOH => # not in spec, wait for 16r04
+# s.a0 = 16r04;
+# s.state = Swaitfor;
+ SS2 =>
+ s.state = Sss2;
+ SYN =>
+ s.state = Sss2; # not in the spec, but acts like SS2
+ ESC =>
+ s.state = Sesc;
+ SO =>
+ s.cset = semigraphic;
+ s.attr &= ~(attrH|attrW|attrP); # 1.2.4.2
+ s.attr &= ~attrL; # 1.2.4.3
+ SI =>
+ s.cset = videotex;
+ s.attr &= ~attrL; # 1.2.4.3
+ s.attr &= ~(attrH|attrW|attrP); # some servers seem to assume this too
+ SEP or SS3 => # 1.2.7
+ s.state = Sskip;
+ BS =>
+ if(s.pos.x == 1) {
+ if(s.pos.y == 0)
+ break;
+ if(s.pos.y == 1)
+ s.pos.y = s.rows - 1;
+ else
+ s.pos.y -= 1;
+ s.pos.x = s.cols;
+ } else
+ s.pos.x -= 1;
+ HT =>
+ if(s.pos.x == s.cols) {
+ if(s.pos.y == 0)
+ break;
+ if(s.pos.y == s.rows - 1)
+ s.pos.y = 1;
+ else
+ s.pos.y += 1;
+ s.pos.x = 1;
+ } else
+ s.pos.x += 1;
+ LF =>
+ if(s.pos.y == s.rows - 1)
+ if(s.spec&Scroll)
+ scroll(1, 1);
+ else
+ s.pos.y = 1;
+ else if(s.pos.y == 0) { # restore attributes on leaving row zero
+ s.pos = s.savepos;
+ s.attr = s.saveattr;
+ } else
+ s.pos.y += 1;
+ VT =>
+ if(s.pos.y == 1)
+ if(s.spec&Scroll)
+ scroll(1, -1);
+ else
+ s.pos.y = s.rows - 1;
+ else if(s.pos.y == 0)
+ break;
+ else
+ s.pos.y -= 1;
+ CR =>
+ s.pos.x = 1;
+ CAN =>
+ cols := s.cols - s.pos.x + 1;
+ disp->Put(dup(' ', cols), Point(s.pos.x,s.pos.y), s.cset, s.attr, 0);
+ US =>
+ # expect US row, col
+ s.state = Sus0;
+ FF =>
+ s.cset = videotex;
+ s.attr = ATTR0;
+ s.pos = Point(1,1);
+ s.spec &= ~Cursor;
+ s.cursor = 1;
+ clear(s);
+ RS =>
+ s.cset = videotex;
+ s.attr = ATTR0;
+ s.pos = Point(1,1);
+ s.spec &= ~Cursor;
+ s.cursor = 1;
+ CON =>
+ s.spec |= Cursor;
+ s.cursor = 1;
+ COFF =>
+ s.spec &= ~Cursor;
+ s.cursor = 1;
+ REP =>
+ # repeat
+ s.state = Srepeat;
+ NUL =>
+ # padding character - ignore, but may appear anywhere
+ ;
+ BEL =>
+ # ah ...
+ ;
+ }
+}
+
+# process a byte from the set c1 - introduced by the ESC character
+vc1(s: ref Screen, ch: int)
+{
+ if(ISC0(ch)) {
+ s.state = Sstart;
+ vc0(s, ch);
+ return;
+ }
+ if(ch >= 16r20 && ch <= 16r2f) {
+ if(ch == 16r25)
+ s.state = Stransparent;
+ else if(ch == 16r23)
+ s.state = Sconceal;
+ else
+ s.state = Siso2022;
+ s.a0 = s.a1 = 0;
+ return;
+ }
+
+ fg := bg := -1;
+ case ch {
+ 16r35 or
+ 16r36 or
+ 16r37 =>
+ s.state = Sskip; # skip next char unless C0
+ return;
+
+ 16r5b => # CSI sequence
+ s.a0 = s.a1 = 0;
+ if(s.pos.y > 0) # 1.2.5.2
+ s.state = Scsi0;
+ return;
+
+ # foreground colour
+ 16r40 => fg = fgBlack;
+ 16r41 => fg = fgRed;
+ 16r42 => fg = fgGreen;
+ 16r43 => fg = fgYellow;
+ 16r44 => fg = fgBlue;
+ 16r45 => fg = fgMagenta;
+ 16r46 => fg = fgCyan;
+ 16r47 => fg = fgWhite;
+
+ # background colour
+ 16r50 => bg = bgBlack;
+ 16r51 => bg = bgRed;
+ 16r52 => bg = bgGreen;
+ 16r53 => bg = bgYellow;
+ 16r54 => bg = bgBlue;
+ 16r55 => bg = bgMagenta;
+ 16r56 => bg = bgCyan;
+ 16r57 => bg = bgWhite;
+
+ # flashing
+ 16r48 => s.attr |= attrF;
+ 16r49 => s.attr &= ~attrF;
+
+ # conceal (serial attribute)
+ 16r58 => s.attr |= attrC;
+ s.delimit = 1;
+ 16r5f => s.attr &= ~attrC;
+ s.delimit = 1;
+
+ # start lining (+separated graphics) (serial attribute)
+ 16r5a => s.attr |= attrL;
+ s.delimit = 1;
+ 16r59 => s.attr &= ~attrL;
+ s.delimit = 1;
+
+ # reverse polarity
+ 16r5d => s.attr |= attrP;
+ 16r5c => s.attr &= ~attrP;
+
+ # normal size
+ 16r4c =>
+ s.attr &= ~(attrW|attrH);
+
+ # double height
+ 16r4d =>
+ if(s.pos.y < 2)
+ break;
+ s.attr &= ~(attrW|attrH);
+ s.attr |= attrH;
+
+ # double width
+ 16r4e =>
+ if(s.pos.y < 1)
+ break;
+ s.attr &= ~(attrW|attrH);
+ s.attr |= attrW;
+
+ # double size
+ 16r4f =>
+ if(s.pos.y < 2)
+ break;
+ s.attr |= (attrW|attrH);
+ }
+ if(fg >= 0) {
+ s.attr &= ~fgMask;
+ s.attr |= fg;
+ }
+ if(bg >= 0) {
+ s.attr &= ~bgMask;
+ s.attr |= bg;
+ s.delimit = 1;
+ }
+ s.state = Sstart;
+}
+
+
+# process a SS2 character
+vss2(s: ref Screen, ch: int)
+{
+ if(ISC0(ch)) {
+ s.state = Sstart;
+ vc0(s, ch);
+ return;
+ }
+ case ch {
+ 16r41 or # grave # 5.1.2
+ 16r42 or # acute
+ 16r43 or # circumflex
+ 16r48 or # umlaut
+ 16r4b => # cedilla
+ s.a0 = ch;
+ s.state = Saccent;
+ return;
+ 16r23 => ch = '£'; # Figure 2.8
+ 16r24 => ch = '$';
+ 16r26 => ch = '#';
+ 16r27 => ch = '§';
+ 16r2c => ch = 16rc3; # '←';
+ 16r2d => ch = 16rc0; # '↑';
+ 16r2e => ch = 16rc4; # '→';
+ 16r2f => ch = 16rc5; # '↓';
+ 16r30 => ch = '°';
+ 16r31 => ch = '±';
+ 16r38 => ch = '÷';
+ 16r3c => ch = '¼';
+ 16r3d => ch = '½';
+ 16r3e => ch = '¾';
+ 16r7a => ch = 'œ';
+ 16r6a => ch = 'Œ';
+ 16r7b => ch = 'ß';
+ }
+ s.put(tostr(ch));
+ s.savech = ch;
+ s.state = Sstart;
+}
+
+# process CSI functions
+vcsi(s: ref Screen, ch: int)
+{
+ case s.state {
+ Scsi0 =>
+ case ch {
+ # move cursor up n rows, stop at top of screen
+ 'A' =>
+ s.pos.y -= s.a0;
+ if(s.pos.y < 1)
+ s.pos.y = 1;
+
+ # move cursor down n rows, stop at bottom of screen
+ 'B' =>
+ s.pos.y += s.a0;
+ if(s.pos.y >= s.rows)
+ s.pos.y = s.rows - 1;
+
+ # move cursor n columns right, stop at edge of screen
+ 'C' =>
+ s.pos.x += s.a0;
+ if(s.pos.x > s.cols)
+ s.pos.x = s.cols;
+
+ # move cursor n columns left, stop at edge of screen
+ 'D' =>
+ s.pos.x -= s.a0;
+ if(s.pos.x < 1)
+ s.pos.x = 1;
+
+ # direct cursor addressing
+ ';' =>
+ s.state = Scsi1;
+ return;
+
+ 'J' =>
+ case s.a0 {
+ # clears from the cursor to the end of the screen inclusive
+ 0 =>
+ rowclear(s.pos.y, s.pos.x, s.cols);
+ for(r:=s.pos.y+1; r<s.rows; r++)
+ rowclear(r, 1, s.cols);
+ # clears from the beginning of the screen to the cursor inclusive
+ 1 =>
+ for(r:=1; r<s.pos.y; r++)
+ rowclear(r, 1, s.cols);
+ rowclear(s.pos.y, 1, s.pos.x);
+ # clears the entire screen
+ 2 =>
+ clear(s);
+ }
+
+ 'K' =>
+ case s.a0 {
+ # clears from the cursor to the end of the row
+ 0 => rowclear(s.pos.y, s.pos.x, s.cols);
+
+ # clears from the start of the row to the cursor
+ 1 => rowclear(s.pos.y, 1, s.pos.x);
+
+ # clears the entire row in which the cursor is positioned
+ 2 => rowclear(s.pos.y, 1, s.cols);
+ }
+
+ # deletes n characters from cursor position
+ 'P' =>
+ rowclear(s.pos.y, s.pos.x, s.pos.x+s.a0-1);
+
+ # inserts n characters from cursor position
+ '@' =>
+ disp->Put(dup(' ', s.a0), Point(s.pos.x,s.pos.y), s.cset, s.attr, 1);
+
+ # starts cursor insert mode
+ 'h' =>
+ if(s.a0 == 4)
+ s.spec |= Insert;
+
+ 'l' => # ends cursor insert mode
+ if(s.a0 == 4)
+ s.spec &= ~Insert;
+
+ # deletes n rows from cursor row
+ 'M' =>
+ scroll(s.pos.y, s.a0);
+
+ # inserts n rows from cursor row
+ 'L' =>
+ scroll(s.pos.y, -1*s.a0);
+ }
+ s.state = Sstart;
+ Scsi1 =>
+ case ch {
+ # direct cursor addressing
+ 'H' =>
+ if(s.a0 > 0 && s.a0 < s.rows && s.a1 > 0 && s.a1 <= s.cols)
+ s.pos = Point(s.a1, s.a0);
+ }
+ s.state = Sstart;
+ }
+}
+
+# Screen state - Videotex mode
+vstate(s: ref Screen, data: array of byte): array of byte
+{
+ i: int;
+ for(i = 0; i < len data; i++) {
+ ch := int data[i];
+
+ if(debug['s']) {
+ cs:="";
+ if(s.cset==videotex) cs = "v"; else cs="s";
+ fprint(stderr, "vstate %d, %ux (%c) %.4ux %.4ux %s (%d,%d)\n", s.state, ch, ch, s.attr, s.spec, cs, s.pos.y, s.pos.x);
+ }
+ case s.state {
+ Sstart =>
+ if(ISG0(ch) || ch == SP) {
+ n := 0;
+ str := "";
+ while(i < len data) {
+ ch = int data[i];
+ if(ISG0(ch) || ch == SP)
+ str[n++] = int data[i++];
+ else {
+ i--;
+ break;
+ }
+ }
+ if(n > 0) {
+ if(debug['s'])
+ fprint(stderr, "vstate puts(%s)\n", str);
+ s.put(str);
+ s.savech = str[n-1];
+ }
+ } else if(ISC0(ch))
+ vc0(s, ch);
+ else if(ch == DEL) {
+ if(s.cset == semigraphic)
+ ch = 16r5f;
+ s.put(tostr(ch));
+ s.savech = ch;
+ }
+ Sss2 =>
+ if(ch == NUL) # 1.2.6.1
+ continue;
+ if(s.cset == semigraphic) # 1.2.3.4
+ continue;
+ vss2(s, ch);
+ Sesc =>
+ if(ch == NUL)
+ continue;
+ vc1(s, ch);
+ Srepeat =>
+ # byte from `columns' 4 to 7 gives repeat count on 6 bits
+ # of the last `Put' character
+ if(ch == NUL)
+ continue;
+ if(ISC0(ch)) {
+ s.state = Sstart;
+ vc0(s, ch);
+ break;
+ }
+ if(ch >= 16r40 && ch <= 16r7f)
+ s.put(dup(s.savech, (ch-16r40)));
+ s.state = Sstart;
+ Saccent =>
+ case s.a0 {
+ 16r41 => # grave
+ case ch {
+ 'a' => ch = 'à';
+ 'e' => ch = 'è';
+ 'u' => ch = 'ù';
+ }
+ 16r42 => # acute
+ case ch {
+ 'e' => ch = 'é';
+ }
+ 16r43 => # circumflex
+ case ch {
+ 'a' => ch = 'â';
+ 'e' => ch = 'ê';
+ 'i' => ch = 'î';
+ 'o' => ch = 'ô';
+ 'u' => ch = 'û';
+ }
+ 16r48 => # umlaut
+ case ch {
+ 'a' => ch = 'ä';
+ 'e' => ch = 'ë';
+ 'i' => ch = 'ï';
+ 'o' => ch = 'ö';
+ 'u' => ch = 'ü';
+ }
+ 16r4b => # cedilla
+ case ch {
+ 'c' => ch = 'ç';
+ }
+ }
+ s.put(tostr(ch));
+ s.savech = ch;
+ s.state = Sstart;
+ Scsi0 =>
+ if(ch >= 16r30 && ch <= 16r39) {
+ s.a0 *= 10;
+ s.a0 += (ch - 16r30);
+ } else if((ch >= 16r20 && ch <= 16r29) || (ch >= 16r3a && ch <= 16r3f)) { # 1.2.7
+ s.a0 = 0;
+ s.state = Siso6429;
+ } else
+ vcsi(s, ch);
+ Scsi1 =>
+ if(ch >= 16r30 && ch <= 16r39) {
+ s.a1 *= 10;
+ s.a1 += (ch - 16r30);
+ } else
+ vcsi(s, ch);
+ Sus0 =>
+ if(ch == 16r23) { # start DRCS definition
+ s.state = Sdrcs;
+ s.a0 = 0;
+ break;
+ }
+ if(ch >= 16r40 && ch < 16r80)
+ s.a0 = (ch - 16r40);
+ else if(ch >= 16r30 && ch <= 16r32)
+ s.a0 = (ch - 16r30);
+ else
+ s.a0 = -1;
+ s.state = Sus1;
+ Sus1 =>
+ if(ch >= 16r40 && ch < 16r80)
+ s.a1 = (ch - 16r40);
+ else if(ch >= 16r30 && ch <= 16r39) {
+ s.a1 = (ch - 16r30);
+ s.a0 = s.a0*10 + s.a1; # shouldn't be used any more
+ s.a1 = 1;
+ } else
+ s.a1 = -1;
+ # US row, col : this is how you get to row zero
+ if(s.a0 >= 0 && s.a0 < s.rows && s.a1 > 0 && s.a1 <= s.cols) {
+ if(s.a0 == 0 && s.pos.y > 0) {
+ s.savepos = s.pos;
+ s.saveattr = s.attr;
+ }
+ s.pos = Point(s.a1, s.a0);
+ s.delimit = 0; # 1.2.5.3, don't reset serial attributes
+ s.attr = ATTR0;
+ s.cset = videotex;
+ }
+ s.state = Sstart;
+ Sskip =>
+ # swallow the next character unless from C0
+ s.state = Sstart;
+ if(ISC0(ch))
+ vc0(s, ch);
+ Swaitfor =>
+ # ignore characters until the character in a0 inclusive
+ if(ch == s.a0)
+ s.state = Sstart;
+ Siso2022 =>
+ # 1.2.7
+ # swallow (upto) 3 characters from column 2,
+ # then 1 character from columns 3 to 7
+ if(ch == NUL)
+ continue;
+ if(ISC0(ch)) {
+ s.state = Sstart;
+ vc0(s, ch);
+ break;
+ }
+ s.a0++;
+ if(s.a0 <= 3) {
+ if(ch >= 16r20 && ch <= 16r2f)
+ break;
+ }
+ if (s.a0 <= 4 && ch >= 16r30 && ch <= 16r7f) {
+ s.state = Sstart;
+ break;
+ }
+ s.state = Sstart;
+ s.put(tostr(DEL));
+ Siso6429 =>
+ # 1.2.7
+ # swallow characters from column 3,
+ # or column 2, then 1 from column 4 to 7
+ if(ISC0(ch)) {
+ s.state = Sstart;
+ vc0(s, ch);
+ break;
+ }
+ if(ch >= 16r20 && ch <= 16r3f)
+ break;
+ if(ch >= 16r40 && ch <= 16r7f) {
+ s.state = Sstart;
+ break;
+ }
+ s.state = Sstart;
+ s.put(tostr(DEL));
+ Stransparent =>
+ # 1.2.7
+ # ignore all codes until ESC, 25, 40 or ESC, 2F, 3F
+ # progress in s.a0 and s.a1
+ match := array [] of {
+ array [] of { ESC, 16r25, 16r40 },
+ array [] of { ESC, 16r2f, 16r3f },
+ };
+ if(ch == ESC) {
+ s.a0 = s.a1 = 1;
+ break;
+ }
+ if(ch == match[0][s.a0])
+ s.a0++;
+ else
+ s.a0 = 0;
+ if(ch == match[1][s.a1])
+ s.a1++;
+ else
+ s.a1 = 0;
+ if(s.a0 == 3 || s.a1 == 3)
+ s.state = Sstart;
+ Sdrcs =>
+ if(s.a0 > 0) { # fixed number of bytes to skip in a0
+ s.a0--;
+ if(s.a0 == 0) {
+ s.state = Sstart;
+ break;
+ }
+ } else if(ch == US) # US XX YY - end of DRCS
+ s.state = Sus0;
+ else if(ch == 16r20) # US 23 20 20 20 4[23] 49
+ s.a0 = 4;
+ Sconceal =>
+ # 1.2.4.4
+ # ESC 23 20 58 - Conceal fields
+ # ESC 23 20 5F - Reveal fields
+ # ESC 23 21 XX - Filter
+ # progress in s.a0
+ case s.a0 {
+ 0 =>
+ if(ch == 16r20 || ch == 16r21)
+ s.a0 = ch;
+ 16r20 =>
+ case ch {
+ 16r58 =>
+ disp->Reveal(0);
+ disp->Refresh();
+ 16r5f =>
+ disp->Reveal(1);
+ disp->Refresh();
+ }
+ s.state = Sstart;
+ 16r21 =>
+ s.state = Sstart;
+ }
+ }
+ }
+ if (i < len data)
+ return data[i:];
+ else
+ return nil;
+}
+
+# Screen state - Mixed mode
+mstate(s: ref Screen, data: array of byte): array of byte
+{
+ i: int;
+Stateloop:
+ for(i = 0; i < len data; i++) {
+ ch := int data[i];
+
+ if(debug['s']) {
+ cs:="";
+ if(s.cset==videotex) cs = "v"; else cs="s";
+ fprint(stderr, "mstate %d, %ux (%c) %.4ux %.4ux %s (%d,%d)\n", s.state, ch, ch, s.attr, s.fstate, cs, s.pos.y, s.pos.x);
+ }
+ case s.state {
+ Sstart =>
+ if(ISG0(ch) || ch == SP) {
+ n := 0;
+ str := "";
+ while(i < len data) {
+ ch = int data[i];
+ if(ISG0(ch) || ch == SP)
+ str[n++] = int data[i++];
+ else {
+ i--;
+ break;
+ }
+ }
+ if(n > 0) {
+ if(debug['s'])
+ fprint(stderr, "mstate puts(%s)\n", str);
+ s.put(str);
+ s.savech = str[n-1];
+ }
+ } else if(ISC0(ch))
+ mc0(s, ch);
+ else if(ch == DEL) {
+ if(s.cset == semigraphic)
+ ch = 16r5f;
+ s.put(tostr(ch));
+ s.savech = ch;
+ }
+ Sesc =>
+ if(ch == NUL)
+ continue;
+ mc1(s, ch);
+ Scsi0 =>
+ if(ch >= 16r30 && ch <= 16r39) {
+ s.a0 *= 10;
+ s.a0 += (ch - 16r30);
+ } else if(ch == '?') {
+ s.a0 = '?';
+ } else
+ mcsi(s, ch);
+ if(T.mode != Mixed) # CSI ? { changes to Videotex mode
+ break Stateloop;
+ Scsi1 =>
+ if(ch >= 16r30 && ch <= 16r39) {
+ s.a1 *= 10;
+ s.a1 += (ch - 16r30);
+ } else
+ mcsi(s, ch);
+ Sus0 =>
+ if(ch >= 16r40 && ch < 16r80)
+ s.a0 = (ch - 16r40);
+ else if(ch >= 16r30 && ch <= 16r32)
+ s.a0 = (ch - 16r30);
+ else
+ s.a0 = -1;
+ s.state = Sus1;
+ Sus1 =>
+ if(ch >= 16r40 && ch < 16r80)
+ s.a1 = (ch - 16r40);
+ else if(ch >= 16r30 && ch <= 16r39) {
+ s.a1 = (ch - 16r30);
+ s.a0 = s.a0*10 + s.a1; # shouldn't be used any more
+ s.a1 = 1;
+ } else
+ s.a1 = -1;
+ # US row, col : this is how you get to row zero
+ if(s.a0 >= 0 && s.a0 < s.rows && s.a1 > 0 && s.a1 <= s.cols) {
+ if(s.a0 == 0 && s.pos.y > 0) {
+ s.savepos = s.pos;
+ s.saveattr = s.attr;
+ }
+ s.pos = Point(s.a1, s.a0);
+ s.delimit = 0; # 1.2.5.3, don't reset serial attributes
+ s.attr = ATTR0;
+ s.cset = videotex;
+ }
+ s.state = Sstart;
+ Siso6429 =>
+ # 1.2.7
+ # swallow characters from column 3,
+ # or column 2, then 1 from column 4 to 7
+ if(ISC0(ch)) {
+ s.state = Sstart;
+ mc0(s, ch);
+ break;
+ }
+ if(ch >= 16r20 && ch <= 16r3f)
+ break;
+ if(ch >= 16r40 && ch <= 16r7f) {
+ s.state = Sstart;
+ break;
+ }
+ s.state = Sstart;
+ s.put(tostr(DEL));
+ }
+ }
+ if (i < len data)
+ return data[i:];
+ else
+ return nil;
+ return nil;
+}
+
+# process a byte from set C0 - Mixed mode
+mc0(s: ref Screen, ch: int)
+{
+ case ch {
+ ESC =>
+ s.state = Sesc;
+ SO =>
+# s.cset = french;
+ ;
+ SI =>
+# s.cset = american;
+ ;
+ BS =>
+ if(s.pos.x > 1)
+ s.pos.x -= 1;
+ HT =>
+ s.pos.x += 8;
+ if(s.pos.x > s.cols)
+ s.pos.x = s.cols;
+ LF or VT or FF =>
+ if(s.pos.y == s.rows - 1)
+ if(s.spec&Scroll)
+ scroll(1, 1);
+ else
+ s.pos.y = 1;
+ else if(s.pos.y == 0) { # restore attributes on leaving row zero
+ if(ch == LF) { # 4.5
+ s.pos = s.savepos;
+ s.attr = s.saveattr;
+ }
+ } else
+ s.pos.y += 1;
+ CR =>
+ s.pos.x = 1;
+ CAN or SUB => # displays the error symbol - filled in rectangle
+ disp->Put(dup(16r5f, 1), Point(s.pos.x,s.pos.y), s.cset, s.attr, 0);
+ NUL =>
+ # padding character - ignore, but may appear anywhere
+ ;
+ BEL =>
+ # ah ...
+ ;
+ XON => # screen copying
+ ;
+ XOFF => # screen copying
+ ;
+ US =>
+ # expect US row, col
+ s.state = Sus0;
+ }
+}
+
+# process a byte from the set c1 - introduced by the ESC character - Mixed mode
+mc1(s: ref Screen, ch: int)
+{
+ if(ISC0(ch)) {
+ s.state = Sstart;
+ mc0(s, ch);
+ return;
+ }
+ case ch {
+ 16r5b => # CSI sequence
+ s.a0 = s.a1 = 0;
+ if(s.pos.y > 0) # 1.2.5.2
+ s.state = Scsi0;
+ return;
+
+ 16r44 or # IND like LF
+ 16r45 => # NEL like CR LF
+ if(ch == 16r45)
+ s.pos.x = 1;
+ if(s.pos.y == s.rows - 1)
+ if(s.spec&Scroll)
+ scroll(1, 1);
+ else
+ s.pos.y = 1;
+ else if(s.pos.y == 0) { # restore attributes on leaving row zero
+ s.pos = s.savepos;
+ s.attr = s.saveattr;
+ } else
+ s.pos.y += 1;
+ 16r4d => # RI
+ if(s.pos.y == 1)
+ if(s.spec&Scroll)
+ scroll(1, -1);
+ else
+ s.pos.y = s.rows - 1;
+ else if(s.pos.y == 0)
+ break;
+ else
+ s.pos.y -= 1;
+ }
+ s.state = Sstart;
+}
+
+
+# process CSI functions - Mixed mode
+mcsi(s: ref Screen, ch: int)
+{
+ case s.state {
+ Scsi0 =>
+ case ch {
+ # move cursor up n rows, stop at top of screen
+ 'A' =>
+ if(s.a0 == 0)
+ s.a0 = 1;
+ s.pos.y -= s.a0;
+ if(s.pos.y < 1)
+ s.pos.y = 1;
+
+ # move cursor down n rows, stop at bottom of screen
+ 'B' =>
+ if(s.a0 == 0)
+ s.a0 = 1;
+ s.pos.y += s.a0;
+ if(s.pos.y >= s.rows)
+ s.pos.y = s.rows - 1;
+
+ # move cursor n columns right, stop at edge of screen
+ 'C' =>
+ if(s.a0 == 0)
+ s.a0 = 1;
+ s.pos.x += s.a0;
+ if(s.pos.x > s.cols)
+ s.pos.x = s.cols;
+
+ # move cursor n columns left, stop at edge of screen
+ 'D' =>
+ if(s.a0 == 0)
+ s.a0 = 1;
+ s.pos.x -= s.a0;
+ if(s.pos.x < 1)
+ s.pos.x = 1;
+
+ # second parameter
+ ';' =>
+ s.state = Scsi1;
+ return;
+
+ 'J' =>
+ case s.a0 {
+ # clears from the cursor to the end of the screen inclusive
+ 0 =>
+ rowclear(s.pos.y, s.pos.x, s.cols);
+ for(r:=s.pos.y+1; r<s.rows; r++)
+ rowclear(r, 1, s.cols);
+ # clears from the beginning of the screen to the cursor inclusive
+ 1 =>
+ for(r:=1; r<s.pos.y; r++)
+ rowclear(r, 1, s.cols);
+ rowclear(s.pos.y, 1, s.pos.x);
+ # clears the entire screen
+ 2 =>
+ clear(s);
+ }
+
+ 'K' =>
+ case s.a0 {
+ # clears from the cursor to the end of the row
+ 0 => rowclear(s.pos.y, s.pos.x, s.cols);
+
+ # clears from the start of the row to the cursor
+ 1 => rowclear(s.pos.y, 1, s.pos.x);
+
+ # clears the entire row in which the cursor is positioned
+ 2 => rowclear(s.pos.y, 1, s.cols);
+ }
+
+ # inserts n characters from cursor position
+ '@' =>
+ disp->Put(dup(' ', s.a0), Point(s.pos.x,s.pos.y), s.cset, s.attr, 1);
+
+ # starts cursor insert mode
+ 'h' =>
+ if(s.a0 == 4)
+ s.spec |= Insert;
+
+ 'l' => # ends cursor insert mode
+ if(s.a0 == 4)
+ s.spec &= ~Insert;
+
+ # inserts n rows from cursor row
+ 'L' =>
+ scroll(s.pos.y, -1*s.a0);
+ s.pos.x = 1;
+
+ # deletes n rows from cursor row
+ 'M' =>
+ scroll(s.pos.y, s.a0);
+ s.pos.x = 1;
+
+ # deletes n characters from cursor position
+ 'P' =>
+ rowclear(s.pos.y, s.pos.x, s.pos.x+s.a0-1);
+
+ # select Videotex mode
+ '{' =>
+ if(s.a0 == '?') {
+ T.mode = Videotex;
+ s.setmode(T.mode);
+ }
+
+ # display attributes
+ 'm' =>
+ case s.a0 {
+ 0 => s.attr &= ~(attrL|attrF|attrP|attrB);
+ 1 => s.attr |= attrB;
+ 4 => s.attr |= attrL;
+ 5 => s.attr |= attrF;
+ 7 => s.attr |= attrP;
+ 22 => s.attr &= ~attrB;
+ 24 => s.attr &= ~attrL;
+ 25 => s.attr &= ~attrF;
+ 27 => s.attr &= ~attrP;
+ }
+ # direct cursor addressing
+ 'H' =>
+ if(s.a0 == 0)
+ s.a0 = 1;
+ if(s.a1 == 0)
+ s.a1 = 1;
+ if(s.a0 > 0 && s.a0 < s.rows && s.a1 > 0 && s.a1 <= s.cols)
+ s.pos = Point(s.a1, s.a0);
+ }
+ s.state = Sstart;
+ Scsi1 =>
+ case ch {
+ # direct cursor addressing
+ 'H' =>
+ if(s.a0 == 0)
+ s.a0 = 1;
+ if(s.a1 == 0)
+ s.a1 = 1;
+ if(s.a0 > 0 && s.a0 < s.rows && s.a1 > 0 && s.a1 <= s.cols)
+ s.pos = Point(s.a1, s.a0);
+ }
+ s.state = Sstart;
+ }
+}
+
+
+# Screen state - ASCII mode
+astate(nil: ref Screen, nil: array of byte): array of byte
+{
+ return nil;
+}
+
+# Put a string in the current attributes to the current writing position
+Screen.put(s: self ref Screen, str: string)
+{
+ while((l := len str) > 0) {
+ n := s.cols - s.pos.x + 1; # characters that will fit on this row
+ if(s.attr & attrW) {
+ if(n > 1) # fit normal width character in last column
+ n /= 2;
+ }
+ if(n > l)
+ n = l;
+ if(s.delimit) { # set delimiter bit on 1st space (if any)
+ for(i:=0; i<n; i++)
+ if(str[i] == ' ')
+ break;
+ if(i > 0) {
+ disp->Put(str[0:i], s.pos, s.cset, s.attr, s.spec&Insert);
+ incpos(s, i);
+ }
+ if(i < n) {
+ if(debug['s']) {
+ cs:="";
+ if(s.cset==videotex) cs = "v"; else cs="s";
+ fprint(stderr, "D %ux %s\n", s.attr|attrD, cs);
+ }
+ disp->Put(tostr(str[i]), s.pos, s.cset, s.attr|attrD, s.spec&Insert);
+ incpos(s, 1);
+ s.delimit = 0;
+ # clear serial attributes once used
+ # hang onto background attribute - needed for semigraphics
+ case s.cset {
+ videotex =>
+ s.attr &= ~(attrL|attrC);
+ semigraphic =>
+ s.attr &= ~(attrC);
+ }
+ }
+ if(i < n-1) {
+ disp->Put(str[i+1:n], s.pos, s.cset, s.attr, s.spec&Insert);
+ incpos(s, n-(i+1));
+ }
+ } else {
+ disp->Put(str[0:n], s.pos, s.cset, s.attr, s.spec&Insert);
+ incpos(s, n);
+ }
+ if(n < len str)
+ str = str[n:];
+ else
+ str = nil;
+ }
+# if(T.state == Local || T.spec&Echo)
+# refresh();
+}
+
+# increment the current writing position by `n' cells.
+# caller must ensure that `n' characters can fit
+incpos(s: ref Screen, n: int)
+{
+ if(s.attr & attrW)
+ s.pos.x += 2*n;
+ else
+ s.pos.x += n;
+ if(s.pos.x > s.cols)
+ if(s.pos.y == 0) # no wraparound from row zero
+ s.pos.x = s.cols;
+ else {
+ s.pos.x = 1;
+ if(s.pos.y == s.rows - 1 && s.spec&Scroll) {
+ if(s.attr & attrH) {
+ scroll(1, 2);
+ } else {
+ scroll(1, 1);
+ rowclear(s.pos.y, 1, s.cols);
+ }
+ } else {
+ if(s.attr & attrH)
+ s.pos.y += 2;
+ else
+ s.pos.y += 1;
+ if(s.pos.y >= s.rows)
+ s.pos.y -= (s.rows-1);
+ }
+ }
+}
+
+# clear row `r' from `first' to `last' column inclusive
+rowclear(r, first, last: int)
+{
+ # 16r5f is the semi-graphic black rectangle
+ disp->Put(dup(16r5f, last-first+1), Point(first,r), semigraphic, fgBlack, 0);
+# disp->Put(dup(' ', last-first+1), Point(first,r), S.cset, fgBlack, 0);
+}
+
+clear(s: ref Screen)
+{
+ for(r:=1; r<s.rows; r++)
+ rowclear(r, 1, s.cols);
+}
+
+# called to suggest a display update
+refresh()
+{
+ disp->Refresh();
+}
+
+# scroll the screen
+scroll(topline, nlines: int)
+{
+ disp->Scroll(topline, nlines);
+ disp->Refresh();
+}
+
+# filter the specified ISO6429 and ISO2022 codes from the screen input
+# TODO: filter some ISO2022 sequences
+filter(s: ref Screen, data: array of byte): array of array of byte
+{
+ case T.mode {
+ Videotex =>
+ return vfilter(s, data);
+ Mixed =>
+ return mfilter(s, data);
+ Ascii =>
+ return afilter(s, data);
+ }
+ return nil;
+}
+
+# filter the specified ISO6429 and ISO2022 codes from the screen input
+vfilter(s: ref Screen, data: array of byte): array of array of byte
+{
+ ba := array [0] of array of byte;
+ changed := 0;
+
+ d0 := 0;
+ for(i:=0; i<len data; i++) {
+ ch := int data[i];
+ case s.fstate {
+ FSstart =>
+ if(ch == ESC) {
+ s.fstate = FSesc;
+ changed = 1;
+ if(i > d0)
+ ba = dappend(ba, data[d0:i]);
+ d0 = i+1;
+ }
+ FSesc =>
+ d0 = i+1;
+ changed = 1;
+ if(ch == '[') {
+ s.fstate = FS6429;
+ s.fsaved = array [0] of byte;
+ s.badp = 0;
+# } else if(ch == 16r20) {
+# s.fstate = FS2022;
+# s.fsaved = array [0] of byte;
+ s.badp = 0;
+ } else if(ch == ESC) {
+ ba = dappend(ba, array [] of { byte ESC });
+ s.fstate = FSesc;
+ } else {
+ # false alarm - don't filter
+ ba = dappend(ba, array [] of { byte ESC, byte ch });
+ s.fstate = FSstart;
+ }
+ FS6429 => # filter out invalid CSI sequences
+ d0 = i+1;
+ changed = 1;
+ if(ch >= 16r20 && ch <= 16r3f) {
+ if((ch < 16r30 || ch > 16r39) && ch != ';')
+ s.badp = 1;
+ a := array [len s.fsaved + 1] of byte;
+ a[0:] = s.fsaved[0:];
+ a[len a - 1] = byte ch;
+ s.fsaved = a;
+ } else {
+ valid := 1;
+ case ch {
+ 'A' => ;
+ 'B' => ;
+ 'C' => ;
+ 'D' => ;
+ 'H' => ;
+ 'J' => ;
+ 'K' => ;
+ 'P' => ;
+ '@' => ;
+ 'h' => ;
+ 'l' => ;
+ 'M' => ;
+ 'L' => ;
+ * =>
+ valid = 0;
+ }
+ if(s.badp)
+ valid = 0;
+ if(debug['f'])
+ fprint(stderr, "vfilter %d: %s%c\n", valid, string s.fsaved, ch);
+ if(valid) { # false alarm - don't filter
+ ba = dappend(ba, array [] of { byte ESC, byte '[' });
+ ba = dappend(ba, s.fsaved);
+ ba = dappend(ba, array [] of { byte ch } );
+ }
+ s.fstate = FSstart;
+ }
+ FS2022 => ;
+ }
+ }
+ if(changed) {
+ if(i > d0)
+ ba = dappend(ba, data[d0:i]);
+ return ba;
+ }
+ return array [] of { data };
+}
+
+# filter the specified ISO6429 and ISO2022 codes from the screen input - Videotex
+mfilter(s: ref Screen, data: array of byte): array of array of byte
+{
+ ba := array [0] of array of byte;
+ changed := 0;
+
+ d0 := 0;
+ for(i:=0; i<len data; i++) {
+ ch := int data[i];
+ case s.fstate {
+ FSstart =>
+ case ch {
+ ESC =>
+ s.fstate = FSesc;
+ changed = 1;
+ if(i > d0)
+ ba = dappend(ba, data[d0:i]);
+ d0 = i+1;
+ SEP =>
+ s.fstate = FSsep;
+ changed = 1;
+ if(i > d0)
+ ba = dappend(ba, data[d0:i]);
+ d0 = i+1;
+ }
+ FSesc =>
+ d0 = i+1;
+ changed = 1;
+ if(ch == '[') {
+ s.fstate = FS6429;
+ s.fsaved = array [0] of byte;
+ s.badp = 0;
+ } else if(ch == ESC) {
+ ba = dappend(ba, array [] of { byte ESC });
+ s.fstate = FSesc;
+ } else {
+ # false alarm - don't filter
+ ba = dappend(ba, array [] of { byte ESC, byte ch });
+ s.fstate = FSstart;
+ }
+ FSsep =>
+ d0 = i+1;
+ changed = 1;
+ if(ch == ESC) {
+ ba = dappend(ba, array [] of { byte SEP });
+ s.fstate = FSesc;
+ } else if(ch == SEP) {
+ ba = dappend(ba, array [] of { byte SEP });
+ s.fstate = FSsep;
+ } else {
+ if(ch >= 16r00 && ch <= 16r1f)
+ ba = dappend(ba, array [] of { byte SEP , byte ch });
+ # consume the character
+ s.fstate = FSstart;
+ }
+ FS6429 => # filter out invalid CSI sequences
+ d0 = i+1;
+ changed = 1;
+ if(ch >= 16r20 && ch <= 16r3f) {
+ if((ch < 16r30 || ch > 16r39) && ch != ';' && ch != '?')
+ s.badp = 1;
+ a := array [len s.fsaved + 1] of byte;
+ a[0:] = s.fsaved[0:];
+ a[len a - 1] = byte ch;
+ s.fsaved = a;
+ } else {
+ valid := 1;
+ case ch {
+ 'm' => ;
+ 'A' => ;
+ 'B' => ;
+ 'C' => ;
+ 'D' => ;
+ 'H' => ;
+ 'J' => ;
+ 'K' => ;
+ '@' => ;
+ 'h' => ;
+ 'l' => ;
+ 'L' => ;
+ 'M' => ;
+ 'P' => ;
+ '{' => # allow CSI ? {
+ n := len s.fsaved;
+ if(n == 0 || s.fsaved[n-1] != byte '?')
+ s.badp = 1;
+ * =>
+ valid = 0;
+ }
+ if(s.badp) # only decimal params
+ valid = 0;
+ if(debug['f'])
+ fprint(stderr, "mfilter %d: %s%c\n", valid, string s.fsaved, ch);
+ if(valid) { # false alarm - don't filter
+ ba = dappend(ba, array [] of { byte ESC, byte '[' });
+ ba = dappend(ba, s.fsaved);
+ ba = dappend(ba, array [] of { byte ch } );
+ }
+ s.fstate = FSstart;
+ }
+ FS2022 => ;
+ }
+ }
+ if(changed) {
+ if(i > d0)
+ ba = dappend(ba, data[d0:i]);
+ return ba;
+ }
+ return array [] of { data };
+}
+
+# filter the specified ISO6429 and ISO2022 codes from the screen input - Videotex
+afilter(nil: ref Screen, data: array of byte): array of array of byte
+{
+ return array [] of { data };
+}
+
+# append to an array of array of byte
+dappend(ba: array of array of byte, b: array of byte): array of array of byte
+{
+ l := len ba;
+ na := array [l+1] of array of byte;
+ na[0:] = ba[0:];
+ na[l] = b;
+ return na;
+}
+
+# Put a diagnostic string to row 0
+Screen.msg(s: self ref Screen, str: string)
+{
+ blank := string array [s.cols -4] of {* => byte ' '};
+ n := len str;
+ if(n > s.cols - 4)
+ n = s.cols - 4;
+ disp->Put(blank, Point(1, 0), videotex, 0, 0);
+ if(str != nil)
+ disp->Put(str[0:n], Point(1, 0), videotex, fgWhite|attrB, 0);
+ disp->Refresh();
+} \ No newline at end of file
diff --git a/appl/wm/minitel/socket.b b/appl/wm/minitel/socket.b
new file mode 100644
index 00000000..b3ce7fcf
--- /dev/null
+++ b/appl/wm/minitel/socket.b
@@ -0,0 +1,49 @@
+#
+# Copyright © 1998 Vita Nuova Limited. All rights reserved.
+#
+
+Socket: adt {
+ m: ref Module; # common attributes
+ in: chan of ref Event;
+
+ init: fn(c: self ref Socket);
+ reset: fn(c: self ref Socket);
+ run: fn(c: self ref Socket);
+ quit: fn(c: self ref Socket);
+};
+
+Socket.init(c: self ref Socket)
+{
+ c.in = chan of ref Event;
+ c.reset();
+}
+
+Socket.reset(c: self ref Socket)
+{
+ c.m = ref Module(Pscreen, 0);
+}
+
+Socket.run(c: self ref Socket)
+{
+Runloop:
+ for(;;){
+ ev := <- c.in;
+ pick e := ev {
+ Equit =>
+ break Runloop;
+ Eproto =>
+ case e.cmd {
+ Creset =>
+ c.reset();
+ * => break;
+ }
+ Edata =>
+ }
+ }
+ send(nil);
+}
+
+Socket.quit(c: self ref Socket)
+{
+ if(c==nil);
+}
diff --git a/appl/wm/minitel/swkeyb.b b/appl/wm/minitel/swkeyb.b
new file mode 100644
index 00000000..50cb238f
--- /dev/null
+++ b/appl/wm/minitel/swkeyb.b
@@ -0,0 +1,370 @@
+###
+### This data and information is not to be used as the basis of manufacture,
+### or be reproduced or copied, or be distributed to another party, in whole
+### or in part, without the prior written consent of Lucent Technologies.
+###
+### (C) Copyright 1997 Lucent Technologies
+###
+### Written by N. W. Knauft
+###
+#
+# Revisions Copyright © 1998 Vita Nuova Limited.
+
+implement Keyboard;
+
+include "sys.m";
+ sys: Sys;
+
+include "draw.m";
+ draw: Draw;
+
+include "tk.m";
+ tk: Tk;
+
+include "tkclient.m";
+ tkclient: Tkclient;
+
+include "swkeyb.m";
+
+#Icon path
+ICPATH: con "keybd/";
+
+#Font
+FONT: con "/fonts/lucidasans/latin1.7.font";
+SPECFONT: con "/fonts/lucidasans/latin1.6.font";
+
+# Dimension constants
+KBDWIDTH: con 360;
+KBDHEIGHT: con 120;
+KEYSIZE: con "19";
+KEYSPACE: con 5;
+KEYBORDER: con 1;
+KEYGAP: con KEYSPACE - (2 * KEYBORDER);
+ENDGAP: con 2 - KEYBORDER;
+
+# Row size constants (cumulative)
+ROW1: con 14;
+ROW2: con 28;
+ROW3: con 41;
+ROW4: con 53;
+NKEYS: con 63;
+
+#Special key number constants
+DELKEY: con 13;
+TABKEY: con 14;
+BACKSLASHKEY: con 27;
+CAPSLOCKKEY: con 28 ;
+RETURNKEY: con 40;
+LSHIFTKEY: con 41;
+RSHIFTKEY: con 52;
+ESCKEY: con 53;
+CTRLKEY: con 54;
+METAKEY: con 55;
+ALTKEY: con 56;
+SPACEKEY: con 57;
+ENTERKEY: con 58;
+LEFTKEY: con 59;
+RIGHTKEY: con 60;
+DOWNKEY: con 61;
+UPKEY: con 62;
+
+#Special key code constants
+CAPSLOCK: con -1 ;
+SHIFT: con -2;
+CTRL: con -3;
+ALT: con -4;
+META: con -5;
+MAGIC_PREFIX: con 256;
+ARROW_OFFSET: con 57344;
+ARROW_PREFIX: con ARROW_OFFSET + 18;
+
+#Special key width constants
+DELSIZE: con 44;
+TABSIZE: con 32;
+BACKSLASHSIZE: con 31;
+CAPSLOCKSIZE: con 44;
+RETURNSIZE: con 43;
+LSHIFTSIZE: con 56;
+RSHIFTSIZE: con 55;
+ESCSIZE: con 21;
+CTRLSIZE: con 23;
+METASIZE: con 38;
+ALTSIZE: con 22;
+SPACESIZE: con 100;
+ENTERSIZE: con 31;
+
+#Arrow key code constants
+UP: con ARROW_PREFIX;
+DOWN: con ARROW_PREFIX + 1;
+LEFT: con ARROW_PREFIX + 2;
+RIGHT: con ARROW_PREFIX + 3;
+
+direction:= array[] of {"up", "down", "left", "right"};
+row_dimensions:= array[] of {0, ROW1, ROW2, ROW3, ROW4, NKEYS};
+
+special_keys:= array[] of {
+ (DELKEY, DELSIZE),
+ (TABKEY, TABSIZE),
+ (BACKSLASHKEY, BACKSLASHSIZE),
+ (CAPSLOCKKEY, CAPSLOCKSIZE),
+ (RETURNKEY, RETURNSIZE),
+ (LSHIFTKEY, LSHIFTSIZE),
+ (RSHIFTKEY, RSHIFTSIZE),
+ (ESCKEY, ESCSIZE),
+ (CTRLKEY, CTRLSIZE),
+ (METAKEY, METASIZE),
+ (ALTKEY, ALTSIZE),
+ (SPACEKEY, SPACESIZE),
+ (ENTERKEY, ENTERSIZE),
+};
+
+keys:= array[] of {
+ # Unshifted
+ "`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "Delete",
+ "Tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\\\",
+ "CapLoc", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "\'", "Return",
+ "Shift", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Shift",
+ "Esc", "Ctrl", " ", "Alt", " ", "Enter", "<-", "->", "v", "^",
+ # Shifted
+ "~", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", "Delete",
+ "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\\{", "\\}", "|",
+ "CapLoc", "A", "S", "D", "F", "G", "H", "J", "K", "L", ":", "\"", "Return",
+ "Shift", "Z", "X", "C", "V", "B", "N", "M", "<", ">", "?", "Shift",
+ "Esc", "Ctrl", " ", "Alt", " ", "Enter", "<-", "->", "v", "^",
+};
+
+keyvals:= array[] of {
+ # Unshifted
+ '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
+ '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\\',
+ CAPSLOCK, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '\n',
+ SHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SHIFT,
+ 27, CTRL, META, ALT, 32, '\n', LEFT, RIGHT, DOWN, UP,
+ # Shifted
+ '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b',
+ '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '|',
+ CAPSLOCK, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '\n',
+ SHIFT, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', SHIFT,
+ 27, CTRL, META, ALT, 32, '\n', LEFT, RIGHT, DOWN, UP,
+};
+
+rowlayout := array[] of {
+ "frame .f1",
+ "frame .f2",
+ "frame .f3",
+ "frame .f4",
+ "frame .f5",
+ "frame .dummy0 -height " + string (ENDGAP),
+ "frame .dummy1 -height " + string KEYGAP,
+ "frame .dummy2 -height " + string KEYGAP,
+ "frame .dummy3 -height " + string KEYGAP,
+ "frame .dummy4 -height " + string KEYGAP,
+ "frame .dummy5 -height " + string (ENDGAP + 1),
+};
+
+# Move key flags
+move_key_enabled := 0;
+meta_active := 0;
+
+# Create keyboard widget, spawn keystroke handler
+initialize(t: ref Tk->Toplevel, ctxt : ref Draw->Context, dot: string): chan of string
+{
+ return chaninit(t, ctxt, dot, chan of string);
+}
+
+chaninit(t: ref Tk->Toplevel, ctxt : ref Draw->Context, dot: string, rc: chan of string): chan of string
+{
+ sys = load Sys Sys->PATH;
+ draw = load Draw Draw->PATH;
+ tk = load Tk Tk->PATH;
+ tkclient = load Tkclient Tkclient->PATH;
+
+ tkclient->init();
+
+ tk->cmd(t, "frame " + dot + " -bd 2 -relief raised -width " + string KBDWIDTH
+ + " -height " + string KBDHEIGHT);
+ tkcmds(t, rowlayout);
+
+ for(i := 0; i < NKEYS; i++) {
+ tk->cmd(t, "button .b" + string i + " -font " + FONT + " -width " + KEYSIZE
+ + " -height " + KEYSIZE + " -bd " + string KEYBORDER);
+
+ tk->cmd(t, ".b" + string i + " configure -text {" + keys[i] +
+ "} -command 'send keypress " + string keyvals[i]);
+ }
+
+ for(i = 0; i < len special_keys; i++) {
+ (keynum, keysize) := special_keys[i];
+ tk->cmd(t, ".b" + string keynum + " configure -font " + SPECFONT + " -width " + string keysize);
+ }
+
+ tk->cmd(t, "image create bitmap Capslock_on -file " + ICPATH + "capson.bit -maskfile " + ICPATH + "capson.bit");
+ tk->cmd(t, "image create bitmap Capslock_off -file " + ICPATH + "capsoff.bit -maskfile " + ICPATH + "capsoff.bit");
+ tk->cmd(t, "image create bitmap Left_arrow -file " + ICPATH + "larrow.bit -maskfile " + ICPATH + "larrow.bit");
+ tk->cmd(t, "image create bitmap Right_arrow -file " + ICPATH + "rarrow.bit -maskfile " + ICPATH + "rarrow.bit");
+ tk->cmd(t, "image create bitmap Down_arrow -file " + ICPATH + "darrow.bit -maskfile " + ICPATH + "darrow.bit");
+ tk->cmd(t, "image create bitmap Up_arrow -file " + ICPATH + "uarrow.bit -maskfile " + ICPATH + "uarrow.bit");
+ tk->cmd(t, "image create bitmap Move_on -file " + ICPATH + "moveon.bit -maskfile " + ICPATH + "moveon.bit");
+ tk->cmd(t, "image create bitmap Move_off -file " + ICPATH + "moveoff.bit -maskfile " + ICPATH + "moveoff.bit");
+ tk->cmd(t, "image create bitmap None -file " + ICPATH + "none.bit -maskfile " + ICPATH + "none.bit");
+ tk->cmd(t, ".b" + string CAPSLOCKKEY + " configure -image Capslock_off");
+ tk->cmd(t, ".b" + string LEFTKEY + " configure -image Left_arrow");
+ tk->cmd(t, ".b" + string RIGHTKEY + " configure -image Right_arrow");
+ tk->cmd(t, ".b" + string DOWNKEY + " configure -image Down_arrow");
+ tk->cmd(t, ".b" + string UPKEY + " configure -image Up_arrow");
+
+ for(j:=1; j < len row_dimensions; j++) {
+ rowstart := row_dimensions[j-1];
+ rowend := row_dimensions[j];
+ for(i=rowstart; i<rowend; i++) {
+ if (i == rowstart) {
+ tk->cmd(t, "frame .f" + string j + ".dummy -width " + string ENDGAP);
+ tk->cmd(t, "pack .f" + string j + ".dummy -side left");
+ }
+ tk->cmd(t, "pack .b" + string i + " -in .f" + string j + " -side left");
+ if (i == rowend-1)
+ tk->cmd(t, "frame .f" + string j + ".dummy" + string i + " -width " + string ENDGAP);
+ else
+ tk->cmd(t, "frame .f" + string j + ".dummy" + string i + " -width " + string KEYGAP);
+ tk->cmd(t, "pack .f" + string j + ".dummy" + string i + " -side left");
+ }
+ }
+
+ tk->cmd(t, "pack .dummy0 .f1 .dummy1 .f2 .dummy2 .f3 .dummy3 .f4 .dummy4 .f5 .dummy5 -in " + dot);
+ tk->cmd(t,"update");
+
+ key := chan of string;
+ spawn handle_keyclicks(t, ctxt, key, rc);
+ return key;
+}
+
+tkcmds(t: ref Tk->Toplevel, cmds: array of string)
+{
+ for(i := 0; i < len cmds; i++)
+ tk->cmd(t, cmds[i]);
+}
+
+# Process key clicks and hand keycodes off to Tk
+handle_keyclicks(t: ref Tk->Toplevel, ctxt : ref Draw->Context, sc, rc: chan of string)
+{
+ keypress := chan of string;
+ tk->namechan(t, keypress, "keypress");
+
+ minitel := 0;
+ caps_locked := 0;
+ shifted := 0;
+ ctrl_active := 0;
+ alt_active := 0;
+
+Work:
+ for(;;){
+ alt {
+ k := <-keypress =>
+ (n, cmdstr) := sys->tokenize(k, " \t\n");
+ keycode := int hd cmdstr;
+ case keycode {
+ CAPSLOCK =>
+ redisplay_keyboard(t, minitel, caps_locked ^= 1, caps_locked);
+ shifted = 0;
+ ctrl_active = 0;
+ alt_active = 0;
+ SHIFT =>
+ redisplay_keyboard(t, minitel, (shifted ^= 1) ^ caps_locked, caps_locked);
+ CTRL =>
+ ctrl_active ^= 1;
+ if (shifted) {
+ redisplay_keyboard(t, minitel, caps_locked, caps_locked);
+ shifted = 0;
+ }
+ alt_active = 0;
+ ALT =>
+ alt_active ^= 1;
+ if (shifted) {
+ redisplay_keyboard(t, minitel, caps_locked, caps_locked);
+ shifted = 0;
+ }
+ ctrl_active = 0;
+ META =>
+ if (move_key_enabled) {
+ if (meta_active ^= 1)
+ tk->cmd(t, ".b" + string METAKEY + " configure -image Move_on");
+ else
+ tk->cmd(t, ".b" + string METAKEY + " configure -image Move_off");
+ }
+ redisplay_keyboard(t, minitel, caps_locked, caps_locked);
+ shifted = 0;
+ ctrl_active = 0;
+ alt_active = 0;
+ * =>
+ if (ctrl_active) {
+ keycode &= 16r1F;
+ ctrl_active = 0;
+ } else if (alt_active) {
+ keycode += MAGIC_PREFIX;
+ alt_active = 0;
+ }
+ if (meta_active && UP <= keycode && keycode <= RIGHT) {
+ spawn send_move_msg(direction[keycode - ARROW_PREFIX], sc);
+ } else
+ tk->keyboard(t, keycode);
+ if (shifted) {
+ redisplay_keyboard(t, minitel, caps_locked, caps_locked);
+ shifted = 0;
+ }
+ }
+ s := <-rc =>
+ case s {
+ "kill" =>
+ break Work;
+ "minitel" =>
+ if (!minitel) {
+ minitel = 1;
+ redisplay_keyboard(t, minitel, shifted, caps_locked);
+ }
+ "standard" =>
+ if (minitel) {
+ minitel = 0;
+ redisplay_keyboard(t, minitel, shifted, caps_locked);
+ }
+ }
+ }
+ }
+}
+
+send_move_msg(dir: string, ch: chan of string)
+{
+ ch <-= dir;
+}
+
+
+# Redisplay keyboard to reflect current state (shifted or unshifted)
+redisplay_keyboard(t: ref Tk->Toplevel, minitel, shifted, caps_locked: int)
+{
+ base: int;
+
+ if (shifted)
+ base = NKEYS;
+ else
+ base = 0;
+
+ for(i:=0; i<NKEYS; i++) {
+ n := base + i;
+ val := keyvals[n];
+ key := keys[n];
+ if (minitel) {
+ if (val >= int 'A' && val <= int 'Z') {
+ key = keys[n-NKEYS];
+ } else if (val >= int 'a' && val <= int 'z') {
+ key = keys[n+NKEYS];
+ }
+ }
+
+ tk->cmd(t, ".b" + string i + " configure -text {" + key
+ + "} -command 'send keypress " + string val);
+ }
+ if (caps_locked)
+ tk->cmd(t, ".b" + string CAPSLOCKKEY + " configure -image Capslock_on");
+ else
+ tk->cmd(t, ".b" + string CAPSLOCKKEY + " configure -image Capslock_off");
+ tk->cmd(t, "update");
+}
diff --git a/appl/wm/minitel/swkeyb.dis b/appl/wm/minitel/swkeyb.dis
new file mode 100644
index 00000000..2928c713
--- /dev/null
+++ b/appl/wm/minitel/swkeyb.dis
Binary files differ
diff --git a/appl/wm/minitel/swkeyb.m b/appl/wm/minitel/swkeyb.m
new file mode 100644
index 00000000..52206801
--- /dev/null
+++ b/appl/wm/minitel/swkeyb.m
@@ -0,0 +1,21 @@
+###
+### This data and information is not to be used as the basis of manufacture,
+### or be reproduced or copied, or be distributed to another party, in whole
+### or in part, without the prior written consent of Lucent Technologies.
+###
+### (C) Copyright 1997 Lucent Technologies
+###
+### Written by N. W. Knauft
+###
+
+# Revisions Copyright © 1998 Vita Nuova Limited.
+
+Keyboard: module
+{
+ PATH: con "/dis/wm/minitel/swkeyb.dis";
+
+ initialize: fn(t: ref Tk->Toplevel, ctxt : ref Draw->Context,
+ dot: string): chan of string;
+ chaninit: fn(t: ref Tk->Toplevel, ctxt : ref Draw->Context,
+ dot: string, rc: chan of string): chan of string;
+};
diff --git a/appl/wm/minitel/swkeyb.sbl b/appl/wm/minitel/swkeyb.sbl
new file mode 100644
index 00000000..f79889f8
--- /dev/null
+++ b/appl/wm/minitel/swkeyb.sbl
@@ -0,0 +1,724 @@
+limbo .sbl 2.1
+Keyboard
+6
+swkeyb.b
+sys.m
+draw.m
+tk.m
+tkclient.m
+swkeyb.m
+504
+172.8,46 0
+17,18 0
+20,24 0
+26,29 0
+31,45 0
+8,46 0
+8,46 0
+1,46 0
+177.1,25 1
+178.1,28 2
+179.1,22 3
+180.1,40 4
+182.1,17 5
+1,17 5
+184.1,185.35 6
+184.9,10 6
+12,26 6
+12,60 6
+12,60 7
+1,185.35 6
+184.1,185.35 6
+184.1,185.35 8
+186.1,21 9
+8,9 9
+11,20 9
+1,21 9
+188.5,11 10
+13,22 11
+189.2,190.59 12
+189.10,11 12
+27,35 12
+13,35 12
+13,47 12
+13,47 13
+2,190.59 12
+189.2,190.59 12
+189.2,190.59 14
+192.2,193.54 15
+192.10,11 15
+20,28 15
+13,28 15
+13,51 15
+54,61 15
+13,61 15
+13,193.33 15
+43,53 15
+36,53 15
+192.13,193.53 15
+192.13,193.53 16
+192.13,193.53 17
+192.2,193.54 15
+192.2,193.54 15
+192.2,193.54 18
+188.24,27 19
+24,27 19
+196.5,10 20
+16,32 21
+12,32 21
+197.23,38 22
+23,38 22
+198.2,97 23
+10,11 23
+20,33 23
+13,33 23
+13,55 23
+82,96 23
+13,96 23
+13,96 24
+13,96 25
+2,97 23
+2,97 23
+2,97 26
+196.34,37 27
+34,37 27
+201.1,112 28
+9,10 28
+12,111 28
+1,112 28
+1,112 28
+1,112 29
+202.1,115 30
+9,10 30
+12,114 30
+1,115 30
+1,115 30
+1,115 31
+203.1,111 32
+9,10 32
+12,110 32
+1,111 32
+1,111 32
+1,111 33
+204.1,112 34
+9,10 34
+12,111 34
+1,112 34
+1,112 34
+1,112 35
+205.1,111 36
+9,10 36
+12,110 36
+1,111 36
+1,111 36
+1,111 37
+206.1,109 38
+9,10 38
+12,108 38
+1,109 38
+1,109 38
+1,109 39
+207.1,108 40
+9,10 40
+12,107 40
+1,108 40
+1,108 40
+1,108 41
+208.1,111 42
+9,10 42
+12,110 42
+1,111 42
+1,111 42
+1,111 43
+209.1,101 44
+9,10 44
+12,100 44
+1,101 44
+1,101 44
+1,101 45
+210.1,73 46
+9,10 46
+12,72 46
+1,73 46
+1,73 46
+1,73 47
+211.1,67 48
+9,10 48
+12,66 48
+1,67 48
+1,67 48
+1,67 49
+212.1,69 50
+9,10 50
+12,68 50
+1,69 50
+1,69 50
+1,69 51
+213.1,67 52
+9,10 52
+12,66 52
+1,67 52
+1,67 52
+1,67 53
+214.1,63 54
+9,10 54
+12,62 54
+1,63 54
+1,63 54
+1,63 55
+216.5,9 56
+15,33 57
+11,33 57
+217.29,32 58
+14,33 58
+2,33 58
+218.12,29 59
+2,29 59
+219.6,16 60
+18,26 61
+220.7,20 62
+221.4,72 63
+12,13 63
+28,36 63
+15,36 63
+15,55 63
+15,55 64
+4,72 63
+4,72 63
+4,72 65
+222.4,58 66
+12,13 66
+27,35 66
+15,35 66
+15,57 66
+15,57 67
+4,58 66
+4,58 66
+4,58 68
+224.3,74 69
+11,12 69
+26,34 69
+14,34 69
+14,46 69
+49,57 69
+14,57 69
+14,57 70
+14,73 69
+14,73 71
+3,74 69
+3,74 69
+3,74 72
+225.12,20 73
+7,20 73
+226.4,88 74
+12,13 74
+28,36 74
+15,36 74
+15,47 74
+50,58 74
+15,58 74
+15,58 75
+15,71 74
+15,71 76
+4,88 74
+4,88 74
+4,88 77
+4,88 78
+228.4,88 79
+12,13 79
+28,36 79
+15,36 79
+15,47 79
+50,58 79
+15,58 79
+15,58 80
+15,71 79
+15,71 81
+4,88 79
+4,88 79
+4,88 82
+229.3,73 83
+11,12 83
+26,34 83
+14,34 83
+14,45 83
+48,56 83
+14,56 83
+14,56 84
+14,72 83
+14,72 85
+3,73 83
+3,73 83
+3,73 86
+219.28,31 87
+28,31 87
+216.35,38 88
+35,38 88
+233.1,98 89
+9,10 89
+12,97 89
+1,98 89
+1,98 89
+1,98 90
+234.1,20 91
+9,10 91
+11,19 91
+1,20 91
+1,20 91
+1,20 92
+236.1,22 93
+237.1,41 94
+24,25 94
+27,31 94
+33,36 94
+38,40 94
+1,41 94
+238.8,11 95
+1,11 95
+243.5,11 96
+17,25 97
+13,25 97
+244.2,21 98
+10,11 98
+13,20 98
+13,20 98
+2,21 98
+2,21 98
+2,21 99
+243.27,30 100
+27,30 100
+245.0,1 101
+250.1,27 102
+251.1,38 103
+14,15 103
+17,25 103
+27,37 103
+1,38 103
+1,38 103
+1,38 104
+253.1,13 105
+254.1,17 106
+255.1,13 107
+256.1,17 108
+257.1,16 109
+262.9,17 110
+9,17 110
+315.9,11 110
+9,11 110
+261.2,8 110
+2,8 110
+2,8 110
+2,8 110
+263.18,43 111
+32,33 111
+35,42 111
+18,43 111
+18,43 111
+4,5 111
+7,13 111
+7,13 112
+264.18,27 113
+3,27 113
+3,27 114
+265.8,15 115
+8,15 115
+8,15 115
+8,15 115
+267.4,65 116
+23,24 116
+26,33 116
+35,51 116
+35,51 116
+53,64 116
+4,65 116
+268.4,15 117
+269.4,19 118
+270.4,18 119
+4,18 115
+272.4,77 120
+23,24 120
+26,33 120
+35,49 120
+35,49 120
+35,63 120
+65,76 120
+4,77 120
+4,77 115
+274.4,20 121
+275.8,15 122
+276.5,61 123
+24,25 123
+27,34 123
+36,47 123
+49,60 123
+5,61 123
+277.5,16 124
+279.4,18 125
+4,18 115
+281.4,19 126
+282.8,15 127
+283.5,61 128
+24,25 128
+27,34 128
+36,47 128
+49,60 128
+5,61 128
+284.5,16 129
+286.4,19 130
+4,19 115
+288.8,24 131
+289.9,25 132
+9,25 132
+9,25 132
+290.6,69 133
+14,15 133
+17,68 133
+6,69 133
+6,69 133
+6,69 134
+6,69 135
+292.6,70 136
+14,15 136
+17,69 136
+6,70 136
+6,70 136
+6,70 137
+294.4,60 138
+23,24 138
+26,33 138
+35,46 138
+48,59 138
+4,60 138
+295.4,15 139
+296.4,19 140
+297.4,18 141
+4,18 115
+299.8,19 142
+300.5,21 143
+301.5,20 144
+5,20 145
+302.15,25 146
+303.5,28 147
+304.5,19 148
+306.8,19 149
+23,36 149
+40,56 149
+307.5,63 150
+35,57 150
+25,58 150
+25,58 150
+60,62 150
+5,63 150
+5,63 151
+309.5,29 152
+18,19 152
+21,28 152
+5,29 152
+310.8,15 153
+311.5,61 154
+24,25 154
+27,34 154
+36,47 154
+49,60 154
+5,61 154
+312.5,16 155
+5,16 115
+5,16 156
+5,16 157
+5,16 110
+316.8,9 158
+8,9 159
+332.0,1 160
+320.9,16 161
+321.5,16 162
+322.5,57 163
+24,25 163
+27,34 163
+36,43 163
+45,56 163
+5,57 163
+5,57 158
+325.8,15 164
+326.5,16 165
+327.5,57 166
+24,25 166
+27,34 166
+36,43 166
+45,56 166
+5,57 166
+5,57 158
+5,57 167
+5,57 110
+336.1,11 168
+337.0,1 169
+345.5,12 170
+346.2,14 171
+2,14 172
+348.2,10 173
+350.5,9 174
+11,18 175
+351.2,15 176
+352.9,19 177
+2,19 177
+353.9,16 178
+2,16 178
+354.6,13 179
+355.7,21 180
+25,39 180
+356.15,22 181
+10,23 181
+4,23 181
+4,23 182
+357.14,28 183
+32,46 183
+358.15,22 184
+10,23 184
+4,23 184
+362.2,363.59 185
+362.10,11 185
+20,28 185
+13,28 185
+13,51 185
+13,57 185
+13,363.45 185
+48,58 185
+362.13,363.58 185
+362.13,363.58 186
+362.13,363.58 187
+362.2,363.59 185
+362.2,363.59 185
+362.2,363.59 188
+362.2,363.59 189
+350.20,23 190
+20,23 190
+365.5,16 191
+366.2,73 192
+10,11 192
+13,72 192
+2,73 192
+2,73 192
+2,73 193
+2,73 194
+368.2,74 195
+10,11 195
+13,73 195
+2,74 195
+2,74 195
+2,74 196
+369.1,21 197
+9,10 197
+12,20 197
+1,21 197
+1,21 197
+1,21 198
+370.0,1 199
+13
+aSys->Dir 1:26.1,39.2 64
+11
+0:name:28.2,6 s
+4:uid:29.2,5 s
+8:gid:30.2,5 s
+12:muid:31.2,6 s
+16:qid:32.2,5 @1
+
+32:mode:33.2,6 i
+36:atime:34.2,7 i
+40:mtime:35.2,7 i
+48:length:36.2,8 B
+56:dtype:37.2,7 i
+60:dev:38.2,5 i
+aSys->Qid 11.1,16.2 16
+3
+0:path:13.2,6 B
+8:vers:14.2,6 i
+12:qtype:15.2,7 i
+aDraw->Chans 2:70.1,82.2 4
+1
+0:desc:72.2,6 i
+aTk->Toplevel 3:5.1,12.2 32
+5
+0:display:7.2,9 R@4
+
+4:wreq:8.2,6 Cs
+8:image:9.2,7 R@5
+
+12:ctxt:10.2,6 R@9
+
+16:screenr:11.2,9 @6
+
+aDraw->Display 2:201.1,230.2 20
+5
+0:image:203.2,7 R@5
+
+4:white:204.2,7 R@5
+
+8:black:205.2,7 R@5
+
+12:opaque:206.2,8 R@5
+
+16:transparent:207.2,13 R@5
+
+aDraw->Image 142.1,198.2 56
+8
+0:r:146.2,3 @6
+
+16:clipr:147.2,7 @6
+
+32:depth:148.2,7 i
+36:chans:149.2,7 @2
+
+40:repl:150.2,6 i
+44:display:151.2,9 R@4
+
+48:screen:152.2,8 R@8
+
+52:iname:153.2,7 s
+aDraw->Rect 116.1,139.2 16
+2
+0:min:118.2,5 @7
+
+8:max:119.2,5 @7
+
+aDraw->Point 99.1,113.2 8
+2
+0:x:101.2,3 i
+4:y:102.2,3 i
+aDraw->Screen 249.1,263.2 16
+4
+0:id:251.2,4 i
+4:image:252.2,7 R@5
+
+8:fill:253.2,6 R@5
+
+12:display:254.2,9 R@4
+
+aDraw->Wmcontext 282.1,291.2 28
+7
+0:kbd:284.2,5 Ci
+4:ptr:285.2,5 CR@10
+
+8:ctl:286.2,5 Cs
+12:wctl:287.2,6 Cs
+16:images:288.2,8 CR@5
+
+20:connfd:289.2,8 R@11
+
+24:ctxt:290.2,6 R@12
+
+aDraw->Pointer 266.1,271.2 16
+3
+0:buttons:268.2,9 i
+4:xy:269.2,4 @7
+
+12:msec:270.2,6 i
+aSys->FD 1:45.1,48.2 4
+1
+0:fd:47.2,4 i
+aDraw->Context 2:274.1,279.2 12
+3
+0:display:276.2,9 R@4
+
+4:screen:277.2,8 R@8
+
+8:wm:278.2,4 Ct8.2
+0:t0:15,21 s
+4:t1:15,21 Ct8.2
+0:t0:32,38 s
+4:t1:32,38 R@9
+
+
+
+6
+0:initialize
+3
+32:t:0:170.11,12 R@3
+
+36:ctxt:32,36 R@12
+
+40:dot:58,61 s
+0
+Cs8:chaninit
+4
+32:t:175.9,10 R@3
+
+36:ctxt:30,34 R@12
+
+40:dot:56,59 s
+44:rc:69,71 Cs
+7
+48:i:188.5,6 i
+52:j:216.5,6 i
+56:key:236.1,4 Cs
+60:rowend:218.2,8 i
+64:rowstart:217.2,10 i
+68:keynum:197.3,9 i
+72:keysize:11,18 i
+Cs267:tkcmds
+2
+32:t:241.7,8 R@3
+
+36:cmds:28,32 As
+1
+40:i:243.5,6 i
+n280:handle_keyclicks
+4
+32:t:248.17,18 R@3
+
+36:ctxt:38,42 R@12
+
+40:sc:64,66 Cs
+44:rc:68,70 Cs
+11
+48:caps_locked:254.1,12 i
+52:minitel:253.1,8 i
+56:shifted:255.1,8 i
+60:keycode:264.3,10 i
+64:alt_active:257.1,11 i
+68:ctrl_active:256.1,12 i
+72:keypress:250.1,9 Cs
+76:k:262.2,3 s
+80:s:315.2,3 s
+96:n:263.4,5 i
+100:cmdstr:7,13 Ls
+n441:send_move_msg
+2
+32:dir:334.14,17 s
+36:ch:27,29 Cs
+0
+n443:redisplay_keyboard
+4
+32:t:341.19,20 R@3
+
+36:minitel:40,47 i
+40:shifted:49,56 i
+44:caps_locked:58,69 i
+5
+48:val:352.2,5 i
+52:i:350.5,6 i
+56:n:351.2,3 i
+60:key:353.2,5 s
+64:base:343.1,5 i
+n12
+188:direction:102.0,9 As
+192:draw:19.8,12 mDraw
+2:1.0,298.1 0
+
+244:keys:0:121.0,4 As
+248:keyvals:136.0,7 Ai
+252:meta_active:167.0,11 i
+256:move_key_enabled:166.0,16 i
+276:row_dimensions:103.0,14 Ai
+280:rowlayout:151.0,9 As
+284:special_keys:105.0,12 At8.2
+0:t0:106.2,8 i
+4:t1:10,17 i
+
+288:sys:16.8,11 mSys
+1:4.0,160.1 0
+
+292:tk:0:22.8,10 mTk
+3:1.0,25.1 0
+
+296:tkclient:0:8,16 mTkclient
+4:1.0,26.1 0
+