~ubuntu-branches/ubuntu/trusty/argyll/trusty-proposed

« back to all changes in this revision

Viewing changes to spectro/instappsup.c

  • Committer: Package Import Robot
  • Author(s): Artur Rona
  • Date: 2014-02-12 00:35:39 UTC
  • mfrom: (13.1.24 sid)
  • Revision ID: package-import@ubuntu.com-20140212003539-24tautzlitsiz61w
Tags: 1.5.1-5ubuntu1
* Merge from Debian unstable. (LP: #1275572) Remaining changes:
  - debian/control:
    + Build-depend on libtiff-dev rather than libtiff4-dev.
  - debian/control, debian/patches/06_fix_udev_rule.patch:
    + Fix udev rules to actually work; ENV{ACL_MANAGE} has
      stopped working ages ago, and with logind it's now the
      "uaccess" tag. Dropping also consolekit from Recommends.
  - debian/patches/drop-usb-db.patch:
    + Use hwdb builtin, instead of the obsolete usb-db
      in the udev rules.
* debian/patches/05_ftbfs-underlinkage.diff:
  - Dropped change, no needed anymore.
* Refresh the patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
 /* Instrument command line application support functions */
 
3
 
 
4
/* 
 
5
 * Argyll Color Correction System
 
6
 *
 
7
 * Author: Graeme W. Gill
 
8
 * Date:   10/3/2001
 
9
 *
 
10
 * Copyright 2001 - 2013 Graeme W. Gill
 
11
 * All rights reserved.
 
12
 *
 
13
 * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
 
14
 * see the License2.txt file for licencing details.
 
15
 */
 
16
 
 
17
#include <stdio.h>
 
18
#include <stdlib.h>
 
19
#include <stdarg.h>
 
20
#include <ctype.h>
 
21
#include <string.h>
 
22
#include <time.h>
 
23
#ifndef SALONEINSTLIB
 
24
#include "copyright.h"
 
25
#include "aconfig.h"
 
26
#else
 
27
#include "sa_config.h"
 
28
#endif /* !SALONEINSTLIB */
 
29
#include "numsup.h"
 
30
#include "xspect.h"
 
31
#include "conv.h"
 
32
#include "insttypes.h"
 
33
 
 
34
#include "icoms.h"
 
35
#include "inst.h"
 
36
#include "insttypeinst.h"
 
37
#include "instappsup.h"
 
38
 
 
39
/* ================================================================= */
 
40
/* a default user interaction handler */
 
41
 
 
42
typedef struct _uicontext {
 
43
        int emit_ret;                           /* Emit \n on inst_triggered */
 
44
        int cut;                                        /* The character that caused the termination */
 
45
        int uih[256];                           /* User interrupt handling key table. Value can be: */
 
46
                                                                /* DUIH_OK, DUIH_ABORT, DUIH_TERM, DUIH_TRIG, DUIH_CMND */
 
47
} uicontext;
 
48
 
 
49
static uicontext def_uicntx = { 1, 0, { 0 } };
 
50
 
 
51
static inst_code def_uicallback(void *cntx, inst_ui_purp purp) {
 
52
        uicontext *p = (uicontext *)cntx;
 
53
 
 
54
        if (purp == inst_triggered) {
 
55
                if (p->emit_ret)
 
56
                        printf("\n");
 
57
                return inst_ok;
 
58
 
 
59
        } else if (purp == inst_negcoms
 
60
                || purp == inst_armed
 
61
                || purp == inst_measuring) {
 
62
                int c;
 
63
 
 
64
                c = poll_con_char();
 
65
                if (c != 0) {
 
66
                        p->cut = c;
 
67
                        c = p->uih[c];
 
68
                        if (c & (DUIH_ABORT | DUIH_TERM | DUIH_CMND))
 
69
                                return inst_user_abort;
 
70
                        if (c & DUIH_TRIG)
 
71
                                return inst_user_trig;
 
72
                }
 
73
 
 
74
        /* Change in measurement configuration */
 
75
        } else if (purp == inst_measuring) {
 
76
                return inst_ok;
 
77
        }
 
78
        return inst_ok;
 
79
}
 
80
 
 
81
/* Return the default uicallback function */
 
82
inst_code (*inst_get_uicallback())(void *, inst_ui_purp) {
 
83
        return &def_uicallback;
 
84
}
 
85
 
 
86
/* Return the default uicallback context */
 
87
void *inst_get_uicontext() {
 
88
        return (void *)&def_uicntx;
 
89
}
 
90
 
 
91
/* Install the default uicallback function in the given inst */
 
92
void inst_set_uicallback(inst *p) {
 
93
        p->set_uicallback(p, def_uicallback, (void *)&def_uicntx);
 
94
}
 
95
 
 
96
/* Set the return on trigger to true or false */
 
97
void inst_set_uicb_trigret(int set) {
 
98
        uicontext *p = &def_uicntx;
 
99
        p->emit_ret = set;
 
100
}
 
101
 
 
102
/* Reset user interaction handling to default (Esc, ^C, q or 'Q' = Abort) */
 
103
void inst_reset_uih() {
 
104
        uicontext *p = &def_uicntx;
 
105
        int i;
 
106
 
 
107
        for (i = 0; i < 255; i++)
 
108
                p->uih[i] = DUIH_NONE;
 
109
 
 
110
        p->uih[0x1b] = DUIH_ABORT;      /* Escape */
 
111
        p->uih['q']  = DUIH_ABORT;      /* q */
 
112
        p->uih['Q']  = DUIH_ABORT;      /* Q */
 
113
        p->uih[0x03] = DUIH_ABORT;      /* ^C */
 
114
}
 
115
 
 
116
/* Set a key range to the given handling type */
 
117
/* min & max are between 0 and 255, status is one of */
 
118
/* DUIH_OK, DUIH_USER, DUIH_TERM, DUIH_TRIG, DUIH_CMND */
 
119
void inst_set_uih(
 
120
int min,                /* Start key code */
 
121
int max,                /* End key code (inclusive) */
 
122
int status              /* ICOM_OK, ICOM_USER, ICOM_TERM, ICOM_TRIG, ICOM_CMND */
 
123
) {
 
124
        uicontext *p = &def_uicntx;
 
125
        int i;
 
126
 
 
127
        if (min < 0)
 
128
                min = 0;
 
129
        else if (min > 255)
 
130
                min = 255;
 
131
        if (max < 0)
 
132
                max = 0;
 
133
        else if (max > 255)
 
134
                max = 255;
 
135
 
 
136
        if (status != DUIH_NONE
 
137
         && status != DUIH_ABORT
 
138
         && status != DUIH_TERM
 
139
         && status != DUIH_CMND
 
140
         && status != DUIH_TRIG)
 
141
                status = DUIH_NONE;
 
142
 
 
143
        for (i = min; i <= max; i++) {
 
144
                p->uih[i] = status;
 
145
        }
 
146
}
 
147
 
 
148
/* Get the character that caused the user interrupt */
 
149
/* + its key type in the upper 8 bits. */
 
150
/* Clear it to 0x00 after reading it. */
 
151
int inst_get_uih_char() {
 
152
        uicontext *p = &def_uicntx;
 
153
        int c = p->cut;
 
154
        c |= p->uih[c];
 
155
        p->cut = 0;
 
156
        return c;
 
157
}
 
158
 
 
159
/* ================================================================= */
 
160
 
 
161
/* A default calibration user interaction handler using the console. */
 
162
/* This handles both normal and display based calibration interaction */
 
163
/* with the instrument, if a disp_setup function and pointer to disp_win_info */
 
164
/* is provided. */
 
165
inst_code inst_handle_calibrate(
 
166
        inst *p,
 
167
        inst_cal_type calt,             /* Calibration type to do */
 
168
        inst_cal_cond calc,             /* Current current condition */
 
169
        inst_code (*disp_setup) (inst *p,inst_cal_cond calc, disp_win_info *dwi),
 
170
                                                        /* Callback for handling a display calibration - May be NULL */
 
171
        disp_win_info *dwi              /* Information to be able to open a display test patch - May be NULL */
 
172
) {
 
173
        inst_code rv = inst_ok, ev;
 
174
        int usermes = 0;                /* User was given a message */
 
175
        char id[200];                   /* Condition identifier */
 
176
        int ch;
 
177
 
 
178
        a1logd(p->log,1,"inst_handle_calibrate called\n");
 
179
 
 
180
        /* Untill we're done with the calibration */
 
181
        for (;;) {
 
182
 
 
183
                a1logd(p->log,1,"About to call calibrate at top of loop\n");
 
184
            ev = p->calibrate(p, &calt, &calc, id);
 
185
                a1logd(p->log,1,"Calibrate returned calt 0x%x, calc 0x%x, ev 0x%x\n",calt,calc,ev);
 
186
 
 
187
                /* We're done */
 
188
                if ((ev & inst_mask) == inst_ok) {
 
189
                        if (calc == inst_calc_message)
 
190
                                printf("%s\n",id);
 
191
                        if (usermes)
 
192
                                printf("Calibration complete\n");
 
193
                        fflush(stdout);
 
194
                        a1logd(p->log,1,"inst_handle_calibrate done 0x%x\n",ev);
 
195
                        return ev;
 
196
                }
 
197
 
 
198
                /* User aborted */
 
199
                if ((ev & inst_mask) == inst_user_abort) {
 
200
                        a1logd(p->log,1,"inst_handle_calibrate user aborted 0x%x\n",ev);
 
201
                        return ev;
 
202
                }
 
203
 
 
204
                /* Retry on an error */
 
205
                if ((ev & inst_mask) != inst_cal_setup) {
 
206
                        if ((ev & inst_mask) == inst_unsupported) {
 
207
                                a1logd(p->log,1,"inst_handle_calibrate err 0x%x, calibration type 0x%x not supported\n",ev, calt);
 
208
                                return inst_unsupported;
 
209
                        }
 
210
 
 
211
                        printf("Calibration failed with '%s' (%s)\n",
 
212
                                       p->inst_interp_error(p, ev), p->interp_error(p, ev));
 
213
                        printf("Hit any key to retry, or Esc or Q to abort:\n");
 
214
 
 
215
                        empty_con_chars();
 
216
                        ch = next_con_char();
 
217
                        printf("\n");
 
218
                        if (ch == 0x1b || ch == 0x3 || ch == 'q' || ch == 'Q') {
 
219
                                a1logd(p->log,1,"inst_handle_calibrate user aborted 0x%x\n",inst_user_abort);
 
220
                                fflush(stdout);
 
221
                                return inst_user_abort;
 
222
                        }
 
223
 
 
224
                /* Get user to do/setup calibration */
 
225
                } else {
 
226
 
 
227
                        switch (calc) {
 
228
                                case inst_calc_uop_ref_white:
 
229
                                        printf("Do a reflective white calibration,\n");
 
230
                                        printf(" and then hit any key to continue,\n"); 
 
231
                                        printf(" or hit Esc or Q to abort: "); 
 
232
                                        break;
 
233
 
 
234
                                case inst_calc_uop_trans_white:
 
235
                                        printf("Do a transmissive white calibration,\n");
 
236
                                        printf(" and then hit any key to continue,\n"); 
 
237
                                        printf(" or hit Esc or Q to abort: "); 
 
238
                                        break;
 
239
                        
 
240
                                case inst_calc_uop_trans_dark:
 
241
                                        printf("Do a transmissive dark calibration,\n");
 
242
                                        printf(" and then hit any key to continue,\n"); 
 
243
                                        printf(" or hit Esc or Q to abort: "); 
 
244
                                        break;
 
245
                        
 
246
                                case inst_calc_man_ref_white:
 
247
                                        printf("Place the instrument on its reflective white reference %s,\n",id);
 
248
                                        printf(" and then hit any key to continue,\n"); 
 
249
                                        printf(" or hit Esc or Q to abort: "); 
 
250
                                        break;
 
251
 
 
252
                                case inst_calc_man_ref_whitek:
 
253
                                        printf("Click the instrument on its reflective white reference %s,\n",id);
 
254
                                        printf(" or hit Esc or Q to abort: "); 
 
255
                                        break;
 
256
 
 
257
                                case inst_calc_man_ref_dark:
 
258
                                        printf("Place the instrument in the dark, not in contact with any surface,\n");
 
259
                                        printf(" and then hit any key to continue,\n"); 
 
260
                                        printf(" or hit Esc or Q to abort: "); 
 
261
                                        break;
 
262
 
 
263
                                case inst_calc_man_em_dark:
 
264
                                        printf("Place cap on the instrument, or place on a dark surface,\n");
 
265
                                        printf("or place on the white calibration reference,\n");
 
266
                                        printf(" and then hit any key to continue,\n"); 
 
267
                                        printf(" or hit Esc or Q to abort: "); 
 
268
                                        break;
 
269
 
 
270
                                case inst_calc_man_am_dark:
 
271
                                        printf("Place ambient adapter and cap on the instrument,\n");
 
272
                                        printf("or place on the white calibration reference,\n");
 
273
                                        printf(" and then hit any key to continue,\n"); 
 
274
                                        printf(" or hit Esc or Q to abort: "); 
 
275
                                        break;
 
276
 
 
277
                                case inst_calc_man_cal_smode:
 
278
                                        printf("Set instrument sensor to calibration position,\n");
 
279
                                        printf(" and then hit any key to continue,\n"); 
 
280
                                        printf(" or hit Esc or Q to abort: "); 
 
281
                                        break;
 
282
 
 
283
                                case inst_calc_man_trans_white:
 
284
                                        printf("Place the instrument on its transmissive white source,\n");
 
285
                                        printf(" and then hit any key to continue,\n"); 
 
286
                                        printf(" or hit Esc or Q to abort: "); 
 
287
                                        break;
 
288
 
 
289
                                case inst_calc_man_trans_dark:
 
290
                                        printf("Use the appropriate tramissive blocking to block the transmission path,\n");
 
291
                                        printf(" and then hit any key to continue,\n"); 
 
292
                                        printf(" or hit Esc or Q to abort: "); 
 
293
                                        break;
 
294
 
 
295
                                case inst_calc_change_filter:
 
296
                                        printf("Change filter on instrument to %s,\n",id);
 
297
                                        printf(" and then hit any key to continue,\n"); 
 
298
                                        printf(" or hit Esc or Q to abort: "); 
 
299
                                        break;
 
300
 
 
301
                                case inst_calc_message:
 
302
                                        printf("%s\n",id);
 
303
                                        printf(" Hit any key to continue,\n"); 
 
304
                                        printf(" or hit Esc or Q to abort: "); 
 
305
                                        break;
 
306
 
 
307
                                case inst_calc_emis_white:
 
308
                                        if (disp_setup == NULL || dwi == NULL) { /* No way of creating a test window */
 
309
                                                printf("Place the instrument on a 100%% white test patch,\n");
 
310
                                                printf(" and then hit any key to continue,\n"); 
 
311
                                                printf(" or hit Esc or Q to abort: "); 
 
312
                                        } else {
 
313
                                                /* We need to display a 100% white patch to proceed with this */
 
314
                                                /* type of calibration */
 
315
                                                if ((rv = disp_setup(p, calc, dwi)) != inst_ok)
 
316
                                                        return rv; 
 
317
                                        }
 
318
                                        break;
 
319
 
 
320
                                case inst_calc_emis_grey:
 
321
                                case inst_calc_emis_grey_darker: 
 
322
                                case inst_calc_emis_grey_ligher:
 
323
                                        if (dwi == NULL) {      /* No way of creating a test window */
 
324
                                                if (calc == inst_calc_emis_grey) {
 
325
                                                        p->cal_gy_level = 0.6;
 
326
                                                        p->cal_gy_count = 0;
 
327
                                                } else if (calc == inst_calc_emis_grey_darker) {
 
328
                                                        p->cal_gy_level *= 0.7;
 
329
                                                        p->cal_gy_count++;
 
330
                                                } else if (calc == inst_calc_emis_grey_ligher) {
 
331
                                                        p->cal_gy_level *= 1.4;
 
332
                                                        if (p->cal_gy_level > 1.0)
 
333
                                                                p->cal_gy_level = 1.0;
 
334
                                                        p->cal_gy_count++;
 
335
                                                }
 
336
                                                if (p->cal_gy_count > 4) {
 
337
                                                        printf("Cell ratio calibration failed - too many tries at setting grey level.\n");
 
338
                                                        a1logd(p->log,1,"inst_handle_calibrate too many tries at setting grey level 0x%x\n",inst_internal_error);
 
339
                                                        return inst_internal_error; 
 
340
                                                } else {
 
341
                                                        printf("Place the instrument on a %d%% white test patch,\n", (int)(p->cal_gy_level * 100.0 + 0.5));
 
342
                                                        printf(" and then hit any key to continue,\n"); 
 
343
                                                        printf(" or hit Esc or Q to abort: "); 
 
344
                                                }
 
345
                                        } else {
 
346
 
 
347
                                                /* We need to display a test patch to proceed with this
 
348
                                                 * type of calibration. Typically this will be:
 
349
                                                 *
 
350
                                                 * inst_calc_xxxx_grey:
 
351
                                                 *              set p->cal_gy_level = 0.6
 
352
                                                 *              set p->cal_gy_count = 0;
 
353
                                                 *
 
354
                                                 * inst_calc_xxxx_grey_darker:
 
355
                                                 *              set p->cal_gy_level *= 0.7
 
356
                                                 *              set p->cal_gy_count++
 
357
                                                 *
 
358
                                                 * inst_calc_xxxx_grey_ligher:
 
359
                                                 *              set p->cal_gy_level *= 1.4
 
360
                                                 *              set p->cal_gy_count++
 
361
                                                 *
 
362
                                                 * and return failure if p->cal_gy_count > 4
 
363
                                                 */
 
364
 
 
365
                                                if ((rv = disp_setup(p, calc, dwi)) != inst_ok)
 
366
                                                        return rv; 
 
367
                                        }
 
368
                                        break;
 
369
 
 
370
                                default:
 
371
                                        /* Something isn't being handled */
 
372
                                        a1logd(p->log,1,"inst_handle_calibrate unhandled calc case 0x%x, err 0x%x\n",calc,inst_internal_error);
 
373
                                        return inst_internal_error;
 
374
                        }
 
375
                        fflush(stdout);
 
376
 
 
377
                        usermes = 1;
 
378
 
 
379
                        if (calc != inst_calc_man_ref_whitek) {
 
380
                                empty_con_chars();
 
381
                                ch = next_con_char();
 
382
                                printf("\n");
 
383
                                if (ch == 0x1b || ch == 0x3 || ch == 'q' || ch == 'Q') {
 
384
                                        a1logd(p->log,1,"inst_handle_calibrate user aborted 0x%x\n",inst_user_abort);
 
385
                                        return inst_user_abort;
 
386
                                }
 
387
                        }
 
388
                }
 
389
        }
 
390
}
 
391
 
 
392
/* ============================================================================= */
 
393
 
 
394
/* A helper function to display -y flag usage for each instrument type available */
 
395
/* Return accumulated capabilities2 of all the instruments */
 
396
/* Return all possible capabilities if there are no instruments */
 
397
/* If docbib is nz, then only display the base calibration display types */
 
398
inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *icmps, int docbib) { 
 
399
        int i, j;
 
400
        char buf[200], *bp;
 
401
        char extra[40];
 
402
        int olen, pstart;
 
403
        int notall = 0;                         /* Not all instruments are USB */
 
404
        int gotone = 0;                         /* Found at least one USB instrument */
 
405
        inst2_capability acap = 0;      /* Accumulate capabilities */
 
406
 
 
407
        if (icmps == NULL)
 
408
                return 0;
 
409
 
 
410
        /* Locate the end of the option */
 
411
        for (bp = oline; *bp != '\000' && *bp == ' '; bp++)
 
412
                ;
 
413
        for (; *bp != '\000' && *bp != ' '; bp++)
 
414
                ;
 
415
        pstart = bp - oline;
 
416
        if (pstart > 10)
 
417
                pstart = 10;
 
418
        strncpy(buf, oline, pstart); 
 
419
        buf[pstart++] = ' ';
 
420
 
 
421
        olen = strlen(oline);           /* lenth of option part of line */
 
422
 
 
423
        for (i = 0; icmps != NULL && i < icmps->npaths; i++) {
 
424
                inst *it;
 
425
                inst2_capability cap;
 
426
                int k;
 
427
 
 
428
                if ((it = new_inst(icmps->paths[i], 1, g_log, NULL, NULL)) == NULL) {
 
429
                        notall = 1;
 
430
                        continue;
 
431
                }
 
432
                gotone = 1;
 
433
 
 
434
                it->capabilities(it, NULL, &cap, NULL);
 
435
                acap |= cap;
 
436
 
 
437
                if (cap & inst2_disptype) {
 
438
                        int nsel;
 
439
                        inst_disptypesel *sels;
 
440
 
 
441
                        if (it->get_disptypesel(it, &nsel, &sels, 1, 0) != inst_ok) {
 
442
                                it->del(it);
 
443
                                continue;
 
444
                        }
 
445
                        for (j = 0; j < nsel; j++) {
 
446
                                int m;
 
447
 
 
448
                                if (docbib && sels[j].cbid == 0)
 
449
                                        continue;                       /* Skip non cbid type */
 
450
 
 
451
                                m = pstart;
 
452
                                for (k = 0; k < (INST_DTYPE_SEL_LEN-1); k++) {
 
453
                                        if (sels[j].sel[k] == '\000')
 
454
                                                break;
 
455
                                        if (m > pstart)
 
456
                                                buf[m++] = '|';
 
457
                                        buf[m++] = sels[j].sel[k];
 
458
                                }
 
459
                                while (m < (olen+1))    /* Indent it by 1 */
 
460
                                        buf[m++] = ' ';
 
461
                                buf[m++] = '\000';
 
462
                                
 
463
                                extra[0] = '\000';
 
464
                                if ((sels[j].flags & inst_dtflags_default) || sels[j].cbid != 0) {
 
465
                                        strcat(extra, " [");
 
466
                                if (sels[j].flags & inst_dtflags_default) {
 
467
                                                strcat(extra, "Default");
 
468
                                                if (sels[j].cbid != 0)
 
469
                                                        strcat(extra, ",");
 
470
                                        }
 
471
                                        if (sels[j].cbid != 0) {
 
472
                                                sprintf(extra + strlen(extra), "CB%d",sels[j].cbid);
 
473
                                        }
 
474
                                        strcat(extra, "]");
 
475
                                }
 
476
 
 
477
                                fprintf(fp, "%s%s: %s%s\n",buf, inst_sname(it->itype), sels[j].desc, extra);
 
478
 
 
479
                                if (j == 0) {
 
480
                                        for (m = 0; m < pstart; m++)
 
481
                                                buf[m] = ' ';
 
482
                                }
 
483
                        }
 
484
                }
 
485
                it->del(it);
 
486
        }
 
487
        /* Output a default desciption if not all instruments are USB */
 
488
        if (notall) {
 
489
                int m = pstart;
 
490
                buf[m++] = 'l';
 
491
                buf[m++] = '|';
 
492
                buf[m++] = 'c';
 
493
                while (m < olen)
 
494
                        buf[m++] = ' ';
 
495
                buf[m++] = '\000';
 
496
                fprintf(fp, "%s%s\n",buf, " Other: l = LCD, c = CRT");
 
497
        }
 
498
        if (!gotone)
 
499
                acap = ~0;
 
500
 
 
501
        return acap;
 
502
}
 
