summaryrefslogtreecommitdiff
path: root/appl/demo/whiteboard
diff options
context:
space:
mode:
Diffstat (limited to 'appl/demo/whiteboard')
-rw-r--r--appl/demo/whiteboard/mkfile28
-rwxr-xr-xappl/demo/whiteboard/runwb.sh7
-rw-r--r--appl/demo/whiteboard/wbsrv.b268
-rw-r--r--appl/demo/whiteboard/wbsrv.disbin0 -> 3717 bytes
-rw-r--r--appl/demo/whiteboard/wbsrv.sbl818
-rw-r--r--appl/demo/whiteboard/whiteboard.b605
-rw-r--r--appl/demo/whiteboard/whiteboard.disbin0 -> 11229 bytes
-rw-r--r--appl/demo/whiteboard/whiteboard.sbl1880
8 files changed, 3606 insertions, 0 deletions
diff --git a/appl/demo/whiteboard/mkfile b/appl/demo/whiteboard/mkfile
new file mode 100644
index 00000000..020e8d21
--- /dev/null
+++ b/appl/demo/whiteboard/mkfile
@@ -0,0 +1,28 @@
+<../../../mkconfig
+
+TARG=\
+ wbsrv.dis\
+ whiteboard.dis\
+
+SHTARG=\
+ runwb.sh\
+
+MODULES=\
+
+SYSMODULES= \
+ draw.m\
+ sys.m\
+ tk.m\
+ tkclient.m\
+
+DISBIN=$ROOT/dis/demo/whiteboard
+
+<$ROOT/mkfiles/mkdis
+
+SHFILES=${SHTARG:%.sh=$DISBIN/%}
+install:V: $SHFILES
+%.install:V: $DISBIN/%
+%.installall:V: $DISBIN/%
+
+$DISBIN/%: %.sh
+ cp $stem.sh $target && chmod a+rx $target
diff --git a/appl/demo/whiteboard/runwb.sh b/appl/demo/whiteboard/runwb.sh
new file mode 100755
index 00000000..f64a6382
--- /dev/null
+++ b/appl/demo/whiteboard/runwb.sh
@@ -0,0 +1,7 @@
+#!/dis/sh.dis
+load std
+pctl forkns
+memfs /tmp
+cp /dis/wm/whiteboard.dis /tmp
+/dis/auxi/wbsrv /tmp $2
+grid/register -a resource Whiteboard -a size 600x400 -a name $1 {export /tmp}
diff --git a/appl/demo/whiteboard/wbsrv.b b/appl/demo/whiteboard/wbsrv.b
new file mode 100644
index 00000000..9bec955b
--- /dev/null
+++ b/appl/demo/whiteboard/wbsrv.b
@@ -0,0 +1,268 @@
+implement Wbserve;
+
+include "sys.m";
+ sys: Sys;
+
+include "draw.m";
+ draw: Draw;
+ Chans, Display, Image, Rect, Point : import draw;
+
+Wbserve : module {
+ init : fn (ctxt : ref Draw->Context, args : list of string);
+};
+
+WBW : con 600;
+WBH : con 400;
+
+savefile := "";
+
+init(nil: ref Draw->Context, args: list of string)
+{
+ sys = load Sys Sys->PATH;
+ draw = load Draw Draw->PATH;
+ if (draw == nil)
+ badmod(Draw->PATH);
+
+ if (args == nil || tl args == nil)
+ error("usage: wbsrv mntpt [savefile]");
+ args = tl args;
+ mntpt := hd args;
+ args = tl args;
+
+ display := Display.allocate(nil);
+ if (display == nil)
+ error(sys->sprint("cannot allocate display: %r"));
+
+ bg: ref Draw->Image;
+ if (args != nil) {
+ savefile = hd args;
+ bg = display.open(savefile);
+ }
+ r := Rect(Point(0,0), Point(WBW, WBH));
+ wb := display.newimage(r, Draw->CMAP8, 0, Draw->White);
+ if (wb == nil)
+ error(sys->sprint("cannot allocate whiteboard image: %r"));
+ if (bg != nil) {
+ wb.draw(bg.r, bg, nil, Point(0,0));
+ bg = nil;
+ }
+
+ nextmsg = ref Msg (nil, nil);
+
+ sys->bind("#s", mntpt, Sys->MBEFORE);
+
+ bit := sys->file2chan(mntpt, "wb.bit");
+ strokes := sys->file2chan(mntpt, "strokes");
+
+ spawn srv(wb, bit, strokes);
+ if (savefile != nil)
+ spawn saveit(display, wb);
+}
+
+srv(wb: ref Image, bit, strokes: ref Sys->FileIO)
+{
+ nwbbytes := draw->bytesperline(wb.r, wb.depth) * wb.r.dy();
+ bithdr := sys->aprint("%11s %11d %11d %11d %11d ", wb.chans.text(), 0, 0, WBW, WBH);
+
+ for (;;) alt {
+ (offset, count, fid, r) := <-bit.read =>
+ if (r == nil) {
+ closeclient(fid);
+ continue;
+ }
+ c := getclient(fid);
+ if (c == nil) {
+ # new client
+ c = newclient(fid);
+ data := array [len bithdr + nwbbytes] of byte;
+ data[0:] = bithdr;
+ wb.readpixels(wb.r, data[len bithdr:]);
+ c.bitdata = data;
+ }
+ if (offset >= len c.bitdata) {
+ rreply(r, (nil, nil));
+ continue;
+ }
+ rreply(r, (c.bitdata[offset:], nil));
+
+ (offset, data, fid, w) := <-bit.write =>
+ if (w != nil)
+ wreply(w, (0, "permission denied"));
+
+ (offset, count, fid, r) := <-strokes.read =>
+ if (r == nil) {
+ closeclient(fid);
+ continue;
+ }
+ c := getclient(fid);
+ if (c == nil) {
+ c = newclient(fid);
+ c.nextmsg = nextmsg;
+ }
+ d := c.nextmsg.data;
+ if (d == nil) {
+ c.pending = r;
+ c.pendlen = count;
+ continue;
+ }
+ c.nextmsg = c.nextmsg.next;
+ rreply(r, (d, nil));
+
+ (offset, data, fid, w) := <-strokes.write =>
+ if (w == nil) {
+ closeclient(fid);
+ continue;
+ }
+ err := drawstrokes(wb, data);
+ if (err != nil) {
+ wreply(w, (0, err));
+ continue;
+ }
+ wreply(w, (len data, nil));
+ writeclients(data);
+ }
+}
+
+rreply(rc: chan of (array of byte, string), reply: (array of byte, string))
+{
+ alt {
+ rc <-= reply =>;
+ * =>;
+ }
+}
+
+wreply(wc: chan of (int, string), reply: (int, string))
+{
+ alt {
+ wc <-= reply=>;
+ * =>;
+ }
+}
+
+export(fd : ref Sys->FD, done : chan of int)
+{
+ sys->export(fd, "/", Sys->EXPWAIT);
+ done <-= 1;
+}
+
+Msg : adt {
+ data : array of byte;
+ next : cyclic ref Msg;
+};
+
+Client : adt {
+ fid : int;
+ bitdata : array of byte; # bit file client
+ nextmsg : ref Msg; # strokes file client
+ pending : Sys->Rread;
+ pendlen : int;
+};
+
+nextmsg : ref Msg;
+clients : list of ref Client;
+
+newclient(fid : int) : ref Client
+{
+ c := ref Client(fid, nil, nil, nil, 0);
+ clients = c :: clients;
+ return c;
+}
+
+getclient(fid : int) : ref Client
+{
+ for(cl := clients; cl != nil; cl = tl cl)
+ if((c := hd cl).fid == fid)
+ return c;
+ return nil;
+}
+
+closeclient(fid : int)
+{
+ nl: list of ref Client;
+ for(cl := clients; cl != nil; cl = tl cl)
+ if((hd cl).fid != fid)
+ nl = hd cl :: nl;
+ clients = nl;
+}
+
+writeclients(data : array of byte)
+{
+ nm := ref Msg(nil, nil);
+ nextmsg.data = data;
+ nextmsg.next = nm;
+
+ for(cl := clients; cl != nil; cl = tl cl){
+ if ((c := hd cl).pending != nil) {
+ n := c.pendlen;
+ if (n > len data)
+ n = len data;
+ alt{
+ c.pending <-= (data[0:n], nil) => ;
+ * => ;
+ }
+ c.pending = nil;
+ c.nextmsg = nm;
+ }
+ }
+ nextmsg = nm;
+}
+
+# data: colour width p0 p1 pn*
+
+pencol: int;
+pen: ref Image;
+
+drawstrokes(wb: ref Image, data : array of byte) : string
+{
+ (n, toks) := sys->tokenize(string data, " ");
+ if (n < 6 || n & 1)
+ return "bad data";
+
+ colour, width, x, y : int;
+ (colour, toks) = (int hd toks, tl toks);
+ (width, toks) = (int hd toks, tl toks);
+ (x, toks) = (int hd toks, tl toks);
+ (y, toks) = (int hd toks, tl toks);
+ if (pen == nil || colour != pencol) {
+ pencol = colour;
+ pen = wb.display.newimage(Rect(Point(0,0), Point(1,1)), Draw->CMAP8, 1, pencol);
+ }
+ p0 := Point(x, y);
+ while (toks != nil) {
+ (x, toks) = (int hd toks, tl toks);
+ (y, toks) = (int hd toks, tl toks);
+ p1 := Point(x, y);
+ # could use poly() instead of line()
+ wb.line(p0, p1, Draw->Enddisc, Draw->Enddisc, width, pen, pen.r.min);
+ p0 = p1;
+ }
+ return nil;
+}
+
+error(e: string)
+{
+ sys->fprint(stderr(), "wbsrv: %s\n", e);
+ raise "fail:error";
+}
+
+stderr(): ref Sys->FD
+{
+ return sys->fildes(2);
+}
+
+badmod(path: string)
+{
+ sys->fprint(stderr(), "wbsrv: cannot load %s: %r\n", path);
+ exit;
+}
+
+saveit(display: ref Display, img: ref Image)
+{
+ for (;;) {
+ sys->sleep(300000);
+ fd := sys->open(savefile, sys->OWRITE);
+ if (fd == nil)
+ exit;
+ display.writeimage(fd, img);
+ }
+} \ No newline at end of file
diff --git a/appl/demo/whiteboard/wbsrv.dis b/appl/demo/whiteboard/wbsrv.dis
new file mode 100644
index 00000000..12d09e5e
--- /dev/null
+++ b/appl/demo/whiteboard/wbsrv.dis
Binary files differ
diff --git a/appl/demo/whiteboard/wbsrv.sbl b/appl/demo/whiteboard/wbsrv.sbl
new file mode 100644
index 00000000..6a09ad7a
--- /dev/null
+++ b/appl/demo/whiteboard/wbsrv.sbl
@@ -0,0 +1,818 @@
+limbo .sbl 2.1
+Wbserve
+3
+wbsrv.b
+sys.m
+draw.m
+510
+21.1,25 0
+22.1,28 1
+23.5,16 2
+24.2,20 3
+9,19 3
+2,20 3
+26.5,16 4
+20,27 4
+20,34 4
+20,34 5
+27.2,40 6
+8,39 6
+2,40 6
+28.1,15 7
+29.1,17 8
+30.1,15 9
+32.1,33 10
+29,32 10
+1,33 10
+1,33 10
+33.5,19 11
+34.8,50 12
+20,49 12
+8,50 12
+8,50 12
+2,51 12
+2,51 12
+2,51 13
+2,51 12
+37.5,16 14
+38.2,20 15
+39.2,29 16
+7,14 16
+20,28 16
+2,29 16
+2,29 16
+41.17,18 17
+19,20 17
+29,32 17
+34,37 17
+42.1,55 18
+7,14 18
+24,25 18
+2:90.18,31 18
+0:42.40,41 18
+43,54 18
+1,55 18
+1,55 18
+43.5,14 19
+44.8,59 20
+20,58 20
+8,59 20
+8,59 20
+2,60 20
+2,60 20
+2,60 21
+2,60 20
+45.5,14 22
+46.2,36 23
+2,4 23
+10,14 23
+16,18 23
+20,23 23
+31,32 23
+33,34 23
+2,36 23
+47.2,10 24
+50.1,29 25
+20,23 25
+25,28 25
+1,29 25
+1,29 26
+52.1,37 27
+11,15 27
+17,22 27
+24,36 27
+1,37 27
+1,37 27
+54.1,39 28
+23,28 28
+30,38 28
+1,39 28
+1,39 28
+55.1,44 29
+27,32 29
+34,43 29
+1,44 29
+1,44 29
+57.1,28 30
+11,13 30
+15,18 30
+20,27 30
+1,28 30
+58.5,20 31
+59.2,27 32
+15,22 32
+24,26 32
+2,27 32
+60.0,1 33
+64.13,47 34
+32,36 34
+38,46 34
+13,47 34
+13,47 34
+50,59 34
+50,54 34
+50,59 34
+50,59 34
+1,59 34
+65.52,67 35
+52,60 35
+52,67 35
+52,67 35
+1,84 35
+23,50 35
+23,50 35
+23,50 36
+69,70 35
+72,73 35
+75,78 35
+80,83 35
+1,84 35
+1,84 35
+68.30,38 37
+30,38 37
+88.29,38 37
+29,38 37
+92.30,42 37
+30,42 37
+111.29,42 37
+29,42 37
+67.10,16 37
+10,16 37
+10,16 37
+10,16 37
+68.28,38 37
+28,38 38
+69.6,14 39
+70.3,19 40
+15,18 40
+3,19 40
+3,19 41
+3,19 42
+3,19 43
+71.3,11 44
+73.2,21 45
+17,20 45
+2,21 45
+2,21 45
+74.6,14 46
+76.3,21 47
+17,20 47
+3,21 47
+3,21 47
+77.18,28 48
+18,39 48
+3,48 48
+78.3,20 49
+79.3,41 50
+3,5 50
+17,21 50
+23,40 50
+28,38 50
+23,27 50
+23,40 50
+3,41 50
+3,41 50
+80.3,19 51
+3,19 52
+82.16,29 53
+6,29 53
+83.3,24 54
+10,11 54
+14,17 54
+19,22 54
+3,24 54
+3,24 55
+3,24 56
+3,24 57
+84.3,11 58
+86.2,38 59
+9,10 59
+13,31 59
+13,22 59
+13,31 59
+33,36 59
+2,38 59
+2,38 60
+2,38 61
+2,38 62
+2,38 37
+88.27,38 37
+27,38 63
+27,38 64
+89.6,14 65
+90.3,38 66
+10,11 66
+14,15 66
+17,36 66
+3,38 66
+3,38 67
+3,38 68
+3,38 69
+3,38 70
+3,38 37
+92.28,42 37
+28,42 71
+93.6,14 72
+94.3,19 73
+15,18 73
+3,19 73
+3,19 74
+3,19 75
+3,19 76
+3,19 77
+95.3,11 78
+97.2,21 79
+17,20 79
+2,21 79
+2,21 79
+98.6,14 80
+99.3,21 81
+17,20 81
+3,21 81
+3,21 81
+100.3,22 82
+102.7,16 83
+2,21 83
+2,21 84
+103.6,14 85
+104.3,16 86
+105.3,20 87
+3,20 88
+3,20 89
+3,20 90
+3,20 91
+106.3,11 92
+108.14,23 93
+2,28 93
+2,28 94
+109.2,21 95
+9,10 95
+13,14 95
+16,19 95
+2,21 95
+2,21 96
+2,21 97
+2,21 98
+2,21 99
+2,21 37
+111.27,42 37
+27,42 100
+27,42 101
+112.6,14 102
+113.3,19 103
+15,18 103
+3,19 103
+3,19 104
+3,19 105
+3,19 106
+3,19 107
+3,19 108
+114.3,11 109
+116.2,30 110
+21,23 110
+25,29 110
+2,30 110
+2,30 110
+117.6,16 111
+118.3,22 112
+10,11 112
+14,15 112
+17,20 112
+3,22 112
+3,22 113
+3,22 114
+3,22 115
+3,22 116
+3,22 117
+119.3,11 118
+121.2,28 119
+9,10 119
+13,21 119
+23,26 119
+2,28 119
+122.2,20 120
+15,19 120
+2,20 120
+2,20 121
+2,20 122
+2,20 123
+2,20 124
+2,20 125
+2,20 37
+129.1,3 126
+1,3 126
+128.1,7 126
+1,7 126
+1,7 126
+1,7 126
+132.0,1 127
+0,1 127
+137.1,3 128
+1,3 128
+136.1,7 128
+1,7 128
+1,7 128
+1,7 128
+140.0,1 129
+0,1 129
+166.1,39 130
+17,20 130
+22,25 130
+27,30 130
+32,35 130
+37,38 130
+1,39 130
+1,39 131
+167.1,23 132
+168.8,9 133
+1,9 133
+173.5,18 134
+20,29 135
+174.5,17 136
+5,17 136
+5,28 136
+5,28 137
+175.10,11 138
+3,11 138
+173.31,41 139
+31,41 139
+176.8,11 140
+1,11 140
+182.5,18 141
+20,29 142
+183.5,12 143
+5,23 143
+5,23 144
+184.8,13 145
+3,19 145
+3,19 146
+182.31,41 147
+31,41 147
+185.1,13 148
+186.0,1 149
+190.1,24 150
+15,18 150
+20,23 150
+1,24 150
+1,24 151
+191.1,20 152
+192.1,18 153
+194.5,18 154
+20,29 155
+195.6,18 156
+6,18 156
+6,33 156
+6,33 157
+196.3,17 158
+197.11,19 159
+7,19 159
+198.4,16 160
+200.3,12 161
+18,22 161
+18,27 161
+29,32 161
+3,12 161
+199.3,9 161
+3,9 161
+3,9 161
+3,9 161
+3,9 162
+3,9 163
+3,9 161
+3,9 161
+203.3,18 164
+204.3,17 165
+3,17 166
+194.31,41 167
+31,41 167
+207.1,13 168
+208.0,1 169
+217.14,45 170
+28,39 170
+41,44 170
+14,45 170
+14,45 170
+218.5,10 171
+14,19 171
+14,19 171
+219.9,19 172
+2,19 172
+222.23,30 173
+19,30 173
+19,30 174
+32,39 173
+2,8 173
+10,14 173
+10,14 175
+223.22,29 176
+18,29 176
+18,29 177
+31,38 176
+2,7 176
+9,13 176
+9,13 178
+224.18,25 179
+14,25 179
+14,25 180
+27,34 179
+2,3 179
+5,9 179
+5,9 181
+225.18,25 182
+14,25 182
+14,25 183
+27,34 182
+2,3 182
+5,9 182
+5,9 184
+226.5,15 185
+19,35 185
+227.2,17 186
+228.2,81 187
+8,18 187
+39,40 187
+41,42 187
+51,52 187
+53,54 187
+2:90.18,31 187
+0:228.71,72 187
+74,80 187
+2,81 187
+2,81 187
+230.13,14 188
+16,17 188
+231.8,19 189
+232.19,26 190
+15,26 190
+15,26 191
+28,35 190
+3,4 190
+6,10 190
+6,10 192
+233.19,26 193
+15,26 193
+15,26 194
+28,35 193
+3,4 193
+6,10 193
+6,10 195
+234.14,15 196
+17,18 196
+236.2,70 197
+2,4 197
+10,12 197
+14,16 197
+18,31 197
+33,46 197
+48,53 197
+55,58 197
+60,69 197
+2,70 197
+237.2,9 198
+2,9 198
+239.8,11 199
+1,11 199
+244.13,21 200
+13,21 200
+13,21 200
+13,21 200
+1,40 200
+1,40 200
+1,40 201
+23,36 200
+38,39 200
+1,40 200
+1,40 200
+245.1,19 202
+255.13,21 203
+13,21 203
+13,21 203
+13,21 203
+1,59 203
+1,59 203
+1,59 204
+23,52 203
+54,58 203
+1,59 203
+1,59 203
+256.1,5 205
+262.2,20 206
+13,19 206
+2,20 206
+2,20 206
+263.2,40 207
+18,26 207
+28,39 207
+2,40 207
+2,40 207
+264.6,15 208
+265.3,7 209
+266.2,29 210
+2,9 210
+21,23 210
+25,28 210
+2,29 210
+2,29 210
+2,29 211
+2,29 211
+17
+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->Context 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
+
+
+
+aDraw->Display 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@3
+
+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
+aSys->FileIO 65.1,69.2 8
+2
+0:read:67.2,6 Ct16.4
+0:t0:17,20 i
+4:t1:17,20 i
+8:t2:17,20 i
+12:t3:17,20 @13
+
+
+4:write:68.2,7 Ct16.4
+0:t0:18,21 i
+4:t1:18,21 Ab
+8:t2:18,21 i
+12:t3:18,21 @14
+
+
+Ct8.2
+0:t0:63.22,35 Ab
+4:t1:22,35 s
+Ct8.2
+0:t0:64.23,26 i
+4:t1:23,26 s
+aClient 0:153.0,159.1 20
+5
+0:fid:154.1,4 i
+4:bitdata:155.1,8 Ab
+8:nextmsg:156.1,8 R@16
+
+12:pending:157.1,8 @13
+
+16:pendlen:158.1,8 i
+aMsg 148.0,151.1 8
+2
+0:data:149.1,5 Ab
+4:next:150.1,5 R@16
+
+12
+0:init
+1
+36:args:19.29,33 Ls
+7
+40:bg:36.1,3 R@5
+
+44:display:32.1,8 R@4
+
+48:wb:42.1,3 R@5
+
+52:mntpt:29.1,6 s
+56:bit:54.1,4 R@12
+
+60:strokes:55.1,8 R@12
+
+76:r:41.1,2 @6
+
+n99:srv
+3
+32:wb:62.4,6 R@5
+
+36:bit:19,22 R@12
+
+40:strokes:24,31 R@12
+
+23
+44:c:97.2,3 R@15
+
+48:c:73.2,3 R@15
+
+52:bithdr:65.1,7 Ab
+56:data:77.3,7 Ab
+60:d:102.2,3 Ab
+64:err:116.2,5 s
+68:offset:68.2,8 i
+72:count:10,15 i
+76:fid:17,20 i
+80:r:22,23 @13
+
+84:nwbbytes:64.1,9 i
+108:offset:88.2,8 i
+112:data:10,14 Ab
+116:fid:16,19 i
+120:w:21,22 @14
+
+124:offset:92.2,8 i
+128:count:10,15 i
+132:fid:17,20 i
+136:r:22,23 @13
+
+140:offset:111.2,8 i
+144:data:10,14 Ab
+148:fid:16,19 i
+152:w:21,22 @14
+
+n294:rreply
+2
+32:rc:126.7,9 Ct8.2
+0:t0:20,33 Ab
+4:t1:20,33 s
+
+36:reply:44,49 t8.2
+0:t0:52,65 Ab
+4:t1:52,65 s
+
+0
+n302:wreply
+2
+32:wc:134.7,9 Ct8.2
+0:t0:20,23 i
+4:t1:20,23 s
+
+36:reply:34,39 t8.2
+0:t0:42,45 i
+4:t1:42,45 s
+
+0
+n310:newclient
+1
+32:fid:164.10,13 i
+1
+36:c:166.1,2 R@15
+
+R@15
+321:getclient
+1
+32:fid:171.10,13 i
+2
+36:cl:173.5,7 LR@15
+
+40:c:174.6,7 R@15
+
+R@15
+333:closeclient
+1
+32:fid:179.12,15 i
+2
+36:cl:182.5,7 LR@15
+
+40:nl:181.1,3 LR@15
+
+n345:writeclients
+1
+32:data:188.13,17 Ab
+4
+36:c:195.7,8 R@15
+
+40:cl:194.5,7 LR@15
+
+44:n:196.3,4 i
+48:nm:190.1,3 R@16
+
+n382:drawstrokes
+2
+32:wb:215.12,14 R@5
+
+36:data:27,31 Ab
+8
+40:x:221.16,17 i
+44:y:19,20 i
+48:colour:1,7 i
+52:n:217.2,3 i
+56:toks:5,9 Ls
+60:width:221.9,14 i
+80:p0:230.1,3 @7
+
+88:p1:234.2,4 @7
+
+s467:error
+1
+32:e:242.6,7 s
+0
+n479:badmod
+1
+32:path:253.7,11 s
+0
+n491:saveit
+2
+32:display:259.7,14 R@4
+
+36:img:29,32 R@5
+
+1
+40:fd:263.2,4 R@11
+
+n6
+88:clients:162.0,7 LR@15
+
+92:draw:7.1,5 mDraw
+2:1.0,298.1 0
+
+100:nextmsg:0:161.0,7 R@16
+
+108:pen:213.0,3 R@5
+
+112:pencol:212.0,6 i
+128:sys:4.1,4 mSys
+1:0,160.1 0
+
diff --git a/appl/demo/whiteboard/whiteboard.b b/appl/demo/whiteboard/whiteboard.b
new file mode 100644
index 00000000..ac9f72f1
--- /dev/null
+++ b/appl/demo/whiteboard/whiteboard.b
@@ -0,0 +1,605 @@
+implement Whiteboard;
+
+include "sys.m";
+ sys: Sys;
+
+include "draw.m";
+ draw: Draw;
+ Screen, Display, Image, Rect, Point, Font: import draw;
+
+include "tk.m";
+ tk: Tk;
+
+include "tkclient.m";
+ tkclient: Tkclient;
+
+Whiteboard: module {
+ init: fn(ctxt: ref Draw->Context, args: list of string);
+};
+
+ERASEWIDTH: con 6;
+
+
+stderr: ref Sys->FD;
+srvfd: ref Sys->FD;
+disp: ref Display;
+font: ref Draw->Font;
+drawctxt: ref Draw->Context;
+
+tksetup := array[] of {
+ "frame .f -bd 2",
+ "frame .c -bg white -width 600 -height 400",
+ "menu .penmenu",
+ ".penmenu add command -command {send cmd pen 0} -image pen0",
+ ".penmenu add command -command {send cmd pen 1} -image pen1",
+ ".penmenu add command -command {send cmd pen 2} -image pen2",
+ ".penmenu add command -command {send cmd pen erase} -image erase",
+ "menubutton .pen -menu .penmenu -image pen1",
+ "button .colour -bg black -activebackground black -command {send cmd getcolour}",
+ "pack .c -in .f",
+ "pack .f -side top -anchor center",
+ "pack .pen -side left",
+ "pack .colour -side left -fill both -expand 1",
+ "update",
+};
+
+tkconnected := array[] of {
+ "bind .c <Button-1> {send cmd down %x %y}",
+ "bind .c <ButtonRelease-1> {send cmd up %x %y}",
+ "update",
+};
+
+init(ctxt: ref Draw->Context, args: list of string)
+{
+ sys = load Sys Sys->PATH;
+ sys->pctl(Sys->NEWPGRP, nil);
+ stderr = sys->fildes(2);
+
+ draw = load Draw Draw->PATH;
+ tk = load Tk Tk->PATH;
+
+ tkclient = load Tkclient Tkclient->PATH;
+ if (tkclient == nil)
+ badmod(Tkclient->PATH);
+
+ args = tl args;
+ servicedir := ".";
+ if(args != nil)
+ (servicedir, args) = (hd args, tl args);
+
+ disp = ctxt.display;
+ if (disp == nil) {
+ sys->fprint(stderr, "bad Draw->Context\n");
+ raise "fail:init";
+ }
+ drawctxt = ctxt;
+
+ tkclient->init();
+ (win, winctl) := tkclient->toplevel(ctxt, nil, "Whiteboard", 0);
+ font = Font.open(disp, tkcmd(win, ". cget -font"));
+ if(font == nil)
+ font = Font.open(disp, "*default*");
+ cmd := chan of string;
+ tk->namechan(win, cmd, "cmd");
+ mkpenimgs(win);
+ tkcmds(win, tksetup);
+ tkclient->onscreen(win, nil);
+ tkclient->startinput(win, "kbd" :: "ptr" :: nil);
+ cimage := makeimage(win);
+
+ sc := chan of array of (Point, Point);
+ cc := chan of (string, ref Image, ref Sys->FD);
+ connected := 0;
+ sfd: ref Sys->FD;
+
+ showtext(cimage, "connecting...");
+ spawn connect(servicedir, cc);
+
+ err: string;
+ strokeimg: ref Image;
+Connect:
+ for (;;) alt {
+ (err, strokeimg, sfd) = <-cc =>
+ if (err == nil)
+ break Connect;
+ else
+ showtext(cimage, "Error: " + err);
+
+ s := <-winctl or
+ s = <-win.wreq or
+ s = <-win.ctxt.ctl =>
+ oldimg := win.image;
+ err = tkclient->wmctl(win, s);
+ if(s[0] == '!' && err == nil && win.image != oldimg){
+ cimage = makeimage(win);
+ showtext(cimage, "connecting...");
+ }
+ p := <-win.ctxt.ptr =>
+ tk->pointer(win, *p);
+ c := <-win.ctxt.kbd =>
+ tk->keyboard(win, c);
+ }
+
+ tkcmd(win, ".c configure -width " + string strokeimg.r.dx());
+ tkcmd(win, ".c configure -height " + string strokeimg.r.dy());
+ tkcmds(win, tkconnected);
+ tkcmd(win, "update");
+ cimage.draw(cimage.r, strokeimg, nil, strokeimg.r.min);
+
+ strokesin := chan of (int, int, array of Point);
+ strokesout := chan of (int, int, Point, Point);
+ spawn reader(sfd, strokesin);
+ spawn writer(sfd, strokesout);
+
+ pendown := 0;
+ p0, p1: Point;
+
+ getcolour := 0;
+ white := disp.white;
+ whitepen := disp.newimage(Rect(Point(0,0), Point(1,1)), Draw->CMAP8, 1, Draw->White);
+ pencolour := Draw->Black;
+ penwidth := 1;
+ erase := 0;
+ drawpen := disp.newimage(Rect(Point(0,0), Point(1,1)), Draw->CMAP8, 1, pencolour);
+
+ for (;;) alt {
+ s := <-winctl or
+ s = <-win.ctxt.ctl or
+ s = <-win.wreq =>
+ oldimg := win.image;
+ err = tkclient->wmctl(win, s);
+ if(s[0] == '!' && err == nil && win.image != oldimg){
+ cimage = makeimage(win);
+ cimage.draw(cimage.r, strokeimg, nil, strokeimg.r.min);
+ }
+ p := <-win.ctxt.ptr =>
+ tk->pointer(win, *p);
+ c := <-win.ctxt.kbd =>
+ tk->keyboard(win, c);
+ (colour, width, strokes) := <-strokesin =>
+ if (strokes == nil)
+ tkclient->settitle(win, "Whiteboard (Disconnected)");
+ else {
+ pen := disp.newimage(Rect(Point(0,0), Point(1,1)), Draw->CMAP8, 1, colour);
+ drawstrokes(cimage, cimage.r.min, pen, width, strokes);
+ drawstrokes(strokeimg, strokeimg.r.min, pen, width, strokes);
+ }
+
+ c := <-cmd =>
+ (nil, toks) := sys->tokenize(c, " ");
+ action := hd toks;
+ case action {
+ "up" or
+ "down" =>
+ toks = tl toks;
+ x := int hd toks;
+ y := int hd tl toks;
+ if (action == "down") {
+ if (!pendown) {
+ pendown = 1;
+ p0 = Point(x, y);
+ continue;
+ }
+ } else
+ pendown = 0;
+ p1 = Point(x, y);
+ if (pendown && p1.x == p0.x && p1.y == p0.y)
+ continue;
+ pen := drawpen;
+ colour := pencolour;
+ width := penwidth;
+ if (erase) {
+ pen = whitepen;
+ colour = Draw->White;
+ width = ERASEWIDTH;
+ }
+ drawstroke(cimage, cimage.r.min, p0, p1, pen, width);
+ drawstroke(strokeimg, strokeimg.r.min, p0, p1, pen, width);
+ strokesout <-= (colour, width, p0, p1);
+ p0 = p1;
+
+ "getcolour" =>
+ pendown = 0;
+ if (!getcolour)
+ spawn colourmenu(cmd);
+ "colour" =>
+ pendown = 0;
+ getcolour = 0;
+ toks = tl toks;
+ if (toks == nil)
+ # colourmenu was dismissed
+ continue;
+ erase = 0;
+ tkcmd(win, ".pen configure -image pen" + string penwidth);
+ tkcmd(win, "update");
+ pencolour = int hd toks;
+ toks = tl toks;
+ tkcolour := hd toks;
+ drawpen = disp.newimage(Rect(Point(0,0), Point(1,1)), Draw->CMAP8, 1, pencolour);
+ tkcmd(win, ".colour configure -bg " + tkcolour + " -activebackground " + tkcolour);
+ tkcmd(win, "update");
+
+ "pen" =>
+ pendown = 0;
+ p := hd tl toks;
+ i := "";
+ if (p == "erase") {
+ erase = 1;
+ i = "erase";
+ } else {
+ erase = 0;
+ penwidth = int p;
+ i = "pen"+p;
+ }
+ tkcmd(win, ".pen configure -image " + i);
+ tkcmd(win, "update");
+ }
+
+ }
+}
+
+makeimage(win: ref Tk->Toplevel): ref Draw->Image
+{
+ if(win.image == nil)
+ return nil;
+ scr := Screen.allocate(win.image, win.image.display.white, 0);
+ w := scr.newwindow(tk->rect(win, ".c", Tk->Local), Draw->Refnone, Draw->Nofill);
+ return w;
+}
+
+showtext(img: ref Image, s: string)
+{
+ r := img.r;
+ r.max.y = img.r.min.y + font.height;
+ img.draw(r, disp.white, nil, (0, 0));
+ img.text(r.min, disp.black, (0, 0), font, s);
+}
+
+penmenu(t: ref Tk->Toplevel, p: Point)
+{
+ topy := int tkcmd(t, ".penmenu yposition 0");
+ boty := int tkcmd(t, ".penmenu yposition end");
+ dy := boty - topy;
+ p.y -= dy;
+ tkcmd(t, ".penmenu post " + string p.x + " " + string p.y);
+}
+
+colourcmds := array[] of {
+ "label .l -height 10",
+ "frame .c -height 224 -width 224",
+ "pack .l -fill x -expand 1",
+ "pack .c -side bottom -fill both -expand 1",
+ "pack propagate . 0",
+ "bind .c <Button-1> {send cmd push %x %y}",
+ "bind .c <ButtonRelease-1> {send cmd release}",
+};
+
+lastcolour := "255";
+lasttkcolour := "#000000";
+
+colourmenu(c: chan of string)
+{
+ (t, winctl) := tkclient->toplevel(drawctxt, nil, "Whiteboard", Tkclient->OK);
+ cmd := chan of string;
+ tk->namechan(t, cmd, "cmd");
+ tkcmds(t, colourcmds);
+ tkcmd(t, ".l configure -bg " + lasttkcolour);
+ tkcmd(t, "update");
+ tkclient->onscreen(t, "onscreen");
+ tkclient->startinput(t, "kbd" :: "ptr" :: nil);
+
+ drawcolours(t.image, tk->rect(t, ".c", Tk->Local));
+
+ for(;;) alt {
+ p := <-t.ctxt.ptr =>
+ tk->pointer(t, *p);
+ s := <-t.ctxt.kbd =>
+ tk->keyboard(t, s);
+ s := <-winctl or
+ s = <-t.ctxt.ctl or
+ s = <-t.wreq =>
+ case s{
+ "ok" =>
+ c <-= "colour " + lastcolour + " " + lasttkcolour;
+ return;
+ "exit" =>
+ c <-= "colour";
+ return;
+ * =>
+ oldimage := t.image;
+ e := tkclient->wmctl(t, s);
+ if(s[0] == '!' && e == nil && oldimage != t.image)
+ drawcolours(t.image, tk->rect(t, ".c", Tk->Local));
+ }
+
+ press := <-cmd =>
+ (n, word) := sys->tokenize(press, " ");
+ case hd word {
+ "push" =>
+ (lastcolour, lasttkcolour) = color(int hd tl word, int hd tl tl word, tk->rect(t, ".c", 0).size());
+ tkcmd(t, ".l configure -bg " + lasttkcolour);
+ }
+ }
+}
+
+drawcolours(img: ref Image, cr: Rect)
+{
+ # use writepixels because it's much faster than allocating all those colors.
+ tmp := disp.newimage(((0,0),(cr.dx(),cr.dy()/16+1)), Draw->CMAP8, 0, 0);
+ if(tmp == nil)
+ return;
+ buf := array[tmp.r.dx()*tmp.r.dy()] of byte;
+ dx := cr.dx();
+ dy := cr.dy();
+ for(y:=0; y<16; y++){
+ for(i:=tmp.r.dx()-1; i>=0; --i)
+ buf[i] = byte (16*y+(16*i)/dx);
+ for(k:=tmp.r.dy()-1; k>=1; --k)
+ buf[dx*k:] = buf[0:dx];
+ tmp.writepixels(tmp.r, buf);
+ r: Rect;
+ r.min.x = cr.min.x;
+ r.max.x = cr.max.x;
+ r.min.y = cr.min.y+(dy*y)/16;
+ r.max.y = cr.min.y+(dy*(y+1))/16;
+ img.draw(r, tmp, nil, tmp.r.min);
+ }
+}
+
+color(x, y: int, size: Point): (string, string)
+{
+ x = (16*x)/size.x;
+ y = (16*y)/size.y;
+ col := 16*y+x;
+ (r, g, b) := disp.cmap2rgb(col);
+ tks := sys->sprint("#%.2x%.2x%.2x", r, g, b);
+ return (string disp.cmap2rgba(col), tks);
+}
+
+opensvc(dir: string, svc: string, name: string): (ref Sys->FD, string, string)
+{
+ ctlfd := sys->open(dir+"/ctl", Sys->ORDWR);
+ if(ctlfd == nil)
+ return (nil, nil, sys->sprint("can't open %s/ctl: %r", dir));
+ if(sys->fprint(ctlfd, "%s %s", svc, name) <= 0)
+ return (nil, nil, sys->sprint("can't access %s service %s: %r", svc, name));
+ buf := array [32] of byte;
+ sys->seek(ctlfd, big 0, Sys->SEEKSTART);
+ n := sys->read(ctlfd, buf, len buf);
+ if (n <= 0)
+ return (nil, nil, sys->sprint("%s/ctl: protocol error: %r", dir));
+ return (ctlfd, dir+"/"+string buf[0:n], nil);
+}
+
+connect(dir: string, res: chan of (string, ref Image, ref Sys->FD))
+{
+ bitpath := dir + "/wb.bit";
+ strokepath := dir + "/strokes";
+
+ sfd := sys->open(strokepath, Sys->ORDWR);
+ if (sfd == nil) {
+ err := sys->sprint("cannot open whiteboard data: %r");
+ res <-= (err, nil, nil);
+ srvfd = nil;
+ return;
+ }
+
+ bfd := sys->open(bitpath, Sys->OREAD);
+ if (bfd == nil) {
+ err := sys->sprint("cannot open whiteboard image: %r");
+ res <-= (err, nil, nil);
+ srvfd = nil;
+ return;
+ }
+
+ img := disp.readimage(bfd);
+ if (img == nil) {
+ err := sys->sprint("cannot read whiteboard image: %r");
+ res <-= (err, nil, nil);
+ srvfd = nil;
+ return;
+ }
+
+ # make sure image is depth 8 (because of image.line() bug)
+ if (img.depth != 8) {
+ nimg := disp.newimage(img.r, Draw->CMAP8, 0, 0);
+ if (nimg == nil) {
+ res <-= ("cannot allocate local image", nil, nil);
+ srvfd = nil;
+ return;
+ }
+ nimg.draw(nimg.r, img, nil, img.r.min);
+ img = nimg;
+ }
+
+ res <-= (nil, img, sfd);
+}
+
+mkpenimgs(win: ref Tk->Toplevel)
+{
+ ZP := Point(0,0);
+ pr := Rect((0,0), (13,14));
+ ir := pr.inset(2);
+ midx := ir.dx()/2 + ir.min.x;
+ start := Point(midx, ir.min.y);
+ end := Point(midx, ir.max.y-1);
+
+ i0 := disp.newimage(pr, Draw->GREY1, 0, Draw->White);
+ i1 := disp.newimage(pr, Draw->GREY1, 0, Draw->Black);
+ i2 := disp.newimage(pr, Draw->GREY1, 0, Draw->Black);
+ i3 := disp.newimage(pr, Draw->GREY1, 0, Draw->Black);
+
+ i0.draw(ir, disp.black, nil, ZP);
+ i1.line(start, end, Draw->Endsquare, Draw->Endsquare, 0, disp.white, ZP);
+ i2.line(start, end, Draw->Endsquare, Draw->Endsquare, 1, disp.white, ZP);
+ i3.line(start, end, Draw->Endsquare, Draw->Endsquare, 2, disp.white, ZP);
+
+ tk->cmd(win, "image create bitmap erase");
+ tk->cmd(win, "image create bitmap pen0");
+ tk->cmd(win, "image create bitmap pen1");
+ tk->cmd(win, "image create bitmap pen2");
+
+ tk->putimage(win, "erase", i0, nil);
+ tk->putimage(win, "pen0", i1, nil);
+ tk->putimage(win, "pen1", i2, nil);
+ tk->putimage(win, "pen2", i3, nil);
+}
+
+reader(fd: ref Sys->FD, sc: chan of (int, int, array of Point))
+{
+ buf := array [Sys->ATOMICIO] of byte;
+
+ for (;;) {
+ n := sys->read(fd, buf, len buf);
+ if (n <= 0) {
+ sc <-= (0, 0, nil);
+ return;
+ }
+ s := string buf[0:n];
+ (npts, toks) := sys->tokenize(s, " ");
+ if (npts & 1)
+ # something wrong
+ npts--;
+ if (npts < 6)
+ # ignore
+ continue;
+
+ colour, width: int;
+ (colour, toks) = (int hd toks, tl toks);
+ (width, toks) = (int hd toks, tl toks);
+ pts := array [(npts - 2)/ 2] of Point;
+ for (i := 0; toks != nil; i++) {
+ x, y: int;
+ (x, toks) = (int hd toks, tl toks);
+ (y, toks) = (int hd toks, tl toks);
+ pts[i] = Point(x, y);
+ }
+ sc <-= (colour, width, pts);
+ pts = nil;
+ }
+}
+
+Wmsg: adt {
+ data: array of byte;
+ datalen: int;
+ next: cyclic ref Wmsg;
+};
+
+writer(fd: ref Sys->FD, sc: chan of (int, int, Point, Point))
+{
+ lastcol := -1;
+ lastw := -1;
+ lastpt := Point(-1, -1);
+ curmsg: ref Wmsg;
+ nextmsg: ref Wmsg;
+
+ eofc := chan of int;
+ wc := chan of ref Wmsg;
+ wseof := 0;
+ spawn wslave(fd, wc, eofc);
+
+ for (;;) {
+ colour := -1;
+ width := 0;
+ p0, p1: Point;
+
+ if (curmsg == nil || wseof)
+ (colour, width, p0, p1) = <-sc;
+ else alt {
+ wseof = <-eofc =>
+ ;
+
+ (colour, width, p0, p1) = <-sc =>
+ ;
+
+ wc <-= curmsg =>
+ curmsg = curmsg.next;
+ continue;
+ }
+
+ newseq := 0;
+ if (curmsg == nil) {
+ curmsg = ref Wmsg(array [Sys->ATOMICIO] of byte, 0, nil);
+ nextmsg = curmsg;
+ newseq = 1;
+ }
+
+ if (colour != lastcol || width != lastw || p0.x != lastpt.x || p0.y != lastpt.y)
+ newseq = 1;
+
+ d: array of byte = nil;
+ if (!newseq) {
+ d = sys->aprint(" %d %d", p1.x, p1.y);
+ if (nextmsg.datalen + len d >= Sys->ATOMICIO) {
+ nextmsg.next = ref Wmsg(array [Sys->ATOMICIO] of byte, 0, nil);
+ nextmsg = nextmsg.next;
+ newseq = 1;
+ }
+ }
+ if (newseq) {
+ d = sys->aprint(" %d %d %d %d %d %d", colour, width, p0.x, p0.y, p1.x, p1.y);
+ if (nextmsg.datalen != 0) {
+ nextmsg.next = ref Wmsg(array [Sys->ATOMICIO] of byte, 0, nil);
+ nextmsg = nextmsg.next;
+ }
+ }
+ nextmsg.data[nextmsg.datalen:] = d;
+ nextmsg.datalen += len d;
+ lastcol = colour;
+ lastw = width;
+ lastpt = p1;
+ }
+}
+
+wslave(fd: ref Sys->FD, wc: chan of ref Wmsg, eof: chan of int)
+{
+ for (;;) {
+ wm := <-wc;
+ n := sys->write(fd, wm.data, wm.datalen);
+ if (n != wm.datalen)
+ break;
+ }
+ eof <-= 1;
+}
+
+drawstroke(img: ref Image, offset, p0, p1: Point, pen: ref Image, width: int)
+{
+ p0 = p0.add(offset);
+ p1 = p1.add(offset);
+ img.line(p0, p1, Draw->Enddisc, Draw->Enddisc, width, pen, p0);
+}
+
+drawstrokes(img: ref Image, offset: Point, pen: ref Image, width: int, pts: array of Point)
+{
+ if (len pts < 2)
+ return;
+ p0, p1: Point;
+ p0 = pts[0].add(offset);
+ for (i := 1; i < len pts; i++) {
+ p1 = pts[i].add(offset);
+ img.line(p0, p1, Draw->Enddisc, Draw->Enddisc, width, pen, p0);
+ p0 = p1;
+ }
+}
+
+badmod(mod: string)
+{
+ sys->fprint(stderr, "cannot load %s: %r\n", mod);
+ raise "fail:bad module";
+}
+
+tkcmd(t: ref Tk->Toplevel, cmd: string): string
+{
+ s := tk->cmd(t, cmd);
+ if (s != nil && s[0] == '!') {
+ sys->fprint(stderr, "%s\n", cmd);
+ sys->fprint(stderr, "tk error: %s\n", s);
+ }
+ return s;
+}
+
+tkcmds(t: ref Tk->Toplevel, cmds: array of string)
+{
+ for (i := 0; i < len cmds; i++)
+ tkcmd(t, cmds[i]);
+}
diff --git a/appl/demo/whiteboard/whiteboard.dis b/appl/demo/whiteboard/whiteboard.dis
new file mode 100644
index 00000000..f777f1a6
--- /dev/null
+++ b/appl/demo/whiteboard/whiteboard.dis
Binary files differ
diff --git a/appl/demo/whiteboard/whiteboard.sbl b/appl/demo/whiteboard/whiteboard.sbl
new file mode 100644
index 00000000..395232c1
--- /dev/null
+++ b/appl/demo/whiteboard/whiteboard.sbl
@@ -0,0 +1,1880 @@
+limbo .sbl 2.1
+Whiteboard
+5
+whiteboard.b
+sys.m
+draw.m
+tk.m
+tkclient.m
+1392
+54.1,25 0
+55.1,29 1
+11,23 1
+25,28 1
+1,29 1
+1,29 1
+56.1,24 2
+22,23 2
+1,24 2
+1,24 2
+58.1,28 3
+59.1,22 4
+61.1,40 5
+62.5,20 6
+63.2,24 7
+9,23 7
+2,24 7
+65.1,15 8
+66.1,18 9
+67.4,15 10
+68.24,31 11
+33,40 11
+3,13 11
+15,19 11
+15,19 12
+15,19 13
+70.1,20 14
+71.5,16 15
+72.2,44 16
+14,20 16
+22,43 16
+2,44 16
+2,44 16
+73.2,19 17
+75.1,16 18
+77.1,17 19
+1,17 19
+78.18,64 20
+37,41 20
+43,46 20
+48,60 20
+62,63 20
+18,64 20
+18,64 20
+79.24,50 21
+30,33 21
+35,49 21
+24,50 21
+24,50 21
+1,51 21
+18,22 21
+18,22 21
+18,22 22
+1,51 21
+1,51 21
+80.4,15 23
+81.2,37 24
+19,23 24
+25,36 24
+2,37 24
+2,37 24
+82.1,22 25
+83.1,30 26
+14,17 26
+19,22 26
+24,29 26
+1,30 26
+1,30 26
+1,30 27
+84.1,15 28
+11,14 28
+1,15 28
+85.1,21 29
+8,11 29
+13,20 29
+1,21 29
+86.1,29 30
+20,23 30
+25,28 30
+1,29 30
+87.1,49 31
+22,25 31
+45,48 31
+36,48 31
+27,48 31
+27,48 31
+27,48 32
+1,49 31
+88.1,25 33
+21,24 33
+1,25 33
+1,25 33
+90.1,38 34
+91.1,47 35
+92.1,15 36
+95.1,34 37
+10,16 37
+18,33 37
+1,34 37
+96.1,30 38
+15,25 38
+27,29 38
+1,30 38
+102.27,29 39
+27,29 39
+108.8,14 39
+8,14 39
+109.7,15 39
+7,15 39
+110.7,15 39
+7,19 39
+7,19 40
+7,19 39
+117.8,16 39
+8,20 39
+8,20 41
+8,20 39
+119.8,16 39
+8,20 39
+8,20 42
+8,20 39
+101.10,16 39
+10,16 39
+10,16 39
+10,16 39
+102.2,5 39
+7,16 39
+18,21 39
+18,21 43
+18,21 44
+18,21 45
+103.6,16 46
+104.3,8 47
+106.3,36 48
+12,18 48
+20,35 48
+3,36 48
+3,36 39
+3,36 39
+3,36 39
+111.2,21 49
+112.2,31 50
+24,27 50
+29,30 50
+2,31 50
+2,31 50
+113.5,9 51
+5,16 51
+20,30 51
+34,53 51
+114.3,26 52
+22,25 52
+3,26 52
+3,26 52
+115.3,36 53
+12,18 53
+20,35 53
+3,36 53
+3,36 54
+3,36 55
+3,36 39
+118.2,22 56
+14,17 56
+19,21 56
+2,22 56
+2,22 57
+2,22 39
+120.2,22 58
+15,18 58
+20,21 58
+2,22 58
+2,22 39
+123.44,60 59
+44,55 59
+44,60 59
+44,60 59
+37,60 59
+12,60 59
+1,61 59
+7,10 59
+7,10 59
+7,10 60
+1,61 59
+1,61 59
+1,61 61
+124.45,61 62
+45,56 62
+45,61 62
+45,61 62
+38,61 62
+12,61 62
+1,62 62
+7,10 62
+7,10 62
+7,10 63
+1,62 62
+1,62 62
+1,62 64
+125.1,25 65
+8,11 65
+13,24 65
+1,25 65
+126.1,21 66
+7,10 66
+12,20 66
+1,21 66
+1,21 66
+1,21 67
+127.1,55 68
+1,7 68
+13,21 68
+23,32 68
+34,37 68
+39,54 68
+1,55 68
+129.1,48 69
+130.1,47 70
+131.1,29 71
+14,17 71
+19,28 71
+1,29 71
+132.1,30 72
+14,17 72
+19,29 72
+1,30 72
+134.1,13 73
+137.1,15 74
+138.1,20 75
+139.1,85 76
+13,17 76
+38,39 76
+40,41 76
+50,51 76
+52,53 76
+2:90.18,31 76
+0:139.70,71 76
+73,84 76
+1,85 76
+1,85 76
+140.1,25 77
+141.1,14 78
+142.1,11 79
+143.1,82 80
+12,16 80
+37,38 80
+39,40 80
+49,50 80
+51,52 80
+2:90.18,31 80
+0:143.69,70 80
+72,81 80
+1,82 80
+1,82 80
+146.8,14 81
+8,14 81
+147.7,15 81
+7,19 81
+7,19 82
+7,19 81
+148.7,15 81
+7,15 81
+155.8,16 81
+8,20 81
+8,20 83
+8,20 81
+157.8,16 81
+8,20 81
+8,20 84
+8,20 81
+159.31,40 81
+31,40 81
+168.8,11 81
+8,11 81
+145.10,16 81
+10,16 81
+10,16 81
+10,16 81
+10,16 81
+10,16 81
+149.2,21 85
+150.2,31 86
+24,27 86
+29,30 86
+2,31 86
+2,31 86
+151.5,9 87
+5,16 87
+20,30 87
+34,53 87
+152.3,26 88
+22,25 88
+3,26 88
+3,26 88
+153.3,57 89
+3,9 89
+15,23 89
+25,34 89
+36,39 89
+41,56 89
+3,57 89
+3,57 90
+3,57 91
+3,57 81
+156.2,22 92
+14,17 92
+19,21 92
+2,22 92
+2,22 93
+2,22 81
+158.2,22 94
+15,18 94
+20,21 94
+2,22 94
+2,22 81
+159.29,40 81
+29,40 95
+160.6,20 96
+161.3,55 97
+22,25 97
+27,54 97
+3,55 97
+3,55 97
+3,55 98
+3,55 99
+163.3,77 100
+10,14 100
+35,36 100
+37,38 100
+47,48 100
+49,50 100
+2:90.18,31 100
+0:163.67,68 100
+70,76 100
+3,77 100
+3,77 100
+164.3,57 101
+15,21 101
+23,35 101
+37,40 101
+42,47 101
+49,56 101
+3,57 101
+165.3,63 102
+15,24 102
+26,41 102
+43,46 102
+48,53 102
+55,62 102
+3,63 102
+3,63 103
+3,63 104
+3,63 105
+3,63 81
+169.17,38 106
+31,32 106
+34,37 106
+17,38 106
+17,38 106
+8,12 106
+8,12 107
+170.2,19 108
+171.7,13 109
+174.3,17 110
+175.12,19 111
+3,19 111
+3,19 112
+176.15,22 113
+12,22 113
+3,22 113
+3,22 114
+177.7,23 115
+178.9,16 116
+179.5,16 117
+180.16,17 118
+19,20 118
+19,20 119
+19,20 120
+19,20 121
+19,20 122
+181.5,13 123
+184.4,15 124
+185.14,15 125
+17,18 125
+186.7,14 126
+18,30 126
+34,46 126
+34,46 127
+34,46 128
+34,46 129
+34,46 130
+187.4,12 131
+188.3,17 132
+189.3,22 133
+190.3,20 134
+191.7,12 135
+192.4,18 136
+193.4,24 137
+194.4,22 138
+196.3,55 139
+14,20 139
+22,34 139
+36,38 139
+40,42 139
+44,47 139
+49,54 139
+3,55 139
+197.3,61 140
+14,23 140
+25,40 140
+42,44 140
+46,48 140
+50,53 140
+55,60 140
+3,61 140
+198.19,25 141
+27,32 141
+34,36 141
+38,40 141
+3,41 141
+199.3,10 142
+3,10 143
+3,10 109
+202.3,14 144
+203.8,17 145
+204.4,25 146
+21,24 146
+4,25 146
+4,25 109
+206.3,14 147
+207.3,16 148
+208.3,17 149
+209.7,18 150
+7,18 151
+7,18 152
+7,18 153
+7,18 154
+211.4,12 155
+212.3,12 156
+213.3,60 157
+9,12 157
+44,59 157
+14,59 157
+14,59 158
+3,60 157
+3,60 157
+3,60 159
+214.3,23 160
+9,12 160
+14,22 160
+3,23 160
+3,23 160
+3,23 161
+215.19,26 162
+3,26 162
+3,26 163
+216.3,17 164
+217.3,22 165
+218.3,83 166
+13,17 166
+38,39 166
+40,41 166
+50,51 166
+52,53 166
+2:90.18,31 166
+0:218.70,71 166
+73,82 166
+3,83 166
+3,83 166
+219.3,85 167
+9,12 167
+14,49 167
+14,73 167
+14,84 167
+14,84 168
+3,85 167
+3,85 167
+3,85 169
+220.3,23 170
+9,12 170
+14,22 170
+3,23 170
+3,23 170
+3,23 171
+3,23 172
+3,23 109
+223.3,14 173
+224.11,18 174
+3,18 174
+3,18 175
+225.3,10 176
+226.7,19 177
+227.4,13 178
+228.4,15 179
+4,15 180
+230.4,13 181
+231.4,20 182
+232.4,15 183
+234.3,43 184
+9,12 184
+14,42 184
+3,43 184
+3,43 184
+3,43 185
+235.3,23 186
+9,12 186
+14,22 186
+3,23 186
+3,23 186
+3,23 187
+3,23 188
+3,23 189
+3,23 109
+3,23 190
+3,23 191
+3,23 192
+3,23 81
+243.4,20 193
+244.9,12 194
+2,12 194
+245.1,62 195
+24,33 195
+35,44 195
+35,52 195
+35,58 195
+35,58 196
+60,61 195
+1,62 195
+1,62 195
+246.20,50 197
+29,32 197
+34,38 197
+40,49 197
+20,50 197
+20,50 197
+1,80 197
+6,9 197
+6,9 197
+52,65 197
+67,79 197
+1,80 197
+1,80 197
+247.8,9 198
+1,9 198
+252.1,11 199
+253.11,22 200
+1,36 200
+254.1,37 201
+1,4 201
+10,11 201
+13,23 201
+25,28 201
+31,32 201
+34,35 201
+1,37 201
+255.1,45 202
+1,4 202
+10,15 202
+17,27 202
+30,31 202
+33,34 202
+37,41 202
+43,44 202
+1,45 202
+1,45 202
+256.0,1 203
+282.16,77 204
+35,43 204
+45,48 204
+50,62 204
+64,76 204
+16,77 204
+16,77 204
+283.1,22 205
+284.1,28 206
+14,15 206
+17,20 206
+22,27 206
+1,28 206
+1,28 206
+1,28 207
+285.1,22 208
+8,9 208
+11,21 208
+1,22 208
+286.1,45 209
+7,8 209
+10,44 209
+1,45 209
+1,45 209
+1,45 210
+287.1,19 211
+7,8 211
+10,18 211
+1,19 211
+1,19 211
+1,19 212
+288.1,34 213
+20,21 213
+23,33 213
+1,34 213
+289.1,47 214
+22,23 214
+43,46 214
+34,46 214
+25,46 214
+25,46 214
+25,46 215
+1,47 214
+291.22,50 216
+31,32 216
+34,38 216
+40,49 216
+22,50 216
+22,50 216
+1,51 216
+13,20 216
+13,20 216
+1,51 216
+294.8,14 217
+8,18 217
+8,18 218
+8,18 217
+296.8,14 217
+8,18 217
+8,18 219
+8,18 217
+298.8,14 217
+8,14 217
+299.7,13 217
+7,17 217
+7,17 220
+7,17 217
+300.7,13 217
+7,13 217
+315.12,15 217
+12,15 217
+293.9,15 217
+9,15 217
+9,15 217
+9,15 217
+295.2,20 221
+14,15 221
+17,19 221
+2,20 221
+2,20 222
+2,20 217
+297.2,20 223
+15,16 223
+18,19 223
+2,20 223
+2,20 217
+301.7,8 224
+7,8 224
+7,8 224
+303.9,31 225
+9,37 225
+9,52 225
+3,52 225
+3,52 226
+304.3,9 227
+306.3,17 228
+307.3,9 229
+309.3,22 230
+310.3,29 231
+24,25 231
+27,28 231
+3,29 231
+3,29 231
+311.6,10 232
+6,17 232
+21,29 232
+33,52 232
+312.25,53 233
+34,35 233
+37,41 233
+43,52 233
+25,53 233
+25,53 233
+4,54 233
+16,23 233
+16,23 233
+4,54 233
+4,54 234
+4,54 235
+4,54 224
+4,54 236
+4,54 217
+316.15,40 237
+29,34 237
+36,39 237
+15,40 237
+15,40 237
+3,4 237
+6,10 237
+6,10 238
+317.7,14 239
+7,14 239
+319.73,93 240
+82,83 240
+85,89 240
+91,92 240
+73,93 240
+73,93 240
+73,100 240
+73,100 240
+73,100 240
+73,100 240
+32,101 240
+45,52 240
+42,52 240
+38,52 240
+38,52 241
+64,71 240
+61,71 240
+58,71 240
+54,71 240
+54,71 242
+54,71 240
+32,101 240
+32,101 240
+4,14 240
+16,28 240
+16,28 243
+16,28 244
+320.3,47 245
+9,10 245
+12,46 245
+3,47 245
+3,47 245
+3,47 246
+3,47 239
+3,47 247
+3,47 248
+3,47 217
+328.24,25 249
+26,27 249
+30,37 249
+30,32 249
+30,37 249
+30,37 249
+38,45 249
+38,40 249
+38,45 249
+38,45 249
+38,48 249
+38,50 249
+1,72 249
+8,12 249
+8,12 249
+2:90.18,31 249
+0:328.67,68 249
+70,71 249
+1,72 249
+1,72 249
+329.4,14 250
+330.2,8 251
+331.14,24 252
+14,19 252
+14,24 252
+14,24 252
+25,35 252
+25,30 252
+25,35 252
+25,35 252
+14,35 252
+1,44 252
+332.1,14 253
+7,9 253
+1,14 253
+1,14 253
+333.1,14 254
+7,9 254
+1,14 254
+1,14 254
+334.5,9 255
+11,15 256
+335.9,19 257
+9,14 257
+9,19 257
+9,19 257
+6,21 257
+23,27 258
+336.3,9 259
+18,22 259
+23,29 259
+23,32 259
+17,33 259
+3,33 259
+335.29,32 260
+29,32 260
+337.9,19 261
+9,14 261
+9,19 261
+9,19 261
+6,21 261
+23,27 262
+338.7,11 263
+16,19 263
+16,25 263
+3,25 263
+3,25 264
+337.29,32 265
+29,32 265
+339.2,29 266
+2,5 266
+18,23 266
+25,28 266
+2,29 266
+2,29 266
+341.2,20 267
+342.2,20 268
+343.21,27 269
+21,30 269
+2,30 269
+344.25,30 270
+21,31 270
+21,34 270
+2,34 270
+345.2,34 271
+2,5 271
+11,12 271
+14,17 271
+19,22 271
+24,33 271
+2,34 271
+334.17,20 272
+17,20 272
+347.0,1 273
+351.5,11 274
+1,18 274
+352.5,11 275
+1,18 275
+353.8,12 276
+1,14 276
+354.14,32 277
+14,18 277
+28,31 277
+14,32 277
+14,32 277
+355.1,45 278
+20,35 278
+37,38 278
+40,41 278
+43,44 278
+1,45 278
+1,45 278
+356.16,35 279
+16,20 279
+31,34 279
+16,35 279
+16,35 279
+9,35 279
+37,40 279
+1,41 279
+376.1,27 280
+377.1,31 281
+379.1,41 282
+18,28 282
+30,40 282
+1,41 282
+1,41 282
+380.5,15 283
+381.2,55 284
+21,54 284
+2,55 284
+2,55 284
+382.11,14 285
+16,19 285
+21,24 285
+2,25 285
+2,25 286
+2,25 287
+2,25 288
+383.2,13 289
+384.2,8 290
+387.1,38 291
+18,25 291
+27,37 291
+1,38 291
+1,38 291
+388.5,15 292
+389.2,56 293
+21,55 293
+2,56 293
+2,56 293
+390.11,14 294
+16,19 294
+21,24 294
+2,25 294
+2,25 295
+2,25 296
+2,25 297
+391.2,13 298
+392.2,8 299
+395.1,27 300
+8,12 300
+23,26 300
+1,27 300
+1,27 300
+396.5,15 301
+397.2,56 302
+21,55 302
+2,56 302
+2,56 302
+398.11,14 303
+16,19 303
+21,24 303
+2,25 303
+2,25 304
+2,25 305
+2,25 306
+399.2,13 307
+400.2,8 308
+404.5,19 309
+405.2,49 310
+10,14 310
+24,29 310
+2:90.18,31 310
+0:405.44,45 310
+47,48 310
+2,49 310
+2,49 310
+406.6,17 311
+407.12,41 312
+43,46 312
+48,51 312
+3,52 312
+3,52 313
+3,52 314
+3,52 315
+408.3,14 316
+409.3,9 317
+411.2,40 318
+2,6 318
+12,18 318
+20,23 318
+25,28 318
+30,39 318
+2,40 318
+412.2,12 319
+2,12 320
+415.10,13 321
+15,18 321
+20,23 321
+1,24 321
+1,24 322
+1,24 323
+1,24 324
+416.0,1 325
+420.13,14 326
+15,16 326
+421.13,14 327
+15,16 327
+20,22 327
+23,25 327
+422.1,18 328
+7,9 328
+16,17 328
+1,18 328
+1,18 328
+423.9,16 329
+9,11 329
+9,16 329
+9,16 329
+9,18 329
+1,29 329
+424.16,20 330
+22,30 330
+425.14,18 331
+20,30 331
+427.1,53 332
+7,11 332
+21,23 332
+2:86.18,32 332
+0:427.38,39 332
+41,52 332
+1,53 332
+1,53 332
+428.1,53 333
+7,11 333
+21,23 333
+2:86.18,32 333
+0:428.38,39 333
+41,52 333
+1,53 333
+1,53 333
+429.1,53 334
+7,11 334
+21,23 334
+2:86.18,32 334
+0:429.38,39 334
+41,52 334
+1,53 334
+1,53 334
+430.1,53 335
+7,11 335
+21,23 335
+2:86.18,32 335
+0:430.38,39 335
+41,52 335
+1,53 335
+1,53 335
+432.1,33 336
+1,3 336
+9,11 336
+13,23 336
+25,28 336
+30,32 336
+1,33 336
+433.1,73 337
+1,3 337
+9,14 337
+16,19 337
+21,36 337
+38,53 337
+55,56 337
+58,68 337
+70,72 337
+1,73 337
+434.1,73 338
+1,3 338
+9,14 338
+16,19 338
+21,36 338
+38,53 338
+55,56 338
+58,68 338
+70,72 338
+1,73 338
+435.1,73 339
+1,3 339
+9,14 339
+16,19 339
+21,36 339
+38,53 339
+55,56 339
+58,68 339
+70,72 339
+1,73 339
+437.1,42 340
+9,12 340
+14,41 340
+1,42 340
+1,42 340
+1,42 341
+438.1,41 342
+9,12 342
+14,40 342
+1,41 342
+1,41 342
+1,41 343
+439.1,41 344
+9,12 344
+14,40 344
+1,41 344
+1,41 344
+1,41 345
+440.1,41 346
+9,12 346
+14,40 346
+1,41 346
+1,41 346
+1,41 347
+442.1,36 348
+14,17 348
+19,26 348
+28,30 348
+32,35 348
+1,36 348
+1,36 348
+1,36 349
+443.1,35 350
+14,17 350
+19,25 350
+27,29 350
+31,34 350
+1,35 350
+1,35 350
+1,35 351
+444.1,35 352
+14,17 352
+19,25 352
+27,29 352
+31,34 352
+1,35 352
+1,35 352
+1,35 353
+445.1,35 354
+14,17 354
+19,25 354
+27,29 354
+31,34 354
+1,35 354
+1,35 354
+1,35 355
+446.0,1 356
+450.1,37 357
+453.2,34 358
+17,19 358
+21,24 358
+26,33 358
+2,34 358
+2,34 358
+454.6,12 359
+455.11,12 360
+14,15 360
+17,20 360
+3,21 360
+3,21 361
+456.3,9 362
+458.14,17 363
+14,22 363
+2,22 363
+2,22 364
+459.18,39 365
+32,33 365
+35,38 365
+18,39 365
+18,39 365
+3,7 365
+9,13 365
+9,13 366
+460.6,14 367
+6,14 367
+462.3,9 368
+463.6,14 369
+6,14 370
+6,14 371
+6,14 372
+465.3,11 373
+468.24,31 374
+20,31 374
+20,31 375
+33,40 374
+3,9 374
+11,15 374
+11,15 376
+469.23,30 377
+19,30 377
+19,30 378
+32,39 377
+3,8 377
+10,14 377
+10,14 379
+470.16,26 380
+16,29 380
+2,39 380
+471.7,13 381
+15,26 382
+473.20,27 383
+16,27 383
+16,27 384
+29,36 383
+4,5 383
+7,11 383
+7,11 385
+474.20,27 386
+16,27 386
+16,27 387
+29,36 386
+4,5 386
+7,11 386
+7,11 388
+475.18,19 389
+21,22 389
+3,9 389
+3,23 389
+471.28,31 390
+28,31 390
+477.10,16 391
+18,23 391
+25,28 391
+2,29 391
+2,29 392
+478.2,11 393
+2,11 394
+2,11 395
+2,11 396
+2,11 396
+490.1,14 397
+491.1,12 398
+492.17,19 399
+21,23 399
+496.1,20 400
+497.1,23 401
+498.1,11 402
+499.1,27 403
+14,16 403
+18,20 403
+22,26 403
+1,27 403
+502.2,14 404
+503.2,12 405
+506.6,19 406
+23,28 406
+507.29,33 407
+4,10 407
+12,17 407
+19,21 407
+23,25 407
+23,25 408
+509.12,16 409
+12,16 409
+512.30,32 409
+30,32 409
+515.2,4 409
+2,4 409
+508.7,13 409
+7,13 409
+7,13 409
+7,13 409
+7,13 409
+512.3,9 409
+11,16 409
+18,20 409
+22,24 409
+22,24 409
+516.3,23 410
+3,23 411
+517.3,11 412
+520.2,13 413
+521.6,19 414
+522.3,59 415
+21,50 415
+52,53 415
+55,58 415
+3,59 415
+3,59 416
+523.3,19 417
+524.3,13 418
+527.6,23 419
+27,41 419
+45,61 419
+65,81 419
+528.3,13 420
+530.21,24 421
+531.7,13 422
+532.3,40 423
+19,27 423
+29,33 423
+35,39 423
+3,40 423
+3,40 423
+533.25,30 424
+7,22 424
+7,30 424
+7,47 424
+534.4,66 425
+28,57 425
+59,60 425
+62,65 425
+4,66 425
+4,66 426
+535.4,26 427
+536.4,14 428
+539.6,12 429
+540.3,79 430
+19,39 430
+41,47 430
+49,54 430
+56,60 430
+62,66 430
+68,72 430
+74,78 430
+3,79 430
+3,79 430
+541.7,27 431
+542.4,66 432
+28,57 432
+59,60 432
+62,65 432
+4,66 432
+4,66 433
+543.4,26 434
+546.15,30 435
+2,36 435
+547.21,26 436
+2,26 436
+548.2,18 437
+549.2,15 438
+550.2,13 439
+2,13 440
+2,13 440
+557.2,12 441
+558.2,42 442
+18,20 442
+22,29 442
+31,41 442
+2,42 442
+2,42 442
+559.6,21 443
+6,21 444
+560.3,8 445
+3,8 446
+3,8 446
+562.1,10 447
+563.0,1 448
+567.1,20 449
+6,8 449
+13,19 449
+1,20 449
+1,20 449
+568.1,20 450
+6,8 450
+13,19 450
+1,20 450
+1,20 450
+569.1,63 451
+1,4 451
+10,12 451
+14,16 451
+18,31 451
+33,46 451
+48,53 451
+55,58 451
+60,62 451
+1,63 451
+570.0,1 452
+574.5,12 453
+5,16 453
+575.2,8 454
+577.1,24 455
+6,12 455
+6,12 455
+17,23 455
+1,24 455
+1,24 455
+578.6,12 456
+18,25 457
+14,25 457
+579.2,25 458
+7,13 458
+7,13 458
+18,24 458
+2,25 458
+2,25 458
+580.2,64 459
+2,5 459
+11,13 459
+15,17 459
+19,32 459
+34,47 459
+49,54 459
+56,59 459
+61,63 459
+2,64 459
+581.2,9 460
+578.27,30 461
+27,30 461
+583.0,1 462
+587.1,49 463
+13,19 463
+21,43 463
+45,48 463
+1,49 463
+1,49 463
+588.1,24 464
+593.1,21 465
+14,15 465
+17,20 465
+1,21 465
+1,21 465
+594.5,13 466
+17,21 466
+17,28 466
+595.2,34 467
+14,20 467
+22,28 467
+30,33 467
+2,34 467
+2,34 467
+596.2,42 468
+14,20 468
+22,38 468
+40,41 468
+2,42 468
+2,42 468
+598.8,9 469
+1,9 469
+603.6,12 470
+18,26 471
+14,26 471
+604.2,19 472
+8,9 472
+11,18 472
+11,18 472
+2,19 472
+2,19 472
+2,19 473
+603.28,31 474
+28,31 474
+605.0,1 475
+15
+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->Context 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
+
+
+
+aDraw->Display 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@3
+
+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
+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
+
+aWmsg 0:482.0,486.1 12
+3
+0:data:483.1,5 Ab
+4:datalen:484.1,8 i
+8:next:485.1,5 R@13
+
+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@4
+
+16
+0:init
+2
+32:ctxt:0:52.5,9 R@3
+
+36:args:30,34 Ls
+46
+40:win:78.2,5 R@12
+
+44:winctl:7,13 Cs
+48:cimage:88.1,7 R@5
+
+52:toks:169.8,12 Ls
+56:strokeimg:99.1,10 R@5
+
+60:err:98.1,4 s
+64:erase:142.1,6 i
+68:pencolour:140.1,10 i
+72:s:108.1,2 s
+76:s:146.1,2 s
+80:width:190.3,8 i
+84:cmd:82.1,4 Cs
+88:i:225.3,4 s
+92:p:224.3,4 s
+96:pen:188.3,6 R@5
+
+100:penwidth:141.1,9 i
+104:action:170.2,8 s
+108:cc:91.1,3 Ct12.3
+0:t0:16,22 s
+4:t1:16,22 R@5
+
+8:t2:16,22 R@11
+
+
+112:colour:189.3,9 i
+116:drawpen:143.1,8 R@5
+
+120:getcolour:137.1,10 i
+124:pen:163.3,6 R@5
+
+128:servicedir:66.1,11 s
+132:sfd:93.1,4 R@11
+
+136:strokesin:129.1,10 Ct12.3
+0:t0:23,26 i
+4:t1:23,26 i
+8:t2:23,26 A@7
+
+
+140:strokesout:130.1,11 Ct24.4
+0:t0:24,27 i
+4:t1:24,27 i
+8:t2:24,27 @7
+
+16:t3:24,27 @7
+
+
+144:tkcolour:217.3,11 s
+148:y:176.3,4 i
+152:c:119.1,2 i
+156:c:157.1,2 i
+160:c:168.1,2 s
+164:colour:159.2,8 i
+168:width:10,15 i
+172:strokes:17,24 A@7
+
+176:oldimg:111.2,8 R@5
+
+180:oldimg:149.2,8 R@5
+
+184:p:117.1,2 R@10
+
+188:p:155.1,2 R@10
+
+192:whitepen:139.1,9 R@5
+
+216:connected:92.1,10 i
+220:sc:90.1,3 CAt16.2
+0:t0:25,30 @7
+
+8:t1:25,30 @7
+
+
+224:white:138.1,6 R@5
+
+228:p0:135.1,3 @7
+
+236:p1:5,7 @7
+
+152:pendown:134.1,8 i
+156:x:175.3,4 i
+n516:makeimage
+1
+32:win:241.10,13 R@12
+
+2
+36:scr:245.1,4 R@8
+
+40:w:246.1,2 R@5
+
+R@5
+543:showtext
+2
+32:img:250.9,12 R@5
+
+36:s:25,26 s
+1
+44:r:252.1,2 @6
+
+n565:colourmenu
+1
+32:c:280.11,12 Cs
+11
+36:t:282.2,3 R@12
+
+40:winctl:5,11 Cs
+44:s:298.1,2 s
+48:cmd:283.1,4 Cs
+52:e:310.3,4 s
+56:oldimage:309.3,11 R@5
+
+60:p:294.1,2 R@10
+
+64:press:315.1,6 s
+68:s:296.1,2 i
+88:n:316.3,4 i
+92:word:6,10 Ls
+n734:drawcolours
+2
+32:img:325.12,15 R@5
+
+36:cr:28,30 @6
+
+8
+52:tmp:328.1,4 R@5
+
+56:y:334.5,6 i
+60:buf:331.1,4 Ab
+64:i:335.6,7 i
+68:dx:332.1,3 i
+72:k:337.6,7 i
+76:dy:333.1,3 i
+96:r:340.2,3 @6
+
+n828:color
+3
+32:x:349.6,7 i
+36:y:9,10 i
+40:size:17,21 @7
+
+5
+48:col:353.1,4 i
+52:r:354.2,3 i
+56:g:5,6 i
+60:b:8,9 i
+64:tks:355.1,4 s
+t8.2
+0:t0:349.32,38 s
+4:t1:32,38 s
+854:connect
+2
+32:dir:374.8,11 s
+36:res:21,24 Ct12.3
+0:t0:35,41 s
+4:t1:35,41 R@5
+
+8:t2:35,41 R@11
+
+
+9
+40:img:395.1,4 R@5
+
+44:nimg:405.2,6 R@5
+
+48:bfd:387.1,4 R@11
+
+52:sfd:379.1,4 R@11
+
+56:bitpath:376.1,8 s
+60:err:381.2,5 s
+64:err:389.2,5 s
+68:err:397.2,5 s
+72:strokepath:377.1,11 s
+n949:mkpenimgs
+1
+32:win:418.10,13 R@12
+
+10
+36:i0:427.1,3 R@5
+
+40:i1:428.1,3 R@5
+
+44:i2:429.1,3 R@5
+
+48:i3:430.1,3 R@5
+
+52:midx:423.1,5 i
+68:ir:422.1,3 @6
+
+84:pr:421.1,3 @6
+
+100:ZP:420.1,3 @7
+
+108:end:425.1,4 @7
+
+116:start:424.1,6 @7
+
+n1096:reader
+2
+32:fd:448.7,9 R@11
+
+36:sc:24,26 Ct12.3
+0:t0:37,40 i
+4:t1:37,40 i
+8:t2:37,40 A@7
+
+
+11
+40:npts:459.3,7 i
+44:toks:9,13 Ls
+48:buf:450.1,4 Ab
+52:pts:470.2,5 A@7
+
+56:i:471.7,8 i
+60:n:453.2,3 i
+64:colour:467.2,8 i
+68:s:458.2,3 s
+72:width:467.10,15 i
+76:x:472.3,4 i
+80:y:6,7 i
+n1179:writer
+2
+32:fd:488.7,9 R@11
+
+36:sc:24,26 Ct24.4
+0:t0:37,40 i
+4:t1:37,40 i
+8:t2:37,40 @7
+
+16:t3:37,40 @7
+
+
+14
+40:nextmsg:494.1,8 R@13
+
+44:curmsg:493.1,7 R@13
+
+48:colour:502.2,8 i
+52:d:530.2,3 Ab
+56:newseq:520.2,8 i
+60:width:503.2,7 i
+64:eofc:496.1,5 Ci
+68:lastcol:490.1,8 i
+72:lastw:491.1,6 i
+76:wc:497.1,3 CR@13
+
+80:wseof:498.1,6 i
+96:p1:504.6,8 @7
+
+104:p0:2,4 @7
+
+112:lastpt:492.1,7 @7
+
+n1283:wslave
+3
+32:fd:554.7,9 R@11
+
+36:wc:24,26 CR@13
+
+40:eof:46,49 Ci
+2
+44:wm:557.2,4 R@13
+
+48:n:558.2,3 i
+n1297:drawstroke
+6
+32:img:565.11,14 R@5
+
+36:offset:27,33 @7
+
+44:p0:35,37 @7
+
+52:p1:39,41 @7
+
+60:pen:50,53 R@5
+
+64:width:66,71 i
+0
+n1318:drawstrokes
+5
+32:img:572.12,15 R@5
+
+36:offset:28,34 @7
+
+44:pen:43,46 R@5
+
+48:width:59,64 i
+52:pts:71,74 A@7
+
+3
+56:i:578.6,7 i
+68:p0:576.1,3 @7
+
+76:p1:5,7 @7
+
+n1350:badmod
+1
+32:mod:585.7,10 s
+0
+n1357:tkcmd
+2
+32:t:591.6,7 R@12
+
+36:cmd:27,30 s
+1
+40:s:593.1,2 s
+s1379:tkcmds
+2
+32:t:601.7,8 R@12
+
+36:cmds:28,32 As
+1
+40:i:603.6,7 i
+n12
+360:colourcmds:267.0,10 As
+368:disp:25.0,4 R@4
+
+376:draw:7.1,5 mDraw
+2:1.0,298.1 0
+
+380:drawctxt:0:27.0,8 R@3
+
+396:font:26.0,4 R@14
+
+456:srvfd:24.0,5 R@11
+
+460:stderr:23.0,6 R@11
+
+464:sys:4.1,4 mSys
+1:0,160.1 0
+
+468:tk:0:11.1,3 mTk
+3:1.0,25.1 0
+
+476:tkclient:0:14.1,9 mTkclient
+4:1.0,26.1 0
+
+480:tkconnected:0:46.0,11 As
+484:tksetup:29.0,7 As