Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
var MuPDF = {
2
monthName: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
3
shortMonthName: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
4
monthPattern: /Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/,
5
dayName: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
6
7
padZeros: function(num, places) {
8
var s = String(num)
9
while (s.length < places)
10
s = '0' + s
11
return s;
12
},
13
14
convertCase: function(str, cmd) {
15
switch (cmd) {
16
case '>': return str.toUpperCase();
17
case '<': return str.toLowerCase();
18
default: return str;
19
}
20
},
21
};
22
23
/* display must be kept in sync with an enum in pdf_form.c */
24
var display = {
25
visible: 0,
26
hidden: 1,
27
noPrint: 2,
28
noView: 3,
29
};
30
31
var border = {
32
s: "Solid",
33
d: "Dashed",
34
b: "Beveled",
35
i: "Inset",
36
u: "Underline",
37
};
38
39
var color = {
40
transparent: [ "T" ],
41
black: [ "G", 0 ],
42
white: [ "G", 1 ],
43
red: [ "RGB", 1,0,0 ],
44
green: [ "RGB", 0,1,0 ],
45
blue: [ "RGB", 0,0,1 ],
46
cyan: [ "CMYK", 1,0,0,0 ],
47
magenta: [ "CMYK", 0,1,0,0 ],
48
yellow: [ "CMYK", 0,0,1,0 ],
49
dkGray: [ "G", 0.25 ],
50
gray: [ "G", 0.5 ],
51
ltGray: [ "G", 0.75 ],
52
};
53
54
var util = {};
55
56
util.printd = function(fmt, d)
57
{
58
var regexp = /(m+|d+|y+|H+|h+|M+|s+|t+|[^mdyHhMst]+)/g;
59
var res = '';
60
var i;
61
62
if (!d)
63
return null;
64
65
var tokens = fmt.match(regexp);
66
var length = tokens ? tokens.length : 0;
67
68
for (i = 0; i < length; i++)
69
{
70
switch(tokens[i])
71
{
72
case 'mmmm': res += MuPDF.monthName[d.getMonth()]; break;
73
case 'mmm': res += MuPDF.monthName[d.getMonth()].substring(0,3); break;
74
case 'mm': res += MuPDF.padZeros(d.getMonth()+1, 2); break;
75
case 'm': res += d.getMonth()+1; break;
76
case 'dddd': res += MuPDF.dayName[d.getDay()]; break;
77
case 'ddd': res += MuPDF.dayName[d.getDay()].substring(0,3); break;
78
case 'dd': res += MuPDF.padZeros(d.getDate(), 2); break;
79
case 'd': res += d.getDate(); break;
80
case 'yyyy': res += d.getFullYear(); break;
81
case 'yy': res += d.getFullYear()%100; break;
82
case 'HH': res += MuPDF.padZeros(d.getHours(), 2); break;
83
case 'H': res += d.getHours(); break;
84
case 'hh': res += MuPDF.padZeros((d.getHours()+11)%12+1, 2); break;
85
case 'h': res += (d.getHours()+11)%12+1; break;
86
case 'MM': res += MuPDF.padZeros(d.getMinutes(), 2); break;
87
case 'M': res += d.getMinutes(); break;
88
case 'ss': res += MuPDF.padZeros(d.getSeconds(), 2); break;
89
case 's': res += d.getSeconds(); break;
90
case 'tt': res += d.getHours() < 12 ? 'am' : 'pm'; break;
91
case 't': res += d.getHours() < 12 ? 'a' : 'p'; break;
92
default: res += tokens[i];
93
}
94
}
95
96
return res;
97
}
98
99
util.printx = function(fmt, val)
100
{
101
var cs = '=';
102
var res = '';
103
var i = 0;
104
var m;
105
var length = fmt ? fmt.length : 0;
106
107
while (i < length)
108
{
109
switch (fmt.charAt(i))
110
{
111
case '\\':
112
i++;
113
if (i >= length) return res;
114
res += fmt.charAt(i);
115
break;
116
117
case 'X':
118
m = val.match(/\w/);
119
if (!m) return res;
120
res += MuPDF.convertCase(m[0],cs);
121
val = val.replace(/^\W*\w/,'');
122
break;
123
124
case 'A':
125
m = val.match(/[A-Za-z]/);
126
if (!m) return res;
127
res += MuPDF.convertCase(m[0],cs);
128
val = val.replace(/^[^A-Za-z]*[A-Za-z]/,'');
129
break;
130
131
case '9':
132
m = val.match(/\d/);
133
if (!m) return res;
134
res += m[0];
135
val = val.replace(/^\D*\d/,'');
136
break;
137
138
case '*':
139
res += val;
140
val = '';
141
break;
142
143
case '?':
144
if (!val) return res;
145
res += MuPDF.convertCase(val.charAt(0),cs);
146
val = val.substring(1);
147
break;
148
149
case '=':
150
case '>':
151
case '<':
152
cs = fmt.charAt(i);
153
break;
154
155
default:
156
res += MuPDF.convertCase(fmt.charAt(i),cs);
157
break;
158
}
159
160
i++;
161
}
162
163
return res;
164
}
165
166
util.printf = function()
167
{
168
var i;
169
170
if (arguments.length < 1)
171
return "";
172
173
var res = "";
174
var arg_i = 1;
175
var regexp = /%[^dfsx]*[dfsx]|[^%]*/g;
176
var tokens = arguments[0].match(regexp);
177
var length = tokens ? tokens.length : 0;
178
179
for (i = 0; i < length; i++)
180
{
181
var tok = tokens[i];
182
if (tok.match(/^%/))
183
{
184
if (arg_i < arguments.length)
185
{
186
var val = arguments[arg_i++];
187
var fval = '';
188
var neg = false;
189
var decsep_re = /^,[0123]/;
190
var flags_re = /^[+ 0#]+/;
191
var width_re = /^\d+/;
192
var prec_re = /^\.\d+/;
193
var conv_re = /^[dfsx]/;
194
195
tok = tok.replace(/^%/, "");
196
var decsep = tok.match(decsep_re);
197
if (decsep) decsep = decsep[0];
198
tok = tok.replace(decsep_re, "");
199
var flags = tok.match(flags_re);
200
if (flags) flags = flags[0];
201
tok = tok.replace(flags_re, "");
202
var width = tok.match(width_re);
203
if (width) width = width[0];
204
tok = tok.replace(width_re, "");
205
var prec = tok.match(prec_re);
206
if (prec) prec = prec[0];
207
tok = tok.replace(prec_re, "");
208
var conv = tok.match(conv_re);
209
if (conv) conv = conv[0];
210
211
prec = prec ? Number(prec.replace(/^\./, '')) : 0;
212
var poschar = (flags && flags.match(/[+ ]/)) ? flags.match(/[+ ]/)[0] : '';
213
var pad = (flags && flags.match(/0/)) ? '0' : ' ';
214
215
var point = '.';
216
var thou = '';
217
218
if (decsep)
219
{
220
switch(decsep)
221
{
222
case ',0': thou = ','; break;
223
case ',1': break;
224
case ',2': thou = '.'; point = ','; break;
225
case ',3': point = ','; break;
226
}
227
}
228
229
switch(conv)
230
{
231
case 'x':
232
val = Math.floor(val);
233
neg = (val < 0);
234
if (neg)
235
val = -val;
236
237
// Convert to hex
238
while (val)
239
{
240
fval = '0123456789ABCDEF'.charAt(val%16) + fval;
241
val = Math.floor(val/16);
242
}
243
244
if (neg)
245
fval = '-' + fval;
246
else
247
fval = poschar + fval;
248
break;
249
250
case 'd':
251
fval = String(Math.floor(val));
252
break;
253
254
case 's':
255
// Always pad strings with space
256
pad = ' ';
257
fval = String(val);
258
break;
259
260
case 'f':
261
fval = String(val);
262
263
if (prec)
264
{
265
var frac = fval.match(/\.\d+/);
266
if (frac)
267
{
268
frac = frac[0];
269
// Matched string includes the dot, so make it
270
// prec+1 in length
271
if (frac.length > prec+1)
272
frac = frac.substring(0, prec+1);
273
else if(frac.length < prec+1)
274
frac += new Array(prec+1-frac.length+1).join('0');
275
276
fval = fval.replace(/\.\d+/, frac);
277
}
278
}
279
break;
280
}
281
282
if (conv.match(/[fd]/))
283
{
284
if (fval >= 0)
285
fval = poschar + fval;
286
287
if (point !== '.')
288
fval.replace(/\./, point);
289
290
if (thou)
291
{
292
var intpart = fval.match(/\d+/)[0];
293
intpart = new Array(2-(intpart.length+2)%3+1).join('0') + intpart;
294
intpart = intpart.match(/.../g).join(thou).replace(/^0*[,.]?/,'');
295
fval = fval.replace(/\d+/, intpart);
296
}
297
}
298
299
if (width && fval.length < width)
300
fval = new Array(width - fval.length + 1).join(pad) + fval;
301
302
res += fval;
303
}
304
}
305
else
306
{
307
res += tok;
308
}
309
}
310
311
return res;
312
}
313
314
function AFMergeChange(event)
315
{
316
return event.value;
317
}
318
319
function AFMakeNumber(str)
320
{
321
var nums = str.match(/\d+/g);
322
323
if (!nums)
324
return null;
325
326
var res = nums.join('.');
327
328
if (str.match(/^[^0-9]*\./))
329
res = '0.'+res;
330
331
return res * (str.match(/-/) ? -1.0 : 1.0);
332
}
333
334
function AFExtractTime(dt)
335
{
336
var ampm = dt.match(/(am|pm)/);
337
dt = dt.replace(/(am|pm)/, '');
338
var t = dt.match(/\d{1,2}:\d{1,2}:\d{1,2}/);
339
dt = dt.replace(/\d{1,2}:\d{1,2}:\d{1,2}/, '');
340
if (!t)
341
{
342
t = dt.match(/\d{1,2}:\d{1,2}/);
343
dt = dt.replace(/\d{1,2}:\d{1,2}/, '');
344
}
345
346
return [dt, t?t[0]+(ampm?ampm[0]:''):''];
347
}
348
349
function AFParseDateOrder(fmt)
350
{
351
var i;
352
var order = '';
353
354
// Ensure all present with those not added in default order
355
fmt += "mdy";
356
357
for (i = 0; i < fmt.length; i++)
358
{
359
var c = fmt.charAt(i);
360
361
if ('ymd'.indexOf(c) !== -1 && order.indexOf(c) === -1)
362
order += c;
363
}
364
365
return order;
366
}
367
368
function AFMatchMonth(d)
369
{
370
var m = d.match(MuPDF.monthPattern);
371
372
return m ? MuPDF.shortMonthName.indexOf(m[0]) : null;
373
}
374
375
function AFParseTime(str, d)
376
{
377
if (!str)
378
return d;
379
380
if (!d)
381
d = new Date();
382
383
var ampm = str.match(/(am|pm)/);
384
var nums = str.match(/\d+/g);
385
var hour, min, sec;
386
387
if (!nums)
388
return null;
389
390
sec = 0;
391
392
switch (nums.length)
393
{
394
case 3:
395
sec = parseInt(nums[2]);
396
case 2:
397
hour = parseInt(nums[0]);
398
min = parseInt(nums[1]);
399
break;
400
401
default:
402
return null;
403
}
404
405
ampm = ampm && ampm[0]
406
407
if (ampm === 'am' && hour < 12)
408
hour = 12 + hour;
409
if (ampm === 'pm' && hour >= 12)
410
hour = 0 + hour - 12;
411
412
d.setHours(hour, min, sec);
413
414
if (d.getHours() !== hour || d.getMinutes() !== min || d.getSeconds() !== sec)
415
return null;
416
417
return d;
418
}
419
420
function AFParseDateEx(d, fmt)
421
{
422
var i;
423
var dt = AFExtractTime(d);
424
var nums = dt[0].match(/\d+/g);
425
var order = AFParseDateOrder(fmt);
426
var text_month = AFMatchMonth(dt[0]);
427
var dout = new Date();
428
var year = dout.getFullYear();
429
var month = dout.getMonth();
430
var date = dout.getDate();
431
432
dout.setHours(12,0,0);
433
434
if (!nums || nums.length < 1 || nums.length > 3)
435
return null;
436
437
if (nums.length < 3 && text_month)
438
{
439
// Use the text month rather than one of the numbers
440
month = text_month;
441
order = order.replace('m','');
442
}
443
444
order = order.substring(0, nums.length);
445
446
// If year and month specified but not date then use the 1st
447
if (order === "ym" || (order === "y" && text_month))
448
date = 1;
449
450
for (i = 0; i < nums.length; i++)
451
{
452
switch (order.charAt(i))
453
{
454
case 'y': year = parseInt(nums[i]); break;
455
case 'm': month = parseInt(nums[i]) - 1; break;
456
case 'd': date = parseInt(nums[i]); break;
457
}
458
}
459
460
if (year < 100)
461
{
462
if (fmt.search("yyyy") !== -1)
463
return null;
464
465
if (year >= 50)
466
year = 1900 + year;
467
else if (year >= 0)
468
year = 2000 + year;
469
}
470
471
dout.setFullYear(year, month, date);
472
473
if (dout.getFullYear() !== year || dout.getMonth() !== month || dout.getDate() !== date)
474
return null;
475
476
return AFParseTime(dt[1], dout);
477
}
478
479
function AFDate_KeystrokeEx(fmt)
480
{
481
if (event.willCommit && !AFParseDateEx(event.value, fmt))
482
{
483
app.alert("The date/time entered ("+event.value+") does not match the format ("+fmt+") of the field [ "+event.target.name+" ]");
484
event.rc = false;
485
}
486
}
487
488
function AFDate_Keystroke(index)
489
{
490
var formats = ['m/d','m/d/yy','mm/dd/yy','mm/yy','d-mmm','d-mmm-yy','dd-mm-yy','yy-mm-dd',
491
'mmm-yy','mmmm-yy','mmm d, yyyy','mmmm d, yyyy','m/d/yy h:MM tt','m/d/yy HH:MM'];
492
AFDate_KeystrokeEx(formats[index]);
493
}
494
495
function AFDate_FormatEx(fmt)
496
{
497
var d = AFParseDateEx(event.value, fmt);
498
499
event.value = d ? util.printd(fmt, d) : "";
500
}
501
502
function AFDate_Format(index)
503
{
504
var formats = ['m/d','m/d/yy','mm/dd/yy','mm/yy','d-mmm','d-mmm-yy','dd-mm-yy','yy-mm-dd',
505
'mmm-yy','mmmm-yy','mmm d, yyyy','mmmm d, yyyy','m/d/yy h:MM tt','m/d/yy HH:MM'];
506
AFDate_FormatEx(formats[index]);
507
}
508
509
function AFTime_Keystroke(index)
510
{
511
if (event.willCommit && !AFParseTime(event.value, null))
512
{
513
app.alert("The value entered ("+event.value+") does not match the format of the field [ "+event.target.name+" ]");
514
event.rc = false;
515
}
516
}
517
518
function AFTime_FormatEx(fmt)
519
{
520
var d = AFParseTime(event.value, null);
521
522
event.value = d ? util.printd(fmt, d) : '';
523
}
524
525
function AFTime_Format(index)
526
{
527
var formats = ['HH:MM','h:MM tt','HH:MM:ss','h:MM:ss tt'];
528
529
AFTime_FormatEx(formats[index]);
530
}
531
532
function AFSpecial_KeystrokeEx(fmt)
533
{
534
var cs = '=';
535
var val = event.value;
536
var res = '';
537
var i = 0;
538
var m;
539
var length = fmt ? fmt.length : 0;
540
541
while (i < length)
542
{
543
switch (fmt.charAt(i))
544
{
545
case '\\':
546
i++;
547
if (i >= length)
548
break;
549
res += fmt.charAt(i);
550
if (val && val.charAt(0) === fmt.charAt(i))
551
val = val.substring(1);
552
break;
553
554
case 'X':
555
m = val.match(/^\w/);
556
if (!m)
557
{
558
event.rc = false;
559
break;
560
}
561
res += MuPDF.convertCase(m[0],cs);
562
val = val.substring(1);
563
break;
564
565
case 'A':
566
m = val.match(/^[A-Za-z]/);
567
if (!m)
568
{
569
event.rc = false;
570
break;
571
}
572
res += MuPDF.convertCase(m[0],cs);
573
val = val.substring(1);
574
break;
575
576
case '9':
577
m = val.match(/^\d/);
578
if (!m)
579
{
580
event.rc = false;
581
break;
582
}
583
res += m[0];
584
val = val.substring(1);
585
break;
586
587
case '*':
588
res += val;
589
val = '';
590
break;
591
592
case '?':
593
if (!val)
594
{
595
event.rc = false;
596
break;
597
}
598
res += MuPDF.convertCase(val.charAt(0),cs);
599
val = val.substring(1);
600
break;
601
602
case '=':
603
case '>':
604
case '<':
605
cs = fmt.charAt(i);
606
break;
607
608
default:
609
res += fmt.charAt(i);
610
if (val && val.charAt(0) === fmt.charAt(i))
611
val = val.substring(1);
612
break;
613
}
614
615
i++;
616
}
617
618
if (event.rc)
619
event.value = res;
620
else if (event.willCommit)
621
app.alert("The value entered ("+event.value+") does not match the format of the field [ "+event.target.name+" ] should be "+fmt);
622
}
623
624
function AFSpecial_Keystroke(index)
625
{
626
if (event.willCommit)
627
{
628
switch (index)
629
{
630
case 0:
631
if (!event.value.match(/^\d{5}$/))
632
event.rc = false;
633
break;
634
case 1:
635
if (!event.value.match(/^\d{5}[-. ]?\d{4}$/))
636
event.rc = false;
637
break;
638
case 2:
639
if (!event.value.match(/^((\(\d{3}\)|\d{3})[-. ]?)?\d{3}[-. ]?\d{4}$/))
640
event.rc = false;
641
break;
642
case 3:
643
if (!event.value.match(/^\d{3}[-. ]?\d{2}[-. ]?\d{4}$/))
644
event.rc = false;
645
break;
646
}
647
648
if (!event.rc)
649
app.alert("The value entered ("+event.value+") does not match the format of the field [ "+event.target.name+" ]");
650
}
651
}
652
653
function AFSpecial_Format(index)
654
{
655
var res;
656
657
switch (index)
658
{
659
case 0:
660
res = util.printx('99999', event.value);
661
break;
662
case 1:
663
res = util.printx('99999-9999', event.value);
664
break;
665
case 2:
666
res = util.printx('9999999999', event.value);
667
res = util.printx(res.length >= 10 ? '(999) 999-9999' : '999-9999', event.value);
668
break;
669
case 3:
670
res = util.printx('999-99-9999', event.value);
671
break;
672
}
673
674
event.value = res ? res : '';
675
}
676
677
function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)
678
{
679
if (sepStyle & 2)
680
{
681
if (!event.value.match(/^[+-]?\d*[,.]?\d*$/))
682
event.rc = false;
683
}
684
else
685
{
686
if (!event.value.match(/^[+-]?\d*\.?\d*$/))
687
event.rc = false;
688
}
689
690
if (event.willCommit)
691
{
692
if (!event.value.match(/\d/))
693
event.rc = false;
694
695
if (!event.rc)
696
app.alert("The value entered ("+event.value+") does not match the format of the field [ "+event.target.name+" ]");
697
}
698
}
699
700
function AFNumber_Format(nDec,sepStyle,negStyle,currStyle,strCurrency,bCurrencyPrepend)
701
{
702
var val = event.value;
703
var fracpart;
704
var intpart;
705
var point = sepStyle&2 ? ',' : '.';
706
var separator = sepStyle&2 ? '.' : ',';
707
708
if (/^\D*\./.test(val))
709
val = '0'+val;
710
711
var groups = val.match(/\d+/g);
712
713
if (!groups)
714
return;
715
716
switch (groups.length)
717
{
718
case 0:
719
return;
720
case 1:
721
fracpart = '';
722
intpart = groups[0];
723
break;
724
default:
725
fracpart = groups.pop();
726
intpart = groups.join('');
727
break;
728
}
729
730
// Remove leading zeros
731
intpart = intpart.replace(/^0*/,'');
732
if (!intpart)
733
intpart = '0';
734
735
if ((sepStyle & 1) === 0)
736
{
737
// Add the thousands sepearators: pad to length multiple of 3 with zeros,
738
// split into 3s, join with separator, and remove the leading zeros
739
intpart = new Array(2-(intpart.length+2)%3+1).join('0') + intpart;
740
intpart = intpart.match(/.../g).join(separator).replace(/^0*/,'');
741
}
742
743
if (!intpart)
744
intpart = '0';
745
746
// Adjust fractional part to correct number of decimal places
747
fracpart += new Array(nDec+1).join('0');
748
fracpart = fracpart.substring(0,nDec);
749
750
if (fracpart)
751
intpart += point+fracpart;
752
753
if (bCurrencyPrepend)
754
intpart = strCurrency+intpart;
755
else
756
intpart += strCurrency;
757
758
if (/-/.test(val))
759
{
760
switch (negStyle)
761
{
762
case 0:
763
intpart = '-'+intpart;
764
break;
765
case 1:
766
break;
767
case 2:
768
case 3:
769
intpart = '('+intpart+')';
770
break;
771
}
772
}
773
774
if (negStyle&1)
775
event.target.textColor = /-/.test(val) ? color.red : color.black;
776
777
event.value = intpart;
778
}
779
780
function AFPercent_Keystroke(nDec, sepStyle)
781
{
782
AFNumber_Keystroke(nDec, sepStyle, 0, 0, "", true);
783
}
784
785
function AFPercent_Format(nDec, sepStyle)
786
{
787
var val = AFMakeNumber(event.value);
788
789
if (!val)
790
{
791
event.value = '';
792
return;
793
}
794
795
event.value = (val * 100) + '';
796
797
AFNumber_Format(nDec, sepStyle, 0, 0, "%", false);
798
}
799
800
function AFSimple_Calculate(op, list)
801
{
802
var i, res;
803
804
switch (op)
805
{
806
case 'SUM':
807
res = 0;
808
break;
809
case 'PRD':
810
res = 1;
811
break;
812
case 'AVG':
813
res = 0;
814
break;
815
}
816
817
if (typeof list === 'string')
818
list = list.split(/ *, */);
819
820
for (i = 0; i < list.length; i++)
821
{
822
var field = getField(list[i]);
823
var value = Number(field.value);
824
825
switch (op)
826
{
827
case 'SUM':
828
res += value;
829
break;
830
case 'PRD':
831
res *= value;
832
break;
833
case 'AVG':
834
res += value;
835
break;
836
case 'MIN':
837
if (i === 0 || value < res)
838
res = value;
839
break;
840
case 'MAX':
841
if (i === 0 || value > res)
842
res = value;
843
break;
844
}
845
}
846
847
if (op === 'AVG')
848
res /= list.length;
849
850
event.value = res;
851
}
852
853
function AFRange_Validate(lowerCheck, lowerLimit, upperCheck, upperLimit)
854
{
855
if (upperCheck && event.value > upperLimit)
856
{
857
event.rc = false;
858
}
859
860
if (lowerCheck && event.value < lowerLimit)
861
{
862
event.rc = false;
863
}
864
865
if (!event.rc)
866
{
867
if (lowerCheck && upperCheck)
868
app.alert(util.printf("The entered value ("+event.value+") must be greater than or equal to %s and less than or equal to %s", lowerLimit, upperLimit));
869
else if (lowerCheck)
870
app.alert(util.printf("The entered value ("+event.value+") must be greater than or equal to %s", lowerLimit));
871
else
872
app.alert(util.printf("The entered value ("+event.value+") must be less than or equal to %s", upperLimit));
873
}
874
}
875
876