503
 
 
504
/* A helper function to turn a -y flag into a selection index */
 
505
/* If docbib is nz, then only allow base calibration display types */
 
506
/* Return -1 on error */
 
507
int inst_get_disptype_index(inst *it, int c, int docbib) {
 
508
        inst2_capability cap;
 
509
        int j, k;
 
510
 
 
511
        it->capabilities(it, NULL, &cap, NULL);
 
512
 
 
513
        if (cap & inst2_disptype) {
 
514
                int nsel;
 
515
                inst_disptypesel *sels;
 
516
 
 
517
                if (it->get_disptypesel(it, &nsel, &sels, 1, 0) != inst_ok) {
 
518
                        return -1;
 
519
                }
 
520
                for (j = 0; j < nsel; j++) {
 
521
                        if (docbib && sels[j].cbid == 0)
 
522
                                continue;                       /* Skip non cbid type */
 
523
 
 
524
                        for (k = 0; k < (INST_DTYPE_SEL_LEN-1); k++) {
 
525
                                if (sels[j].sel[k] == '\000')
 
526
                                        break;
 
527
                                if (sels[j].sel[k] == c) {
 
528
                                        return j;
 
529
                                }
 
530
                        }
 
531
                }
 
532
        }
 
533
        return -1;
 
534
}
 
535
 
 
536
/* ================================================================= */
 
537
 
 
538
 
 
539
 
 
540
 
 
541
 
 
542
 
 
543
 
 
544
 
 
545
 
 
546
 
 
547
 
 
548
 
 
549
 
 
550
 
 
551
 
 
552
 
 
553
 
 
554
 
 
555
 
 
556