total5 0.0.1-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/503.html +65 -0
  2. package/CONTRIBUTING.md +55 -0
  3. package/LICENSE +211 -0
  4. package/README.md +32 -0
  5. package/api.js +289 -0
  6. package/bin/total5 +984 -0
  7. package/builders.js +1435 -0
  8. package/bundles.js +457 -0
  9. package/cache.js +58 -0
  10. package/changelog.txt +3 -0
  11. package/cluster.js +320 -0
  12. package/cms.js +625 -0
  13. package/controller.js +1419 -0
  14. package/cron.js +99 -0
  15. package/debug.js +539 -0
  16. package/edit.js +469 -0
  17. package/error.html +49 -0
  18. package/filestorage.js +1088 -0
  19. package/flow-flowstream.js +3152 -0
  20. package/flow.js +209 -0
  21. package/flowstream.js +1991 -0
  22. package/global.js +125 -0
  23. package/helpers/index.js +32 -0
  24. package/htmlparser.js +650 -0
  25. package/http.js +81 -0
  26. package/image.js +773 -0
  27. package/images.js +747 -0
  28. package/index.js +2658 -0
  29. package/jsonschema.js +691 -0
  30. package/ldap.js +792 -0
  31. package/mail.js +936 -0
  32. package/minificators.js +858 -0
  33. package/nosql-builder.js +440 -0
  34. package/nosql-querybuilder.js +316 -0
  35. package/nosql-reader.js +353 -0
  36. package/nosql-stream.js +617 -0
  37. package/nosql.js +763 -0
  38. package/openclient.js +219 -0
  39. package/package.json +32 -0
  40. package/pause.html +67 -0
  41. package/querybuilder.js +1361 -0
  42. package/release.js +167 -0
  43. package/routing.js +905 -0
  44. package/sourcemap.js +160 -0
  45. package/tangular.js +409 -0
  46. package/templates.js +145 -0
  47. package/templates.json +74 -0
  48. package/tms.js +384 -0
  49. package/tmsclient.js +125 -0
  50. package/todo.txt +7 -0
  51. package/tools/beta.sh +6 -0
  52. package/tools/release.sh +6 -0
  53. package/uibuilder.js +206 -0
  54. package/utils.js +6374 -0
  55. package/viewengine.js +880 -0
  56. package/websocket.js +1939 -0
  57. package/workers.js +129 -0
package/images.js ADDED
@@ -0,0 +1,747 @@
1
+ // Total.js Images
2
+ // The MIT License
3
+ // Copyright 2014-2023 (c) Peter Širka <petersirka@gmail.com>
4
+
5
+ 'use strict';
6
+
7
+ const D = F.isWindows ? '"' : '\'';
8
+ const SOF = { 0xc0: true, 0xc1: true, 0xc2: true, 0xc3: true, 0xc5: true, 0xc6: true, 0xc7: true, 0xc9: true, 0xca: true, 0xcb: true, 0xcd: true, 0xce: true, 0xcf: true };
9
+ const SPAWN_OPT = { shell: true };
10
+ const CMD_CONVERT = { gm: 'gm', im: 'convert', magick: 'magick' };
11
+ const CMD_CONVERT2 = { gm: 'gm convert', im: 'convert', magick: 'magick' };
12
+ const SUPPORTED = { jpg: 1, png: 1, gif: 1, apng: 1, jpeg: 1, heif: 1, heic: 1, webp: 1, ico: 1 };
13
+
14
+ const REG_SVG = /(width="\d+")+|(height="\d+")+/g;
15
+ const REG_PATH = /\//g;
16
+ const REG_ESCAPE = /'/g;
17
+
18
+ function u16(buf, o) {
19
+ return buf[o] << 8 | buf[o + 1];
20
+ }
21
+
22
+ function u32(buf, o) {
23
+ return buf[o] << 24 | buf[o + 1] << 16 | buf[o + 2] << 8 | buf[o + 3];
24
+ }
25
+
26
+ exports.measureGIF = function(buffer) {
27
+ return { width: buffer.readInt16LE(6), height: buffer.readInt16LE(8) };
28
+ };
29
+
30
+ // MIT
31
+ // Written by TJ Holowaychuk
32
+ // visionmedia
33
+ exports.measureJPG = function(buffer) {
34
+
35
+ var len = buffer.length;
36
+ var o = 0;
37
+
38
+ var jpeg = 0xff == buffer[0] && 0xd8 == buffer[1];
39
+ if (jpeg) {
40
+ o += 2;
41
+ while (o < len) {
42
+ while (0xff != buffer[o]) o++;
43
+ while (0xff == buffer[o]) o++;
44
+ if (SOF[buffer[o]])
45
+ return { width: u16(buffer, o + 6), height: u16(buffer, o + 4) };
46
+ else
47
+ o += u16(buffer, ++o);
48
+
49
+ }
50
+ }
51
+
52
+ return null;
53
+ };
54
+
55
+ // MIT
56
+ // Written by TJ Holowaychuk
57
+ // visionmedia
58
+ exports.measurePNG = function(buffer) {
59
+ return { width: u32(buffer, 16), height: u32(buffer, 16 + 4) };
60
+ };
61
+
62
+ exports.measureSVG = function(buffer) {
63
+
64
+ var match = buffer.toString('utf8').match(REG_SVG);
65
+ if (!match)
66
+ return;
67
+
68
+ var width = 0;
69
+ var height = 0;
70
+
71
+ for (var i = 0, length = match.length; i < length; i++) {
72
+ var value = match[i];
73
+
74
+ if (width > 0 && height > 0)
75
+ break;
76
+
77
+ if (!width && value.startsWith('width="'))
78
+ width = value.parseInt2();
79
+
80
+ if (!height && value.startsWith('height="'))
81
+ height = value.parseInt2();
82
+ }
83
+
84
+ return { width: width, height: height };
85
+ };
86
+
87
+ // image-size
88
+ // Git: https://github.com/image-size/image-size
89
+ // MIT License
90
+ exports.measureWEBP = function(buffer) {
91
+
92
+ var header = buffer.toString('ascii', 12, 16);
93
+
94
+ buffer = buffer.slice(20, 30);
95
+
96
+ if (header === 'VP8X') {
97
+ var extendedheader = buffer[0];
98
+ var start = (extendedheader & 0xc0) === 0;
99
+ var end = (extendedheader & 0x01) === 0;
100
+ if (start && end)
101
+ return { width: 1 + buffer.readUIntLE(7, 3), height: 1 + buffer.readUIntLE(4, 3) };
102
+ }
103
+
104
+ if (header === 'VP8 ' && buffer[0] !== 0x2f)
105
+ return { width: buffer.readInt16LE(8) & 0x3fff, height: buffer.readInt16LE(6) & 0x3fff };
106
+
107
+ var signature = buffer.toString('hex', 3, 6);
108
+ if (header === 'VP8L' && signature !== '9d012a')
109
+ return { width: 1 + (((buffer[2] & 0x3F) << 8) | buffer[1]), height: 1 + (((buffer[4] & 0xF) << 10) | (buffer[3] << 2) | ((buffer[2] & 0xC0) >> 6)) };
110
+ };
111
+
112
+ // image-size
113
+ // Git: https://github.com/image-size/image-size
114
+ // MIT License
115
+ exports.measureBMP = function(buffer) {
116
+ return { width: buffer.readUInt32LE(18), height: Math.abs(buffer.readInt32LE(22)) };
117
+ };
118
+
119
+ // image-size
120
+ // Git: https://github.com/image-size/image-size
121
+ // MIT License
122
+ exports.measurePSD = function(buffer) {
123
+ return { width: buffer.readUInt32BE(18), height: buffer.readUInt32BE(14) };
124
+ };
125
+
126
+ exports.measure = function(type, buffer) {
127
+ switch (type) {
128
+ case '.jpg':
129
+ case '.jpeg':
130
+ case 'jpg':
131
+ case 'jpeg':
132
+ case 'image/jpeg':
133
+ return exports.measureJPG(buffer);
134
+ case '.png':
135
+ case 'png':
136
+ case 'image/png':
137
+ return exports.measurePNG(buffer);
138
+ case '.svg':
139
+ case 'svg':
140
+ case 'image/svg+xml':
141
+ return exports.measureSVG(buffer);
142
+ case '.gif':
143
+ case 'gif':
144
+ case 'image/gif':
145
+ return exports.measureGIF(buffer);
146
+ case '.webp':
147
+ case 'webp':
148
+ case 'image/webp':
149
+ return exports.measureWEBP(buffer);
150
+ case '.psd':
151
+ case 'psd':
152
+ case 'image/vnd.adobe.photoshop':
153
+ return exports.measurePSD(buffer);
154
+ case '.bmp':
155
+ case 'bmp':
156
+ case 'image/bmp':
157
+ return exports.measureBMP(buffer);
158
+ }
159
+ };
160
+
161
+ function Image(filename, cmd, width, height) {
162
+ var t = this;
163
+ var type = typeof(filename);
164
+ t.width = width;
165
+ t.height = height;
166
+ t.builder = [];
167
+ t.filename = type === 'string' ? filename : null;
168
+ t.stream = type === 'object' ? filename : null;
169
+ t.type = type === 'string' ? F.TUtils.getExtension(filename) : 'jpg';
170
+ t.islimit = false;
171
+ t.shell = cmd || F.config.$imageconverter;
172
+ }
173
+
174
+ var ImageProto = Image.prototype;
175
+
176
+ ImageProto.clear = function() {
177
+ var self = this;
178
+ self.builder = [];
179
+ return self;
180
+ };
181
+
182
+ ImageProto.measure = function(callback) {
183
+
184
+ var self = this;
185
+ var index = self.filename.lastIndexOf('.');
186
+
187
+ if (!self.filename) {
188
+ callback(new Error('Measure does not support stream.'));
189
+ return;
190
+ }
191
+
192
+ if (index === -1) {
193
+ callback(new Error('This type of file is not supported.'));
194
+ return;
195
+ }
196
+
197
+ F.stats.performance.open++;
198
+ var extension = self.filename.substring(index).toLowerCase();
199
+ var stream = require('fs').createReadStream(self.filename, { start: 0, end: (extension === '.jpg' || extension === '.webp') ? 40000 : 24 });
200
+
201
+ stream.on('data', function(buffer) {
202
+
203
+ switch (extension) {
204
+ case '.jpg':
205
+ callback(null, exports.measureJPG(buffer));
206
+ return;
207
+ case '.gif':
208
+ callback(null, exports.measureGIF(buffer));
209
+ return;
210
+ case '.png':
211
+ callback(null, exports.measurePNG(buffer));
212
+ return;
213
+ case '.webp':
214
+ callback(null, exports.measureWEBP(buffer));
215
+ return;
216
+ }
217
+
218
+ callback(new Error('This type of file is not supported.'));
219
+ });
220
+
221
+ stream.on('error', callback);
222
+ return self;
223
+ };
224
+
225
+ ImageProto.$$measure = function() {
226
+ var self = this;
227
+ return callback => self.measure(callback);
228
+ };
229
+
230
+ ImageProto.save = function(filename, callback, writer) {
231
+
232
+ var self = this;
233
+
234
+ if (typeof(filename) === 'function') {
235
+ callback = filename;
236
+ filename = null;
237
+ }
238
+
239
+ !self.builder.length && self.minify();
240
+ filename = filename || self.filename || '';
241
+
242
+ var command = self.cmd(self.filename ? self.filename : '-', filename);
243
+
244
+ if (F.isWindows)
245
+ command = command.replace(REG_PATH, '\\');
246
+
247
+ var cmd = F.Child.exec(command, function(err) {
248
+
249
+ // clean up
250
+ cmd.kill();
251
+ cmd = null;
252
+
253
+ self.clear();
254
+
255
+ if (!callback)
256
+ return;
257
+
258
+ if (err) {
259
+ callback(err, false);
260
+ return;
261
+ }
262
+
263
+ var middleware = F.routes.imagesmiddleware[self.type];
264
+ if (!middleware)
265
+ return callback(null, true);
266
+
267
+ F.stats.performance.open++;
268
+ var reader = F.Fs.createReadStream(filename);
269
+ var writer = F.Fs.createWriteStream(filename + '_');
270
+
271
+ reader.pipe(middleware()).on('data', chunk => print('--->', chunk.length)).pipe(writer);
272
+ writer.on('finish', () => F.Fs.rename(filename + '_', filename, () => callback(null, true)));
273
+ });
274
+
275
+ if (self.stream) {
276
+ if (self.stream instanceof Buffer)
277
+ cmd.stdin.end(self.stream);
278
+ else
279
+ self.stream.pipe(cmd.stdin);
280
+ }
281
+
282
+ F.cleanup(cmd.stdin);
283
+ writer && writer(cmd.stdin);
284
+ return self;
285
+ };
286
+
287
+ ImageProto.$$save = function(filename, writer) {
288
+ var self = this;
289
+ return function(callback) {
290
+ self.save(filename, callback, writer);
291
+ };
292
+ };
293
+
294
+ ImageProto.pipe = function(stream, type, options) {
295
+
296
+ var self = this;
297
+
298
+ if (typeof(type) === 'object') {
299
+ options = type;
300
+ type = null;
301
+ }
302
+
303
+ !self.builder.length && self.minify();
304
+
305
+ if (!type || !SUPPORTED[type])
306
+ type = self.type;
307
+
308
+ var cmd = F.Child.spawn(CMD_CONVERT[self.shell], self.arg(self.filename ? wrap(self.filename) : '-', (type ? type + ':' : '') + '-'), SPAWN_OPT);
309
+ cmd.stderr.on('data', stream.emit.bind(stream, 'error'));
310
+ cmd.stdout.on('data', stream.emit.bind(stream, 'data'));
311
+ cmd.stdout.on('end', stream.emit.bind(stream, 'end'));
312
+ cmd.on('error', stream.emit.bind(stream, 'error'));
313
+
314
+ var middleware = F.routes.imagesmiddleware[type];
315
+ if (middleware)
316
+ cmd.stdout.pipe(middleware()).pipe(stream, options);
317
+ else
318
+ cmd.stdout.pipe(stream, options);
319
+
320
+ if (self.stream) {
321
+ if (self.stream instanceof Buffer)
322
+ cmd.stdin.end(self.stream);
323
+ else
324
+ self.stream.pipe(cmd.stdin);
325
+ }
326
+
327
+ return self;
328
+ };
329
+
330
+ ImageProto.stream = function(type, writer) {
331
+
332
+ var self = this;
333
+
334
+ !self.builder.length && self.minify();
335
+
336
+ if (!type || !SUPPORTED[type])
337
+ type = self.type;
338
+
339
+ F.stats.performance.open++;
340
+ var cmd = F.Child.spawn(CMD_CONVERT[self.shell], self.arg(self.filename ? wrap(self.filename) : '-', (type ? type + ':' : '') + '-'), SPAWN_OPT);
341
+ if (self.stream) {
342
+ if (self.stream instanceof Buffer)
343
+ cmd.stdin.end(self.stream);
344
+ else
345
+ self.stream.pipe(cmd.stdin);
346
+ }
347
+
348
+ writer && writer(cmd.stdin);
349
+ var middleware = F.routes.imagesmiddleware[type];
350
+ return middleware ? cmd.stdout.pipe(middleware()) : cmd.stdout;
351
+ };
352
+
353
+ ImageProto.cmd = function(filenameFrom, filenameTo) {
354
+
355
+ var self = this;
356
+ var cmd = '';
357
+
358
+ if (!self.islimit) {
359
+ var tmp = F.config.$imagememory;
360
+ if (tmp) {
361
+ self.limit('memory', (1500 / 100) * tmp);
362
+ self.limit('map', (3000 / 100) * tmp);
363
+ }
364
+ }
365
+
366
+ self.builder.sort(sort);
367
+
368
+ var length = self.builder.length;
369
+ for (var i = 0; i < length; i++)
370
+ cmd += (cmd ? ' ' : '') + self.builder[i].cmd;
371
+
372
+ return CMD_CONVERT2[self.shell] + wrap(filenameFrom, true) + ' ' + cmd + wrap(filenameTo, true);
373
+ };
374
+
375
+ function sort(a, b) {
376
+ return a.priority > b.priority ? 1 : -1;
377
+ }
378
+
379
+ ImageProto.arg = function(first, last) {
380
+
381
+ var self = this;
382
+ var arr = [];
383
+
384
+ if (self.shell === 'gm')
385
+ arr.push('convert');
386
+
387
+ first && arr.push(first);
388
+
389
+ if (!self.islimit) {
390
+ let tmp = F.config.$imagememory;
391
+ if (tmp) {
392
+ self.limit('memory', (1500 / 100) * tmp);
393
+ self.limit('map', (3000 / 100) * tmp);
394
+ }
395
+ }
396
+
397
+ self.builder.sort(sort);
398
+
399
+ for (let o of self.builder) {
400
+ let index = o.cmd.indexOf(' ');
401
+ if (index === -1) {
402
+ arr.push(o.cmd);
403
+ } else {
404
+ arr.push(o.cmd.substring(0, index));
405
+ arr.push(o.cmd.substring(index + 1).replace(/"/g, ''));
406
+ }
407
+ }
408
+
409
+ last && arr.push(last);
410
+ return arr;
411
+ };
412
+
413
+ ImageProto.identify = function(callback) {
414
+ var self = this;
415
+ F.Child.exec((self.shell === 'gm' ? 'gm ' : '') + 'identify' + wrap(self.filename, true), function(err, stdout) {
416
+
417
+ if (err) {
418
+ callback(err, null);
419
+ return;
420
+ }
421
+
422
+ var arr = stdout.split(' ');
423
+ var size = arr[2].split('x');
424
+ var obj = { type: arr[1], width: F.TUtils.parseInt(size[0]), height: F.TUtils.parseInt(size[1]) };
425
+ callback(null, obj);
426
+ });
427
+
428
+ return self;
429
+ };
430
+
431
+ ImageProto.$$identify = function() {
432
+ var self = this;
433
+ return function(callback) {
434
+ self.identify(callback);
435
+ };
436
+ };
437
+
438
+ ImageProto.push = function(key, value, priority, encode) {
439
+ var self = this;
440
+ var cmd = key;
441
+
442
+ if (value != null) {
443
+ if (encode && typeof(value) === 'string')
444
+ cmd += ' ' + D + value.replace(REG_ESCAPE, '') + D;
445
+ else
446
+ cmd += ' ' + value;
447
+ }
448
+
449
+ var obj = F.temporary.images[cmd];
450
+ if (obj) {
451
+ obj.priority = priority;
452
+ self.builder.push(obj);
453
+ } else {
454
+ F.temporary.images[cmd] = { cmd: cmd, priority: priority };
455
+ self.builder.push(F.temporary.images[cmd]);
456
+ }
457
+
458
+ return self;
459
+ };
460
+
461
+ ImageProto.output = function(type) {
462
+ var self = this;
463
+ if (type[0] === '.')
464
+ type = type.substring(1);
465
+ self.type = type;
466
+ return self;
467
+ };
468
+
469
+ ImageProto.resize = function(w, h, options) {
470
+ options = options || '';
471
+
472
+ var self = this;
473
+ var size = '';
474
+
475
+ if (w && h)
476
+ size = w + 'x' + h;
477
+ else if (w && !h)
478
+ size = w + 'x';
479
+ else if (!w && h)
480
+ size = 'x' + h;
481
+
482
+ return self.push('-resize', size + options, 1, true);
483
+ };
484
+
485
+ ImageProto.thumbnail = function(w, h, options) {
486
+ options = options || '';
487
+
488
+ var self = this;
489
+ var size = '';
490
+
491
+ if (w && h)
492
+ size = w + 'x' + h;
493
+ else if (w && !h)
494
+ size = w;
495
+ else if (!w && h)
496
+ size = 'x' + h;
497
+
498
+ return self.push('-thumbnail', size + options, 1, true);
499
+ };
500
+
501
+ ImageProto.geometry = function(w, h, options) {
502
+ options = options || '';
503
+
504
+ var self = this;
505
+ var size = '';
506
+
507
+ if (w && h)
508
+ size = w + 'x' + h;
509
+ else if (w && !h)
510
+ size = w;
511
+ else if (!w && h)
512
+ size = 'x' + h;
513
+
514
+ return self.push('-geometry', size + options, 1, true);
515
+ };
516
+
517
+
518
+ ImageProto.filter = function(type) {
519
+ return this.push('-filter', type, 1, true);
520
+ };
521
+
522
+ ImageProto.trim = function() {
523
+ return this.push('-trim +repage', 1);
524
+ };
525
+
526
+ ImageProto.limit = function(type, value) {
527
+ this.islimit = true;
528
+ return this.push('-limit', type + ' ' + value, 1);
529
+ };
530
+
531
+ ImageProto.extent = function(w, h, x, y) {
532
+
533
+ var self = this;
534
+ var size = '';
535
+
536
+ if (w && h)
537
+ size = w + 'x' + h;
538
+ else if (w && !h)
539
+ size = w;
540
+ else if (!w && h)
541
+ size = 'x' + h;
542
+
543
+ if (x || y) {
544
+ !x && (x = 0);
545
+ !y && (y = 0);
546
+ size += (x >= 0 ? '+' : '') + x + (y >= 0 ? '+' : '') + y;
547
+ }
548
+
549
+ return self.push('-extent', size, 4, true);
550
+ };
551
+
552
+ ImageProto.miniature = function(w, h, color, filter) {
553
+ return this.filter(filter || 'Hamming').thumbnail(w, h).background(color ? color : 'white').align('center').extent(w, h);
554
+ };
555
+
556
+ /**
557
+ * Resize picture to center
558
+ * @param {Number} w
559
+ * @param {Number} h
560
+ * @param {String} color Optional, background color.
561
+ * @return {Image}
562
+ */
563
+ ImageProto.resizecenter = function(w, h, color) {
564
+ return this.resize(w, h, '^').background(color ? color : 'white').align('center').crop(w, h);
565
+ };
566
+
567
+ /**
568
+ * Resize picture to align
569
+ * @param {Number} w
570
+ * @param {Number} h
571
+ * @param {String} align (top, center, bottom)
572
+ * @param {String} color Optional, background color.
573
+ * @return {Image}
574
+ */
575
+ ImageProto.resizealign = function(w, h, align, color) {
576
+ return this.resize(w, h, '^').background(color ? color : 'white').align(align || 'center').crop(w, h);
577
+ };
578
+
579
+ ImageProto.scale = function(w, h, options) {
580
+ options = options || '';
581
+
582
+ var self = this;
583
+ var size = '';
584
+
585
+ if (w && h)
586
+ size = w + 'x' + h;
587
+ else if (w && !h)
588
+ size = w;
589
+ else if (!w && h)
590
+ size = 'x' + h;
591
+
592
+ return self.push('-scale', size + options, 1, true);
593
+ };
594
+
595
+ ImageProto.crop = function(w, h, x, y) {
596
+ return this.push('-crop', w + 'x' + h + '+' + (x || 0) + '+' + (y || 0), 4, true);
597
+ };
598
+
599
+ ImageProto.quality = function(percentage) {
600
+ return this.push('-quality', percentage || 80, 5, true);
601
+ };
602
+
603
+ ImageProto.align = function(type) {
604
+
605
+ var output;
606
+
607
+ switch (type) {
608
+ case 'left top':
609
+ case 'top left':
610
+ output = 'NorthWest';
611
+ break;
612
+ case 'left bottom':
613
+ case 'bottom left':
614
+ output = 'SouthWest';
615
+ break;
616
+ case 'right top':
617
+ case 'top right':
618
+ output = 'NorthEast';
619
+ break;
620
+ case 'right bottom':
621
+ case 'bottom right':
622
+ output = 'SouthEast';
623
+ break;
624
+ case 'left center':
625
+ case 'center left':
626
+ case 'left':
627
+ output = 'West';
628
+ break;
629
+ case 'right center':
630
+ case 'center right':
631
+ case 'right':
632
+ output = 'East';
633
+ break;
634
+ case 'bottom center':
635
+ case 'center bottom':
636
+ case 'bottom':
637
+ output = 'South';
638
+ break;
639
+ case 'top center':
640
+ case 'center top':
641
+ case 'top':
642
+ output = 'North';
643
+ break;
644
+ case 'center center':
645
+ case 'center':
646
+ case 'middle':
647
+ output = 'Center';
648
+ break;
649
+ default:
650
+ output = type;
651
+ break;
652
+ }
653
+
654
+ output && this.push('-gravity', output, 3, true);
655
+ return this;
656
+ };
657
+
658
+ ImageProto.gravity = function(type) {
659
+ return this.align(type);
660
+ };
661
+
662
+ ImageProto.blur = function(radius) {
663
+ return this.push('-blur', radius, 10, true);
664
+ };
665
+
666
+ ImageProto.normalize = function() {
667
+ return this.push('-normalize', null, 10);
668
+ };
669
+
670
+ ImageProto.rotate = function(deg) {
671
+ return this.push('-rotate', deg || 0, 8, true);
672
+ };
673
+
674
+ ImageProto.flip = function() {
675
+ return this.push('-flip', null, 10);
676
+ };
677
+
678
+ ImageProto.flop = function() {
679
+ return this.push('-flop', null, 10);
680
+ };
681
+
682
+ ImageProto.define = function(value) {
683
+ return this.push('-define', value, 10, true);
684
+ };
685
+
686
+ ImageProto.minify = function() {
687
+ return this.push('+profile', '*', null, 10, true);
688
+ };
689
+
690
+ ImageProto.grayscale = function() {
691
+ return this.push('-colorspace', 'Gray', 10, true);
692
+ };
693
+
694
+ ImageProto.bitdepth = function(value) {
695
+ return this.push('-depth', value, 10, true);
696
+ };
697
+
698
+ ImageProto.colors = function(value) {
699
+ return this.push('-colors', value, 10, true);
700
+ };
701
+
702
+ ImageProto.background = function(color) {
703
+ return this.push('-background', color, 2, true).push('-extent 0x0', null, 2);
704
+ };
705
+
706
+ ImageProto.fill = function(color) {
707
+ return this.push('-fill', color, 2, true);
708
+ };
709
+
710
+ ImageProto.sepia = function() {
711
+ return this.push('-modulate', '115,0,100', 4).push('-colorize', '7,21,50', 5);
712
+ };
713
+
714
+ ImageProto.watermark = function(filename, x, y, w, h) {
715
+ return this.push('-draw', 'image over {1},{2} {3},{4} {5}{0}{5}'.format(filename, x || 0, y || 0, w || 0, h || 0, D), 6, true);
716
+ };
717
+
718
+ ImageProto.make = function(fn) {
719
+ fn.call(this, this);
720
+ return this;
721
+ };
722
+
723
+ ImageProto.command = function(key, value, priority, esc) {
724
+
725
+ if (priority === true) {
726
+ priority = 0;
727
+ esc = true;
728
+ }
729
+
730
+ return this.push(key, value, priority || 10, esc);
731
+ };
732
+
733
+ function wrap(command, empty) {
734
+ return (empty ? ' ' : '') + (command === '-' ? command : (D + command.replace(REG_ESCAPE, '') + D));
735
+ }
736
+
737
+ exports.Image = Image;
738
+
739
+ exports.load = function(filename, cmd, width, height) {
740
+ return new Image(filename, cmd, width, height);
741
+ };
742
+
743
+ exports.middleware = function(type, fn) {
744
+ if (type[0] === '.')
745
+ type = type.substring(1);
746
+ F.routes.imagesmiddleware[type] = fn;
747
+ };