PageSourceSearch

https://dribnet.github.io/sewn/p5App/p5_1.2.0.js

js dribnet.github.io collected 2026-10-03 09:04:07 UTC 3,691,092 bytes, 95,702 lines download raw bytes

1/*! p5.js v1.2.0 December 19, 2020 */
2(function(f) {
3  if (typeof exports === 'object' && typeof module !== 'undefined') {
4    module.exports = f();
5  } else if (typeof define === 'function' && define.amd) {
6    define([], f);
7  } else {
8    var g;
9    if (typeof window !== 'undefined') {
10      g = window;
11    } else if (typeof global !== 'undefined') {
12      g = global;
13    } else if (typeof self !== 'undefined') {
14      g = self;
15    } else {
16      g = this;
17    }
18    g.p5 = f();
19  }
20})(function() {
21  var define, module, exports;
22  return (function() {
23    function r(e, n, t) {
24      function o(i, f) {
25        if (!n[i]) {
26          if (!e[i]) {
27            var c = 'function' == typeof require && require;
28            if (!f && c) return c(i, !0);
29            if (u) return u(i, !0);
30            var a = new Error("Cannot find module '" + i + "'");
31            throw ((a.code = 'MODULE_NOT_FOUND'), a);
32          }
33          var p = (n[i] = { exports: {} });
34          e[i][0].call(
35            p.exports,
36            function(r) {
37              var n = e[i][1][r];
38              return o(n || r);
39            },
40            p,
41            p.exports,
42            r,
43            e,
44            n,
45            t
46          );
47        }
48        return n[i].exports;
49      }
50      for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++)
51        o(t[i]);
52      return o;
53    }
54    return r;
55  })()(
56    {
57      1: [
58        function(_dereq_, module, exports) {
59          module.exports = {
60            p5: {
61              describe: {
62                name: 'describe',
63                params: [
64                  {
65                    name: 'text',
66                    description: '<p>description of the canvas</p>\n',
67                    type: 'String'
68                  },
69                  {
70                    name: 'display',
71                    description: '<p>either LABEL or FALLBACK (Optional)</p>\n',
72                    type: 'Constant',
73                    optional: true
74                  }
75                ],
76                class: 'p5',
77                module: 'Environment'
78              },
79              describeElement: {
80                name: 'describeElement',
81                params: [
82                  {
83                    name: 'name',
84                    description: '<p>name of the element</p>\n',
85                    type: 'String'
86                  },
87                  {
88                    name: 'text',
89                    description: '<p>description of the element</p>\n',
90                    type: 'String'
91                  },
92                  {
93                    name: 'display',
94                    description: '<p>either LABEL or FALLBACK (Optional)</p>\n',
95                    type: 'Constant',
96                    optional: true
97                  }
98                ],
99                class: 'p5',
100                module: 'Environment'
101              },
102              textOutput: {
103                name: 'textOutput',
104                params: [
105                  {
106                    name: 'display',
107                    description: '<p>either FALLBACK or LABEL (Optional)</p>\n',
108                    type: 'Constant',
109                    optional: true
110                  }
111                ],
112                class: 'p5',
113                module: 'Environment'
114              },
115              gridOutput: {
116                name: 'gridOutput',
117                params: [
118                  {
119                    name: 'display',
120                    description: '<p>either FALLBACK or LABEL (Optional)</p>\n',
121                    type: 'Constant',
122                    optional: true
123                  }
124                ],
125                class: 'p5',
126                module: 'Environment'
127              },
128              alpha: {
129                name: 'alpha',
130                params: [
131                  {
132                    name: 'color',
133                    description:
134                      '<p><a href="#/p5.Color">p5.Color</a> object, color components,\n                                        or CSS color</p>\n',
135                    type: 'p5.Color|Number[]|String'
136                  }
137                ],
138                class: 'p5',
139                module: 'Color'
140              },
141              blue: {
142                name: 'blue',
143                params: [
144                  {
145                    name: 'color',
146                    description:
147                      '<p><a href="#/p5.Color">p5.Color</a> object, color components,\n                                        or CSS color</p>\n',
148                    type: 'p5.Color|Number[]|String'
149                  }
150                ],
151                class: 'p5',
152                module: 'Color'
153              },
154              brightness: {
155                name: 'brightness',
156                params: [
157                  {
158                    name: 'color',
159                    description:
160                      '<p><a href="#/p5.Color">p5.Color</a> object, color components,\n                                        or CSS color</p>\n',
161                    type: 'p5.Color|Number[]|String'
162                  }
163                ],
164                class: 'p5',
165                module: 'Color'
166              },
167              color: {
168                name: 'color',
169                class: 'p5',
170                module: 'Color',
171                overloads: [
172                  {
173                    params: [
174                      {
175                        name: 'gray',
176                        description:
177                          '<p>number specifying value between white and black.</p>\n',
178                        type: 'Number'
179                      },
180                      {
181                        name: 'alpha',
182                        description:
183                          '<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n',
184                        type: 'Number',
185                        optional: true
186                      }
187                    ]
188                  },
189                  {
190                    params: [
191                      {
192                        name: 'v1',
193                        description:
194                          '<p>red or hue value relative to\n                                the current color range</p>\n',
195                        type: 'Number'
196                      },
197                      {
198                        name: 'v2',
199                        description:
200                          '<p>
200green or saturation value\n                                relative to the current color range</p>\n',
201                        type: 'Number'
202                      },
203                      {
204                        name: 'v3',
205                        description:
206                          '<p>blue or brightness value\n                                relative to the current color range</p>\n',
207                        type: 'Number'
208                      },
209                      {
210                        name: 'alpha',
211                        description: '',
212                        type: 'Number',
213                        optional: true
214                      }
215                    ]
216                  },
217                  {
218                    params: [
219                      {
220                        name: 'value',
221                        description: '<p>a color string</p>\n',
222                        type: 'String'
223                      }
224                    ]
225                  },
226                  {
227                    params: [
228                      {
229                        name: 'values',
230                        description:
231                          '<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n',
232                        type: 'Number[]'
233                      }
234                    ]
235                  },
236                  {
237                    params: [
238                      {
239                        name: 'color',
240                        description: '',
241                        type: 'p5.Color'
242                      }
243                    ]
244                  }
245                ]
246              },
247              green: {
248                name: 'green',
249                params: [
250                  {
251                    name: 'color',
252                    description:
253                      '<p><a href="#/p5.Color">p5.Color</a> object, color components,\n                                        or CSS color</p>\n',
254                    type: 'p5.Color|Number[]|String'
255                  }
256                ],
257                class: 'p5',
258                module: 'Color'
259              },
260              hue: {
261                name: 'hue',
262                params: [
263                  {
264                    name: 'color',
265                    description:
266                      '<p><a href="#/p5.Color">p5.Color</a> object, color components,\n                                        or CSS color</p>\n',
267                    type: 'p5.Color|Number[]|String'
268                  }
269                ],
270                class: 'p5',
271                module: 'Color'
272              },
273              lerpColor: {
274                name: 'lerpColor',
275                params: [
276                  {
277                    name: 'c1',
278                    description: '<p>interpolate from this color</p>\n',
279                    type: 'p5.Color'
280                  },
281                  {
282                    name: 'c2',
283                    description: '<p>interpolate to this color</p>\n',
284                    type: 'p5.Color'
285                  },
286                  {
287                    name: 'amt',
288                    description: '<p>number between 0 and 1</p>\n',
289                    type: 'Number'
290                  }
291                ],
292                class: 'p5',
293                module: 'Color'
294              },
295              lightness: {
296                name: 'lightness',
297                params: [
298                  {
299                    name: 'color',
300                    description:
301                      '<p><a href="#/p5.Color">p5.Color</a> object, color components,\n                                        or CSS color</p>\n',
302                    type: 'p5.Color|Number[]|String'
303                  }
304                ],
305                class: 'p5',
306                module: 'Color'
307              },
308              red: {
309                name: 'red',
310                params: [
311                  {
312                    name: 'color',
313                    description:
314                      '<p><a href="#/p5.Color">p5.Color</a> object, color components,\n                                        or CSS color</p>\n',
315                    type: 'p5.Color|Number[]|String'
316                  }
317                ],
318                class: 'p5',
319                module: 'Color'
320              },
321              saturation: {
322                name: 'saturation',
323                params: [
324                  {
325                    name: 'color',
326                    description:
327                      '<p><a href="#/p5.Color">p5.Color</a> object, color components,\n                                        or CSS color</p>\n',
328                    type: 'p5.Color|Number[]|String'
329                  }
330                ],
331                class: 'p5',
332                module: 'Color'
333              },
334              background: {
335                name: 'background',
336                class: 'p5',
337                module: 'Color',
338                overloads: [
339                  {
340                    params: [
341                      {
342                        name: 'color',
343                        description:
344                          '<p>any value created by the <a href="#/p5/color">color()</a> function</p>\n',
345                        type: 'p5.Color'
346                      }
347                    ],
348                    chainable: 1
349                  },
350                  {
351                    params: [
352                      {
353                        name: 'colorstring',
354                        description:
355                          '<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n',
356                        type: 'String'
357                      },
358                      {
359                        name: 'a',
360                        description:
361                          '<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n',
362                        type: 'Number',
363                        optional: true
364                      }
365                    ],
366                    chainable: 1
367                  },
368                  {
369                    params: [
370                      {
371                        name: 'gray',
372                        description: '<p>specifies a value between white and black</p>\n',
373                        type: 'Number'
374                      },
375                      {
376                        name: 'a',
377                        description: '',
378                        type: 'Number',
379                        optional: true
380                      }
381                    ],
382                    chainable: 1
383                  },
384                  {
385                    params: [
386                      {
387                        name: 'v1',
388                        description:
389                          '<p>red or hue value (depending on the current color\n                       mode)</p>\n',
390                        type: 'Number'
391                      },
392                      {
393                        name: 'v2',
394                        description:
395                          '<p>green or saturation value (depending on the current\n                       color mode)</p>\n',
396                        type: 'Number'
397                      },
398                      {
399                        name: 'v3',
400                        description:
401                          '<p>blue or brightness value (depending on the current\n                       color mode)</p>\n',
402                        type: 'Number'
403                      },
404                      {
405                        name: 'a',
406                        description: '',
407                        type: 'Number',
408                        optional: true
409                      }
410                    ],
411                    chainable: 1
412                  },
413                  {
414                    params: [
415                      {
416                        name: 'values',
417                        description:
418                          '<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n',
419                        type: 'Number[]'
420                      }
421                    ],
422                    chainable: 1
423                  },
424                  {
425                    params: [
426                      {
427                        name: 'image',
428                        description:
429                          '<p>image created with <a href="#/p5/loadImage">loadImage()</a> or <a href="#/p5/createImage">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n',
430                        type: 'p5.Image'
431                      },
432                      {
433                        name: 'a',
434                        description: '',
435                        type: 'Number',
436                        optional: true
437                      }
438                    ],
439                    chainable: 1
440                  }
441                ]
442              },
443              clear: {
444                name: 'clear',
445                class: 'p5',
446                module: 'Color'
447              },
448              colorMode: {
449                name: 'colorMode',
450                class: 'p5',
451                module: 'Color',
452                overloads: [
453                  {
454                    params: [
455                      {
456                        name: 'mode',
457                        description:
458                          '<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n',
459                        type: 'Constant'
460                      },
461                      {
462                        name: 'max',
463                        description: '<p>range for all values</p>\n',
464                        type: 'Number',
465                        optional: true
466                      }
467                    ],
468                    chainable: 1
469                  },
470                  {
471                    params: [
472                      {
473                        name: 'mode',
474                        description: '',
475                        type: 'Constant'
476                      },
477                      {
478                        name: 'max1',
479                        description:
480                          '<p>range for the red or hue depending on the\n                             current color mode</p>\n',
481                        type: 'Number'
482                      },
483                      {
484                        name: 'max2',
485                        description:
486                          '<p>range for the green or saturation depending\n                             on the current color mode</p>\n',
487                        type: 'Number'
488                      },
489                      {
490                        name: 'max3',
491                        description:
492                          '<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n',
493                        type: 'Number'
494                      },
495                      {
496                        name: 'maxA',
497                        description: '<p>range for the alpha</p>\n',
498                        type: 'Number',
499                        optional: true
500                      }
501                    ],
502                    chainable: 1
503                  }
504                ]
505              },
506              fill: {
507                name: 'fill',
508                class: 'p5',
509                module: 'Color',
510                overloads: [
511                  {
512                    params: [
513                      {
514                        name: 'v1',
515                        description:
516                          '<p>red or hue value relative to\n                                the current color range</p>\n',
517                        type: 'Number'
518                      },
519                      {
520                        name: 'v2',
521                        description:
522                          '<p>
522green or saturation value\n                                relative to the current color range</p>\n',
523                        type: 'Number'
524                      },
525                      {
526                        name: 'v3',
527                        description:
528                          '<p>blue or brightness value\n                                relative to the current color range</p>\n',
529                        type: 'Number'
530                      },
531                      {
532                        name: 'alpha',
533                        description: '',
534                        type: 'Number',
535                        optional: true
536                      }
537                    ],
538                    chainable: 1
539                  },
540                  {
541                    params: [
542                      {
543                        name: 'value',
544                        description: '<p>a color string</p>\n',
545                        type: 'String'
546                      }
547                    ],
548                    chainable: 1
549                  },
550                  {
551                    params: [
552                      {
553                        name: 'gray',
554                        description: '<p>a gray value</p>\n',
555                        type: 'Number'
556                      },
557                      {
558                        name: 'alpha',
559                        description: '',
560                        type: 'Number',
561                        optional: true
562                      }
563                    ],
564                    chainable: 1
565                  },
566                  {
567                    params: [
568                      {
569                        name: 'values',
570                        description:
571                          '<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n',
572                        type: 'Number[]'
573                      }
574                    ],
575                    chainable: 1
576                  },
577                  {
578                    params: [
579                      {
580                        name: 'color',
581                        description: '<p>the fill color</p>\n',
582                        type: 'p5.Color'
583                      }
584                    ],
585                    chainable: 1
586                  }
587                ]
588              },
589              noFill: {
590                name: 'noFill',
591                class: 'p5',
592                module: 'Color'
593              },
594              noStroke: {
595                name: 'noStroke',
596                class: 'p5',
597                module: 'Color'
598              },
599              stroke: {
600                name: 'stroke',
601                class: 'p5',
602                module: 'Color',
603                overloads: [
604                  {
605                    params: [
606                      {
607                        name: 'v1',
608                        description:
609                          '<p>red or hue value relative to\n                                the current color range</p>\n',
610                        type: 'Number'
611                      },
612                      {
613                        name: 'v2',
614                        description:
615                          '<p>green or saturation value\n                                relative to the current color range</p>\n',
616                        type: 'Number'
617                      },
618                      {
619                        name: 'v3',
620                        description:
621                          '<p>blue or brightness value\n                                relative to the current color range</p>\n',
622                        type: 'Number'
623                      },
624                      {
625                        name: 'alpha',
626                        description: '',
627                        type: 'Number',
628                        optional: true
629                      }
630                    ],
631                    chainable: 1
632                  },
633                  {
634                    params: [
635                      {
636                        name: 'value',
637                        description: '<p>a color string</p>\n',
638                        type: 'String'
639                      }
640                    ],
641                    chainable: 1
642                  },
643                  {
644                    params: [
645                      {
646                        name: 'gray',
647                        description: '<p>a gray value</p>\n',
648                        type: 'Number'
649                      },
650                      {
651                        name: 'alpha',
652                        description: '',
653                        type: 'Number',
654                        optional: true
655                      }
656                    ],
657                    chainable: 1
658                  },
659                  {
660                    params: [
661                      {
662                        name: 'values',
663                        description:
664                          '<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n',
665                        type: 'Number[]'
666                      }
667                    ],
668                    chainable: 1
669                  },
670                  {
671                    params: [
672                      {
673                        name: 'color',
674                        description: '<p>the stroke color</p>\n',
675                        type: 'p5.Color'
676                      }
677                    ],
678                    chainable: 1
679                  }
680                ]
681              },
682              erase: {
683                name: 'erase',
684                params: [
685                  {
686                    name: 'strengthFill',
687                    description:
688                      "<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
689                    type: 'Number',
690                    optional: true
691                  },
692                  {
693                    name: 'strengthStroke',
694                    description:
695                      "<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
696                    type: 'Number',
697                    optional: true
698                  }
699                ],
700                class: 'p5',
701                module: 'Color'
702              },
703              noErase: {
704                name: 'noErase',
705                class: 'p5',
706                module: 'Color'
707              },
708              arc: {
709                name: 'arc',
710                params: [
711                  {
712                    name: 'x',
713                    description: "<p>x-coordinate of the arc's ellipse</p>\n",
714                    type: 'Number'
715                  },
716                  {
717                    name: 'y',
718                    description: "<p>y-coordinate of the arc's ellipse</p>\n",
719                    type: 'Number'
720                  },
721                  {
722                    name: 'w',
723                    description: "<p>width of the arc's ellipse by default</p>\n",
724                    type: 'Number'
725                  },
726                  {
727                    name: 'h',
728                    description: "<p>height of the arc's ellipse by default</p>\n",
729                    type: 'Number'
730                  },
731                  {
732                    name: 'start',
733                    description: '<p>angle to start the arc, specified in radians</p>\n',
734                    type: 'Number'
735                  },
736                  {
737                    name: 'stop',
738                    description: '<p>angle to stop the arc, specified in radians</p>\n',
739                    type: 'Number'
740                  },
741                  {
742                    name: 'mode',
743                    description:
744                      '<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n',
745                    type: 'Constant',
746                    optional: true
747                  },
748                  {
749                    name: 'detail',
750                    description:
751                      '<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25.</p>\n',
752                    type: 'Number',
753                    optional: true
754                  }
755                ],
756                class: 'p5',
757                module: 'Shape'
758              },
759              ellipse: {
760                name: 'ellipse',
761                class: 'p5',
762                module: 'Shape',
763                overloads: [
764                  {
765                    params: [
766                      {
767                        name: 'x',
768                        description: '<p>x-coordinate of the center of ellipse.</p>\n',
769                        type: 'Number'
770                      },
771                      {
772                        name: 'y',
773                        description: '<p>y-coordinate of the center of ellipse.</p>\n',
774                        type: 'Number'
775                      },
776                      {
777                        name: 'w',
778                        description: '<p>width of the ellipse.</p>\n',
779                        type: 'Number'
780                      },
781                      {
782                        name: 'h',
783                        description: '<p>height of the ellipse.</p>\n',
784                        type: 'Number',
785                        optional: true
786                      }
787                    ],
788                    chainable: 1
789                  },
790                  {
791                    params: [
792                      {
793                        name: 'x',
794                        description: '',
795                        type: 'Number'
796                      },
797                      {
798                        name: 'y',
799                        description: '',
800                        type: 'Number'
801                      },
802                      {
803                        name: 'w',
804                        description: '',
805                        type: 'Number'
806                      },
807                      {
808                        name: 'h',
809                        description: '',
810                        type: 'Number'
811                      },
812                      {
813                        name: 'detail',
814                        description:
815                          '<p>number of radial sectors to draw (for WebGL mode)</p>\n',
816                        type: 'Integer'
817                      }
818                    ]
819                  }
820                ]
821              },
822              circle: {
823                name: 'circle',
824                params: [
825                  {
826                    name: 'x',
827                    description: '<p>x-coordinate of the centre of the circle.</p>\n',
828                    type: 'Number'
829                  },
830                  {
831                    name: 'y',
832                    description: '<p>y-coordinate of the centre of the circle.</p>\n',
833                    type: 'Number'
834                  },
835                  {
836                    name: 'd',
837                    description: '<p>diameter of the circle.</p>\n',
838                    type: 'Number'
839                  }
840                ],
841                class: 'p5',
842                module: 'Shape'
843              },
844              line: {
845                name: 'line',
846                class: 'p5',
847                module: 'Shape',
848                overloads: [
849                  {
850                    params: [
851                      {
852                        name: 'x1',
853                        description: '<p>the x-coordinate of the first point</p>\n',
854                        type: 'Number'
855                      },
856                      {
857                        name: 'y1',
858                        description: '<p>the y-coordinate of the first point</p>\n',
859                        type: 'Number'
860                      },
861                      {
862                        name: 'x2',
863                        description: '<p>the x-coordinate of the second point</p>\n',
864                        type: 'Number'
865                      },
866                      {
867                        name: 'y2',
868                        description: '<p>the y-coordinate of the second point</p>\n',
869                        type: 'Number'
870                      }
871                    ],
872                    chainable: 1
873                  },
874                  {
875                    params: [
876                      {
877                        name: 'x1',
878                        description: '',
879                        type: 'Number'
880                      },
881                      {
882                        name: 'y1',
883                        description: '',
884                        type: 'Number'
885                      },
886                      {
887                        name: 'z1',
888                        description: '<p>the z-coordinate of the first point</p>\n',
889                        type: 'Number'
890                      },
891                      {
892                        name: 'x2',
893                        description: '',
894                        type: 'Number'
895                      },
896                      {
897                        name: 'y2',
898                        description: '',
899                        type: 'Number'
900                      },
901                      {
902                        name: 'z2',
903                        description: '<p>the z-coordinate of the second point</p>\n',
904                        type: 'Number'
905                      }
906                    ],
907                    chainable: 1
908                  }
909                ]
910              },
911              point: {
912                name: 'point',
913                class: 'p5',
914                module: 'Shape',
915                overloads: [
916                  {
917                    params: [
918                      {
919                        name: 'x',
920                        description: '<p>the x-coordinate</p>\n',
921                        type: 'Number'
922                      },
923                      {
924                        name: 'y',
925                        description: '<p>the y-coordinate</p>\n',
926                        type: 'Number'
927                      },
928                      {
929                        name: 'z',
930                        description: '<p>the z-coordinate (for WebGL mode)</p>\n',
931                        type: 'Number',
932                        optional: true
933                      }
934                    ],
935                    chainable: 1
936                  },
937                  {
938                    params: [
939                      {
940                        name: 'coordinate_vector',
941                        description: '<p>the coordinate vector</p>\n',
942                        type: 'p5.Vector'
943                      }
944                    ],
945                    chainable: 1
946                  }
947                ]
948              },
949              quad: {
950                name: 'quad',
951                class: 'p5',
952                module: 'Shape',
953                overloads: [
954                  {
955                    params: [
956                      {
957                        name: 'x1',
958                        description: '<p>the x-coordinate of the first point</p>\n',
959                        type: 'Number'
960                      },
961                      {
962                        name: 'y1',
963                        description: '<p>the y-coordinate of the first point</p>\n',
964                        type: 'Number'
965                      },
966                      {
967                        name: 'x2',
968                        description: '<p>the x-coordinate of the second point</p>\n',
969                        type: 'Number'
970                      },
971                      {
972                        name: 'y2',
973                        description: '<p>the y-coordinate of the second point</p>\n',
974                        type: 'Number'
975                      },
976                      {
977                        name: 'x3',
978                        description: '<p>the x-coordinate of the third point</p>\n',
979                        type: 'Number'
980                      },
981                      {
982                        name: 'y3',
983                        description: '<p>the y-coordinate of the third point</p>\n',
984                        type: 'Number'
985                      },
986                      {
987                        name: 'x4',
988                        description: '<p>the x-coordinate of the fourth point</p>\n',
989                        type: 'Number'
990                      },
991                      {
992                        name: 'y4',
993                        description: '<p>the y-coordinate of the fourth point</p>\n',
994                        type: 'Number'
995                      }
996                    ],
997                    chainable: 1
998                  },
999                  {
1000                    params: [
1001                      {
1002                        name: 'x1',
1003                        description: '',
1004                        type: 'Number'
1005                      },
1006                      {
1007                        name: 'y1',
1008                        description: '',
1009                        type: 'Number'
1010                      },
1011                      {
1012                        name: 'z1',
1013                        description: '<p>the z-coordinate of the first point</p>\n',
1014                        type: 'Number'
1015                      },
1016                      {
1017                        name: 'x2',
1018                        description: '',
1019                        type: 'Number'
1020                      },
1021                      {
1022                        name: 'y2',
1023                        description: '',
1024                        type: 'Number'
1025                      },
1026                      {
1027                        name: 'z2',
1028                        description: '<p>the z-coordinate of the second point</p>\n',
1029                        type: 'Number'
1030                      },
1031                      {
1032                        name: 'x3',
1033                        description: '',
1034                        type: 'Number'
1035                      },
1036                      {
1037                        name: 'y3',
1038                        description: '',
1039                        type: 'Number'
1040                      },
1041                      {
1042                        name: 'z3',
1043                        description: '<p>the z-coordinate of the third point</p>\n',
1044                        type: 'Number'
1045                      },
1046                      {
1047                        name: 'x4',
1048                        description: '',
1049                        type: 'Number'
1050                      },
1051                      {
1052                        name: 'y4',
1053                        description: '',
1054                        type: 'Number'
1055                      },
1056                      {
1057                        name: 'z4',
1058                        description: '<p>the z-coordinate of the fourth point</p>\n',
1059                        type: 'Number'
1060                      }
1061                    ],
1062                    chainable: 1
1063                  }
1064                ]
1065              },
1066              rect: {
1067                name: 'rect',
1068                class: 'p5',
1069                module: 'Shape',
1070                overloads: [
1071                  {
1072                    params: [
1073                      {
1074                        name: 'x',
1075                        description: '<p>x-coordinate of the rectangle.</p>\n',
1076                        type: 'Number'
1077                      },
1078                      {
1079                        name: 'y',
1080                        description: '<p>y-coordinate of the rectangle.</p>\n',
1081                        type: 'Number'
1082                      },
1083                      {
1084                        name: 'w',
1085                        description: '<p>width of the rectangle.</p>\n',
1086                        type: 'Number'
1087                      },
1088                      {
1089                        name: 'h',
1090                        description: '<p>height of the rectangle.</p>\n',
1091                        type: 'Number',
1092                        optional: true
1093                      },
1094                      {
1095                        name: 'tl',
1096                        description: '<p>optional radius of top-left corner.</p>\n',
1097                        type: 'Number',
1098                        optional: true
1099                      },
1100                      {
1101                        name: 'tr',
1102                        description: '<p>optional radius of top-right corner.</p>\n',
1103                        type: 'Number',
1104                        optional: true
1105                      },
1106                      {
1107                        name: 'br',
1108                        description: '<p>optional radius of bottom-right corner.</p>\n',
1109                        type: 'Number',
1110                        optional: true
1111                      },
1112                      {
1113                        name: 'bl',
1114                        description: '<p>optional radius of bottom-left corner.</p>\n',
1115                        type: 'Number',
1116                        optional: true
1117                      }
1118                    ],
1119                    chainable: 1
1120                  },
1121                  {
1122                    params: [
1123                      {
1124                        name: 'x',
1125                        description: '',
1126                        type: 'Number'
1127                      },
1128                  
1128    {
1129                        name: 'y',
1130                        description: '',
1131                        type: 'Number'
1132                      },
1133                      {
1134                        name: 'w',
1135                        description: '',
1136                        type: 'Number'
1137                      },
1138                      {
1139                        name: 'h',
1140                        description: '',
1141                        type: 'Number'
1142                      },
1143                      {
1144                        name: 'detailX',
1145                        description:
1146                          '<p>number of segments in the x-direction (for WebGL mode)</p>\n',
1147                        type: 'Integer',
1148                        optional: true
1149                      },
1150                      {
1151                        name: 'detailY',
1152                        description:
1153                          '<p>number of segments in the y-direction (for WebGL mode)</p>\n',
1154                        type: 'Integer',
1155                        optional: true
1156                      }
1157                    ],
1158                    chainable: 1
1159                  }
1160                ]
1161              },
1162              square: {
1163                name: 'square',
1164                params: [
1165                  {
1166                    name: 'x',
1167                    description: '<p>x-coordinate of the square.</p>\n',
1168                    type: 'Number'
1169                  },
1170                  {
1171                    name: 'y',
1172                    description: '<p>y-coordinate of the square.</p>\n',
1173                    type: 'Number'
1174                  },
1175                  {
1176                    name: 's',
1177                    description: '<p>side size of the square.</p>\n',
1178                    type: 'Number'
1179                  },
1180                  {
1181                    name: 'tl',
1182                    description: '<p>optional radius of top-left corner.</p>\n',
1183                    type: 'Number',
1184                    optional: true
1185                  },
1186                  {
1187                    name: 'tr',
1188                    description: '<p>optional radius of top-right corner.</p>\n',
1189                    type: 'Number',
1190                    optional: true
1191                  },
1192                  {
1193                    name: 'br',
1194                    description: '<p>optional radius of bottom-right corner.</p>\n',
1195                    type: 'Number',
1196                    optional: true
1197                  },
1198                  {
1199                    name: 'bl',
1200                    description: '<p>optional radius of bottom-left corner.</p>\n',
1201                    type: 'Number',
1202                    optional: true
1203                  }
1204                ],
1205                class: 'p5',
1206                module: 'Shape'
1207              },
1208              triangle: {
1209                name: 'triangle',
1210                params: [
1211                  {
1212                    name: 'x1',
1213                    description: '<p>x-coordinate of the first point</p>\n',
1214                    type: 'Number'
1215                  },
1216                  {
1217                    name: 'y1',
1218                    description: '<p>y-coordinate of the first point</p>\n',
1219                    type: 'Number'
1220                  },
1221                  {
1222                    name: 'x2',
1223                    description: '<p>x-coordinate of the second point</p>\n',
1224                    type: 'Number'
1225                  },
1226                  {
1227                    name: 'y2',
1228                    description: '<p>y-coordinate of the second point</p>\n',
1229                    type: 'Number'
1230                  },
1231                  {
1232                    name: 'x3',
1233                    description: '<p>x-coordinate of the third point</p>\n',
1234                    type: 'Number'
1235                  },
1236                  {
1237                    name: 'y3',
1238                    description: '<p>y-coordinate of the third point</p>\n',
1239                    type: 'Number'
1240                  }
1241                ],
1242                class: 'p5',
1243                module: 'Shape'
1244              },
1245              ellipseMode: {
1246                name: 'ellipseMode',
1247                params: [
1248                  {
1249                    name: 'mode',
1250                    description: '<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n',
1251                    type: 'Constant'
1252                  }
1253                ],
1254                class: 'p5',
1255                module: 'Shape'
1256              },
1257              noSmooth: {
1258                name: 'noSmooth',
1259                class: 'p5',
1260                module: 'Shape'
1261              },
1262              rectMode: {
1263                name: 'rectMode',
1264                params: [
1265                  {
1266                    name: 'mode',
1267                    description: '<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n',
1268                    type: 'Constant'
1269                  }
1270                ],
1271                class: 'p5',
1272                module: 'Shape'
1273              },
1274              smooth: {
1275                name: 'smooth',
1276                class: 'p5',
1277                module: 'Shape'
1278              },
1279              strokeCap: {
1280                name: 'strokeCap',
1281                params: [
1282                  {
1283                    name: 'cap',
1284                    description: '<p>either ROUND, SQUARE or PROJECT</p>\n',
1285                    type: 'Constant'
1286                  }
1287                ],
1288                class: 'p5',
1289                module: 'Shape'
1290              },
1291              strokeJoin: {
1292                name: 'strokeJoin',
1293                params: [
1294                  {
1295                    name: 'join',
1296                    description: '<p>either MITER, BEVEL, ROUND</p>\n',
1297                    type: 'Constant'
1298                  }
1299                ],
1300                class: 'p5',
1301                module: 'Shape'
1302              },
1303              strokeWeight: {
1304                name: 'strokeWeight',
1305                params: [
1306                  {
1307                    name: 'weight',
1308                    description: '<p>the weight of the stroke (in pixels)</p>\n',
1309                    type: 'Number'
1310                  }
1311                ],
1312                class: 'p5',
1313                module: 'Shape'
1314              },
1315              bezier: {
1316                name: 'bezier',
1317                class: 'p5',
1318                module: 'Shape',
1319                overloads: [
1320                  {
1321                    params: [
1322                      {
1323                        name: 'x1',
1324                        description: '<p>x-coordinate for the first anchor point</p>\n',
1325                        type: 'Number'
1326                      },
1327                      {
1328                        name: 'y1',
1329                        description: '<p>y-coordinate for the first anchor point</p>\n',
1330                        type: 'Number'
1331                      },
1332                      {
1333                        name: 'x2',
1334                        description: '<p>x-coordinate for the first control point</p>\n',
1335                        type: 'Number'
1336                      },
1337                      {
1338                        name: 'y2',
1339                        description: '<p>y-coordinate for the first control point</p>\n',
1340                        type: 'Number'
1341                      },
1342                      {
1343                        name: 'x3',
1344                        description: '<p>x-coordinate for the second control point</p>\n',
1345                        type: 'Number'
1346                      },
1347                      {
1348                        name: 'y3',
1349                        description: '<p>y-coordinate for the second control point</p>\n',
1350                        type: 'Number'
1351                      },
1352                      {
1353                        name: 'x4',
1354                        description: '<p>x-coordinate for the second anchor point</p>\n',
1355                        type: 'Number'
1356                      },
1357                      {
1358                        name: 'y4',
1359                        description: '<p>y-coordinate for the second anchor point</p>\n',
1360                        type: 'Number'
1361                      }
1362                    ],
1363                    chainable: 1
1364                  },
1365                  {
1366                    params: [
1367                      {
1368                        name: 'x1',
1369                        description: '',
1370                        type: 'Number'
1371                      },
1372                      {
1373                        name: 'y1',
1374                        description: '',
1375                        type: 'Number'
1376                      },
1377                      {
1378                        name: 'z1',
1379                        description: '<p>z-coordinate for the first anchor point</p>\n',
1380                        type: 'Number'
1381                      },
1382                      {
1383                        name: 'x2',
1384                        description: '',
1385                        type: 'Number'
1386                      },
1387                      {
1388                        name: 'y2',
1389                        description: '',
1390                        type: 'Number'
1391                      },
1392                      {
1393                        name: 'z2',
1394                        description: '<p>z-coordinate for the first control point</p>\n',
1395                        type: 'Number'
1396                      },
1397                      {
1398                        name: 'x3',
1399                        description: '',
1400                        type: 'Number'
1401                      },
1402                      {
1403                        name: 'y3',
1404                        description: '',
1405                        type: 'Number'
1406                      },
1407                      {
1408                        name: 'z3',
1409                        description: '<p>z-coordinate for the second control point</p>\n',
1410                        type: 'Number'
1411                      },
1412                      {
1413                        name: 'x4',
1414                        description: '',
1415                        type: 'Number'
1416                      },
1417                      {
1418                        name: 'y4',
1419                        description: '',
1420                        type: 'Number'
1421                      },
1422                      {
1423                        name: 'z4',
1424                        description: '<p>z-coordinate for the second anchor point</p>\n',
1425                        type: 'Number'
1426                      }
1427                    ],
1428                    chainable: 1
1429                  }
1430                ]
1431              },
1432              bezierDetail: {
1433                name: 'bezierDetail',
1434                params: [
1435                  {
1436                    name: 'detail',
1437                    description: '<p>resolution of the curves</p>\n',
1438                    type: 'Number'
1439                  }
1440                ],
1441                class: 'p5',
1442                module: 'Shape'
1443              },
1444              bezierPoint: {
1445                name: 'bezierPoint',
1446                params: [
1447                  {
1448                    name: 'a',
1449                    description: '<p>coordinate of first point on the curve</p>\n',
1450                    type: 'Number'
1451                  },
1452                  {
1453                    name: 'b',
1454                    description: '<p>coordinate of first control point</p>\n',
1455                    type: 'Number'
1456                  },
1457                  {
1458                    name: 'c',
1459                    description: '<p>coordinate of second control point</p>\n',
1460                    type: 'Number'
1461                  },
1462                  {
1463                    name: 'd',
1464                    description: '<p>coordinate of second point on the curve</p>\n',
1465                    type: 'Number'
1466                  },
1467                  {
1468                    name: 't',
1469                    description: '<p>value between 0 and 1</p>\n',
1470                    type: 'Number'
1471                  }
1472                ],
1473                class: 'p5',
1474                module: 'Shape'
1475              },
1476              bezierTangent: {
1477                name: 'bezierTangent',
1478                params: [
1479                  {
1480                    name: 'a',
1481                    description: '<p>coordinate of first point on the curve</p>\n',
1482                    type: 'Number'
1483                  },
1484                  {
1485                    name: 'b',
1486                    description: '<p>coordinate of first control point</p>\n',
1487                    type: 'Number'
1488                  },
1489                  {
1490                    name: 'c',
1491                    description: '<p>coordinate of second control point</p>\n',
1492                    type: 'Number'
1493                  },
1494                  {
1495                    name: 'd',
1496                    description: '<p>coordinate of second point on the curve</p>\n',
1497                    type: 'Number'
1498                  },
1499                  {
1500                    name: 't',
1501                    description: '<p>value between 0 and 1</p>\n',
1502                    type: 'Number'
1503                  }
1504                ],
1505                class: 'p5',
1506                module: 'Shape'
1507              },
1508              curve: {
1509                name: 'curve',
1510                class: 'p5',
1511                module: 'Shape',
1512                overloads: [
1513                  {
1514                    params: [
1515                      {
1516                        name: 'x1',
1517                        description:
1518                          '<p>x-coordinate for the beginning control point</p>\n',
1519                        type: 'Number'
1520                      },
1521                      {
1522                        name: 'y1',
1523                        description:
1524                          '<p>y-coordinate for the beginning control point</p>\n',
1525                        type: 'Number'
1526                      },
1527                      {
1528                        name: 'x2',
1529                        description: '<p>x-coordinate for the first point</p>\n',
1530                        type: 'Number'
1531                      },
1532                      {
1533                        name: 'y2',
1534                        description: '<p>y-coordinate for the first point</p>\n',
1535                        type: 'Number'
1536                      },
1537                      {
1538                        name: 'x3',
1539                        description: '<p>x-coordinate for the second point</p>\n',
1540                        type: 'Number'
1541                      },
1542                      {
1543                        name: 'y3',
1544                        description: '<p>y-coordinate for the second point</p>\n',
1545                        type: 'Number'
1546                      },
1547                      {
1548                        name: 'x4',
1549                        description: '<p>x-coordinate for the ending control point</p>\n',
1550                        type: 'Number'
1551                      },
1552                      {
1553                        name: 'y4',
1554                        description: '<p>y-coordinate for the ending control point</p>\n',
1555                        type: 'Number'
1556                      }
1557                    ],
1558                    chainable: 1
1559                  },
1560                  {
1561                    params: [
1562                      {
1563                        name: 'x1',
1564                        description: '',
1565                        type: 'Number'
1566                      },
1567                      {
1568                        name: 'y1',
1569                        description: '',
1570                        type: 'Number'
1571                      },
1572                      {
1573                        name: 'z1',
1574                        description:
1575                          '<p>z-coordinate for the beginning control point</p>\n',
1576                        type: 'Number'
1577                      },
1578                      {
1579                        name: 'x2',
1580                        description: '',
1581                        type: 'Number'
1582                      },
1583                      {
1584                        name: 'y2',
1585                        description: '',
1586                        type: 'Number'
1587                      },
1588                      {
1589                        name: 'z2',
1590                        description: '<p>z-coordinate for the first point</p>\n',
1591                        type: 'Number'
1592                      },
1593                      {
1594                        name: 'x3',
1595                        description: '',
1596                        type: 'Number'
1597                      },
1598                      {
1599                        name: 'y3',
1600                        description: '',
1601                        type: 'Number'
1602                      },
1603                      {
1604                        name: 'z3',
1605                        description: '<p>z-coordinate for the second point</p>\n',
1606                        type: 'Number'
1607                      },
1608                      {
1609                        name: 'x4',
1610                        description: '',
1611                        type: 'Number'
1612                      },
1613                      {
1614                        name: 'y4',
1615                        description: '',
1616                        type: 'Number'
1617                      },
1618                      {
1619                        name: 'z4',
1620                        description: '<p>z-coordinate for the ending control point</p>\n',
1621                        type: 'Number'
1622                      }
1623                    ],
1624                    chainable: 1
1625                  }
1626                ]
1627              },
1628              curveDetail: {
1629                name: 'curveDetail',
1630                params: [
1631                  {
1632                    name: 'resolution',
1633                    description: '<p>resolution of the curves</p>\n',
1634                    type: 'Number'
1635                  }
1636                ],
1637                class: 'p5',
1638                module: 'Shape'
1639              },
1640              curveTightness: {
1641                name: 'curveTightness',
1642                params: [
1643                  {
1644                    name: 'amount',
1645                    description:
1646                      '<p>amount of deformation from the original vertices</p>\n',
1647                    type: 'Number'
1648                  }
1649                ],
1650                class: 'p5',
1651                module: 'Shape'
1652              },
1653              curvePoint: {
1654                name: 'curvePoint',
1655                params: [
1656                  {
1657                    name: 'a',
1658                    description: '<p>coordinate of first control point of the curve</p>\n',
1659                    type: 'Number'
1660                  },
1661                  {
1662                    name: 'b',
1663                    description: '<p>coordinate of first point</p>\n',
1664                    type: 'Number'
1665                  },
1666                  {
1667                    name: 'c',
1668                    description: '<p>coordinate of second point</p>\n',
1669                    type: 'Number'
1670                  },
1671                  {
1672                    name: 'd',
1673                    description: '<p>coordinate of second control point</p>\n',
1674                    type: 'Number'
1675                  },
1676                  {
1677                    name: 't',
1678                    description: '<p>value between 0 and 1</p>\n',
1679                    type: 'Number'
1680                  }
1681                ],
1682                class: 'p5',
1683                module: 'Shape'
1684              },
1685              curveTangent: {
1686                name: 'curveTangent',
1687                params: [
1688                  {
1689                    name: 'a',
1690                    description: '<p>coordinate of first control point</p>\n',
1691                    type: 'Number'
1692                  },
1693                  {
1694                    name: 'b',
1695                    description: '<p>coordinate of first point on the curve</p>\n',
1696                    type: 'Number'
1697                  },
1698                  {
1699                    name: 'c',
1700                    description: '<p>coordinate of second point on the curve</p>\n',
1701                    type: 'Number'
1702                  },
1703                  {
1704                    name: 'd',
1705                    description: '<p>coordinate of second conrol point</p>\n',
1706                    type: 'Number'
1707                  },
1708                  {
1709                    name: 't',
1710                    description: '<p>value between 0 and 1</p>\n',
1711                    type: 'Number'
1712                  }
1713                ],
1714                class: 'p5',
1715                module: 'Shape'
1716              },
1717              beginContour: {
1718                name: 'beginContour',
1719                class: 'p5',
1720                module: 'Shape'
1721              },
1722              beginShape: {
1723                name: 'beginShape',
1724                params: [
1725                  {
1726                    name: 'kind',
1727                    description:
1728                      '<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n',
1729                    type: 'Constant',
1730                    optional: true
1731                  }
1732                ],
1733                class: 'p5',
1734                module: 'Shape'
1735              },
1736              bezierVertex: {
1737                name: 'bezierVertex',
1738                class: 'p5',
1739                module: 'Shape',
1740                overloads: [
1741                  {
1742                    params: [
1743                      {
1744                        name: 'x2',
1745                        description: '<p>x-coordinate for the first control point</p>\n',
1746                        type: 'Number'
1747                      },
1748                      {
1749                        name: 'y2',
1750                        description: '<p>y-coordinate for the first control point</p>\n',
1751                        type: 'Number'
1752                      },
1753                      {
1754                        name: 'x3',
1755                        description: '<p>x-coordinate for the second control point</p>\n',
1756                        type: 'Number'
1757                      },
1758                      {
1759                        name: 'y3',
1760                        description: '<p>y-coordinate for the second control point</p>\n',
1761                        type: 'Number'
1762                      },
1763                      {
1764                        name: 'x4',
1765                        description: '<p>
1765x-coordinate for the anchor point</p>\n',
1766                        type: 'Number'
1767                      },
1768                      {
1769                        name: 'y4',
1770                        description: '<p>y-coordinate for the anchor point</p>\n',
1771                        type: 'Number'
1772                      }
1773                    ],
1774                    chainable: 1
1775                  },
1776                  {
1777                    params: [
1778                      {
1779                        name: 'x2',
1780                        description: '',
1781                        type: 'Number'
1782                      },
1783                      {
1784                        name: 'y2',
1785                        description: '',
1786                        type: 'Number'
1787                      },
1788                      {
1789                        name: 'z2',
1790                        description:
1791                          '<p>z-coordinate for the first control point (for WebGL mode)</p>\n',
1792                        type: 'Number'
1793                      },
1794                      {
1795                        name: 'x3',
1796                        description: '',
1797                        type: 'Number'
1798                      },
1799                      {
1800                        name: 'y3',
1801                        description: '',
1802                        type: 'Number'
1803                      },
1804                      {
1805                        name: 'z3',
1806                        description:
1807                          '<p>z-coordinate for the second control point (for WebGL mode)</p>\n',
1808                        type: 'Number'
1809                      },
1810                      {
1811                        name: 'x4',
1812                        description: '',
1813                        type: 'Number'
1814                      },
1815                      {
1816                        name: 'y4',
1817                        description: '',
1818                        type: 'Number'
1819                      },
1820                      {
1821                        name: 'z4',
1822                        description:
1823                          '<p>z-coordinate for the anchor point (for WebGL mode)</p>\n',
1824                        type: 'Number'
1825                      }
1826                    ],
1827                    chainable: 1
1828                  }
1829                ]
1830              },
1831              curveVertex: {
1832                name: 'curveVertex',
1833                class: 'p5',
1834                module: 'Shape',
1835                overloads: [
1836                  {
1837                    params: [
1838                      {
1839                        name: 'x',
1840                        description: '<p>x-coordinate of the vertex</p>\n',
1841                        type: 'Number'
1842                      },
1843                      {
1844                        name: 'y',
1845                        description: '<p>y-coordinate of the vertex</p>\n',
1846                        type: 'Number'
1847                      }
1848                    ],
1849                    chainable: 1
1850                  },
1851                  {
1852                    params: [
1853                      {
1854                        name: 'x',
1855                        description: '',
1856                        type: 'Number'
1857                      },
1858                      {
1859                        name: 'y',
1860                        description: '',
1861                        type: 'Number'
1862                      },
1863                      {
1864                        name: 'z',
1865                        description: '<p>z-coordinate of the vertex (for WebGL mode)</p>\n',
1866                        type: 'Number',
1867                        optional: true
1868                      }
1869                    ],
1870                    chainable: 1
1871                  }
1872                ]
1873              },
1874              endContour: {
1875                name: 'endContour',
1876                class: 'p5',
1877                module: 'Shape'
1878              },
1879              endShape: {
1880                name: 'endShape',
1881                params: [
1882                  {
1883                    name: 'mode',
1884                    description: '<p>use CLOSE to close the shape</p>\n',
1885                    type: 'Constant',
1886                    optional: true
1887                  }
1888                ],
1889                class: 'p5',
1890                module: 'Shape'
1891              },
1892              quadraticVertex: {
1893                name: 'quadraticVertex',
1894                class: 'p5',
1895                module: 'Shape',
1896                overloads: [
1897                  {
1898                    params: [
1899                      {
1900                        name: 'cx',
1901                        description: '<p>x-coordinate for the control point</p>\n',
1902                        type: 'Number'
1903                      },
1904                      {
1905                        name: 'cy',
1906                        description: '<p>y-coordinate for the control point</p>\n',
1907                        type: 'Number'
1908                      },
1909                      {
1910                        name: 'x3',
1911                        description: '<p>
1911x-coordinate for the anchor point</p>\n',
1912                        type: 'Number'
1913                      },
1914                      {
1915                        name: 'y3',
1916                        description: '<p>y-coordinate for the anchor point</p>\n',
1917                        type: 'Number'
1918                      }
1919                    ],
1920                    chainable: 1
1921                  },
1922                  {
1923                    params: [
1924                      {
1925                        name: 'cx',
1926                        description: '',
1927                        type: 'Number'
1928                      },
1929                      {
1930                        name: 'cy',
1931                        description: '',
1932                        type: 'Number'
1933                      },
1934                      {
1935                        name: 'cz',
1936                        description:
1937                          '<p>z-coordinate for the control point (for WebGL mode)</p>\n',
1938                        type: 'Number'
1939                      },
1940                      {
1941                        name: 'x3',
1942                        description: '',
1943                        type: 'Number'
1944                      },
1945                      {
1946                        name: 'y3',
1947                        description: '',
1948                        type: 'Number'
1949                      },
1950                      {
1951                        name: 'z3',
1952                        description:
1953                          '<p>z-coordinate for the anchor point (for WebGL mode)</p>\n',
1954                        type: 'Number'
1955                      }
1956                    ],
1957                    chainable: 1
1958                  }
1959                ]
1960              },
1961              vertex: {
1962                name: 'vertex',
1963                class: 'p5',
1964                module: 'Shape',
1965                overloads: [
1966                  {
1967                    params: [
1968                      {
1969                        name: 'x',
1970                        description: '<p>x-coordinate of the vertex</p>\n',
1971                        type: 'Number'
1972                      },
1973                      {
1974                        name: 'y',
1975                        description: '<p>y-coordinate of the vertex</p>\n',
1976                        type: 'Number'
1977                      }
1978                    ],
1979                    chainable: 1
1980                  },
1981                  {
1982                    params: [
1983                      {
1984                        name: 'x',
1985                        description: '',
1986                        type: 'Number'
1987                      },
1988                      {
1989                        name: 'y',
1990                        description: '',
1991                        type: 'Number'
1992                      },
1993                      {
1994                        name: 'z',
1995                        description: '<p>z-coordinate of the vertex</p>\n',
1996                        type: 'Number'
1997                      },
1998                      {
1999                        name: 'u',
2000                        description: "<p>the vertex's texture u-coordinate</p>\n",
2001                        type: 'Number',
2002                        optional: true
2003                      },
2004                      {
2005                        name: 'v',
2006                        description: "<p>the vertex's texture v-coordinate</p>\n",
2007                        type: 'Number',
2008                        optional: true
2009                      }
2010                    ],
2011                    chainable: 1
2012                  }
2013                ]
2014              },
2015              P2D: {
2016                name: 'P2D',
2017                class: 'p5',
2018                module: 'Constants'
2019              },
2020              WEBGL: {
2021                name: 'WEBGL',
2022                class: 'p5',
2023                module: 'Constants'
2024              },
2025              ARROW: {
2026                name: 'ARROW',
2027                class: 'p5',
2028                module: 'Constants'
2029              },
2030              CROSS: {
2031                name: 'CROSS',
2032                class: 'p5',
2033                module: 'Constants'
2034              },
2035              HAND: {
2036                name: 'HAND',
2037                class: 'p5',
2038                module: 'Constants'
2039              },
2040              MOVE: {
2041                name: 'MOVE',
2042                class: 'p5',
2043                module: 'Constants'
2044              },
2045              TEXT: {
2046                name: 'TEXT',
2047                class: 'p5',
2048                module: 'Constants'
2049              },
2050              WAIT: {
2051                name: 'WAIT',
2052                class: 'p5',
2053                module: 'Constants'
2054              },
2055              HALF_PI: {
2056                name: 'HALF_PI',
2057                class: 'p5',
2058                module: 'Constants'
2059              },
2060              PI: {
2061                name: 'PI',
2062                class: 'p5',
2063                module: 'Constants'
2064              },
2065              QUARTER_PI: {
2066                name: 'QUARTER_PI',
2067                class: 'p5',
2068                module: 'Constants'
2069              },
2070              TAU: {
2071                name: 'TAU',
2072                class: 'p5',
2073                module: 'Constants'
2074              },
2075              TWO_PI: {
2076                name: 'TWO_PI',
2077                class: 'p5',
2078                module: 'Constants'
2079              },
2080              DEGREES: {
2081                name: 'DEGREES',
2082                class: 'p5',
2083                module: 'Constants'
2084              },
2085              RADIANS: {
2086                name: 'RADIANS',
2087                class: 'p5',
2088                module: 'Constants'
2089              },
2090              CORNER: {
2091                name: 'CORNER',
2092                class: 'p5',
2093                module: 'Constants'
2094              },
2095              CORNERS: {
2096                name: 'CORNERS',
2097                class: 'p5',
2098                module: 'Constants'
2099              },
2100              RADIUS: {
2101                name: 'RADIUS',
2102                class: 'p5',
2103                module: 'Constants'
2104              },
2105              RIGHT: {
2106                name: 'RIGHT',
2107                class: 'p5',
2108                module: 'Constants'
2109              },
2110              LEFT: {
2111                name: 'LEFT',
2112                class: 'p5',
2113                module: 'Constants'
2114              },
2115              CENTER: {
2116                name: 'CENTER',
2117                class: 'p5',
2118                module: 'Constants'
2119              },
2120              TOP: {
2121                name: 'TOP',
2122                class: 'p5',
2123                module: 'Constants'
2124              },
2125              BOTTOM: {
2126                name: 'BOTTOM',
2127                class: 'p5',
2128                module: 'Constants'
2129              },
2130              BASELINE: {
2131                name: 'BASELINE',
2132                class: 'p5',
2133                module: 'Constants'
2134              },
2135              POINTS: {
2136                name: 'POINTS',
2137                class: 'p5',
2138                module: 'Constants'
2139              },
2140              LINES: {
2141                name: 'LINES',
2142                class: 'p5',
2143                module: 'Constants'
2144              },
2145              LINE_STRIP: {
2146                name: 'LINE_STRIP',
2147                class: 'p5',
2148                module: 'Constants'
2149              },
2150              LINE_LOOP: {
2151                name: 'LINE_LOOP',
2152                class: 'p5',
2153                module: 'Constants'
2154              },
2155              TRIANGLES: {
2156                name: 'TRIANGLES',
2157                class: 'p5',
2158                module: 'Constants'
2159              },
2160              TRIANGLE_FAN: {
2161                name: 'TRIANGLE_FAN',
2162                class: 'p5',
2163                module: 'Constants'
2164              },
2165              TRIANGLE_STRIP: {
2166                name: 'TRIANGLE_STRIP',
2167                class: 'p5',
2168                module: 'Constants'
2169              },
2170              QUADS: {
2171                name: 'QUADS',
2172                class: 'p5',
2173                module: 'Constants'
2174              },
2175              QUAD_STRIP: {
2176                name: 'QUAD_STRIP',
2177                class: 'p5',
2178                module: 'Constants'
2179              },
2180              TESS: {
2181                name: 'TESS',
2182                class: 'p5',
2183                module: 'Constants'
2184              },
2185              CLOSE: {
2186                name: 'CLOSE',
2187                class: 'p5',
2188                module: 'Constants'
2189              },
2190              OPEN: {
2191                name: 'OPEN',
2192                class: 'p5',
2193                module: 'Constants'
2194              },
2195              CHORD: {
2196                name: 'CHORD',
2197                class: 'p5',
2198                module: 'Constants'
2199              },
2200              PIE: {
2201                name: 'PIE',
2202                class: 'p5',
2203                module: 'Constants'
2204              },
2205              PROJECT: {
2206                name: 'PROJECT',
2207                class: 'p5',
2208                module: 'Constants'
2209              },
2210              SQUARE: {
2211                name: 'SQUARE',
2212                class: 'p5',
2213                module: 'Constants'
2214              },
2215              ROUND: {
2216                name: 'ROUND',
2217                class: 'p5',
2218                module: 'Constants'
2219              },
2220              BEVEL: {
2221                name: 'BEVEL',
2222                class: 'p5',
2223                module: 'Constants'
2224              },
2225              MITER: {
2226                name: 'MITER',
2227                class: 'p5',
2228                module: 'Constants'
2229              },
2230              RGB: {
2231                name: 'RGB',
2232                class: 'p5',
2233                module: 'Constants'
2234              },
2235              HSB: {
2236                name: 'HSB',
2237                class: 'p5',
2238                module: 'Constants'
2239              },
2240              HSL: {
2241                name: 'HSL',
2242                class: 'p5',
2243                module: 'Constants'
2244              },
2245              AUTO: {
2246                name: 'AUTO',
2247                class: 'p5',
2248                module: 'Constants'
2249              },
2250              ALT: {
2251                name: 'ALT',
2252                class: 'p5',
2253                module: 'Constants'
2254              },
2255              BACKSPACE: {
2256                name: 'BACKSPACE',
2257                class: 'p5',
2258                module: 'Constants'
2259              },
2260              CONTROL: {
2261                name: 'CONTROL',
2262                class: 'p5',
2263                module: 'Constants'
2264              },
2265              DELETE: {
2266                name: 'DELETE',
2267                class: 'p5',
2268                module: 'Constants'
2269              },
2270              DOWN_ARROW: {
2271                name: 'DOWN_ARROW',
2272                class: 'p5',
2273                module: 'Constants'
2274              },
2275              ENTER: {
2276                name: 'ENTER',
2277                class: 'p5',
2278                module: 'Constants'
2279              },
2280              ESCAPE: {
2281                name: 'ESCAPE',
2282                class: 'p5',
2283                module: 'Constants'
2284              },
2285              LEFT_ARROW: {
2286                name: 'LEFT_ARROW',
2287                class: 'p5',
2288                module: 'Constants'
2289              },
2290              OPTION: {
2291                name: 'OPTION',
2292                class: 'p5',
2293                module: 'Constants'
2294              },
2295              RETURN: {
2296                name: 'RETURN',
2297                class: 'p5',
2298                module: 'Constants'
2299              },
2300              RIGHT_ARROW: {
2301                name: 'RIGHT_ARROW',
2302                class: 'p5',
2303                module: 'Constants'
2304              },
2305              SHIFT: {
2306                name: 'SHIFT',
2307                class: 'p5',
2308                module: 'Constants'
2309              },
2310              TAB: {
2311                name: 'TAB',
2312                class: 'p5',
2313                module: 'Constants'
2314              },
2315              UP_ARROW: {
2316                name: 'UP_ARROW',
2317                class: 'p5',
2318                module: 'Constants'
2319              },
2320              BLEND: {
2321                name: 'BLEND',
2322                class: 'p5',
2323                module: 'Constants'
2324              },
2325              REMOVE: {
2326                name: 'REMOVE',
2327                class: 'p5',
2328                module: 'Constants'
2329              },
2330              ADD: {
2331                name: 'ADD',
2332                class: 'p5',
2333                module: 'Constants'
2334              },
2335              DARKEST: {
2336                name: 'DARKEST',
2337                class: 'p5',
2338                module: 'Constants'
2339              },
2340              LIGHTEST: {
2341                name: 'LIGHTEST',
2342                class: 'p5',
2343                module: 'Constants'
2344              },
2345              DIFFERENCE: {
2346                name: 'DIFFERENCE',
2347                class: 'p5',
2348                module: 'Constants'
2349              },
2350              SUBTRACT: {
2351                name: 'SUBTRACT',
2352                class: 'p5',
2353                module: 'Constants'
2354              },
2355              EXCLUSION: {
2356                name: 'EXCLUSION',
2357                class: 'p5',
2358                module: 'Constants'
2359              },
2360              MULTIPLY: {
2361                name: 'MULTIPLY',
2362                class: 'p5',
2363                module: 'Constants'
2364              },
2365              SCREEN: {
2366                name: 'SCREEN',
2367                class: 'p5',
2368                module: 'Constants'
2369              },
2370              REPLACE: {
2371                name: 'REPLACE',
2372                class: 'p5',
2373                module: 'Constants'
2374              },
2375              OVERLAY: {
2376                name: 'OVERLAY',
2377                class: 'p5',
2378                module: 'Constants'
2379              },
2380              HARD_LIGHT: {
2381                name: 'HARD_LIGHT',
2382                class: 'p5',
2383                module: 'Constants'
2384              },
2385              SOFT_LIGHT: {
2386                name: 'SOFT_LIGHT',
2387                class: 'p5',
2388                module: 'Constants'
2389              },
2390              DODGE: {
2391                name: 'DODGE',
2392                class: 'p5',
2393                module: 'Constants'
2394              },
2395              BURN: {
2396                name: 'BURN',
2397                class: 'p5',
2398                module: 'Constants'
2399              },
2400              THRESHOLD: {
2401                name: 'THRESHOLD',
2402                class: 'p5',
2403                module: 'Constants'
2404              },
2405              GRAY: {
2406                name: 'GRAY',
2407                class: 'p5',
2408                module: 'Constants'
2409              },
2410              OPAQUE: {
2411                name: 'OPAQUE',
2412                class: 'p5',
2413                module: 'Constants'
2414              },
2415              INVERT: {
2416                name: 'INVERT',
2417                class: 'p5',
2418                module: 'Constants'
2419              },
2420              POSTERIZE: {
2421                name: 'POSTERIZE',
2422                class: 'p5',
2423                module: 'Constants'
2424              },
2425              DILATE: {
2426                name: 'DILATE',
2427                class: 'p5',
2428                module: 'Constants'
2429              },
2430              ERODE: {
2431                name: 'ERODE',
2432                class: 'p5',
2433                module: 'Constants'
2434              },
2435              BLUR: {
2436                name: 'BLUR',
2437                class: 'p5',
2438                module: 'Constants'
2439              },
2440              NORMAL: {
2441                name: 'NORMAL',
2442                class: 'p5',
2443                module: 'Constants'
2444              },
2445              ITALIC: {
2446                name: 'ITALIC',
2447                class: 'p5',
2448                module: 'Constants'
2449              },
2450              BOLD: {
2451                name: 'BOLD',
2452                class: 'p5',
2453                module: 'Constants'
2454              },
2455              BOLDITALIC: {
2456                name: 'BOLDITALIC',
2457                class: 'p5',
2458                module: 'Constants'
2459              },
2460              LINEAR: {
2461                name: 'LINEAR',
2462                class: 'p5',
2463                module: 'Constants'
2464              },
2465              QUADRATIC: {
2466                name: 'QUADRATIC',
2467                class: 'p5',
2468                module: 'Constants'
2469              },
2470              BEZIER: {
2471                name: 'BEZIER',
2472                class: 'p5',
2473                module: 'Constants'
2474              },
2475              CURVE: {
2476                name: 'CURVE',
2477                class: 'p5',
2478   
2478             module: 'Constants'
2479              },
2480              STROKE: {
2481                name: 'STROKE',
2482                class: 'p5',
2483                module: 'Constants'
2484              },
2485              FILL: {
2486                name: 'FILL',
2487                class: 'p5',
2488                module: 'Constants'
2489              },
2490              TEXTURE: {
2491                name: 'TEXTURE',
2492                class: 'p5',
2493                module: 'Constants'
2494              },
2495              IMMEDIATE: {
2496                name: 'IMMEDIATE',
2497                class: 'p5',
2498                module: 'Constants'
2499              },
2500              IMAGE: {
2501                name: 'IMAGE',
2502                class: 'p5',
2503                module: 'Constants'
2504              },
2505              NEAREST: {
2506                name: 'NEAREST',
2507                class: 'p5',
2508                module: 'Constants'
2509              },
2510              REPEAT: {
2511                name: 'REPEAT',
2512                class: 'p5',
2513                module: 'Constants'
2514              },
2515              CLAMP: {
2516                name: 'CLAMP',
2517                class: 'p5',
2518                module: 'Constants'
2519              },
2520              MIRROR: {
2521                name: 'MIRROR',
2522                class: 'p5',
2523                module: 'Constants'
2524              },
2525              LANDSCAPE: {
2526                name: 'LANDSCAPE',
2527                class: 'p5',
2528                module: 'Constants'
2529              },
2530              PORTRAIT: {
2531                name: 'PORTRAIT',
2532                class: 'p5',
2533                module: 'Constants'
2534              },
2535              GRID: {
2536                name: 'GRID',
2537                class: 'p5',
2538                module: 'Constants'
2539              },
2540              AXES: {
2541                name: 'AXES',
2542                class: 'p5',
2543                module: 'Constants'
2544              },
2545              LABEL: {
2546                name: 'LABEL',
2547                class: 'p5',
2548                module: 'Constants'
2549              },
2550              FALLBACK: {
2551                name: 'FALLBACK',
2552                class: 'p5',
2553                module: 'Constants'
2554              },
2555              print: {
2556                name: 'print',
2557                params: [
2558                  {
2559                    name: 'contents',
2560                    description:
2561                      '<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n',
2562                    type: 'Any'
2563                  }
2564                ],
2565                class: 'p5',
2566                module: 'Environment'
2567              },
2568              frameCount: {
2569                name: 'frameCount',
2570                class: 'p5',
2571                module: 'Environment'
2572              },
2573              deltaTime: {
2574                name: 'deltaTime',
2575                class: 'p5',
2576                module: 'Environment'
2577              },
2578              focused: {
2579                name: 'focused',
2580                class: 'p5',
2581                module: 'Environment'
2582              },
2583              cursor: {
2584                name: 'cursor',
2585                params: [
2586                  {
2587                    name: 'type',
2588                    description:
2589                      "<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n",
2590                    type: 'String|Constant'
2591                  },
2592                  {
2593                    name: 'x',
2594                    description:
2595                      '<p>the horizontal active spot of the cursor (must be less than 32)</p>\n',
2596                    type: 'Number',
2597                    optional: true
2598                  },
2599                  {
2600                    name: 'y',
2601                    description:
2602                      '<p>the vertical active spot of the cursor (must be less than 32)</p>\n',
2603                    type: 'Number',
2604                    optional: true
2605                  }
2606                ],
2607                class: 'p5',
2608                module: 'Environment'
2609              },
2610              frameRate: {
2611                name: 'frameRate',
2612                class: 'p5',
2613                module: 'Environment',
2614                overloads: [
2615                  {
2616                    params: [
2617                      {
2618                        name: 'fps',
2619                        description:
2620                          '<p>number of frames to be displayed every second</p>\n',
2621                        type: 'Number'
2622                      }
2623                    ],
2624                    chainable: 1
2625                  },
2626                  {
2627                    params: []
2628                  }
2629                ]
2630              },
2631              noCursor: {
2632                name: 'noCursor',
2633                class: 'p5',
2634                module: 'Environment'
2635              },
2636              displayWidth: {
2637                name: 'displayWidth',
2638                class: 'p5',
2639                module: 'Environment'
2640              },
2641              displayHeight: {
2642                name: 'displayHeight',
2643                class: 'p5',
2644                module: 'Environment'
2645              },
2646              windowWidth: {
2647                name: 'windowWidth',
2648                class: 'p5',
2649                module: 'Environment'
2650              },
2651              windowHeight: {
2652                name: 'windowHeight',
2653                class: 'p5',
2654                module: 'Environment'
2655              },
2656              windowResized: {
2657                name: 'windowResized',
2658                class: 'p5',
2659                module: 'Environment'
2660              },
2661              width: {
2662                name: 'width',
2663                class: 'p5',
2664                module: 'Environment'
2665              },
2666              height: {
2667                name: 'height',
2668                class: 'p5',
2669                module: 'Environment'
2670              },
2671              fullscreen: {
2672                name: 'fullscreen',
2673                params: [
2674                  {
2675                    name: 'val',
2676                    description:
2677                      '<p>whether the sketch should be in fullscreen mode\nor not</p>\n',
2678                    type: 'Boolean',
2679                    optional: true
2680                  }
2681                ],
2682                class: 'p5',
2683                module: 'Environment'
2684              },
2685              pixelDensity: {
2686                name: 'pixelDensity',
2687                class: 'p5',
2688                module: 'Environment',
2689                overloads: [
2690                  {
2691                    params: [
2692                      {
2693                        name: 'val',
2694                        description: '<p>whether or how much the sketch should scale</p>\n',
2695                        type: 'Number'
2696                      }
2697                    ],
2698                    chainable: 1
2699                  },
2700                  {
2701                    params: []
2702                  }
2703                ]
2704              },
2705              displayDensity: {
2706                name: 'displayDensity',
2707                class: 'p5',
2708                module: 'Environment'
2709              },
2710              getURL: {
2711                name: 'getURL',
2712                class: 'p5',
2713                module: 'Environment'
2714              },
2715              getURLPath: {
2716                name: 'getURLPath',
2717                class: 'p5',
2718                module: 'Environment'
2719              },
2720              getURLParams: {
2721                name: 'getURLParams',
2722                class: 'p5',
2723                module: 'Environment'
2724              },
2725              preload: {
2726                name: 'preload',
2727                class: 'p5',
2728                module: 'Structure'
2729              },
2730              setup: {
2731                name: 'setup',
2732                class: 'p5',
2733                module: 'Structure'
2734              },
2735              draw: {
2736                name: 'draw',
2737                class: 'p5',
2738                module: 'Structure'
2739              },
2740              remove: {
2741                name: 'remove',
2742                class: 'p5',
2743                module: 'Structure'
2744              },
2745              disableFriendlyErrors: {
2746                name: 'disableFriendlyErrors',
2747                class: 'p5',
2748                module: 'Structure'
2749              },
2750              let: {
2751                name: 'let',
2752                class: 'p5',
2753                module: 'Foundation'
2754              },
2755              const: {
2756                name: 'const',
2757                class: 'p5',
2758                module: 'Foundation'
2759              },
2760              '===': {
2761                name: '===',
2762                class: 'p5',
2763                module: 'Foundation'
2764              },
2765              '>': {
2766                name: '>',
2767                class: 'p5',
2768                module: 'Foundation'
2769              },
2770              '>=': {
2771                name: '>=',
2772                class: 'p5',
2773                module: 'Foundation'
2774              },
2775              '<': {
2776                name: '<',
2777                class: 'p5',
2778                module: 'Foundation'
2779              },
2780              '<=': {
2781                name: '<=',
2782                class: 'p5',
2783                module: 'Foundation'
2784              },
2785              'if-else': {
2786                name: 'if-else',
2787                class: 'p5',
2788                module: 'Foundation'
2789              },
2790              function: {
2791                name: 'function',
2792                class: 'p5',
2793                module: 'Foundation'
2794              },
2795              return: {
2796                name: 'return',
2797                class: 'p5',
2798                module: 'Foundation'
2799              },
2800              boolean: {
2801                name: 'boolean',
2802                params: [
2803                  {
2804                    name: 'n',
2805                    description: '<p>value to parse</p>\n',
2806                    type: 'String|Boolean|Number|Array'
2807                  }
2808                ],
2809                class: 'p5',
2810                module: 'Data'
2811              },
2812              string: {
2813                name: 'string',
2814                class: 'p5',
2815                module: 'Foundation'
2816              },
2817              number: {
2818                name: 'number',
2819                class: 'p5',
2820                module: 'Foundation'
2821              },
2822              object: {
2823                name: 'object',
2824                class: 'p5',
2825                module: 'Foundation'
2826              },
2827              class: {
2828                name: 'class',
2829                class: 'p5',
2830                module: 'Foundation'
2831              },
2832              for: {
2833                name: 'for',
2834                class: 'p5',
2835                module: 'Foundation'
2836              },
2837              while: {
2838                name: 'while',
2839                class: 'p5',
2840                module: 'Foundation'
2841              },
2842              createCanvas: {
2843                name: 'createCanvas',
2844                params: [
2845                  {
2846                    name: 'w',
2847                    description: '<p>width of the canvas</p>\n',
2848                    type: 'Number'
2849                  },
2850                  {
2851                    name: 'h',
2852                    description: '<p>height of the canvas</p>\n',
2853                    type: 'Number'
2854                  },
2855                  {
2856                    name: 'renderer',
2857                    description: '<p>either P2D or WEBGL</p>\n',
2858                    type: 'Constant',
2859                    optional: true
2860                  }
2861                ],
2862                class: 'p5',
2863                module: 'Rendering'
2864              },
2865              resizeCanvas: {
2866                name: 'resizeCanvas',
2867                params: [
2868                  {
2869                    name: 'w',
2870                    description: '<p>width of the canvas</p>\n',
2871                    type: 'Number'
2872                  },
2873                  {
2874                    name: 'h',
2875                    description: '<p>height of the canvas</p>\n',
2876                    type: 'Number'
2877                  },
2878                  {
2879                    name: 'noRedraw',
2880                    description: "<p>don't redraw the canvas immediately</p>\n",
2881                    type: 'Boolean',
2882                    optional: true
2883                  }
2884                ],
2885                class: 'p5',
2886                module: 'Rendering'
2887              },
2888              noCanvas: {
2889                name: 'noCanvas',
2890                class: 'p5',
2891                module: 'Rendering'
2892              },
2893              createGraphics: {
2894                name: 'createGraphics',
2895                params: [
2896                  {
2897                    name: 'w',
2898                    description: '<p>width of the offscreen graphics buffer</p>\n',
2899                    type: 'Number'
2900                  },
2901                  {
2902                    name: 'h',
2903                    description: '<p>height of the offscreen graphics buffer</p>\n',
2904                    type: 'Number'
2905                  },
2906                  {
2907                    name: 'renderer',
2908                    description:
2909                      '<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n',
2910                    type: 'Constant',
2911                    optional: true
2912                  }
2913                ],
2914                class: 'p5',
2915                module: 'Rendering'
2916              },
2917              blendMode: {
2918                name: 'blendMode',
2919                params: [
2920                  {
2921                    name: 'mode',
2922                    description:
2923                      '<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n',
2924                    type: 'Constant'
2925                  }
2926                ],
2927                class: 'p5',
2928                module: 'Rendering'
2929              },
2930              drawingContext: {
2931                name: 'drawingContext',
2932                class: 'p5',
2933                module: 'Rendering'
2934              },
2935              noLoop: {
2936                name: 'noLoop',
2937                class: 'p5',
2938                module: 'Structure'
2939              },
2940              loop: {
2941                name: 'loop',
2942                class: 'p5',
2943                module: 'Structure'
2944              },
2945              isLooping: {
2946                name: 'isLooping',
2947                class: 'p5',
2948                module: 'Structure'
2949              },
2950              push: {
2951                name: 'push',
2952                class: 'p5',
2953                module: 'Structure'
2954              },
2955              pop: {
2956                name: 'pop',
2957                class: 'p5',
2958                module: 'Structure'
2959              },
2960              redraw: {
2961                name: 'redraw',
2962                params: [
2963                  {
2964                    name: 'n',
2965                    description: '<p>Redraw for n-times. The default value is 1.</p>\n',
2966                    type: 'Integer',
2967                    optional: true
2968                  }
2969                ],
2970                class: 'p5',
2971                module: 'Structure'
2972              },
2973              p5: {
2974                name: 'p5',
2975                params: [
2976                  {
2977                    name: 'sketch',
2978                    description: '<p>a function containing a p5.js sketch</p>\n',
2979                    type: 'Object'
2980                  },
2981                  {
2982                    name: 'node',
2983                    description:
2984                      '<p>ID or pointer to HTML DOM node to contain sketch in</p>\n',
2985                    type: 'String|Object'
2986                  }
2987                ],
2988                class: 'p5',
2989                module: 'Structure'
2990              },
2991              applyMatrix: {
2992                name: 'applyMatrix',
2993                params: [
2994                  {
2995                    name: 'a',
2996                    description:
2997                      '<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
2998                    type: 'Number'
2999                  },
3000                  {
3001                    name: 'b',
3002                    description:
3003                      '<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
3004                    type: 'Number'
3005                  },
3006                  {
3007                    name: 'c',
3008                    description:
3009                      '<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
3010                    type: 'Number'
3011                  },
3012                  {
3013                    name: 'd',
3014                    description:
3015                      '<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
3016                    type: 'Number'
3017                  },
3018                  {
3019                    name: 'e',
3020                    description:
3021                      '<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
3022                    type: 'Number'
3023                  },
3024                  {
3025                    name: 'f',
3026                    description:
3027                      '<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
3028                    type: 'Number'
3029                  }
3030                ],
3031                class: 'p5',
3032                module: 'Transform'
3033              },
3034              resetMatrix: {
3035                name: 'resetMatrix',
3036                class: 'p5',
3037                module: 'Transform'
3038              },
3039              rotate: {
3040                name: 'rotate',
3041                params: [
3042                  {
3043                    name: 'angle',
3044                    description:
3045                      '<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n',
3046                    type: 'Number'
3047                  },
3048                  {
3049                    name: 'axis',
3050                    description: '<p>(in 3d) the axis to rotate around</p>\n',
3051                    type: 'p5.Vector|Number[]',
3052                    optional: true
3053                  }
3054                ],
3055                class: 'p5',
3056                module: 'Transform'
3057              },
3058              rotateX: {
3059                name: 'rotateX',
3060                params: [
3061                  {
3062                    name: 'angle',
3063                    description:
3064                      '<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n',
3065                    type: 'Number'
3066                  }
3067                ],
3068                class: 'p5',
3069                module: 'Transform'
3070              },
3071              rotateY: {
3072                name: 'rotateY',
3073                params: [
3074                  {
3075                    name: 'angle',
3076                    description:
3077                      '<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n',
3078                    type: 'Number'
3079                  }
3080                ],
3081                class: 'p5',
3082                module: 'Transform'
3083              },
3084              rotateZ: {
3085                name: 'rotateZ',
3086                params: [
3087                  {
3088                    name: 'angle',
3089                    description:
3090                      '<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n',
3091                    type: 'Number'
3092                  }
3093                ],
3094                class: 'p5',
3095                module: 'Transform'
3096              },
3097              scale: {
3098                name: 'scale',
3099                class: 'p5',
3100                module: 'Transform',
3101                overloads: [
3102                  {
3103                    params: [
3104                      {
3105                        name: 's',
3106                        description:
3107                          '<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n',
3108                        type: 'Number|p5.Vector|Number[]'
3109                      },
3110                      {
3111                        name: 'y',
3112                        description: '<p>percent to scale the object in the y-axis</p>\n',
3113                        type: 'Number',
3114                        optional: true
3115                      },
3116                      {
3117                        name: 'z',
3118                        description:
3119                          '<p>percent to scale the object in the z-axis (webgl only)</p>\n',
3120                        type: 'Number',
3121                        optional: true
3122                      }
3123                    ],
3124                    chainable: 1
3125                  },
3126                  {
3127                    params: [
3128                      {
3129                        name: 'scales',
3130                        description: '<p>per-axis percents to scale the object</p>\n',
3131                        type: 'p5.Vector|Number[]'
3132                      }
3133                    ],
3134                    chainable: 1
3135                  }
3136                ]
3137              },
3138              shearX: {
3139                name: 'shearX',
3140                params: [
3141                  {
3142                    name: 'angle',
3143                    description:
3144                      '<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n',
3145                    type: 'Number'
3146                  }
3147                ],
3148                class: 'p5',
3149                module: 'Transform'
3150              },
3151              shearY: {
3152                name: 'shearY',
3153                params: [
3154                  {
3155                    name: 'angle',
3156                    description:
3157                      '<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n',
3158                    type: 'Number'
3159                  }
3160                ],
3161                class: 'p5',
3162                module: 'Transform'
3163              },
3164              translate: {
3165                name: 'translate',
3166                class: 'p5',
3167                module: 'Transform',
3168                overloads: [
3169                  {
3170                    params: [
3171                      {
3172                        name: 'x',
3173                        description: '<p>left/right translation</p>\n',
3174                        type: 'Number'
3175                      },
3176                      {
3177                        name: 'y',
3178                        description: '<p>up/down translation</p>\n',
3179                        type: 'Number'
3180                      },
3181                      {
3182                        name: 'z',
3183                        description: '<p>forward/backward translation (webgl only)</p>\n',
3184                        type: 'Number',
3185                        optional: true
3186                      }
3187                    ],
3188                    chainable: 1
3189                  },
3190                  {
3191                    params: [
3192                      {
3193                        name: 'vector',
3194                        description: '<p>the vector to translate by</p>\n',
3195                        type: 'p5.Vector'
3196                      }
3197                    ],
3198                    chainable: 1
3199                  }
3200                ]
3201              },
3202              storeItem: {
3203                name: 'storeItem',
3204                params: [
3205                  {
3206                    name: 'key',
3207                    description: '',
3208                    type: 'String'
3209                  },
3210                  {
3211                    name: 'value',
3212                    description: '',
3213                    type: 'String|Number|Object|Boolean|p5.Color|p5.Vector'
3214                  }
3215                ],
3216                class: 'p5',
3217                module: 'Data'
3218              },
3219              getItem: {
3220                name: 'getItem',
3221                params: [
3222                  {
3223                    name: 'key',
3224                    description:
3225                      '<p>name that you wish to use to store in local storage</p>\n',
3226                    type: 'String'
3227                  }
3228                ],
3229                class: 'p5',
3230                module: 'Data'
3231              },
3232              clearStorage: {
3233                name: 'clearStorage',
3234                class: 'p5',
3235                module: 'Data'
3236              },
3237              removeItem: {
3238                name: 'removeItem',
3239                params: [
3240                  {
3241                    name: 'key',
3242                    description: '',
3243                    type: 'String'
3244                  }
3245                ],
3246                class: 'p5',
3247                module: 'Data'
3248              },
3249              createStringDict: {
3250                name: 'createStringDict',
3251                class: 'p5',
3252                module: 'Data',
3253                overloads: [
3254                  {
3255                    params: [
3256                      {
3257                        name: 'key',
3258                        description: '',
3259                        type: 'String'
3260                      },
3261                      {
3262                        name: 'value',
3263                        description: '',
3264                        type: 'String'
3265                      }
3266                    ]
3267                  },
3268                  {
3269                    params: [
3270                      {
3271                        name: 'object',
3272                        description: '<p>object</p>\n',
3273                        type: 'Object'
3274                      }
3275                    ]
3276                  }
3277                ]
3278              },
3279              createNumberDict: {
3280                name: 'createNumberDict',
3281                class: 'p5',
3282                module: 'Data',
3283                overloads: [
3284                  {
3285                    params: [
3286                      {
3287                        name: 'key',
3288                        description: '',
3289                        type: 'Number'
3290                      },
3291                      {
3292                        name: 'value',
3293                        description: '',
3294                        type: 'Number'
3295                      }
3296                    ]
3297                  },
3298                  {
3299                    p
3299arams: [
3300                      {
3301                        name: 'object',
3302                        description: '<p>object</p>\n',
3303                        type: 'Object'
3304                      }
3305                    ]
3306                  }
3307                ]
3308              },
3309              select: {
3310                name: 'select',
3311                params: [
3312                  {
3313                    name: 'selectors',
3314                    description: '<p>CSS selector string of element to search for</p>\n',
3315                    type: 'String'
3316                  },
3317                  {
3318                    name: 'container',
3319                    description:
3320                      '<p>CSS selector string, <a href="#/p5.Element">p5.Element</a>, or\n                                            HTML element to search within</p>\n',
3321                    type: 'String|p5.Element|HTMLElement',
3322                    optional: true
3323                  }
3324                ],
3325                class: 'p5',
3326                module: 'DOM'
3327              },
3328              selectAll: {
3329                name: 'selectAll',
3330                params: [
3331                  {
3332                    name: 'selectors',
3333                    description: '<p>CSS selector string of elements to search for</p>\n',
3334                    type: 'String'
3335                  },
3336                  {
3337                    name: 'container',
3338                    description:
3339                      '<p>CSS selector string, <a href="#/p5.Element">p5.Element</a>\n                                            , or HTML element to search within</p>\n',
3340                    type: 'String|p5.Element|HTMLElement',
3341                    optional: true
3342                  }
3343                ],
3344                class: 'p5',
3345                module: 'DOM'
3346              },
3347              removeElements: {
3348                name: 'removeElements',
3349                class: 'p5',
3350                module: 'DOM'
3351              },
3352              changed: {
3353                name: 'changed',
3354                params: [
3355                  {
3356                    name: 'fxn',
3357                    description:
3358                      '<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
3359                    type: 'Function|Boolean'
3360                  }
3361                ],
3362                class: 'p5',
3363                module: 'DOM'
3364              },
3365              input: {
3366                name: 'input',
3367                params: [
3368                  {
3369                    name: 'fxn',
3370                    description:
3371                      '<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
3372                    type: 'Function|Boolean'
3373                  }
3374                ],
3375                class: 'p5',
3376                module: 'DOM'
3377              },
3378              createDiv: {
3379                name: 'createDiv',
3380                params: [
3381                  {
3382                    name: 'html',
3383                    description: '<p>inner HTML for element created</p>\n',
3384                    type: 'String',
3385                    optional: true
3386                  }
3387                ],
3388                class: 'p5',
3389                module: 'DOM'
3390              },
3391              createP: {
3392                name: 'createP',
3393                params: [
3394                  {
3395                    name: 'html',
3396                    description: '<p>inner HTML for element created</p>\n',
3397                    type: 'String',
3398                    optional: true
3399                  }
3400                ],
3401                class: 'p5',
3402                module: 'DOM'
3403              },
3404              createSpan: {
3405                name: 'createSpan',
3406                params: [
3407                  {
3408                    name: 'html',
3409                    description: '<p>inner HTML for element created</p>\n',
3410                    type: 'String',
3411                    optional: true
3412                  }
3413                ],
3414                class: 'p5',
3415                module: 'DOM'
3416              },
3417              createImg: {
3418                name: 'createImg',
3419                class: 'p5',
3420                module: 'DOM',
3421                overloads: [
3422                  {
3423                    params: [
3424                      {
3425                        name: 'src',
3426                        description: '<p>src path or url for image</p>\n',
3427                        type: 'String'
3428                      },
3429                      {
3430                        name: 'alt',
3431                        description:
3432                          '<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes">alternate text</a> to be used if image does not load. You can use also an empty string (<code>""</code>) if that an image is not intended to be viewed.</p>\n',
3433                        type: 'String'
3434                      }
3435                    ]
3436                  },
3437                  {
3438                    params: [
3439                      {
3440                        name: 'src',
3441                        description: '',
3442                        type: 'String'
3443                      },
3444                      {
3445                        name: 'alt',
3446                        description: '',
3447                        type: 'String'
3448                      },
3449                      {
3450                        name: 'crossOrigin',
3451                        description:
3452                          '<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes">crossOrigin property</a> of the <code>img</code> element; use either \'anonymous\' or \'use-credentials\' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>""</code>) is passed, CORS is not used</p>\n',
3453                        type: 'String'
3454                      },
3455                      {
3456                        name: 'successCallback',
3457                        description:
3458                          '<p>callback to be called once image data is loaded with the <a href="#/p5.Element">p5.Element</a> as argument</p>\n',
3459                        type: 'Function',
3460                        optional: true
3461                      }
3462                    ]
3463                  }
3464                ]
3465              },
3466              createA: {
3467                name: 'createA',
3468                params: [
3469                  {
3470                    name: 'href',
3471                    description: '<p>url of page to link to</p>\n',
3472                    type: 'String'
3473                  },
3474                  {
3475                    name: 'html',
3476                    description: '<p>inner html of link element to display</p>\n',
3477                    type: 'String'
3478                  },
3479                  {
3480                    name: 'target',
3481                    description:
3482                      '<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n',
3483                    type: 'String',
3484                    optional: true
3485                  }
3486                ],
3487                class: 'p5',
3488                module: 'DOM'
3489              },
3490              createSlider: {
3491                name: 'createSlider',
3492                params: [
3493                  {
3494                    name: 'min',
3495                    description: '<p>minimum value of the slider</p>\n',
3496                    type: 'Number'
3497                  },
3498                  {
3499                    name: 'max',
3500                    description: '<p>maximum value of the slider</p>\n',
3501                    type: 'Number'
3502                  },
3503                  {
3504                    name: 'value',
3505                    description: '<p>default value of the slider</p>\n',
3506                    type: 'Number',
3507                    optional: true
3508                  },
3509                  {
3510                    name: 'step',
3511                    description:
3512                      '<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n',
3513                    type: 'Number',
3514                    optional: true
3515                  }
3516                ],
3517                class: 'p5',
3518                module: 'DOM'
3519              },
3520              createButton: {
3521                name: 'createButton',
3522                params: [
3523                  {
3524                    name: 'label',
3525                    description: '<p>label displayed on the button</p>\n',
3526                    type: 'String'
3527                  },
3528                  {
3529                    name: 'value',
3530                    description: '<p>value of the button</p>\n',
3531                    type: 'String',
3532                    optional: true
3533                  }
3534                ],
3535                class: 'p5',
3536                module: 'DOM'
3537              },
3538              createCheckbox: {
3539                name: 'createCheckbox',
3540                params: [
3541                  {
3542                    name: 'label',
3543                    description: '<p>label displayed after checkbox</p>\n',
3544                    type: 'String',
3545                    optional: true
3546                  },
3547                  {
3548                    name: 'value',
3549                    description:
3550                      '<p>value of the checkbox; checked is true, unchecked is false</p>\n',
3551                    type: 'Boolean',
3552                    optional: true
3553                  }
3554                ],
3555                class: 'p5',
3556                module: 'DOM'
3557              },
3558              createSelect: {
3559                name: 'createSelect',
3560                class: 'p5',
3561                module: 'DOM',
3562                overloads: [
3563                  {
3564                    params: [
3565                      {
3566                        name: 'multiple',
3567                        description:
3568                          '<p>true if dropdown should support multiple selections</p>\n',
3569                        type: 'Boolean',
3570                        optional: true
3571                      }
3572                    ]
3573                  },
3574                  {
3575                    params: [
3576                      {
3577                        name: 'existing',
3578                        description: '<p>DOM select element</p>\n',
3579                        type: 'Object'
3580                      }
3581                    ]
3582                  }
3583                ]
3584              },
3585              createRadio: {
3586                name: 'createRadio',
3587                class: 'p5',
3588                module: 'DOM',
3589                overloads: [
3590                  {
3591                    params: [
3592                      {
3593                        name: 'containerElement',
3594                        description:
3595                          '<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.
3595</p>\n',
3596                        type: 'Object'
3597                      },
3598                      {
3599                        name: 'name',
3600                        description: '<p>A name parameter for each Input Element.</p>\n',
3601                        type: 'String',
3602                        optional: true
3603                      }
3604                    ]
3605                  },
3606                  {
3607                    params: [
3608                      {
3609                        name: 'name',
3610                        description: '',
3611                        type: 'String'
3612                      }
3613                    ]
3614                  },
3615                  {
3616                    params: []
3617                  }
3618                ]
3619              },
3620              createColorPicker: {
3621                name: 'createColorPicker',
3622                params: [
3623                  {
3624                    name: 'value',
3625                    description: '<p>default color of element</p>\n',
3626                    type: 'String|p5.Color',
3627                    optional: true
3628                  }
3629                ],
3630                class: 'p5',
3631                module: 'DOM'
3632              },
3633              createInput: {
3634                name: 'createInput',
3635                class: 'p5',
3636                module: 'DOM',
3637                overloads: [
3638                  {
3639                    params: [
3640                      {
3641                        name: 'value',
3642                        description: '<p>default value of the input box</p>\n',
3643                        type: 'String'
3644                      },
3645                      {
3646                        name: 'type',
3647                        description:
3648                          '<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n',
3649                        type: 'String',
3650                        optional: true
3651                      }
3652                    ]
3653                  },
3654                  {
3655                    params: [
3656                      {
3657                        name: 'value',
3658                        description: '',
3659                        type: 'String',
3660                        optional: true
3661                      }
3662                    ]
3663                  }
3664                ]
3665              },
3666              createFileInput: {
3667                name: 'createFileInput',
3668                params: [
3669                  {
3670                    name: 'callback',
3671                    description: '<p>callback function for when a file is loaded</p>\n',
3672                    type: 'Function'
3673                  },
3674                  {
3675                    name: 'multiple',
3676                    description:
3677                      '<p>optional, to allow multiple files to be selected</p>\n',
3678                    type: 'Boolean',
3679                    optional: true
3680                  }
3681                ],
3682                class: 'p5',
3683                module: 'DOM'
3684              },
3685              createVideo: {
3686                name: 'createVideo',
3687                params: [
3688                  {
3689                    name: 'src',
3690                    description:
3691                      '<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n',
3692                    type: 'String|String[]'
3693                  },
3694                  {
3695                    name: 'callback',
3696                    description:
3697                      "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
3698                    type: 'Function',
3699                    optional: true
3700                  }
3701                ],
3702                class: 'p5',
3703                module: 'DOM'
3704              },
3705              createAudio: {
3706                name: 'createAudio',
3707                params: [
3708                  {
3709                    name: 'src',
3710                    description:
3711                      '<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n',
3712                    type: 'String|String[]',
3713                    optional: true
3714                  },
3715                  {
3716                    name: 'callback',
3717                    description:
3718                      "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
3719                    type: 'Function',
3720                    optional: true
3721                  }
3722                ],
3723                class: 'p5',
3724                module: 'DOM'
3725              },
3726              VIDEO: {
3727                name: 'VIDEO',
3728                class: 'p5',
3729                module: 'DOM'
3730              },
3731              AUDIO: {
3732                name: 'AUDIO',
3733                class: 'p5',
3734                module: 'DOM'
3735              },
3736              createCapture: {
3737                name: 'createCapture',
3738                params: [
3739                  {
3740                    name: 'type',
3741                    description:
3742                      '<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n',
3743                    type: 'String|Constant|Object'
3744                  },
3745                  {
3746                    name: 'callback',
3747                    description:
3748                      '<p>function to be called once\n                                  stream has loaded</p>\n',
3749                    type: 'Function',
3750                    optional: true
3751                  }
3752                ],
3753                class: 'p5',
3754                module: 'DOM'
3755              },
3756              createElement: {
3757                name: 'createElement',
3758                params: [
3759                  {
3760                    name: 'tag',
3761                    description: '<p>tag for the new element</p>\n',
3762                    type: 'String'
3763                  },
3764                  {
3765                    name: 'content',
3766                    description: '<p>html content to be inserted into the element</p>\n',
3767                    type: 'String',
3768                    optional: true
3769                  }
3770                ],
3771                class: 'p5',
3772                module: 'DOM'
3773              },
3774              deviceOrientation: {
3775                name: 'deviceOrientation',
3776                class: 'p5',
3777                module: 'Events'
3778              },
3779              accelerationX: {
3780                name: 'accelerationX',
3781                class: 'p5',
3782                module: 'Events'
3783              },
3784              accelerationY: {
3785                name: 'accelerationY',
3786                class: 'p5',
3787                module: 'Events'
3788              },
3789              accelerationZ: {
3790                name: 'accelerationZ',
3791                class: 'p5',
3792                module: 'Events'
3793              },
3794              pAccelerationX: {
3795                name: 'pAccelerationX',
3796                class: 'p5',
3797                module: 'Events'
3798              },
3799              pAccelerationY: {
3800                name: 'pAccelerationY',
3801                class: 'p5',
3802                module: 'Events'
3803              },
3804              pAccelerationZ: {
3805                name: 'pAccelerationZ',
3806                class: 'p5',
3807                module: 'Events'
3808              },
3809              rotationX: {
3810                name: 'rotationX',
3811                class: 'p5',
3812                module: 'Events'
3813              },
3814              rotationY: {
3815                name: 'rotationY',
3816                class: 'p5',
3817                module: 'Events'
3818              },
3819              rotationZ: {
3820                name: 'rotationZ',
3821                class: 'p5',
3822                module: 'Events'
3823              },
3824              pRotationX: {
3825                name: 'pRotationX',
3826                class: 'p5',
3827                module: 'Events'
3828              },
3829              pRotationY: {
3830                name: 'pRotationY',
3831                class: 'p5',
3832                module: 'Events'
3833              },
3834              pRotationZ: {
3835                name: 'pRotationZ',
3836                class: 'p5',
3837                module: 'Events'
3838              },
3839              turnAxis: {
3840                name: 'turnAxis',
3841                class: 'p5',
3842                module: 'Events'
3843              },
3844              setMoveThreshold: {
3845                name: 'setMoveThreshold',
3846                params: [
3847                  {
3848                    name: 'value',
3849                    description: '<p>The threshold value</p>\n',
3850                    type: 'Number'
3851                  }
3852                ],
3853                class: 'p5',
3854                module: 'Events'
3855              },
3856              setShakeThreshold: {
3857                name: 'setShakeThreshold',
3858                params: [
3859                  {
3860                    name: 'value',
3861                    description: '<p>The threshold value</p>\n',
3862                    type: 'Number'
3863                  }
3864                ],
3865                class: 'p5',
3866                module: 'Events'
3867              },
3868              deviceMoved: {
3869                name: 'deviceMoved',
3870                class: 'p5',
3871                module: 'Events'
3872              },
3873              deviceTurned: {
3874                name: 'deviceTurned',
3875                class: 'p5',
3876                module: 'Events'
3877              },
3878              deviceShaken: {
3879                name: 'deviceShaken',
3880                class: 'p5',
3881                module: 'Events'
3882              },
3883              keyIsPressed: {
3884                name: 'keyIsPressed',
3885                class: 'p5',
3886                module: 'Events'
3887              },
3888              key: {
3889                name: 'key',
3890                class: 'p5',
3891                module: 'Events'
3892              },
3893              keyCode: {
3894                name: 'keyCode',
3895                class: 'p5',
3896                module: 'Events'
3897              },
3898              keyPressed: {
3899                name: 'keyPressed',
3900                class: 'p5',
3901                module: 'Events'
3902              },
3903              keyReleased: {
3904                name: 'keyReleased',
3905                class: 'p5',
3906                module: 'Events'
3907              },
3908              keyTyped: {
3909                name: 'keyTyped',
3910                class: 'p5',
3911                module: 'Events'
3912              },
3913              keyIsDown: {
3914                name: 'keyIsDown',
3915                params: [
3916                  {
3917                    name: 'code',
3918                    description: '<p>The key to check for.</p>\n',
3919                    type: 'Number'
3920                  }
3921                ],
3922                class: 'p5',
3923                module: 'Events'
3924              },
3925              movedX: {
3926                name: 'movedX',
3927                class: 'p5',
3928                module: 'Events'
3929              },
3930              movedY: {
3931                name: 'movedY',
3932                class: 'p5',
3933                module: 'Events'
3934              },
3935              mouseX: {
3936                name: 'mouseX',
3937                class: 'p5',
3938                module: 'Events'
3939              },
3940              mouseY: {
3941                name: 'mouseY',
3942                class: 'p5',
3943                module: 'Events'
3944              },
3945              pmouseX: {
3946                name: 'pmouseX',
3947                class: 'p5',
3948                module: 'Events'
3949              },
3950              pmouseY: {
3951                name: 'pmouseY',
3952                class: 'p5',
3953                module: 'Events'
3954              },
3955              winMouseX: {
3956                name: 'winMouseX',
3957                class: 'p5',
3958                module: 'Events'
3959              },
3960              winMouseY: {
3961                name: 'winMouseY',
3962                class: 'p5',
3963                module: 'Events'
3964              },
3965              pwinMouseX: {
3966                name: 'pwinMouseX',
3967                class: 'p5',
3968                module: 'Events'
3969              },
3970              pwinMouseY: {
3971                name: 'pwinMouseY',
3972                class: 'p5',
3973                module: 'Events'
3974              },
3975              mouseButton: {
3976                name: 'mouseButton',
3977                class: 'p5',
3978                module: 'Events'
3979              },
3980              mouseIsPressed: {
3981                name: 'mouseIsPressed',
3982                class: 'p5',
3983                module: 'Events'
3984              },
3985              mouseMoved: {
3986                name: 'mouseMoved',
3987                params: [
3988                  {
3989                    name: 'event',
3990                    description: '<p>optional MouseEvent callback argument.</p>\n',
3991                    type: 'Object',
3992                    optional: true
3993                  }
3994                ],
3995                class: 'p5',
3996                module: 'Events'
3997              },
3998              mouseDragged: {
3999                name: 'mouseDragged',
4000                params: [
4001                  {
4002                    name: 'event',
4003                    description: '<p>optional MouseEvent callback argument.</p>\n',
4004                    type: 'Object',
4005                    optional: true
4006                  }
4007                ],
4008                class: 'p5',
4009                module: 'Events'
4010              },
4011              mousePressed: {
4012                name: 'mousePressed',
4013                params: [
4014                  {
4015                    name: 'event',
4016                    description: '<p>optional MouseEvent callback argument.</p>\n',
4017                    type: 'Object',
4018                    optional: true
4019                  }
4020                ],
4021                class: 'p5',
4022                module: 'Events'
4023              },
4024              mouseReleased: {
4025                name: 'mouseReleased',
4026                params: [
4027                  {
4028                    name: 'event',
4029                    description: '<p>optional MouseEvent callback argument.</p>\n',
4030                    type: 'Object',
4031                    optional: true
4032                  }
4033                ],
4034                class: 'p5',
4035                module: 'Events'
4036              },
4037              mouseClicked: {
4038                name: 'mouseClicked',
4039                params: [
4040                  {
4041                    name: 'event',
4042                    description: '<p>optional MouseEvent callback argument.</p>\n',
4043                    type: 'Object',
4044                    optional: true
4045                  }
4046                ],
4047                class: 'p5',
4048                module: 'Events'
4049              },
4050              doubleClicked: {
4051                name: 'doubleClicked',
4052                params: [
4053                  {
4054                    name: 'event',
4055                    description: '<p>optional MouseEvent callback argument.</p>\n',
4056                    type: 'Object',
4057                    optional: true
4058                  }
4059                ],
4060                class: 'p5',
4061                module: 'Events'
4062              },
4063              mouseWheel: {
4064                name: 'mouseWheel',
4065                params: [
4066                  {
4067                    name: 'event',
4068                    description: '<p>optional WheelEvent callback argument.</p>\n',
4069                    type: 'Object',
4070                    optional: true
4071                  }
4072                ],
4073                class: 'p5',
4074                module: 'Events'
4075              },
4076              requestPointerLock: {
4077                name: 'requestPointerLock',
4078                class: 'p5',
4079                module: 'Events'
4080              },
4081              exitPointerLock: {
4082                name: 'exitPointerLock',
4083                class: 'p5',
4084                module: 'Events'
4085              },
4086              touches: {
4087                name: 'touches',
4088                class: 'p5',
4089                module: 'Events'
4090             
4090 },
4091              touchStarted: {
4092                name: 'touchStarted',
4093                params: [
4094                  {
4095                    name: 'event',
4096                    description: '<p>optional TouchEvent callback argument.</p>\n',
4097                    type: 'Object',
4098                    optional: true
4099                  }
4100                ],
4101                class: 'p5',
4102                module: 'Events'
4103              },
4104              touchMoved: {
4105                name: 'touchMoved',
4106                params: [
4107                  {
4108                    name: 'event',
4109                    description: '<p>optional TouchEvent callback argument.</p>\n',
4110                    type: 'Object',
4111                    optional: true
4112                  }
4113                ],
4114                class: 'p5',
4115                module: 'Events'
4116              },
4117              touchEnded: {
4118                name: 'touchEnded',
4119                params: [
4120                  {
4121                    name: 'event',
4122                    description: '<p>optional TouchEvent callback argument.</p>\n',
4123                    type: 'Object',
4124                    optional: true
4125                  }
4126                ],
4127                class: 'p5',
4128                module: 'Events'
4129              },
4130              createImage: {
4131                name: 'createImage',
4132                params: [
4133                  {
4134                    name: 'width',
4135                    description: '<p>width in pixels</p>\n',
4136                    type: 'Integer'
4137                  },
4138                  {
4139                    name: 'height',
4140                    description: '<p>height in pixels</p>\n',
4141                    type: 'Integer'
4142                  }
4143                ],
4144                class: 'p5',
4145                module: 'Image'
4146              },
4147              saveCanvas: {
4148                name: 'saveCanvas',
4149                class: 'p5',
4150                module: 'Image',
4151                overloads: [
4152                  {
4153                    params: [
4154                      {
4155                        name: 'selectedCanvas',
4156                        description:
4157                          '<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n',
4158                        type: 'p5.Element|HTMLCanvasElement'
4159                      },
4160                      {
4161                        name: 'filename',
4162                        description: '',
4163                        type: 'String',
4164                        optional: true
4165                      },
4166                      {
4167                        name: 'extension',
4168                        description: "<p>'jpg' or 'png'</p>\n",
4169                        type: 'String',
4170                        optional: true
4171                      }
4172                    ]
4173                  },
4174                  {
4175                    params: [
4176                      {
4177                        name: 'filename',
4178                        description: '',
4179                        type: 'String',
4180                        optional: true
4181                      },
4182                      {
4183                        name: 'extension',
4184                        description: '',
4185                        type: 'String',
4186                        optional: true
4187                      }
4188                    ]
4189                  }
4190                ]
4191              },
4192              saveFrames: {
4193                name: 'saveFrames',
4194                params: [
4195                  {
4196                    name: 'filename',
4197                    description: '',
4198                    type: 'String'
4199                  },
4200                  {
4201                    name: 'extension',
4202                    description: "<p>'jpg' or 'png'</p>\n",
4203                    type: 'String'
4204                  },
4205                  {
4206                    name: 'duration',
4207                    description: '<p>Duration in seconds to save the frames for.</p>\n',
4208                    type: 'Number'
4209                  },
4210                  {
4211                    name: 'framerate',
4212                    description: '<p>Framerate to save the frames in.</p>\n',
4213                    type: 'Number'
4214                  },
4215                  {
4216                    name: 'callback',
4217                    description:
4218                      '<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n',
4219                    type: 'Function(Array)',
4220                    optional: true
4221                  }
4222                ],
4223                class: 'p5',
4224                module: 'Image'
4225              },
4226              loadImage: {
4227                name: 'loadImage',
4228                params: [
4229                  {
4230                    name: 'path',
4231                    description: '<p>Path of the image to be loaded</p>\n',
4232                    type: 'String'
4233                  },
4234                  {
4235                    name: 'successCallback',
4236                    description:
4237                      '<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href="#/p5.Image">p5.Image</a>.</p>\n',
4238                    type: 'function(p5.Image)',
4239                    optional: true
4240                  },
4241                  {
4242                    name: 'failureCallback',
4243                    description:
4244                      '<p>called with event error if\n                               the image fails to load.</p>\n',
4245                    type: 'Function(Event)',
4246                    optional: true
4247                  }
4248                ],
4249                class: 'p5',
4250                module: 'Image'
4251              },
4252              image: {
4253                name: 'image',
4254                class: 'p5',
4255                module: 'Image',
4256                overloads: [
4257                  {
4258                    params: [
4259                      {
4260                        name: 'img',
4261                        description: '<p>the image to display</p>\n',
4262                        type: 'p5.Image|p5.Element'
4263                      },
4264                      {
4265                        name: 'x',
4266                        description:
4267                          '<p>the x-coordinate of the top-left corner of the image</p>\n',
4268                        type: 'Number'
4269                      },
4270                      {
4271                        name: 'y',
4272                        description:
4273                          '<p>the y-coordinate of the top-left corner of the image</p>\n',
4274                        type: 'Number'
4275                      },
4276                      {
4277                        name: 'width',
4278                        description: '<p>the width to draw the image</p>\n',
4279                        type: 'Number',
4280                        optional: true
4281                      },
4282                      {
4283                        name: 'height',
4284                        description: '<p>the height to draw the image</p>\n',
4285                        type: 'Number',
4286                        optional: true
4287                      }
4288                    ]
4289                  },
4290                  {
4291                    params: [
4292                      {
4293                        name: 'img',
4294                        description: '',
4295                        type: 'p5.Image|p5.Element'
4296                      },
4297                      {
4298                        name: 'dx',
4299                        description:
4300                          '<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n',
4301                        type: 'Number'
4302                      },
4303                      {
4304                        name: 'dy',
4305                        description:
4306                          '<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n',
4307                        type: 'Number'
4308                      },
4309                      {
4310                        name: 'dWidth',
4311                        description: '<p>the width of the destination rectangle</p>\n',
4312                        type: 'Number'
4313                      },
4314                      {
4315                        name: 'dHeight',
4316                        description: '<p>the height of the destination rectangle</p>\n',
4317                        type: 'Number'
4318                      },
4319                      {
4320                        name: 'sx',
4321                        description:
4322                          '<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n',
4323                        type: 'Number'
4324                      },
4325                      {
4326                        name: 'sy',
4327                        description:
4328                          '<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n',
4329                        type: 'Number'
4330                      },
4331                      {
4332                        name: 'sWidth',
4333                        description:
4334                          '<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n',
4335                        type: 'Number',
4336                        optional: true
4337                      },
4338                      {
4339                        name: 'sHeight',
4340                        description:
4341                          '<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n',
4342                        type: 'Number',
4343                        optional: true
4344                      }
4345                    ]
4346                  }
4347                ]
4348              },
4349              tint: {
4350                name: 'tint',
4351                class: 'p5',
4352                module: 'Image',
4353                overloads: [
4354                  {
4355                    params: [
4356                      {
4357                        name: 'v1',
4358                        description:
4359                          '<p>red or hue value relative to\n                                the current color range</p>\n',
4360                        type: 'Number'
4361                      },
4362                      {
4363                        name: 'v2',
4364                        description:
4365                          '<p>
4365green or saturation value\n                                relative to the current color range</p>\n',
4366                        type: 'Number'
4367                      },
4368                      {
4369                        name: 'v3',
4370                        description:
4371                          '<p>blue or brightness value\n                                relative to the current color range</p>\n',
4372                        type: 'Number'
4373                      },
4374                      {
4375                        name: 'alpha',
4376                        description: '',
4377                        type: 'Number',
4378                        optional: true
4379                      }
4380                    ]
4381                  },
4382                  {
4383                    params: [
4384                      {
4385                        name: 'value',
4386                        description: '<p>a color string</p>\n',
4387                        type: 'String'
4388                      }
4389                    ]
4390                  },
4391                  {
4392                    params: [
4393                      {
4394                        name: 'gray',
4395                        description: '<p>a gray value</p>\n',
4396                        type: 'Number'
4397                      },
4398                      {
4399                        name: 'alpha',
4400                        description: '',
4401                        type: 'Number',
4402                        optional: true
4403                      }
4404                    ]
4405                  },
4406                  {
4407                    params: [
4408                      {
4409                        name: 'values',
4410                        description:
4411                          '<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n',
4412                        type: 'Number[]'
4413                      }
4414                    ]
4415                  },
4416                  {
4417                    params: [
4418                      {
4419                        name: 'color',
4420                        description: '<p>the tint color</p>\n',
4421                        type: 'p5.Color'
4422                      }
4423                    ]
4424                  }
4425                ]
4426              },
4427              noTint: {
4428                name: 'noTint',
4429                class: 'p5',
4430                module: 'Image'
4431              },
4432              imageMode: {
4433                name: 'imageMode',
4434                params: [
4435                  {
4436                    name: 'mode',
4437                    description: '<p>either CORNER, CORNERS, or CENTER</p>\n',
4438                    type: 'Constant'
4439                  }
4440                ],
4441                class: 'p5',
4442                module: 'Image'
4443              },
4444              pixels: {
4445                name: 'pixels',
4446                class: 'p5',
4447                module: 'Image'
4448              },
4449              blend: {
4450                name: 'blend',
4451                class: 'p5',
4452                module: 'Image',
4453                overloads: [
4454                  {
4455                    params: [
4456                      {
4457                        name: 'srcImage',
4458                        description: '<p>source image</p>\n',
4459                        type: 'p5.Image'
4460                      },
4461                      {
4462                        name: 'sx',
4463                        description:
4464                          "<p>X coordinate of the source's upper left corner</p>\n",
4465                        type: 'Integer'
4466                      },
4467                      {
4468                        name: 'sy',
4469                        description:
4470                          "<p>Y coordinate of the source's upper left corner</p>\n",
4471                        type: 'Integer'
4472                      },
4473                      {
4474                        name: 'sw',
4475                        description: '<p>source image width</p>\n',
4476                        type: 'Integer'
4477                      },
4478                      {
4479                        name: 'sh',
4480                        description: '<p>source image height</p>\n',
4481                        type: 'Integer'
4482                      },
4483                      {
4484                        name: 'dx',
4485                        description:
4486                          "<p>X coordinate of the destination's upper left corner</p>\n",
4487                        type: 'Integer'
4488                      },
4489                      {
4490                        name: 'dy',
4491                        description:
4492                          "<p>Y coordinate of the destination's upper left corner</p>\n",
4493                        type: 'Integer'
4494                      },
4495                      {
4496                        name: 'dw',
4497                        description: '<p>destination image width</p>\n',
4498                        type: 'Integer'
4499                      },
4500                      {
4501                        name: 'dh',
4502                        description: '<p>destination image height</p>\n',
4503                        type: 'Integer'
4504                      },
4505                      {
4506                        name: 'blendMode',
4507                        description:
4508                          '<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n',
4509                        type: 'Constant'
4510                      }
4511                    ]
4512                  },
4513                  {
4514                    params: [
4515                      {
4516                        name: 'sx',
4517                        description: '',
4518                        type: 'Integer'
4519                      },
4520                      {
4521                        name: 'sy',
4522                        description: '',
4523                        type: 'Integer'
4524                      },
4525                      {
4526                        name: 'sw',
4527                        description: '',
4528                        type: 'Integer'
4529                      },
4530                      {
4531                        name: 'sh',
4532                        description: '',
4533                        type: 'Integer'
4534                      },
4535                      {
4536                        name: 'dx',
4537                        description: '',
4538                        type: 'Integer'
4539                      },
4540                      {
4541                        name: 'dy',
4542                        description: '',
4543                        type: 'Integer'
4544                      },
4545                      {
4546                        name: 'dw',
4547                        description: '',
4548                        type: 'Integer'
4549                      },
4550                      {
4551                        name: 'dh',
4552                        description: '',
4553                        type: 'Integer'
4554                      },
4555                      {
4556                        name: 'blendMode',
4557                        description: '',
4558                        type: 'Constant'
4559                      }
4560                    ]
4561                  }
4562                ]
4563              },
4564              copy: {
4565                name: 'copy',
4566                class: 'p5',
4567                module: 'Image',
4568                overloads: [
4569                  {
4570                    params: [
4571                      {
4572                        name: 'srcImage',
4573                        description: '<p>source image</p>\n',
4574                        type: 'p5.Image|p5.Element'
4575                      },
4576                      {
4577                        name: 'sx',
4578                        description:
4579                          "<p>X coordinate of the source's upper left corner</p>\n",
4580                        type: 'Integer'
4581                      },
4582                      {
4583                        name: 'sy',
4584                        description:
4585                          "<p>Y coordinate of the source's upper left corner</p>\n",
4586                        type: 'Integer'
4587                      },
4588                      {
4589                        name: 'sw',
4590                        description: '<p>source image width</p>\n',
4591                        type: 'Integer'
4592                      },
4593                      {
4594                        name: 'sh',
4595                        description: '<p>source image height</p>\n',
4596                        type: 'Integer'
4597                      },
4598                      {
4599                        name: 'dx',
4600                        description:
4601                          "<p>X coordinate of the destination's upper left corner</p>\n",
4602                        type: 'Integer'
4603                      },
4604                      {
4605                        name: 'dy',
4606                        description:
4607                          "<p>Y coordinate of the destination's upper left corner</p>\n",
4608                        type: 'Integer'
4609                      },
4610                      {
4611                        name: 'dw',
4612                        description: '<p>destination image width</p>\n',
4613                        type: 'Integer'
4614                      },
4615                      {
4616                        name: 'dh',
4617                        description: '<p>destination image height</p>\n',
4618                        type: 'Integer'
4619                      }
4620                    ]
4621                  },
4622                  {
4623                    params: [
4624                      {
4625                        name: 'sx',
4626                        description: '',
4627                        type: 'Integer'
4628                      },
4629                      {
4630                        name: 'sy',
4631                        description: '',
4632                        type: 'Integer'
4633                      },
4634                      {
4635                        name: 'sw',
4636                        description: '',
4637                        type: 'Integer'
4638                      },
4639                      {
4640                        name: 'sh',
4641                        description: '',
4642                        type: 'Integer'
4643                      },
4644                      {
4645                        name: 'dx',
4646                        description: '',
4647                        type: 'Integer'
4648                      },
4649                      {
4650                        name: 'dy',
4651                        description: '',
4652                        type: 'Integer'
4653                      },
4654                      {
4655                        name: 'dw',
4656                        description: '',
4657                        type: 'Integer'
4658                      },
4659                      {
4660                        name: 'dh',
4661                        description: '',
4662                        type: 'Integer'
4663                      }
4664                    ]
4665                  }
4666                ]
4667              },
4668              filter: {
4669                name: 'filter',
4670                params: [
4671                  {
4672                    name: 'filterType',
4673                    description:
4674                      '<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\
4674n                               See Filters.js for docs on\n                               each available filter</p>\n',
4675                    type: 'Constant'
4676                  },
4677                  {
4678                    name: 'filterParam',
4679                    description:
4680                      '<p>an optional parameter unique\n                               to each filter, see above</p>\n',
4681                    type: 'Number',
4682                    optional: true
4683                  }
4684                ],
4685                class: 'p5',
4686                module: 'Image'
4687              },
4688              get: {
4689                name: 'get',
4690                class: 'p5',
4691                module: 'Image',
4692                overloads: [
4693                  {
4694                    params: [
4695                      {
4696                        name: 'x',
4697                        description: '<p>x-coordinate of the pixel</p>\n',
4698                        type: 'Number'
4699                      },
4700                      {
4701                        name: 'y',
4702                        description: '<p>y-coordinate of the pixel</p>\n',
4703                        type: 'Number'
4704                      },
4705                      {
4706                        name: 'w',
4707                        description: '<p>width</p>\n',
4708                        type: 'Number'
4709                      },
4710                      {
4711                        name: 'h',
4712                        description: '<p>height</p>\n',
4713                        type: 'Number'
4714                      }
4715                    ]
4716                  },
4717                  {
4718                    params: []
4719                  },
4720                  {
4721                    params: [
4722                      {
4723                        name: 'x',
4724                        description: '',
4725                        type: 'Number'
4726                      },
4727                      {
4728                        name: 'y',
4729                        description: '',
4730                        type: 'Number'
4731                      }
4732                    ]
4733                  }
4734                ]
4735              },
4736              loadPixels: {
4737                name: 'loadPixels',
4738                class: 'p5',
4739                module: 'Image'
4740              },
4741              set: {
4742                name: 'set',
4743                params: [
4744                  {
4745                    name: 'x',
4746                    description: '<p>x-coordinate of the pixel</p>\n',
4747                    type: 'Number'
4748                  },
4749                  {
4750                    name: 'y',
4751                    description: '<p>y-coordinate of the pixel</p>\n',
4752                    type: 'Number'
4753                  },
4754                  {
4755                    name: 'c',
4756                    description:
4757                      '<p>insert a grayscale value | a pixel array |\n                               a <a href="#/p5.Color">p5.Color</a> object | a <a href="#/p5.Image">p5.Image</a> to copy</p>\n',
4758                    type: 'Number|Number[]|Object'
4759                  }
4760                ],
4761                class: 'p5',
4762                module: 'Image'
4763              },
4764              updatePixels: {
4765                name: 'updatePixels',
4766                params: [
4767                  {
4768                    name: 'x',
4769                    description:
4770                      '<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n',
4771                    type: 'Number',
4772                    optional: true
4773                  },
4774                  {
4775                    name: 'y',
4776                    description:
4777                      '<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n',
4778                    type: 'Number',
4779                    optional: true
4780                  },
4781                  {
4782                    name: 'w',
4783                    description: '<p>width of region to update</p>\n',
4784                    type: 'Number',
4785                    optional: true
4786                  },
4787                  {
4788                    name: 'h',
4789                    description: '<p>height of region to update</p>\n',
4790                    type: 'Number',
4791                    optional: true
4792                  }
4793                ],
4794                class: 'p5',
4795                module: 'Image'
4796              },
4797              loadJSON: {
4798                name: 'loadJSON',
4799                class: 'p5',
4800                module: 'IO',
4801                overloads: [
4802                  {
4803                    params: [
4804                      {
4805                        name: 'path',
4806                        description: '<p>name of the file or url to load</p>\n',
4807                        type: 'String'
4808                      },
4809                      {
4810                        name: 'jsonpOptions',
4811                        description: '<p>options object for jsonp related settings</p>\n',
4812                        type: 'Object',
4813                        optional: true
4814                      },
4815                      {
4816                        name: 'datatype',
4817                        description: '<p>"json" or "jsonp"</p>\n',
4818                        type: 'String',
4819                        optional: true
4820                      },
4821                      {
4822                        name: 'callback',
4823                        description:
4824                          '<p>function to be executed after\n                                   <a href="#/p5/loadJSON">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n',
4825                        type: 'Function',
4826                        optional: true
4827                      },
4828                      {
4829                        name: 'errorCallback',
4830                        description:
4831                          '<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n',
4832                        type: 'Function',
4833                        optional: true
4834                      }
4835                    ]
4836                  },
4837                  {
4838                    params: [
4839                      {
4840                        name: 'path',
4841                        description: '',
4842                        type: 'String'
4843                      },
4844                      {
4845                        name: 'datatype',
4846                        description: '',
4847                        type: 'String'
4848                      },
4849                      {
4850                        name: 'callback',
4851                        description: '',
4852                        type: 'Function',
4853                        optional: true
4854                      },
4855                      {
4856                        name: 'errorCallback',
4857                        description: '',
4858                        type: 'Function',
4859                        optional: true
4860                      }
4861                    ]
4862                  },
4863                  {
4864                    params: [
4865                      {
4866                        name: 'path',
4867                        description: '',
4868                        type: 'String'
4869                      },
4870                      {
4871                        name: 'callback',
4872                        description: '',
4873                        type: 'Function'
4874                      },
4875                      {
4876                        name: 'errorCallback',
4877                        description: '',
4878                        type: 'Function',
4879                        optional: true
4880                      }
4881                    ]
4882                  }
4883                ]
4884              },
4885              loadStrings: {
4886                name: 'loadStrings',
4887                params: [
4888                  {
4889                    name: 'filename',
4890                    description: '<p>name of the file or url to load</p>\n',
4891                    type: 'String'
4892                  },
4893                  {
4894                    name: 'callback',
4895                    description:
4896                      '<p>function to be executed after <a href="#/p5/loadStrings">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n',
4897                    type: 'Function',
4898                    optional: true
4899                  },
4900                  {
4901                    name: 'errorCallback',
4902                    description:
4903                      '<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n',
4904                    type: 'Function',
4905                    optional: true
4906                  }
4907                ],
4908                class: 'p5',
4909                module: 'IO'
4910              },
4911              loadTable: {
4912                name: 'loadTable',
4913                params: [
4914                  {
4915                    name: 'filename',
4916                    description: '<p>name of the file or URL to load</p>\n',
4917                    type: 'String'
4918                  },
4919                  {
4920                    name: 'extension',
4921                    description:
4922                      '<p>parse the table by comma-separated values "csv", semicolon-separated\n                                     values "ssv", or tab-separated values "tsv"</p>\n',
4923                    type: 'String',
4924                    optional: true
4925                  },
4926                  {
4927                    name: 'header',
4928                    description: '<p>"header" to indicate table has header row</p>\n',
4929                    type: 'String',
4930                    optional: true
4931                  },
4932                  {
4933                    name: 'callback',
4934                    description:
4935                      '<p>function to be executed after\n                                     <a href="#/p5/loadTable">loadTable()</a> completes. On success, the\n                                     <a href="#/p5.Table">Table</a> object is passed in as the\n                                     first argument.</p>\n',
4936                    type: 'Function',
4937                    optional: true
4938                  },
4939                  {
4940                    name: 'errorCallback',
4941                    description:
4942                      '<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n',
4943                    type: 'Function',
4944                    optional: true
4945                  }
4946                ],
4947                class: 'p5',
4948                module: 'IO'
4949              },
4950              loadXML: {
4951                name: 'loadXML',
4952                params: [
4953                  {
4954                    name: 'filename',
4955                    description: '<p>name of the file or URL to load</p>\n',
4956                    type: 'String'
4957                  },
4958                  {
4959                    name: 'callback',
4960                    description:
4961                      '<p>function to be executed after <a href="#/p5/loadXML">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n',
4962                    type: 'Function',
4963                    optional: true
4964                  },
4965                  {
4966                    name: 'errorCallback',
4967                    description:
4968                      '<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n',
4969                    type: 'Function',
4970                    optional: true
4971                  }
4972                ],
4973                class: 'p5',
4974                module: 'IO'
4975              },
4976              loadBytes: {
4977                name: 'loadBytes',
4978                params: [
4979                  {
4980                    name: 'file',
4981                    description: '<p>name of the file or URL to load</p>\n',
4982                    type: 'String'
4983                  },
4984                  {
4985                    name: 'callback',
4986                    description:
4987                      '<p>function to be executed after <a href="#/p5/loadBytes">loadBytes()</a>\n                                   completes</p>\n',
4988                    type: 'Function',
4989                    optional: true
4990                  },
4991                  {
4992                    name: 'errorCallback',
4993                    description:
4994                      '<p>function to be executed if there\n                                   is an error</p>\n',
4995                    type: 'Function',
4996                    optional: true
4997                  }
4998                ],
4999                class: 'p5',
5000                module: 'IO'
5001              },
5002              httpGet: {
5003                name: 'httpGet',
5004                class: 'p5',
5005                module: 'IO',
5006                overloads: [
5007                  {
5008                    params: [
5009                      {
5010                        name: 'path',
5011                        description: '<p>name of the file or url to load</p>\n',
5012                        type: 'String'
5013                      },
5014                      {
5015                        name: 'datatype',
5016                        description:
5017                          '<p>"json", "jsonp", "binary", "arrayBuffer",\n                                   "xml", or "text"</p>\n',
5018                        type: 'String',
5019                        optional: true
5020                      },
5021                      {
5022                        name: 'data',
5023                        description: '<p>param data passed sent with request</p>\n',
5024                        type: 'Object|Boolean',
5025                        optional: true
5026                      },
5027                      {
5028                        name: 'callback',
5029                        description:
5030                          '<p>function to be executed after\n                                   <a href="#/p5/httpGet">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n',
5031                        type: 'Function',
5032                        optional: true
5033                      },
5034                      {
5035                        name: 'errorCallback',
5036                        description:
5037                          '<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n',
5038                        type: 'Function',
5039                        optional: true
5040                      }
5041                    ]
5042                  },
5043                  {
5044                    params: [
5045                      {
5046                        name: 'path',
5047                        description: '',
5048                        type: 'String'
5049                      },
5050                      {
5051                        name: 'data',
5052                        description: '',
5053                        type: 'Object|Boolean'
5054                      },
5055                      {
5056                        name: 'callback',
5057                        description: '',
5058                        type: 'Function',
5059                        optional: true
5060                      },
5061                      {
5062                        name: 'errorCallback',
5063                        description: '',
5064                        type: 'Function',
5065                        optional: true
5066                      }
5067                    ]
5068                  },
5069                  {
5070                    params: [
5071                      {
5072                        name: 'path',
5073                        description: '',
5074                        type: 'String'
5075                      },
5076                      {
5077                        name: 'callback',
5078                        description: '',
5079                        type: 'Function'
5080                      },
5081                      {
5082                        name: 'errorCallback',
5083                        description: '',
5084                        type: 'Function',
5085                        optional: true
5086                      }
5087                    ]
5088                  }
5089                ]
5090              },
5091              httpPost: {
5092                name: 'httpPost',
5093                class: 'p5',
5094                module: 'IO'
5094,
5095                overloads: [
5096                  {
5097                    params: [
5098                      {
5099                        name: 'path',
5100                        description: '<p>name of the file or url to load</p>\n',
5101                        type: 'String'
5102                      },
5103                      {
5104                        name: 'datatype',
5105                        description:
5106                          '<p>"json", "jsonp", "xml", or "text".\n                                   If omitted, <a href="#/p5/httpPost">httpPost()</a> will guess.</p>\n',
5107                        type: 'String',
5108                        optional: true
5109                      },
5110                      {
5111                        name: 'data',
5112                        description: '<p>param data passed sent with request</p>\n',
5113                        type: 'Object|Boolean',
5114                        optional: true
5115                      },
5116                      {
5117                        name: 'callback',
5118                        description:
5119                          '<p>function to be executed after\n                                   <a href="#/p5/httpPost">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n',
5120                        type: 'Function',
5121                        optional: true
5122                      },
5123                      {
5124                        name: 'errorCallback',
5125                        description:
5126                          '<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n',
5127                        type: 'Function',
5128                        optional: true
5129                      }
5130                    ]
5131                  },
5132                  {
5133                    params: [
5134                      {
5135                        name: 'path',
5136                        description: '',
5137                        type: 'String'
5138                      },
5139                      {
5140                        name: 'data',
5141                        description: '',
5142                        type: 'Object|Boolean'
5143                      },
5144                      {
5145                        name: 'callback',
5146                        description: '',
5147                        type: 'Function',
5148                        optional: true
5149                      },
5150                      {
5151                        name: 'errorCallback',
5152                        description: '',
5153                        type: 'Function',
5154                        optional: true
5155                      }
5156                    ]
5157                  },
5158                  {
5159                    params: [
5160                      {
5161                        name: 'path',
5162                        description: '',
5163                        type: 'String'
5164                      },
5165                      {
5166                        name: 'callback',
5167                        description: '',
5168                        type: 'Function'
5169                      },
5170                      {
5171                        name: 'errorCallback',
5172                        description: '',
5173                        type: 'Function',
5174                        optional: true
5175                      }
5176                    ]
5177                  }
5178                ]
5179              },
5180              httpDo: {
5181                name: 'httpDo',
5182                class: 'p5',
5183                module: 'IO',
5184                overloads: [
5185                  {
5186                    params: [
5187                      {
5188                        name: 'path',
5189                        description: '<p>name of the file or url to load</p>\n',
5190                        type: 'String'
5191                      },
5192                      {
5193                        name: 'method',
5194                        description:
5195                          '<p>either "GET", "POST", or "PUT",\n                                   defaults to "GET"</p>\n',
5196                        type: 'String',
5197                        optional: true
5198                      },
5199                      {
5200                        name: 'datatype',
5201                        description: '<p>"json", "jsonp", "xml", or "text"</p>\n',
5202                        type: 'String',
5203                        optional: true
5204                      },
5205                      {
5206                        name: 'data',
5207                        description: '<p>param data passed sent with request</p>\n',
5208                        type: 'Object',
5209                        optional: true
5210                      },
5211                      {
5212                        name: 'callback',
5213                        description:
5214                          '<p>function to be executed after\n                                   <a href="#/p5/httpGet">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n',
5215                        type: 'Function',
5216                        optional: true
5217                      },
5218                      {
5219                        name: 'errorCallback',
5220                        description:
5221                          '<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n',
5222                        type: 'Function',
5223                        optional: true
5224                      }
5225                    ]
5226                  },
5227                  {
5228                    params: [
5229                      {
5230                        name: 'path',
5231                        description: '',
5232                        type: 'String'
5233                      },
5234                      {
5235                        name: 'options',
5236                        description:
5237                          '<p>Request object options as documented in the\n                                   "fetch" API\n<a href="https://developer.mozilla.org/en/docs/Web/API/Fetch_API">reference</a></p>\n',
5238                        type: 'Object'
5239                      },
5240                      {
5241                        name: 'callback',
5242                        description: '',
5243                        type: 'Function',
5244                        optional: true
5245                      },
5246                      {
5247                        name: 'errorCallback',
5248                        description: '',
5249                        type: 'Function',
5250                        optional: true
5251                      }
5252                    ]
5253                  }
5254                ]
5255              },
5256              createWriter: {
5257                name: 'createWriter',
5258                params: [
5259                  {
5260                    name: 'name',
5261                    description: '<p>name of the file to be created</p>\n',
5262                    type: 'String'
5263                  },
5264                  {
5265                    name: 'extension',
5266                    description: '',
5267                    type: 'String',
5268                    optional: true
5269                  }
5270                ],
5271                class: 'p5',
5272                module: 'IO'
5273              },
5274              save: {
5275                name: 'save',
5276                params: [
5277                  {
5278                    name: 'objectOrFilename',
5279                    description:
5280                      '<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n',
5281                    type: 'Object|String',
5282                    optional: true
5283                  },
5284                  {
5285                    name: 'filename',
5286                    description:
5287                      '<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n',
5288                    type: 'String',
5289                    optional: true
5290                  },
5291                  {
5292                    name: 'options',
5293                    description:
5294                      '<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n',
5295                    type: 'Boolean|String',
5296                    optional: true
5297                  }
5298                ],
5299                class: 'p5',
5300                module: 'IO'
5301              },
5302              saveJSON: {
5303                name: 'saveJSON',
5304                params: [
5305                  {
5306                    name: 'json',
5307                    description: '',
5308                    type: 'Array|Object'
5309                  },
5310                  {
5311                    name: 'filename',
5312                    description: '',
5313                    type: 'String'
5314                  },
5315                  {
5316                    name: 'optimize',
5317                    description:
5318                      '<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n',
5319                    type: 'Boolean',
5320                    optional: true
5321                  }
5322                ],
5323                class: 'p5',
5324                module: 'IO'
5325              },
5326              saveStrings: {
5327                name: 'saveStrings',
5328                params: [
5329                  {
5330                    name: 'list',
5331                    description: '<p>string array to be written</p>\n',
5332                    type: 'String[]'
5333                  },
5334                  {
5335                    name: 'filename',
5336                    description: '<p>filename for output</p>\n',
5337                    type: 'String'
5338                  },
5339                  {
5340                    name: 'extension',
5341                    description: "<p>the filename's extension</p>\n",
5342                    type: 'String',
5343                    optional: true
5344                  },
5345                  {
5346                    name: 'isCRLF',
5347                    description: '<p>if true, change line-break to CRLF</p>\n',
5348                    type: 'Boolean',
5349                    optional: true
5350                  }
5351                ],
5352                class: 'p5',
5353                module: 'IO'
5354              },
5355              saveTable: {
5356                name: 'saveTable',
5357                params: [
5358                  {
5359                    name: 'Table',
5360                    description:
5361                      '<p>the <a href="#/p5.Table">Table</a> object to save to a file</p>\n',
5362                    type: 'p5.Table'
5363                  },
5364                  {
5365                    name: 'filename',
5366                    description: '<p>the filename to which the Table should be saved</p>\n',
5367                    type: 'String'
5368                  },
5369                  {
5370                    name: 'options',
5371                    description: '<p>can be one of "tsv", "csv", or "html"</p>\n',
5372                    type: 'String',
5373                    optional: true
5374                  }
5375                ],
5376                class: 'p5',
5377                module: 'IO'
5378              },
5379              abs: {
5380                name: 'abs',
5381                params: [
5382                  {
5383                    name: 'n',
5384                    description: '<p>number to compute</p>\n',
5385                    type: 'Number'
5386                  }
5387                ],
5388                class: 'p5',
5389                module: 'Math'
5390              },
5391              ceil: {
5392                name: 'ceil',
5393                params: [
5394                  {
5395                    name: 'n',
5396                    description: '<p>number to round up</p>\n',
5397                    type: 'Number'
5398                  }
5399                ],
5400                class: 'p5',
5401                module: 'Math'
5402              },
5403              constrain: {
5404                name: 'constrain',
5405                params: [
5406                  {
5407                    name: 'n',
5408                    description: '<p>number to constrain</p>\n',
5409                    type: 'Number'
5410                  },
5411                  {
5412                    name: 'low',
5413                    description: '<p>minimum limit</p>\n',
5414                    type: 'Number'
5415                  },
5416                  {
5417                    name: 'high',
5418                    description: '<p>maximum limit</p>\n',
5419                    type: 'Number'
5420                  }
5421                ],
5422                class: 'p5',
5423                module: 'Math'
5424              },
5425              dist: {
5426                name: 'dist',
5427                class: 'p5',
5428                module: 'Math',
5429                overloads: [
5430                  {
5431                    params: [
5432                      {
5433                        name: 'x1',
5434                        description: '<p>x-coordinate of the first point</p>\n',
5435                        type: 'Number'
5436                      },
5437                      {
5438                        name: 'y1',
5439                        description: '<p>y-coordinate of the first point</p>\n',
5440                        type: 'Number'
5441                      },
5442                      {
5443                        name: 'x2',
5444                        description: '<p>x-coordinate of the second point</p>\n',
5445                        type: 'Number'
5446                      },
5447                      {
5448                        name: 'y2',
5449                        description: '<p>y-coordinate of the second point</p>\n',
5450                        type: 'Number'
5451                      }
5452                    ]
5453                  },
5454                  {
5455                    params: [
5456                      {
5457                        name: 'x1',
5458                        description: '',
5459                        type: 'Number'
5460                      },
5461                      {
5462                        name: 'y1',
5463                        description: '',
5464                        type: 'Number'
5465                      },
5466                      {
5467                        name: 'z1',
5468                        description: '<p>z-coordinate of the first point</p>\n',
5469                        type: 'Number'
5470                      },
5471                      {
5472                        name: 'x2',
5473                        description: '',
5474                        type: 'Number'
5475                      },
5476                      {
5477                        name: 'y2',
5478                        description: '',
5479                        type: 'Number'
5480                      },
5481                      {
5482                        name: 'z2',
5483                        description: '<p>z-coordinate of the second point</p>\n',
5484                        type: 'Number'
5485                      }
5486                    ]
5487                  }
5488                ]
5489              },
5490              exp: {
5491                name: 'exp',
5492                params: [
5493                  {
5494                    name: 'n',
5495                    description: '<p>exponent to raise</p>\n',
5496                    type: 'Number'
5497                  }
5498                ],
5499                class: 'p5',
5500                module: 'Math'
5501              },
5502              floor: {
5503                name: 'floor',
5504                params: [
5505                  {
5506                    name: 'n',
5507                    description: '<p>number to round down</p>\n',
5508                    type: 'Number'
5509                  }
5510                ],
5511                class: 'p5',
5512                module: 'Math'
5513              },
5514              lerp: {
5515                name: 'lerp',
5516                params: [
5517                  {
5518                    name: 'start',
5519                    description: '<p>first value</p>\n',
5520                    type: 'Number'
5521          
5521        },
5522                  {
5523                    name: 'stop',
5524                    description: '<p>second value</p>\n',
5525                    type: 'Number'
5526                  },
5527                  {
5528                    name: 'amt',
5529                    description: '<p>number</p>\n',
5530                    type: 'Number'
5531                  }
5532                ],
5533                class: 'p5',
5534                module: 'Math'
5535              },
5536              log: {
5537                name: 'log',
5538                params: [
5539                  {
5540                    name: 'n',
5541                    description: '<p>number greater than 0</p>\n',
5542                    type: 'Number'
5543                  }
5544                ],
5545                class: 'p5',
5546                module: 'Math'
5547              },
5548              mag: {
5549                name: 'mag',
5550                params: [
5551                  {
5552                    name: 'a',
5553                    description: '<p>first value</p>\n',
5554                    type: 'Number'
5555                  },
5556                  {
5557                    name: 'b',
5558                    description: '<p>second value</p>\n',
5559                    type: 'Number'
5560                  }
5561                ],
5562                class: 'p5',
5563                module: 'Math'
5564              },
5565              map: {
5566                name: 'map',
5567                params: [
5568                  {
5569                    name: 'value',
5570                    description: '<p>the incoming value to be converted</p>\n',
5571                    type: 'Number'
5572                  },
5573                  {
5574                    name: 'start1',
5575                    description: "<p>lower bound of the value's current range</p>\n",
5576                    type: 'Number'
5577                  },
5578                  {
5579                    name: 'stop1',
5580                    description: "<p>upper bound of the value's current range</p>\n",
5581                    type: 'Number'
5582                  },
5583                  {
5584                    name: 'start2',
5585                    description: "<p>lower bound of the value's target range</p>\n",
5586                    type: 'Number'
5587                  },
5588                  {
5589                    name: 'stop2',
5590                    description: "<p>upper bound of the value's target range</p>\n",
5591                    type: 'Number'
5592                  },
5593                  {
5594                    name: 'withinBounds',
5595                    description: '<p>constrain the value to the newly mapped range</p>\n',
5596                    type: 'Boolean',
5597                    optional: true
5598                  }
5599                ],
5600                class: 'p5',
5601                module: 'Math'
5602              },
5603              max: {
5604                name: 'max',
5605                class: 'p5',
5606                module: 'Math',
5607                overloads: [
5608                  {
5609                    params: [
5610                      {
5611                        name: 'n0',
5612                        description: '<p>Number to compare</p>\n',
5613                        type: 'Number'
5614                      },
5615                      {
5616                        name: 'n1',
5617                        description: '<p>Number to compare</p>\n',
5618                        type: 'Number'
5619                      }
5620                    ]
5621                  },
5622                  {
5623                    params: [
5624                      {
5625                        name: 'nums',
5626                        description: '<p>Numbers to compare</p>\n',
5627                        type: 'Number[]'
5628                      }
5629                    ]
5630                  }
5631                ]
5632              },
5633              min: {
5634                name: 'min',
5635                class: 'p5',
5636                module: 'Math',
5637                overloads: [
5638                  {
5639                    params: [
5640                      {
5641                        name: 'n0',
5642                        description: '<p>Number to compare</p>\n',
5643                        type: 'Number'
5644                      },
5645                      {
5646                        name: 'n1',
5647                        description: '<p>Number to compare</p>\n',
5648                        type: 'Number'
5649                      }
5650                    ]
5651                  },
5652                  {
5653                    params: [
5654                      {
5655                        name: 'nums',
5656                        description: '<p>Numbers to compare</p>\n',
5657                        type: 'Number[]'
5658                      }
5659                    ]
5660                  }
5661                ]
5662              },
5663              norm: {
5664                name: 'norm',
5665                params: [
5666                  {
5667                    name: 'value',
5668                    description: '<p>incoming value to be normalized</p>\n',
5669                    type: 'Number'
5670                  },
5671                  {
5672                    name: 'start',
5673                    description: "<p>lower bound of the value's current range</p>\n",
5674                    type: 'Number'
5675                  },
5676                  {
5677                    name: 'stop',
5678                    description: "<p>upper bound of the value's current range</p>\n",
5679                    type: 'Number'
5680                  }
5681                ],
5682                class: 'p5',
5683                module: 'Math'
5684              },
5685              pow: {
5686                name: 'pow',
5687                params: [
5688                  {
5689                    name: 'n',
5690                    description: '<p>base of the exponential expression</p>\n',
5691                    type: 'Number'
5692                  },
5693                  {
5694                    name: 'e',
5695                    description: '<p>power by which to raise the base</p>\n',
5696                    type: 'Number'
5697                  }
5698                ],
5699                class: 'p5',
5700                module: 'Math'
5701              },
5702              round: {
5703                name: 'round',
5704                params: [
5705                  {
5706                    name: 'n',
5707                    description: '<p>number to round</p>\n',
5708                    type: 'Number'
5709                  },
5710                  {
5711                    name: 'decimals',
5712                    description:
5713                      '<p>number of decimal places to round to, default is 0</p>\n',
5714                    type: 'Number',
5715                    optional: true
5716                  }
5717                ],
5718                class: 'p5',
5719                module: 'Math'
5720              },
5721              sq: {
5722                name: 'sq',
5723                params: [
5724                  {
5725                    name: 'n',
5726                    description: '<p>number to square</p>\n',
5727                    type: 'Number'
5728                  }
5729                ],
5730                class: 'p5',
5731                module: 'Math'
5732              },
5733              sqrt: {
5734                name: 'sqrt',
5735                params: [
5736                  {
5737                    name: 'n',
5738                    description: '<p>non-negative number to square root</p>\n',
5739                    type: 'Number'
5740                  }
5741                ],
5742                class: 'p5',
5743                module: 'Math'
5744              },
5745              fract: {
5746                name: 'fract',
5747                params: [
5748                  {
5749                    name: 'num',
5750                    description:
5751                      '<p>Number whose fractional part needs to be found out</p>\n',
5752                    type: 'Number'
5753                  }
5754                ],
5755                class: 'p5',
5756                module: 'Math'
5757              },
5758              createVector: {
5759                name: 'createVector',
5760                params: [
5761                  {
5762                    name: 'x',
5763                    description: '<p>x component of the vector</p>\n',
5764                    type: 'Number',
5765                    optional: true
5766                  },
5767                  {
5768                    name: 'y',
5769                    description: '<p>y component of the vector</p>\n',
5770                    type: 'Number',
5771                    optional: true
5772                  },
5773                  {
5774                    name: 'z',
5775                    description: '<p>z component of the vector</p>\n',
5776                    type: 'Number',
5777                    optional: true
5778                  }
5779                ],
5780                class: 'p5',
5781                module: 'Math'
5782              },
5783              noise: {
5784                name: 'noise',
5785                params: [
5786                  {
5787                    name: 'x',
5788                    description: '<p>x-coordinate in noise space</p>\n',
5789                    type: 'Number'
5790                  },
5791                  {
5792                    name: 'y',
5793                    description: '<p>y-coordinate in noise space</p>\n',
5794                    type: 'Number',
5795                    optional: true
5796                  },
5797                  {
5798                    name: 'z',
5799                    description: '<p>z-coordinate in noise space</p>\n',
5800                    type: 'Number',
5801                    optional: true
5802                  }
5803                ],
5804                class: 'p5',
5805                module: 'Math'
5806              },
5807              noiseDetail: {
5808                name: 'noiseDetail',
5809                params: [
5810                  {
5811                    name: 'lod',
5812                    description: '<p>number of octaves to be used by the noise</p>\n',
5813                    type: 'Number'
5814                  },
5815                  {
5816                    name: 'falloff',
5817                    description: '<p>falloff factor for each octave</p>\n',
5818                    type: 'Number'
5819                  }
5820                ],
5821                class: 'p5',
5822                module: 'Math'
5823              },
5824              noiseSeed: {
5825                name: 'noiseSeed',
5826                params: [
5827                  {
5828                    name: 'seed',
5829                    description: '<p>the seed value</p>\n',
5830                    type: 'Number'
5831                  }
5832                ],
5833                class: 'p5',
5834                module: 'Math'
5835              },
5836              randomSeed: {
5837                name: 'randomSeed',
5838                params: [
5839                  {
5840                    name: 'seed',
5841                    description: '<p>the seed value</p>\n',
5842                    type: 'Number'
5843                  }
5844                ],
5845                class: 'p5',
5846                module: 'Math'
5847              },
5848              random: {
5849                name: 'random',
5850                class: 'p5',
5851                module: 'Math',
5852                overloads: [
5853                  {
5854                    params: [
5855                      {
5856                        name: 'min',
5857                        description: '<p>the lower bound (inclusive)</p>\n',
5858                        type: 'Number',
5859                        optional: true
5860                      },
5861                      {
5862                        name: 'max',
5863                        description: '<p>the upper bound (exclusive)</p>\n',
5864                        type: 'Number',
5865                        optional: true
5866                      }
5867                    ]
5868                  },
5869                  {
5870                    params: [
5871                      {
5872                        name: 'choices',
5873                        description: '<p>the array to choose from</p>\n',
5874                        type: 'Array'
5875                      }
5876                    ]
5877                  }
5878                ]
5879              },
5880              randomGaussian: {
5881                name: 'randomGaussian',
5882                params: [
5883                  {
5884                    name: 'mean',
5885                    description: '<p>the mean</p>\n',
5886                    type: 'Number',
5887                    optional: true
5888                  },
5889                  {
5890                    name: 'sd',
5891                    description: '<p>the standard deviation</p>\n',
5892                    type: 'Number',
5893                    optional: true
5894                  }
5895                ],
5896                class: 'p5',
5897                module: 'Math'
5898              },
5899              acos: {
5900                name: 'acos',
5901                params: [
5902                  {
5903                    name: 'value',
5904                    description: '<p>the value whose arc cosine is to be returned</p>\n',
5905                    type: 'Number'
5906                  }
5907                ],
5908                class: 'p5',
5909                module: 'Math'
5910              },
5911              asin: {
5912                name: 'asin',
5913                params: [
5914                  {
5915                    name: 'value',
5916                    description: '<p>the value whose arc sine is to be returned</p>\n',
5917                    type: 'Number'
5918                  }
5919                ],
5920                class: 'p5',
5921                module: 'Math'
5922              },
5923              atan: {
5924                name: 'atan',
5925                params: [
5926                  {
5927                    name: 'value',
5928                    description: '<p>the value whose arc tangent is to be returned</p>\n',
5929                    type: 'Number'
5930                  }
5931                ],
5932                class: 'p5',
5933                module: 'Math'
5934              },
5935              atan2: {
5936                name: 'atan2',
5937                params: [
5938                  {
5939                    name: 'y',
5940                    description: '<p>y-coordinate of the point</p>\n',
5941                    type: 'Number'
5942                  },
5943                  {
5944                    name: 'x',
5945                    description: '<p>x-coordinate of the point</p>\n',
5946                    type: 'Number'
5947                  }
5948                ],
5949                class: 'p5',
5950                module: 'Math'
5951              },
5952              cos: {
5953                name: 'cos',
5954                params: [
5955                  {
5956                    name: 'angle',
5957                    description: '<p>the angle</p>\n',
5958                    type: 'Number'
5959                  }
5960                ],
5961                class: 'p5',
5962                module: 'Math'
5963              },
5964              sin: {
5965                name: 'sin',
5966                params: [
5967                  {
5968                    name: 'angle',
5969                    description: '<p>the angle</p>\n',
5970                    type: 'Number'
5971                  }
5972                ],
5973                class: 'p5',
5974                module: 'Math'
5975              },
5976              tan: {
5977                name: 'tan',
5978                params: [
5979                  {
5980                    name: 'angle',
5981                    description: '<p>the angle</p>\n',
5982                    type: 'Number'
5983                  }
5984                ],
5985                class: 'p5',
5986                module: 'Math'
5987              },
5988              degrees: {
5989                name: 'degrees',
5990                params: [
5991                  {
5992                    name: 'radians',
5993                    description: '<p>the radians value to convert to degrees</p>\n',
5994                    type: 'Number'
5995                  }
5996                ],
5997                class: 'p5',
5998                module: 'Math'
5999              },
6000              radians: {
6001                name: 'radians',
6002                params: [
6003                  {
6004                    name: 'degrees',
6005                    description: '<p>the degree value to convert to radians</p>\n',
6006                    type: 'Number'
6007                  }
6008                ],
6009                class: 'p5',
6010                module: 'Math'
6011              },
6012              angleMode: {
6013                name: 'angleMode',
6014                params: [
6015                  {
6016                    name: 'mode',
6017                    description: '<p>either RADIANS or DEGREES</p>\n',
6018                    type: 'Constant'
6019                  }
6020                ],
6021                class: 'p5',
6022                module: 'Math'
6023              },
6024              textAlign: {
6025                name: 'textAlign',
6026                class: 'p5',
6027                module: 'Typography',
6028                overloads: [
6029                  {
6030                    params: [
6031                      {
6032                        name: 'horizAlign',
6033                        description:
6034                          '<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n',
6035                        type: 'Constant'
6036                     
6036 },
6037                      {
6038                        name: 'vertAlign',
6039                        description:
6040                          '<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n',
6041                        type: 'Constant',
6042                        optional: true
6043                      }
6044                    ],
6045                    chainable: 1
6046                  },
6047                  {
6048                    params: []
6049                  }
6050                ]
6051              },
6052              textLeading: {
6053                name: 'textLeading',
6054                class: 'p5',
6055                module: 'Typography',
6056                overloads: [
6057                  {
6058                    params: [
6059                      {
6060                        name: 'leading',
6061                        description:
6062                          '<p>the size in pixels for spacing between lines</p>\n',
6063                        type: 'Number'
6064                      }
6065                    ],
6066                    chainable: 1
6067                  },
6068                  {
6069                    params: []
6070                  }
6071                ]
6072              },
6073              textSize: {
6074                name: 'textSize',
6075                class: 'p5',
6076                module: 'Typography',
6077                overloads: [
6078                  {
6079                    params: [
6080                      {
6081                        name: 'theSize',
6082                        description: '<p>the size of the letters in units of pixels</p>\n',
6083                        type: 'Number'
6084                      }
6085                    ],
6086                    chainable: 1
6087                  },
6088                  {
6089                    params: []
6090                  }
6091                ]
6092              },
6093              textStyle: {
6094                name: 'textStyle',
6095                class: 'p5',
6096                module: 'Typography',
6097                overloads: [
6098                  {
6099                    params: [
6100                      {
6101                        name: 'theStyle',
6102                        description:
6103                          '<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n',
6104                        type: 'Constant'
6105                      }
6106                    ],
6107                    chainable: 1
6108                  },
6109                  {
6110                    params: []
6111                  }
6112                ]
6113              },
6114              textWidth: {
6115                name: 'textWidth',
6116                params: [
6117                  {
6118                    name: 'theText',
6119                    description: '<p>the String of characters to measure</p>\n',
6120                    type: 'String'
6121                  }
6122                ],
6123                class: 'p5',
6124                module: 'Typography'
6125              },
6126              textAscent: {
6127                name: 'textAscent',
6128                class: 'p5',
6129                module: 'Typography'
6130              },
6131              textDescent: {
6132                name: 'textDescent',
6133                class: 'p5',
6134                module: 'Typography'
6135              },
6136              loadFont: {
6137                name: 'loadFont',
6138                params: [
6139                  {
6140                    name: 'path',
6141                    description: '<p>name of the file or url to load</p>\n',
6142                    type: 'String'
6143                  },
6144                  {
6145                    name: 'callback',
6146                    description:
6147                      '<p>function to be executed after\n                                   <a href="#/p5/loadFont">loadFont()</a> completes</p>\n',
6148                    type: 'Function',
6149                    optional: true
6150                  },
6151                  {
6152                    name: 'onError',
6153                    description:
6154                      '<p>function to be executed if\n                                   an error occurs</p>\n',
6155                    type: 'Function',
6156                    optional: true
6157                  }
6158                ],
6159                class: 'p5',
6160                module: 'Typography'
6161              },
6162              text: {
6163                name: 'text',
6164                params: [
6165                  {
6166                    name: 'str',
6167                    description:
6168                      '<p>the alphanumeric\n                                            symbols to be displayed</p>\n',
6169                    type: 'String|Object|Array|Number|Boolean'
6170                  },
6171                  {
6172                    name: 'x',
6173                    description: '<p>x-coordinate of text</p>\n',
6174                    type: 'Number'
6175                  },
6176                  {
6177                    name: 'y',
6178                    description: '<p>y-coordinate of text</p>\n',
6179                    type: 'Number'
6180                  },
6181                  {
6182                    name: 'x2',
6183                    description:
6184                      '<p>by default, the width of the text box,\n                    see <a href="#/p5/rectMode">rectMode()</a> for more info</p>\n',
6185                    type: 'Number',
6186                    optional: true
6187                  },
6188                  {
6189                    name: 'y2',
6190                    description:
6191                      '<p>by default, the height of the text box,\n                    see <a href="#/p5/rectMode">rectMode()</a> for more info</p>\n',
6192                    type: 'Number',
6193                    optional: true
6194                  }
6195                ],
6196                class: 'p5',
6197                module: 'Typography'
6198              },
6199              textFont: {
6200                name: 'textFont',
6201                class: 'p5',
6202                module: 'Typography',
6203                overloads: [
6204                  {
6205                    params: []
6206                  },
6207                  {
6208                    params: [
6209                      {
6210                        name: 'font',
6211                        description:
6212                          '<p>a font loaded via <a href="#/p5/loadFont">loadFont()</a>,\nor a String representing a <a href="https://mzl.la/2dOw8WD">web safe font</a>\n(a font that is generally available across all systems)</p>\n',
6213                        type: 'Object|String'
6214                      },
6215                      {
6216                        name: 'size',
6217                        description: '<p>the font size to use</p>\n',
6218                        type: 'Number',
6219                        optional: true
6220                      }
6221                    ],
6222                    chainable: 1
6223                  }
6224                ]
6225              },
6226              append: {
6227                name: 'append',
6228                params: [
6229                  {
6230                    name: 'array',
6231                    description: '<p>Array to append</p>\n',
6232                    type: 'Array'
6233                  },
6234                  {
6235                    name: 'value',
6236                    description: '<p>to be added to the Array</p>\n',
6237                    type: 'Any'
6238                  }
6239                ],
6240                class: 'p5',
6241                module: 'Data'
6242              },
6243              arrayCopy: {
6244                name: 'arrayCopy',
6245                class: 'p5',
6246                module: 'Data',
6247                overloads: [
6248                  {
6249                    params: [
6250                      {
6251                        name: 'src',
6252                        description: '<p>the source Array</p>\n',
6253                        type: 'Array'
6254                      },
6255                      {
6256                        name: 'srcPosition',
6257                        description: '<p>starting position in the source Array</p>\n',
6258                        type: 'Integer'
6259                      },
6260                      {
6261                        name: 'dst',
6262                        description: '<p>the destination Array</p>\n',
6263                        type: 'Array'
6264                      },
6265                      {
6266                        name: 'dstPosition',
6267                        description: '<p>starting position in the destination Array</p>\n',
6268                        type: 'Integer'
6269                      },
6270                      {
6271                        name: 'length',
6272                        description: '<p>number of Array elements to be copied</p>\n',
6273                        type: 'Integer'
6274                      }
6275                    ]
6276                  },
6277                  {
6278                    params: [
6279                      {
6280                        name: 'src',
6281                        description: '',
6282                        type: 'Array'
6283                      },
6284                      {
6285                        name: 'dst',
6286                        description: '',
6287                        type: 'Array'
6288                      },
6289                      {
6290                        name: 'length',
6291                        description: '',
6292                        type: 'Integer',
6293                        optional: true
6294                      }
6295                    ]
6296                  }
6297                ]
6298              },
6299              concat: {
6300                name: 'concat',
6301                params: [
6302                  {
6303                    name: 'a',
6304                    description: '<p>first Array to concatenate</p>\n',
6305                    type: 'Array'
6306                  },
6307                  {
6308                    name: 'b',
6309                    description: '<p>second Array to concatenate</p>\n',
6310                    type: 'Array'
6311                  }
6312                ],
6313                class: 'p5',
6314                module: 'Data'
6315              },
6316              reverse: {
6317                name: 'reverse',
6318                params: [
6319                  {
6320                    name: 'list',
6321                    description: '<p>Array to reverse</p>\n',
6322                    type: 'Array'
6323                  }
6324                ],
6325                class: 'p5',
6326                module: 'Data'
6327              },
6328              shorten: {
6329                name: 'shorten',
6330                params: [
6331                  {
6332                    name: 'list',
6333                    description: '<p>Array to shorten</p>\n',
6334                    type: 'Array'
6335                  }
6336                ],
6337                class: 'p5',
6338                module: 'Data'
6339              },
6340              shuffle: {
6341                name: 'shuffle',
6342                params: [
6343                  {
6344                    name: 'array',
6345                    description: '<p>Array to shuffle</p>\n',
6346                    type: 'Array'
6347                  },
6348                  {
6349                    name: 'bool',
6350                    description: '<p>modify passed array</p>\n',
6351                    type: 'Boolean',
6352                    optional: true
6353                  }
6354                ],
6355                class: 'p5',
6356                module: 'Data'
6357              },
6358              sort: {
6359                name: 'sort',
6360                params: [
6361                  {
6362                    name: 'list',
6363                    description: '<p>Array to sort</p>\n',
6364                    type: 'Array'
6365                  },
6366                  {
6367                    name: 'count',
6368                    description: '<p>number of elements to sort, starting from 0</p>\n',
6369                    type: 'Integer',
6370                    optional: true
6371                  }
6372                ],
6373                class: 'p5',
6374                module: 'Data'
6375              },
6376              splice: {
6377                name: 'splice',
6378                params: [
6379                  {
6380                    name: 'list',
6381                    description: '<p>Array to splice into</p>\n',
6382                    type: 'Array'
6383                  },
6384                  {
6385                    name: 'value',
6386                    description: '<p>value to be spliced in</p>\n',
6387                    type: 'Any'
6388                  },
6389                  {
6390                    name: 'position',
6391                    description: '<p>in the array from which to insert data</p>\n',
6392                    type: 'Integer'
6393                  }
6394                ],
6395                class: 'p5',
6396                module: 'Data'
6397              },
6398              subset: {
6399                name: 'subset',
6400                params: [
6401                  {
6402                    name: 'list',
6403                    description: '<p>Array to extract from</p>\n',
6404                    type: 'Array'
6405                  },
6406                  {
6407                    name: 'start',
6408                    description: '<p>position to begin</p>\n',
6409                    type: 'Integer'
6410                  },
6411                  {
6412                    name: 'count',
6413                    description: '<p>number of values to extract</p>\n',
6414                    type: 'Integer',
6415                    optional: true
6416                  }
6417                ],
6418                class: 'p5',
6419                module: 'Data'
6420              },
6421              float: {
6422                name: 'float',
6423                params: [
6424                  {
6425                    name: 'str',
6426                    description: '<p>float string to parse</p>\n',
6427                    type: 'String'
6428                  }
6429                ],
6430                class: 'p5',
6431                module: 'Data'
6432              },
6433              int: {
6434                name: 'int',
6435                class: 'p5',
6436                module: 'Data',
6437                overloads: [
6438                  {
6439                    params: [
6440                      {
6441                        name: 'n',
6442                        description: '<p>value to parse</p>\n',
6443                        type: 'String|Boolean|Number'
6444                      },
6445                      {
6446                        name: 'radix',
6447                        description: '<p>the radix to convert to (default: 10)</p>\n',
6448                        type: 'Integer',
6449                        optional: true
6450                      }
6451                    ]
6452                  },
6453                  {
6454                    params: [
6455                      {
6456                        name: 'ns',
6457                        description: '<p>values to parse</p>\n',
6458                        type: 'Array'
6459                      }
6460                    ]
6461                  }
6462                ]
6463              },
6464              str: {
6465                name: 'str',
6466                params: [
6467                  {
6468                    name: 'n',
6469                    description: '<p>value to parse</p>\n',
6470                    type: 'String|Boolean|Number|Array'
6471                  }
6472                ],
6473                class: 'p5',
6474                module: 'Data'
6475              },
6476              byte: {
6477                name: 'byte',
6478                class: 'p5',
6479                module: 'Data',
6480                overloads: [
6481                  {
6482                    params: [
6483                      {
6484                        name: 'n',
6485                        description: '<p>value to parse</p>\n',
6486                        type: 'String|Boolean|Number'
6487                      }
6488                    ]
6489                  },
6490                  {
6491                    params: [
6492                      {
6493                        name: 'ns',
6494                        description: '<p>values to parse</p>\n',
6495                        type: 'Array'
6496                      }
6497                    ]
6498                  }
6499                ]
6500              },
6501              char: {
6502                name: 'char',
6503                class: 'p5',
6504                module: 'Data',
6505                overloads: [
6506                  {
6507                    params: [
6508                      {
6509                        name: 'n',
6510                        description: '<p>value to parse</p>\n',
6511                        type: 'String|Number'
6512                      }
6513                    ]
6514                  },
6515                  {
6516                    params: [
6517                      {
6518                        name: 'ns',
6519                        description: '<p>values to parse</p>\n',
6520                        type: 'Array'
6521                      }
6522                    ]
6523                  }
6524                ]
6525              },
6526              unchar: {
6527                name: 'unchar',
6528                class: 'p5',
6529                module: 'Data',
6530                overloads: [
6531                  {
6532                    params: [
6533       
6533               {
6534                        name: 'n',
6535                        description: '<p>value to parse</p>\n',
6536                        type: 'String'
6537                      }
6538                    ]
6539                  },
6540                  {
6541                    params: [
6542                      {
6543                        name: 'ns',
6544                        description: '<p>values to parse</p>\n',
6545                        type: 'Array'
6546                      }
6547                    ]
6548                  }
6549                ]
6550              },
6551              hex: {
6552                name: 'hex',
6553                class: 'p5',
6554                module: 'Data',
6555                overloads: [
6556                  {
6557                    params: [
6558                      {
6559                        name: 'n',
6560                        description: '<p>value to parse</p>\n',
6561                        type: 'Number'
6562                      },
6563                      {
6564                        name: 'digits',
6565                        description: '',
6566                        type: 'Number',
6567                        optional: true
6568                      }
6569                    ]
6570                  },
6571                  {
6572                    params: [
6573                      {
6574                        name: 'ns',
6575                        description: '<p>array of values to parse</p>\n',
6576                        type: 'Number[]'
6577                      },
6578                      {
6579                        name: 'digits',
6580                        description: '',
6581                        type: 'Number',
6582                        optional: true
6583                      }
6584                    ]
6585                  }
6586                ]
6587              },
6588              unhex: {
6589                name: 'unhex',
6590                class: 'p5',
6591                module: 'Data',
6592                overloads: [
6593                  {
6594                    params: [
6595                      {
6596                        name: 'n',
6597                        description: '<p>value to parse</p>\n',
6598                        type: 'String'
6599                      }
6600                    ]
6601                  },
6602                  {
6603                    params: [
6604                      {
6605                        name: 'ns',
6606                        description: '<p>values to parse</p>\n',
6607                        type: 'Array'
6608                      }
6609                    ]
6610                  }
6611                ]
6612              },
6613              join: {
6614                name: 'join',
6615                params: [
6616                  {
6617                    name: 'list',
6618                    description: '<p>array of Strings to be joined</p>\n',
6619                    type: 'Array'
6620                  },
6621                  {
6622                    name: 'separator',
6623                    description: '<p>String to be placed between each item</p>\n',
6624                    type: 'String'
6625                  }
6626                ],
6627                class: 'p5',
6628                module: 'Data'
6629              },
6630              match: {
6631                name: 'match',
6632                params: [
6633                  {
6634                    name: 'str',
6635                    description: '<p>the String to be searched</p>\n',
6636                    type: 'String'
6637                  },
6638                  {
6639                    name: 'regexp',
6640                    description: '<p>the regexp to be used for matching</p>\n',
6641                    type: 'String'
6642                  }
6643                ],
6644                class: 'p5',
6645                module: 'Data'
6646              },
6647              matchAll: {
6648                name: 'matchAll',
6649                params: [
6650                  {
6651                    name: 'str',
6652                    description: '<p>the String to be searched</p>\n',
6653                    type: 'String'
6654                  },
6655                  {
6656                    name: 'regexp',
6657                    description: '<p>the regexp to be used for matching</p>\n',
6658                    type: 'String'
6659                  }
6660                ],
6661                class: 'p5',
6662                module: 'Data'
6663              },
6664              nf: {
6665                name: 'nf',
6666                class: 'p5',
6667                module: 'Data',
6668                overloads: [
6669                  {
6670                    params: [
6671                      {
6672                        name: 'num',
6673                        description: '<p>the Number to format</p>\n',
6674                        type: 'Number|String'
6675                      },
6676                      {
6677                        name: 'left',
6678                        description:
6679                          '<p>number of digits to the left of the\n                               decimal point</p>\n',
6680                        type: 'Integer|String',
6681                        optional: true
6682                      },
6683                      {
6684                        name: 'right',
6685                        description:
6686                          '<p>number of digits to the right of the\n                               decimal point</p>\n',
6687                        type: 'Integer|String',
6688                        optional: true
6689                      }
6690                    ]
6691                  },
6692                  {
6693                    params: [
6694                      {
6695                        name: 'nums',
6696                        description: '<p>the Numbers to format</p>\n',
6697                        type: 'Array'
6698                      },
6699                      {
6700                        name: 'left',
6701                        description: '',
6702                        type: 'Integer|String',
6703                        optional: true
6704                      },
6705                      {
6706                        name: 'right',
6707                        description: '',
6708                        type: 'Integer|String',
6709                        optional: true
6710                      }
6711                    ]
6712                  }
6713                ]
6714              },
6715              nfc: {
6716                name: 'nfc',
6717                class: 'p5',
6718                module: 'Data',
6719                overloads: [
6720                  {
6721                    params: [
6722                      {
6723                        name: 'num',
6724                        description: '<p>the Number to format</p>\n',
6725                        type: 'Number|String'
6726                      },
6727                      {
6728                        name: 'right',
6729                        description:
6730                          '<p>number of digits to the right of the\n                                 decimal point</p>\n',
6731                        type: 'Integer|String',
6732                        optional: true
6733                      }
6734                    ]
6735                  },
6736                  {
6737                    params: [
6738                      {
6739                        name: 'nums',
6740                        description: '<p>the Numbers to format</p>\n',
6741                        type: 'Array'
6742                      },
6743                      {
6744                        name: 'right',
6745                        description: '',
6746                        type: 'Integer|String',
6747                        optional: true
6748                      }
6749                    ]
6750                  }
6751                ]
6752              },
6753              nfp: {
6754                name: 'nfp',
6755                class: 'p5',
6756                module: 'Data',
6757                overloads: [
6758                  {
6759                    params: [
6760                      {
6761                        name: 'num',
6762                        description: '<p>the Number to format</p>\n',
6763                        type: 'Number'
6764                      },
6765                      {
6766                        name: 'left',
6767                        description:
6768                          '<p>number of digits to the left of the decimal\n                               point</p>\n',
6769                        type: 'Integer',
6770                        optional: true
6771                      },
6772                      {
6773                        name: 'right',
6774                        description:
6775                          '<p>number of digits to the right of the\n                               decimal point</p>\n',
6776                        type: 'Integer',
6777                        optional: true
6778                      }
6779                    ]
6780                  },
6781                  {
6782                    params: [
6783                      {
6784                        name: 'nums',
6785                        description: '<p>the Numbers to format</p>\n',
6786                        type: 'Number[]'
6787                      },
6788                      {
6789                        name: 'left',
6790                        description: '',
6791                        type: 'Integer',
6792                        optional: true
6793                      },
6794                      {
6795                        name: 'right',
6796                        description: '',
6797                        type: 'Integer',
6798                        optional: true
6799                      }
6800                    ]
6801                  }
6802                ]
6803              },
6804              nfs: {
6805                name: 'nfs',
6806                class: 'p5',
6807                module: 'Data',
6808                overloads: [
6809                  {
6810                    params: [
6811                      {
6812                        name: 'num',
6813                        description: '<p>the Number to format</p>\n',
6814                        type: 'Number'
6815                      },
6816                      {
6817                        name: 'left',
6818                        description:
6819                          '<p>number of digits to the left of the decimal\n                               point</p>\n',
6820                        type: 'Integer',
6821                        optional: true
6822                      },
6823                      {
6824                        name: 'right',
6825                        description:
6826                          '<p>number of digits to the right of the\n                               decimal point</p>\n',
6827                        type: 'Integer',
6828                        optional: true
6829                      }
6830                    ]
6831                  },
6832                  {
6833                    params: [
6834                      {
6835                        name: 'nums',
6836                        description: '<p>the Numbers to format</p>\n',
6837                        type: 'Array'
6838                      },
6839                      {
6840                        name: 'left',
6841                        description: '',
6842                        type: 'Integer',
6843                        optional: true
6844                      },
6845                      {
6846                        name: 'right',
6847                        description: '',
6848                        type: 'Integer',
6849                        optional: true
6850                      }
6851                    ]
6852                  }
6853                ]
6854              },
6855              split: {
6856                name: 'split',
6857                params: [
6858                  {
6859                    name: 'value',
6860                    description: '<p>the String to be split</p>\n',
6861                    type: 'String'
6862                  },
6863                  {
6864                    name: 'delim',
6865                    description: '<p>the String used to separate the data</p>\n',
6866                    type: 'String'
6867                  }
6868                ],
6869                class: 'p5',
6870                module: 'Data'
6871              },
6872              splitTokens: {
6873                name: 'splitTokens',
6874                params: [
6875                  {
6876                    name: 'value',
6877                    description: '<p>the String to be split</p>\n',
6878                    type: 'String'
6879                  },
6880                  {
6881                    name: 'delim',
6882                    description:
6883                      '<p>list of individual Strings that will be used as\n                         separators</p>\n',
6884                    type: 'String',
6885                    optional: true
6886                  }
6887                ],
6888                class: 'p5',
6889                module: 'Data'
6890              },
6891              trim: {
6892                name: 'trim',
6893                class: 'p5',
6894                module: 'Data',
6895                overloads: [
6896                  {
6897                    params: [
6898                      {
6899                        name: 'str',
6900                        description: '<p>a String to be trimmed</p>\n',
6901                        type: 'String'
6902                      }
6903                    ]
6904                  },
6905                  {
6906                    params: [
6907                      {
6908                        name: 'strs',
6909                        description: '<p>an Array of Strings to be trimmed</p>\n',
6910                        type: 'Array'
6911                      }
6912                    ]
6913                  }
6914                ]
6915              },
6916              day: {
6917                name: 'day',
6918                class: 'p5',
6919                module: 'IO'
6920              },
6921              hour: {
6922                name: 'hour',
6923                class: 'p5',
6924                module: 'IO'
6925              },
6926              minute: {
6927                name: 'minute',
6928                class: 'p5',
6929                module: 'IO'
6930              },
6931              millis: {
6932                name: 'millis',
6933                class: 'p5',
6934                module: 'IO'
6935              },
6936              month: {
6937                name: 'month',
6938                class: 'p5',
6939                module: 'IO'
6940              },
6941              second: {
6942                name: 'second',
6943                class: 'p5',
6944                module: 'IO'
6945              },
6946              year: {
6947                name: 'year',
6948                class: 'p5',
6949                module: 'IO'
6950              },
6951              plane: {
6952                name: 'plane',
6953                params: [
6954                  {
6955                    name: 'width',
6956                    description: '<p>width of the plane</p>\n',
6957                    type: 'Number',
6958                    optional: true
6959                  },
6960                  {
6961                    name: 'height',
6962                    description: '<p>height of the plane</p>\n',
6963                    type: 'Number',
6964                    optional: true
6965                  },
6966                  {
6967                    name: 'detailX',
6968                    description:
6969                      '<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n',
6970                    type: 'Integer',
6971                    optional: true
6972                  },
6973                  {
6974                    name: 'detailY',
6975                    description:
6976                      '<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n',
6977                    type: 'Integer',
6978                    optional: true
6979                  }
6980                ],
6981                class: 'p5',
6982                module: 'Shape'
6983              },
6984              box: {
6985                name: 'box',
6986                params: [
6987                  {
6988                    name: 'width',
6989                    description: '<p>width of the box</p>\n',
6990                    type: 'Number',
6991                    optional: true
6992                  },
6993                  {
6994                    name: 'Height',
6995                    description: '<p>height of the box</p>\n',
6996                    type: 'Number',
6997                    optional: true
6998                  },
6999                  {
7000                    name: 'depth',
7001                    description: '<p>depth of the box</p>\n',
7002                    type: 'Number',
7003                    optional: true
7004                  },
7005                  {
7006                    name: 'detailX',
7007                    description:
7008                      '<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n',
7009                    type: 'Integer',
7010                    optional: true
7011                  },
7012                  {
7013                    name: 'detailY',
7014                    description:
7015                      '<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n',
7016                    type: 'Integer',
7017                    optional: true
7018                  }
7019                ],
7020                class: 'p5',
7021                module: 'Shape'
7022              },
7023              sphere: {
7024                name: 'sphere',
7025                params: [
7026                  {
7027                    name: 'radius',
7028                    description: '<p>radius of circle</p>\n',
7029                    type: 'Number',
7030                    optional: true
7031                  },
7032                  {
7033                    name: 'detailX',
7034                    description: '<p>optional number of subdivisions in x-dimension</p>\n',
7035                    type: 'Integer',
7036                    optional: true
7037                  },
7038                  {
7039                    name: 'detailY',
7040                    description: '<p>optional number of subdivisions in y-dimension</p>\n',
7041                    type: 'Integer',
7042                    optional: true
7043                  }
7044                ],
7045                class: 'p5',
7046                module: 'Shape'
7047              },
7048              cylinder: {
7049                name: 'cylinder',
7050                params: [
7051                  {
7052                    name: 'radius',
7053                    description: '<p>radius of the surface</p>\n',
7054                    type: 'Number',
7055                    optional: true
7056                  },
7057                  {
7058                    name: 'height',
7059                    description: '<p>height of the cylinder</p>\n',
7060                    type: 'Number',
7061                    optional: true
7062                  },
7063                  {
7064                    name: 'detailX',
7065                    description:
7066                      '<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n',
7067                    type: 'Integer',
7068                    optional: true
7069                  },
7070                  {
7071                    name: 'detailY',
7072                    description:
7073                      '<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n',
7074                    type: 'Integer',
7075                    optional: true
7076                  },
7077                  {
7078                    name: 'bottomCap',
7079                    description: '<p>whether to draw the bottom of the cylinder</p>\n',
7080                    type: 'Boolean',
7081                    optional: true
7082                  },
7083                  {
7084                    name: 'topCap',
7085                    description: '<p>whether to draw the top of the cylinder</p>\n',
7086                    type: 'Boolean',
7087                    optional: true
7088                  }
7089                ],
7090                class: 'p5',
7091                module: 'Shape'
7092              },
7093              cone: {
7094                name: 'cone',
7095                params: [
7096                  {
7097                    name: 'radius',
7098                    description: '<p>radius of the bottom surface</p>\n',
7099                    type: 'Number',
7100                    optional: true
7101                  },
7102                  {
7103                    name: 'height',
7104                    description: '<p>height of the cone</p>\n',
7105                    type: 'Number',
7106                    optional: true
7107                  },
7108                  {
7109                    name: 'detailX',
7110                    description:
7111                      '<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n',
7112                    type: 'Integer',
7113                    optional: true
7114                  },
7115                  {
7116                    name: 'detailY',
7117                    description:
7118                      '<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n',
7119                    type: 'Integer',
7120                    optional: true
7121                  },
7122                  {
7123                    name: 'cap',
7124                    description: '<p>whether to draw the base of the cone</p>\n',
7125                    type: 'Boolean',
7126                    optional: true
7127                  }
7128                ],
7129                class: 'p5',
7130                module: 'Shape'
7131              },
7132              ellipsoid: {
7133                name: 'ellipsoid',
7134                params: [
7135                  {
7136                    name: 'radiusx',
7137                    description: '<p>x-radius of ellipsoid</p>\n',
7138                    type: 'Number',
7139                    optional: true
7140                  },
7141                  {
7142                    name: 'radiusy',
7143                    description: '<p>y-radius of ellipsoid</p>\n',
7144                    type: 'Number',
7145                    optional: true
7146                  },
7147                  {
7148                    name: 'radiusz',
7149                    description: '<p>z-radius of ellipsoid</p>\n',
7150                    type: 'Number',
7151                    optional: true
7152                  },
7153                  {
7154                    name: 'detailX',
7155                    description:
7156                      '<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n',
7157                    type: 'Integer',
7158                    optional: true
7159                  },
7160                  {
7161                    name: 'detailY',
7162                    description:
7163                      '<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n',
7164                    type: 'Integer',
7165                    optional: true
7166                  }
7167                ],
7168                class: 'p5',
7169                module: 'Shape'
7170              },
7171              torus: {
7172                name: 'torus',
7173                params: [
7174                  {
7175                    name: 'radius',
7176                    description: '<p>radius of the whole ring</p>\n',
7177                    type: 'Number',
7178                    optional: true
7179                  },
7180                  {
7181                    name: 'tubeRadius',
7182                    description: '<p>radius of the tube</p>\n',
7183                    type: 'Number',
7184                    optional: true
7185                  },
7186                  {
7187                    name: 'detailX',
7188                    description:
7189                      '<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n',
7190                    type: 'Integer',
7191                    optional: true
7192                  },
7193                  {
7194                    name: 'detailY',
7195                    description:
7196                      '<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n',
7197                    type: 'Integer',
7198                    optional: true
7199                  }
7200                ],
7201                class: 'p5',
7202                module: 'Shape'
7203              },
7204              orbitControl: {
7205                name: 'orbitControl',
7206                params: [
7207                  {
7208                    name: 'sensitivityX',
7209                    description: '<p>sensitivity to mouse movement along X axis</p>\n',
7210                    type: 'Number',
7211                    optional: true
7212                  },
7213                  {
7214                    name: 'sensitivityY',
7215                    description: '<p>sensitivity to mouse movement along Y axis</p>\n',
7216                    type: 'Number',
7217                    optional: true
7218                  },
7219                  {
7220                    name: 'sensitivityZ',
7221                    description: '<p>sensitivity to scroll movement along Z axis</p>\n',
7222                    type: 'Number',
7223                    optional: true
7224                  }
7225                ],
7226                class: 'p5',
7227                module: 'Lights, Camera'
7228              },
7229              debugMode: {
7230                name: 'debugMode',
7231                class: 'p5',
7232                module: 'Lights, Camera',
7233                overloads: [
7234                  {
7235                    params: []
7236                  },
7237                  {
7238                    params: [
7239                      {
7240                        name: 'mode',
7241                        description: '<p>either GRID or AXES</p>\n',
7242                        type: 'Constant'
7243                      }
7244                    ]
7245                  },
7246                  {
7247                    params: [
7248                      {
7249                        name: 'mode',
7250                        description: '',
7251                        type: 'Constant'
7252                      },
7253                      {
7254                        name: 'gridSize',
7255                        description: '<p>size of one side of the grid</p>\n',
7256                        type: 'Number',
7257                        optional: true
7258                      },
7259                      {
7260                        name: 'gridDivisions',
7261                        description: '<p>number of divisions in the grid</p>\n',
7262                        type: 'Number',
7263                        optional: true
7264                      },
7265                      {
7266                        name: 'xOff',
7267                        description: '<p>X axis offset from origin (0,0,0)</p>\n',
7268                        type: 'Number',
7269                        optional: true
7270                      },
7271                      {
7272                        name: 'yOff',
7273                        description: '<p>Y axis offset from origin (0,0,0)</p>\n',
7274                        type: 'Number',
7275                        optional: true
7276                      },
7277                      {
7278                        name: 'zOff',
7279                        description: '<p>Z axis offset from origin (0,0,0)</p>\n',
7280                        type: 'Number',
7281                        optional: true
7282                      }
7283                    ]
7284                  },
7285                  {
7286                    params: [
7287                      {
7288                        name: 'mode',
7289                        description: '',
7290                        type: 'Constant'
7291                      },
7292                      {
7293                        name: 'axesSize',
7294                        description: '<p>size of axes icon</p>\n',
7295                        type: 'Number',
7296                        optional: true
7297                      },
7298                      {
7299                        name: 'xOff',
7300                        description: '',
7301                        type: 'Number',
7302                        optional: true
7303                      },
7304                      {
7305                        name: 'yOff',
7306                        description: '',
7307                        type: 'Number',
7308                        optional: true
7309                      },
7310                      {
7311                        name: 'zOff',
7312                        description: '',
7313                        type: 'Number',
7314                        optional: true
7315                      }
7316                    ]
7317                  },
7318                  {
7319                    params: [
7320                      {
7321                        name: 'gridSize',
7322                        description: '',
7323                        type: 'Number',
7324                        optional: true
7325                      },
7326                      {
7327                        name: 'gridDivisions',
7328                        description: '',
7329                        type: 'Number',
7330                        optional: true
7331                      },
7332                      {
7333                        name: 'gridXOff',
7334                        description: '',
7335                        type: 'Number',
7336                        optional: true
7337                      },
7338                      {
7339                        name: 'gridYOff',
7340                        description: '',
7341                        type: 'Number',
7342                        optional: true
7343                      },
7344                      {
7345                        name: 'gridZOff',
7346                        description: '',
7347                        type: 'Number',
7348                        optional: true
7349                      },
7350                      {
7351                        name: 'axesSize',
7352                        description: '',
7353                        type: 'Number',
7354                        optional: true
7355                      },
7356                      {
7357                        name: 'axesXOff',
7358                        description: '',
7359                        type: 'Number',
7360                        optional: true
7361                      },
7362                      {
7363                        name: 'axesYOff',
7364                        description: '',
7365                        type: 'Number',
7366                        optional: true
7367                      },
7368                      {
7369                        name: 'axesZOff',
7370                        description: '',
7371                        type: 'Number',
7372                        optional: true
7373                      }
7374                    ]
7375                  }
7376                ]
7377              },
7378              noDebugMode: {
7379                name: 'noDebugMode',
7380                class: 'p5',
7381                module: 'Lights, Camera'
7382              },
7383              ambientLight: {
7384                name: 'ambientLight',
7385                class: 'p5',
7386                module: 'Lights, Camera',
7387                overloads: [
7388                  {
7389                    params: [
7390                      {
7391                        name: 'v1',
7392                        description:
7393          
7393                '<p>red or hue value relative to\n                                the current color range</p>\n',
7394                        type: 'Number'
7395                      },
7396                      {
7397                        name: 'v2',
7398                        description:
7399                          '<p>green or saturation value\n                                relative to the current color range</p>\n',
7400                        type: 'Number'
7401                      },
7402                      {
7403                        name: 'v3',
7404                        description:
7405                          '<p>blue or brightness value\n                                relative to the current color range</p>\n',
7406                        type: 'Number'
7407                      },
7408                      {
7409                        name: 'alpha',
7410                        description: '<p>the alpha value</p>\n',
7411                        type: 'Number',
7412                        optional: true
7413                      }
7414                    ],
7415                    chainable: 1
7416                  },
7417                  {
7418                    params: [
7419                      {
7420                        name: 'value',
7421                        description: '<p>a color string</p>\n',
7422                        type: 'String'
7423                      }
7424                    ],
7425                    chainable: 1
7426                  },
7427                  {
7428                    params: [
7429                      {
7430                        name: 'gray',
7431                        description: '<p>a gray value</p>\n',
7432                        type: 'Number'
7433                      },
7434                      {
7435                        name: 'alpha',
7436                        description: '',
7437                        type: 'Number',
7438                        optional: true
7439                      }
7440                    ],
7441                    chainable: 1
7442                  },
7443                  {
7444                    params: [
7445                      {
7446                        name: 'values',
7447                        description:
7448                          '<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n',
7449                        type: 'Number[]'
7450                      }
7451                    ],
7452                    chainable: 1
7453                  },
7454                  {
7455                    params: [
7456                      {
7457                        name: 'color',
7458                        description: '<p>the ambient light color</p>\n',
7459                        type: 'p5.Color'
7460                      }
7461                    ],
7462                    chainable: 1
7463                  }
7464                ]
7465              },
7466              specularColor: {
7467                name: 'specularColor',
7468                class: 'p5',
7469                module: 'Lights, Camera',
7470                overloads: [
7471                  {
7472                    params: [
7473                      {
7474                        name: 'v1',
7475                        description:
7476                          '<p>red or hue value relative to\n                                the current color range</p>\n',
7477                        type: 'Number'
7478                      },
7479                      {
7480                        name: 'v2',
7481                        description:
7482                          '<p>green or saturation value\n                                relative to the current color range</p>\n',
7483                        type: 'Number'
7484                      },
7485                      {
7486                        name: 'v3',
7487                        description:
7488                          '<p>blue or brightness value\n                                relative to the current color range</p>\n',
7489                        type: 'Number'
7490                      }
7491                    ],
7492                    chainable: 1
7493                  },
7494                  {
7495                    params: [
7496                      {
7497                        name: 'value',
7498                        description: '<p>a color string</p>\n',
7499                        type: 'String'
7500                      }
7501                    ],
7502                    chainable: 1
7503                  },
7504                  {
7505                    params: [
7506                      {
7507                        name: 'gray',
7508                        description: '<p>a gray value</p>\n',
7509                        type: 'Number'
7510                      }
7511                    ],
7512                    chainable: 1
7513                  },
7514                  {
7515                    params: [
7516                      {
7517                        name: 'values',
7518                        description:
7519                          '<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n',
7520                        type: 'Number[]'
7521                      }
7522                    ],
7523                    chainable: 1
7524                  },
7525                  {
7526                    params: [
7527                      {
7528                        name: 'color',
7529                        description: '<p>the ambient light color</p>\n',
7530                        type: 'p5.Color'
7531                      }
7532                    ],
7533                    chainable: 1
7534                  }
7535                ]
7536              },
7537              directionalLight: {
7538                name: 'directionalLight',
7539                class: 'p5',
7540                module: 'Lights, Camera',
7541                overloads: [
7542                  {
7543                    params: [
7544                      {
7545                        name: 'v1',
7546                        description:
7547                          '<p>red or hue value (depending on the current\ncolor mode),</p>\n',
7548                        type: 'Number'
7549                      },
7550                      {
7551                        name: 'v2',
7552                        description: '<p>green or saturation value</p>\n',
7553                        type: 'Number'
7554                      },
7555                      {
7556                        name: 'v3',
7557                        description: '<p>blue or brightness value</p>\n',
7558                        type: 'Number'
7559                      },
7560                      {
7561                        name: 'position',
7562                        description: '<p>the direction of the light</p>\n',
7563                        type: 'p5.Vector'
7564                      }
7565                    ],
7566                    chainable: 1
7567                  },
7568                  {
7569                    params: [
7570                      {
7571                        name: 'color',
7572                        description:
7573                          '<p>color Array, CSS color string,\n                                            or <a href="#/p5.Color">p5.Color</a> value</p>\n',
7574                        type: 'Number[]|String|p5.Color'
7575                      },
7576                      {
7577                        name: 'x',
7578                        description: '<p>x axis direction</p>\n',
7579                        type: 'Number'
7580                      },
7581                      {
7582                        name: 'y',
7583                        description: '<p>y axis direction</p>\n',
7584                        type: 'Number'
7585                      },
7586                      {
7587                        name: 'z',
7588                        description: '<p>z axis direction</p>\n',
7589                        type: 'Number'
7590                      }
7591                    ],
7592                    chainable: 1
7593                  },
7594                  {
7595                    params: [
7596                      {
7597                        name: 'color',
7598                        description: '',
7599                        type: 'Number[]|String|p5.Color'
7600                      },
7601                      {
7602                        name: 'position',
7603                        description: '',
7604                        type: 'p5.Vector'
7605                      }
7606                    ],
7607                    chainable: 1
7608                  },
7609                  {
7610                    params: [
7611                      {
7612                        name: 'v1',
7613                        description: '',
7614                        type: 'Number'
7615                      },
7616                      {
7617                        name: 'v2',
7618                        description: '',
7619                        type: 'Number'
7620                      },
7621                      {
7622                        name: 'v3',
7623                        description: '',
7624                        type: 'Number'
7625                      },
7626                      {
7627                        name: 'x',
7628                        description: '',
7629                        type: 'Number'
7630                      },
7631                      {
7632                        name: 'y',
7633                        description: '',
7634                        type: 'Number'
7635                      },
7636                      {
7637                        name: 'z',
7638                        description: '',
7639                        type: 'Number'
7640                      }
7641                    ],
7642                    chainable: 1
7643                  }
7644                ]
7645              },
7646              pointLight: {
7647                name: 'pointLight',
7648                class: 'p5',
7649                module: 'Lights, Camera',
7650                overloads: [
7651                  {
7652                    params: [
7653                      {
7654                        name: 'v1',
7655                        description:
7656                          '<p>red or hue value (depending on the current\ncolor mode),</p>\n',
7657                        type: 'Number'
7658                      },
7659                      {
7660                        name: 'v2',
7661                        description: '<p>green or saturation value</p>\n',
7662                        type: 'Number'
7663                      },
7664                      {
7665                        name: 'v3',
7666                        description: '<p>blue or brightness value</p>\n',
7667                        type: 'Number'
7668                      },
7669                      {
7670                        name: 'x',
7671                        description: '<p>x axis position</p>\n',
7672                        type: 'Number'
7673                      },
7674                      {
7675                        name: 'y',
7676                        description: '<p>y axis position</p>\n',
7677                        type: 'Number'
7678                      },
7679                      {
7680                        name: 'z',
7681                        description: '<p>z axis position</p>\n',
7682                        type: 'Number'
7683                      }
7684                    ],
7685                    chainable: 1
7686                  },
7687                  {
7688                    params: [
7689                      {
7690                        name: 'v1',
7691                        description: '',
7692                        type: 'Number'
7693                      },
7694                      {
7695                        name: 'v2',
7696                        description: '',
7697                        type: 'Number'
7698                      },
7699                      {
7700                        name: 'v3',
7701                        description: '',
7702                        type: 'Number'
7703                      },
7704                      {
7705                        name: 'position',
7706                        description: '<p>the position of the light</p>\n',
7707                        type: 'p5.Vector'
7708                      }
7709                    ],
7710                    chainable: 1
7711                  },
7712                  {
7713                    params: [
7714                      {
7715                        name: 'color',
7716                        description:
7717                          '<p>color Array, CSS color string,\nor <a href="#/p5.Color">p5.Color</a> value</p>\n',
7718                        type: 'Number[]|String|p5.Color'
7719                      },
7720                      {
7721                        name: 'x',
7722                        description: '',
7723                        type: 'Number'
7724                      },
7725                      {
7726                        name: 'y',
7727                        description: '',
7728                        type: 'Number'
7729                      },
7730                      {
7731                        name: 'z',
7732                        description: '',
7733                        type: 'Number'
7734                      }
7735                    ],
7736                    chainable: 1
7737                  },
7738                  {
7739                    params: [
7740                      {
7741                        name: 'color',
7742                        description: '',
7743                        type: 'Number[]|String|p5.Color'
7744                      },
7745                      {
7746                        name: 'position',
7747                        description: '',
7748                        type: 'p5.Vector'
7749                      }
7750                    ],
7751                    chainable: 1
7752                  }
7753                ]
7754              },
7755              lights: {
7756                name: 'lights',
7757                class: 'p5',
7758                module: 'Lights, Camera'
7759              },
7760              lightFalloff: {
7761                name: 'lightFalloff',
7762                params: [
7763                  {
7764                    name: 'constant',
7765                    description: '<p>constant value for determining falloff</p>\n',
7766                    type: 'Number'
7767                  },
7768                  {
7769                    name: 'linear',
7770                    description: '<p>linear value for determining falloff</p>\n',
7771                    type: 'Number'
7772                  },
7773                  {
7774                    name: 'quadratic',
7775                    description: '<p>quadratic value for determining falloff</p>\n',
7776                    type: 'Number'
7777                  }
7778                ],
7779                class: 'p5',
7780                module: 'Lights, Camera'
7781              },
7782              spotLight: {
7783                name: 'spotLight',
7784                class: 'p5',
7785                module: 'Lights, Camera',
7786                overloads: [
7787                  {
7788                    params: [
7789                      {
7790                        name: 'v1',
7791                        description:
7792                          '<p>red or hue value (depending on the current\ncolor mode),</p>\n',
7793                        type: 'Number'
7794                      },
7795                      {
7796                        name: 'v2',
7797                        description: '<p>green or saturation value</p>\n',
7798                        type: 'Number'
7799                      },
7800                      {
7801                        name: 'v3',
7802                        description: '<p>blue or brightness value</p>\n',
7803                        type: 'Number'
7804                      },
7805                      {
7806                        name: 'x',
7807                        description: '<p>x axis position</p>\n',
7808                        type: 'Number'
7809                      },
7810                      {
7811                        name: 'y',
7812                        description: '<p>y axis position</p>\n',
7813                        type: 'Number'
7814                      },
7815                      {
7816                        name: 'z',
7817                        description: '<p>z axis position</p>\n',
7818                        type: 'Number'
7819                      },
7820                      {
7821                        name: 'rx',
7822                        description: '<p>x axis direction of light</p>\n',
7823                        type: 'Number'
7824                      },
7825                      {
7826                        name: 'ry',
7827                        description: '<p>y axis direction of light</p>\n',
7828                        type: 'Number'
7829                      },
7830                      {
7831                        name: 'rz',
7832                        description: '<p>z axis direction of light</p>\n',
7833                        type: 'Number'
7834                      },
7835                      {
7836                        name: 'angle',
7837                        description:
7838                          '<p>optional parameter for angle. Defaults to PI/3</p>\n',
7839                        type: 'Number',
7840                        optional: true
7841                      },
7842                      {
7843                        name: 'conc',
7844                        description:
7845                          '<p>optional parameter for concentration. Defaults to 100</p>\n',
7846                        type: 'Nu
7846mber',
7847                        optional: true
7848                      }
7849                    ],
7850                    chainable: 1
7851                  },
7852                  {
7853                    params: [
7854                      {
7855                        name: 'color',
7856                        description:
7857                          '<p>color Array, CSS color string,\nor <a href="#/p5.Color">p5.Color</a> value</p>\n',
7858                        type: 'Number[]|String|p5.Color'
7859                      },
7860                      {
7861                        name: 'position',
7862                        description: '<p>the position of the light</p>\n',
7863                        type: 'p5.Vector'
7864                      },
7865                      {
7866                        name: 'direction',
7867                        description: '<p>the direction of the light</p>\n',
7868                        type: 'p5.Vector'
7869                      },
7870                      {
7871                        name: 'angle',
7872                        description: '',
7873                        type: 'Number',
7874                        optional: true
7875                      },
7876                      {
7877                        name: 'conc',
7878                        description: '',
7879                        type: 'Number',
7880                        optional: true
7881                      }
7882                    ]
7883                  },
7884                  {
7885                    params: [
7886                      {
7887                        name: 'v1',
7888                        description: '',
7889                        type: 'Number'
7890                      },
7891                      {
7892                        name: 'v2',
7893                        description: '',
7894                        type: 'Number'
7895                      },
7896                      {
7897                        name: 'v3',
7898                        description: '',
7899                        type: 'Number'
7900                      },
7901                      {
7902                        name: 'position',
7903                        description: '',
7904                        type: 'p5.Vector'
7905                      },
7906                      {
7907                        name: 'direction',
7908                        description: '',
7909                        type: 'p5.Vector'
7910                      },
7911                      {
7912                        name: 'angle',
7913                        description: '',
7914                        type: 'Number',
7915                        optional: true
7916                      },
7917                      {
7918                        name: 'conc',
7919                        description: '',
7920                        type: 'Number',
7921                        optional: true
7922                      }
7923                    ]
7924                  },
7925                  {
7926                    params: [
7927                      {
7928                        name: 'color',
7929                        description: '',
7930                        type: 'Number[]|String|p5.Color'
7931                      },
7932                      {
7933                        name: 'x',
7934                        description: '',
7935                        type: 'Number'
7936                      },
7937                      {
7938                        name: 'y',
7939                        description: '',
7940                        type: 'Number'
7941                      },
7942                      {
7943                        name: 'z',
7944                        description: '',
7945                        type: 'Number'
7946                      },
7947                      {
7948                        name: 'direction',
7949                        description: '',
7950                        type: 'p5.Vector'
7951                      },
7952                      {
7953                        name: 'angle',
7954                        description: '',
7955                        type: 'Number',
7956                        optional: true
7957                      },
7958                      {
7959                        name: 'conc',
7960                        description: '',
7961                        type: 'Number',
7962                        optional: true
7963                      }
7964                    ]
7965                  },
7966                  {
7967                    params: [
7968                      {
7969                        name: 'color',
7970                        description: '',
7971                        type: 'Number[]|String|p5.Color'
7972                      },
7973                      {
7974                        name: 'position',
7975                        description: '',
7976                        type: 'p5.Vector'
7977                      },
7978                      {
7979                        name: 'rx',
7980                        description: '',
7981                        type: 'Number'
7982                      },
7983                      {
7984                        name: 'ry',
7985                        description: '',
7986                        type: 'Number'
7987                      },
7988                      {
7989                        name: 'rz',
7990                        description: '',
7991                        type: 'Number'
7992                      },
7993                      {
7994                        name: 'angle',
7995                        description: '',
7996                        type: 'Number',
7997                        optional: true
7998                      },
7999                      {
8000                        name: 'conc',
8001                        description: '',
8002                        type: 'Number',
8003                        optional: true
8004                      }
8005                    ]
8006                  },
8007                  {
8008                    params: [
8009                      {
8010                        name: 'v1',
8011                        description: '',
8012                        type: 'Number'
8013                      },
8014                      {
8015                        name: 'v2',
8016                        description: '',
8017                        type: 'Number'
8018                      },
8019                      {
8020                        name: 'v3',
8021                        description: '',
8022                        type: 'Number'
8023                      },
8024                      {
8025                        name: 'x',
8026                        description: '',
8027                        type: 'Number'
8028                      },
8029                      {
8030                        name: 'y',
8031                        description: '',
8032                        type: 'Number'
8033                      },
8034                      {
8035                        name: 'z',
8036                        description: '',
8037                        type: 'Number'
8038                      },
8039                      {
8040                        name: 'direction',
8041                        description: '',
8042                        type: 'p5.Vector'
8043                      },
8044                      {
8045                        name: 'angle',
8046                        description: '',
8047                        type: 'Number',
8048                        optional: true
8049                      },
8050                      {
8051                        name: 'conc',
8052                        description: '',
8053                        type: 'Number',
8054                        optional: true
8055                      }
8056                    ]
8057                  },
8058                  {
8059                    params: [
8060                      {
8061                        name: 'v1',
8062                        description: '',
8063                        type: 'Number'
8064                      },
8065                      {
8066                        name: 'v2',
8067                        description: '',
8068                        type: 'Number'
8069                      },
8070                      {
8071                        name: 'v3',
8072                        description: '',
8073                        type: 'Number'
8074                      },
8075                      {
8076                        name: 'position',
8077                        description: '',
8078                        type: 'p5.Vector'
8079                      },
8080                      {
8081                        name: 'rx',
8082                        description: '',
8083                        type: 'Number'
8084                      },
8085                      {
8086                        name: 'ry',
8087                        description: '',
8088                        type: 'Number'
8089                      },
8090                      {
8091                        name: 'rz',
8092                        description: '',
8093                        type: 'Number'
8094                      },
8095                      {
8096                        name: 'angle',
8097                        description: '',
8098                        type: 'Number',
8099                        optional: true
8100                      },
8101                      {
8102                        name: 'conc',
8103                        description: '',
8104                        type: 'Number',
8105                        optional: true
8106                      }
8107                    ]
8108                  },
8109                  {
8110                    params: [
8111                      {
8112                        name: 'color',
8113                        description: '',
8114                        type: 'Number[]|String|p5.Color'
8115                      },
8116                      {
8117                        name: 'x',
8118                        description: '',
8119                        type: 'Number'
8120                      },
8121                      {
8122                        name: 'y',
8123                        description: '',
8124                        type: 'Number'
8125                      },
8126                      {
8127                        name: 'z',
8128                        description: '',
8129                        type: 'Number'
8130                      },
8131                      {
8132                        name: 'rx',
8133                        description: '',
8134                        type: 'Number'
8135                      },
8136                      {
8137                        name: 'ry',
8138                        description: '',
8139                        type: 'Number'
8140                      },
8141                      {
8142                        name: 'rz',
8143                        description: '',
8144                        type: 'Number'
8145                      },
8146                      {
8147                        name: 'angle',
8148                        description: '',
8149                        type: 'Number',
8150                        optional: true
8151                      },
8152                      {
8153                        name: 'conc',
8154                        description: '',
8155                        type: 'Number',
8156                        optional: true
8157                      }
8158                    ]
8159                  }
8160                ]
8161              },
8162              noLights: {
8163                name: 'noLights',
8164                class: 'p5',
8165                module: 'Lights, Camera'
8166              },
8167              loadModel: {
8168                name: 'loadModel',
8169                class: 'p5',
8170                module: 'Shape',
8171                overloads: [
8172                  {
8173                    params: [
8174                      {
8175                        name: 'path',
8176                        description: '<p>Path of the model to be loaded</p>\n',
8177                        type: 'String'
8178                      },
8179                      {
8180                        name: 'normalize',
8181                        description:
8182                          '<p>If true, scale the model to a\n                                     standardized size when loading</p>\n',
8183                        type: 'Boolean'
8184                      },
8185                      {
8186                        name: 'successCallback',
8187                        description:
8188                          '<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n',
8189                        type: 'function(p5.Geometry)',
8190                        optional: true
8191                      },
8192                      {
8193                        name: 'failureCallback',
8194                        description:
8195                          '<p>called with event error if\n                                        the model fails to load.</p>\n',
8196                        type: 'Function(Event)',
8197                        optional: true
8198                      },
8199                      {
8200                        name: 'fileType',
8201                        description:
8202                          '<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n',
8203                        type: 'String',
8204                        optional: true
8205                      }
8206                    ]
8207                  },
8208                  {
8209                    params: [
8210                      {
8211                        name: 'path',
8212                        description: '',
8213                        type: 'String'
8214                      },
8215                      {
8216                        name: 'successCallback',
8217                        description: '',
8218                        type: 'function(p5.Geometry)',
8219                        optional: true
8220                      },
8221                      {
8222                        name: 'failureCallback',
8223                        description: '',
8224                        type: 'Function(Event)',
8225                        optional: true
8226                      },
8227                      {
8228                        name: 'fileType',
8229                        description: '',
8230                        type: 'String',
8231                        optional: true
8232                      }
8233                    ]
8234                  }
8235                ]
8236              },
8237              model: {
8238                name: 'model',
8239                params: [
8240                  {
8241                    name: 'model',
8242                    description: '<p>Loaded 3d model to be rendered</p>\n',
8243                    type: 'p5.Geometry'
8244                  }
8245                ],
8246                class: 'p5',
8247                module: 'Shape'
8248              },
8249              loadShader: {
8250                name: 'loadShader',
8251                params: [
8252                  {
8253                    name: 'vertFilename',
8254                    description:
8255                      '<p>path to file containing vertex shader\nsource code</p>\n',
8256                    type: 'String'
8257                  },
8258                  {
8259                    name: 'fragFilename',
8260                    description:
8261                      '<p>path to file containing fragment shader\nsource code</p>\n',
8262                    type: 'String'
8263                  },
8264                  {
8265                    name: 'callback',
8266                    description:
8267                      '<p>callback to be executed after loadShader\ncompletes. On success, the Shader object is passed as the first argument.</p>\n',
8268                    type: 'Function',
8269                    optional: true
8270                  },
8271                  {
8272                    name: 'errorCallback',
8273                    description:
8274                      '<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n',
8275                    type: 'Function',
8276                    optional: true
8277                  }
8278                ],
8279                class: 'p5',
8280                module: 'Lights, Camera'
8281              },
8282              createShader: {
8283                name: 'createShader',
8284                params: [
8285                  {
8286                    name: 'vertSrc',
8287                    description: '<p>source code for the vertex shader</p>\n',
8288                    type: 'String'
8289                  },
8290                  {
8291                    name: 'fragSrc',
8292                    description: '<p>source code for the fragment shader</p>\n',
8293                    type: 'String'
8294                  }
8295                ],
8296                class: 'p5',
8297                module: 'Lights, Camera'
8298              },
8299              shader: {
8300                name: 'shader',
8301                params: [
8302                  {
8303                    name: 's',
8304                    description:
8305                      '<p>the desired <a href="#/p5.Shader">p5.Shader</a> to use for rendering\nshapes.</p>\n',
8306                    type: 'p5.Shader',
8307                    optional: true
8308                  }
8309                ],
8310                class: 'p5',
8311                module: 'Lights, Camera'
8312              },
8313              resetShader: {
8314                name: 'resetShader',
8315                class: 'p5',
8316                module: 'Lights, Camera'
8317              },
8318              normalMaterial: {
8319                name: 'normalMaterial',
8320                class: 'p5',
8321                module: 'Lights, Camera'
8322              },
8323              texture: {
8324                name: 'texture',
8325                params: [
8326                  {
8327                    name: 'tex',
8328                    description:
8329                      '<p>2-dimensional graphics\n                   to render as texture</p>\n',
8330                    type: 'p5.Image|p5.MediaElement|p5.Graphics'
8331                  }
8332                ],
8333                class: 'p5',
8334                module: 'Lights, Camera'
8335              },
8336              textureMode: {
8337                name: 'textureMode',
8338                params: [
8339                  {
8340                    name: 'mode',
8341                    description: '<p>either IMAGE or NORMAL</p>\n',
8342                    type: 'Constant'
8343                  }
8344                ],
8345                class: 'p5',
8346                module: 'Lights, Camera'
8347              },
8348              textureWrap: {
8349                name: 'textureWrap',
8350                params: [
8351                  {
8352                    name: 'wrapX',
8353                    description: '<p>either CLAMP, REPEAT, or MIRROR</p>\n',
8354                    type: 'Constant'
8355                  },
8356                  {
8357                    name: 'wrapY',
8358                    description: '<p>either CLAMP, REPEAT, or MIRROR</p>\n',
8359                    type: 'Constant',
8360                    optional: true
8361                  }
8362                ],
8363                class: 'p5',
8364                module: 'Lights, Camera'
8365              },
8366              ambientMaterial: {
8367                name: 'ambientMaterial',
8368                class: 'p5',
8369                module: 'Lights, Camera',
8370                overloads: [
8371                  {
8372                    params: [
8373                      {
8374                        name: 'v1',
8375                        description:
8376                          '<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n',
8377                        type: 'Number'
8378                      },
8379                      {
8380                        name: 'v2',
8381                        description: '<p>green or saturation value</p>\n',
8382                        type: 'Number',
8383                        optional: true
8384                      },
8385                      {
8386                        name: 'v3',
8387                        description: '<p>blue or brightness value</p>\n',
8388                        type: 'Number',
8389                        optional: true
8390                      }
8391                    ],
8392                    chainable: 1
8393                  },
8394                  {
8395                    params: [
8396                      {
8397                        name: 'color',
8398                        description: '<p>color, color Array, or CSS color string</p>\n',
8399                        type: 'Number[]|String|p5.Color'
8400                      }
8401                    ],
8402                    chainable: 1
8403                  }
8404                ]
8405              },
8406              emissiveMaterial: {
8407                name: 'emissiveMaterial',
8408                class: 'p5',
8409                module: 'Lights, Camera',
8410                overloads: [
8411                  {
8412                    params: [
8413                      {
8414                        name: 'v1',
8415                        description:
8416                          '<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n',
8417                        type: 'Number'
8418                      },
8419                      {
8420                        name: 'v2',
8421                        description: '<p>green or saturation value</p>\n',
8422                        type: 'Number',
8423                        optional: true
8424                      },
8425                      {
8426                        name: 'v3',
8427                        description: '<p>blue or brightness value</p>\n',
8428                        type: 'Number',
8429                        optional: true
8430                      },
8431                      {
8432                        name: 'a',
8433                        description: '<p>opacity</p>\n',
8434                        type: 'Number',
8435                        optional: true
8436                      }
8437                    ],
8438                    chainable: 1
8439                  },
8440                  {
8441                    params: [
8442                      {
8443                        name: 'color',
8444                        description: '<p>color, color Array, or CSS color string</p>\n',
8445                        type: 'Number[]|String|p5.Color'
8446                      }
8447                    ],
8448                    chainable: 1
8449                  }
8450                ]
8451              },
8452              specularMaterial: {
8453                name: 'specularMaterial',
8454                class: 'p5',
8455                module: 'Lights, Camera',
8456                overloads: [
8457                  {
8458                    params: [
8459                      {
8460                        name: 'gray',
8461                        description:
8462                          '<p>number specifying value between white and black.</p>\n',
8463                        type: 'Number'
8464                      },
8465                      {
8466                        name: 'alpha',
8467                        description:
8468                          '<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n',
8469                        type: 'Number',
8470                        optional: true
8471                      }
8472                    ],
8473                    chainable: 1
8474                  },
8475                  {
8476                    params: [
8477                      {
8478                        name: 'v1',
8479                        description:
8480                          '<p>red or hue value relative to\n                                the current color range</p>\n',
8481                        type: 'Number'
8482                      },
8483                      {
8484                        name: 'v2',
8485                        description:
8486                          '<p>
8486green or saturation value\n                                relative to the current color range</p>\n',
8487                        type: 'Number'
8488                      },
8489                      {
8490                        name: 'v3',
8491                        description:
8492                          '<p>blue or brightness value\n                                relative to the current color range</p>\n',
8493                        type: 'Number'
8494                      },
8495                      {
8496                        name: 'alpha',
8497                        description: '',
8498                        type: 'Number',
8499                        optional: true
8500                      }
8501                    ],
8502                    chainable: 1
8503                  },
8504                  {
8505                    params: [
8506                      {
8507                        name: 'color',
8508                        description: '<p>color Array, or CSS color string</p>\n',
8509                        type: 'Number[]|String|p5.Color'
8510                      }
8511                    ],
8512                    chainable: 1
8513                  }
8514                ]
8515              },
8516              shininess: {
8517                name: 'shininess',
8518                params: [
8519                  {
8520                    name: 'shine',
8521                    description:
8522                      '<p>Degree of Shininess.\n                      Defaults to 1.</p>\n',
8523                    type: 'Number'
8524                  }
8525                ],
8526                class: 'p5',
8527                module: 'Lights, Camera'
8528              },
8529              camera: {
8530                name: 'camera',
8531                params: [
8532                  {
8533                    name: 'x',
8534                    description: '<p>camera position value on x axis</p>\n',
8535                    type: 'Number',
8536                    optional: true
8537                  },
8538                  {
8539                    name: 'y',
8540                    description: '<p>camera position value on y axis</p>\n',
8541                    type: 'Number',
8542                    optional: true
8543                  },
8544                  {
8545                    name: 'z',
8546                    description: '<p>camera position value on z axis</p>\n',
8547                    type: 'Number',
8548                    optional: true
8549                  },
8550                  {
8551                    name: 'centerX',
8552                    description: '<p>x coordinate representing center of the sketch</p>\n',
8553                    type: 'Number',
8554                    optional: true
8555                  },
8556                  {
8557                    name: 'centerY',
8558                    description: '<p>y coordinate representing center of the sketch</p>\n',
8559                    type: 'Number',
8560                    optional: true
8561                  },
8562                  {
8563                    name: 'centerZ',
8564                    description: '<p>z coordinate representing center of the sketch</p>\n',
8565                    type: 'Number',
8566                    optional: true
8567                  },
8568                  {
8569                    name: 'upX',
8570                    description: "<p>x component of direction 'up' from camera</p>\n",
8571                    type: 'Number',
8572                    optional: true
8573                  },
8574                  {
8575                    name: 'upY',
8576                    description: "<p>y component of direction 'up' from camera</p>\n",
8577                    type: 'Number',
8578                    optional: true
8579                  },
8580                  {
8581                    name: 'upZ',
8582                    description: "<p>z component of direction 'up' from camera</p>\n",
8583                    type: 'Number',
8584                    optional: true
8585                  }
8586                ],
8587                class: 'p5',
8588                module: 'Lights, Camera'
8589              },
8590              perspective: {
8591                name: 'perspective',
8592                params: [
8593                  {
8594                    name: 'fovy',
8595                    description:
8596                      '<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href="#/p5/angleMode">angleMode</a> units</p>\n',
8597                    type: 'Number',
8598                    optional: true
8599                  },
8600                  {
8601                    name: 'aspect',
8602                    description: '<p>camera frustum aspect ratio</p>\n',
8603                    type: 'Number',
8604                    optional: true
8605                  },
8606                  {
8607                    name: 'near',
8608                    description: '<p>frustum near plane length</p>\n',
8609                    type: 'Number',
8610                    optional: true
8611                  },
8612                  {
8613                    name: 'far',
8614                    description: '<p>frustum far plane length</p>\n',
8615                    type: 'Number',
8616                    optional: true
8617                  }
8618                ],
8619                class: 'p5',
8620                module: 'Lights, Camera'
8621              },
8622              ortho: {
8623                name: 'ortho',
8624                params: [
8625                  {
8626                    name: 'left',
8627                    description: '<p>camera frustum left plane</p>\n',
8628                    type: 'Number',
8629                    optional: true
8630                  },
8631                  {
8632                    name: 'right',
8633                    description: '<p>camera frustum right plane</p>\n',
8634                    type: 'Number',
8635                    optional: true
8636                  },
8637                  {
8638                    name: 'bottom',
8639                    description: '<p>camera frustum bottom plane</p>\n',
8640                    type: 'Number',
8641                    optional: true
8642                  },
8643                  {
8644                    name: 'top',
8645                    description: '<p>camera frustum top plane</p>\n',
8646                    type: 'Number',
8647                    optional: true
8648                  },
8649                  {
8650                    name: 'near',
8651                    description: '<p>camera frustum near plane</p>\n',
8652                    type: 'Number',
8653                    optional: true
8654                  },
8655                  {
8656                    name: 'far',
8657                    description: '<p>camera frustum far plane</p>\n',
8658                    type: 'Number',
8659                    optional: true
8660                  }
8661                ],
8662                class: 'p5',
8663                module: 'Lights, Camera'
8664              },
8665              frustum: {
8666                name: 'frustum',
8667                params: [
8668                  {
8669                    name: 'left',
8670                    description: '<p>camera frustum left plane</p>\n',
8671                    type: 'Number',
8672                    optional: true
8673                  },
8674                  {
8675                    name: 'right',
8676                    description: '<p>camera frustum right plane</p>\n',
8677                    type: 'Number',
8678                    optional: true
8679                  },
8680                  {
8681                    name: 'bottom',
8682                    description: '<p>camera frustum bottom plane</p>\n',
8683                    type: 'Number',
8684                    optional: true
8685                  },
8686                  {
8687                    name: 'top',
8688                    description: '<p>camera frustum top plane</p>\n',
8689                    type: 'Number',
8690                    optional: true
8691                  },
8692                  {
8693                    name: 'near',
8694                    description: '<p>camera frustum near plane</p>\n',
8695                    type: 'Number',
8696                    optional: true
8697                  },
8698                  {
8699                    name: 'far',
8700                    description: '<p>camera frustum far plane</p>\n',
8701                    type: 'Number',
8702                    optional: true
8703                  }
8704                ],
8705                class: 'p5',
8706                module: 'Lights, Camera'
8707              },
8708              createCamera: {
8709                name: 'createCamera',
8710                class: 'p5',
8711                module: 'Lights, Camera'
8712              },
8713              setCamera: {
8714                name: 'setCamera',
8715                params: [
8716                  {
8717                    name: 'cam',
8718                    description: '<p>p5.Camera object</p>\n',
8719                    type: 'p5.Camera'
8720                  }
8721                ],
8722                class: 'p5',
8723                module: 'Lights, Camera'
8724              },
8725              setAttributes: {
8726                name: 'setAttributes',
8727                class: 'p5',
8728                module: 'Rendering',
8729                overloads: [
8730                  {
8731                    params: [
8732                      {
8733                        name: 'key',
8734                        description: '<p>Name of attribute</p>\n',
8735                        type: 'String'
8736                      },
8737                      {
8738                        name: 'value',
8739                        description: '<p>New value of named attribute</p>\n',
8740                        type: 'Boolean'
8741                      }
8742                    ]
8743                  },
8744                  {
8745                    params: [
8746                      {
8747                        name: 'obj',
8748                        description: '<p>object with key-value pairs</p>\n',
8749                        type: 'Object'
8750                      }
8751                    ]
8752                  }
8753                ]
8754              },
8755              sampleRate: {
8756                name: 'sampleRate',
8757                class: 'p5',
8758                module: 'p5.sound'
8759              },
8760              freqToMidi: {
8761                name: 'freqToMidi',
8762                params: [
8763                  {
8764                    name: 'frequency',
8765                    description:
8766                      '<p>A freqeuncy, for example, the "A"\n                           above Middle C is 440Hz</p>\n',
8767                    type: 'Number'
8768                  }
8769                ],
8770                class: 'p5',
8771                module: 'p5.sound'
8772              },
8773              midiToFreq: {
8774                name: 'midiToFreq',
8775                params: [
8776                  {
8777                    name: 'midiNote',
8778                    description: '<p>
8778The number of a MIDI note</p>\n',
8779                    type: 'Number'
8780                  }
8781                ],
8782                class: 'p5',
8783                module: 'p5.sound'
8784              },
8785              soundFormats: {
8786                name: 'soundFormats',
8787                params: [
8788                  {
8789                    name: 'formats',
8790                    description: "<p>i.e. 'mp3', 'wav', 'ogg'</p>\n",
8791                    type: 'String',
8792                    optional: true,
8793                    multiple: true
8794                  }
8795                ],
8796                class: 'p5',
8797                module: 'p5.sound'
8798              },
8799              getAudioContext: {
8800                name: 'getAudioContext',
8801                class: 'p5',
8802                module: 'p5.sound'
8803              },
8804              userStartAudio: {
8805                params: [
8806                  {
8807                    name: 'element(s)',
8808                    description:
8809                      '<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n',
8810                    type: 'Element|Array',
8811                    optional: true
8812                  },
8813                  {
8814                    name: 'callback',
8815                    description:
8816                      '<p>Callback to invoke when the AudioContext\n                              has started</p>\n',
8817                    type: 'Function',
8818                    optional: true
8819                  }
8820                ],
8821                name: 'userStartAudio',
8822                class: 'p5',
8823                module: 'p5.sound'
8824              },
8825              loadSound: {
8826                name: 'loadSound',
8827                params: [
8828                  {
8829                    name: 'path',
8830                    description:
8831                      "<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n",
8832                    type: 'String|Array'
8833                  },
8834                  {
8835                    name: 'successCallback',
8836                    description: '<p>Name of a function to call once file loads</p>\n',
8837                    type: 'Function',
8838                    optional: true
8839                  },
8840                  {
8841                    name: 'errorCallback',
8842                    description:
8843                      '<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n',
8844                    type: 'Function',
8845                    optional: true
8846                  },
8847                  {
8848                    name: 'whileLoading',
8849                    description:
8850                      '<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n',
8851                    type: 'Function',
8852                    optional: true
8853                  }
8854                ],
8855                class: 'p5',
8856                module: 'p5.sound'
8857              },
8858              createConvolver: {
8859                name: 'createConvolver',
8860                params: [
8861                  {
8862                    name: 'path',
8863                    description: '<p>path to a sound file</p>\n',
8864                    type: 'String'
8865                  },
8866                  {
8867                    name: 'callback',
8868                    description:
8869                      '<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n',
8870                    type: 'Function',
8871                    optional: true
8872                  },
8873                  {
8874                    name: 'errorCallback',
8875                    description:
8876                      '<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n',
8877                    type: 'Function',
8878                    optional: true
8879                  }
8880                ],
8881                class: 'p5',
8882                module: 'p5.sound'
8883              },
8884              setBPM: {
8885                name: 'setBPM',
8886                params: [
8887                  {
8888                    name: 'BPM',
8889                    description: '<p>Beats Per Minute</p>\n',
8890                    type: 'Number'
8891                  },
8892                  {
8893                    name: 'rampTime',
8894                    description: '<p>Seconds from now</p>\n',
8895                    type: 'Number'
8896                  }
8897                ],
8898                class: 'p5',
8899                module: 'p5.sound'
8900              },
8901              saveSound: {
8902                name: 'saveSound',
8903                params: [
8904                  {
8905                    name: 'soundFile',
8906                    description: '<p>
8906p5.SoundFile that you wish to save</p>\n',
8907                    type: 'p5.SoundFile'
8908                  },
8909                  {
8910                    name: 'fileName',
8911                    description: '<p>name of the resulting .wav file.</p>\n',
8912                    type: 'String'
8913                  }
8914                ],
8915                class: 'p5',
8916                module: 'p5.sound'
8917              }
8918            },
8919            'p5.Color': {
8920              toString: {
8921                name: 'toString',
8922                params: [
8923                  {
8924                    name: 'format',
8925                    description:
8926                      "<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n",
8927                    type: 'String',
8928                    optional: true
8929                  }
8930                ],
8931                class: 'p5.Color',
8932                module: 'Color'
8933              },
8934              setRed: {
8935                name: 'setRed',
8936                params: [
8937                  {
8938                    name: 'red',
8939                    description: '<p>the new red value</p>\n',
8940                    type: 'Number'
8941                  }
8942                ],
8943                class: 'p5.Color',
8944                module: 'Color'
8945              },
8946              setGreen: {
8947                name: 'setGreen',
8948                params: [
8949                  {
8950                    name: 'green',
8951                    description: '<p>the new green value</p>\n',
8952                    type: 'Number'
8953                  }
8954                ],
8955                class: 'p5.Color',
8956                module: 'Color'
8957              },
8958              setBlue: {
8959                name: 'setBlue',
8960                params: [
8961                  {
8962                    name: 'blue',
8963                    description: '<p>the new blue value</p>\n',
8964                    type: 'Number'
8965                  }
8966                ],
8967                class: 'p5.Color',
8968                module: 'Color'
8969              },
8970              setAlpha: {
8971                name: 'setAlpha',
8972                params: [
8973                  {
8974                    name: 'alpha',
8975                    description: '<p>the new alpha value</p>\n',
8976                    type: 'Number'
8977                  }
8978                ],
8979                class: 'p5.Color',
8980                module: 'Color'
8981              }
8982            },
8983            'p5.Element': {
8984              elt: {
8985                name: 'elt',
8986                class: 'p5.Element',
8987                module: 'DOM'
8988              },
8989              parent: {
8990                name: 'parent',
8991                class: 'p5.Element',
8992                module: 'DOM',
8993                overloads: [
8994                  {
8995                    params: [
8996                      {
8997                        name: 'parent',
8998                        description:
8999                          '<p>the ID, DOM node, or <a href="#/p5.Element">p5.Element</a>\n                         of desired parent element</p>\n',
9000                        type: 'String|p5.Element|Object'
9001                      }
9002                    ],
9003                    chainable: 1
9004                  },
9005                  {
9006                    params: []
9007                  }
9008                ]
9009              },
9010              id: {
9011                name: 'id',
9012                class: 'p5.Element',
9013                module: 'DOM',
9014                overloads: [
9015                  {
9016                    params: [
9017                      {
9018                        name: 'id',
9019                        description: '<p>ID of the element</p>\n',
9020                        type: 'String'
9021                      }
9022                    ],
9023                    chainable: 1
9024                  },
9025                  {
9026                    params: []
9027                  }
9028                ]
9029              },
9030              class: {
9031                name: 'class',
9032                class: 'p5.Element',
9033                module: 'DOM',
9034                overloads: [
9035                  {
9036                    params: [
9037                      {
9038                        name: 'class',
9039                        description: '<p>class to add</p>\n',
9040                        type: 'String'
9041                      }
9042                    ],
9043                    chainable: 1
9044                  },
9045                  {
9046                    params: []
9047                  }
9048                ]
9049              },
9050              mousePressed: {
9051                name: 'mousePressed',
9052                params: [
9053                  {
9054                    name: 'fxn',
9055                    description:
9056                      '<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9057                    type: 'Function|Boolean'
9058                  }
9059                ],
9060                class: 'p5.Element',
9061                module: 'DOM'
9062              },
9063              doubleClicked: {
9064                name: 'doubleClicked',
9065                params: [
9066                  {
9067                    name: 'fxn',
9068                    description:
9069                      '<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9070                    type: 'Function|Boolean'
9071                  }
9072                ],
9073                class: 'p5.Element',
9074                module: 'DOM'
9075              },
9076              mouseWheel: {
9077                name: 'mouseWheel',
9078                params: [
9079                  {
9080                    name: 'fxn',
9081                    description:
9082                      '<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9083                    type: 'Function|Boolean'
9084                  }
9085                ],
9086                class: 'p5.Element',
9087                module: 'DOM'
9088              },
9089              mouseReleased: {
9090                name: 'mouseReleased',
9091                params: [
9092                  {
9093                    name: 'fxn',
9094                    description:
9095                      '<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9096                    type: 'Function|Boolean'
9097                  }
9098                ],
9099                class: 'p5.Element',
9100                module: 'DOM'
9101              },
9102              mouseClicked: {
9103                name: 'mouseClicked',
9104                params: [
9105                  {
9106                    name: 'fxn',
9107                    description:
9108                      '<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9109                    type: 'Function|Boolean'
9110                  }
9111                ],
9112                class: 'p5.Element',
9113                module: 'DOM'
9114              },
9115              mouseMoved: {
9116                name: 'mouseMoved',
9117                params: [
9118                  {
9119                    name: 'fxn',
9120                    description:
9121                      '<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9122                    type: 'Function|Boolean'
9123                  }
9124                ],
9125                class: 'p5.Element',
9126                module: 'DOM'
9127              },
9128              mouseOver: {
9129                name: 'mouseOver',
9130                params: [
9131                  {
9132                    name: 'fxn',
9133                    description:
9134                      '<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9135                    type: 'Function|Boolean'
9136                  }
9137                ],
9138                class: 'p5.Element',
9139                module: 'DOM'
9140              },
9141              mouseOut: {
9142                name: 'mouseOut',
9143                params: [
9144                  {
9145                    name: 'fxn',
9146                    description:
9147                      '<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9148                    type: 'Function|Boolean'
9149                  }
9150                ],
9151                class: 'p5.Element',
9152                module: 'DOM'
9153              },
9154              touchStarted: {
9155                name: 'touchStarted',
9156                params: [
9157                  {
9158                    name: 'fxn',
9159                    description:
9160                      '<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9161                    type: 'Function|Boolean'
9162                  }
9163                ],
9164                class: 'p5.Element',
9165                module: 'DOM'
9166              },
9167              touchMoved: {
9168                name: 'touchMoved',
9169                params: [
9170                  {
9171                    name: 'fxn',
9172                    description:
9173                      '<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9174                    type: 'Function|Boolean'
9175                  }
9176                ],
9177                class: 'p5.Element',
9178                module: 'DOM'
9179              },
9180              touchEnded: {
9181                name: 'touchEnded',
9182                params: [
9183                  {
9184                    name: 'fxn',
9185                    description:
9186                      '<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9187                    type: 'Function|Boolean'
9188                  }
9189                ],
9190                class: 'p5.Element',
9191                module: 'DOM'
9192              },
9193              dragOver: {
9194                name: 'dragOver',
9195                params: [
9196                  {
9197                    name: 'fxn',
9198                    description:
9199                      '<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9200                    type: 'Function|Boolean'
9201                  }
9202                ],
9203                class: 'p5.Element',
9204                module: 'DOM'
9205              },
9206              dragLeave: {
9207                name: 'dragLeave',
9208                params: [
9209                  {
9210                    name: 'fxn',
9211                    description:
9212                      '<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n',
9213                    type: 'Function|Boolean'
9214                  }
9215                ],
9216                class: 'p5.Element',
9217                module: 'DOM'
9218              },
9219              addClass: {
9220                name: 'addClass',
9221                params: [
9222                  {
9223                    name: 'class',
9224                    description: '<p>name of class to add</p>\n',
9225                    type: 'String'
9226                  }
9227                ],
9228                class: 'p5.Element',
9229                module: 'DOM'
9230              },
9231              removeClass: {
9232                name: 'removeClass',
9233                params: [
9234                  {
9235                    name: 'class',
9236                    description: '<p>name of class to remove</p>\n',
9237                    type: 'String'
9238                  }
9239                ],
9240                class: 'p5.Element',
9241                module: 'DOM'
9242              },
9243              hasClass: {
9244                name: 'hasClass',
9245                params: [
9246                  {
9247                    name: 'c',
9248                    description: '<p>class name of class to check</p>\n',
9249                    type: 'String'
9250                  }
9251                ],
9252                class: 'p5.Element',
9253                module: 'DOM'
9254              },
9255              toggleClass: {
9256                name: 'toggleClass',
9257                params: [
9258                  {
9259                    name: 'c',
9260                    description: '<p>class name to toggle</p>\n',
9261                    type: 'String'
9262                  }
9263                ],
9264                class: 'p5.Element',
9265                module: 'DOM'
9266              },
9267              child: {
9268                name: 'child',
9269                class: 'p5.Element',
9270                module: 'DOM',
9271                overloads: [
9272                  {
9273                    params: []
9274                  },
9275                  {
9276                    params: [
9277                      {
9278                        name: 'child',
9279                        description:
9280                          '<p>the ID, DOM node, or <a href="#/p5.Element">p5.Element</a>\n                        to add to the current element</p>\n',
9281                        type: 'String|p5.Element',
9282                        optional: true
9283                      }
9284                    ],
9285                    chainable: 1
9286                  }
9287                ]
9288              },
9289              center: {
9290                name: 'center',
9291                params: [
9292                  {
9293                    name: 'align',
9294                    description:
9295                      "<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n",
9296                    type: 'String',
9297                    optional: true
9298                  }
9299                ],
9300                class: 'p5.Element',
9301                module: 'DOM'
9302              },
9303              html: {
9304                name: 'html',
9305                class: 'p5.Element',
9306                module: 'DOM',
9307                overloads: [
9308                  {
9309                    params: []
9310                  },
9311                  {
9312                    params: [
9313                      {
9314                        name: 'html',
9315                        description: '<p>the HTML to be placed inside the element</p>\n',
9316                        type: 'String',
9317                        optional: true
9318                      },
9319                      {
9320                        name: 'append',
9321                        description: '<p>whether to append HTML to existing</p>\n',
9322                        type: 'Boolean',
9323                        optional: true
9324                      }
9325                    ],
9326            
9326        chainable: 1
9327                  }
9328                ]
9329              },
9330              position: {
9331                name: 'position',
9332                class: 'p5.Element',
9333                module: 'DOM',
9334                overloads: [
9335                  {
9336                    params: []
9337                  },
9338                  {
9339                    params: [
9340                      {
9341                        name: 'x',
9342                        description:
9343                          '<p>x-position relative to upper left of window (optional)</p>\n',
9344                        type: 'Number',
9345                        optional: true
9346                      },
9347                      {
9348                        name: 'y',
9349                        description:
9350                          '<p>y-position relative to upper left of window (optional)</p>\n',
9351                        type: 'Number',
9352                        optional: true
9353                      },
9354                      {
9355                        name: 'positionType',
9356                        description:
9357                          '<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n',
9358                        type: 'String'
9359                      }
9360                    ],
9361                    chainable: 1
9362                  }
9363                ]
9364              },
9365              style: {
9366                name: 'style',
9367                class: 'p5.Element',
9368                module: 'DOM',
9369                overloads: [
9370                  {
9371                    params: [
9372                      {
9373                        name: 'property',
9374                        description: '<p>property to be set</p>\n',
9375                        type: 'String'
9376                      }
9377                    ]
9378                  },
9379                  {
9380                    params: [
9381                      {
9382                        name: 'property',
9383                        description: '',
9384                        type: 'String'
9385                      },
9386                      {
9387                        name: 'value',
9388                        description: '<p>value to assign to property</p>\n',
9389                        type: 'String|p5.Color'
9390                      }
9391                    ],
9392                    chainable: 1
9393                  }
9394                ]
9395              },
9396              attribute: {
9397                name: 'attribute',
9398                class: 'p5.Element',
9399                module: 'DOM',
9400                overloads: [
9401                  {
9402                    params: []
9403                  },
9404                  {
9405                    params: [
9406                      {
9407                        name: 'attr',
9408                        description: '<p>attribute to set</p>\n',
9409                        type: 'String'
9410                      },
9411                      {
9412                        name: 'value',
9413                        description: '<p>value to assign to attribute</p>\n',
9414                        type: 'String'
9415                      }
9416                    ],
9417                    chainable: 1
9418                  }
9419                ]
9420              },
9421              removeAttribute: {
9422                name: 'removeAttribute',
9423                params: [
9424                  {
9425                    name: 'attr',
9426                    description: '<p>attribute to remove</p>\n',
9427                    type: 'String'
9428                  }
9429                ],
9430                class: 'p5.Element',
9431                module: 'DOM'
9432              },
9433              value: {
9434                name: 'value',
9435                class: 'p5.Element',
9436                module: 'DOM',
9437                overloads: [
9438                  {
9439                    params: []
9440                  },
9441                  {
9442                    params: [
9443                      {
9444                        name: 'value',
9445                        description: '',
9446                        type: 'String|Number'
9447                      }
9448                    ],
9449                    chainable: 1
9450                  }
9451                ]
9452              },
9453              show: {
9454                name: 'show',
9455                class: 'p5.Element',
9456                module: 'DOM'
9457              },
9458              hide: {
9459                name: 'hide',
9460                class: 'p5.Element',
9461                module: 'DOM'
9462              },
9463              size: {
9464                name: 'size',
9465                class: 'p5.Element',
9466                module: 'DOM',
9467                overloads: [
9468                  {
9469                    params: []
9470                  },
9471                  {
9472                    params: [
9473                      {
9474                        name: 'w',
9475                        description:
9476                          '<p>width of the element, either AUTO, or a number</p>\n',
9477                        type: 'Number|Constant'
9478                      },
9479                      {
9480                        name: 'h',
9481                        description:
9482                          '<p>height of the element, either AUTO, or a number</p>\n',
9483                        type: 'Number|Constant',
9484                        optional: true
9485                      }
9486                    ],
9487                    chainable: 1
9488                  }
9489                ]
9490              },
9491              remove: {
9492                name: 'remove',
9493                class: 'p5.Element',
9494                module: 'DOM'
9495              },
9496              drop: {
9497                name: 'drop',
9498                params: [
9499                  {
9500                    name: 'callback',
9501                    description:
9502                      '<p>callback to receive loaded file, called for each file dropped.</p>\n',
9503                    type: 'Function'
9504                  },
9505                  {
9506                    name: 'fxn',
9507                    description:
9508                      '<p>callback triggered once when files are dropped with the drop event.</p>\n',
9509                    type: 'Function',
9510                    optional: true
9511                  }
9512                ],
9513                class: 'p5.Element',
9514                module: 'DOM'
9515              }
9516            },
9517            'p5.Graphics': {
9518              reset: {
9519                name: 'reset',
9520                class: 'p5.Graphics',
9521                module: 'Rendering'
9522              },
9523              remove: {
9524                name: 'remove',
9525                class: 'p5.Graphics',
9526                module: 'Rendering'
9527              }
9528            },
9529            JSON: {
9530              stringify: {
9531                name: 'stringify',
9532                params: [
9533                  {
9534                    name: 'object',
9535                    description:
9536                      '<p>:Javascript object that you would like to convert to JSON</p>\n',
9537                    type: 'Object'
9538                  }
9539                ],
9540                class: 'JSON',
9541                module: 'Foundation'
9542              }
9543            },
9544            console: {
9545              log: {
9546                name: 'log',
9547                params: [
9548                  {
9549                    name: 'message',
9550                    description:
9551                      '<p>:Message that you would like to print to the console</p>\n',
9552                    type: 'String|Expression|Object'
9553                  }
9554                ],
9555                class: 'console',
9556                module: 'Foundation'
9557              }
9558            },
9559            'p5.TypedDict': {
9560              size: {
9561                name: 'size',
9562                class: 'p5.TypedDict',
9563                module: 'Data'
9564              },
9565              hasKey: {
9566                name: 'hasKey',
9567                params: [
9568                  {
9569                    name: 'key',
9570                    description: '<p>that you want to look up</p>\n',
9571                    type: 'Number|String'
9572                  }
9573                ],
9574                class: 'p5.TypedDict',
9575                module: 'Data'
9576              },
9577              get: {
9578                name: 'get',
9579                params: [
9580                  {
9581                    name: 'the',
9582                    description: '<p>key you want to access</p>\n',
9583                    type: 'Number|String'
9584                  }
9585                ],
9586                class: 'p5.TypedDict',
9587                module: 'Data'
9588              },
9589              set: {
9590                name: 'set',
9591                params: [
9592                  {
9593                    name: 'key',
9594                    description: '',
9595                    type: 'Number|String'
9596                  },
9597                  {
9598                    name: 'value',
9599                    description: '',
9600                    type: 'Number|String'
9601                  }
9602                ],
9603                class: 'p5.TypedDict',
9604                module: 'Data'
9605              },
9606              create: {
9607                name: 'create',
9608                class: 'p5.TypedDict',
9609                module: 'Data',
9610                overloads: [
9611                  {
9612                    params: [
9613                      {
9614                        name: 'key',
9615                        description: '',
9616                        type: 'Number|String'
9617                      },
9618                      {
9619                        name: 'value',
9620                        description: '',
9621                        type: 'Number|String'
9622                      }
9623                    ]
9624                  },
9625                  {
9626                    params: [
9627                      {
9628                        name: 'obj',
9629                        description: '<p>key/value pair</p>\n',
9630                        type: 'Object'
9631                      }
9632                    ]
9633                  }
9634                ]
9635              },
9636              clear: {
9637                name: 'clear',
9638                class: 'p5.TypedDict',
9639                module: 'Data'
9640              },
9641              remove: {
9642                name: 'remove',
9643                params: [
9644                  {
9645                    name: 'key',
9646                    description: '<p>for the pair to remove</p>\n',
9647                    type: 'Number|String'
9648                  }
9649                ],
9650                class: 'p5.TypedDict',
9651                module: 'Data'
9652              },
9653              print: {
9654                name: 'print',
9655                class: 'p5.TypedDict',
9656                module: 'Data'
9657              },
9658              saveTable: {
9659                name: 'saveTable',
9660                class: 'p5.TypedDict',
9661                module: 'Data'
9662              },
9663              saveJSON: {
9664                name: 'saveJSON',
9665                class: 'p5.TypedDict',
9666                module: 'Data'
9667              }
9668            },
9669            'p5.NumberDict': {
9670              add: {
9671                name: 'add',
9672                params: [
9673                  {
9674                    name: 'Key',
9675                    description: '<p>for the value you wish to add to</p>\n',
9676                    type: 'Number'
9677                  },
9678                  {
9679                    name: 'Number',
9680                    description: '<p>to add to the value</p>\n',
9681                    type: 'Number'
9682                  }
9683                ],
9684                class: 'p5.NumberDict',
9685                module: 'Data'
9686              },
9687              sub: {
9688                name: 'sub',
9689                params: [
9690                  {
9691                    name: 'Key',
9692                    description: '<p>
9692for the value you wish to subtract from</p>\n',
9693                    type: 'Number'
9694                  },
9695                  {
9696                    name: 'Number',
9697                    description: '<p>to subtract from the value</p>\n',
9698                    type: 'Number'
9699                  }
9700                ],
9701                class: 'p5.NumberDict',
9702                module: 'Data'
9703              },
9704              mult: {
9705                name: 'mult',
9706                params: [
9707                  {
9708                    name: 'Key',
9709                    description: '<p>for value you wish to multiply</p>\n',
9710                    type: 'Number'
9711                  },
9712                  {
9713                    name: 'Amount',
9714                    description: '<p>to multiply the value by</p>\n',
9715                    type: 'Number'
9716                  }
9717                ],
9718                class: 'p5.NumberDict',
9719                module: 'Data'
9720              },
9721              div: {
9722                name: 'div',
9723                params: [
9724                  {
9725                    name: 'Key',
9726                    description: '<p>for value you wish to divide</p>\n',
9727                    type: 'Number'
9728                  },
9729                  {
9730                    name: 'Amount',
9731                    description: '<p>to divide the value by</p>\n',
9732                    type: 'Number'
9733                  }
9734                ],
9735                class: 'p5.NumberDict',
9736                module: 'Data'
9737              },
9738              minValue: {
9739                name: 'minValue',
9740                class: 'p5.NumberDict',
9741                module: 'Data'
9742              },
9743              maxValue: {
9744                name: 'maxValue',
9745                class: 'p5.NumberDict',
9746                module: 'Data'
9747              },
9748              minKey: {
9749                name: 'minKey',
9750                class: 'p5.NumberDict',
9751                module: 'Data'
9752              },
9753              maxKey: {
9754                name: 'maxKey',
9755                class: 'p5.NumberDict',
9756                module: 'Data'
9757              }
9758            },
9759            'p5.MediaElement': {
9760              src: {
9761                name: 'src',
9762                class: 'p5.MediaElement',
9763                module: 'DOM'
9764              },
9765              play: {
9766                name: 'play',
9767                class: 'p5.MediaElement',
9768                module: 'DOM'
9769              },
9770              stop: {
9771                name: 'stop',
9772                class: 'p5.MediaElement',
9773                module: 'DOM'
9774              },
9775              pause: {
9776                name: 'pause',
9777                class: 'p5.MediaElement',
9778                module: 'DOM'
9779              },
9780              loop: {
9781                name: 'loop',
9782                class: 'p5.MediaElement',
9783                module: 'DOM'
9784              },
9785              noLoop: {
9786                name: 'noLoop',
9787                class: 'p5.MediaElement',
9788                module: 'DOM'
9789              },
9790              autoplay: {
9791                name: 'autoplay',
9792                params: [
9793                  {
9794                    name: 'shouldAutoplay',
9795                    description: '<p>whether the element should autoplay</p>\n',
9796                    type: 'Boolean'
9797                  }
9798                ],
9799                class: 'p5.MediaElement',
9800                module: 'DOM'
9801              },
9802              volume: {
9803                name: 'volume',
9804                class: 'p5.MediaElement',
9805                module: 'DOM',
9806                overloads: [
9807                  {
9808                    params: []
9809                  },
9810                  {
9811                    params: [
9812                      {
9813                        name: 'val',
9814                        description: '<p>volume between 0.0 and 1.0</p>\n',
9815                        type: 'Number'
9816                      }
9817                    ],
9818                    chainable: 1
9819                  }
9820                ]
9821              },
9822              speed: {
9823                name: 'speed',
9824                class: 'p5.MediaElement',
9825                module: 'DOM',
9826                overloads: [
9827                  {
9828                    params: []
9829                  },
9830                  {
9831                    params: [
9832                      {
9833                        name: 'speed',
9834                        description: '<p>speed multiplier for element playback</p>\n',
9835                        type: 'Number'
9836                      }
9837                    ],
9838                    chainable: 1
9839                  }
9840                ]
9841              },
9842              time: {
9843                name: 'time',
9844                class: 'p5.MediaElement',
9845                module: 'DOM',
9846                overloads: [
9847                  {
9848                    params: []
9849                  },
9850                  {
9851                    params: [
9852                      {
9853                        name: 'time',
9854                        description: '<p>time to jump to (in seconds)</p>\n',
9855                        type: 'Number'
9856                      }
9857                    ],
9858                    chainable: 1
9859                  }
9860                ]
9861              },
9862              duration: {
9863                name: 'duration',
9864                class: 'p5.MediaElement',
9865                module: 'DOM'
9866              },
9867              onended: {
9868                name: 'onended',
9869                params: [
9870                  {
9871                    name: 'callback',
9872                    description:
9873                      '<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n',
9874                    type: 'Function'
9875                  }
9876                ],
9877                class: 'p5.MediaElement',
9878                module: 'DOM'
9879              },
9880              connect: {
9881                name: 'connect',
9882                params: [
9883                  {
9884                    name: 'audioNode',
9885                    description:
9886                      '<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n',
9887                    type: 'AudioNode|Object'
9888                  }
9889                ],
9890                class: 'p5.MediaElement',
9891                module: 'DOM'
9892              },
9893              disconnect: {
9894                name: 'disconnect',
9895                class: 'p5.MediaElement',
9896                module: 'DOM'
9897              },
9898              showControls: {
9899                name: 'showControls',
9900                class: 'p5.MediaElement',
9901                module: 'DOM'
9902              },
9903              hideControls: {
9904                name: 'hideControls',
9905                class: 'p5.MediaElement',
9906                module: 'DOM'
9907              },
9908              addCue: {
9909                name: 'addCue',
9910                params: [
9911                  {
9912                    name: 'time',
9913                    description:
9914                      "<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n",
9915                    type: 'Number'
9916                  },
9917                  {
9918                    name: 'callback',
9919                    description:
9920                      '<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n',
9921                    type: 'Function'
9922                  },
9923                  {
9924                    name: 'value',
9925                    description:
9926                      '<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n',
9927                    type: 'Object',
9928                    optional: true
9929                  }
9930                ],
9931                class: 'p5.MediaElement',
9932                module: 'DOM'
9933              },
9934              removeCue: {
9935                name: 'removeCue',
9936                params: [
9937                  {
9938                    name: 'id',
9939                    description: '<p>ID of the cue, as returned by addCue</p>\n',
9940                    type: 'Number'
9941                  }
9942                ],
9943                class: 'p5.MediaElement',
9944                module: 'DOM'
9945              },
9946              clearCues: {
9947                name: 'clearCues',
9948                params: [
9949                  {
9950                    name: 'id',
9951                    description: '<p>ID of the cue, as returned by addCue</p>\n',
9952                    type: 'Number'
9953                  }
9954                ],
9955                class: 'p5.MediaElement',
9956                module: 'DOM'
9957              }
9958            },
9959            'p5.File': {
9960              file: {
9961                name: 'file',
9962                class: 'p5.File',
9963                module: 'DOM'
9964              },
9965              type: {
9966                name: 'type',
9967                class: 'p5.File',
9968                module: 'DOM'
9969              },
9970              subtype: {
9971                name: 'subtype',
9972                class: 'p5.File',
9973                module: 'DOM'
9974              },
9975              name: {
9976                name: 'name',
9977                class: 'p5.File',
9978                module: 'DOM'
9979              },
9980              size: {
9981                name: 'size',
9982                class: 'p5.File',
9983                module: 'DOM'
9984              },
9985              data: {
9986                name: 'data',
9987                class: 'p5.File',
9988                module: 'DOM'
9989              }
9990            },
9991            'p5.Image': {
9992              width: {
9993                name: 'width',
9994                class: 'p5.Image',
9995                module: 'Image'
9996              },
9997              height: {
9998                name: 'height',
9999                class: 'p5.Image',
10000                module: 'Image'
10001              },
10002              pixels: {
10003                name: 'pixels',
10004                class: 'p5.Image',
10005                module: 'Image'
10006              },
10007              loadPixels: {
10008                name: 'loadPixels',
10009                class: 'p5.Image',
10010                module: 'Image'
10011              },
10012              updatePixels: {
10013                name: 'updatePixels',
10014                class: 'p5.Image',
10015                module: 'Image',
10016                overloads: [
10017                  {
10018                    params: [
10019                      {
10020                        name: 'x',
10021                        description:
10022                          '<p>x-offset of the target update area for the\n                             underlying canvas</p>\n',
10023                        type: 'Integer'
10024                      },
10025                      {
10026                        name: 'y',
10027                        description:
10028                          '<p>y-offset of the target update area for the\n                             underlying canvas</p>\n',
10029                        type: 'Integer'
10030                      },
10031                      {
10032                        name: 'w',
10033                        description:
10034                          '<p>height of the target update area for the\n                             underlying canvas</p>\n',
10035                        type: 'Integer'
10036                      },
10037                      {
10038                        name: 'h',
10039                        description:
10040                          '<p>height of the target update area for the\n                             underlying canvas</p>\n',
10041                        type: 'Integer'
10042                      }
10043                    ]
10044                  },
10045                  {
10046                    params: []
10047                  }
10048                ]
10049              },
10050              get: {
10051                name: 'get',
10052                class: 'p5.Image',
10053                module: 'Image',
10054                overloads: [
10055                  {
10056                    params: [
10057                      {
10058                        name: 'x',
10059                        description: '<p>x-coordinate of the pixel</p>\n',
10060                        type: 'Number'
10061                      },
10062                      {
10063                        name: 'y',
10064                        description: '<p>y-coordinate of the pixel</p>\n',
10065                        type: 'Number'
10066                      },
10067                      {
10068                        name: 'w',
10069                        description: '<p>width</p>\n',
10070                        type: 'Number'
10071                      },
10072                      {
10073                        name: 'h',
10074                        description: '<p>height</p>\n',
10075                        type: 'Number'
10076                      }
10077                    ]
10078                  },
10079                  {
10080                    params: []
10081                  },
10082                  {
10083                    params: [
10084                      {
10085                        name: 'x',
10086                        description: '',
10087                        type: 'Number'
10088                      },
10089                      {
10090                        name: 'y',
10091                        description: '',
10092                        type: 'Number'
10093                      }
10094                    ]
10095                  }
10096                ]
10097              },
10098              set: {
10099                name: 'set',
10100                params: [
10101                  {
10102                    name: 'x',
10103                    description: '<p>x-coordinate of the pixel</p>\n',
10104                    type: 'Number'
10105                  },
10106                  {
10107                    name: 'y',
10108                    description: '<p>y-coordinate of the pixel</p>\n',
10109                    type: 'Number'
10110                  },
10111                  {
10112                    name: 'a',
10113                    description:
10114                      '<p>grayscale value | pixel array |\n                               a <a href="#/p5.Color">p5.Color</a> | image to copy</p>\n',
10115                    type: 'Number|Number[]|Object'
10116                  }
10117                ],
10118                class: 'p5.Image',
10119                module: 'Image'
10120              },
10121              resize: {
10122                name: 'resize',
10123                params: [
10124                  {
10125                    name: 'width',
10126                    description: '<p>the resized image width</p>\n',
10127                    type: 'Number'
10128                  },
10129                  {
10130                    name: 'height',
10131                    description: '<p>the resized image height</p>\n',
10132                    type: 'Number'
10133                  }
10134                ],
10135                class: 'p5.Image',
10136                module: 'Image'
10137              },
10138              copy: {
10139                name: 'copy',
10140                class: 'p5.Image',
10141                module: 'Image',
10142                overloads: [
10143                  {
10144                    params: [
10145                      {
10146                        name: 'srcImage',
10147                        description: '<p>source image</p>\n',
10148                        type: 'p5.Image|p5.Element'
10149                      },
10150                      {
10151                        name: 'sx',
10152                        description:
10153                          "<p>X coordinate of the source's upper left corner</p>\n",
10154                        type: 'Integer'
10155                      },
10156                      {
10157                        name: 'sy',
10158                        description:
10159                          "<p>Y coordinate of the source's upper left corner</p>\n",
10160                        type: 'Integer'
10161                      },
10162                      {
10163                        name: 'sw',
10164                        description: '<p>source image width</p>\n',
10165                        type: 'Integer'
10166                      },
10167                      {
10168                        name: 'sh',
10169                        description: '<p>source image height</p>\n',
10170                        type: 'Integer'
10171                      },
10172                      {
10173                        name: 'dx',
10174                        description:
10175                          "<p>X coordinate of 
10175the destination's upper left corner</p>\n",
10176                        type: 'Integer'
10177                      },
10178                      {
10179                        name: 'dy',
10180                        description:
10181                          "<p>Y coordinate of the destination's upper left corner</p>\n",
10182                        type: 'Integer'
10183                      },
10184                      {
10185                        name: 'dw',
10186                        description: '<p>destination image width</p>\n',
10187                        type: 'Integer'
10188                      },
10189                      {
10190                        name: 'dh',
10191                        description: '<p>destination image height</p>\n',
10192                        type: 'Integer'
10193                      }
10194                    ]
10195                  },
10196                  {
10197                    params: [
10198                      {
10199                        name: 'sx',
10200                        description: '',
10201                        type: 'Integer'
10202                      },
10203                      {
10204                        name: 'sy',
10205                        description: '',
10206                        type: 'Integer'
10207                      },
10208                      {
10209                        name: 'sw',
10210                        description: '',
10211                        type: 'Integer'
10212                      },
10213                      {
10214                        name: 'sh',
10215                        description: '',
10216                        type: 'Integer'
10217                      },
10218                      {
10219                        name: 'dx',
10220                        description: '',
10221                        type: 'Integer'
10222                      },
10223                      {
10224                        name: 'dy',
10225                        description: '',
10226                        type: 'Integer'
10227                      },
10228                      {
10229                        name: 'dw',
10230                        description: '',
10231                        type: 'Integer'
10232                      },
10233                      {
10234                        name: 'dh',
10235                        description: '',
10236                        type: 'Integer'
10237                      }
10238                    ]
10239                  }
10240                ]
10241              },
10242              mask: {
10243                name: 'mask',
10244                params: [
10245                  {
10246                    name: 'srcImage',
10247                    description: '<p>source image</p>\n',
10248                    type: 'p5.Image'
10249                  }
10250                ],
10251                class: 'p5.Image',
10252                module: 'Image'
10253              },
10254              filter: {
10255                name: 'filter',
10256                params: [
10257                  {
10258                    name: 'filterType',
10259                    description:
10260                      '<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n',
10261                    type: 'Constant'
10262                  },
10263                  {
10264                    name: 'filterParam',
10265                    description:
10266                      '<p>an optional parameter unique\n                               to each filter, see above</p>\n',
10267                    type: 'Number',
10268                    optional: true
10269                  }
10270                ],
10271                class: 'p5.Image',
10272                module: 'Image'
10273              },
10274              blend: {
10275                name: 'blend',
10276                class: 'p5.Image',
10277                module: 'Image',
10278                overloads: [
10279                  {
10280                    params: [
10281                      {
10282                        name: 'srcImage',
10283                        description: '<p>source image</p>\n',
10284                        type: 'p5.Image'
10285                      },
10286                      {
10287                        name: 'sx',
10288                        description:
10289                          "<p>X coordinate of the source's upper left corner</p>\n",
10290                        type: 'Integer'
10291                      },
10292                      {
10293                        name: 'sy',
10294                        description:
10295                          "<p>Y coordinate of the source's upper left corner</p>\n",
10296                        type: 'Integer'
10297                      },
10298                      {
10299                        name: 'sw',
10300                        description: '<p>source image width</p>\n',
10301                        type: 'Integer'
10302                      },
10303                      {
10304                        name: 'sh',
10305                        description: '<p>source image height</p>\n',
10306                        type: 'Integer'
10307                      },
10308                      {
10309                        name: 'dx',
10310                        description:
10311                          "<p>X coordinate of the destination's upper left corner</p>\n",
10312                        type: 'Integer'
10313                      },
10314                      {
10315                        name: 'dy',
10316                        description:
10317                          "<p>Y coordinate of the destination's upper left corner</p>\n",
10318                        type: 'Integer'
10319                      },
10320                      {
10321                        name: 'dw',
10322                        description: '<p>destination image width</p>\n',
10323                        type: 'Integer'
10324                      },
10325                      {
10326                        name: 'dh',
10327                        description: '<p>destination image height</p>\n',
10328                        type: 'Integer'
10329                      },
10330                      {
10331                        name: 'blendMode',
10332                        description:
10333                          '<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href="http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n',
10334                        type: 'Constant'
10335                      }
10336                    ]
10337                  },
10338                  {
10339                    params: [
10340                      {
10341                        name: 'sx',
10342                        description: '',
10343                        type: 'Integer'
10344                      },
10345                      {
10346                        name: 'sy',
10347                        description: '',
10348                        type: 'Integer'
10349                      },
10350                      {
10351                        name: 'sw',
10352                        description: '',
10353                        type: 'Integer'
10354                      },
10355                      {
10356                        name: 'sh',
10357                        description: '',
10358                        type: 'Integer'
10359                      },
10360                      {
10361                        name: 'dx',
10362                        description: '',
10363                        type: 'Integer'
10364                      },
10365                      {
10366                        name: 'dy',
10367                        description: '',
10368                        type: 'Integer'
10369                      },
10370                      {
10371                        name: 'dw',
10372                        description: '',
10373                        type: 'Integer'
10374                      },
10375                      {
10376                        name: 'dh',
10377                        description: '',
10378                        type: 'Integer'
10379                      },
10380                      {
10381                        name: 'blendMode',
10382                        description: '',
10383                        type: 'Constant'
10384                      }
10385                    ]
10386                  }
10387                ]
10388              },
10389              save: {
10390                name: 'save',
10391                params: [
10392                  {
10393                    name: 'filename',
10394                    description: '<p>give your file a name</p>\n',
10395                    type: 'String'
10396                  },
10397                  {
10398                    name: 'extension',
10399                    description: "<p>'png' or 'jpg'</p>\n",
10400                    type: 'String'
10401                  }
10402                ],
10403                class: 'p5.Image',
10404                module: 'Image'
10405              },
10406              reset: {
10407                name: 'reset',
10408                class: 'p5.Image',
10409                module: 'Image'
10410              },
10411              getCurrentFrame: {
10412                name: 'getCurrentFrame',
10413                class: 'p5.Image',
10414                module: 'Image'
10415              },
10416              setFrame: {
10417                name: 'setFrame',
10418                params: [
10419                  {
10420                    name: 'index',
10421                    description:
10422                      '<p>the index for the frame that should be displayed</p>\n',
10423                    type: 'Number'
10424                  }
10425                ],
10426                class: 'p5.Image',
10427                module: 'Image'
10428              },
10429              numFrames: {
10430                name: 'numFrames',
10431                class: 'p5.Image',
10432                module: 'Image'
10433              },
10434              play: {
10435                name: 'play',
10436                class: 'p5.Image',
10437                module: 'Image'
10438              },
10439              pause: {
10440                name: 'pause',
10441                class: 'p5.Image',
10442                module: 'Image'
10443              },
10444              delay: {
10445                name: 'delay',
10446                params: [
10447                  {
10448                    name: 'd',
10449                    description:
10450                      '<p>the amount in milliseconds to delay between switching frames</p>\n',
10451                    type: 'Number'
10452                  },
10453                  {
10454                    name: 'index',
10455                    description:
10456                      '<p>the index of the frame that should have the new delay value {optional}</p>\n',
10457                    type: 'Number',
10458                    optional: true
10459                  }
10460                ],
10461                class: 'p5.Image',
10462                module: 'Image'
10463              }
10464            },
10465            'p5.PrintWriter': {
10466              write: {
10467                name: 'write',
10468                params: [
10469                  {
10470                    name: 'data',
10471                    description: '<p>all data to be written by the PrintWriter</p>\n',
10472                    type: 'Array'
10473                  }
10474                ],
10475                class: 'p5.PrintWriter',
10476                module: 'IO'
10477              },
10478              print: {
10479                name: 'print',
10480                params: [
10481                  {
10482                    name: 'data',
10483                    description: '<p>all data to be printed by the PrintWriter</p>\n',
10484                    type: 'Array'
10485                  }
10486                ],
10487                class: 'p5.PrintWriter',
10488                module: 'IO'
10489              },
10490              clear: {
10491                name: 'clear',
10492                class: 'p5.PrintWriter',
10493                module: 'IO'
10494              },
10495              close: {
10496                name: 'close',
10497                class: 'p5.PrintWriter',
10498                module: 'IO'
10499              }
10500            },
10501            'p5.Table': {
10502              columns: {
10503                name: 'columns',
10504                class: 'p5.Table',
10505                module: 'IO'
10506              },
10507              rows: {
10508                name: 'rows',
10509                class: 'p5.Table',
10510                module: 'IO'
10511              },
10512              addRow: {
10513                name: 'addRow',
10514                params: [
10515                  {
10516                    name: 'row',
10517                    description: '<p>row to be added to the table</p>\n',
10518                    type: 'p5.TableRow',
10519                    optional: true
10520                  }
10521                ],
10522                class: 'p5.Table',
10523                module: 'IO'
10524              },
10525              removeRow: {
10526                name: 'removeRow',
10527                params: [
10528                  {
10529                    name: 'id',
10530                    description: '<p>ID number of the row to remove</p>\n',
10531                    type: 'Integer'
10532                  }
10533                ],
10534                class: 'p5.Table',
10535                module: 'IO'
10536              },
10537              getRow: {
10538                name: 'getRow',
10539                params: [
10540                  {
10541                    name: 'rowID',
10542                    description: '<p>ID number of the row to get</p>\n',
10543                    type: 'Integer'
10544                  }
10545                ],
10546                class: 'p5.Table',
10547                module: 'IO'
10548              },
10549              getRows: {
10550                name: 'getRows',
10551                class: 'p5.Table',
10552                module: 'IO'
10553              },
10554              findRow: {
10555                name: 'findRow',
10556                params: [
10557                  {
10558                    name: 'value',
10559                    description: '<p>The value to match</p>\n',
10560                    type: 'String'
10561                  },
10562                  {
10563                    name: 'column',
10564                    description:
10565                      '<p>ID number or title of the\n                               column to search</p>\n',
10566                    type: 'Integer|String'
10567                  }
10568                ],
10569                class: 'p5.Table',
10570                module: 'IO'
10571              },
10572              findRows: {
10573                name: 'findRows',
10574                params: [
10575                  {
10576                    name: 'value',
10577                    description: '<p>The value to match</p>\n',
10578                    type: 'String'
10579                  },
10580                  {
10581                    name: 'column',
10582                    description:
10583                      '<p>ID number or title of the\n                               column to search</p>\n',
10584                    type: 'Integer|String'
10585                  }
10586                ],
10587                class: 'p5.Table',
10588                module: 'IO'
10589              },
10590              matchRow: {
10591                name: 'matchRow',
10592                params: [
10593                  {
10594                    name: 'regexp',
10595                    description: '<p>The regular expression to match</p>\n',
10596                    type: 'String|RegExp'
10597                  },
10598                  {
10599                    name: 'column',
10600                    description:
10601                      '<p>The column ID (number) or\n                                 title (string)</p>\n',
10602                    type: 'String|Integer'
10603                  }
10604                ],
10605                class: 'p5.Table',
10606                module: 'IO'
10607              },
10608              matchRows: {
10609                name: 'matchRows',
10610                params: [
10611                  {
10612                    name: 'regexp',
10613                    description: '<p>The regular expression to match</p>\n',
10614                    type: 'String'
10615                  },
10616                  {
10617                    name: 'column',
10618                    description:
10619                      '<p>The column ID (number) or\n                                 title (string)</p>\n',
10620                    type: 'String|Integer',
10621                    optional: true
10622                  }
10623                ],
10624                class: 'p5.Table',
10625                module: 'IO'
10626              },
10627              getColumn: {
10628                name: 'getColumn',
10629                params: [
10630                  {
10631                    name: 'column',
10632                    description: '<p>String or Number of the column to return</p>\n',
10633                    type: 'String|Number'
10634                  }
10635                ],
10636                class: 'p5.Table',
10637                module: 'IO'
10638              },
10639              clearRows: {
10640                name: 'clearRows',
10641                class: 'p5.Table',
10642                module: 'IO'
10643              },
10644              addColumn: {
10645                name: 'addColumn',
10646                params: [
10646
10647                  {
10648                    name: 'title',
10649                    description: '<p>title of the given column</p>\n',
10650                    type: 'String',
10651                    optional: true
10652                  }
10653                ],
10654                class: 'p5.Table',
10655                module: 'IO'
10656              },
10657              getColumnCount: {
10658                name: 'getColumnCount',
10659                class: 'p5.Table',
10660                module: 'IO'
10661              },
10662              getRowCount: {
10663                name: 'getRowCount',
10664                class: 'p5.Table',
10665                module: 'IO'
10666              },
10667              removeTokens: {
10668                name: 'removeTokens',
10669                params: [
10670                  {
10671                    name: 'chars',
10672                    description: '<p>String listing characters to be removed</p>\n',
10673                    type: 'String'
10674                  },
10675                  {
10676                    name: 'column',
10677                    description:
10678                      '<p>Column ID (number)\n                                 or name (string)</p>\n',
10679                    type: 'String|Integer',
10680                    optional: true
10681                  }
10682                ],
10683                class: 'p5.Table',
10684                module: 'IO'
10685              },
10686              trim: {
10687                name: 'trim',
10688                params: [
10689                  {
10690                    name: 'column',
10691                    description:
10692                      '<p>Column ID (number)\n                                 or name (string)</p>\n',
10693                    type: 'String|Integer',
10694                    optional: true
10695                  }
10696                ],
10697                class: 'p5.Table',
10698                module: 'IO'
10699              },
10700              removeColumn: {
10701                name: 'removeColumn',
10702                params: [
10703                  {
10704                    name: 'column',
10705                    description: '<p>columnName (string) or ID (number)</p>\n',
10706                    type: 'String|Integer'
10707                  }
10708                ],
10709                class: 'p5.Table',
10710                module: 'IO'
10711              },
10712              set: {
10713                name: 'set',
10714                params: [
10715                  {
10716                    name: 'row',
10717                    description: '<p>row ID</p>\n',
10718                    type: 'Integer'
10719                  },
10720                  {
10721                    name: 'column',
10722                    description:
10723                      '<p>column ID (Number)\n                              or title (String)</p>\n',
10724                    type: 'String|Integer'
10725                  },
10726                  {
10727                    name: 'value',
10728                    description: '<p>value to assign</p>\n',
10729                    type: 'String|Number'
10730                  }
10731                ],
10732                class: 'p5.Table',
10733                module: 'IO'
10734              },
10735              setNum: {
10736                name: 'setNum',
10737                params: [
10738                  {
10739                    name: 'row',
10740                    description: '<p>row ID</p>\n',
10741                    type: 'Integer'
10742                  },
10743                  {
10744                    name: 'column',
10745                    description:
10746                      '<p>column ID (Number)\n                              or title (String)</p>\n',
10747                    type: 'String|Integer'
10748                  },
10749                  {
10750                    name: 'value',
10751                    description: '<p>value to assign</p>\n',
10752                    type: 'Number'
10753                  }
10754                ],
10755                class: 'p5.Table',
10756                module: 'IO'
10757              },
10758              setString: {
10759                name: 'setString',
10760                params: [
10761                  {
10762                    name: 'row',
10763                    description: '<p>row ID</p>\n',
10764                    type: 'Integer'
10765                  },
10766                  {
10767                    name: 'column',
10768                    description:
10769                      '<p>column ID (Number)\n                              or title (String)</p>\n',
10770                    type: 'String|Integer'
10771                  },
10772                  {
10773                    name: 'value',
10774                    description: '<p>value to assign</p>\n',
10775                    type: 'String'
10776                  }
10777                ],
10778                class: 'p5.Table',
10779                module: 'IO'
10780              },
10781              get: {
10782                name: 'get',
10783                params: [
10784                  {
10785                    name: 'row',
10786                    description: '<p>row ID</p>\n',
10787                    type: 'Integer'
10788                  },
10789                  {
10790                    name: 'column',
10791                    description:
10792                      '<p>columnName (string) or\n                                  ID (number)</p>\n',
10793                    type: 'String|Integer'
10794                  }
10795                ],
10796                class: 'p5.Table',
10797                module: 'IO'
10798              },
10799              getNum: {
10800                name: 'getNum',
10801                params: [
10802                  {
10803                    name: 'row',
10804                    description: '<p>row ID</p>\n',
10805                    type: 'Integer'
10806                  },
10807                  {
10808                    name: 'column',
10809                    description:
10810                      '<p>columnName (string) or\n                                  ID (number)</p>\n',
10811                    type: 'String|Integer'
10812                  }
10813                ],
10814                class: 'p5.Table',
10815                module: 'IO'
10816              },
10817              getString: {
10818                name: 'getString',
10819                params: [
10820                  {
10821                    name: 'row',
10822                    description: '<p>row ID</p>\n',
10823                    type: 'Integer'
10824                  },
10825                  {
10826                    name: 'column',
10827                    description:
10828                      '<p>columnName (string) or\n                                  ID (number)</p>\n',
10829                    type: 'String|Integer'
10830                  }
10831                ],
10832                class: 'p5.Table',
10833                module: 'IO'
10834              },
10835              getObject: {
10836                name: 'getObject',
10837                params: [
10838                  {
10839                    name: 'headerColumn',
10840                    description:
10841                      '<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n',
10842                    type: 'String',
10843                    optional: true
10844                  }
10845                ],
10846                class: 'p5.Table',
10847                module: 'IO'
10848              },
10849              getArray: {
10850                name: 'getArray',
10851                class: 'p5.Table',
10852                module: 'IO'
10853              }
10854            },
10855            'p5.TableRow': {
10856              set: {
10857                name: 'set',
10858                params: [
10859                  {
10860                    name: 'column',
10861                    description:
10862                      '<p>Column ID (Number)\n                              or Title (String)</p>\n',
10863                    type: 'String|Integer'
10864                  },
10865                  {
10866                    name: 'value',
10867                    description: '<p>The value to be stored</p>\n',
10868                    type: 'String|Number'
10869                  }
10870                ],
10871                class: 'p5.TableRow',
10872                module: 'IO'
10873              },
10874              setNum: {
10875                name: 'setNum',
10876                params: [
10877                  {
10878                    name: 'column',
10879                    description:
10880                      '<p>Column ID (Number)\n                              or Title (String)</p>\n',
10881                    type: 'String|Integer'
10882                  },
10883                  {
10884                    name: 'value',
10885                    description:
10886                      '<p>The value to be stored\n                              as a Float</p>\n',
10887                    type: 'Number|String'
10888                  }
10889                ],
10890                class: 'p5.TableRow',
10891                module: 'IO'
10892              },
10893              setString: {
10894                name: 'setString',
10895                params: [
10896                  {
10897                    name: 'column',
10898                    description:
10899                      '<p>Column ID (Number)\n                              or Title (String)</p>\n',
10900                    type: 'String|Integer'
10901                  },
10902                  {
10903                    name: 'value',
10904                    description:
10905                      '<p>The value to be stored\n                              as a String</p>\n',
10906                    type: 'String|Number|Boolean|Object'
10907                  }
10908                ],
10909                class: 'p5.TableRow',
10910                module: 'IO'
10911              },
10912              get: {
10913                name: 'get',
10914                params: [
10915                  {
10916                    name: 'column',
10917                    description:
10918                      '<p>columnName (string) or\n                                 ID (number)</p>\n',
10919                    type: 'String|Integer'
10920                  }
10921                ],
10922                class: 'p5.TableRow',
10923                module: 'IO'
10924              },
10925              getNum: {
10926                name: 'getNum',
10927                params: [
10928                  {
10929                    name: 'column',
10930                    description:
10931                      '<p>columnName (string) or\n                                 ID (number)</p>\n',
10932                    type: 'String|Integer'
10933                  }
10934                ],
10935                class: 'p5.TableRow',
10936                module: 'IO'
10937              },
10938              getString: {
10939                name: 'getString',
10940                params: [
10941                  {
10942                    name: 'column',
10943                    description:
10944                      '<p>columnName (string) or\n                                 ID (number)</p>\n',
10945                    type: 'String|Integer'
10946                  }
10947                ],
10948                class: 'p5.TableRow',
10949                module: 'IO'
10950              }
10951            },
10952            'p5.XML': {
10953              getParent: {
10954                name: 'getParent',
10955                class: 'p5.XML',
10956                module: 'IO'
10957              },
10958              getName: {
10959                name: 'getName',
10960                class: 'p5.XML',
10961                module: 'IO'
10962              },
10963              setName: {
10964                name: 'setName',
10965                params: [
10966                  {
10967                    name: 'the',
10968                    description: '<p>new name of the node</p>\n',
10969                    type: 'String'
10970                  }
10971                ],
10972                class: 'p5.XML',
10973                module: 'IO'
10974              },
10975              hasChildren: {
10976                name: 'hasChildren',
10977                class: 'p5.XML',
10978                module: 'IO'
10979              },
10980              listChildren: {
10981                name: 'listChildren',
10982                class: 'p5.XML',
10983                module: 'IO'
10984              },
10985              getChildren: {
10986                name: 'getChildren',
10987                params: [
10988                  {
10989                    name: 'name',
10990                    description: '<p>element name</p>\n',
10991                    type: 'String',
10992                    optional: true
10993                  }
10994                ],
10995                class: 'p5.XML',
10996                module: 'IO'
10997              },
10998              getChild: {
10999                name: 'getChild',
11000                params: [
11001                  {
11002                    name: 'name',
11003                    description: '<p>element name or index</p>\n',
11004                    type: 'String|Integer'
11005                  }
11006                ],
11007                class: 'p5.XML',
11008                module: 'IO'
11009              },
11010              addChild: {
11011                name: 'addChild',
11012                params: [
11013                  {
11014                    name: 'node',
11015                    description:
11016                      '<p>a <a href="#/p5.XML">p5.XML</a> Object which will be the child to be added</p>\n',
11017                    type: 'p5.XML'
11018                  }
11019                ],
11020                class: 'p5.XML',
11021                module: 'IO'
11022              },
11023              removeChild: {
11024                name: 'removeChild',
11025                params: [
11026                  {
11027                    name: 'name',
11028                    description: '<p>element name or index</p>\n',
11029                    type: 'String|Integer'
11030                  }
11031                ],
11032                class: 'p5.XML',
11033                module: 'IO'
11034              },
11035              getAttributeCount: {
11036                name: 'getAttributeCount',
11037                class: 'p5.XML',
11038                module: 'IO'
11039              },
11040              listAttributes: {
11041                name: 'listAttributes',
11042                class: 'p5.XML',
11043                module: 'IO'
11044              },
11045              hasAttribute: {
11046                name: 'hasAttribute',
11047                params: [
11048                  {
11049                    name: 'the',
11050                    description: '<p>attribute to be checked</p>\n',
11051                    type: 'String'
11052                  }
11053                ],
11054                class: 'p5.XML',
11055                module: 'IO'
11056              },
11057              getNum: {
11058                name: 'getNum',
11059                params: [
11060                  {
11061                    name: 'name',
11062                    description: '<p>the non-null full name of the attribute</p>\n',
11063                    type: 'String'
11064                  },
11065                  {
11066                    name: 'defaultValue',
11067                    description: '<p>the default value of the attribute</p>\n',
11068                    type: 'Number',
11069                    optional: true
11070                  }
11071                ],
11072                class: 'p5.XML',
11073                module: 'IO'
11074              },
11075              getString: {
11076                name: 'getString',
11077                params: [
11078                  {
11079                    name: 'name',
11080                    description: '<p>the non-null full name of the attribute</p>\n',
11081                    type: 'String'
11082                  },
11083                  {
11084                    name: 'defaultValue',
11085                    description: '<p>the default value of the attribute</p>\n',
11086                    type: 'Number',
11087                    optional: true
11088                  }
11089                ],
11090                class: 'p5.XML',
11091                module: 'IO'
11092              },
11093              setAttribute: {
11094                name: 'setAttribute',
11095                params: [
11096                  {
11097                    name: 'name',
11098                    description: '<p>the full name of the attribute</p>\n',
11099                    type: 'String'
11100                  },
11101                  {
11102                    name: 'value',
11103                    description: '<p>the value of the attribute</p>\n',
11104                    type: 'Number|String|Boolean'
11105                  }
11106                ],
11107                class: 'p5.XML',
11108                module: 'IO'
11109              },
11110              getContent: {
11111                name: 'getContent',
11112                params: [
11113                  {
11114                    name: 'defaultValue',
11115                    description: '<p>value returned if no content is found</p>\n',
11116                    type: 'String',
11117                    optional: true
11118                  }
11119                ],
11120                class: 'p5.XML',
11121                module: 'IO'
11122              },
11123              setContent: {
11124                name: 'setContent',
11125                params: [
11126                  {
11127                    name: 'text',
11128                    description: '<p>the new content</p>\n',
11129                    type: 'String'
11130                  }
11131                ],
11132                class: 'p5.XML',
11133                module: 'IO'
11134              },
11135              serialize: {
11136                name: 'serialize',
11137                class: 'p5.XML',
11138                module: 'IO'
11139              }
11140            },
11141            'p5.Vector': {
11142              x: {
11143                name: 'x',
11144                class: 'p5.Vector',
11145             
11145   module: 'Math'
11146              },
11147              y: {
11148                name: 'y',
11149                class: 'p5.Vector',
11150                module: 'Math'
11151              },
11152              z: {
11153                name: 'z',
11154                class: 'p5.Vector',
11155                module: 'Math'
11156              },
11157              toString: {
11158                name: 'toString',
11159                class: 'p5.Vector',
11160                module: 'Math'
11161              },
11162              set: {
11163                name: 'set',
11164                class: 'p5.Vector',
11165                module: 'Math',
11166                overloads: [
11167                  {
11168                    params: [
11169                      {
11170                        name: 'x',
11171                        description: '<p>the x component of the vector</p>\n',
11172                        type: 'Number',
11173                        optional: true
11174                      },
11175                      {
11176                        name: 'y',
11177                        description: '<p>the y component of the vector</p>\n',
11178                        type: 'Number',
11179                        optional: true
11180                      },
11181                      {
11182                        name: 'z',
11183                        description: '<p>the z component of the vector</p>\n',
11184                        type: 'Number',
11185                        optional: true
11186                      }
11187                    ],
11188                    chainable: 1
11189                  },
11190                  {
11191                    params: [
11192                      {
11193                        name: 'value',
11194                        description: '<p>the vector to set</p>\n',
11195                        type: 'p5.Vector|Number[]'
11196                      }
11197                    ],
11198                    chainable: 1
11199                  }
11200                ]
11201              },
11202              copy: {
11203                name: 'copy',
11204                class: 'p5.Vector',
11205                module: 'Math'
11206              },
11207              add: {
11208                name: 'add',
11209                class: 'p5.Vector',
11210                module: 'Math',
11211                overloads: [
11212                  {
11213                    params: [
11214                      {
11215                        name: 'x',
11216                        description: '<p>the x component of the vector to be added</p>\n',
11217                        type: 'Number'
11218                      },
11219                      {
11220                        name: 'y',
11221                        description: '<p>the y component of the vector to be added</p>\n',
11222                        type: 'Number',
11223                        optional: true
11224                      },
11225                      {
11226                        name: 'z',
11227                        description: '<p>the z component of the vector to be added</p>\n',
11228                        type: 'Number',
11229                        optional: true
11230                      }
11231                    ],
11232                    chainable: 1
11233                  },
11234                  {
11235                    params: [
11236                      {
11237                        name: 'value',
11238                        description: '<p>the vector to add</p>\n',
11239                        type: 'p5.Vector|Number[]'
11240                      }
11241                    ],
11242                    chainable: 1
11243                  },
11244                  {
11245                    params: [
11246                      {
11247                        name: 'v1',
11248                        description:
11249                          '<p>a <a href="#/p5.Vector">p5.Vector</a> to add</p>\n',
11250                        type: 'p5.Vector'
11251                      },
11252                      {
11253                        name: 'v2',
11254                        description:
11255                          '<p>a <a href="#/p5.Vector">p5.Vector</a> to add</p>\n',
11256                        type: 'p5.Vector'
11257                      },
11258                      {
11259                        name: 'target',
11260                        description: '<p>the vector to receive the result (Optional)</p>\n',
11261                        type: 'p5.Vector',
11262                        optional: true
11263                      }
11264                    ],
11265                    static: 1
11266                  }
11267                ]
11268              },
11269              rem: {
11270                name: 'rem',
11271                class: 'p5.Vector',
11272                module: 'Math',
11273                overloads: [
11274                  {
11275                    params: [
11276                      {
11277                        name: 'x',
11278                        description: '<p>the x component of divisor vector</p>\n',
11279                        type: 'Number'
11280                      },
11281                      {
11282                        name: 'y',
11283                        description: '<p>the y component of divisor vector</p>\n',
11284                        type: 'Number'
11285                      },
11286                      {
11287                        name: 'z',
11288                        description: '<p>the z component of divisor vector</p>\n',
11289                        type: 'Number'
11290                      }
11291                    ],
11292                    chainable: 1
11293                  },
11294                  {
11295                    params: [
11296                      {
11297                        name: 'value',
11298                        description: '<p>divisor vector</p>\n',
11299                        type: 'p5.Vector | Number[]'
11300                      }
11301                    ],
11302                    chainable: 1
11303                  },
11304                  {
11305                    params: [
11306                      {
11307                        name: 'v1',
11308                        description:
11309                          '<p>dividend <a href="#/p5.Vector">p5.Vector</a></p>\n',
11310                        type: 'p5.Vector'
11311                      },
11312                      {
11313                        name: 'v2',
11314                        description: '<p>divisor <a href="#/p5.Vector">p5.Vector</a></p>\n',
11315                        type: 'p5.Vector'
11316                      }
11317                    ],
11318                    static: 1
11319                  },
11320                  {
11321                    params: [
11322                      {
11323                        name: 'v1',
11324                        description: '',
11325                        type: 'p5.Vector'
11326                      },
11327                      {
11328                        name: 'v2',
11329                        description: '',
11330                        type: 'p5.Vector'
11331                      }
11332                    ],
11333                    static: 1
11334                  }
11335                ]
11336              },
11337              sub: {
11338                name: 'sub',
11339                class: 'p5.Vector',
11340                module: 'Math',
11341                overloads: [
11342                  {
11343                    params: [
11344                      {
11345                        name: 'x',
11346                        description: '<p>the x component of the vector to subtract</p>\n',
11347                        type: 'Number'
11348                      },
11349                      {
11350                        name: 'y',
11351                        description: '<p>the y component of the vector to subtract</p>\n',
11352                        type: 'Number',
11353                        optional: true
11354                      },
11355                      {
11356                        name: 'z',
11357                        description: '<p>the z component of the vector to subtract</p>\n',
11358                        type: 'Number',
11359                        optional: true
11360                      }
11361                    ],
11362                    chainable: 1
11363                  },
11364                  {
11365                    params: [
11366                      {
11367                        name: 'value',
11368                        description: '<p>the vector to subtract</p>\n',
11369                        type: 'p5.Vector|Number[]'
11370                      }
11371                    ],
11372                    chainable: 1
11373                  },
11374                  {
11375                    params: [
11376                      {
11377                        name: 'v1',
11378                        description:
11379                          '<p>a <a href="#/p5.Vector">p5.Vector</a> to subtract from</p>\n',
11380                        type: 'p5.Vector'
11381                      },
11382                      {
11383                        name: 'v2',
11384                        description:
11385                          '<p>a <a href="#/p5.Vector">p5.Vector</a> to subtract</p>\n',
11386                        type: 'p5.Vector'
11387                      },
11388                      {
11389                        name: 'target',
11390                        description: '<p>the vector to receive the result (Optional)</p>\n',
11391                        type: 'p5.Vector',
11392                        optional: true
11393                      }
11394                    ],
11395                    static: 1
11396                  }
11397                ]
11398              },
11399              mult: {
11400                name: 'mult',
11401                class: 'p5.Vector',
11402                module: 'Math',
11403                overloads: [
11404                  {
11405                    params: [
11406                      {
11407                        name: 'n',
11408                        description: '<p>The number to multiply with the vector</p>\n',
11409                        type: 'Number'
11410                      }
11411                    ],
11412                    chainable: 1
11413                  },
11414                  {
11415                    params: [
11416                      {
11417                        name: 'x',
11418                        description:
11419                          '<p>The number to multiply with the x component of the vector</p>\n',
11420                        type: 'Number'
11421                      },
11422                      {
11423                        name: 'y',
11424                        description:
11425                          '<p>The number to multiply with the y component of the vector</p>\n',
11426                        type: 'Number'
11427                      },
11428                      {
11429                        name: 'z',
11430                        description:
11431                          '<p>The number to multiply with the z component of the vector</p>\n',
11432                        type: 'Number',
11433                        optional: true
11434                      }
11435                    ],
11436                    chainable: 1
11437                  },
11438                  {
11439                    params: [
11440                      {
11441                        name: 'arr',
11442                        description:
11443                          '<p>The array to multiply with the components of the vector</p>\n',
11444                        type: 'Number[]'
11445                      }
11446                    ],
11447                    chainable: 1
11448                  },
11449                  {
11450                    params: [
11451                      {
11452                        name: 'v',
11453                        description:
11454                          '<p>The vector to multiply with the components of the original vector</p>\n',
11455                        type: 'p5.Vector'
11456                      }
11457                    ],
11458                    chainable: 1
11459                  },
11460                  {
11461                    params: [
11462                      {
11463                        name: 'x',
11464                        description: '',
11465                        type: 'Number'
11466                      },
11467                      {
11468                        name: 'y',
11469                        description: '',
11470                        type: 'Number'
11471                      },
11472                      {
11473                        name: 'z',
11474                        description: '',
11475                        type: 'Number',
11476                        optional: true
11477                      }
11478                    ],
11479                    static: 1
11480                  },
11481                  {
11482                    params: [
11483                      {
11484                        name: 'v',
11485                        description: '',
11486                        type: 'p5.Vector'
11487                      },
11488                      {
11489                        name: 'n',
11490                        description: '',
11491                        type: 'Number'
11492                      },
11493                      {
11494                        name: 'target',
11495                        description: '<p>the vector to receive the result (Optional)</p>\n',
11496                        type: 'p5.Vector',
11497                        optional: true
11498                      }
11499                    ],
11500                    static: 1
11501                  },
11502                  {
11503                    params: [
11504                      {
11505                        name: 'v0',
11506                        description: '',
11507                        type: 'p5.Vector'
11508                      },
11509                      {
11510                        name: 'v1',
11511                        description: '',
11512                        type: 'p5.Vector'
11513                      },
11514                      {
11515                        name: 'target',
11516                        description: '',
11517                        type: 'p5.Vector',
11518                        optional: true
11519                      }
11520                    ],
11521                    static: 1
11522                  },
11523                  {
11524                    params: [
11525                      {
11526                        name: 'v0',
11527                        description: '',
11528                        type: 'p5.Vector'
11529                      },
11530                      {
11531                        name: 'arr',
11532                        description: '',
11533                        type: 'Number[]'
11534                      },
11535                      {
11536                        name: 'target',
11537                        description: '',
11538                        type: 'p5.Vector',
11539                        optional: true
11540                      }
11541                    ],
11542                    static: 1
11543                  }
11544                ]
11545              },
11546              div: {
11547                name: 'div',
11548                class: 'p5.Vector',
11549                module: 'Math',
11550                overloads: [
11551                  {
11552                    params: [
11553                      {
11554                        name: 'n',
11555                        description: '<p>The number to divide the vector by</p>\n',
11556                        type: 'Number'
11557                      }
11558                    ],
11559                    chainable: 1
11560                  },
11561                  {
11562                    params: [
11563                      {
11564                        name: 'x',
11565                        description:
11566                          '<p>The number to divide with the x component of the vector</p>\n',
11567                        type: 'Number'
11568                      },
11569                      {
11570                        name: 'y',
11571                        description:
11572                          '<p>The number to divide with the y component of the vector</p>\n',
11573                        type: 'Number'
11574                      },
11575                      {
11576                        name: 'z',
11577                        description:
11578                          '<p>The number to divide with the z component of the vector</p>\n',
11579                        type: 'Number',
11580                        optional: true
11581                      }
11582                    ],
11583                    chainable: 1
11584                  },
11585                  {
11586                    params: [
11587                      {
11588                        name: 'arr',
11589                        description:
11590                          '<p>The array to divide the components of the vector by</p>\n',
11591                        type: 'Number[]'
11592                      }
11593                    ],
11594                    chainable: 1
11595                  },
11596                  {
11597                    params: [
11598                      {
11599                        name: 'v',
11600                        description:
11601                          '<p>The vector to divide the components of the original vector by</p>\n',
11602                        type: 'p5.Vector'
11603                      }
11604                    ],
11605                    chainable: 1
11606                  },
11607                  {
11608                    params: [
11609                      {
11610                        name: 'x',
11611                        description: '',
11612                        type: 'Number'
11613                      },
11614                      {
11615                        name: 'y',
11616                        description: '',
11617                        type: 'Number'
11618                      },
11619                      {
11620                        name: 'z',
11621                        description: '',
11622                        type: 'Num
11622ber',
11623                        optional: true
11624                      }
11625                    ],
11626                    static: 1
11627                  },
11628                  {
11629                    params: [
11630                      {
11631                        name: 'v',
11632                        description: '',
11633                        type: 'p5.Vector'
11634                      },
11635                      {
11636                        name: 'n',
11637                        description: '',
11638                        type: 'Number'
11639                      },
11640                      {
11641                        name: 'target',
11642                        description: '<p>the vector to receive the result (Optional)</p>\n',
11643                        type: 'p5.Vector',
11644                        optional: true
11645                      }
11646                    ],
11647                    static: 1
11648                  },
11649                  {
11650                    params: [
11651                      {
11652                        name: 'v0',
11653                        description: '',
11654                        type: 'p5.Vector'
11655                      },
11656                      {
11657                        name: 'v1',
11658                        description: '',
11659                        type: 'p5.Vector'
11660                      },
11661                      {
11662                        name: 'target',
11663                        description: '',
11664                        type: 'p5.Vector',
11665                        optional: true
11666                      }
11667                    ],
11668                    static: 1
11669                  },
11670                  {
11671                    params: [
11672                      {
11673                        name: 'v0',
11674                        description: '',
11675                        type: 'p5.Vector'
11676                      },
11677                      {
11678                        name: 'arr',
11679                        description: '',
11680                        type: 'Number[]'
11681                      },
11682                      {
11683                        name: 'target',
11684                        description: '',
11685                        type: 'p5.Vector',
11686                        optional: true
11687                      }
11688                    ],
11689                    static: 1
11690                  }
11691                ]
11692              },
11693              mag: {
11694                name: 'mag',
11695                class: 'p5.Vector',
11696                module: 'Math',
11697                overloads: [
11698                  {
11699                    params: []
11700                  },
11701                  {
11702                    params: [
11703                      {
11704                        name: 'vecT',
11705                        description: '<p>the vector to return the magnitude of</p>\n',
11706                        type: 'p5.Vector'
11707                      }
11708                    ],
11709                    static: 1
11710                  }
11711                ]
11712              },
11713              magSq: {
11714                name: 'magSq',
11715                class: 'p5.Vector',
11716                module: 'Math'
11717              },
11718              dot: {
11719                name: 'dot',
11720                class: 'p5.Vector',
11721                module: 'Math',
11722                overloads: [
11723                  {
11724                    params: [
11725                      {
11726                        name: 'x',
11727                        description: '<p>x component of the vector</p>\n',
11728                        type: 'Number'
11729                      },
11730                      {
11731                        name: 'y',
11732                        description: '<p>y component of the vector</p>\n',
11733                        type: 'Number',
11734                        optional: true
11735                      },
11736                      {
11737                        name: 'z',
11738                        description: '<p>z component of the vector</p>\n',
11739                        type: 'Number',
11740                        optional: true
11741                      }
11742                    ]
11743                  },
11744                  {
11745                    params: [
11746                      {
11747                        name: 'value',
11748                        description:
11749                          '<p>value component of the vector or a <a href="#/p5.Vector">p5.Vector</a></p>\n',
11750                        type: 'p5.Vector'
11751                      }
11752                    ]
11753                  },
11754                  {
11755                    params: [
11756                      {
11757                        name: 'v1',
11758                        description:
11759                          '<p>the first <a href="#/p5.Vector">p5.Vector</a></p>\n',
11760                        type: 'p5.Vector'
11761                      },
11762                      {
11763                        name: 'v2',
11764                        description:
11765                          '<p>the second <a href="#/p5.Vector">p5.Vector</a></p>\n',
11766                        type: 'p5.Vector'
11767                      }
11768                    ],
11769                    static: 1
11770                  }
11771                ]
11772              },
11773              cross: {
11774                name: 'cross',
11775                class: 'p5.Vector',
11776                module: 'Math',
11777                overloads: [
11778                  {
11779                    params: [
11780                      {
11781                        name: 'v',
11782                        description:
11783                          '<p><a href="#/p5.Vector">p5.Vector</a> to be crossed</p>\n',
11784                        type: 'p5.Vector'
11785                      }
11786                    ]
11787                  },
11788                  {
11789                    params: [
11790                      {
11791                        name: 'v1',
11792                        description:
11793                          '<p>the first <a href="#/p5.Vector">p5.Vector</a></p>\n',
11794                        type: 'p5.Vector'
11795                      },
11796                      {
11797                        name: 'v2',
11798                        description:
11799                          '<p>the second <a href="#/p5.Vector">p5.Vector</a></p>\n',
11800                        type: 'p5.Vector'
11801                      }
11802                    ],
11803                    static: 1
11804                  }
11805                ]
11806              },
11807              dist: {
11808                name: 'dist',
11809                class: 'p5.Vector',
11810                module: 'Math',
11811                overloads: [
11812                  {
11813                    params: [
11814                      {
11815                        name: 'v',
11816                        description:
11817                          '<p>the x, y, and z coordinates of a <a href="#/p5.Vector">p5.Vector</a></p>\n',
11818                        type: 'p5.Vector'
11819                      }
11820                    ]
11821                  },
11822                  {
11823                    params: [
11824                      {
11825                        name: 'v1',
11826                        description:
11827                          '<p>the first <a href="#/p5.Vector">p5.Vector</a></p>\n',
11828                        type: 'p5.Vector'
11829                      },
11830                      {
11831                        name: 'v2',
11832                        description:
11833                          '<p>the second <a href="#/p5.Vector">p5.Vector</a></p>\n',
11834                        type: 'p5.Vector'
11835                      }
11836                    ],
11837                    static: 1
11838                  }
11839                ]
11840              },
11841              normalize: {
11842                name: 'normalize',
11843                class: 'p5.Vector',
11844                module: 'Math'
11845              },
11846              limit: {
11847                name: 'limit',
11848                params: [
11849                  {
11850                    name: 'max',
11851                    description: '<p>the maximum magnitude for the vector</p>\n',
11852                    type: 'Number'
11853                  }
11854                ],
11855                class: 'p5.Vector',
11856                module: 'Math'
11857              },
11858              setMag: {
11859                name: 'setMag',
11860                params: [
11861                  {
11862                    name: 'len',
11863                    description: '<p>the new length for this vector</p>\n',
11864                    type: 'Number'
11865                  }
11866                ],
11867                class: 'p5.Vector',
11868                module: 'Math'
11869              },
11870              heading: {
11871                name: 'heading',
11872                class: 'p5.Vector',
11873                module: 'Math'
11874              },
11875              setHeading: {
11876                name: 'setHeading',
11877                params: [
11878                  {
11879                    name: 'angle',
11880                    description: '<p>the angle of rotation</p>\n',
11881                    type: 'Number'
11882                  }
11883                ],
11884                class: 'p5.Vector',
11885                module: 'Math'
11886              },
11887              rotate: {
11888                name: 'rotate',
11889                params: [
11890                  {
11891                    name: 'angle',
11892                    description: '<p>the angle of rotation</p>\n',
11893                    type: 'Number'
11894                  }
11895                ],
11896                class: 'p5.Vector',
11897                module: 'Math'
11898              },
11899              angleBetween: {
11900                name: 'angleBetween',
11901                params: [
11902                  {
11903                    name: 'value',
11904                    description:
11905                      '<p>the x, y, and z components of a <a href="#/p5.Vector">p5.Vector</a></p>\n',
11906                    type: 'p5.Vector'
11907                  }
11908                ],
11909                class: 'p5.Vector',
11910                module: 'Math'
11911              },
11912              lerp: {
11913                name: 'lerp',
11914                class: 'p5.Vector',
11915                module: 'Math',
11916                overloads: [
11917                  {
11918                    params: [
11919                      {
11920                        name: 'x',
11921                        description: '<p>the x component</p>\n',
11922                        type: 'Number'
11923                      },
11924                      {
11925                        name: 'y',
11926                        description: '<p>the y component</p>\n',
11927                        type: 'Number'
11928                      },
11929                      {
11930                        name: 'z',
11931                        description: '<p>the z component</p>\n',
11932                        type: 'Number'
11933                      },
11934                      {
11935                        name: 'amt',
11936                        description:
11937                          '<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n',
11938                        type: 'Number'
11939                      }
11940                    ],
11941                    chainable: 1
11942                  },
11943                  {
11944                    params: [
11945                      {
11946                        name: 'v',
11947                        description:
11948                          '<p>the <a href="#/p5.Vector">p5.Vector</a> to lerp to</p>\n',
11949                        type: 'p5.Vector'
11950                      },
11951                      {
11952                        name: 'amt',
11953                        description: '',
11954                        type: 'Number'
11955                      }
11956                    ],
11957                    chainable: 1
11958                  },
11959                  {
11960                    params: [
11961                      {
11962                        name: 'v1',
11963                        description: '',
11964                        type: 'p5.Vector'
11965                      },
11966                      {
11967                        name: 'v2',
11968                        description: '',
11969                        type: 'p5.Vector'
11970                      },
11971                      {
11972                        name: 'amt',
11973                        description: '',
11974                        type: 'Number'
11975                      },
11976                      {
11977                        name: 'target',
11978                        description: '<p>the vector to receive the result (Optional)</p>\n',
11979                        type: 'p5.Vector',
11980                        optional: true
11981                      }
11982                    ],
11983                    static: 1
11984                  }
11985                ]
11986              },
11987              reflect: {
11988                name: 'reflect',
11989                params: [
11990                  {
11991                    name: 'surfaceNormal',
11992                    description:
11993                      '<p>the <a href="#/p5.Vector">p5.Vector</a> to reflect about, will be normalized by this method</p>\n',
11994                    type: 'p5.Vector'
11995                  }
11996                ],
11997                class: 'p5.Vector',
11998                module: 'Math'
11999              },
12000              array: {
12001                name: 'array',
12002                class: 'p5.Vector',
12003                module: 'Math'
12004              },
12005              equals: {
12006                name: 'equals',
12007                class: 'p5.Vector',
12008                module: 'Math',
12009                overloads: [
12010                  {
12011                    params: [
12012                      {
12013                        name: 'x',
12014                        description: '<p>the x component of the vector</p>\n',
12015                        type: 'Number',
12016                        optional: true
12017                      },
12018                      {
12019                        name: 'y',
12020                        description: '<p>the y component of the vector</p>\n',
12021                        type: 'Number',
12022                        optional: true
12023                      },
12024                      {
12025                        name: 'z',
12026                        description: '<p>the z component of the vector</p>\n',
12027                        type: 'Number',
12028                        optional: true
12029                      }
12030                    ]
12031                  },
12032                  {
12033                    params: [
12034                      {
12035                        name: 'value',
12036                        description: '<p>the vector to compare</p>\n',
12037                        type: 'p5.Vector|Array'
12038                      }
12039                    ]
12040                  }
12041                ]
12042              },
12043              fromAngle: {
12044                name: 'fromAngle',
12045                params: [
12046                  {
12047                    name: 'angle',
12048                    description:
12049                      '<p>the desired angle, in radians (unaffected by <a href="#/p5/angleMode">angleMode</a>)</p>\n',
12050                    type: 'Number'
12051                  },
12052                  {
12053                    name: 'length',
12054                    description: '<p>the length of the new vector (defaults to 1)</p>\n',
12055                    type: 'Number',
12056                    optional: true
12057                  }
12058                ],
12059                class: 'p5.Vector',
12060                module: 'Math'
12061              },
12062              fromAngles: {
12063                name: 'fromAngles',
12064                params: [
12065                  {
12066                    name: 'theta',
12067                    description: '<p>the polar angle, in radians (zero is up)</p>\n',
12068                    type: 'Number'
12069                  },
12070                  {
12071                    name: 'phi',
12072                    description:
12073                      '<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n',
12074                    type: 'Number'
12075                  },
12076                  {
12077                    name: 'length',
12078                    description: '<p>the length of the new vector (defaults to 1)</p>\n',
12079                    type: 'Number',
12080                    optional: true
12081                  }
12082                ],
12083                class: 'p5.Vector',
12084                module: 'Math'
12085              },
12086              random2D: {
12087                name: 'random2D',
12088                class: 'p5.Vector',
12089                module: 'Math'
12090              },
12091              random3D: {
12092                name: 'random3D',
12093                class: 'p5.Vector',
12094                module: 'Math'
12095              }
12096            },
12097            'p5.Font': {
12098              font: {
12099                name: 'font',
12100                class: 'p5.Font',
12101                module: 'Typography'
12102              },
12103              textBounds: {
12104                name: 'textBounds',
12105                params: [
12106                  {
12107                    name: 'line',
12108                    description: '<p>a line of text</p>\n',
12109                    type: 'String'
12110                  },
12111                  {
12112                  
12112  name: 'x',
12113                    description: '<p>x-position</p>\n',
12114                    type: 'Number'
12115                  },
12116                  {
12117                    name: 'y',
12118                    description: '<p>y-position</p>\n',
12119                    type: 'Number'
12120                  },
12121                  {
12122                    name: 'fontSize',
12123                    description: '<p>font size to use (optional) Default is 12.</p>\n',
12124                    type: 'Number',
12125                    optional: true
12126                  },
12127                  {
12128                    name: 'options',
12129                    description:
12130                      "<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n",
12131                    type: 'Object',
12132                    optional: true
12133                  }
12134                ],
12135                class: 'p5.Font',
12136                module: 'Typography'
12137              },
12138              textToPoints: {
12139                name: 'textToPoints',
12140                params: [
12141                  {
12142                    name: 'txt',
12143                    description: '<p>a line of text</p>\n',
12144                    type: 'String'
12145                  },
12146                  {
12147                    name: 'x',
12148                    description: '<p>x-position</p>\n',
12149                    type: 'Number'
12150                  },
12151                  {
12152                    name: 'y',
12153                    description: '<p>y-position</p>\n',
12154                    type: 'Number'
12155                  },
12156                  {
12157                    name: 'fontSize',
12158                    description: '<p>font size to use (optional)</p>\n',
12159                    type: 'Number'
12160                  },
12161                  {
12162                    name: 'options',
12163                    description:
12164                      '<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n',
12165                    type: 'Object',
12166                    optional: true
12167                  }
12168                ],
12169                class: 'p5.Font',
12170                module: 'Typography'
12171              }
12172            },
12173            'p5.Camera': {
12174              perspective: {
12175                name: 'perspective',
12176                class: 'p5.Camera',
12177                module: 'Lights, Camera'
12178              },
12179              ortho: {
12180                name: 'ortho',
12181                class: 'p5.Camera',
12182                module: 'Lights, Camera'
12183              },
12184              frustum: {
12185                name: 'frustum',
12186                class: 'p5.Camera',
12187                module: 'Lights, Camera'
12188              },
12189              pan: {
12190                name: 'pan',
12191                params: [
12192                  {
12193                    name: 'angle',
12194                    description:
12195                      '<p>amount to rotate camera in current\n<a href="#/p5/angleMode">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n',
12196                    type: 'Number'
12197                  }
12198                ],
12199                class: 'p5.Camera',
12200                module: 'Lights, Camera'
12201              },
12202              tilt: {
12203                name: 'tilt',
12204                params: [
12205                  {
12206                    name: 'angle',
12207                    description:
12208                      '<p>amount to rotate camera in current\n<a href="#/p5/angleMode">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n',
12209                    type: 'Number'
12210                  }
12211                ],
12212                class: 'p5.Camera',
12213                module: 'Lights, Camera'
12214              },
12215              lookAt: {
12216                name: 'lookAt',
12217                params: [
12218                  {
12219                    name: 'x',
12220                    description: '<p>x position of a point in world space</p>\n',
12221                    type: 'Number'
12222                  },
12223                  {
12224                    name: 'y',
12225                    description: '<p>y position of a point in world space</p>\n',
12226                    type: 'Number'
12227                  },
12228                  {
12229                    name: 'z',
12230                    description: '<p>z position of a point in world space</p>\n',
12231                    type: 'Number'
12232                  }
12233                ],
12234                class: 'p5.Camera',
12235                module: 'Lights, Camera'
12236              },
12237              camera: {
12238                name: 'camera',
12239                class: 'p5.Camera',
12240                module: 'Lights, Camera'
12241              },
12242              move: {
12243                name: 'move',
12244                params: [
12245                  {
12246                    name: 'x',
12247                    description: "<p>amount to move along camera's left-right axis</p>\n",
12248                    type: 'Number'
12249                  },
12250                  {
12251                    name: 'y',
12252                    description: "<p>amount to move along camera's up-down axis</p>\n",
12253                    type: 'Number'
12254                  },
12255                  {
12256                    name: 'z',
12257                    description:
12258                      "<p>amount to move along camera's forward-backward axis</p>\n",
12259                    type: 'Number'
12260                  }
12261                ],
12262                class: 'p5.Camera',
12263                module: 'Lights, Camera'
12264              },
12265              setPosition: {
12266                name: 'setPosition',
12267                params: [
12268                  {
12269                    name: 'x',
12270                    description: '<p>x position of a point in world space</p>\n',
12271                    type: 'Number'
12272                  },
12273                  {
12274                    name: 'y',
12275                    description: '<p>y position of a point in world space</p>\n',
12276                    type: 'Number'
12277                  },
12278                  {
12279                    name: 'z',
12280                    description: '<p>z position of a point in world space</p>\n',
12281                    type: 'Number'
12282                  }
12283                ],
12284                class: 'p5.Camera',
12285                module: 'Lights, Camera'
12286              }
12287            },
12288            'p5.Geometry': {
12289              computeFaces: {
12290                name: 'computeFaces',
12291                class: 'p5.Geometry',
12292                module: 'Lights, Camera'
12293              },
12294              computeNormals: {
12295                name: 'computeNormals',
12296                class: 'p5.Geometry',
12297                module: 'Lights, Camera'
12298              },
12299              averageNormals: {
12300                name: 'averageNormals',
12301                class: 'p5.Geometry',
12302                module: 'Lights, Camera'
12303              },
12304              averagePoleNormals: {
12305                name: 'averagePoleNormals',
12306                class: 'p5.Geometry',
12307                module: 'Lights, Camera'
12308              },
12309              normalize: {
12310                name: 'normalize',
12311                class: 'p5.Geometry',
12312                module: 'Lights, Camera'
12313              }
12314            },
12315            'p5.Shader': {
12316              setUniform: {
12317                name: 'setUniform',
12318                params: [
12319                  {
12320                    name: 'uniformName',
12321                    description: '<p>the name of the uniform in the\nshader program</p>\n',
12322                    type: 'String'
12323                  },
12324                  {
12325                    name: 'data',
12326                    description:
12327                      '<p>the data to be associated\nwith that uniform; type varies (could be a single numerical value, array,\nmatrix, or texture / sampler reference)</p>\n',
12328                    type: 'Object|Number|Boolean|Number[]'
12329                  }
12330                ],
12331                class: 'p5.Shader',
12332                module: 'Lights, Camera'
12333              }
12334            },
12335            'p5.sound': {
12336              getMasterVolume: {
12337                name: 'getMasterVolume',
12338                class: 'p5.sound',
12339                module: 'p5.sound'
12340              },
12341              masterVolume: {
12342                name: 'masterVolume',
12343                params: [
12344                  {
12345                    name: 'volume',
12346                    description:
12347                      '<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n',
12348                    type: 'Number|Object'
12349                  },
12350                  {
12351                    name: 'rampTime',
12352                    description: '<p>Fade for t seconds</p>\n',
12353                    type: 'Number',
12354                    optional: true
12355                  },
12356                  {
12357                    name: 'timeFromNow',
12358                    description:
12359                      '<p>Schedule this event to happen at\n                               t seconds 
12359in the future</p>\n',
12360                    type: 'Number',
12361                    optional: true
12362                  }
12363                ],
12364                class: 'p5.sound',
12365                module: 'p5.sound'
12366              },
12367              soundOut: {
12368                name: 'soundOut',
12369                class: 'p5.sound',
12370                module: 'p5.sound'
12371              }
12372            },
12373            'p5.Effect': {
12374              amp: {
12375                name: 'amp',
12376                params: [
12377                  {
12378                    name: 'vol',
12379                    description: '<p>amplitude between 0 and 1.0</p>\n',
12380                    type: 'Number',
12381                    optional: true
12382                  },
12383                  {
12384                    name: 'rampTime',
12385                    description: '<p>create a fade that lasts until rampTime</p>\n',
12386                    type: 'Number',
12387                    optional: true
12388                  },
12389                  {
12390                    name: 'tFromNow',
12391                    description:
12392                      '<p>schedule this event to happen in tFromNow seconds</p>\n',
12393                    type: 'Number',
12394                    optional: true
12395                  }
12396                ],
12397                class: 'p5.Effect',
12398                module: 'p5.sound'
12399              },
12400              chain: {
12401                name: 'chain',
12402                params: [
12403                  {
12404                    name: 'arguments',
12405                    description: '<p>Chain together multiple sound objects</p>\n',
12406                    type: 'Object',
12407                    optional: true
12408                  }
12409                ],
12410                class: 'p5.Effect',
12411                module: 'p5.sound'
12412              },
12413              drywet: {
12414                name: 'drywet',
12415                params: [
12416                  {
12417                    name: 'fade',
12418                    description: '<p>The desired drywet value (0 - 1.0)</p>\n',
12419                    type: 'Number',
12420                    optional: true
12421                  }
12422                ],
12423                class: 'p5.Effect',
12424                module: 'p5.sound'
12425              },
12426              connect: {
12427                name: 'connect',
12428                params: [
12429                  {
12430                    name: 'unit',
12431                    description: '',
12432                    type: 'Object'
12433                  }
12434                ],
12435                class: 'p5.Effect',
12436                module: 'p5.sound'
12437              },
12438              disconnect: {
12439                name: 'disconnect',
12440                class: 'p5.Effect',
12441                module: 'p5.sound'
12442              }
12443            },
12444            'p5.Filter': {
12445              biquadFilter: {
12446                name: 'biquadFilter',
12447                class: 'p5.Filter',
12448                module: 'p5.sound'
12449              },
12450              process: {
12451                name: 'process',
12452                params: [
12453                  {
12454                    name: 'Signal',
12455                    description: '<p>An object that outputs audio</p>\n',
12456                    type: 'Object'
12457                  },
12458                  {
12459                    name: 'freq',
12460                    description: '<p>Frequency in Hz, from 10 to 22050</p>\n',
12461                    type: 'Number',
12462                    optional: true
12463                  },
12464                  {
12465                    name: 'res',
12466                    description:
12467                      '<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n',
12468                    type: 'Number',
12469                    optional: true
12470                  }
12471                ],
12472                class: 'p5.Filter',
12473                module: 'p5.sound'
12474              },
12475              set: {
12476                name: 'set',
12477                params: [
12478                  {
12479                    name: 'freq',
12480                    description: '<p>Frequency in Hz, from 10 to 22050</p>\n',
12481                    type: 'Number',
12482                    optional: true
12483                  },
12484                  {
12485                    name: 'res',
12486                    description: '<p>Resonance (Q) from 0.001 to 1000</p>\n',
12487                    type: 'Number',
12488                    optional: true
12489                  },
12490                  {
12491                    name: 'timeFromNow',
12492                    description:
12493                      '<p>schedule this event to happen\n                              seconds from now</p>\n',
12494                    type: 'Number',
12495                    optional: true
12496                  }
12497                ],
12498                class: 'p5.Filter',
12499                module: 'p5.sound'
12500              },
12501              freq: {
12502                name: 'freq',
12503                params: [
12504                  {
12505                    name: 'freq',
12506                    description: '<p>Filter Frequency</p>\n',
12507                    type: 'Number'
12508                  },
12509                  {
12510                    name: 'timeFromNow',
12511                    description:
12512                      '<p>schedule this event to happen\n                              seconds from now</p>\n',
12513                    type: 'Number',
12514                    optional: true
12515                  }
12516                ],
12517                class: 'p5.Filter',
12518                module: 'p5.sound'
12519              },
12520              res: {
12521                name: 'res',
12522                params: [
12523                  {
12524                    name: 'res',
12525                    description:
12526                      '<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n',
12527                    type: 'Number'
12528                  },
12529                  {
12530                    name: 'timeFromNow',
12531                    description:
12532                      '<p>schedule this event to happen\n                              seconds from now</p>\n',
12533                    type: 'Number',
12534                    optional: true
12535                  }
12536                ],
12537                class: 'p5.Filter',
12538                module: 'p5.sound'
12539              },
12540              gain: {
12541                name: 'gain',
12542                params: [
12543                  {
12544                    name: 'gain',
12545                    description: '',
12546                    type: 'Number'
12547                  }
12548                ],
12549                class: 'p5.Filter',
12550                module: 'p5.sound'
12551              },
12552              toggle: {
12553                name: 'toggle',
12554                class: 'p5.Filter',
12555                module: 'p5.sound'
12556              },
12557              setType: {
12558                name: 'setType',
12559                params: [
12560                  {
12561                    name: 't',
12562                    description: '',
12563                    type: 'String'
12564                  }
12565                ],
12566                class: 'p5.Filter',
12567                module: 'p5.sound'
12568              }
12569            },
12570            'p5.Oscillator': {
12571              start: {
12572                name: 'start',
12573                params: [
12574                  {
12575                    name: 'time',
12576                    description: '<p>startTime in seconds from now.</p>\n',
12577                    type: 'Number',
12578                    optional: true
12579                  },
12580                  {
12581                    name: 'frequency',
12582                    description: '<p>frequency in Hz.</p>\n',
12583                    type: 'Number',
12584                    optional: true
12585                  }
12586                ],
12587                class: 'p5.Oscillator',
12588                module: 'p5.sound'
12589              },
12590              stop: {
12591                name: 'stop',
12592                params: [
12593                  {
12594                    name: 'secondsFromNow',
12595                    description: '<p>Time, in seconds from now.</p>\n',
12596                    type: 'Number'
12597                  }
12598                ],
12599                class: 'p5.Oscillator',
12600                module: 'p5.sound'
12601              },
12602              amp: {
12603                name: 'amp',
12604                params: [
12605                  {
12606                    name: 'vol',
12607                    description:
12608                      '<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n',
12609                    type: 'Number|Object'
12610                  },
12611                  {
12612                    name: 'rampTime',
12613                    description: '<p>create a fade that lasts rampTime</p>\n',
12614                    type: 'Number',
12615                    optional: true
12616                  },
12617                  {
12618                    name: 'timeFromNow',
12619                    description:
12620                      '<p>schedule this event to happen\n                              seconds from now</p>\n',
12621                    type: 'Number',
12622                    optional: true
12623                  }
12624                ],
12625                class: 'p5.Oscillator',
12626                module: 'p5.sound'
12627              },
12628              freq: {
12629                name: 'freq',
12630                params: [
12631                  {
12632                    name: 'Frequency',
12633                    description:
12634                      '<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n',
12635                    type: 'Number|Object'
12636                  },
12637                  {
12638                    name: 'rampTime',
12639                    description: '<p>Ramp time (in seconds)</p>\n',
12640                    type: 'Number',
12641                    optional: true
12642                  },
12643                  {
12644                    name: 'timeFromNow',
12645                    description:
12646                      '<p>Schedule this event to happen\n                                 at x seconds from now</p>\n',
12647                    type: 'Number',
12648                    optional: true
12649                  }
12650                ],
12651                class: 'p5.Oscillator',
12652                module: 'p5.sound'
12653              },
12654              setType: {
12655                name: 'setType',
12656                params: [
12657                  {
12658                    name: 'type',
12659                    description: "<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
12660                    type: 'String'
12661                  }
12662                ],
12663                class: 'p5.Oscillator',
12664                module: 'p5.sound'
12665              },
12666              connect: {
12667                name: 'connect',
12668                params: [
12669                  {
12670                    name: 'unit',
12671                    description: '<p>A p5.sound or Web Audio object</p>\n',
12672                    type: 'Object'
12673                  }
12674                ],
12675                class: 'p5.Oscillator',
12676                module: 'p5.sound'
12677              },
12678              disconnect: {
12679                name: 'disconnect',
12680                class: 'p5.Oscillator',
12681                module: 'p5.sound'
12682              },
12683              pan: {
12684                name: 'pan',
12685                params: [
12686                  {
12687                    name: 'panning',
12688                    description: '<p>Number between -1 and 1</p>\n',
12689                    type: 'Number'
12690                  },
12691                  {
12692                    name: 'timeFromNow',
12693                    description:
12694                      '<p>schedule this event to happen\n                              seconds from now</p>\n',
12695                    type: 'Number'
12696                  }
12697                ],
12698                class: 'p5.Oscillator',
12699                module: 'p5.sound'
12700              },
12701              phase: {
12702                name: 'phase',
12703                params: [
12704                  {
12705                    name: 'phase',
12706                    description: '<p>float between 0.0 and 1.0</p>\n',
12707                    type: 'Number'
12708                  }
12709                ],
12710                class: 'p5.Oscillator',
12711                module: 'p5.sound'
12712              },
12713              add: {
12714                name: 'add',
12715                params: [
12716                  {
12717                    name: 'number',
12718                    description: '<p>Constant number to add</p>\n',
12719                    type: 'Number'
12720                  }
12721                ],
12722                class: 'p5.Oscillator',
12723                module: 'p5.sound'
12724              },
12725              mult: {
12726                name: 'mult',
12727                params: [
12728                  {
12729                    name: 'number',
12730                    description: '<p>Constant number to multiply</p>\n',
12731                    type: 'Number'
12732                  }
12733                ],
12734                class: 'p5.Oscillator',
12735                module: 'p5.sound'
12736              },
12737              scale: {
12738                name: 'scale',
12739                params: [
12740                  {
12741                    name: 'inMin',
12742                    description: '<p>input range minumum</p>\n',
12743                    type: 'Number'
12744                  },
12745                  {
12746                    name: 'inMax',
12747                    description: '<p>input range maximum</p>\n',
12748                    type: 'Number'
12749                  },
12750                  {
12751                    name: 'outMin',
12752                    description: '<p>input range minumum</p>\n',
12753                    type: 'Number'
12754                  },
12755                  {
12756                    name: 'outMax',
12757                    description: '<p>input range maximum</p>\n',
12758                    type: 'Number'
12759                  }
12760                ],
12761                class: 'p5.Oscillator',
12762                module: 'p5.sound'
12763              }
12764            },
12765            'p5.MonoSynth': {
12766              play: {
12767                name: 'play',
12768                params: [
12769                  {
12770                    name: 'note',
12771                    description:
12772                      '<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format ("C4", "Eb3"...etc")\n                               See <a href = "https://github.com/Tonejs/Tone.js/wiki/Instruments">\n                               Tone</a>. Defaults to 440 hz.</p>\n',
12773                    type: 'String | Number'
12774                  },
12775                  {
12776                    name: 'velocity',
12777                    description:
12778                      '<p>velocity of the note to play (ranging from 0 to 1)</p>\n',
12779                    type: 'Number',
12780                    optional: true
12781                  },
12782                  {
12783                    name: 'secondsFromNow',
12784                    description: '<p>time from now (in seconds) at which to play</p>\n',
12785                    type: 'Number',
12786                    optional: true
12787                  },
12788                  {
12789                    name: 'sustainTime',
12790                    description:
12791                      '<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n',
12792                    type: 'Number',
12793                    optional: true
12794                  }
12795                ],
12796                class: 'p5.MonoSynth',
12797                module: 'p5.sound'
12798              },
12799              triggerAttack: {
12800                params: [
12801                  {
12802                    name: 'note',
12803                    description:
12804                      '<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format ("C4", "Eb3"...etc")\n                               See <a href = "https://github.com/Tonejs/Tone.js/wiki/Instruments">\n                               Tone</a>. Defaults to 440 hz</p>\n',
12805                    type: 'String | Number'
12806                  },
12807                  {
12808                    name: 'velocity',
12809                    description:
12810                      '<p>velocity of the note to play (ranging from 0 to 1)</p>\n',
12811                    type: 'Number',
12812                    optional: true
12813                  },
12814                  {
12815                    name: 'secondsFromNow',
12816                    description: '<p>time from now (in seconds) at which to play</p>\n',
12817                    type: 'Number',
12818                    optional: true
12819                  }
12820                ],
12821                name: 'triggerAttack',
12822                class: 'p5.MonoSynth',
12823                module: 'p5.sound'
12824              },
12825              triggerRelease: {
12826                params: [
12827                  {
12828                    name: 'secondsFromNo
12828w',
12829                    description: '<p>time to trigger the release</p>\n',
12830                    type: 'Number'
12831                  }
12832                ],
12833                name: 'triggerRelease',
12834                class: 'p5.MonoSynth',
12835                module: 'p5.sound'
12836              },
12837              setADSR: {
12838                name: 'setADSR',
12839                params: [
12840                  {
12841                    name: 'attackTime',
12842                    description:
12843                      '<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n',
12844                    type: 'Number'
12845                  },
12846                  {
12847                    name: 'decayTime',
12848                    description:
12849                      '<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n',
12850                    type: 'Number',
12851                    optional: true
12852                  },
12853                  {
12854                    name: 'susRatio',
12855                    description:
12856                      '<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n',
12857                    type: 'Number',
12858                    optional: true
12859                  },
12860                  {
12861                    name: 'releaseTime',
12862                    description: '<p>Time in seconds from now (defaults to 0)</p>\n',
12863                    type: 'Number',
12864                    optional: true
12865                  }
12866                ],
12867                class: 'p5.MonoSynth',
12868                module: 'p5.sound'
12869              },
12870              attack: {
12871                name: 'attack',
12872                class: 'p5.MonoSynth',
12873                module: 'p5.sound'
12874              },
12875              decay: {
12876                name: 'decay',
12877                class: 'p5.MonoSynth',
12878                module: 'p5.sound'
12879              },
12880              sustain: {
12881                name: 'sustain',
12882                class: 'p5.MonoSynth',
12883                module: 'p5.sound'
12884              },
12885              release: {
12886                name: 'release',
12887                class: 'p5.MonoSynth',
12888                module: 'p5.sound'
12889              },
12890              amp: {
12891                name: 'amp',
12892                params: [
12893                  {
12894                    name: 'vol',
12895                    description: '<p>desired volume</p>\n',
12896                    type: 'Number'
12897                  },
12898                  {
12899                    name: 'rampTime',
12900                    description: '<p>Time to reach new volume</p>\n',
12901                    type: 'Number',
12902                    optional: true
12903                  }
12904                ],
12905                class: 'p5.MonoSynth',
12906                module: 'p5.sound'
12907              },
12908              connect: {
12909                name: 'connect',
12910                params: [
12911                  {
12912                    name: 'unit',
12913                    description: '<p>A p5.sound or Web Audio object</p>\n',
12914                    type: 'Object'
12915                  }
12916                ],
12917                class: 'p5.MonoSynth',
12918                module: 'p5.sound'
12919              },
12920              disconnect: {
12921                name: 'disconnect',
12922                class: 'p5.MonoSynth',
12923                module: 'p5.sound'
12924              },
12925              dispose: {
12926                name: 'dispose',
12927                class: 'p5.MonoSynth',
12928                module: 'p5.sound'
12929              }
12930            },
12931            'p5.AudioVoice': {
12932              connect: {
12933                name: 'connect',
12934                params: [
12935                  {
12936                    name: 'unit',
12937                    description: '',
12938                    type: 'Object'
12939                  }
12940                ],
12941                class: 'p5.AudioVoice',
12942                module: 'p5.sound'
12943              },
12944              disconnect: {
12945                name: 'disconnect',
12946                class: 'p5.AudioVoice',
12947                module: 'p5.sound'
12948              }
12949            },
12950            'p5.PolySynth': {
12951              notes: {
12952                name: 'notes',
12953                class: 'p5.PolySynth',
12954                module: 'p5.sound'
12955              },
12956              polyvalue: {
12957                name: 'polyvalue',
12958                class: 'p5.PolySynth',
12959                module: 'p5.sound'
12960              },
12961              AudioVoice: {
12962                name: 'AudioVoice',
12963                class: 'p5.PolySynth',
12964                module: 'p5.sound'
12965              },
12966              play: {
12967                name: 'play',
12968                params: [
12969                  {
12970                    name: 'note',
12971                    description:
12972                      '<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n',
12973                    type: 'Number',
12974                    optional: true
12975                  },
12976                  {
12977                    name: 'velocity',
12978                    description:
12979                      '<p>velocity of the note to play (ranging from 0 to 1)</p>\n',
12980                    type: 'Number',
12981                    optional: true
12982                  },
12983                  {
12984                    name: 'secondsFromNow',
12985                    description: '<p>time from now (in seconds) at which to play</p>\n',
12986                    type: 'Number',
12987                    optional: true
12988                  },
12989                  {
12990                    name: 'sustainTime',
12991                    description: '<p>time to sustain before releasing the envelope</p>\n',
12992                    type: 'Number',
12993                    optional: true
12994                  }
12995                ],
12996                class: 'p5.PolySynth',
12997                module: 'p5.sound'
12998              },
12999              noteADSR: {
13000                name: 'noteADSR',
13001                params: [
13002                  {
13003                    name: 'note',
13004                    description: '<p>Midi note on which ADSR should be set.</p>\n',
13005                    type: 'Number',
13006                    optional: true
13007                  },
13008                  {
13009                    name: 'attackTime',
13010                    description:
13011                      '<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n',
13012                    type: 'Number',
13013                    optional: true
13014                  },
13015                  {
13016                    name: 'decayTime',
13017                    description:
13018                      '<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n',
13019                    type: 'Number',
13020                    optional: true
13021                  },
13022                  {
13023                    name: 'susRatio',
13024                    description:
13025                      '<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n',
13026                    type: 'Number',
13027                    optional: true
13028                  },
13029                  {
13030                    name: 'releaseTime',
13031                    description: '<p>Time in seconds from now (defaults to 0)</p>\n',
13032                    type: 'Number',
13033                    optional: true
13034                  }
13035                ],
13036                class: 'p5.PolySynth',
13037                module: 'p5.sound'
13038              },
13039              setADSR: {
13040                name: 'setADSR',
13041                params: [
13042                  {
13043                    name: 'attackTime',
13044                    description:
13045                      '<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n',
13046                    type: 'Number',
13047                    optional: true
13048                  },
13049                  {
13050                    name: 'decayTime',
13051                    description:
13052                      '<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n',
13053                    type: 'Number',
13054                    optional: true
13055                  },
13056                  {
13057                    name: 'susRatio',
13058                    description:
13059                      '<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n',
13060                    type: 'Number',
13061                    optional: true
13062                  },
13063                  {
13064                    name: 'releaseTime',
13065                    description: '<p>Time in seconds from now (defaults to 0)</p>\n',
13066                    type: 'Number',
13067                    optional: true
13068                  }
13069                ],
13070                class: 'p5.PolySynth',
13071                module: 'p5.sound'
13072              },
13073              noteAttack: {
13074                name: 'noteAttack',
13075                params: [
13076                  {
13077                    name: 'note',
13078                    description: '<p>midi note on which attack should be triggered.</p>\n',
13079                    type: 'Number',
13080                    optional: true
13081                  },
13082                  {
13083                    name: 'velocity',
13084                    description:
13085                      '<p>velocity of the note to play (ranging from 0 to 1)/</p>\n',
13086                    type: 'Number',
13087                    optional: true
13088                  },
13089                  {
13090                    name: 'secondsFromNow',
13091                    description: '<p>time from now (in seconds)</p>\n',
13092                    type: 'Number',
13093                    optional: true
13094                  }
13095                ],
13096                class: 'p5.PolySynth',
13097                module: 'p5.sound'
13098              },
13099              noteRelease: {
13100                name: 'noteRelease',
13101                params: [
13102                  {
13103                    name: 'note',
13104                    description:
13105                      '<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n',
13106                    type: 'Number',
13107                    optional: true
13108                  },
13109                  {
13110                    name: 'secondsFromNow',
13111                    description: '<p>time to trigger the release</p>\n',
13112                    type: 'Number',
13113                    optional: true
13114                  }
13115                ],
13116                class: 'p5.PolySynth',
13117                module: 'p5.sound'
13118              },
13119              connect: {
13120                name: 'connect',
13121                params: [
13122                  {
13123                    name: 'unit',
13124                    description: '<p>A p5.sound or Web Audio object</p>\n',
13125                    type: 'Object'
13126                  }
13127                ],
13128                class: 'p5.PolySynth',
13129                module: 'p5.sound'
13130              },
13131              disconnect: {
13132                name: 'disconnect',
13133                class: 'p5.PolySynth',
13134                module: 'p5.sound'
13135              },
13136              dispose: {
13137                name: 'dispose',
13138                class: 'p5.PolySynth',
13139                module: 'p5.sound'
13140              }
13141            },
13142            'p5.SoundFile': {
13143              isLoaded: {
13144                name: 'isLoaded',
13145                class: 'p5.SoundFile',
13146                module: 'p5.sound'
13147              },
13148              play: {
13149                name: 'play',
13150                params: [
13151                  {
13152                    name: 'startTime',
13153                    description:
13154                      '<p>(optional) schedule playback to start (in seconds from now).</p>\n',
13155                    type: 'Number',
13156                    optional: true
13157                  },
13158                  {
13159                    name: 'rate',
13160                    description: '<p>(optional) playback rate</p>\n',
13161                    type: 'Number',
13162                    optional: true
13163                  },
13164                  {
13165                    name: 'amp',
13166                    description:
13167                      '<p>(optional) amplitude (volume)\n                                    of playback</p>\n',
13168                    type: 'Number',
13169                    optional: true
13170                  },
13171                  {
13172                    name: 'cueStart',
13173                    description: '<p>(optional) cue start time in seconds</p>\n',
13174                    type: 'Number',
13175                    optional: true
13176                  },
13177                  {
13178                    name: 'duration',
13179                    description: '<p>(optional) duration of playback in seconds</p>\n',
13180                    type: 'Number',
13181                    optional: true
13182                  }
13183                ],
13184                class: 'p5.SoundFile',
13185                module: 'p5.sound'
13186              },
13187              playMode: {
13188                name: 'playMode',
13189                params: [
13190                  {
13191                    name: 'str',
13192                    description: "<p>'restart' or 'sustain' or 'untilDone'</p>\n",
13193                    type: 'String'
13194                  }
13195                ],
13196                class: 'p5.SoundFile',
13197                module: 'p5.sound'
13198              },
13199              pause: {
13200                name: 'pause',
13201                params: [
13202                  {
13203                    name: 'startTime',
13204                    description:
13205                      '<p>(optional) schedule event to occur\n                             seconds from now</p>\n',
13206                    type: 'Number',
13207                    optional: true
13208                  }
13209                ],
13210                class: 'p5.SoundFile',
13211                module: 'p5.sound'
13212              },
13213              loop: {
13214                name: 'loop',
13215                params: [
13216                  {
13217                    name: 'startTime',
13218                    description:
13219                      '<p>(optional) schedule event to occur\n                            seconds from now</p>\n',
13220                    type: 'Number',
13221                    optional: true
13222                  },
13223                  {
13224                    name: 'rate',
13225                    description: '<p>(optional) playback rate</p>\n',
13226                    type: 'Number',
13227                    optional: true
13228                  },
13229                  {
13230                    name: 'amp',
13231                    description: '<p>(optional) playback volume</p>\n',
13232                    type: 'Number',
13233                    optional: true
13234                  },
13235                  {
13236                    name: 'cueLoopStart',
13237                    description: '<p>(optional) startTime in seconds</p>\n',
13238                    type: 'Number',
13239                    optional: true
13240                  },
13241                  {
13242         
13242           name: 'duration',
13243                    description: '<p>(optional) loop duration in seconds</p>\n',
13244                    type: 'Number',
13245                    optional: true
13246                  }
13247                ],
13248                class: 'p5.SoundFile',
13249                module: 'p5.sound'
13250              },
13251              setLoop: {
13252                name: 'setLoop',
13253                params: [
13254                  {
13255                    name: 'Boolean',
13256                    description: '<p>set looping to true or false</p>\n',
13257                    type: 'Boolean'
13258                  }
13259                ],
13260                class: 'p5.SoundFile',
13261                module: 'p5.sound'
13262              },
13263              isLooping: {
13264                name: 'isLooping',
13265                class: 'p5.SoundFile',
13266                module: 'p5.sound'
13267              },
13268              isPlaying: {
13269                name: 'isPlaying',
13270                class: 'p5.SoundFile',
13271                module: 'p5.sound'
13272              },
13273              isPaused: {
13274                name: 'isPaused',
13275                class: 'p5.SoundFile',
13276                module: 'p5.sound'
13277              },
13278              stop: {
13279                name: 'stop',
13280                params: [
13281                  {
13282                    name: 'startTime',
13283                    description:
13284                      '<p>(optional) schedule event to occur\n                            in seconds from now</p>\n',
13285                    type: 'Number',
13286                    optional: true
13287                  }
13288                ],
13289                class: 'p5.SoundFile',
13290                module: 'p5.sound'
13291              },
13292              setVolume: {
13293                name: 'setVolume',
13294                params: [
13295                  {
13296                    name: 'volume',
13297                    description:
13298                      '<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n',
13299                    type: 'Number|Object'
13300                  },
13301                  {
13302                    name: 'rampTime',
13303                    description: '<p>Fade for t seconds</p>\n',
13304                    type: 'Number',
13305                    optional: true
13306                  },
13307                  {
13308                    name: 'timeFromNow',
13309                    description:
13310                      '<p>Schedule this event to happen at\n                               t seconds in the future</p>\n',
13311                    type: 'Number',
13312                    optional: true
13313                  }
13314                ],
13315                class: 'p5.SoundFile',
13316                module: 'p5.sound'
13317              },
13318              pan: {
13319                name: 'pan',
13320                params: [
13321                  {
13322                    name: 'panValue',
13323                    description: '<p>Set the stereo panner</p>\n',
13324                    type: 'Number',
13325                    optional: true
13326                  },
13327                  {
13328                    name: 'timeFromNow',
13329                    description:
13330                      '<p>schedule this event to happen\n                                seconds from now</p>\n',
13331                    type: 'Number',
13332                    optional: true
13333                  }
13334                ],
13335                class: 'p5.SoundFile',
13336                module: 'p5.sound'
13337              },
13338              getPan: {
13339                name: 'getPan',
13340                class: 'p5.SoundFile',
13341                module: 'p5.sound'
13342              },
13343              rate: {
13344                name: 'rate',
13345                params: [
13346                  {
13347                    name: 'playbackRate',
13348                    description:
13349                      '<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n',
13350                    type: 'Number',
13351                    optional: true
13352                  }
13353                ],
13354                class: 'p5.SoundFile',
13355                module: 'p5.sound'
13356              },
13357              duration: {
13358                name: 'duration',
13359                class: 'p5.SoundFile',
13360                module: 'p5.sound'
13361              },
13362              currentTime: {
13363                name: 'currentTime',
13364                class: 'p5.SoundFile',
13365                module: 'p5.sound'
13366              },
13367              jump: {
13368                name: 'jump',
13369                params: [
13370                  {
13371                    name: 'cueTime',
13372                    description: '<p>cueTime of the soundFile in seconds.</p>\n',
13373                    type: 'Number'
13374                  },
13375                  {
13376                    name: 'duration',
13377                    description: '<p>duration in seconds.</p>\n',
13378                    type: 'Number'
13379                  }
13380                ],
13381                class: 'p5.SoundFile',
13382                module: 'p5.sound'
13383              },
13384              channels: {
13385                name: 'channels',
13386                class: 'p5.SoundFile',
13387                module: 'p5.sound'
13388              },
13389              sampleRate: {
13390                name: 'sampleRate',
13391                class: 'p5.SoundFile',
13392                module: 'p5.sound'
13393              },
13394              frames: {
13395                name: 'frames',
13396                class: 'p5.SoundFile',
13397                module: 'p5.sound'
13398              },
13399              getPeaks: {
13400                name: 'getPeaks',
13401                params: [
13402                  {
13403                    name: 'length',
13404                    description:
13405                      '<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n',
13406                    type: 'Number',
13407                    optional: true
13408                  }
13409                ],
13410                class: 'p5.SoundFile',
13411                module: 'p5.sound'
13412              },
13413              reverseBuffer: {
13414                name: 'reverseBuffer',
13415                class: 'p5.SoundFile',
13416                module: 'p5.sound'
13417              },
13418              onended: {
13419                name: 'onended',
13420                params: [
13421                  {
13422                    name: 'callback',
13423                    description:
13424                      '<p>function to call when the\n                            soundfile has ended.</p>\n',
13425                    type: 'Function'
13426                  }
13427                ],
13428                class: 'p5.SoundFile',
13429                module: 'p5.sound'
13430              },
13431              connect: {
13432                name: 'connect',
13433                params: [
13434                  {
13435                    name: 'object',
13436                    description: '<p>Audio object that accepts an input</p>\n',
13437                    type: 'Object',
13438                    optional: true
13439                  }
13440                ],
13441                class: 'p5.SoundFile',
13442                module: 'p5.sound'
13443              },
13444              disconnect: {
13445                name: 'disconnect',
13446                class: 'p5.SoundFile',
13447                module: 'p5.sound'
13448              },
13449              setPath: {
13450                name: 'setPath',
13451                params: [
13452                  {
13453                    name: 'path',
13454                    description: '<p>path to audio file</p>\n',
13455                    type: 'String'
13456                  },
13457                  {
13458                    name: 'callback',
13459                    description: '<p>Callback</p>\n',
13460                    type: 'Function'
13461                  }
13462                ],
13463                class: 'p5.SoundFile',
13464                module: 'p5.sound'
13465              },
13466              setBuffer: {
13467                name: 'setBuffer',
13468                params: [
13469                  {
13470                    name: 'buf',
13471                    description:
13472                      '<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n',
13473                    type: 'Array'
13474                  }
13475                ],
13476                class: 'p5.SoundFile',
13477                module: 'p5.sound'
13478              },
13479              processPeaks: {
13480                name: 'processPeaks',
13481                params: [
13482                  {
13483                    name: 'callback',
13484                    description: '<p>a function to call once this data is returned</p>\n',
13485                    type: 'Function'
13486                  },
13487                  {
13488                    name: 'initThreshold',
13489                    description: '<p>initial threshold defaults to 0.9</p>\n',
13490                    type: 'Number',
13491                    optional: true
13492                  },
13493                  {
13494                    name: 'minThreshold',
13495                    description: '<p>minimum threshold defaults to 0.22</p>\n',
13496                    type: 'Number',
13497                    optional: true
13498                  },
13499                  {
13500                    name: 'minPeaks',
13501                    description: '<p>minimum number of peaks defaults to 200</p>\n',
13502                    type: 'Number',
13503                    optional: true
13504                  }
13505                ],
13506                class: 'p5.SoundFile',
13507                module: 'p5.sound'
13508              },
13509              addCue: {
13510                name: 'addCue',
13511                params: [
13512                  {
13513                    name: 'time',
13514                    description:
13515                      "<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n",
13516                    type: 'Number'
13517                  },
13518                  {
13519                    name: 'callback',
13520                    description:
13521                      '<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n',
13522                    type: 'Function'
13523                  },
13524                  {
13525                    name: 'value',
13526                    description:
13527                      '<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n',
13528                    type: 'Object',
13529                    optional: true
13530                  }
13531                ],
13532                class: 'p5.SoundFile',
13533                module: 'p5.sound'
13534              },
13535              removeCue: {
13536                name: 'removeCue',
13537                params: [
13538                  {
13539                    name: 'id',
13540                    description: '<p>ID of the cue, as returned by addCue</p>\n',
13541                    type: 'Number'
13542                  }
13543                ],
13544                class: 'p5.SoundFile',
13545                module: 'p5.sound'
13546              },
13547              clearCues: {
13548                name: 'clearCues',
13549                class: 'p5.SoundFile',
13550                module: 'p5.sound'
13551              },
13552              save: {
13553                name: 'save',
13554                params: [
13555                  {
13556                    name: 'fileName',
13557                    description: '<p>name of the resulting .wav file.</p>\n',
13558                    type: 'String',
13559                    optional: true
13560                  }
13561                ],
13562                class: 'p5.SoundFile',
13563                module: 'p5.sound'
13564              },
13565              getBlob: {
13566                name: 'getBlob',
13567                class: 'p5.SoundFile',
13568                module: 'p5.sound'
13569              }
13570            },
13571            'p5.Amplitude': {
13572              setInput: {
13573                name: 'setInput',
13574                params: [
13575                  {
13576                    name: 'snd',
13577                    description:
13578                      '<p>set the sound source\n                                     (optional, defaults to\n                                     master output)</p>\n',
13579                    type: 'SoundObject|undefined',
13580                    optional: true
13581                  },
13582                  {
13583                    name: 'smoothing',
13584                    description:
13585                      '<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n',
13586                    type: 'Number|undefined',
13587                    optional: true
13588                  }
13589                ],
13590                class: 'p5.Amplitude',
13591                module: 'p5.sound'
13592              },
13593              getLevel: {
13594                name: 'getLevel',
13595                params: [
13596                  {
13597                    name: 'channel',
13598                    description:
13599                      '<p>Optionally return only channel 0 (left) or 1 (right)</p>\n',
13600                    type: 'Number',
13601                    optional: true
13602                  }
13603                ],
13604                class: 'p5.Amplitude',
13605                module: 'p5.sound'
13606              },
13607              toggleNormalize: {
13608                name: 'toggleNormalize',
13609                params: [
13610                  {
13611                    name: 'boolean',
13612                    description: '<p>set normalize to true (1) or false (0)</p>\n',
13613                    type: 'Boolean',
13614                    optional: true
13615                  }
13616                ],
13617                class: 'p5.Amplitude',
13618                module: 'p5.sound'
13619              },
13620              smooth: {
13621                name: 'smooth',
13622                params: [
13623                  {
13624                    name: 'set',
13625                    description: '<p>smoothing from 0.0 <= 1</p>\n',
13626                    type: 'Number'
13627                  }
13628                ],
13629                class: 'p5.Amplitude',
13630                module: 'p5.sound'
13631              }
13632            },
13633            'p5.FFT': {
13634              setInput: {
13635                name: 'setInput',
13636                params: [
13637                  {
13638                    name: 'source',
13639                    description: '<p>p5.sound object (or web audio API source node)</p>\n',
13640                    type: 'Object',
13641                    optional: true
13642                  }
13643                ],
13644                class: 'p5.FFT',
13645                module: 'p5.sound'
13646              },
13647              waveform: {
13648                name: 'waveform',
13649                params: [
13650                  {
13651                    name: 'bins',
13652                    description:
13653                      '<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n',
13654                    type: 'Number',
13655                    optional: true
13656                  },
13657                  {
13658                    name: 'precision',
13659                    description:
13660                      '<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n',
13661                    type: 'String',
13662                    optional: true
13663                  }
13664                ],
13665                class: 'p5.FFT',
13666                module: 'p5.sound'
13667              },
13668              analyze: {
13669                name: 'analyze',
13670                params: [
13671                  {
13672                    name: 'bins',
13673                    description:
13674                      '<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n',
13675                    type: 'Number',
13676                    optional: true
13677                  },
13678                  {
13679                    name: 'scale',
13680                    description:
13681                      '<p>If "dB," returns decibel\n                           float measurements between\n                           -14
136810 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n',
13682                    type: 'Number',
13683                    optional: true
13684                  }
13685                ],
13686                class: 'p5.FFT',
13687                module: 'p5.sound'
13688              },
13689              getEnergy: {
13690                name: 'getEnergy',
13691                params: [
13692                  {
13693                    name: 'frequency1',
13694                    description:
13695                      '<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings "bass", "lowMid" "mid",\n                              "highMid", and "treble" will return\n                              predefined frequency ranges.</p>\n',
13696                    type: 'Number|String'
13697                  },
13698                  {
13699                    name: 'frequency2',
13700                    description:
13701                      '<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n',
13702                    type: 'Number',
13703                    optional: true
13704                  }
13705                ],
13706                class: 'p5.FFT',
13707                module: 'p5.sound'
13708              },
13709              getCentroid: {
13710                name: 'getCentroid',
13711                class: 'p5.FFT',
13712                module: 'p5.sound'
13713              },
13714              smooth: {
13715                name: 'smooth',
13716                params: [
13717                  {
13718                    name: 'smoothing',
13719                    description:
13720                      '<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n',
13721                    type: 'Number'
13722                  }
13723                ],
13724                class: 'p5.FFT',
13725                module: 'p5.sound'
13726              },
13727              linAverages: {
13728                name: 'linAverages',
13729                params: [
13730                  {
13731                    name: 'N',
13732                    description: '<p>Number of returned frequency groups</p>\n',
13733                    type: 'Number'
13734                  }
13735                ],
13736                class: 'p5.FFT',
13737                module: 'p5.sound'
13738              },
13739              logAverages: {
13740                name: 'logAverages',
13741                params: [
13742                  {
13743                    name: 'octaveBands',
13744                    description: '<p>Array of Octave Bands objects for grouping</p>\n',
13745                    type: 'Array'
13746                  }
13747                ],
13748                class: 'p5.FFT',
13749                module: 'p5.sound'
13750              },
13751              getOctaveBands: {
13752                name: 'getOctaveBands',
13753                params: [
13754                  {
13755                    name: 'N',
13756                    description:
13757                      '<p>Specifies the 1/N type of generated octave bands</p>\n',
13758                    type: 'Number'
13759                  },
13760                  {
13761                    name: 'fCtr0',
13762                    description: '<p>Minimum central frequency for the lowest band</p>\n',
13763                    type: 'Number'
13764                  }
13765                ],
13766                class: 'p5.FFT',
13767                module: 'p5.sound'
13768              }
13769            },
13770            'p5.Signal': {
13771              fade: {
13772                name: 'fade',
13773                params: [
13774                  {
13775                    name: 'value',
13776                    description: '<p>Value to set this signal</p>\n',
13777                    type: 'Number'
13778                  },
13779                  {
13780                    name: 'secondsFromNow',
13781                    description: '<p>Length of fade, in seconds from now</p>\n',
13782                    type: 'Number',
13783                    optional: true
13784                  }
13785                ],
13786                class: 'p5.Signal',
13787                module: 'p5.sound'
13788              },
13789              setInput: {
13790                name: 'setInput',
13791                params: [
13792                  {
13793                    name: 'input',
13794                    description: '',
13795                    type: 'Object'
13796                  }
13797                ],
13798                class: 'p5.Signal',
13799                module: 'p5.sound'
13800              },
13801              add: {
13802                name: 'add',
13803                params: [
13804                  {
13805                    name: 'number',
13806                    description: '',
13807                    type: 'Number'
13808                  }
13809                ],
13810                class: 'p5.Signal',
13811                module: 'p5.sound'
13812              },
13813              mult: {
13814                name: 'mult',
13815                params: [
13816                  {
13817                    name: 'number',
13818                    description: '<p>to multiply</p>\n',
13819                    type: 'Number'
13820                  }
13821                ],
13822                class: 'p5.Signal',
13823                module: 'p5.sound'
13824              },
13825              scale: {
13826                name: 'scale',
13827                params: [
13828                  {
13829                    name: 'number',
13830                    description: '<p>to multiply</p>\n',
13831                    type: 'Number'
13832                  },
13833                  {
13834                    name: 'inMin',
13835                    description: '<p>input range minumum</p>\n',
13836                    type: 'Number'
13837                  },
13838                  {
13839                    name: 'inMax',
13840                    description: '<p>input range maximum</p>\n',
13841                    type: 'Number'
13842                  },
13843                  {
13844                    name: 'outMin',
13845                    description: '<p>input range minumum</p>\n',
13846                    type: 'Number'
13847                  },
13848                  {
13849                    name: 'outMax',
13850                    description: '<p>input range maximum</p>\n',
13851                    type: 'Number'
13852                  }
13853                ],
13854                class: 'p5.Signal',
13855                module: 'p5.sound'
13856              }
13857            },
13858            'p5.Envelope': {
13859              attackTime: {
13860                name: 'attackTime',
13861                class: 'p5.Envelope',
13862                module: 'p5.sound'
13863              },
13864              attackLevel: {
13865                name: 'attackLevel',
13866                class: 'p5.Envelope',
13867                module: 'p5.sound'
13868              },
13869              decayTime: {
13870                name: 'decayTime',
13871                class: 'p5.Envelope',
13872                module: 'p5.sound'
13873              },
13874              decayLevel: {
13875                name: 'decayLevel',
13876                class: 'p5.Envelope',
13877                module: 'p5.sound'
13878              },
13879              releaseTime: {
13880                name: 'releaseTime',
13881                class: 'p5.Envelope',
13882                module: 'p5.sound'
13883              },
13884              releaseLevel: {
13885                name: 'releaseLevel',
13886                class: 'p5.Envelope',
13887                module: 'p5.sound'
13888              },
13889              set: {
13890                name: 'set',
13891                params: [
13892                  {
13893                    name: 'attackTime',
13894                    description:
13895                      '<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n',
13896                    type: 'Number'
13897                  },
13898                  {
13899                    name: 'attackLevel',
13900                    description:
13901                      '<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n',
13902                    type: 'Number'
13903                  },
13904                  {
13905                    name: 'decayTime',
13906                    description: '<p>Time</p>\n',
13907                    type: 'Number'
13908                  },
13909                  {
13910                    name: 'decayLevel',
13911                    description:
13912                      '<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n',
13913                    type: 'Number'
13914                  },
13915                  {
13916                    name: 'releaseTime',
13917                    description: '<p>Release Time (in seconds)</p>\n',
13918                    type: 'Number'
13919                  },
13920                  {
13921                    name: 'releaseLevel',
13922                    description: '<p>Amplitude</p>\n',
13923                    type: 'Number'
13924                  }
13925                ],
13926                class: 'p5.Envelope',
13927                module: 'p5.sound'
13928              },
13929              setADSR: {
13930                name: 'setADSR',
13931                params: [
13932                  {
13933                    name: 'attackTime',
13934                    description:
13935                      '<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n',
13936                    type: 'Number'
13937                  },
13938                  {
13939                    name: 'decayTime',
13940                    description:
13941                      '<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n',
13942                    type: 'Number',
13943                    optional: true
13944                  },
13945                  {
13946                    name: 'susRatio',
13947                    description:
13948                      '<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n',
13949                    type: 'Number',
13950                    optional: true
13951                  },
13952                  {
13953                    name: 'releaseTime',
13954                    description: '<p>Time in seconds from now (defaults to 0)</p>\n',
13955                    type: 'Number',
13956                    optional: true
13957                  }
13958                ],
13959                class: 'p5.Envelope',
13960                module: 'p5.sound'
13961              },
13962              setRange: {
13963                name: 'setRange',
13964                params: [
13965                  {
13966                    name: 'aLevel',
13967                    description: '<p>attack level (defaults to 1)</p>\n',
13968                    type: 'Number'
13969                  },
13970                  {
13971                    name: 'rLevel',
13972                    description: '<p>release level (defaults to 0)</p>\n',
13973                    type: 'Number'
13974                  }
13975                ],
13976                class: 'p5.Envelope',
13977                module: 'p5.sound'
13978              },
13979              setInput: {
13980                name: 'setInput',
13981                params: [
13982                  {
13983                    name: 'inputs',
13984                    description:
13985                      '<p>A p5.sound object or\n                              Web Audio Param.</p>\n',
13986                    type: 'Object',
13987                    optional: true,
13988                    multiple: true
13989                  }
13990                ],
13991                class: 'p5.Envelope',
13992                module: 'p5.sound'
13993              },
13994              setExp: {
13995                name: 'setExp',
13996                params: [
13997                  {
13998                    name: 'isExp',
13999                    description: '<p>true is exponential, false is linear</p>\n',
14000                    type: 'Boolean'
14001                  }
14002                ],
14003                class: 'p5.Envelope',
14004                module: 'p5.sound'
14005              },
14006              play: {
14007                name: 'play',
14008                params: [
14009                  {
14010                    name: 'unit',
14011                    description:
14012                      '<p>A p5.sound object or\n                              Web Audio Param.</p>\n',
14013                    type: 'Object'
14014                  },
14015                  {
14016                    name: 'startTime',
14017                    description: '<p>time from now (in seconds) at which to play</p>\n',
14018                    type: 'Number',
14019                    optional: true
14020                  },
14021                  {
14022                    name: 'sustainTime',
14023                    description: '<p>time to sustain before releasing the envelope</p>\n',
14024                    type: 'Number',
14025                    optional: true
14026                  }
14027                ],
14028                class: 'p5.Envelope',
14029                module: 'p5.sound'
14030              },
14031              triggerAttack: {
14032                name: 'triggerAttack',
14033                params: [
14034                  {
14035                    name: 'unit',
14036                    description: '<p>p5.sound Object or Web Audio Param</p>\n',
14037                    type: 'Object'
14038                  },
14039                  {
14040                    name: 'secondsFromNow',
14041                    description: '<p>time from now (in seconds)</p>\n',
14042                    type: 'Number'
14043                  }
14044                ],
14045                class: 'p5.Envelope',
14046                module: 'p5.sound'
14047              },
14048              triggerRelease: {
14049                name: 'triggerRelease',
14050                params: [
14051                  {
14052                    name: 'unit',
14053                    description: '<p>p5.sound Object or Web Audio Param</p>\n',
14054                    type: 'Object'
14055                  },
14056                  {
14057                    name: 'secondsFromNow',
14058                    description: '<p>time to trigger the release</p>\n',
14059                    type: 'Number'
14060                  }
14061                ],
14062                class: 'p5.Envelope',
14063                module: 'p5.sound'
14064              },
14065              ramp: {
14066                name: 'ramp',
14067                params: [
14068                  {
14069                    name: 'unit',
14070                    description: '<p>p5.sound Object or Web Audio Param</p>\n',
14071                    type: 'Object'
14072                  },
14073                  {
14074                    name: 'secondsFromNow',
14075                    description: '<p>When to trigger the ramp</p>\n',
14076                    type: 'Number'
14077                  },
14078                  {
14079                    name: 'v',
14080                    description: '<p>Target value</p>\n',
14081                    type: 'Number'
14082                  },
14083                  {
14084                    name: 'v2',
14085                    description: '<p>Second target value (optional)</p>\n',
14086                    type: 'Number',
14087                    optional: true
14088                  }
14089                ],
14090                class: 'p5.Envelope',
14091                module: 'p5.sound'
14092              },
14093              add: {
14094                name: 'add',
14095                params: [
14096                  {
14097                    name: 'number',
14098                    description: '<p>Constant number to add</p>\n',
14099                    type: 'Number'
14100                  }
14101                ],
14102                class: 'p5.Envelope',
14103                module: 'p5.sound'
14104              },
14105              mult: {
14106                name: 'mult',
14107                params: [
14108                  {
14109                    name: 'number',
14110                    description: '<p>Constant number to multiply</p>\n',
14111                    type: 'Number'
14112                  }
14113                ],
14114                class: 'p5.Envelope',
14115                module: 'p5.sound'
14116              },
14117              scale: {
14118                name: 'scale',
14119                params: [
14120                  {
14121                    name: 'inMin',
14122                    description: '<p>input range minumum</p>\n',
14123                    type: 'Number'
14124                  },
14125                  {
14126                    name: 'inMax',
14127                    description: '<p>input range maximum</p>\n',
14128                    type: 'Number'
14129                  },
14130                  {
14131                    name: 'outMin',
14132                    description: '<p>input range minumum</p>\n',
14133                    type: 'Number'
14134                  },
14135                  {
14136                    name: 'outMax',
14137                    description: '<p>input range maximum</p>\n',
14138                    type: 'Number'
14139                  }
14140                ],
14141                class: 'p5.Envelope',
14142                module: 'p5.sound'
14143              }
14144            },
14145            'p5.Pulse': {
14146              width: {
14147                name: 'width',
14148                params: [
14149                  {
14150                    name: 'width',
14151                    description:
14152                      '<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n',
14153                    type: 'Number',
14154                    optional: true
14155                  }
14156                ],
14157                class: 'p5.Pulse',
14158                module: 'p5.sound'
14159              }
14160            },
14161            'p5.Noise': {
14162              setType: {
14163                name: 'setType',
14164                params: [
14165                  {
14166                    name: 'type',
14167                    description: "<p>'white', 'pink' or 'brown'</p>\n",
14168                    type: 'String',
14169                    optional: true
14170                  }
14171                ],
14172                class: 'p5.Noise',
14173                module: 'p5.sound'
14174              }
14175            },
14176            'p5.AudioIn': {
14177              input: {
14178                name: 'input',
14179                class: 'p5.AudioIn',
14180                module: 'p5.sound'
14181              },
14182              output: {
14183                name: 'output',
14184                class: 'p5.AudioIn',
14185                module: 'p5.sound'
14186              },
14187              stream: {
14188                name: 'stream',
14189                class: 'p5.AudioIn',
14190                module: 'p5.sound'
14191              },
14192              mediaStream: {
14193                name: 'mediaStream',
14194                class: 'p5.AudioIn',
14195                module: 'p5.sound'
14196              },
14197              currentSource: {
14198                name: 'currentSource',
14199                class: 'p5.AudioIn',
14200                module: 'p5.sound'
14201              },
14202              enabled: {
14203                name: 'enabled',
14204                class: 'p5.AudioIn',
14205                module: 'p5.sound'
14206              },
14207              amplitude: {
14208                name: 'amplitude',
14209                class: 'p5.AudioIn',
14210                module: 'p5.sound'
14211              },
14212              start: {
14213                name: 'start',
14214                params: [
14215                  {
14216                    name: 'successCallback',
14217                    description:
14218                      '<p>Name of a function to call on\n                                  success.</p>\n',
14219                    type: 'Function',
14220                    optional: true
14221                  },
14222                  {
14223                    name: 'errorCallback',
14224                    description:
14225                      '<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n',
14226                    type: 'Function',
14227                    optional: true
14228                  }
14229                ],
14230                class: 'p5.AudioIn',
14231                module: 'p5.sound'
14232              },
14233              stop: {
14234                name: 'stop',
14235                class: 'p5.AudioIn',
14236                module: 'p5.sound'
14237              },
14238              connect: {
14239                name: 'connect',
14240                params: [
14241                  {
14242                    name: 'unit',
14243                    description:
14244                      '<p>An object that accepts audio input,\n                        such as an FFT</p>\n',
14245                    type: 'Object',
14246                    optional: true
14247                  }
14248                ],
14249                class: 'p5.AudioIn',
14250                module: 'p5.sound'
14251              },
14252              disconnect: {
14253                name: 'disconnect',
14254                class: 'p5.AudioIn',
14255                module: 'p5.sound'
14256              },
14257              getLevel: {
14258                name: 'getLevel',
14259                params: [
14260                  {
14261                    name: 'smoothing',
14262                    description:
14263                      '<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n',
14264                    type: 'Number',
14265                    optional: true
14266                  }
14267                ],
14268                class: 'p5.AudioIn',
14269                module: 'p5.sound'
14270              },
14271              amp: {
14272                name: 'amp',
14273                params: [
14274                  {
14275                    name: 'vol',
14276                    description: '<p>between 0 and 1.0</p>\n',
14277                    type: 'Number'
14278                  },
14279                  {
14280                    name: 'time',
14281                    description: '<p>ramp time (optional)</p>\n',
14282                    type: 'Number',
14283                    optional: true
14284                  }
14285                ],
14286                class: 'p5.AudioIn',
14287                module: 'p5.sound'
14288              },
14289              getSources: {
14290                name: 'getSources',
14291                params: [
14292                  {
14293                    name: 'successCallback',
14294                    description:
14295                      '<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n',
14296                    type: 'Function',
14297                    optional: true
14298                  },
14299                  {
14300                    name: 'errorCallback',
14301                    description:
14302                      '<p>This optional callback receives the error\n                                   message as its argument.</p>\n',
14303                    type: 'Function',
14304                    optional: true
14305                  }
14306                ],
14307                class: 'p5.AudioIn',
14308                module: 'p5.sound'
14309              },
14310              setSource: {
14311                name: 'setSource',
14312              
14312  params: [
14313                  {
14314                    name: 'num',
14315                    description: '<p>position of input source in the array</p>\n',
14316                    type: 'Number'
14317                  }
14318                ],
14319                class: 'p5.AudioIn',
14320                module: 'p5.sound'
14321              }
14322            },
14323            'p5.EQ': {
14324              bands: {
14325                name: 'bands',
14326                class: 'p5.EQ',
14327                module: 'p5.sound'
14328              },
14329              process: {
14330                name: 'process',
14331                params: [
14332                  {
14333                    name: 'src',
14334                    description: '<p>Audio source</p>\n',
14335                    type: 'Object'
14336                  }
14337                ],
14338                class: 'p5.EQ',
14339                module: 'p5.sound'
14340              }
14341            },
14342            'p5.Panner3D': {
14343              panner: {
14344                name: 'panner',
14345                class: 'p5.Panner3D',
14346                module: 'p5.sound'
14347              },
14348              process: {
14349                name: 'process',
14350                params: [
14351                  {
14352                    name: 'src',
14353                    description: '<p>Input source</p>\n',
14354                    type: 'Object'
14355                  }
14356                ],
14357                class: 'p5.Panner3D',
14358                module: 'p5.sound'
14359              },
14360              set: {
14361                name: 'set',
14362                params: [
14363                  {
14364                    name: 'xVal',
14365                    description: '',
14366                    type: 'Number'
14367                  },
14368                  {
14369                    name: 'yVal',
14370                    description: '',
14371                    type: 'Number'
14372                  },
14373                  {
14374                    name: 'zVal',
14375                    description: '',
14376                    type: 'Number'
14377                  },
14378                  {
14379                    name: 'time',
14380                    description: '',
14381                    type: 'Number'
14382                  }
14383                ],
14384                class: 'p5.Panner3D',
14385                module: 'p5.sound'
14386              },
14387              positionX: {
14388                name: 'positionX',
14389                class: 'p5.Panner3D',
14390                module: 'p5.sound'
14391              },
14392              positionY: {
14393                name: 'positionY',
14394                class: 'p5.Panner3D',
14395                module: 'p5.sound'
14396              },
14397              positionZ: {
14398                name: 'positionZ',
14399                class: 'p5.Panner3D',
14400                module: 'p5.sound'
14401              },
14402              orient: {
14403                name: 'orient',
14404                params: [
14405                  {
14406                    name: 'xVal',
14407                    description: '',
14408                    type: 'Number'
14409                  },
14410                  {
14411                    name: 'yVal',
14412                    description: '',
14413                    type: 'Number'
14414                  },
14415                  {
14416                    name: 'zVal',
14417                    description: '',
14418                    type: 'Number'
14419                  },
14420                  {
14421                    name: 'time',
14422                    description: '',
14423                    type: 'Number'
14424                  }
14425                ],
14426                class: 'p5.Panner3D',
14427                module: 'p5.sound'
14428              },
14429              orientX: {
14430                name: 'orientX',
14431                class: 'p5.Panner3D',
14432                module: 'p5.sound'
14433              },
14434              orientY: {
14435                name: 'orientY',
14436                class: 'p5.Panner3D',
14437                module: 'p5.sound'
14438              },
14439              orientZ: {
14440                name: 'orientZ',
14441                class: 'p5.Panner3D',
14442                module: 'p5.sound'
14443              },
14444              setFalloff: {
14445                name: 'setFalloff',
14446                params: [
14447                  {
14448                    name: 'maxDistance',
14449                    description: '',
14450                    type: 'Number',
14451                    optional: true
14452                  },
14453                  {
14454                    name: 'rolloffFactor',
14455                    description: '',
14456                    type: 'Number',
14457                    optional: true
14458                  }
14459                ],
14460                class: 'p5.Panner3D',
14461                module: 'p5.sound'
14462              },
14463              maxDist: {
14464                name: 'maxDist',
14465                params: [
14466                  {
14467                    name: 'maxDistance',
14468                    description: '',
14469                    type: 'Number'
14470                  }
14471                ],
14472                class: 'p5.Panner3D',
14473                module: 'p5.sound'
14474              },
14475              rollof: {
14476                name: 'rollof',
14477                params: [
14478                  {
14479                    name: 'rolloffFactor',
14480                    description: '',
14481                    type: 'Number'
14482                  }
14483                ],
14484                class: 'p5.Panner3D',
14485                module: 'p5.sound'
14486              }
14487            },
14488            'p5.Delay': {
14489              leftDelay: {
14490                name: 'leftDelay',
14491                class: 'p5.Delay',
14492                module: 'p5.sound'
14493              },
14494              rightDelay: {
14495                name: 'rightDelay',
14496                class: 'p5.Delay',
14497                module: 'p5.sound'
14498              },
14499              process: {
14500                name: 'process',
14501                params: [
14502                  {
14503                    name: 'Signal',
14504                    description: '<p>An object that outputs audio</p>\n',
14505                    type: 'Object'
14506                  },
14507                  {
14508                    name: 'delayTime',
14509                    description:
14510                      '<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n',
14511                    type: 'Number',
14512                    optional: true
14513                  },
14514                  {
14515                    name: 'feedback',
14516                    description:
14517                      '<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n',
14518                    type: 'Number',
14519                    optional: true
14520                  },
14521                  {
14522                    name: 'lowPass',
14523                    description:
14524                      '<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n',
14525                    type: 'Number',
14526                    optional: true
14527                  }
14528                ],
14529                class: 'p5.Delay',
14530                module: 'p5.sound'
14531              },
14532              delayTime: {
14533                name: 'delayTime',
14534                params: [
14535                  {
14536                    name: 'delayTime',
14537                    description: '<p>Time (in seconds) of the delay</p>\n',
14538                    type: 'Number'
14539                  }
14540                ],
14541                class: 'p5.Delay',
14542                module: 'p5.sound'
14543              },
14544              feedback: {
14545                name: 'feedback',
14546                params: [
14547                  {
14548                    name: 'feedback',
14549                    description:
14550                      '<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n',
14551                    type: 'Number|Object'
14552                  }
14553                ],
14554                class: 'p5.Delay',
14555                module: 'p5.sound'
14556              },
14557              filter: {
14558                name: 'filter',
14559                params: [
14560                  {
14561                    name: 'cutoffFreq',
14562                    description:
14563                      '<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n',
14564                    type: 'Number|Object'
14565                  },
14566                  {
14567                    name: 'res',
14568                    description:
14569                      '<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n',
14570                    type: 'Number|Object'
14571                  }
14572                ],
14573                class: 'p5.Delay',
14574                module: 'p5.sound'
14575              },
14576              setType: {
14577                name: 'setType',
14578                params: [
14579                  {
14580                    name: 'type',
14581                    description: "<p>'pingPong' (1) or 'default' (0)</p>\n",
14582                    type: 'String|Number'
14583                  }
14584                ],
14585                class: 'p5.Delay',
14586                module: 'p5.sound'
14587              },
14588              amp: {
14589                name: 'amp',
14590                params: [
14591                  {
14592                    name: 'volume',
14593                    description: '<p>amplitude between 0 and 1.0</p>\n',
14594                    type: 'Number'
14595                  },
14596                  {
14597                    name: 'rampTime',
14598                    description: '<p>create a fade that lasts rampTime</p>\n',
14599                    type: 'Number',
14600                    optional: true
14601                  },
14602                  {
14603                    name: 'timeFromNow',
14604                    description:
14605                      '<p>schedule this event to happen\n                              seconds from now</p>\n',
14606                    type: 'Number',
14607                    optional: true
14608                  }
14609                ],
14610                class: 'p5.Delay',
14611                module: 'p5.sound'
14612              },
14613              connect: {
14614                name: 'connect',
14615                params: [
14616                  {
14617                    name: 'unit',
14618                    description: '',
14619                    type: 'Object'
14620                  }
14621                ],
14622                class: 'p5.Delay',
14623                module: 'p5.sound'
14624              },
14625              disconnect: {
14626                name: 'disconnect',
14627                class: 'p5.Delay',
14628                module: 'p5.sound'
14629              }
14630            },
14631            'p5.Reverb': {
14632              process: {
14633                name: 'process',
14634                params: [
14635                  {
14636                    name: 'src',
14637                    description:
14638                      '<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n',
14639                    type: 'Object'
14640                  },
14641                  {
14642                    name: 'seconds',
14643                    description:
14644                      '<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n',
14645                    type: 'Number',
14646                    optional: true
14647                  },
14648                  {
14649                    name: 'decayRate',
14650                    description:
14651                      '<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n',
14652                    type: 'Number',
14653                    optional: true
14654                  },
14655                  {
14656                    name: 'reverse',
14657                    description: '<p>Play the reverb backwards or forwards.</p>\n',
14658                    type: 'Boolean',
14659                    optional: true
14660                  }
14661                ],
14662                class: 'p5.Reverb',
14663                module: 'p5.sound'
14664              },
14665              set: {
14666                name: 'set',
14667                params: [
14668                  {
14669                    name: 'seconds',
14670                    description:
14671                      '<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n',
14672                    type: 'Number',
14673                    optional: true
14674                  },
14675                  {
14676                    name: 'decayRate',
14677                    description:
14678                      '<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n',
14679                    type: 'Number',
14680                    optional: true
14681                  },
14682                  {
14683                    name: 'reverse',
14684                    description: '<p>Play the reverb backwards or forwards.</p>\n',
14685                    type: 'Boolean',
14686                    optional: true
14687                  }
14688                ],
14689                class: 'p5.Reverb',
14690                module: 'p5.sound'
14691              },
14692              amp: {
14693                name: 'amp',
14694                params: [
14695                  {
14696                    name: 'volume',
14697                    description: '<p>amplitude between 0 and 1.0</p>\n',
14698                    type: 'Number'
14699                  },
14700                  {
14701                    name: 'rampTime',
14702                    description: '<p>create a fade that lasts rampTime</p>\n',
14703                    type: 'Number',
14704                    optional: true
14705                  },
14706                  {
14707                    name: 'timeFromNow',
14708                    description:
14709                      '<p>schedule this event to happen\n                              seconds from now</p>\n',
14710                    type: 'Number',
14711                    optional: true
14712                  }
14713                ],
14714                class: 'p5.Reverb',
14715                module: 'p5.sound'
14716              },
14717              connect: {
14718                name: 'connect',
14719                params: [
14720                  {
14721                    name: 'unit',
14722                    description: '',
14723                    type: 'Object'
14724                  }
14725                ],
14726                class: 'p5.Reverb',
14727                module: 'p5.sound'
14728              },
14729              disconnect: {
14730                name: 'disconnect',
14731                class: 'p5.Reverb',
14732                module: 'p5.sound'
14733              }
14734            },
14735            'p5.Convolver': {
14736              convolverNode: {
14737                name: 'convolverNode',
14738                class: 'p5.Convolver',
14739                module: 'p5.sound'
14740              },
14741              process: {
14742                name: 'process',
14743                params: [
14744                  {
14745                    name: 'src',
14746                    description:
14747                      '<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n',
14748                    type: 'Object'
14749                  }
14750                ],
14751                class: 'p5.Convolver',
14752                module: 'p5.sound'
14753              },
14754              impulses: {
14755                name: 'impulses',
14756                class: 'p5.Convolver',
14757                module: 'p5.sound'
14758              },
14759              addImpulse: {
14760                name: 'addImpulse',
14761                params: [
14762                  {
14763                    name: 'path',
14764                    description: '<p>
14764path to a sound file</p>\n',
14765                    type: 'String'
14766                  },
14767                  {
14768                    name: 'callback',
14769                    description: '<p>function (optional)</p>\n',
14770                    type: 'Function'
14771                  },
14772                  {
14773                    name: 'errorCallback',
14774                    description: '<p>function (optional)</p>\n',
14775                    type: 'Function'
14776                  }
14777                ],
14778                class: 'p5.Convolver',
14779                module: 'p5.sound'
14780              },
14781              resetImpulse: {
14782                name: 'resetImpulse',
14783                params: [
14784                  {
14785                    name: 'path',
14786                    description: '<p>path to a sound file</p>\n',
14787                    type: 'String'
14788                  },
14789                  {
14790                    name: 'callback',
14791                    description: '<p>function (optional)</p>\n',
14792                    type: 'Function'
14793                  },
14794                  {
14795                    name: 'errorCallback',
14796                    description: '<p>function (optional)</p>\n',
14797                    type: 'Function'
14798                  }
14799                ],
14800                class: 'p5.Convolver',
14801                module: 'p5.sound'
14802              },
14803              toggleImpulse: {
14804                name: 'toggleImpulse',
14805                params: [
14806                  {
14807                    name: 'id',
14808                    description:
14809                      '<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n',
14810                    type: 'String|Number'
14811                  }
14812                ],
14813                class: 'p5.Convolver',
14814                module: 'p5.sound'
14815              }
14816            },
14817            'p5.Phrase': {
14818              sequence: {
14819                name: 'sequence',
14820                class: 'p5.Phrase',
14821                module: 'p5.sound'
14822              }
14823            },
14824            'p5.Part': {
14825              setBPM: {
14826                name: 'setBPM',
14827                params: [
14828                  {
14829                    name: 'BPM',
14830                    description: '<p>Beats Per Minute</p>\n',
14831                    type: 'Number'
14832                  },
14833                  {
14834                    name: 'rampTime',
14835                    description: '<p>Seconds from now</p>\n',
14836                    type: 'Number',
14837                    optional: true
14838                  }
14839                ],
14840                class: 'p5.Part',
14841                module: 'p5.sound'
14842              },
14843              getBPM: {
14844                name: 'getBPM',
14845                class: 'p5.Part',
14846                module: 'p5.sound'
14847              },
14848              start: {
14849                name: 'start',
14850                params: [
14851                  {
14852                    name: 'time',
14853                    description: '<p>seconds from now</p>\n',
14854                    type: 'Number',
14855                    optional: true
14856                  }
14857                ],
14858                class: 'p5.Part',
14859                module: 'p5.sound'
14860              },
14861              loop: {
14862                name: 'loop',
14863                params: [
14864                  {
14865                    name: 'time',
14866                    description: '<p>seconds from now</p>\n',
14867                    type: 'Number',
14868                    optional: true
14869                  }
14870                ],
14871                class: 'p5.Part',
14872                module: 'p5.sound'
14873              },
14874              noLoop: {
14875                name: 'noLoop',
14876                class: 'p5.Part',
14877                module: 'p5.sound'
14878              },
14879              stop: {
14880                name: 'stop',
14881                params: [
14882                  {
14883                    name: 'time',
14884                    description: '<p>seconds from now</p>\n',
14885                    type: 'Number',
14886                    optional: true
14887                  }
14888                ],
14889                class: 'p5.Part',
14890                module: 'p5.sound'
14891              },
14892              pause: {
14893                name: 'pause',
14894                params: [
14895                  {
14896                    name: 'time',
14897                    description: '<p>seconds from now</p>\n',
14898                    type: 'Number'
14899                  }
14900                ],
14901                class: 'p5.Part',
14902                module: 'p5.sound'
14903              },
14904              addPhrase: {
14905                name: 'addPhrase',
14906                params: [
14907                  {
14908                    name: 'phrase',
14909                    description: '<p>reference to a p5.Phrase</p>\n',
14910                    type: 'p5.Phrase'
14911                  }
14912                ],
14913                class: 'p5.Part',
14914                module: 'p5.sound'
14915              },
14916              removePhrase: {
14917                name: 'removePhrase',
14918                params: [
14919                  {
14920                    name: 'phraseName',
14921                    description: '',
14922                    type: 'String'
14923                  }
14924                ],
14925                class: 'p5.Part',
14926                module: 'p5.sound'
14927              },
14928              getPhrase: {
14929                name: 'getPhrase',
14930                params: [
14931                  {
14932                    name: 'phraseName',
14933                    description: '',
14934                    type: 'String'
14935                  }
14936                ],
14937                class: 'p5.Part',
14938                module: 'p5.sound'
14939              },
14940              replaceSequence: {
14941                name: 'replaceSequence',
14942                params: [
14943                  {
14944                    name: 'phraseName',
14945                    description: '',
14946                    type: 'String'
14947                  },
14948                  {
14949                    name: 'sequence',
14950                    description:
14951                      '<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n',
14952                    type: 'Array'
14953                  }
14954                ],
14955                class: 'p5.Part',
14956                module: 'p5.sound'
14957              },
14958              onStep: {
14959                name: 'onStep',
14960                params: [
14961                  {
14962                    name: 'callback',
14963                    description:
14964                      '<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n',
14965                    type: 'Function'
14966                  }
14967                ],
14968                class: 'p5.Part',
14969                module: 'p5.sound'
14970              }
14971            },
14972            'p5.Score': {
14973              start: {
14974                name: 'start',
14975                class: 'p5.Score',
14976                module: 'p5.sound'
14977              },
14978              stop: {
14979                name: 'stop',
14980                class: 'p5.Score',
14981                module: 'p5.sound'
14982              },
14983              pause: {
14984                name: 'pause',
14985                class: 'p5.Score',
14986                module: 'p5.sound'
14987              },
14988              loop: {
14989                name: 'loop',
14990                class: 'p5.Score',
14991                module: 'p5.sound'
14992              },
14993              noLoop: {
14994                name: 'noLoop',
14995                class: 'p5.Score',
14996                module: 'p5.sound'
14997              },
14998              setBPM: {
14999                name: 'setBPM',
15000                params: [
15001                  {
15002                    name: 'BPM',
15003                    description: '<p>Beats Per Minute</p>\n',
15004                    type: 'Number'
15005                  },
15006                  {
15007                    name: 'rampTime',
15008                    description: '<p>Seconds from now</p>\n',
15009                    type: 'Number'
15010                  }
15011                ],
15012                class: 'p5.Score',
15013                module: 'p5.sound'
15014              }
15015            },
15016            'p5.SoundLoop': {
15017              musicalTimeMode: {
15018                name: 'musicalTimeMode',
15019                class: 'p5.SoundLoop',
15020                module: 'p5.sound'
15021              },
15022              maxIterations: {
15023                name: 'maxIterations',
15024                class: 'p5.SoundLoop',
15025                module: 'p5.sound'
15026              },
15027              start: {
15028                name: 'start',
15029                params: [
15030                  {
15031                    name: 'timeFromNow',
15032                    description: '<p>schedule a starting time</p>\n',
15033                    type: 'Number',
15034                    optional: true
15035                  }
15036                ],
15037                class: 'p5.SoundLoop',
15038                module: 'p5.sound'
15039              },
15040              stop: {
15041                name: 'stop',
15042                params: [
15043                  {
15044                    name: 'timeFromNow',
15045                    description: '<p>schedule a stopping time</p>\n',
15046                    type: 'Number',
15047                    optional: true
15048                  }
15049                ],
15050                class: 'p5.SoundLoop',
15051                module: 'p5.sound'
15052              },
15053              pause: {
15054                name: 'pause',
15055                params: [
15056                  {
15057                    name: 'timeFromNow',
15058                    description: '<p>schedule a pausing time</p>\n',
15059                    type: 'Number',
15060                    optional: true
15061                  }
15062                ],
15063                class: 'p5.SoundLoop',
15064                module: 'p5.sound'
15065              },
15066              syncedStart: {
15067                name: 'syncedStart',
15068                params: [
15069                  {
15070                    name: 'otherLoop',
15071                    description: '<p>a p5.SoundLoop to sync with</p>\n',
15072                    type: 'Object'
15073                  },
15074                  {
15075                    name: 'timeFromNow',
15076                    description:
15077                      '<p>Start the loops in sync after timeFromNow seconds</p>\n',
15078                    type: 'Number',
15079                    optional: true
15080                  }
15081                ],
15082                class: 'p5.SoundLoop',
15083                module: 'p5.sound'
15084              },
15085              bpm: {
15086                name: 'bpm',
15087                class: 'p5.SoundLoop',
15088                module: 'p5.sound'
15089              },
15090              timeSignature: {
15091                name: 'timeSignature',
15092                class: 'p5.SoundLoop',
15093                module: 'p5.sound'
15094              },
15095              interval: {
15096                name: 'interval',
15097                class: 'p5.SoundLoop',
15098                module: 'p5.sound'
15099              },
15100              iterations: {
15101                name: 'iterations',
15102                class: 'p5.SoundLoop',
15103                module: 'p5.sound'
15104              }
15105            },
15106            'p5.Compressor': {
15107              compressor: {
15108                name: 'compressor',
15109                class: 'p5.Compressor',
15110                module: 'p5.sound'
15111              },
15112              process: {
15113                name: 'process',
15114                params: [
15115                  {
15116                    name: 'src',
15117                    description: '<p>Sound source to be connected</p>\n',
15118                    type: 'Object'
15119                  },
15120                  {
15121                    name: 'attack',
15122                    description:
15123                      '<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n',
15124                    type: 'Number',
15125                    optional: true
15126                  },
15127                  {
15128                    name: 'knee',
15129                    description:
15130                      '<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the "ratio" portion.\n                           default = 30, range 0 - 40</p>\n',
15131                    type: 'Number',
15132                    optional: true
15133                  },
15134                  {
15135                    name: 'ratio',
15136                    description:
15137                      '<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n',
15138                    type: 'Number',
15139                    optional: true
15140                  },
15141                  {
15142                    name: 'threshold',
15143                    description:
15144                      '<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n',
15145                    type: 'Number',
15146                    optional: true
15147                  },
15148                  {
15149                    name: 'release',
15150                    description:
15151                      '<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n',
15152                    type: 'Number',
15153                    optional: true
15154                  }
15155                ],
15156                class: 'p5.Compressor',
15157                module: 'p5.sound'
15158              },
15159              set: {
15160                name: 'set',
15161                params: [
15162                  {
15163                    name: 'attack',
15164                    description:
15165                      '<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n',
15166                    type: 'Number'
15167                  },
15168                  {
15169                    name: 'knee',
15170                    description:
15171                      '<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the "ratio" portion.\n                           default = 30, range 0 - 40</p>\n',
15172                    type: 'Number'
15173                  },
15174                  {
15175                    name: 'ratio',
15176                    description:
15177                      '<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n',
15178                    type: 'Number'
15179                  },
15180                  {
15181                    name: 'threshold',
15182                    description:
15183                      '<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n',
15184                    type: 'Number'
15185                  },
15186                  {
15187                    name: 'release',
15188                    description:
15189                      '<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n',
15190                    type: 'Number'
15191                  }
15192                ],
15193                class: 'p5.Compressor',
15194                module: 'p5.sound'
15195              },
15196              attack: {
15197                name: 'attack',
15198                params: [
15199                  {
15200                    name: 'attack',
15201                    description:
15202                      '<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n',
15203                    type: 'Number',
15204                    optional: true
15205                  },
15206                  {
15207                    name: 'time',
15208                    description:
15209                      '<p>Assign time value to schedule the change in value</p>\n',
15210                    type: 'Number',
15211                    optional: true
15212                  }
15213                ],
15214                class: 'p5.Compressor',
15215                module: 'p5.sound'
15216              },
15217              knee: {
15218                name: 'knee',
15219                params: [
15220                  {
15221                    name: 'knee',
15222                    description:
15223                      '<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the "ratio" portion.\n                       default = 30, range 0 - 40</p>\n',
15224                    type: 'Number',
15225                    optional: true
15226                  },
15227                  {
15228                    name: 'time',
15229                    description:
15230                      '<p>Assign time value to schedule the change in value</p>\n',
15231               
15231     type: 'Number',
15232                    optional: true
15233                  }
15234                ],
15235                class: 'p5.Compressor',
15236                module: 'p5.sound'
15237              },
15238              ratio: {
15239                name: 'ratio',
15240                params: [
15241                  {
15242                    name: 'ratio',
15243                    description:
15244                      '<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n',
15245                    type: 'Number',
15246                    optional: true
15247                  },
15248                  {
15249                    name: 'time',
15250                    description:
15251                      '<p>Assign time value to schedule the change in value</p>\n',
15252                    type: 'Number',
15253                    optional: true
15254                  }
15255                ],
15256                class: 'p5.Compressor',
15257                module: 'p5.sound'
15258              },
15259              threshold: {
15260                name: 'threshold',
15261                params: [
15262                  {
15263                    name: 'threshold',
15264                    description:
15265                      '<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n',
15266                    type: 'Number'
15267                  },
15268                  {
15269                    name: 'time',
15270                    description:
15271                      '<p>Assign time value to schedule the change in value</p>\n',
15272                    type: 'Number',
15273                    optional: true
15274                  }
15275                ],
15276                class: 'p5.Compressor',
15277                module: 'p5.sound'
15278              },
15279              release: {
15280                name: 'release',
15281                params: [
15282                  {
15283                    name: 'release',
15284                    description:
15285                      '<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n',
15286                    type: 'Number'
15287                  },
15288                  {
15289                    name: 'time',
15290                    description:
15291                      '<p>Assign time value to schedule the change in value</p>\n',
15292                    type: 'Number',
15293                    optional: true
15294                  }
15295                ],
15296                class: 'p5.Compressor',
15297                module: 'p5.sound'
15298              },
15299              reduction: {
15300                name: 'reduction',
15301                class: 'p5.Compressor',
15302                module: 'p5.sound'
15303              }
15304            },
15305            'p5.SoundRecorder': {
15306              setInput: {
15307                name: 'setInput',
15308                params: [
15309                  {
15310                    name: 'unit',
15311                    description:
15312                      '<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n',
15313                    type: 'Object',
15314                    optional: true
15315                  }
15316                ],
15317                class: 'p5.SoundRecorder',
15318                module: 'p5.sound'
15319              },
15320              record: {
15321                name: 'record',
15322                params: [
15323                  {
15324                    name: 'soundFile',
15325                    description: '<p>p5.SoundFile</p>\n',
15326                    type: 'p5.SoundFile'
15327                  },
15328                  {
15329                    name: 'duration',
15330                    description: '<p>Time (in seconds)</p>\n',
15331                    type: 'Number',
15332                    optional: true
15333                  },
15334                  {
15335                    name: 'callback',
15336                    description:
15337                      '<p>The name of a function that will be\n                              called once the recording completes</p>\n',
15338                    type: 'Function',
15339                    optional: true
15340                  }
15341                ],
15342                class: 'p5.SoundRecorder',
15343                module: 'p5.sound'
15344              },
15345              stop: {
15346                name: 'stop',
15347                class: 'p5.SoundRecorder',
15348                module: 'p5.sound'
15349              }
15350            },
15351            'p5.PeakDetect': {
15352              isDetected: {
15353                name: 'isDetected',
15354                class: 'p5.PeakDetect',
15355                module: 'p5.sound'
15356              },
15357              update: {
15358                name: 'update',
15359                params: [
15360                  {
15361                    name: 'fftObject',
15362                    description: '<p>A p5.FFT object</p>\n',
15363                    type: 'p5.FFT'
15364                  }
15365                ],
15366                class: 'p5.PeakDetect',
15367                module: 'p5.sound'
15368              },
15369              onPeak: {
15370                name: 'onPeak',
15371                params: [
15372                  {
15373                    name: 'callback',
15374                    description:
15375                      '<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n',
15376                    type: 'Function'
15377                  },
15378                  {
15379                    name: 'val',
15380                    description:
15381                      '<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n',
15382                    type: 'Object',
15383                    optional: true
15384                  }
15385                ],
15386                class: 'p5.PeakDetect',
15387                module: 'p5.sound'
15388              }
15389            },
15390            'p5.Gain': {
15391              setInput: {
15392                name: 'setInput',
15393                params: [
15394                  {
15395                    name: 'src',
15396                    description:
15397                      '<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n',
15398                    type: 'Object'
15399                  }
15400                ],
15401                class: 'p5.Gain',
15402                module: 'p5.sound'
15403              },
15404              connect: {
15405                name: 'connect',
15406                params: [
15407                  {
15408                    name: 'unit',
15409                    description: '',
15410                    type: 'Object'
15411                  }
15412                ],
15413                class: 'p5.Gain',
15414                module: 'p5.sound'
15415              },
15416              disconnect: {
15417                name: 'disconnect',
15418                class: 'p5.Gain',
15419                module: 'p5.sound'
15420              },
15421              amp: {
15422                name: 'amp',
15423                params: [
15424                  {
15425                    name: 'volume',
15426                    description: '<p>amplitude between 0 and 1.0</p>\n',
15427                    type: 'Number'
15428                  },
15429                  {
15430                    name: 'rampTime',
15431                    description: '<p>create a fade that lasts rampTime</p>\n',
15432                    type: 'Number',
15433                    optional: true
15434                  },
15435                  {
15436                    name: 'timeFromNow',
15437                    description:
15438                      '<p>schedule this event to happen\n                              seconds from now</p>\n',
15439                    type: 'Number',
15440                    optional: true
15441                  }
15442                ],
15443                class: 'p5.Gain',
15444                module: 'p5.sound'
15445              }
15446            },
15447            'p5.Distortion': {
15448              WaveShaperNode: {
15449                name: 'WaveShaperNode',
15450                class: 'p5.Distortion',
15451                module: 'p5.sound'
15452              },
15453              process: {
15454                name: 'process',
15455                params: [
15456                  {
15457                    name: 'amount',
15458                    description:
15459                      '<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n',
15460                    type: 'Number',
15461                    optional: true,
15462                    optdefault: '0.25'
15463                  },
15464                  {
15465                    name: 'oversample',
15466                    description: "<p>'none', '2x', or '4x'.</p>\n",
15467                    type: 'String',
15468                    optional: true,
15469                    optdefault: "'none'"
15470                  }
15471                ],
15472                class: 'p5.Distortion',
15473                module: 'p5.sound'
15474              },
15475              set: {
15476                name: 'set',
15477                params: [
15478                  {
15479                    name: 'amount',
15480                    description:
15481                      '<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n',
15482                    type: 'Number',
15483                    optional: true,
15484                    optdefault: '0.25'
15485                  },
15486                  {
15487                    name: 'oversample',
15488                    description: "<p>'none', '2x', or '4x'.</p>\n",
15489                    type: 'String',
15490                    optional: true,
15491                    optdefault: "'none'"
15492                  }
15493                ],
15494                class: 'p5.Distortion',
15495                module: 'p5.sound'
15496              },
15497              getAmount: {
15498                name: 'getAmount',
15499                class: 'p5.Distortion',
15500                module: 'p5.sound'
15501              },
15502              getOversample: {
15503                name: 'getOversample',
15504                class: 'p5.Distortion',
15505                module: 'p5.sound'
15506              }
15507            }
15508          };
15509        },
15510        {}
15511      ],
15512      2: [
15513        function(_dereq_, module, exports) {
15514          function _arrayWithHoles(arr) {
15515            if (Array.isArray(arr)) return arr;
15516          }
15517
15518          module.exports = _arrayWithHoles;
15519        },
15520        {}
15521      ],
15522      3: [
15523        function(_dereq_, module, exports) {
15524          function _arrayWithoutHoles(arr) {
15525            if (Array.isArray(arr)) {
15526              for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
15527                arr2[i] = arr[i];
15528              }
15529
15530              return arr2;
15531            }
15532          }
15533
15534          module.exports = _arrayWithoutHoles;
15535        },
15536        {}
15537      ],
15538      4: [
15539        function(_dereq_, module, exports) {
15540          function _assertThisInitialized(self) {
15541            if (self === void 0) {
15542              throw new ReferenceError(
15543                "this hasn't been initialised - super() hasn't been called"
15544              );
15545            }
15546
15547            return self;
15548          }
15549
15550          module.exports = _assertThisInitialized;
15551        },
15552        {}
15553      ],
15554      5: [
15555        function(_dereq_, module, exports) {
15556          function _classCallCheck(instance, Constructor) {
15557            if (!(instance instanceof Constructor)) {
15558              throw new TypeError('Cannot call a class as a function');
15559            }
15560          }
15561
15562          module.exports = _classCallCheck;
15563        },
15564        {}
15565      ],
15566      6: [
15567        function(_dereq_, module, exports) {
15568          function _defineProperties(target, props) {
15569            for (var i = 0; i < props.length; i++) {
15570              var descriptor = props[i];
15571              descriptor.enumerable = descriptor.enumerable || false;
15572              descriptor.configurable = true;
15573              if ('value' in descriptor) descriptor.writable = true;
15574              Object.defineProperty(target, descriptor.key, descriptor);
15575            }
15576          }
15577
15578          function _createClass(Constructor, protoProps, staticProps) {
15579            if (protoProps) _defineProperties(Constructor.prototype, protoProps);
15580            if (staticProps) _defineProperties(Constructor, staticProps);
15581            return Constructor;
15582          }
15583
15584          module.exports = _createClass;
15585        },
15586        {}
15587      ],
15588      7: [
15589        function(_dereq_, module, exports) {
15590          function _defineProperty(obj, key, value) {
15591            if (key in obj) {
15592              Object.defineProperty(obj, key, {
15593                value: value,
15594                enumerable: true,
15595                configurable: true,
15596                writable: true
15597              });
15598            } else {
15599              obj[key] = value;
15600            }
15601
15602            return obj;
15603          }
15604
15605          module.exports = _defineProperty;
15606        },
15607        {}
15608      ],
15609      8: [
15610        function(_dereq_, module, exports) {
15611          function _getPrototypeOf(o) {
15612            module.exports = _getPrototypeOf = Object.setPrototypeOf
15613              ? Object.getPrototypeOf
15614              : function _getPrototypeOf(o) {
15615                  return o.__proto__ || Object.getPrototypeOf(o);
15616                };
15617            return _getPrototypeOf(o);
15618          }
15619
15620          module.exports = _getPrototypeOf;
15621        },
15622        {}
15623      ],
15624      9: [
15625        function(_dereq_, module, exports) {
15626          var setPrototypeOf = _dereq_('./setPrototypeOf');
15627
15628          function _inherits(subClass, superClass) {
15629            if (typeof superClass !== 'function' && superClass !== null) {
15630              throw new TypeError('Super expression must either be null or a function');
15631            }
15632
15633            subClass.prototype = Object.create(superClass && superClass.prototype, {
15634              constructor: {
15635                value: subClass,
15636                writable: true,
15637                configurable: true
15638              }
15639            });
15640            if (superClass) setPrototypeOf(subClass, superClass);
15641          }
15642
15643          module.exports = _inherits;
15644        },
15645        { './setPrototypeOf': 16 }
15646      ],
15647      10: [
15648        function(_dereq_, module, exports) {
15649          function _iterableToArray(iter) {
15650            if (
15651              Symbol.iterator in Object(iter) ||
15652              Object.prototype.toString.call(iter) === '[object Arguments]'
15653            )
15654              return Array.from(iter);
15655          }
15656
15657          module.exports = _iterableToArray;
15658        },
15659        {}
15660      ],
15661      11: [
15662        function(_dereq_, module, exports) {
15663          function _iterableToArrayLimit(arr, i) {
15664            var _arr = [];
15665            var _n = true;
15666            var _d = false;
15667            var _e = undefined;
15668
15669            try {
15670              for (
15671                var _i = arr[Symbol.iterator](), _s;
15672                !(_n = (_s = _i.next()).done);
15673                _n = true
15674              ) {
15675                _arr.push(_s.value);
15676
15677                if (i && _arr.length === i) break;
15678              }
15679            } catch (err) {
15680              _d = true;
15681              _e = err;
15682            } finally {
15683              try {
15684                if (!_n && _i['return'] != null) _i['return']();
15685              } finally {
15686                if (_d) throw _e;
15687              }
15688            }
15689
15690            return _arr;
15691          }
15692
15693          module.exports = _iterableToArrayLimit;
15694        },
15695        {}
15696      ],
15697      12: [
15698        function(_dereq_, module, exports) {
15699          function _nonIterableRest() {
15700            throw new TypeError('Invalid attempt to destructure non-iterable instance');
15701          }
15702
15703          module.exports = _nonIterableRest;
15704        },
15705        {}
15706      ],
15707      13: [
15708        function(_dereq_, module, exports) {
15709          function _nonIterableSpread() {
15710            throw new TypeError('Invalid attempt to spread non-iterable instance');
15711          }
15712
15713          module.exports = _nonIterableSpread;
15714        },
15715        {}
15716      ],
15717      14: [
15718        function(_dereq_, module, exports) {
15719          var defineProperty = _dereq_('./defineProperty');
15720
15721          function _objectSpread(target) {
15722            for (var i = 1; i < arguments.length; i++) {
15723              var source = arguments[i] != null ? arguments[i] : {};
15724              var ownKeys = Object.keys(source);
15725
15726              if (typeof Object.getOwnPropertySymbols === 'function') {
15727                ownKeys = ownKeys.concat(
15728                  Object.getOwnPropertySymbols(source).filter(function(sym) {
15729                    return Object.getOwnPropertyDescriptor(source, sym).enumerable;
15730                  })
15731                );
15732              }
15733
15734              ownKeys.forEach(function(key) {
15735                defineProperty(target, key, source[key]);
15736              });
15737            }
15738
15739            return target;
15740          }
15741
15742          module.exports = _objectSpread;
15743        },
15744        { './defineProperty': 7 }
15745      ],
15746      15: [
15747        function(_dereq_, module, exports) {
15748          var _typeof = _dereq_('../helpers/typeof');
15749
15750          var assertThisInitialized = _dereq_('./assertThisInitialized');
15751
15752          function _possibleConstructorReturn(self, call) {
15753            if (call && (_typeof(call) === 'object' || typeof call === 'function')) {
15754              return call;
15755            }
15756
15757            return assertThisInitialized(self);
15758          }
15759
15760          module.exports = _possibleConstructorReturn;
15761        },
15762        { '../helpers/typeof': 19, './assertThisInitialized': 4 }
15763      ],
15764      16: [
15765        function(_dereq_, module, exports) {
15766          function _setPrototypeOf(o, p) {
15767            module.exports = _setPrototypeOf =
15768              Object.setPrototypeOf ||
15769              function _setPrototypeOf(o, p) {
15770                o.__proto__ = p;
15771                return o;
15772              };
15773
15774            return _setPrototypeOf(o, p);
15775          }
15776
15777          module.exports = _setPrototypeOf;
15778        },
15779        {}
15780      ],
15781      17: [
15782        function(_dereq_, module, exports) {
15783          var arrayWithHoles = _dereq_('./arrayWithHoles');
15784
15785          var iterableToArrayLimit = _dereq_('./iterableToArrayLimit');
15786
15787          var nonIterableRest = _dereq_('./nonIterableRest');
15788
15789          function _slicedToArray(arr, i) {
15790            return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();
15791          }
15792
15793          module.exports = _slicedToArray;
15794        },
15795        { './arrayWithHoles': 2, './iterableToArrayLimit': 11, './nonIterableRest': 12 }
15796      ],
15797      18: [
15798        function(_dereq_, module, exports) {
15799          var arrayWithoutHoles = _dereq_('./arrayWithoutHoles');
15800
15801          var iterableToArray = _dereq_('./iterableToArray');
15802
15803          var nonIterableSpread = _dereq_('./nonIterableSpread');
15804
15805          function _toConsumableArray(arr) {
15806            return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
15807          }
15808
15809          module.exports = _toConsumableArray;
15810        },
15811        { './arrayWithoutHoles': 3, './iterableToArray': 10, './nonIterableSpread': 13 }
15812      ],
15813      19: [
15814        function(_dereq_, module, exports) {
15815          function _typeof2(obj) {
15816            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
15817              _typeof2 = function _typeof2(obj) {
15818                return typeof obj;
15819              };
15820            } else {
15821              _typeof2 = function _typeof2(obj) {
15822                return obj &&
15823                  typeof Symbol === 'function' &&
15824                  obj.constructor === Symbol &&
15825                  obj !== Symbol.prototype
15826                  ? 'symbol'
15827                  : typeof obj;
15828              };
15829            }
15830            return _typeof2(obj);
15831          }
15832
15833          function _typeof(obj) {
15834            if (typeof Symbol === 'function' && _typeof2(Symbol.iterator) === 'symbol') {
15835              module.exports = _typeof = function _typeof(obj) {
15836                return _typeof2(obj);
15837              };
15838            } else {
15839              module.exports = _typeof = function _typeof(obj) {
15840                return obj &&
15841                  typeof Symbol === 'function' &&
15842                  obj.constructor === Symbol &&
15843                  obj !== Symbol.prototype
15844                  ? 'symbol'
15845                  : _typeof2(obj);
15846              };
15847            }
15848
15849            return _typeof(obj);
15850          }
15851
15852          module.exports = _typeof;
15853        },
15854        {}
15855      ],
15856      20: [
15857        function(_dereq_, module, exports) {
15858          'use strict';
15859
15860          exports.byteLength = byteLength;
15861          exports.toByteArray = toByteArray;
15862          exports.fromByteArray = fromByteArray;
15863
15864          var lookup = [];
15865          var revLookup = [];
15866          var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
15867
15868          var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
15869          for (var i = 0, len = code.length; i < len; ++i) {
15870            lookup[i] = code[i];
15871            revLookup[code.charCodeAt(i)] = i;
15872          }
15873
15874          // Support decoding URL-safe base64 strings, as Node.js does.
15875          // See: https://en.wikipedia.org/wiki/Base64#URL_applications
15876          revLookup['-'.charCodeAt(0)] = 62;
15877          revLookup['_'.charCodeAt(0)] = 63;
15878
15879          function getLens(b64) {
15880            var len = b64.length;
15881
15882            if (len % 4 > 0) {
15883              throw new Error('Invalid string. Length must be a multiple of 4');
15884            }
15885
15886            // Trim off extra bytes after placeholder bytes are found
15887            // See: https://github.com/beatgammit/base64-js/issues/42
15888            var validLen = b64.indexOf('=');
15889            if (validLen === -1) validLen = len;
15890
15891            var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;
15892
15893            return [validLen, placeHoldersLen];
15894          }
15895
15896          // base64 is 4/3 + up to two characters of the original data
15897          function byteLength(b64) {
15898            var lens = getLens(b64);
15899            var validLen = lens[0];
15900            var placeHoldersLen = lens[1];
15901            return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
15902          }
15903
15904          function _byteLength(b64, validLen, placeHoldersLen) {
15905            return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
15906          }
15907
15908          function toByteArray(b64) {
15909            var tmp;
15910            var lens = getLens(b64);
15911            var validLen = lens[0];
15912            var placeHoldersLen = lens[1];
15913
15914            var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
15915
15916            var curByte = 0;
15917
15918            // if there are placeholders, only get up to the last complete 4 chars
15919            var len = placeHoldersLen > 0 ? validLen - 4 : validLen;
15920
15921            var i;
15922            for (i = 0; i < len; i += 4) {
15923              tmp =
15924                (revLookup[b64.charCodeAt(i)] << 18) |
15925                (revLookup[b64.charCodeAt(i + 1)] << 12) |
15926                (revLookup[b64.charCodeAt(i + 2)] << 6) |
15927                revLookup[b64.charCodeAt(i + 3)];
15928              arr[curByte++] = (tmp >> 16) & 0xff;
15929              arr[curByte++] = (tmp >> 8) & 0xff;
15930              arr[curByte++] = tmp & 0xff;
15931            }
15932
15933            if (placeHoldersLen === 2) {
15934              tmp =
15935                (revLookup[b64.charCodeAt(i)] << 2) |
15936                (revLookup[b64.charCodeAt(i + 1)] >> 4);
15937              arr[curByte++] = tmp & 0xff;
15938            }
15939
15940            if (placeHoldersLen === 1) {
15941              tmp =
15942                (revLookup[b64.charCodeAt(i)] << 10) |
15943                (revLookup[b64.charCodeAt(i + 1)] << 4) |
15944                (revLookup[b64.charCodeAt(i + 2)] >> 2);
15945              arr[curByte++] = (tmp >> 8) & 0xff;
15946              arr[curByte++] = tmp & 0xff;
15947            }
15948
15949            return arr;
15950          }
15951
15952          function tripletToBase64(num) {
15953            return (
15954              lookup[(num >> 18) & 0x3f] +
15955              lookup[(num >> 12) & 0x3f] +
15956              lookup[(num >> 6) & 0x3f] +
15957              lookup[num & 0x3f]
15958            );
15959          }
15960
15961          function encodeChunk(uint8, start, end) {
15962            var tmp;
15963            var output = [];
15964            for (var i = start; i < end; i += 3) {
15965              tmp =
15966                ((uint8[i] << 16) & 0xff0000) +
15967                ((uint8[i + 1] << 8) & 0xff00) +
15968                (uint8[i + 2] & 0xff);
15969              output.push(tripletToBase64(tmp));
15970            }
15971            return output.join('');
15972          }
15973
15974          function fromByteArray(uint8) {
15975            var tmp;
15976            var len = uint8.length;
15977            var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
15978            var parts = [];
15979            var maxChunkLength = 16383; // must be multiple of 3
15980
15981            // go through the array every three bytes, we'll deal with trailing stuff later
15982            for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
15983              parts.push(
15984                encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength)
15985              );
15986            }
15987
15988            // pad the end with zeros, but make sure to not forget the extra bytes
15989            if (extraBytes === 1) {
15990              tmp = uint8[len - 1];
15991              parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==');
15992            } else if (extraBytes === 2) {
15993              tmp = (uint8[len - 2] << 8) + uint8[len - 1];
15994              parts.push(
15995                lookup[tmp >> 10] +
15996                  lookup[(tmp >> 4) & 0x3f] +
15997                  lookup[(tmp << 2) & 0x3f] +
15998                  '='
15999              );
16000            }
16001
16002            return parts.join('');
16003          }
16004        },
16005        {}
16006      ],
16007      21: [function(_dereq_, module, exports) {}, {}],
16008      22: [
16009        function(_dereq_, module, exports) {
16010          (function(Buffer) {
16011            /*!
16012 * The buffer module from node.js, for the browser.
16013 *
16014 * @author   Feross Aboukhadijeh <https://feross.org>
16015 * @license  MIT
16016 */
16017            /* eslint-disable no-proto */
16018
16019            'use strict';
16020
16021            var base64 = _dereq_('base64-js');
16022            var ieee754 = _dereq_('ieee754');
16023            var customInspectSymbol =
16024              typeof Symbol === 'function' && typeof Symbol.for === 'function'
16025                ? Symbol.for('nodejs.util.inspect.custom')
16026                : null;
16027
16028            exports.Buffer = Buffer;
16029            exports.SlowBuffer = SlowBuffer;
16030            exports.INSPECT_MAX_BYTES = 50;
16031
16032            var K_MAX_LENGTH = 0x7fffffff;
16033            exports.kMaxLength = K_MAX_LENGTH;
16034
16035            /**
16036             * If `Buffer.TYPED_ARRAY_SUPPORT`:
16037             *   === true    Use Uint8Array implementation (fastest)
16038             *   === false   Print warning and recommend using `buffer` v4.x which has an Object
16039             *               implementation (most compatible, even IE6)
16040             *
16041             * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
16042             * Opera 11.6+, iOS 4.2+.
16043             *
16044             * We report that the browser does not support typed arrays if the are not subclassable
16045             * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
16046             * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks supp
vendor: 6,630 bytes, lines 16046-16224
16046ort
16047             * for __proto__ and has a buggy typed array implementation.
16048             */
16049            Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport();
16050
16051            if (
16052              !Buffer.TYPED_ARRAY_SUPPORT &&
16053              typeof console !== 'undefined' &&
16054              typeof console.error === 'function'
16055            ) {
16056              console.error(
16057                'This browser lacks typed array (Uint8Array) support which is required by ' +
16058                  '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
16059              );
16060            }
16061
16062            function typedArraySupport() {
16063              // Can typed array instances can be augmented?
16064              try {
16065                var arr = new Uint8Array(1);
16066                var proto = {
16067                  foo: function() {
16068                    return 42;
16069                  }
16070                };
16071                Object.setPrototypeOf(proto, Uint8Array.prototype);
16072                Object.setPrototypeOf(arr, proto);
16073                return arr.foo() === 42;
16074              } catch (e) {
16075                return false;
16076              }
16077            }
16078
16079            Object.defineProperty(Buffer.prototype, 'parent', {
16080              enumerable: true,
16081              get: function() {
16082                if (!Buffer.isBuffer(this)) return undefined;
16083                return this.buffer;
16084              }
16085            });
16086
16087            Object.defineProperty(Buffer.prototype, 'offset', {
16088              enumerable: true,
16089              get: function() {
16090                if (!Buffer.isBuffer(this)) return undefined;
16091                return this.byteOffset;
16092              }
16093            });
16094
16095            function createBuffer(length) {
16096              if (length > K_MAX_LENGTH) {
16097                throw new RangeError(
16098                  'The value "' + length + '" is invalid for option "size"'
16099                );
16100              }
16101              // Return an augmented `Uint8Array` instance
16102              var buf = new Uint8Array(length);
16103              Object.setPrototypeOf(buf, Buffer.prototype);
16104              return buf;
16105            }
16106
16107            /**
16108             * The Buffer constructor returns instances of `Uint8Array` that have their
16109             * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
16110             * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
16111             * and the `Uint8Array` methods. Square bracket notation works as expected -- it
16112             * returns a single octet.
16113             *
16114             * The `Uint8Array` prototype remains unmodified.
16115             */
16116
16117            function Buffer(arg, encodingOrOffset, length) {
16118              // Common case.
16119              if (typeof arg === 'number') {
16120                if (typeof encodingOrOffset === 'string') {
16121                  throw new TypeError(
16122                    'The "string" argument must be of type string. Received type number'
16123                  );
16124                }
16125                return allocUnsafe(arg);
16126              }
16127              return from(arg, encodingOrOffset, length);
16128            }
16129
16130            // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
16131            if (
16132              typeof Symbol !== 'undefined' &&
16133              Symbol.species != null &&
16134              Buffer[Symbol.species] === Buffer
16135            ) {
16136              Object.defineProperty(Buffer, Symbol.species, {
16137                value: null,
16138                configurable: true,
16139                enumerable: false,
16140                writable: false
16141              });
16142            }
16143
16144            Buffer.poolSize = 8192; // not used by this implementation
16145
16146            function from(value, encodingOrOffset, length) {
16147              if (typeof value === 'string') {
16148                return fromString(value, encodingOrOffset);
16149              }
16150
16151              if (ArrayBuffer.isView(value)) {
16152                return fromArrayLike(value);
16153              }
16154
16155              if (value == null) {
16156                throw new TypeError(
16157                  'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
16158                    'or Array-like Object. Received type ' +
16159                    typeof value
16160                );
16161              }
16162
16163              if (
16164                isInstance(value, ArrayBuffer) ||
16165                (value && isInstance(value.buffer, ArrayBuffer))
16166              ) {
16167                return fromArrayBuffer(value, encodingOrOffset, length);
16168              }
16169
16170              if (typeof value === 'number') {
16171                throw new TypeError(
16172                  'The "value" argument must not be of type number. Received type number'
16173                );
16174              }
16175
16176              var valueOf = value.valueOf && value.valueOf();
16177              if (valueOf != null && valueOf !== value) {
16178                return Buffer.from(valueOf, encodingOrOffset, length);
16179              }
16180
16181              var b = fromObject(value);
16182              if (b) return b;
16183
16184              if (
16185                typeof Symbol !== 'undefined' &&
16186                Symbol.toPrimitive != null &&
16187                typeof value[Symbol.toPrimitive] === 'function'
16188              ) {
16189                return Buffer.from(
16190                  value[Symbol.toPrimitive]('string'),
16191                  encodingOrOffset,
16192                  length
16193                );
16194              }
16195
16196              throw new TypeError(
16197                'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
16198                  'or Array-like Object. Received type ' +
16199                  typeof value
16200              );
16201            }
16202
16203            /**
16204             * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
16205             * if value is a number.
16206             * Buffer.from(str[, encoding])
16207             * Buffer.from(array)
16208             * Buffer.from(buffer)
16209             * Buffer.from(arrayBuffer[, byteOffset[, length]])
16210             **/
16211            Buffer.from = function(value, encodingOrOffset, length) {
16212              return from(value, encodingOrOffset, length);
16213            };
16214
16215            // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
16216            // https://github.com/feross/buffer/pull/148
16217            Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype);
16218            Object.setPrototypeOf(Buffer, Uint8Array);
16219
16220            function assertSize(size) {
16221              if (typeof size !== 'number') {
16222                throw new TypeError('"size" argument must be of type number');
16223              } else if (size < 0) {
16224                throw new RangeError(
vendor: 5,389 bytes, lines 16225-16377
16225                  'The value "' + size + '" is invalid for option "size"'
16226                );
16227              }
16228            }
16229
16230            function alloc(size, fill, encoding) {
16231              assertSize(size);
16232              if (size <= 0) {
16233                return createBuffer(size);
16234              }
16235              if (fill !== undefined) {
16236                // Only pay attention to encoding if it's a string. This
16237                // prevents accidentally sending in a number that would
16238                // be interpretted as a start offset.
16239                return typeof encoding === 'string'
16240                  ? createBuffer(size).fill(fill, encoding)
16241                  : createBuffer(size).fill(fill);
16242              }
16243              return createBuffer(size);
16244            }
16245
16246            /**
16247             * Creates a new filled Buffer instance.
16248             * alloc(size[, fill[, encoding]])
16249             **/
16250            Buffer.alloc = function(size, fill, encoding) {
16251              return alloc(size, fill, encoding);
16252            };
16253
16254            function allocUnsafe(size) {
16255              assertSize(size);
16256              return createBuffer(size < 0 ? 0 : checked(size) | 0);
16257            }
16258
16259            /**
16260             * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
16261             * */
16262            Buffer.allocUnsafe = function(size) {
16263              return allocUnsafe(size);
16264            };
16265            /**
16266             * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
16267             */
16268            Buffer.allocUnsafeSlow = function(size) {
16269              return allocUnsafe(size);
16270            };
16271
16272            function fromString(string, encoding) {
16273              if (typeof encoding !== 'string' || encoding === '') {
16274                encoding = 'utf8';
16275              }
16276
16277              if (!Buffer.isEncoding(encoding)) {
16278                throw new TypeError('Unknown encoding: ' + encoding);
16279              }
16280
16281              var length = byteLength(string, encoding) | 0;
16282              var buf = createBuffer(length);
16283
16284              var actual = buf.write(string, encoding);
16285
16286              if (actual !== length) {
16287                // Writing a hex string, for example, that contains invalid characters will
16288                // cause everything after the first invalid character to be ignored. (e.g.
16289                // 'abxxcd' will be treated as 'ab')
16290                buf = buf.slice(0, actual);
16291              }
16292
16293              return buf;
16294            }
16295
16296            function fromArrayLike(array) {
16297              var length = array.length < 0 ? 0 : checked(array.length) | 0;
16298              var buf = createBuffer(length);
16299              for (var i = 0; i < length; i += 1) {
16300                buf[i] = array[i] & 255;
16301              }
16302              return buf;
16303            }
16304
16305            function fromArrayBuffer(array, byteOffset, length) {
16306              if (byteOffset < 0 || array.byteLength < byteOffset) {
16307                throw new RangeError('"offset" is outside of buffer bounds');
16308              }
16309
16310              if (array.byteLength < byteOffset + (length || 0)) {
16311                throw new RangeError('"length" is outside of buffer bounds');
16312              }
16313
16314              var buf;
16315              if (byteOffset === undefined && length === undefined) {
16316                buf = new Uint8Array(array);
16317              } else if (length === undefined) {
16318                buf = new Uint8Array(array, byteOffset);
16319              } else {
16320                buf = new Uint8Array(array, byteOffset, length);
16321              }
16322
16323              // Return an augmented `Uint8Array` instance
16324              Object.setPrototypeOf(buf, Buffer.prototype);
16325
16326              return buf;
16327            }
16328
16329            function fromObject(obj) {
16330              if (Buffer.isBuffer(obj)) {
16331                var len = checked(obj.length) | 0;
16332                var buf = createBuffer(len);
16333
16334                if (buf.length === 0) {
16335                  return buf;
16336                }
16337
16338                obj.copy(buf, 0, 0, len);
16339                return buf;
16340              }
16341
16342              if (obj.length !== undefined) {
16343                if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
16344                  return createBuffer(0);
16345                }
16346                return fromArrayLike(obj);
16347              }
16348
16349              if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
16350                return fromArrayLike(obj.data);
16351              }
16352            }
16353
16354            function checked(length) {
16355              // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
16356              // length is NaN (which is otherwise coerced to zero.)
16357              if (length >= K_MAX_LENGTH) {
16358                throw new RangeError(
16359                  'Attempt to allocate Buffer larger than maximum ' +
16360                    'size: 0x' +
16361                    K_MAX_LENGTH.toString(16) +
16362                    ' bytes'
16363                );
16364              }
16365              return length | 0;
16366            }
16367
16368            function SlowBuffer(length) {
16369              if (+length != length) {
16370                // eslint-disable-line eqeqeq
16371                length = 0;
16372              }
16373              return Buffer.alloc(+length);
16374            }
16375
16376            Buffer.isBuffer = function isBuffer(b) {
16377              return b != null && b._isBuffer === true && b !== Buffer.prototype;
vendor: 4,569 bytes, lines 16377-16510
16377 // so Buffer.isBuffer(Buffer.prototype) will be false
16378            };
16379
16380            Buffer.compare = function compare(a, b) {
16381              if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength);
16382              if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength);
16383              if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
16384                throw new TypeError(
16385                  'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
16386                );
16387              }
16388
16389              if (a === b) return 0;
16390
16391              var x = a.length;
16392              var y = b.length;
16393
16394              for (var i = 0, len = Math.min(x, y); i < len; ++i) {
16395                if (a[i] !== b[i]) {
16396                  x = a[i];
16397                  y = b[i];
16398                  break;
16399                }
16400              }
16401
16402              if (x < y) return -1;
16403              if (y < x) return 1;
16404              return 0;
16405            };
16406
16407            Buffer.isEncoding = function isEncoding(encoding) {
16408              switch (String(encoding).toLowerCase()) {
16409                case 'hex':
16410                case 'utf8':
16411                case 'utf-8':
16412                case 'ascii':
16413                case 'latin1':
16414                case 'binary':
16415                case 'base64':
16416                case 'ucs2':
16417                case 'ucs-2':
16418                case 'utf16le':
16419                case 'utf-16le':
16420                  return true;
16421                default:
16422                  return false;
16423              }
16424            };
16425
16426            Buffer.concat = function concat(list, length) {
16427              if (!Array.isArray(list)) {
16428                throw new TypeError('"list" argument must be an Array of Buffers');
16429              }
16430
16431              if (list.length === 0) {
16432                return Buffer.alloc(0);
16433              }
16434
16435              var i;
16436              if (length === undefined) {
16437                length = 0;
16438                for (i = 0; i < list.length; ++i) {
16439                  length += list[i].length;
16440                }
16441              }
16442
16443              var buffer = Buffer.allocUnsafe(length);
16444              var pos = 0;
16445              for (i = 0; i < list.length; ++i) {
16446                var buf = list[i];
16447                if (isInstance(buf, Uint8Array)) {
16448                  buf = Buffer.from(buf);
16449                }
16450                if (!Buffer.isBuffer(buf)) {
16451                  throw new TypeError('"list" argument must be an Array of Buffers');
16452                }
16453                buf.copy(buffer, pos);
16454                pos += buf.length;
16455              }
16456              return buffer;
16457            };
16458
16459            function byteLength(string, encoding) {
16460              if (Buffer.isBuffer(string)) {
16461                return string.length;
16462              }
16463              if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
16464                return string.byteLength;
16465              }
16466              if (typeof string !== 'string') {
16467                throw new TypeError(
16468                  'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
16469                    'Received type ' +
16470                    typeof string
16471                );
16472              }
16473
16474              var len = string.length;
16475              var mustMatch = arguments.length > 2 && arguments[2] === true;
16476              if (!mustMatch && len === 0) return 0;
16477
16478              // Use a for loop to avoid recursion
16479              var loweredCase = false;
16480              for (;;) {
16481                switch (encoding) {
16482                  case 'ascii':
16483                  case 'latin1':
16484                  case 'binary':
16485                    return len;
16486                  case 'utf8':
16487                  case 'utf-8':
16488                    return utf8ToBytes(string).length;
16489                  case 'ucs2':
16490                  case 'ucs-2':
16491                  case 'utf16le':
16492                  case 'utf-16le':
16493                    return len * 2;
16494                  case 'hex':
16495                    return len >>> 1;
16496                  case 'base64':
16497                    return base64ToBytes(string).length;
16498                  default:
16499                    if (loweredCase) {
16500                      return mustMatch ? -1 : utf8ToBytes(string).length; // assume utf8
16501                    }
16502                    encoding = ('' + encoding).toLowerCase();
16503                    loweredCase = true;
16504                }
16505              }
16506            }
16507            Buffer.byteLength = byteLength;
16508
16509            function slowToString(encoding, start, end) {
16510              var loweredCase = false;
vendor: 4,552 bytes, lines 16511-16636
16511
16512              // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
16513              // property of a typed array.
16514
16515              // This behaves neither like String nor Uint8Array in that we set start/end
16516              // to their upper/lower bounds if the value passed is out of range.
16517              // undefined is handled specially as per ECMA-262 6th Edition,
16518              // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
16519              if (start === undefined || start < 0) {
16520                start = 0;
16521              }
16522              // Return early if start > this.length. Done here to prevent potential uint32
16523              // coercion fail below.
16524              if (start > this.length) {
16525                return '';
16526              }
16527
16528              if (end === undefined || end > this.length) {
16529                end = this.length;
16530              }
16531
16532              if (end <= 0) {
16533                return '';
16534              }
16535
16536              // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
16537              end >>>= 0;
16538              start >>>= 0;
16539
16540              if (end <= start) {
16541                return '';
16542              }
16543
16544              if (!encoding) encoding = 'utf8';
16545
16546              while (true) {
16547                switch (encoding) {
16548                  case 'hex':
16549                    return hexSlice(this, start, end);
16550
16551                  case 'utf8':
16552                  case 'utf-8':
16553                    return utf8Slice(this, start, end);
16554
16555                  case 'ascii':
16556                    return asciiSlice(this, start, end);
16557
16558                  case 'latin1':
16559                  case 'binary':
16560                    return latin1Slice(this, start, end);
16561
16562                  case 'base64':
16563                    return base64Slice(this, start, end);
16564
16565                  case 'ucs2':
16566                  case 'ucs-2':
16567                  case 'utf16le':
16568                  case 'utf-16le':
16569                    return utf16leSlice(this, start, end);
16570
16571                  default:
16572                    if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
16573                    encoding = (encoding + '').toLowerCase();
16574                    loweredCase = true;
16575                }
16576              }
16577            }
16578
16579            // This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
16580            // to detect a Buffer instance. It's not possible to use `instanceof Buffer`
16581            // reliably in a browserify context because there could be multiple different
16582            // copies of the 'buffer' package in use. This method works even for Buffer
16583            // instances that were created from another copy of the `buffer` package.
16584            // See: https://github.com/feross/buffer/issues/154
16585            Buffer.prototype._isBuffer = true;
16586
16587            function swap(b, n, m) {
16588              var i = b[n];
16589              b[n] = b[m];
16590              b[m] = i;
16591            }
16592
16593            Buffer.prototype.swap16 = function swap16() {
16594              var len = this.length;
16595              if (len % 2 !== 0) {
16596                throw new RangeError('Buffer size must be a multiple of 16-bits');
16597              }
16598              for (var i = 0; i < len; i += 2) {
16599                swap(this, i, i + 1);
16600              }
16601              return this;
16602            };
16603
16604            Buffer.prototype.swap32 = function swap32() {
16605              var len = this.length;
16606              if (len % 4 !== 0) {
16607                throw new RangeError('Buffer size must be a multiple of 32-bits');
16608              }
16609              for (var i = 0; i < len; i += 4) {
16610                swap(this, i, i + 3);
16611                swap(this, i + 1, i + 2);
16612              }
16613              return this;
16614            };
16615
16616            Buffer.prototype.swap64 = function swap64() {
16617              var len = this.length;
16618              if (len % 8 !== 0) {
16619                throw new RangeError('Buffer size must be a multiple of 64-bits');
16620              }
16621              for (var i = 0; i < len; i += 8) {
16622                swap(this, i, i + 7);
16623                swap(this, i + 1, i + 6);
16624                swap(this, i + 2, i + 5);
16625                swap(this, i + 3, i + 4);
16626              }
16627              return this;
16628            };
16629
16630            Buffer.prototype.toString = function toString() {
16631              var length = this.length;
16632              if (length === 0) return '';
16633              if (arguments.length === 0) return utf8Slice(this, 0, length);
16634              return slowToString.apply(this, arguments);
16635            };
16636
vendor: 12,005 bytes, lines 16637-16966
16637            Buffer.prototype.toLocaleString = Buffer.prototype.toString;
16638
16639            Buffer.prototype.equals = function equals(b) {
16640              if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer');
16641              if (this === b) return true;
16642              return Buffer.compare(this, b) === 0;
16643            };
16644
16645            Buffer.prototype.inspect = function inspect() {
16646              var str = '';
16647              var max = exports.INSPECT_MAX_BYTES;
16648              str = this.toString('hex', 0, max)
16649                .replace(/(.{2})/g, '$1 ')
16650                .trim();
16651              if (this.length > max) str += ' ... ';
16652              return '<Buffer ' + str + '>';
16653            };
16654            if (customInspectSymbol) {
16655              Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect;
16656            }
16657
16658            Buffer.prototype.compare = function compare(
16659              target,
16660              start,
16661              end,
16662              thisStart,
16663              thisEnd
16664            ) {
16665              if (isInstance(target, Uint8Array)) {
16666                target = Buffer.from(target, target.offset, target.byteLength);
16667              }
16668              if (!Buffer.isBuffer(target)) {
16669                throw new TypeError(
16670                  'The "target" argument must be one of type Buffer or Uint8Array. ' +
16671                    'Received type ' +
16672                    typeof target
16673                );
16674              }
16675
16676              if (start === undefined) {
16677                start = 0;
16678              }
16679              if (end === undefined) {
16680                end = target ? target.length : 0;
16681              }
16682              if (thisStart === undefined) {
16683                thisStart = 0;
16684              }
16685              if (thisEnd === undefined) {
16686                thisEnd = this.length;
16687              }
16688
16689              if (
16690                start < 0 ||
16691                end > target.length ||
16692                thisStart < 0 ||
16693                thisEnd > this.length
16694              ) {
16695                throw new RangeError('out of range index');
16696              }
16697
16698              if (thisStart >= thisEnd && start >= end) {
16699                return 0;
16700              }
16701              if (thisStart >= thisEnd) {
16702                return -1;
16703              }
16704              if (start >= end) {
16705                return 1;
16706              }
16707
16708              start >>>= 0;
16709              end >>>= 0;
16710              thisStart >>>= 0;
16711              thisEnd >>>= 0;
16712
16713              if (this === target) return 0;
16714
16715              var x = thisEnd - thisStart;
16716              var y = end - start;
16717              var len = Math.min(x, y);
16718
16719              var thisCopy = this.slice(thisStart, thisEnd);
16720              var targetCopy = target.slice(start, end);
16721
16722              for (var i = 0; i < len; ++i) {
16723                if (thisCopy[i] !== targetCopy[i]) {
16724                  x = thisCopy[i];
16725                  y = targetCopy[i];
16726                  break;
16727                }
16728              }
16729
16730              if (x < y) return -1;
16731              if (y < x) return 1;
16732              return 0;
16733            };
16734
16735            // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
16736            // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
16737            //
16738            // Arguments:
16739            // - buffer - a Buffer to search
16740            // - val - a string, Buffer, or number
16741            // - byteOffset - an index into `buffer`; will be clamped to an int32
16742            // - encoding - an optional encoding, relevant is val is a string
16743            // - dir - true for indexOf, false for lastIndexOf
16744            function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
16745              // Empty buffer means no match
16746              if (buffer.length === 0) return -1;
16747
16748              // Normalize byteOffset
16749              if (typeof byteOffset === 'string') {
16750                encoding = byteOffset;
16751                byteOffset = 0;
16752              } else if (byteOffset > 0x7fffffff) {
16753                byteOffset = 0x7fffffff;
16754              } else if (byteOffset < -0x80000000) {
16755                byteOffset = -0x80000000;
16756              }
16757              byteOffset = +byteOffset; // Coerce to Number.
16758              if (numberIsNaN(byteOffset)) {
16759                // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
16760                byteOffset = dir ? 0 : buffer.length - 1;
16761              }
16762
16763              // Normalize byteOffset: negative offsets start from the end of the buffer
16764              if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
16765              if (byteOffset >= buffer.length) {
16766                if (dir) return -1;
16767                else byteOffset = buffer.length - 1;
16768              } else if (byteOffset < 0) {
16769                if (dir) byteOffset = 0;
16770                else return -1;
16771              }
16772
16773              // Normalize val
16774              if (typeof val === 'string') {
16775                val = Buffer.from(val, encoding);
16776              }
16777
16778              // Finally, search either indexOf (if dir is true) or lastIndexOf
16779              if (Buffer.isBuffer(val)) {
16780                // Special case: looking for empty string/buffer always fails
16781                if (val.length === 0) {
16782                  return -1;
16783                }
16784                return arrayIndexOf(buffer, val, byteOffset, encoding, dir);
16785              } else if (typeof val === 'number') {
16786                val = val & 0xff; // Search for a byte value [0-255]
16787                if (typeof Uint8Array.prototype.indexOf === 'function') {
16788                  if (dir) {
16789                    return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
16790                  } else {
16791                    return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
16792                  }
16793                }
16794                return arrayIndexOf(buffer, [val], byteOffset, encoding, dir);
16795              }
16796
16797              throw new TypeError('val must be string, number or Buffer');
16798            }
16799
16800            function arrayIndexOf(arr, val, byteOffset, encoding, dir) {
16801              var indexSize = 1;
16802              var arrLength = arr.length;
16803              var valLength = val.length;
16804
16805              if (encoding !== undefined) {
16806                encoding = String(encoding).toLowerCase();
16807                if (
16808                  encoding === 'ucs2' ||
16809                  encoding === 'ucs-2' ||
16810                  encoding === 'utf16le' ||
16811                  encoding === 'utf-16le'
16812                ) {
16813                  if (arr.length < 2 || val.length < 2) {
16814                    return -1;
16815                  }
16816                  indexSize = 2;
16817                  arrLength /= 2;
16818                  valLength /= 2;
16819                  byteOffset /= 2;
16820                }
16821              }
16822
16823              function read(buf, i) {
16824                if (indexSize === 1) {
16825                  return buf[i];
16826                } else {
16827                  return buf.readUInt16BE(i * indexSize);
16828                }
16829              }
16830
16831              var i;
16832              if (dir) {
16833                var foundIndex = -1;
16834                for (i = byteOffset; i < arrLength; i++) {
16835                  if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
16836                    if (foundIndex === -1) foundIndex = i;
16837                    if (i - foundIndex + 1 === valLength) return foundIndex * indexSize;
16838                  } else {
16839                    if (foundIndex !== -1) i -= i - foundIndex;
16840                    foundIndex = -1;
16841                  }
16842                }
16843              } else {
16844                if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength;
16845                for (i = byteOffset; i >= 0; i--) {
16846                  var found = true;
16847                  for (var j = 0; j < valLength; j++) {
16848                    if (read(arr, i + j) !== read(val, j)) {
16849                      found = false;
16850                      break;
16851                    }
16852                  }
16853                  if (found) return i;
16854                }
16855              }
16856
16857              return -1;
16858            }
16859
16860            Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
16861              return this.indexOf(val, byteOffset, encoding) !== -1;
16862            };
16863
16864            Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
16865              return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
16866            };
16867
16868            Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
16869              return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
16870            };
16871
16872            function hexWrite(buf, string, offset, length) {
16873              offset = Number(offset) || 0;
16874              var remaining = buf.length - offset;
16875              if (!length) {
16876                length = remaining;
16877              } else {
16878                length = Number(length);
16879                if (length > remaining) {
16880                  length = remaining;
16881                }
16882              }
16883
16884              var strLen = string.length;
16885
16886              if (length > strLen / 2) {
16887                length = strLen / 2;
16888              }
16889              for (var i = 0; i < length; ++i) {
16890                var parsed = parseInt(string.substr(i * 2, 2), 16);
16891                if (numberIsNaN(parsed)) return i;
16892                buf[offset + i] = parsed;
16893              }
16894              return i;
16895            }
16896
16897            function utf8Write(buf, string, offset, length) {
16898              return blitBuffer(
16899                utf8ToBytes(string, buf.length - offset),
16900                buf,
16901                offset,
16902                length
16903              );
16904            }
16905
16906            function asciiWrite(buf, string, offset, length) {
16907              return blitBuffer(asciiToBytes(string), buf, offset, length);
16908            }
16909
16910            function latin1Write(buf, string, offset, length) {
16911              return asciiWrite(buf, string, offset, length);
16912            }
16913
16914            function base64Write(buf, string, offset, length) {
16915              return blitBuffer(base64ToBytes(string), buf, offset, length);
16916            }
16917
16918            function ucs2Write(buf, string, offset, length) {
16919              return blitBuffer(
16920                utf16leToBytes(string, buf.length - offset),
16921                buf,
16922                offset,
16923                length
16924              );
16925            }
16926
16927            Buffer.prototype.write = function write(string, offset, length, encoding) {
16928              // Buffer#write(string)
16929              if (offset === undefined) {
16930                encoding = 'utf8';
16931                length = this.length;
16932                offset = 0;
16933                // Buffer#write(string, encoding)
16934              } else if (length === undefined && typeof offset === 'string') {
16935                encoding = offset;
16936                length = this.length;
16937                offset = 0;
16938                // Buffer#write(string, offset[, length][, encoding])
16939              } else if (isFinite(offset)) {
16940                offset = offset >>> 0;
16941                if (isFinite(length)) {
16942                  length = length >>> 0;
16943                  if (encoding === undefined) encoding = 'utf8';
16944                } else {
16945                  encoding = length;
16946                  length = undefined;
16947                }
16948              } else {
16949                throw new Error(
16950                  'Buffer.write(string, encoding, offset[, length]) is no longer supported'
16951                );
16952              }
16953
16954              var remaining = this.length - offset;
16955              if (length === undefined || length > remaining) length = remaining;
16956
16957              if (
16958                (string.length > 0 && (length < 0 || offset < 0)) ||
16959                offset > this.length
16960              ) {
16961                throw new RangeError('Attempt to write outside buffer bounds');
16962              }
16963
16964              if (!encoding) encoding = 'utf8';
16965
16966              var loweredCase = false;
vendor: 20,195 bytes, lines 16967-17528
16967              for (;;) {
16968                switch (encoding) {
16969                  case 'hex':
16970                    return hexWrite(this, string, offset, length);
16971
16972                  case 'utf8':
16973                  case 'utf-8':
16974                    return utf8Write(this, string, offset, length);
16975
16976                  case 'ascii':
16977                    return asciiWrite(this, string, offset, length);
16978
16979                  case 'latin1':
16980                  case 'binary':
16981                    return latin1Write(this, string, offset, length);
16982
16983                  case 'base64':
16984                    // Warning: maxLength not taken into account in base64Write
16985                    return base64Write(this, string, offset, length);
16986
16987                  case 'ucs2':
16988                  case 'ucs-2':
16989                  case 'utf16le':
16990                  case 'utf-16le':
16991                    return ucs2Write(this, string, offset, length);
16992
16993                  default:
16994                    if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding);
16995                    encoding = ('' + encoding).toLowerCase();
16996                    loweredCase = true;
16997                }
16998              }
16999            };
17000
17001            Buffer.prototype.toJSON = function toJSON() {
17002              return {
17003                type: 'Buffer',
17004                data: Array.prototype.slice.call(this._arr || this, 0)
17005              };
17006            };
17007
17008            function base64Slice(buf, start, end) {
17009              if (start === 0 && end === buf.length) {
17010                return base64.fromByteArray(buf);
17011              } else {
17012                return base64.fromByteArray(buf.slice(start, end));
17013              }
17014            }
17015
17016            function utf8Slice(buf, start, end) {
17017              end = Math.min(buf.length, end);
17018              var res = [];
17019
17020              var i = start;
17021              while (i < end) {
17022                var firstByte = buf[i];
17023                var codePoint = null;
17024                var bytesPerSequence =
17025                  firstByte > 0xef ? 4 : firstByte > 0xdf ? 3 : firstByte > 0xbf ? 2 : 1;
17026
17027                if (i + bytesPerSequence <= end) {
17028                  var secondByte, thirdByte, fourthByte, tempCodePoint;
17029
17030                  switch (bytesPerSequence) {
17031                    case 1:
17032                      if (firstByte < 0x80) {
17033                        codePoint = firstByte;
17034                      }
17035                      break;
17036                    case 2:
17037                      secondByte = buf[i + 1];
17038                      if ((secondByte & 0xc0) === 0x80) {
17039                        tempCodePoint = ((firstByte & 0x1f) << 0x6) | (secondByte & 0x3f);
17040                        if (tempCodePoint > 0x7f) {
17041                          codePoint = tempCodePoint;
17042                        }
17043                      }
17044                      break;
17045                    case 3:
17046                      secondByte = buf[i + 1];
17047                      thirdByte = buf[i + 2];
17048                      if ((secondByte & 0xc0) === 0x80 && (thirdByte & 0xc0) === 0x80) {
17049                        tempCodePoint =
17050                          ((firstByte & 0xf) << 0xc) |
17051                          ((secondByte & 0x3f) << 0x6) |
17052                          (thirdByte & 0x3f);
17053                        if (
17054                          tempCodePoint > 0x7ff &&
17055                          (tempCodePoint < 0xd800 || tempCodePoint > 0xdfff)
17056                        ) {
17057                          codePoint = tempCodePoint;
17058                        }
17059                      }
17060                      break;
17061                    case 4:
17062                      secondByte = buf[i + 1];
17063                      thirdByte = buf[i + 2];
17064                      fourthByte = buf[i + 3];
17065                      if (
17066                        (secondByte & 0xc0) === 0x80 &&
17067                        (thirdByte & 0xc0) === 0x80 &&
17068                        (fourthByte & 0xc0) === 0x80
17069                      ) {
17070                        tempCodePoint =
17071                          ((firstByte & 0xf) << 0x12) |
17072                          ((secondByte & 0x3f) << 0xc) |
17073                          ((thirdByte & 0x3f) << 0x6) |
17074                          (fourthByte & 0x3f);
17075                        if (tempCodePoint > 0xffff && tempCodePoint < 0x110000) {
17076                          codePoint = tempCodePoint;
17077                        }
17078                      }
17079                  }
17080                }
17081
17082                if (codePoint === null) {
17083                  // we did not generate a valid codePoint so insert a
17084                  // replacement char (U+FFFD) and advance only 1 byte
17085                  codePoint = 0xfffd;
17086                  bytesPerSequence = 1;
17087                } else if (codePoint > 0xffff) {
17088                  // encode to utf16 (surrogate pair dance)
17089                  codePoint -= 0x10000;
17090                  res.push(((codePoint >>> 10) & 0x3ff) | 0xd800);
17091                  codePoint = 0xdc00 | (codePoint & 0x3ff);
17092                }
17093
17094                res.push(codePoint);
17095                i += bytesPerSequence;
17096              }
17097
17098              return decodeCodePointsArray(res);
17099            }
17100
17101            // Based on http://stackoverflow.com/a/22747272/680742, the browser with
17102            // the lowest limit is Chrome, with 0x10000 args.
17103            // We go 1 magnitude less, for safety
17104            var MAX_ARGUMENTS_LENGTH = 0x1000;
17105
17106            function decodeCodePointsArray(codePoints) {
17107              var len = codePoints.length;
17108              if (len <= MAX_ARGUMENTS_LENGTH) {
17109                return String.fromCharCode.apply(String, codePoints); // avoid extra slice()
17110              }
17111
17112              // Decode in chunks to avoid "call stack size exceeded".
17113              var res = '';
17114              var i = 0;
17115              while (i < len) {
17116                res += String.fromCharCode.apply(
17117                  String,
17118                  codePoints.slice(i, (i += MAX_ARGUMENTS_LENGTH))
17119                );
17120              }
17121              return res;
17122            }
17123
17124            function asciiSlice(buf, start, end) {
17125              var ret = '';
17126              end = Math.min(buf.length, end);
17127
17128              for (var i = start; i < end; ++i) {
17129                ret += String.fromCharCode(buf[i] & 0x7f);
17130              }
17131              return ret;
17132            }
17133
17134            function latin1Slice(buf, start, end) {
17135              var ret = '';
17136              end = Math.min(buf.length, end);
17137
17138              for (var i = start; i < end; ++i) {
17139                ret += String.fromCharCode(buf[i]);
17140              }
17141              return ret;
17142            }
17143
17144            function hexSlice(buf, start, end) {
17145              var len = buf.length;
17146
17147              if (!start || start < 0) start = 0;
17148              if (!end || end < 0 || end > len) end = len;
17149
17150              var out = '';
17151              for (var i = start; i < end; ++i) {
17152                out += hexSliceLookupTable[buf[i]];
17153              }
17154              return out;
17155            }
17156
17157            function utf16leSlice(buf, start, end) {
17158              var bytes = buf.slice(start, end);
17159              var res = '';
17160              for (var i = 0; i < bytes.length; i += 2) {
17161                res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256);
17162              }
17163              return res;
17164            }
17165
17166            Buffer.prototype.slice = function slice(start, end) {
17167              var len = this.length;
17168              start = ~~start;
17169              end = end === undefined ? len : ~~end;
17170
17171              if (start < 0) {
17172                start += len;
17173                if (start < 0) start = 0;
17174              } else if (start > len) {
17175                start = len;
17176              }
17177
17178              if (end < 0) {
17179                end += len;
17180                if (end < 0) end = 0;
17181              } else if (end > len) {
17182                end = len;
17183              }
17184
17185              if (end < start) end = start;
17186
17187              var newBuf = this.subarray(start, end);
17188              // Return an augmented `Uint8Array` instance
17189              Object.setPrototypeOf(newBuf, Buffer.prototype);
17190
17191              return newBuf;
17192            };
17193
17194            /*
17195 * Need to make sure that buffer isn't trying to write out of bounds.
17196 */
17197            function checkOffset(offset, ext, length) {
17198              if (offset % 1 !== 0 || offset < 0)
17199                throw new RangeError('offset is not uint');
17200              if (offset + ext > length)
17201                throw new RangeError('Trying to access beyond buffer length');
17202            }
17203
17204            Buffer.prototype.readUIntLE = function readUIntLE(
17205              offset,
17206              byteLength,
17207              noAssert
17208            ) {
17209              offset = offset >>> 0;
17210              byteLength = byteLength >>> 0;
17211              if (!noAssert) checkOffset(offset, byteLength, this.length);
17212
17213              var val = this[offset];
17214              var mul = 1;
17215              var i = 0;
17216              while (++i < byteLength && (mul *= 0x100)) {
17217                val += this[offset + i] * mul;
17218              }
17219
17220              return val;
17221            };
17222
17223            Buffer.prototype.readUIntBE = function readUIntBE(
17224              offset,
17225              byteLength,
17226              noAssert
17227            ) {
17228              offset = offset >>> 0;
17229              byteLength = byteLength >>> 0;
17230              if (!noAssert) {
17231                checkOffset(offset, byteLength, this.length);
17232              }
17233
17234              var val = this[offset + --byteLength];
17235              var mul = 1;
17236              while (byteLength > 0 && (mul *= 0x100)) {
17237                val += this[offset + --byteLength] * mul;
17238              }
17239
17240              return val;
17241            };
17242
17243            Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) {
17244              offset = offset >>> 0;
17245              if (!noAssert) checkOffset(offset, 1, this.length);
17246              return this[offset];
17247            };
17248
17249            Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) {
17250              offset = offset >>> 0;
17251              if (!noAssert) checkOffset(offset, 2, this.length);
17252              return this[offset] | (this[offset + 1] << 8);
17253            };
17254
17255            Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) {
17256              offset = offset >>> 0;
17257              if (!noAssert) checkOffset(offset, 2, this.length);
17258              return (this[offset] << 8) | this[offset + 1];
17259            };
17260
17261            Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) {
17262              offset = offset >>> 0;
17263              if (!noAssert) checkOffset(offset, 4, this.length);
17264
17265              return (
17266                (this[offset] | (this[offset + 1] << 8) | (this[offset + 2] << 16)) +
17267                this[offset + 3] * 0x1000000
17268              );
17269            };
17270
17271            Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) {
17272              offset = offset >>> 0;
17273              if (!noAssert) checkOffset(offset, 4, this.length);
17274
17275              return (
17276                this[offset] * 0x1000000 +
17277                ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3])
17278              );
17279            };
17280
17281            Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) {
17282              offset = offset >>> 0;
17283              byteLength = byteLength >>> 0;
17284              if (!noAssert) checkOffset(offset, byteLength, this.length);
17285
17286              var val = this[offset];
17287              var mul = 1;
17288              var i = 0;
17289              while (++i < byteLength && (mul *= 0x100)) {
17290                val += this[offset + i] * mul;
17291              }
17292              mul *= 0x80;
17293
17294              if (val >= mul) val -= Math.pow(2, 8 * byteLength);
17295
17296              return val;
17297            };
17298
17299            Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) {
17300              offset = offset >>> 0;
17301              byteLength = byteLength >>> 0;
17302              if (!noAssert) checkOffset(offset, byteLength, this.length);
17303
17304              var i = byteLength;
17305              var mul = 1;
17306              var val = this[offset + --i];
17307              while (i > 0 && (mul *= 0x100)) {
17308                val += this[offset + --i] * mul;
17309              }
17310              mul *= 0x80;
17311
17312              if (val >= mul) val -= Math.pow(2, 8 * byteLength);
17313
17314              return val;
17315            };
17316
17317            Buffer.prototype.readInt8 = function readInt8(offset, noAssert) {
17318              offset = offset >>> 0;
17319              if (!noAssert) checkOffset(offset, 1, this.length);
17320              if (!(this[offset] & 0x80)) return this[offset];
17321              return (0xff - this[offset] + 1) * -1;
17322            };
17323
17324            Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) {
17325              offset = offset >>> 0;
17326              if (!noAssert) checkOffset(offset, 2, this.length);
17327              var val = this[offset] | (this[offset + 1] << 8);
17328              return val & 0x8000 ? val | 0xffff0000 : val;
17329            };
17330
17331            Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) {
17332              offset = offset >>> 0;
17333              if (!noAssert) checkOffset(offset, 2, this.length);
17334              var val = this[offset + 1] | (this[offset] << 8);
17335              return val & 0x8000 ? val | 0xffff0000 : val;
17336            };
17337
17338            Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) {
17339              offset = offset >>> 0;
17340              if (!noAssert) checkOffset(offset, 4, this.length);
17341
17342              return (
17343                this[offset] |
17344                (this[offset + 1] << 8) |
17345                (this[offset + 2] << 16) |
17346                (this[offset + 3] << 24)
17347              );
17348            };
17349
17350            Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) {
17351              offset = offset >>> 0;
17352              if (!noAssert) checkOffset(offset, 4, this.length);
17353
17354              return (
17355                (this[offset] << 24) |
17356                (this[offset + 1] << 16) |
17357                (this[offset + 2] << 8) |
17358                this[offset + 3]
17359              );
17360            };
17361
17362            Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
17363              offset = offset >>> 0;
17364              if (!noAssert) checkOffset(offset, 4, this.length);
17365              return ieee754.read(this, offset, true, 23, 4);
17366            };
17367
17368            Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
17369              offset = offset >>> 0;
17370              if (!noAssert) checkOffset(offset, 4, this.length);
17371              return ieee754.read(this, offset, false, 23, 4);
17372            };
17373
17374            Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
17375              offset = offset >>> 0;
17376              if (!noAssert) checkOffset(offset, 8, this.length);
17377              return ieee754.read(this, offset, true, 52, 8);
17378            };
17379
17380            Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
17381              offset = offset >>> 0;
17382              if (!noAssert) checkOffset(offset, 8, this.length);
17383              return ieee754.read(this, offset, false, 52, 8);
17384            };
17385
17386            function checkInt(buf, value, offset, ext, max, min) {
17387              if (!Buffer.isBuffer(buf))
17388                throw new TypeError('"buffer" argument must be a Buffer instance');
17389              if (value > max || value < min)
17390                throw new RangeError('"value" argument is out of bounds');
17391              if (offset + ext > buf.length) throw new RangeError('Index out of range');
17392            }
17393
17394            Buffer.prototype.writeUIntLE = function writeUIntLE(
17395              value,
17396              offset,
17397              byteLength,
17398              noAssert
17399            ) {
17400              value = +value;
17401              offset = offset >>> 0;
17402              byteLength = byteLength >>> 0;
17403              if (!noAssert) {
17404                var maxBytes = Math.pow(2, 8 * byteLength) - 1;
17405                checkInt(this, value, offset, byteLength, maxBytes, 0);
17406              }
17407
17408              var mul = 1;
17409              var i = 0;
17410              this[offset] = value & 0xff;
17411              while (++i < byteLength && (mul *= 0x100)) {
17412                this[offset + i] = (value / mul) & 0xff;
17413              }
17414
17415              return offset + byteLength;
17416            };
17417
17418            Buffer.prototype.writeUIntBE = function writeUIntBE(
17419              value,
17420              offset,
17421              byteLength,
17422              noAssert
17423            ) {
17424              value = +value;
17425              offset = offset >>> 0;
17426              byteLength = byteLength >>> 0;
17427              if (!noAssert) {
17428                var maxBytes = Math.pow(2, 8 * byteLength) - 1;
17429                checkInt(this, value, offset, byteLength, maxBytes, 0);
17430              }
17431
17432              var i = byteLength - 1;
17433              var mul = 1;
17434              this[offset + i] = value & 0xff;
17435              while (--i >= 0 && (mul *= 0x100)) {
17436                this[offset + i] = (value / mul) & 0xff;
17437              }
17438
17439              return offset + byteLength;
17440            };
17441
17442            Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) {
17443              value = +value;
17444              offset = offset >>> 0;
17445              if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0);
17446              this[offset] = value & 0xff;
17447              return offset + 1;
17448            };
17449
17450            Buffer.prototype.writeUInt16LE = function writeUInt16LE(
17451              value,
17452              offset,
17453              noAssert
17454            ) {
17455              value = +value;
17456              offset = offset >>> 0;
17457              if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
17458              this[offset] = value & 0xff;
17459              this[offset + 1] = value >>> 8;
17460              return offset + 2;
17461            };
17462
17463            Buffer.prototype.writeUInt16BE = function writeUInt16BE(
17464              value,
17465              offset,
17466              noAssert
17467            ) {
17468              value = +value;
17469              offset = offset >>> 0;
17470              if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0);
17471              this[offset] = value >>> 8;
17472              this[offset + 1] = value & 0xff;
17473              return offset + 2;
17474            };
17475
17476            Buffer.prototype.writeUInt32LE = function writeUInt32LE(
17477              value,
17478              offset,
17479              noAssert
17480            ) {
17481              value = +value;
17482              offset = offset >>> 0;
17483              if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
17484              this[offset + 3] = value >>> 24;
17485              this[offset + 2] = value >>> 16;
17486              this[offset + 1] = value >>> 8;
17487              this[offset] = value & 0xff;
17488              return offset + 4;
17489            };
17490
17491            Buffer.prototype.writeUInt32BE = function writeUInt32BE(
17492              value,
17493              offset,
17494              noAssert
17495            ) {
17496              value = +value;
17497              offset = offset >>> 0;
17498              if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0);
17499              this[offset] = value >>> 24;
17500              this[offset + 1] = value >>> 16;
17501              this[offset + 2] = value >>> 8;
17502              this[offset + 3] = value & 0xff;
17503              return offset + 4;
17504            };
17505
17506            Buffer.prototype.writeIntLE = function writeIntLE(
17507              value,
17508              offset,
17509              byteLength,
17510              noAssert
17511            ) {
17512              value = +value;
17513              offset = offset >>> 0;
17514              if (!noAssert) {
17515                var limit = Math.pow(2, 8 * byteLength - 1);
17516
17517                checkInt(this, value, offset, byteLength, limit - 1, -limit);
17518              }
17519
17520              var i = 0;
17521              var mul = 1;
17522              var sub = 0;
17523              this[offset] = value & 0xff;
17524              while (++i < byteLength && (mul *= 0x100)) {
17525                if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
17526                  sub = 1;
17527                }
17528                this[offset + i] = (((value / mul) >> 0) - sub) & 0xff;
vendor: 9,736 bytes, lines 17529-17784
17529              }
17530
17531              return offset + byteLength;
17532            };
17533
17534            Buffer.prototype.writeIntBE = function writeIntBE(
17535              value,
17536              offset,
17537              byteLength,
17538              noAssert
17539            ) {
17540              value = +value;
17541              offset = offset >>> 0;
17542              if (!noAssert) {
17543                var limit = Math.pow(2, 8 * byteLength - 1);
17544
17545                checkInt(this, value, offset, byteLength, limit - 1, -limit);
17546              }
17547
17548              var i = byteLength - 1;
17549              var mul = 1;
17550              var sub = 0;
17551              this[offset + i] = value & 0xff;
17552              while (--i >= 0 && (mul *= 0x100)) {
17553                if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
17554                  sub = 1;
17555                }
17556                this[offset + i] = (((value / mul) >> 0) - sub) & 0xff;
17557              }
17558
17559              return offset + byteLength;
17560            };
17561
17562            Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) {
17563              value = +value;
17564              offset = offset >>> 0;
17565              if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80);
17566              if (value < 0) value = 0xff + value + 1;
17567              this[offset] = value & 0xff;
17568              return offset + 1;
17569            };
17570
17571            Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) {
17572              value = +value;
17573              offset = offset >>> 0;
17574              if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
17575              this[offset] = value & 0xff;
17576              this[offset + 1] = value >>> 8;
17577              return offset + 2;
17578            };
17579
17580            Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) {
17581              value = +value;
17582              offset = offset >>> 0;
17583              if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000);
17584              this[offset] = value >>> 8;
17585              this[offset + 1] = value & 0xff;
17586              return offset + 2;
17587            };
17588
17589            Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) {
17590              value = +value;
17591              offset = offset >>> 0;
17592              if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
17593              this[offset] = value & 0xff;
17594              this[offset + 1] = value >>> 8;
17595              this[offset + 2] = value >>> 16;
17596              this[offset + 3] = value >>> 24;
17597              return offset + 4;
17598            };
17599
17600            Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) {
17601              value = +value;
17602              offset = offset >>> 0;
17603              if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
17604              if (value < 0) value = 0xffffffff + value + 1;
17605              this[offset] = value >>> 24;
17606              this[offset + 1] = value >>> 16;
17607              this[offset + 2] = value >>> 8;
17608              this[offset + 3] = value & 0xff;
17609              return offset + 4;
17610            };
17611
17612            function checkIEEE754(buf, value, offset, ext, max, min) {
17613              if (offset + ext > buf.length) throw new RangeError('Index out of range');
17614              if (offset < 0) throw new RangeError('Index out of range');
17615            }
17616
17617            function writeFloat(buf, value, offset, littleEndian, noAssert) {
17618              value = +value;
17619              offset = offset >>> 0;
17620              if (!noAssert) {
17621                checkIEEE754(
17622                  buf,
17623                  value,
17624                  offset,
17625                  4,
17626                  3.4028234663852886e38,
17627                  -3.4028234663852886e38
17628                );
17629              }
17630              ieee754.write(buf, value, offset, littleEndian, 23, 4);
17631              return offset + 4;
17632            }
17633
17634            Buffer.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) {
17635              return writeFloat(this, value, offset, true, noAssert);
17636            };
17637
17638            Buffer.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) {
17639              return writeFloat(this, value, offset, false, noAssert);
17640            };
17641
17642            function writeDouble(buf, value, offset, littleEndian, noAssert) {
17643              value = +value;
17644              offset = offset >>> 0;
17645              if (!noAssert) {
17646                checkIEEE754(
17647                  buf,
17648                  value,
17649                  offset,
17650                  8,
17651                  1.7976931348623157e308,
17652                  -1.7976931348623157e308
17653                );
17654              }
17655              ieee754.write(buf, value, offset, littleEndian, 52, 8);
17656              return offset + 8;
17657            }
17658
17659            Buffer.prototype.writeDoubleLE = function writeDoubleLE(
17660              value,
17661              offset,
17662              noAssert
17663            ) {
17664              return writeDouble(this, value, offset, true, noAssert);
17665            };
17666
17667            Buffer.prototype.writeDoubleBE = function writeDoubleBE(
17668              value,
17669              offset,
17670              noAssert
17671            ) {
17672              return writeDouble(this, value, offset, false, noAssert);
17673            };
17674
17675            // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
17676            Buffer.prototype.copy = function copy(target, targetStart, start, end) {
17677              if (!Buffer.isBuffer(target))
17678                throw new TypeError('argument should be a Buffer');
17679              if (!start) start = 0;
17680              if (!end && end !== 0) end = this.length;
17681              if (targetStart >= target.length) targetStart = target.length;
17682              if (!targetStart) targetStart = 0;
17683              if (end > 0 && end < start) end = start;
17684
17685              // Copy 0 bytes; we're done
17686              if (end === start) return 0;
17687              if (target.length === 0 || this.length === 0) return 0;
17688
17689              // Fatal error conditions
17690              if (targetStart < 0) {
17691                throw new RangeError('targetStart out of bounds');
17692              }
17693              if (start < 0 || start >= this.length)
17694                throw new RangeError('Index out of range');
17695              if (end < 0) throw new RangeError('sourceEnd out of bounds');
17696
17697              // Are we oob?
17698              if (end > this.length) end = this.length;
17699              if (target.length - targetStart < end - start) {
17700                end = target.length - targetStart + start;
17701              }
17702
17703              var len = end - start;
17704
17705              if (
17706                this === target &&
17707                typeof Uint8Array.prototype.copyWithin === 'function'
17708              ) {
17709                // Use built-in when available, missing from IE11
17710                this.copyWithin(targetStart, start, end);
17711              } else if (this === target && start < targetStart && targetStart < end) {
17712                // descending copy from end
17713                for (var i = len - 1; i >= 0; --i) {
17714                  target[i + targetStart] = this[i + start];
17715                }
17716              } else {
17717                Uint8Array.prototype.set.call(
17718                  target,
17719                  this.subarray(start, end),
17720                  targetStart
17721                );
17722              }
17723
17724              return len;
17725            };
17726
17727            // Usage:
17728            //    buffer.fill(number[, offset[, end]])
17729            //    buffer.fill(buffer[, offset[, end]])
17730            //    buffer.fill(string[, offset[, end]][, encoding])
17731            Buffer.prototype.fill = function fill(val, start, end, encoding) {
17732              // Handle string cases:
17733              if (typeof val === 'string') {
17734                if (typeof start === 'string') {
17735                  encoding = start;
17736                  start = 0;
17737                  end = this.length;
17738                } else if (typeof end === 'string') {
17739                  encoding = end;
17740                  end = this.length;
17741                }
17742                if (encoding !== undefined && typeof encoding !== 'string') {
17743                  throw new TypeError('encoding must be a string');
17744                }
17745                if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
17746                  throw new TypeError('Unknown encoding: ' + encoding);
17747                }
17748                if (val.length === 1) {
17749                  var code = val.charCodeAt(0);
17750                  if ((encoding === 'utf8' && code < 128) || encoding === 'latin1') {
17751                    // Fast path: If `val` fits into a single byte, use that numeric value.
17752                    val = code;
17753                  }
17754                }
17755              } else if (typeof val === 'number') {
17756                val = val & 255;
17757              } else if (typeof val === 'boolean') {
17758                val = Number(val);
17759              }
17760
17761              // Invalid ranges are not set to a default, so can range check early.
17762              if (start < 0 || this.length < start || this.length < end) {
17763                throw new RangeError('Out of range index');
17764              }
17765
17766              if (end <= start) {
17767                return this;
17768              }
17769
17770              start = start >>> 0;
17771              end = end === undefined ? this.length : end >>> 0;
17772
17773              if (!val) val = 0;
17774
17775              var i;
17776              if (typeof val === 'number') {
17777                for (i = start; i < end; ++i) {
17778                  this[i] = val;
17779                }
17780              } else {
17781                var bytes = Buffer.isBuffer(val) ? val : Buffer.from(val, encoding);
17782                var len = bytes.length;
17783                if (len === 0) {
17784                  throw new TypeError(
vendor: 6,256 bytes, lines 17785-17954
17785                    'The value "' + val + '" is invalid for argument "value"'
17786                  );
17787                }
17788                for (i = 0; i < end - start; ++i) {
17789                  this[i + start] = bytes[i % len];
17790                }
17791              }
17792
17793              return this;
17794            };
17795
17796            // HELPER FUNCTIONS
17797            // ================
17798
17799            var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g;
17800
17801            function base64clean(str) {
17802              // Node takes equal signs as end of the Base64 encoding
17803              str = str.split('=')[0];
17804              // Node strips out invalid characters like \n and \t from the string, base64-js does not
17805              str = str.trim().replace(INVALID_BASE64_RE, '');
17806              // Node converts strings with length < 2 to ''
17807              if (str.length < 2) return '';
17808              // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
17809              while (str.length % 4 !== 0) {
17810                str = str + '=';
17811              }
17812              return str;
17813            }
17814
17815            function utf8ToBytes(string, units) {
17816              units = units || Infinity;
17817              var codePoint;
17818              var length = string.length;
17819              var leadSurrogate = null;
17820              var bytes = [];
17821
17822              for (var i = 0; i < length; ++i) {
17823                codePoint = string.charCodeAt(i);
17824
17825                // is surrogate component
17826                if (codePoint > 0xd7ff && codePoint < 0xe000) {
17827                  // last char was a lead
17828                  if (!leadSurrogate) {
17829                    // no lead yet
17830                    if (codePoint > 0xdbff) {
17831                      // unexpected trail
17832                      if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd);
17833                      continue;
17834                    } else if (i + 1 === length) {
17835                      // unpaired lead
17836                      if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd);
17837                      continue;
17838                    }
17839
17840                    // valid lead
17841                    leadSurrogate = codePoint;
17842
17843                    continue;
17844                  }
17845
17846                  // 2 leads in a row
17847                  if (codePoint < 0xdc00) {
17848                    if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd);
17849                    leadSurrogate = codePoint;
17850                    continue;
17851                  }
17852
17853                  // valid surrogate pair
17854                  codePoint =
17855                    (((leadSurrogate - 0xd800) << 10) | (codePoint - 0xdc00)) + 0x10000;
17856                } else if (leadSurrogate) {
17857                  // valid bmp char, but last char was a lead
17858                  if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd);
17859                }
17860
17861                leadSurrogate = null;
17862
17863                // encode utf8
17864                if (codePoint < 0x80) {
17865                  if ((units -= 1) < 0) break;
17866                  bytes.push(codePoint);
17867                } else if (codePoint < 0x800) {
17868                  if ((units -= 2) < 0) break;
17869                  bytes.push((codePoint >> 0x6) | 0xc0, (codePoint & 0x3f) | 0x80);
17870                } else if (codePoint < 0x10000) {
17871                  if ((units -= 3) < 0) break;
17872                  bytes.push(
17873                    (codePoint >> 0xc) | 0xe0,
17874                    ((codePoint >> 0x6) & 0x3f) | 0x80,
17875                    (codePoint & 0x3f) | 0x80
17876                  );
17877                } else if (codePoint < 0x110000) {
17878                  if ((units -= 4) < 0) break;
17879                  bytes.push(
17880                    (codePoint >> 0x12) | 0xf0,
17881                    ((codePoint >> 0xc) & 0x3f) | 0x80,
17882                    ((codePoint >> 0x6) & 0x3f) | 0x80,
17883                    (codePoint & 0x3f) | 0x80
17884                  );
17885                } else {
17886                  throw new Error('Invalid code point');
17887                }
17888              }
17889
17890              return bytes;
17891            }
17892
17893            function asciiToBytes(str) {
17894              var byteArray = [];
17895              for (var i = 0; i < str.length; ++i) {
17896                // Node's code seems to be doing this and not & 0x7F..
17897                byteArray.push(str.charCodeAt(i) & 0xff);
17898              }
17899              return byteArray;
17900            }
17901
17902            function utf16leToBytes(str, units) {
17903              var c, hi, lo;
17904              var byteArray = [];
17905              for (var i = 0; i < str.length; ++i) {
17906                if ((units -= 2) < 0) break;
17907
17908                c = str.charCodeAt(i);
17909                hi = c >> 8;
17910                lo = c % 256;
17911                byteArray.push(lo);
17912                byteArray.push(hi);
17913              }
17914
17915              return byteArray;
17916            }
17917
17918            function base64ToBytes(str) {
17919              return base64.toByteArray(base64clean(str));
17920            }
17921
17922            function blitBuffer(src, dst, offset, length) {
17923              for (var i = 0; i < length; ++i) {
17924                if (i + offset >= dst.length || i >= src.length) break;
17925                dst[i + offset] = src[i];
17926              }
17927              return i;
17928            }
17929
17930            // ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
17931            // the `instanceof` check but they should be treated as of that type.
17932            // See: https://github.com/feross/buffer/issues/166
17933            function isInstance(obj, type) {
17934              return (
17935                obj instanceof type ||
17936                (obj != null &&
17937                  obj.constructor != null &&
17938                  obj.constructor.name != null &&
17939                  obj.constructor.name === type.name)
17940              );
17941            }
17942            function numberIsNaN(obj) {
17943              // For IE11 support
17944              return obj !== obj; // eslint-disable-line no-self-compare
17945            }
17946
17947            // Create lookup table for `toString('hex')`
17948            // See: https://github.com/feross/buffer/issues/219
17949            var hexSliceLookupTable = (function() {
17950              var alphabet = '0123456789abcdef';
17951              var table = new Array(256);
17952              for (var i = 0; i < 16; ++i) {
17953                var i16 = i * 16;
17954                for (var j = 0; j < 16; ++j) {
vendor: 6,584 bytes, lines 17955-18136
17955                  table[i16 + j] = alphabet[i] + alphabet[j];
17956                }
17957              }
17958              return table;
17959            })();
17960          }.call(this, _dereq_('buffer').Buffer));
17961        },
17962        { 'base64-js': 20, buffer: 22, ieee754: 31 }
17963      ],
17964      23: [
17965        function(_dereq_, module, exports) {
17966          // This file can be required in Browserify and Node.js for automatic polyfill
17967          // To use it:  require('es6-promise/auto');
17968          'use strict';
17969          module.exports = _dereq_('./').polyfill();
17970        },
17971        { './': 24 }
17972      ],
17973      24: [
17974        function(_dereq_, module, exports) {
17975          (function(process, global) {
17976            /*!
17977 * @overview es6-promise - a tiny implementation of Promises/A+.
17978 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
17979 * @license   Licensed under MIT license
17980 *            See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
17981 * @version   v4.2.8+1e68dce6
17982 */
17983
17984            (function(global, factory) {
17985              typeof exports === 'object' && typeof module !== 'undefined'
17986                ? (module.exports = factory())
17987                : typeof define === 'function' && define.amd
17988                  ? define(factory)
17989                  : (global.ES6Promise = factory());
17990            })(this, function() {
17991              'use strict';
17992
17993              function objectOrFunction(x) {
17994                var type = typeof x;
17995                return x !== null && (type === 'object' || type === 'function');
17996              }
17997
17998              function isFunction(x) {
17999                return typeof x === 'function';
18000              }
18001
18002              var _isArray = void 0;
18003              if (Array.isArray) {
18004                _isArray = Array.isArray;
18005              } else {
18006                _isArray = function(x) {
18007                  return Object.prototype.toString.call(x) === '[object Array]';
18008                };
18009              }
18010
18011              var isArray = _isArray;
18012
18013              var len = 0;
18014              var vertxNext = void 0;
18015              var customSchedulerFn = void 0;
18016
18017              var asap = function asap(callback, arg) {
18018                queue[len] = callback;
18019                queue[len + 1] = arg;
18020                len += 2;
18021                if (len === 2) {
18022                  // If len is 2, that means that we need to schedule an async flush.
18023                  // If additional callbacks are queued before the queue is flushed, they
18024                  // will be processed by this flush that we are scheduling.
18025                  if (customSchedulerFn) {
18026                    customSchedulerFn(flush);
18027                  } else {
18028                    scheduleFlush();
18029                  }
18030                }
18031              };
18032
18033              function setScheduler(scheduleFn) {
18034                customSchedulerFn = scheduleFn;
18035              }
18036
18037              function setAsap(asapFn) {
18038                asap = asapFn;
18039              }
18040
18041              var browserWindow = typeof window !== 'undefined' ? window : undefined;
18042              var browserGlobal = browserWindow || {};
18043              var BrowserMutationObserver =
18044                browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
18045              var isNode =
18046                typeof self === 'undefined' &&
18047                typeof process !== 'undefined' &&
18048                {}.toString.call(process) === '[object process]';
18049
18050              // test for web worker but not in IE10
18051              var isWorker =
18052                typeof Uint8ClampedArray !== 'undefined' &&
18053                typeof importScripts !== 'undefined' &&
18054                typeof MessageChannel !== 'undefined';
18055
18056              // node
18057              function useNextTick() {
18058                // node version 0.10.x displays a deprecation warning when nextTick is used recursively
18059                // see https://github.com/cujojs/when/issues/410 for details
18060                return function() {
18061                  return process.nextTick(flush);
18062                };
18063              }
18064
18065              // vertx
18066              function useVertxTimer() {
18067                if (typeof vertxNext !== 'undefined') {
18068                  return function() {
18069                    vertxNext(flush);
18070                  };
18071                }
18072
18073                return useSetTimeout();
18074              }
18075
18076              function useMutationObserver() {
18077                var iterations = 0;
18078                var observer = new BrowserMutationObserver(flush);
18079                var node = document.createTextNode('');
18080                observer.observe(node, { characterData: true });
18081
18082                return function() {
18083                  node.data = iterations = ++iterations % 2;
18084                };
18085              }
18086
18087              // web worker
18088              function useMessageChannel() {
18089                var channel = new MessageChannel();
18090                channel.port1.onmessage = flush;
18091                return function() {
18092                  return channel.port2.postMessage(0);
18093                };
18094              }
18095
18096              function useSetTimeout() {
18097                // Store setTimeout reference so es6-promise will be unaffected by
18098                // other code modifying setTimeout (like sinon.useFakeTimers())
18099                var globalSetTimeout = setTimeout;
18100                return function() {
18101                  return globalSetTimeout(flush, 1);
18102                };
18103              }
18104
18105              var queue = new Array(1000);
18106              function flush() {
18107                for (var i = 0; i < len; i += 2) {
18108                  var callback = queue[i];
18109                  var arg = queue[i + 1];
18110
18111                  callback(arg);
18112
18113                  queue[i] = undefined;
18114                  queue[i + 1] = undefined;
18115                }
18116
18117                len = 0;
18118              }
18119
18120              function attemptVertx() {
18121                try {
18122                  var vertx = Function('return this')().require('vertx');
18123                  vertxNext = vertx.runOnLoop || vertx.runOnContext;
18124                  return useVertxTimer();
18125                } catch (e) {
18126                  return useSetTimeout();
18127                }
18128              }
18129
18130              var scheduleFlush = void 0;
18131              // Decide what async method to use to triggering processing of queued callbacks:
18132              if (isNode) {
18133                scheduleFlush = useNextTick();
18134              } else if (BrowserMutationObserver) {
18135                scheduleFlush = useMutationObserver();
18136              } else if (isWorker) {
vendor: 6,310 bytes, lines 18137-18333
18137                scheduleFlush = useMessageChannel();
18138              } else if (browserWindow === undefined && typeof _dereq_ === 'function') {
18139                scheduleFlush = attemptVertx();
18140              } else {
18141                scheduleFlush = useSetTimeout();
18142              }
18143
18144              function then(onFulfillment, onRejection) {
18145                var parent = this;
18146
18147                var child = new this.constructor(noop);
18148
18149                if (child[PROMISE_ID] === undefined) {
18150                  makePromise(child);
18151                }
18152
18153                var _state = parent._state;
18154
18155                if (_state) {
18156                  var callback = arguments[_state - 1];
18157                  asap(function() {
18158                    return invokeCallback(_state, child, callback, parent._result);
18159                  });
18160                } else {
18161                  subscribe(parent, child, onFulfillment, onRejection);
18162                }
18163
18164                return child;
18165              }
18166
18167              /**
18168  `Promise.resolve` returns a promise that will become resolved with the
18169  passed `value`. It is shorthand for the following:
18170
18171  ```javascript
18172  let promise = new Promise(function(resolve, reject){
18173    resolve(1);
18174  });
18175
18176  promise.then(function(value){
18177    // value === 1
18178  });
18179  ```
18180
18181  Instead of writing the above, your code now simply becomes the following:
18182
18183  ```javascript
18184  let promise = Promise.resolve(1);
18185
18186  promise.then(function(value){
18187    // value === 1
18188  });
18189  ```
18190
18191  @method resolve
18192  @static
18193  @param {Any} value value that the returned promise will be resolved with
18194  Useful for tooling.
18195  @return {Promise} a promise that will become fulfilled with the given
18196  `value`
18197*/
18198              function resolve$1(object) {
18199                /*jshint validthis:true */
18200                var Constructor = this;
18201
18202                if (
18203                  object &&
18204                  typeof object === 'object' &&
18205                  object.constructor === Constructor
18206                ) {
18207                  return object;
18208                }
18209
18210                var promise = new Constructor(noop);
18211                resolve(promise, object);
18212                return promise;
18213              }
18214
18215              var PROMISE_ID = Math.random()
18216                .toString(36)
18217                .substring(2);
18218
18219              function noop() {}
18220
18221              var PENDING = void 0;
18222              var FULFILLED = 1;
18223              var REJECTED = 2;
18224
18225              function selfFulfillment() {
18226                return new TypeError('You cannot resolve a promise with itself');
18227              }
18228
18229              function cannotReturnOwn() {
18230                return new TypeError(
18231                  'A promises callback cannot return that same promise.'
18232                );
18233              }
18234
18235              function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
18236                try {
18237                  then$$1.call(value, fulfillmentHandler, rejectionHandler);
18238                } catch (e) {
18239                  return e;
18240                }
18241              }
18242
18243              function handleForeignThenable(promise, thenable, then$$1) {
18244                asap(function(promise) {
18245                  var sealed = false;
18246                  var error = tryThen(
18247                    then$$1,
18248                    thenable,
18249                    function(value) {
18250                      if (sealed) {
18251                        return;
18252                      }
18253                      sealed = true;
18254                      if (thenable !== value) {
18255                        resolve(promise, value);
18256                      } else {
18257                        fulfill(promise, value);
18258                      }
18259                    },
18260                    function(reason) {
18261                      if (sealed) {
18262                        return;
18263                      }
18264                      sealed = true;
18265
18266                      reject(promise, reason);
18267                    },
18268                    'Settle: ' + (promise._label || ' unknown promise')
18269                  );
18270
18271                  if (!sealed && error) {
18272                    sealed = true;
18273                    reject(promise, error);
18274                  }
18275                }, promise);
18276              }
18277
18278              function handleOwnThenable(promise, thenable) {
18279                if (thenable._state === FULFILLED) {
18280                  fulfill(promise, thenable._result);
18281                } else if (thenable._state === REJECTED) {
18282                  reject(promise, thenable._result);
18283                } else {
18284                  subscribe(
18285                    thenable,
18286                    undefined,
18287                    function(value) {
18288                      return resolve(promise, value);
18289                    },
18290                    function(reason) {
18291                      return reject(promise, reason);
18292                    }
18293                  );
18294                }
18295              }
18296
18297              function handleMaybeThenable(promise, maybeThenable, then$$1) {
18298                if (
18299                  maybeThenable.constructor === promise.constructor &&
18300                  then$$1 === then &&
18301                  maybeThenable.constructor.resolve === resolve$1
18302                ) {
18303                  handleOwnThenable(promise, maybeThenable);
18304                } else {
18305                  if (then$$1 === undefined) {
18306                    fulfill(promise, maybeThenable);
18307                  } else if (isFunction(then$$1)) {
18308                    handleForeignThenable(promise, maybeThenable, then$$1);
18309                  } else {
18310                    fulfill(promise, maybeThenable);
18311                  }
18312                }
18313              }
18314
18315              function resolve(promise, value) {
18316                if (promise === value) {
18317                  reject(promise, selfFulfillment());
18318                } else if (objectOrFunction(value)) {
18319                  var then$$1 = void 0;
18320                  try {
18321                    then$$1 = value.then;
18322                  } catch (error) {
18323                    reject(promise, error);
18324                    return;
18325                  }
18326                  handleMaybeThenable(promise, value, then$$1);
18327                } else {
18328                  fulfill(promise, value);
18329                }
18330              }
18331
18332              function publishRejection(promise) {
18333                if (promise._onerror) {
vendor: 11,219 bytes, lines 18334-18679
18334                  promise._onerror(promise._result);
18335                }
18336
18337                publish(promise);
18338              }
18339
18340              function fulfill(promise, value) {
18341                if (promise._state !== PENDING) {
18342                  return;
18343                }
18344
18345                promise._result = value;
18346                promise._state = FULFILLED;
18347
18348                if (promise._subscribers.length !== 0) {
18349                  asap(publish, promise);
18350                }
18351              }
18352
18353              function reject(promise, reason) {
18354                if (promise._state !== PENDING) {
18355                  return;
18356                }
18357                promise._state = REJECTED;
18358                promise._result = reason;
18359
18360                asap(publishRejection, promise);
18361              }
18362
18363              function subscribe(parent, child, onFulfillment, onRejection) {
18364                var _subscribers = parent._subscribers;
18365                var length = _subscribers.length;
18366
18367                parent._onerror = null;
18368
18369                _subscribers[length] = child;
18370                _subscribers[length + FULFILLED] = onFulfillment;
18371                _subscribers[length + REJECTED] = onRejection;
18372
18373                if (length === 0 && parent._state) {
18374                  asap(publish, parent);
18375                }
18376              }
18377
18378              function publish(promise) {
18379                var subscribers = promise._subscribers;
18380                var settled = promise._state;
18381
18382                if (subscribers.length === 0) {
18383                  return;
18384                }
18385
18386                var child = void 0,
18387                  callback = void 0,
18388                  detail = promise._result;
18389
18390                for (var i = 0; i < subscribers.length; i += 3) {
18391                  child = subscribers[i];
18392                  callback = subscribers[i + settled];
18393
18394                  if (child) {
18395                    invokeCallback(settled, child, callback, detail);
18396                  } else {
18397                    callback(detail);
18398                  }
18399                }
18400
18401                promise._subscribers.length = 0;
18402              }
18403
18404              function invokeCallback(settled, promise, callback, detail) {
18405                var hasCallback = isFunction(callback),
18406                  value = void 0,
18407                  error = void 0,
18408                  succeeded = true;
18409
18410                if (hasCallback) {
18411                  try {
18412                    value = callback(detail);
18413                  } catch (e) {
18414                    succeeded = false;
18415                    error = e;
18416                  }
18417
18418                  if (promise === value) {
18419                    reject(promise, cannotReturnOwn());
18420                    return;
18421                  }
18422                } else {
18423                  value = detail;
18424                }
18425
18426                if (promise._state !== PENDING) {
18427                  // noop
18428                } else if (hasCallback && succeeded) {
18429                  resolve(promise, value);
18430                } else if (succeeded === false) {
18431                  reject(promise, error);
18432                } else if (settled === FULFILLED) {
18433                  fulfill(promise, value);
18434                } else if (settled === REJECTED) {
18435                  reject(promise, value);
18436                }
18437              }
18438
18439              function initializePromise(promise, resolver) {
18440                try {
18441                  resolver(
18442                    function resolvePromise(value) {
18443                      resolve(promise, value);
18444                    },
18445                    function rejectPromise(reason) {
18446                      reject(promise, reason);
18447                    }
18448                  );
18449                } catch (e) {
18450                  reject(promise, e);
18451                }
18452              }
18453
18454              var id = 0;
18455              function nextId() {
18456                return id++;
18457              }
18458
18459              function makePromise(promise) {
18460                promise[PROMISE_ID] = id++;
18461                promise._state = undefined;
18462                promise._result = undefined;
18463                promise._subscribers = [];
18464              }
18465
18466              function validationError() {
18467                return new Error('Array Methods must be provided an Array');
18468              }
18469
18470              var Enumerator = (function() {
18471                function Enumerator(Constructor, input) {
18472                  this._instanceConstructor = Constructor;
18473                  this.promise = new Constructor(noop);
18474
18475                  if (!this.promise[PROMISE_ID]) {
18476                    makePromise(this.promise);
18477                  }
18478
18479                  if (isArray(input)) {
18480                    this.length = input.length;
18481                    this._remaining = input.length;
18482
18483                    this._result = new Array(this.length);
18484
18485                    if (this.length === 0) {
18486                      fulfill(this.promise, this._result);
18487                    } else {
18488                      this.length = this.length || 0;
18489                      this._enumerate(input);
18490                      if (this._remaining === 0) {
18491                        fulfill(this.promise, this._result);
18492                      }
18493                    }
18494                  } else {
18495                    reject(this.promise, validationError());
18496                  }
18497                }
18498
18499                Enumerator.prototype._enumerate = function _enumerate(input) {
18500                  for (var i = 0; this._state === PENDING && i < input.length; i++) {
18501                    this._eachEntry(input[i], i);
18502                  }
18503                };
18504
18505                Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
18506                  var c = this._instanceConstructor;
18507                  var resolve$$1 = c.resolve;
18508
18509                  if (resolve$$1 === resolve$1) {
18510                    var _then = void 0;
18511                    var error = void 0;
18512                    var didError = false;
18513                    try {
18514                      _then = entry.then;
18515                    } catch (e) {
18516                      didError = true;
18517                      error = e;
18518                    }
18519
18520                    if (_then === then && entry._state !== PENDING) {
18521                      this._settledAt(entry._state, i, entry._result);
18522                    } else if (typeof _then !== 'function') {
18523                      this._remaining--;
18524                      this._result[i] = entry;
18525                    } else if (c === Promise$1) {
18526                      var promise = new c(noop);
18527                      if (didError) {
18528                        reject(promise, error);
18529                      } else {
18530                        handleMaybeThenable(promise, entry, _then);
18531                      }
18532                      this._willSettleAt(promise, i);
18533                    } else {
18534                      this._willSettleAt(
18535                        new c(function(resolve$$1) {
18536                          return resolve$$1(entry);
18537                        }),
18538                        i
18539                      );
18540                    }
18541                  } else {
18542                    this._willSettleAt(resolve$$1(entry), i);
18543                  }
18544                };
18545
18546                Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
18547                  var promise = this.promise;
18548
18549                  if (promise._state === PENDING) {
18550                    this._remaining--;
18551
18552                    if (state === REJECTED) {
18553                      reject(promise, value);
18554                    } else {
18555                      this._result[i] = value;
18556                    }
18557                  }
18558
18559                  if (this._remaining === 0) {
18560                    fulfill(promise, this._result);
18561                  }
18562                };
18563
18564                Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
18565                  var enumerator = this;
18566
18567                  subscribe(
18568                    promise,
18569                    undefined,
18570                    function(value) {
18571                      return enumerator._settledAt(FULFILLED, i, value);
18572                    },
18573                    function(reason) {
18574                      return enumerator._settledAt(REJECTED, i, reason);
18575                    }
18576                  );
18577                };
18578
18579                return Enumerator;
18580              })();
18581
18582              /**
18583  `Promise.all` accepts an array of promises, and returns a new promise which
18584  is fulfilled with an array of fulfillment values for the passed promises, or
18585  rejected with the reason of the first passed promise to be rejected. It casts all
18586  elements of the passed iterable to promises as it runs this algorithm.
18587
18588  Example:
18589
18590  ```javascript
18591  let promise1 = resolve(1);
18592  let promise2 = resolve(2);
18593  let promise3 = resolve(3);
18594  let promises = [ promise1, promise2, promise3 ];
18595
18596  Promise.all(promises).then(function(array){
18597    // The array here would be [ 1, 2, 3 ];
18598  });
18599  ```
18600
18601  If any of the `promises` given to `all` are rejected, the first promise
18602  that is rejected will be given as an argument to the returned promises's
18603  rejection handler. For example:
18604
18605  Example:
18606
18607  ```javascript
18608  let promise1 = resolve(1);
18609  let promise2 = reject(new Error("2"));
18610  let promise3 = reject(new Error("3"));
18611  let promises = [ promise1, promise2, promise3 ];
18612
18613  Promise.all(promises).then(function(array){
18614    // Code here never runs because there are rejected promises!
18615  }, function(error) {
18616    // error.message === "2"
18617  });
18618  ```
18619
18620  @method all
18621  @static
18622  @param {Array} entries array of promises
18623  @param {String} label optional string for labeling the promise.
18624  Useful for tooling.
18625  @return {Promise} promise that is fulfilled when all `promises` have been
18626  fulfilled, or rejected if any of them become rejected.
18627  @static
18628*/
18629              function all(entries) {
18630                return new Enumerator(this, entries).promise;
18631              }
18632
18633              /**
18634  `Promise.race` returns a new promise which is settled in the same way as the
18635  first passed promise to settle.
18636
18637  Example:
18638
18639  ```javascript
18640  let promise1 = new Promise(function(resolve, reject){
18641    setTimeout(function(){
18642      resolve('promise 1');
18643    }, 200);
18644  });
18645
18646  let promise2 = new Promise(function(resolve, reject){
18647    setTimeout(function(){
18648      resolve('promise 2');
18649    }, 100);
18650  });
18651
18652  Promise.race([promise1, promise2]).then(function(result){
18653    // result === 'promise 2' because it was resolved before promise1
18654    // was resolved.
18655  });
18656  ```
18657
18658  `Promise.race` is deterministic in that only the state of the first
18659  settled promise matters. For example, even if other promises given to the
18660  `promises` array argument are resolved, but the first settled promise has
18661  become rejected before the other promises became fulfilled, the returned
18662  promise will become rejected:
18663
18664  ```javascript
18665  let promise1 = new Promise(function(resolve, reject){
18666    setTimeout(function(){
18667      resolve('promise 1');
18668    }, 200);
18669  });
18670
18671  let promise2 = new Promise(function(resolve, reject){
18672    setTimeout(function(){
18673      reject(new Error('promise 2'));
18674    }, 100);
18675  });
18676
18677  Promise.race([promise1, promise2]).then(function(result){
18678    // Code here never runs
18679  }, function(reason){
18680    // reason.message === 'promise 2' because promise 2 became rejected before
18681    // promise 1 became fulfilled
18682  });
18683  ```
18684
18685  An example real-world use case is implementing timeouts:
18686
18687  ```javascript
18688  Promise.race([ajax('foo.json'), timeout(5000)])
18689  ```
18690
18691  @method race
18692  @static
18693  @param {Array} promises array of promises to observe
18694  Useful for tooling.
18695  @return {Promise} a promise which settles in the same way as the first passed
18696  promise to settle.
18697*/
18698              function race(entries) {
18699                /*jshint validthis:true */
18700                var Constructor = this;
18701
18702                if (!isArray(entries)) {
18703                  return new Constructor(function(_, reject) {
18704                    return reject(new TypeError('You must pass an array to race.'));
18705                  });
18706                } else {
18707                  return new Constructor(function(resolve, reject) {
18708                    var length = entries.length;
18709                    for (var i = 0; i < length; i++) {
18710                      Constructor.resolve(entries[i]).then(resolve, reject);
18711                    }
18712                  });
18713                }
18714              }
18715
18716              /**
18717  `Promise.reject` returns a promise rejected with the passed `reason`.
18718  It is shorthand for the following:
18719
18720  ```javascript
18721  let promise = new Promise(function(resolve, reject){
18722    reject(new Error('WHOOPS'));
18723  });
18724
18725  promise.then(function(value){
18726    // Code here doesn't run because the promise is rejected!
18727  }, function(reason){
18728    // reason.message === 'WHOOPS'
18729  });
18730  ```
18731
18732  Instead of writing the above, your code now simply becomes the following:
18733
18734  ```javascript
18735  let promise = Promise.reject(new Error('WHOOPS'));
18736
18737  promise.then(function(value){
18738    // Code here doesn't run because the promise is rejected!
18739  }, function(reason){
18740    // reason.message === 'WHOOPS'
18741  });
18742  ```
18743
18744  @method reject
18745  @static
18746  @param {Any} reason value that the returned promise will be rejected with.
18747  Useful for tooling.
18748  @return {Promise} a promise rejected with the given `reason`.
18749*/
18750              function reject$1(reason) {
18751                /*jshint validthis:true */
18752                var Constructor = this;
18753                var promise = new Constructor(noop);
18754                reject(promise, reason);
18755                return promise;
18756              }
18757
18758              function needsResolver() {
18759                throw new TypeError(
18760                  'You must pass a resolver function as the first argument to the promise constructor'
18761                );
18762              }
18763
18764              function needsNew() {
18765                throw new TypeError(
18766                  "Failed to construct 'Promise': Please use the 'new' operator, this object c
18766onstructor cannot be called as a function."
18767                );
18768              }
18769
18770              /**
18771  Promise objects represent the eventual result of an asynchronous operation. The
18772  primary way of interacting with a promise is through its `then` method, which
18773  registers callbacks to receive either a promise's eventual value or the reason
18774  why the promise cannot be fulfilled.
18775
18776  Terminology
18777  -----------
18778
18779  - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
18780  - `thenable` is an object or function that defines a `then` method.
18781  - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
18782  - `exception` is a value that is thrown using the throw statement.
18783  - `reason` is a value that indicates why a promise was rejected.
18784  - `settled` the final resting state of a promise, fulfilled or rejected.
18785
18786  A promise can be in one of three states: pending, fulfilled, or rejected.
18787
18788  Promises that are fulfilled have a fulfillment value and are in the fulfilled
18789  state.  Promises that are rejected have a rejection reason and are in the
18790  rejected state.  A fulfillment value is never a thenable.
18791
18792  Promises can also be said to *resolve* a value.  If this value is also a
18793  promise, then the original promise's settled state will match the value's
18794  settled state.  So a promise that *resolves* a promise that rejects will
18795  itself reject, and a promise that *resolves* a promise that fulfills will
18796  itself fulfill.
18797
18798
18799  Basic Usage:
18800  ------------
18801
18802  ```js
18803  let promise = new Promise(function(resolve, reject) {
18804    // on success
18805    resolve(value);
18806
18807    // on failure
18808    reject(reason);
18809  });
18810
18811  promise.then(function(value) {
18812    // on fulfillment
18813  }, function(reason) {
18814    // on rejection
18815  });
18816  ```
18817
18818  Advanced Usage:
18819  ---------------
18820
18821  Promises shine when abstracting away asynchronous interactions such as
18822  `XMLHttpRequest`s.
18823
18824  ```js
18825  function getJSON(url) {
18826    return new Promise(function(resolve, reject){
18827      let xhr = new XMLHttpRequest();
18828
18829      xhr.open('GET', url);
18830      xhr.onreadystatechange = handler;
18831      xhr.responseType = 'json';
18832      xhr.setRequestHeader('Accept', 'application/json');
18833      xhr.send();
18834
18835      function handler() {
18836        if (this.readyState === this.DONE) {
18837          if (this.status === 200) {
18838            resolve(this.response);
18839          } else {
18840            reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
18841          }
18842        }
18843      };
18844    });
18845  }
18846
18847  getJSON('/posts.json').then(function(json) {
18848    // on fulfillment
18849  }, function(reason) {
18850    // on rejection
18851  });
18852  ```
18853
18854  Unlike callbacks, promises are great composable primitives.
18855
18856  ```js
18857  Promise.all([
18858    getJSON('/posts'),
18859    getJSON('/comments')
18860  ]).then(function(values){
18861    values[0] // => postsJSON
18862    values[1] // => commentsJSON
18863
18864    return values;
18865  });
18866  ```
18867
18868  @class Promise
18869  @param {Function} resolver
18870  Useful for tooling.
18871  @constructor
18872*/
18873
18874              var Promise$1 = (function() {
18875                function Promise(resolver) {
18876                  this[PROMISE_ID] = nextId();
18877                  this._result = this._state = undefined;
18878                  this._subscribers = [];
18879
18880                  if (noop !== resolver) {
18881                    typeof resolver !== 'function' && needsResolver();
18882                    this instanceof Promise
18883                      ? initializePromise(this, resolver)
18884                      : needsNew();
18885                  }
18886                }
18887
18888                /**
18889  The primary way of interacting with a promise is through its `then` method,
18890  which registers callbacks to receive either a promise's eventual value or the
18891  reason why the promise cannot be fulfilled.
18892   ```js
18893  findUser().then(function(user){
18894    // user is available
18895  }, function(reason){
18896    // user is unavailable, and you are given the reason why
18897  });
18898  ```
18899   Chaining
18900  --------
18901   The return value of `then` is itself a promise.  This second, 'downstream'
18902  promise is resolved with the return value of the first promise's fulfillment
18903  or rejection handler, or rejected if the handler throws an exception.
18904   ```js
18905  findUser().then(function (user) {
18906    return user.name;
18907  }, function (reason) {
18908    return 'default name';
18909  }).then(function (userName) {
18910    // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
18911    // will be `'default name'`
18912  });
18913   findUser().then(function (user) {
18914    throw new Error('Found user, but still unhappy');
18915  }, function (reason) {
18916    throw new Error('`findUser` rejected and we're unhappy');
18917  }).then(function (value) {
18918    // never reached
18919  }, function (reason) {
18920    // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
18921    // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
18922  });
18923  ```
18924  If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
18925   ```js
18926  findUser().then(function (user) {
18927    throw new PedagogicalException('Upstream error');
18928  }).then(function (value) {
18929    // never reached
18930  }).then(function (value) {
18931    // never reached
18932  }, function (reason) {
18933    // The `PedgagocialException` is propagated all the way down to here
18934  });
18935  ```
18936   Assimilation
18937  ------------
18938   Sometimes the value you want to propagate to a downstream promise can only be
18939  retrieved asynchronously. This can be achieved by returning a promise in the
18940  fulfillment or rejection handler. The downstream promise will then be pending
18941  until the returned promise is settled. This is called *assimilation*.
18942   ```js
18943  findUser().then(function (user) {
18944    return findCommentsByAuthor(user);
18945  }).then(function (comments) {
18946    // The user's comments are now available
18947  });
18948  ```
18949   If the assimliated promise rejects, then the downstream promise will also reject.
18950   ```js
18951  findUser().then(function (user) {
18952    return findCommentsByAuthor(user);
18953  }).then(function (comments) {
18954    // If `findCommentsByAuthor` fulfills, we'll have the value here
18955  }, function (reason) {
18956    // If `findCommentsByAuthor` rejects, we'll have the reason here
18957  });
18958  ```
18959   Simple Example
18960  --------------
18961   Synchronous Example
18962   ```javascript
18963  let result;
18964   try {
18965    result = findResult();
18966    // success
18967  } catch(reason) {
18968    // failure
18969  }
18970  ```
18971   Errback Example
18972   ```js
18973  findResult(function(result, err){
18974    if (err) {
18975      // failure
18976    } else {
18977      // success
18978    }
18979  });
18980  ```
18981   Promise Example;
18982   ```javascript
18983  findResult().then(function(result){
18984    // success
18985  }, function(reason){
18986    // failure
18987  });
18988  ```
18989   Advanced Example
18990  --------------
18991   Synchronous Example
18992   ```javascript
18993  let author, books;
18994   try {
18995    author = findAuthor();
18996    books  = findBooksByAuthor(author);
18997    // success
18998  } catch(reason) {
18999    // failure
19000  }
19001  ```
19002   Errback Example
19003   ```js
19004   function foundBooks(books) {
19005   }
19006   function failure(reason) {
19007   }
19008   findAuthor(function(author, err){
19009    if (err) {
19010      failure(err);
19011      // failure
19012    } else {
19013      try {
19014        findBoooksByAuthor(author, function(books, err) {
19015          if (err) {
19016            failure(err);
19017          } else {
19018            try {
19019              foundBooks(books);
19020            } catch(reason) {
19021              failure(reason);
19022            }
19023          }
19024        });
19025      } catch(error) {
19026        failure(err);
19027      }
19028      // success
19029    }
19030  });
19031  ```
19032   Promise Example;
19033   ```javascript
19034  findAuthor().
19035    then(findBooksByAuthor).
19036    then(function(books){
19037      // found books
19038  }).catch(function(reason){
19039    // something went wrong
19040  });
19041  ```
19042   @method then
19043  @param {Function} onFulfilled
19044  @param {Function} onRejected
19045  Useful for tooling.
19046  @return {Promise}
19047  */
19048
19049                /**
19050  `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
19051  as the catch block of a try/catch statement.
19052  ```js
19053  function findAuthor(){
19054  throw new Error('couldn't find that author');
19055  }
19056  // synchronous
19057  try {
19058  findAuthor();
19059  } catch(reason) {
19060  // something went wrong
19061  }
19062  // async with promises
19063  findAuthor().catch(function(reason){
19064  // something went wrong
19065  });
19066  ```
19067  @method catch
19068  @param {Function} onRejection
19069  Useful for tooling.
19070  @return {Promise}
19071  */
19072
19073                Promise.prototype.catch = function _catch(onRejection) {
19074                  return this.then(null, onRejection);
19075                };
19076
19077                /**
19078    `finally` will be invoked regardless of the promise's fate just as native
19079    try/catch/finally behaves
19080  
19081    Synchronous example:
19082  
19083    ```js
19084    findAuthor() {
19085      if (Math.random() > 0.5) {
19086        throw new Error();
19087      }
19088      return new Author();
19089    }
19090  
19091    try {
19092      return findAuthor(); // succeed or fail
19093    } catch(error) {
19094      return findOtherAuther();
19095    } finally {
19096      // always runs
19097      // doesn't affect the return value
19098    }
19099    ```
19100  
19101    Asynchronous example:
19102  
19103    ```js
19104    findAuthor().catch(function(reason){
19105      return findOtherAuther();
19106    }).finally(function(){
19107      // author was either found, or not
19108    });
19109    ```
19110  
19111    @method finally
19112    @param {Function} callback
19113    @return {Promise}
19114  */
19115
19116                Promise.prototype.finally = function _finally(callback) {
19117                  var promise = this;
19118                  var constructor = promise.constructor;
19119
19120                  if (isFunction(callback)) {
19121                    return promise.then(
19122                      function(value) {
19123                        return constructor.resolve(callback()).then(function() {
19124                          return value;
19125                        });
19126                      },
19127                      function(reason) {
19128                        return constructor.resolve(callback()).then(function() {
19129                          throw reason;
19130                        });
19131                      }
19132                    );
19133                  }
19134
19135                  return promise.then(callback, callback);
19136                };
19137
19138                return Promise;
19139              })();
19140
19141              Promise$1.prototype.then = then;
19142              Promise$1.all = all;
19143              Promise$1.race = race;
19144              Promise$1.resolve = resolve$1;
19145              Promise$1.reject = reject$1;
19146              Promise$1._setScheduler = setScheduler;
19147              Promise$1._setAsap = setAsap;
19148              Promise$1._asap = asap;
19149
19150              /*global self*/
19151              function polyfill() {
19152                var local = void 0;
19153
19154                if (typeof global !== 'undefined') {
19155                  local = global;
19156                } else if (typeof self !== 'undefined') {
19157                  local = self;
19158                } else {
19159                  try {
19160                    local = Function('return this')();
19161                  } catch (e) {
19162                    throw new Error(
19163                      'polyfill failed because global object is unavailable in this environment'
19164                    );
19165                  }
19166                }
19167
19168                var P = local.Promise;
19169
19170                if (P) {
19171                  var promiseToString = null;
19172                  try {
19173                    promiseToString = Object.prototype.toString.call(P.resolve());
19174                  } catch (e) {
19175                    // silently ignored
19176                  }
19177
19178                  if (promiseToString === '[object Promise]' && !P.cast) {
19179                    return;
19180                  }
19181                }
19182
19183                local.Promise = Promise$1;
19184              }
19185
19186              // Strange compat..
19187              Promise$1.polyfill = polyfill;
19188              Promise$1.Promise = Promise$1;
19189
19190              return Promise$1;
19191            });
19192          }.call(
19193            this,
19194            _dereq_('_process'),
19195            typeof global !== 'undefined'
19196              ? global
19197              : typeof self !== 'undefined'
19198                ? self
19199                : typeof window !== 'undefined' ? window : {}
19200          ));
19201        },
19202        { _process: 36 }
19203      ],
19204      25: [
vendor: 4,623 bytes, lines 19205-19337
19205        function(_dereq_, module, exports) {
19206          (function(global, factory) {
19207            if (typeof define === 'function' && define.amd) {
19208              define(['exports', 'module'], factory);
19209            } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
19210              factory(exports, module);
19211            } else {
19212              var mod = {
19213                exports: {}
19214              };
19215              factory(mod.exports, mod);
19216              global.fetchJsonp = mod.exports;
19217            }
19218          })(this, function(exports, module) {
19219            'use strict';
19220
19221            var defaultOptions = {
19222              timeout: 5000,
19223              jsonpCallback: 'callback',
19224              jsonpCallbackFunction: null
19225            };
19226
19227            function generateCallbackFunction() {
19228              return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000);
19229            }
19230
19231            function clearFunction(functionName) {
19232              // IE8 throws an exception when you try to delete a property on window
19233              // http://stackoverflow.com/a/1824228/751089
19234              try {
19235                delete window[functionName];
19236              } catch (e) {
19237                window[functionName] = undefined;
19238              }
19239            }
19240
19241            function removeScript(scriptId) {
19242              var script = document.getElementById(scriptId);
19243              if (script) {
19244                document.getElementsByTagName('head')[0].removeChild(script);
19245              }
19246            }
19247
19248            function fetchJsonp(_url) {
19249              var options =
19250                arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
19251
19252              // to avoid param reassign
19253              var url = _url;
19254              var timeout = options.timeout || defaultOptions.timeout;
19255              var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;
19256
19257              var timeoutId = undefined;
19258
19259              return new Promise(function(resolve, reject) {
19260                var callbackFunction =
19261                  options.jsonpCallbackFunction || generateCallbackFunction();
19262                var scriptId = jsonpCallback + '_' + callbackFunction;
19263
19264                window[callbackFunction] = function(response) {
19265                  resolve({
19266                    ok: true,
19267                    // keep consistent with fetch API
19268                    json: function json() {
19269                      return Promise.resolve(response);
19270                    }
19271                  });
19272
19273                  if (timeoutId) clearTimeout(timeoutId);
19274
19275                  removeScript(scriptId);
19276
19277                  clearFunction(callbackFunction);
19278                };
19279
19280                // Check if the user set their own params, and if not add a ? to start a list of params
19281                url += url.indexOf('?') === -1 ? '?' : '&';
19282
19283                var jsonpScript = document.createElement('script');
19284                jsonpScript.setAttribute(
19285                  'src',
19286                  '' + url + jsonpCallback + '=' + callbackFunction
19287                );
19288                if (options.charset) {
19289                  jsonpScript.setAttribute('charset', options.charset);
19290                }
19291                jsonpScript.id = scriptId;
19292                document.getElementsByTagName('head')[0].appendChild(jsonpScript);
19293
19294                timeoutId = setTimeout(function() {
19295                  reject(new Error('JSONP request to ' + _url + ' timed out'));
19296
19297                  clearFunction(callbackFunction);
19298                  removeScript(scriptId);
19299                  window[callbackFunction] = function() {
19300                    clearFunction(callbackFunction);
19301                  };
19302                }, timeout);
19303
19304                // Caught if got 404/500
19305                jsonpScript.onerror = function() {
19306                  reject(new Error('JSONP request to ' + _url + ' failed'));
19307
19308                  clearFunction(callbackFunction);
19309                  removeScript(scriptId);
19310                  if (timeoutId) clearTimeout(timeoutId);
19311                };
19312              });
19313            }
19314
19315            // export as global function
19316            /*
19317  let local;
19318  if (typeof global !== 'undefined') {
19319    local = global;
19320  } else if (typeof self !== 'undefined') {
19321    local = self;
19322  } else {
19323    try {
19324      local = Function('return this')();
19325    } catch (e) {
19326      throw new Error('polyfill failed because global object is unavailable in this environment');
19327    }
19328  }
19329  local.fetchJsonp = fetchJsonp;
19330  */
19331
19332            module.exports = fetchJsonp;
19333          });
19334        },
19335        {}
19336      ],
19337      26: [
vendor: 6,694 bytes, lines 19338-19483
19338        function(_dereq_, module, exports) {
19339          /* FileSaver.js
19340 * A saveAs() FileSaver implementation.
19341 * 1.3.2
19342 * 2016-06-16 18:25:19
19343 *
19344 * By Eli Grey, http://eligrey.com
19345 * License: MIT
19346 *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
19347 */
19348
19349          /*global self */
19350          /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
19351
19352          /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
19353
19354          var saveAs =
19355            saveAs ||
19356            (function(view) {
19357              'use strict';
19358              // IE <10 is explicitly unsupported
19359              if (
19360                typeof view === 'undefined' ||
19361                (typeof navigator !== 'undefined' &&
19362                  /MSIE [1-9]\./.test(navigator.userAgent))
19363              ) {
19364                return;
19365              }
19366              var doc = view.document,
19367                // only get URL when necessary in case Blob.js hasn't overridden it yet
19368                get_URL = function() {
19369                  return view.URL || view.webkitURL || view;
19370                },
19371                save_link = doc.createElementNS('http://www.w3.org/1999/xhtml', 'a'),
19372                can_use_save_link = 'download' in save_link,
19373                click = function(node) {
19374                  var event = new MouseEvent('click');
19375                  node.dispatchEvent(event);
19376                },
19377                is_safari = /constructor/i.test(view.HTMLElement) || view.safari,
19378                is_chrome_ios = /CriOS\/[\d]+/.test(navigator.userAgent),
19379                throw_outside = function(ex) {
19380                  (view.setImmediate || view.setTimeout)(function() {
19381                    throw ex;
19382                  }, 0);
19383                },
19384                force_saveable_type = 'application/octet-stream',
19385                // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
19386                arbitrary_revoke_timeout = 1000 * 40, // in ms
19387                revoke = function(file) {
19388                  var revoker = function() {
19389                    if (typeof file === 'string') {
19390                      // file is an object URL
19391                      get_URL().revokeObjectURL(file);
19392                    } else {
19393                      // file is a File
19394                      file.remove();
19395                    }
19396                  };
19397                  setTimeout(revoker, arbitrary_revoke_timeout);
19398                },
19399                dispatch = function(filesaver, event_types, event) {
19400                  event_types = [].concat(event_types);
19401                  var i = event_types.length;
19402                  while (i--) {
19403                    var listener = filesaver['on' + event_types[i]];
19404                    if (typeof listener === 'function') {
19405                      try {
19406                        listener.call(filesaver, event || filesaver);
19407                      } catch (ex) {
19408                        throw_outside(ex);
19409                      }
19410                    }
19411                  }
19412                },
19413                auto_bom = function(blob) {
19414                  // prepend BOM for UTF-8 XML and text/* types (including HTML)
19415                  // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
19416                  if (
19417                    /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(
19418                      blob.type
19419                    )
19420                  ) {
19421                    return new Blob([String.fromCharCode(0xfeff), blob], {
19422                      type: blob.type
19423                    });
19424                  }
19425                  return blob;
19426                },
19427                FileSaver = function(blob, name, no_auto_bom) {
19428                  if (!no_auto_bom) {
19429                    blob = auto_bom(blob);
19430                  }
19431                  // First try a.download, then web filesystem, then object URLs
19432                  var filesaver = this,
19433                    type = blob.type,
19434                    force = type === force_saveable_type,
19435                    object_url,
19436                    dispatch_all = function() {
19437                      dispatch(filesaver, 'writestart progress write writeend'.split(' '));
19438                    },
19439                    // on any filesys errors revert to saving with object URLs
19440                    fs_error = function() {
19441                      if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
19442                        // Safari doesn't allow downloading of blob urls
19443                        var reader = new FileReader();
19444                        reader.onloadend = function() {
19445                          var url = is_chrome_ios
19446                            ? reader.result
19447                            : reader.result.replace(
19448                                /^data:[^;]*;/,
19449                                'data:attachment/file;'
19450                              );
19451                          var popup = view.open(url, '_blank');
19452                          if (!popup) view.location.href = url;
19453                          url = undefined; // release reference before dispatching
19454                          filesaver.readyState = filesaver.DONE;
19455                          dispatch_all();
19456                        };
19457                        reader.readAsDataURL(blob);
19458                        filesaver.readyState = filesaver.INIT;
19459                        return;
19460                      }
19461                      // don't create more object URLs than needed
19462                      if (!object_url) {
19463                        object_url = get_URL().createObjectURL(blob);
19464                      }
19465                      if (force) {
19466                        view.location.href = object_url;
19467                      } else {
19468                        var opened = view.open(object_url, '_blank');
19469                        if (!opened) {
19470                          // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
19471                          view.location.href = object_url;
19472                        }
19473                      }
19474                      filesaver.readyState = filesaver.DONE;
19475                      dispatch_all();
19476                      revoke(object_url);
19477                    };
19478                  filesaver.readyState = filesaver.INIT;
19479
19480                  if (can_use_save_link) {
19481                    object_url = get_URL().createObjectURL(blob);
19482                    setTimeout(function() {
19483                      save_link.href = object_url;
19484                      save_link.download = name;
19485                      click(save_link);
19486                      dispatch_all();
19487                      revoke(object_url);
19488                      filesaver.readyState = filesaver.DONE;
19489                    });
19490                    return;
19491                  }
19492
19493                  fs_error();
19494                },
19495                FS_proto = FileSaver.prototype,
19496                saveAs = function(blob, name, no_auto_bom) {
19497                  return new FileSaver(blob, name || blob.name || 'download', no_auto_bom);
19498                };
19499              // IE 10+ (native saveAs)
19500              if (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob) {
19501                return function(blob, name, no_auto_bom) {
19502                  name = name || blob.name || 'download';
19503
19504                  if (!no_auto_bom) {
19505                    blob = auto_bom(blob);
19506                  }
19507                  return navigator.msSaveOrOpenBlob(blob, name);
19508                };
19509              }
19510
19511              FS_proto.abort = function() {};
19512              FS_proto.readyState = FS_proto.INIT = 0;
19513              FS_proto.WRITING = 1;
19514              FS_proto.DONE = 2;
19515
19516              FS_proto.error = FS_proto.onwritestart = FS_proto.onprogress = FS_proto.onwrite = FS_proto.onabort = FS_proto.onerror = FS_proto.onwriteend = null;
19517
19518              return saveAs;
19519            })(
19520              (typeof self !== 'undefined' && self) ||
19521                (typeof window !== 'undefined' && window) ||
19522                this.content
19523            );
19524          // `self` is undefined in Firefox for Android content script context
19525          // while `this` is nsIContentFrameMessageManager
19526          // with an attribute `content` that corresponds to the window
19527
19528          if (typeof module !== 'undefined' && module.exports) {
19529            module.exports.saveAs = saveAs;
19530          } else if (
19531            typeof define !== 'undefined' &&
19532            define !== null &&
19533            define.amd !== null
19534          ) {
19535            define('FileSaver.js', function() {
19536              return saveAs;
19537            });
19538          }
19539        },
19540        {}
19541      ],
19542      27: [
19543        function(_dereq_, module, exports) {
19544          'use strict';
19545
19546          function _interopDefault(ex) {
19547            return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;
19548          }
19549
19550          var _classCallCheck = _interopDefault(
19551            _dereq_('@babel/runtime/helpers/classCallCheck')
19552          );
19553          var _createClass = _interopDefault(_dereq_('@babel/runtime/helpers/createClass'));
19554
19555          var arr = [];
19556          var each = arr.forEach;
19557          var slice = arr.slice;
19558          function defaults(obj) {
19559            each.call(slice.call(arguments, 1), function(source) {
19560              if (source) {
19561                for (var prop in source) {
19562                  if (obj[prop] === undefined) obj[prop] = source[prop];
19563                }
19564              }
19565            });
19566            return obj;
19567          }
19568
19569          var cookie = {
19570            create: function create(name, value, minutes, domain) {
19571              var expires;
19572
19573              if (minutes) {
19574                var date = new Date();
19575                date.setTime(date.getTime() + minutes * 60 * 1000);
19576                expires = '; expires=' + date.toGMTString();
19577              } else expires = '';
19578
19579              domain = domain ? 'domain=' + domain + ';' : '';
19580              document.cookie = name + '=' + value + expires + ';' + domain + 'path=/';
19581            },
19582            read: function read(name) {
19583              var nameEQ = name + '=';
19584              var ca = document.cookie.split(';');
19585
19586              for (var i = 0; i < ca.length; i++) {
19587                var c = ca[i];
19588
19589                while (c.charAt(0) === ' ') {
19590                  c = c.substring(1, c.length);
19591                }
19592
19593                if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
19594              }
19595
19596              return null;
19597            },
19598            remove: function remove(name) {
19599              this.create(name, '', -1);
19600            }
19601          };
19602          var cookie$1 = {
19603            name: 'cookie',
19604            lookup: function lookup(options) {
19605              var found;
19606
19607              if (options.lookupCookie && typeof document !== 'undefined') {
19608                var c = cookie.read(options.lookupCookie);
19609                if (c) found = c;
19610              }
19611
19612              return found;
19613            },
19614            cacheUserLanguage: function cacheUserLanguage(lng, options) {
19615              if (options.lookupCookie && typeof document !== 'undefined') {
19616                cookie.create(
19617                  options.lookupCookie,
19618                  lng,
19619                  options.cookieMinutes,
19620                  options.cookieDomain
19621                );
19622              }
19623            }
19624          };
19625
19626          var querystring = {
19627            name: 'querystring',
19628            lookup: function lookup(options) {
19629              var found;
19630
19631              if (typeof window !== 'undefined') {
19632                var query = window.location.search.substring(1);
19633                var params = query.split('&');
19634
19635                for (var i = 0; i < params.length; i++) {
19636                  var pos = params[i].indexOf('=');
19637
19638                  if (pos > 0) {
19639                    var key = params[i].substring(0, pos);
19640
19641                    if (key === options.lookupQuerystring) {
19642                      found = params[i].substring(pos + 1);
19643                    }
19644                  }
19645                }
19646              }
19647
19648              return found;
19649            }
19650          };
19651
19652          var hasLocalStorageSupport;
19653
19654          try {
19655            hasLocalStorageSupport = window !== 'undefined' && window.localStorage !== null;
19656            var testKey = 'i18next.translate.boo';
19657            window.localStorage.setItem(testKey, 'foo');
19658            window.localStorage.removeItem(testKey);
19659          } catch (e) {
19660            hasLocalStorageSupport = false;
vendor: 6,234 bytes, lines 19661-19841
19661          }
19662
19663          var localStorage = {
19664            name: 'localStorage',
19665            lookup: function lookup(options) {
19666              var found;
19667
19668              if (options.lookupLocalStorage && hasLocalStorageSupport) {
19669                var lng = window.localStorage.getItem(options.lookupLocalStorage);
19670                if (lng) found = lng;
19671              }
19672
19673              return found;
19674            },
19675            cacheUserLanguage: function cacheUserLanguage(lng, options) {
19676              if (options.lookupLocalStorage && hasLocalStorageSupport) {
19677                window.localStorage.setItem(options.lookupLocalStorage, lng);
19678              }
19679            }
19680          };
19681
19682          var navigator$1 = {
19683            name: 'navigator',
19684            lookup: function lookup(options) {
19685              var found = [];
19686
19687              if (typeof navigator !== 'undefined') {
19688                if (navigator.languages) {
19689                  // chrome only; not an array, so can't use .push.apply instead of iterating
19690                  for (var i = 0; i < navigator.languages.length; i++) {
19691                    found.push(navigator.languages[i]);
19692                  }
19693                }
19694
19695                if (navigator.userLanguage) {
19696                  found.push(navigator.userLanguage);
19697                }
19698
19699                if (navigator.language) {
19700                  found.push(navigator.language);
19701                }
19702              }
19703
19704              return found.length > 0 ? found : undefined;
19705            }
19706          };
19707
19708          var htmlTag = {
19709            name: 'htmlTag',
19710            lookup: function lookup(options) {
19711              var found;
19712              var htmlTag =
19713                options.htmlTag ||
19714                (typeof document !== 'undefined' ? document.documentElement : null);
19715
19716              if (htmlTag && typeof htmlTag.getAttribute === 'function') {
19717                found = htmlTag.getAttribute('lang');
19718              }
19719
19720              return found;
19721            }
19722          };
19723
19724          var path = {
19725            name: 'path',
19726            lookup: function lookup(options) {
19727              var found;
19728
19729              if (typeof window !== 'undefined') {
19730                var language = window.location.pathname.match(/\/([a-zA-Z-]*)/g);
19731
19732                if (language instanceof Array) {
19733                  if (typeof options.lookupFromPathIndex === 'number') {
19734                    if (typeof language[options.lookupFromPathIndex] !== 'string') {
19735                      return undefined;
19736                    }
19737
19738                    found = language[options.lookupFromPathIndex].replace('/', '');
19739                  } else {
19740                    found = language[0].replace('/', '');
19741                  }
19742                }
19743              }
19744
19745              return found;
19746            }
19747          };
19748
19749          var subdomain = {
19750            name: 'subdomain',
19751            lookup: function lookup(options) {
19752              var found;
19753
19754              if (typeof window !== 'undefined') {
19755                var language = window.location.href.match(
19756                  /(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/gi
19757                );
19758
19759                if (language instanceof Array) {
19760                  if (typeof options.lookupFromSubdomainIndex === 'number') {
19761                    found = language[options.lookupFromSubdomainIndex]
19762                      .replace('http://', '')
19763                      .replace('https://', '')
19764                      .replace('.', '');
19765                  } else {
19766                    found = language[0]
19767                      .replace('http://', '')
19768                      .replace('https://', '')
19769                      .replace('.', '');
19770                  }
19771                }
19772              }
19773
19774              return found;
19775            }
19776          };
19777
19778          function getDefaults() {
19779            return {
19780              order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag'],
19781              lookupQuerystring: 'lng',
19782              lookupCookie: 'i18next',
19783              lookupLocalStorage: 'i18nextLng',
19784              // cache user language
19785              caches: ['localStorage'],
19786              excludeCacheFor: ['cimode'],
19787              //cookieMinutes: 10,
19788              //cookieDomain: 'myDomain'
19789              checkWhitelist: true
19790            };
19791          }
19792
19793          var Browser =
19794            /*#__PURE__*/
19795            (function() {
19796              function Browser(services) {
19797                var options =
19798                  arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
19799
19800                _classCallCheck(this, Browser);
19801
19802                this.type = 'languageDetector';
19803                this.detectors = {};
19804                this.init(services, options);
19805              }
19806
19807              _createClass(Browser, [
19808                {
19809                  key: 'init',
19810                  value: function init(services) {
19811                    var options =
19812                      arguments.length > 1 && arguments[1] !== undefined
19813                        ? arguments[1]
19814                        : {};
19815                    var i18nOptions =
19816                      arguments.length > 2 && arguments[2] !== undefined
19817                        ? arguments[2]
19818                        : {};
19819                    this.services = services;
19820                    this.options = defaults(options, this.options || {}, getDefaults()); // backwards compatibility
19821
19822                    if (this.options.lookupFromUrlIndex)
19823                      this.options.lookupFromPathIndex = this.options.lookupFromUrlIndex;
19824                    this.i18nOptions = i18nOptions;
19825                    this.addDetector(cookie$1);
19826                    this.addDetector(querystring);
19827                    this.addDetector(localStorage);
19828                    this.addDetector(navigator$1);
19829                    this.addDetector(htmlTag);
19830                    this.addDetector(path);
19831                    this.addDetector(subdomain);
19832                  }
19833                },
19834                {
19835                  key: 'addDetector',
19836                  value: function addDetector(detector) {
19837                    this.detectors[detector.name] = detector;
19838                  }
19839                },
19840                {
19841                  key: 'detect',
19842                  value: function detect(detectionOrder) {
19843                    var _this = this;
19844
19845                    if (!detectionOrder) detectionOrder = this.options.order;
19846                    var detected = [];
19847                    detectionOrder.forEach(function(detectorName) {
19848                      if (_this.detectors[detectorName]) {
19849                        var lookup = _this.detectors[detectorName].lookup(_this.options);
19850
19851                        if (lookup && typeof lookup === 'string') lookup = [lookup];
19852                        if (lookup) detected = detected.concat(lookup);
19853                      }
19854                    });
19855                    var found;
19856                    detected.forEach(function(lng) {
19857                      if (found) return;
19858
19859                      var cleanedLng = _this.services.languageUtils.formatLanguageCode(lng);
19860
19861                      if (
19862                        !_this.options.checkWhitelist ||
19863                        _this.services.languageUtils.isWhitelisted(cleanedLng)
19864                      )
19865                        found = cleanedLng;
19866                    });
19867
19868                    if (!found) {
19869                      var fallbacks = this.i18nOptions.fallbackLng;
19870                      if (typeof fallbacks === 'string') fallbacks = [fallbacks];
19871                      if (!fallbacks) fallbacks = [];
19872
19873                      if (Object.prototype.toString.apply(fallbacks) === '[object Array]') {
19874                        found = fallbacks[0];
19875                      } else {
19876                        found =
19877                          fallbacks[0] || (fallbacks['default'] && fallbacks['default'][0]);
19878                      }
19879                    }
19880
19881                    return found;
19882                  }
19883                },
19884                {
19885                  key: 'cacheUserLanguage',
19886                  value: function cacheUserLanguage(lng, caches) {
19887                    var _this2 = this;
19888
19889                    if (!caches) caches = this.options.caches;
19890                    if (!caches) return;
19891                    if (
19892                      this.options.excludeCacheFor &&
19893                      this.options.excludeCacheFor.indexOf(lng) > -1
19894                    )
19895                      return;
19896                    caches.forEach(function(cacheName) {
19897                      if (_this2.detectors[cacheName])
19898                        _this2.detectors[cacheName].cacheUserLanguage(lng, _this2.options);
19899                    });
19900                  }
19901                }
19902              ]);
19903
19904              return Browser;
19905            })();
19906
19907          Browser.type = 'languageDetector';
19908
19909          module.exports = Browser;
19910        },
19911        {
19912          '@babel/runtime/helpers/classCallCheck': 28,
19913          '@babel/runtime/helpers/createClass': 29
19914        }
19915      ],
19916      28: [
19917        function(_dereq_, module, exports) {
19918          arguments[4][5][0].apply(exports, arguments);
19919        },
19920        { dup: 5 }
19921      ],
19922      29: [
19923        function(_dereq_, module, exports) {
19924          arguments[4][6][0].apply(exports, arguments);
19925        },
19926        { dup: 6 }
19927      ],
19928      30: [
19929        function(_dereq_, module, exports) {
19930          'use strict';
19931
19932          function _interopDefault(ex) {
19933            return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;
19934          }
19935
19936          var _typeof = _interopDefault(_dereq_('@babel/runtime/helpers/typeof'));
19937          var _objectSpread = _interopDefault(
19938            _dereq_('@babel/runtime/helpers/objectSpread')
19939          );
19940          var _classCallCheck = _interopDefault(
19941            _dereq_('@babel/runtime/helpers/classCallCheck')
19942          );
19943          var _createClass = _interopDefault(_dereq_('@babel/runtime/helpers/createClass'));
19944          var _possibleConstructorReturn = _interopDefault(
19945            _dereq_('@babel/runtime/helpers/possibleConstructorReturn')
19946          );
19947          var _getPrototypeOf = _interopDefault(
19948            _dereq_('@babel/runtime/helpers/getPrototypeOf')
19949          );
19950          var _assertThisInitialized = _interopDefault(
19951            _dereq_('@babel/runtime/helpers/assertThisInitialized')
19952          );
19953          var _inherits = _interopDefault(_dereq_('@babel/runtime/helpers/inherits'));
19954          var _toConsumableArray = _interopDefault(
19955            _dereq_('@babel/runtime/helpers/toConsumableArray')
19956          );
19957          var _slicedToArray = _interopDefault(
19958            _dereq_('@babel/runtime/helpers/slicedToArray')
19959          );
19960
19961          var consoleLogger = {
19962            type: 'logger',
19963            log: function log(args) {
19964              this.output('log', args);
19965            },
19966            warn: function warn(args) {
19967              this.output('warn', args);
19968            },
19969            error: function error(args) {
19970              this.output('error', args);
19971            },
19972            output: function output(type, args) {
19973              var _console;
19974
19975              /* eslint no-console: 0 */
19976              if (console && console[type])
19977                (_console = console)[type].apply(_console, _toConsumableArray(args));
19978            }
19979          };
19980
19981          var Logger =
19982            /*#__PURE__*/
19983            (function() {
19984              function Logger(concreteLogger) {
19985                var options =
19986                  arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
19987
19988                _classCallCheck(this, Logger);
19989
19990                this.init(concreteLogger, options);
19991              }
19992
19993              _createClass(Logger, [
19994                {
19995                  key: 'init',
19996                  value: function init(concreteLogger) {
19997                    var options =
19998                      arguments.length > 1 && arguments[1] !== undefined
19999                        ? arguments[1]
20000                        : {};
20001                    this.prefix = options.prefix || 'i18next:';
20002                    this.logger = concreteLogger || consoleLogger;
20003                    this.options = options;
20004                    this.debug = options.debug;
20005                  }
20006                },
20007                {
20008                  key: 'setDebug',
20009                  value: function setDebug(bool) {
20010                    this.debug = bool;
20011                  }
20012                },
20013                {
20014                  key: 'log',
20015                  value: function log() {
20016                    for (
20017                      var _len = arguments.length, args = new Array(_len), _key = 0;
20018                      _key < _len;
20019                      _key++
20020                    ) {
20021                      args[_key] = arguments[_key];
20022                    }
20023
20024                    return this.forward(args, 'log', '', true);
20025                  }
20026                },
20027                {
20028                  key: 'warn',
20029                  value: function warn() {
20030                    for (
20031                      var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
20032                      _key2 < _len2;
20033                      _key2++
20034                    ) {
20035                      args[_key2] = arguments[_key2];
20036                    }
20037
20038                    return this.forward(args, 'warn', '', true);
20039                  }
20040                },
20041                {
20042                  key: 'error',
20043                  value: function error() {
20044                    for (
20045                      var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;
20046                      _key3 < _len3;
20047                      _key3++
20048                    ) {
20049                      args[_key3] = arguments[_key3];
20050                    }
20051
20052                    return this.forward(args, 'error', '');
20053                  }
20054                },
20055                {
20056                  key: 'deprecate',
20057                  value: function deprecate() {
20058                    for (
20059                      var _len4 = arguments.length, args = new Array(_len4), _key4 = 0;
20060                      _key4 < _len4;
20061                      _key4++
20062                    ) {
vendor: 6,649 bytes, lines 20063-20261
20063                      args[_key4] = arguments[_key4];
20064                    }
20065
20066                    return this.forward(args, 'warn', 'WARNING DEPRECATED: ', true);
20067                  }
20068                },
20069                {
20070                  key: 'forward',
20071                  value: function forward(args, lvl, prefix, debugOnly) {
20072                    if (debugOnly && !this.debug) return null;
20073                    if (typeof args[0] === 'string')
20074                      args[0] = ''
20075                        .concat(prefix)
20076                        .concat(this.prefix, ' ')
20077                        .concat(args[0]);
20078                    return this.logger[lvl](args);
20079                  }
20080                },
20081                {
20082                  key: 'create',
20083                  value: function create(moduleName) {
20084                    return new Logger(
20085                      this.logger,
20086                      _objectSpread(
20087                        {},
20088                        {
20089                          prefix: ''.concat(this.prefix, ':').concat(moduleName, ':')
20090                        },
20091                        this.options
20092                      )
20093                    );
20094                  }
20095                }
20096              ]);
20097
20098              return Logger;
20099            })();
20100
20101          var baseLogger = new Logger();
20102
20103          var EventEmitter =
20104            /*#__PURE__*/
20105            (function() {
20106              function EventEmitter() {
20107                _classCallCheck(this, EventEmitter);
20108
20109                this.observers = {};
20110              }
20111
20112              _createClass(EventEmitter, [
20113                {
20114                  key: 'on',
20115                  value: function on(events, listener) {
20116                    var _this = this;
20117
20118                    events.split(' ').forEach(function(event) {
20119                      _this.observers[event] = _this.observers[event] || [];
20120
20121                      _this.observers[event].push(listener);
20122                    });
20123                    return this;
20124                  }
20125                },
20126                {
20127                  key: 'off',
20128                  value: function off(event, listener) {
20129                    if (!this.observers[event]) return;
20130
20131                    if (!listener) {
20132                      delete this.observers[event];
20133                      return;
20134                    }
20135
20136                    this.observers[event] = this.observers[event].filter(function(l) {
20137                      return l !== listener;
20138                    });
20139                  }
20140                },
20141                {
20142                  key: 'emit',
20143                  value: function emit(event) {
20144                    for (
20145                      var _len = arguments.length,
20146                        args = new Array(_len > 1 ? _len - 1 : 0),
20147                        _key = 1;
20148                      _key < _len;
20149                      _key++
20150                    ) {
20151                      args[_key - 1] = arguments[_key];
20152                    }
20153
20154                    if (this.observers[event]) {
20155                      var cloned = [].concat(this.observers[event]);
20156                      cloned.forEach(function(observer) {
20157                        observer.apply(void 0, args);
20158                      });
20159                    }
20160
20161                    if (this.observers['*']) {
20162                      var _cloned = [].concat(this.observers['*']);
20163
20164                      _cloned.forEach(function(observer) {
20165                        observer.apply(observer, [event].concat(args));
20166                      });
20167                    }
20168                  }
20169                }
20170              ]);
20171
20172              return EventEmitter;
20173            })();
20174
20175          // http://lea.verou.me/2016/12/resolve-promises-externally-with-this-one-weird-trick/
20176          function defer() {
20177            var res;
20178            var rej;
20179            var promise = new Promise(function(resolve, reject) {
20180              res = resolve;
20181              rej = reject;
20182            });
20183            promise.resolve = res;
20184            promise.reject = rej;
20185            return promise;
20186          }
20187          function makeString(object) {
20188            if (object == null) return '';
20189            /* eslint prefer-template: 0 */
20190
20191            return '' + object;
20192          }
20193          function copy(a, s, t) {
20194            a.forEach(function(m) {
20195              if (s[m]) t[m] = s[m];
20196            });
20197          }
20198
20199          function getLastOfPath(object, path, Empty) {
20200            function cleanKey(key) {
20201              return key && key.indexOf('###') > -1 ? key.replace(/###/g, '.') : key;
20202            }
20203
20204            function canNotTraverseDeeper() {
20205              return !object || typeof object === 'string';
20206            }
20207
20208            var stack = typeof path !== 'string' ? [].concat(path) : path.split('.');
20209
20210            while (stack.length > 1) {
20211              if (canNotTraverseDeeper()) return {};
20212              var key = cleanKey(stack.shift());
20213              if (!object[key] && Empty) object[key] = new Empty();
20214              object = object[key];
20215            }
20216
20217            if (canNotTraverseDeeper()) return {};
20218            return {
20219              obj: object,
20220              k: cleanKey(stack.shift())
20221            };
20222          }
20223
20224          function setPath(object, path, newValue) {
20225            var _getLastOfPath = getLastOfPath(object, path, Object),
20226              obj = _getLastOfPath.obj,
20227              k = _getLastOfPath.k;
20228
20229            obj[k] = newValue;
20230          }
20231          function pushPath(object, path, newValue, concat) {
20232            var _getLastOfPath2 = getLastOfPath(object, path, Object),
20233              obj = _getLastOfPath2.obj,
20234              k = _getLastOfPath2.k;
20235
20236            obj[k] = obj[k] || [];
20237            if (concat) obj[k] = obj[k].concat(newValue);
20238            if (!concat) obj[k].push(newValue);
20239          }
20240          function getPath(object, path) {
20241            var _getLastOfPath3 = getLastOfPath(object, path),
20242              obj = _getLastOfPath3.obj,
20243              k = _getLastOfPath3.k;
20244
20245            if (!obj) return undefined;
20246            return obj[k];
20247          }
20248          function getPathWithDefaults(data, defaultData, key) {
20249            var value = getPath(data, key);
20250
20251            if (value !== undefined) {
20252              return value;
20253            } // Fallback to default values
20254
20255            return getPath(defaultData, key);
20256          }
20257          function deepExtend(target, source, overwrite) {
20258            /* eslint no-restricted-syntax: 0 */
20259            for (var prop in source) {
20260              if (prop in target) {
20261                // If we reached a leaf string in target or source then replace with source or skip depen
20261ding on the 'overwrite' switch
20262                if (
20263                  typeof target[prop] === 'string' ||
20264                  target[prop] instanceof String ||
20265                  typeof source[prop] === 'string' ||
20266                  source[prop] instanceof String
20267                ) {
20268                  if (overwrite) target[prop] = source[prop];
20269                } else {
20270                  deepExtend(target[prop], source[prop], overwrite);
20271                }
20272              } else {
20273                target[prop] = source[prop];
20274              }
20275            }
20276
20277            return target;
20278          }
20279          function regexEscape(str) {
20280            /* eslint no-useless-escape: 0 */
20281            return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
20282          }
20283          /* eslint-disable */
20284
20285          var _entityMap = {
20286            '&': '&amp;',
20287            '<': '&lt;',
20288            '>': '&gt;',
20289            '"': '&quot;',
20290            "'": '&#39;',
20291            '/': '&#x2F;'
20292          };
20293          /* eslint-enable */
20294
20295          function escape(data) {
20296            if (typeof data === 'string') {
20297              return data.replace(/[&<>"'\/]/g, function(s) {
20298                return _entityMap[s];
20299              });
20300            }
20301
20302            return data;
20303          }
20304
20305          var ResourceStore =
20306            /*#__PURE__*/
20307            (function(_EventEmitter) {
20308              _inherits(ResourceStore, _EventEmitter);
20309
20310              function ResourceStore(data) {
20311                var _this;
20312
20313                var options =
20314                  arguments.length > 1 && arguments[1] !== undefined
20315                    ? arguments[1]
20316                    : {
20317                        ns: ['translation'],
20318                        defaultNS: 'translation'
20319                      };
20320
20321                _classCallCheck(this, ResourceStore);
20322
20323                _this = _possibleConstructorReturn(
20324                  this,
20325                  _getPrototypeOf(ResourceStore).call(this)
20326                );
20327                EventEmitter.call(_assertThisInitialized(_this)); // <=IE10 fix (unable to call parent constructor)
20328
20329                _this.data = data || {};
20330                _this.options = options;
20331
20332                if (_this.options.keySeparator === undefined) {
20333                  _this.options.keySeparator = '.';
20334                }
20335
20336                return _this;
20337              }
20338
20339              _createClass(ResourceStore, [
20340                {
20341                  key: 'addNamespaces',
20342                  value: function addNamespaces(ns) {
20343                    if (this.options.ns.indexOf(ns) < 0) {
20344                      this.options.ns.push(ns);
20345                    }
20346                  }
20347                },
20348                {
20349                  key: 'removeNamespaces',
20350                  value: function removeNamespaces(ns) {
20351                    var index = this.options.ns.indexOf(ns);
20352
20353                    if (index > -1) {
20354                      this.options.ns.splice(index, 1);
20355                    }
20356                  }
20357                },
20358                {
20359                  key: 'getResource',
20360                  value: function getResource(lng, ns, key) {
20361                    var options =
20362                      arguments.length > 3 && arguments[3] !== undefined
20363                        ? arguments[3]
20364                        : {};
20365                    var keySeparator =
20366                      options.keySeparator !== undefined
20367                        ? options.keySeparator
20368                        : this.options.keySeparator;
20369                    var path = [lng, ns];
20370                    if (key && typeof key !== 'string') path = path.concat(key);
20371                    if (key && typeof key === 'string')
20372                      path = path.concat(keySeparator ? key.split(keySeparator) : key);
20373
20374                    if (lng.indexOf('.') > -1) {
20375                      path = lng.split('.');
20376                    }
20377
20378                    return getPath(this.data, path);
20379                  }
20380                },
20381                {
20382                  key: 'addResource',
20383                  value: function addResource(lng, ns, key, value) {
20384                    var options =
20385                      arguments.length > 4 && arguments[4] !== undefined
20386                        ? arguments[4]
20387                        : {
20388                            silent: false
20389                          };
20390                    var keySeparator = this.options.keySeparator;
20391                    if (keySeparator === undefined) keySeparator = '.';
20392                    var path = [lng, ns];
20393                    if (key)
20394                      path = path.concat(keySeparator ? key.split(keySeparator) : key);
20395
20396                    if (lng.indexOf('.') > -1) {
20397                      path = lng.split('.');
20398                      value = ns;
20399                      ns = path[1];
20400                    }
20401
20402                    this.addNamespaces(ns);
20403                    setPath(this.data, path, value);
vendor: 4,105 bytes, lines 20404-20513
20404                    if (!options.silent) this.emit('added', lng, ns, key, value);
20405                  }
20406                },
20407                {
20408                  key: 'addResources',
20409                  value: function addResources(lng, ns, resources) {
20410                    var options =
20411                      arguments.length > 3 && arguments[3] !== undefined
20412                        ? arguments[3]
20413                        : {
20414                            silent: false
20415                          };
20416
20417                    /* eslint no-restricted-syntax: 0 */
20418                    for (var m in resources) {
20419                      if (
20420                        typeof resources[m] === 'string' ||
20421                        Object.prototype.toString.apply(resources[m]) === '[object Array]'
20422                      )
20423                        this.addResource(lng, ns, m, resources[m], {
20424                          silent: true
20425                        });
20426                    }
20427
20428                    if (!options.silent) this.emit('added', lng, ns, resources);
20429                  }
20430                },
20431                {
20432                  key: 'addResourceBundle',
20433                  value: function addResourceBundle(lng, ns, resources, deep, overwrite) {
20434                    var options =
20435                      arguments.length > 5 && arguments[5] !== undefined
20436                        ? arguments[5]
20437                        : {
20438                            silent: false
20439                          };
20440                    var path = [lng, ns];
20441
20442                    if (lng.indexOf('.') > -1) {
20443                      path = lng.split('.');
20444                      deep = resources;
20445                      resources = ns;
20446                      ns = path[1];
20447                    }
20448
20449                    this.addNamespaces(ns);
20450                    var pack = getPath(this.data, path) || {};
20451
20452                    if (deep) {
20453                      deepExtend(pack, resources, overwrite);
20454                    } else {
20455                      pack = _objectSpread({}, pack, resources);
20456                    }
20457
20458                    setPath(this.data, path, pack);
20459                    if (!options.silent) this.emit('added', lng, ns, resources);
20460                  }
20461                },
20462                {
20463                  key: 'removeResourceBundle',
20464                  value: function removeResourceBundle(lng, ns) {
20465                    if (this.hasResourceBundle(lng, ns)) {
20466                      delete this.data[lng][ns];
20467                    }
20468
20469                    this.removeNamespaces(ns);
20470                    this.emit('removed', lng, ns);
20471                  }
20472                },
20473                {
20474                  key: 'hasResourceBundle',
20475                  value: function hasResourceBundle(lng, ns) {
20476                    return this.getResource(lng, ns) !== undefined;
20477                  }
20478                },
20479                {
20480                  key: 'getResourceBundle',
20481                  value: function getResourceBundle(lng, ns) {
20482                    if (!ns) ns = this.options.defaultNS; // COMPATIBILITY: remove extend in v2.1.0
20483
20484                    if (this.options.compatibilityAPI === 'v1')
20485                      return _objectSpread({}, {}, this.getResource(lng, ns));
20486                    return this.getResource(lng, ns);
20487                  }
20488                },
20489                {
20490                  key: 'getDataByLanguage',
20491                  value: function getDataByLanguage(lng) {
20492                    return this.data[lng];
20493                  }
20494                },
20495                {
20496                  key: 'toJSON',
20497                  value: function toJSON() {
20498                    return this.data;
20499                  }
20500                }
20501              ]);
20502
20503              return ResourceStore;
20504            })(EventEmitter);
20505
20506          var postProcessor = {
20507            processors: {},
20508            addPostProcessor: function addPostProcessor(module) {
20509              this.processors[module.name] = module;
20510            },
20511            handle: function handle(processors, value, key, options, translator) {
20512              var _this = this;
20513
20514              processors.forEach(function(processor) {
20515                if (_this.processors[processor])
20516                  value = _this.processors[processor].process(
20517                    value,
20518                    key,
20519                    options,
20520                    translator
20521                  );
20522              });
20523              return value;
20524            }
20525          };
20526
20527          var checkedLoadedFor = {};
20528
20529          var Translator =
20530            /*#__PURE__*/
20531            (function(_EventEmitter) {
20532              _inherits(Translator, _EventEmitter);
20533
20534              function Translator(services) {
20535                var _this;
20536
20537                var options =
20538                  arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
20539
20540                _classCallCheck(this, Translator);
20541
20542                _this = _possibleConstructorReturn(
20543                  this,
20544                  _getPrototypeOf(Translator).call(this)
20545                );
20546                EventEmitter.call(_assertThisInitialized(_this)); // <=IE10 fix (unable to call parent constructor)
20547
20548                copy(
20549                  [
20550                    'resourceStore',
20551                    'languageUtils',
20552                    'pluralResolver',
20553                    'interpolator',
20554                    'backendConnector',
20555                    'i18nFormat',
20556                    'utils'
20557                  ],
20558                  services,
20559                  _assertThisInitialized(_this)
20560                );
20561                _this.options = options;
20562
20563                if (_this.options.keySeparator === undefined) {
20564                  _this.options.keySeparator = '.';
20565                }
20566
20567                _this.logger = baseLogger.create('translator');
20568                return _this;
20569              }
20570
20571              _createClass(Translator, [
20572                {
20573                  key: 'changeLanguage',
20574                  value: function changeLanguage(lng) {
20575                    if (lng) this.language = lng;
20576                  }
20577                },
20578                {
20579                  key: 'exists',
20580                  value: function exists(key) {
20581                    var options =
20582                      arguments.length > 1 && arguments[1] !== undefined
20583                        ? arguments[1]
20584                        : {
20585                            interpolation: {}
20586                          };
20587                    var resolved = this.resolve(key, options);
20588                    return resolved && resolved.res !== undefined;
20589                  }
20590                },
20591                {
20592                  key: 'extractFromKey',
20593                  value: function extractFromKey(key, options) {
20594                    var nsSeparator = options.nsSeparator || this.options.nsSeparator;
20595                    if (nsSeparator === undefined) nsSeparator = ':';
20596                    var keySeparator =
20597                      options.keySeparator !== undefined
20598                        ? options.keySeparator
20599                        : this.options.keySeparator;
20600                    var namespaces = options.ns || this.options.defaultNS;
20601
20602                    if (nsSeparator && key.indexOf(nsSeparator) > -1) {
20603                      var parts = key.split(nsSeparator);
20604                      if (
20605                        nsSeparator !== keySeparator ||
20606                        (nsSeparator === keySeparator &&
20607                          this.options.ns.indexOf(parts[0]) > -1)
20608                      )
20609                        namespaces = parts.shift();
20610                      key = parts.join(keySeparator);
20611                    }
20612
20613                    if (typeof namespaces === 'string') namespaces = [namespaces];
20614                    return {
20615                      key: key,
20616                      namespaces: namespaces
20617                    };
20618                  }
20619                },
20620                {
20621                  key: 'translate',
20622                  value: function translate(keys, options) {
20623                    var _this2 = this;
20624
20625                    if (
20626                      _typeof(options) !== 'object' &&
20627                      this.options.overloadTranslationOptionHandler
20628                    ) {
20629                      /* eslint prefer-rest-params: 0 */
20630                      options = this.options.overloadTranslationOptionHandler(arguments);
20631                    }
20632
20633                    if (!options) options = {}; // non valid keys handling
20634
20635                    if (
20636                      keys === undefined ||
20637                      keys === null
20638                      /* || keys === ''*/
20639                    )
20640                      return '';
20641                    if (!Array.isArray(keys)) keys = [String(keys)]; // separators
20642
20643                    var keySeparator =
20644                      options.keySeparator !== undefined
20645                        ? options.keySeparator
20646                        : this.options.keySeparator; // get namespace(s)
20647
20648                    var _this$extractFromKey = this.extractFromKey(
20649                        keys[keys.length - 1],
20650                        options
20651                      ),
20652                      key = _this$extractFromKey.key,
20653                      namespaces = _this$extractFromKey.namespaces;
20654
20655                    var namespace = namespaces[namespaces.length - 1]; // return key on CIMode
20656
20657                    var lng = options.lng || this.language;
20658                    var appendNamespaceToCIMode =
20659                      options.appendNamespaceToCIMode ||
20660                      this.options.appendNamespaceToCIMode;
20661
20662                    if (lng && lng.toLowerCase() === 'cimode') {
20663                      if (appendNamespaceToCIMode) {
20664                        var nsSeparator = options.nsSeparator || this.options.nsSeparator;
20665                        return namespace + nsSeparator + key;
20666                      }
20667
20668                      return key;
20669                    } // resolve from store
20670
20671                    var resolved = this.resolve(keys, options);
20672                    var res = resolved && resolved.res;
20673                    var resUsedKey = (resolved && resolved.usedKey) || key;
20674                    var resExactUsedKey = (resolved && resolved.exactUsedKey) || key;
20675                    var resType = Object.prototype.toString.apply(res);
20676                    var noObject = [
20677                      '[object Number]',
20678                      '[object Function]',
20679                      '[object RegExp]'
20680                    ];
20681                    var joinArrays =
20682                      options.joinArrays !== undefined
20683                        ? options.joinArrays
20684                        : this.options.joinArrays; // object
20685
20686                    var handleAsObjectInI18nFormat =
20687                      !this.i18nFormat || this.i18nFormat.handleAsObject;
20688                    var handleAsObject =
20689                      typeof res !== 'string' &&
20690                      typeof res !== 'boolean' &&
20691                      typeof res !== 'number';
20692
20693                    if (
20694                      handleAsObjectInI18nFormat &&
20695                      res &&
20696                      handleAsObject &&
20697                      noObject.indexOf(resType) < 0 &&
20698                      !(typeof joinArrays === 'string' && resType === '[object Array]')
20699                    ) {
20700                      if (!options.returnObjects && !this.options.returnObjects) {
20701                        this.logger.warn(
20702                          'accessing an object - but returnObjects options is not enabled!'
20703                        );
20704                        return this.options.returnedObjectHandler
20705                          ? this.options.returnedObjectHandler(resUsedKey, res, options)
20706                          : "key '"
20707                              .concat(key, ' (')
20708                              .concat(
20709                                this.language,
20710                                ")' returned an object instead of string."
20711                              );
20712                      } // if we got a separator we loop over children - else we just return object as is
20713                      // as having it set to false means no hierarchy so no lookup for nested values
20714
20715                      if (keySeparator) {
20716                        var resTypeIsArray = resType === '[object Array]';
20717                        var copy$$1 = resTypeIsArray ? [] : {}; // apply child translation on a copy
20718
20719                        /* eslint no-restricted-syntax: 0 */
20720
20721                        var newKeyToUse = resTypeIsArray ? resExactUsedKey : resUsedKey;
20722
20723                        for (var m in res) {
20724                          if (Object.prototype.hasOwnProperty.call(res, m)) {
20725                            var deepKey = ''
20726                              .concat(newKeyToUse)
20727                              .concat(keySeparator)
20728                              .concat(m);
20729                            copy$$1[m] = this.translate(
20730                              deepKey,
20731                              _objectSpread({}, options, {
20732                                joinArrays: false,
20733                                ns: namespaces
20734                              })
20735                            );
20736                            if (copy$$1[m] === deepKey) copy$$1[m] = res[m]; // if nothing found use orginal value as fallback
20737                          }
20738                        }
20739
20740                        res = copy$$1;
20741                      }
20742                    } else if (
20743                      handleAsObjectInI18nFormat &&
20744                      typeof joinArrays === 'string' &&
20745                      resType === '[object Array]'
20746                    ) {
20747                      // array special treatment
20748                      res = res.join(joinArrays);
20749                      if (res) res = this.extendTranslation(res, keys, options);
20750                    } else {
20751                      // string, empty or null
20752                      var usedDefault = false;
20753                      var usedKey = false; // fallback value
20754
20755                      if (!this.isValidLookup(res) && options.defaultValue !== undefined) {
20756                        usedDefault = true;
20757
20758                        if (options.count !== undefined) {
20759                          var suffix = this.pluralResolver.getSuffix(lng, options.count);
20760                          res = options['defaultValue'.concat(suffix)];
20761                        }
20762
20763                        if (!res) res = options.defaultValue;
20764                      }
20765
20766                      if (!this.isValidLookup(res)) {
20767                        usedKey = true;
20768                        res = key;
20769                      } // save missing
20770
20771                      var updateMissing =
20772                        options.defaultValue &&
20773                        options.defaultValue !== res &&
20774                        this.options.updateMissing;
20775
20776                      if (usedKey || usedDefault || updateMissing) {
20777                        this.logger.log(
20778                          updateMissing ? 'updateKey' : 'missingKey',
20779                          lng,
20780                          namespace,
20781                          key,
20782                          updateMissing ? options.defaultValue : res
20783                        );
20784                        var lngs = [];
20785                        var fallbackLngs = this.languageUtils.getFallbackCodes(
20786                          this.options.fallbackLng,
20787                          options.lng || this.language
20788                        );
20789
20790                        if (
20791                          this.options.saveMissingTo === 'fallback' &&
20792                          fallbackLngs &&
20793                          fallbackLngs[0]
20794                        ) {
20795                          for (var i = 0; i < fallbackLngs.length; i++) {
20796                            lngs.push(fallbackLngs[i]);
20797                          }
20798                        } else if (this.options.saveMissingTo === 'all') {
20799                          lngs = this.languageUtils.toResolveHierarchy(
20800                            options.lng || this.language
20801                          );
20802                        } else {
20803                          lngs.push(options.lng || this.language);
20804                        }
20805
20806                        var send = function send(l, k) {
20807                          if (_this2.options.missingKeyHandler) {
20808                            _this2.options.missingKeyHandler(
20809                              l,
20810                              namespace,
20811                              k,
20812                              updateMissing ? options.defaultValue : res,
20813                              updateMissing,
20814                              options
20815                            );
20816                          } else if (
20817                            _this2.backendConnector &&
20818                            _this2.backendConnector.saveMissing
20819                          ) {
20820                            _this2.backendConnector.saveMissing(
20821                              l,
20822                              namespace,
20823                              k,
20824                              updateMissing ? options.defaultValue : res,
20825                              updateMissing,
20826                              options
20827                            );
20828                          }
20829
20830                          _this2.emit('missingKey', l, namespace, k, res);
20831                        };
20832
20833                        if (this.options.saveMissing) {
20834                          var needsPluralHandling =
20835                            options.count !== undefined &&
20836                            typeof options.count !== 'string';
20837
20838                          if (this.options.saveMissingPlurals && needsPluralHandling) {
20839                            lngs.forEach(function(l) {
20840                              var plurals = _this2.pluralResolver.getPluralFormsOfKey(
20841                                l,
20842                                key
20843                              );
20844
20845                              plurals.forEach(function(p) {
20846                                return send([l], p);
20847                              });
20848                            });
20849                          } else {
20850                            send(lngs, key);
20851                          }
20852                        }
20853                      } // extend
20854
20855                      res = this.extendTranslation(res, keys, options, resolved); // append namespace if still key
20856
20857                      if (
20858                        usedKey &&
20859                        res === key &&
20860                        this.options.appendNamespaceToMissingKey
20861                      )
20862                        res = ''.concat(namespace, ':').concat(key); // parseMissingKeyHandler
20863
20864                      if (usedKey && this.options.parseMissingKeyHandler)
20865                        res = this.options.parseMissingKeyHandler(res);
20866                    } // return
20867
20868                    return res;
20869                  }
20870                },
20871                {
20872                  key: 'extendTranslation',
20873                  value: function extendTranslation(res, key, options, resolved) {
20874                    var _this3 = this;
20875
20876                    if (this.i18nFormat && this.i18nFormat.parse) {
20877                      res = this.i18nFormat.parse(
20878                        res,
20879                        options,
20880                        resolved.usedLng,
20881                        resolved.usedNS,
20882                        resolved.usedKey,
20883                        {
20884                          resolved: resolved
20885                        }
20886                      );
20887                    } else if (!options.skipInterpolation) {
20888                      // i18next.parsing
20889                      if (options.interpolation)
20890                        this.interpolator.init(
20891                          _objectSpread({}, options, {
20892                            interpolation: _objectSpread(
20893                              {},
20894                              this.options.interpolation,
20895                              options.interpolation
20896                            )
20897                          })
20898                        ); // interpolate
20899
20900                      var data =
20901                        options.replace && typeof options.replace !== 'string'
20902                          ? options.replace
20903                          : options;
20904                      if (this.options.interpolation.defaultVariables)
20905                        data = _objectSpread(
20906                          {},
20907                          this.options.interpolation.defaultVariables,
20908                          data
20909                        );
20910                      res = this.interpolator.interpolate(
20911                        res,
20912                        data,
20913                        options.lng || this.language,
20914                        options
20915                      ); // nesting
20916
20917                      if (options.nest !== false)
20918                        res = this.interpolator.nest(
20919                          res,
20920                          function() {
20921                            return _this3.translate.apply(_this3, arguments);
20922                          },
20923                          options
20924                        );
20925                      if (options.interpolation) this.interpolator.reset();
20926                    } // post process
20927
20928                    var postProcess = options.postProcess || this.options.postProcess;
20929                    var postProcessorNames =
20930                      typeof postProcess === 'string' ? [postProcess] : postProcess;
20931
20932                    if (
20933                      res !== undefined &&
20934                      res !== null &&
20935                      postProcessorNames &&
20936                      postProcessorNames.length &&
20937                      options.applyPostProcessor !== false
20938                    ) {
20939                      res = postProcessor.handle(
20940                        postProcessorNames,
20941                        res,
20942                        key,
20943                        this.options && this.options.postProcessPassResolved
20944                          ? _objectSpread(
20945                              {
20946                                i18nResolved: resolved
20947                              },
20948                              options
20949                            )
20950                          : options,
20951                        this
20952                      );
20953                    }
20954
20955                    return res;
20956                  }
20957                },
20958                {
20959                  key: 'resolve',
20960                  value: function resolve(keys) {
20961                    var _this4 = this;
20962
20963                    var options =
20964                      arguments.length > 1 && arguments[1] !== undefined
20965                        ? arguments[1]
20966                        : {};
20967                    var found;
20968                    var usedKey; // plain key
20969
20970                    var exactUsedKey; // key with context / plural
20971
20972                    var usedLng;
20973                    var usedNS;
20974                    if (typeof keys === 'string') keys = [keys]; // forEach possible key
20975
20976                    keys.forEach(function(k) {
20977                      if (_this4.isValidLookup(found)) return;
20978
20979                      var extracted = _this4.extractFromKey(k, options);
20980
20981                      var key = extracted.key;
20982                      usedKey = key;
20983                      var namespaces = extracted.namespaces;
20984                      if (_this4.options.fallbackNS)
20985                        namespaces = namespaces.concat(_this4.options.fallbackNS);
20986                      var needsPluralHandling =
20987                        options.count !== undefined && typeof options.count !== 'string';
20988                      var needsContextHandling =
20989                        options.context !== undefined &&
20990                        typeof options.context === 'string' &&
20991                        options.context !== '';
20992                      var codes = options.lngs
20993                        ? options.lngs
20994                        : _this4.languageUtils.toResolveHierarchy(
20995                            options.lng || _this4.language,
20996                            options.fallbackLng
20997                          );
20998                      namespaces.forEach(function(ns) {
20999                        if (_this4.isValidLookup(found)) return;
21000                        usedNS = ns;
21001
21002                        if (
21003                          !checkedLoadedFor[''.concat(codes[0], '-').concat(ns)] &&
21004                          _this4.utils &&
21005                          _this4.utils.hasLoadedNamespace &&
21006                          !_this4.utils.hasLoadedNamespace(usedNS)
21007                        ) {
21008                          checkedLoadedFor[''.concat(codes[0], '-').concat(ns)] = true;
21009
21010                          _this4.logger.warn(
21011                            'key "'
21012                              .concat(usedKey, '" for namespace "')
21013                              .concat(usedNS, '" for languages "')
21014                              .concat(
21015                                codes.join(', '),
21016                                '" won\'t get resolved as namespace was not yet loaded'
21017                              ),
21018                            'This means something IS WRONG in your application setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!'
21019                          );
21020                        }
21021
21022                        codes.forEach(function(code) {
21023                          if (_this4.isValidLookup(found)) return;
21024                          usedLng = code;
21025                          var finalKey = key;
21026                          var finalKeys = [finalKey];
21027
21028                          if (_this4.i18nFormat && _this4.i18nFormat.addLookupKeys) {
21029                            _this4.i18nFormat.addLookupKeys(
21030                              finalKeys,
21031                              key,
21032                              code,
21033                              ns,
21034                              options
21035                            );
21036                          } else {
21037                            var pluralSuffix;
21038                            if (needsPluralHandling)
21039                              pluralSuffix = _this4.pluralResolver.getSuffix(
21040                                code,
21041                                options.count
21042                              ); // fallback for plural if context not found
21043
21044                            if (needsPluralHandling && needsContextHandling)
21045                              finalKeys.push(finalKey + pluralSuffix); // get key for context if needed
21046
21047                            if (needsContextHandling)
21048                              finalKeys.push(
21049                                (finalKey += ''
21050                                  .concat(_this4.options.contextSeparator)
21051                                  .concat(options.context))
21052                              ); // get key for plural if needed
21053
21054                            if (needsPluralHandling)
21055                              finalKeys.push((finalKey += pluralSuffix));
21056                          } // iterate over finalKeys starting with most specific pluralkey (-> contextkey only) -> singularkey only
21057
21058                          var possibleKey;
21059                          /* eslint no-cond-assign: 0 */
21060
21061                          while ((possibleKey = finalKeys.pop())) {
21062                            if (!_this4.isValidLookup(found)) {
21063                              exactUsedKey = possibleKey;
21064                              found = _this4.getResource(code, ns, possibleKey, options);
21065                            }
21066                          }
21067                        });
21068                      });
21069                    });
21070                    return {
21071                      res: found,
21072                      usedKey: usedKey,
21073                      exactUsedKey: exactUsedKey,
21074                      usedLng: usedLng,
21075                      usedNS: usedNS
21076                    };
21077                  }
21078                },
21079                {
21080                  key: 'isValidLookup',
21081                  value: function isValidLookup(res) {
21082                    return (
21083                      res !== undefined &&
21084                      !(!this.options.returnNull && res === null) &&
21085                      !(!this.options.returnEmptyString && res === '')
21086                    );
21087                  }
21088                },
21089                {
21090                  key: 'getResource',
21091                  value: function getResource(code, ns, key) {
21092                    var options =
21093                      arguments.length > 3 && arguments[3] !== undefined
21094                        ? arguments[3]
21095                        : {};
21096                    if (this.i18nFormat && this.i18nFormat.getResource)
21097                      return this.i18nFormat.getResource(code, ns, key, options);
21098                    return this.resourceStore.getResource(code, ns, key, options);
21099                  }
21100                }
21101              ]);
21102
21103              return Translator;
21104            })(EventEmitter);
21105
21106          function capitalize(string) {
21107            return string.charAt(0).toUpperCase() + string.slice(1);
21108          }
21109
21110          var LanguageUtil =
21111            /*#__PURE__*/
21112            (function() {
21113              function LanguageUtil(options) {
21114                _classCallCheck(this, LanguageUtil);
21115
21116                this.options = options;
21117                this.whitelist = this.options.whitelist || false;
vendor: 10,268 bytes, lines 21118-21450
21118                this.logger = baseLogger.create('languageUtils');
21119              }
21120
21121              _createClass(LanguageUtil, [
21122                {
21123                  key: 'getScriptPartFromCode',
21124                  value: function getScriptPartFromCode(code) {
21125                    if (!code || code.indexOf('-') < 0) return null;
21126                    var p = code.split('-');
21127                    if (p.length === 2) return null;
21128                    p.pop();
21129                    return this.formatLanguageCode(p.join('-'));
21130                  }
21131                },
21132                {
21133                  key: 'getLanguagePartFromCode',
21134                  value: function getLanguagePartFromCode(code) {
21135                    if (!code || code.indexOf('-') < 0) return code;
21136                    var p = code.split('-');
21137                    return this.formatLanguageCode(p[0]);
21138                  }
21139                },
21140                {
21141                  key: 'formatLanguageCode',
21142                  value: function formatLanguageCode(code) {
21143                    // http://www.iana.org/assignments/language-tags/language-tags.xhtml
21144                    if (typeof code === 'string' && code.indexOf('-') > -1) {
21145                      var specialCases = [
21146                        'hans',
21147                        'hant',
21148                        'latn',
21149                        'cyrl',
21150                        'cans',
21151                        'mong',
21152                        'arab'
21153                      ];
21154                      var p = code.split('-');
21155
21156                      if (this.options.lowerCaseLng) {
21157                        p = p.map(function(part) {
21158                          return part.toLowerCase();
21159                        });
21160                      } else if (p.length === 2) {
21161                        p[0] = p[0].toLowerCase();
21162                        p[1] = p[1].toUpperCase();
21163                        if (specialCases.indexOf(p[1].toLowerCase()) > -1)
21164                          p[1] = capitalize(p[1].toLowerCase());
21165                      } else if (p.length === 3) {
21166                        p[0] = p[0].toLowerCase(); // if lenght 2 guess it's a country
21167
21168                        if (p[1].length === 2) p[1] = p[1].toUpperCase();
21169                        if (p[0] !== 'sgn' && p[2].length === 2) p[2] = p[2].toUpperCase();
21170                        if (specialCases.indexOf(p[1].toLowerCase()) > -1)
21171                          p[1] = capitalize(p[1].toLowerCase());
21172                        if (specialCases.indexOf(p[2].toLowerCase()) > -1)
21173                          p[2] = capitalize(p[2].toLowerCase());
21174                      }
21175
21176                      return p.join('-');
21177                    }
21178
21179                    return this.options.cleanCode || this.options.lowerCaseLng
21180                      ? code.toLowerCase()
21181                      : code;
21182                  }
21183                },
21184                {
21185                  key: 'isWhitelisted',
21186                  value: function isWhitelisted(code) {
21187                    if (
21188                      this.options.load === 'languageOnly' ||
21189                      this.options.nonExplicitWhitelist
21190                    ) {
21191                      code = this.getLanguagePartFromCode(code);
21192                    }
21193
21194                    return (
21195                      !this.whitelist ||
21196                      !this.whitelist.length ||
21197                      this.whitelist.indexOf(code) > -1
21198                    );
21199                  }
21200                },
21201                {
21202                  key: 'getFallbackCodes',
21203                  value: function getFallbackCodes(fallbacks, code) {
21204                    if (!fallbacks) return [];
21205                    if (typeof fallbacks === 'string') fallbacks = [fallbacks];
21206                    if (Object.prototype.toString.apply(fallbacks) === '[object Array]')
21207                      return fallbacks;
21208                    if (!code) return fallbacks['default'] || []; // asume we have an object defining fallbacks
21209
21210                    var found = fallbacks[code];
21211                    if (!found) found = fallbacks[this.getScriptPartFromCode(code)];
21212                    if (!found) found = fallbacks[this.formatLanguageCode(code)];
21213                    if (!found) found = fallbacks['default'];
21214                    return found || [];
21215                  }
21216                },
21217                {
21218                  key: 'toResolveHierarchy',
21219                  value: function toResolveHierarchy(code, fallbackCode) {
21220                    var _this = this;
21221
21222                    var fallbackCodes = this.getFallbackCodes(
21223                      fallbackCode || this.options.fallbackLng || [],
21224                      code
21225                    );
21226                    var codes = [];
21227
21228                    var addCode = function addCode(c) {
21229                      if (!c) return;
21230
21231                      if (_this.isWhitelisted(c)) {
21232                        codes.push(c);
21233                      } else {
21234                        _this.logger.warn(
21235                          'rejecting non-whitelisted language code: '.concat(c)
21236                        );
21237                      }
21238                    };
21239
21240                    if (typeof code === 'string' && code.indexOf('-') > -1) {
21241                      if (this.options.load !== 'languageOnly')
21242                        addCode(this.formatLanguageCode(code));
21243                      if (
21244                        this.options.load !== 'languageOnly' &&
21245                        this.options.load !== 'currentOnly'
21246                      )
21247                        addCode(this.getScriptPartFromCode(code));
21248                      if (this.options.load !== 'currentOnly')
21249                        addCode(this.getLanguagePartFromCode(code));
21250                    } else if (typeof code === 'string') {
21251                      addCode(this.formatLanguageCode(code));
21252                    }
21253
21254                    fallbackCodes.forEach(function(fc) {
21255                      if (codes.indexOf(fc) < 0) addCode(_this.formatLanguageCode(fc));
21256                    });
21257                    return codes;
21258                  }
21259                }
21260              ]);
21261
21262              return LanguageUtil;
21263            })();
21264
21265          /* eslint-disable */
21266
21267          var sets = [
21268            {
21269              lngs: [
21270                'ach',
21271                'ak',
21272                'am',
21273                'arn',
21274                'br',
21275                'fil',
21276                'gun',
21277                'ln',
21278                'mfe',
21279                'mg',
21280                'mi',
21281                'oc',
21282                'pt',
21283                'pt-BR',
21284                'tg',
21285                'ti',
21286                'tr',
21287                'uz',
21288                'wa'
21289              ],
21290              nr: [1, 2],
21291              fc: 1
21292            },
21293            {
21294              lngs: [
21295                'af',
21296                'an',
21297                'ast',
21298                'az',
21299                'bg',
21300                'bn',
21301                'ca',
21302                'da',
21303                'de',
21304                'dev',
21305                'el',
21306                'en',
21307                'eo',
21308                'es',
21309                'et',
21310                'eu',
21311                'fi',
21312                'fo',
21313                'fur',
21314                'fy',
21315                'gl',
21316                'gu',
21317                'ha',
21318                'hi',
21319                'hu',
21320                'hy',
21321                'ia',
21322                'it',
21323                'kn',
21324                'ku',
21325                'lb',
21326                'mai',
21327                'ml',
21328                'mn',
21329                'mr',
21330                'nah',
21331                'nap',
21332                'nb',
21333                'ne',
21334                'nl',
21335                'nn',
21336                'no',
21337                'nso',
21338                'pa',
21339                'pap',
21340                'pms',
21341                'ps',
21342                'pt-PT',
21343                'rm',
21344                'sco',
21345                'se',
21346                'si',
21347                'so',
21348                'son',
21349                'sq',
21350                'sv',
21351                'sw',
21352                'ta',
21353                'te',
21354                'tk',
21355                'ur',
21356                'yo'
21357              ],
21358              nr: [1, 2],
21359              fc: 2
21360            },
21361            {
21362              lngs: [
21363                'ay',
21364                'bo',
21365                'cgg',
21366                'fa',
21367                'id',
21368                'ja',
21369                'jbo',
21370                'ka',
21371                'kk',
21372                'km',
21373                'ko',
21374                'ky',
21375                'lo',
21376                'ms',
21377                'sah',
21378                'su',
21379                'th',
21380                'tt',
21381                'ug',
21382                'vi',
21383                'wo',
21384                'zh'
21385              ],
21386              nr: [1],
21387              fc: 3
21388            },
21389            {
21390              lngs: ['be', 'bs', 'cnr', 'dz', 'hr', 'ru', 'sr', 'uk'],
21391              nr: [1, 2, 5],
21392              fc: 4
21393            },
21394            {
21395              lngs: ['ar'],
21396              nr: [0, 1, 2, 3, 11, 100],
21397              fc: 5
21398            },
21399            {
21400              lngs: ['cs', 'sk'],
21401              nr: [1, 2, 5],
21402              fc: 6
21403            },
21404            {
21405              lngs: ['csb', 'pl'],
21406              nr: [1, 2, 5],
21407              fc: 7
21408            },
21409            {
21410              lngs: ['cy'],
21411              nr: [1, 2, 3, 8],
21412              fc: 8
21413            },
21414            {
21415              lngs: ['fr'],
21416              nr: [1, 2],
21417              fc: 9
21418            },
21419            {
21420              lngs: ['ga'],
21421              nr: [1, 2, 3, 7, 11],
21422              fc: 10
21423            },
21424            {
21425              lngs: ['gd'],
21426              nr: [1, 2, 3, 20],
21427              fc: 11
21428            },
21429            {
21430              lngs: ['is'],
21431              nr: [1, 2],
21432              fc: 12
21433            },
21434            {
21435              lngs: ['jv'],
21436              nr: [0, 1],
21437              fc: 13
21438            },
21439            {
21440              lngs: ['kw'],
21441              nr: [1, 2, 3, 4],
21442              fc: 14
21443            },
21444            {
21445              lngs: ['lt'],
21446              nr: [1, 2, 10],
21447              fc: 15
21448            },
21449            {
21450              lngs: ['lv'],
vendor: 4,273 bytes, lines 21451-21591
21451              nr: [1, 2, 0],
21452              fc: 16
21453            },
21454            {
21455              lngs: ['mk'],
21456              nr: [1, 2],
21457              fc: 17
21458            },
21459            {
21460              lngs: ['mnk'],
21461              nr: [0, 1, 2],
21462              fc: 18
21463            },
21464            {
21465              lngs: ['mt'],
21466              nr: [1, 2, 11, 20],
21467              fc: 19
21468            },
21469            {
21470              lngs: ['or'],
21471              nr: [2, 1],
21472              fc: 2
21473            },
21474            {
21475              lngs: ['ro'],
21476              nr: [1, 2, 20],
21477              fc: 20
21478            },
21479            {
21480              lngs: ['sl'],
21481              nr: [5, 1, 2, 3],
21482              fc: 21
21483            },
21484            {
21485              lngs: ['he'],
21486              nr: [1, 2, 20, 21],
21487              fc: 22
21488            }
21489          ];
21490          var _rulesPluralsTypes = {
21491            1: function _(n) {
21492              return Number(n > 1);
21493            },
21494            2: function _(n) {
21495              return Number(n != 1);
21496            },
21497            3: function _(n) {
21498              return 0;
21499            },
21500            4: function _(n) {
21501              return Number(
21502                n % 10 == 1 && n % 100 != 11
21503                  ? 0
21504                  : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2
21505              );
21506            },
21507            5: function _(n) {
21508              return Number(
21509                n === 0
21510                  ? 0
21511                  : n == 1
21512                    ? 1
21513                    : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5
21514              );
21515            },
21516            6: function _(n) {
21517              return Number(n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2);
21518            },
21519            7: function _(n) {
21520              return Number(
21521                n == 1
21522                  ? 0
21523                  : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2
21524              );
21525            },
21526            8: function _(n) {
21527              return Number(n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3);
21528            },
21529            9: function _(n) {
21530              return Number(n >= 2);
21531            },
21532            10: function _(n) {
21533              return Number(n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4);
21534            },
21535            11: function _(n) {
21536              return Number(
21537                n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3
21538              );
21539            },
21540            12: function _(n) {
21541              return Number(n % 10 != 1 || n % 100 == 11);
21542            },
21543            13: function _(n) {
21544              return Number(n !== 0);
21545            },
21546            14: function _(n) {
21547              return Number(n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3);
21548            },
21549            15: function _(n) {
21550              return Number(
21551                n % 10 == 1 && n % 100 != 11
21552                  ? 0
21553                  : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2
21554              );
21555            },
21556            16: function _(n) {
21557              return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n !== 0 ? 1 : 2);
21558            },
21559            17: function _(n) {
21560              return Number(n == 1 || n % 10 == 1 ? 0 : 1);
21561            },
21562            18: function _(n) {
21563              return Number(n == 0 ? 0 : n == 1 ? 1 : 2);
21564            },
21565            19: function _(n) {
21566              return Number(
21567                n == 1
21568                  ? 0
21569                  : n === 0 || (n % 100 > 1 && n % 100 < 11)
21570                    ? 1
21571                    : n % 100 > 10 && n % 100 < 20 ? 2 : 3
21572              );
21573            },
21574            20: function _(n) {
21575              return Number(n == 1 ? 0 : n === 0 || (n % 100 > 0 && n % 100 < 20) ? 1 : 2);
21576            },
21577            21: function _(n) {
21578              return Number(
21579                n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0
21580              );
21581            },
21582            22: function _(n) {
21583              return Number(
21584                n === 1 ? 0 : n === 2 ? 1 : (n < 0 || n > 10) && n % 10 == 0 ? 2 : 3
21585              );
21586            }
21587          };
21588          /* eslint-enable */
21589
21590          function createRules() {
21591            var rules = {};
21592            sets.forEach(function(set) {
21593              set.lngs.forEach(function(l) {
21594                rules[l] = {
21595                  numbers: set.nr,
21596                  plurals: _rulesPluralsTypes[set.fc]
21597                };
21598              });
21599            });
21600            return rules;
21601          }
21602
21603          var PluralResolver =
21604            /*#__PURE__*/
21605            (function() {
21606              function PluralResolver(languageUtils) {
21607                var options =
21608                  arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
21609
21610                _classCallCheck(this, PluralResolver);
21611
21612                this.languageUtils = languageUtils;
21613                this.options = options;
21614                this.logger = baseLogger.create('pluralResolver');
21615                this.rules = createRules();
21616              }
21617
21618              _createClass(PluralResolver, [
21619                {
21620                  key: 'addRule',
21621                  value: function addRule(lng, obj) {
21622                    this.rules[lng] = obj;
21623                  }
21624                },
21625                {
21626                  key: 'getRule',
21627                  value: function getRule(code) {
21628                    return (
21629                      this.rules[code] ||
21630                      this.rules[this.languageUtils.getLanguagePartFromCode(code)]
21631                    );
21632                  }
21633                },
21634                {
21635                  key: 'needsPlural',
21636                  value: function needsPlural(code) {
21637                    var rule = this.getRule(code);
21638                    return rule && rule.numbers.length > 1;
21639                  }
21640                },
21641                {
21642                  key: 'getPluralFormsOfKey',
21643                  value: function getPluralFormsOfKey(code, key) {
21644                    var _this = this;
21645
21646                    var ret = [];
21647                    var rule = this.getRule(code);
21648                    if (!rule) return ret;
21649                    rule.numbers.forEach(function(n) {
21650                      var suffix = _this.getSuffix(code, n);
21651
21652                      ret.push(''.concat(key).concat(suffix));
21653                    });
21654                    return ret;
21655                  }
21656                },
21657                {
21658                  key: 'getSuffix',
21659                  value: function getSuffix(code, count) {
21660                    var _this2 = this;
21661
21662                    var rule = this.getRule(code);
21663
21664                    if (rule) {
21665                      // if (rule.numbers.length === 1) return ''; // only singular
21666                      var idx = rule.noAbs
21667                        ? rule.plurals(count)
21668                        : rule.plurals(Math.abs(count));
21669                      var suffix = rule.numbers[idx]; // special treatment for lngs only having singular and plural
21670
21671                      if (
21672                        this.options.simplifyPluralSuffix &&
21673                        rule.numbers.length === 2 &&
21674                        rule.numbers[0] === 1
21675                      ) {
21676                        if (suffix === 2) {
21677                          suffix = 'plural';
21678                        } else if (suffix === 1) {
21679                          suffix = '';
21680                        }
21681                      }
21682
21683                      var returnSuffix = function returnSuffix() {
21684                        return _this2.options.prepend && suffix.toString()
21685                          ? _this2.options.prepend + suffix.toString()
21686                          : suffix.toString();
21687                      }; // COMPATIBILITY JSON
21688                      // v1
21689
21690                      if (this.options.compatibilityJSON === 'v1') {
21691                        if (suffix === 1) return '';
21692                        if (typeof suffix === 'number')
21693                          return '_plural_'.concat(suffix.toString());
21694                        return returnSuffix();
21695                      } else if (
21696                        /* v2 */
21697                        this.options.compatibilityJSON === 'v2'
21698                      ) {
21699                        return returnSuffix();
21700                      } else if (
21701                        /* v3 - gettext index */
21702                        this.options.simplifyPluralSuffix &&
21703                        rule.numbers.length === 2 &&
vendor: 4,196 bytes, lines 21704-21806
21704                        rule.numbers[0] === 1
21705                      ) {
21706                        return returnSuffix();
21707                      }
21708
21709                      return this.options.prepend && idx.toString()
21710                        ? this.options.prepend + idx.toString()
21711                        : idx.toString();
21712                    }
21713
21714                    this.logger.warn('no plural rule found for: '.concat(code));
21715                    return '';
21716                  }
21717                }
21718              ]);
21719
21720              return PluralResolver;
21721            })();
21722
21723          var Interpolator =
21724            /*#__PURE__*/
21725            (function() {
21726              function Interpolator() {
21727                var options =
21728                  arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
21729
21730                _classCallCheck(this, Interpolator);
21731
21732                this.logger = baseLogger.create('interpolator');
21733                this.options = options;
21734
21735                this.format =
21736                  (options.interpolation && options.interpolation.format) ||
21737                  function(value) {
21738                    return value;
21739                  };
21740
21741                this.init(options);
21742              }
21743              /* eslint no-param-reassign: 0 */
21744
21745              _createClass(Interpolator, [
21746                {
21747                  key: 'init',
21748                  value: function init() {
21749                    var options =
21750                      arguments.length > 0 && arguments[0] !== undefined
21751                        ? arguments[0]
21752                        : {};
21753                    if (!options.interpolation)
21754                      options.interpolation = {
21755                        escapeValue: true
21756                      };
21757                    var iOpts = options.interpolation;
21758                    this.escape = iOpts.escape !== undefined ? iOpts.escape : escape;
21759                    this.escapeValue =
21760                      iOpts.escapeValue !== undefined ? iOpts.escapeValue : true;
21761                    this.useRawValueToEscape =
21762                      iOpts.useRawValueToEscape !== undefined
21763                        ? iOpts.useRawValueToEscape
21764                        : false;
21765                    this.prefix = iOpts.prefix
21766                      ? regexEscape(iOpts.prefix)
21767                      : iOpts.prefixEscaped || '{{';
21768                    this.suffix = iOpts.suffix
21769                      ? regexEscape(iOpts.suffix)
21770                      : iOpts.suffixEscaped || '}}';
21771                    this.formatSeparator = iOpts.formatSeparator
21772                      ? iOpts.formatSeparator
21773                      : iOpts.formatSeparator || ',';
21774                    this.unescapePrefix = iOpts.unescapeSuffix
21775                      ? ''
21776                      : iOpts.unescapePrefix || '-';
21777                    this.unescapeSuffix = this.unescapePrefix
21778                      ? ''
21779                      : iOpts.unescapeSuffix || '';
21780                    this.nestingPrefix = iOpts.nestingPrefix
21781                      ? regexEscape(iOpts.nestingPrefix)
21782                      : iOpts.nestingPrefixEscaped || regexEscape('$t(');
21783                    this.nestingSuffix = iOpts.nestingSuffix
21784                      ? regexEscape(iOpts.nestingSuffix)
21785                      : iOpts.nestingSuffixEscaped || regexEscape(')');
21786                    this.maxReplaces = iOpts.maxReplaces ? iOpts.maxReplaces : 1000; // the regexp
21787
21788                    this.resetRegExp();
21789                  }
21790                },
21791                {
21792                  key: 'reset',
21793                  value: function reset() {
21794                    if (this.options) this.init(this.options);
21795                  }
21796                },
21797                {
21798                  key: 'resetRegExp',
21799                  value: function resetRegExp() {
21800                    // the regexp
21801                    var regexpStr = ''.concat(this.prefix, '(.+?)').concat(this.suffix);
21802                    this.regexp = new RegExp(regexpStr, 'g');
21803                    var regexpUnescapeStr = ''
21804                      .concat(this.prefix)
21805                      .concat(this.unescapePrefix, '(.+?)')
21806                      .concat(this.unescapeSuffix)
21807                      .concat(this.suffix);
21808                    this.regexpUnescape = new RegExp(regexpUnescapeStr, 'g');
21809                    var nestingRegexpStr = ''
21810                      .concat(this.nestingPrefix, '(.+?)')
21811                      .concat(this.nestingSuffix);
21812                    this.nestingRegexp = new RegExp(nestingRegexpStr, 'g');
21813                  }
21814                },
21815                {
21816                  key: 'interpolate',
21817                  value: function interpolate(str, data, lng, options) {
21818                    var _this = this;
21819
21820                    var match;
21821                    var value;
21822                    var replaces;
21823                    var defaultData =
21824                      (this.options &&
21825                        this.options.interpolation &&
21826                        this.options.interpolation.defaultVariables) ||
21827                      {};
21828
21829                    function regexSafe(val) {
21830                      return val.replace(/\$/g, '$$$$');
21831                    }
21832
21833                    var handleFormat = function handleFormat(key) {
21834                      if (key.indexOf(_this.formatSeparator) < 0) {
21835                        return getPathWithDefaults(data, defaultData, key);
21836                      }
21837
21838                      var p = key.split(_this.formatSeparator);
21839                      var k = p.shift().trim();
21840                      var f = p.join(_this.formatSeparator).trim();
21841                      return _this.format(
21842                        getPathWithDefaults(data, defaultData, k),
21843                        f,
21844                        lng
21845                      );
21846                    };
21847
21848                    this.resetRegExp();
21849                    var missingInterpolationHandler =
21850                      (options && options.missingInterpolationHandler) ||
21851                      this.options.missingInterpolationHandler;
21852                    replaces = 0; // unescape if has unescapePrefix/Suffix
21853
21854                    /* eslint no-cond-assign: 0 */
21855
21856                    while ((match = this.regexpUnescape.exec(str))) {
21857                      value = handleFormat(match[1].trim());
21858
21859                      if (value === undefined) {
21860                        if (typeof missingInterpolationHandler === 'function') {
21861                          var temp = missingInterpolationHandler(str, match, options);
21862                          value = typeof temp === 'string' ? temp : '';
21863                        } else {
21864                          this.logger.warn(
21865                            'missed to pass in variable '
21866                              .concat(match[1], ' for interpolating ')
21867                              .concat(str)
21868                          );
21869                          value = '';
21870                        }
21871                      } else if (typeof value !== 'string' && !this.useRawValueToEscape) {
21872                        value = makeString(value);
21873                      }
21874
21875                      str = str.replace(match[0], regexSafe(value));
21876                      this.regexpUnescape.lastIndex = 0;
21877                      replaces++;
21878
21879                      if (replaces >= this.maxReplaces) {
21880                        break;
21881                      }
21882                    }
21883
21884                    replaces = 0; // regular escape on demand
21885
21886                    while ((match = this.regexp.exec(str))) {
21887                      value = handleFormat(match[1].trim());
21888
21889                      if (value === undefined) {
21890                        if (typeof missingInterpolationHandler === 'function') {
21891                          var _temp = missingInterpolationHandler(str, match, options);
21892
21893                          value = typeof _temp === 'string' ? _temp : '';
21894                        } else {
21895                          this.logger.warn(
21896                            'missed to pass in variable '
21897                              .concat(match[1], ' for interpolating ')
21898                              .concat(str)
21899                          );
21900                          value = '';
21901                        }
21902                      } else if (typeof value !== 'string' && !this.useRawValueToEscape) {
21903                        value = makeString(value);
21904                      }
21905
21906                      value = this.escapeValue
21907                        ? regexSafe(this.escape(value))
21908                        : regexSafe(value);
21909                      str = str.replace(match[0], value);
21910                      this.regexp.lastIndex = 0;
21911                      replaces++;
21912
21913                      if (replaces >= this.maxReplaces) {
21914                        break;
21915                      }
21916                    }
21917
21918                    return str;
21919                  }
21920                },
21921                {
21922                  key: 'nest',
21923                  value: function nest(str, fc) {
21924                    var options =
21925                      arguments.length > 2 && arguments[2] !== undefined
21926                        ? arguments[2]
21927                        : {};
21928                    var match;
21929                    var value;
21930
21931                    var clonedOptions = _objectSpread({}, options);
21932
21933                    clonedOptions.applyPostProcessor = false; // avoid post processing on nested lookup
21934
21935                    delete clonedOptions.defaultValue; // assert we do not get a endless loop on interpolating defaultValue again and again
21936                    // if value is something like "myKey": "lorem $(anotherKey, { "count": {{aValueInOptions}} })"
21937
21938                    function handleHasOptions(key, inheritedOptions) {
21939                      if (key.indexOf(',') < 0) return key;
21940                      var p = key.split(',');
21941                      key = p.shift();
21942                      var optionsString = p.join(',');
21943                      optionsString = this.interpolate(optionsString, clonedOptions);
21944                      optionsString = optionsString.replace(/'/g, '"');
21945
21946                      try {
21947                        clonedOptions = JSON.parse(optionsString);
21948                        if (inheritedOptions)
21949                          clonedOptions = _objectSpread(
21950                            {},
21951                            inheritedOptions,
21952                            clonedOptions
21953                          );
21954                      } catch (e) {
21955                        this.logger.error(
21956                          'failed parsing options string in nesting for key '.concat(key),
21957                          e
21958                        );
21959                      } // assert we do not get a endless loop on interpolating defaultValue again and again
21960
21961                      delete clonedOptions.defaultValue;
21962                      return key;
21963                    } // regular escape on demand
21964
21965                    while ((match = this.nestingRegexp.exec(str))) {
21966                      value = fc(
21967                        handleHasOptions.call(this, match[1].trim(), clonedOptions),
21968                        clonedOptions
21969                      ); // is only the nesting key (key1 = '$(key2)') return the value without stringify
21970
21971                      if (value && match[0] === str && typeof value !== 'string')
21972                        return value; // no string to include or empty
21973
21974                      if (typeof value !== 'string') value = makeString(value);
21975
21976                      if (!value) {
21977                        this.logger.warn(
21978                          'missed to resolve '.concat(match[1], ' for nesting ').concat(str)
21979                        );
21980                        value = '';
21981                      } // Nested keys should not be escaped by default #854
21982                      // value = this.escapeValue ? regexSafe(utils.escape(value)) : regexSafe(value);
21983
21984                      str = str.replace(match[0], value);
21985                      this.regexp.lastIndex = 0;
21986                    }
21987
21988                    return str;
21989                  }
21990                }
21991              ]);
21992
21993              return Interpolator;
21994            })();
21995
21996          function remove(arr, what) {
21997            var found = arr.indexOf(what);
21998
21999            while (found !== -1) {
22000              arr.splice(found, 1);
22001              found = arr.indexOf(what);
22002            }
22003          }
22004
22005          var Connector =
22006            /*#__PURE__*/
22007            (function(_EventEmitter) {
22008              _inherits(Connector, _EventEmitter);
22009
22010              function Connector(backend, store, services) {
22011                var _this;
22012
22013                var options =
22014                  arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
22015
22016                _classCallCheck(this, Connector);
22017
22018                _this = _possibleConstructorReturn(
22019                  this,
22020                  _getPrototypeOf(Connector).call(this)
22021                );
22022                EventEmitter.call(_assertThisInitialized(_this)); // <=IE10 fix (unable to call parent constructor)
22023
22024                _this.backend = backend;
22025                _this.store = store;
22026                _this.services = services;
22027                _this.languageUtils = services.languageUtils;
22028                _this.options = options;
22029                _this.logger = baseLogger.create('backendConnector');
22030                _this.state = {};
22031                _this.queue = [];
22032
22033                if (_this.backend && _this.backend.init) {
22034                  _this.backend.init(services, options.backend, options);
22035                }
22036
22037                return _this;
22038              }
22039
22040              _createClass(Connector, [
22041                {
22042                  key: 'queueLoad',
22043                  value: function queueLoad(languages, namespaces, options, callback) {
22044                    var _this2 = this;
22045
22046                    // find what needs to be loaded
22047                    var toLoad = [];
22048                    var pending = [];
22049                    var toLoadLanguages = [];
22050                    var toLoadNamespaces = [];
22051                    languages.forEach(function(lng) {
22052                      var hasAllNamespaces = true;
22053                      namespaces.forEach(function(ns) {
22054                        var name = ''.concat(lng, '|').concat(ns);
22055
22056                        if (!options.reload && _this2.store.hasResourceBundle(lng, ns)) {
22057                          _this2.state[name] = 2; // loaded
22058                        } else if (_this2.state[name] < 0);
22059                        else if (_this2.state[name] === 1) {
22060                          if (pending.indexOf(name) < 0) pending.push(name);
22061                        } else {
22062                          _this2.state[name] = 1; // pending
22063
22064                          hasAllNamespaces = false;
22065                          if (pending.indexOf(name) < 0) pending.push(name);
22066                          if (toLoad.indexOf(name) < 0) toLoad.push(name);
22067                          if (toLoadNamespaces.indexOf(ns) < 0) toLoadNamespaces.push(ns);
22068                        }
22069                      });
22070                      if (!hasAllNamespaces) toLoadLanguages.push(lng);
22071                    });
22072
22073                    if (toLoad.length || pending.length) {
22074                      this.queue.push({
22075                        pending: pending,
22076                        loaded: {},
22077                        errors: [],
22078                        callback: callback
22079                      });
22080                    }
22081
22082                    return {
22083                      toLoad: toLoad,
22084                      pending: pending,
22085                      toLoadLanguages: toLoadLanguages,
22086                      toLoadNamespaces: toLoadNamespaces
22087                    };
22088                  }
22089                },
22090                {
22091                  key: 'loaded',
22092                  value: function loaded(name, err, data) {
22093                    var _name$split = name.split('|'),
22094                      _name$split2 = _slicedToArray(_name$split, 2),
22095                      lng = _name$split2[0],
22096                      ns = _name$split2[1];
22097
22098                    if (err) this.emit('failedLoading', lng, ns, err);
22099
22100                    if (data) {
22101                      this.store.addResourceBundle(lng, ns, data);
22102                    } // set loaded
22103
22104                    this.state[name] = err ? -1 : 2; // consolidated loading done in this run - only emit once for a loaded namespace
22105
22106                    var loaded = {}; // callback if ready
22107
22108                    this.queue.forEach(function(q) {
22109                      pushPath(q.loaded, [lng], ns);
22110                      remove(q.pending, name);
22111                      if (err) q.errors.push(err);
22112
22113                      if (q.pending.length === 0 && !q.done) {
22114                        // only do once per loaded -> this.emit('loaded', q.loaded);
22115                        Object.keys(q.loaded).forEach(function(l) {
22116                          if (!loaded[l]) loaded[l] = [];
22117
22118                          if (q.loaded[l].length) {
22119                            q.loaded[l].forEach(function(ns) {
22120                              if (loaded[l].indexOf(ns) < 0) loaded[l].push(ns);
22121                            });
22122                          }
22123                        });
22124                        /* eslint no-param-reassign: 0 */
22125
22126                        q.done = true;
22127
22128                        if (q.errors.length) {
22129                          q.callback(q.errors);
22130                        } else {
22131                          q.callback();
22132                        }
22133                      }
22134                    }); // emit consolidated loaded event
22135
22136                    this.emit('loaded', loaded); // remove done load requests
22137
22138                    this.queue = this.queue.filter(function(q) {
22139                      return !q.done;
22140                    });
22141                  }
22142                },
22143                {
22144                  key: 'read',
22145                  value: function read(lng, ns, fcName) {
22146                    var _this3 = this;
22147
22148                    var tried =
22149                      arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
22150                    var wait =
22151                      arguments.length > 4 && arguments[4] !== undefined
22152                        ? arguments[4]
22153                        : 250;
22154                    var callback = arguments.length > 5 ? arguments[5] : undefined;
22155                    if (!lng.length) return callback(null, {}); // noting to load
22156
22157                    return this.backend[fcName](lng, ns, function(err, data) {
22158                      if (
22159                        err &&
22160                        data &&
22161                        /* = retryFlag */
22162                        tried < 5
22163                      ) {
22164                        setTimeout(function() {
22165                          _this3.read.call(
22166                            _this3,
22167                            lng,
22168                            ns,
22169                            fcName,
22170                            tried + 1,
22171                            wait * 2,
22172                            callback
22173                          );
22174                        }, wait);
22175                        return;
22176                      }
22177
22178                      callback(err, data);
22179                    });
22180                  }
22181                  /* eslint consistent-return: 0 */
22182                },
22183                {
22184                  key: 'prepareLoading',
22185                  value: function prepareLoading(languages, namespaces) {
22186                    var _this4 = this;
22187
22188                    var options =
22189                      arguments.length > 2 && arguments[2] !== undefined
22190                        ? arguments[2]
22191                        : {};
22192                    var callback = arguments.length > 3 ? arguments[3] : undefined;
22193
22194                    if (!this.backend) {
22195                      this.logger.warn(
vendor: 27,572 bytes, lines 22196-22895
22196                        'No backend was added via i18next.use. Will not load resources.'
22197                      );
22198                      return callback && callback();
22199                    }
22200
22201                    if (typeof languages === 'string')
22202                      languages = this.languageUtils.toResolveHierarchy(languages);
22203                    if (typeof namespaces === 'string') namespaces = [namespaces];
22204                    var toLoad = this.queueLoad(languages, namespaces, options, callback);
22205
22206                    if (!toLoad.toLoad.length) {
22207                      if (!toLoad.pending.length) callback(); // nothing to load and no pendings...callback now
22208
22209                      return null; // pendings will trigger callback
22210                    }
22211
22212                    toLoad.toLoad.forEach(function(name) {
22213                      _this4.loadOne(name);
22214                    });
22215                  }
22216                },
22217                {
22218                  key: 'load',
22219                  value: function load(languages, namespaces, callback) {
22220                    this.prepareLoading(languages, namespaces, {}, callback);
22221                  }
22222                },
22223                {
22224                  key: 'reload',
22225                  value: function reload(languages, namespaces, callback) {
22226                    this.prepareLoading(
22227                      languages,
22228                      namespaces,
22229                      {
22230                        reload: true
22231                      },
22232                      callback
22233                    );
22234                  }
22235                },
22236                {
22237                  key: 'loadOne',
22238                  value: function loadOne(name) {
22239                    var _this5 = this;
22240
22241                    var prefix =
22242                      arguments.length > 1 && arguments[1] !== undefined
22243                        ? arguments[1]
22244                        : '';
22245
22246                    var _name$split3 = name.split('|'),
22247                      _name$split4 = _slicedToArray(_name$split3, 2),
22248                      lng = _name$split4[0],
22249                      ns = _name$split4[1];
22250
22251                    this.read(lng, ns, 'read', null, null, function(err, data) {
22252                      if (err)
22253                        _this5.logger.warn(
22254                          ''
22255                            .concat(prefix, 'loading namespace ')
22256                            .concat(ns, ' for language ')
22257                            .concat(lng, ' failed'),
22258                          err
22259                        );
22260                      if (!err && data)
22261                        _this5.logger.log(
22262                          ''
22263                            .concat(prefix, 'loaded namespace ')
22264                            .concat(ns, ' for language ')
22265                            .concat(lng),
22266                          data
22267                        );
22268
22269                      _this5.loaded(name, err, data);
22270                    });
22271                  }
22272                },
22273                {
22274                  key: 'saveMissing',
22275                  value: function saveMissing(
22276                    languages,
22277                    namespace,
22278                    key,
22279                    fallbackValue,
22280                    isUpdate
22281                  ) {
22282                    var options =
22283                      arguments.length > 5 && arguments[5] !== undefined
22284                        ? arguments[5]
22285                        : {};
22286
22287                    if (
22288                      this.services.utils &&
22289                      this.services.utils.hasLoadedNamespace &&
22290                      !this.services.utils.hasLoadedNamespace(namespace)
22291                    ) {
22292                      this.logger.warn(
22293                        'did not save key "'
22294                          .concat(key, '" for namespace "')
22295                          .concat(namespace, '" as the namespace was not yet loaded'),
22296                        'This means something IS WRONG in your application setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!'
22297                      );
22298                      return;
22299                    } // ignore non valid keys
22300
22301                    if (key === undefined || key === null || key === '') return;
22302
22303                    if (this.backend && this.backend.create) {
22304                      this.backend.create(
22305                        languages,
22306                        namespace,
22307                        key,
22308                        fallbackValue,
22309                        null,
22310                        /* unused callback */
22311                        _objectSpread({}, options, {
22312                          isUpdate: isUpdate
22313                        })
22314                      );
22315                    } // write to store to avoid resending
22316
22317                    if (!languages || !languages[0]) return;
22318                    this.store.addResource(languages[0], namespace, key, fallbackValue);
22319                  }
22320                }
22321              ]);
22322
22323              return Connector;
22324            })(EventEmitter);
22325
22326          function get() {
22327            return {
22328              debug: false,
22329              initImmediate: true,
22330              ns: ['translation'],
22331              defaultNS: ['translation'],
22332              fallbackLng: ['dev'],
22333              fallbackNS: false,
22334              // string or array of namespaces
22335              whitelist: false,
22336              // array with whitelisted languages
22337              nonExplicitWhitelist: false,
22338              load: 'all',
22339              // | currentOnly | languageOnly
22340              preload: false,
22341              // array with preload languages
22342              simplifyPluralSuffix: true,
22343              keySeparator: '.',
22344              nsSeparator: ':',
22345              pluralSeparator: '_',
22346              contextSeparator: '_',
22347              partialBundledLanguages: false,
22348              // allow bundling certain languages that are not remotely fetched
22349              saveMissing: false,
22350              // enable to send missing values
22351              updateMissing: false,
22352              // enable to update default values if different from translated value (only useful on initial development, or when keeping code as source of truth)
22353              saveMissingTo: 'fallback',
22354              // 'current' || 'all'
22355              saveMissingPlurals: true,
22356              // will save all forms not only singular key
22357              missingKeyHandler: false,
22358              // function(lng, ns, key, fallbackValue) -> override if prefer on handling
22359              missingInterpolationHandler: false,
22360              // function(str, match)
22361              postProcess: false,
22362              // string or array of postProcessor names
22363              postProcessPassResolved: false,
22364              // pass resolved object into 'options.i18nResolved' for postprocessor
22365              returnNull: true,
22366              // allows null value as valid translation
22367              returnEmptyString: true,
22368              // allows empty string value as valid translation
22369              returnObjects: false,
22370              joinArrays: false,
22371              // or string to join array
22372              returnedObjectHandler: false,
22373              // function(key, value, options) triggered if key returns object but returnObjects is set to false
22374              parseMissingKeyHandler: false,
22375              // function(key) parsed a key that was not found in t() before returning
22376              appendNamespaceToMissingKey: false,
22377              appendNamespaceToCIMode: false,
22378              overloadTranslationOptionHandler: function handle(args) {
22379                var ret = {};
22380                if (_typeof(args[1]) === 'object') ret = args[1];
22381                if (typeof args[1] === 'string') ret.defaultValue = args[1];
22382                if (typeof args[2] === 'string') ret.tDescription = args[2];
22383
22384                if (_typeof(args[2]) === 'object' || _typeof(args[3]) === 'object') {
22385                  var options = args[3] || args[2];
22386                  Object.keys(options).forEach(function(key) {
22387                    ret[key] = options[key];
22388                  });
22389                }
22390
22391                return ret;
22392              },
22393              interpolation: {
22394                escapeValue: true,
22395                format: function format(value, _format, lng) {
22396                  return value;
22397                },
22398                prefix: '{{',
22399                suffix: '}}',
22400                formatSeparator: ',',
22401                // prefixEscaped: '{{',
22402                // suffixEscaped: '}}',
22403                // unescapeSuffix: '',
22404                unescapePrefix: '-',
22405                nestingPrefix: '$t(',
22406                nestingSuffix: ')',
22407                // nestingPrefixEscaped: '$t(',
22408                // nestingSuffixEscaped: ')',
22409                // defaultVariables: undefined // object that can have values to interpolate on - extends passed in interpolation data
22410                maxReplaces: 1000 // max replaces to prevent endless loop
22411              }
22412            };
22413          }
22414          /* eslint no-param-reassign: 0 */
22415
22416          function transformOptions(options) {
22417            // create namespace object if namespace is passed in as string
22418            if (typeof options.ns === 'string') options.ns = [options.ns];
22419            if (typeof options.fallbackLng === 'string')
22420              options.fallbackLng = [options.fallbackLng];
22421            if (typeof options.fallbackNS === 'string')
22422              options.fallbackNS = [options.fallbackNS]; // extend whitelist with cimode
22423
22424            if (options.whitelist && options.whitelist.indexOf('cimode') < 0) {
22425              options.whitelist = options.whitelist.concat(['cimode']);
22426            }
22427
22428            return options;
22429          }
22430
22431          function noop() {}
22432
22433          var I18n =
22434            /*#__PURE__*/
22435            (function(_EventEmitter) {
22436              _inherits(I18n, _EventEmitter);
22437
22438              function I18n() {
22439                var _this;
22440
22441                var options =
22442                  arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
22443                var callback = arguments.length > 1 ? arguments[1] : undefined;
22444
22445                _classCallCheck(this, I18n);
22446
22447                _this = _possibleConstructorReturn(this, _getPrototypeOf(I18n).call(this));
22448                EventEmitter.call(_assertThisInitialized(_this)); // <=IE10 fix (unable to call parent constructor)
22449
22450                _this.options = transformOptions(options);
22451                _this.services = {};
22452                _this.logger = baseLogger;
22453                _this.modules = {
22454                  external: []
22455                };
22456
22457                if (callback && !_this.isInitialized && !options.isClone) {
22458                  // https://github.com/i18next/i18next/issues/879
22459                  if (!_this.options.initImmediate) {
22460                    _this.init(options, callback);
22461
22462                    return _possibleConstructorReturn(_this, _assertThisInitialized(_this));
22463                  }
22464
22465                  setTimeout(function() {
22466                    _this.init(options, callback);
22467                  }, 0);
22468                }
22469
22470                return _this;
22471              }
22472
22473              _createClass(I18n, [
22474                {
22475                  key: 'init',
22476                  value: function init() {
22477                    var _this2 = this;
22478
22479                    var options =
22480                      arguments.length > 0 && arguments[0] !== undefined
22481                        ? arguments[0]
22482                        : {};
22483                    var callback = arguments.length > 1 ? arguments[1] : undefined;
22484
22485                    if (typeof options === 'function') {
22486                      callback = options;
22487                      options = {};
22488                    }
22489
22490                    this.options = _objectSpread(
22491                      {},
22492                      get(),
22493                      this.options,
22494                      transformOptions(options)
22495                    );
22496                    this.format = this.options.interpolation.format;
22497                    if (!callback) callback = noop;
22498
22499                    function createClassOnDemand(ClassOrObject) {
22500                      if (!ClassOrObject) return null;
22501                      if (typeof ClassOrObject === 'function') return new ClassOrObject();
22502                      return ClassOrObject;
22503                    } // init services
22504
22505                    if (!this.options.isClone) {
22506                      if (this.modules.logger) {
22507                        baseLogger.init(
22508                          createClassOnDemand(this.modules.logger),
22509                          this.options
22510                        );
22511                      } else {
22512                        baseLogger.init(null, this.options);
22513                      }
22514
22515                      var lu = new LanguageUtil(this.options);
22516                      this.store = new ResourceStore(this.options.resources, this.options);
22517                      var s = this.services;
22518                      s.logger = baseLogger;
22519                      s.resourceStore = this.store;
22520                      s.languageUtils = lu;
22521                      s.pluralResolver = new PluralResolver(lu, {
22522                        prepend: this.options.pluralSeparator,
22523                        compatibilityJSON: this.options.compatibilityJSON,
22524                        simplifyPluralSuffix: this.options.simplifyPluralSuffix
22525                      });
22526                      s.interpolator = new Interpolator(this.options);
22527                      s.utils = {
22528                        hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
22529                      };
22530                      s.backendConnector = new Connector(
22531                        createClassOnDemand(this.modules.backend),
22532                        s.resourceStore,
22533                        s,
22534                        this.options
22535                      ); // pipe events from backendConnector
22536
22537                      s.backendConnector.on('*', function(event) {
22538                        for (
22539                          var _len = arguments.length,
22540                            args = new Array(_len > 1 ? _len - 1 : 0),
22541                            _key = 1;
22542                          _key < _len;
22543                          _key++
22544                        ) {
22545                          args[_key - 1] = arguments[_key];
22546                        }
22547
22548                        _this2.emit.apply(_this2, [event].concat(args));
22549                      });
22550
22551                      if (this.modules.languageDetector) {
22552                        s.languageDetector = createClassOnDemand(
22553                          this.modules.languageDetector
22554                        );
22555                        s.languageDetector.init(s, this.options.detection, this.options);
22556                      }
22557
22558                      if (this.modules.i18nFormat) {
22559                        s.i18nFormat = createClassOnDemand(this.modules.i18nFormat);
22560                        if (s.i18nFormat.init) s.i18nFormat.init(this);
22561                      }
22562
22563                      this.translator = new Translator(this.services, this.options); // pipe events from translator
22564
22565                      this.translator.on('*', function(event) {
22566                        for (
22567                          var _len2 = arguments.length,
22568                            args = new Array(_len2 > 1 ? _len2 - 1 : 0),
22569                            _key2 = 1;
22570                          _key2 < _len2;
22571                          _key2++
22572                        ) {
22573                          args[_key2 - 1] = arguments[_key2];
22574                        }
22575
22576                        _this2.emit.apply(_this2, [event].concat(args));
22577                      });
22578                      this.modules.external.forEach(function(m) {
22579                        if (m.init) m.init(_this2);
22580                      });
22581                    } // append api
22582
22583                    var storeApi = [
22584                      'getResource',
22585                      'addResource',
22586                      'addResources',
22587                      'addResourceBundle',
22588                      'removeResourceBundle',
22589                      'hasResourceBundle',
22590                      'getResourceBundle',
22591                      'getDataByLanguage'
22592                    ];
22593                    storeApi.forEach(function(fcName) {
22594                      _this2[fcName] = function() {
22595                        var _this2$store;
22596
22597                        return (_this2$store = _this2.store)[fcName].apply(
22598                          _this2$store,
22599                          arguments
22600                        );
22601                      };
22602                    });
22603                    var deferred = defer();
22604
22605                    var load = function load() {
22606                      _this2.changeLanguage(_this2.options.lng, function(err, t) {
22607                        _this2.isInitialized = true;
22608
22609                        _this2.logger.log('initialized', _this2.options);
22610
22611                        _this2.emit('initialized', _this2.options);
22612
22613                        deferred.resolve(t); // not rejecting on err (as err is only a loading translation failed warning)
22614
22615                        callback(err, t);
22616                      });
22617                    };
22618
22619                    if (this.options.resources || !this.options.initImmediate) {
22620                      load();
22621                    } else {
22622                      setTimeout(load, 0);
22623                    }
22624
22625                    return deferred;
22626                  }
22627                  /* eslint consistent-return: 0 */
22628                },
22629                {
22630                  key: 'loadResources',
22631                  value: function loadResources(language) {
22632                    var _this3 = this;
22633
22634                    var callback =
22635                      arguments.length > 1 && arguments[1] !== undefined
22636                        ? arguments[1]
22637                        : noop;
22638                    var usedCallback = callback;
22639                    var usedLng = typeof language === 'string' ? language : this.language;
22640                    if (typeof language === 'function') usedCallback = language;
22641
22642                    if (!this.options.resources || this.options.partialBundledLanguages) {
22643                      if (usedLng && usedLng.toLowerCase() === 'cimode')
22644                        return usedCallback(); // avoid loading resources for cimode
22645
22646                      var toLoad = [];
22647
22648                      var append = function append(lng) {
22649                        if (!lng) return;
22650
22651                        var lngs = _this3.services.languageUtils.toResolveHierarchy(lng);
22652
22653                        lngs.forEach(function(l) {
22654                          if (toLoad.indexOf(l) < 0) toLoad.push(l);
22655                        });
22656                      };
22657
22658                      if (!usedLng) {
22659                        // at least load fallbacks in this case
22660                        var fallbacks = this.services.languageUtils.getFallbackCodes(
22661                          this.options.fallbackLng
22662                        );
22663                        fallbacks.forEach(function(l) {
22664                          return append(l);
22665                        });
22666                      } else {
22667                        append(usedLng);
22668                      }
22669
22670                      if (this.options.preload) {
22671                        this.options.preload.forEach(function(l) {
22672                          return append(l);
22673                        });
22674                      }
22675
22676                      this.services.backendConnector.load(
22677                        toLoad,
22678                        this.options.ns,
22679                        usedCallback
22680                      );
22681                    } else {
22682                      usedCallback(null);
22683                    }
22684                  }
22685                },
22686                {
22687                  key: 'reloadResources',
22688                  value: function reloadResources(lngs, ns, callback) {
22689                    var deferred = defer();
22690                    if (!lngs) lngs = this.languages;
22691                    if (!ns) ns = this.options.ns;
22692                    if (!callback) callback = noop;
22693                    this.services.backendConnector.reload(lngs, ns, function(err) {
22694                      deferred.resolve(); // not rejecting on err (as err is only a loading translation failed warning)
22695
22696                      callback(err);
22697                    });
22698                    return deferred;
22699                  }
22700                },
22701                {
22702                  key: 'use',
22703                  value: function use(module) {
22704                    if (module.type === 'backend') {
22705                      this.modules.backend = module;
22706                    }
22707
22708                    if (
22709                      module.type === 'logger' ||
22710                      (module.log && module.warn && module.error)
22711                    ) {
22712                      this.modules.logger = module;
22713                    }
22714
22715                    if (module.type === 'languageDetector') {
22716                      this.modules.languageDetector = module;
22717                    }
22718
22719                    if (module.type === 'i18nFormat') {
22720                      this.modules.i18nFormat = module;
22721                    }
22722
22723                    if (module.type === 'postProcessor') {
22724                      postProcessor.addPostProcessor(module);
22725                    }
22726
22727                    if (module.type === '3rdParty') {
22728                      this.modules.external.push(module);
22729                    }
22730
22731                    return this;
22732                  }
22733                },
22734                {
22735                  key: 'changeLanguage',
22736                  value: function changeLanguage(lng, callback) {
22737                    var _this4 = this;
22738
22739                    this.isLanguageChangingTo = lng;
22740                    var deferred = defer();
22741                    this.emit('languageChanging', lng);
22742
22743                    var done = function done(err, l) {
22744                      if (l) {
22745                        _this4.language = l;
22746                        _this4.languages = _this4.services.languageUtils.toResolveHierarchy(
22747                          l
22748                        );
22749
22750                        _this4.translator.changeLanguage(l);
22751
22752                        _this4.isLanguageChangingTo = undefined;
22753
22754                        _this4.emit('languageChanged', l);
22755
22756                        _this4.logger.log('languageChanged', l);
22757                      } else {
22758                        _this4.isLanguageChangingTo = undefined;
22759                      }
22760
22761                      deferred.resolve(function() {
22762                        return _this4.t.apply(_this4, arguments);
22763                      });
22764                      if (callback)
22765                        callback(err, function() {
22766                          return _this4.t.apply(_this4, arguments);
22767                        });
22768                    };
22769
22770                    var setLng = function setLng(l) {
22771                      if (l) {
22772                        if (!_this4.language) {
22773                          _this4.language = l;
22774                          _this4.languages = _this4.services.languageUtils.toResolveHierarchy(
22775                            l
22776                          );
22777                        }
22778
22779                        if (!_this4.translator.language)
22780                          _this4.translator.changeLanguage(l);
22781                        if (_this4.services.languageDetector)
22782                          _this4.services.languageDetector.cacheUserLanguage(l);
22783                      }
22784
22785                      _this4.loadResources(l, function(err) {
22786                        done(err, l);
22787                      });
22788                    };
22789
22790                    if (
22791                      !lng &&
22792                      this.services.languageDetector &&
22793                      !this.services.languageDetector.async
22794                    ) {
22795                      setLng(this.services.languageDetector.detect());
22796                    } else if (
22797                      !lng &&
22798                      this.services.languageDetector &&
22799                      this.services.languageDetector.async
22800                    ) {
22801                      this.services.languageDetector.detect(setLng);
22802                    } else {
22803                      setLng(lng);
22804                    }
22805
22806                    return deferred;
22807                  }
22808                },
22809                {
22810                  key: 'getFixedT',
22811                  value: function getFixedT(lng, ns) {
22812                    var _this5 = this;
22813
22814                    var fixedT = function fixedT(key, opts) {
22815                      var options;
22816
22817                      if (_typeof(opts) !== 'object') {
22818                        for (
22819                          var _len3 = arguments.length,
22820                            rest = new Array(_len3 > 2 ? _len3 - 2 : 0),
22821                            _key3 = 2;
22822                          _key3 < _len3;
22823                          _key3++
22824                        ) {
22825                          rest[_key3 - 2] = arguments[_key3];
22826                        }
22827
22828                        options = _this5.options.overloadTranslationOptionHandler(
22829                          [key, opts].concat(rest)
22830                        );
22831                      } else {
22832                        options = _objectSpread({}, opts);
22833                      }
22834
22835                      options.lng = options.lng || fixedT.lng;
22836                      options.lngs = options.lngs || fixedT.lngs;
22837                      options.ns = options.ns || fixedT.ns;
22838                      return _this5.t(key, options);
22839                    };
22840
22841                    if (typeof lng === 'string') {
22842                      fixedT.lng = lng;
22843                    } else {
22844                      fixedT.lngs = lng;
22845                    }
22846
22847                    fixedT.ns = ns;
22848                    return fixedT;
22849                  }
22850                },
22851                {
22852                  key: 't',
22853                  value: function t() {
22854                    var _this$translator;
22855
22856                    return (
22857                      this.translator &&
22858                      (_this$translator = this.translator).translate.apply(
22859                        _this$translator,
22860                        arguments
22861                      )
22862                    );
22863                  }
22864                },
22865                {
22866                  key: 'exists',
22867                  value: function exists() {
22868                    var _this$translator2;
22869
22870                    return (
22871                      this.translator &&
22872                      (_this$translator2 = this.translator).exists.apply(
22873                        _this$translator2,
22874                        arguments
22875                      )
22876                    );
22877                  }
22878                },
22879                {
22880                  key: 'setDefaultNamespace',
22881                  value: function setDefaultNamespace(ns) {
22882                    this.options.defaultNS = ns;
22883                  }
22884                },
22885                {
22886                  key: 'hasLoadedNamespace',
22887                  value: function hasLoadedNamespace(ns) {
22888                    var _this6 = this;
22889
22890                    if (!this.isInitialized) {
22891                      this.logger.warn(
22892                        'hasLoadedNamespace: i18next was not initialized',
22893                        this.languages
22894                      );
22895                      return false;
vendor: 5,423 bytes, lines 22896-23045
22896                    }
22897
22898                    if (!this.languages || !this.languages.length) {
22899                      this.logger.warn(
22900                        'hasLoadedNamespace: i18n.languages were undefined or empty',
22901                        this.languages
22902                      );
22903                      return false;
22904                    }
22905
22906                    var lng = this.languages[0];
22907                    var fallbackLng = this.options ? this.options.fallbackLng : false;
22908                    var lastLng = this.languages[this.languages.length - 1]; // we're in cimode so this shall pass
22909
22910                    if (lng.toLowerCase() === 'cimode') return true;
22911
22912                    var loadNotPending = function loadNotPending(l, n) {
22913                      var loadState =
22914                        _this6.services.backendConnector.state[''.concat(l, '|').concat(n)];
22915
22916                      return loadState === -1 || loadState === 2;
22917                    }; // loaded -> SUCCESS
22918
22919                    if (this.hasResourceBundle(lng, ns)) return true; // were not loading at all -> SEMI SUCCESS
22920
22921                    if (!this.services.backendConnector.backend) return true; // failed loading ns - but at least fallback is not pending -> SEMI SUCCESS
22922
22923                    if (
22924                      loadNotPending(lng, ns) &&
22925                      (!fallbackLng || loadNotPending(lastLng, ns))
22926                    )
22927                      return true;
22928                    return false;
22929                  }
22930                },
22931                {
22932                  key: 'loadNamespaces',
22933                  value: function loadNamespaces(ns, callback) {
22934                    var _this7 = this;
22935
22936                    var deferred = defer();
22937
22938                    if (!this.options.ns) {
22939                      callback && callback();
22940                      return Promise.resolve();
22941                    }
22942
22943                    if (typeof ns === 'string') ns = [ns];
22944                    ns.forEach(function(n) {
22945                      if (_this7.options.ns.indexOf(n) < 0) _this7.options.ns.push(n);
22946                    });
22947                    this.loadResources(function(err) {
22948                      deferred.resolve();
22949                      if (callback) callback(err);
22950                    });
22951                    return deferred;
22952                  }
22953                },
22954                {
22955                  key: 'loadLanguages',
22956                  value: function loadLanguages(lngs, callback) {
22957                    var deferred = defer();
22958                    if (typeof lngs === 'string') lngs = [lngs];
22959                    var preloaded = this.options.preload || [];
22960                    var newLngs = lngs.filter(function(lng) {
22961                      return preloaded.indexOf(lng) < 0;
22962                    }); // Exit early if all given languages are already preloaded
22963
22964                    if (!newLngs.length) {
22965                      if (callback) callback();
22966                      return Promise.resolve();
22967                    }
22968
22969                    this.options.preload = preloaded.concat(newLngs);
22970                    this.loadResources(function(err) {
22971                      deferred.resolve();
22972                      if (callback) callback(err);
22973                    });
22974                    return deferred;
22975                  }
22976                },
22977                {
22978                  key: 'dir',
22979                  value: function dir(lng) {
22980                    if (!lng)
22981                      lng =
22982                        this.languages && this.languages.length > 0
22983                          ? this.languages[0]
22984                          : this.language;
22985                    if (!lng) return 'rtl';
22986                    var rtlLngs = [
22987                      'ar',
22988                      'shu',
22989                      'sqr',
22990                      'ssh',
22991                      'xaa',
22992                      'yhd',
22993                      'yud',
22994                      'aao',
22995                      'abh',
22996                      'abv',
22997                      'acm',
22998                      'acq',
22999                      'acw',
23000                      'acx',
23001                      'acy',
23002                      'adf',
23003                      'ads',
23004                      'aeb',
23005                      'aec',
23006                      'afb',
23007                      'ajp',
23008                      'apc',
23009                      'apd',
23010                      'arb',
23011                      'arq',
23012                      'ars',
23013                      'ary',
23014                      'arz',
23015                      'auz',
23016                      'avl',
23017                      'ayh',
23018                      'ayl',
23019                      'ayn',
23020                      'ayp',
23021                      'bbz',
23022                      'pga',
23023                      'he',
23024                      'iw',
23025                      'ps',
23026                      'pbt',
23027                      'pbu',
23028                      'pst',
23029                      'prp',
23030                      'prd',
23031                      'ur',
23032                      'ydd',
23033                      'yds',
23034                      'yih',
23035                      'ji',
23036                      'yi',
23037                      'hbo',
23038                      'men',
23039                      'xmn',
23040                      'fa',
23041                      'jpr',
23042                      'peo',
23043                      'pes',
23044                      'prs',
23045                      'dv',
23046                      'sam'
23047                    ];
23048                    return rtlLngs.indexOf(
23049                      this.services.languageUtils.getLanguagePartFromCode(lng)
23050                    ) >= 0
23051                      ? 'rtl'
23052                      : 'ltr';
23053                  }
23054                  /* eslint class-methods-use-this: 0 */
23055                },
23056                {
23057                  key: 'createInstance',
23058                  value: function createInstance() {
23059                    var options =
23060                      arguments.length > 0 && arguments[0] !== undefined
23061                        ? arguments[0]
23062                        : {};
23063                    var callback = arguments.length > 1 ? arguments[1] : undefined;
23064                    return new I18n(options, callback);
23065                  }
23066                },
23067                {
23068                  key: 'cloneInstance',
23069                  value: function cloneInstance() {
23070                    var _this8 = this;
23071
23072                    var options =
23073                      arguments.length > 0 && arguments[0] !== undefined
23074                        ? arguments[0]
23075                        : {};
23076                    var callback =
23077                      arguments.length > 1 && arguments[1] !== undefined
23078                        ? arguments[1]
23079                        : noop;
23080
23081                    var mergedOptions = _objectSpread({}, this.options, options, {
23082                      isClone: true
23083                    });
23084
23085                    var clone = new I18n(mergedOptions);
23086                    var membersToCopy = ['store', 'services', 'language'];
23087                    membersToCopy.forEach(function(m) {
23088                      clone[m] = _this8[m];
23089                    });
23090                    clone.translator = new Translator(clone.services, clone.options);
23091                    clone.translator.on('*', function(event) {
23092                      for (
23093                        var _len4 = arguments.length,
23094                          args = new Array(_len4 > 1 ? _len4 - 1 : 0),
23095                          _key4 = 1;
23096                        _key4 < _len4;
23097                        _key4++
23098                      ) {
23099                        args[_key4 - 1] = arguments[_key4];
23100                      }
23101
23102                      clone.emit.apply(clone, [event].concat(args));
23103                    });
23104                    clone.init(mergedOptions, callback);
23105                    clone.translator.options = clone.options; // sync options
23106
23107                    return clone;
23108                  }
23109                }
23110              ]);
23111
23112              return I18n;
23113            })(EventEmitter);
23114
23115          var i18next = new I18n();
23116
23117          module.exports = i18next;
23118        },
23119        {
23120          '@babel/runtime/helpers/assertThisInitialized': 4,
23121          '@babel/runtime/helpers/classCallCheck': 5,
23122          '@babel/runtime/helpers/createClass': 6,
23123          '@babel/runtime/helpers/getPrototypeOf': 8,
23124          '@babel/runtime/helpers/inherits': 9,
23125          '@babel/runtime/helpers/objectSpread': 14,
23126          '@babel/runtime/helpers/possibleConstructorReturn': 15,
23127          '@babel/runtime/helpers/slicedToArray': 17,
23128          '@babel/runtime/helpers/toConsumableArray': 18,
23129          '@babel/runtime/helpers/typeof': 19
23130        }
23131      ],
23132      31: [
23133        function(_dereq_, module, exports) {
23134          exports.read = function(buffer, offset, isLE, mLen, nBytes) {
23135            var e, m;
23136            var eLen = nBytes * 8 - mLen - 1;
23137            var eMax = (1 << eLen) - 1;
23138            var eBias = eMax >> 1;
23139            var nBits = -7;
23140            var i = isLE ? nBytes - 1 : 0;
23141            var d = isLE ? -1 : 1;
23142            var s = buffer[offset + i];
23143
23144            i += d;
23145
23146            e = s & ((1 << -nBits) - 1);
23147            s >>= -nBits;
23148            nBits += eLen;
23149            for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
23150
23151            m = e & ((1 << -nBits) - 1);
23152            e >>= -nBits;
23153            nBits += mLen;
23154            for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
23155
23156            if (e === 0) {
23157              e = 1 - eBias;
23158            } else if (e === eMax) {
23159              return m ? NaN : (s ? -1 : 1) * Infinity;
23160            } else {
23161              m = m + Math.pow(2, mLen);
23162              e = e - eBias;
23163            }
23164            return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
23165          };
23166
23167          exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
23168            var e, m, c;
23169            var eLen = nBytes * 8 - mLen - 1;
23170            var eMax = (1 << eLen) - 1;
23171            var eBias = eMax >> 1;
23172            var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;
23173            var i = isLE ? 0 : nBytes - 1;
23174            var d = isLE ? 1 : -1;
23175            var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
23176
23177            value = Math.abs(value);
23178
23179            if (isNaN(value) || value === Infinity) {
23180              m = isNaN(value) ? 1 : 0;
23181              e = eMax;
23182            } else {
23183              e = Math.floor(Math.log(value) / Math.LN2);
23184              if (value * (c = Math.pow(2, -e)) < 1) {
23185                e--;
23186                c *= 2;
23187              }
23188              if (e + eBias >= 1) {
23189                value += rt / c;
23190              } else {
23191                value += rt * Math.pow(2, 1 - eBias);
23192              }
23193              if (value * c >= 2) {
23194                e++;
23195                c /= 2;
23196              }
23197
23198              if (e + eBias >= eMax) {
23199                m = 0;
23200                e = eMax;
23201              } else if (e + eBias >= 1) {
23202                m = (value * c - 1) * Math.pow(2, mLen);
23203                e = e + eBias;
23204              } else {
23205                m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
23206                e = 0;
23207              }
23208            }
23209
23210            for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
23211
23212            e = (e << mLen) | m;
23213            eLen += mLen;
23214            for (; eLen > 0;
23214 buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
23215
23216            buffer[offset + i - d] |= s * 128;
23217          };
23218        },
23219        {}
23220      ],
23221      32: [
23222        function(_dereq_, module, exports) {
23223          /*
23224
23225 Copyright 2000, Silicon Graphics, Inc. All Rights Reserved.
23226 Copyright 2015, Google Inc. All Rights Reserved.
23227
23228 Permission is hereby granted, free of charge, to any person obtaining a copy
23229 of this software and associated documentation files (the "Software"), to
23230 deal in the Software without restriction, including without limitation the
23231 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
23232 sell copies of the Software, and to permit persons to whom the Software is
23233 furnished to do so, subject to the following conditions:
23234
23235 The above copyright notice including the dates of first publication and
23236 either this permission notice or a reference to http://oss.sgi.com/projects/FreeB/
23237 shall be included in all copies or substantial portions of the Software.
23238
23239 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23240 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23241 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23242 SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23243 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
23244 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23245
23246 Original Code. The Original Code is: OpenGL Sample Implementation,
23247 Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
23248 Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
23249 Copyright in any portions created by third parties is as indicated
23250 elsewhere herein. All Rights Reserved.
23251*/
23252          'use strict';
23253          var n;
23254          function t(a, b) {
23255            return a.b === b.b && a.a === b.a;
23256          }
23257          function u(a, b) {
23258            return a.b < b.b || (a.b === b.b && a.a <= b.a);
23259          }
23260          function v(a, b, c) {
23261            var d = b.b - a.b,
23262              e = c.b - b.b;
23263            return 0 < d + e
23264              ? d < e
23265                ? b.a - a.a + d / (d + e) * (a.a - c.a)
23266                : b.a - c.a + e / (d + e) * (c.a - a.a)
23267              : 0;
23268          }
23269          function x(a, b, c) {
23270            var d = b.b - a.b,
23271              e = c.b - b.b;
23272            return 0 < d + e ? (b.a - c.a) * d + (b.a - a.a) * e : 0;
23273          }
23274          function z(a, b) {
23275            return a.a < b.a || (a.a === b.a && a.b <= b.b);
23276          }
23277          function aa(a, b, c) {
23278            var d = b.a - a.a,
23279              e = c.a - b.a;
23280            return 0 < d + e
23281              ? d < e
23282                ? b.b - a.b + d / (d + e) * (a.b - c.b)
23283                : b.b - c.b + e / (d + e) * (c.b - a.b)
23284              : 0;
23285          }
23286          function ba(a, b, c) {
23287            var d = b.a - a.a,
23288              e = c.a - b.a;
23289            return 0 < d + e ? (b.b - c.b) * d + (b.b - a.b) * e : 0;
23290          }
23291          function ca(a) {
23292            return u(a.b.a, a.a);
23293          }
23294          function da(a) {
23295            return u(a.a, a.b.a);
23296          }
23297          function A(a, b, c, d) {
23298            a = 0 > a ? 0 : a;
23299            c = 0 > c ? 0 : c;
23300            return a <= c
23301              ? 0 === c ? (b + d) / 2 : b + a / (a + c) * (d - b)
23302              : d + c / (a + c) * (b - d);
23303          }
23304          function ea(a) {
23305            var b = B(a.b);
23306            C(b, a.c);
23307            C(b.b, a.c);
23308            D(b, a.a);
23309            return b;
23310          }
23311          function E(a, b) {
23312            var c = !1,
23313              d = !1;
23314            a !== b &&
23315              (b.a !== a.a && ((d = !0), F(b.a, a.a)),
23316              b.d !== a.d && ((c = !0), G(b.d, a.d)),
23317              H(b, a),
23318              d || (C(b, a.a), (a.a.c = a)),
23319              c || (D(b, a.d), (a.d.a = a)));
23320          }
23321          function I(a) {
23322            var b = a.b,
23323              c = !1;
23324            a.d !== a.b.d && ((c = !0), G(a.d, a.b.d));
23325            a.c === a
23326              ? F(a.a, null)
23327              : ((a.b.d.a = J(a)), (a.a.c = a.c), H(a, J(a)), c || D(a, a.d));
23328            b.c === b
23329              ? (F(b.a, null), G(b.d, null))
23330              : ((a.d.a = J(b)), (b.a.c = b.c), H(b, J(b)));
23331            fa(a);
23332          }
23333          function K(a) {
23334            var b = B(a),
23335              c = b.b;
23336            H(b, a.e);
23337            b.a = a.b.a;
23338            C(c, b.a);
23339            b.d = c.d = a.d;
23340            b = b.b;
23341            H(a.b, J(a.b));
23342            H(a.b, b);
23343            a.b.a = b.a;
23344            b.b.a.c = b.b;
23345            b.b.d = a.b.d;
23346            b.f = a.f;
23347            b.b.f = a.b.f;
23348            return b;
23349          }
23350          function L(a, b) {
23351            var c = !1,
23352              d = B(a),
23353              e = d.b;
23354            b.d !== a.d && ((c = !0), G(b.d, a.d));
23355            H(d, a.e);
23356            H(e, b);
23357            d.a = a.b.a;
23358            e.a = b.a;
23359            d.d = e.d = a.d;
23360            a.d.a = e;
23361            c || D(d, a.d);
23362            return d;
23363          }
23364          function B(a) {
23365            var b = new M(),
23366              c = new M(),
23367              d = a.b.h;
23368            c.h = d;
23369            d.b.h = b;
23370            b.h = a;
23371            a.b.h = c;
23372            b.b = c;
23373            b.c = b;
23374            b.e = c;
23375            c.b = b;
23376            c.c = c;
23377            return (c.e = b);
23378          }
23379          function H(a, b) {
23380            var c = a.c,
23381              d = b.c;
23382            c.b.e = b;
23383            d.b.e = a;
23384            a.c = d;
23385            b.c = c;
23386          }
23387          function C(a, b) {
23388            var c = b.f,
23389              d = new N(b, c);
23390            c.e = d;
23391            b.f = d;
23392            c = d.c = a;
23393            do (c.a = d), (c = c.c);
23394            while (c !== a);
23395          }
23396          function D(a, b) {
23397            var c = b.d,
23398              d = new ga(b, c);
23399            c.b = d;
23400            b.d = d;
23401            d.a = a;
23402            d.c = b.c;
23403            c = a;
23404            do (c.d = d), (c = c.e);
23405            while (c !== a);
23406          }
23407          function fa(a) {
23408            var b = a.h;
23409            a = a.b.h;
23410            b.b.h = a;
23411            a.b.h = b;
23412          }
23413          function F(a, b) {
23414            var c = a.c,
23415              d = c;
23416            do (d.a = b), (d = d.c);
23417            while (d !== c);
23418            c = a.f;
23419            d = a.e;
23420            d.f = c;
23421            c.e = d;
23422          }
23423          function G(a, b) {
23424            var c = a.a,
23425              d = c;
23426            do (d.d = b), (d = d.e);
23427            while (d !== c);
23428            c = a.d;
23429            d = a.b;
23430            d.d = c;
23431            c.b = d;
23432          }
23433          function ha(a) {
23434            var b = 0;
23435            Math.abs(a[1]) > Math.abs(a[0]) && (b = 1);
23436            Math.abs(a[2]) > Math.abs(a[b]) && (b = 2);
23437            return b;
23438          }
23439          var O = 4 * 1e150;
23440          function P(a, b) {
23441            a.f += b.f;
23442            a.b.f += b.b.f;
23443          }
23444          function ia(a, b, c) {
23445            a = a.a;
23446            b = b.a;
23447            c = c.a;
23448            if (b.b.a === a)
23449              return c.b.a === a
23450                ? u(b.a, c.a) ? 0 >= x(c.b.a, b.a, c.a) : 0 <= x(b.b.a, c.a, b.a)
23451                : 0 >= x(c.b.a, a, c.a);
23452            if (c.b.a === a) return 0 <= x(b.b.a, a, b.a);
23453            b = v(b.b.a, a, b.a);
23454            a = v(c.b.a, a, c.a);
23455            return b >= a;
23456          }
23457          function Q(a) {
23458            a.a.i = null;
23459            var b = a.e;
23460            b.a.c = b.c;
23461            b.c.a = b.a;
23462            a.e = null;
23463          }
23464          function ja(a, b) {
23465            I(a.a);
23466            a.c = !1;
23467            a.a = b;
23468            b.i = a;
23469          }
23470          function ka(a) {
23471            var b = a.a.a;
23472            do a = R(a);
23473            while (a.a.a === b);
23474            a.c && ((b = L(S(a).a.b, a.a.e)), ja(a, b), (a = R(a)));
23475            return a;
23476          }
23477          function la(a, b, c) {
23478            var d = new ma();
23479            d.a = c;
23480            d.e = na(a.f, b.e, d);
23481            return (c.i = d);
23482          }
23483          function oa(a, b) {
23484            switch (a.s) {
23485              case 100130:
23486                return 0 !== (b & 1);
23487              case 100131:
23488                return 0 !== b;
23489              case 100132:
23490                return 0 < b;
23491              case 100133:
23492                return 0 > b;
23493              case 100134:
23494                return 2 <= b || -2 >= b;
23495            }
23496            return !1;
23497          }
23498          function pa(a) {
23499            var b = a.a,
23500              c = b.d;
23501            c.c = a.d;
23502            c.a = b;
23503            Q(a);
23504          }
23505          function T(a, b, c) {
23506            a = b;
23507            for (b = b.a; a !== c; ) {
23508              a.c = !1;
23509              var d = S(a),
23510                e = d.a;
23511              if (e.a !== b.a) {
23512                if (!d.c) {
23513                  pa(a);
23514                  break;
23515                }
23516                e = L(b.c.b, e.b);
23517                ja(d, e);
23518              }
23519              b.c !== e && (E(J(e), e), E(b, e));
23520              pa(a);
23521              b = d.a;
23522              a = d;
23523            }
23524            return b;
23525          }
23526          function U(a, b, c, d, e, f) {
23527            var g = !0;
23528            do la(a, b, c.b), (c = c.c);
23529            while (c !== d);
23530            for (null === e && (e = S(b).a.b.c); ; ) {
23531              d = S(b);
23532              c = d.a.b;
23533              if (c.a !== e.a) break;
23534              c.c !== e && (E(J(c), c), E(J(e), c));
23535              d.f = b.f - c.f;
23536              d.d = oa(a, d.f);
23537              b.b = !0;
23538              !g && qa(a, b) && (P(c, e), Q(b), I(e));
23539              g = !1;
23540              b = d;
23541              e = c;
23542            }
23543            b.b = !0;
23544            f && ra(a, b);
23545          }
23546          function sa(a, b, c, d, e) {
23547            var f = [b.g[0], b.g[1], b.g[2]];
23548            b.d = null;
23549            b.d = a.o ? a.o(f, c, d, a.c) || null : null;
23550            null === b.d && (e ? a.n || (V(a, 100156), (a.n = !0)) : (b.d = c[0]));
23551          }
23552          function ta(a, b, c) {
23553            var d = [null, null, null, null];
23554            d[0] = b.a.d;
23555            d[1] = c.a.d;
23556            sa(a, b.a, d, [0.5, 0.5, 0, 0], !1);
23557            E(b, c);
23558          }
23559          function ua(a, b, c, d, e) {
23560            var f = Math.abs(b.b - a.b) + Math.abs(b.a - a.a),
23561              g = Math.abs(c.b - a.b) + Math.abs(c.a - a.a),
23562              h = e + 1;
23563            d[e] = 0.5 * g / (f + g);
23564            d[h] = 0.5 * f / (f + g);
23565            a.g[0] += d[e] * b.g[0] + d[h] * c.g[0];
23566            a.g[1] += d[e] * b.g[1] + d[h] * c.g[1];
23567            a.g[2] += d[e] * b.g[2] + d[h] * c.g[2];
23568          }
23569          function qa(a, b) {
23570            var c = S(b),
23571              d = b.a,
23572              e = c.a;
23573            if (u(d.a, e.a)) {
23574              if (0 < x(e.b.a, d.a, e.a)) return !1;
23575              if (!t(d.a, e.a)) K(e.b), E(d, J(e)), (b.b = c.b = !0);
23576              else if (d.a !== e.a) {
23577                var c = a.e,
23578                  f = d.a.h;
23579                if (0 <= f) {
23580                  var c = c.b,
23581                    g = c.d,
23582                    h = c.e,
23583                    k = c.c,
23584                    l = k[f];
23585                  g[l] = g[c.a];
23586                  k[g[l]] = l;
23587                  l <= --c.a &&
23588                    (1 >= l ? W(c, l) : u(h[g[l >> 1]], h[g[l]]) ? W(c, l) : va(c, l));
23589                  h[f] = null;
23590                  k[f] = c.b;
23591                  c.b = f;
23592                } else
23593                  for (c.c[-(f + 1)] = null; 0 < c.a && null === c.c[c.d[c.a - 1]]; ) --c.a;
23594                ta(a, J(e), d);
23595              }
23596            } else {
23597              if (0 > x(d.b.a, e.a, d.a)) return !1;
23598              R(b).b = b.b = !0;
23599              K(d.b);
23600              E(J(e), d);
23601            }
23602            return !0;
23603          }
23604          function wa(a, b) {
23605            var c = S(b),
23606              d = b.a,
23607              e = c.a,
23608              f = d.a,
23609              g = e.a,
23610              h = d.b.a,
23611              k = e.b.a,
23612              l = new N();
23613            x(h, a.a, f);
23614            x(k, a.a, g);
23615            if (f === g || Math.min(f.a, h.a) > Math.max(g.a, k.a)) return !1;
23616            if (u(f, g)) {
23617              if (0 < x(k, f, g)) return !1;
23618            } else if (0 > x(h, g, f)) return !1;
23619            var r = h,
23620              p = f,
23621              q = k,
23622              y = g,
23623              m,
23624              w;
23625            u(r, p) || ((m = r), (r = p), (p = m));
23626            u(q, y) || ((m = q), (q = y), (y = m));
23627            u(r, q) || ((m = r), (r = q), (q = m), (m = p), (p = y), (y = m));
23628            u(q, p)
23629              ? u(p, y)
23630                ? ((m = v(r, q, p)),
23631                  (w = v(q, p, y)),
23632                  0 > m + w && ((m = -m), (w = -w)),
23633                  (l.b = A(m, q.b, w, p.b)))
23634                : ((m = x(r, q, p)),
23635                  (w = -x(r, y, p)),
23636                  0 > m + w && ((m = -m), (w = -w)),
23637                  (l.b = A(m, q.b, w, y.b)))
23638              : (l.b = (q.b + p.b) / 2);
23639            z(r, p) || ((m = r), (r = p), (p = m));
23640            z(q, y) || ((m = q), (q = y), (y = m));
23641            z(r, q) || ((m = r), (r = q), (q = m), (m = p), (p = y), (y = m));
23642            z(q, p)
23643              ? z(p, y)
23644                ? ((m = aa(r, q, p)),
23645                  (w = aa(q, p, y)),
23646                  0 > m + w && ((m = -m), (w = -w)),
23647                  (l.a = A(m, q.a, w, p.a)))
23648                : ((m = ba(r, q, p)),
23649                  (w = -ba(r, y, p)),
23650                  0 > m + w && ((m = -m), (w = -w)),
23651                  (l.a = A(m, q.a, w, y.a)))
23652              : (l.a = (q.a + p.a) / 2);
23653            u(l, a.a) && ((l.b = a.a.b), (l.a = a.a.a));
23654            r = u(f, g) ? f : g;
23655            u(r, l) && ((l.b = r.b), (l.a = r.a));
23656            if (t(l, f) || t(l, g)) return qa(a, b), !1;
23657            if ((!t(h, a.a) && 0 <= x(h, a.a, l)) || (!t(k, a.a) && 0 >= x(k, a.a, l))) {
23658              if (k === a.a)
23659                return (
23660                  K(d.b),
23661                  E(e.b, d),
23662                  (b = ka(b)),
23663                  (d = S(b).a),
23664                  T(a, S(b), c),
23665                  U(a, b, J(d), d, d, !0),
23666                  !0
23667                );
23668              if (h === a.a) {
23669                K(e.b);
23670                E(d.e, J(e));
23671                f = c = b;
23672                g = f.a.b.a;
23673                do f = R(f);
23674                while (f.a.b.a === g);
23675                b = f;
23676                f = S(b).a.b.c;
23677                c.a = J(e);
23678                e = T(a, c, null);
23679                U(a, b, e.c, d.b.c, f, !0);
23680                return !0;
23681              }
23682              0 <= x(h, a.a, l) &&
23683                ((R(b).b = b.b = !0), K(d.b), (d.a.b = a.a.b), (d.a.a = a.a.a));
23684              0 >= x(k, a.a, l) &&
23685                ((b.b = c.b = !0), K(e.b), (e.a.b = a.a.b), (e.a.a = a.a.a));
23686              return !1;
23687            }
23688            K(d.b);
23689            K(e.b);
23690            E(J(e), d);
23691            d.a.b = l.b;
23692            d.a.a = l.a;
23693            d.a.h = xa(a.e, d.a);
23694            d = d.a;
23695            e = [0, 0, 0, 0];
23696            l = [f.d, h.d, g.d, k.d];
23697            d.g[0] = d.g[1] = d.g[2] = 0;
23698            ua(d, f, h, e, 0);
23699            ua(d, g, k, e, 2);
23700            sa(a, d, l, e, !0);
23701            R(b).b = b.b = c.b = !0;
23702            return !1;
23703          }
23704          function ra(a, b) {
23705            for (var c = S(b); ; ) {
23706              for (; c.b; ) (b = c), (c = S(c));
23707              if (!b.b && ((c = b), (b = R(b)), null === b || !b.b)) break;
23708              b.b = !1;
23709              var d = b.a,
23710                e = c.a,
23711                f;
23712              if ((f = d.b.a !== e.b.a))
23713                a: {
23714                  f = b;
23715                  var g = S(f),
23716                    h = f.a,
23717                    k = g.a,
23718                    l = void 0;
23719                  if (u(h.b.a, k.b.a)) {
23720                    if (0 > x(h.b.a, k.b.a, h.a)) {
23721                      f = !1;
23722                      break a;
23723                    }
23724                    R(f).b = f.b = !0;
23725                    l = K(h);
23726                    E(k.b, l);
23727                    l.d.c = f.d;
23728                  } else {
23729                    if (0 < x(k.b.a, h.b.a, k.a)) {
23730                      f = !1;
23731                      break a;
23732                    }
23733                    f.b = g.b = !0;
23734                    l = K(k);
23735                    E(h.e, k.b);
23736                    l.b.d.c = f.d;
23737                  }
23738                  f = !0;
23739                }
23740              f &&
23741                (c.c
23742                  ? (Q(c), I(e), (c = S(b)), (e = c.a))
23743                  : b.c && (Q(b), I(d), (b = R(c)), (d = b.a)));
23744              if (d.a !== e.a)
23745                if (d.b.a === e.b.a || b.c || c.c || (d.b.a !== a.a && e.b.a !== a.a))
23746                  qa(a, b);
23747                else if (wa(a, b)) break;
23748              d.a === e.a && d.b.a === e.b.a && (P(e, d), Q(b), I(d), (b = R(c)));
23749            }
23750          }
23751          function ya(a, b) {
23752            a.a = b;
23753            for (var c = b.c; null === c.i; )
23754              if (((c = c.c), c === b.c)) {
23755                var c = a,
23756                  d = b,
23757                  e = new ma();
23758                e.a = d.c.b;
23759                var f = c.f,
23760                  g = f.a;
23761                do g = g.a;
23762                while (null !== g.b && !f.c(f.b, e, g.b));
23763                var f = g.b,
23764                  h = S(f),
23765                  e = f.a,
23766                  g = h.a;
23767                if (0 === x(e.b.a, d, e.a))
23768                  (e = f.a),
23769                    t(e.a, d) ||
23770                      t(e.b.a, d) ||
23771                      (K(e.b), f.c && (I(e.c), (f.c = !1)), E(d.c, e), ya(c, d));
23772                else {
23773                  var k = u(g.b.a, e.b.a) ? f : h,
23774                    h = void 0;
23775                  f.d || k.c
23776                    ? (k === f ? (h = L(d.c.b, e.e)) : (h = L(g.b.c.b, d.c).b),
23777                      k.c
23778                        ? ja(k, h)
23779                        : ((e = c),
23780                          (f = la(c, f, h)),
23781                          (f.f = R(f).f + f.a.f),
23782                          (f.d = oa(e, f.f))),
23783                      ya(c, d))
23784                    : U(c, f, d.c, d.c, null, !0);
23785                }
23786                return;
23787              }
23788            c = ka(c.i);
23789            e = S(c);
23790            f = e.a;
23791            e = T(a, e, null);
23792            if (e.c === f) {
23793              var f = e,
23794                e = f.c,
23795                g = S(c),
23796                h = c.a,
23797                k = g.a,
23798                l = !1;
23799              h.b.a !== k.b.a && wa(a, c);
23800              t(h.a, a.a) &&
23801                (E(J(e), h), (c = ka(c)), (e = S(c).a), T(a, S(c), g), (l = !0));
23802              t(k.a, a.a) && (E(f, J(k)), (f = T(a, g, null)), (l = !0));
23803              l
23804                ? U(a, c, f.c, e, e, !0)
23805                : (u(k.a, h.a) ? (d = J(k)) : (d = h),
23806                  (d = L(f.c.b, d)),
23807                  U(a, c, d, d.c, d.c, !1),
23808                  (d.b.i.c = !0),
23809                  ra(a, c));
23810            } else U(a, c, e.c, f, f, !0);
23811          }
23812          function za(a, b) {
23813            var c = new ma(),
23814              d = ea(a.b);
23815            d.a.b = O;
23816            d.a.a = b;
23817            d.b.a.b = -O;
23818            d.b.a.a = b;
23819            a.a = d.b.a;
23820            c.a = d;
23821            c.f = 0;
23822            c.d = !1;
23823            c.c = !1;
23824            c.h = !0;
23825            c.b = !1;
23826            d = a.f;
23827            d = na(d, d.a, c);
23828            c.e = d;
23829          }
23830          function Aa(a) {
23831            this.a = new Ba();
23832            this.b = a;
23833            this.c = ia;
23834          }
23835          function na(a, b, c) {
23836            do b = b.c;
23837            while (null !== b.b && !a.c(a.b, b.b, c));
23838            a = new Ba(c, b.a, b);
23839            b.a.c = a;
23840            return (b.a = a);
23841          }
23842          function Ba(a, b, c) {
23843            this.b = a || null;
23844            this.a = b || this;
23845            this.c = c || this;
23846          }
23847          function X() {
23848            this.d = Y;
23849            this.p = this.b = this.q = null;
23850            this.j = [0, 0, 0];
23851            this.s = 100130;
23852            this.n = !1;
23853            this.o = this.a = this.e = this.f = null;
23854            this.m = !1;
23855            this.c = this.r = this.i = this.k = this.l = this.h = null;
23856          }
23857          var Y = 0;
23858          n = X.prototype;
23859          n.x = function() {
23860            Z(this, Y);
23861          };
23862          n.B = function(a, b) {
23863            switch (a) {
23864              case 100142:
23865                return;
23866              case 100140:
23867                switch (b) {
23868                  case 100130:
23869                  case 100131:
23870                  case 100132:
23871                  case 100133:
23872                  case 100134:
23873                    this.s = b;
23874                    return;
23875                }
23876                break;
23877              case 100141:
23878                this.m = !!b;
23879                return;
23880              default:
23881                V(this, 100900);
23882                return;
23883            }
23884            V(this, 100901);
23885          };
23886          n.y = function(a) {
23887            switch (a) {
23888              case 100142:
23889                return 0;
23890              case 100140:
23891                return this.s;
23892              case 100141:
23893                return this.m;
23894              default:
23895                V(this, 100900);
23896            }
23897            return !1;
23898          };
23899          n.A = function(a, b, c) {
23900            this.j[0] = a;
23901            this.j[1] = b;
23902            this.j[2] = c;
23903          };
23904          n.z = function(a, b) {
23905            var c = b ? b : null;
23906            switch (a) {
23907              case 100100:
23908              case 100106:
23909                this.h = c;
23910                break;
23911              case 100104:
23912              case 100110:
23913                this.l = c;
23914                break;
23915              case 100101:
23916              case 100107:
23917                this.k = c;
23918                break;
23919              case 100102:
23920              case 100108:
23921                this.i = c;
23922                break;
23923              case 100103:
23924              case 100109:
23925                this.p = c;
23926                break;
23927              case 100105:
23928              case 100111:
23929                this.o = c;
23930                break;
23931              case 100112:
23932                this.r = c;
23933                break;
23934              default:
23935                V(this, 100900);
23936            }
23937          };
23938          n.C = function(a, b) {
23939            var c = !1,
23940              d = [0, 0, 0];
23941            Z(this, 2);
23942            for (var e = 0; 3 > e; ++e) {
23943              var f = a[e];
23944              -1e150 > f && ((f = -1e150), (c = !0));
23945              1e150 < f && ((f = 1e150), (c = !0));
23946              d[e] = f;
23947            }
23948            c && V(this, 100155);
23949            c = this.q;
23950            null === c ? ((c = ea(this.b)), E(c, c.b)) : (K(c), (c = c.e));
23951            c.a.d = b;
23952            c.a.g[0] = d[0];
23953            c.a.g[1] = d[1];
23954            c.a.g[2] = d[2];
23955            c.f = 1;
23956            c.b.f = -1;
23957            this.q = c;
23958          };
23959          n.u = function(a) {
23960            Z(this, Y);
23961            this.d = 1;
23962            this.b = new Ca();
23963            this.c = a;
23964          };
23965          n.t = function() {
23966            Z(this, 1);
23967            this.d = 2;
23968            this.q = null;
23969          };
23970          n.v = function() {
23971            Z(this, 2);
23972            this.d = 1;
23973          };
23974          n.w = function() {
23975            Z(this, 1);
23976            this.d = Y;
23977            var a = this.j[0],
23978              b = this.j[1],
23979              c = this.j[2],
23980              d = !1,
23981              e = [a, b, c];
23982            if (0 === a && 0 === b && 0 === c) {
23983              for (
23984                var b = [-2 * 1e150, -2 * 1e150, -2 * 1e150],
23985                  f = [2 * 1e150, 2 * 1e150, 2 * 1e150],
23986                  c = [],
23987                  g = [],
23988                  d = this.b.c,
23989                  a = d.e;
23990                a !== d;
23991                a = a.e
23992              )
23993                for (var h = 0; 3 > h; ++h) {
23994                  var k = a.g[h];
23995                  k < f[h] && ((f[h] = k), (g[h] = a));
23996                  k > b[h] && ((b[h] = k), (c[h] = a));
23997                }
23998              a = 0;
23999              b[1] - f[1] > b[0] - f[0] && (a = 1);
24000              b[2] - f[2] > b[a] - f[a] && (a = 2);
24001              if (f[a] >= b[a]) (e[0] = 0), (e[1] = 0), (e[2] = 1);
24002              else {
24003                b = 0;
24004                f = g[a];
24005                c = c[a];
24006                g = [0, 0, 0];
24007                f = [f.g[0] - c.g[0], f.g[1] - c.g[1], f.g[2] - c.g[2]];
24008                h = [0, 0, 0];
24009                for (a = d.e; a !== d; a = a.e)
24010                  (h[0] = a.g[0] - c.g[0]),
24011                    (h[1] = a.g[1] - c.g[1]),
24012                    (h[2] = a.g[2] - c.g[2]),
24013                    (g[0] = f[1] * h[2] - f[2] * h[1]),
24014                    (g[1] = f[2] * h[0] - f[0] * h[2]),
24015                    (g[2] = f[0] * h[1] - f[1] * h[0]),
24016                    (k = g[0] * g[0] + g[1] * g[1] + g[2] * g[2]),
24017                    k > b && ((b = k), (e[0] = g[0]), (e[1] = g[1]), (e[2] = g[2]));
24018                0 >= b && ((e[0] = e[1] = e[2] = 0), (e[ha(f)] = 1));
24019              }
24020              d = !0;
24021            }
24022            g = ha(e);
24023            a = this.b.c;
24024            b = (g + 1) % 3;
24025            c = (g + 2) % 3;
24026            g = 0 < e[g] ? 1 : -1;
24027            for (e = a.e; e !== a; e = e.e) (e.b = e.g[b]), (e.a = g * e.g[c]);
24028            if (d) {
24029              e = 0;
24030              d = this.b.a;
24031              for (a = d.b; a !== d; a = a.b)
24032                if (((b = a.a), !(0 >= b.f))) {
24033                  do (e += (b.a.b - b.b.a.b) * (b.a.a + b.b.a.a)), (b = b.e);
24034                  while (b !== a.a);
24035                }
24036              if (0 > e) for (e = this.b.c, d = e.e; d !== e; d = d.e) d.a = -d.a;
24037            }
24038            this.n = !1;
24039            e = this.b.b;
24040            for (a = e.h; a !== e; a = d)
24041              if (
24042                ((d = a.h),
24043                (b = a.e),
24044                t(a.a, a.b.a) && a.e.e !== a && (ta(this, b, a), I(a), (a = b), (b = a.e)),
24045                b.e === a)
24046              ) {
24047                if (b !== a) {
24048                  if (b === d || b === d.b) d = d.h;
24049                  I(b);
24050                }
24051                if (a === d || a === d.b) d = d.h;
24052                I(a);
24053              }
24054            this.e = e = new Da();
24055            d = this.b.c;
24056            for (a = d.e; a !== d; a = a.e) a.h = xa(e, a);
24057            Ea(e);
24058            this.f = new Aa(this);
24059            za(this, -O);
24060            for (za(this, O); null !== (e = Fa(this.e)); ) {
24061              for (;;) {
24062                a: if (((a = this.e), 0 === a.a)) d = Ga(a.b);
24063                else if (
24064                  ((d = a.c[a.d[a.a - 1]]), 0 !== a.b.a && ((a = Ga(a.b)), u(a, d)))
24065                ) {
24066                  d = a;
24067                  break a;
24068                }
24069                if (null === d || !t(d, e)) break;
24070                d = Fa(this.e);
24071                ta(this, e.c, d.c);
24072              }
24073              ya(this, e);
24074            }
24075            this.a = this.f.a.a.b.a.a;
24076            for (e = 0; null !== (d = this.f.a.a.b); ) d.h || ++e, Q(d);
24077            this.f = null;
24078            e = this.e;
24079            e.b = null;
24080            e.d = null;
24081            this.e = e.c = null;
24082            e = this.b;
24083            for (a = e.a.b; a !== e.a; a = d)
24084              (d = a.b), (a = a.a), a.e.e === a && (P(a.c, a), I(a));
24085            if (!this.n) {
24086              e = this.b;
24087              if (this.m)
24088                for (a = e.b.h; a !== e.b; a = d)
24089                  (d = a.h), a.b.d.c !== a.d.c ? (a.f = a.d.c ? 1 : -1) : I(a);
24090              else
24091                for (a = e.a.b; a !== e.a; a = d)
24092                  if (((d = a.b), a.c)) {
24093                    for (a = a.a; u(a.b.a, a.a); a = a.c.b);
24094                    for (; u(a.a, a.b.a); a = a.e);
24095                    b = a.c.b;
24096                    for (c = void 0; a.e !== b; )
24097                      if (u(a.b.a, b.a)) {
24098                        for (; b.e !== a && (ca(b.e) || 0 >= x(b.a, b.b.a, b.e.b.a)); )
24099                          (c = L(b.e, b)), (b = c.b);
24100                        b = b.c.b;
24101                      } else {
24102                        for (; b.e !== a && (da(a.c.b) || 0 <= x(a.b.a, a.a, a.c.b.a)); )
24103                          (c = L(a, a.c.b)), (a = c.b);
24104                        a = a.e;
24105                      }
24106                    for (; b.e.e !== a; ) (c = L(b.e, b)), (b = c.b);
24107                  }
24108              if (this.h || this.i || this.k || this.l)
24109                if (this.m)
24110                  for (e = this.b, d = e.a.b; d !== e.a; d = d.b) {
24111                    if (d.c) {
24112                      this.h && this.h(2, this.c);
24113                      a = d.a;
24114                      do this.k && this.k(a.a.d, this.c), (a = a.e);
24115                      while (a !== d.a);
24116                      this.i && this.i(this.c);
24117                    }
24118                  }
24119                else {
24120                  e = this.b;
24121                  d = !!this.l;
24122                  a = !1;
24123                  b = -1;
24124                  for (c = e.a.d; c !== e.a; c = c.d)
24125                    if (c.c) {
24126                      a || (this.h && this.h(4, this.c), (a = !0));
24127                      g = c.a;
24128                      do
24129                        d &&
24130                          ((f = g.b.d.c ? 0 : 1),
24131                          b !== f && ((b = f), this.l && this.l(!!b, this.c))),
24132                          this.k && this.k(g.a.d, this.c),
24133                          (g = g.e);
24134                      while (g !== c.a);
24135                    }
24136                  a && this.i && this.i(this.c);
24137                }
24138              if (this.r) {
24139                e = this.b;
24140                for (a = e.a.b; a !== e.a; a = d)
24141                  if (((d = a.b), !a.c)) {
24142                    b = a.a;
24143                    c = b.e;
24144                    g = void 0;
24145                    do
24146                      (g = c),
24147                        (c = g.e),
24148                        (g.d = null),
24149                        null === g.b.d &&
24150                          (g.c === g ? F(g.a, null) : ((g.a.c = g.c), H(g, J(g))),
24151                          (f = g.b),
24152                          f.c === f ? F(f.a, null) : ((f.a.c = f.c), H(f, J(f))),
24153                          fa(g));
24154                    while (g !== b);
24155                    b = a.d;
24156                    a = a.b;
24157                    a.d = b;
24158                    b.b = a;
24159                  }
24160                this.r(this.b);
24161                this.c = this.b = null;
24162                return;
24163              }
24164            }
24165            this.b = this.c = null;
24166          };
24167          function Z(a, b) {
24168            if (a.d !== b)
24169              for (; a.d !== b; )
24170                if (a.d < b)
24171                  switch (a.d) {
24172                    case Y:
24173                      V(a, 100151);
24174                      a.u(null);
24175                      break;
24176                    case 1:
24177                      V(a, 100152), a.t();
24178                  }
24179                else
24180                  switch (a.d) {
24181                    case 2:
24182                      V(a, 100154);
24183                      a.v();
24184                      break;
24185                    case 1:
24186                      V(a, 100153), a.w();
24187                  }
24188          }
24189          function V(a, b) {
24190            a.p && a.p(b, a.c);
24191          }
24192          function ga(a, b) {
24193            this.b = a || this;
24194            this.d = b || this;
24195            this.a = null;
24196            this.c = !1;
24197          }
24198          function M() {
24199            this.h = this;
24200            this.i = this.d = this.a = this.e = this.c = this.b = null;
24201            this.f = 0;
24202          }
24203          function J(a) {
24204            return a.b.e;
24205          }
24206          function Ca() {
24207            this.c = new N();
24208            this.a = new ga();
24209            this.b = new M();
24210            this.d = new M();
24211            this.b.b = this.d;
24212            this.d.b = this.b;
24213          }
24214          function N(a, b) {
24215            this.e = a || this;
24216            this.f = b || this;
24217            this.d = this.c = null;
24218            this.g = [0, 0, 0];
24219            this.h = this.a = this.b = 0;
24220          }
24221          function Da() {
24222            this.c = [];
24223            this.d = null;
24224            this.a = 0;
24225            this.e = !1;
24226            this.b = new Ha();
24227          }
24228          function Ea(a) {
24229            a.d = [];
24230            for (var b = 0; b < a.a; b++) a.d[b] = b;
24231            a.d.sort(
24232              (function(a) {
24233                return function(b, e) {
24234                  return u(a[b], a[e]) ? 1 : -1;
24235                };
24236              })(a.c)
24237            );
24238            a.e = !0;
24239            Ia(a.b);
24240          }
24241          function xa(a, b) {
24242            if (a.e) {
24243              var c = a.b,
24244                d = ++c.a;
24245              2 * d > c.f && ((c.f *= 2), (c.c = Ja(c.c, c.f + 1)));
24246              var e;
24247              0 === c.b ? (e = d) : ((e = c.b), (c.b = c.c[c.b]));
24248              c.e[e] = b;
24249              c.c[e] = d;
24250              c.d[d] = e;
24251              c.h && va(c, d);
24252              return e;
24253            }
24254            c = a.a++;
24255            a.c[c] = b;
24256            return -(c + 1);
24257          }
24258          function Fa(a) {
24259            if (0 === a.a) return Ka(a.b);
24260            var b = a.c[a.d[a.a - 1]];
24261            if (0 !== a.b.a && u(Ga(a.b), b)) return Ka(a.b);
24262            do --a.a;
24263            while (0 < a.a && null === a.c[a.d[a.a - 1]]);
24264            return b;
24265          }
24266          function Ha() {
24267            this.d = Ja([0], 33);
24268            this.e = [null, null];
24269            this.c = [0, 0];
24270            this.a = 0;
24271            this.f = 32;
24272            this.b = 0;
24273            this.h = !1;
24274            this.d[1] = 1;
24275          }
24276          function Ja(a, b) {
24277            for (var c = Array(b), d = 0; d < a.length; d++) c[d] = a[d];
24278            for (; d < b; d++) c[d] = 0;
24279            return c;
24280          }
24281          function Ia(a) {
24282            for (var b = a.a; 1 <= b; --b) W(a, b);
24283            a.h = !0;
24284          }
24285          function Ga(a) {
24286            return a.e[a.d[1]];
24287          }
24288          function Ka(a) {
24289            var b = a.d,
24290              c = a.e,
24291              d = a.c,
24292              e = b[1],
24293              f = c[e];
24294            0 < a.a &&
24295              ((b[1] = b[a.a]),
24296              (d[b[1]] = 1),
24297              (c[e] = null),
24298              (d[e] = a.b),
24299              (a.b = e),
24300              0 < --a.a && W(a, 1));
24301            return f;
24302          }
24303          function W(a, b) {
24304            for (var c = a.d, d = a.e, e = a.c, f = b, g = c[f]; ; ) {
24305              var h = f << 1;
24306              h < a.a && u(d[c[h + 1]], d[c[h]]) && (h += 1);
24307              var k = c[h];
24308              if (h > a.a || u(d[g], d[k])) {
24309                c[f] = g;
24310                e[g] = f;
24311                break;
24312              }
24313              c[f] = k;
24314              e[k] = f;
24315              f = h;
24316            }
24317          }
24318          function va(a, b) {
24319            for (var c = a.d, d = a.e, e = a.c, f = b, g = c[f]; ; ) {
24320              var h = f >> 1,
24321                k = c[h];
24322              if (0 === h || u(d[k], d[g])) {
24323                c[f] = g;
24324                e[g] = f;
24325                break;
24326              }
24327              c[f] = k;
24328              e[k] = f;
24329              f = h;
24330            }
24331          }
24332          function ma() {
24333            this.e = this.a = null;
24334            this.f = 0;
24335            this.c = this.b = this.h = this.d = !1;
24336          }
24337          function S(a) {
24338            return a.e.c.b;
24339          }
24340          function R(a) {
24341            return a.e.a.b;
24342          }
24343          this.libtess = {
24344            GluTesselator: X,
24345            windingRule: {
24346              GLU_TESS_WINDING_ODD: 100130,
24347              GLU_TESS_WINDING_NONZERO: 100131,
24348              GLU_TESS_WINDING_POSITIVE: 100132,
24349              GLU_TESS_WINDING_NEGATIVE: 100133,
24350              GLU_TESS_WINDING_ABS_GEQ_TWO: 100134
24351            },
24352            primitiveType: {
24353              GL_LINE_LOOP: 2,
24354              GL_TRIANGLES: 4,
24355              GL_TRIANGLE_STRIP: 5,
24356              GL_TRIANGLE_FAN: 6
24357            },
24358            errorType: {
24359              GLU_TESS_MISSING_BEGIN_POLYGON: 100151,
24360              GLU_TESS_MISSING_END_POLYGON: 100153,
24361              GLU_TESS_MISSING_BEGIN_CONTOUR: 100152,
24362              GLU_TESS_MISSING_END_CONTOUR: 100154,
24363              GLU_TESS_COORD_TOO_LARGE: 100155,
24364              GLU_TESS_NEED_COMBINE_CALLBACK: 100156
24365            },
24366            gluEnum: {
24367              GLU_TESS_MESH: 100112,
24368              GLU_TESS_TOLERANCE: 100142,
24369              GLU_TESS_WINDING_RULE: 100140,
24370              GLU_TESS_BOUNDARY_ONLY: 100141,
24371              GLU_INVALID_ENUM: 100900,
24372              GLU_INVALID_VALUE: 100901,
24373              GLU_TESS_BEGIN: 100100,
24374              GLU_TESS_VERTEX: 100101,
24375              GLU_TESS_END: 100102,
24376              GLU_TESS_ERROR: 100103,
24377              GLU_TESS_EDGE_FLAG: 100104,
24378              GLU_TESS_COMBINE: 100105,
24379              GLU_TESS_BEGIN_DATA: 100106,
24380              GLU_TESS_VERTEX_DATA: 100107,
24381              GLU_TESS_END_DATA: 100108,
24382              GLU_TESS_ERROR_DATA: 100109,
24383              GLU_TESS_EDGE_FLAG_DATA: 100110,
24384              GLU_TESS_COMBINE_DATA: 100111
24385            }
24386          };
24387          X.prototype.gluDeleteTess = X.prototype.x;
24388          X.prototype.gluTessProperty = X.prototype.B;
24389          X.prototype.gluGetTessProperty = X.prototype.y;
24390          X.prototype.gluTessNormal = X.prototype.A;
24391          X.prototype.gluTessCallback = X.prototype.z;
24392          X.prototype.gluTessVertex = X.prototype.C;
24393          X.prototype.gluTessBeginPolygon = X.prototype.u;
24394          X.prototype.gluTessBeginContour = X.prototype.t;
24395          X.prototype.gluTessEndContour = X.prototype.v;
24396          X.prototype.gluTessEndPolygon = X.prototype.w;
24397          if (typeof module !== 'undefined') {
24398            module.exports = this.libtess;
24399          }
24400        },
24401        {}
24402      ],
24403      33: [
24404        function(_dereq_, module, exports) {
24405          // (c) Dean McNamee <[email protected]>, 2013.
24406          //
24407          // https://github.com/deanm/omggif
24408          //
24409          // Permission is hereby granted, free of charge, to any person obtaining a copy
24410          // of this software and associated documentation files (the "Software"), to
24411          // deal in the Software without restriction, including without limitation the
24412          // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
24413          // sell copies of the Software, and to permit persons to whom the Software is
24414          // furnished to do so, subject to the following conditions:
24415          //
24416          // The above copyright notice and this permission notice shall be included in
24417          // all copies or substantial portions of the Software.
24418          //
24419          // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24420          // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24421          // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24422          // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24423          // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24424          // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24425          // IN THE SOFTWARE.
24426          //
24427          // omggif is a JavaScript implementation of a GIF 89a encoder and decoder,
24428          // including animation and compression.  It does not rely on any specific
24429          // underlying system, so should run in the browser, Node, or Plask.
24430
24431          'use strict';
24432
24433          function GifWriter(buf, width, height, gopts) {
24434            var p = 0;
24435
24436            var gopts = gopts === undefined ? {} : gopts;
24437            var loop_count = gopts.loop === undefined ? null : gopts.loop;
24438            var global_palette = gopts.palette === undefined ? null : gopts.palette;
24439
24440            if (width <= 0 || height <= 0 || width > 65535 || height > 65535)
24441              throw new Error('Width/Height invalid.');
24442
24443            function check_palette_and_num_colors(palette) {
24444              var num_colors = palette.length;
24445              if (num_colors < 2 || num_colors > 256 || num_colors & (num_colors - 1)) {
24446                throw new Error(
24447                  'Invalid code/color length, must be power of 2 and 2 .. 256.'
24448                );
24449              }
24450              return num_colors;
24451            }
24452
24453            // - Header.
24454            buf[p++] = 0x47;
24455            buf[p++] = 0x49;
24456            buf[p++] = 0x46; // GIF
24457            buf[p++] = 0x38;
24458            buf[p++] = 0x39;
24459            buf[p++] = 0x61; // 89a
24460
24461            // Handling of Global Color Table (palette) and background index.
24462            var gp_num_colors_pow2 = 0;
24463            var background = 0;
24464            if (global_palette !== null) {
24465              var gp_num_colors = check_palette_and_num_colors(global_palette);
24466              while ((gp_num_colors >>= 1)) ++gp_num_colors_pow2;
24467              gp_num_colors = 1 << gp_num_colors_pow2;
24468              --gp_num_colors_pow2;
24469              if (gopts.background !== undefined) {
24470                background = gopts.background;
24471                if (background >= gp_num_colors)
24472                  throw new Error('Background index out of range.');
24473                // The GIF spec states that a background index of 0 should be ignored, so
24474                // this is probably a mistake and you really want to set it to another
24475                // slot in the palette.  But actually in the end most browsers, etc end
24476                // up ignoring this almost completely (including for dispose background).
24477                if (background === 0)
24478                  throw new Error('Background index explicitly passed as 0.');
24479              }
24480            }
24481
24482            // - Logical Screen Descriptor.
24483            // NOTE(deanm): w/h apparently ignored by implementations, but set anyway.
24484            buf[p++] = width & 0xff;
24485            buf[p++] = (width >> 8) & 0xff;
24486            buf[p++] = height & 0xff;
24487            buf[p++] = (height >> 8) & 0xff;
24488            // NOTE: Indicates 0-bpp original color resolution (unused?).
24489            buf[p++] =
24490              (global_palette !== null ? 0x80 : 0) | gp_num_colors_pow2; // Global Color Table Flag. // NOTE: No sort flag (unused?).
24491            buf[p++] = background; // Background Color Index.
24492            buf[p++] = 0; // Pixel aspect ratio (unused?).
24493
24494            // - Global Color Table
24495            if (global_palette !== null) {
24496              for (var i = 0, il = global_palette.length; i < il; ++i) {
24497                var rgb = global_palette[i];
24498                buf[p++] = (rgb >> 16) & 0xff;
24499                buf[p++] = (rgb >> 8) & 0xff;
24500                buf[p++] = rgb & 0xff;
24501              }
24502            }
24503
24504            if (loop_count !== null) {
24505              // Netscape block for looping.
24506              if (loop_count < 0 || loop_count > 65535)
24507                throw new Error('Loop count invalid.');
24508              // Extension code, label, and length.
24509              buf[p++] = 0x21;
24510              buf[p++] = 0xff;
24511              buf[p++] = 0x0b;
24512              // NETSCAPE2.0
24513              buf[p++] = 0x4e;
24514              buf[p++] = 0x45;
24515              buf[p++] = 0x54;
24516              buf[p++] = 0x53;
24517              buf[p++] = 0x43;
24518              buf[p++] = 0x41;
24519              buf[p++] = 0x50;
24520              buf[p++] = 0x45;
24521              buf[p++] = 0x32;
24522              buf[p++] = 0x2e;
24523              buf[p++] = 0x30;
24524              // Sub-block
24525              buf[p++] = 0x03;
24526              buf[p++] = 0x01;
24527              buf[p++] = loop_count & 0xff;
24528              buf[p++] = (loop_count >> 8) & 0xff;
24529              buf[p++] = 0x00; // Terminator.
24530            }
24531
24532            var ended = false;
24533
24534            this.addFrame = function(x, y, w, h, indexed_pixels, opts) {
24535              if (ended === true) {
24536                --p;
24537                ended = false;
24538              } // Un-end.
24539
24540              opts = opts === undefined ? {} : opts;
24541
24542              // TODO(deanm): Bounds check x, y.  Do they need to be within the virtual
24543              // canvas width/height, I imagine?
24544              if (x < 0 || y < 0 || x > 65535 || y > 65535) throw new Error('x/y invalid.');
24545
24546              if (w <= 0 || h <= 0 || w > 65535 || h > 65535)
24547                throw new Error('Width/Height invalid.');
24548
24549              if (indexed_pixels.length < w * h)
24550                throw new Error('Not enough pixels for the frame size.');
24551
24552              var using_local_palette = true;
24553              var palette = opts.palette;
24554              if (palette === undefined || palette === null) {
24555                using_local_palette = false;
24556                palette = global_palette;
24557              }
24558
24559              if (palette === undefined || palette === null)
24560                throw new Error('Must supply either a local or global palette.');
24561
24562              var num_colors = check_palette_and_num_colors(palette);
24563
24564              // Compute the min_code_size (power of 2), destroying num_colors.
24565              var min_code_size = 0;
24566              while ((num_colors >>= 1)) ++min_code_size;
24567              num_colors = 1 << min_code_size; // Now we can easily get it back.
24568
24569              var delay = opts.delay === undefined ? 0 : opts.delay;
24570
24571              // From the spec:
24572              //     0 -   No disposal specified. The decoder is
24573              //           not required to take any action.
24574              //     1 -   Do not dispose. The graphic is to be left
24575              //           in place.
24576              //     2 -   Restore to background color. The area used by the
24577              //           graphic must be restored to the background color.
24578              //     3 -   Restore to previous. The decoder is required to
24579              //           restore the area overwritten by the graphic with
24580              //           what was there prior to rendering the graphic.
24581              //  4-7 -    To be defined.
24582              // NOTE(deanm): Dispose background doesn't really work, apparently most
24583              // browsers ignore the background palette index and clear to transparency.
24584              var disposal = opts.disposal === undefined ? 0 : opts.disposal;
24585              if (disposal < 0 || disposal > 3)
24586                // 4-7 is reserved.
24587                throw new Error('Disposal out of range.');
24588
24589              var use_transparency = false;
24590              var transparent_index = 0;
24591              if (opts.transparent !== undefined && opts.transparent !== null) {
24592                use_transparency = true;
24593                transparent_index = opts.transparent;
24594                if (transparent_index < 0 || transparent_index >= num_colors)
24595                  throw new Error('Transparent color index.');
24596              }
24597
24598              if (disposal !== 0 || use_transparency || delay !== 0) {
24599                // - Graphics Control Extension
24600                buf[p++] = 0x21;
24601                buf[p++] = 0xf9; // Extension / Label.
24602                buf[p++] = 4; // Byte size.
24603
24604                buf[p++] = (disposal << 2) | (use_transparency === true ? 1 : 0);
24605                buf[p++] = delay & 0xff;
24606                buf[p++] = (delay >> 8) & 0xff;
vendor: 5,225 bytes, lines 24607-24726
24607                buf[p++] = transparent_index; // Transparent color index.
24608                buf[p++] = 0; // Block Terminator.
24609              }
24610
24611              // - Image Descriptor
24612              buf[p++] = 0x2c; // Image Seperator.
24613              buf[p++] = x & 0xff;
24614              buf[p++] = (x >> 8) & 0xff; // Left.
24615              buf[p++] = y & 0xff;
24616              buf[p++] = (y >> 8) & 0xff; // Top.
24617              buf[p++] = w & 0xff;
24618              buf[p++] = (w >> 8) & 0xff;
24619              buf[p++] = h & 0xff;
24620              buf[p++] = (h >> 8) & 0xff;
24621              // NOTE: No sort flag (unused?).
24622              // TODO(deanm): Support interlace.
24623              buf[p++] = using_local_palette === true ? 0x80 | (min_code_size - 1) : 0;
24624
24625              // - Local Color Table
24626              if (using_local_palette === true) {
24627                for (var i = 0, il = palette.length; i < il; ++i) {
24628                  var rgb = palette[i];
24629                  buf[p++] = (rgb >> 16) & 0xff;
24630                  buf[p++] = (rgb >> 8) & 0xff;
24631                  buf[p++] = rgb & 0xff;
24632                }
24633              }
24634
24635              p = GifWriterOutputLZWCodeStream(
24636                buf,
24637                p,
24638                min_code_size < 2 ? 2 : min_code_size,
24639                indexed_pixels
24640              );
24641
24642              return p;
24643            };
24644
24645            this.end = function() {
24646              if (ended === false) {
24647                buf[p++] = 0x3b; // Trailer.
24648                ended = true;
24649              }
24650              return p;
24651            };
24652
24653            this.getOutputBuffer = function() {
24654              return buf;
24655            };
24656            this.setOutputBuffer = function(v) {
24657              buf = v;
24658            };
24659            this.getOutputBufferPosition = function() {
24660              return p;
24661            };
24662            this.setOutputBufferPosition = function(v) {
24663              p = v;
24664            };
24665          }
24666
24667          // Main compression routine, palette indexes -> LZW code stream.
24668          // |index_stream| must have at least one entry.
24669          function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) {
24670            buf[p++] = min_code_size;
24671            var cur_subblock = p++; // Pointing at the length field.
24672
24673            var clear_code = 1 << min_code_size;
24674            var code_mask = clear_code - 1;
24675            var eoi_code = clear_code + 1;
24676            var next_code = eoi_code + 1;
24677
24678            var cur_code_size = min_code_size + 1; // Number of bits per code.
24679            var cur_shift = 0;
24680            // We have at most 12-bit codes, so we should have to hold a max of 19
24681            // bits here (and then we would write out).
24682            var cur = 0;
24683
24684            function emit_bytes_to_buffer(bit_block_size) {
24685              while (cur_shift >= bit_block_size) {
24686                buf[p++] = cur & 0xff;
24687                cur >>= 8;
24688                cur_shift -= 8;
24689                if (p === cur_subblock + 256) {
24690                  // Finished a subblock.
24691                  buf[cur_subblock] = 255;
24692                  cur_subblock = p++;
24693                }
24694              }
24695            }
24696
24697            function emit_code(c) {
24698              cur |= c << cur_shift;
24699              cur_shift += cur_code_size;
24700              emit_bytes_to_buffer(8);
24701            }
24702
24703            // I am not an expert on the topic, and I don't want to write a thesis.
24704            // However, it is good to outline here the basic algorithm and the few data
24705            // structures and optimizations here that make this implementation fast.
24706            // The basic idea behind LZW is to build a table of previously seen runs
24707            // addressed by a short id (herein called output code).  All data is
24708            // referenced by a code, which represents one or more values from the
24709            // original input stream.  All input bytes can be referenced as the same
24710            // value as an output code.  So if you didn't want any compression, you
24711            // could more or less just output the original bytes as codes (there are
24712            // some details to this, but it is the idea).  In order to achieve
24713            // compression, values greater then the input range (codes can be up to
24714            // 12-bit while input only 8-bit) represent a sequence of previously seen
24715            // inputs.  The decompressor is able to build the same mapping while
24716            // decoding, so there is always a shared common knowledge between the
24717            // encoding and decoder, which is also important for "timing" aspects like
24718            // how to handle variable bit width code encoding.
24719            //
24720            // One obvious but very important consequence of the table system is there
24721            // is always a unique id (at most 12-bits) to map the runs.  'A' might be
24722            // 4, then 'AA' might be 10, 'AAA' 11, 'AAAA' 12, etc.  This relationship
24723            // can be used for an effecient lookup strategy for the code mapping.  We
24724            // need to know if a run has been seen before, and be able to map that run
24725            // to the output code.  Since we start with known unique ids (input bytes),
24726            // and then from those build more unique ids (table entr
24726ies), we can
24727            // continue this chain (almost like a linked list) to always have small
24728            // integer values that represent the current byte chains in the encoder.
24729            // This means instead of tracking the input bytes (AAAABCD) to know our
24730            // current state, we can track the table entry for AAAABC (it is guaranteed
24731            // to exist by the nature of the algorithm) and the next character D.
24732            // Therefor the tuple of (table_entry, byte) is guaranteed to also be
24733            // unique.  This allows us to create a simple lookup key for mapping input
24734            // sequences to codes (table indices) without having to store or search
24735            // any of the code sequences.  So if 'AAAA' has a table entry of 12, the
24736            // tuple of ('AAAA', K) for any input byte K will be unique, and can be our
24737            // key.  This leads to a integer value at most 20-bits, which can always
24738            // fit in an SMI value and be used as a fast sparse array / object key.
24739
24740            // Output code for the current contents of the index buffer.
24741            var ib_code = index_stream[0] & code_mask; // Load first input index.
24742            var code_table = {}; // Key'd on our 20-bit "tuple".
24743
24744            emit_code(clear_code); // Spec says first code should be a clear code.
24745
24746            // First index already loaded, process the rest of the stream.
24747            for (var i = 1, il = index_stream.length; i < il; ++i) {
24748              var k = index_stream[i] & code_mask;
24749              var cur_key = (ib_code << 8) | k; // (prev, k) unique tuple.
24750              var cur_code = code_table[cur_key]; // buffer + k.
24751
24752              // Check if we have to create a new code table entry.
24753              if (cur_code === undefined) {
24754                // We don't have buffer + k.
24755                // Emit index buffer (without k).
24756                // This is an inline version of emit_code, because this is the core
24757                // writing routine of the compressor (and V8 cannot inline emit_code
24758                // because it is a closure here in a different context).  Additionally
24759                // we can call emit_byte_to_buffer less often, because we can have
24760                // 30-bits (from our 31-bit signed SMI), and we know our codes will only
24761                // be 12-bits, so can safely have 18-bits there without overflow.
24762                // emit_code(ib_code);
24763                cur |= ib_code << cur_shift;
24764                cur_shift += cur_code_size;
24765                while (cur_shift >= 8) {
24766                  buf[p++] = cur & 0xff;
24767                  cur >>= 8;
24768                  cur_shift -= 8;
24769                  if (p === cur_subblock + 256) {
24770                    // Finished a subblock.
24771                    buf[cur_subblock] = 255;
24772                    cur_subblock = p++;
24773                  }
24774                }
24775
24776                if (next_code === 4096) {
24777                  // Table full, need a clear.
24778                  emit_code(clear_code);
24779                  next_code = eoi_code + 1;
24780                  cur_code_size = min_code_size + 1;
24781                  code_table = {};
24782                } else {
24783                  // Table not full, insert a new entry.
24784                  // Increase our variable bit code sizes if necessary.  This is a bit
24785                  // tricky as it is based on "timing" between the encoding and
24786                  // decoder.  From the encoders perspective this should happen after
24787                  // we've already emitted the index buffer and are about to create the
24788                  // first table entry that would overflow our current code bit size.
24789                  if (next_code >= 1 << cur_code_size) ++cur_code_size;
24790                  code_table[cur_key] = next_code++; // Insert into code table.
24791                }
24792
24793                ib_code = k; // Index buffer to single input k.
24794              } else {
24795                ib_code = cur_code; // Index buffer to sequence in code table.
24796              }
24797            }
24798
24799            emit_code(ib_code); // There will still be something in the index buffer.
24800            emit_code(eoi_code); // End Of Information.
24801
24802            // Flush / finalize the sub-blocks stream to the buffer.
24803            emit_bytes_to_buffer(1);
24804
vendor: 10,715 bytes, lines 24805-25058
24805            // Finish the sub-blocks, writing out any unfinished lengths and
24806            // terminating with a sub-block of length 0.  If we have already started
24807            // but not yet used a sub-block it can just become the terminator.
24808            if (cur_subblock + 1 === p) {
24809              // Started but unused.
24810              buf[cur_subblock] = 0;
24811            } else {
24812              // Started and used, write length and additional terminator block.
24813              buf[cur_subblock] = p - cur_subblock - 1;
24814              buf[p++] = 0;
24815            }
24816            return p;
24817          }
24818
24819          function GifReader(buf) {
24820            var p = 0;
24821
24822            // - Header (GIF87a or GIF89a).
24823            if (
24824              buf[p++] !== 0x47 ||
24825              buf[p++] !== 0x49 ||
24826              buf[p++] !== 0x46 ||
24827              buf[p++] !== 0x38 ||
24828              ((buf[p++] + 1) & 0xfd) !== 0x38 ||
24829              buf[p++] !== 0x61
24830            ) {
24831              throw new Error('Invalid GIF 87a/89a header.');
24832            }
24833
24834            // - Logical Screen Descriptor.
24835            var width = buf[p++] | (buf[p++] << 8);
24836            var height = buf[p++] | (buf[p++] << 8);
24837            var pf0 = buf[p++]; // <Packed Fields>.
24838            var global_palette_flag = pf0 >> 7;
24839            var num_global_colors_pow2 = pf0 & 0x7;
24840            var num_global_colors = 1 << (num_global_colors_pow2 + 1);
24841            var background = buf[p++];
24842            buf[p++]; // Pixel aspect ratio (unused?).
24843
24844            var global_palette_offset = null;
24845            var global_palette_size = null;
24846
24847            if (global_palette_flag) {
24848              global_palette_offset = p;
24849              global_palette_size = num_global_colors;
24850              p += num_global_colors * 3; // Seek past palette.
24851            }
24852
24853            var no_eof = true;
24854
24855            var frames = [];
24856
24857            var delay = 0;
24858            var transparent_index = null;
24859            var disposal = 0; // 0 - No disposal specified.
24860            var loop_count = null;
24861
24862            this.width = width;
24863            this.height = height;
24864
24865            while (no_eof && p < buf.length) {
24866              switch (buf[p++]) {
24867                case 0x21: // Graphics Control Extension Block
24868                  switch (buf[p++]) {
24869                    case 0xff: // Application specific block
24870                      // Try if it's a Netscape block (with animation loop counter).
24871                      if (
24872                        buf[p] !== 0x0b || // 21 FF already read, check block size.
24873                        // NETSCAPE2.0
24874                        (buf[p + 1] == 0x4e &&
24875                          buf[p + 2] == 0x45 &&
24876                          buf[p + 3] == 0x54 &&
24877                          buf[p + 4] == 0x53 &&
24878                          buf[p + 5] == 0x43 &&
24879                          buf[p + 6] == 0x41 &&
24880                          buf[p + 7] == 0x50 &&
24881                          buf[p + 8] == 0x45 &&
24882                          buf[p + 9] == 0x32 &&
24883                          buf[p + 10] == 0x2e &&
24884                          buf[p + 11] == 0x30 &&
24885                          // Sub-block
24886                          buf[p + 12] == 0x03 &&
24887                          buf[p + 13] == 0x01 &&
24888                          buf[p + 16] == 0)
24889                      ) {
24890                        p += 14;
24891                        loop_count = buf[p++] | (buf[p++] << 8);
24892                        p++; // Skip terminator.
24893                      } else {
24894                        // We don't know what it is, just try to get past it.
24895                        p += 12;
24896                        while (true) {
24897                          // Seek through subblocks.
24898                          var block_size = buf[p++];
24899                          // Bad block size (ex: undefined from an out of bounds read).
24900                          if (!(block_size >= 0)) throw Error('Invalid block size');
24901                          if (block_size === 0) break; // 0 size is terminator
24902                          p += block_size;
24903                        }
24904                      }
24905                      break;
24906
24907                    case 0xf9: // Graphics Control Extension
24908                      if (buf[p++] !== 0x4 || buf[p + 4] !== 0)
24909                        throw new Error('Invalid graphics extension block.');
24910                      var pf1 = buf[p++];
24911                      delay = buf[p++] | (buf[p++] << 8);
24912                      transparent_index = buf[p++];
24913                      if ((pf1 & 1) === 0) transparent_index = null;
24914                      disposal = (pf1 >> 2) & 0x7;
24915                      p++; // Skip terminator.
24916                      break;
24917
24918                    case 0xfe: // Comment Extension.
24919                      while (true) {
24920                        // Seek through subblocks.
24921                        var block_size = buf[p++];
24922                        // Bad block size (ex: undefined from an out of bounds read).
24923                        if (!(block_size >= 0)) throw Error('Invalid block size');
24924                        if (block_size === 0) break; // 0 size is terminator
24925                        // console.log(buf.slice(p, p+block_size).toString('ascii'));
24926                        p += block_size;
24927                      }
24928                      break;
24929
24930                    default:
24931                      throw new Error(
24932                        'Unknown graphic control label: 0x' + buf[p - 1].toString(16)
24933                      );
24934                  }
24935                  break;
24936
24937                case 0x2c: // Image Descriptor.
24938                  var x = buf[p++] | (buf[p++] << 8);
24939                  var y = buf[p++] | (buf[p++] << 8);
24940                  var w = buf[p++] | (buf[p++] << 8);
24941                  var h = buf[p++] | (buf[p++] << 8);
24942                  var pf2 = buf[p++];
24943                  var local_palette_flag = pf2 >> 7;
24944                  var interlace_flag = (pf2 >> 6) & 1;
24945                  var num_local_colors_pow2 = pf2 & 0x7;
24946                  var num_local_colors = 1 << (num_local_colors_pow2 + 1);
24947                  var palette_offset = global_palette_offset;
24948                  var palette_size = global_palette_size;
24949                  var has_local_palette = false;
24950                  if (local_palette_flag) {
24951                    var has_local_palette = true;
24952                    palette_offset = p; // Override with local palette.
24953                    palette_size = num_local_colors;
24954                    p += num_local_colors * 3; // Seek past palette.
24955                  }
24956
24957                  var data_offset = p;
24958
24959                  p++; // codesize
24960                  while (true) {
24961                    var block_size = buf[p++];
24962                    // Bad block size (ex: undefined from an out of bounds read).
24963                    if (!(block_size >= 0)) throw Error('Invalid block size');
24964                    if (block_size === 0) break; // 0 size is terminator
24965                    p += block_size;
24966                  }
24967
24968                  frames.push({
24969                    x: x,
24970                    y: y,
24971                    width: w,
24972                    height: h,
24973                    has_local_palette: has_local_palette,
24974                    palette_offset: palette_offset,
24975                    palette_size: palette_size,
24976                    data_offset: data_offset,
24977                    data_length: p - data_offset,
24978                    transparent_index: transparent_index,
24979                    interlaced: !!interlace_flag,
24980                    delay: delay,
24981                    disposal: disposal
24982                  });
24983                  break;
24984
24985                case 0x3b: // Trailer Marker (end of file).
24986                  no_eof = false;
24987                  break;
24988
24989                default:
24990                  throw new Error('Unknown gif block: 0x' + buf[p - 1].toString(16));
24991                  break;
24992              }
24993            }
24994
24995            this.numFrames = function() {
24996              return frames.length;
24997            };
24998
24999            this.loopCount = function() {
25000              return loop_count;
25001            };
25002
25003            this.frameInfo = function(frame_num) {
25004              if (frame_num < 0 || frame_num >= frames.length)
25005                throw new Error('Frame index out of range.');
25006              return frames[frame_num];
25007            };
25008
25009            this.decodeAndBlitFrameBGRA = function(frame_num, pixels) {
25010              var frame = this.frameInfo(frame_num);
25011              var num_pixels = frame.width * frame.height;
25012              var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.
25013              GifReaderLZWOutputIndexStream(
25014                buf,
25015                frame.data_offset,
25016                index_stream,
25017                num_pixels
25018              );
25019              var palette_offset = frame.palette_offset;
25020
25021              // NOTE(deanm): It seems to be much faster to compare index to 256 than
25022              // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
25023              // the profile, not sure if it's related to using a Uint8Array.
25024              var trans = frame.transparent_index;
25025              if (trans === null) trans = 256;
25026
25027              // We are possibly just blitting to a portion of the entire frame.
25028              // That is a subrect within the framerect, so the additional pixels
25029              // must be skipped over after we finished a scanline.
25030              var framewidth = frame.width;
25031              var framestride = width - framewidth;
25032              var xleft = framewidth; // Number of subrect pixels left in scanline.
25033
25034              // Output indicies of the top left and bottom right corners of the subrect.
25035              var opbeg = (frame.y * width + frame.x) * 4;
25036              var opend = ((frame.y + frame.height) * width + frame.x) * 4;
25037              var op = opbeg;
25038
25039              var scanstride = framestride * 4;
25040
25041              // Use scanstride to skip past the rows when interlacing.  This is skipping
25042              // 7 rows for the first two passes, then 3 then 1.
25043              if (frame.interlaced === true) {
25044                scanstride += width * 4 * 7; // Pass 1.
25045              }
25046
25047              var interlaceskip = 8; // Tracking the row interval in the current pass.
25048
25049              for (var i = 0, il = index_stream.length; i < il; ++i) {
25050                var index = index_stream[i];
25051
25052                if (xleft === 0) {
25053                  // Beginning of new scan line
25054                  op += scanstride;
25055                  xleft = framewidth;
25056                  if (op >= opend) {
25057                    // Catch the wrap to switch passes when interlacing.
25058                    scanstride = framestride * 4 + width * 4 * (interlaceskip - 1);
vendor: 5,704 bytes, lines 25059-25195
25059                    // interlaceskip / 2 * 4 is interlaceskip << 1.
25060                    op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
25061                    interlaceskip >>= 1;
25062                  }
25063                }
25064
25065                if (index === trans) {
25066                  op += 4;
25067                } else {
25068                  var r = buf[palette_offset + index * 3];
25069                  var g = buf[palette_offset + index * 3 + 1];
25070                  var b = buf[palette_offset + index * 3 + 2];
25071                  pixels[op++] = b;
25072                  pixels[op++] = g;
25073                  pixels[op++] = r;
25074                  pixels[op++] = 255;
25075                }
25076                --xleft;
25077              }
25078            };
25079
25080            // I will go to copy and paste hell one day...
25081            this.decodeAndBlitFrameRGBA = function(frame_num, pixels) {
25082              var frame = this.frameInfo(frame_num);
25083              var num_pixels = frame.width * frame.height;
25084              var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.
25085              GifReaderLZWOutputIndexStream(
25086                buf,
25087                frame.data_offset,
25088                index_stream,
25089                num_pixels
25090              );
25091              var palette_offset = frame.palette_offset;
25092
25093              // NOTE(deanm): It seems to be much faster to compare index to 256 than
25094              // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
25095              // the profile, not sure if it's related to using a Uint8Array.
25096              var trans = frame.transparent_index;
25097              if (trans === null) trans = 256;
25098
25099              // We are possibly just blitting to a portion of the entire frame.
25100              // That is a subrect within the framerect, so the additional pixels
25101              // must be skipped over after we finished a scanline.
25102              var framewidth = frame.width;
25103              var framestride = width - framewidth;
25104              var xleft = framewidth; // Number of subrect pixels left in scanline.
25105
25106              // Output indicies of the top left and bottom right corners of the subrect.
25107              var opbeg = (frame.y * width + frame.x) * 4;
25108              var opend = ((frame.y + frame.height) * width + frame.x) * 4;
25109              var op = opbeg;
25110
25111              var scanstride = framestride * 4;
25112
25113              // Use scanstride to skip past the rows when interlacing.  This is skipping
25114              // 7 rows for the first two passes, then 3 then 1.
25115              if (frame.interlaced === true) {
25116                scanstride += width * 4 * 7; // Pass 1.
25117              }
25118
25119              var interlaceskip = 8; // Tracking the row interval in the current pass.
25120
25121              for (var i = 0, il = index_stream.length; i < il; ++i) {
25122                var index = index_stream[i];
25123
25124                if (xleft === 0) {
25125                  // Beginning of new scan line
25126                  op += scanstride;
25127                  xleft = framewidth;
25128                  if (op >= opend) {
25129                    // Catch the wrap to switch passes when interlacing.
25130                    scanstride = framestride * 4 + width * 4 * (interlaceskip - 1);
25131                    // interlaceskip / 2 * 4 is interlaceskip << 1.
25132                    op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
25133                    interlaceskip >>= 1;
25134                  }
25135                }
25136
25137                if (index === trans) {
25138                  op += 4;
25139                } else {
25140                  var r = buf[palette_offset + index * 3];
25141                  var g = buf[palette_offset + index * 3 + 1];
25142                  var b = buf[palette_offset + index * 3 + 2];
25143                  pixels[op++] = r;
25144                  pixels[op++] = g;
25145                  pixels[op++] = b;
25146                  pixels[op++] = 255;
25147                }
25148                --xleft;
25149              }
25150            };
25151          }
25152
25153          function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) {
25154            var min_code_size = code_stream[p++];
25155
25156            var clear_code = 1 << min_code_size;
25157            var eoi_code = clear_code + 1;
25158            var next_code = eoi_code + 1;
25159
25160            var cur_code_size = min_code_size + 1; // Number of bits per code.
25161            // NOTE: This shares the same name as the encoder, but has a different
25162            // meaning here.  Here this masks each code coming from the code stream.
25163            var code_mask = (1 << cur_code_size) - 1;
25164            var cur_shift = 0;
25165            var cur = 0;
25166
25167            var op = 0; // Output pointer.
25168
25169            var subblock_size = code_stream[p++];
25170
25171            // TODO(deanm): Would using a TypedArray be any faster?  At least it would
25172            // solve the fast mode / backing store uncertainty.
25173            // var code_table = Array(4096);
25174            var code_table = new Int32Array(4096); // Can be signed, we only use 20 bits.
25175
25176            var prev_code = null; // Track code-1.
25177
25178            while (true) {
25179              // Read up to two bytes, making sure we always 12-bits for max sized code.
25180              while (cur_shift < 16) {
25181                if (subblock_size === 0) break; // No more data to be read.
25182
25183                cur |= code_stream[p++] << cur_shift;
25184                cur_shift += 8;
25185
25186                if (subblock_size === 1) {
25187                  // Never let it get to 0 to hold logic above.
25188                  subblock_size = code_stream[p++]; // Next subblock.
25189                } else {
25190                  --subblock_size;
25191                }
25192              }
25193
25194              // TODO(deanm): We should never really get here, we should have received
25195              // and EOI.
vendor: 4,418 bytes, lines 25196-25282
25196              if (cur_shift < cur_code_size) break;
25197
25198              var code = cur & code_mask;
25199              cur >>= cur_code_size;
25200              cur_shift -= cur_code_size;
25201
25202              // TODO(deanm): Maybe should check that the first code was a clear code,
25203              // at least this is what you're supposed to do.  But actually our encoder
25204              // now doesn't emit a clear code first anyway.
25205              if (code === clear_code) {
25206                // We don't actually have to clear the table.  This could be a good idea
25207                // for greater error checking, but we don't really do any anyway.  We
25208                // will just track it with next_code and overwrite old entries.
25209
25210                next_code = eoi_code + 1;
25211                cur_code_size = min_code_size + 1;
25212                code_mask = (1 << cur_code_size) - 1;
25213
25214                // Don't update prev_code ?
25215                prev_code = null;
25216                continue;
25217              } else if (code === eoi_code) {
25218                break;
25219              }
25220
25221              // We have a similar situation as the decoder, where we want to store
25222              // variable length entries (code table entries), but we want to do in a
25223              // faster manner than an array of arrays.  The code below stores sort of a
25224              // linked list within the code table, and then "chases" through it to
25225              // construct the dictionary entries.  When a new entry is created, just the
25226              // last byte is stored, and the rest (prefix) of the entry is only
25227              // referenced by its table entry.  Then the code chases through the
25228              // prefixes until it reaches a single byte code.  We have to chase twice,
25229              // first to compute the length, and then to actually copy the data to the
25230              // output (backwards, since we know the length).  The alternative would be
25231              // storing something in an intermediate stack, but that doesn't make any
25232              // more sense.  I implemented an approach where it also stored the length
25233              // in the code table, although it's a bit tricky because you run out of
25234              // bits (12 + 12 + 8), but I didn't measure much improvements (the table
25235              // entries are generally not the long).  Even when I created benchmarks for
25236              // very long table entries the complexity did not seem worth it.
25237              // The code table stores the prefix entry in 12 bits and then the suffix
25238              // byte in 8 bits, so each entry is 20 bits.
25239
25240              var chase_code = code < next_code ? code : prev_code;
25241
25242              // Chase what we will output, either {CODE} or {CODE-1}.
25243              var chase_length = 0;
25244              var chase = chase_code;
25245              while (chase > clear_code) {
25246                chase = code_table[chase] >> 8;
25247                ++chase_length;
25248              }
25249
25250              var k = chase;
25251
25252              var op_end = op + chase_length + (chase_code !== code ? 1 : 0);
25253              if (op_end > output_length) {
25254                console.log('Warning, gif stream longer than expected.');
25255                return;
25256              }
25257
25258              // Already have the first byte from the chase, might as well write it fast.
25259              output[op++] = k;
25260
25261              op += chase_length;
25262              var b = op; // Track pointer, writing backwards.
25263
25264              if (chase_code !== code)
25265                // The case of emitting {CODE-1} + k.
25266                output[op++] = k;
25267
25268              chase = chase_code;
25269              while (chase_length--) {
25270                chase = code_table[chase];
25271                output[--b] = chase & 0xff; // Write backwards.
25272                chase >>= 8; // Pull down to the prefix code.
25273              }
25274
25275              if (prev_code !== null && next_code < 4096) {
25276                code_table[next_code++] = (prev_code << 8) | k;
25277                // TODO(deanm): Figure out this clearing vs code growth logic better.  I
25278                // have an feeling that it should just happen somewhere else, for now it
25279                // is awkward between when we grow past the max and then hit a clear code.
25280                // For now just check if we hit the max 12-bits (then a clear code should
25281                // follow, also of course encoded in 12-bits).
25282                if (next_code >= code_mask + 1 && cur_code_size < 12) {
25283                  ++cur_code_size;
25284                  code_mask = (code_mask << 1) | 1;
25285                }
25286              }
25287
25288              prev_code = code;
25289            }
25290
25291            if (op !== output_length) {
25292              console.log('Warning, gif stream shorter than expected.');
25293            }
25294
25295            return output;
25296          }
25297
25298          // CommonJS.
25299          try {
25300            exports.GifWriter = GifWriter;
25301            exports.GifReader = GifReader;
25302          } catch (e) {}
25303        },
25304        {}
25305      ],
25306      34: [
25307        function(_dereq_, module, exports) {
25308          (function(Buffer) {
25309            /**
25310             * https://opentype.js.org v0.9.0 | (c) Frederik De Bleser and other contributors | MIT License | Uses tiny-inflate by Devon Govett and string.prototype.codepointat polyfill by Mathias Bynens
25311             */
25312
25313            (function(global, factory) {
25314              typeof exports === 'object' && typeof module !== 'undefined'
25315                ? factory(exports)
25316                : typeof define === 'function' && define.amd
25317                  ? define(['exports'], factory)
25318                  : factory((global.opentype = {}));
25319            })(this, function(exports) {
25320              'use strict';
25321
25322              /*! https://mths.be/codepointat v0.2.0 by @mathias */
25323              if (!String.prototype.codePointAt) {
25324                (function() {
25325                  var defineProperty = (function() {
25326                    // IE 8 only supports `Object.defineProperty` on DOM elements
25327                    try {
25328                      var object = {};
25329                      var $defineProperty = Object.defineProperty;
25330                      var result =
25331                        $defineProperty(object, object, object) && $defineProperty;
25332                    } catch (error) {}
25333                    return result;
25334                  })();
25335                  var codePointAt = function(position) {
25336                    if (this == null) {
25337                      throw TypeError();
25338                    }
25339                    var string = String(this);
25340                    var size = string.length;
25341                    // `ToInteger`
25342                    var index = position ? Number(position) : 0;
25343                    if (index != index) {
25344                      // better `isNaN`
25345                      index = 0;
25346                    }
25347                    // Account for out-of-bounds indices:
25348                    if (index < 0 || index >= size) {
25349                      return undefined;
25350                    }
25351                    // Get the first code unit
25352                    var first = string.charCodeAt(index);
25353                    var second;
25354                    if (
25355                      // check if it’s the start of a surrogate pair
25356                      first >= 0xd800 &&
25357                      first <= 0xdbff && // high surrogate
25358                      size > index + 1 // there is a next code unit
25359                    ) {
25360                      second = string.charCodeAt(index + 1);
25361                      if (second >= 0xdc00 && second <= 0xdfff) {
25362                        // low surrogate
25363                        // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
25364                        return (first - 0xd800) * 0x400 + second - 0xdc00 + 0x10000;
25365                      }
25366                    }
25367                    return first;
25368                  };
25369                  if (defineProperty) {
25370                    defineProperty(String.prototype, 'codePointAt', {
25371                      value: codePointAt,
25372                      configurable: true,
25373                      writable: true
25374                    });
25375                  } else {
25376                    String.prototype.codePointAt = codePointAt;
25377                  }
25378                })();
25379              }
25380
25381              var TINF_OK = 0;
25382              var TINF_DATA_ERROR = -3;
25383
25384              function Tree() {
25385                this.table = new Uint16Array(16); /* table of code length counts */
25386                this.trans = new Uint16Array(288); /* code -> symbol translation table */
25387              }
25388
25389              function Data(source, dest) {
25390                this.source = source;
25391                this.sourceIndex = 0;
25392                this.tag = 0;
25393                this.bitcount = 0;
25394
25395                this.dest = dest;
25396                this.destLen = 0;
25397
25398                this.ltree = new Tree(); /* dynamic length/symbol tree */
25399                this.dtree = new Tree(); /* dynamic distance tree */
25400              }
25401
25402              /* --------------------------------------------------- *
vendor: 11,225 bytes, lines 25403-25746
25403	 * -- uninitialized global data (static structures) -- *
25404	 * --------------------------------------------------- */
25405
25406              var sltree = new Tree();
25407              var sdtree = new Tree();
25408
25409              /* extra bits and base tables for length codes */
25410              var length_bits = new Uint8Array(30);
25411              var length_base = new Uint16Array(30);
25412
25413              /* extra bits and base tables for distance codes */
25414              var dist_bits = new Uint8Array(30);
25415              var dist_base = new Uint16Array(30);
25416
25417              /* special ordering of code length codes */
25418              var clcidx = new Uint8Array([
25419                16,
25420                17,
25421                18,
25422                0,
25423                8,
25424                7,
25425                9,
25426                6,
25427                10,
25428                5,
25429                11,
25430                4,
25431                12,
25432                3,
25433                13,
25434                2,
25435                14,
25436                1,
25437                15
25438              ]);
25439
25440              /* used by tinf_decode_trees, avoids allocations every call */
25441              var code_tree = new Tree();
25442              var lengths = new Uint8Array(288 + 32);
25443
25444              /* ----------------------- *
25445	 * -- utility functions -- *
25446	 * ----------------------- */
25447
25448              /* build extra bits and base tables */
25449              function tinf_build_bits_base(bits, base, delta, first) {
25450                var i, sum;
25451
25452                /* build bits table */
25453                for (i = 0; i < delta; ++i) {
25454                  bits[i] = 0;
25455                }
25456                for (i = 0; i < 30 - delta; ++i) {
25457                  bits[i + delta] = (i / delta) | 0;
25458                }
25459
25460                /* build base table */
25461                for (sum = first, i = 0; i < 30; ++i) {
25462                  base[i] = sum;
25463                  sum += 1 << bits[i];
25464                }
25465              }
25466
25467              /* build the fixed huffman trees */
25468              function tinf_build_fixed_trees(lt, dt) {
25469                var i;
25470
25471                /* build fixed length tree */
25472                for (i = 0; i < 7; ++i) {
25473                  lt.table[i] = 0;
25474                }
25475
25476                lt.table[7] = 24;
25477                lt.table[8] = 152;
25478                lt.table[9] = 112;
25479
25480                for (i = 0; i < 24; ++i) {
25481                  lt.trans[i] = 256 + i;
25482                }
25483                for (i = 0; i < 144; ++i) {
25484                  lt.trans[24 + i] = i;
25485                }
25486                for (i = 0; i < 8; ++i) {
25487                  lt.trans[24 + 144 + i] = 280 + i;
25488                }
25489                for (i = 0; i < 112; ++i) {
25490                  lt.trans[24 + 144 + 8 + i] = 144 + i;
25491                }
25492
25493                /* build fixed distance tree */
25494                for (i = 0; i < 5; ++i) {
25495                  dt.table[i] = 0;
25496                }
25497
25498                dt.table[5] = 32;
25499
25500                for (i = 0; i < 32; ++i) {
25501                  dt.trans[i] = i;
25502                }
25503              }
25504
25505              /* given an array of code lengths, build a tree */
25506              var offs = new Uint16Array(16);
25507
25508              function tinf_build_tree(t, lengths, off, num) {
25509                var i, sum;
25510
25511                /* clear code length count table */
25512                for (i = 0; i < 16; ++i) {
25513                  t.table[i] = 0;
25514                }
25515
25516                /* scan symbol lengths, and sum code length counts */
25517                for (i = 0; i < num; ++i) {
25518                  t.table[lengths[off + i]]++;
25519                }
25520
25521                t.table[0] = 0;
25522
25523                /* compute offset table for distribution sort */
25524                for (sum = 0, i = 0; i < 16; ++i) {
25525                  offs[i] = sum;
25526                  sum += t.table[i];
25527                }
25528
25529                /* create code->symbol translation table (symbols sorted by code) */
25530                for (i = 0; i < num; ++i) {
25531                  if (lengths[off + i]) {
25532                    t.trans[offs[lengths[off + i]]++] = i;
25533                  }
25534                }
25535              }
25536
25537              /* ---------------------- *
25538	 * -- decode functions -- *
25539	 * ---------------------- */
25540
25541              /* get one bit from source stream */
25542              function tinf_getbit(d) {
25543                /* check if tag is empty */
25544                if (!d.bitcount--) {
25545                  /* load next tag */
25546                  d.tag = d.source[d.sourceIndex++];
25547                  d.bitcount = 7;
25548                }
25549
25550                /* shift bit out of tag */
25551                var bit = d.tag & 1;
25552                d.tag >>>= 1;
25553
25554                return bit;
25555              }
25556
25557              /* read a num bit value from a stream and add base */
25558              function tinf_read_bits(d, num, base) {
25559                if (!num) {
25560                  return base;
25561                }
25562
25563                while (d.bitcount < 24) {
25564                  d.tag |= d.source[d.sourceIndex++] << d.bitcount;
25565                  d.bitcount += 8;
25566                }
25567
25568                var val = d.tag & (0xffff >>> (16 - num));
25569                d.tag >>>= num;
25570                d.bitcount -= num;
25571                return val + base;
25572              }
25573
25574              /* given a data stream and a tree, decode a symbol */
25575              function tinf_decode_symbol(d, t) {
25576                while (d.bitcount < 24) {
25577                  d.tag |= d.source[d.sourceIndex++] << d.bitcount;
25578                  d.bitcount += 8;
25579                }
25580
25581                var sum = 0,
25582                  cur = 0,
25583                  len = 0;
25584                var tag = d.tag;
25585
25586                /* get more bits while code value is above sum */
25587                do {
25588                  cur = 2 * cur + (tag & 1);
25589                  tag >>>= 1;
25590                  ++len;
25591
25592                  sum += t.table[len];
25593                  cur -= t.table[len];
25594                } while (cur >= 0);
25595
25596                d.tag = tag;
25597                d.bitcount -= len;
25598
25599                return t.trans[sum + cur];
25600              }
25601
25602              /* given a data stream, decode dynamic trees from it */
25603              function tinf_decode_trees(d, lt, dt) {
25604                var hlit, hdist, hclen;
25605                var i, num, length;
25606
25607                /* get 5 bits HLIT (257-286) */
25608                hlit = tinf_read_bits(d, 5, 257);
25609
25610                /* get 5 bits HDIST (1-32) */
25611                hdist = tinf_read_bits(d, 5, 1);
25612
25613                /* get 4 bits HCLEN (4-19) */
25614                hclen = tinf_read_bits(d, 4, 4);
25615
25616                for (i = 0; i < 19; ++i) {
25617                  lengths[i] = 0;
25618                }
25619
25620                /* read code lengths for code length alphabet */
25621                for (i = 0; i < hclen; ++i) {
25622                  /* get 3 bits code length (0-7) */
25623                  var clen = tinf_read_bits(d, 3, 0);
25624                  lengths[clcidx[i]] = clen;
25625                }
25626
25627                /* build code length tree */
25628                tinf_build_tree(code_tree, lengths, 0, 19);
25629
25630                /* decode code lengths for the dynamic trees */
25631                for (num = 0; num < hlit + hdist; ) {
25632                  var sym = tinf_decode_symbol(d, code_tree);
25633
25634                  switch (sym) {
25635                    case 16:
25636                      /* copy previous code length 3-6 times (read 2 bits) */
25637                      var prev = lengths[num - 1];
25638                      for (length = tinf_read_bits(d, 2, 3); length; --length) {
25639                        lengths[num++] = prev;
25640                      }
25641                      break;
25642                    case 17:
25643                      /* repeat code length 0 for 3-10 times (read 3 bits) */
25644                      for (length = tinf_read_bits(d, 3, 3); length; --length) {
25645                        lengths[num++] = 0;
25646                      }
25647                      break;
25648                    case 18:
25649                      /* repeat code length 0 for 11-138 times (read 7 bits) */
25650                      for (length = tinf_read_bits(d, 7, 11); length; --length) {
25651                        lengths[num++] = 0;
25652                      }
25653                      break;
25654                    default:
25655                      /* values 0-15 represent the actual code lengths */
25656                      lengths[num++] = sym;
25657                      break;
25658                  }
25659                }
25660
25661                /* build dynamic trees */
25662                tinf_build_tree(lt, lengths, 0, hlit);
25663                tinf_build_tree(dt, lengths, hlit, hdist);
25664              }
25665
25666              /* ----------------------------- *
25667	 * -- block inflate functions -- *
25668	 * ----------------------------- */
25669
25670              /* given a stream and two trees, inflate a block of data */
25671              function tinf_inflate_block_data(d, lt, dt) {
25672                while (1) {
25673                  var sym = tinf_decode_symbol(d, lt);
25674
25675                  /* check for end of block */
25676                  if (sym === 256) {
25677                    return TINF_OK;
25678                  }
25679
25680                  if (sym < 256) {
25681                    d.dest[d.destLen++] = sym;
25682                  } else {
25683                    var length, dist, offs;
25684                    var i;
25685
25686                    sym -= 257;
25687
25688                    /* possibly get more bits from length code */
25689                    length = tinf_read_bits(d, length_bits[sym], length_base[sym]);
25690
25691                    dist = tinf_decode_symbol(d, dt);
25692
25693                    /* possibly get more bits from distance code */
25694                    offs = d.destLen - tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
25695
25696                    /* copy match */
25697                    for (i = offs; i < offs + length; ++i) {
25698                      d.dest[d.destLen++] = d.dest[i];
25699                    }
25700                  }
25701                }
25702              }
25703
25704              /* inflate an uncompressed block of data */
25705              function tinf_inflate_uncompressed_block(d) {
25706                var length, invlength;
25707                var i;
25708
25709                /* unread from bitbuffer */
25710                while (d.bitcount > 8) {
25711                  d.sourceIndex--;
25712                  d.bitcount -= 8;
25713                }
25714
25715                /* get length */
25716                length = d.source[d.sourceIndex + 1];
25717                length = 256 * length + d.source[d.sourceIndex];
25718
25719                /* get one's complement of length */
25720                invlength = d.source[d.sourceIndex + 3];
25721                invlength = 256 * invlength + d.source[d.sourceIndex + 2];
25722
25723                /* check length */
25724                if (length !== (~invlength & 0x0000ffff)) {
25725                  return TINF_DATA_ERROR;
25726                }
25727
25728                d.sourceIndex += 4;
25729
25730                /* copy block */
25731                for (i = length; i; --i) {
25732                  d.dest[d.destLen++] = d.source[d.sourceIndex++];
25733                }
25734
25735                /* make sure we start next block on a byte boundary */
25736                d.bitcount = 0;
25737
25738                return TINF_OK;
25739              }
25740
25741              /* inflate stream from source to dest */
25742              function tinf_uncompress(source, dest) {
25743                var d = new Data(source, dest);
25744                var bfinal, btype, res;
25745
25746                do {
25747                  /* read final block flag */
25748                  bfinal = tinf_getbit(d);
25749
25750                  /* read block type (2 bits) */
25751                  btype = tinf_read_bits(d, 2, 0);
25752
25753                  /* decompress block */
25754                  switch (btype) {
25755                    case 0:
25756                      /* decompress uncompressed block */
25757                      res = tinf_inflate_uncompressed_block(d);
25758                      break;
25759                    case 1:
25760                      /* decompress block with fixed huffman trees */
25761                      res = tinf_inflate_block_data(d, sltree, sdtree);
25762                      break;
25763                    case 2:
25764                      /* decompress block with dynamic huffman trees */
25765                      tinf_decode_trees(d, d.ltree, d.dtree);
25766                      res = tinf_inflate_block_data(d, d.ltree, d.dtree);
25767                      break;
25768                    default:
25769                      res = TINF_DATA_ERROR;
25770                  }
25771
25772                  if (res !== TINF_OK) {
25773                    throw new Error('Data error');
25774                  }
25775                } while (!bfinal);
25776
25777                if (d.destLen < d.dest.length) {
25778                  if (typeof d.dest.slice === 'function') {
25779                    return d.dest.slice(0, d.destLen);
25780                  } else {
25781                    return d.dest.subarray(0, d.destLen);
25782                  }
25783                }
25784
25785                return d.dest;
25786              }
25787
25788              /* -------------------- *
25789	 * -- initialization -- *
25790	 * -------------------- */
25791
25792              /* build fixed huffman trees */
25793              tinf_build_fixed_trees(sltree, sdtree);
25794
25795              /* build extra bits and base tables */
25796              tinf_build_bits_base(length_bits, length_base, 4, 3);
25797              tinf_build_bits_base(dist_bits, dist_base, 2, 1);
25798
25799              /* fix a special case */
25800              length_bits[28] = 0;
25801              length_base[28] = 258;
25802
25803              var tinyInflate = tinf_uncompress;
25804
25805              // The Bounding Box object
25806
25807              function derive(v0, v1, v2, v3, t) {
25808                return (
25809                  Math.pow(1 - t, 3) * v0 +
25810                  3 * Math.pow(1 - t, 2) * t * v1 +
25811                  3 * (1 - t) * Math.pow(t, 2) * v2 +
25812                  Math.pow(t, 3) * v3
25813                );
25814              }
25815              /**
25816               * A bounding box is an enclosing box that describes the smallest measure within which all the points lie.
25817               * It is used to calculate the bounding box of a glyph or text path.
25818               *
25819               * On initialization, x1/y1/x2/y2 will be NaN. Check if the bounding box is empty using `isEmpty()`.
25820               *
25821               * @exports opentype.BoundingBox
25822               * @class
25823               * @constructor
25824               */
25825              function BoundingBox() {
25826                this.x1 = Number.NaN;
25827                this.y1 = Number.NaN;
25828                this.x2 = Number.NaN;
25829                this.y2 = Number.NaN;
25830              }
25831
25832              /**
25833               * Returns true if the bounding box is empty, that is, no points have been added to the box yet.
25834               */
25835              BoundingBox.prototype.isEmpty = function() {
25836                return isNaN(this.x1) || isNaN(this.y1) || isNaN(this.x2) || isNaN(this.y2);
25837              };
25838
25839              /**
25840               * Add the point to the bounding box.
25841               * The x1/y1/x2/y2 coordinates of the bounding box will now encompass the given point.
25842               * @param {number} x - The X coordinate of the point.
25843               * @param {number} y - The Y coordinate of the point.
25844               */
25845              BoundingBox.prototype.addPoint = function(x, y) {
25846                if (typeof x === 'number') {
25847                  if (isNaN(this.x1) || isNaN(this.x2)) {
25848                    this.x1 = x;
25849                    this.x2 = x;
25850                  }
25851                  if (x < this.x1) {
25852                    this.x1 = x;
25853                  }
25854                  if (x > this.x2) {
25855                    this.x2 = x;
25856                  }
25857                }
25858                if (typeof y === 'number') {
25859                  if (isNaN(this.y1) || isNaN(this.y2)) {
25860                    this.y1 = y;
25861                    this.y2 = y;
25862                  }
25863                  if (y < this.y1) {
25864                    this.y1 = y;
25865                  }
25866                  if (y > this.y2) {
25867                    this.y2 = y;
25868                  }
25869                }
25870              };
25871
25872              /**
25873               * Add a X coordinate to the bounding box.
25874               * This extends the bounding box to include the X coordinate.
25875               * This function is used internally inside of addBezier.
25876               * @param {number} x - The X coordinate of the point.
25877               */
25878              BoundingBox.prototype.addX = function(x) {
25879                this.addPoint(x, null);
25880              };
25881
25882              /**
25883               * Add a Y coordinate to the bounding box.
25884               * This extends the bounding box to include the Y coordinate.
25885               * This function is used internally inside of addBezier.
25886               * @param {number} y - The Y coordinate of the point.
25887               */
25888              BoundingBox.prototype.addY = function(y) {
25889                this.addPoint(null, y);
25890              };
25891
25892              /**
25893               * Add a Bézier curve to the bounding box.
25894               * This extends the bounding box to include the entire Bézier.
25895               * @param {number} x0 - The starting X coordinate.
25896               * @param {number} y0 - The starting Y coordinate.
25897               * @param {number} x1 - The X coordinate of the first control point.
25898               * @param {number} y1 - The Y coordinate of the first control point.
25899               * @param {number} x2 - The X coordinate of the second control point.
25900               * @param {number} y2 - The Y coordinate of the second control point.
25901               * @param {number} x - The ending X coordinate.
25902               * @param {number} y - The ending Y coordinate.
25903               */
25904              BoundingBox.prototype.addBezier = function(x0, y0, x1, y1, x2, y2, x, y) {
25905                var this$1 = this;
25906
25907                // This code is based on http://nishiohirokazu.blogspot.com/2009/06/how-to-calculate-bezier-curves-bounding.html
25908                // and https://github.com/icons8/svg-path-bounding-box
25909
25910                var p0 = [x0, y0];
25911                var p1 = [x1, y1];
25912                var p2 = [x2, y2];
25913                var p3 = [x, y];
25914
25915                this.addPoint(x0, y0);
25916                this.addPoint(x, y);
25917
25918                for (var i = 0; i <= 1; i++) {
25919                  var b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
25920                  var a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
25921                  var c = 3 * p1[i] - 3 * p0[i];
25922
25923                  if (a === 0) {
25924                    if (b === 0) {
25925                      continue;
25926                    }
25927                    var t = -c / b;
25928                    if (0 < t && t < 1) {
25929                      if (i === 0) {
25930                        this$1.addX(derive(p0[i], p1[i], p2[i], p3[
25930i], t));
25931                      }
25932                      if (i === 1) {
25933                        this$1.addY(derive(p0[i], p1[i], p2[i], p3[i], t));
25934                      }
25935                    }
25936                    continue;
25937                  }
25938
25939                  var b2ac = Math.pow(b, 2) - 4 * c * a;
25940                  if (b2ac < 0) {
25941                    continue;
25942                  }
25943                  var t1 = (-b + Math.sqrt(b2ac)) / (2 * a);
25944                  if (0 < t1 && t1 < 1) {
25945                    if (i === 0) {
25946                      this$1.addX(derive(p0[i], p1[i], p2[i], p3[i], t1));
25947                    }
25948                    if (i === 1) {
25949                      this$1.addY(derive(p0[i], p1[i], p2[i], p3[i], t1));
25950                    }
25951                  }
25952                  var t2 = (-b - Math.sqrt(b2ac)) / (2 * a);
25953                  if (0 < t2 && t2 < 1) {
25954                    if (i === 0) {
25955                      this$1.addX(derive(p0[i], p1[i], p2[i], p3[i], t2));
25956                    }
25957                    if (i === 1) {
25958                      this$1.addY(derive(p0[i], p1[i], p2[i], p3[i], t2));
25959                    }
25960                  }
25961                }
25962              };
25963
25964              /**
25965               * Add a quadratic curve to the bounding box.
25966               * This extends the bounding box to include the entire quadratic curve.
25967               * @param {number} x0 - The starting X coordinate.
25968               * @param {number} y0 - The starting Y coordinate.
25969               * @param {number} x1 - The X coordinate of the control point.
25970               * @param {number} y1 - The Y coordinate of the control point.
25971               * @param {number} x - The ending X coordinate.
25972               * @param {number} y - The ending Y coordinate.
25973               */
25974              BoundingBox.prototype.addQuad = function(x0, y0, x1, y1, x, y) {
25975                var cp1x = x0 + 2 / 3 * (x1 - x0);
25976                var cp1y = y0 + 2 / 3 * (y1 - y0);
25977                var cp2x = cp1x + 1 / 3 * (x - x0);
25978                var cp2y = cp1y + 1 / 3 * (y - y0);
25979                this.addBezier(x0, y0, cp1x, cp1y, cp2x, cp2y, x, y);
25980              };
25981
25982              // Geometric objects
25983
25984              /**
25985               * A bézier path containing a set of path commands similar to a SVG path.
25986               * Paths can be drawn on a context using `draw`.
25987               * @exports opentype.Path
25988               * @class
25989               * @constructor
25990               */
25991              function Path() {
25992                this.commands = [];
25993                this.fill = 'black';
25994                this.stroke = null;
25995                this.strokeWidth = 1;
25996              }
25997
25998              /**
25999               * @param  {number} x
26000               * @param  {number} y
26001               */
26002              Path.prototype.moveTo = function(x, y) {
26003                this.commands.push({
26004                  type: 'M',
26005                  x: x,
26006                  y: y
26007                });
26008              };
26009
26010              /**
26011               * @param  {number} x
26012               * @param  {number} y
26013               */
26014              Path.prototype.lineTo = function(x, y) {
26015                this.commands.push({
26016                  type: 'L',
26017                  x: x,
26018                  y: y
26019                });
26020              };
26021
26022              /**
26023               * Draws cubic curve
26024               * @function
26025               * curveTo
26026               * @memberof opentype.Path.prototype
26027               * @param  {number} x1 - x of control 1
26028               * @param  {number} y1 - y of control 1
26029               * @param  {number} x2 - x of control 2
26030               * @param  {number} y2 - y of control 2
26031               * @param  {number} x - x of path point
26032               * @param  {number} y - y of path point
26033               */
26034
26035              /**
26036               * Draws cubic curve
26037               * @function
26038               * bezierCurveTo
26039               * @memberof opentype.Path.prototype
26040               * @param  {number} x1 - x of control 1
26041               * @param  {number} y1 - y of control 1
26042               * @param  {number} x2 - x of control 2
26043               * @param  {number} y2 - y of control 2
26044               * @param  {number} x - x of path point
26045               * @param  {number} y - y of path point
26046               * @see curveTo
26047               */
26048              Path.prototype.curveTo = Path.prototype.bezierCurveTo = function(
26049                x1,
26050                y1,
26051                x2,
26052                y2,
26053                x,
26054                y
26055              ) {
26056                this.commands.push({
26057                  type: 'C',
26058                  x1: x1,
26059                  y1: y1,
26060                  x2: x2,
26061                  y2: y2,
26062                  x: x,
26063                  y: y
26064                });
26065              };
26066
26067              /**
26068               * Draws quadratic curve
26069               * @function
26070               * quadraticCurveTo
26071               * @memberof opentype.Path.prototype
26072               * @param  {number} x1 - x of control
26073               * @param  {number} y1 - y of control
26074               * @param  {number} x - x of path point
26075               * @param  {number} y - y of path point
26076               */
26077
26078              /**
26079               * Draws quadratic curve
26080               * @function
26081               * quadTo
26082               * @memberof opentype.Path.prototype
26083               * @param  {number} x1 - x of control
26084               * @param  {number} y1 - y of control
26085               * @param  {number} x - x of path point
26086               * @param  {number} y - y of path point
26087               */
26088              Path.prototype.quadTo = Path.prototype.quadraticCurveTo = function(
26089                x1,
26090                y1,
26091                x,
26092                y
26093              ) {
26094                this.commands.push({
26095                  type: 'Q',
26096                  x1: x1,
26097                  y1: y1,
26098                  x: x,
26099                  y: y
26100                });
26101              };
26102
26103              /**
26104               * Closes the path
26105               * @function closePath
26106               * @memberof opentype.Path.prototype
26107               */
26108
26109              /**
26110               * Close the path
26111               * @function close
26112               * @memberof opentype.Path.prototype
26113               */
26114              Path.prototype.close = Path.prototype.closePath = function() {
26115                this.commands.push({
26116                  type: 'Z'
26117                });
26118              };
26119
26120              /**
26121               * Add the given path or list of commands to the commands of this path.
26122               * @param  {Array} pathOrCommands - another opentype.Path, an opentype.BoundingBox, or an array of commands.
26123               */
26124              Path.prototype.extend = function(pathOrCommands) {
26125                if (pathOrCommands.commands) {
26126                  pathOrCommands = pathOrCommands.commands;
26127                } else if (pathOrCommands instanceof BoundingBox) {
26128                  var box = pathOrCommands;
26129                  this.moveTo(box.x1, box.y1);
26130                  this.lineTo(box.x2, box.y1);
26131                  this.lineTo(box.x2, box.y2);
26132                  this.lineTo(box.x1, box.y2);
26133                  this.close();
26134                  return;
26135                }
26136
26137                Array.prototype.push.apply(this.commands, pathOrCommands);
26138              };
26139
26140              /**
26141               * Calculate the bounding box of the path.
26142               * @returns {opentype.BoundingBox}
26143               */
26144              Path.prototype.getBoundingBox = function() {
26145                var this$1 = this;
26146
26147                var box = new BoundingBox();
26148
26149                var startX = 0;
26150                var startY = 0;
26151                var prevX = 0;
26152                var prevY = 0;
26153                for (var i = 0; i < this.commands.length; i++) {
26154                  var cmd = this$1.commands[i];
26155                  switch (cmd.type) {
26156                    case 'M':
26157                      box.addPoint(cmd.x, cmd.y);
26158                      startX = prevX = cmd.x;
26159                      startY = prevY = cmd.y;
26160                      break;
26161                    case 'L':
26162                      box.addPoint(cmd.x, cmd.y);
26163                      prevX = cmd.x;
26164                      prevY = cmd.y;
26165                      break;
26166                    case 'Q':
26167                      box.addQuad(prevX, prevY, cmd.x1, cmd.y1, cmd.x, cmd.y);
26168                      prevX = cmd.x;
26169                      prevY = cmd.y;
26170                      break;
26171                    case 'C':
26172                      box.addBezier(
26173                        prevX,
26174                        prevY,
26175                        cmd.x1,
26176                        cmd.y1,
26177                        cmd.x2,
26178                        cmd.y2,
26179                        cmd.x,
26180                        cmd.y
26181                      );
26182                      prevX = cmd.x;
26183                      prevY = cmd.y;
26184                      break;
26185                    case 'Z':
26186                      prevX = startX;
26187                      prevY = startY;
26188                      break;
26189                    default:
26190                      throw new Error('Unexpected path command ' + cmd.type);
26191                  }
26192                }
26193                if (box.isEmpty()) {
26194                  box.addPoint(0, 0);
26195                }
26196                return box;
26197              };
26198
26199              /**
26200               * Draw the path to a 2D context.
26201               * @param {CanvasRenderingContext2D} ctx - A 2D drawing context.
26202               */
26203              Path.prototype.draw = function(ctx) {
26204                var this$1 = this;
26205
26206                ctx.beginPath();
26207                for (var i = 0; i < this.commands.length; i += 1) {
26208                  var cmd = this$1.commands[i];
26209                  if (cmd.type === 'M') {
26210                    ctx.moveTo(cmd.x, cmd.y);
26211                  } else if (cmd.type === 'L') {
26212                    ctx.lineTo(cmd.x, cmd.y);
26213                  } else if (cmd.type === 'C') {
26214                    ctx.bezierCurveTo(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
26215                  } else if (cmd.type === 'Q') {
26216                    ctx.quadraticCurveTo(cmd.x1, cmd.y1, cmd.x, cmd.y);
26217                  } else if (cmd.type === 'Z') {
26218                    ctx.closePath();
26219                  }
26220                }
26221
26222                if (this.fill) {
26223                  ctx.fillStyle = this.fill;
26224                  ctx.fill();
26225                }
26226
26227                if (this.stroke) {
26228                  ctx.strokeStyle = this.stroke;
26229                  ctx.lineWidth = this.strokeWidth;
26230                  ctx.stroke();
26231                }
26232              };
26233
26234              /**
26235               * Convert the Path to a string of path data instructions
26236               * See http://www.w3.org/TR/SVG/paths.html#PathData
26237               * @param  {number} [decimalPlaces=2] - The amount of decimal places for floating-point values
26238               * @return {string}
26239               */
26240              Path.prototype.toPathData = function(decimalPlaces) {
26241                var this$1 = this;
26242
26243                decimalPlaces = decimalPlaces !== undefined ? decimalPlaces : 2;
26244
26245                function floatToString(v) {
26246                  if (Math.round(v) === v) {
26247                    return '' + Math.round(v);
26248                  } else {
26249                    return v.toFixed(decimalPlaces);
26250                  }
26251                }
26252
26253                function packValues() {
26254                  var arguments$1 = arguments;
26255
26256                  var s = '';
26257                  for (var i = 0; i < arguments.length; i += 1) {
26258                    var v = arguments$1[i];
26259                    if (v >= 0 && i > 0) {
26260                      s += ' ';
26261                    }
26262
26263                    s += floatToString(v);
26264                  }
26265
26266                  return s;
26267                }
26268
26269                var d = '';
26270                for (var i = 0; i < this.commands.length; i += 1) {
26271                  var cmd = this$1.commands[i];
26272                  if (cmd.type === 'M') {
26273                    d += 'M' + packValues(cmd.x, cmd.y);
26274                  } else if (cmd.type === 'L') {
26275                    d += 'L' + packValues(cmd.x, cmd.y);
26276                  } else if (cmd.type === 'C') {
26277                    d += 'C' + packValues(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
26278                  } else if (cmd.type === 'Q') {
26279                    d += 'Q' + packValues(cmd.x1, cmd.y1, cmd.x, cmd.y);
26280                  } else if (cmd.type === 'Z') {
26281                    d += 'Z';
26282                  }
26283                }
26284
26285                return d;
26286              };
26287
26288              /**
26289               * Convert the path to an SVG <path> element, as a string.
26290               * @param  {number} [decimalPlaces=2] - The amount of decimal places for floating-point values
26291               * @return {string}
26292               */
26293              Path.prototype.toSVG = function(decimalPlaces) {
26294                var svg = '<path d="';
26295                svg += this.toPathData(decimalPlaces);
26296                svg += '"';
26297                if (this.fill && this.fill !== 'black') {
26298                  if (this.fill === null) {
26299                    svg += ' fill="none"';
26300                  } else {
26301                    svg += ' fill="' + this.fill + '"';
26302                  }
26303                }
26304
26305                if (this.stroke) {
26306                  svg +=
26307                    ' stroke="' + this.stroke + '" stroke-width="' + this.strokeWidth + '"';
26308                }
26309
26310                svg += '/>';
26311                return svg;
26312              };
26313
26314              /**
26315               * Convert the path to a DOM element.
26316               * @param  {number} [decimalPlaces=2] - The amount of decimal places for floating-point values
26317               * @return {SVGPathElement}
26318               */
26319              Path.prototype.toDOMElement = function(decimalPlaces) {
26320                var temporaryPath = this.toPathData(decimalPlaces);
26321                var newPath = document.createElementNS(
26322                  'http://www.w3.org/2000/svg',
26323                  'path'
26324                );
26325
26326                newPath.setAttribute('d', temporaryPath);
26327
26328                return newPath;
26329              };
26330
26331              // Run-time checking of preconditions.
26332
26333              function fail(message) {
26334                throw new Error(message);
26335              }
26336
26337              // Precondition function that checks if the given predicate is true.
26338              // If not, it will throw an error.
26339              function argument(predicate, message) {
26340                if (!predicate) {
26341                  fail(message);
26342                }
26343              }
26344              var check = { fail: fail, argument: argument, assert: argument };
26345
26346              // Data types used in the OpenType font file.
26347
26348              var LIMIT16 = 32768; // The limit at which a 16-bit number switches signs == 2^15
26349              var LIMIT32 = 2147483648; // The limit at which a 32-bit number switches signs == 2 ^ 31
26350
26351              /**
26352               * @exports opentype.decode
26353               * @class
26354               */
26355              var decode = {};
26356              /**
26357               * @exports opentype.encode
26358               * @class
26359               */
26360              var encode = {};
26361              /**
26362               * @exports opentype.sizeOf
26363               * @class
26364               */
26365              var sizeOf = {};
26366
26367              // Return a function that always returns the same value.
26368              function constant(v) {
26369                return function() {
26370                  return v;
26371                };
26372              }
26373
26374              // OpenType data types //////////////////////////////////////////////////////
26375
26376              /**
26377               * Convert an 8-bit unsigned integer to a list of 1 byte.
26378               * @param {number}
26379               * @returns {Array}
26380               */
26381              encode.BYTE = function(v) {
26382                check.argument(
26383                  v >= 0 && v <= 255,
26384                  'Byte value should be between 0 and 255.'
26385                );
26386                return [v];
26387              };
26388              /**
26389               * @constant
26390               * @type {number}
26391               */
26392              sizeOf.BYTE = constant(1);
26393
26394              /**
26395               * Convert a 8-bit signed integer to a list of 1 byte.
26396               * @param {string}
26397               * @returns {Array}
26398               */
26399              encode.CHAR = function(v) {
26400                return [v.charCodeAt(0)];
26401              };
26402
26403              /**
26404               * @constant
26405               * @type {number}
26406               */
26407              sizeOf.CHAR = constant(1);
26408
26409              /**
26410               * Convert an ASCII string to a list of bytes.
26411               * @param {string}
26412               * @returns {Array}
26413               */
26414              encode.CHARARRAY = function(v) {
26415                var b = [];
26416                for (var i = 0; i < v.length; i += 1) {
26417                  b[i] = v.charCodeAt(i);
26418                }
26419
26420                return b;
26421              };
26422
26423              /**
26424               * @param {Array}
26425               * @returns {number}
26426               */
26427              sizeOf.CHARARRAY = function(v) {
26428                return v.length;
26429              };
26430
26431              /**
26432               * Convert a 16-bit unsigned integer to a list of 2 bytes.
26433               * @param {number}
26434               * @returns {Array}
26435               */
26436              encode.USHORT = function(v) {
26437                return [(v >> 8) & 0xff, v & 0xff];
26438              };
26439
26440              /**
26441               * @constant
26442               * @type {number}
26443               */
26444              sizeOf.USHORT = constant(2);
26445
26446              /**
26447               * Convert a 16-bit signed integer to a list of 2 bytes.
26448               * @param {number}
26449               * @returns {Array}
26450               */
26451              encode.SHORT = function(v) {
26452                // Two's complement
26453                if (v >= LIMIT16) {
26454                  v = -(2 * LIMIT16 - v);
26455                }
26456
26457                return [(v >> 8) & 0xff, v & 0xff];
26458              };
26459
26460              /**
26461               * @constant
26462               * @type {number}
26463               */
26464              sizeOf.SHORT = constant(2);
26465
26466              /**
26467               * Convert a 24-bit unsigned integer to a list of 3 bytes.
26468               * @param {number}
26469               * @returns {Array}
26470               */
26471              encode.UINT24 = function(v) {
26472                return [(v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];
26473              };
26474
26475              /**
26476               * @constant
26477               * @type {number}
26478               */
26479              sizeOf.UINT24 = constant(3);
26480
26481              /**
26482               * Convert a 32-bit unsigned integer to a list of 4 bytes.
26483               * @param {number}
26484               * @returns {Array}
26485               */
26486              encode.ULONG = function(v) {
26487                return [(v >> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];
26488              };
26489
26490              /**
26491               * @constant
26492               * @type {number}
26493               */
26494              sizeOf.ULONG = constant(4);
26495
26496              /**
26497               * Convert a 32-bit unsigned integer to a list of 4 bytes.
26498               * @param {number}
26499               * @returns {Array}
26500               */
26501              encode.LONG = function(v) {
26502                // Two's complement
26503                if (v >= LIMIT32) {
26504                  v = -(2 * LIMIT32 - v);
26505                }
26506
26507                return [(v >> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];
26508              };
26509
26510              /**
26511               * @constant
26512               * @type {number}
26513               */
26514              sizeOf.LONG = constant(4);
26515
26516              encode.FIXED = encode.ULONG;
26517              sizeOf.FIXED = sizeOf.ULONG;
26518
26519              encode.FWORD = encode.SHORT;
26520              sizeOf.FWORD = sizeOf.SHORT;
26521
26522              encode.UFWORD = encode.USHORT;
26523              sizeOf.UFWORD = sizeOf.USHORT;
26524
26525              /**
26526               * Convert a 32-bit Apple Mac timestamp integer to a list of 8 bytes, 64-bit timestamp.
26527               * @param {number}
26528               * @returns {Array}
26529               */
26530              encode.LONGDATETIME = function(v) {
26531                return [
26532                  0,
26533                  0,
26534                  0,
26535                  0,
26536                  (v >> 24) & 0xff,
26537                  (v >> 16) & 0xff,
26538                  (v >> 8) & 0xff,
26539                  v & 0xff
26540                ];
26541              };
26542
26543              /**
26544               * @constant
26545               * @type {number}
26546               */
26547              sizeOf.LONGDATETIME = constant(8);
26548
26549              /**
26550               * Convert a 4-char tag to a list of 4 bytes.
26551               * @param {string}
26552               * @returns {Array}
26553               */
26554              encode.TAG = function(v) {
26555                check.argument(v.length === 4, 'Tag should be exactly 4 ASCII characters.');
26556                return [v.charCodeAt(0), v.charCodeAt(1), v.charCodeAt(2), v.charCodeAt(3)];
26557              };
26558
26559              /**
26560               * @constant
26561               * @type {number}
26562               */
26563              sizeOf.TAG = constant(4);
26564
26565              // CFF data types ///////////////////////////////////////////////////////////
26566
26567              encode.Card8 = encode.BYTE;
26568              sizeOf.Card8 = sizeOf.BYTE;
26569
26570              encode.Card16 = encode.USHORT;
26571              sizeOf.Card16 = sizeOf.USHORT;
26572
26573              encode.OffSize = encode.BYTE;
26574              sizeOf.OffSize = sizeOf.BYTE;
26575
26576              encode.SID = encode.USHORT;
26577              sizeOf.SID = sizeOf.USHORT;
26578
26579              // Convert a numeric operand or charstring number to a variable-size list of bytes.
26580              /**
26581               * Convert a numeric operand or charstring number to a variable-size list of bytes.
26582               * @param {number}
26583               * @returns {Array}
26584               */
26585              encode.NUMBER = function(v) {
26586                if (v >= -107 && v <= 107) {
26587                  return [v + 139];
26588                } else if (v >= 108 && v <= 1131) {
26589                  v = v - 108;
26590                  return [(v >> 8) + 247, v & 0xff];
26591                } else if (v >= -1131 && v <= -108) {
26592                  v = -v - 108;
26593                  return [(v >> 8) + 251, v & 0xff];
26594                } else if (v >= -32768 && v <= 32767) {
26595                  return encode.NUMBER16(v);
26596                } else {
26597                  return encode.NUMBER32(v);
26598                }
26599              };
26600
26601              /**
26602               * @param {number}
26603               * @returns {number}
26604               */
26605              sizeOf.NUMBER = function(v) {
26606                return encode.NUMBER(v).length;
26607              };
26608
26609              /**
26610               * Convert a signed number between -32768 and +32767 to a three-byte value.
26611               * This ensures we always use three bytes, but is not the most compact format.
26612               * @param {number}
26613               * @returns {Array}
26614               */
26615              encode.NUMBER16 = function(v) {
26616                return [28, (v >> 8) & 0xff, v & 0xff];
26617              };
26618
26619              /**
26620               * @constant
26621               * @type {number}
26622               */
26623              sizeOf.NUMBER16 = constant(3);
26624
26625              /**
26626               * Convert a signed number between -(2^31) and +(2^31-1) to a five-byte value.
26627               * This is useful if you want to be sure you always use four bytes,
26628               * at the expense of wasting a few bytes for smaller numbers.
26629               * @param {number}
26630               * @returns {Array}
26631               */
26632              encode.NUMBER32 = function(v) {
26633                return [29, (v >> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];
26634              };
26635
26636              /**
26637               * @constant
26638               * @type {number}
26639               */
26640              sizeOf.NUMBER32 = constant(5);
26641
26642              /**
26643               * @param {number}
26644               * @returns {Array}
26645               */
26646              encode.REAL = function(v) {
26647                var value = v.toString();
26648
26649                // Some numbers use an epsilon to encode the value. (e.g. JavaScript will store 0.0000001 as 1e-7)
26650                // This code converts it back to a number without the epsilon.
26651                var m = /\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(value);
26652                if (m) {
26653                  var epsilon = parseFloat('1e' + ((m[2] ? +m[2] : 0) + m[1].length));
26654                  value = (Math.round(v * epsilon) / epsilon).toString();
26655                }
26656
26657                var nibbles = '';
26658                for (var i = 0, ii = value.length; i < ii; i += 1) {
26659                  var c = value[i];
26660                  if (c === 'e') {
26661                    nibbles += value[++i] === '-' ? 'c' : 'b';
26662                  } else if (c === '.') {
26663                    nibbles += 'a';
26664                  } else if (c === '-') {
26665                    nibbles += 'e';
26666                  } else {
26667                    nibbles += c;
26668                  }
26669                }
26670
26671                nibbles += nibbles.length & 1 ? 'f' : 'ff';
26672                var out = [30];
26673                for (var i$1 = 0, ii$1 = nibbles.length; i$1 < ii$1; i$1 += 2) {
26674                  out.push(parseInt(nibbles.substr(i$1, 2), 16));
26675                }
26676
26677                return out;
26678              };
26679
26680              /**
26681               * @param {number}
26682               * @returns {number}
26683               */
26684              sizeOf.REAL = function(v) {
26685                return encode.REAL(v).length;
26686              };
26687
26688              encode.NAME = encode.CHARARRAY;
26689              sizeOf.NAME = sizeOf.CHARARRAY;
26690
26691              encode.STRING = encode.CHARARRAY;
26692              sizeOf.STRING = sizeOf.CHARARRAY;
26693
26694              /**
26695               * @param {DataView} data
26696               * @param {number} offset
26697               * @param {number} numBytes
26698               * @returns {string}
26699               */
26700              decode.UTF8 = function(data, offset, numBytes) {
26701                var codePoints = [];
26702                var numChars = numBytes;
26703                for (var j = 0; j < numChars; j++, offset += 1) {
26704                  codePoints[j] = data.getUint8(offset);
26705                }
26706
26707                return String.fromCharCode.apply(null, codePoints);
26708              };
26709
26710              /**
26711               * @param {DataView} data
26712               * @param {number} offset
26713               * @param {number} numBytes
26714               * @returns {string}
26715               */
26716              decode.UTF16 = function(data, offset, numBytes) {
26717                var codePoints = [];
26718                var numChars = numBytes / 2;
26719                for (var j = 0; j < numChars; j++, offset += 2) {
26720                  codePoints[j] = data.getUint16(offset);
26721                }
26722
26723                return String.fromCharCode.apply(null, codePoints);
26724              };
26725
26726              /**
26727               * Convert a JavaScript string to UTF16-BE.
26728               * @param {string}
26729               * @returns {Array}
26730               */
26731              encode.UTF16 = function(v) {
26732                var b = [];
26733                for (var i = 0; i < v.length; i += 1) {
26734                  var codepoint = v.charCodeAt(i);
26735                  b[b.length] = (codepoint >> 8) & 0xff;
26736                  b[b.length] = codepoint & 0xff;
26737                }
26738
26739                return b;
26740              };
26741
26742              /**
26743               * @param {string}
26744               * @returns {number}
26745               */
26746              sizeOf.UTF16 = function(v) {
26747                return v.length * 2;
26748              };
26749
26750              // Data for converting old eight-bit Macintosh encodings to Unicode.
26751              // This representation is optimized for decoding; encoding is slower
26752              // and needs more memory. The assumption is that all opentype.js users
26753              // want to open fonts, but saving a font will be comparatively rare
26754              // so it can be more expensive. Keyed by IANA character set name.
26755              //
26756              // Python script for generating these strings:
26757              //
26758              //     s = u''.join([chr(c).decode('mac_greek') for c in range(128, 256)])
26759              //     print(s.encode('utf-8'))
26760              /**
26761               * @private
26762               */
26763              var eightBitMacEncodings = {
26764                // Python: 'mac_croatian'
26765                'x-mac-croatian':
26766                  'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø' +
26767                  '¿¡¬√ƒ≈ƫȅ ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ',
26768                // Python: 'mac_cyrillic'
26769                'x-mac-cyrillic':
26770                  'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњ' +
26771                  'јЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю',
26772                // http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/GAELIC.TXT
26773                'x-mac-gaelic':
26774                  'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæø' +
26775                  'ṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ',
26776                // Python: 'mac_greek'
26777                'x-mac-greek':
26778                  'Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩ' +
26779                  'άΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ\u00AD',
26780                // Python: 'mac_iceland'
26781                'x-mac-icelandic':
26782                  'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüݰ¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø' +
26783                  '¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ',
26784                // http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/INUIT.TXT
26785                'x-mac-inuit':
26786                  'ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗ' +
26787                  'ᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł',
26788                // Python: 'mac_latin2'
26789                'x-mac-ce':
26790                  'ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅ' +
26791                  'ņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ',
26792                // Python: 'mac_roman'
26793                macintosh:
26794                  'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø' +
26795                  '¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ',
26796                // Python: 'mac_romanian'
26797                'x-mac-romanian':
26798                  'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș' +
26799                  '¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ',
26800                // Python: 'mac_turkish'
26801                'x-mac-turkish':
26802                  'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø' +
26803                  '¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ'
26804              };
26805
26806              /**
26807               * Decodes an old-style Macintosh string. Returns either a Unicode JavaScript
26808               * string, or 'undefined' if the encoding is unsupported. For example, we do
26809               * not support Chinese, Japanese or Korean because these would need large
26810               * mapping tables.
26811               * @param {DataView} dataView
26812               * @param {number} offset
26813               * @param {number} dataLength
26814               * @param {string} encoding
26815               * @returns {string}
26816               */
26817              decode.MACSTRING = function(dataView, offset, dataLength, encoding) {
26818                var table = eightBitMacEncodings[encoding];
26819                if (table === undefined) {
26820                  return undefined;
26821                }
26822
26823                var result = '';
26824                for (var i = 0; i < dataLength; i++) {
26825                  var c = dataView.getUint8(offset + i);
26826                  // In all eight-bit Mac encodings, the characters 0x00..0x7F are
26827                  // mapped to U+0000..U+007F; we only need to look up the others.
26828                  if (c <= 0x7f) {
26829                    result += String.fromCharCode(c);
26830                  } else {
26831                    result += table[c & 0x7f];
26832                  }
26833                }
26834
26835                return result;
26836              };
26837
26838              // Helper function for encode.MACSTRING. Returns a dictionary for mapping
26839              // Unicode character codes to their 8-bit MacOS equivalent. This table
26840              // is not exactly a super cheap data structure, but we do not care because
26841              // encoding Macintosh strings is only rarely needed in typical applications.
26842              var macEncodingTableCache = typeof WeakMap === 'function' && new WeakMap();
26843              var macEncodingCacheKeys;
26844              var getMacEncodingTable = function(encoding) {
26845                // Since we use encoding as a cache key for WeakMap, it has to be
26846                // a String object and not a literal. And at least on NodeJS 2.10.1,
26847                // WeakMap requires that the same String instance is passed for cache hits.
26848                if (!macEncodingCacheKeys) {
26849                  macEncodingCacheKeys = {};
26850                  for (var e in eightBitMacEncodings) {
26851                    /*jshint -W053 */ // Suppress "Do not use String as a constructor."
26852                    macEncodingCacheKeys[e] = new String(e);
26853                  }
26854                }
26855
26856                var cacheKey = macEncodingCacheKeys[encoding];
26857                if (cacheKey === undefined) {
26858                  return undefined;
26859                }
26860
26861                // We can't do "if (cache.has(key)) {return cache.get(key)}" here:
26862                // since garbage collection may run at any time, it could also kick in
26863                // between the calls to cache.has() and cache.get(). In that case,
26864                // we would return 'undefined' even though we do support the encoding.
26865                if (macEncodingTableCache) {
26866                  var cachedTable = macEncodingTableCache.get(cacheKey);
26867                  if (cachedTable !== undefined) {
26868                    return cachedTable;
26869                  }
26870                }
26871
26872                var decodingTable = eightBitMacEncodings[encoding];
26873                if (decodingTable === undefined) {
26874                  return undefined;
26875                }
26876
26877                var encodingTable = {};
26878                for (var i = 0; i < decodingTable.length; i++) {
26879                  encodingTable[decodingTable.charCodeAt(i)] = i + 0x80;
26880                }
26881
26882                if (macEncodingTableCache) {
26883                  macEncodingTableCache.set(cacheKey, encodingTable);
26884                }
26885
26886                return encodingTable;
26887              };
26888
26889              /**
26890               * Encodes an old-style Macintosh string. Returns a byte array upon success.
26891               * If the requested encoding is unsupported, or if the input string contains
26892               * a character that cannot be expressed in the encoding, the function returns
26893               * 'undefined'.
26894               * @param {string} str
26895               * @param {string} encoding
26896               * @returns {Array}
26897               */
26898              encode.MACSTRING = function(str, encoding) {
26899                var table = getMacEncodingTable(encoding);
26900                if (table === undefined) {
26901                  return undefined;
26902                }
26903
26904                var result = [];
26905                for (var i = 0; i < str.length; i++) {
26906                  var c = str.charCodeAt(i);
26907
26908                  // In all eight-bit Mac encodings, the characters 0x00..0x7F are
26909                  // mapped to U+0000..U+007F; we only need to look up the others.
26910                  if (c >= 0x80) {
26911                    c = table[c];
26912                    if (c === undefined) {
26913                      // str contains a Unicode character that cannot be encoded
26914                      // in the requested encoding.
26915                      return undefined;
26916                    }
26917                  }
26918                  result[i] = c;
26919                  // result.push(c);
26920                }
26921
26922                return result;
26923              };
26924
26925              /**
26926               * @param {string} str
26927               * @param {string} encoding
26928               * @returns {number}
26929               */
26930              sizeOf.MACSTRING = function(str, encoding) {
26931                var b = encode.MACSTRING(str, encoding);
26932                if (b !== undefined) {
26933                  return b.length;
26934                } else {
26935                  return 0;
26936                }
26937              };
26938
26939              // Helper for encode.VARDELTAS
26940              function isByteEncodable(value) {
26941                return value >= -128 && value <= 127;
26942              }
26943
26944              // Helper for encode.VARDELTAS
26945              function encodeVarDeltaRunAsZeroes(deltas, pos, result) {
26946                var runLength = 0;
26947                var numDeltas = deltas.length;
26948                while (pos < numDeltas && runLength < 64 && deltas[pos] === 0) {
26949                  ++pos;
26950                  ++runLength;
26951                }
26952                result.push(0x80 | (runLength - 1));
26953                return pos;
26954              }
26955
26956              // Helper for encode.VARDELTAS
26957              function encodeVarDeltaRunAsBytes(deltas, offset, result) {
26958                var runLength = 0;
26959                var numDeltas = deltas.length;
26960                var pos = offset;
26961                while (pos < numDeltas && runLength < 64) {
26962                  var value = deltas[pos];
26963                  if (!isByteEncodable(value)) {
26964                    break;
26965                  }
26966
26967                  // Within a byte-encoded run of deltas, a single zero is best
26968                  // stored literally as 0x00 value. However, if we have two or
26969                  // more zeroes in a sequence, it is better to start a new run.
26970                  // Fore example, the sequence of deltas [15, 15, 0, 15, 15]
26971                  // becomes 6 bytes (04 0F 0F 00 0F 0F) when storing the zero
26972                  // within the current run, but 7 bytes (01 0F 0F 80 01 0F 0F)
26973                  // when starting a new run.
26974                  if (value === 0 && pos + 1 < numDeltas && deltas[pos + 1] === 0) {
26975                    break;
26976                  }
26977
26978                  ++pos;
26979                  ++runLength;
26980                }
26981                result.push(runLength - 1);
26982                for (var i = offset; i < pos; ++i) {
26983                  result.push((deltas[i] + 256) & 0xff);
26984                }
26985                return pos;
26986              }
26987
26988              // Helper for encode.VARDELTAS
26989              function encodeVarDeltaRunAsWords(deltas, offset, result) {
26990                var runLength = 0;
26991                var numDeltas = deltas.length;
26992                var pos = offset;
26993                while (pos < numDeltas && runLength < 64) {
26994                  var value = deltas[pos];
26995
26996                  // Within a word-encoded run of deltas, it is easiest to start
26997                  // a new run (with a different encoding) whenever we encounter
26998                  // a zero value. For example, the sequence [0x6666, 0, 0x7777]
26999                  // needs 7 bytes when storing the zero inside the current run
27000                  // (42 66 66 00 00 77 77), and equally 7 bytes when starting a
27001                  // new run (40 66 66 80 40 77 77).
27002                  if (value === 0) {
27003                    break;
27004                  }
27005
27006                  // Within a word-encoded run of deltas, a single value in the
27007                  // range (-128..127) should be encoded within the current run
27008                  // because it is more compact. For example, the sequence
27009                  // [0x6666, 2, 0x7777] becomes 7 bytes when storing the value
27010                  // literally (42 66 66 00 02 77 77), but 8 bytes when starting
27011                  // a new run (40 66 66 00 02 40 77 77).
27012                  if (
27013                    isByteEncodable(value) &&
27014                    pos + 1 < numDeltas &&
27015                    isByteEncodable(deltas[pos + 1])
27016                  ) {
27017                    break;
27018                  }
27019
27020                  ++pos;
27021                  ++runLength;
27022                }
27023                result.push(0x40 | (runLength - 1));
27024                for (var i = offset; i < pos; ++i) {
27025                  var val = deltas[i];
27026                  result.push(((val + 0x10000) >> 8) & 0xff, (val + 0x100) & 0xff);
27027                }
27028                return pos;
27029              }
27030
27031              /**
27032               * Encode a list of variation adjustment deltas.
27033               *
27034               * Variation adjustment deltas are used in ‘gvar’ and ‘cvar’ tables.
27035               * They indicate how points (in ‘gvar’) or values (in ‘cvar’) get adjusted
27036               * when generating instances of variation fonts.
27037               *
27038               * @see https://www.microsoft.com/typography/otspec/gvar.htm
27039               * @see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gvar.html
27040               * @param {Array}
27041               * @return {Array}
27042               */
27043              encode.VARDELTAS = function(deltas) {
27044                var pos = 0;
27045                var result = [];
27046                while (pos < deltas.length) {
27047                  var value = deltas[pos];
27048                  if (value === 0) {
27049                    pos = encodeVarDeltaRunAsZeroes(deltas, pos, result);
27050                  } else if (value >= -128 && value <= 127) {
27051                    pos = encodeVarDeltaRunAsBytes(deltas, pos, result);
27052                  } else {
27053                    pos = encodeVarDeltaRunAsWords(deltas, pos, result);
27054                  }
27055                }
27056                return result;
27057              };
27058
27059              // Convert a list of values to a CFF INDEX structure.
27060              // The values should be objects containing name / type / value.
27061              /**
27062               * @param {Array} l
27063               * @returns {Array}
27064               */
27065              encode.INDEX = function(l) {
27066                //var offset, offsets, offsetEncoder, encodedOffsets, encodedOffset, data,
27067                //    i, v;
27068                // Because we have to know which data type to use to encode the offsets,
27069                // we have to go through the values twice: once to encode the data and
27070                // calculate the offsets, then again to encode the offsets using the fitting data type.
27071                var offset = 1; // First offset is always 1.
27072                var offsets = [offset];
27073                var data = [];
27074                for (var i = 0; i < l.length; i += 1) {
27075                  var v = encode.OBJECT(l[i]);
27076                  Array.prototype.push.apply(data, v);
27077                  offset += v.length;
27078                  offsets.push(offset);
27079                }
27080
27081                if (data.length === 0) {
27082                  return [0, 0];
27083                }
27084
27085                var encodedOffsets = [];
27086                var offSize = (1 + Math.floor(Math.log(offset) / Math.log(2)) / 8) | 0;
27087                var offsetEncoder = [
27088                  undefined,
27089                  encode.BYTE,
27090                  encode.USHORT,
27091                  encode.UINT24,
27092                  encode.ULONG
27093                ][offSize];
27094                for (var i$1 = 0; i$1 < offsets.length; i$1 += 1) {
27095                  var encodedOffset = offsetEncoder(offsets[i$1]);
27096                  Array.prototype.push.apply(encodedOffsets, encodedOffset);
27097                }
27098
27099                return Array.prototype.concat(
27100                  encode.Card16(l.length),
27101                  encode.OffSize(offSize),
27102                  encodedOffsets,
27103                  data
27104                );
27105              };
27106
27107              /**
27108               * @param {Array}
27109               * @returns {number}
27110               */
27111              sizeOf.INDEX = function(v) {
27112                return encode.INDEX(v).length;
27113              };
27114
27115              /**
27116               * Convert an object to a CFF DICT structure.
27117               * The keys should be numeric.
27118               * The values should be objects containing name / type / value.
27119               * @param {Object} m
27120               * @returns {Array}
27121               */
27122              encode.DICT = function(m) {
27123                var d = [];
27124                var keys = Object.keys(m);
27125                var length = keys.length;
27126
27127                for (var i = 0; i < length; i += 1) {
27128                  // Object.keys() return string keys, but our keys are always numeric.
27129                  var k = parseInt(keys[i], 0);
27130                  var v = m[k];
27131                  // Value comes before the key.
27132                  d = d.concat(encode.OPERAND(v.value, v.type));
27133                  d = d.concat(encode.OPERATOR(k));
27134                }
27135
27136                return d;
27137              };
27138
27139              /**
27140               * @param {Object}
27141               * @returns {number}
27142               */
27143              sizeOf.DICT = function(m) {
27144                return encode.DICT(m).length;
27145              };
27146
27147              /**
27148               * @param {number}
27149               * @returns {Array}
27150               */
27151              encode.OPERATOR = function(v) {
27152                if (v < 1200) {
27153                  return [v];
27154                } else {
27155                  return [12, v - 1200];
27156                }
27157              };
27158
27159              /**
27160               * @param {Array} v
27161               * @param {string}
27162               * @returns {Array}
27163               */
27164              encode.OPERAND = function(v, type) {
27165                var d = [];
27166                if (Array.isArray(type)) {
27167                  for (var i = 0; i < type.length; i += 1) {
27168                    check.argument(
27169                      v.length === type.length,
27170                      'Not enough arguments given for type' + type
27171                    );
27172                    d = d.concat(encode.OPERAND(v[i], type[i]));
27173                  }
27174                } else {
27175                  if (type === 'SID') {
27176                    d = d.concat(encode.NUMBER(v));
27177                  } else if (type === 'offset') {
27178                    // We make it easy for ourselves and always encode offsets as
27179                    // 4 bytes. This makes offset calculation for the top dict easier.
27180                    d = d.concat(encode.NUMBER32(v));
27181                  } else if (type === 'number') {
27182                    d = d.concat(encode.NUMBER(v));
27183                  } else if (type === 'real') {
27184                    d = d.concat(encode.REAL(v));
27185                  } else {
27186                    throw new Error('Unknown operand type ' + type);
27187                    // FIXME Add support for booleans
27188                  }
27189                }
27190
27191                return d;
27192              };
27193
27194              encode.OP = encode.BYTE;
27195              sizeOf.OP = sizeOf.BYTE;
27196
27197              // memoize charstring encoding using WeakMap if available
27198              var wmm = typeof WeakMap === 'function' && new WeakMap();
27199
27200              /**
27201               * Convert a list of CharString operations to bytes.
27202               * @param {Array}
27203               * @returns {Array}
27204               */
27205              encode.CHARSTRING = function(ops) {
27206                // See encode.MACSTRING for why we don't do "if (wmm && wmm.has(ops))".
27207                if (wmm) {
27208                  var cachedValue = wmm.get(ops);
27209                  if (cachedValue !== undefined) {
27210                    return cachedValue;
27211                  }
27212                }
27213
27214                var d = [];
27215                var length = ops.length;
27216
27217                for (var i = 0; i < length; i += 1) {
27218                  var op = ops[i];
27219                  d = d.concat(encode[op.type](op.value));
27220                }
27221
27222                if (wmm) {
27223                  wmm.set(ops, d);
27224                }
27225
27226                return d;
27227              };
27228
27229              /**
27230               * @param {Array}
27231               * @returns {number}
27232               */
27233              sizeOf.CHARSTRING = function(ops) {
27234                return encode.CHARSTRING(ops).length;
27235              };
27236
27237              // Utility functions ////////////////////////////////////////////////////////
27238
27239              /**
27240               * Convert an object containing name / type / value to bytes.
27241               * @param {Object}
27242               * @returns {Array}
27243               */
27244              encode.OBJECT = function(v) {
27245                var encodingFunction = encode[v.type];
27246                check.argument(
27247                  encodingFunction !== undefined,
27248                  'No encoding function for type ' + v.type
27249                );
27250                return encodingFunction(v.value);
27251              };
27252
27253              /**
27254               * @param {Object}
27255               * @returns {number}
27256               */
27257              sizeOf.OBJECT = function(v) {
27258                var sizeOfFunction = sizeOf[v.type];
27259                check.argument(
27260                  sizeOfFunction !== undefined,
27261                  'No sizeOf function for type ' + v.type
27262                );
27263                return sizeOfFunction(v.value);
27264              };
27265
27266              /**
27267               * Convert a table object to bytes.
27268               * A table contains a list of fields containing the metadata (name, type and default value).
27269               * The table itself has the field values set as attributes.
27270               * @param {opentype.Table}
27271               * @returns {Array}
27272               */
27273              encode.TABLE = function(table) {
27274                var d = [];
27275                var length = table.fields.length;
27276                var subtables = [];
27277                var subtableOffsets = [];
27278
27279                for (var i = 0; i < length; i += 1) {
27280                  var field = table.fields[i];
27281                  var encodingFunction = encode[field.type];
27282                  check.argument(
27283                    encodingFunction !== undefined,
27284                    'No encoding function for field type ' +
27285                      field.type +
27286                      ' (' +
27287                      field.name +
27288                      ')'
27289                  );
27290                  var value = table[field.name];
27291                  if (value === undefined) {
27292                    value = field.value;
27293                  }
27294
27295                  var bytes = encodingFunction(value);
27296
27297                  if (field.type === 'TABLE') {
27298                    subtableOffsets.push(d.length);
27299                    d = d.concat([0, 0]);
27300                    subtables.push(bytes);
27301                  } else {
27302                    d = d.concat(bytes);
27303                  }
27304                }
27305
27306                for (var i$1 = 0; i$1 < subtables.length; i$1 += 1) {
27307                  var o = subtableOffsets[i$1];
27308                  var offset = d.length;
27309                  check.argument(offset < 65536, 'Table ' + table.tableName + ' too big.');
27310                  d[o] = offset >> 8;
27311                  d[o + 1] = offset & 0xff;
27312                  d = d.concat(subtables[i$1]);
27313                }
27314
27315                return d;
27316              };
27317
27318              /**
27319               * @param {opentype.Table}
27320               * @returns {number}
27321               */
27322              sizeOf.TABLE = function(table) {
27323                var numBytes = 0;
27324                var length = table.fields.length;
27325
27326                for (var i = 0; i < length; i += 1) {
27327                  var field = table.fields[i];
27328                  var sizeOfFunction = sizeOf[field.type];
27329                  check.argument(
27330                    sizeOfFunction !== undefined,
27331                    'No sizeOf function for field type ' +
27332                      field.type +
27333                      ' (' +
27334                      field.name +
27335                      ')'
27336                  );
27337                  var value = table[field.name];
27338                  if (value === undefined) {
27339                    value = field.value;
27340                  }
27341
27342                  numBytes += sizeOfFunction(value);
27343
27344                  // Subtables take 2 more bytes for offsets.
27345                  if (field.type === 'TABLE') {
27346                    numBytes += 2;
27347                  }
27348                }
27349
27350                return numBytes;
27351              };
27352
27353              encode.RECORD = encode.TABLE;
27354              sizeOf.RECORD = sizeOf.TABLE;
27355
27356              // Merge in a list of bytes.
27357              encode.LITERAL = function(v) {
27358                return v;
27359              };
27360
27361              sizeOf.LITERAL = function(v) {
27362                return v.length;
27363              };
27364
27365              // Table metadata
27366
27367              /**
27368               * @exports opentype.Table
27369               * @class
27370               * @param {string} tableName
27371               * @param {Array} fields
27372               * @param {Object} options
27373               * @constructor
27374               */
27375              function Table(tableName, fields, options) {
27376                var this$1 = this;
27377
27378                for (var i = 0; i < fields.length; i += 1) {
27379                  var field = fields[i];
27380                  this$1[field.name] = field.value;
27381                }
27382
27383                this.tableName = tableName;
27384                this.fields = fields;
27385                if (options) {
27386                  var optionKeys = Object.keys(options);
27387                  for (var i$1 = 0; i$1 < optionKeys.length; i$1 += 1) {
27388                    var k = optionKeys[i$1];
27389                    var v = options[k];
27390                    if (this$1[k] !== undefined) {
27391                      this$1[k] = v;
27392                    }
27393                  }
27394                }
27395              }
27396
27397              /**
27398               * Encodes the table and returns an array of bytes
27399               * @return {Array}
27400               */
27401              Table.prototype.encode = function() {
27402                return encode.TABLE(this);
27403              };
27404
27405              /**
27406               * Get the size of the table.
27407               * @return {number}
27408               */
27409              Table.prototype.sizeOf = function() {
27410                return sizeOf.TABLE(this);
27411              };
27412
27413              /**
27414               * @private
27415               */
27416              function ushortList(itemName, list, count) {
27417                if (count === undefined) {
27418                  count = list.length;
27419                }
27420                var fields = new Array(list.length + 1);
27421                fields[0] = { name: itemName + 'Count', type: 'USHORT', value: count };
27422                for (var i = 0; i < list.length; i++) {
27423                  fields[i + 1] = { name: itemName + i, type: 'USHORT', value: list[i] };
27424                }
27425                return fields;
27426              }
27427
27428              /**
27429               * @private
27430               */
27431              function tableList(itemName, records, itemCallback) {
27432                var count = records.length;
27433                var fields = new Array(count + 1);
27434                fields[0] = { name: itemName + 'Count', type: 'USHORT', value: count };
27435                for (var i = 0; i < count; i++) {
27436                  fields[i + 1] = {
27437                    name: itemName + i,
27438                    type: 'TABLE',
27439                    value: itemCallback(records[i], i)
27440                  };
27441                }
27442                return fields;
27443              }
27444
27445              /**
27446               * @private
27447               */
27448              function recordList(itemName, records, itemCallback) {
27449                var count = records.length;
27450                var fields = [];
27451                fields[0] = { name: itemName + 'Count', type: 'USHORT', value: count };
27452                for (var i = 0; i < count; i++) {
27453                  fields = fields.concat(itemCallback(records[i], i));
27454                }
27455                return fields;
27456              }
27457
27458              // Common Layout Tables
27459
27460              /**
27461               * @exports opentype.Coverage
27462               * @class
27463               * @param {opentype.Table}
27464               * @constructor
27465               * @extends opentype.Table
27466               */
27467              function Coverage(coverageTable) {
27468                if (coverageTable.format === 1) {
27469                  Table.call(
27470                    this,
27471                    'coverageTable',
27472                    [{ name: 'coverageFormat', type: 'USHORT', value: 1 }].concat(
27473                      ushortList('glyph', coverageTable.glyphs)
27474                    )
27475                  );
27476                } else {
vendor: 4,697 bytes, lines 27477-27583
27477                  check.assert(false, "Can't create coverage table format 2 yet.");
27478                }
27479              }
27480              Coverage.prototype = Object.create(Table.prototype);
27481              Coverage.prototype.constructor = Coverage;
27482
27483              function ScriptList(scriptListTable) {
27484                Table.call(
27485                  this,
27486                  'scriptListTable',
27487                  recordList('scriptRecord', scriptListTable, function(scriptRecord, i) {
27488                    var script = scriptRecord.script;
27489                    var defaultLangSys = script.defaultLangSys;
27490                    check.assert(
27491                      !!defaultLangSys,
27492                      'Unable to write GSUB: script ' +
27493                        scriptRecord.tag +
27494                        ' has no default language system.'
27495                    );
27496                    return [
27497                      { name: 'scriptTag' + i, type: 'TAG', value: scriptRecord.tag },
27498                      {
27499                        name: 'script' + i,
27500                        type: 'TABLE',
27501                        value: new Table(
27502                          'scriptTable',
27503                          [
27504                            {
27505                              name: 'defaultLangSys',
27506                              type: 'TABLE',
27507                              value: new Table(
27508                                'defaultLangSys',
27509                                [
27510                                  { name: 'lookupOrder', type: 'USHORT', value: 0 },
27511                                  {
27512                                    name: 'reqFeatureIndex',
27513                                    type: 'USHORT',
27514                                    value: defaultLangSys.reqFeatureIndex
27515                                  }
27516                                ].concat(
27517                                  ushortList('featureIndex', defaultLangSys.featureIndexes)
27518                                )
27519                              )
27520                            }
27521                          ].concat(
27522                            recordList('langSys', script.langSysRecords, function(
27523                              langSysRecord,
27524                              i
27525                            ) {
27526                              var langSys = langSysRecord.langSys;
27527                              return [
27528                                {
27529                                  name: 'langSysTag' + i,
27530                                  type: 'TAG',
27531                                  value: langSysRecord.tag
27532                                },
27533                                {
27534                                  name: 'langSys' + i,
27535                                  type: 'TABLE',
27536                                  value: new Table(
27537                                    'langSys',
27538                                    [
27539                                      { name: 'lookupOrder', type: 'USHORT', value: 0 },
27540                                      {
27541                                        name: 'reqFeatureIndex',
27542                                        type: 'USHORT',
27543                                        value: langSys.reqFeatureIndex
27544                                      }
27545                                    ].concat(
27546                                      ushortList('featureIndex', langSys.featureIndexes)
27547                                    )
27548                                  )
27549                                }
27550                              ];
27551                            })
27552                          )
27553                        )
27554                      }
27555                    ];
27556                  })
27557                );
27558              }
27559              ScriptList.prototype = Object.create(Table.prototype);
27560              ScriptList.prototype.constructor = ScriptList;
27561
27562              /**
27563               * @exports opentype.FeatureList
27564               * @class
27565               * @param {opentype.Table}
27566               * @constructor
27567               * @extends opentype.Table
27568               */
27569              function FeatureList(featureListTable) {
27570                Table.call(
27571                  this,
27572                  'featureListTable',
27573                  recordList('featureRecord', featureListTable, function(featureRecord, i) {
27574                    var feature = featureRecord.feature;
27575                    return [
27576                      { name: 'featureTag' + i, type: 'TAG', value: featureRecord.tag },
27577                      {
27578                        name: 'feature' + i,
27579                        type: 'TABLE',
27580                        value: new Table(
27581                          'featureTable',
27582                          [
27583                            {
27584                              name: 'featureParams',
27585                              type: 'USHORT',
27586                              value: feature.featureParams
27587                            }
27588                          ].concat(ushortList('lookupListIndex', feature.lookupListIndexes))
27589                        )
27590                      }
27591                    ];
27592                  })
27593                );
27594              }
27595              FeatureList.prototype = Object.create(Table.prototype);
27596              FeatureList.prototype.constructor = FeatureList;
27597
27598              /**
27599               * @exports opentype.LookupList
27600               * @class
27601               * @param {opentype.Table}
27602               * @param {Object}
27603               * @constructor
27604               * @extends opentype.Table
27605               */
27606              function LookupList(lookupListTable, subtableMakers) {
27607                Table.call(
27608                  this,
27609                  'lookupListTable',
27610                  tableList('lookup', lookupListTable, function(lookupTable) {
27611                    var subtableCallback = subtableMakers[lookupTable.lookupType];
27612                    check.assert(
27613                      !!subtableCallback,
27614                      'Unable to write GSUB lookup type ' +
27615                        lookupTable.lookupType +
27616                        ' tables.'
27617                    );
27618                    return new Table(
27619                      'lookupTable',
27620                      [
27621                        {
27622                          name: 'lookupType',
27623                          type: 'USHORT',
27624                          value: lookupTable.lookupType
27625                        },
27626                        {
27627                          name: 'lookupFlag',
27628                          type: 'USHORT',
27629                          value: lookupTable.lookupFlag
27630                        }
27631                      ].concat(
27632                        tableList('subtable', lookupTable.subtables, subtableCallback)
27633                      )
27634                    );
27635                  })
27636                );
27637              }
27638              LookupList.prototype = Object.create(Table.prototype);
27639              LookupList.prototype.constructor = LookupList;
27640
27641              // Record = same as Table, but inlined (a Table has an offset and its data is further in the stream)
27642              // Don't use offsets inside Records (probable bug), only in Tables.
27643              var table = {
27644                Table: Table,
27645                Record: Table,
27646                Coverage: Coverage,
27647                ScriptList: ScriptList,
27648                FeatureList: FeatureList,
27649                LookupList: LookupList,
27650                ushortList: ushortList,
27651                tableList: tableList,
27652                recordList: recordList
27653              };
27654
27655              // Parsing utility functions
27656
27657              // Retrieve an unsigned byte from the DataView.
27658              function getByte(dataView, offset) {
27659                return dataView.getUint8(offset);
27660              }
27661
27662              // Retrieve an unsigned 16-bit short from the DataView.
27663              // The value is stored in big endian.
27664              function getUShort(dataView, offset) {
27665                return dataView.getUint16(offset, false);
27666              }
27667
27668              // Retrieve a signed 16-bit short from the DataView.
27669              // The value is stored in big endian.
27670              function getShort(dataView, offset) {
27671                return dataView.getInt16(offset, false);
27672              }
27673
27674              // Retrieve an unsigned 32-bit long from the DataView.
27675              // The value is stored in big endian.
27676              function getULong(dataView, offset) {
27677                return dataView.getUint32(offset, false);
27678              }
27679
27680              // Retrieve a 32-bit signed fixed-point number (16.16) from the DataView.
27681              // The value is stored in big endian.
27682              function getFixed(dataView, offset) {
27683                var decimal = dataView.getInt16(offset, false);
27684                var fraction = dataView.getUint16(offset + 2, false);
27685                return decimal + fraction / 65535;
27686              }
27687
27688              // Retrieve a 4-character tag from the DataView.
27689              // Tags are used to identify tables.
27690              function getTag(dataView, offset) {
27691                var tag = '';
27692                for (var i = offset; i < offset + 4; i += 1) {
27693                  tag += String.fromCharCode(dataView.getInt8(i));
27694                }
27695
27696                return tag;
27697              }
27698
27699              // Retrieve an offset from the DataView.
27700              // Offsets are 1 to 4 bytes in length, depending on the offSize argument.
27701              function getOffset(dataView, offset, offSize) {
27702                var v = 0;
27703                for (var i = 0; i < offSize; i += 1) {
27704                  v <<= 8;
27705                  v += dataView.getUint8(offset + i);
27706                }
27707
27708                return v;
27709              }
27710
27711              // Retrieve a number of bytes from start offset to the end offset from the DataView.
27712              function getBytes(dataView, startOffset, endOffset) {
27713                var bytes = [];
27714                for (var i = startOffset; i < endOffset; i += 1) {
27715                  bytes.push(dataView.getUint8(i));
27716                }
27717
27718                return bytes;
27719              }
27720
vendor: 7,076 bytes, lines 27721-27902
27721              // Convert the list of bytes to a string.
27722              function bytesToString(bytes) {
27723                var s = '';
27724                for (var i = 0; i < bytes.length; i += 1) {
27725                  s += String.fromCharCode(bytes[i]);
27726                }
27727
27728                return s;
27729              }
27730
27731              var typeOffsets = {
27732                byte: 1,
27733                uShort: 2,
27734                short: 2,
27735                uLong: 4,
27736                fixed: 4,
27737                longDateTime: 8,
27738                tag: 4
27739              };
27740
27741              // A stateful parser that changes the offset whenever a value is retrieved.
27742              // The data is a DataView.
27743              function Parser(data, offset) {
27744                this.data = data;
27745                this.offset = offset;
27746                this.relativeOffset = 0;
27747              }
27748
27749              Parser.prototype.parseByte = function() {
27750                var v = this.data.getUint8(this.offset + this.relativeOffset);
27751                this.relativeOffset += 1;
27752                return v;
27753              };
27754
27755              Parser.prototype.parseChar = function() {
27756                var v = this.data.getInt8(this.offset + this.relativeOffset);
27757                this.relativeOffset += 1;
27758                return v;
27759              };
27760
27761              Parser.prototype.parseCard8 = Parser.prototype.parseByte;
27762
27763              Parser.prototype.parseUShort = function() {
27764                var v = this.data.getUint16(this.offset + this.relativeOffset);
27765                this.relativeOffset += 2;
27766                return v;
27767              };
27768
27769              Parser.prototype.parseCard16 = Parser.prototype.parseUShort;
27770              Parser.prototype.parseSID = Parser.prototype.parseUShort;
27771              Parser.prototype.parseOffset16 = Parser.prototype.parseUShort;
27772
27773              Parser.prototype.parseShort = function() {
27774                var v = this.data.getInt16(this.offset + this.relativeOffset);
27775                this.relativeOffset += 2;
27776                return v;
27777              };
27778
27779              Parser.prototype.parseF2Dot14 = function() {
27780                var v = this.data.getInt16(this.offset + this.relativeOffset) / 16384;
27781                this.relativeOffset += 2;
27782                return v;
27783              };
27784
27785              Parser.prototype.parseULong = function() {
27786                var v = getULong(this.data, this.offset + this.relativeOffset);
27787                this.relativeOffset += 4;
27788                return v;
27789              };
27790
27791              Parser.prototype.parseOffset32 = Parser.prototype.parseULong;
27792
27793              Parser.prototype.parseFixed = function() {
27794                var v = getFixed(this.data, this.offset + this.relativeOffset);
27795                this.relativeOffset += 4;
27796                return v;
27797              };
27798
27799              Parser.prototype.parseString = function(length) {
27800                var dataView = this.data;
27801                var offset = this.offset + this.relativeOffset;
27802                var string = '';
27803                this.relativeOffset += length;
27804                for (var i = 0; i < length; i++) {
27805                  string += String.fromCharCode(dataView.getUint8(offset + i));
27806                }
27807
27808                return string;
27809              };
27810
27811              Parser.prototype.parseTag = function() {
27812                return this.parseString(4);
27813              };
27814
27815              // LONGDATETIME is a 64-bit integer.
27816              // JavaScript and unix timestamps traditionally use 32 bits, so we
27817              // only take the last 32 bits.
27818              // + Since until 2038 those bits will be filled by zeros we can ignore them.
27819              Parser.prototype.parseLongDateTime = function() {
27820                var v = getULong(this.data, this.offset + this.relativeOffset + 4);
27821                // Subtract seconds between 01/01/1904 and 01/01/1970
27822                // to convert Apple Mac timestamp to Standard Unix timestamp
27823                v -= 2082844800;
27824                this.relativeOffset += 8;
27825                return v;
27826              };
27827
27828              Parser.prototype.parseVersion = function(minorBase) {
27829                var major = getUShort(this.data, this.offset + this.relativeOffset);
27830
27831                // How to interpret the minor version is very vague in the spec. 0x5000 is 5, 0x1000 is 1
27832                // Default returns the correct number if minor = 0xN000 where N is 0-9
27833                // Set minorBase to 1 for tables that use minor = N where N is 0-9
27834                var minor = getUShort(this.data, this.offset + this.relativeOffset + 2);
27835                this.relativeOffset += 4;
27836                if (minorBase === undefined) {
27837                  minorBase = 0x1000;
27838                }
27839                return major + minor / minorBase / 10;
27840              };
27841
27842              Parser.prototype.skip = function(type, amount) {
27843                if (amount === undefined) {
27844                  amount = 1;
27845                }
27846
27847                this.relativeOffset += typeOffsets[type] * amount;
27848              };
27849
27850              ///// Parsing lists and records ///////////////////////////////
27851
27852              // Parse a list of 32 bit unsigned integers.
27853              Parser.prototype.parseULongList = function(count) {
27854                if (count === undefined) {
27855                  count = this.parseULong();
27856                }
27857                var offsets = new Array(count);
27858                var dataView = this.data;
27859                var offset = this.offset + this.relativeOffset;
27860                for (var i = 0; i < count; i++) {
27861                  offsets[i] = dataView.getUint32(offset);
27862                  offset += 4;
27863                }
27864
27865                this.relativeOffset += count * 4;
27866                return offsets;
27867              };
27868
27869              // Parse a list of 16 bit unsigned integers. The length of the list can be read on the stream
27870              // or provided as an argument.
27871              Parser.prototype.parseOffset16List = Parser.prototype.parseUShortList = function(
27872                count
27873              ) {
27874                if (count === undefined) {
27875                  count = this.parseUShort();
27876                }
27877                var offsets = new Array(count);
27878                var dataView = this.data;
27879                var offset = this.offset + this.relativeOffset;
27880                for (var i = 0; i < count; i++) {
27881                  offsets[i] = dataView.getUint16(offset);
27882                  offset += 2;
27883                }
27884
27885                this.relativeOffset += count * 2;
27886                return offsets;
27887              };
27888
27889              // Parses a list of 16 bit signed integers.
27890              Parser.prototype.parseShortList = function(count) {
27891                var list = new Array(count);
27892                var dataView = this.data;
27893                var offset = this.offset + this.relativeOffset;
27894                for (var i = 0; i < count; i++) {
27895                  list[i] = dataView.getInt16(offset);
27896                  offset += 2;
27897                }
27898
27899                this.relativeOffset += count * 2;
27900                return list;
27901              };
27902
27903              // Parses a list of bytes.
27904              Parser.prototype.parseByteList = function(count) {
27905                var list = new Array(count);
27906                var dataView = this.data;
27907                var offset = this.offset + this.relativeOffset;
27908                for (var i = 0; i < count; i++) {
27909                  list[i] = dataView.getUint8(offset++);
27910                }
27911
27912                this.relativeOffset += count;
27913                return list;
27914              };
27915
27916              /**
27917               * Parse a list of items.
27918               * Record count is optional, if omitted it is read from the stream.
27919               * itemCallback is one of the Parser methods.
27920               */
27921              Parser.prototype.parseList = function(count, itemCallback) {
27922                var this$1 = this;
27923
27924                if (!itemCallback) {
27925                  itemCallback = count;
27926                  count = this.parseUShort();
27927                }
27928                var list = new Array(count);
27929                for (var i = 0; i < count; i++) {
27930                  list[i] = itemCallback.call(this$1);
27931                }
27932                return list;
27933              };
27934
27935              Parser.prototype.parseList32 = function(count, itemCallback) {
27936                var this$1 = this;
27937
27938                if (!itemCallback) {
27939                  itemCallback = count;
27940                  count = this.parseULong();
27941                }
27942                var list = new Array(count);
27943                for (var i = 0; i < count; i++) {
27944                  list[i] = itemCallback.call(this$1);
27945                }
27946                return list;
27947              };
27948
27949              /**
27950               * Parse a list of records.
27951               * Record count is optional, if omitted it is read from the stream.
27952               * Example of recordDescription: { sequenceIndex: Parser.uShort, lookupListIndex: Parser.uShort }
27953               */
27954              Parser.prototype.parseRecordList = function(count, recordDescription) {
27955                var this$1 = this;
27956
27957                // If the count argument is absent, read it in the stream.
27958                if (!recordDescription) {
27959                  recordDescription = count;
27960                  count = this.parseUShort();
27961                }
27962                var records = new Array(count);
27963                var fields = Object.keys(recordDescription);
27964                for (var i = 0; i < count; i++) {
27965                  var rec = {};
27966                  for (var j = 0; j < fields.length; j++) {
27967                    var fieldName = fields[j];
27968                    var fieldType = recordDescription[fieldName];
27969                    rec[fieldName] = fieldType.call(this$1);
27970                  }
27971                  records[i] = rec;
27972                }
27973                return records;
27974              };
27975
27976              Parser.prototype.parseRecordList32 = function(count, recordDescription) {
27977                var this$1 = this;
27978
27979                // If the count argument is absent, read it in the stream.
27980                if (!recordDescription) {
27981                  recordDescription = count;
27982                  count = this.parseULong();
27983                }
27984                var records = new Array(count);
27985                var fields = Object.keys(recordDescription);
27986                for (var i = 0; i < count; i++) {
27987                  var rec = {};
27988                  for (var j = 0; j < fields.length; j++) {
27989                    var fieldName = fields[j];
27990                    var fieldType = recordDescription[fieldName];
27991                    rec[fieldName] = fieldType.call(this$1);
27992                  }
27993                  records[i] = rec;
27994                }
27995                return records;
27996              };
27997
27998              // Parse a data structure into an object
27999              // Example of description: { sequenceIndex: Parser.uShort, lookupListIndex: Parser.uShort }
28000              Parser.prototype.parseStruct = function(description) {
28001                var this$1 = this;
28002
28003                if (typeof description === 'function') {
28004                  return description.call(this);
28005                } else {
28006                  var fields = Object.keys(description);
28007                  var struct = {};
28008                  for (var j = 0; j < fields.length; j++) {
28009                    var fieldName = fields[j];
28010                    var fieldType = description[fieldName];
28011                    struct[fieldName] = fieldType.call(this$1);
28012                  }
28013                  return struct;
28014                }
28015              };
28016
28017              /**
28018               * Parse a GPOS valueRecord
28019               * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#value-record
28020               * valueFormat is optional, if omitted it is read from the stream.
28021               */
28022              Parser.prototype.parseValueRecord = function(valueFormat) {
28023                if (valueFormat === undefined) {
28024                  valueFormat = this.parseUShort();
28025                }
28026                if (valueFormat === 0) {
28027                  // valueFormat2 in kerning pairs is most often 0
28028                  // in this case return undefined instead of an empty object, to save space
28029                  return;
28030                }
28031                var valueRecord = {};
28032
28033                if (valueFormat & 0x0001) {
28034                  valueRecord.xPlacement = this.parseShort();
28035                }
28036                if (valueFormat & 0x0002) {
28037                  valueRecord.yPlacement = this.parseShort();
28038                }
28039                if (valueFormat & 0x0004) {
28040                  valueRecord.xAdvance = this.parseShort();
28041                }
28042                if (valueFormat & 0x0008) {
28043                  valueRecord.yAdvance = this.parseShort();
28044                }
28045
28046                // Device table (non-variable font) / VariationIndex table (variable font) not supported
28047                // https://docs.microsoft.com/fr-fr/typography/opentype/spec/chapter2#devVarIdxTbls
28048                if (valueFormat & 0x0010) {
28049                  valueRecord.xPlaDevice = undefined;
28050                  this.parseShort();
28051                }
28052                if (valueFormat & 0x0020) {
28053                  valueRecord.yPlaDevice = undefined;
28054                  this.parseShort();
28055                }
28056                if (valueFormat & 0x0040) {
28057                  valueRecord.xAdvDevice = undefined;
28058                  this.parseShort();
28059                }
28060                if (valueFormat & 0x0080) {
28061                  valueRecord.yAdvDevice = undefined;
28062                  this.parseShort();
28063                }
28064
28065                return valueRecord;
28066              };
28067
28068              /**
28069               * Parse a list of GPOS valueRecords
28070               * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#value-record
28071               * valueFormat and valueCount are read from the stream.
28072               */
28073              Parser.prototype.parseValueRecordList = function() {
28074                var this$1 = this;
28075
28076                var valueFormat = this.parseUShort();
28077                var valueCount = this.parseUShort();
28078                var values = new Array(valueCount);
28079                for (var i = 0; i < valueCount; i++) {
28080                  values[i] = this$1.parseValueRecord(valueFormat);
28081                }
28082                return values;
28083              };
28084
28085              Parser.prototype.parsePointer = function(description) {
28086                var structOffset = this.parseOffset16();
28087                if (structOffset > 0) {
28088                  // NULL offset => return undefined
28089                  return new Parser(this.data, this.offset + structOffset).parseStruct(
28090                    description
28091                  );
28092                }
28093                return undefined;
28094              };
28095
28096              Parser.prototype.parsePointer32 = function(description) {
28097                var structOffset = this.parseOffset32();
28098                if (structOffset > 0) {
28099                  // NULL offset => return undefined
28100                  return new Parser(this.data, this.offset + structOffset).parseStruct(
28101                    description
28102                  );
28103                }
28104                return undefined;
28105              };
28106
28107              /**
28108               * Parse a list of offsets to lists of 16-bit integers,
28109               * or a list of offsets to lists of offsets to any kind of items.
28110               * If itemCallback is not provided, a list of list of UShort is assumed.
28111               * If provided, itemCallback is called on each item and must parse the item.
28112               * See examples in tables/gsub.js
28113               */
28114              Parser.prototype.parseListOfLists = function(itemCallback) {
28115                var this$1 = this;
28116
28117                var offsets = this.parseOffset16List();
28118                var count = offsets.length;
28119                var relativeOffset = this.relativeOffset;
28120                var list = new Array(count);
28121                for (var i = 0; i < count; i++) {
28122                  var start = offsets[i];
28123                  if (start === 0) {
28124                    // NULL offset
28125                    // Add i as owned property to list. Convenient with assert.
28126                    list[i] = undefined;
28127                    continue;
28128                  }
28129                  this$1.relativeOffset = start;
28130                  if (itemCallback) {
28131                    var subOffsets = this$1.parseOffset16List();
28132                    var subList = new Array(subOffsets.length);
28133                    for (var j = 0; j < subOffsets.length; j++) {
28134                      this$1.relativeOffset = start + subOffsets[j];
28135                      subList[j] = itemCallback.call(this$1);
28136                    }
28137                    list[i] = subList;
28138                  } else {
28139                    list[i] = this$1.parseUShortList();
28140                  }
28141                }
28142                this.relativeOffset = relativeOffset;
28143                return list;
28144              };
28145
vendor: 5,706 bytes, lines 28146-28287
28146              ///// Complex tables parsing //////////////////////////////////
28147
28148              // Parse a coverage table in a GSUB, GPOS or GDEF table.
28149              // https://www.microsoft.com/typography/OTSPEC/chapter2.htm
28150              // parser.offset must point to the start of the table containing the coverage.
28151              Parser.prototype.parseCoverage = function() {
28152                var this$1 = this;
28153
28154                var startOffset = this.offset + this.relativeOffset;
28155                var format = this.parseUShort();
28156                var count = this.parseUShort();
28157                if (format === 1) {
28158                  return {
28159                    format: 1,
28160                    glyphs: this.parseUShortList(count)
28161                  };
28162                } else if (format === 2) {
28163                  var ranges = new Array(count);
28164                  for (var i = 0; i < count; i++) {
28165                    ranges[i] = {
28166                      start: this$1.parseUShort(),
28167                      end: this$1.parseUShort(),
28168                      index: this$1.parseUShort()
28169                    };
28170                  }
28171                  return {
28172                    format: 2,
28173                    ranges: ranges
28174                  };
28175                }
28176                throw new Error(
28177                  '0x' + startOffset.toString(16) + ': Coverage format must be 1 or 2.'
28178                );
28179              };
28180
28181              // Parse a Class Definition Table in a GSUB, GPOS or GDEF table.
28182              // https://www.microsoft.com/typography/OTSPEC/chapter2.htm
28183              Parser.prototype.parseClassDef = function() {
28184                var startOffset = this.offset + this.relativeOffset;
28185                var format = this.parseUShort();
28186                if (format === 1) {
28187                  return {
28188                    format: 1,
28189                    startGlyph: this.parseUShort(),
28190                    classes: this.parseUShortList()
28191                  };
28192                } else if (format === 2) {
28193                  return {
28194                    format: 2,
28195                    ranges: this.parseRecordList({
28196                      start: Parser.uShort,
28197                      end: Parser.uShort,
28198                      classId: Parser.uShort
28199                    })
28200                  };
28201                }
28202                throw new Error(
28203                  '0x' + startOffset.toString(16) + ': ClassDef format must be 1 or 2.'
28204                );
28205              };
28206
28207              ///// Static methods ///////////////////////////////////
28208              // These convenience methods can be used as callbacks and should be called with "this" context set to a Parser instance.
28209
28210              Parser.list = function(count, itemCallback) {
28211                return function() {
28212                  return this.parseList(count, itemCallback);
28213                };
28214              };
28215
28216              Parser.list32 = function(count, itemCallback) {
28217                return function() {
28218                  return this.parseList32(count, itemCallback);
28219                };
28220              };
28221
28222              Parser.recordList = function(count, recordDescription) {
28223                return function() {
28224                  return this.parseRecordList(count, recordDescription);
28225                };
28226              };
28227
28228              Parser.recordList32 = function(count, recordDescription) {
28229                return function() {
28230                  return this.parseRecordList32(count, recordDescription);
28231                };
28232              };
28233
28234              Parser.pointer = function(description) {
28235                return function() {
28236                  return this.parsePointer(description);
28237                };
28238              };
28239
28240              Parser.pointer32 = function(description) {
28241                return function() {
28242                  return this.parsePointer32(description);
28243                };
28244              };
28245
28246              Parser.tag = Parser.prototype.parseTag;
28247              Parser.byte = Parser.prototype.parseByte;
28248              Parser.uShort = Parser.offset16 = Parser.prototype.parseUShort;
28249              Parser.uShortList = Parser.prototype.parseUShortList;
28250              Parser.uLong = Parser.offset32 = Parser.prototype.parseULong;
28251              Parser.uLongList = Parser.prototype.parseULongList;
28252              Parser.struct = Parser.prototype.parseStruct;
28253              Parser.coverage = Parser.prototype.parseCoverage;
28254              Parser.classDef = Parser.prototype.parseClassDef;
28255
28256              ///// Script, Feature, Lookup lists ///////////////////////////////////////////////
28257              // https://www.microsoft.com/typography/OTSPEC/chapter2.htm
28258
28259              var langSysTable = {
28260                reserved: Parser.uShort,
28261                reqFeatureIndex: Parser.uShort,
28262                featureIndexes: Parser.uShortList
28263              };
28264
28265              Parser.prototype.parseScriptList = function() {
28266                return (
28267                  this.parsePointer(
28268                    Parser.recordList({
28269                      tag: Parser.tag,
28270                      script: Parser.pointer({
28271                        defaultLangSys: Parser.pointer(langSysTable),
28272                        langSysRecords: Parser.recordList({
28273                          tag: Parser.tag,
28274                          langSys: Parser.pointer(langSysTable)
28275                        })
28276                      })
28277                    })
28278                  ) || []
28279                );
28280              };
28281
28282              Parser.prototype.parseFeatureList = function() {
28283                return (
28284                  this.parsePointer(
28285                    Parser.recordList({
28286                      tag: Parser.tag,
28287                      feature: Parser.pointer({
28288                        featureParams: Parser.offset16,
28289                        lookupListIndexes: Parser.uShortList
28290                      })
28291                    })
28292                  ) || []
28293                );
28294              };
28295
28296              Parser.prototype.parseLookupList = function(lookupTableParsers) {
28297                return (
28298                  this.parsePointer(
28299                    Parser.list(
28300                      Parser.pointer(function() {
28301                        var lookupType = this.parseUShort();
28302                        check.argument(
28303                          1 <= lookupType && lookupType <= 9,
28304                          'GPOS/GSUB lookup type ' + lookupType + ' unknown.'
28305                        );
28306                        var lookupFlag = this.parseUShort();
28307                        var useMarkFilteringSet = lookupFlag & 0x10;
28308                        return {
28309                          lookupType: lookupType,
28310                          lookupFlag: lookupFlag,
28311                          subtables: this.parseList(
28312                            Parser.pointer(lookupTableParsers[lookupType])
28313                          ),
28314                          markFilteringSet: useMarkFilteringSet
28315                            ? this.parseUShort()
28316                            : undefined
28317                        };
28318                      })
28319                    )
28320                  ) || []
28321                );
28322              };
28323
28324              Parser.prototype.parseFeatureVariationsList = function() {
28325                return (
28326                  this.parsePointer32(function() {
28327                    var majorVersion = this.parseUShort();
28328                    var minorVersion = this.parseUShort();
28329                    check.argument(
28330                      majorVersion === 1 && minorVersion < 1,
28331                      'GPOS/GSUB feature variations table unknown.'
28332                    );
28333                    var featureVariations = this.parseRecordList32({
28334                      conditionSetOffset: Parser.offset32,
28335                      featureTableSubstitutionOffset: Parser.offset32
28336                    });
28337                    return featureVariations;
28338                  }) || []
28339                );
28340              };
28341
28342              var parse = {
28343                getByte: getByte,
28344                getCard8: getByte,
28345                getUShort: getUShort,
28346                getCard16: getUShort,
28347                getShort: getShort,
28348                getULong: getULong,
28349                getFixed: getFixed,
28350                getTag: getTag,
28351                getOffset: getOffset,
28352                getBytes: getBytes,
28353                bytesToString: bytesToString,
28354                Parser: Parser
28355              };
28356
28357              // The `cmap` table stores the mappings from characters to glyphs.
28358
28359              function parseCmapTableFormat12(cmap, p) {
28360                //Skip reserved.
28361                p.parseUShort();
28362
28363                // Length in bytes of the sub-tables.
28364                cmap.length = p.parseULong();
28365                cmap.language = p.parseULong();
28366
28367                var groupCount;
28368                cmap.groupCount = groupCount = p.parseULong();
28369                cmap.glyphIndexMap = {};
28370
28371                for (var i = 0; i < groupCount; i += 1) {
28372                  var startCharCode = p.parseULong();
28373                  var endCharCode = p.parseULong();
28374                  var startGlyphId = p.parseULong();
28375
28376                  for (var c = startCharCode; c <= endCharCode; c += 1) {
28377                    cmap.glyphIndexMap[c] = startGlyphId;
28378                    startGlyphId++;
28379                  }
28380                }
28381              }
28382
28383              function parseCmapTableFormat4(cmap, p, data, start, offset) {
28384                // Length in bytes of the sub-tables.
28385                cmap.length = p.parseUShort();
28386                cmap.language = p.parseUShort();
28387
28388                // segCount is stored x 2.
28389                var segCount;
28390                cmap.segCount = segCount = p.parseUShort() >> 1;
28391
28392                // Skip searchRange, entrySelector, rangeShift.
28393                p.skip('uShort', 3);
28394
28395                // The "unrolled" mapping from character codes to glyph indices.
28396                cmap.glyphIndexMap = {};
28397                var endCountParser = new parse.Parser(data, start + offset + 14);
28398                var startCountParser = new parse.Parser(
28399                  data,
28400                  start + offset + 16 + segCount * 2
28401                );
28402                var idDeltaParser = new parse.Parser(
28403                  data,
28404                  start + offset + 16 + segCount * 4
28405                );
28406                var idRangeOffsetParser = new parse.Parser(
28407                  data,
28408                  start + offset + 16 + segCount * 6
28409                );
28410                var glyphIndexOffset = start + offset + 16 + segCount * 8;
28411                for (var i = 0; i < segCount - 1; i += 1) {
28412                  var glyphIndex = void 0;
28413                  var endCount = endCountParser.parseUShort();
28414                  var startCount = startCountParser.parseUShort();
28415                  var idDelta = idDeltaParser.parseShort();
28416                  var idRangeOffset = idRangeOffsetParser.parseUShort();
28417                  for (var c = startCount; c <= endCount; c += 1) {
28418                    if (idRangeOffset !== 0) {
28419                      // The idRangeOffset is relative to the current position in the idRangeOffset array.
28420                      // Take the current offset in the idRangeOffset array.
28421                      glyphIndexOffset =
28422                        idRangeOffsetParser.offset + idRangeOffsetParser.relativeOffset - 2;
28423
28424                      // Add the value of the idRangeOffset, which will move us into the glyphIndex array.
28425                      glyphIndexOffset += idRangeOffset;
28426
28427                      // Then add the character index of the current segment, multiplied by 2 for USHORTs.
28428                      glyphIndexOffset += (c - startCount) * 2;
28429                      glyphIndex = parse.getUShort(data, glyphIndexOffset);
28430                      if (glyphIndex !== 0) {
28431                        glyphIndex = (glyphIndex + idDelta) & 0xffff;
28432                      }
28433                    } else {
28434                      glyphIndex = (c + idDelta) & 0xffff;
28435                    }
28436
28437                    cmap.glyphIndexMap[c] = glyphIndex;
28438                  }
28439                }
28440              }
28441
28442              // Parse the `cmap` table. This table stores the mappings from characters to glyphs.
28443              // There are many available formats, but we only support the Windows format 4 and 12.
28444              // This function returns a `CmapEncoding` object or null if no supported format could be found.
28445              function parseCmapTable(data, start) {
28446                var cmap = {};
28447                cmap.version = parse.getUShort(data, start);
28448                check.argument(cmap.version === 0, 'cmap table version should be 0.');
28449
28450                // The cmap table can contain many sub-tables, each with their own format.
28451                // We're only interested in a "platform 0" (Unicode format) and "platform 3" (Windows format) table.
28452                cmap.numTables = parse.getUShort(data, start + 2);
28453                var offset = -1;
28454                for (var i = cmap.numTables - 1; i >= 0; i -= 1) {
28455                  var platformId = parse.getUShort(data, start + 4 + i * 8);
28456                  var encodingId = parse.getUShort(data, start + 4 + i * 8 + 2);
28457                  if (
28458                    (platformId === 3 &&
28459                      (encodingId === 0 || encodingId === 1 || encodingId === 10)) ||
28460                    (platformId === 0 &&
28461                      (encodingId === 0 ||
28462                        encodingId === 1 ||
28463                        encodingId === 2 ||
28464                        encodingId === 3 ||
28465                        encodingId === 4))
28466                  ) {
28467                    offset = parse.getULong(data, start + 4 + i * 8 + 4);
28468                    break;
28469                  }
28470                }
28471
28472                if (offset === -1) {
28473                  // There is no cmap table in the font that we support.
28474                  throw new Error('No valid cmap sub-tables found.');
28475                }
28476
28477                var p = new parse.Parser(data, start + offset);
28478                cmap.format = p.parseUShort();
28479
28480                if (cmap.format === 12) {
28481                  parseCmapTableFormat12(cmap, p);
28482                } else if (cmap.format === 4) {
28483                  parseCmapTableFormat4(cmap, p, data, start, offset);
28484                } else {
28485                  throw new Error(
28486                    'Only format 4 and 12 cmap tables are supported (found format ' +
28487                      cmap.format +
28488                      ').'
28489                  );
28490                }
28491
28492                return cmap;
28493              }
28494
28495              function addSegment(t, code, glyphIndex) {
28496                t.segments.push({
28497                  end: code,
28498                  start: code,
28499                  delta: -(code - glyphIndex),
28500                  offset: 0,
28501                  glyphIndex: glyphIndex
28502                });
28503              }
28504
28505              function addTerminatorSegment(t) {
28506                t.segments.push({
28507                  end: 0xffff,
28508                  start: 0xffff,
28509                  delta: 1,
28510                  offset: 0
28511                });
28512              }
28513
28514              // Make cmap table, format 4 by default, 12 if needed only
28515              function makeCmapTable(glyphs) {
28516                // Plan 0 is the base Unicode Plan but emojis, for example are on another plan, and needs cmap 12 format (with 32bit)
28517                var isPlan0Only = true;
28518                var i;
28519
28520                // Check if we need to add cmap format 12 or if format 4 only is fine
28521                for (i = glyphs.length - 1; i > 0; i -= 1) {
28522                  var g = glyphs.get(i);
28523                  if (g.unicode > 65535) {
28524                    console.log('Adding CMAP format 12 (needed!)');
28525                    isPlan0Only = false;
28526                    break;
28527                  }
28528                }
28529
28530                var cmapTable = [
28531                  { name: 'version', type: 'USHORT', value: 0 },
28532                  { name: 'numTables', type: 'USHORT', value: isPlan0Only ? 1 : 2 },
28533
28534                  // CMAP 4 header
28535                  { name: 'platformID', type: 'USHORT', value: 3 },
28536                  { name: 'encodingID', type: 'USHORT', value: 1 },
28537                  { name: 'offset', type: 'ULONG', value: isPlan0Only ? 12 : 12 + 8 }
28538                ];
28539
28540                if (!isPlan0Only) {
28541                  cmapTable = cmapTable.concat([
28542                    // CMAP 12 header
28543                    { name: 'cmap12PlatformID', type: 'USHORT', value: 3 }, // We encode only for PlatformID = 3 (Windows) because it is supported everywhere
28544                    { name: 'cmap12EncodingID', type: 'USHORT', value: 10 },
28545                    { name: 'cmap12Offset', type: 'ULONG', value: 0 }
28546                  ]);
28547                }
28548
28549                cmapTable = cmapTable.concat([
28550                  // CMAP 4 Subtable
28551                  { name: 'format', type: 'USHORT', value: 4 },
28552                  { name: 'cmap4Length', type: 'USHORT', value: 0 },
28553                  { name: 'language', type: 'USHORT', value: 0 },
28554                  { name: 'segCountX2', type: 'USHORT', value: 0 },
28555                  { name: 'searchRange', type: 'USHORT', value: 0 },
28556                  { name: 'entrySelector', type: 'USHORT', value: 0 },
28557                  { name: 'rangeShift', type: 'USHORT', value: 0 }
28558                ]);
28559
28560                var t = new table.Table('cmap', cmapTable);
28561
28562                t.segments = [];
28563                for (i = 0; i < glyphs.length; i += 1) {
28564                  var glyph = glyphs.get(i);
28565                  for (var j = 0; j < glyph.unicodes.length; j += 1) {
28566                    addSegment(t, glyph.unicodes[j], i);
28567                  }
28568
28569                  t.segments = t.segments.sort(function(a, b) {
28570                    return a.start - b.start;
28571                  });
28572                }
28573
28574                addTerminatorSegment(t);
28575
28576                var segCount = t.segments.length;
28577                var segCountToRemove = 0;
28578
28579                // CMAP 4
28580                // Set up parallel segment arrays.
28581                var endCounts = [];
28582                var startCounts = [];
28583                var idDeltas = [];
28584                var idRangeOffsets = [];
28585                var glyphIds = [];
28586
28587                // CMAP 12
28588                var cmap12Groups = [];
28589
28590                // Reminder this loop is not following the specification at 100%
28591                // The specification -> find suites of characters and make a group
28592                // Here we're doing one group for each letter
28593                // Doing as the spec can save 8 times (or more) space
28594                for (i = 0; i < segCount; i += 1) {
28595                  var segment = t.segments[i];
28596
28597                  // CMAP 4
28598                  if (segment.end <= 65535 && segment.start <= 65535) {
28599                    endCounts = endCounts.concat({
28600                      name: 'end_' + i,
28601                      type: 'USHORT',
28602                      value: segment.end
28603                    });
28604                    startCounts = startCounts.concat({
28605                      name: 'start_' + i,
28606                      type: 'USHORT',
28607                      value: segment.start
28608                    });
28609                    idDeltas = idDeltas.concat({
28610                      name: 'idDelta_' + i,
28611                      type: 'SHORT',
28612                      value: segment.delta
28613                    });
28614                    idRangeOffsets = idRangeOffsets.concat({
28615                      name: 'idRangeOffset_' + i,
28616                      type: 'USHORT',
28617                      value: segment.offset
28618                    });
28619                    if (segment.glyphId !== undefined) {
28620                      glyphIds = glyphIds.concat({
28621                        name: 'glyph_' + i,
28622                        type: 'USHORT',
28623                        value: segment.glyphId
28624                      });
28625                    }
28626                  } else {
28627                    // Skip Unicode > 65535 (16bit unsigned max) for CMAP 4, will be added in CMAP 12
28628                    segCountToRemove += 1;
28629                  }
28630
28631                  // CMAP 12
28632                  // Skip Terminator Segment
28633                  if (!isPlan0Only && segment.glyphIndex !== undefined) {
28634                    cmap12Groups = cmap12Groups.concat({
28635                      name: 'cmap12Start_' + i,
28636                      type: 'ULONG',
28637                      value: segment.start
28638                    });
28639                    cmap12Groups = cmap12Groups.concat({
28640                      name: 'cmap12End_' + i,
28641                      type: 'ULONG',
28642                      value: segment.end
28643                    });
28644                    cmap12Groups = cmap12Groups.concat({
28645                      name: 'cmap12Glyph_' + i,
28646                      type: 'ULONG',
28647                      value: segment.glyphIndex
28648                    });
28649                  }
28650                }
28651
28652                // CMAP 4 Subtable
28653                t.segCountX2 = (segCount - segCountToRemove) * 2;
28654                t.searchRange =
28655                  Math.pow(
28656                    2,
28657                    Math.floor(Math.log(segCount - segCountToRemove) / Math.log(2))
28658                  ) * 2;
28659                t.entrySelector = Math.log(t.searchRange / 2) / Math.log(2);
28660                t.rangeShift = t.segCountX2 - t.searchRange;
28661
28662                t.fields = t.fields.concat(endCounts);
28663                t.fields.push({ name: 'reservedPad', type: 'USHORT', value: 0 });
28664                t.fields = t.fields.concat(startCounts);
28665                t.fields = t.fields.concat(idDeltas);
28666                t.fields = t.fields.concat(idRangeOffsets);
28667                t.fields = t.fields.concat(glyphIds);
28668
28669                t.cmap4Length =
28670                  14 + // Subtable header
28671                  endCounts.length * 2 +
28672                  2 + // reservedPad
28673                  startCounts.length * 2 +
28674                  idDeltas.length * 2 +
28675                  idRangeOffsets.length * 2 +
28676                  glyphIds.length * 2;
28677
28678                if (!isPlan0Only) {
28679                  // CMAP 12 Subtable
28680                  var cmap12Length =
28681                    16 + // Subtable header
28682                    cmap12Groups.length * 4;
28683
28684                  t.cmap12Offset = 12 + 2 * 2 + 4 + t.cmap4Length;
28685                  t.fields = t.fields.concat([
28686                    { name: 'cmap12Format', type: 'USHORT', value: 12 },
28687                    { name: 'cmap12Reserved', type: 'USHORT', value: 0 },
28688                    { name: 'cmap12Length', type: 'ULONG', value: cmap12Length },
28689                    { name: 'cmap12Language', type: 'ULONG', value: 0 },
28690                    { name: 'cmap12nGroups', type: 'ULONG', value: cmap12Groups.length / 3 }
28691                  ]);
28692
28693                  t.fields = t.fields.concat(cmap12Groups);
28694                }
28695
28696                return t;
28697              }
28698
28699              var cmap = { parse: parseCmapTable, make: makeCmapTable };
28700
28701              // Glyph encoding
28702
28703              var cffStandardStrings = [
28704                '.notdef',
28705                'space',
28706                'exclam',
28707                'quotedbl',
28708                'numbersign',
28709                'dollar',
28710                'percent',
28711                'ampersand',
28712                'quoteright',
28713                'parenleft',
28714                'parenright',
28715                'asterisk',
28716                'plus',
28717                'comma',
28718                'hyphen',
28719                'period',
28720                'slash',
28721                'zero',
28722                'one',
28723                'two',
28724                'three',
28725                'four',
28726                'five',
28727                'six',
28728                'seven',
28729                'eight',
28730                'nine',
28731                'colon',
28732                'semicolon',
28733                'less',
28734                'equal',
28735                'greater',
28736                'question',
28737                'at',
28738                'A',
28739                'B',
28740                'C',
28741                'D',
28742                'E',
28743                'F',
28744                'G',
28745                'H',
28746                'I',
28747                'J',
28748                'K',
28749                'L',
28750                'M',
28751                'N',
28752                'O',
28753                'P',
28754                'Q',
28755                'R',
28756                'S',
28757                'T',
28758                'U',
28759                'V',
28760                'W',
28761                'X',
28762                'Y',
28763                'Z',
28764                'bracketleft',
28765                'backslash',
28766                'bracketright',
28767                'asciicircum',
28768                'underscore',
28769                'quoteleft',
28770                'a',
28771                'b',
28772                'c',
28773                'd',
28774                'e',
28775                'f',
28776                'g',
28777                'h',
28778                'i',
28779                'j',
28780                'k',
28781                'l',
28782                'm',
28783                'n',
28784                'o',
28785                'p',
28786                'q',
28787                'r',
28788                's',
28789                't',
28790                'u',
28791                'v',
28792                'w',
28793                'x',
28794                'y',
28795                'z',
28796                'braceleft',
28797                'bar',
28798                'braceright',
28799                'asciitilde',
28800                'exclamdown',
28801                'cent',
28802                'sterling',
28803                'fraction',
28804                'yen',
28805                'florin',
28806                'section',
28807                'currency',
28808                'quotesingle',
28809                'quotedblleft',
28810                'guillemotleft',
28811                'guilsinglleft',
28812                'guilsinglright',
28813                'fi',
28814                'fl',
28815                'endash',
28816                'dagger',
28817                'daggerdbl',
28818                'periodcentered',
28819                'paragraph',
28820                'bullet',
28821                'quotesinglbase',
28822                'quotedblbase',
28823                'quotedblright',
28824                'guillemotright',
28825                'ellipsis',
28826                'perthousand',
28827                'questiondown',
28828                'grave',
28829                'acute',
28830                'circumflex',
28831                'tilde',
28832                'macron',
28833                'breve',
28834                'dotaccent',
28835                'dieresis',
28836                'ring',
28837                'cedilla',
28838                'hungarumlaut',
28839                'ogonek',
28840                'caron',
28841                'emdash',
28842                'AE',
28843                'ordfeminine',
28844                'Lslash',
28845                'Oslash',
28846                'OE',
28847                'ordmasculine',
28848                'ae',
28849                'dotlessi',
28850                'lslash',
28851                'oslash',
28852                'oe',
28853                'germandbls',
28854                'onesuperior',
28855                'logicalnot',
28856                'mu',
28857                'trademark',
28858                'Eth',
28859                'onehalf',
28860                'plusminus',
28861                'Thorn',
28862                'onequarter',
28863                'divide',
28864                'brokenbar',
28865                'degree',
28866                'thorn',
28867                'threequarters',
28868                'twosuperior',
28869                'registered',
28870                'minus',
28871                'eth',
28872                'multiply',
28873                'threesuperior',
28874                'copyright',
28875                'Aacute',
28876                'Acircumflex',
28877                'Adieresis',
28878                'Agrave',
28879                'Aring',
28880                'Atilde',
28881                'Ccedilla',
28882                'Eacute',
28883                'Ecircumflex',
28884                'Edieresis',
28885                'Egrave',
28886                'Iacute',
28887                'Icircumflex',
28888                'Idieresis',
28889                'Igrave',
28890                'Ntilde',
28891                'Oacute',
28892                'Ocircumflex',
28893                'Odieresis',
28894                'Ograve',
28895                'Otilde',
28896                'Scaron',
28897                'Uacute',
28898                'Ucircumflex',
28899                'Udieresis',
28900                'Ugrave',
28901                'Yacute',
28902                'Ydieresis',
28903                'Zcaron',
28904                'aacute',
28905                'acircumflex',
28906                'adieresis',
28907                'agrave',
28908                'aring',
28909                'atilde',
28910                'ccedilla',
28911                'eacute',
28912                'ecircumflex',
28913                'edieresis',
28914                'egrave',
28915                'iacute',
28916                'icircumflex',
28917                'idieresis',
28918                'igrave',
28919                'ntilde',
28920                'oacute',
28921                'ocircumflex',
28922                'odieresis',
28923                'ograve',
28924                'otilde',
28925                'scaron',
28926                'uacute',
28927                'ucircumflex',
28928                'udieresis',
28929                'ugrave',
28930                'yacute',
28931                'ydieresis',
28932                'zcaron',
28933                'exclamsmall',
28934                'Hungarumlautsmall',
28935                'dollaroldstyle',
28936                'dollarsuperior',
28937                'ampersandsmall',
28938                'Acutesmall',
28939                'parenleftsuperior',
28940                'parenrightsuperior',
28941                '266 ff',
28942                'onedotenleader',
28943                'zerooldstyle',
28944                'oneoldstyle',
28945                'twooldstyle',
28946                'threeoldstyle',
28947                'fouroldstyle',
28948                'fiveoldstyle',
28949                'sixoldstyle',
28950                'sevenoldstyle',
28951                'eightoldstyle',
28952                'nineoldstyle',
28953                'commasuperior',
28954                'threequartersemdash',
28955                'periodsuperior',
28956                'questionsmall',
28957                'asuperior',
28958                'bsuperior',
28959                'centsuperior',
28960                'dsuperior',
28961                'esuperior',
28962                'isuperior',
28963                'lsuperior',
28964                'msuperior',
28965                'nsuperior',
28966                'osuperior',
28967                'rsuperior',
28968                'ssuperior',
28969                'tsuperior',
28970                'ff',
28971                'ffi',
28972                'ffl',
28973                'parenleftinferior',
28974                'parenrightinferior',
28975                'Circumflexsmall',
28976                'hyphensuperior',
28977                'Gravesmall',
28978                'Asmall',
28979                'Bsmall',
28980                'Csmall',
28981                'Dsmall',
28982                'Esmall',
28983                'Fsmall',
28984                'Gsmall',
28985                'Hsmall',
28986                'Ismall',
28987                'Jsmall',
28988                'Ksmall',
28989                'Lsmall',
28990                'Msmall',
28991                'Nsmall',
28992                'Osmall',
28993                'Psmall',
28994                'Qsmall',
28995                'Rsmall',
28996                'Ssmall',
28997                'Tsmall',
28998                'Usmall',
28999                'Vsmall',
29000                'Wsmall',
29001                'Xsmall',
29002                'Ysmall',
29003                'Zsmall',
29004                'colonmonetary',
29005                'onefitted',
29006                'rupiah',
29007                'Tildesmall',
29008                'exclamdownsmall',
29009                'centoldstyle',
29010                'Lslashsmall',
29011                'Scaronsmall',
29012                'Zcaronsmall',
29013                'Dieresissmall',
29014                'Brevesmall',
29015                'Caronsmall',
29016                'Dotaccentsmall',
29017                'Macronsmall',
29018                'figuredash',
29019                'hypheninferior',
29020                'Ogoneksmall',
29021                'Ringsmall',
29022                'Cedillasmall',
29023                'questiondownsmall',
29024                'oneeighth',
29025                'threeeighths',
29026                'fiveeighths',
29027                'seveneighths',
29028                'onethird',
29029                'twothirds',
29030                'zerosuperior',
29031                'foursuperior',
29032                'fivesuperior',
29033                'sixsuperior',
29034                'sevensuperior',
29035                'eightsuperior',
29036                'ninesuperior',
29037                'zeroinferior',
29038                'oneinferior',
29039                'twoinferior',
29040                'threeinferior',
29041                'fourinferior',
29042                'fiveinferior',
29043                'sixinferior',
29044                'seveninferior',
29045                'eightinferior',
29046                'nineinferior',
29047                'centinferior',
29048                'dollarinferior',
29049                'periodinferior',
29050                'commainferior',
29051                'Agravesmall',
29052                'Aacutesmall',
29053                'Acircumflexsmall',
29054                'Atildesmall',
29055                'Adieresissmall',
29056                'Aringsmall',
29057                'AEsmall',
29058                'Ccedillasmall',
29059                'Egravesmall',
29060                'Eacutesmall',
29061                'Ecircumflexsmall',
29062                'Edieresissmall',
29063                'Igravesmall',
29064                'Iacutesmall',
29065                'Icircumflexsmall',
29066                'Idieresissmall',
29067                'Ethsmall',
29068                'Ntildesmall',
29069                'Ogravesmall',
29070                'Oacutesmall',
29071                'Ocircumflexsmall',
29072                'Otildesmall',
29073                'Odieresissmall',
29074                'OEsmall',
29075                'Oslashsmall',
29076                'Ugravesmall',
29077                'Uacutesmall',
29078                'Ucircumflexsmall',
29079                'Udieresissmall',
29080                'Yacutesmall',
29081                'Thornsmall',
29082                'Ydieresissmall',
29083                '001.000',
29084                '001.001',
29085                '001.002',
29086                '001.003',
29087                'Black',
29088                'Bold',
29089                'Book',
29090                'Light',
29091                'Medium',
29092                'Regular',
29093                'Roman',
29094                'Semibold'
29095              ];
29096
29097              var cffStandardEncoding = [
29098                '',
29099                '',
29100                '',
29101                '',
29102                '',
29103                '',
29104                '',
29105                '',
29106                '',
29107                '',
29108                '',
29109                '',
29110                '',
29111                '',
29112                '',
29113                '',
29114                '',
29115                '',
29116                '',
29117                '',
29118                '',
29119                '',
29120                '',
29121                '',
29122                '',
29123                '',
29124                '',
29125                '',
29126                '',
29127                '',
29128                '',
29129                '',
29130                'space',
29131                'exclam',
29132                'quotedbl',
29133                'numbersign',
29134                'dollar',
29135                'percent',
29136                'ampersand',
29137                'quoteright',
29138                'parenleft',
29139                'parenright',
29140                'asterisk',
29141                'plus',
29142                'comma',
29143                'hyphen',
29144                'period',
29145                'slash',
29146                'zero',
29147                'one',
29148                'two',
29149                'three',
29150                'four',
29151                'five',
29152                'six',
29153                'seven',
29154                'eight',
29155                'nine',
29156                'colon',
29157                'semicolon',
29158                'less',
29159                'equal',
29160                'greater',
29161                'question',
29162                'at',
29163                'A',
29164                'B',
29165                'C',
29166                'D',
29167                'E',
29168                'F',
29169                'G',
29170                'H',
29171                'I',
29172                'J',
29173                'K',
29174                'L',
29175                'M',
29176                'N',
29177                'O',
29178                'P',
29179                'Q',
29180                'R',
29181                'S',
29182                'T',
29183                'U',
29184                'V',
29185                'W',
29186                'X',
29187                'Y',
29188                'Z',
29189                'bracketleft',
29190                'backslash',
29191                'bracketright',
29192                'asciicircum',
29193                'underscore',
29194                'quoteleft',
29195                'a',
29196                'b',
29197                'c',
29198                'd',
29199                'e',
29200                'f',
29201                'g',
29202                'h',
29203                'i',
29204                'j',
29205                'k',
29206                'l',
29207                'm',
29208                'n',
29209                'o',
29210                'p',
29211                'q',
29212                'r',
29213                's',
29214                't',
29215                'u',
29216                'v',
29217                'w',
29218                'x',
29219                'y',
29220                'z',
29221                'braceleft',
29222                'bar',
29223                'braceright',
29224                'asciitilde',
29225                '',
29226                '',
29227                '',
29228                '',
29229                '',
29230                '',
29231                '',
29232                '',
29233                '',
29234                '',
29235                '',
29236                '',
29237                '',
29238                '',
29239                '',
29240                '',
29241                '',
29242                '',
29243                '',
29244                '',
29245                '',
29246                '',
29247                '',
29248                '',
29249                '',
29250                '',
29251                '',
29252                '',
29253                '',
29254                '',
29255                '',
29256                '',
29257                '',
29258                '',
29259                'exclamdown',
29260                'cent',
29261                'sterling',
29262                'fraction',
29263                'yen',
29264                'florin',
29265                'section',
29266                'currency',
29267                'quotesingle',
29268                'quotedblleft',
29269                'guillemotleft',
29270                'guilsinglleft',
29271                'guilsinglright',
29272                'fi',
29273                'fl',
29274                '',
29275                'endash',
29276                'dagger',
29277                'daggerdbl',
29278                'periodcentered',
29279                '',
29280                'paragraph',
29281                'bullet',
29282                'quotesinglbase',
29283                'quotedblbase',
29284                'quotedblright',
29285                'guillemotright',
29286                'ellipsis',
29287                'perthousand',
29288                '',
29289                'questiondown',
29290                '',
29291                'grave',
29292                'acute',
29293                'circumflex',
29294                'tilde',
29295                'macron',
29296                'breve',
29297                'dotaccent',
29298                'dieresis',
29299                '',
29300                'ring',
29301                'cedilla',
29302                '',
29303                'hungarumlaut',
29304                'ogonek',
29305                'caron',
29306                'emdash',
29307                '',
29308                '',
29309                '',
29310                '',
29311                '',
29312                '',
29313                '',
29314                '',
29315                '',
29316                '',
29317                '',
29318                '',
29319                '',
29320                '',
29321                '',
29322                '',
29323                'AE',
29324                '',
29325                'ordfeminine',
29326                '',
29327                '',
29328                '',
29329                '',
29330                'Lslash',
29331                'Oslash',
29332                'OE',
29333                'ordmasculine',
29334                '',
29335                '',
29336                '',
29337                '',
29338                '',
29339                'ae',
29340                '',
29341                '',
29342                '',
29343                'dotlessi',
29344                '',
29345                '',
29346                'lslash',
29347                'oslash',
29348                'oe',
29349                'germandbls'
29350              ];
29351
29352              var cffExpertEncoding = [
29353                '',
29354                '',
29355                '',
29356                '',
29357                '',
29358                '',
29359                '',
29360                '',
29361                '',
29362                '',
29363                '',
29364                '',
29365                '',
29366                '',
29367                '',
29368                '',
29369                '',
29370                '',
29371                '',
29372                '',
29373                '',
29374                '',
29375                '',
29376                '',
29377                '',
29378                '',
29379                '',
29380                '',
29381                '',
29382                '',
29383                '',
29384                '',
29385                'space',
29386                'exclamsmall',
29387                'Hungarumlautsmall',
29388                '',
29389                'dollaroldstyle',
29390                'dollarsuperior',
29391                'ampersandsmall',
29392                'Acutesmall',
29393                'parenleftsuperior',
29394                'parenrightsuperior',
29395                'twodotenleader',
29396                'onedotenleader',
29397                'comma',
29398                'hyphen',
29399                'period',
29400                'fraction',
29401                'zerooldstyle',
29402                'oneoldstyle',
29403                'twooldstyle',
29404                'threeoldstyle',
29405                'fouroldstyle',
29406                'fiveoldstyle',
29407                'sixoldstyle',
29408                'sevenoldstyle',
29409                'eightoldstyle',
29410                'nineoldstyle',
29411                'colon',
29412                'semicolon',
29413                'commasuperior',
29414                'threequartersemdash',
29415                'periodsuperior',
29416                'questionsmall',
29417                '',
29418                'asuperior',
29419                'bsuperior',
29420                'centsuperior',
29421                'dsuperior',
29422                'esuperior',
29423                '',
29424                '',
29425                'isuperior',
29426                '',
29427                '',
29428                'lsuperior',
29429                'msuperior',
29430                'nsuperior',
29431                'osuperior',
29432                '',
29433                '',
29434                'rsuperior',
29435                'ssuperior',
29436                'tsuperior',
29437                '',
29438                'ff',
29439                'fi',
29440                'fl',
29441                'ffi',
29442                'ffl',
29443                'parenleftinferior',
29444                '',
29445                'parenrightinferior',
29446                'Circumflexsmall',
29447                'hyphensuperior',
29448                'Gravesmall',
29449                'Asmall',
29450                'Bsmall',
29451                'Csmall',
29452                'Dsmall',
29453                'Esmall',
29454                'Fsmall',
29455                'Gsmall',
29456                'Hsmall',
29457                'Ismall',
29458                'Jsmall',
29459                'Ksmall',
29460                'Lsmall',
29461                'Msmall',
29462                'Nsmall',
29463                'Osmall',
29464                'Psmall',
29465                'Qsmall',
29466                'Rsmall',
29467                'Ssmall',
29468                'Tsmall',
29469                'Usmall',
29470                'Vsmall',
29471                'Wsmall',
29472                'Xsmall',
29473                'Ysmall',
29474                'Zsmall',
29475                'colonmonetary',
29476                'onefitted',
29477                'rupiah',
29478                'Tildesmall',
29479                '',
29480                '',
29481                '',
29482                '',
29483                '',
29484                '',
29485                '',
29486                '',
29487                '',
29488                '',
29489                '',
29490                '',
29491                '',
29492                '',
29493                '',
29494                '',
29495                '',
29496                '',
29497                '',
29498                '',
29499                '',
29500                '',
29501                '',
29502                '',
29503                '',
29504                '',
29505                '',
29506                '',
29507                '',
29508                '',
29509                '',
29510                '',
29511                '',
29512                '',
29513                'exclamdownsmall',
29514                'centoldstyle',
29515                'Lslashsmall',
29516                '',
29517                '',
29518                'Scaronsmall',
29519                'Zcaronsmall',
29520                'Dieresissmall',
29521                'Brevesmall',
29522                'Caronsmall',
29523                '',
29524                'Dotaccentsmall',
29525                '',
29526                '',
29527                'Macronsmall',
29528                '',
29529                '',
29530                'figuredash',
29531                'hypheninferior',
29532                '',
29533                '',
29534                'Ogoneksmall',
29535                'Ringsmall',
29536                'Cedillasmall',
29537                '',
29538                '',
29539                '',
29540                'onequarter',
29541                'onehalf',
29542                'threequarters',
29543                'questiondownsmall',
29544                'oneeighth',
29545                'threeeighths',
29546                'fiveeighths',
29547                'seveneighths',
29548                'onethird',
29549                'twothirds',
29550                '',
29551                '',
29552                'zerosuperior',
29553                'onesuperior',
29554                'twosuperior',
29555                'threesuperior',
29556                'foursuperior',
29557                'fivesuperior',
29558                'sixsuperior',
29559                'sevensuperior',
29560                'eightsuperior',
29561                'ninesuperior',
29562                'zeroinferior',
29563                'oneinferior',
29564                'twoinferior',
29565                'threeinferior',
29566                'fourinferior',
29567                'fiveinferior',
29568                'sixinferior',
29569                'seveninferior',
29570                'eightinferior',
29571                'nineinferior',
29572                'centinferior',
29573                'dollarinferior',
29574                'periodinferior',
29575                'commainferior',
29576                'Agravesmall',
29577                'Aacutesmall',
29578                'Acircumflexsmall',
29579                'Atildesmall',
29580                'Adieresissmall',
29581                'Aringsmall',
29582                'AEsmall',
29583                'Ccedillasmall',
29584                'Egravesmall',
29585                'Eacutesmall',
29586                'Ecircumflexsmall',
29587                'Edieresissmall',
29588                'Igravesmall',
29589                'Iacutesmall',
29590                'Icircumflexsmall',
29591                'Idieresissmall',
29592                'Ethsmall',
29593                'Ntildesmall',
29594                'Ogravesmall',
29595                'Oacutesmall',
29596                'Ocircumflexsmall',
29597                'Otildesmall',
29598                'Odieresissmall',
29599                'OEsmall',
29600                'Oslashsmall',
29601                'Ugravesmall',
29602                'Uacutesmall',
29603                'Ucircumflexsmall',
29604                'Udieresissmall',
29605                'Yacutesmall',
29606                'Thornsmall',
29607                'Ydieresissmall'
29608              ];
29609
29610              var standardNames = [
29611                '.notdef',
29612                '.null',
29613                'nonmarkingreturn',
29614                'space',
29615                'exclam',
29616                'quotedbl',
29617                'numbersign',
29618                'dollar',
29619                'percent',
29620                'ampersand',
29621                'quotesingle',
29622                'parenleft',
29623                'parenright',
29624                'asterisk',
29625                'plus',
29626                'comma',
29627                'hyphen',
29628                'period',
29629                'slash',
29630                'zero',
29631                'one',
29632                'two',
29633                'three',
29634                'four',
29635                'five',
29636                'six',
29637                'seven',
29638                'eight',
29639                'nine',
29640                'colon',
29641                'semicolon',
29642                'less',
29643                'equal',
29644                'greater',
29645                'question',
29646                'at',
29647                'A',
29648                'B',
29649                'C',
29650                'D',
29651                'E',
29652                'F',
29653                'G',
29654                'H',
29655                'I',
29656                'J',
29657                'K',
29658                'L',
29659                'M',
29660                'N',
29661                'O',
29662                'P',
29663                'Q',
29664                'R',
29665                'S',
29666                'T',
29667                'U',
29668                'V',
29669                'W',
29670                'X',
29671                'Y',
29672                'Z',
29673                'bracketleft',
29674                'backslash',
29675                'bracketright',
29676                'asciicircum',
29677                'underscore',
29678                'grave',
29679                'a',
29680                'b',
29681                'c',
29682                'd',
29683                'e',
29684                'f',
29685                'g',
29686                'h',
29687                'i',
29688                'j',
29689                'k',
29690                'l',
29691                'm',
29692                'n',
29693                'o',
29694                'p',
29695                'q',
29696                'r',
29697                's',
29698                't',
29699                'u',
29700                'v',
29701                'w',
29702                'x',
29703                'y',
29704                'z',
29705                'braceleft',
29706                'bar',
29707                'braceright',
29708                'asciitilde',
29709                'Adieresis',
29710                'Aring',
29711                'Ccedilla',
29712                'Eacute',
29713                'Ntilde',
29714                'Odieresis',
29715                'Udieresis',
29716                'aacute',
29717                'agrave',
29718                'acircumflex',
29719                'adieresis',
29720                'atilde',
29721                'aring',
29722                'ccedilla',
29723                'eacute',
29724                'egrave',
29725                'ecircumflex',
29726                'edieresis',
29727                'iacute',
29728                'igrave',
29729                'icircumflex',
29730                'idieresis',
29731                'ntilde',
29732                'oacute',
29733                'ograve',
29734                'ocircumflex',
29735                'odieresis',
29736                'otilde',
29737                'uacute',
29738                'ugrave',
29739                'ucircumflex',
29740                'udieresis',
29741                'dagger',
29742                'degree',
29743                'cent',
29744                'sterling',
29745                'section',
29746                'bullet',
29747                'paragraph',
29748                'germandbls',
29749                'registered',
29750                'copyright',
29751                'trademark',
29752                'acute',
29753                'dieresis',
29754                'notequal',
29755                'AE',
29756                'Oslash',
29757                'infinity',
29758                'plusminus',
29759                'lessequal',
29760                'greaterequal',
29761                'yen',
29762                'mu',
29763                'partialdiff',
29764                'summation',
29765                'product',
29766                'pi',
29767                'integral',
29768                'ordfeminine',
29769                'ordmasculine',
29770                'Omega',
29771                'ae',
29772                'oslash',
29773                'questiondown',
29774                'exclamdown',
29775                'logicalnot',
29776                'radical',
29777                'florin',
29778                'approxequal',
29779                'Delta',
29780                'guillemotleft',
29781                'guillemotright',
29782                'ellipsis',
29783                'nonbreakingspace',
29784                'Agrave',
29785                'Atilde',
29786                'Otilde',
29787                'OE',
29788                'oe',
29789                'endash',
29790                'emdash',
29791                'quotedblleft',
29792                'quotedblright',
29793                'quoteleft',
29794                'quoteright',
29795                'divide',
29796                'lozenge',
29797                'ydieresis',
29798                'Ydieresis',
29799                'fraction',
29800                'currency',
29801                'guilsinglleft',
29802                'guilsinglright',
29803                'fi',
29804                'fl',
29805                'daggerdbl',
29806                'periodcentered',
29807                'quotesinglbase',
29808                'quotedblbase',
29809                'perthousand',
29810                'Acircumflex',
29811                'Ecircumflex',
29812                'Aacute',
29813                'Edieresis',
29814                'Egrave',
29815                'Iacute',
29816                'Icircumflex',
29817                'Idieresis',
29818                'Igrave',
29819                'Oacute',
29820                'Ocircumflex',
29821                'apple',
29822                'Ograve',
29823                'Uacute',
29824                'Ucircumflex',
29825                'Ugrave',
29826                'dotlessi',
29827                'circumflex',
29828                'tilde',
29829                'macron',
29830                'breve',
29831                'dotaccent',
29832                'ring',
29833                'cedilla',
29834                'hungarumlaut',
29835                'ogonek',
29836                'caron',
29837                'Lslash',
29838                'lslash',
29839                'Scaron',
29840                'scaron',
29841                'Zcaron',
29842                'zcaron',
29843                'brokenbar',
29844                'Eth',
29845                'eth',
29846                'Yacute',
29847                'yacute',
29848                'Thorn',
29849                'thorn',
29850                'minus',
29851                'multiply',
29852                'onesuperior',
29853                'twosuperior',
29854                'threesuperior',
29855                'onehalf',
29856                'onequarter',
29857                'threequarters',
29858                'franc',
29859                'Gbreve',
29860                'gbreve',
29861                'Idotaccent',
29862                'Scedilla',
29863                'scedilla',
29864                'Cacute',
29865                'cacute',
29866                'Ccaron',
29867                'ccaron',
29868                'dcroat'
29869              ];
29870
29871              /**
29872               * This is the encoding used for fonts created from scratch.
29873               * It loops through all glyphs and finds the appropriate unicode value.
29874               * Since it's linear time, other encodings will be faster.
29875               * @exports opentype.DefaultEncoding
29876               * @class
29877               * @constructor
29878               * @param {opentype.Font}
29879               */
29880              function DefaultEncoding(font) {
29881                this.font = font;
29882              }
29883
29884              DefaultEncoding.prototype.charToGlyphIndex = function(c) {
29885                var code = c.codePointAt(0);
29886                var glyphs = this.font.glyphs;
29887                if (glyphs) {
29888                  for (var i = 0; i < glyphs.length; i += 1) {
29889                    var glyph = glyphs.get(i);
29890                    for (var j = 0; j < glyph.unicodes.length; j += 1) {
29891                      if (glyph.unicodes[j] === code) {
29892                        return i;
29893                      }
29894                    }
29895                  }
29896                }
29897                return null;
29898              };
29899
29900              /**
29901               * @exports opentype.CmapEncoding
29902               * @class
29903               * @constructor
29904               * @param {Object} cmap - a object with the cmap encoded data
29905               */
29906              function CmapEncoding(cmap) {
29907                this.cmap = cmap;
29908              }
29909
29910              /**
29911               * @param  {string} c - the character
29912               * @return {number} The glyph index.
29913               */
29914              CmapEncoding.prototype.charToGlyphIndex = function(c) {
29915                return this.cmap.glyphIndexMap[c.codePointAt(0)] || 0;
29916              };
29917
29918              /**
29919               * @exports opentype.CffEncoding
29920               * @class
29921               * @constructor
29922               * @param {string} encoding - The encoding
29923               * @param {Array} charset - The character set.
29924               */
29925              function CffEncoding(encoding, charset) {
29926                this.encoding = encoding;
29927                this.charset = charset;
29928              }
29929
29930              /**
29931               * @param  {string} s - The character
29932               * @return {number} The index.
29933               */
29934              CffEncoding.prototype.charToGlyphIndex = function(s) {
29935                var code = s.codePointAt(0);
29936                var charName = this.encoding[code];
29937                return this.charset.indexOf(charName);
29938              };
29939
29940              /**
29941               * @exports opentype.GlyphNames
29942               * @class
29943               * @constructor
29944               * @param {Object} post
29945               */
29946              function GlyphNames(post) {
29947                var this$1 = this;
29948
29949                switch (post.version) {
29950                  case 1:
29951                    this.names = standardNames.slice();
29952                    break;
29953                  case 2:
29954                    this.names = new Array(post.numberOfGlyphs);
29955                    for (var i = 0; i < post.numberOfGlyphs; i++) {
29956                      if (post.glyphNameIndex[i] < standardNames.length) {
29957                        this$1.names[i] = standardNames[post.glyphNameIndex[i]];
29958                      } else {
29959                        this$1.names[i] =
29960                          post.names[post.glyphNameIndex[i] - standardNames.length];
29961                      }
29962                    }
29963
29964                    break;
29965                  case 2.5:
29966                    this.names = new Array(post.numberOfGlyphs);
29967                    for (var i$1 = 0; i$1 < post.numberOfGlyphs; i$1++) {
29968                      this$1.names[i$1] = standardNames[i$1 + post.glyphNameIndex[i$1]];
29969                    }
29970
29971                    break;
29972                  case 3:
29973                    this.names = [];
29974                    break;
29975                  default:
29976                    this.names = [];
29977                    break;
29978                }
29979              }
29980
29981              /**
29982               * Gets the index of a glyph by name.
29983               * @param  {string} name - The glyph name
29984               * @return {number} The index
29985               */
29986              GlyphNames.prototype.nameToGlyphIndex = function(name) {
29987                return this.names.indexOf(name);
29988              };
29989
29990              /**
29991               * @param  {number} gid
29992               * @return {string}
29993               */
29994              GlyphNames.prototype.glyphIndexToName = function(gid) {
29995                return this.names[gid];
29996              };
29997
29998              /**
29999               * @alias opentype.addGlyphNames
30000               * @param {opentype.Font}
30001               */
30002              function addGlyphNames(font) {
30003                var glyph;
30004                var glyphIndexMap = font.tables.cmap.glyphIndexMap;
30005                var charCodes = Object.keys(glyphIndexMap);
30006
30007                for (var i = 0; i < charCodes.length; i += 1) {
30008                  var c = charCodes[i];
30009                  var glyphIndex = glyphIndexMap[c];
30010                  glyph = font.glyphs.get(glyphIndex);
30011                  glyph.addUnicode(parseInt(c));
30012                }
30013
30014                for (var i$1 = 0; i$1 < font.glyphs.length; i$1 += 1) {
30015                  glyph = font.glyphs.get(i$1);
30016                  if (font.cffEncoding) {
30017                    if (font.isCIDFont) {
30018                      glyph.name = 'gid' + i$1;
30019                    } else {
30020                      glyph.name = font.cffEncoding.charset[i$1];
30021                    }
30022                  } else if (font.glyphNames.names) {
30023                    glyph.name = font.glyphNames.glyphIndexToName(i$1);
30024                  }
30025                }
30026              }
30027
30028              // Drawing utility functions.
30029
30030              // Draw a line on the given context from point `x1,y1` to point `x2,y2`.
30031              function line(ctx, x1, y1, x2, y2) {
30032                ctx.beginPath();
30033                ctx.moveTo(x1, y1);
30034                ctx.lineTo(x2, y2);
30035                ctx.stroke();
30036              }
30037
30038              var draw = { line: line };
30039
30040              // The Glyph object
30041              // import glyf from './tables/glyf' Can't be imported here, because it's a circular dependency
30042
30043              function getPathDefinition(glyph, path) {
30044                var _path = path || new Path();
30045                return {
30046                  configurable: true,
30047
30048                  get: function() {
30049                    if (typeof _path === 'function') {
30050                      _path = _path();
30051                    }
30052
30053                    return _path;
30054                  },
30055
30056                  set: function(p) {
30057                    _path = p;
30058                  }
30059                };
30060              }
30061              /**
30062               * @typedef GlyphOptions
30063               * @type Object
30064               * @property {string} [name] - The glyph name
30065               * @property {number} [unicode]
30066               * @property {Array} [unicodes]
30067               * @property {number} [xMin]
30068               * @property {number} [yMin]
30069               * @property {number} [xMax]
30070               * @property {number} [yMax]
30071               * @property {number} [advanceWidth]
30072               */
30073
30074              // A Glyph is an individual mark that often corresponds to a character.
30075              // Some glyphs, such as ligatures, are a combination of many characters.
30076              // Glyphs are the basic building blocks of a font.
30077              //
30078              // The `Glyph` class contains utility methods for drawing the path and its points.
30079              /**
30080               * @exports opentype.Glyph
30081               * @class
30082               * @param {GlyphOptions}
30083               * @constructor
30084               */
30085              function Glyph(options) {
30086                // By putting all the code on a prototype function (which is only declared once)
30087                // we reduce the memory requirements for larger fonts by some 2%
30088                this.bindConstructorValues(options);
30089              }
30090
30091              /**
30092               * @param  {GlyphOptions}
30093               */
30094              Glyph.prototype.bindConstructorValues = function(options) {
30095                this.index = options.index || 0;
30096
30097                // These three values cannot be deferred for memory optimization:
30098                this.name = options.name || null;
30099                this.unicode = options.unicode || undefined;
30100                this.unicodes =
30101                  options.unicodes || options.unicode !== undefined
30102                    ? [options.unicode]
30103                    : [];
30104
30105                // But by binding these values only when necessary, we reduce can
30106                // the memory requirements by almost 3% for larger fonts.
30107                if (options.xMin) {
30108                  this.xMin = options.xMin;
30109                }
30110
30111                if (options.yMin) {
30112                  this.yMin = options.yMin;
30113                }
30114
30115                if (options.xMax) {
30116                  this.xMax = options.xMax;
30117                }
30118
30119                if (options.yMax) {
30120                  this.yMax = options.yMax;
30121                }
30122
30123                if (options.advanceWidth) {
30124                  this.advanceWidth = options.advanceWidth;
30125                }
30126
30127                // The path for a glyph is the most memory intensive, and is bound as a value
30128                // with a getter/setter to ensure we actually do path parsing only once the
30129                // path is actually needed by anything.
30130                Object.defineProperty(this, 'path', getPathDefinition(this, options.path));
30131              };
30132
30133              /**
30134               * @param {number}
30135               */
30136              Glyph.prototype.addUnicode = function(unicode) {
30137                if (this.unicodes.length === 0) {
30138                  this.unicode = unicode;
30139                }
30140
30141                this.unicodes.push(unicode);
30142              };
30143
30144              /**
30145               * Calculate the minimum bounding box for this glyph.
30146               * @return {opentype.BoundingBox}
30147               */
30148              Glyph.prototype.getBoundingBox = function() {
30149                return this.path.getBoundingBox();
30150              };
30151
30152              /**
30153               * Convert the glyph to a Path we can draw on a drawing context.
30154               * @param  {number} [x=0] - Horizontal position of the beginning of the text.
30155               * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
30156               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
30157               * @param  {Object=} options - xScale, yScale to stretch the glyph.
30158               * @param  {opentype.Font} if hinting is to be used, the font
30159               * @return {opentype.Path}
30160               */
30161              Glyph.prototype.getPath = function(x, y, fontSize, options, font) {
30162                x = x !== undefined ? x : 0;
30163                y = y !== undefined ? y : 0;
30164                fontSize = fontSize !== undefined ? fontSize : 72;
30165                var commands;
30166                var hPoints;
30167                if (!options) {
30168                  options = {};
30169                }
30170                var xScale = options.xScale;
30171                var yScale = options.yScale;
30172
30173                if (options.hinting && font && font.hinting) {
30174                  // in case of hinting, the hinting engine takes care
30175                  // of scaling the points (not the path) before hinting.
30176                  hPoints = this.path && font.hinting.exec(this, fontSize);
30177                  // in case the hinting engine failed hPoints is undefined
30178                  // and thus reverts to plain rending
30179                }
30180
30181                if (hPoints) {
30182                  // Call font.hinting.getCommands instead of `glyf.getPath(hPoints).commands` to avoid a circular dependency
30183                  commands = font.hinting.getCommands(hPoints);
30184                  x = Math.round(x);
30185                  y = Math.round(y);
30186                  // TODO in case of hinting xyScaling is not yet supported
30187                  xScale = yScale = 1;
30188                } else {
30189                  commands = this.path.commands;
30190                  var scale = 1 / this.path.unitsPerEm * fontSize;
30191                  if (xScale === undefined) {
30192                    xScale = scale;
30193                  }
30194                  if (yScale === undefined) {
30195                    yScale = scale;
30196                  }
30197                }
30198
30199                var p = new Path();
30200                for (var i = 0; i < commands.length; i += 1) {
30201                  var cmd = commands[i];
30202                  if (cmd.type === 'M') {
30203                    p.moveTo(x + cmd.x * xScale, y + -cmd.y * yScale);
30204                  } else if (cmd.type === 'L') {
30205                    p.lineTo(x + cmd.x * xScale, y + -cmd.y * yScale);
30206                  } else if (cmd.type === 'Q') {
30207                    p.quadraticCurveTo(
30208                      x + cmd.x1 * xScale,
30209                      y + -cmd.y1 * yScale,
30210                      x + cmd.x * xScale,
30211                      y + -cmd.y * yScale
30212                    );
30213                  } else if (cmd.type === 'C') {
30214                    p.curveTo(
30215                      x + cmd.x1 * xScale,
30216                      y + -cmd.y1 * yScale,
30217                      x + cmd.x2 * xScale,
30218                      y + -cmd.y2 * yScale,
30219                      x + cmd.x * xScale,
30220                      y + -cmd.y * yScale
30221                    );
30222                  } else if (cmd.type === 'Z') {
30223                    p.closePath();
30224                  }
30225                }
30226
30227                return p;
30228              };
30229
30230              /**
30231               * Split the glyph into contours.
30232               * This function is here for backwards compatibility, and to
30233               * provide raw access to the TrueType glyph outlines.
30234               * @return {Array}
30235               */
30236              Glyph.prototype.getContours = function() {
30237                var this$1 = this;
30238
30239                if (this.points === undefined) {
30240                  return [];
30241                }
30242
30243                var contours = [];
30244                var currentContour = [];
30245                for (var i = 0; i < this.points.length; i += 1) {
30246                  var pt = this$1.points[i];
30247                  currentContour.push(pt);
30248                  if (pt.lastPointOfContour) {
30249                    contours.push(currentContour);
30250                    currentContour = [];
30251                  }
30252                }
30253
30254                check.argument(
30255                  currentContour.length === 0,
30256                  'There are still points left in the current contour.'
30257                );
30258                return contours;
30259              };
30260
30261              /**
30262               * Calculate the xMin/yMin/xMax/yMax/lsb/rsb for a Glyph.
30263               * @return {Object}
30264               */
30265              Glyph.prototype.getMetrics = function() {
30266                var commands = this.path.commands;
30267                var xCoords = [];
30268                var yCoords = [];
30269                for (var i = 0; i < commands.length; i += 1) {
30270                  var cmd = commands[i];
30271                  if (cmd.type !== 'Z') {
30272                    xCoords.push(cmd.x);
30273                    yCoords.push(cmd.y);
30274                  }
30275
30276                  if (cmd.type === 'Q' || cmd.type === 'C') {
30277                    xCoords.push(cmd.x1);
30278                    yCoords.push(cmd.y1);
30279                  }
30280
30281                  if (cmd.type === 'C') {
30282                    xCoords.push(cmd.x2);
30283                    yCoords.push(cmd.y2);
30284                  }
30285                }
30286
30287                var metrics = {
30288                  xMin: Math.min.apply(null, xCoords),
30289                  yMin: Math.min.apply(null, yCoords),
30290                  xMax: Math.max.apply(null, xCoords),
30291                  yMax: Math.max.apply(null, yCoords),
30292                  leftSideBearing: this.leftSideBearing
30293                };
30294
30295                if (!isFinite(metrics.xMin)) {
30296                  metrics.xMin = 0;
30297                }
30298
30299                if (!isFinite(metrics.xMax)) {
30300                  metrics.xMax = this.advanceWidth;
30301                }
30302
30303                if (!isFinite(metrics.yMin)) {
30304                  metrics.yMin = 0;
30305                }
30306
30307                if (!isFinite(metrics.yMax)) {
30308                  metrics.yMax = 0;
30309                }
30310
30311                metrics.rightSideBearing =
30312                  this.advanceWidth -
30313                  metrics.leftSideBearing -
30314                  (metrics.xMax - metrics.xMin);
30315                return metrics;
30316              };
30317
30318              /**
30319               * Draw the glyph on the given context.
30320               * @param  {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
30321               * @param  {number} [x=0] - Horizontal position of the beginning of the text.
30322               * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
30323               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
30324               * @param  {Object=} options - xScale, yScale to stretch the glyph.
30325               */
30326              Glyph.prototype.draw = function(ctx, x, y, fontSize, options) {
30327                this.getPath(x, y, fontSize, options).draw(ctx);
30328              };
30329
30330              /**
30331               * Draw the points of the glyph.
30332               * On-curve points will be drawn in blue, off-curve points will be drawn in red.
30333               * @param  {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
30334               * @param  {number} [x=0] - Horizontal position of the beginning of the text.
30335               * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
30336               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
30337               */
30338              Glyph.prototype.drawPoints = function(ctx, x, y, fontSize) {
30339                function drawCircles(l, x, y, scale) {
30340                  var PI_SQ = Math.PI * 2;
30341                  ctx.beginPath();
30342                  for (var j = 0; j < l.length; j += 1) {
30343                    ctx.moveTo(x + l[j].x * scale, y + l[j].y * scale);
30344                    ctx.arc(x + l[j].x * scale, y + l[j].y * scale, 2, 0, PI_SQ, false);
30345                  }
30346
30347                  ctx.closePath();
30348                  ctx.fill();
30349                }
30350
30351                x = x !== undefined ? x : 0;
30352                y = y !== undefined ? y : 0;
30353                fontSize = fontSize !== undefined ? fontSize : 24;
30354                var scale = 1 / this.path.unitsPerEm * fontSize;
30355
30356                var blueCircles = [];
30357                var redCircles = [];
30358                var path = this.path;
30359                for (var i = 0; i < path.commands.length; i += 1) {
30360                  var cmd = path.commands[i];
30361                  if (cmd.x !== undefined) {
30362                    blueCircles.push({ x: cmd.x, y: -cmd.y });
30363                  }
30364
30365                  if (cmd.x1 !== undefined) {
30366                    redCircles.push({ x: cmd.x1, y: -cmd.y1 });
30367                  }
30368
30369                  if (cmd.x2 !== undefined) {
30370                    redCircles.push({ x: cmd.x2, y: -cmd.y2 });
30371                  }
30372                }
30373
30374                ctx.fillStyle = 'blue';
30375                drawCircles(blueCircles, x, y, scale);
30376                ctx.fillStyle = 'red';
30377                drawCircles(redCircles, x, y, scale);
30378              };
30379
30380              /**
30381               * Draw lines indicating important font measurements.
30382               * Black lines indicate the origin of the coordinate system (point 0,0).
30383               * Blue lines indicate the glyph bounding box.
30384               * Green line indicates the advance width of the glyph.
30385               * @param  {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
30386               * @param  {number} [x=0] - Horizontal position of the beginning of the text.
30387               * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
30388               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
30389               */
30390              Glyph.prototype.drawMetrics = function(ctx, x, y, fontSize) {
30391                var scale;
30392                x = x !== undefined ? x : 0;
30393                y = y !== undefined ? y : 0;
30394                fontSize = fontSize !== undefined ? fontSize : 24;
30395                scale = 1 / this.path.unitsPerEm * fontSize;
30396                ctx.lineWidth = 1;
30397
30398                // Draw the origin
30399                ctx.strokeStyle = 'black';
30400                draw.line(ctx, x, -10000, x, 10000);
30401                draw.line(ctx, -10000, y, 10000, y);
30402
30403                // This code is here due to memory optimization: by not using
30404                // defaults in the constructor, we save a notable amount of memory.
30405                var xMin = this.xMin || 0;
30406                var yMin = this.yMin || 0;
30407                var xMax = this.xMax || 0;
30408                var yMax = this.yMax || 0;
30409                var advanceWidth = this.advanceWidth || 0;
30410
30411                // Draw the glyph box
30412                ctx.strokeStyle = 'blue';
30413                draw.line(ctx, x + xMin * scale, -10000, x + xMin * scale, 10000);
30414                draw.line(ctx, x + xMax * scale, -10000, x + xMax * scale, 10000);
30415                draw.line(ctx, -10000, y + -yMin * scale, 10000, y + -yMin * scale);
30416                draw.line(ctx, -10000, y + -yMax * scale, 10000, y + -yMax * scale);
30417
30418                // Draw the advance width
30419                ctx.strokeStyle = 'green';
30420                draw.line(
30421                  ctx,
30422                  x + advanceWidth * scale,
30423                  -10000,
30424                  x + advanceWidth * scale,
30425                  10000
30426                );
30427              };
30428
30429              // The GlyphSet object
30430
30431              // Define a property on the glyph that depends on the path being loaded.
30432              function defineDependentProperty(glyph, externalName, internalName) {
30433                Object.defineProperty(glyph, externalName, {
30434                  get: function() {
30435                    // Request the path property to make sure the path is loaded.
30436                    glyph.path; // jshint ignore:line
30437                    return glyph[internalName];
30438                  },
30439                  set: function(newValue) {
30440                    glyph[internalName] = newValue;
30441                  },
30442                  enumerable: true,
30443                  configurable: true
30444                });
30445              }
30446
30447              /**
30448               * A GlyphSet represents all glyphs available in the font, but modelled using
30449               * a deferred glyph loader, for retrieving glyphs only once they are absolutely
30450               * necessary, to keep the memory footprint down.
30451               * @exports opentype.GlyphSet
30452               * @class
30453               * @param {opentype.Font}
30454               * @param {Array}
30455               */
30456              function GlyphSet(font, glyphs) {
30457                var this$1 = this;
30458
30459                this.font = font;
30460                this.glyphs = {};
30461                if (Array.isArray(glyphs)) {
30462                  for (var i = 0; i < glyphs.length; i++) {
30463                    this$1.glyphs[i] = glyphs[i];
30464                  }
30465                }
30466
30467                this.length = (glyphs && glyphs.length) || 0;
30468              }
30469
30470              /**
30471               * @param  {number} index
30472               * @return {opentype.Glyph}
30473               */
30474              GlyphSet.prototype.get = function(index) {
30475                if (typeof this.glyphs[index] === 'function') {
30476                  this.glyphs[index] = this.glyphs[index]();
30477                }
30478
30479                return this.glyphs[index];
30480              };
30481
30482              /**
30483               * @param  {number} index
30484               * @param  {Object}
30485               */
30486              GlyphSet.prototype.push = function(index, loader) {
30487                this.glyphs[index] = loader;
30488                this.length++;
30489              };
30490
30491              /**
30492               * @alias opentype.glyphLoader
30493               * @param  {opentype.Font} font
30494               * @param  {number} index
30495               * @return {opentype.Glyph}
30496               */
30497              function glyphLoader(font, index) {
30498                return new Glyph({ index: index, font: font });
30499              }
30500
30501              /**
30502               * Generate a stub glyph that can be filled with all metadata *except*
30503               * the "points" and "path" properties, which must be loaded only once
30504               * the glyph's path is actually requested for text shaping.
30505               * @alias opentype.ttfGlyphLoader
30506               * @param  {opentype.Font} font
30507               * @param  {number} index
30508               * @param  {Function} parseGlyph
30509               * @param  {Object} data
30510               * @param  {number} position
30511               * @param  {Function} buildPath
30512               * @return {opentype.Glyph}
30513               */
30514              function ttfGlyphLoader(font, index, parseGlyph, data, position, buildPath) {
30515                return function() {
30516                  var glyph = new Glyph({ index: index, font: font });
30517
30518                  glyph.path = function() {
30519                    parseGlyph(glyph, data, position);
30520                    var path = buildPath(font.glyphs, glyph);
30521                    path.unitsPerEm = font.unitsPerEm;
30522                    return path;
30523                  };
30524
30525                  defineDependentProperty(glyph, 'xMin', '_xMin');
30526                  defineDependentProperty(glyph, 'xMax', '_xMax');
30527                  defineDependentProperty(glyph, 'yMin', '_yMin');
30528                  defineDependentProperty(glyph, 'yMax', '_yMax');
30529
30530                  return glyph;
30531                };
30532              }
30533              /**
30534               * @alias opentype.cffGlyphLoader
30535               * @param  {opentype.Font} font
30536               * @param  {number} index
30537               * @param  {Function} parseCFFCharstring
30538               * @param  {string} charstring
30539               * @return {opentype.Glyph}
30540               */
30541              function cffGlyphLoader(font, index, parseCFFCharstring, charstring) {
30542                return function() {
30543                  var glyph = new Glyph({ index: index, font: font });
30544
30545                  glyph.path = function() {
30546                    var path = parseCFFCharstring(font, glyph, charstring);
30547                    path.unitsPerEm = font.unitsPerEm;
30548                    return path;
30549                  };
30550
30551                  return glyph;
30552                };
30553              }
30554
30555              var glyphset = {
30556                GlyphSet: GlyphSet,
30557                glyphLoader: glyphLoader,
30558                ttfGlyphLoader: ttfGlyphLoader,
30559                cffGlyphLoader: cffGlyphLoader
30560              };
30561
30562              // The `CFF` table contains the glyph outlines in PostScript format.
30563
30564              // Custom equals function that can also check lists.
30565              function equals(a, b) {
30566                if (a === b) {
30567                  return true;
30568                } else if (Array.isArray(a) && Array.isArray(b)) {
30569                  if (a.length !== b.length) {
30570                    return false;
30571                  }
30572
30573                  for (var i = 0; i < a.length; i += 1) {
30574                    if (!equals(a[i], b[i])) {
30575                      return false;
30576                    }
30577                  }
30578
30579                  return true;
30580                } else {
30581                  return false;
30582                }
30583              }
30584
30585              // Subroutines are encoded using the negative half of the number space.
30586              // See type 2 chapter 4.7 "Subroutine operators".
30587              function calcCFFSubroutineBias(subrs) {
30588                var bias;
30589                if (subrs.length < 1240) {
30590                  bias = 107;
30591                } else if (subrs.length < 33900) {
30592                  bias = 1131;
30593                } else {
30594                  bias = 32768;
30595                }
30596
30597                return bias;
30598              }
30599
30600              // Parse a `CFF` INDEX array.
30601              // An index array consists of a list of offsets, then a list of objects at those offsets.
30602              function parseCFFIndex(data, start, conversionFn) {
30603                var offsets = [];
30604                var objects = [];
30605                var count = parse.getCard16(data, start);
30606                var objectOffset;
30607                var endOffset;
30608                if (count !== 0) {
30609                  var offsetSize = parse.getByte(data, start + 2);
30610                  objectOffset = start + (count + 1) * offsetSize + 2;
30611                  var pos = start + 3;
30612                  for (var i = 0; i < count + 1; i += 1) {
30613                    offsets.push(parse.getOffset(data, pos, offsetSize));
30614                    pos += offsetSize;
30615                  }
30616
30617                  // The total size of the index array is 4 header bytes + the value of the last offset.
30618                  endOffset = objectOffset + offsets[count];
30619                } else {
30620                  endOffset = start + 2;
30621                }
30622
30623                for (var i$1 = 0; i$1 < offsets.length - 1; i$1 += 1) {
30624                  var value = parse.getBytes(
30625                    data,
30626                    objectOffset + offsets[i$1],
30627                    objectOffset + offsets[i$1 + 1]
30628                  );
30629                  if (conversionFn) {
30630                    value = conversionFn(value);
30631                  }
30632
30633                  objects.push(value);
30634                }
30635
30636                return { objects: objects, startOffset: start, endOffset: endOffset };
30637              }
30638
30639              // Parse a `CFF` DICT real value.
30640              function parseFloatOperand(parser) {
30641                var s = '';
30642                var eof = 15;
30643                var lookup = [
30644                  '0',
30645                  '1',
30646                  '2',
30647                  '3',
30648                  '4',
30649                  '5',
30650                  '6',
30651                  '7',
30652                  '8',
30653                  '9',
30654                  '.',
30655                  'E',
30656                  'E-',
30657                  null,
vendor: 4,555 bytes, lines 30658-30790
30658                  '-'
30659                ];
30660                while (true) {
30661                  var b = parser.parseByte();
30662                  var n1 = b >> 4;
30663                  var n2 = b & 15;
30664
30665                  if (n1 === eof) {
30666                    break;
30667                  }
30668
30669                  s += lookup[n1];
30670
30671                  if (n2 === eof) {
30672                    break;
30673                  }
30674
30675                  s += lookup[n2];
30676                }
30677
30678                return parseFloat(s);
30679              }
30680
30681              // Parse a `CFF` DICT operand.
30682              function parseOperand(parser, b0) {
30683                var b1;
30684                var b2;
30685                var b3;
30686                var b4;
30687                if (b0 === 28) {
30688                  b1 = parser.parseByte();
30689                  b2 = parser.parseByte();
30690                  return (b1 << 8) | b2;
30691                }
30692
30693                if (b0 === 29) {
30694                  b1 = parser.parseByte();
30695                  b2 = parser.parseByte();
30696                  b3 = parser.parseByte();
30697                  b4 = parser.parseByte();
30698                  return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
30699                }
30700
30701                if (b0 === 30) {
30702                  return parseFloatOperand(parser);
30703                }
30704
30705                if (b0 >= 32 && b0 <= 246) {
30706                  return b0 - 139;
30707                }
30708
30709                if (b0 >= 247 && b0 <= 250) {
30710                  b1 = parser.parseByte();
30711                  return (b0 - 247) * 256 + b1 + 108;
30712                }
30713
30714                if (b0 >= 251 && b0 <= 254) {
30715                  b1 = parser.parseByte();
30716                  return -(b0 - 251) * 256 - b1 - 108;
30717                }
30718
30719                throw new Error('Invalid b0 ' + b0);
30720              }
30721
30722              // Convert the entries returned by `parseDict` to a proper dictionary.
30723              // If a value is a list of one, it is unpacked.
30724              function entriesToObject(entries) {
30725                var o = {};
30726                for (var i = 0; i < entries.length; i += 1) {
30727                  var key = entries[i][0];
30728                  var values = entries[i][1];
30729                  var value = void 0;
30730                  if (values.length === 1) {
30731                    value = values[0];
30732                  } else {
30733                    value = values;
30734                  }
30735
30736                  if (o.hasOwnProperty(key) && !isNaN(o[key])) {
30737                    throw new Error('Object ' + o + ' already has key ' + key);
30738                  }
30739
30740                  o[key] = value;
30741                }
30742
30743                return o;
30744              }
30745
30746              // Parse a `CFF` DICT object.
30747              // A dictionary contains key-value pairs in a compact tokenized format.
30748              function parseCFFDict(data, start, size) {
30749                start = start !== undefined ? start : 0;
30750                var parser = new parse.Parser(data, start);
30751                var entries = [];
30752                var operands = [];
30753                size = size !== undefined ? size : data.length;
30754
30755                while (parser.relativeOffset < size) {
30756                  var op = parser.parseByte();
30757
30758                  // The first byte for each dict item distinguishes between operator (key) and operand (value).
30759                  // Values <= 21 are operators.
30760                  if (op <= 21) {
30761                    // Two-byte operators have an initial escape byte of 12.
30762                    if (op === 12) {
30763                      op = 1200 + parser.parseByte();
30764                    }
30765
30766                    entries.push([op, operands]);
30767                    operands = [];
30768                  } else {
30769                    // Since the operands (values) come before the operators (keys), we store all operands in a list
30770                    // until we encounter an operator.
30771                    operands.push(parseOperand(parser, op));
30772                  }
30773                }
30774
30775                return entriesToObject(entries);
30776              }
30777
30778              // Given a String Index (SID), return the value of the string.
30779              // Strings below index 392 are standard CFF strings and are not encoded in the font.
30780              function getCFFString(strings, index) {
30781                if (index <= 390) {
30782                  index = cffStandardStrings[index];
30783                } else {
30784                  index = strings[index - 391];
30785                }
30786
30787                return index;
30788              }
30789
30790              // Interpret a dictionary and return a new dictionary with readable keys and values for missing entr
30790ies.
30791              // This function takes `meta` which is a list of objects containing `operand`, `name` and `default`.
30792              function interpretDict(dict, meta, strings) {
30793                var newDict = {};
30794                var value;
30795
30796                // Because we also want to include missing values, we start out from the meta list
30797                // and lookup values in the dict.
30798                for (var i = 0; i < meta.length; i += 1) {
30799                  var m = meta[i];
30800
30801                  if (Array.isArray(m.type)) {
30802                    var values = [];
30803                    values.length = m.type.length;
30804                    for (var j = 0; j < m.type.length; j++) {
30805                      value = dict[m.op] !== undefined ? dict[m.op][j] : undefined;
30806                      if (value === undefined) {
30807                        value =
30808                          m.value !== undefined && m.value[j] !== undefined
30809                            ? m.value[j]
30810                            : null;
30811                      }
30812                      if (m.type[j] === 'SID') {
30813                        value = getCFFString(strings, value);
30814                      }
30815                      values[j] = value;
30816                    }
30817                    newDict[m.name] = values;
30818                  } else {
30819                    value = dict[m.op];
30820                    if (value === undefined) {
30821                      value = m.value !== undefined ? m.value : null;
30822                    }
30823
30824                    if (m.type === 'SID') {
30825                      value = getCFFString(strings, value);
30826                    }
30827                    newDict[m.name] = value;
30828                  }
30829                }
30830
30831                return newDict;
30832              }
30833
30834              // Parse the CFF header.
30835              function parseCFFHeader(data, start) {
30836                var header = {};
30837                header.formatMajor = parse.getCard8(data, start);
30838                header.formatMinor = parse.getCard8(data, start + 1);
30839                header.size = parse.getCard8(data, start + 2);
30840                header.offsetSize = parse.getCard8(data, start + 3);
30841                header.startOffset = start;
30842                header.endOffset = start + 4;
30843                return header;
30844              }
30845
30846              var TOP_DICT_META = [
30847                { name: 'version', op: 0, type: 'SID' },
30848                { name: 'notice', op: 1, type: 'SID' },
30849                { name: 'copyright', op: 1200, type: 'SID' },
30850                { name: 'fullName', op: 2, type: 'SID' },
30851                { name: 'familyName', op: 3, type: 'SID' },
30852                { name: 'weight', op: 4, type: 'SID' },
30853                { name: 'isFixedPitch', op: 1201, type: 'number', value: 0 },
30854                { name: 'italicAngle', op: 1202, type: 'number', value: 0 },
30855                { name: 'underlinePosition', op: 1203, type: 'number', value: -100 },
30856                { name: 'underlineThickness', op: 1204, type: 'number', value: 50 },
30857                { name: 'paintType', op: 1205, type: 'number', value: 0 },
30858                { name: 'charstringType', op: 1206, type: 'number', value: 2 },
30859                {
30860                  name: 'fontMatrix',
30861                  op: 1207,
30862                  type: ['real', 'real', 'real', 'real', 'real', 'real'],
30863                  value: [0.001, 0, 0, 0.001, 0, 0]
30864                },
30865                { name: 'uniqueId', op: 13, type: 'number' },
30866                {
30867                  name: 'fontBBox',
30868                  op: 5,
30869                  type: ['number', 'number', 'number', 'number'],
30870                  value: [0, 0, 0, 0]
30871                },
30872                { name: 'strokeWidth', op: 1208, type: 'number', value: 0 },
30873                { name: 'xuid', op: 14, type: [], value: null },
30874                { name: 'charset', op: 15, type: 'offset', value: 0 },
30875                { name: 'encoding', op: 16, type: 'offset', value: 0 },
30876                { name: 'charStrings', op: 17, type: 'offset', value: 0 },
30877                { name: 'private', op: 18, type: ['number', 'offset'], value: [0, 0] },
30878                { name: 'ros', op: 1230, type: ['SID', 'SID', 'number'] },
30879                { name: 'cidFontVersion', op: 1231, type: 'number', value: 0 },
30880                { name: 'cidFontRevision', op: 1232, type: 'number', value: 0 },
30881                { name: 'cidFontType', op: 1233, type: 'number', value: 0 },
30882                { name: 'cidCount', op: 1234, type: 'number', value: 8720 },
30883                { name: 'uidBase', op: 1235, type: 'number' },
30884                { name: 'fdArray', op: 1236, type: 'offset' },
30885                { name: 'fdSelect', op: 1237, type: 'offset' },
30886                { name: 'fontName', op: 1238, type: 'SID' }
30887              ];
30888
30889              var PRIVATE_DICT_META = [
30890                { name: 'subrs', op: 19, type: 'offset', value: 0 },
30891                { name: 'defaultWidthX', op: 20, type: 'number', value: 0 },
30892                { name: 'nominalWidthX', op: 21, type: 'number', value: 0 }
30893              ];
30894
30895              // Parse the CFF top dictionary. A CFF table can contain multiple fonts, each with their own top dictionary.
30896              // The top dictionary contains the essential metadata for the font, together with the private dictionary.
30897              function parseCFFTopDict(data, strings) {
30898                var dict = parseCFFDict(data, 0, data.byteLength);
30899                return interpretDict(dict, TOP_DICT_META, strings);
30900              }
30901
30902              // Parse the CFF private dictionary. We don't fully parse out all the values, only the ones we need.
30903              function parseCFFPrivateDict(data, start, size, strings) {
30904                var dict = parseCFFDict(data, start, size);
30905                return interpretDict(dict, PRIVATE_DICT_META, strings);
30906              }
30907
30908              // Returns a list of "Top DICT"s found using an INDEX list.
30909              // Used to read both the usual high-level Top DICTs and also the FDArray
30910              // discovered inside CID-keyed fonts.  When a Top DICT has a reference to
30911              // a Private DICT that is read and saved into the Top DICT.
30912              //
30913              // In addition to the expected/optional values as outlined in TOP_DICT_META
30914              // the following values might be saved into the Top DICT.
30915              //
vendor: 26,738 bytes, lines 30916-31537
30916              //    _subrs []        array of local CFF subroutines from Private DICT
30917              //    _subrsBias       bias value computed from number of subroutines
30918              //                      (see calcCFFSubroutineBias() and parseCFFCharstring())
30919              //    _defaultWidthX   default widths for CFF characters
30920              //    _nominalWidthX   bias added to width embedded within glyph description
30921              //
30922              //    _privateDict     saved copy of parsed Private DICT from Top DICT
30923              function gatherCFFTopDicts(data, start, cffIndex, strings) {
30924                var topDictArray = [];
30925                for (var iTopDict = 0; iTopDict < cffIndex.length; iTopDict += 1) {
30926                  var topDictData = new DataView(new Uint8Array(cffIndex[iTopDict]).buffer);
30927                  var topDict = parseCFFTopDict(topDictData, strings);
30928                  topDict._subrs = [];
30929                  topDict._subrsBias = 0;
30930                  var privateSize = topDict.private[0];
30931                  var privateOffset = topDict.private[1];
30932                  if (privateSize !== 0 && privateOffset !== 0) {
30933                    var privateDict = parseCFFPrivateDict(
30934                      data,
30935                      privateOffset + start,
30936                      privateSize,
30937                      strings
30938                    );
30939                    topDict._defaultWidthX = privateDict.defaultWidthX;
30940                    topDict._nominalWidthX = privateDict.nominalWidthX;
30941                    if (privateDict.subrs !== 0) {
30942                      var subrOffset = privateOffset + privateDict.subrs;
30943                      var subrIndex = parseCFFIndex(data, subrOffset + start);
30944                      topDict._subrs = subrIndex.objects;
30945                      topDict._subrsBias = calcCFFSubroutineBias(topDict._subrs);
30946                    }
30947                    topDict._privateDict = privateDict;
30948                  }
30949                  topDictArray.push(topDict);
30950                }
30951                return topDictArray;
30952              }
30953
30954              // Parse the CFF charset table, which contains internal names for all the glyphs.
30955              // This function will return a list of glyph names.
30956              // See Adobe TN #5176 chapter 13, "Charsets".
30957              function parseCFFCharset(data, start, nGlyphs, strings) {
30958                var sid;
30959                var count;
30960                var parser = new parse.Parser(data, start);
30961
30962                // The .notdef glyph is not included, so subtract 1.
30963                nGlyphs -= 1;
30964                var charset = ['.notdef'];
30965
30966                var format = parser.parseCard8();
30967                if (format === 0) {
30968                  for (var i = 0; i < nGlyphs; i += 1) {
30969                    sid = parser.parseSID();
30970                    charset.push(getCFFString(strings, sid));
30971                  }
30972                } else if (format === 1) {
30973                  while (charset.length <= nGlyphs) {
30974                    sid = parser.parseSID();
30975                    count = parser.parseCard8();
30976                    for (var i$1 = 0; i$1 <= count; i$1 += 1) {
30977                      charset.push(getCFFString(strings, sid));
30978                      sid += 1;
30979                    }
30980                  }
30981                } else if (format === 2) {
30982                  while (charset.length <= nGlyphs) {
30983                    sid = parser.parseSID();
30984                    count = parser.parseCard16();
30985                    for (var i$2 = 0; i$2 <= count; i$2 += 1) {
30986                      charset.push(getCFFString(strings, sid));
30987                      sid += 1;
30988                    }
30989                  }
30990                } else {
30991                  throw new Error('Unknown charset format ' + format);
30992                }
30993
30994                return charset;
30995              }
30996
30997              // Parse the CFF encoding data. Only one encoding can be specified per font.
30998              // See Adobe TN #5176 chapter 12, "Encodings".
30999              function parseCFFEncoding(data, start, charset) {
31000                var code;
31001                var enc = {};
31002                var parser = new parse.Parser(data, start);
31003                var format = parser.parseCard8();
31004                if (format === 0) {
31005                  var nCodes = parser.parseCard8();
31006                  for (var i = 0; i < nCodes; i += 1) {
31007                    code = parser.parseCard8();
31008                    enc[code] = i;
31009                  }
31010                } else if (format === 1) {
31011                  var nRanges = parser.parseCard8();
31012                  code = 1;
31013                  for (var i$1 = 0; i$1 < nRanges; i$1 += 1) {
31014                    var first = parser.parseCard8();
31015                    var nLeft = parser.parseCard8();
31016                    for (var j = first; j <= first + nLeft; j += 1) {
31017                      enc[j] = code;
31018                      code += 1;
31019                    }
31020                  }
31021                } else {
31022                  throw new Error('Unknown encoding format ' + format);
31023                }
31024
31025                return new CffEncoding(enc, charset);
31026              }
31027
31028              // Take in charstring code and return a Glyph object.
31029              // The encoding is described in the Type 2 Charstring Format
31030              // https://www.microsoft.com/typography/OTSPEC/charstr2.htm
31031              function parseCFFCharstring(font, glyph, code) {
31032                var c1x;
31033                var c1y;
31034                var c2x;
31035                var c2y;
31036                var p = new Path();
31037                var stack = [];
31038                var nStems = 0;
31039                var haveWidth = false;
31040                var open = false;
31041                var x = 0;
31042                var y = 0;
31043                var subrs;
31044                var subrsBias;
31045                var defaultWidthX;
31046                var nominalWidthX;
31047                if (font.isCIDFont) {
31048                  var fdIndex = font.tables.cff.topDict._fdSelect[glyph.index];
31049                  var fdDict = font.tables.cff.topDict._fdArray[fdIndex];
31050                  subrs = fdDict._subrs;
31051                  subrsBias = fdDict._subrsBias;
31052                  defaultWidthX = fdDict._defaultWidthX;
31053                  nominalWidthX = fdDict._nominalWidthX;
31054                } else {
31055                  subrs = font.tables.cff.topDict._subrs;
31056                  subrsBias = font.tables.cff.topDict._subrsBias;
31057                  defaultWidthX = font.tables.cff.topDict._defaultWidthX;
31058                  nominalWidthX = font.tables.cff.topDict._nominalWidthX;
31059                }
31060                var width = defaultWidthX;
31061
31062                function newContour(x, y) {
31063                  if (open) {
31064                    p.closePath();
31065                  }
31066
31067                  p.moveTo(x, y);
31068                  open = true;
31069                }
31070
31071                function parseStems() {
31072                  var hasWidthArg;
31073
31074                  // The number of stem operators on the stack is always even.
31075                  // If the value is uneven, that means a width is specified.
31076                  hasWidthArg = stack.length % 2 !== 0;
31077                  if (hasWidthArg && !haveWidth) {
31078                    width = stack.shift() + nominalWidthX;
31079                  }
31080
31081                  nStems += stack.length >> 1;
31082                  stack.length = 0;
31083                  haveWidth = true;
31084                }
31085
31086                function parse$$1(code) {
31087                  var b1;
31088                  var b2;
31089                  var b3;
31090                  var b4;
31091                  var codeIndex;
31092                  var subrCode;
31093                  var jpx;
31094                  var jpy;
31095                  var c3x;
31096                  var c3y;
31097                  var c4x;
31098                  var c4y;
31099
31100                  var i = 0;
31101                  while (i < code.length) {
31102                    var v = code[i];
31103                    i += 1;
31104                    switch (v) {
31105                      case 1: // hstem
31106                        parseStems();
31107                        break;
31108                      case 3: // vstem
31109                        parseStems();
31110                        break;
31111                      case 4: // vmoveto
31112                        if (stack.length > 1 && !haveWidth) {
31113                          width = stack.shift() + nominalWidthX;
31114                          haveWidth = true;
31115                        }
31116
31117                        y += stack.pop();
31118                        newContour(x, y);
31119                        break;
31120                      case 5: // rlineto
31121                        while (stack.length > 0) {
31122                          x += stack.shift();
31123                          y += stack.shift();
31124                          p.lineTo(x, y);
31125                        }
31126
31127                        break;
31128                      case 6: // hlineto
31129                        while (stack.length > 0) {
31130                          x += stack.shift();
31131                          p.lineTo(x, y);
31132                          if (stack.length === 0) {
31133                            break;
31134                          }
31135
31136                          y += stack.shift();
31137                          p.lineTo(x, y);
31138                        }
31139
31140                        break;
31141                      case 7: // vlineto
31142                        while (stack.length > 0) {
31143                          y += stack.shift();
31144                          p.lineTo(x, y);
31145                          if (stack.length === 0) {
31146                            break;
31147                          }
31148
31149                          x += stack.shift();
31150                          p.lineTo(x, y);
31151                        }
31152
31153                        break;
31154                      case 8: // rrcurveto
31155                        while (stack.length > 0) {
31156                          c1x = x + stack.shift();
31157                          c1y = y + stack.shift();
31158                          c2x = c1x + stack.shift();
31159                          c2y = c1y + stack.shift();
31160                          x = c2x + stack.shift();
31161                          y = c2y + stack.shift();
31162                          p.curveTo(c1x, c1y, c2x, c2y, x, y);
31163                        }
31164
31165                        break;
31166                      case 10: // callsubr
31167                        codeIndex = stack.pop() + subrsBias;
31168                        subrCode = subrs[codeIndex];
31169                        if (subrCode) {
31170                          parse$$1(subrCode);
31171                        }
31172
31173                        break;
31174                      case 11: // return
31175                        return;
31176                      case 12: // flex operators
31177                        v = code[i];
31178                        i += 1;
31179                        switch (v) {
31180                          case 35: // flex
31181                            // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd flex (12 35) |-
31182                            c1x = x + stack.shift(); // dx1
31183                            c1y = y + stack.shift(); // dy1
31184                            c2x = c1x + stack.shift(); // dx2
31185                            c2y = c1y + stack.shift(); // dy2
31186                            jpx = c2x + stack.shift(); // dx3
31187                            jpy = c2y + stack.shift(); // dy3
31188                            c3x = jpx + stack.shift(); // dx4
31189                            c3y = jpy + stack.shift(); // dy4
31190                            c4x = c3x + stack.shift(); // dx5
31191                            c4y = c3y + stack.shift(); // dy5
31192                            x = c4x + stack.shift(); // dx6
31193                            y = c4y + stack.shift(); // dy6
31194                            stack.shift(); // flex depth
31195                            p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy);
31196                            p.curveTo(c3x, c3y, c4x, c4y, x, y);
31197                            break;
31198                          case 34: // hflex
31199                            // |- dx1 dx2 dy2 dx3 dx4 dx5 dx6 hflex (12 34) |-
31200                            c1x = x + stack.shift(); // dx1
31201                            c1y = y; // dy1
31202                            c2x = c1x + stack.shift(); // dx2
31203                            c2y = c1y + stack.shift(); // dy2
31204                            jpx = c2x + stack.shift(); // dx3
31205                            jpy = c2y; // dy3
31206                            c3x = jpx + stack.shift(); // dx4
31207                            c3y = c2y; // dy4
31208                            c4x = c3x + stack.shift(); // dx5
31209                            c4y = y; // dy5
31210                            x = c4x + stack.shift(); // dx6
31211                            p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy);
31212                            p.curveTo(c3x, c3y, c4x, c4y, x, y);
31213                            break;
31214                          case 36: // hflex1
31215                            // |- dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6 hflex1 (12 36) |-
31216                            c1x = x + stack.shift(); // dx1
31217                            c1y = y + stack.shift(); // dy1
31218                            c2x = c1x + stack.shift(); // dx2
31219                            c2y = c1y + stack.shift(); // dy2
31220                            jpx = c2x + stack.shift(); // dx3
31221                            jpy = c2y; // dy3
31222                            c3x = jpx + stack.shift(); // dx4
31223                            c3y = c2y; // dy4
31224                            c4x = c3x + stack.shift(); // dx5
31225                            c4y = c3y + stack.shift(); // dy5
31226                            x = c4x + stack.shift(); // dx6
31227                            p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy);
31228                            p.curveTo(c3x, c3y, c4x, c4y, x, y);
31229                            break;
31230                          case 37: // flex1
31231                            // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6 flex1 (12 37) |-
31232                            c1x = x + stack.shift(); // dx1
31233                            c1y = y + stack.shift(); // dy1
31234                            c2x = c1x + stack.shift(); // dx2
31235                            c2y = c1y + stack.shift(); // dy2
31236                            jpx = c2x + stack.shift(); // dx3
31237                            jpy = c2y + stack.shift(); // dy3
31238                            c3x = jpx + stack.shift(); // dx4
31239                            c3y = jpy + stack.shift(); // dy4
31240                            c4x = c3x + stack.shift(); // dx5
31241                            c4y = c3y + stack.shift(); // dy5
31242                            if (Math.abs(c4x - x) > Math.abs(c4y - y)) {
31243                              x = c4x + stack.shift();
31244                            } else {
31245                              y = c4y + stack.shift();
31246                            }
31247
31248                            p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy);
31249                            p.curveTo(c3x, c3y, c4x, c4y, x, y);
31250                            break;
31251                          default:
31252                            console.log(
31253                              'Glyph ' + glyph.index + ': unknown operator ' + 1200 + v
31254                            );
31255                            stack.length = 0;
31256                        }
31257                        break;
31258                      case 14: // endchar
31259                        if (stack.length > 0 && !haveWidth) {
31260                          width = stack.shift() + nominalWidthX;
31261                          haveWidth = true;
31262                        }
31263
31264                        if (open) {
31265                          p.closePath();
31266                          open = false;
31267                        }
31268
31269                        break;
31270                      case 18: // hstemhm
31271                        parseStems();
31272                        break;
31273                      case 19: // hintmask
31274                      case 20: // cntrmask
31275                        parseStems();
31276                        i += (nStems + 7) >> 3;
31277                        break;
31278                      case 21: // rmoveto
31279                        if (stack.length > 2 && !haveWidth) {
31280                          width = stack.shift() + nominalWidthX;
31281                          haveWidth = true;
31282                        }
31283
31284                        y += stack.pop();
31285                        x += stack.pop();
31286                        newContour(x, y);
31287                        break;
31288                      case 22: // hmoveto
31289                        if (stack.length > 1 && !haveWidth) {
31290                          width = stack.shift() + nominalWidthX;
31291                          haveWidth = true;
31292                        }
31293
31294                        x += stack.pop();
31295                        newContour(x, y);
31296                        break;
31297                      case 23: // vstemhm
31298                        parseStems();
31299                        break;
31300                      case 24: // rcurveline
31301                        while (stack.length > 2) {
31302                          c1x = x + stack.shift();
31303                          c1y = y + stack.shift();
31304                          c2x = c1x + stack.shift();
31305                          c2y = c1y + stack.shift();
31306                          x = c2x + stack.shift();
31307                          y = c2y + stack.shift();
31308                          p.curveTo(c1x, c1y, c2x, c2y, x, y);
31309                        }
31310
31311                        x += stack.shift();
31312                        y += stack.shift();
31313                        p.lineTo(x, y);
31314                        break;
31315                      case 25: // rlinecurve
31316                        while (stack.length > 6) {
31317                          x += stack.shift();
31318                          y += stack.shift();
31319                          p.lineTo(x, y);
31320                        }
31321
31322                        c1x = x + stack.shift();
31323                        c1y = y + stack.shift();
31324                        c2x = c1x + stack.shift();
31325                        c2y = c1y + stack.shift();
31326                        x = c2x + stack.shift();
31327                        y = c2y + stack.shift();
31328                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
31329                        break;
31330                      case 26: // vvcurveto
31331                        if (stack.length % 2) {
31332                          x += stack.shift();
31333                        }
31334
31335                        while (stack.length > 0) {
31336                          c1x = x;
31337                          c1y = y + stack.shift();
31338                          c2x = c1x + stack.shift();
31339                          c2y = c1y + stack.shift();
31340                          x = c2x;
31341                          y = c2y + stack.shift();
31342                          p.curveTo(c1x, c1y, c2x, c2y, x, y);
31343                        }
31344
31345                        break;
31346                      case 27: // hhcurveto
31347                        if (stack.length % 2) {
31348                          y += stack.shift();
31349                        }
31350
31351                        while (stack.length > 0) {
31352                          c1x = x + stack.shift();
31353                          c1y = y;
31354                          c2x = c1x + stack.shift();
31355                          c2y = c1y + stack.shift();
31356                          x = c2x + stack.shift();
31357                          y = c2y;
31358                          p.curveTo(c1x, c1y, c2x, c2y, x, y);
31359                        }
31360
31361                        break;
31362                      case 28: // shortint
31363                        b1 = code[i];
31364                        b2 = code[i + 1];
31365                        stack.push(((b1 << 24) | (b2 << 16)) >> 16);
31366                        i += 2;
31367                        break;
31368                      case 29: // callgsubr
31369                        codeIndex = stack.pop() + font.gsubrsBias;
31370                        subrCode = font.gsubrs[codeIndex];
31371                        if (subrCode) {
31372                          parse$$1(subrCode);
31373                        }
31374
31375                        break;
31376                      case 30: // vhcurveto
31377                        while (stack.length > 0) {
31378                          c1x = x;
31379                          c1y = y + stack.shift();
31380                          c2x = c1x + stack.shift();
31381                          c2y = c1y + stack.shift();
31382                          x = c2x + stack.shift();
31383                          y = c2y + (stack.length === 1 ? stack.shift() : 0);
31384                          p.curveTo(c1x, c1y, c2x, c2y, x, y);
31385                          if (stack.length === 0) {
31386                            break;
31387                          }
31388
31389                          c1x = x + stack.shift();
31390                          c1y = y;
31391                          c2x = c1x + stack.shift();
31392                          c2y = c1y + stack.shift();
31393                          y = c2y + stack.shift();
31394                          x = c2x + (stack.length === 1 ? stack.shift() : 0);
31395                          p.curveTo(c1x, c1y, c2x, c2y, x, y);
31396                        }
31397
31398                        break;
31399                      case 31: // hvcurveto
31400                        while (stack.length > 0) {
31401                          c1x = x + stack.shift();
31402                          c1y = y;
31403                          c2x = c1x + stack.shift();
31404                          c2y = c1y + stack.shift();
31405                          y = c2y + stack.shift();
31406                          x = c2x + (stack.length === 1 ? stack.shift() : 0);
31407                          p.curveTo(c1x, c1y, c2x, c2y, x, y);
31408                          if (stack.length === 0) {
31409                            break;
31410                          }
31411
31412                          c1x = x;
31413                          c1y = y + stack.shift();
31414                          c2x = c1x + stack.shift();
31415                          c2y = c1y + stack.shift();
31416                          x = c2x + stack.shift();
31417                          y = c2y + (stack.length === 1 ? stack.shift() : 0);
31418                          p.curveTo(c1x, c1y, c2x, c2y, x, y);
31419                        }
31420
31421                        break;
31422                      default:
31423                        if (v < 32) {
31424                          console.log('Glyph ' + glyph.index + ': unknown operator ' + v);
31425                        } else if (v < 247) {
31426                          stack.push(v - 139);
31427                        } else if (v < 251) {
31428                          b1 = code[i];
31429                          i += 1;
31430                          stack.push((v - 247) * 256 + b1 + 108);
31431                        } else if (v < 255) {
31432                          b1 = code[i];
31433                          i += 1;
31434                          stack.push(-(v - 251) * 256 - b1 - 108);
31435                        } else {
31436                          b1 = code[i];
31437                          b2 = code[i + 1];
31438                          b3 = code[i + 2];
31439                          b4 = code[i + 3];
31440                          i += 4;
31441                          stack.push(((b1 << 24) | (b2 << 16) | (b3 << 8) | b4) / 65536);
31442                        }
31443                    }
31444                  }
31445                }
31446
31447                parse$$1(code);
31448
31449                glyph.advanceWidth = width;
31450                return p;
31451              }
31452
31453              function parseCFFFDSelect(data, start, nGlyphs, fdArrayCount) {
31454                var fdSelect = [];
31455                var fdIndex;
31456                var parser = new parse.Parser(data, start);
31457                var format = parser.parseCard8();
31458                if (format === 0) {
31459                  // Simple list of nGlyphs elements
31460                  for (var iGid = 0; iGid < nGlyphs; iGid++) {
31461                    fdIndex = parser.parseCard8();
31462                    if (fdIndex >= fdArrayCount) {
31463                      throw new Error(
31464                        'CFF table CID Font FDSelect has bad FD index value ' +
31465                          fdIndex +
31466                          ' (FD count ' +
31467                          fdArrayCount +
31468                          ')'
31469                      );
31470                    }
31471                    fdSelect.push(fdIndex);
31472                  }
31473                } else if (format === 3) {
31474                  // Ranges
31475                  var nRanges = parser.parseCard16();
31476                  var first = parser.parseCard16();
31477                  if (first !== 0) {
31478                    throw new Error(
31479                      'CFF Table CID Font FDSelect format 3 range has bad initial GID ' +
31480                        first
31481                    );
31482                  }
31483                  var next;
31484                  for (var iRange = 0; iRange < nRanges; iRange++) {
31485                    fdIndex = parser.parseCard8();
31486                    next = parser.parseCard16();
31487                    if (fdIndex >= fdArrayCount) {
31488                      throw new Error(
31489                        'CFF table CID Font FDSelect has bad FD index value ' +
31490                          fdIndex +
31491                          ' (FD count ' +
31492                          fdArrayCount +
31493                          ')'
31494                      );
31495                    }
31496                    if (next > nGlyphs) {
31497                      throw new Error(
31498                        'CFF Table CID Font FDSelect format 3 range has bad GID ' + next
31499                      );
31500                    }
31501                    for (; first < next; first++) {
31502                      fdSelect.push(fdIndex);
31503                    }
31504                    first = next;
31505                  }
31506                  if (next !== nGlyphs) {
31507                    throw new Error(
31508                      'CFF Table CID Font FDSelect format 3 range has bad final GID ' + next
31509                    );
31510                  }
31511                } else {
31512                  throw new Error(
31513                    'CFF Table CID Font FDSelect table has unsupported format ' + format
31514                  );
31515                }
31516                return fdSelect;
31517              }
31518
31519              // Parse the `CFF` table, which contains the glyph outlines in PostScript format.
31520              function parseCFFTable(data, start, font) {
31521                font.tables.cff = {};
31522                var header = parseCFFHeader(data, start);
31523                var nameIndex = parseCFFIndex(data, header.endOffset, parse.bytesToString);
31524                var topDictIndex = parseCFFIndex(data, nameIndex.endOffset);
31525                var stringIndex = parseCFFIndex(
31526                  data,
31527                  topDictIndex.endOffset,
31528                  parse.bytesToString
31529                );
31530                var globalSubrIndex = parseCFFIndex(data, stringIndex.endOffset);
31531                font.gsubrs = globalSubrIndex.objects;
31532                font.gsubrsBias = calcCFFSubroutineBias(font.gsubrs);
31533
31534                var topDictArray = gatherCFFTopDicts(
31535                  data,
31536                  start,
31537                  topDictIndex.objects,
31538                  stringIndex.objects
31539                );
31540                if (topDictArray.length !== 1) {
31541                  throw new Error(
31542                    "CFF table has too many fonts in 'FontSet' - count of fonts NameIndex.length = " +
31543                      topDictArray.length
31544                  );
31545                }
31546
31547                var topDict = topDictArray[0];
31548                font.tables.cff.topDict = topDict;
31549
31550                if (topDict._privateDict) {
31551                  font.defaultWidthX = topDict._privateDict.defaultWidthX;
31552                  font.nominalWidthX = topDict._privateDict.nominalWidthX;
31553                }
31554
31555                if (topDict.ros[0] !== undefined && topDict.ros[1] !== undefined) {
31556                  font.isCIDFont = true;
31557                }
31558
31559                if (font.isCIDFont) {
31560                  var fdArrayOffset = topDict.fdArray;
31561                  var fdSelectOffset = topDict.fdSelect;
31562                  if (fdArrayOffset === 0 || fdSelectOffset === 0) {
31563                    throw new Error(
31564                      'Font is marked as a CID font, but FDArray and/or FDSelect information is missing'
31565                    );
31566                  }
31567                  fdArrayOffset += start;
31568                  var fdArrayIndex = parseCFFIndex(data, fdArrayOffset);
31569                  var fdArray = gatherCFFTopDicts(
31570                    data,
31571                    start,
31572                    fdArrayIndex.objects,
31573                    stringIndex.objects
31574                  );
31575                  topDict._fdArray = fdArray;
31576                  fdSelectOffset += start;
31577                  topDict._fdSelect = parseCFFFDSelect(
31578                    data,
31579                    fdSelectOffset,
31580                    font.numGlyphs,
31581                    fdArray.length
31582                  );
31583                }
31584
31585                var privateDictOffset = start + topDict.private[1];
31586                var privateDict = parseCFFPrivateDict(
31587                  data,
31588                  privateDictOffset,
31589                  topDict.private[0],
31590                  stringIndex.objects
31591                );
31592                font.defaultWidthX = privateDict.defaultWidthX;
31593                font.nominalWidthX = privateDict.nominalWidthX;
31594
31595                if (privateDict.subrs !== 0) {
31596                  var subrOffset = privateDictOffset + privateDict.subrs;
31597                  var subrIndex = parseCFFIndex(data, subrOffset);
31598                  font.subrs = subrIndex.objects;
31599                  font.subrsBias = calcCFFSubroutineBias(font.subrs);
31600                } else {
31601                  font.subrs = [];
31602                  font.subrsBias = 0;
31603                }
31604
31605                // Offsets in the top dict are relative to the beginning of the CFF data, so add the CFF start offset.
31606                var charStringsIndex = parseCFFIndex(data, start + topDict.charStrings);
31607                font.nGlyphs = charStringsIndex.objects.length;
31608
31609                var charset = parseCFFCharset(
31610                  data,
31611                  start + topDict.charset,
31612                  font.nGlyphs,
31613                  stringIndex.objects
31614                );
31615                if (topDict.encoding === 0) {
31616                  // Standard encoding
31617                  font.cffEncoding = new CffEncoding(cffStandardEncoding, charset);
31618                } else if (topDict.encoding === 1) {
31619                  // Expert encoding
31620                  font.cffEncoding = new CffEncoding(cffExpertEncoding, charset);
31621                } else {
31622                  font.cffEncoding = parseCFFEncoding(
31623                    data,
31624                    start + topDict.encoding,
31625                    charset
31626                  );
31627                }
31628
31629                // Prefer the CMAP encoding to the CFF encoding.
31630                font.encoding = font.encoding || font.cffEncoding;
31631
31632                font.glyphs = new glyphset.GlyphSet(font);
31633                for (var i = 0; i < font.nGlyphs; i += 1) {
31634                  var charString = charStringsIndex.objects[i];
31635                  font.glyphs.push(
31636                    i,
31637                    glyphset.cffGlyphLoader(font, i, parseCFFCharstring, charString)
31638                  );
31639                }
31640              }
31641
31642              // Convert a string to a String ID (SID).
31643              // The list of strings is modified in place.
31644              function encodeString(s, strings) {
31645                var sid;
31646
31647                // Is the string in the CFF standard strings?
31648                var i = cffStandardStrings.indexOf(s);
31649                if (i >= 0) {
31650                  sid = i;
31651                }
31652
31653                // Is the string already in the string index?
31654                i = strings.indexOf(s);
31655                if (i >= 0) {
31656                  sid = i + cffStandardStrings.length;
31657                } else {
31658                  sid = cffStandardStrings.length + strings.length;
31659                  strings.push(s);
31660                }
31661
31662                return sid;
31663              }
31664
31665              function makeHeader() {
31666                return new table.Record('Header', [
31667                  { name: 'major', type: 'Card8', value: 1 },
31668                  { name: 'minor', type: 'Card8', value: 0 },
31669                  { name: 'hdrSize', type: 'Card8', value: 4 },
31670                  { name: 'major', type: 'Card8', value: 1 }
31671                ]);
31672              }
31673
31674              function makeNameIndex(fontNames) {
31675                var t = new table.Record('Name INDEX', [
31676                  { name: 'names', type: 'INDEX', value: [] }
31677                ]);
31678                t.names = [];
31679                for (var i = 0; i < fontNames.length; i += 1) {
31680                  t.names.push({ name: 'name_' + i, type: 'NAME', value: fontNames[i] });
31681                }
31682
31683                return t;
31684              }
31685
31686              // Given a dictionary's metadata, create a DICT structure.
31687              function makeDict(meta, attrs, strings) {
31688                var m = {};
31689                for (var i = 0; i < meta.length; i += 1) {
31690                  var entry = meta[i];
31691                  var value = attrs[entry.name];
31692                  if (value !== undefined && !equals(value, entry.value)) {
31693                    if (entry.type === 'SID') {
31694                      value = encodeString(value, strings);
31695                    }
31696
31697                    m[entry.op] = { name: entry.name, type: entry.type, value: value };
31698                  }
31699                }
31700
31701                return m;
31702              }
31703
31704              // The Top DICT houses the global font attributes.
31705              function makeTopDict(attrs, strings) {
31706                var t = new table.Record('Top DICT', [
31707                  { name: 'dict', type: 'DICT', value: {} }
31708                ]);
31709                t.dict = makeDict(TOP_DICT_META, attrs, strings);
31710                return t;
31711              }
31712
31713              function makeTopDictIndex(topDict) {
31714                var t = new table.Record('Top DICT INDEX', [
31715                  { name: 'topDicts', type: 'INDEX', value: [] }
31716                ]);
31717                t.topDicts = [{ name: 'topDict_0', type: 'TABLE', value: topDict }];
31718                return t;
31719              }
31720
31721              function makeStringIndex(strings) {
31722                var t = new table.Record('String INDEX', [
31723                  { name: 'strings', type: 'INDEX', value: [] }
31724                ]);
31725                t.strings = [];
31726                for (var i = 0; i < strings.length; i += 1) {
31727                  t.strings.push({
31728                    name: 'string_' + i,
31729                    type: 'STRING',
31730                    value: strings[i]
31731                  });
31732                }
31733
31734                return t;
31735              }
31736
31737              function makeGlobalSubrIndex() {
31738                // Currently we don't use subroutines.
31739                return new table.Record('Global Subr INDEX', [
31740                  { name: 'subrs', type: 'INDEX', value: [] }
31741                ]);
31742              }
31743
31744              function makeCharsets(glyphNames, strings) {
31745                var t = new table.Record('Charsets', [
31746                  { name: 'format', type: 'Card8', value: 0 }
31747                ]);
31748                for (var i = 0; i < glyphNames.length; i += 1) {
31749                  var glyphName = glyphNames[i];
31750                  var glyphSID = encodeString(glyphName, strings);
31751                  t.fields.push({ name: 'glyph_' + i, type: 'SID', value: glyphSID });
31752                }
31753
31754                return t;
31755              }
31756
31757              function glyphToOps(glyph) {
31758                var ops = [];
31759                var path = glyph.path;
31760                ops.push({ name: 'width', type: 'NUMBER', value: glyph.advanceWidth });
31761                var x = 0;
31762                var y = 0;
31763                for (var i = 0; i < path.commands.length; i += 1) {
31764                  var dx = void 0;
31765                  var dy = void 0;
31766                  var cmd = path.commands[i];
31767                  if (cmd.type === 'Q') {
31768                    // CFF only supports bézier curves, so convert the quad to a bézier.
31769                    var _13 = 1 / 3;
31770                    var _23 = 2 / 3;
31771
31772                    // We're going to create a new command so we don't change the original path.
31773                    cmd = {
31774                      type: 'C',
31775                      x: cmd.x,
31776                      y: cmd.y,
31777                      x1: _13 * x + _23 * cmd.x1,
31778                      y1: _13 * y + _23 * cmd.y1,
31779                      x2: _13 * cmd.x + _23 * cmd.x1,
31780                      y2: _13 * cmd.y + _23 * cmd.y1
31781                    };
31782                  }
31783
31784                  if (cmd.type === 'M') {
31785                    dx = Math.round(cmd.x - x);
31786                    dy = Math.round(cmd.y - y);
31787                    ops.push({ name: 'dx', type: 'NUMBER', value: dx });
31788                    ops.push({ name: 'dy', type: 'NUMBER', value: dy });
31789                    ops.push({ name: 'rmoveto', type: 'OP', value: 21 });
31790                    x = Math.round(cmd.x);
31791                    y = Math.round(cmd.y);
31792                  } else if (cmd.type === 'L') {
31793                    dx = Math.round(cmd.x - x);
31794                    dy = Math.round(cmd.y - y);
31795                    ops.push({ name: 'dx', type: 'NUMBER', value: dx });
31796                    ops.push({ name: 'dy', type: 'NUMBER', value: dy });
31797                    ops.push({ name: 'rlineto', type: 'OP', value: 5 });
31798                    x = Math.round(cmd.x);
31799                    y = Math.round(cmd.y);
31800                  } else if (cmd.type === 'C') {
31801                    var dx1 = Math.round(cmd.x1 - x);
31802                    var dy1 = Math.round(cmd.y1 - y);
31803                    var dx2 = Math.round(cmd.x2 - cmd.x1);
31804                    var dy2 = Math.round(cmd.y2 - cmd.y1);
31805                    dx = Math.round(cmd.x - cmd.x2);
31806                    dy = Math.round(cmd.y - cmd.y2);
31807                    ops.push({ name: 'dx1', type: 'NUMBER', value: dx1 });
31808                    ops.push({ name: 'dy1', type: 'NUMBER', value: dy1 });
31809                    ops.push({ name: 'dx2', type: 'NUMBER', value: dx2 });
31810                    ops.push({ name: 'dy2', type: 'NUMBER', value: dy2 });
31811                    ops.push({ name: 'dx', type: 'NUMBER', value: dx });
31812                    ops.push({ name: 'dy', type: 'NUMBER', value: dy });
31813                    ops.push({ name: 'rrcurveto', type: 'OP', value: 8 });
31814                    x = Math.round(cmd.x);
31815                    y = Math.round(cmd.y);
31816                  }
31817
31818                  // Contours are closed automatically.
31819                }
31820
31821                ops.push({ name: 'endchar', type: 'OP', value: 14 });
31822                return ops;
31823              }
31824
31825              function makeCharStringsIndex(glyphs) {
31826                var t = new table.Record('CharStrings INDEX', [
31827                  { name: 'charStrings', type: 'INDEX', value: [] }
31828                ]);
31829
31830                for (var i = 0; i < glyphs.length; i += 1) {
31831                  var glyph = glyphs.get(i);
31832                  var ops = glyphToOps(glyph);
31833                  t.charStrings.push({ name: glyph.name, type: 'CHARSTRING', value: ops });
31834                }
31835
31836                return t;
31837              }
31838
31839              function makePrivateDict(attrs, strings) {
31840                var t = new table.Record('Private DICT', [
31841                  { name: 'dict', type: 'DICT', value: {} }
31842                ]);
31843                t.dict = makeDict(PRIVATE_DICT_META, attrs, strings);
31844                return t;
31845              }
31846
31847              function makeCFFTable(glyphs, options) {
31848                var t = new table.Table('CFF ', [
31849                  { name: 'header', type: 'RECORD' },
31850                  { name: 'nameIndex', type: 'RECORD' },
31851                  { name: 'topDictIndex', type: 'RECORD' },
31852                  { name: 'stringIndex', type: 'RECORD' },
31853                  { name: 'globalSubrIndex', type: 'RECORD' },
31854                  { name: 'charsets', type: 'RECORD' },
31855                  { name: 'charStringsIndex', type: 'RECORD' },
31856                  { name: 'privateDict', type: 'RECORD' }
31857                ]);
31858
31859                var fontScale = 1 / options.unitsPerEm;
31860                // We use non-zero values for the offsets so that the DICT encodes them.
31861                // This is important because the size of the Top DICT plays a role in offset calculation,
31862                // and the size shouldn't change after we've written correct offsets.
31863                var attrs = {
31864                  version: options.version,
31865                  fullName: options.fullName,
31866                  familyName: options.familyName,
31867                  weight: options.weightName,
31868                  fontBBox: options.fontBBox || [0, 0, 0, 0],
31869                  fontMatrix: [fontScale, 0, 0, fontScale, 0, 0],
31870                  charset: 999,
31871                  encoding: 0,
31872                  charStrings: 999,
31873                  private: [0, 999]
31874                };
31875
31876                var privateAttrs = {};
31877
31878                var glyphNames = [];
31879                var glyph;
31880
31881                // Skip first glyph (.notdef)
31882                for (var i = 1; i < glyphs.length; i += 1) {
31883                  glyph = glyphs.get(i);
31884                  glyphNames.push(glyph.name);
31885                }
31886
31887                var strings = [];
31888
31889                t.header = makeHeader();
31890                t.nameIndex = makeNameIndex([options.postScriptName]);
31891                var topDict = makeTopDict(attrs, strings);
31892                t.topDictIndex = makeTopDictIndex(topDict);
31893                t.globalSubrIndex = makeGlobalSubrIndex();
31894                t.charsets = makeCharsets(glyphNames, strings);
31895                t.charStringsIndex = makeCharStringsIndex(glyphs);
31896                t.privateDict = makePrivateDict(privateAttrs, strings);
31897
31898                // Needs to come at the end, to encode all custom strings used in the font.
31899                t.stringIndex = makeStringIndex(strings);
31900
31901                var startOffset =
31902                  t.header.sizeOf() +
31903                  t.nameIndex.sizeOf() +
31904                  t.topDictIndex.sizeOf() +
31905                  t.stringIndex.sizeOf() +
31906                  t.globalSubrIndex.sizeOf();
31907                attrs.charset = startOffset;
31908
31909                // We use the CFF standard encoding; proper encoding will be handled in cmap.
31910                attrs.encoding = 0;
31911                attrs.charStrings = attrs.charset + t.charsets.sizeOf();
31912                attrs.private[1] = attrs.charStrings + t.charStringsIndex.sizeOf();
31913
31914                // Recreate the Top DICT INDEX with the correct offsets.
31915                topDict = makeTopDict(attrs, strings);
31916                t.topDictIndex = makeTopDictIndex(topDict);
31917
31918                return t;
31919              }
31920
31921              var cff = { parse: parseCFFTable, make: makeCFFTable };
31922
31923              // The `head` table contains global information about the font.
31924
31925              // Parse the header `head` table
31926              function parseHeadTable(data, start) {
31927                var head = {};
31928                var p = new parse.Parser(data, start);
31929                head.version = p.parseVersion();
31930                head.fontRevision = Math.round(p.parseFixed() * 1000) / 1000;
31931                head.checkSumAdjustment = p.parseULong();
31932                head.magicNumber = p.parseULong();
31933                check.argument(
31934                  head.magicNumber === 0x5f0f3cf5,
31935                  'Font header has wrong magic number.'
31936                );
31937                head.flags = p.parseUShort();
31938                head.unitsPerEm = p.parseUShort();
31939                head.created = p.parseLongDateTime();
31940                head.modified = p.parseLongDateTime();
31941                head.xMin = p.parseShort();
31942                head.yMin = p.parseShort();
31943                head.xMax = p.parseShort();
31944                head.yMax = p.parseShort();
31945                head.macStyle = p.parseUShort();
31946                head.lowestRecPPEM = p.parseUShort();
31947                head.fontDirectionHint = p.parseShort();
31948                head.indexToLocFormat = p.parseShort();
31949                head.glyphDataFormat = p.parseShort();
31950                return head;
31951              }
31952
31953              function makeHeadTable(options) {
31954                // Apple Mac timestamp epoch is 01/01/1904 not 01/01/1970
31955                var timestamp = Math.round(new Date().getTime() / 1000) + 2082844800;
31956                var createdTimestamp = timestamp;
31957
31958                if (options.createdTimestamp) {
31959                  createdTimestamp = options.createdTimestamp + 2082844800;
31960                }
31961
31962                return new table.Table(
31963                  'head',
31964                  [
31965                    { name: 'version', type: 'FIXED', value: 0x00010000 },
31966                    { name: 'fontRevision', type: 'FIXED', value: 0x00010000 },
31967                    { name: 'checkSumAdjustment', type: 'ULONG', value: 0 },
31968                    { name: 'magicNumber', type: 'ULONG', value: 0x5f0f3cf5 },
31969                    { name: 'flags', type: 'USHORT', value: 0 },
31970                    { name: 'unitsPerEm', type: 'USHORT', value: 1000 },
31971                    { name: 'created', type: 'LONGDATETIME', value: createdTimestamp },
31972                    { name: 'modified', type: 'LONGDATETIME', value: timestamp },
31973                    { name: 'xMin', type: 'SHORT', value: 0 },
31974                    { name: 'yMin', type: 'SHORT', value: 0 },
31975                    { name: 'xMax', type: 'SHORT', value: 0 },
31976                    { name: 'yMax', type: 'SHORT', value: 0 },
31977                    { name: 'macStyle', type: 'USHORT', value: 0 },
31978                    { name: 'lowestRecPPEM', type: 'USHORT', value: 0 },
31979                    { name: 'fontDirectionHint', type: 'SHORT', value: 2 },
31980                    { name: 'indexToLocFormat', type: 'SHORT', value: 0 },
31981                    { name: 'glyphDataFormat', type: 'SHORT', value: 0 }
31982                  ],
31983                  options
31984                );
31985              }
31986
31987              var head = { parse: parseHeadTable, make: makeHeadTable };
31988
31989              // The `hhea` table contains information for horizontal layout.
31990
31991              // Parse the horizontal header `hhea` table
31992              function parseHheaTable(data, start) {
31993                var hhea = {};
31994                var p = new parse.Parser(data, start);
31995                hhea.version = p.parseVersion();
31996                hhea.ascender = p.parseShort();
31997                hhea.descender = p.parseShort();
31998                hhea.lineGap = p.parseShort();
31999                hhea.advanceWidthMax = p.parseUShort();
32000                hhea.minLeftSideBearing = p.parseShort();
32001                hhea.minRightSideBearing = p.parseShort();
32002                hhea.xMaxExtent = p.parseShort();
32003                hhea.caretSlopeRise = p.parseShort();
32004                hhea.caretSlopeRun = p.parseShort();
32005                hhea.caretOffset = p.parseShort();
32006                p.relativeOffset += 8;
32007                hhea.metricDataFormat = p.parseShort();
32008                hhea.numberOfHMetrics = p.parseUShort();
32009                return hhea;
32010              }
32011
32012              function makeHheaTable(options) {
32013                return new table.Table(
32014                  'hhea',
32015                  [
32016                    { name: 'version', type: 'FIXED', value: 0x00010000 },
32017                    { name: 'ascender', type: 'FWORD', value: 0 },
32018                    { name: 'descender', type: 'FWORD', value: 0 },
32019                    { name: 'lineGap', type: 'FWORD', value: 0 },
32020                    { name: 'advanceWidthMax', type: 'UFWORD', value: 0 },
32021                    { name: 'minLeftSideBearing', type: 'FWORD', value: 0 },
32022                    { name: 'minRightSideBearing', type: 'FWORD', value: 0 },
32023                    { name: 'xMaxExtent', type: 'FWORD', value: 0 },
32024                    { name: 'caretSlopeRise', type: 'SHORT', value: 1 },
32025                    { name: 'caretSlopeRun', type: 'SHORT', value: 0 },
32026                    { name: 'caretOffset', type: 'SHORT', value: 0 },
32027                    { name: 'reserved1', type: 'SHORT', value: 0 },
32028                    { name: 'reserved2', type: 'SHORT', value: 0 },
32029                    { name: 'reserved3', type: 'SHORT', value: 0 },
32030                    { name: 'reserved4', type: 'SHORT', value: 0 },
32031                    { name: 'metricDataFormat', type: 'SHORT', value: 0 },
32032                    { name: 'numberOfHMetrics', type: 'USHORT', value: 0 }
32033                  ],
32034                  options
32035                );
32036              }
32037
32038              var hhea = { parse: parseHheaTable, make: makeHheaTable };
32039
32040              // The `hmtx` table contains the horizontal metrics for all glyphs.
32041
32042              // Parse the `hmtx` table, which contains the horizontal metrics for all glyphs.
32043              // This function augments the glyph array, adding the advanceWidth and leftSideBearing to each glyph.
32044              function parseHmtxTable(data, start, numMetrics, numGlyphs, glyphs) {
32045                var advanceWidth;
32046                var leftSideBearing;
32047                var p = new parse.Parser(data, start);
32048                for (var i = 0; i < numGlyphs; i += 1) {
32049                  // If the font is monospaced, only one entry is needed. This last entry applies to all subsequent glyphs.
32050                  if (i < numMetrics) {
32051                    advanceWidth = p.parseUShort();
32052                    leftSideBearing = p.parseShort();
32053                  }
32054
32055                  var glyph = glyphs.get(i);
32056                  glyph.advanceWidth = advanceWidth;
32057                  glyph.leftSideBearing = leftSideBearing;
32058                }
32059              }
32060
32061              function makeHmtxTable(glyphs) {
32062                var t = new table.Table('hmtx', []);
32063                for (var i = 0; i < glyphs.length; i += 1) {
32064                  var glyph = glyphs.get(i);
32065                  var advanceWidth = glyph.advanceWidth || 0;
32066                  var leftSideBearing = glyph.leftSideBearing || 0;
32067                  t.fields.push({
32068                    name: 'advanceWidth_' + i,
32069                    type: 'USHORT',
32070                    value: advanceWidth
32071                  });
32072                  t.fields.push({
32073                    name: 'leftSideBearing_' + i,
32074                    type: 'SHORT',
32075                    value: leftSideBearing
32076                  });
32077                }
32078
32079                return t;
32080              }
32081
32082              var hmtx = { parse: parseHmtxTable, make: makeHmtxTable };
32083
32084              // The `ltag` table stores IETF BCP-47 language tags. It allows supporting
32085
32086              function makeLtagTable(tags) {
32087                var result = new table.Table('ltag', [
32088                  { name: 'version', type: 'ULONG', value: 1 },
32089                  { name: 'flags', type: 'ULONG', value: 0 },
32090                  { name: 'numTags', type: 'ULONG', value: tags.length }
32091                ]);
32092
32093                var stringPool = '';
32094                var stringPoolOffset = 12 + tags.length * 4;
32095                for (var i = 0; i < tags.length; ++i) {
32096                  var pos = stringPool.indexOf(tags[i]);
32097                  if (pos < 0) {
32098                    pos = stringPool.length;
vendor: 8,463 bytes, lines 32099-32349
32099                    stringPool += tags[i];
32100                  }
32101
32102                  result.fields.push({
32103                    name: 'offset ' + i,
32104                    type: 'USHORT',
32105                    value: stringPoolOffset + pos
32106                  });
32107                  result.fields.push({
32108                    name: 'length ' + i,
32109                    type: 'USHORT',
32110                    value: tags[i].length
32111                  });
32112                }
32113
32114                result.fields.push({
32115                  name: 'stringPool',
32116                  type: 'CHARARRAY',
32117                  value: stringPool
32118                });
32119                return result;
32120              }
32121
32122              function parseLtagTable(data, start) {
32123                var p = new parse.Parser(data, start);
32124                var tableVersion = p.parseULong();
32125                check.argument(tableVersion === 1, 'Unsupported ltag table version.');
32126                // The 'ltag' specification does not define any flags; skip the field.
32127                p.skip('uLong', 1);
32128                var numTags = p.parseULong();
32129
32130                var tags = [];
32131                for (var i = 0; i < numTags; i++) {
32132                  var tag = '';
32133                  var offset = start + p.parseUShort();
32134                  var length = p.parseUShort();
32135                  for (var j = offset; j < offset + length; ++j) {
32136                    tag += String.fromCharCode(data.getInt8(j));
32137                  }
32138
32139                  tags.push(tag);
32140                }
32141
32142                return tags;
32143              }
32144
32145              var ltag = { make: makeLtagTable, parse: parseLtagTable };
32146
32147              // The `maxp` table establishes the memory requirements for the font.
32148
32149              // Parse the maximum profile `maxp` table.
32150              function parseMaxpTable(data, start) {
32151                var maxp = {};
32152                var p = new parse.Parser(data, start);
32153                maxp.version = p.parseVersion();
32154                maxp.numGlyphs = p.parseUShort();
32155                if (maxp.version === 1.0) {
32156                  maxp.maxPoints = p.parseUShort();
32157                  maxp.maxContours = p.parseUShort();
32158                  maxp.maxCompositePoints = p.parseUShort();
32159                  maxp.maxCompositeContours = p.parseUShort();
32160                  maxp.maxZones = p.parseUShort();
32161                  maxp.maxTwilightPoints = p.parseUShort();
32162                  maxp.maxStorage = p.parseUShort();
32163                  maxp.maxFunctionDefs = p.parseUShort();
32164                  maxp.maxInstructionDefs = p.parseUShort();
32165                  maxp.maxStackElements = p.parseUShort();
32166                  maxp.maxSizeOfInstructions = p.parseUShort();
32167                  maxp.maxComponentElements = p.parseUShort();
32168                  maxp.maxComponentDepth = p.parseUShort();
32169                }
32170
32171                return maxp;
32172              }
32173
32174              function makeMaxpTable(numGlyphs) {
32175                return new table.Table('maxp', [
32176                  { name: 'version', type: 'FIXED', value: 0x00005000 },
32177                  { name: 'numGlyphs', type: 'USHORT', value: numGlyphs }
32178                ]);
32179              }
32180
32181              var maxp = { parse: parseMaxpTable, make: makeMaxpTable };
32182
32183              // The `name` naming table.
32184
32185              // NameIDs for the name table.
32186              var nameTableNames = [
32187                'copyright', // 0
32188                'fontFamily', // 1
32189                'fontSubfamily', // 2
32190                'uniqueID', // 3
32191                'fullName', // 4
32192                'version', // 5
32193                'postScriptName', // 6
32194                'trademark', // 7
32195                'manufacturer', // 8
32196                'designer', // 9
32197                'description', // 10
32198                'manufacturerURL', // 11
32199                'designerURL', // 12
32200                'license', // 13
32201                'licenseURL', // 14
32202                'reserved', // 15
32203                'preferredFamily', // 16
32204                'preferredSubfamily', // 17
32205                'compatibleFullName', // 18
32206                'sampleText', // 19
32207                'postScriptFindFontName', // 20
32208                'wwsFamily', // 21
32209                'wwsSubfamily' // 22
32210              ];
32211
32212              var macLanguages = {
32213                0: 'en',
32214                1: 'fr',
32215                2: 'de',
32216                3: 'it',
32217                4: 'nl',
32218                5: 'sv',
32219                6: 'es',
32220                7: 'da',
32221                8: 'pt',
32222                9: 'no',
32223                10: 'he',
32224                11: 'ja',
32225                12: 'ar',
32226                13: 'fi',
32227                14: 'el',
32228                15: 'is',
32229                16: 'mt',
32230                17: 'tr',
32231                18: 'hr',
32232                19: 'zh-Hant',
32233                20: 'ur',
32234                21: 'hi',
32235                22: 'th',
32236                23: 'ko',
32237                24: 'lt',
32238                25: 'pl',
32239                26: 'hu',
32240                27: 'es',
32241                28: 'lv',
32242                29: 'se',
32243                30: 'fo',
32244                31: 'fa',
32245                32: 'ru',
32246                33: 'zh',
32247                34: 'nl-BE',
32248                35: 'ga',
32249                36: 'sq',
32250                37: 'ro',
32251                38: 'cz',
32252                39: 'sk',
32253                40: 'si',
32254                41: 'yi',
32255                42: 'sr',
32256                43: 'mk',
32257                44: 'bg',
32258                45: 'uk',
32259                46: 'be',
32260                47: 'uz',
32261                48: 'kk',
32262                49: 'az-Cyrl',
32263                50: 'az-Arab',
32264                51: 'hy',
32265                52: 'ka',
32266                53: 'mo',
32267                54: 'ky',
32268                55: 'tg',
32269                56: 'tk',
32270                57: 'mn-CN',
32271                58: 'mn',
32272                59: 'ps',
32273                60: 'ks',
32274                61: 'ku',
32275                62: 'sd',
32276                63: 'bo',
32277                64: 'ne',
32278                65: 'sa',
32279                66: 'mr',
32280                67: 'bn',
32281                68: 'as',
32282                69: 'gu',
32283                70: 'pa',
32284                71: 'or',
32285                72: 'ml',
32286                73: 'kn',
32287                74: 'ta',
32288                75: 'te',
32289                76: 'si',
32290                77: 'my',
32291                78: 'km',
32292                79: 'lo',
32293                80: 'vi',
32294                81: 'id',
32295                82: 'tl',
32296                83: 'ms',
32297                84: 'ms-Arab',
32298                85: 'am',
32299                86: 'ti',
32300                87: 'om',
32301                88: 'so',
32302                89: 'sw',
32303                90: 'rw',
32304                91: 'rn',
32305                92: 'ny',
32306                93: 'mg',
32307                94: 'eo',
32308                128: 'cy',
32309                129: 'eu',
32310                130: 'ca',
32311                131: 'la',
32312                132: 'qu',
32313                133: 'gn',
32314                134: 'ay',
32315                135: 'tt',
32316                136: 'ug',
32317                137: 'dz',
32318                138: 'jv',
32319                139: 'su',
32320                140: 'gl',
32321                141: 'af',
32322                142: 'br',
32323                143: 'iu',
32324                144: 'gd',
32325                145: 'gv',
32326                146: 'ga',
32327                147: 'to',
32328                148: 'el-polyton',
32329                149: 'kl',
32330                150: 'az',
32331                151: 'nn'
32332              };
32333
32334              // MacOS language ID → MacOS script ID
32335              //
32336              // Note that the script ID is not sufficient to determine what encoding
32337              // to use in TrueType files. For some languages, MacOS used a modification
32338              // of a mainstream script. For example, an Icelandic name would be stored
32339              // with smRoman in the TrueType naming table, but the actual encoding
32340              // is a special Icelandic version of the normal Macintosh Roman encoding.
32341              // As another example, Inuktitut uses an 8-bit encoding for Canadian Aboriginal
32342              // Syllables but MacOS had run out of available script codes, so this was
32343              // done as a (pretty radical) "modification" of Ethiopic.
32344              //
32345              // http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt
32346              var macLanguageToScript = {
32347                0: 0, // langEnglish → smRoman
32348                1: 0, // langFrench → smRoman
32349                2: 0, // langGerman → smRoman
32350                3: 0, // langItalian → smRoman
32351                4: 0, // langDutch → smRoman
32352                5: 0, // langSwedish → smRoman
32353                6: 0, // langSpanish → smRoman
32354                7: 0, // langDanish → smRoman
32355                8: 0, // langPortuguese → smRoman
32356                9: 0, // langNorwegian → smRoman
32357                10: 5, // langHebrew → smHebrew
32358                11: 1, // langJapanese → smJapanese
32359                12: 4, // langArabic → smArabic
32360                13: 0, // langFinnish → smRoman
32361                14: 6, // langGreek → smGreek
32362                15: 0, // langIcelandic → smRoman (modified)
32363                16: 0, // langMaltese → smRoman
32364                17: 0, // langTurkish → smRoman (modified)
32365                18: 0, // langCroatian → smRoman (modified)
32366                19: 2, // langTradChinese → smTradChinese
32367                20: 4, // langUrdu → smArabic
32368                21: 9, // langHindi → smDevanagari
32369                22: 21, // langThai → smThai
32370                23: 3, // langKorean → smKorean
32371                24: 29, // langLithuanian → smCentralEuroRoman
32372                25: 29, // langPolish → smCentralEuroRoman
32373                26: 29, // langHungarian → smCentralEuroRoman
32374                27: 29, // langEstonian → smCentralEuroRoman
32375                28: 29, // langLatvian → smCentralEuroRoman
32376                29: 0, // langSami → smRoman
32377                30: 0, // langFaroese → smRoman (modified)
32378                31: 4, // langFarsi → smArabic (modified)
32379                32: 7, // langRussian → smCyrillic
32380                33: 25, // langSimpChinese → smSimpChinese
32381                34: 0, // langFlemish → smRoman
32382                35: 0, // langIrishGaelic → smRoman (modified)
32383                36: 0, // langAlbanian → smRoman
32384                37: 0, // langRomanian → smRoman (modified)
32385                38: 29, // langCzech → smCentralEuroRoman
32386                39: 29, // langSlovak → smCentralEuroRoman
32387                40: 0, // langSlovenian → smRoman (modified)
32388                41: 5, // langYiddish → smHebrew
32389                42: 7, // langSerbian → smCyrillic
32390                43: 7, // langMacedonian → smCyrillic
32391                44: 7, // langBulgarian → smCyrillic
32392                45: 7, // langUkrainian → smCyrillic (modified)
32393                46: 7, // langByelorussian → smCyrillic
32394                47: 7, // langUzbek → smCyrillic
32395                48: 7, // langKazakh → smCyrillic
32396                49: 7, // langAzerbaijani → smCyrillic
32397                50: 4, // langAzerbaijanAr → smArabic
32398                51: 24, // langArmenian → smArmenian
32399                52: 23, // langGeorgian → smGeorgian
32400                53: 7, // langMoldavian → smCyrillic
32401                54: 7, // langKirghiz → smCyrillic
32402                55: 7, // langTajiki → smCyrillic
32403                56: 7, // langTurkmen → smCyrillic
32404                57: 27, // langMongolian → smMongolian
32405                58: 7, // langMongolianCyr → smCyrillic
32406                59: 4, // langPashto → smArabic
32407                60: 4, // langKurdish → smArabic
32408                61: 4, // langKashmiri → smArabic
32409                62: 4, // langSindhi → smArabic
32410                63: 26, // langTibetan → smTibetan
32411                64: 9, // langNepali → smDevanagari
32412                65: 9, // langSanskrit → smDevanagari
32413                66: 9, // langMarathi → smDevanagari
32414                67: 13, // langBengali → smBengali
32415                68: 13, // langAssamese → smBengali
32416                69: 11, // langGujarati → smGujarati
32417                70: 10, // langPunjabi → smGurmukhi
32418                71: 12, // langOriya → smOriya
32419                72: 17, // langMalayalam → smMalayalam
32420                73: 16, // langKannada → smKannada
32421                74: 14, // langTamil → smTamil
32422                75: 15, // langTelugu → smTelugu
32423                76: 18, // langSinhalese → smSinhalese
32424                77: 19, // langBurmese → smBurmese
32425                78: 20, // langKhmer → smKhmer
32426                79: 22, // langLao → smLao
32427                80: 30, // langVietnamese → smVietnamese
32428                81: 0, // langIndonesian → smRoman
32429                82: 0, // langTagalog → smRoman
32430                83: 0, // langMalayRoman → smRoman
32431                84: 4, // langMalayArabic → smArabic
32432                85: 28, // langAmharic → smEthiopic
32433                86: 28, // langTigrinya → smEthiopic
32434                87: 28, // langOromo → smEthiopic
32435                88: 0, // langSomali → smRoman
32436                89: 0, // langSwahili → smRoman
32437                90: 0, // langKinyarwanda → smRoman
32438                91: 0, // langRundi → smRoman
32439                92: 0, // langNyanja → smRoman
32440                93: 0, // langMalagasy → smRoman
32441                94: 0, // langEsperanto → smRoman
32442                128: 0, // langWelsh → smRoman (modified)
32443                129: 0, // langBasque → smRoman
32444                130: 0, // langCatalan → smRoman
32445                131: 0, // langLatin → smRoman
32446                132: 0, // langQuechua → smRoman
32447                133: 0, // langGuarani → smRoman
32448                134: 0, // langAymara → smRoman
32449                135: 7, // langTatar → smCyrillic
32450                136: 4, // langUighur → smArabic
32451                137: 26, // langDzongkha → smTibetan
32452                138: 0, // langJavaneseRom → smRoman
32453                139: 0, // langSundaneseRom → smRoman
32454                140: 0, // langGalician → smRoman
32455                141: 0, // langAfrikaans → smRoman
32456                142: 0, // langBreton → smRoman (modified)
32457                143: 28, // langInuktitut → smEthiopic (modified)
32458                144: 0, // langScottishGaelic → smRoman (modified)
32459                145: 0, // langManxGaelic → smRoman (modified)
32460                146: 0, // langIrishGaelicScript → smRoman (modified)
32461                147: 0, // langTongan → smRoman
32462                148: 6, // langGreekAncient → smRoman
32463                149: 0, // langGreenlandic → smRoman
32464                150: 0, // langAzerbaijanRoman → smRoman
32465                151: 0 // langNynorsk → smRoman
32466              };
32467
32468              // While Microsoft indicates a region/country for all its language
32469              // IDs, we omit the region code if it's equal to the "most likely
32470              // region subtag" according to Unicode CLDR. For scripts, we omit
32471              // the subtag if it is equal to the Suppress-Script entry in the
32472              // IANA language subtag registry for IETF BCP 47.
32473              //
32474              // For example, Microsoft states that its language code 0x041A is
32475              // Croatian in Croatia. We transform this to the BCP 47 language code 'hr'
32476              // and not 'hr-HR' because Croatia is the default country for Croatian,
32477              // according to Unicode CLDR. As another example, Microsoft states
32478              // that 0x101A is Croatian (Latin) in Bosnia-Herzegovina. We transform
32479              // this to 'hr-BA' and not 'hr-Latn-BA' because Latin is the default script
32480              // for the Croatian language, according to IANA.
32481              //
32482              // http://www.unicode.org/cldr/charts/latest/supplemental/likely_subtags.html
32483              // http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
32484              var windowsLanguages = {
32485                0x0436: 'af',
32486                0x041c: 'sq',
32487                0x0484: 'gsw',
32488                0x045e: 'am',
32489                0x1401: 'ar-DZ',
32490                0x3c01: 'ar-BH',
32491                0x0c01: 'ar',
32492                0x0801: 'ar-IQ',
32493                0x2c01: 'ar-JO',
32494                0x3401: 'ar-KW',
32495                0x3001: 'ar-LB',
32496                0x1001: 'ar-LY',
32497                0x1801: 'ary',
32498                0x2001: 'ar-OM',
32499                0x4001: 'ar-QA',
32500                0x0401: 'ar-SA',
32501                0x2801: 'ar-SY',
32502                0x1c01: 'aeb',
32503                0x3801: 'ar-AE',
32504                0x2401: 'ar-YE',
32505                0x042b: 'hy',
32506                0x044d: 'as',
32507                0x082c: 'az-Cyrl',
32508                0x042c: 'az',
32509                0x046d: 'ba',
32510                0x042d: 'eu',
32511                0x0423: 'be',
32512                0x0845: 'bn',
32513                0x0445: 'bn-IN',
32514                0x201a: 'bs-Cyrl',
32515                0x141a: 'bs',
32516                0x047e: 'br',
32517                0x0402: 'bg',
32518                0x0403: 'ca',
32519                0x0c04: 'zh-HK',
32520                0x1404: 'zh-MO',
32521                0x0804: 'zh',
32522                0x1004: 'zh-SG',
32523                0x0404: 'zh-TW',
32524                0x0483: 'co',
32525                0x041a: 'hr',
32526                0x101a: 'hr-BA',
32527                0x0405: 'cs',
32528                0x0406: 'da',
32529                0x048c: 'prs',
32530                0x0465: 'dv',
32531                0x0813: 'nl-BE',
32532                0x0413: 'nl',
32533                0x0c09: 'en-AU',
32534                0x2809: 'en-BZ',
32535                0x1009: 'en-CA',
32536                0x2409: 'en-029',
32537                0x4009: 'en-IN',
32538                0x1809: 'en-IE',
32539                0x2009: 'en-JM',
32540                0x4409: 'en-MY',
32541                0x1409: 'en-NZ',
32542                0x3409: 'en-PH',
32543                0x4809: 'en-SG',
32544                0x1c09: 'en-ZA',
32545                0x2c09: 'en-TT',
32546                0x0809: 'en-GB',
32547                0x0409: 'en',
32548                0x3009: 'en-ZW',
32549                0x0425: 'et',
32550                0x0438: 'fo',
32551                0x0464: 'fil',
32552                0x040b: 'fi',
32553                0x080c: 'fr-BE',
32554                0x0c0c: 'fr-CA',
32555                0x040c: 'fr',
32556                0x140c: 'fr-LU',
32557                0x180c: 'fr-MC',
32558                0x100c: 'fr-CH',
32559                0x0462: 'fy',
32560                0x0456: 'gl',
32561                0x0437: 'ka',
32562                0x0c07: 'de-AT',
32563                0x0407: 'de',
32564                0x1407: 'de-LI',
32565                0x1007: 'de-LU',
32566                0x0807: 'de-CH',
32567                0x0408: 'el',
32568                0x046f: 'kl',
32569                0x0447: 'gu',
32570                0x0468: 'ha',
32571                0x040d: 'he',
32572                0x0439: 'hi',
32573                0x040e: 'hu',
32574                0x040f: 'is',
32575                0x0470: 'ig',
32576                0x0421: 'id',
32577                0x045d: 'iu',
32578                0x085d: 'iu-Latn',
32579                0x083c: 'ga',
32580                0x0434: 'xh',
32581                0x0435: 'zu',
32582                0x0410: 'it',
32583                0x0810: 'it-CH',
32584                0x0411: 'ja',
32585                0x044b: 'kn',
32586                0x043f: 'kk',
32587                0x0453: 'km',
32588                0x0486: 'quc',
32589                0x0487: 'rw',
32590                0x0441: 'sw',
32591                0x0457: 'kok',
32592                0x0412: 'ko',
32593                0x0440: 'ky',
32594                0x0454: 'lo',
32595                0x0426: 'lv',
32596                0x0427: 'lt',
32597                0x082e: 'dsb',
32598                0x046e: 'lb',
32599                0x042f: 'mk',
32600                0x083e: 'ms-BN',
32601                0x043e: 'ms',
32602                0x044c: 'ml',
32603                0x043a: 'mt',
32604                0x0481: 'mi',
32605                0x047a: 'arn',
32606                0x044e: 'mr',
32607                0x047c: 'moh',
32608                0x0450: 'mn',
32609                0x0850: 'mn-CN',
32610                0x0461: 'ne',
32611                0x0414: 'nb',
32612                0x0814: 'nn',
32613                0x0482: 'oc',
32614                0x0448: 'or',
32615                0x0463: 'ps',
32616                0x0415: 'pl',
32617                0x0416: 'pt',
32618                0x0816: 'pt-PT',
32619                0x0446: 'pa',
32620                0x046b: 'qu-BO',
32621                0x086b: 'qu-EC',
32622                0x0c6b: 'qu',
32623                0x0418: 'ro',
32624                0x0417: 'rm',
32625                0x0419: 'ru',
32626                0x243b: 'smn',
32627                0x103b: 'smj-NO',
32628                0x143b: 'smj',
32629                0x0c3b: 'se-FI',
32630                0x043b: 'se',
32631                0x083b: 'se-SE',
32632                0x203b: 'sms',
32633                0x183b: 'sma-NO',
32634                0x1c3b: 'sms',
32635                0x044f: 'sa',
32636                0x1c1a: 'sr-Cyrl-BA',
32637                0x0c1a: 'sr',
32638                0x181a: 'sr-Latn-BA',
32639                0x081a: 'sr-Latn',
32640                0x046c: 'nso',
32641                0x0432: 'tn',
32642                0x045b: 'si',
32643                0x041b: 'sk',
32644                0x0424: 'sl',
32645                0x2c0a: 'es-AR',
32646                0x400a: 'es-BO',
32647                0x340a: 'es-CL',
32648                0x240a: 'es-CO',
32649                0x140a: 'es-CR',
32650                0x1c0a: 'es-DO',
32651                0x300a: 'es-EC',
32652                0x440a: 'es-SV',
32653                0x100a: 'es-GT',
32654                0x480a: 'es-HN',
32655                0x080a: 'es-MX',
32656                0x4c0a: 'es-NI',
32657                0x180a: 'es-PA',
32658                0x3c0a: 'es-PY',
32659                0x280a: 'es-PE',
32660                0x500a: 'es-PR',
32661
32662                // Microsoft has defined two different language codes for
32663                // “Spanish with modern sorting” and “Spanish with traditional
32664                // sorting”. This makes sense for collation APIs, and it would be
32665                // possible to express this in BCP 47 language tags via Unicode
32666                // extensions (eg., es-u-co-trad is Spanish with traditional
32667                // sorting). However, for storing names in fonts, the distinction
32668                // does not make sense, so we give “es” in both cases.
32669                0x0c0a: 'es',
32670                0x040a: 'es',
32671
32672                0x540a: 'es-US',
32673                0x380a: 'es-UY',
32674                0x200a: 'es-VE',
32675                0x081d: 'sv-FI',
32676                0x041d: 'sv',
32677                0x045a: 'syr',
32678                0x0428: 'tg',
32679                0x085f: 'tzm',
32680                0x0449: 'ta',
32681                0x0444: 'tt',
32682                0x044a: 'te',
32683                0x041e: 'th',
32684                0x0451: 'bo',
32685                0x041f: 'tr',
32686                0x0442: 'tk',
32687                0x0480: 'ug',
32688                0x0422: 'uk',
32689                0x042e: 'hsb',
32690                0x0420: 'ur',
32691                0x0843: 'uz-Cyrl',
32692                0x0443: 'uz',
32693                0x042a: 'vi',
32694                0x0452: 'cy',
32695                0x0488: 'wo',
32696                0x0485: 'sah',
32697                0x0478: 'ii',
32698                0x046a: 'yo'
32699              };
32700
32701              // Returns a IETF BCP 47 language code, for example 'zh-Hant'
32702              // for 'Chinese in the traditional script'.
32703              function getLanguageCode(platformID, languageID, ltag) {
32704                switch (platformID) {
32705                  case 0: // Unicode
32706                    if (languageID === 0xffff) {
32707                      return 'und';
32708                    } else if (ltag) {
32709                      return ltag[languageID];
32710                    }
32711
32712                    break;
32713
32714                  case 1: // Macintosh
32715                    return macLanguages[languageID];
32716
32717                  case 3: // Windows
32718                    return windowsLanguages[languageID];
32719                }
32720
32721                return undefined;
32722              }
32723
32724              var utf16 = 'utf-16';
32725
32726              // MacOS script ID → encoding. This table stores the default case,
32727              // which can be overridden by macLanguageEncodings.
32728              var macScriptEncodings = {
32729                0: 'macintosh', // smRoman
32730                1: 'x-mac-japanese', // smJapanese
32731                2: 'x-mac-chinesetrad', // smTradChinese
32732                3: 'x-mac-korean', // smKorean
32733                6: 'x-mac-greek', // smGreek
32734                7: 'x-mac-cyrillic', // smCyrillic
32735                9: 'x-mac-devanagai', // smDevanagari
32736                10: 'x-mac-gurmukhi', // smGurmukhi
32737                11: 'x-mac-gujarati', // smGujarati
32738                12: 'x-mac-oriya', // smOriya
32739                13: 'x-mac-bengali', // smBengali
32740                14: 'x-mac-tamil', // smTamil
32741                15: 'x-mac-telugu', // smTelugu
32742                16: 'x-mac-kannada', // smKannada
32743                17: 'x-mac-malayalam', // smMalayalam
32744                18: 'x-mac-sinhalese', // smSinhalese
32745                19: 'x-mac-burmese', // smBurmese
32746                20: 'x-mac-khmer', // smKhmer
32747                21: 'x-mac-thai', // smThai
32748                22: 'x-mac-lao', // smLao
32749                23: 'x-mac-georgian', // smGeorgian
32750                24: 'x-mac-armenian', // smArmenian
32751                25: 'x-mac-chinesesimp', // smSimpChinese
32752                26: 'x-mac-tibetan', // smTibetan
32753                27: 'x-mac-mongolian', // smMongolian
32754                28: 'x-mac-ethiopic', // smEthiopic
32755                29: 'x-mac-ce', // smCentralEuroRoman
32756                30: 'x-mac-vietnamese', // smVietnamese
32757                31: 'x-mac-extarabic' // smExtArabic
32758              };
32759
32760              // MacOS language ID → encoding. This table stores the exceptional
32761              // cases, which override macScriptEncodings. For writing MacOS naming
32762              // tables, we need to emit a MacOS script ID. Therefore, we cannot
32763              // merge macScriptEncodings into macLanguageEncodings.
32764              //
32765              // http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt
32766              var macLanguageEncodings = {
32767                15: 'x-mac-icelandic', // langIcelandic
32768                17: 'x-mac-turkish', // langTurkish
32769                18: 'x-mac-croatian', // langCroatian
32770                24: 'x-mac-ce', // langLithuanian
32771                25: 'x-mac-ce', // langPolish
32772                26: 'x-mac-ce', // langHungarian
32773                27: 'x-mac-ce', // langEstonian
32774                28: 'x-mac-ce', // langLatvian
32775                30: 'x-mac-icelandic', // langFaroese
32776                37: 'x-mac-romanian', // langRomanian
32777                38: 'x-mac-ce', // langCzech
32778                39: 'x-mac-ce', // langSlovak
32779                40: 'x-mac-ce', // langSlovenian
32780                143: 'x-mac-inuit', // langInuktitut
32781                146: 'x-mac-gaelic' // langIrishGaelicScript
32782              };
32783
32784              function getEncoding(platformID, encodingID, languageID) {
32785                switch (platformID) {
32786                  case 0: // Unicode
32787                    return utf16;
32788
32789                  case 1: // Apple Macintosh
32790                    return (
32791                      macLanguageEncodings[languageID] || macScriptEncodings[encodingID]
32792                    );
32793
32794                  case 3: // Microsoft Windows
32795                    if (encodingID === 1 || encodingID === 10) {
32796                      return utf16;
32797                    }
32798
32799                    break;
32800                }
32801
32802                return undefined;
32803              }
32804
32805              // Parse the naming `name` table.
32806              // FIXME: Format 1 additional fields are not supported yet.
32807              // ltag is the content of the `ltag' table, such as ['en', 'zh-Hans', 'de-CH-1904'].
32808              function parseNameTable(data, start, ltag) {
32809                var name = {};
32810                var p = new parse.Parser(data, start);
32811                var format = p.parseUShort();
32812                var count = p.parseUShort();
32813                var stringOffset = p.offset + p.parseUShort();
32814                for (var i = 0; i < count; i++) {
32815                  var platformID = p.parseUShort();
32816                  var encodingID = p.parseUShort();
32817                  var languageID = p.parseUShort();
32818                  var nameID = p.parseUShort();
32819                  var property = nameTableNames[nameID] || nameID;
32820                  var byteLength = p.parseUShort();
32821                  var offset = p.parseUShort();
32822                  var language = getLanguageCode(platformID, languageID, ltag);
32823                  var encoding = getEncoding(platformID, encodingID, languageID);
32824                  if (encoding !== undefined && language !== undefined) {
32825                    var text = void 0;
32826                    if (encoding === utf16) {
32827                      text = decode.UTF16(data, stringOffset + offset, byteLength);
32828                    } else {
32829                      text = decode.MACSTRING(
32830                        data,
32831                        stringOffset + offset,
32832                        byteLength,
32833                        encoding
32834                      );
32835                    }
32836
32837                    if (text) {
32838                      var translations = name[property];
32839                      if (translations === undefined) {
32840                        translations = name[property] = {};
32841                      }
32842
32843                      translations[language] = text;
32844                    }
32845                  }
32846                }
32847
32848                var langTagCount = 0;
32849                if (format === 1) {
32850                  // FIXME: Also handle Microsoft's 'name' table 1.
32851                  langTagCount = p.parseUShort();
32852                }
32853
32854                return name;
32855              }
32856
32857              // {23: 'foo'} → {'foo': 23}
32858              // ['bar', 'baz'] → {'bar': 0, 'baz': 1}
32859              function reverseDict(dict) {
32860                var result = {};
32861                for (var key in dict) {
32862                  result[dict[key]] = parseInt(key);
32863                }
32864
32865                return result;
32866              }
32867
32868              function makeNameRecord(
32869                platformID,
32870                encodingID,
32871                languageID,
32872                nameID,
32873                length,
32874                offset
32875              ) {
32876                return new table.Record('NameRecord', [
32877                  { name: 'platformID', type: 'USHORT', value: platformID },
32878                  { name: 'encodingID', type: 'USHORT', value: encodingID },
32879                  { name: 'languageID', type: 'USHORT', value: languageID },
32880                  { name: 'nameID', type: 'USHORT', value: nameID },
32881                  { name: 'length', type: 'USHORT', value: length },
32882                  { name: 'offset', type: 'USHORT', value: offset }
32883                ]);
32884              }
32885
32886              // Finds the position of needle in haystack, or -1 if not there.
32887              // Like String.indexOf(), but for arrays.
32888              function findSubArray(needle, haystack) {
32889                var needleLength = needle.length;
32890                var limit = haystack.length - needleLength + 1;
32891
32892                loop: for (var pos = 0; pos < limit; pos++) {
32893                  for (; pos < limit; pos++) {
32894                    for (var k = 0; k < needleLength; k++) {
32895                      if (haystack[pos + k] !== needle[k]) {
32896                        continue loop;
32897                      }
32898                    }
32899
32900                    return pos;
32901                  }
32902                }
32903
32904                return -1;
32905              }
32906
32907              function addStringToPool(s, pool) {
32908                var offset = findSubArray(s, pool);
32909                if (offset < 0) {
32910                  offset = pool.length;
32911                  var i = 0;
32912                  var len = s.length;
32913                  for (; i < len; ++i) {
32914                    pool.push(s[i]);
32915                  }
32916                }
32917
32918                return offset;
32919              }
32920
32921              function makeNameTable(names, ltag) {
32922                var nameID;
32923                var nameIDs = [];
32924
32925                var namesWithNumericKeys = {};
32926                var nameTableIds = reverseDict(nameTableNames);
32927                for (var key in names) {
32928                  var id = nameTableIds[key];
32929                  if (id === undefined) {
32930                    id = key;
32931                  }
32932
32933                  nameID = parseInt(id);
32934
32935                  if (isNaN(nameID)) {
32936                    throw new Error(
32937                      'Name table entry "' +
32938                        key +
32939                        '" does not exist, see nameTableNames for complete list.'
32940                    );
32941                  }
32942
32943                  namesWithNumericKeys[nameID] = names[key];
32944                  nameIDs.push(nameID);
32945                }
32946
32947                var macLanguageIds = reverseDict(macLanguages);
32948                var windowsLanguageIds = reverseDict(windowsLanguages);
32949
32950                var nameRecords = [];
32951                var stringPool = [];
32952
32953                for (var i = 0; i < nameIDs.length; i++) {
32954                  nameID = nameIDs[i];
32955                  var translations = namesWithNumericKeys[nameID];
32956                  for (var lang in translations) {
32957                    var text = translations[lang];
32958
32959                    // For MacOS, we try to emit the name in the form that was introduced
32960                    // in the initial version of the TrueType spec (in the late 1980s).
32961                    // However, this can fail for various reasons: the requested BCP 47
32962                    // language code might not have an old-style Mac equivalent;
32963                    // we might not have a codec for the needed character encoding;
32964                    // or the name might contain characters that cannot be expressed
32965                    // in the old-style Macintosh encoding. In case of failure, we emit
32966                    // the name in a more modern fashion (Unicode encoding with BCP 47
32967                    // language tags) that is recognized by MacOS 10.5, released in 2009.
32968                    // If fonts were only read by operating systems, we could simply
32969                    // emit all names in the modern form; this would be much easier.
32970                    // However, there are many applications and libraries that read
32971                    // 'name' tables directly, and these will usually only recognize
32972                    // the ancient form (silently skipping the unrecognized names).
32973                    var macPlatform = 1; // Macintosh
32974                    var macLanguage = macLanguageIds[lang];
32975                    var macScript = macLanguageToScript[macLanguage];
32976                    var macEncoding = getEncoding(macPlatform, macScript, macLanguage);
32977                    var macName = encode.MACSTRING(text, macEncoding);
32978                    if (macName === undefined) {
32979                      macPlatform = 0; // Unicode
32980                      macLanguage = ltag.indexOf(lang);
32981                      if (macLanguage < 0) {
32982                        macLanguage = ltag.length;
32983                        ltag.push(lang);
32984                      }
32985
32986                      macScript = 4; // Unicode 2.0 and later
32987                      macName = encode.UTF16(text);
32988                    }
32989
32990                    var macNameOffset = addStringToPool(macName, stringPool);
32991                    nameRecords.push(
32992                      makeNameRecord(
32993                        macPlatform,
32994                        macScript,
32995                        macLanguage,
32996                        nameID,
32997                        macName.length,
32998                        macNameOffset
32999                      )
33000                    );
33001
33002                    var winLanguage = windowsLanguageIds[lang];
33003                    if (winLanguage !== undefined) {
33004                      var winName = encode.UTF16(text);
33005                      var winNameOffset = addStringToPool(winName, stringPool);
33006                      nameRecords.push(
33007                        makeNameRecord(
33008                          3,
33009                          1,
33010                          winLanguage,
33011                          nameID,
33012                          winName.length,
33013                          winNameOffset
33014                        )
33015                      );
33016                    }
33017                  }
33018                }
33019
33020                nameRecords.sort(function(a, b) {
33021                  return (
33022                    a.platformID - b.platformID ||
33023                    a.encodingID - b.encodingID ||
33024                    a.languageID - b.languageID ||
33025                    a.nameID - b.nameID
33026                  );
33027                });
33028
33029                var t = new table.Table('name', [
33030                  { name: 'format', type: 'USHORT', value: 0 },
33031                  { name: 'count', type: 'USHORT', value: nameRecords.length },
33032                  {
33033                    name: 'stringOffset',
33034                    type: 'USHORT',
33035                    value: 6 + nameRecords.length * 12
33036                  }
33037                ]);
33038
33039                for (var r = 0; r < nameRecords.length; r++) {
33040                  t.fields.push({
33041                    name: 'record_' + r,
33042                    type: 'RECORD',
33043                    value: nameRecords[r]
33044                  });
33045                }
33046
33047                t.fields.push({ name: 'strings', type: 'LITERAL', value: stringPool });
33048                return t;
33049              }
33050
33051              var _name = { parse: parseNameTable, make: makeNameTable };
33052
33053              // The `OS/2` table contains metrics required in OpenType fonts.
33054
33055              var unicodeRanges = [
33056                { begin: 0x0000, end: 0x007f }, // Basic Latin
33057                { begin: 0x0080, end: 0x00ff }, // Latin-1 Supplement
33058                { begin: 0x0100, end: 0x017f }, // Latin Extended-A
33059                { begin: 0x0180, end: 0x024f }, // Latin Extended-B
33060                { begin: 0x0250, end: 0x02af }, // IPA Extensions
33061                { begin: 0x02b0, end: 0x02ff }, // Spacing Modifier Letters
33062                { begin: 0x0300, end: 0x036f }, // Combining Diacritical Marks
33063                { begin: 0x0370, end: 0x03ff }, // Greek and Coptic
33064                { begin: 0x2c80, end: 0x2cff }, // Coptic
33065                { begin: 0x0400, end: 0x04ff }, // Cyrillic
33066                { begin: 0x0530, end: 0x058f }, // Armenian
33067                { begin: 0x0590, end: 0x05ff }, // Hebrew
33068                { begin: 0xa500, end: 0xa63f }, // Vai
33069                { begin: 0x0600, end: 0x06ff }, // Arabic
33070                { begin: 0x07c0, end: 0x07ff }, // NKo
33071                { begin: 0x0900, end: 0x097f }, // Devanagari
33072                { begin: 0x0980, end: 0x09ff }, // Bengali
33073                { begin: 0x0a00, end: 0x0a7f }, // Gurmukhi
33074                { begin: 0x0a80, end: 0x0aff }, // Gujarati
33075                { begin: 0x0b00, end: 0x0b7f }, // Oriya
33076                { begin: 0x0b80, end: 0x0bff }, // Tamil
33077                { begin: 0x0c00, end: 0x0c7f }, // Telugu
33078                { begin: 0x0c80, end: 0x0cff }, // Kannada
33079                { begin: 0x0d00, end: 0x0d7f }, // Malayalam
33080                { begin: 0x0e00, end: 0x0e7f }, // Thai
33081                { begin: 0x0e80, end: 0x0eff }, // Lao
33082                { begin: 0x10a0, end: 0x10ff }, // Georgian
33083                { begin: 0x1b00, end: 0x1b7f }, // Balinese
33084                { begin: 0x1100, end: 0x11ff }, // Hangul Jamo
33085                { begin: 0x1e00, end: 0x1eff }, // Latin Extended Additional
33086                { begin: 0x1f00, end: 0x1fff }, // Greek Extended
33087                { begin: 0x2000, end: 0x206f }, // General Punctuation
33088                { begin: 0x2070, end: 0x209f }, // Superscripts And Subscripts
33089                { begin: 0x20a0, end: 0x20cf }, // Currency Symbol
33090                { begin: 0x20d0, end: 0x20ff }, // Combining Diacritical Marks For Symbols
33091                { begin: 0x2100, end: 0x214f }, // Letterlike Symbols
33092                { begin: 0x2150, end: 0x218f }, // Number Forms
33093                { begin: 0x2190, end: 0x21ff }, // Arrows
33094                { begin: 0x2200, end: 0x22ff }, // Mathematical Operators
33095                { begin: 0x2300, end: 0x23ff }, // Miscellaneous Technical
33096                { begin: 0x2400, end: 0x243f }, // Control Pictures
33097                { begin: 0x2440, end: 0x245f }, // Optical Character Recognition
33098                { begin: 0x2460, end: 0x24ff }, // Enclosed Alphanumerics
33099                { begin: 0x2500, end: 0x257f }, // Box Drawing
33100                { begin: 0x2580, end: 0x259f }, // Block Elements
33101                { begin: 0x25a0, end: 0x25ff }, // Geometric Shapes
33102                { begin: 0x2600, end: 0x26ff }, // Miscellaneous Symbols
33103                { begin: 0x2700, end: 0x27bf }, // Dingbats
33104                { begin: 0x3000, end: 0x303f }, // CJK Symbols And Punctuation
33105                { begin: 0x3040, end: 0x309f }, // Hiragana
33106                { begin: 0x30a0, end: 0x30ff }, // Katakana
33107                { begin: 0x3100, end: 0x312f }, // Bopomofo
33108                { begin: 0x3130, end: 0x318f }, // Hangul Compatibility Jamo
33109                { begin: 0xa840, end: 0xa87f }, // Phags-pa
33110                { begin: 0x3200, end: 0x32ff }, // Enclosed CJK Letters And Months
33111                { begin: 0x3300, end: 0x33ff }, // CJK Compatibility
33112                { begin: 0xac00, end: 0xd7af }, // Hangul Syllables
33113                { begin: 0xd800, end: 0xdfff }, // Non-Plane 0 *
33114                { begin: 0x10900, end: 0x1091f }, // Phoenicia
33115                { begin: 0x4e00, end: 0x9fff }, // CJK Unified Ideographs
33116                { begin: 0xe000, end: 0xf8ff }, // Private Use Area (plane 0)
33117                { begin: 0x31c0, end: 0x31ef }, // CJK Strokes
33118                { begin: 0xfb00, end: 0xfb4f }, // Alphabetic Presentation Forms
33119                { begin: 0xfb50, end: 0xfdff }, // Arabic Presentation Forms-A
33120                { begin: 0xfe20, end: 0xfe2f }, // Combining Half Marks
33121                { begin: 0xfe10, end: 0xfe1f }, // Vertical Forms
33122                { begin: 0xfe50, end: 0xfe6f }, // Small Form Variants
33123                { begin: 0xfe70, end: 0xfeff }, // Arabic Presentation Forms-B
33124                { begin: 0xff00, end: 0xffef }, // Halfwidth And Fullwidth Forms
33125                { begin: 0xfff0, end: 0xffff }, // Specials
33126                { begin: 0x0f00, end: 0x0fff }, // Tibetan
33127                { begin: 0x0700, end: 0x074f }, // Syriac
33128                { begin: 0x0780, end: 0x07bf }, // Thaana
33129                { begin: 0x0d80, end: 0x0dff }, // Sinhala
33130                { begin: 0x1000, end: 0x109f }, // Myanmar
33131                { begin: 0x1200, end: 0x137f }, // Ethiopic
33132                { begin: 0x13a0, end: 0x13ff }, // Cherokee
33133                { begin: 0x1400, end: 0x167f }, // Unified Canadian Aboriginal Syllabics
33134                { begin: 0x1680, end: 0x169f }, // Ogham
33135                { begin: 0x16a0, end: 0x16ff }, // Runic
33136                { begin: 0x1780, end: 0x17ff }, // Khmer
33137                { begin: 0x1800, end: 0x18af }, // Mongolian
33138                { begin: 0x2800, end: 0x28ff }, // Braille Patterns
33139                { begin: 0xa000, end: 0xa48f }, // Yi Syllables
33140                { begin: 0x1700, end: 0x171f }, // Tagalog
33141                { begin: 0x10300, end: 0x1032f }, // Old Italic
33142                { begin: 0x10330, end: 0x1034f }, // Gothic
33143                { begin: 0x10400, end: 0x1044f }, // Deseret
33144                { begin: 0x1d000, end: 0x1d0ff }, // Byzantine Musical Symbols
33145                { begin: 0x1d400, end: 0x1d7ff }, // Mathematical Alphanumeric Symbols
33146                { begin: 0xff000, end: 0xffffd }, // Private Use (plane 15)
33147                { begin: 0xfe00, end: 0xfe0f }, // Variation Selectors
33148                { begin: 0xe0000, end: 0xe007f }, // Tags
33149                { begin: 0x1900, end: 0x194f }, // Limbu
33150                { begin: 0x1950, end: 0x197f }, // Tai Le
33151                { begin: 0x1980, end: 0x19df }, // New Tai Lue
33152                { begin: 0x1a00, end: 0x1a1f }, // Buginese
33153                { begin: 0x2c00, end: 0x2c5f }, // Glagolitic
33154                { begin: 0x2d30, end: 0x2d7f }, // Tifinagh
33155                { begin: 0x4dc0, end: 0x4dff }, // Yijing Hexagram Symbols
33156                { begin: 0xa800, end: 0xa82f }, // Syloti Nagri
33157                { begin: 0x10000, end: 0x1007f }, // Linear B Syllabary
33158                { begin: 0x10140, end: 0x1018f }, // Ancient Greek Numbers
33159                { begin: 0x10380, end: 0x1039f }, // Ugaritic
33160                { begin: 0x103a0, end: 0x103df }, // Old Persian
33161                { begin: 0x10450, end: 0x1047f }, // Shavian
33162                { begin: 0x10480, end: 0x104af }, // Osmanya
33163                { begin: 0x10800, end: 0x1083f }, // Cypriot Syllabary
33164                { begin: 0x10a00, end: 0x10a5f }, // Kharoshthi
33165                { begin: 0x1d300, end: 0x1d35f }, // Tai Xuan Jing Symbols
33166                { begin: 0x12000, end: 0x123ff }, // Cuneiform
33167                { begin: 0x1d360, end: 0x1d37f }, // Counting Rod Numerals
33168                { begin: 0x1b80, end: 0x1bbf }, // Sundanese
33169                { begin: 0x1c00, end: 0x1c4f }, // Lepcha
33170                { begin: 0x1c50, end: 0x1c7f }, // Ol Chiki
33171                { begin: 0xa880, end: 0xa8df }, // Saurashtra
33172                { begin: 0xa900, end: 0xa92f }, // Kayah Li
33173                { begin: 0xa930, end: 0xa95f }, // Rejang
33174                { begin: 0xaa00, end: 0xaa5f }, // Cham
33175                { begin: 0x10190, end: 0x101cf }, // Ancient Symbols
33176                { begin: 0x101d0, end: 0x101ff }, // Phaistos Disc
33177                { begin: 0x102a0, end: 0x102df }, // Carian
33178                { begin: 0x1f030, end: 0x1f09f } // Domino Tiles
33179              ];
33180
33181              function getUnicodeRange(unicode) {
33182                for (var i = 0; i < unicodeRanges.length; i += 1) {
33183                  var range = unicodeRanges[i];
33184                  if (unicode >= range.begin && unicode < range.end) {
33185                    return i;
33186                  }
33187                }
33188
33189                return -1;
33190              }
33191
33192              // Parse the OS/2 and Windows metrics `OS/2` table
33193              function parseOS2Table(data, start) {
33194                var os2 = {};
33195                var p = new parse.Parser(data, start);
33196                os2.version = p.parseUShort();
33197                os2.xAvgCharWidth = p.parseShort();
33198                os2.usWeightClass = p.parseUShort();
33199                os2.usWidthClass = p.parseUShort();
33200                os2.fsType = p.parseUShort();
33201                os2.ySubscriptXSize = p.parseShort();
33202                os2.ySubscriptYSize = p.parseShort();
33203                os2.ySubscriptXOffset = p.parseShort();
33204                os2.ySubscriptYOffset = p.parseShort();
33205                os2.ySuperscriptXSize = p.parseShort();
33206                os2.ySuperscriptYSize = p.parseShort();
33207                os2.ySuperscriptXOffset = p.parseShort();
33208                os2.ySuperscriptYOffset = p.parseShort();
33209                os2.yStrikeoutSize = p.parseShort();
33210                os2.yStrikeoutPosition = p.parseShort();
33211                os2.sFamilyClass = p.parseShort();
33212                os2.panose = [];
33213                for (var i = 0; i < 10; i++) {
33214                  os2.panose[i] = p.parseByte();
33215                }
33216
33217                os2.ulUnicodeRange1 = p.parseULong();
33218                os2.ulUnicodeRange2 = p.parseULong();
33219                os2.ulUnicodeRange3 = p.parseULong();
33220                os2.ulUnicodeRange4 = p.parseULong();
33221                os2.achVendID = String.fromCharCode(
33222                  p.parseByte(),
33223                  p.parseByte(),
33224                  p.parseByte(),
33225                  p.parseByte()
33226                );
33227                os2.fsSelection = p.parseUShort();
33228                os2.usFirstCharIndex = p.parseUShort();
33229                os2.usLastCharIndex = p.parseUShort();
33230                os2.sTypoAscender = p.parseShort();
33231                os2.sTypoDescender = p.parseShort();
33232                os2.sTypoLineGap = p.parseShort();
33233                os2.usWinAscent = p.parseUShort();
33234                os2.usWinDescent = p.parseUShort();
33235                if (os2.version >= 1) {
33236                  os2.ulCodePageRange1 = p.parseULong();
33237                  os2.ulCodePageRange2 = p.parseULong();
33238                }
33239
33240                if (os2.version >= 2) {
33241                  os2.sxHeight = p.parseShort();
33242                  os2.sCapHeight = p.parseShort();
33243                  os2.usDefaultChar = p.parseUShort();
33244                  os2.usBreakChar = p.parseUShort();
33245                  os2.usMaxContent = p.parseUShort();
33246                }
33247
33248                return os2;
33249              }
33250
33251              function makeOS2Table(options) {
33252                return new table.Table(
33253                  'OS/2',
33254                  [
33255                    { name: 'version', type: 'USHORT', value: 0x0003 },
33256                    { name: 'xAvgCharWidth', type: 'SHORT', value: 0 },
33257                    { name: 'usWeightClass', type: 'USHORT', value: 0 },
33258                    { name: 'usWidthClass', type: 'USHORT', value: 0 },
33259                    { name: 'fsType', type: 'USHORT', value: 0 },
33260                    { name: 'ySubscriptXSize', type: 'SHORT', value: 650 },
33261                    { name: 'ySubscriptYSize', type: 'SHORT', value: 699 },
33262                    { name: 'ySubscriptXOffset', type: 'SHORT', value: 0 },
33263                    { name: 'ySubscriptYOffset', type: 'SHORT', value: 140 },
33264                    { name: 'ySuperscriptXSize', type: 'SHORT', value: 650 },
33265                    { name: 'ySuperscriptYSize', type: 'SHORT', value: 699 },
33266                    { name: 'ySuperscriptXOffset', type: 'SHORT', value: 0 },
33267                    { name: 'ySuperscriptYOffset', type: 'SHORT', value: 479 },
33268                    { name: 'yStrikeoutSize', type: 'SHORT', value: 49 },
33269                    { name: 'yStrikeoutPosition', type: 'SHORT', value: 258 },
33270                    { name: 'sFamilyClass', type: 'SHORT', value: 0 },
33271                    { name: 'bFamilyType', type: 'BYTE', value: 0 },
33272                    { name: 'bSerifStyle', type: 'BYTE', value: 0 },
33273                    { name: 'bWeight', type: 'BYTE', value: 0 },
33274                    { name: 'bProportion', type: 'BYTE', value: 0 },
33275                    { name: 'bContrast', type: 'BYTE', value: 0 },
33276                    { name: 'bStrokeVariation', type: 'BYTE', value: 0 },
33277                    { name: 'bArmStyle', type: 'BYTE', value: 0 },
33278                    { name: 'bLetterform', type: 'BYTE', value: 0 },
33279                    { name: 'bMidline', type: 'BYTE', value: 0 },
33280                    { name: 'bXHeight', type: 'BYTE', value: 0 },
33281                    { name: 'ulUnicodeRange1', type: 'ULONG', value: 0 },
33282                    { name: 'ulUnicodeRange2', type: 'ULONG', value: 0 },
33283                    { name: 'ulUnicodeRange3', type: 'ULONG', value: 0 },
33284                    { name: 'ulUnicodeRange4', type: 'ULONG', value: 0 },
33285                    { name: 'achVendID', type: 'CHARARRAY', value: 'XXXX' },
33286                    { name: 'fsSelection', type: 'USHORT', value: 0 },
33287                    { name: 'usFirstCharIndex', type: 'USHORT', value: 0 },
33288                    { name: 'usLastCharIndex', type: 'USHORT', value: 0 },
33289                    { name: 'sTypoAscender', type: 'SHORT', value: 0 },
33290                    { name: 'sTypoDescender', type: 'SHORT', value: 0 },
33291                    { name: 'sTypoLineGap', type: 'SHORT', value: 0 },
33292                    { name: 'usWinAscent', type: 'USHORT', value: 0 },
33293                    { name: 'usWinDescent', type: 'USHORT', value: 0 },
33294                    { name: 'ulCodePageRange1', type: 'ULONG', value: 0 },
33295                    { name: 'ulCodePageRange2', type: 'ULONG', value: 0 },
33296                    { name: 'sxHeight', type: 'SHORT', value: 0 },
33297                    { name: 'sCapHeight', type: 'SHORT', value: 0 },
33298                    { name: 'usDefaultChar', type: 'USHORT', value: 0 },
vendor: 18,359 bytes, lines 33299-33724
33299                    { name: 'usBreakChar', type: 'USHORT', value: 0 },
33300                    { name: 'usMaxContext', type: 'USHORT', value: 0 }
33301                  ],
33302                  options
33303                );
33304              }
33305
33306              var os2 = {
33307                parse: parseOS2Table,
33308                make: makeOS2Table,
33309                unicodeRanges: unicodeRanges,
33310                getUnicodeRange: getUnicodeRange
33311              };
33312
33313              // The `post` table stores additional PostScript information, such as glyph names.
33314
33315              // Parse the PostScript `post` table
33316              function parsePostTable(data, start) {
33317                var post = {};
33318                var p = new parse.Parser(data, start);
33319                post.version = p.parseVersion();
33320                post.italicAngle = p.parseFixed();
33321                post.underlinePosition = p.parseShort();
33322                post.underlineThickness = p.parseShort();
33323                post.isFixedPitch = p.parseULong();
33324                post.minMemType42 = p.parseULong();
33325                post.maxMemType42 = p.parseULong();
33326                post.minMemType1 = p.parseULong();
33327                post.maxMemType1 = p.parseULong();
33328                switch (post.version) {
33329                  case 1:
33330                    post.names = standardNames.slice();
33331                    break;
33332                  case 2:
33333                    post.numberOfGlyphs = p.parseUShort();
33334                    post.glyphNameIndex = new Array(post.numberOfGlyphs);
33335                    for (var i = 0; i < post.numberOfGlyphs; i++) {
33336                      post.glyphNameIndex[i] = p.parseUShort();
33337                    }
33338
33339                    post.names = [];
33340                    for (var i$1 = 0; i$1 < post.numberOfGlyphs; i$1++) {
33341                      if (post.glyphNameIndex[i$1] >= standardNames.length) {
33342                        var nameLength = p.parseChar();
33343                        post.names.push(p.parseString(nameLength));
33344                      }
33345                    }
33346
33347                    break;
33348                  case 2.5:
33349                    post.numberOfGlyphs = p.parseUShort();
33350                    post.offset = new Array(post.numberOfGlyphs);
33351                    for (var i$2 = 0; i$2 < post.numberOfGlyphs; i$2++) {
33352                      post.offset[i$2] = p.parseChar();
33353                    }
33354
33355                    break;
33356                }
33357                return post;
33358              }
33359
33360              function makePostTable() {
33361                return new table.Table('post', [
33362                  { name: 'version', type: 'FIXED', value: 0x00030000 },
33363                  { name: 'italicAngle', type: 'FIXED', value: 0 },
33364                  { name: 'underlinePosition', type: 'FWORD', value: 0 },
33365                  { name: 'underlineThickness', type: 'FWORD', value: 0 },
33366                  { name: 'isFixedPitch', type: 'ULONG', value: 0 },
33367                  { name: 'minMemType42', type: 'ULONG', value: 0 },
33368                  { name: 'maxMemType42', type: 'ULONG', value: 0 },
33369                  { name: 'minMemType1', type: 'ULONG', value: 0 },
33370                  { name: 'maxMemType1', type: 'ULONG', value: 0 }
33371                ]);
33372              }
33373
33374              var post = { parse: parsePostTable, make: makePostTable };
33375
33376              // The `GSUB` table contains ligatures, among other things.
33377
33378              var subtableParsers = new Array(9); // subtableParsers[0] is unused
33379
33380              // https://www.microsoft.com/typography/OTSPEC/GSUB.htm#SS
33381              subtableParsers[1] = function parseLookup1() {
33382                var start = this.offset + this.relativeOffset;
33383                var substFormat = this.parseUShort();
33384                if (substFormat === 1) {
33385                  return {
33386                    substFormat: 1,
33387                    coverage: this.parsePointer(Parser.coverage),
33388                    deltaGlyphId: this.parseUShort()
33389                  };
33390                } else if (substFormat === 2) {
33391                  return {
33392                    substFormat: 2,
33393                    coverage: this.parsePointer(Parser.coverage),
33394                    substitute: this.parseOffset16List()
33395                  };
33396                }
33397                check.assert(
33398                  false,
33399                  '0x' + start.toString(16) + ': lookup type 1 format must be 1 or 2.'
33400                );
33401              };
33402
33403              // https://www.microsoft.com/typography/OTSPEC/GSUB.htm#MS
33404              subtableParsers[2] = function parseLookup2() {
33405                var substFormat = this.parseUShort();
33406                check.argument(
33407                  substFormat === 1,
33408                  'GSUB Multiple Substitution Subtable identifier-format must be 1'
33409                );
33410                return {
33411                  substFormat: substFormat,
33412                  coverage: this.parsePointer(Parser.coverage),
33413                  sequences: this.parseListOfLists()
33414                };
33415              };
33416
33417              // https://www.microsoft.com/typography/OTSPEC/GSUB.htm#AS
33418              subtableParsers[3] = function parseLookup3() {
33419                var substFormat = this.parseUShort();
33420                check.argument(
33421                  substFormat === 1,
33422                  'GSUB Alternate Substitution Subtable identifier-format must be 1'
33423                );
33424                return {
33425                  substFormat: substFormat,
33426                  coverage: this.parsePointer(Parser.coverage),
33427                  alternateSets: this.parseListOfLists()
33428                };
33429              };
33430
33431              // https://www.microsoft.com/typography/OTSPEC/GSUB.htm#LS
33432              subtableParsers[4] = function parseLookup4() {
33433                var substFormat = this.parseUShort();
33434                check.argument(
33435                  substFormat === 1,
33436                  'GSUB ligature table identifier-format must be 1'
33437                );
33438                return {
33439                  substFormat: substFormat,
33440                  coverage: this.parsePointer(Parser.coverage),
33441                  ligatureSets: this.parseListOfLists(function() {
33442                    return {
33443                      ligGlyph: this.parseUShort(),
33444                      components: this.parseUShortList(this.parseUShort() - 1)
33445                    };
33446                  })
33447                };
33448              };
33449
33450              var lookupRecordDesc = {
33451                sequenceIndex: Parser.uShort,
33452                lookupListIndex: Parser.uShort
33453              };
33454
33455              // https://www.microsoft.com/typography/OTSPEC/GSUB.htm#CSF
33456              subtableParsers[5] = function parseLookup5() {
33457                var start = this.offset + this.relativeOffset;
33458                var substFormat = this.parseUShort();
33459
33460                if (substFormat === 1) {
33461                  return {
33462                    substFormat: substFormat,
33463                    coverage: this.parsePointer(Parser.coverage),
33464                    ruleSets: this.parseListOfLists(function() {
33465                      var glyphCount = this.parseUShort();
33466                      var substCount = this.parseUShort();
33467                      return {
33468                        input: this.parseUShortList(glyphCount - 1),
33469                        lookupRecords: this.parseRecordList(substCount, lookupRecordDesc)
33470                      };
33471                    })
33472                  };
33473                } else if (substFormat === 2) {
33474                  return {
33475                    substFormat: substFormat,
33476                    coverage: this.parsePointer(Parser.coverage),
33477                    classDef: this.parsePointer(Parser.classDef),
33478                    classSets: this.parseListOfLists(function() {
33479                      var glyphCount = this.parseUShort();
33480                      var substCount = this.parseUShort();
33481                      return {
33482                        classes: this.parseUShortList(glyphCount - 1),
33483                        lookupRecords: this.parseRecordList(substCount, lookupRecordDesc)
33484                      };
33485                    })
33486                  };
33487                } else if (substFormat === 3) {
33488                  var glyphCount = this.parseUShort();
33489                  var substCount = this.parseUShort();
33490                  return {
33491                    substFormat: substFormat,
33492                    coverages: this.parseList(glyphCount, Parser.pointer(Parser.coverage)),
33493                    lookupRecords: this.parseRecordList(substCount, lookupRecordDesc)
33494                  };
33495                }
33496                check.assert(
33497                  false,
33498                  '0x' + start.toString(16) + ': lookup type 5 format must be 1, 2 or 3.'
33499                );
33500              };
33501
33502              // https://www.microsoft.com/typography/OTSPEC/GSUB.htm#CC
33503              subtableParsers[6] = function parseLookup6() {
33504                var start = this.offset + this.relativeOffset;
33505                var substFormat = this.parseUShort();
33506                if (substFormat === 1) {
33507                  return {
33508                    substFormat: 1,
33509                    coverage: this.parsePointer(Parser.coverage),
33510                    chainRuleSets: this.parseListOfLists(function() {
33511                      return {
33512                        backtrack: this.parseUShortList(),
33513                        input: this.parseUShortList(this.parseShort() - 1),
33514                        lookahead: this.parseUShortList(),
33515                        lookupRecords: this.parseRecordList(lookupRecordDesc)
33516                      };
33517                    })
33518                  };
33519                } else if (substFormat === 2) {
33520                  return {
33521                    substFormat: 2,
33522                    coverage: this.parsePointer(Parser.coverage),
33523                    backtrackClassDef: this.parsePointer(Parser.classDef),
33524                    inputClassDef: this.parsePointer(Parser.classDef),
33525                    lookaheadClassDef: this.parsePointer(Parser.classDef),
33526                    chainClassSet: this.parseListOfLists(function() {
33527                      return {
33528                        backtrack: this.parseUShortList(),
33529                        input: this.parseUShortList(this.parseShort() - 1),
33530                        lookahead: this.parseUShortList(),
33531                        lookupRecords: this.parseRecordList(lookupRecordDesc)
33532                      };
33533                    })
33534                  };
33535                } else if (substFormat === 3) {
33536                  return {
33537                    substFormat: 3,
33538                    backtrackCoverage: this.parseList(Parser.pointer(Parser.coverage)),
33539                    inputCoverage: this.parseList(Parser.pointer(Parser.coverage)),
33540                    lookaheadCoverage: this.parseList(Parser.pointer(Parser.coverage)),
33541                    lookupRecords: this.parseRecordList(lookupRecordDesc)
33542                  };
33543                }
33544                check.assert(
33545                  false,
33546                  '0x' + start.toString(16) + ': lookup type 6 format must be 1, 2 or 3.'
33547                );
33548              };
33549
33550              // https://www.microsoft.com/typography/OTSPEC/GSUB.htm#ES
33551              subtableParsers[7] = function parseLookup7() {
33552                // Extension Substitution subtable
33553                var substFormat = this.parseUShort();
33554                check.argument(
33555                  substFormat === 1,
33556                  'GSUB Extension Substitution subtable identifier-format must be 1'
33557                );
33558                var extensionLookupType = this.parseUShort();
33559                var extensionParser = new Parser(
33560                  this.data,
33561                  this.offset + this.parseULong()
33562                );
33563                return {
33564                  substFormat: 1,
33565                  lookupType: extensionLookupType,
33566                  extension: subtableParsers[extensionLookupType].call(extensionParser)
33567                };
33568              };
33569
33570              // https://www.microsoft.com/typography/OTSPEC/GSUB.htm#RCCS
33571              subtableParsers[8] = function parseLookup8() {
33572                var substFormat = this.parseUShort();
33573                check.argument(
33574                  substFormat === 1,
33575                  'GSUB Reverse Chaining Contextual Single Substitution Subtable identifier-format must be 1'
33576                );
33577                return {
33578                  substFormat: substFormat,
33579                  coverage: this.parsePointer(Parser.coverage),
33580                  backtrackCoverage: this.parseList(Parser.pointer(Parser.coverage)),
33581                  lookaheadCoverage: this.parseList(Parser.pointer(Parser.coverage)),
33582                  substitutes: this.parseUShortList()
33583                };
33584              };
33585
33586              // https://www.microsoft.com/typography/OTSPEC/gsub.htm
33587              function parseGsubTable(data, start) {
33588                start = start || 0;
33589                var p = new Parser(data, start);
33590                var tableVersion = p.parseVersion(1);
33591                check.argument(
33592                  tableVersion === 1 || tableVersion === 1.1,
33593                  'Unsupported GSUB table version.'
33594                );
33595                if (tableVersion === 1) {
33596                  return {
33597                    version: tableVersion,
33598                    scripts: p.parseScriptList(),
33599                    features: p.parseFeatureList(),
33600                    lookups: p.parseLookupList(subtableParsers)
33601                  };
33602                } else {
33603                  return {
33604                    version: tableVersion,
33605                    scripts: p.parseScriptList(),
33606                    features: p.parseFeatureList(),
33607                    lookups: p.parseLookupList(subtableParsers),
33608                    variations: p.parseFeatureVariationsList()
33609                  };
33610                }
33611              }
33612
33613              // GSUB Writing //////////////////////////////////////////////
33614              var subtableMakers = new Array(9);
33615
33616              subtableMakers[1] = function makeLookup1(subtable) {
33617                if (subtable.substFormat === 1) {
33618                  return new table.Table('substitutionTable', [
33619                    { name: 'substFormat', type: 'USHORT', value: 1 },
33620                    {
33621                      name: 'coverage',
33622                      type: 'TABLE',
33623                      value: new table.Coverage(subtable.coverage)
33624                    },
33625                    { name: 'deltaGlyphID', type: 'USHORT', value: subtable.deltaGlyphId }
33626                  ]);
33627                } else {
33628                  return new table.Table(
33629                    'substitutionTable',
33630                    [
33631                      { name: 'substFormat', type: 'USHORT', value: 2 },
33632                      {
33633                        name: 'coverage',
33634                        type: 'TABLE',
33635                        value: new table.Coverage(subtable.coverage)
33636                      }
33637                    ].concat(table.ushortList('substitute', subtable.substitute))
33638                  );
33639                }
33640                check.fail('Lookup type 1 substFormat must be 1 or 2.');
33641              };
33642
33643              subtableMakers[3] = function makeLookup3(subtable) {
33644                check.assert(
33645                  subtable.substFormat === 1,
33646                  'Lookup type 3 substFormat must be 1.'
33647                );
33648                return new table.Table(
33649                  'substitutionTable',
33650                  [
33651                    { name: 'substFormat', type: 'USHORT', value: 1 },
33652                    {
33653                      name: 'coverage',
33654                      type: 'TABLE',
33655                      value: new table.Coverage(subtable.coverage)
33656                    }
33657                  ].concat(
33658                    table.tableList('altSet', subtable.alternateSets, function(
33659                      alternateSet
33660                    ) {
33661                      return new table.Table(
33662                        'alternateSetTable',
33663                        table.ushortList('alternate', alternateSet)
33664                      );
33665                    })
33666                  )
33667                );
33668              };
33669
33670              subtableMakers[4] = function makeLookup4(subtable) {
33671                check.assert(
33672                  subtable.substFormat === 1,
33673                  'Lookup type 4 substFormat must be 1.'
33674                );
33675                return new table.Table(
33676                  'substitutionTable',
33677                  [
33678                    { name: 'substFormat', type: 'USHORT', value: 1 },
33679                    {
33680                      name: 'coverage',
33681                      type: 'TABLE',
33682                      value: new table.Coverage(subtable.coverage)
33683                    }
33684                  ].concat(
33685                    table.tableList('ligSet', subtable.ligatureSets, function(ligatureSet) {
33686                      return new table.Table(
33687                        'ligatureSetTable',
33688                        table.tableList('ligature', ligatureSet, function(ligature) {
33689                          return new table.Table(
33690                            'ligatureTable',
33691                            [
33692                              { name: 'ligGlyph', type: 'USHORT', value: ligature.ligGlyph }
33693                            ].concat(
33694                              table.ushortList(
33695                                'component',
33696                                ligature.components,
33697                                ligature.components.length + 1
33698                              )
33699                            )
33700                          );
33701                        })
33702                      );
33703                    })
33704                  )
33705                );
33706              };
33707
33708              function makeGsubTable(gsub) {
33709                return new table.Table('GSUB', [
33710                  { name: 'version', type: 'ULONG', value: 0x10000 },
33711                  {
33712                    name: 'scripts',
33713                    type: 'TABLE',
33714                    value: new table.ScriptList(gsub.scripts)
33715                  },
33716                  {
33717                    name: 'features',
33718                    type: 'TABLE',
33719                    value: new table.FeatureList(gsub.features)
33720                  },
33721                  {
33722                    name: 'lookups',
33723                    type: 'TABLE',
33724                    value: new table.LookupList(gsub.lookups, subtableMakers
33724)
33725                  }
33726                ]);
33727              }
33728
33729              var gsub = { parse: parseGsubTable, make: makeGsubTable };
33730
33731              // The `GPOS` table contains kerning pairs, among other things.
33732
33733              // Parse the metadata `meta` table.
33734              // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html
33735              function parseMetaTable(data, start) {
33736                var p = new parse.Parser(data, start);
33737                var tableVersion = p.parseULong();
33738                check.argument(tableVersion === 1, 'Unsupported META table version.');
33739                p.parseULong(); // flags - currently unused and set to 0
33740                p.parseULong(); // tableOffset
33741                var numDataMaps = p.parseULong();
33742
33743                var tags = {};
33744                for (var i = 0; i < numDataMaps; i++) {
33745                  var tag = p.parseTag();
33746                  var dataOffset = p.parseULong();
33747                  var dataLength = p.parseULong();
33748                  var text = decode.UTF8(data, start + dataOffset, dataLength);
33749
33750                  tags[tag] = text;
33751                }
33752                return tags;
33753              }
33754
33755              function makeMetaTable(tags) {
33756                var numTags = Object.keys(tags).length;
33757                var stringPool = '';
33758                var stringPoolOffset = 16 + numTags * 12;
33759
33760                var result = new table.Table('meta', [
33761                  { name: 'version', type: 'ULONG', value: 1 },
33762                  { name: 'flags', type: 'ULONG', value: 0 },
33763                  { name: 'offset', type: 'ULONG', value: stringPoolOffset },
33764                  { name: 'numTags', type: 'ULONG', value: numTags }
33765                ]);
33766
33767                for (var tag in tags) {
33768                  var pos = stringPool.length;
33769                  stringPool += tags[tag];
33770
33771                  result.fields.push({ name: 'tag ' + tag, type: 'TAG', value: tag });
33772                  result.fields.push({
33773                    name: 'offset ' + tag,
33774                    type: 'ULONG',
33775                    value: stringPoolOffset + pos
33776                  });
33777                  result.fields.push({
33778                    name: 'length ' + tag,
33779                    type: 'ULONG',
33780                    value: tags[tag].length
33781                  });
33782                }
33783
33784                result.fields.push({
33785                  name: 'stringPool',
33786                  type: 'CHARARRAY',
33787                  value: stringPool
33788                });
33789
33790                return result;
33791              }
33792
33793              var meta = { parse: parseMetaTable, make: makeMetaTable };
33794
33795              // The `sfnt` wrapper provides organization for the tables in the font.
33796
33797              function log2(v) {
33798                return (Math.log(v) / Math.log(2)) | 0;
33799              }
33800
33801              function computeCheckSum(bytes) {
33802                while (bytes.length % 4 !== 0) {
33803                  bytes.push(0);
33804                }
33805
33806                var sum = 0;
33807                for (var i = 0; i < bytes.length; i += 4) {
33808                  sum +=
33809                    (bytes[i] << 24) +
33810                    (bytes[i + 1] << 16) +
33811                    (bytes[i + 2] << 8) +
33812                    bytes[i + 3];
33813                }
33814
33815                sum %= Math.pow(2, 32);
33816                return sum;
33817              }
33818
33819              function makeTableRecord(tag, checkSum, offset, length) {
33820                return new table.Record('Table Record', [
33821                  { name: 'tag', type: 'TAG', value: tag !== undefined ? tag : '' },
33822                  {
33823                    name: 'checkSum',
33824                    type: 'ULONG',
33825                    value: checkSum !== undefined ? checkSum : 0
33826                  },
33827                  {
33828                    name: 'offset',
33829                    type: 'ULONG',
33830                    value: offset !== undefined ? offset : 0
33831                  },
33832                  {
33833                    name: 'length',
33834                    type: 'ULONG',
33835                    value: length !== undefined ? length : 0
33836                  }
33837                ]);
33838              }
33839
33840              function makeSfntTable(tables) {
33841                var sfnt = new table.Table('sfnt', [
33842                  { name: 'version', type: 'TAG', value: 'OTTO' },
33843                  { name: 'numTables', type: 'USHORT', value: 0 },
33844                  { name: 'searchRange', type: 'USHORT', value: 0 },
33845                  { name: 'entrySelector', type: 'USHORT', value: 0 },
33846                  { name: 'rangeShift', type: 'USHORT', value: 0 }
33847                ]);
33848                sfnt.tables = tables;
33849                sfnt.numTables = tables.length;
33850                var highestPowerOf2 = Math.pow(2, log2(sfnt.numTables));
33851                sfnt.searchRange = 16 * highestPowerOf2;
33852                sfnt.entrySelector = log2(highestPowerOf2);
33853                sfnt.rangeShift = sfnt.numTables * 16 - sfnt.searchRange;
33854
33855                var recordFields = [];
33856                var tableFields = [];
33857
33858                var offset = sfnt.sizeOf() + makeTableRecord().sizeOf() * sfnt.numTables;
33859                while (offset % 4 !== 0) {
33860                  offset += 1;
33861                  tableFields.push({ name: 'padding', type: 'BYTE', value: 0 });
33862                }
33863
33864                for (var i = 0; i < tables.length; i += 1) {
33865                  var t = tables[i];
33866                  check.argument(
33867                    t.tableName.length === 4,
33868                    'Table name' + t.tableName + ' is invalid.'
33869                  );
33870                  var tableLength = t.sizeOf();
33871                  var tableRecord = makeTableRecord(
33872                    t.tableName,
33873                    computeCheckSum(t.encode()),
33874                    offset,
33875                    tableLength
33876                  );
33877                  recordFields.push({
33878                    name: tableRecord.tag + ' Table Record',
33879                    type: 'RECORD',
33880                    value: tableRecord
33881                  });
33882                  tableFields.push({
33883                    name: t.tableName + ' table',
33884                    type: 'RECORD',
33885                    value: t
33886                  });
33887                  offset += tableLength;
33888                  check.argument(
33889                    !isNaN(offset),
33890                    'Something went wrong calculating the offset.'
33891                  );
33892                  while (offset % 4 !== 0) {
33893                    offset += 1;
33894                    tableFields.push({ name: 'padding', type: 'BYTE', value: 0 });
33895                  }
33896                }
33897
33898                // Table records need to be sorted alphabetically.
33899                recordFields.sort(function(r1, r2) {
33900                  if (r1.value.tag > r2.value.tag) {
33901                    return 1;
33902                  } else {
33903                    return -1;
33904                  }
33905                });
33906
33907                sfnt.fields = sfnt.fields.concat(recordFields);
33908                sfnt.fields = sfnt.fields.concat(tableFields);
33909                return sfnt;
33910              }
33911
33912              // Get the metrics for a character. If the string has more than one character
33913              // this function returns metrics for the first available character.
33914              // You can provide optional fallback metrics if no characters are available.
33915              function metricsForChar(font, chars, notFoundMetrics) {
33916                for (var i = 0; i < chars.length; i += 1) {
33917                  var glyphIndex = font.charToGlyphIndex(chars[i]);
33918                  if (glyphIndex > 0) {
33919                    var glyph = font.glyphs.get(glyphIndex);
33920                    return glyph.getMetrics();
33921                  }
33922                }
33923
33924                return notFoundMetrics;
33925              }
33926
33927              function average(vs) {
33928                var sum = 0;
33929                for (var i = 0; i < vs.length; i += 1) {
33930                  sum += vs[i];
33931                }
33932
33933                return sum / vs.length;
33934              }
33935
33936              // Convert the font object to a SFNT data structure.
33937              // This structure contains all the necessary tables and metadata to create a binary OTF file.
33938              function fontToSfntTable(font) {
33939                var xMins = [];
33940                var yMins = [];
33941                var xMaxs = [];
33942                var yMaxs = [];
33943                var advanceWidths = [];
33944                var leftSideBearings = [];
33945                var rightSideBearings = [];
33946                var firstCharIndex;
33947                var lastCharIndex = 0;
33948                var ulUnicodeRange1 = 0;
33949                var ulUnicodeRange2 = 0;
33950                var ulUnicodeRange3 = 0;
33951                var ulUnicodeRange4 = 0;
33952
33953                for (var i = 0; i < font.glyphs.length; i += 1) {
33954                  var glyph = font.glyphs.get(i);
33955                  var unicode = glyph.unicode | 0;
33956
33957                  if (isNaN(glyph.advanceWidth)) {
33958                    throw new Error(
33959                      'Glyph ' + glyph.name + ' (' + i + '): advanceWidth is not a number.'
33960                    );
33961                  }
33962
33963                  if (firstCharIndex > unicode || firstCharIndex === undefined) {
33964                    // ignore .notdef char
33965                    if (unicode > 0) {
33966                      firstCharIndex = unicode;
33967                    }
33968                  }
33969
33970                  if (lastCharIndex < unicode) {
33971                    lastCharIndex = unicode;
33972                  }
33973
33974                  var position = os2.getUnicodeRange(unicode);
33975                  if (position < 32) {
33976                    ulUnicodeRange1 |= 1 << position;
33977                  } else if (position < 64) {
33978                    ulUnicodeRange2 |= 1 << (position - 32);
33979                  } else if (position < 96) {
33980                    ulUnicodeRange3 |= 1 << (position - 64);
33981                  } else if (position < 123) {
33982                    ulUnicodeRange4 |= 1 << (position - 96);
33983                  } else {
33984                    throw new Error(
33985                      'Unicode ranges bits > 123 are reserved for internal usage'
33986                    );
33987                  }
33988                  // Skip non-important characters.
33989                  if (glyph.name === '.notdef') {
33990                    continue;
33991                  }
33992                  var metrics = glyph.getMetrics();
33993                  xMins.push(metrics.xMin);
33994                  yMins.push(metrics.yMin);
33995                  xMaxs.push(metrics.xMax);
33996                  yMaxs.push(metrics.yMax);
33997                  leftSideBearings.push(metrics.leftSideBearing);
33998                  rightSideBearings.push(metrics.rightSideBearing);
33999                  advanceWidths.push(glyph.advanceWidth);
34000                }
34001
34002                var globals = {
34003                  xMin: Math.min.apply(null, xMins),
34004                  yMin: Math.min.apply(null, yMins),
34005                  xMax: Math.max.apply(null, xMaxs),
34006                  yMax: Math.max.apply(null, yMaxs),
34007                  advanceWidthMax: Math.max.apply(null, advanceWidths),
34008                  advanceWidthAvg: average(advanceWidths),
34009                  minLeftSideBearing: Math.min.apply(null, leftSideBearings),
34010                  maxLeftSideBearing: Math.max.apply(null, leftSideBearings),
34011                  minRightSideBearing: Math.min.apply(null, rightSideBearings)
34012                };
34013                globals.ascender = font.ascender;
34014                globals.descender = font.descender;
34015
34016                var headTable = head.make({
34017                  flags: 3, // 00000011 (baseline for font at y=0; left sidebearing point at x=0)
34018                  unitsPerEm: font.unitsPerEm,
34019                  xMin: globals.xMin,
34020                  yMin: globals.yMin,
34021                  xMax: globals.xMax,
34022                  yMax: globals.yMax,
34023                  lowestRecPPEM: 3,
34024                  createdTimestamp: font.createdTimestamp
34025                });
34026
34027                var hheaTable = hhea.make({
34028                  ascender: globals.ascender,
34029                  descender: globals.descender,
34030                  advanceWidthMax: globals.advanceWidthMax,
34031                  minLeftSideBearing: globals.minLeftSideBearing,
34032                  minRightSideBearing: globals.minRightSideBearing,
34033                  xMaxExtent: globals.maxLeftSideBearing + (globals.xMax - globals.xMin),
34034                  numberOfHMetrics: font.glyphs.length
34035                });
34036
34037                var maxpTable = maxp.make(font.glyphs.length);
34038
34039                var os2Table = os2.make({
34040                  xAvgCharWidth: Math.round(globals.advanceWidthAvg),
34041                  usWeightClass: font.tables.os2.usWeightClass,
34042                  usWidthClass: font.tables.os2.usWidthClass,
34043                  usFirstCharIndex: firstCharIndex,
34044                  usLastCharIndex: lastCharIndex,
34045                  ulUnicodeRange1: ulUnicodeRange1,
34046                  ulUnicodeRange2: ulUnicodeRange2,
34047                  ulUnicodeRange3: ulUnicodeRange3,
34048                  ulUnicodeRange4: ulUnicodeRange4,
34049                  fsSelection: font.tables.os2.fsSelection, // REGULAR
34050                  // See http://typophile.com/node/13081 for more info on vertical metrics.
34051                  // We get metrics for typical characters (such as "x" for xHeight).
34052                  // We provide some fallback characters if characters are unavailable: their
34053                  // ordering was chosen experimentally.
34054                  sTypoAscender: globals.ascender,
34055                  sTypoDescender: globals.descender,
34056                  sTypoLineGap: 0,
34057                  usWinAscent: globals.yMax,
34058                  usWinDescent: Math.abs(globals.yMin),
34059                  ulCodePageRange1: 1, // FIXME: hard-code Latin 1 support for now
34060                  sxHeight: metricsForChar(font, 'xyvw', {
34061                    yMax: Math.round(globals.ascender / 2)
34062                  }).yMax,
34063                  sCapHeight: metricsForChar(font, 'HIKLEFJMNTZBDPRAGOQSUVWXY', globals)
34064                    .yMax,
34065                  usDefaultChar: font.hasChar(' ') ? 32 : 0, // Use space as the default character, if available.
34066                  usBreakChar: font.hasChar(' ') ? 32 : 0 // Use space as the break character, if available.
34067                });
34068
34069                var hmtxTable = hmtx.make(font.glyphs);
34070                var cmapTable = cmap.make(font.glyphs);
34071
34072                var englishFamilyName = font.getEnglishName('fontFamily');
34073                var englishStyleName = font.getEnglishName('fontSubfamily');
34074                var englishFullName = englishFamilyName + ' ' + englishStyleName;
34075                var postScriptName = font.getEnglishName('postScriptName');
34076                if (!postScriptName) {
34077                  postScriptName =
34078                    englishFamilyName.replace(/\s/g, '') + '-' + englishStyleName;
34079                }
34080
34081                var names = {};
34082                for (var n in font.names) {
34083                  names[n] = font.names[n];
34084                }
34085
34086                if (!names.uniqueID) {
34087                  names.uniqueID = {
34088                    en: font.getEnglishName('manufacturer') + ':' + englishFullName
34089                  };
34090                }
34091
34092                if (!names.postScriptName) {
34093                  names.postScriptName = { en: postScriptName };
34094                }
34095
34096                if (!names.preferredFamily) {
34097                  names.preferredFamily = font.names.fontFamily;
34098                }
34099
34100                if (!names.preferredSubfamily) {
34101                  names.preferredSubfamily = font.names.fontSubfam
34101ily;
34102                }
34103
34104                var languageTags = [];
34105                var nameTable = _name.make(names, languageTags);
34106                var ltagTable =
34107                  languageTags.length > 0 ? ltag.make(languageTags) : undefined;
34108
34109                var postTable = post.make();
34110                var cffTable = cff.make(font.glyphs, {
34111                  version: font.getEnglishName('version'),
34112                  fullName: englishFullName,
34113                  familyName: englishFamilyName,
34114                  weightName: englishStyleName,
34115                  postScriptName: postScriptName,
34116                  unitsPerEm: font.unitsPerEm,
34117                  fontBBox: [0, globals.yMin, globals.ascender, globals.advanceWidthMax]
34118                });
34119
34120                var metaTable =
34121                  font.metas && Object.keys(font.metas).length > 0
34122                    ? meta.make(font.metas)
34123                    : undefined;
34124
34125                // The order does not matter because makeSfntTable() will sort them.
34126                var tables = [
34127                  headTable,
34128                  hheaTable,
34129                  maxpTable,
34130                  os2Table,
34131                  nameTable,
34132                  cmapTable,
34133                  postTable,
34134                  cffTable,
34135                  hmtxTable
34136                ];
34137                if (ltagTable) {
34138                  tables.push(ltagTable);
34139                }
34140                // Optional tables
34141                if (font.tables.gsub) {
34142                  tables.push(gsub.make(font.tables.gsub));
34143                }
34144                if (metaTable) {
34145                  tables.push(metaTable);
34146                }
34147
34148                var sfntTable = makeSfntTable(tables);
34149
34150                // Compute the font's checkSum and store it in head.checkSumAdjustment.
34151                var bytes = sfntTable.encode();
34152                var checkSum = computeCheckSum(bytes);
34153                var tableFields = sfntTable.fields;
34154                var checkSumAdjusted = false;
34155                for (var i$1 = 0; i$1 < tableFields.length; i$1 += 1) {
34156                  if (tableFields[i$1].name === 'head table') {
34157                    tableFields[i$1].value.checkSumAdjustment = 0xb1b0afba - checkSum;
34158                    checkSumAdjusted = true;
34159                    break;
34160                  }
34161                }
34162
34163                if (!checkSumAdjusted) {
34164                  throw new Error('Could not find head table with checkSum to adjust.');
34165                }
34166
34167                return sfntTable;
34168              }
34169
34170              var sfnt = {
34171                make: makeSfntTable,
34172                fontToTable: fontToSfntTable,
34173                computeCheckSum: computeCheckSum
34174              };
34175
34176              // The Layout object is the prototype of Substitution objects, and provides
34177
34178              function searchTag(arr, tag) {
34179                /* jshint bitwise: false */
34180                var imin = 0;
34181                var imax = arr.length - 1;
34182                while (imin <= imax) {
34183                  var imid = (imin + imax) >>> 1;
34184                  var val = arr[imid].tag;
34185                  if (val === tag) {
34186                    return imid;
34187                  } else if (val < tag) {
34188                    imin = imid + 1;
34189                  } else {
34190                    imax = imid - 1;
34191                  }
34192                }
34193                // Not found: return -1-insertion point
34194                return -imin - 1;
34195              }
34196
34197              function binSearch(arr, value) {
34198                /* jshint bitwise: false */
34199                var imin = 0;
34200                var imax = arr.length - 1;
34201                while (imin <= imax) {
34202                  var imid = (imin + imax) >>> 1;
34203                  var val = arr[imid];
34204                  if (val === value) {
34205                    return imid;
34206                  } else if (val < value) {
34207                    imin = imid + 1;
34208                  } else {
34209                    imax = imid - 1;
34210                  }
34211                }
34212                // Not found: return -1-insertion point
34213                return -imin - 1;
34214              }
34215
34216              // binary search in a list of ranges (coverage, class definition)
vendor: 10,989 bytes, lines 34217-34481
34217              function searchRange(ranges, value) {
34218                // jshint bitwise: false
34219                var range;
34220                var imin = 0;
34221                var imax = ranges.length - 1;
34222                while (imin <= imax) {
34223                  var imid = (imin + imax) >>> 1;
34224                  range = ranges[imid];
34225                  var start = range.start;
34226                  if (start === value) {
34227                    return range;
34228                  } else if (start < value) {
34229                    imin = imid + 1;
34230                  } else {
34231                    imax = imid - 1;
34232                  }
34233                }
34234                if (imin > 0) {
34235                  range = ranges[imin - 1];
34236                  if (value > range.end) {
34237                    return 0;
34238                  }
34239                  return range;
34240                }
34241              }
34242
34243              /**
34244               * @exports opentype.Layout
34245               * @class
34246               */
34247              function Layout(font, tableName) {
34248                this.font = font;
34249                this.tableName = tableName;
34250              }
34251
34252              Layout.prototype = {
34253                /**
34254                 * Binary search an object by "tag" property
34255                 * @instance
34256                 * @function searchTag
34257                 * @memberof opentype.Layout
34258                 * @param  {Array} arr
34259                 * @param  {string} tag
34260                 * @return {number}
34261                 */
34262                searchTag: searchTag,
34263
34264                /**
34265                 * Binary search in a list of numbers
34266                 * @instance
34267                 * @function binSearch
34268                 * @memberof opentype.Layout
34269                 * @param  {Array} arr
34270                 * @param  {number} value
34271                 * @return {number}
34272                 */
34273                binSearch: binSearch,
34274
34275                /**
34276                 * Get or create the Layout table (GSUB, GPOS etc).
34277                 * @param  {boolean} create - Whether to create a new one.
34278                 * @return {Object} The GSUB or GPOS table.
34279                 */
34280                getTable: function(create) {
34281                  var layout = this.font.tables[this.tableName];
34282                  if (!layout && create) {
34283                    layout = this.font.tables[this.tableName] = this.createDefaultTable();
34284                  }
34285                  return layout;
34286                },
34287
34288                /**
34289                 * Returns all scripts in the substitution table.
34290                 * @instance
34291                 * @return {Array}
34292                 */
34293                getScriptNames: function() {
34294                  var layout = this.getTable();
34295                  if (!layout) {
34296                    return [];
34297                  }
34298                  return layout.scripts.map(function(script) {
34299                    return script.tag;
34300                  });
34301                },
34302
34303                /**
34304                 * Returns the best bet for a script name.
34305                 * Returns 'DFLT' if it exists.
34306                 * If not, returns 'latn' if it exists.
34307                 * If neither exist, returns undefined.
34308                 */
34309                getDefaultScriptName: function() {
34310                  var layout = this.getTable();
34311                  if (!layout) {
34312                    return;
34313                  }
34314                  var hasLatn = false;
34315                  for (var i = 0; i < layout.scripts.length; i++) {
34316                    var name = layout.scripts[i].tag;
34317                    if (name === 'DFLT') {
34318                      return name;
34319                    }
34320                    if (name === 'latn') {
34321                      hasLatn = true;
34322                    }
34323                  }
34324                  if (hasLatn) {
34325                    return 'latn';
34326                  }
34327                },
34328
34329                /**
34330                 * Returns all LangSysRecords in the given script.
34331                 * @instance
34332                 * @param {string} [script='DFLT']
34333                 * @param {boolean} create - forces the creation of this script table if it doesn't exist.
34334                 * @return {Object} An object with tag and script properties.
34335                 */
34336                getScriptTable: function(script, create) {
34337                  var layout = this.getTable(create);
34338                  if (layout) {
34339                    script = script || 'DFLT';
34340                    var scripts = layout.scripts;
34341                    var pos = searchTag(layout.scripts, script);
34342                    if (pos >= 0) {
34343                      return scripts[pos].script;
34344                    } else if (create) {
34345                      var scr = {
34346                        tag: script,
34347                        script: {
34348                          defaultLangSys: {
34349                            reserved: 0,
34350                            reqFeatureIndex: 0xffff,
34351                            featureIndexes: []
34352                          },
34353                          langSysRecords: []
34354                        }
34355                      };
34356                      scripts.splice(-1 - pos, 0, scr);
34357                      return scr.script;
34358                    }
34359                  }
34360                },
34361
34362                /**
34363                 * Returns a language system table
34364                 * @instance
34365                 * @param {string} [script='DFLT']
34366                 * @param {string} [language='dlft']
34367                 * @param {boolean} create - forces the creation of this langSysTable if it doesn't exist.
34368                 * @return {Object}
34369                 */
34370                getLangSysTable: function(script, language, create) {
34371                  var scriptTable = this.getScriptTable(script, create);
34372                  if (scriptTable) {
34373                    if (!language || language === 'dflt' || language === 'DFLT') {
34374                      return scriptTable.defaultLangSys;
34375                    }
34376                    var pos = searchTag(scriptTable.langSysRecords, language);
34377                    if (pos >= 0) {
34378                      return scriptTable.langSysRecords[pos].langSys;
34379                    } else if (create) {
34380                      var langSysRecord = {
34381                        tag: language,
34382                        langSys: {
34383                          reserved: 0,
34384                          reqFeatureIndex: 0xffff,
34385                          featureIndexes: []
34386                        }
34387                      };
34388                      scriptTable.langSysRecords.splice(-1 - pos, 0, langSysRecord);
34389                      return langSysRecord.langSys;
34390                    }
34391                  }
34392                },
34393
34394                /**
34395                 * Get a specific feature table.
34396                 * @instance
34397                 * @param {string} [script='DFLT']
34398                 * @param {string} [language='dlft']
34399                 * @param {string} feature - One of the codes listed at https://www.microsoft.com/typography/OTSPEC/featurelist.htm
34400                 * @param {boolean} create - forces the creation of the feature table if it doesn't exist.
34401                 * @return {Object}
34402                 */
34403                getFeatureTable: function(script, language, feature, create) {
34404                  var langSysTable = this.getLangSysTable(script, language, create);
34405                  if (langSysTable) {
34406                    var featureRecord;
34407                    var featIndexes = langSysTable.featureIndexes;
34408                    var allFeatures = this.font.tables[this.tableName].features;
34409                    // The FeatureIndex array of indices is in arbitrary order,
34410                    // even if allFeatures is sorted alphabetically by feature tag.
34411                    for (var i = 0; i < featIndexes.length; i++) {
34412                      featureRecord = allFeatures[featIndexes[i]];
34413                      if (featureRecord.tag === feature) {
34414                        return featureRecord.feature;
34415                      }
34416                    }
34417                    if (create) {
34418                      var index = allFeatures.length;
34419                      // Automatic ordering of features would require to shift feature indexes in the script list.
34420                      check.assert(
34421                        index === 0 || feature >= allFeatures[index - 1].tag,
34422                        'Features must be added in alphabetical order.'
34423                      );
34424                      featureRecord = {
34425                        tag: feature,
34426                        feature: { params: 0, lookupListIndexes: [] }
34427                      };
34428                      allFeatures.push(featureRecord);
34429                      featIndexes.push(index);
34430                      return featureRecord.feature;
34431                    }
34432                  }
34433                },
34434
34435                /**
34436                 * Get the lookup tables of a given type for a script/language/feature.
34437                 * @instance
34438                 * @param {string} [script='DFLT']
34439                 * @param {string} [language='dlft']
34440                 * @param {string} feature - 4-letter feature code
34441                 * @param {number} lookupType - 1 to 9
34442                 * @param {boolean} create - forces the creation of the lookup table if it doesn't exist, with no subtables.
34443                 * @return {Object[]}
34444                 */
34445                getLookupTables: function(script, language, feature, lookupType, create) {
34446                  var featureTable = this.getFeatureTable(
34447                    script,
34448                    language,
34449                    feature,
34450                    create
34451                  );
34452                  var tables = [];
34453                  if (featureTable) {
34454                    var lookupTable;
34455                    var lookupListIndexes = featureTable.lookupListIndexes;
34456                    var allLookups = this.font.tables[this.tableName].lookups;
34457                    // lookupListIndexes are in no particular order, so use naive search.
34458                    for (var i = 0; i < lookupListIndexes.length; i++) {
34459                      lookupTable = allLookups[lookupListIndexes[i]];
34460                      if (lookupTable.lookupType === lookupType) {
34461                        tables.push(lookupTable);
34462                      }
34463                    }
34464                    if (tables.length === 0 && create) {
34465                      lookupTable = {
34466                        lookupType: lookupType,
34467                        lookupFlag: 0,
34468                        subtables: [],
34469                        markFilteringSet: undefined
34470                      };
34471                      var index = allLookups.length;
34472                      allLookups.push(lookupTable);
34473                      lookupListIndexes.push(index);
34474                      return [lookupTable];
34475                    }
34476                  }
34477                  return tables;
34478                },
34479
34480                /**
34481                 * Find a glyph in a class definition table
34482                 * https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table
34483                 * @param {object} classDefTable - an OpenType Layout class definition table
34484                 * @param {number} glyphIndex - the index of the glyph to find
34485                 * @returns {number} -1 if not found
34486                 */
34487                getGlyphClass: function(classDefTable, glyphIndex) {
34488                  switch (classDefTable.format) {
34489                    case 1:
34490                      if (
34491                        classDefTable.startGlyph <= glyphIndex &&
34492                        glyphIndex < classDefTable.startGlyph + classDefTable.classes.length
34493                      ) {
34494                        return classDefTable.classes[glyphIndex - classDefTable.startGlyph];
34495                      }
34496                      return 0;
34497                    case 2:
34498                      var range = searchRange(classDefTable.ranges, glyphIndex);
34499                      return range ? range.classId : 0;
34500                  }
34501                },
34502
34503                /**
34504                 * Find a glyph in a coverage table
34505                 * https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-table
34506                 * @param {object} coverageTable - an OpenType Layout coverage table
34507                 * @param {number} glyphIndex - the index of the glyph to find
34508                 * @returns {number} -1 if not found
34509                 */
34510                getCoverageIndex: function(coverageTable, glyphIndex) {
34511                  switch (coverageTable.format) {
34512                    case 1:
34513                      var index = binSearch(coverageTable.glyphs, glyphIndex);
34514                      return index >= 0 ? index : -1;
34515                    case 2:
34516                      var range = searchRange(coverageTable.ranges, glyphIndex);
34517                      return range ? range.index + glyphIndex - range.start : -1;
34518                  }
34519                },
34520
34521                /**
34522                 * Returns the list of glyph indexes of a coverage table.
34523                 * Format 1: the list is stored raw
34524                 * Format 2: compact list as range records.
34525                 * @instance
34526                 * @param  {Object} coverageTable
34527                 * @return {Array}
34528                 */
34529                expandCoverage: function(coverageTable) {
34530                  if (coverageTable.format === 1) {
34531                    return coverageTable.glyphs;
34532                  } else {
34533                    var glyphs = [];
34534                    var ranges = coverageTable.ranges;
34535                    for (var i = 0; i < ranges.length; i++) {
34536                      var range = ranges[i];
34537                      var start = range.start;
34538                      var end = range.end;
34539                      for (var j = start; j <= end; j++) {
34540                        glyphs.push(j);
34541                      }
34542                    }
34543                    return glyphs;
34544                  }
34545                }
34546              };
34547
34548              // The Position object provides utility methods to manipulate
34549
34550              /**
34551               * @exports opentype.Position
34552               * @class
34553               * @extends opentype.Layout
34554               * @param {opentype.Font}
34555               * @constructor
34556               */
34557              function Position(font) {
34558                Layout.call(this, font, 'gpos');
34559              }
34560
34561              Position.prototype = Layout.prototype;
34562
34563              /**
34564               * Init some data for faster and easier access later.
34565               */
34566              Position.prototype.init = function() {
34567                var script = this.getDefaultScriptName();
34568                this.defaultKerningTables = this.getKerningTables(script);
34569              };
34570
34571              /**
34572               * Find a glyph pair in a list of lookup tables of type 2 and retrieve the xAdvance kerning value.
34573               *
34574               * @param {integer} leftIndex - left glyph index
34575               * @param {integer} rightIndex - right glyph index
34576               * @returns {integer}
34577               */
34578              Position.prototype.getKerningValue = function(
34579                kerningLookups,
34580                leftIndex,
34581                rightIndex
34582              ) {
34583                var this$1 = this;
34584
34585                for (var i = 0; i < kerningLookups.length; i++) {
34586                  var subtables = kerningLookups[i].subtables;
34587                  for (var j = 0; j < subtables.length; j++) {
34588                    var subtable = subtables[j];
34589                    var covIndex = this$1.getCoverageIndex(subtable.coverage, leftIndex);
34590                    if (covIndex < 0) {
34591                      continue;
34592                    }
34593                    switch (subtable.posFormat) {
34594                      case 1:
34595                        // Search Pair Adjustment Positioning Format 1
34596                        var pairSet = subtable.pairSets[covIndex];
34597                        for (var k = 0; k < pairSet.length; k++) {
34598                          var pair = pairSet[k];
34599                          if (pair.secondGlyph === rightIndex) {
34600                            return (pair.value1 && pair.value1.xAdvance) || 0;
34601                          }
34602                        }
34603                        break; // left glyph found, not right glyph - try next subtable
34604                      case 2:
34605                        // Search Pair Adjustment Positioning Format 2
34606                        var class1 = this$1.getGlyphClass(subtable.classDef1, leftIndex);
34607                        var class2 = this$1.getGlyphClass(subtable.classDef2, rightIndex);
34608                        var pair$1 = subtable.classRecords[class1][class2];
34609                        return (pair$1.value1 && pair$1.value1.xAdvance) || 0;
34610                    }
34611                  }
34612                }
34613                return 0;
34614              };
34615
34616              /**
34617               * List all kerning lookup tables.
34618               *
34619               * @param {string} [script='DFLT'] - use font.position.getDefaultScriptName() for a better default value
34620               * @param {string} [language='dflt']
34621               * @return {object[]} The list of kerning lookup tables (may be empty), or undefined if there is no GPOS table (and we should use the kern table)
34622               */
34623              Position.prototype.getKerningTables = function(script, language) {
34624                if (this.font.tables.gpos) {
34625                  return this.getLookupTables(script, language, 'kern', 2);
34626                }
34627              };
34628
34629              // The Substitution object provides utility methods to manipulate
34630
34631              /**
34632               * @exports opentype.Substitution
34633               * @class
vendor: 117,208 bytes, lines 34634-38203
34634               * @extends opentype.Layout
34635               * @param {opentype.Font}
34636               * @constructor
34637               */
34638              function Substitution(font) {
34639                Layout.call(this, font, 'gsub');
34640              }
34641
34642              // Check if 2 arrays of primitives are equal.
34643              function arraysEqual(ar1, ar2) {
34644                var n = ar1.length;
34645                if (n !== ar2.length) {
34646                  return false;
34647                }
34648                for (var i = 0; i < n; i++) {
34649                  if (ar1[i] !== ar2[i]) {
34650                    return false;
34651                  }
34652                }
34653                return true;
34654              }
34655
34656              // Find the first subtable of a lookup table in a particular format.
34657              function getSubstFormat(lookupTable, format, defaultSubtable) {
34658                var subtables = lookupTable.subtables;
34659                for (var i = 0; i < subtables.length; i++) {
34660                  var subtable = subtables[i];
34661                  if (subtable.substFormat === format) {
34662                    return subtable;
34663                  }
34664                }
34665                if (defaultSubtable) {
34666                  subtables.push(defaultSubtable);
34667                  return defaultSubtable;
34668                }
34669                return undefined;
34670              }
34671
34672              Substitution.prototype = Layout.prototype;
34673
34674              /**
34675               * Create a default GSUB table.
34676               * @return {Object} gsub - The GSUB table.
34677               */
34678              Substitution.prototype.createDefaultTable = function() {
34679                // Generate a default empty GSUB table with just a DFLT script and dflt lang sys.
34680                return {
34681                  version: 1,
34682                  scripts: [
34683                    {
34684                      tag: 'DFLT',
34685                      script: {
34686                        defaultLangSys: {
34687                          reserved: 0,
34688                          reqFeatureIndex: 0xffff,
34689                          featureIndexes: []
34690                        },
34691                        langSysRecords: []
34692                      }
34693                    }
34694                  ],
34695                  features: [],
34696                  lookups: []
34697                };
34698              };
34699
34700              /**
34701               * List all single substitutions (lookup type 1) for a given script, language, and feature.
34702               * @param {string} [script='DFLT']
34703               * @param {string} [language='dflt']
34704               * @param {string} feature - 4-character feature name ('aalt', 'salt', 'ss01'...)
34705               * @return {Array} substitutions - The list of substitutions.
34706               */
34707              Substitution.prototype.getSingle = function(feature, script, language) {
34708                var this$1 = this;
34709
34710                var substitutions = [];
34711                var lookupTables = this.getLookupTables(script, language, feature, 1);
34712                for (var idx = 0; idx < lookupTables.length; idx++) {
34713                  var subtables = lookupTables[idx].subtables;
34714                  for (var i = 0; i < subtables.length; i++) {
34715                    var subtable = subtables[i];
34716                    var glyphs = this$1.expandCoverage(subtable.coverage);
34717                    var j = void 0;
34718                    if (subtable.substFormat === 1) {
34719                      var delta = subtable.deltaGlyphId;
34720                      for (j = 0; j < glyphs.length; j++) {
34721                        var glyph = glyphs[j];
34722                        substitutions.push({ sub: glyph, by: glyph + delta });
34723                      }
34724                    } else {
34725                      var substitute = subtable.substitute;
34726                      for (j = 0; j < glyphs.length; j++) {
34727                        substitutions.push({ sub: glyphs[j], by: substitute[j] });
34728                      }
34729                    }
34730                  }
34731                }
34732                return substitutions;
34733              };
34734
34735              /**
34736               * List all alternates (lookup type 3) for a given script, language, and feature.
34737               * @param {string} [script='DFLT']
34738               * @param {string} [language='dflt']
34739               * @param {string} feature - 4-character feature name ('aalt', 'salt'...)
34740               * @return {Array} alternates - The list of alternates
34741               */
34742              Substitution.prototype.getAlternates = function(feature, script, language) {
34743                var this$1 = this;
34744
34745                var alternates = [];
34746                var lookupTables = this.getLookupTables(script, language, feature, 3);
34747                for (var idx = 0; idx < lookupTables.length; idx++) {
34748                  var subtables = lookupTables[idx].subtables;
34749                  for (var i = 0; i < subtables.length; i++) {
34750                    var subtable = subtables[i];
34751                    var glyphs = this$1.expandCoverage(subtable.coverage);
34752                    var alternateSets = subtable.alternateSets;
34753                    for (var j = 0; j < glyphs.length; j++) {
34754                      alternates.push({ sub: glyphs[j], by: alternateSets[j] });
34755                    }
34756                  }
34757                }
34758                return alternates;
34759              };
34760
34761              /**
34762               * List all ligatures (lookup type 4) for a given script, language, and feature.
34763               * The result is an array of ligature objects like { sub: [ids], by: id }
34764               * @param {string} feature - 4-letter feature name ('liga', 'rlig', 'dlig'...)
34765               * @param {string} [script='DFLT']
34766               * @param {string} [language='dflt']
34767               * @return {Array} ligatures - The list of ligatures.
34768               */
34769              Substitution.prototype.getLigatures = function(feature, script, language) {
34770                var this$1 = this;
34771
34772                var ligatures = [];
34773                var lookupTables = this.getLookupTables(script, language, feature, 4);
34774                for (var idx = 0; idx < lookupTables.length; idx++) {
34775                  var subtables = lookupTables[idx].subtables;
34776                  for (var i = 0; i < subtables.length; i++) {
34777                    var subtable = subtables[i];
34778                    var glyphs = this$1.expandCoverage(subtable.coverage);
34779                    var ligatureSets = subtable.ligatureSets;
34780                    for (var j = 0; j < glyphs.length; j++) {
34781                      var startGlyph = glyphs[j];
34782                      var ligSet = ligatureSets[j];
34783                      for (var k = 0; k < ligSet.length; k++) {
34784                        var lig = ligSet[k];
34785                        ligatures.push({
34786                          sub: [startGlyph].concat(lig.components),
34787                          by: lig.ligGlyph
34788                        });
34789                      }
34790                    }
34791                  }
34792                }
34793                return ligatures;
34794              };
34795
34796              /**
34797               * Add or modify a single substitution (lookup type 1)
34798               * Format 2, more flexible, is always used.
34799               * @param {string} feature - 4-letter feature name ('liga', 'rlig', 'dlig'...)
34800               * @param {Object} substitution - { sub: id, delta: number } for format 1 or { sub: id, by: id } for format 2.
34801               * @param {string} [script='DFLT']
34802               * @param {string} [language='dflt']
34803               */
34804              Substitution.prototype.addSingle = function(
34805                feature,
34806                substitution,
34807                script,
34808                language
34809              ) {
34810                var lookupTable = this.getLookupTables(
34811                  script,
34812                  language,
34813                  feature,
34814                  1,
34815                  true
34816                )[0];
34817                var subtable = getSubstFormat(lookupTable, 2, {
34818                  // lookup type 1 subtable, format 2, coverage format 1
34819                  substFormat: 2,
34820                  coverage: { format: 1, glyphs: [] },
34821                  substitute: []
34822                });
34823                check.assert(
34824                  subtable.coverage.format === 1,
34825                  'Ligature: unable to modify coverage table format ' +
34826                    subtable.coverage.format
34827                );
34828                var coverageGlyph = substitution.sub;
34829                var pos = this.binSearch(subtable.coverage.glyphs, coverageGlyph);
34830                if (pos < 0) {
34831                  pos = -1 - pos;
34832                  subtable.coverage.glyphs.splice(pos, 0, coverageGlyph);
34833                  subtable.substitute.splice(pos, 0, 0);
34834                }
34835                subtable.substitute[pos] = substitution.by;
34836              };
34837
34838              /**
34839               * Add or modify an alternate substitution (lookup type 1)
34840               * @param {string} feature - 4-letter feature name ('liga', 'rlig', 'dlig'...)
34841               * @param {Object} substitution - { sub: id, by: [ids] }
34842               * @param {string} [script='DFLT']
34843               * @param {string} [language='dflt']
34844               */
34845              Substitution.prototype.addAlternate = function(
34846                feature,
34847                substitution,
34848                script,
34849                language
34850              ) {
34851                var lookupTable = this.getLookupTables(
34852                  script,
34853                  language,
34854                  feature,
34855                  3,
34856                  true
34857                )[0];
34858                var subtable = getSubstFormat(lookupTable, 1, {
34859                  // lookup type 3 subtable, format 1, coverage format 1
34860                  substFormat: 1,
34861                  coverage: { format: 1, glyphs: [] },
34862                  alternateSets: []
34863                });
34864                check.assert(
34865                  subtable.coverage.format === 1,
34866                  'Ligature: unable to modify coverage table format ' +
34867                    subtable.coverage.format
34868                );
34869                var coverageGlyph = substitution.sub;
34870                var pos = this.binSearch(subtable.coverage.glyphs, coverageGlyph);
34871                if (pos < 0) {
34872                  pos = -1 - pos;
34873                  subtable.coverage.glyphs.splice(pos, 0, coverageGlyph);
34874                  subtable.alternateSets.splice(pos, 0, 0);
34875                }
34876                subtable.alternateSets[pos] = substitution.by;
34877              };
34878
34879              /**
34880               * Add a ligature (lookup type 4)
34881               * Ligatures with more components must be stored ahead of those with fewer components in order to be found
34882               * @param {string} feature - 4-letter feature name ('liga', 'rlig', 'dlig'...)
34883               * @param {Object} ligature - { sub: [ids], by: id }
34884               * @param {string} [script='DFLT']
34885               * @param {string} [language='dflt']
34886               */
34887              Substitution.prototype.addLigature = function(
34888                feature,
34889                ligature,
34890                script,
34891                language
34892              ) {
34893                var lookupTable = this.getLookupTables(
34894                  script,
34895                  language,
34896                  feature,
34897                  4,
34898                  true
34899                )[0];
34900                var subtable = lookupTable.subtables[0];
34901                if (!subtable) {
34902                  subtable = {
34903                    // lookup type 4 subtable, format 1, coverage format 1
34904                    substFormat: 1,
34905                    coverage: { format: 1, glyphs: [] },
34906                    ligatureSets: []
34907                  };
34908                  lookupTable.subtables[0] = subtable;
34909                }
34910                check.assert(
34911                  subtable.coverage.format === 1,
34912                  'Ligature: unable to modify coverage table format ' +
34913                    subtable.coverage.format
34914                );
34915                var coverageGlyph = ligature.sub[0];
34916                var ligComponents = ligature.sub.slice(1);
34917                var ligatureTable = {
34918                  ligGlyph: ligature.by,
34919                  components: ligComponents
34920                };
34921                var pos = this.binSearch(subtable.coverage.glyphs, coverageGlyph);
34922                if (pos >= 0) {
34923                  // ligatureSet already exists
34924                  var ligatureSet = subtable.ligatureSets[pos];
34925                  for (var i = 0; i < ligatureSet.length; i++) {
34926                    // If ligature already exists, return.
34927                    if (arraysEqual(ligatureSet[i].components, ligComponents)) {
34928                      return;
34929                    }
34930                  }
34931                  // ligature does not exist: add it.
34932                  ligatureSet.push(ligatureTable);
34933                } else {
34934                  // Create a new ligatureSet and add coverage for the first glyph.
34935                  pos = -1 - pos;
34936                  subtable.coverage.glyphs.splice(pos, 0, coverageGlyph);
34937                  subtable.ligatureSets.splice(pos, 0, [ligatureTable]);
34938                }
34939              };
34940
34941              /**
34942               * List all feature data for a given script and language.
34943               * @param {string} feature - 4-letter feature name
34944               * @param {string} [script='DFLT']
34945               * @param {string} [language='dflt']
34946               * @return {Array} substitutions - The list of substitutions.
34947               */
34948              Substitution.prototype.getFeature = function(feature, script, language) {
34949                if (/ss\d\d/.test(feature)) {
34950                  // ss01 - ss20
34951                  return this.getSingle(feature, script, language);
34952                }
34953                switch (feature) {
34954                  case 'aalt':
34955                  case 'salt':
34956                    return this.getSingle(feature, script, language).concat(
34957                      this.getAlternates(feature, script, language)
34958                    );
34959                  case 'dlig':
34960                  case 'liga':
34961                  case 'rlig':
34962                    return this.getLigatures(feature, script, language);
34963                }
34964                return undefined;
34965              };
34966
34967              /**
34968               * Add a substitution to a feature for a given script and language.
34969               * @param {string} feature - 4-letter feature name
34970               * @param {Object} sub - the substitution to add (an object like { sub: id or [ids], by: id or [ids] })
34971               * @param {string} [script='DFLT']
34972               * @param {string} [language='dflt']
34973               */
34974              Substitution.prototype.add = function(feature, sub, script, language) {
34975                if (/ss\d\d/.test(feature)) {
34976                  // ss01 - ss20
34977                  return this.addSingle(feature, sub, script, language);
34978                }
34979                switch (feature) {
34980                  case 'aalt':
34981                  case 'salt':
34982                    if (typeof sub.by === 'number') {
34983                      return this.addSingle(feature, sub, script, language);
34984                    }
34985                    return this.addAlternate(feature, sub, script, language);
34986                  case 'dlig':
34987                  case 'liga':
34988                  case 'rlig':
34989                    return this.addLigature(feature, sub, script, language);
34990                }
34991                return undefined;
34992              };
34993
34994              function isBrowser() {
34995                return typeof window !== 'undefined';
34996              }
34997
34998              function nodeBufferToArrayBuffer(buffer) {
34999                var ab = new ArrayBuffer(buffer.length);
35000                var view = new Uint8Array(ab);
35001                for (var i = 0; i < buffer.length; ++i) {
35002                  view[i] = buffer[i];
35003                }
35004
35005                return ab;
35006              }
35007
35008              function arrayBufferToNodeBuffer(ab) {
35009                var buffer = new Buffer(ab.byteLength);
35010                var view = new Uint8Array(ab);
35011                for (var i = 0; i < buffer.length; ++i) {
35012                  buffer[i] = view[i];
35013                }
35014
35015                return buffer;
35016              }
35017
35018              function checkArgument(expression, message) {
35019                if (!expression) {
35020                  throw message;
35021                }
35022              }
35023
35024              // The `glyf` table describes the glyphs in TrueType outline format.
35025
35026              // Parse the coordinate data for a glyph.
35027              function parseGlyphCoordinate(
35028                p,
35029                flag,
35030                previousValue,
35031                shortVectorBitMask,
35032                sameBitMask
35033              ) {
35034                var v;
35035                if ((flag & shortVectorBitMask) > 0) {
35036                  // The coordinate is 1 byte long.
35037                  v = p.parseByte();
35038                  // The `same` bit is re-used for short values to signify the sign of the value.
35039                  if ((flag & sameBitMask) === 0) {
35040                    v = -v;
35041                  }
35042
35043                  v = previousValue + v;
35044                } else {
35045                  //  The coordinate is 2 bytes long.
35046                  // If the `same` bit is set, the coordinate is the same as the previous coordinate.
35047                  if ((flag & sameBitMask) > 0) {
35048                    v = previousValue;
35049                  } else {
35050                    // Parse the coordinate as a signed 16-bit delta value.
35051                    v = previousValue + p.parseShort();
35052                  }
35053                }
35054
35055                return v;
35056              }
35057
35058              // Parse a TrueType glyph.
35059              function parseGlyph(glyph, data, start) {
35060                var p = new parse.Parser(data, start);
35061                glyph.numberOfContours = p.parseShort();
35062                glyph._xMin = p.parseShort();
35063                glyph._yMin = p.parseShort();
35064                glyph._xMax = p.parseShort();
35065                glyph._yMax = p.parseShort();
35066                var flags;
35067                var flag;
35068
35069                if (glyph.numberOfContours > 0) {
35070                  // This glyph is not a composite.
35071                  var endPointIndices = (glyph.endPointIndices = []);
35072                  for (var i = 0; i < glyph.numberOfContours; i += 1) {
35073                    endPointIndices.push(p.parseUShort());
35074                  }
35075
35076                  glyph.instructionLength = p.parseUShort();
35077                  glyph.instructions = [];
35078                  for (var i$1 = 0; i$1 < glyph.instructionLength; i$1 += 1) {
35079                    glyph.instructions.push(p.parseByte());
35080                  }
35081
35082                  var numberOfCoordinates = endPointIndices[endPointIndices.length - 1] + 1;
35083                  flags = [];
35084                  for (var i$2 = 0; i$2 < numberOfCoordinates; i$2 += 1) {
35085                    flag = p.parseByte();
35086                    flags.push(flag);
35087                    // If bit 3 is set, we repeat this flag n times, where n is the next byte.
35088                    if ((flag & 8) > 0) {
35089                      var repeatCount = p.parseByte();
35090                      for (var j = 0; j < repeatCount; j += 1) {
35091                        flags.push(flag);
35092                        i$2 += 1;
35093                      }
35094                    }
35095                  }
35096
35097                  check.argument(flags.length === numberOfCoordinates, 'Bad flags.');
35098
35099                  if (endPointIndices.length > 0) {
35100                    var points = [];
35101                    var point;
35102                    // X/Y coordinates are relative to the previous point, except for the first point which is relative to 0,0.
35103                    if (numberOfCoordinates > 0) {
35104                      for (var i$3 = 0; i$3 < numberOfCoordinates; i$3 += 1) {
35105                        flag = flags[i$3];
35106                        point = {};
35107                        point.onCurve = !!(flag & 1);
35108                        point.lastPointOfContour = endPointIndices.indexOf(i$3) >= 0;
35109                        points.push(point);
35110                      }
35111
35112                      var px = 0;
35113                      for (var i$4 = 0; i$4 < numberOfCoordinates; i$4 += 1) {
35114                        flag = flags[i$4];
35115                        point = points[i$4];
35116                        point.x = parseGlyphCoordinate(p, flag, px, 2, 16);
35117                        px = point.x;
35118                      }
35119
35120                      var py = 0;
35121                      for (var i$5 = 0; i$5 < numberOfCoordinates; i$5 += 1) {
35122                        flag = flags[i$5];
35123                        point = points[i$5];
35124                        point.y = parseGlyphCoordinate(p, flag, py, 4, 32);
35125                        py = point.y;
35126                      }
35127                    }
35128
35129                    glyph.points = points;
35130                  } else {
35131                    glyph.points = [];
35132                  }
35133                } else if (glyph.numberOfContours === 0) {
35134                  glyph.points = [];
35135                } else {
35136                  glyph.isComposite = true;
35137                  glyph.points = [];
35138                  glyph.components = [];
35139                  var moreComponents = true;
35140                  while (moreComponents) {
35141                    flags = p.parseUShort();
35142                    var component = {
35143                      glyphIndex: p.parseUShort(),
35144                      xScale: 1,
35145                      scale01: 0,
35146                      scale10: 0,
35147                      yScale: 1,
35148                      dx: 0,
35149                      dy: 0
35150                    };
35151                    if ((flags & 1) > 0) {
35152                      // The arguments are words
35153                      if ((flags & 2) > 0) {
35154                        // values are offset
35155                        component.dx = p.parseShort();
35156                        component.dy = p.parseShort();
35157                      } else {
35158                        // values are matched points
35159                        component.matchedPoints = [p.parseUShort(), p.parseUShort()];
35160                      }
35161                    } else {
35162                      // The arguments are bytes
35163                      if ((flags & 2) > 0) {
35164                        // values are offset
35165                        component.dx = p.parseChar();
35166                        component.dy = p.parseChar();
35167                      } else {
35168                        // values are matched points
35169                        component.matchedPoints = [p.parseByte(), p.parseByte()];
35170                      }
35171                    }
35172
35173                    if ((flags & 8) > 0) {
35174                      // We have a scale
35175                      component.xScale = component.yScale = p.parseF2Dot14();
35176                    } else if ((flags & 64) > 0) {
35177                      // We have an X / Y scale
35178                      component.xScale = p.parseF2Dot14();
35179                      component.yScale = p.parseF2Dot14();
35180                    } else if ((flags & 128) > 0) {
35181                      // We have a 2x2 transformation
35182                      component.xScale = p.parseF2Dot14();
35183                      component.scale01 = p.parseF2Dot14();
35184                      component.scale10 = p.parseF2Dot14();
35185                      component.yScale = p.parseF2Dot14();
35186                    }
35187
35188                    glyph.components.push(component);
35189                    moreComponents = !!(flags & 32);
35190                  }
35191                  if (flags & 0x100) {
35192                    // We have instructions
35193                    glyph.instructionLength = p.parseUShort();
35194                    glyph.instructions = [];
35195                    for (var i$6 = 0; i$6 < glyph.instructionLength; i$6 += 1) {
35196                      glyph.instructions.push(p.parseByte());
35197                    }
35198                  }
35199                }
35200              }
35201
35202              // Transform an array of points and return a new array.
35203              function transformPoints(points, transform) {
35204                var newPoints = [];
35205                for (var i = 0; i < points.length; i += 1) {
35206                  var pt = points[i];
35207                  var newPt = {
35208                    x: transform.xScale * pt.x + transform.scale01 * pt.y + transform.dx,
35209                    y: transform.scale10 * pt.x + transform.yScale * pt.y + transform.dy,
35210                    onCurve: pt.onCurve,
35211                    lastPointOfContour: pt.lastPointOfContour
35212                  };
35213                  newPoints.push(newPt);
35214                }
35215
35216                return newPoints;
35217              }
35218
35219              function getContours(points) {
35220                var contours = [];
35221                var currentContour = [];
35222                for (var i = 0; i < points.length; i += 1) {
35223                  var pt = points[i];
35224                  currentContour.push(pt);
35225                  if (pt.lastPointOfContour) {
35226                    contours.push(currentContour);
35227                    currentContour = [];
35228                  }
35229                }
35230
35231                check.argument(
35232                  currentContour.length === 0,
35233                  'There are still points left in the current contour.'
35234                );
35235                return contours;
35236              }
35237
35238              // Convert the TrueType glyph outline to a Path.
35239              function getPath(points) {
35240                var p = new Path();
35241                if (!points) {
35242                  return p;
35243                }
35244
35245                var contours = getContours(points);
35246
35247                for (var contourIndex = 0; contourIndex < contours.length; ++contourIndex) {
35248                  var contour = contours[contourIndex];
35249
35250                  var prev = null;
35251                  var curr = contour[contour.length - 1];
35252                  var next = contour[0];
35253
35254                  if (curr.onCurve) {
35255                    p.moveTo(curr.x, curr.y);
35256                  } else {
35257                    if (next.onCurve) {
35258                      p.moveTo(next.x, next.y);
35259                    } else {
35260                      // If both first and last points are off-curve, start at their middle.
35261                      var start = {
35262                        x: (curr.x + next.x) * 0.5,
35263                        y: (curr.y + next.y) * 0.5
35264                      };
35265                      p.moveTo(start.x, start.y);
35266                    }
35267                  }
35268
35269                  for (var i = 0; i < contour.length; ++i) {
35270                    prev = curr;
35271                    curr = next;
35272                    next = contour[(i + 1) % contour.length];
35273
35274                    if (curr.onCurve) {
35275                      // This is a straight line.
35276                      p.lineTo(curr.x, curr.y);
35277                    } else {
35278                      var prev2 = prev;
35279                      var next2 = next;
35280
35281                      if (!prev.onCurve) {
35282                        prev2 = { x: (curr.x + prev.x) * 0.5, y: (curr.y + prev.y) * 0.5 };
35283                      }
35284
35285                      if (!next.onCurve) {
35286                        next2 = { x: (curr.x + next.x) * 0.5, y: (curr.y + next.y) * 0.5 };
35287                      }
35288
35289                      p.quadraticCurveTo(curr.x, curr.y, next2.x, next2.y);
35290                    }
35291                  }
35292
35293                  p.closePath();
35294                }
35295                return p;
35296              }
35297
35298              function buildPath(glyphs, glyph) {
35299                if (glyph.isComposite) {
35300                  for (var j = 0; j < glyph.components.length; j += 1) {
35301                    var component = glyph.components[j];
35302                    var componentGlyph = glyphs.get(component.glyphIndex);
35303                    // Force the ttfGlyphLoader to parse the glyph.
35304                    componentGlyph.getPath();
35305                    if (componentGlyph.points) {
35306                      var transformedPoints = void 0;
35307                      if (component.matchedPoints === undefined) {
35308                        // component positioned by offset
35309                        transformedPoints = transformPoints(
35310                          componentGlyph.points,
35311                          component
35312                        );
35313                      } else {
35314                        // component positioned by matched points
35315                        if (
35316                          component.matchedPoints[0] > glyph.points.length - 1 ||
35317                          component.matchedPoints[1] > componentGlyph.points.length - 1
35318                        ) {
35319                          throw Error('Matched points out of range in ' + glyph.name);
35320                        }
35321                        var firstPt = glyph.points[component.matchedPoints[0]];
35322                        var secondPt = componentGlyph.points[component.matchedPoints[1]];
35323                        var transform = {
35324                          xScale: component.xScale,
35325                          scale01: component.scale01,
35326                          scale10: component.scale10,
35327                          yScale: component.yScale,
35328                          dx: 0,
35329                          dy: 0
35330                        };
35331                        secondPt = transformPoints([secondPt], transform)[0];
35332                        transform.dx = firstPt.x - secondPt.x;
35333                        transform.dy = firstPt.y - secondPt.y;
35334                        transformedPoints = transformPoints(
35335                          componentGlyph.points,
35336                          transform
35337                        );
35338                      }
35339                      glyph.points = glyph.points.concat(transformedPoints);
35340                    }
35341                  }
35342                }
35343
35344                return getPath(glyph.points);
35345              }
35346
35347              // Parse all the glyphs according to the offsets from the `loca` table.
35348              function parseGlyfTable(data, start, loca, font) {
35349                var glyphs = new glyphset.GlyphSet(font);
35350
35351                // The last element of the loca table is invalid.
35352                for (var i = 0; i < loca.length - 1; i += 1) {
35353                  var offset = loca[i];
35354                  var nextOffset = loca[i + 1];
35355                  if (offset !== nextOffset) {
35356                    glyphs.push(
35357                      i,
35358                      glyphset.ttfGlyphLoader(
35359                        font,
35360                        i,
35361                        parseGlyph,
35362                        data,
35363                        start + offset,
35364                        buildPath
35365                      )
35366                    );
35367                  } else {
35368                    glyphs.push(i, glyphset.glyphLoader(font, i));
35369                  }
35370                }
35371
35372                return glyphs;
35373              }
35374
35375              var glyf = { getPath: getPath, parse: parseGlyfTable };
35376
35377              /* A TrueType font hinting interpreter.
35378	*
35379	* (c) 2017 Axel Kittenberger
35380	*
35381	* This interpreter has been implemented according to this documentation:
35382	* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM05/Chap5.html
35383	*
35384	* According to the documentation F24DOT6 values are used for pixels.
35385	* That means calculation is 1/64 pixel accurate and uses integer operations.
35386	* However, Javascript has floating point operations by default and only
35387	* those are available. One could make a case to simulate the 1/64 accuracy
35388	* exactly by truncating after every division operation
35389	* (for example with << 0) to get pixel exactly results as other TrueType
35390	* implementations. It may make sense since some fonts are pixel optimized
35391	* by hand using DELTAP instructions. The current implementation doesn't
35392	* and rather uses full floating point precision.
35393	*
35394	* xScale, yScale and rotation is currently ignored.
35395	*
35396	* A few non-trivial instructions are missing as I didn't encounter yet
35397	* a font that used them to test a possible implementation.
35398	*
35399	* Some fonts seem to use undocumented features regarding the twilight zone.
35400	* Only some of them are implemented as they were encountered.
35401	*
35402	* The exports.DEBUG statements are removed on the minified distribution file.
35403	*/
35404
35405              var instructionTable;
35406              var exec;
35407              var execGlyph;
35408              var execComponent;
35409
35410              /*
35411	* Creates a hinting object.
35412	*
35413	* There ought to be exactly one
35414	* for each truetype font that is used for hinting.
35415	*/
35416              function Hinting(font) {
35417                // the font this hinting object is for
35418                this.font = font;
35419
35420                this.getCommands = function(hPoints) {
35421                  return glyf.getPath(hPoints).commands;
35422                };
35423
35424                // cached states
35425                this._fpgmState = this._prepState = undefined;
35426
35427                // errorState
35428                // 0 ... all okay
35429                // 1 ... had an error in a glyf,
35430                //       continue working but stop spamming
35431                //       the console
35432                // 2 ... error at prep, stop hinting at this ppem
35433                // 3 ... error at fpeg, stop hinting for this font at all
35434                this._errorState = 0;
35435              }
35436
35437              /*
35438	* Not rounding.
35439	*/
35440              function roundOff(v) {
35441                return v;
35442              }
35443
35444              /*
35445	* Rounding to grid.
35446	*/
35447              function roundToGrid(v) {
35448                //Rounding in TT is supposed to "symmetrical around zero"
35449                return Math.sign(v) * Math.round(Math.abs(v));
35450              }
35451
35452              /*
35453	* Rounding to double grid.
35454	*/
35455              function roundToDoubleGrid(v) {
35456                return Math.sign(v) * Math.round(Math.abs(v * 2)) / 2;
35457              }
35458
35459              /*
35460	* Rounding to half grid.
35461	*/
35462              function roundToHalfGrid(v) {
35463                return Math.sign(v) * (Math.round(Math.abs(v) + 0.5) - 0.5);
35464              }
35465
35466              /*
35467	* Rounding to up to grid.
35468	*/
35469              function roundUpToGrid(v) {
35470                return Math.sign(v) * Math.ceil(Math.abs(v));
35471              }
35472
35473              /*
35474	* Rounding to down to grid.
35475	*/
35476              function roundDownToGrid(v) {
35477                return Math.sign(v) * Math.floor(Math.abs(v));
35478              }
35479
35480              /*
35481	* Super rounding.
35482	*/
35483              var roundSuper = function(v) {
35484                var period = this.srPeriod;
35485                var phase = this.srPhase;
35486                var threshold = this.srThreshold;
35487                var sign = 1;
35488
35489                if (v < 0) {
35490                  v = -v;
35491                  sign = -1;
35492                }
35493
35494                v += threshold - phase;
35495
35496                v = Math.trunc(v / period) * period;
35497
35498                v += phase;
35499
35500                // according to http://xgridfit.sourceforge.net/round.html
35501                if (v < 0) {
35502                  return phase * sign;
35503                }
35504
35505                return v * sign;
35506              };
35507
35508              /*
35509	* Unit vector of x-axis.
35510	*/
35511              var xUnitVector = {
35512                x: 1,
35513
35514                y: 0,
35515
35516                axis: 'x',
35517
35518                // Gets the projected distance between two points.
35519                // o1/o2 ... if true, respective original position is used.
35520                distance: function(p1, p2, o1, o2) {
35521                  return (o1 ? p1.xo : p1.x) - (o2 ? p2.xo : p2.x);
35522                },
35523
35524                // Moves point p so the moved position has the same relative
35525                // position to the moved positions of rp1 and rp2 than the
35526                // original positions had.
35527                //
35528                // See APPENDIX on INTERPOLATE at the bottom of this file.
35529                interpolate: function(p, rp1, rp2, pv) {
35530                  var do1;
35531                  var do2;
35532                  var doa1;
35533                  var doa2;
35534                  var dm1;
35535                  var dm2;
35536                  var dt;
35537
35538                  if (!pv || pv === this) {
35539                    do1 = p.xo - rp1.xo;
35540                    do2 = p.xo - rp2.xo;
35541                    dm1 = rp1.x - rp1.xo;
35542                    dm2 = rp2.x - rp2.xo;
35543                    doa1 = Math.abs(do1);
35544                    doa2 = Math.abs(do2);
35545                    dt = doa1 + doa2;
35546
35547                    if (dt === 0) {
35548                      p.x = p.xo + (dm1 + dm2) / 2;
35549                      return;
35550                    }
35551
35552                    p.x = p.xo + (dm1 * doa2 + dm2 * doa1) / dt;
35553                    return;
35554                  }
35555
35556                  do1 = pv.distance(p, rp1, true, true);
35557                  do2 = pv.distance(p, rp2, true, true);
35558                  dm1 = pv.distance(rp1, rp1, false, true);
35559                  dm2 = pv.distance(rp2, rp2, false, true);
35560                  doa1 = Math.abs(do1);
35561                  doa2 = Math.abs(do2);
35562                  dt = doa1 + doa2;
35563
35564                  if (dt === 0) {
35565                    xUnitVector.setRelative(p, p, (dm1 + dm2) / 2, pv, true);
35566                    return;
35567                  }
35568
35569                  xUnitVector.setRelative(p, p, (dm1 * doa2 + dm2 * doa1) / dt, pv, true);
35570                },
35571
35572                // Slope of line normal to this
35573                normalSlope: Number.NEGATIVE_INFINITY,
35574
35575                // Sets the point 'p' relative to point 'rp'
35576                // by the distance 'd'.
35577                //
35578                // See APPENDIX on SETRELATIVE at the bottom of this file.
35579                //
35580                // p   ... point to set
35581                // rp  ... reference point
35582                // d   ... distance on projection vector
35583                // pv  ... projection vector (undefined = this)
35584                // org ... if true, uses the original position of rp as reference.
35585                setRelative: function(p, rp, d, pv, org) {
35586                  if (!pv || pv === this) {
35587                    p.x = (org ? rp.xo : rp.x) + d;
35588                    return;
35589                  }
35590
35591                  var rpx = org ? rp.xo : rp.x;
35592                  var rpy = org ? rp.yo : rp.y;
35593                  var rpdx = rpx + d * pv.x;
35594                  var rpdy = rpy + d * pv.y;
35595
35596                  p.x = rpdx + (p.y - rpdy) / pv.normalSlope;
35597                },
35598
35599                // Slope of vector line.
35600                slope: 0,
35601
35602                // Touches the point p.
35603                touch: function(p) {
35604                  p.xTouched = true;
35605                },
35606
35607                // Tests if a point p is touched.
35608                touched: function(p) {
35609                  return p.xTouched;
35610                },
35611
35612                // Untouches the point p.
35613                untouch: function(p) {
35614                  p.xTouched = false;
35615                }
35616              };
35617
35618              /*
35619	* Unit vector of y-axis.
35620	*/
35621              var yUnitVector = {
35622                x: 0,
35623
35624                y: 1,
35625
35626                axis: 'y',
35627
35628                // Gets the projected distance between two points.
35629                // o1/o2 ... if true, respective original position is used.
35630                distance: function(p1, p2, o1, o2) {
35631                  return (o1 ? p1.yo : p1.y) - (o2 ? p2.yo : p2.y);
35632                },
35633
35634                // Moves point p so the moved position has the same relative
35635                // position to the moved positions of rp1 and rp2 than the
35636                // original positions had.
35637                //
35638                // See APPENDIX on INTERPOLATE at the bottom of this file.
35639                interpolate: function(p, rp1, rp2, pv) {
35640                  var do1;
35641                  var do2;
35642                  var doa1;
35643                  var doa2;
35644                  var dm1;
35645                  var dm2;
35646                  var dt;
35647
35648                  if (!pv || pv === this) {
35649                    do1 = p.yo - rp1.yo;
35650                    do2 = p.yo - rp2.yo;
35651                    dm1 = rp1.y - rp1.yo;
35652                    dm2 = rp2.y - rp2.yo;
35653                    doa1 = Math.abs(do1);
35654                    doa2 = Math.abs(do2);
35655                    dt = doa1 + doa2;
35656
35657                    if (dt === 0) {
35658                      p.y = p.yo + (dm1 + dm2) / 2;
35659                      return;
35660                    }
35661
35662                    p.y = p.yo + (dm1 * doa2 + dm2 * doa1) / dt;
35663                    return;
35664                  }
35665
35666                  do1 = pv.distance(p, rp1, true, true);
35667                  do2 = pv.distance(p, rp2, true, true);
35668                  dm1 = pv.distance(rp1, rp1, false, true);
35669                  dm2 = pv.distance(rp2, rp2, false, true);
35670                  doa1 = Math.abs(do1);
35671                  doa2 = Math.abs(do2);
35672                  dt = doa1 + doa2;
35673
35674                  if (dt === 0) {
35675                    yUnitVector.setRelative(p, p, (dm1 + dm2) / 2, pv, true);
35676                    return;
35677                  }
35678
35679                  yUnitVector.setRelative(p, p, (dm1 * doa2 + dm2 * doa1) / dt, pv, true);
35680                },
35681
35682                // Slope of line normal to this.
35683                normalSlope: 0,
35684
35685                // Sets the point 'p' relative to point 'rp'
35686                // by the distance 'd'
35687                //
35688                // See APPENDIX on SETRELATIVE at the bottom of this file.
35689                //
35690                // p   ... point to set
35691                // rp  ... reference point
35692                // d   ... distance on projection vector
35693                // pv  ... projection vector (undefined = this)
35694                // org ... if true, uses the original position of rp as reference.
35695                setRelative: function(p, rp, d, pv, org) {
35696                  if (!pv || pv === this) {
35697                    p.y = (org ? rp.yo : rp.y) + d;
35698                    return;
35699                  }
35700
35701                  var rpx = org ? rp.xo : rp.x;
35702                  var rpy = org ? rp.yo : rp.y;
35703                  var rpdx = rpx + d * pv.x;
35704                  var rpdy = rpy + d * pv.y;
35705
35706                  p.y = rpdy + pv.normalSlope * (p.x - rpdx);
35707                },
35708
35709                // Slope of vector line.
35710                slope: Number.POSITIVE_INFINITY,
35711
35712                // Touches the point p.
35713                touch: function(p) {
35714                  p.yTouched = true;
35715                },
35716
35717                // Tests if a point p is touched.
35718                touched: function(p) {
35719                  return p.yTouched;
35720                },
35721
35722                // Untouches the point p.
35723                untouch: function(p) {
35724                  p.yTouched = false;
35725                }
35726              };
35727
35728              Object.freeze(xUnitVector);
35729              Object.freeze(yUnitVector);
35730
35731              /*
35732	* Creates a unit vector that is not x- or y-axis.
35733	*/
35734              function UnitVector(x, y) {
35735                this.x = x;
35736                this.y = y;
35737                this.axis = undefined;
35738                this.slope = y / x;
35739                this.normalSlope = -x / y;
35740                Object.freeze(this);
35741              }
35742
35743              /*
35744	* Gets the projected distance between two points.
35745	* o1/o2 ... if true, respective original position is used.
35746	*/
35747              UnitVector.prototype.distance = function(p1, p2, o1, o2) {
35748                return (
35749                  this.x * xUnitVector.distance(p1, p2, o1, o2) +
35750                  this.y * yUnitVector.distance(p1, p2, o1, o2)
35751                );
35752              };
35753
35754              /*
35755	* Moves point p so the moved position has the same relative
35756	* position to the moved positions of rp1 and rp2 than the
35757	* original positions had.
35758	*
35759	* See APPENDIX on INTERPOLATE at the bottom of this file.
35760	*/
35761              UnitVector.prototype.interpolate = function(p, rp1, rp2, pv) {
35762                var dm1;
35763                var dm2;
35764                var do1;
35765                var do2;
35766                var doa1;
35767                var doa2;
35768                var dt;
35769
35770                do1 = pv.distance(p, rp1, true, true);
35771                do2 = pv.distance(p, rp2, true, true);
35772                dm1 = pv.distance(rp1, rp1, false, true);
35773                dm2 = pv.distance(rp2, rp2, false, true);
35774                doa1 = Math.abs(do1);
35775                doa2 = Math.abs(do2);
35776                dt = doa1 + doa2;
35777
35778                if (dt === 0) {
35779                  this.setRelative(p, p, (dm1 + dm2) / 2, pv, true);
35780                  return;
35781                }
35782
35783                this.setRelative(p, p, (dm1 * doa2 + dm2 * doa1) / dt, pv, true);
35784              };
35785
35786              /*
35787	* Sets the point 'p' relative to point 'rp'
35788	* by the distance 'd'
35789	*
35790	* See APPENDIX on SETRELATIVE at the bottom of this file.
35791	*
35792	* p   ...  point to set
35793	* rp  ... reference point
35794	* d   ... distance on projection vector
35795	* pv  ... projection vector (undefined = this)
35796	* org ... if true, uses the original position of rp as reference.
35797	*/
35798              UnitVector.prototype.setRelative = function(p, rp, d, pv, org) {
35799                pv = pv || this;
35800
35801                var rpx = org ? rp.xo : rp.x;
35802                var rpy = org ? rp.yo : rp.y;
35803                var rpdx = rpx + d * pv.x;
35804                var rpdy = rpy + d * pv.y;
35805
35806                var pvns = pv.normalSlope;
35807                var fvs = this.slope;
35808
35809                var px = p.x;
35810                var py = p.y;
35811
35812                p.x = (fvs * px - pvns * rpdx + rpdy - py) / (fvs - pvns);
35813                p.y = fvs * (p.x - px) + py;
35814              };
35815
35816              /*
35817	* Touches the point p.
35818	*/
35819              UnitVector.prototype.touch = function(p) {
35820                p.xTouched = true;
35821                p.yTouched = true;
35822              };
35823
35824              /*
35825	* Returns a unit vector with x/y coordinates.
35826	*/
35827              function getUnitVector(x, y) {
35828                var d = Math.sqrt(x * x + y * y);
35829
35830                x /= d;
35831                y /= d;
35832
35833                if (x === 1 && y === 0) {
35834                  return xUnitVector;
35835                } else if (x === 0 && y === 1) {
35836                  return yUnitVector;
35837                } else {
35838                  return new UnitVector(x, y);
35839                }
35840              }
35841
35842              /*
35843	* Creates a point in the hinting engine.
35844	*/
35845              function HPoint(x, y, lastPointOfContour, onCurve) {
35846                this.x = this.xo = Math.round(x * 64) / 64; // hinted x value and original x-value
35847                this.y = this.yo = Math.round(y * 64) / 64; // hinted y value and original y-value
35848
35849                this.lastPointOfContour = lastPointOfContour;
35850                this.onCurve = onCurve;
35851                this.prevPointOnContour = undefined;
35852                this.nextPointOnContour = undefined;
35853                this.xTouched = false;
35854                this.yTouched = false;
35855
35856                Object.preventExtensions(this);
35857              }
35858
35859              /*
35860	* Returns the next touched point on the contour.
35861	*
35862	* v  ... unit vector to test touch axis.
35863	*/
35864              HPoint.prototype.nextTouched = function(v) {
35865                var p = this.nextPointOnContour;
35866
35867                while (!v.touched(p) && p !== this) {
35868                  p = p.nextPointOnContour;
35869                }
35870
35871                return p;
35872              };
35873
35874              /*
35875	* Returns the previous touched point on the contour
35876	*
35877	* v  ... unit vector to test touch axis.
35878	*/
35879              HPoint.prototype.prevTouched = function(v) {
35880                var p = this.prevPointOnContour;
35881
35882                while (!v.touched(p) && p !== this) {
35883                  p = p.prevPointOnContour;
35884                }
35885
35886                return p;
35887              };
35888
35889              /*
35890	* The zero point.
35891	*/
35892              var HPZero = Object.freeze(new HPoint(0, 0));
35893
35894              /*
35895	* The default state of the interpreter.
35896	*
35897	* Note: Freezing the defaultState and then deriving from it
35898	* makes the V8 Javascript engine going awkward,
35899	* so this is avoided, albeit the defaultState shouldn't
35900	* ever change.
35901	*/
35902              var defaultState = {
35903                cvCutIn: 17 / 16, // control value cut in
35904                deltaBase: 9,
35905                deltaShift: 0.125,
35906                loop: 1, // loops some instructions
35907                minDis: 1, // minimum distance
35908                autoFlip: true
35909              };
35910
35911              /*
35912	* The current state of the interpreter.
35913	*
35914	* env  ... 'fpgm' or 'prep' or 'glyf'
35915	* prog ... the program
35916	*/
35917              function State(env, prog) {
35918                this.env = env;
35919                this.stack = [];
35920                this.prog = prog;
35921
35922                switch (env) {
35923                  case 'glyf':
35924                    this.zp0 = this.zp1 = this.zp2 = 1;
35925                    this.rp0 = this.rp1 = this.rp2 = 0;
35926                  /* fall through */
35927                  case 'prep':
35928                    this.fv = this.pv = this.dpv = xUnitVector;
35929                    this.round = roundToGrid;
35930                }
35931              }
35932
35933              /*
35934	* Executes a glyph program.
35935	*
35936	* This does the hinting for each glyph.
35937	*
35938	* Returns an array of moved points.
35939	*
35940	* glyph: the glyph to hint
35941	* ppem: the size the glyph is rendered for
35942	*/
35943              Hinting.prototype.exec = function(glyph, ppem) {
35944                if (typeof ppem !== 'number') {
35945                  throw new Error('Point size is not a number!');
35946                }
35947
35948                // Received a fatal error, don't do any hinting anymore.
35949                if (this._errorState > 2) {
35950                  return;
35951                }
35952
35953                var font = this.font;
35954                var prepState = this._prepState;
35955
35956                if (!prepState || prepState.ppem !== ppem) {
35957                  var fpgmState = this._fpgmState;
35958
35959                  if (!fpgmState) {
35960                    // Executes the fpgm state.
35961                    // This is used by fonts to define functions.
35962                    State.prototype = defaultState;
35963
35964                    fpgmState = this._fpgmState = new State('fpgm', font.tables.fpgm);
35965
35966                    fpgmState.funcs = [];
35967                    fpgmState.font = font;
35968
35969                    if (exports.DEBUG) {
35970                      console.log('---EXEC FPGM---');
35971                      fpgmState.step = -1;
35972                    }
35973
35974                    try {
35975                      exec(fpgmState);
35976                    } catch (e) {
35977                      console.log('Hinting error in FPGM:' + e);
35978                      this._errorState = 3;
35979                      return;
35980                    }
35981                  }
35982
35983                  // Executes the prep program for this ppem setting.
35984                  // This is used by fonts to set cvt values
35985                  // depending on to be rendered font size.
35986
35987                  State.prototype = fpgmState;
35988                  prepState = this._prepState = new State('prep', font.tables.prep);
35989
35990                  prepState.ppem = ppem;
35991
35992                  // Creates a copy of the cvt table
35993                  // and scales it to the current ppem setting.
35994                  var oCvt = font.tables.cvt;
35995                  if (oCvt) {
35996                    var cvt = (prepState.cvt = new Array(oCvt.length));
35997                    var scale = ppem / font.unitsPerEm;
35998                    for (var c = 0; c < oCvt.length; c++) {
35999                      cvt[c] = oCvt[c] * scale;
36000                    }
36001                  } else {
36002                    prepState.cvt = [];
36003                  }
36004
36005                  if (exports.DEBUG) {
36006                    console.log('---EXEC PREP---');
36007                    prepState.step = -1;
36008                  }
36009
36010                  try {
36011                    exec(prepState);
36012                  } catch (e) {
36013                    if (this._errorState < 2) {
36014                      console.log('Hinting error in PREP:' + e);
36015                    }
36016                    this._errorState = 2;
36017                  }
36018                }
36019
36020                if (this._errorState > 1) {
36021                  return;
36022                }
36023
36024                try {
36025                  return execGlyph(glyph, prepState);
36026                } catch (e) {
36027                  if (this._errorState < 1) {
36028                    console.log('Hinting error:' + e);
36029                    console.log('Note: further hinting errors are silenced');
36030                  }
36031                  this._errorState = 1;
36032                  return undefined;
36033                }
36034              };
36035
36036              /*
36037	* Executes the hinting program for a glyph.
36038	*/
36039              execGlyph = function(glyph, prepState) {
36040                // original point positions
36041                var xScale = prepState.ppem / prepState.font.unitsPerEm;
36042                var yScale = xScale;
36043                var components = glyph.components;
36044                var contours;
36045                var gZone;
36046                var state;
36047
36048                State.prototype = prepState;
36049                if (!components) {
36050                  state = new State('glyf', glyph.instructions);
36051                  if (exports.DEBUG) {
36052                    console.log('---EXEC GLYPH---');
36053                    state.step = -1;
36054                  }
36055                  execComponent(glyph, state, xScale, yScale);
36056                  gZone = state.gZone;
36057                } else {
36058                  var font = prepState.font;
36059                  gZone = [];
36060                  contours = [];
36061                  for (var i = 0; i < components.length; i++) {
36062                    var c = components[i];
36063                    var cg = font.glyphs.get(c.glyphIndex);
36064
36065                    state = new State('glyf', cg.instructions);
36066
36067                    if (exports.DEBUG) {
36068                      console.log('---EXEC COMP ' + i + '---');
36069                      state.step = -1;
36070                    }
36071
36072                    execComponent(cg, state, xScale, yScale);
36073                    // appends the computed points to the result array
36074                    // post processes the component points
36075                    var dx = Math.round(c.dx * xScale);
36076                    var dy = Math.round(c.dy * yScale);
36077                    var gz = state.gZone;
36078                    var cc = state.contours;
36079                    for (var pi = 0; pi < gz.length; pi++) {
36080                      var p = gz[pi];
36081                      p.xTouched = p.yTouched = false;
36082                      p.xo = p.x = p.x + dx;
36083                      p.yo = p.y = p.y + dy;
36084                    }
36085
36086                    var gLen = gZone.length;
36087                    gZone.push.apply(gZone, gz);
36088                    for (var j = 0; j < cc.length; j++) {
36089                      contours.push(cc[j] + gLen);
36090                    }
36091                  }
36092
36093                  if (glyph.instructions && !state.inhibitGridFit) {
36094                    // the composite has instructions on its own
36095                    state = new State('glyf', glyph.instructions);
36096
36097                    state.gZone = state.z0 = state.z1 = state.z2 = gZone;
36098
36099                    state.contours = contours;
36100
36101                    // note: HPZero cannot be used here, since
36102                    //       the point might be modified
36103                    gZone.push(
36104                      new HPoint(0, 0),
36105                      new HPoint(Math.round(glyph.advanceWidth * xScale), 0)
36106                    );
36107
36108                    if (exports.DEBUG) {
36109                      console.log('---EXEC COMPOSITE---');
36110                      state.step = -1;
36111                    }
36112
36113                    exec(state);
36114
36115                    gZone.length -= 2;
36116                  }
36117                }
36118
36119                return gZone;
36120              };
36121
36122              /*
36123	* Executes the hinting program for a component of a multi-component glyph
36124	* or of the glyph itself for a non-component glyph.
36125	*/
36126              execComponent = function(glyph, state, xScale, yScale) {
36127                var points = glyph.points || [];
36128                var pLen = points.length;
36129                var gZone = (state.gZone = state.z0 = state.z1 = state.z2 = []);
36130                var contours = (state.contours = []);
36131
36132                // Scales the original points and
36133                // makes copies for the hinted points.
36134                var cp; // current point
36135                for (var i = 0; i < pLen; i++) {
36136                  cp = points[i];
36137
36138                  gZone[i] = new HPoint(
36139                    cp.x * xScale,
36140                    cp.y * yScale,
36141                    cp.lastPointOfContour,
36142                    cp.onCurve
36143                  );
36144                }
36145
36146                // Chain links the contours.
36147                var sp; // start point
36148                var np; // next point
36149
36150                for (var i$1 = 0; i$1 < pLen; i$1++) {
36151                  cp = gZone[i$1];
36152
36153                  if (!sp) {
36154                    sp = cp;
36155                    contours.push(i$1);
36156                  }
36157
36158                  if (cp.lastPointOfContour) {
36159                    cp.nextPointOnContour = sp;
36160                    sp.prevPointOnContour = cp;
36161                    sp = undefined;
36162                  } else {
36163                    np = gZone[i$1 + 1];
36164                    cp.nextPointOnContour = np;
36165                    np.prevPointOnContour = cp;
36166                  }
36167                }
36168
36169                if (state.inhibitGridFit) {
36170                  return;
36171                }
36172
36173                if (exports.DEBUG) {
36174                  console.log('PROCESSING GLYPH', state.stack);
36175                  for (var i$2 = 0; i$2 < pLen; i$2++) {
36176                    console.log(i$2, gZone[i$2].x, gZone[i$2].y);
36177                  }
36178                }
36179
36180                gZone.push(
36181                  new HPoint(0, 0),
36182                  new HPoint(Math.round(glyph.advanceWidth * xScale), 0)
36183                );
36184
36185                exec(state);
36186
36187                // Removes the extra points.
36188                gZone.length -= 2;
36189
36190                if (exports.DEBUG) {
36191                  console.log('FINISHED GLYPH', state.stack);
36192                  for (var i$3 = 0; i$3 < pLen; i$3++) {
36193                    console.log(i$3, gZone[i$3].x, gZone[i$3].y);
36194                  }
36195                }
36196              };
36197
36198              /*
36199	* Executes the program loaded in state.
36200	*/
36201              exec = function(state) {
36202                var prog = state.prog;
36203
36204                if (!prog) {
36205                  return;
36206                }
36207
36208                var pLen = prog.length;
36209                var ins;
36210
36211                for (state.ip = 0; state.ip < pLen; state.ip++) {
36212                  if (exports.DEBUG) {
36213                    state.step++;
36214                  }
36215                  ins = instructionTable[prog[state.ip]];
36216
36217                  if (!ins) {
36218                    throw new Error(
36219                      'unknown instruction: 0x' + Number(prog[state.ip]).toString(16)
36220                    );
36221                  }
36222
36223                  ins(state);
36224
36225                  // very extensive debugging for each step
36226                  /*
36227	        if (exports.DEBUG) {
36228	            var da;
36229	            if (state.gZone) {
36230	                da = [];
36231	                for (let i = 0; i < state.gZone.length; i++)
36232	                {
36233	                    da.push(i + ' ' +
36234	                        state.gZone[i].x * 64 + ' ' +
36235	                        state.gZone[i].y * 64 + ' ' +
36236	                        (state.gZone[i].xTouched ? 'x' : '') +
36237	                        (state.gZone[i].yTouched ? 'y' : '')
36238	                    );
36239	                }
36240	                console.log('GZ', da);
36241	            }
36242
36243	            if (state.tZone) {
36244	                da = [];
36245	                for (let i = 0; i < state.tZone.length; i++) {
36246	                    da.push(i + ' ' +
36247	                        state.tZone[i].x * 64 + ' ' +
36248	                        state.tZone[i].y * 64 + ' ' +
36249	                        (state.tZone[i].xTouched ? 'x' : '') +
36250	                        (state.tZone[i].yTouched ? 'y' : '')
36251	                    );
36252	                }
36253	                console.log('TZ', da);
36254	            }
36255
36256	            if (state.stack.length > 10) {
36257	                console.log(
36258	                    state.stack.length,
36259	                    '...', state.stack.slice(state.stack.length - 10)
36260	                );
36261	            } else {
36262	                console.log(state.stack.length, state.stack);
36263	            }
36264	        }
36265	        */
36266                }
36267              };
36268
36269              /*
36270	* Initializes the twilight zone.
36271	*
36272	* This is only done if a SZPx instruction
36273	* refers to the twilight zone.
36274	*/
36275              function initTZone(state) {
36276                var tZone = (state.tZone = new Array(state.gZone.length));
36277
36278                // no idea if this is actually correct...
36279                for (var i = 0; i < tZone.length; i++) {
36280                  tZone[i] = new HPoint(0, 0);
36281                }
36282              }
36283
36284              /*
36285	* Skips the instruction pointer ahead over an IF/ELSE block.
36286	* handleElse .. if true breaks on matching ELSE
36287	*/
36288              function skip(state, handleElse) {
36289                var prog = state.prog;
36290                var ip = state.ip;
36291                var nesting = 1;
36292                var ins;
36293
36294                do {
36295                  ins = prog[++ip];
36296                  if (ins === 0x58) {
36297                    // IF
36298                    nesting++;
36299                  } else if (ins === 0x59) {
36300                    // EIF
36301                    nesting--;
36302                  } else if (ins === 0x40) {
36303                    // NPUSHB
36304                    ip += prog[ip + 1] + 1;
36305                  } else if (ins === 0x41) {
36306                    // NPUSHW
36307                    ip += 2 * prog[ip + 1] + 1;
36308                  } else if (ins >= 0xb0 && ins <= 0xb7) {
36309                    // PUSHB
36310                    ip += ins - 0xb0 + 1;
36311                  } else if (ins >= 0xb8 && ins <= 0xbf) {
36312                    // PUSHW
36313                    ip += (ins - 0xb8 + 1) * 2;
36314                  } else if (handleElse && nesting === 1 && ins === 0x1b) {
36315                    // ELSE
36316                    break;
36317                  }
36318                } while (nesting > 0);
36319
36320                state.ip = ip;
36321              }
36322
36323              /*----------------------------------------------------------*
36324	*          And then a lot of instructions...                *
36325	*----------------------------------------------------------*/
36326
36327              // SVTCA[a] Set freedom and projection Vectors To Coordinate Axis
36328              // 0x00-0x01
36329              function SVTCA(v, state) {
36330                if (exports.DEBUG) {
36331                  console.log(state.step, 'SVTCA[' + v.axis + ']');
36332                }
36333
36334                state.fv = state.pv = state.dpv = v;
36335              }
36336
36337              // SPVTCA[a] Set Projection Vector to Coordinate Axis
36338              // 0x02-0x03
36339              function SPVTCA(v, state) {
36340                if (exports.DEBUG) {
36341                  console.log(state.step, 'SPVTCA[' + v.axis + ']');
36342                }
36343
36344                state.pv = state.dpv = v;
36345              }
36346
36347              // SFVTCA[a] Set Freedom Vector to Coordinate Axis
36348              // 0x04-0x05
36349              function SFVTCA(v, state) {
36350                if (exports.DEBUG) {
36351                  console.log(state.step, 'SFVTCA[' + v.axis + ']');
36352                }
36353
36354                state.fv = v;
36355              }
36356
36357              // SPVTL[a] Set Projection Vector To Line
36358              // 0x06-0x07
36359              function SPVTL(a, state) {
36360                var stack = state.stack;
36361                var p2i = stack.pop();
36362                var p1i = stack.pop();
36363                var p2 = state.z2[p2i];
36364                var p1 = state.z1[p1i];
36365
36366                if (exports.DEBUG) {
36367                  console.log('SPVTL[' + a + ']', p2i, p1i);
36368                }
36369
36370                var dx;
36371                var dy;
36372
36373                if (!a) {
36374                  dx = p1.x - p2.x;
36375                  dy = p1.y - p2.y;
36376                } else {
36377                  dx = p2.y - p1.y;
36378                  dy = p1.x - p2.x;
36379                }
36380
36381                state.pv = state.dpv = getUnitVector(dx, dy);
36382              }
36383
36384              // SFVTL[a] Set Freedom Vector To Line
36385              // 0x08-0x09
36386              function SFVTL(a, state) {
36387                var stack = state.stack;
36388                var p2i = stack.pop();
36389                var p1i = stack.pop();
36390                var p2 = state.z2[p2i];
36391                var p1 = state.z1[p1i];
36392
36393                if (exports.DEBUG) {
36394                  console.log('SFVTL[' + a + ']', p2i, p1i);
36395                }
36396
36397                var dx;
36398                var dy;
36399
36400                if (!a) {
36401                  dx = p1.x - p2.x;
36402                  dy = p1.y - p2.y;
36403                } else {
36404                  dx = p2.y - p1.y;
36405                  dy = p1.x - p2.x;
36406                }
36407
36408                state.fv = getUnitVector(dx, dy);
36409              }
36410
36411              // SPVFS[] Set Projection Vector From Stack
36412              // 0x0A
36413              function SPVFS(state) {
36414                var stack = state.stack;
36415                var y = stack.pop();
36416                var x = stack.pop();
36417
36418                if (exports.DEBUG) {
36419                  console.log(state.step, 'SPVFS[]', y, x);
36420                }
36421
36422                state.pv = state.dpv = getUnitVector(x, y);
36423              }
36424
36425              // SFVFS[] Set Freedom Vector From Stack
36426              // 0x0B
36427              function SFVFS(state) {
36428                var stack = state.stack;
36429                var y = stack.pop();
36430                var x = stack.pop();
36431
36432                if (exports.DEBUG) {
36433                  console.log(state.step, 'SPVFS[]', y, x);
36434                }
36435
36436                state.fv = getUnitVector(x, y);
36437              }
36438
36439              // GPV[] Get Projection Vector
36440              // 0x0C
36441              function GPV(state) {
36442                var stack = state.stack;
36443                var pv = state.pv;
36444
36445                if (exports.DEBUG) {
36446                  console.log(state.step, 'GPV[]');
36447                }
36448
36449                stack.push(pv.x * 0x4000);
36450                stack.push(pv.y * 0x4000);
36451              }
36452
36453              // GFV[] Get Freedom Vector
36454              // 0x0C
36455              function GFV(state) {
36456                var stack = state.stack;
36457                var fv = state.fv;
36458
36459                if (exports.DEBUG) {
36460                  console.log(state.step, 'GFV[]');
36461                }
36462
36463                stack.push(fv.x * 0x4000);
36464                stack.push(fv.y * 0x4000);
36465              }
36466
36467              // SFVTPV[] Set Freedom Vector To Projection Vector
36468              // 0x0E
36469              function SFVTPV(state) {
36470                state.fv = state.pv;
36471
36472                if (exports.DEBUG) {
36473                  console.log(state.step, 'SFVTPV[]');
36474                }
36475              }
36476
36477              // ISECT[] moves point p to the InterSECTion of two lines
36478              // 0x0F
36479              function ISECT(state) {
36480                var stack = state.stack;
36481                var pa0i = stack.pop();
36482                var pa1i = stack.pop();
36483                var pb0i = stack.pop();
36484                var pb1i = stack.pop();
36485                var pi = stack.pop();
36486                var z0 = state.z0;
36487                var z1 = state.z1;
36488                var pa0 = z0[pa0i];
36489                var pa1 = z0[pa1i];
36490                var pb0 = z1[pb0i];
36491                var pb1 = z1[pb1i];
36492                var p = state.z2[pi];
36493
36494                if (exports.DEBUG) {
36495                  console.log('ISECT[], ', pa0i, pa1i, pb0i, pb1i, pi);
36496                }
36497
36498                // math from
36499                // en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_two_points_on_each_line
36500
36501                var x1 = pa0.x;
36502                var y1 = pa0.y;
36503                var x2 = pa1.x;
36504                var y2 = pa1.y;
36505                var x3 = pb0.x;
36506                var y3 = pb0.y;
36507                var x4 = pb1.x;
36508                var y4 = pb1.y;
36509
36510                var div = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
36511                var f1 = x1 * y2 - y1 * x2;
36512                var f2 = x3 * y4 - y3 * x4;
36513
36514                p.x = (f1 * (x3 - x4) - f2 * (x1 - x2)) / div;
36515                p.y = (f1 * (y3 - y4) - f2 * (y1 - y2)) / div;
36516              }
36517
36518              // SRP0[] Set Reference Point 0
36519              // 0x10
36520              function SRP0(state) {
36521                state.rp0 = state.stack.pop();
36522
36523                if (exports.DEBUG) {
36524                  console.log(state.step, 'SRP0[]', state.rp0);
36525                }
36526              }
36527
36528              // SRP1[] Set Reference Point 1
36529              // 0x11
36530              function SRP1(state) {
36531                state.rp1 = state.stack.pop();
36532
36533                if (exports.DEBUG) {
36534                  console.log(state.step, 'SRP1[]', state.rp1);
36535                }
36536              }
36537
36538              // SRP1[] Set Reference Point 2
36539              // 0x12
36540              function SRP2(state) {
36541                state.rp2 = state.stack.pop();
36542
36543                if (exports.DEBUG) {
36544                  console.log(state.step, 'SRP2[]', state.rp2);
36545                }
36546              }
36547
36548              // SZP0[] Set Zone Pointer 0
36549              // 0x13
36550              function SZP0(state) {
36551                var n = state.stack.pop();
36552
36553                if (exports.DEBUG) {
36554                  console.log(state.step, 'SZP0[]', n);
36555                }
36556
36557                state.zp0 = n;
36558
36559                switch (n) {
36560                  case 0:
36561                    if (!state.tZone) {
36562                      initTZone(state);
36563                    }
36564                    state.z0 = state.tZone;
36565                    break;
36566                  case 1:
36567                    state.z0 = state.gZone;
36568                    break;
36569                  default:
36570                    throw new Error('Invalid zone pointer');
36571                }
36572              }
36573
36574              // SZP1[] Set Zone Pointer 1
36575              // 0x14
36576              function SZP1(state) {
36577                var n = state.stack.pop();
36578
36579                if (exports.DEBUG) {
36580                  console.log(state.step, 'SZP1[]', n);
36581                }
36582
36583                state.zp1 = n;
36584
36585                switch (n) {
36586                  case 0:
36587                    if (!state.tZone) {
36588                      initTZone(state);
36589                    }
36590                    state.z1 = state.tZone;
36591                    break;
36592                  case 1:
36593                    state.z1 = state.gZone;
36594                    break;
36595                  default:
36596                    throw new Error('Invalid zone pointer');
36597                }
36598              }
36599
36600              // SZP2[] Set Zone Pointer 2
36601              // 0x15
36602              function SZP2(state) {
36603                var n = state.stack.pop();
36604
36605                if (exports.DEBUG) {
36606                  console.log(state.step, 'SZP2[]', n);
36607                }
36608
36609                state.zp2 = n;
36610
36611                switch (n) {
36612                  case 0:
36613                    if (!state.tZone) {
36614                      initTZone(state);
36615                    }
36616                    state.z2 = state.tZone;
36617                    break;
36618                  case 1:
36619                    state.z2 = state.gZone;
36620                    break;
36621                  default:
36622                    throw new Error('Invalid zone pointer');
36623                }
36624              }
36625
36626              // SZPS[] Set Zone PointerS
36627              // 0x16
36628              function SZPS(state) {
36629                var n = state.stack.pop();
36630
36631                if (exports.DEBUG) {
36632                  console.log(state.step, 'SZPS[]', n);
36633                }
36634
36635                state.zp0 = state.zp1 = state.zp2 = n;
36636
36637                switch (n) {
36638                  case 0:
36639                    if (!state.tZone) {
36640                      initTZone(state);
36641                    }
36642                    state.z0 = state.z1 = state.z2 = state.tZone;
36643                    break;
36644                  case 1:
36645                    state.z0 = state.z1 = state.z2 = state.gZone;
36646                    break;
36647                  default:
36648                    throw new Error('Invalid zone pointer');
36649                }
36650              }
36651
36652              // SLOOP[] Set LOOP variable
36653              // 0x17
36654              function SLOOP(state) {
36655                state.loop = state.stack.pop();
36656
36657                if (exports.DEBUG) {
36658                  console.log(state.step, 'SLOOP[]', state.loop);
36659                }
36660              }
36661
36662              // RTG[] Round To Grid
36663              // 0x18
36664              function RTG(state) {
36665                if (exports.DEBUG) {
36666                  console.log(state.step, 'RTG[]');
36667                }
36668
36669                state.round = roundToGrid;
36670              }
36671
36672              // RTHG[] Round To Half Grid
36673              // 0x19
36674              function RTHG(state) {
36675                if (exports.DEBUG) {
36676                  console.log(state.step, 'RTHG[]');
36677                }
36678
36679                state.round = roundToHalfGrid;
36680              }
36681
36682              // SMD[] Set Minimum Distance
36683              // 0x1A
36684              function SMD(state) {
36685                var d = state.stack.pop();
36686
36687                if (exports.DEBUG) {
36688                  console.log(state.step, 'SMD[]', d);
36689                }
36690
36691                state.minDis = d / 0x40;
36692              }
36693
36694              // ELSE[] ELSE clause
36695              // 0x1B
36696              function ELSE(state) {
36697                // This instruction has been reached by executing a then branch
36698                // so it just skips ahead until matching EIF.
36699                //
36700                // In case the IF was negative the IF[] instruction already
36701                // skipped forward over the ELSE[]
36702
36703                if (exports.DEBUG) {
36704                  console.log(state.step, 'ELSE[]');
36705                }
36706
36707                skip(state, false);
36708              }
36709
36710              // JMPR[] JuMP Relative
36711              // 0x1C
36712              function JMPR(state) {
36713                var o = state.stack.pop();
36714
36715                if (exports.DEBUG) {
36716                  console.log(state.step, 'JMPR[]', o);
36717                }
36718
36719                // A jump by 1 would do nothing.
36720                state.ip += o - 1;
36721              }
36722
36723              // SCVTCI[] Set Control Value Table Cut-In
36724              // 0x1D
36725              function SCVTCI(state) {
36726                var n = state.stack.pop();
36727
36728                if (exports.DEBUG) {
36729                  console.log(state.step, 'SCVTCI[]', n);
36730                }
36731
36732                state.cvCutIn = n / 0x40;
36733              }
36734
36735              // DUP[] DUPlicate top stack element
36736              // 0x20
36737              function DUP(state) {
36738                var stack = state.stack;
36739
36740                if (exports.DEBUG) {
36741                  console.log(state.step, 'DUP[]');
36742                }
36743
36744                stack.push(stack[stack.length - 1]);
36745              }
36746
36747              // POP[] POP top stack element
36748              // 0x21
36749              function POP(state) {
36750                if (exports.DEBUG) {
36751                  console.log(state.step, 'POP[]');
36752                }
36753
36754                state.stack.pop();
36755              }
36756
36757              // CLEAR[] CLEAR the stack
36758              // 0x22
36759              function CLEAR(state) {
36760                if (exports.DEBUG) {
36761                  console.log(state.step, 'CLEAR[]');
36762                }
36763
36764                state.stack.length = 0;
36765              }
36766
36767              // SWAP[] SWAP the top two elements on the stack
36768              // 0x23
36769              function SWAP(state) {
36770                var stack = state.stack;
36771
36772                var a = stack.pop();
36773                var b = stack.pop();
36774
36775                if (exports.DEBUG) {
36776                  console.log(state.step, 'SWAP[]');
36777                }
36778
36779                stack.push(a);
36780                stack.push(b);
36781              }
36782
36783              // DEPTH[] DEPTH of the stack
36784              // 0x24
36785              function DEPTH(state) {
36786                var stack = state.stack;
36787
36788                if (exports.DEBUG) {
36789                  console.log(state.step, 'DEPTH[]');
36790                }
36791
36792                stack.push(stack.length);
36793              }
36794
36795              // LOOPCALL[] LOOPCALL function
36796              // 0x2A
36797              function LOOPCALL(state) {
36798                var stack = state.stack;
36799                var fn = stack.pop();
36800                var c = stack.pop();
36801
36802                if (exports.DEBUG) {
36803                  console.log(state.step, 'LOOPCALL[]', fn, c);
36804                }
36805
36806                // saves callers program
36807                var cip = state.ip;
36808                var cprog = state.prog;
36809
36810                state.prog = state.funcs[fn];
36811
36812                // executes the function
36813                for (var i = 0; i < c; i++) {
36814                  exec(state);
36815
36816                  if (exports.DEBUG) {
36817                    console.log(
36818                      ++state.step,
36819                      i + 1 < c ? 'next loopcall' : 'done loopcall',
36820                      i
36821                    );
36822                  }
36823                }
36824
36825                // restores the callers program
36826                state.ip = cip;
36827                state.prog = cprog;
36828              }
36829
36830              // CALL[] CALL function
36831              // 0x2B
36832              function CALL(state) {
36833                var fn = state.stack.pop();
36834
36835                if (exports.DEBUG) {
36836                  console.log(state.step, 'CALL[]', fn);
36837                }
36838
36839                // saves callers program
36840                var cip = state.ip;
36841                var cprog = state.prog;
36842
36843                state.prog = state.funcs[fn];
36844
36845                // executes the function
36846                exec(state);
36847
36848                // restores the callers program
36849                state.ip = cip;
36850                state.prog = cprog;
36851
36852                if (exports.DEBUG) {
36853                  console.log(++state.step, 'returning from', fn);
36854                }
36855              }
36856
36857              // CINDEX[] Copy the INDEXed element to the top of the stack
36858              // 0x25
36859              function CINDEX(state) {
36860                var stack = state.stack;
36861                var k = stack.pop();
36862
36863                if (exports.DEBUG) {
36864                  console.log(state.step, 'CINDEX[]', k);
36865                }
36866
36867                // In case of k == 1, it copies the last element after popping
36868                // thus stack.length - k.
36869                stack.push(stack[stack.length - k]);
36870              }
36871
36872              // MINDEX[] Move the INDEXed element to the top of the stack
36873              // 0x26
36874              function MINDEX(state) {
36875                var stack = state.stack;
36876                var k = stack.pop();
36877
36878                if (exports.DEBUG) {
36879                  console.log(state.step, 'MINDEX[]', k);
36880                }
36881
36882                stack.push(stack.splice(stack.length - k, 1)[0]);
36883              }
36884
36885              // FDEF[] Function DEFinition
36886              // 0x2C
36887              function FDEF(state) {
36888                if (state.env !== 'fpgm') {
36889                  throw new Error('FDEF not allowed here');
36890                }
36891                var stack = state.stack;
36892                var prog = state.prog;
36893                var ip = state.ip;
36894
36895                var fn = stack.pop();
36896                var ipBegin = ip;
36897
36898                if (exports.DEBUG) {
36899                  console.log(state.step, 'FDEF[]', fn);
36900                }
36901
36902                while (prog[++ip] !== 0x2d) {}
36903
36904                state.ip = ip;
36905                state.funcs[fn] = prog.slice(ipBegin + 1, ip);
36906              }
36907
36908              // MDAP[a] Move Direct Absolute Point
36909              // 0x2E-0x2F
36910              function MDAP(round, state) {
36911                var pi = state.stack.pop();
36912                var p = state.z0[pi];
36913                var fv = state.fv;
36914                var pv = state.pv;
36915
36916                if (exports.DEBUG) {
36917                  console.log(state.step, 'MDAP[' + round + ']', pi);
36918                }
36919
36920                var d = pv.distance(p, HPZero);
36921
36922                if (round) {
36923                  d = state.round(d);
36924                }
36925
36926                fv.setRelative(p, HPZero, d, pv);
36927                fv.touch(p);
36928
36929                state.rp0 = state.rp1 = pi;
36930              }
36931
36932              // IUP[a] Interpolate Untouched Points through the outline
36933              // 0x30
36934              function IUP(v, state) {
36935                var z2 = state.z2;
36936                var pLen = z2.length - 2;
36937                var cp;
36938                var pp;
36939                var np;
36940
36941                if (exports.DEBUG) {
36942                  console.log(state.step, 'IUP[' + v.axis + ']');
36943                }
36944
36945                for (var i = 0; i < pLen; i++) {
36946                  cp = z2[i]; // current point
36947
36948                  // if this point has been touched go on
36949                  if (v.touched(cp)) {
36950                    continue;
36951                  }
36952
36953                  pp = cp.prevTouched(v);
36954
36955                  // no point on the contour has been touched?
36956                  if (pp === cp) {
36957                    continue;
36958                  }
36959
36960                  np = cp.nextTouched(v);
36961
36962                  if (pp === np) {
36963                    // only one point on the contour has been touched
36964                    // so simply moves the point like that
36965
36966                    v.setRelative(cp, cp, v.distance(pp, pp, false, true), v, true);
36967                  }
36968
36969                  v.interpolate(cp, pp, np, v);
36970                }
36971              }
36972
36973              // SHP[] SHift Point using reference point
36974              // 0x32-0x33
36975              function SHP(a, state) {
36976                var stack = state.stack;
36977                var rpi = a ? state.rp1 : state.rp2;
36978                var rp = (a ? state.z0 : state.z1)[rpi];
36979                var fv = state.fv;
36980                var pv = state.pv;
36981                var loop = state.loop;
36982                var z2 = state.z2;
36983
36984                while (loop--) {
36985                  var pi = stack.pop();
36986                  var p = z2[pi];
36987
36988                  var d = pv.distance(rp, rp, false, true);
36989                  fv.setRelative(p, p, d, pv);
36990                  fv.touch(p);
36991
36992                  if (exports.DEBUG) {
36993                    console.log(
36994                      state.step,
36995                      (state.loop > 1 ? 'loop ' + (state.loop - loop) + ': ' : '') +
36996                        'SHP[' +
36997                        (a ? 'rp1' : 'rp2') +
36998                        ']',
36999                      pi
37000                    );
37001                  }
37002                }
37003
37004                state.loop = 1;
37005              }
37006
37007              // SHC[] SHift Contour using reference point
37008              // 0x36-0x37
37009              function SHC(a, state) {
37010                var stack = state.stack;
37011                var rpi = a ? state.rp1 : state.rp2;
37012                var rp = (a ? state.z0 : state.z1)[rpi];
37013                var fv = state.fv;
37014                var pv = state.pv;
37015                var ci = stack.pop();
37016                var sp = state.z2[state.contours[ci]];
37017                var p = sp;
37018
37019                if (exports.DEBUG) {
37020                  console.log(state.step, 'SHC[' + a + ']', ci);
37021                }
37022
37023                var d = pv.distance(rp, rp, false, true);
37024
37025                do {
37026                  if (p !== rp) {
37027                    fv.setRelative(p, p, d, pv);
37028                  }
37029                  p = p.nextPointOnContour;
37030                } while (p !== sp);
37031              }
37032
37033              // SHZ[] SHift Zone using reference point
37034              // 0x36-0x37
37035              function SHZ(a, state) {
37036                var stack = state.stack;
37037                var rpi = a ? state.rp1 : state.rp2;
37038                var rp = (a ? state.z0 : state.z1)[rpi];
37039                var fv = state.fv;
37040                var pv = state.pv;
37041
37042                var e = stack.pop();
37043
37044                if (exports.DEBUG) {
37045                  console.log(state.step, 'SHZ[' + a + ']', e);
37046                }
37047
37048                var z;
37049                switch (e) {
37050                  case 0:
37051                    z = state.tZone;
37052                    break;
37053                  case 1:
37054                    z = state.gZone;
37055                    break;
37056                  default:
37057                    throw new Error('Invalid zone');
37058                }
37059
37060                var p;
37061                var d = pv.distance(rp, rp, false, true);
37062                var pLen = z.length - 2;
37063                for (var i = 0; i < pLen; i++) {
37064                  p = z[i];
37065                  fv.setRelative(p, p, d, pv);
37066                  //if (p !== rp) fv.setRelative(p, p, d, pv);
37067                }
37068              }
37069
37070              // SHPIX[] SHift point by a PIXel amount
37071              // 0x38
37072              function SHPIX(state) {
37073                var stack = state.stack;
37074                var loop = state.loop;
37075                var fv = state.fv;
37076                var d = stack.pop() / 0x40;
37077                var z2 = state.z2;
37078
37079                while (loop--) {
37080                  var pi = stack.pop();
37081                  var p = z2[pi];
37082
37083                  if (exports.DEBUG) {
37084                    console.log(
37085                      state.step,
37086                      (state.loop > 1 ? 'loop ' + (state.loop - loop) + ': ' : '') +
37087                        'SHPIX[]',
37088                      pi,
37089                      d
37090                    );
37091                  }
37092
37093                  fv.setRelative(p, p, d);
37094                  fv.touch(p);
37095                }
37096
37097                state.loop = 1;
37098              }
37099
37100              // IP[] Interpolate Point
37101              // 0x39
37102              function IP(state) {
37103                var stack = state.stack;
37104                var rp1i = state.rp1;
37105                var rp2i = state.rp2;
37106                var loop = state.loop;
37107                var rp1 = state.z0[rp1i];
37108                var rp2 = state.z1[rp2i];
37109                var fv = state.fv;
37110                var pv = state.dpv;
37111                var z2 = state.z2;
37112
37113                while (loop--) {
37114                  var pi = stack.pop();
37115                  var p = z2[pi];
37116
37117                  if (exports.DEBUG) {
37118                    console.log(
37119                      state.step,
37120                      (state.loop > 1 ? 'loop ' + (state.loop - loop) + ': ' : '') + 'IP[]',
37121                      pi,
37122                      rp1i,
37123                      '<->',
37124                      rp2i
37125                    );
37126                  }
37127
37128                  fv.interpolate(p, rp1, rp2, pv);
37129
37130                  fv.touch(p);
37131                }
37132
37133                state.loop = 1;
37134              }
37135
37136              // MSIRP[a] Move Stack Indirect Relative Point
37137              // 0x3A-0x3B
37138              function MSIRP(a, state) {
37139                var stack = state.stack;
37140                var d = stack.pop() / 64;
37141                var pi = stack.pop();
37142                var p = state.z1[pi];
37143                var rp0 = state.z0[state.rp0];
37144                var fv = state.fv;
37145                var pv = state.pv;
37146
37147                fv.setRelative(p, rp0, d, pv);
37148                fv.touch(p);
37149
37150                if (exports.DEBUG) {
37151                  console.log(state.step, 'MSIRP[' + a + ']', d, pi);
37152                }
37153
37154                state.rp1 = state.rp0;
37155                state.rp2 = pi;
37156                if (a) {
37157                  state.rp0 = pi;
37158                }
37159              }
37160
37161              // ALIGNRP[] Align to reference point.
37162              // 0x3C
37163              function ALIGNRP(state) {
37164                var stack = state.stack;
37165                var rp0i = state.rp0;
37166                var rp0 = state.z0[rp0i];
37167                var loop = state.loop;
37168                var fv = state.fv;
37169                var pv = state.pv;
37170                var z1 = state.z1;
37171
37172                while (loop--) {
37173                  var pi = stack.pop();
37174                  var p = z1[pi];
37175
37176                  if (exports.DEBUG) {
37177                    console.log(
37178                      state.step,
37179                      (state.loop > 1 ? 'loop ' + (state.loop - loop) + ': ' : '') +
37180                        'ALIGNRP[]',
37181                      pi
37182                    );
37183                  }
37184
37185                  fv.setRelative(p, rp0, 0, pv);
37186                  fv.touch(p);
37187                }
37188
37189                state.loop = 1;
37190              }
37191
37192              // RTG[] Round To Double Grid
37193              // 0x3D
37194              function RTDG(state) {
37195                if (exports.DEBUG) {
37196                  console.log(state.step, 'RTDG[]');
37197                }
37198
37199                state.round = roundToDoubleGrid;
37200              }
37201
37202              // MIAP[a] Move Indirect Absolute Point
37203              // 0x3E-0x3F
37204              function MIAP(round, state) {
37205                var stack = state.stack;
37206                var n = stack.pop();
37207                var pi = stack.pop();
37208                var p = state.z0[pi];
37209                var fv = state.fv;
37210                var pv = state.pv;
37211                var cv = state.cvt[n];
37212
37213                if (exports.DEBUG) {
37214                  console.log(state.step, 'MIAP[' + round + ']', n, '(', cv, ')', pi);
37215                }
37216
37217                var d = pv.distance(p, HPZero);
37218
37219                if (round) {
37220                  if (Math.abs(d - cv) < state.cvCutIn) {
37221                    d = cv;
37222                  }
37223
37224                  d = state.round(d);
37225                }
37226
37227                fv.setRelative(p, HPZero, d, pv);
37228
37229                if (state.zp0 === 0) {
37230                  p.xo = p.x;
37231                  p.yo = p.y;
37232                }
37233
37234                fv.touch(p);
37235
37236                state.rp0 = state.rp1 = pi;
37237              }
37238
37239              // NPUSB[] PUSH N Bytes
37240              // 0x40
37241              function NPUSHB(state) {
37242                var prog = state.prog;
37243                var ip = state.ip;
37244                var stack = state.stack;
37245
37246                var n = prog[++ip];
37247
37248                if (exports.DEBUG) {
37249                  console.log(state.step, 'NPUSHB[]', n);
37250                }
37251
37252                for (var i = 0; i < n; i++) {
37253                  stack.push(prog[++ip]);
37254                }
37255
37256                state.ip = ip;
37257              }
37258
37259              // NPUSHW[] PUSH N Words
37260              // 0x41
37261              function NPUSHW(state) {
37262                var ip = state.ip;
37263                var prog = state.prog;
37264                var stack = state.stack;
37265                var n = prog[++ip];
37266
37267                if (exports.DEBUG) {
37268                  console.log(state.step, 'NPUSHW[]', n);
37269                }
37270
37271                for (var i = 0; i < n; i++) {
37272                  var w = (prog[++ip] << 8) | prog[++ip];
37273                  if (w & 0x8000) {
37274                    w = -((w ^ 0xffff) + 1);
37275                  }
37276                  stack.push(w);
37277                }
37278
37279                state.ip = ip;
37280              }
37281
37282              // WS[] Write Store
37283              // 0x42
37284              function WS(state) {
37285                var stack = state.stack;
37286                var store = state.store;
37287
37288                if (!store) {
37289                  store = state.store = [];
37290                }
37291
37292                var v = stack.pop();
37293                var l = stack.pop();
37294
37295                if (exports.DEBUG) {
37296                  console.log(state.step, 'WS', v, l);
37297                }
37298
37299                store[l] = v;
37300              }
37301
37302              // RS[] Read Store
37303              // 0x43
37304              function RS(state) {
37305                var stack = state.stack;
37306                var store = state.store;
37307
37308                var l = stack.pop();
37309
37310                if (exports.DEBUG) {
37311                  console.log(state.step, 'RS', l);
37312                }
37313
37314                var v = (store && store[l]) || 0;
37315
37316                stack.push(v);
37317              }
37318
37319              // WCVTP[] Write Control Value Table in Pixel units
37320              // 0x44
37321              function WCVTP(state) {
37322                var stack = state.stack;
37323
37324                var v = stack.pop();
37325                var l = stack.pop();
37326
37327                if (exports.DEBUG) {
37328                  console.log(state.step, 'WCVTP', v, l);
37329                }
37330
37331                state.cvt[l] = v / 0x40;
37332              }
37333
37334              // RCVT[] Read Control Value Table entry
37335              // 0x45
37336              function RCVT(state) {
37337                var stack = state.stack;
37338                var cvte = stack.pop();
37339
37340                if (exports.DEBUG) {
37341                  console.log(state.step, 'RCVT', cvte);
37342                }
37343
37344                stack.push(state.cvt[cvte] * 0x40);
37345              }
37346
37347              // GC[] Get Coordinate projected onto the projection vector
37348              // 0x46-0x47
37349              function GC(a, state) {
37350                var stack = state.stack;
37351                var pi = stack.pop();
37352                var p = state.z2[pi];
37353
37354                if (exports.DEBUG) {
37355                  console.log(state.step, 'GC[' + a + ']', pi);
37356                }
37357
37358                stack.push(state.dpv.distance(p, HPZero, a, false) * 0x40);
37359              }
37360
37361              // MD[a] Measure Distance
37362              // 0x49-0x4A
37363              function MD(a, state) {
37364                var stack = state.stack;
37365                var pi2 = stack.pop();
37366                var pi1 = stack.pop();
37367                var p2 = state.z1[pi2];
37368                var p1 = state.z0[pi1];
37369                var d = state.dpv.distance(p1, p2, a, a);
37370
37371                if (exports.DEBUG) {
37372                  console.log(state.step, 'MD[' + a + ']', pi2, pi1, '->', d);
37373                }
37374
37375                state.stack.push(Math.round(d * 64));
37376              }
37377
37378              // MPPEM[] Measure Pixels Per EM
37379              // 0x4B
37380              function MPPEM(state) {
37381                if (exports.DEBUG) {
37382                  console.log(state.step, 'MPPEM[]');
37383                }
37384                state.stack.push(state.ppem);
37385              }
37386
37387              // FLIPON[] set the auto FLIP Boolean to ON
37388              // 0x4D
37389              function FLIPON(state) {
37390                if (exports.DEBUG) {
37391                  console.log(state.step, 'FLIPON[]');
37392                }
37393                state.autoFlip = true;
37394              }
37395
37396              // LT[] Less Than
37397              // 0x50
37398              function LT(state) {
37399                var stack = state.stack;
37400                var e2 = stack.pop();
37401                var e1 = stack.pop();
37402
37403                if (exports.DEBUG) {
37404                  console.log(state.step, 'LT[]', e2, e1);
37405                }
37406
37407                stack.push(e1 < e2 ? 1 : 0);
37408              }
37409
37410              // LTEQ[] Less Than or EQual
37411              // 0x53
37412              function LTEQ(state) {
37413                var stack = state.stack;
37414                var e2 = stack.pop();
37415                var e1 = stack.pop();
37416
37417                if (exports.DEBUG) {
37418                  console.log(state.step, 'LTEQ[]', e2, e1);
37419                }
37420
37421                stack.push(e1 <= e2 ? 1 : 0);
37422              }
37423
37424              // GTEQ[] Greater Than
37425              // 0x52
37426              function GT(state) {
37427                var stack = state.stack;
37428                var e2 = stack.pop();
37429                var e1 = stack.pop();
37430
37431                if (exports.DEBUG) {
37432                  console.log(state.step, 'GT[]', e2, e1);
37433                }
37434
37435                stack.push(e1 > e2 ? 1 : 0);
37436              }
37437
37438              // GTEQ[] Greater Than or EQual
37439              // 0x53
37440              function GTEQ(state) {
37441                var stack = state.stack;
37442                var e2 = stack.pop();
37443                var e1 = stack.pop();
37444
37445                if (exports.DEBUG) {
37446                  console.log(state.step, 'GTEQ[]', e2, e1);
37447                }
37448
37449                stack.push(e1 >= e2 ? 1 : 0);
37450              }
37451
37452              // EQ[] EQual
37453              // 0x54
37454              function EQ(state) {
37455                var stack = state.stack;
37456                var e2 = stack.pop();
37457                var e1 = stack.pop();
37458
37459                if (exports.DEBUG) {
37460                  console.log(state.step, 'EQ[]', e2, e1);
37461                }
37462
37463                stack.push(e2 === e1 ? 1 : 0);
37464              }
37465
37466              // NEQ[] Not EQual
37467              // 0x55
37468              function NEQ(state) {
37469                var stack = state.stack;
37470                var e2 = stack.pop();
37471                var e1 = stack.pop();
37472
37473                if (exports.DEBUG) {
37474                  console.log(state.step, 'NEQ[]', e2, e1);
37475                }
37476
37477                stack.push(e2 !== e1 ? 1 : 0);
37478              }
37479
37480              // ODD[] ODD
37481              // 0x56
37482              function ODD(state) {
37483                var stack = state.stack;
37484                var n = stack.pop();
37485
37486                if (exports.DEBUG) {
37487                  console.log(state.step, 'ODD[]', n);
37488                }
37489
37490                stack.push(Math.trunc(n) % 2 ? 1 : 0);
37491              }
37492
37493              // EVEN[] EVEN
37494              // 0x57
37495              function EVEN(state) {
37496                var stack = state.stack;
37497                var n = stack.pop();
37498
37499                if (exports.DEBUG) {
37500                  console.log(state.step, 'EVEN[]', n);
37501                }
37502
37503                stack.push(Math.trunc(n) % 2 ? 0 : 1);
37504              }
37505
37506              // IF[] IF test
37507              // 0x58
37508              function IF(state) {
37509                var test = state.stack.pop();
37510
37511                if (exports.DEBUG) {
37512                  console.log(state.step, 'IF[]', test);
37513                }
37514
37515                // if test is true it just continues
37516                // if not the ip is skipped until matching ELSE or EIF
37517                if (!test) {
37518                  skip(state, true);
37519
37520                  if (exports.DEBUG) {
37521                    console.log(state.step, 'EIF[]');
37522                  }
37523                }
37524              }
37525
37526              // EIF[] End IF
37527              // 0x59
37528              function EIF(state) {
37529                // this can be reached normally when
37530                // executing an else branch.
37531                // -> just ignore it
37532
37533                if (exports.DEBUG) {
37534                  console.log(state.step, 'EIF[]');
37535                }
37536              }
37537
37538              // AND[] logical AND
37539              // 0x5A
37540              function AND(state) {
37541                var stack = state.stack;
37542                var e2 = stack.pop();
37543                var e1 = stack.pop();
37544
37545                if (exports.DEBUG) {
37546                  console.log(state.step, 'AND[]', e2, e1);
37547                }
37548
37549                stack.push(e2 && e1 ? 1 : 0);
37550              }
37551
37552              // OR[] logical OR
37553              // 0x5B
37554              function OR(state) {
37555                var stack = state.stack;
37556                var e2 = stack.pop();
37557                var e1 = stack.pop();
37558
37559                if (exports.DEBUG) {
37560                  console.log(state.step, 'OR[]', e2, e1);
37561                }
37562
37563                stack.push(e2 || e1 ? 1 : 0);
37564              }
37565
37566              // NOT[] logical NOT
37567              // 0x5C
37568              function NOT(state) {
37569                var stack = state.stack;
37570                var e = stack.pop();
37571
37572                if (exports.DEBUG) {
37573                  console.log(state.step, 'NOT[]', e);
37574                }
37575
37576                stack.push(e ? 0 : 1);
37577              }
37578
37579              // DELTAP1[] DELTA exception P1
37580              // DELTAP2[] DELTA exception P2
37581              // DELTAP3[] DELTA exception P3
37582              // 0x5D, 0x71, 0x72
37583              function DELTAP123(b, state) {
37584                var stack = state.stack;
37585                var n = stack.pop();
37586                var fv = state.fv;
37587                var pv = state.pv;
37588                var ppem = state.ppem;
37589                var base = state.deltaBase + (b - 1) * 16;
37590                var ds = state.deltaShift;
37591                var z0 = state.z0;
37592
37593                if (exports.DEBUG) {
37594                  console.log(state.step, 'DELTAP[' + b + ']', n, stack);
37595                }
37596
37597                for (var i = 0; i < n; i++) {
37598                  var pi = stack.pop();
37599                  var arg = stack.pop();
37600                  var appem = base + ((arg & 0xf0) >> 4);
37601                  if (appem !== ppem) {
37602                    continue;
37603                  }
37604
37605                  var mag = (arg & 0x0f) - 8;
37606                  if (mag >= 0) {
37607                    mag++;
37608                  }
37609                  if (exports.DEBUG) {
37610                    console.log(state.step, 'DELTAPFIX', pi, 'by', mag * ds);
37611                  }
37612
37613                  var p = z0[pi];
37614                  fv.setRelative(p, p, mag * ds, pv);
37615                }
37616              }
37617
37618              // SDB[] Set Delta Base in the graphics state
37619              // 0x5E
37620              function SDB(state) {
37621                var stack = state.stack;
37622                var n = stack.pop();
37623
37624                if (exports.DEBUG) {
37625                  console.log(state.step, 'SDB[]', n);
37626                }
37627
37628                state.deltaBase = n;
37629              }
37630
37631              // SDS[] Set Delta Shift in the graphics state
37632              // 0x5F
37633              function SDS(state) {
37634                var stack = state.stack;
37635                var n = stack.pop();
37636
37637                if (exports.DEBUG) {
37638                  console.log(state.step, 'SDS[]', n);
37639                }
37640
37641                state.deltaShift = Math.pow(0.5, n);
37642              }
37643
37644              // ADD[] ADD
37645              // 0x60
37646              function ADD(state) {
37647                var stack = state.stack;
37648                var n2 = stack.pop();
37649                var n1 = stack.pop();
37650
37651                if (exports.DEBUG) {
37652                  console.log(state.step, 'ADD[]', n2, n1);
37653                }
37654
37655                stack.push(n1 + n2);
37656              }
37657
37658              // SUB[] SUB
37659              // 0x61
37660              function SUB(state) {
37661                var stack = state.stack;
37662                var n2 = stack.pop();
37663                var n1 = stack.pop();
37664
37665                if (exports.DEBUG) {
37666                  console.log(state.step, 'SUB[]', n2, n1);
37667                }
37668
37669                stack.push(n1 - n2);
37670              }
37671
37672              // DIV[] DIV
37673              // 0x62
37674              function DIV(state) {
37675                var stack = state.stack;
37676                var n2 = stack.pop();
37677                var n1 = stack.pop();
37678
37679                if (exports.DEBUG) {
37680                  console.log(state.step, 'DIV[]', n2, n1);
37681                }
37682
37683                stack.push(n1 * 64 / n2);
37684              }
37685
37686              // MUL[] MUL
37687              // 0x63
37688              function MUL(state) {
37689                var stack = state.stack;
37690                var n2 = stack.pop();
37691                var n1 = stack.pop();
37692
37693                if (exports.DEBUG) {
37694                  console.log(state.step, 'MUL[]', n2, n1);
37695                }
37696
37697                stack.push(n1 * n2 / 64);
37698              }
37699
37700              // ABS[] ABSolute value
37701              // 0x64
37702              function ABS(state) {
37703                var stack = state.stack;
37704                var n = stack.pop();
37705
37706                if (exports.DEBUG) {
37707                  console.log(state.step, 'ABS[]', n);
37708                }
37709
37710                stack.push(Math.abs(n));
37711              }
37712
37713              // NEG[] NEGate
37714              // 0x65
37715              function NEG(state) {
37716                var stack = state.stack;
37717                var n = stack.pop();
37718
37719                if (exports.DEBUG) {
37720                  console.log(state.step, 'NEG[]', n);
37721                }
37722
37723                stack.push(-n);
37724              }
37725
37726              // FLOOR[] FLOOR
37727              // 0x66
37728              function FLOOR(state) {
37729                var stack = state.stack;
37730                var n = stack.pop();
37731
37732                if (exports.DEBUG) {
37733                  console.log(state.step, 'FLOOR[]', n);
37734                }
37735
37736                stack.push(Math.floor(n / 0x40) * 0x40);
37737              }
37738
37739              // CEILING[] CEILING
37740              // 0x67
37741              function CEILING(state) {
37742                var stack = state.stack;
37743                var n = stack.pop();
37744
37745                if (exports.DEBUG) {
37746                  console.log(state.step, 'CEILING[]', n);
37747                }
37748
37749                stack.push(Math.ceil(n / 0x40) * 0x40);
37750              }
37751
37752              // ROUND[ab] ROUND value
37753              // 0x68-0x6B
37754              function ROUND(dt, state) {
37755                var stack = state.stack;
37756                var n = stack.pop();
37757
37758                if (exports.DEBUG) {
37759                  console.log(state.step, 'ROUND[]');
37760                }
37761
37762                stack.push(state.round(n / 0x40) * 0x40);
37763              }
37764
37765              // WCVTF[] Write Control Value Table in Funits
37766              // 0x70
37767              function WCVTF(state) {
37768                var stack = state.stack;
37769                var v = stack.pop();
37770                var l = stack.pop();
37771
37772                if (exports.DEBUG) {
37773                  console.log(state.step, 'WCVTF[]', v, l);
37774                }
37775
37776                state.cvt[l] = v * state.ppem / state.font.unitsPerEm;
37777              }
37778
37779              // DELTAC1[] DELTA exception C1
37780              // DELTAC2[] DELTA exception C2
37781              // DELTAC3[] DELTA exception C3
37782              // 0x73, 0x74, 0x75
37783              function DELTAC123(b, state) {
37784                var stack = state.stack;
37785                var n = stack.pop();
37786                var ppem = state.ppem;
37787                var base = state.deltaBase + (b - 1) * 16;
37788                var ds = state.deltaShift;
37789
37790                if (exports.DEBUG) {
37791                  console.log(state.step, 'DELTAC[' + b + ']', n, stack);
37792                }
37793
37794                for (var i = 0; i < n; i++) {
37795                  var c = stack.pop();
37796                  var arg = stack.pop();
37797                  var appem = base + ((arg & 0xf0) >> 4);
37798                  if (appem !== ppem) {
37799                    continue;
37800                  }
37801
37802                  var mag = (arg & 0x0f) - 8;
37803                  if (mag >= 0) {
37804                    mag++;
37805                  }
37806
37807                  var delta = mag * ds;
37808
37809                  if (exports.DEBUG) {
37810                    console.log(state.step, 'DELTACFIX', c, 'by', delta);
37811                  }
37812
37813                  state.cvt[c] += delta;
37814                }
37815              }
37816
37817              // SROUND[] Super ROUND
37818              // 0x76
37819              function SROUND(state) {
37820                var n = state.stack.pop();
37821
37822                if (exports.DEBUG) {
37823                  console.log(state.step, 'SROUND[]', n);
37824                }
37825
37826                state.round = roundSuper;
37827
37828                var period;
37829
37830                switch (n & 0xc0) {
37831                  case 0x00:
37832                    period = 0.5;
37833                    break;
37834                  case 0x40:
37835                    period = 1;
37836                    break;
37837                  case 0x80:
37838                    period = 2;
37839                    break;
37840                  default:
37841                    throw new Error('invalid SROUND value');
37842                }
37843
37844                state.srPeriod = period;
37845
37846                switch (n & 0x30) {
37847                  case 0x00:
37848                    state.srPhase = 0;
37849                    break;
37850                  case 0x10:
37851                    state.srPhase = 0.25 * period;
37852                    break;
37853                  case 0x20:
37854                    state.srPhase = 0.5 * period;
37855                    break;
37856                  case 0x30:
37857                    state.srPhase = 0.75 * period;
37858                    break;
37859                  default:
37860                    throw new Error('invalid SROUND value');
37861                }
37862
37863                n &= 0x0f;
37864
37865                if (n === 0) {
37866                  state.srThreshold = 0;
37867                } else {
37868                  state.srThreshold = (n / 8 - 0.5) * period;
37869                }
37870              }
37871
37872              // S45ROUND[] Super ROUND 45 degrees
37873              // 0x77
37874              function S45ROUND(state) {
37875                var n = state.stack.pop();
37876
37877                if (exports.DEBUG) {
37878                  console.log(state.step, 'S45ROUND[]', n);
37879                }
37880
37881                state.round = roundSuper;
37882
37883                var period;
37884
37885                switch (n & 0xc0) {
37886                  case 0x00:
37887                    period = Math.sqrt(2) / 2;
37888                    break;
37889                  case 0x40:
37890                    period = Math.sqrt(2);
37891                    break;
37892                  case 0x80:
37893                    period = 2 * Math.sqrt(2);
37894                    break;
37895                  default:
37896                    throw new Error('invalid S45ROUND value');
37897                }
37898
37899                state.srPeriod = period;
37900
37901                switch (n & 0x30) {
37902                  case 0x00:
37903                    state.srPhase = 0;
37904                    break;
37905                  case 0x10:
37906                    state.srPhase = 0.25 * period;
37907                    break;
37908                  case 0x20:
37909                    state.srPhase = 0.5 * period;
37910                    break;
37911                  case 0x30:
37912                    state.srPhase = 0.75 * period;
37913                    break;
37914                  default:
37915                    throw new Error('invalid S45ROUND value');
37916                }
37917
37918                n &= 0x0f;
37919
37920                if (n === 0) {
37921                  state.srThreshold = 0;
37922                } else {
37923                  state.srThreshold = (n / 8 - 0.5) * period;
37924                }
37925              }
37926
37927              // ROFF[] Round Off
37928              // 0x7A
37929              function ROFF(state) {
37930                if (exports.DEBUG) {
37931                  console.log(state.step, 'ROFF[]');
37932                }
37933
37934                state.round = roundOff;
37935              }
37936
37937              // RUTG[] Round Up To Grid
37938              // 0x7C
37939              function RUTG(state) {
37940                if (exports.DEBUG) {
37941                  console.log(state.step, 'RUTG[]');
37942                }
37943
37944                state.round = roundUpToGrid;
37945              }
37946
37947              // RDTG[] Round Down To Grid
37948              // 0x7D
37949              function RDTG(state) {
37950                if (exports.DEBUG) {
37951                  console.log(state.step, 'RDTG[]');
37952                }
37953
37954                state.round = roundDownToGrid;
37955              }
37956
37957              // SCANCTRL[] SCAN conversion ConTRoL
37958              // 0x85
37959              function SCANCTRL(state) {
37960                var n = state.stack.pop();
37961
37962                // ignored by opentype.js
37963
37964                if (exports.DEBUG) {
37965                  console.log(state.step, 'SCANCTRL[]', n);
37966                }
37967              }
37968
37969              // SDPVTL[a] Set Dual Projection Vector To Line
37970              // 0x86-0x87
37971              function SDPVTL(a, state) {
37972                var stack = state.stack;
37973                var p2i = stack.pop();
37974                var p1i = stack.pop();
37975                var p2 = state.z2[p2i];
37976                var p1 = state.z1[p1i];
37977
37978                if (exports.DEBUG) {
37979                  console.log(state.step, 'SDPVTL[' + a + ']', p2i, p1i);
37980                }
37981
37982                var dx;
37983                var dy;
37984
37985                if (!a) {
37986                  dx = p1.x - p2.x;
37987                  dy = p1.y - p2.y;
37988                } else {
37989                  dx = p2.y - p1.y;
37990                  dy = p1.x - p2.x;
37991                }
37992
37993                state.dpv = getUnitVector(dx, dy);
37994              }
37995
37996              // GETINFO[] GET INFOrmation
37997              // 0x88
37998              function GETINFO(state) {
37999                var stack = state.stack;
38000                var sel = stack.pop();
38001                var r = 0;
38002
38003                if (exports.DEBUG) {
38004                  console.log(state.step, 'GETINFO[]', sel);
38005                }
38006
38007                // v35 as in no subpixel hinting
38008                if (sel & 0x01) {
38009                  r = 35;
38010                }
38011
38012                // TODO rotation and stretch currently not supported
38013                // and thus those GETINFO are always 0.
38014
38015                // opentype.js is always gray scaling
38016                if (sel & 0x20) {
38017                  r |= 0x1000;
38018                }
38019
38020                stack.push(r);
38021              }
38022
38023              // ROLL[] ROLL the top three stack elements
38024              // 0x8A
38025              function ROLL(state) {
38026                var stack = state.stack;
38027                var a = stack.pop();
38028                var b = stack.pop();
38029                var c = stack.pop();
38030
38031                if (exports.DEBUG) {
38032                  console.log(state.step, 'ROLL[]');
38033                }
38034
38035                stack.push(b);
38036                stack.push(a);
38037                stack.push(c);
38038              }
38039
38040              // MAX[] MAXimum of top two stack elements
38041              // 0x8B
38042              function MAX(state) {
38043                var stack = state.stack;
38044                var e2 = stack.pop();
38045                var e1 = stack.pop();
38046
38047                if (exports.DEBUG) {
38048                  console.log(state.step, 'MAX[]', e2, e1);
38049                }
38050
38051                stack.push(Math.max(e1, e2));
38052              }
38053
38054              // MIN[] MINimum of top two stack elements
38055              // 0x8C
38056              function MIN(state) {
38057                var stack = state.stack;
38058                var e2 = stack.pop();
38059                var e1 = stack.pop();
38060
38061                if (exports.DEBUG) {
38062                  console.log(state.step, 'MIN[]', e2, e1);
38063                }
38064
38065                stack.push(Math.min(e1, e2));
38066              }
38067
38068              // SCANTYPE[] SCANTYPE
38069              // 0x8D
38070              function SCANTYPE(state) {
38071                var n = state.stack.pop();
38072                // ignored by opentype.js
38073                if (exports.DEBUG) {
38074                  console.log(state.step, 'SCANTYPE[]', n);
38075                }
38076              }
38077
38078              // INSTCTRL[] INSTCTRL
38079              // 0x8D
38080              function INSTCTRL(state) {
38081                var s = state.stack.pop();
38082                var v = state.stack.pop();
38083
38084                if (exports.DEBUG) {
38085                  console.log(state.step, 'INSTCTRL[]', s, v);
38086                }
38087
38088                switch (s) {
38089                  case 1:
38090                    state.inhibitGridFit = !!v;
38091                    return;
38092                  case 2:
38093                    state.ignoreCvt = !!v;
38094                    return;
38095                  default:
38096                    throw new Error('invalid INSTCTRL[] selector');
38097                }
38098              }
38099
38100              // PUSHB[abc] PUSH Bytes
38101              // 0xB0-0xB7
38102              function PUSHB(n, state) {
38103                var stack = state.stack;
38104                var prog = state.prog;
38105                var ip = state.ip;
38106
38107                if (exports.DEBUG) {
38108                  console.log(state.step, 'PUSHB[' + n + ']');
38109                }
38110
38111                for (var i = 0; i < n; i++) {
38112                  stack.push(prog[++ip]);
38113                }
38114
38115                state.ip = ip;
38116              }
38117
38118              // PUSHW[abc] PUSH Words
38119              // 0xB8-0xBF
38120              function PUSHW(n, state) {
38121                var ip = state.ip;
38122                var prog = state.prog;
38123                var stack = state.stack;
38124
38125                if (exports.DEBUG) {
38126                  console.log(state.ip, 'PUSHW[' + n + ']');
38127                }
38128
38129                for (var i = 0; i < n; i++) {
38130                  var w = (prog[++ip] << 8) | prog[++ip];
38131                  if (w & 0x8000) {
38132                    w = -((w ^ 0xffff) + 1);
38133                  }
38134                  stack.push(w);
38135                }
38136
38137                state.ip = ip;
38138              }
38139
38140              // MDRP[abcde] Move Direct Relative Point
38141              // 0xD0-0xEF
38142              // (if indirect is 0)
38143              //
38144              // and
38145              //
38146              // MIRP[abcde] Move Indirect Relative Point
38147              // 0xE0-0xFF
38148              // (if indirect is 1)
38149
38150              function MDRP_MIRP(indirect, setRp0, keepD, ro, dt, state) {
38151                var stack = state.stack;
38152                var cvte = indirect && stack.pop();
38153                var pi = stack.pop();
38154                var rp0i = state.rp0;
38155                var rp = state.z0[rp0i];
38156                var p = state.z1[pi];
38157
38158                var md = state.minDis;
38159                var fv = state.fv;
38160                var pv = state.dpv;
38161                var od; // original distance
38162                var d; // moving distance
38163                var sign; // sign of distance
38164                var cv;
38165
38166                d = od = pv.distance(p, rp, true, true);
38167                sign = d >= 0 ? 1 : -1; // Math.sign would be 0 in case of 0
38168
38169                // TODO consider autoFlip
38170                d = Math.abs(d);
38171
38172                if (indirect) {
38173                  cv = state.cvt[cvte];
38174
38175                  if (ro && Math.abs(d - cv) < state.cvCutIn) {
38176                    d = cv;
38177                  }
38178                }
38179
38180                if (keepD && d < md) {
38181                  d = md;
38182                }
38183
38184                if (ro) {
38185                  d = state.round(d);
38186                }
38187
38188                fv.setRelative(p, rp, sign * d, pv);
38189                fv.touch(p);
38190
38191                if (exports.DEBUG) {
38192                  console.log(
38193                    state.step,
38194                    (indirect ? 'MIRP[' : 'MDRP[') +
38195                      (setRp0 ? 'M' : 'm') +
38196                      (keepD ? '>' : '_') +
38197                      (ro ? 'R' : '_') +
38198                      (dt === 0 ? 'Gr' : dt === 1 ? 'Bl' : dt === 2 ? 'Wh' : '') +
38199                      ']',
38200                    indirect ? cvte + '(' + state.cvt[cvte] + ',' + cv + ')' : '',
38201                    pi,
38202                    '(d =',
38203                    od,
38204                    '->',
38205                    sign * d,
38206                    ')'
38207                  );
38208                }
38209
38210                state.rp1 = state.rp0;
38211                state.rp2 = pi;
38212                if (setRp0) {
38213                  state.rp0 = pi;
38214                }
38215              }
38216
38217              /*
38218	* The instruction table.
38219	*/
38220              instructionTable = [
38221                /* 0x00 */ SVTCA.bind(undefined, yUnitVector),
38222                /* 0x01 */ SVTCA.bind(undefined, xUnitVector),
38223                /* 0x02 */ SPVTCA.bind(undefined, yUnitVector),
38224                /* 0x03 */ SPVTCA.bind(undefined, xUnitVector),
38225                /* 0x04 */ SFVTCA.bind(undefined, yUnitVector),
38226                /* 0x05 */ SFVTCA.bind(undefined, xUnitVector),
38227                /* 0x06 */ SPVTL.bind(undefined, 0),
38228                /* 0x07 */ SPVTL.bind(undefined, 1),
38229                /* 0x08 */ SFVTL.bind(undefined, 0),
38230                /* 0x09 */ SFVTL.bind(undefined, 1),
38231                /* 0x0A */ SPVFS,
38232                /* 0x0B */ SFVFS,
38233                /* 0x0C */ GPV,
38234                /* 0x0D */ GFV,
38235                /* 0x0E */ SFVTPV,
38236                /* 0x0F */ ISECT,
38237                /* 0x10 */ SRP0,
38238                /* 0x11 */ SRP1,
38239                /* 0x12 */ SRP2,
38240                /* 0x13 */ SZP0,
38241                /* 0x14 */ SZP1,
38242                /* 0x15 */ SZP2,
38243                /* 0x16 */ SZPS,
38244                /* 0x17 */ SLOOP,
38245                /* 0x18 */ RTG,
38246                /* 0x19 */ RTHG,
38247                /* 0x1A */ SMD,
38248                /* 0x1B */ ELSE,
38249                /* 0x1C */ JMPR,
38250                /* 0x1D */ SCVTCI,
38251                /* 0x1E */ undefined, // TODO SSWCI
38252                /* 0x1F */ undefined, // TODO SSW
38253                /* 0x20 */ DUP,
38254                /* 0x21 */ POP,
38255                /* 0x22 */ CLEAR,
38256                /* 0x23 */ SWAP,
38257                /* 0x24 */ DEPTH,
38258                /* 0x25 */ CINDEX,
38259                /* 0x26 */ MINDEX,
38260                /* 0x27 */ undefined, // TODO ALIGNPTS
38261                /* 0x28 */ undefined,
38262                /* 0x29 */ undefined, // TODO UTP
38263                /* 0x2A */ LOOPCALL,
38264                /* 0x2B */ CALL,
38265                /* 0x2C */ FDEF,
38266                /* 0x2D */ undefined, // ENDF (eaten by FDEF)
38267                /* 0x2E */ MDAP.bind(undefined, 0),
38268                /* 0x2F */ MDAP.bind(undefined, 1),
38269                /* 0x30 */ IUP.bind(undefined, yUnitVector),
38270                /* 0x31 */ IUP.bind(undefined, xUnitVector),
38271                /* 0x32 */ SHP.bind(undefined, 0),
38272                /* 0x33 */ SHP.bind(undefined, 1),
38273                /* 0x34 */ SHC.bind(undefined, 0),
38274                /* 0x35 */ SHC.bind(undefined, 1),
38275                /* 0x36 */ SHZ.bind(undefined, 0),
38276                /* 0x37 */ SHZ.bind(undefined, 1),
38277                /* 0x38 */ SHPIX,
38278                /* 0x39 */ IP,
38279                /* 0x3A */ MSIRP.bind(undefined, 0),
38280                /* 0x3B */ MSIRP.bind(undefined, 1),
38281                /* 0x3C */ ALIGNRP,
38282                /* 0x3D */ RTDG,
38283                /* 0x3E */ MIAP.bind(undefined, 0),
38284                /* 0x3F */ MIAP.bind(undefined, 1),
38285                /* 0x40 */ NPUSHB,
38286                /* 0x41 */ NPUSHW,
38287                /* 0x42 */ WS,
38288                /* 0x43 */ RS,
38289                /* 0x44 */ WCVTP,
38290                /* 0x45 */ RCVT,
38291                /* 0x46 */ GC.bind(undefined, 0),
38292                /* 0x47 */ GC.bind(undefined, 1),
38293                /* 0x48 */ undefined, // TODO SCFS
38294                /* 0x49 */ MD.bind(undefined, 0),
38295                /* 0x4A */ MD.bind(undefined, 1),
38296                /* 0x4B */ MPPEM,
38297                /* 0x4C */ undefined, // TODO MPS
38298                /* 0x4D */ FLIPON,
38299                /* 0x4E */ undefined, // TODO FLIPOFF
38300                /* 0x4F */ undefined, // TODO DEBUG
38301                /* 0x50 */ LT,
38302                /* 0x51 */ LTEQ,
38303                /* 0x52 */ GT,
38304                /* 0x53 */ GTEQ,
38305                /* 0x54 */ EQ,
38306                /* 0x55 */ NEQ,
38307                /* 0x56 */ ODD,
38308                /* 0x57 */ EVEN,
38309                /* 0x58 */ IF,
38310                /* 0x59 */ EIF,
38311                /* 0x5A */ AND,
38312                /* 0x5B */ OR,
38313                /* 0x5C */ NOT,
38314                /* 0x5D */ DELTAP123.bind(undefined, 1),
38315                /* 0x5E */ SDB,
38316                /* 0x5F */ SDS,
38317                /* 0x60 */ ADD,
38318                /* 0x61 */ SUB,
38319                /* 0x62 */ DIV,
38320                /* 0x63 */ MUL,
38321                /* 0x64 */ ABS,
38322                /* 0x65 */ NEG,
38323                /* 0x66 */ FLOOR,
38324                /* 0x67 */ CEILING,
38325                /* 0x68 */ ROUND.bind(undefined, 0),
38326                /* 0x69 */ ROUND.bind(undefined, 1),
38327                /* 0x6A */ ROUND.bind(undefined, 2),
38328                /* 0x6B */ ROUND.bind(undefined, 3),
38329                /* 0x6C */ undefined, // TODO NROUND[ab]
38330                /* 0x6D */ undefined, // TODO NROUND[ab]
38331                /* 0x6E */ undefined, // TODO NROUND[ab]
38332                /* 0x6F */ undefined, // TODO NROUND[ab]
38333                /* 0x70 */ WCVTF,
38334                /* 0x71 */ DELTAP123.bind(undefined, 2),
38335                /* 0x72 */ DELTAP123.bind(undefined, 3),
38336                /* 0x73 */ DELTAC123.bind(undefined, 1),
38337                /* 0x74 */ DELTAC123.bind(undefined, 2),
38338                /* 0x75 */ DELTAC123.bind(undefined, 3),
38339                /* 0x76 */ SROUND,
38340                /* 0x77 */ S45ROUND,
38341                /* 0x78 */ undefined, // TODO JROT[]
38342                /* 0x79 */ undefined, // TODO JROF[]
38343                /* 0x7A */ ROFF,
38344                /* 0x7B */ undefined,
38345                /* 0x7C */ RUTG,
38346                /* 0x7D */ RDTG,
38347                /* 0x7E */ POP, // actually SANGW, supposed to do only a pop though
38348                /* 0x7F */ POP, // actually AA, supposed to do only a pop though
38349                /* 0x80 */ undefined, // TODO FLIPPT
38350                /* 0x81 */ undefined, // TODO FLIPRGON
38351                /* 0x82 */ undefined, // TODO FLIPRGOFF
38352                /* 0x83 */ undefined,
38353                /* 0x84 */ undefined,
38354                /* 0x85 */ SCANCTRL,
38355                /* 0x86 */ SDPVTL.bind(undefined, 0),
38356                /* 0x87 */ SDPVTL.bind(undefined, 1),
38357                /* 0x88 */ GETINFO,
38358                /* 0x89 */ undefined, // TODO IDEF
38359                /* 0x8A */ ROLL,
38360                /* 0x8B */ MAX,
38361                /* 0x8C */ MIN,
38362                /* 0x8D */ SCANTYPE,
38363                /* 0x8E */ INSTCTRL,
38364                /* 0x8F */ undefined,
38365                /* 0x90 */ undefined,
38366                /* 0x91 */ undefined,
38367                /* 0x92 */ undefined,
38368                /* 0x93 */ undefined,
38369                /* 0x94 */ undefined,
38370                /* 0x95 */ undefined,
38371                /* 0x96 */ undefined,
38372                /* 0x97 */ undefined,
38373                /* 0x98 */ undefined,
38374                /* 0x99 */ undefined,
38375                /* 0x9A */ undefined,
38376                /* 0x9B */ undefined,
38377                /* 0x9C */ undefined,
38378                /* 0x9D */ undefined,
38379                /* 0x9E */ undefined,
38380                /* 0x9F */ undefined,
38381                /* 0xA0 */ undefined,
38382                /* 0xA1 */ undefined,
38383                /* 0xA2 */ undefined,
38384                /* 0xA3 */ undefined,
38385                /* 0xA4 */ undefined,
38386                /* 0xA5 */ undefined,
38387                /* 0xA6 */ undefined,
38388                /* 0xA7 */ undefined,
38389                /* 0xA8 */ undefined,
38390                /* 0xA9 */ undefined,
38391                /* 0xAA */ undefined,
38392                /* 0xAB */ undefined,
38393                /* 0xAC */ undefined,
38394                /* 0xAD */ undefined,
38395                /* 0xAE */ undefined,
38396                /* 0xAF */ undefined,
38397                /* 0xB0 */ PUSHB.bind(undefined, 1),
38398                /* 0xB1 */ PUSHB.bind(undefined, 2),
38399                /* 0xB2 */ PUSHB.bind(undefined, 3),
38400                /* 0xB3 */ PUSHB.bind(undefined, 4),
38401                /* 0xB4 */ PUSHB.bind(undefined, 5),
38402                /* 0xB5 */ PUSHB.bind(undefined, 6),
38403                /* 0xB6 */ PUSHB.bind(undefined, 7),
38404                /* 0xB7 */ PUSHB.bind(undefined, 8),
38405                /* 0xB8 */ PUSHW.bind(undefined, 1),
38406                /* 0xB9 */ PUSHW.bind(undefined, 2),
38407                /* 0xBA */ PUSHW.bind(undefined, 3),
38408                /* 0xBB */ PUSHW.bind(undefined, 4),
38409                /* 0xBC */ PUSHW.bind(undefined, 5),
38410                /* 0xBD */ PUSHW.bind(undefined, 6),
38411                /* 0xBE */ PUSHW.bind(undefined, 7),
38412                /* 0xBF */ PUSHW.bind(undefined, 8),
38413                /* 0xC0 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 0, 0),
38414                /* 0xC1 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 0, 1),
38415                /* 0xC2 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 0, 2),
38416                /* 0xC3 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 0, 3),
38417                /* 0xC4 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 1, 0),
38418                /* 0xC5 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 1, 1),
38419                /* 0xC6 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 1, 2),
38420                /* 0xC7 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 1, 3),
38421                /* 0xC8 */ MDRP_MIRP.bind(undefined, 0, 0, 1, 0, 0),
38422                /* 0xC9 */ MDRP_MIRP.bind(undefined, 0, 0, 1, 0, 1),
38423                /* 0xCA */ MDRP_MIRP.bind(undefined, 0, 0, 1, 0, 2),
38424                /* 0xCB */ MDRP_MIRP.bind(undefined, 0, 0, 1, 0, 3),
38425                /* 0xCC */ MDRP_MIRP.bind(undefined, 0, 0, 1, 1, 0),
38426                /* 0xCD */ MDRP_MIRP.bind(undefined, 0, 0, 1, 1, 1),
38427                /* 0xCE */ MDRP_MIRP.bind(undefined, 0, 0, 1, 1, 2),
38428                /* 0xCF */ MDRP_MIRP.bind(undefined, 0, 0, 1, 1, 3),
38429                /* 0xD0 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 0, 0),
38430                /* 0xD1 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 0, 1),
38431                /* 0xD2 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 0, 2),
38432                /* 0xD3 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 0, 3),
38433                /* 0xD4 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 1, 0),
38434                /* 0xD5 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 1, 1),
38435                /* 0xD6 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 1, 2),
38436                /* 0xD7 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 1, 3),
38437                /* 0xD8 */ MDRP_MIRP.bind(undefined, 0, 1, 1, 0, 0),
38438                /* 0xD9 */ MDRP_MIRP.bind(undefined, 0, 1, 1, 0, 1),
38439                /* 0xDA */ MDRP_MIRP.bind(undefined, 0, 1, 1, 0, 2),
38440                /* 0xDB */ MDRP_MIRP.bind(undefined, 0, 1, 1, 0, 3),
38441                /* 0xDC */ MDRP_MIRP.bind(undefined, 0, 1, 1, 1, 0),
38442                /* 0xDD */ MDRP_MIRP.bind(undefined, 0, 1, 1, 1, 1),
38443                /* 0xDE */ MDRP_MIRP.bind(undefined, 0, 1, 1, 1, 2),
38444                /* 0xDF */ MDRP_MIRP.bind(undefined, 0, 1, 1, 1, 3),
38445                /* 0xE0 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 0, 0),
38446                /* 0xE1 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 0, 1),
38447                /* 0xE2 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 0, 2),
38448                /* 0xE3 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 0, 3),
38449                /* 0xE4 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 1, 0),
38450                /* 0xE5 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 1, 1),
38451                /* 0xE6 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 1, 2),
38452                /* 0xE7 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 1, 3),
38453                /* 0xE8 */ MDRP_MIRP.bind(undefined, 1, 0, 1, 0, 0),
38454                /* 0xE9 */ MDRP_MIRP.bind(undefined, 1, 0, 1, 0, 1),
38455                /* 0xEA */ MDRP_MIRP.bind(undefined, 1, 0, 1, 0, 2),
38456                /* 0xEB */ MDRP_MIRP.bind(undefined, 1, 0, 1, 0, 3),
38457                /* 0xEC */ MDRP_MIRP.bind(undefined, 1, 0, 1, 1, 0),
38458                /* 0xED */ MDRP_MIRP.bind(undefined, 1, 0, 1, 1, 1),
38459                /* 0xEE */ MDRP_MIRP.bind(undefined, 1, 0, 1, 1, 2),
38460                /* 0xEF */ MDRP_MIRP.bind(undefined, 1, 0, 1, 1, 3),
38461                /* 0xF0 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 0, 0),
38462                /* 0xF1 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 0, 1),
38463                /* 0xF2 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 0, 2),
38464                /* 0xF3 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 0, 3),
38465                /* 0xF4 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 1, 0),
38466                /* 0xF5 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 1, 1),
38467                /* 0xF6 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 1, 2),
38468                /* 0xF7 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 1, 3),
38469                /* 0xF8 */ MDRP_MIRP.bind(undefined, 1, 1, 1, 0, 0),
38470                /* 0xF9 */ MDRP_MIRP.bind(undefined, 1, 1, 1, 0, 1),
38471                /* 0xFA */ MDRP_MIRP.bind(undefined, 1, 1, 1, 0, 2),
38472                /* 0xFB */ MDRP_MIRP.bind(undefined, 1, 1, 1, 0, 3),
38473                /* 0xFC */ MDRP_MIRP.bind(undefined, 1, 1, 1, 1, 0),
38474                /* 0xFD */ MDRP_MIRP.bind(undefined, 1, 1, 1, 1, 1),
38475                /* 0xFE */ MDRP_MIRP.bind(undefined, 1, 1, 1, 1, 2),
38476                /* 0xFF */ MDRP_MIRP.bind(undefined, 1, 1, 1, 1, 3)
38477              ];
38478
38479              /*****************************
38480	  Mathematical Considerations
38481	******************************
38482
38483	fv ... refers to freedom vector
38484	pv ... refers to projection vector
38485	rp ... refers to reference point
38486	p  ... refers to to point being operated on
38487	d  ... refers to distance
38488
38489	SETRELATIVE:
38490	============
38491
38492	case freedom vector == x-axis:
38493	------------------------------
38494
38495	                        (pv)
38496	                     .-'
38497	              rpd .-'
38498	               .-*
38499	          d .-'90°'
38500	         .-'       '
38501	      .-'           '
38502	   *-'               ' b
38503	  rp                  '
38504	                       '
38505	                        '
38506	            p *----------*-------------- (fv)
38507	                          pm
38508
38509	  rpdx = rpx + d * pv.x
38510	  rpdy = rpy + d * pv.y
38511
38512	  equation of line b
38513
38514	   y - rpdy = pvns * (x- rpdx)
38515
38516	   y = p.y
38517
38518	   x = rpdx + ( p.y - rpdy ) / pvns
38519
38520
38521	case freedom vector == y-axis:
38522	------------------------------
38523
38524	    * pm
38525	    |\
38526	    | \
38527	    |  \
38528	    |   \
38529	    |    \
38530	    |     \
38531	    |      \
38532	    |       \
38533	    |        \
38534	    |         \ b
38535	    |          \
38536	    |           \
38537	    |            \    .-' (pv)
38538	    |         90° \.-'
38539	    |           .-'* rpd
38540	    |        .-'
38541	    *     *-'  d
38542	    p     rp
38543
38544	  rpdx = rpx + d * pv.x
38545	  rpdy = rpy + d * pv.y
38546
38547	  equation of line b:
38548	           pvns ... normal slope to pv
38549
38550	   y - rpdy = pvns * (x - rpdx)
38551
38552	   x = p.x
38553
38554	   y = rpdy +  pvns * (p.x - rpdx)
38555
38556
38557
38558	generic case:
38559	-------------
38560
38561
38562	                              .'(fv)
38563	                            .'
38564	                          .* pm
38565	                        .' !
38566	                      .'    .
38567	                    .'      !
38568	                  .'         . b
38569	                .'           !
38570	               *              .
38571	              p               !
38572	                         90°   .    ... (pv)
38573	                           ...-*-'''
38574	                  ...---'''    rpd
38575	         ...---'''   d
38576	   *--'''
38577	  rp
38578
38579	    rpdx = rpx + d * pv.x
38580	    rpdy = rpy + d * pv.y
38581
38582	 equation of line b:
38583	    pvns... normal slope to pv
38584
38585	    y - rpdy = pvns * (x - rpdx)
38586
38587	 equation of freedom vector line:
38588	    fvs ... slope of freedom vector (=fy/fx)
38589
38590	    y - py = fvs * (x - px)
38591
38592
38593	  on pm both equations are true for same x/y
38594
38595	    y - rpdy = pvns * (x - rpdx)
38596
38597	    y - py = fvs * (x - px)
38598
38599	  form to y and set equal:
38600
38601	    pvns * (x - rpdx) + rpdy = fvs * (x - px) + py
38602
38603	  expand:
38604
38605	    pvns * x - pvns * rpdx + rpdy = fvs * x - fvs * px + py
38606
38607	  switch:
38608
38609	    fvs * x - fvs * px + py = pvns * x - pvns * rpdx + rpdy
38610
38611	  solve for x:
38612
38613	    fvs * x - pvns * x = fvs * px - pvns * rpdx - py + rpdy
38614
38615
38616
38617	          fvs * px - pvns * rpdx + rpdy - py
38618	    x =  -----------------------------------
38619	                 fvs - pvns
38620
38621	  and:
38622
38623	    y = fvs * (x - px) + py
38624
38625
38626
38627	INTERPOLATE:
38628	============
38629
38630	Examples of point interpolation.
38631
38632	The weight of the movement of the reference point gets bigger
38633	the further the other reference point is away, thus the safest
38634	option (that is avoiding 0/0 divisions) is to weight the
38635	original distance of the other point by the sum of both distances.
38636
38637	If the sum of both distances is 0, then move the point by the
38638	arithmetic average of the movement of both reference points.
38639
38640
38641
38642
38643	           (+6)
38644	    rp1o *---->*rp1
38645	         .     .                          (+12)
38646	         .     .                  rp2o *---------->* rp2
38647	         .     .                       .           .
38648	         .     .                       .           .
38649	         .    10          20           .           .
38650	         |.........|...................|           .
38651	               .   .                               .
38652	               .   . (+8)                          .
38653	                po *------>*p                      .
38654	               .           .                       .
38655	               .    12     .          24           .
38656	               |...........|.......................|
38657	                                  36
38658
38659
38660	-------
38661
38662
38663
38664	           (+10)
38665	    rp1o *-------->*rp1
38666	         .         .                      (-10)
38667	         .         .              rp2 *<---------* rpo2
38668	         .         .                   .         .
38669	         .         .                   .         .
38670	         .    10   .          30       .         .
38671	         |.........|.............................|
38672	                   .                   .
38673	                   . (+5)              .
38674	                po *--->* p            .
38675	                   .    .              .
38676	                   .    .   20         .
38677	                   |....|..............|
38678	                     5        15
38679
38680
38681	-------
38682
38683
38684	           (+10)
38685	    rp1o *-------->*rp1
38686	         .         .
38687	         .         .
38688	    rp2o *-------->*rp2
38689
38690
38691	                               (+10)
38692	                          po *-------->* p
38693
38694	-------
38695
38696
38697	           (+10)
38698	    rp1o *-------->*rp1
38699	         .         .
38700	         .         .(+30)
38701	    rp2o *---------------------------->*rp2
38702
38703
38704	                                        (+25)
38705	                          po *----------------------->* p
38706
38707
38708
38709	vim: set ts=4 sw=4 expandtab:
38710	*****/
38711
38712              // The Font object
38713
38714              // This code is based on Array.from implementation for strings in https://github.com/mathiasbynens/Array.from
38715              var arrayFromString =
38716                Array.from ||
38717                function(s) {
38718                  return (
38719                    s.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]?|[^\uD800-\uDFFF]|./g) || []
38720                  );
38721                };
38722
38723              /**
38724               * @typedef FontOptions
38725               * @type Object
38726               * @property {Boolean} empty - whether to create a new empty font
38727               * @property {string} familyName
38728               * @property {string} styleName
38729               * @property {string=} fullName
38730               * @property {string=} postScriptName
38731               * @property {string=} designer
38732               * @property {string=} designerURL
38733               * @property {string=} manufacturer
38734               * @property {string=} manufacturerURL
38735               * @property {string=} license
38736               * @property {string=} licenseURL
38737               * @property {string=} version
38738               * @property {string=} description
38739               * @property {string=} copyright
38740               * @property {string=} trademark
38741               * @property {Number} unitsPerEm
38742               * @property {Number} ascender
38743               * @property {Number} descender
38744               * @property {Number} createdTimestamp
38745               * @property {string=} weightClass
38746               * @property {string=} widthClass
38747               * @property {string=} fsSelection
38748               */
38749
38750              /**
38751               * A Font represents a loaded OpenType font file.
38752               * It contains a set of glyphs and methods to draw text on a drawing context,
38753               * or to get a path representing the text.
38754               * @exports opentype.Font
38755               * @class
38756               * @param {FontOptions}
38757               * @constructor
38758               */
38759              function Font(options) {
38760                options = options || {};
38761
38762                if (!options.empty) {
38763                  // Check that we've provided the minimum set of names.
38764                  checkArgument(
38765                    options.familyName,
38766                    'When creating a new Font object, familyName is required.'
38767                  );
38768                  checkArgument(
38769                    options.styleName,
38770                    'When creating a new Font object, styleName is required.'
38771                  );
38772                  checkArgument(
38773                    options.unitsPerEm,
38774                    'When creating a new Font object, unitsPerEm is required.'
38775                  );
38776                  checkArgument(
38777                    options.ascender,
38778                    'When creating a new Font object, ascender is required.'
38779                  );
38780                  checkArgument(
38781                    options.descender,
38782                    'When creating a new Font object, descender is required.'
38783                  );
38784                  checkArgument(
38785                    options.descender < 0,
38786                    'Descender should be negative (e.g. -512).'
38787                  );
38788
38789                  // OS X will complain if the names are empty, so we put a single space everywhere by default.
38790                  this.names = {
38791                    fontFamily: { en: options.familyName || ' ' },
38792                    fontSubfamily: { en: options.styleName || ' ' },
38793                    fullName: {
38794                      en: options.fullName || options.familyName + ' ' + options.styleName
38795                    },
38796                    // postScriptName may not contain any whitespace
38797                    postScriptName: {
38798                      en:
38799                        options.postScriptName ||
38800                        (options.familyName + options.styleName).replace(/\s/g, '')
38801                    },
38802                    designer: { en: options.designer || ' ' },
38803                    designerURL: { en: options.designerURL || ' ' },
38804                    manufacturer: { en: options.manufacturer || ' ' },
38805                    manufacturerURL: { en: options.manufacturerURL || ' ' },
38806                    license: { en: o
38806ptions.license || ' ' },
38807                    licenseURL: { en: options.licenseURL || ' ' },
38808                    version: { en: options.version || 'Version 0.1' },
38809                    description: { en: options.description || ' ' },
38810                    copyright: { en: options.copyright || ' ' },
38811                    trademark: { en: options.trademark || ' ' }
38812                  };
38813                  this.unitsPerEm = options.unitsPerEm || 1000;
38814                  this.ascender = options.ascender;
38815                  this.descender = options.descender;
38816                  this.createdTimestamp = options.createdTimestamp;
38817                  this.tables = {
38818                    os2: {
38819                      usWeightClass: options.weightClass || this.usWeightClasses.MEDIUM,
38820                      usWidthClass: options.widthClass || this.usWidthClasses.MEDIUM,
38821                      fsSelection: options.fsSelection || this.fsSelectionValues.REGULAR
38822                    }
38823                  };
38824                }
38825
38826                this.supported = true; // Deprecated: parseBuffer will throw an error if font is not supported.
38827                this.glyphs = new glyphset.GlyphSet(this, options.glyphs || []);
38828                this.encoding = new DefaultEncoding(this);
38829                this.position = new Position(this);
38830                this.substitution = new Substitution(this);
38831                this.tables = this.tables || {};
38832
38833                Object.defineProperty(this, 'hinting', {
38834                  get: function() {
38835                    if (this._hinting) {
38836                      return this._hinting;
38837                    }
38838                    if (this.outlinesFormat === 'truetype') {
38839                      return (this._hinting = new Hinting(this));
38840                    }
38841                  }
38842                });
38843              }
38844
38845              /**
38846               * Check if the font has a glyph for the given character.
38847               * @param  {string}
38848               * @return {Boolean}
38849               */
38850              Font.prototype.hasChar = function(c) {
38851                return this.encoding.charToGlyphIndex(c) !== null;
38852              };
38853
38854              /**
38855               * Convert the given character to a single glyph index.
38856               * Note that this function assumes that there is a one-to-one mapping between
38857               * the given character and a glyph; for complex scripts this might not be the case.
38858               * @param  {string}
38859               * @return {Number}
38860               */
38861              Font.prototype.charToGlyphIndex = function(s) {
38862                return this.encoding.charToGlyphIndex(s);
38863              };
38864
38865              /**
38866               * Convert the given character to a single Glyph object.
38867               * Note that this function assumes that there is a one-to-one mapping between
38868               * the given character and a glyph; for complex scripts this might not be the case.
38869               * @param  {string}
38870               * @return {opentype.Glyph}
38871               */
38872              Font.prototype.charToGlyph = function(c) {
38873                var glyphIndex = this.charToGlyphIndex(c);
38874                var glyph = this.glyphs.get(glyphIndex);
38875                if (!glyph) {
38876                  // .notdef
38877                  glyph = this.glyphs.get(0);
38878                }
38879
38880                return glyph;
38881              };
38882
38883              /**
38884               * Convert the given text to a list of Glyph objects.
38885               * Note that there is no strict one-to-one mapping between characters and
38886               * glyphs, so the list of returned glyphs can be larger or smaller than the
38887               * length of the given string.
38888               * @param  {string}
38889               * @param  {GlyphRenderOptions} [options]
38890               * @return {opentype.Glyph[]}
38891               */
38892              Font.prototype.stringToGlyphs = function(s, options) {
38893                var this$1 = this;
38894
38895                options = options || this.defaultRenderOptions;
38896                // Get glyph indexes
38897                var chars = arrayFromString(s);
38898                var indexes = [];
38899                for (var i = 0; i < chars.length; i += 1) {
38900                  var c = chars[i];
38901                  indexes.push(this$1.charToGlyphIndex(c));
38902                }
38903                var length = indexes.length;
38904
38905                // Apply substitutions on glyph indexes
38906                if (options.features) {
38907                  var script = options.script || this.substitution.getDefaultScriptName();
38908                  var manyToOne = [];
38909                  if (options.features.liga) {
38910                    manyToOne = manyToOne.concat(
38911                      this.substitution.getFeature('liga', script, options.language)
38912                    );
38913                  }
38914                  if (options.features.rlig) {
38915                    manyToOne = manyToOne.concat(
38916                      this.substitution.getFeature('rlig', script, options.language)
38917                    );
38918                  }
38919                  for (var i$1 = 0; i$1 < length; i$1 += 1) {
38920                    for (var j = 0; j < manyToOne.length; j++) {
38921                      var ligature = manyToOne[j];
38922                      var components = ligature.sub;
38923                      var compCount = components.length;
38924                      var k = 0;
38925                      while (k < compCount && components[k] === indexes[i$1 + k]) {
38926                        k++;
38927                      }
38928                      if (k === compCount) {
38929                        indexes.splice(i$1, compCount, ligature.by);
38930                        length = length - compCount + 1;
38931                      }
38932                    }
38933                  }
38934                }
38935
38936                // convert glyph indexes to glyph objects
38937                var glyphs = new Array(length);
38938                var notdef = this.glyphs.get(0);
38939                for (var i$2 = 0; i$2 < length; i$2 += 1) {
38940                  glyphs[i$2] = this$1.glyphs.get(indexes[i$2]) || notdef;
38941                }
38942                return glyphs;
38943              };
38944
38945              /**
38946               * @param  {string}
38947               * @return {Number}
38948               */
38949              Font.prototype.nameToGlyphIndex = function(name) {
38950                return this.glyphNames.nameToGlyphIndex(name);
38951              };
38952
38953              /**
38954               * @param  {string}
38955               * @return {opentype.Glyph}
38956               */
38957              Font.prototype.nameToGlyph = function(name) {
38958                var glyphIndex = this.nameToGlyphIndex(name);
38959                var glyph = this.glyphs.get(glyphIndex);
38960                if (!glyph) {
38961                  // .notdef
38962                  glyph = this.glyphs.get(0);
38963                }
38964
38965                return glyph;
38966              };
38967
38968              /**
38969               * @param  {Number}
38970               * @return {String}
38971               */
38972              Font.prototype.glyphIndexToName = function(gid) {
38973                if (!this.glyphNames.glyphIndexToName) {
38974                  return '';
38975                }
38976
38977                return this.glyphNames.glyphIndexToName(gid);
38978              };
38979
38980              /**
38981               * Retrieve the value of the kerning pair between the left glyph (or its index)
38982               * and the right glyph (or its index). If no kerning pair is found, return 0.
38983               * The kerning value gets added to the advance width when calculating the spacing
38984               * between glyphs.
38985               * For GPOS kerning, this method uses the default script and language, which covers
38986               * most use cases. To have greater control, use font.position.getKerningValue .
38987               * @param  {opentype.Glyph} leftGlyph
38988               * @param  {opentype.Glyph} rightGlyph
38989               * @return {Number}
38990               */
38991              Font.prototype.getKerningValue = function(leftGlyph, rightGlyph) {
38992                leftGlyph = leftGlyph.index || leftGlyph;
38993                rightGlyph = rightGlyph.index || rightGlyph;
38994                var gposKerning = this.position.defaultKerningTables;
38995                if (gposKerning) {
38996                  return this.position.getKerningValue(gposKerning, leftGlyph, rightGlyph);
38997                }
38998                // "kern" table
38999                return this.kerningPairs[leftGlyph + ',' + rightGlyph] || 0;
39000              };
39001
39002              /**
39003               * @typedef GlyphRenderOptions
39004               * @type Object
39005               * @property {string} [script] - script used to determine which features to apply. By default, 'DFLT' or 'latn' is used.
39006               *                               See https://www.microsoft.com/typography/otspec/scripttags.htm
39007               * @property {string} [language='dflt'] - language system used to determine which features to apply.
39008               *                                        See https://www.microsoft.com/typography/developers/opentype/languagetags.aspx
39009               * @property {boolean} [kerning=true] - whether to include kerning values
39010               * @property {object} [features] - OpenType Layout feature tags. Used to enable or disable the features of the given script/language system.
39011               *                                 See https://www.microsoft.com/typography/otspec/featuretags.htm
39012               */
39013              Font.prototype.defaultRenderOptions = {
39014                kerning: true,
39015                features: {
39016                  liga: true,
39017                  rlig: true
39018                }
39019              };
39020
39021              /**
39022               * Helper function that invokes the given callback for each glyph in the given text.
39023               * The callback gets `(glyph, x, y, fontSize, options)`.* @param  {string} text
39024               * @param {string} text - The text to apply.
39025               * @param  {number} [x=0] - Horizontal position of the beginning of the text.
39026               * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
39027               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
39028               * @param  {GlyphRenderOptions=} options
39029               * @param  {Function} callback
39030               */
39031              Font.prototype.forEachGlyph = function(
39032                text,
39033                x,
39034                y,
39035                fontSize,
39036                options,
39037                callback
39038              ) {
39039                var this$1 = this;
39040
39041                x = x !== undefined ? x : 0;
39042                y = y !== undefined ? y : 0;
39043                fontSize = fontSize !== undefined ? fontSize : 72;
39044                options = options || this.defaultRenderOptions;
39045                var fontScale = 1 / this.unitsPerEm * fontSize;
39046                var glyphs = this.stringToGlyphs(text, options);
39047                var kerningLookups;
39048                if (options.kerning) {
39049                  var script = options.script || this.position.getDefaultScriptName();
39050                  kerningLookups = this.position.getKerningTables(script, options.language);
39051                }
39052                for (var i = 0; i < glyphs.length; i += 1) {
39053                  var glyph = glyphs[i];
39054                  callback.call(this$1, glyph, x, y, fontSize, options);
39055                  if (glyph.advanceWidth) {
39056                    x += glyph.advanceWidth * fontScale;
39057                  }
39058
39059                  if (options.kerning && i < glyphs.length - 1) {
39060                    // We should apply position adjustment lookups in a more generic way.
39061                    // Here we only use the xAdvance value.
39062                    var kerningValue = kerningLookups
39063                      ? this$1.position.getKerningValue(
39064                          kerningLookups,
39065                          glyph.index,
39066                          glyphs[i + 1].index
39067                        )
39068                      : this$1.getKerningValue(glyph, glyphs[i + 1]);
39069                    x += kerningValue * fontScale;
39070                  }
39071
39072                  if (options.letterSpacing) {
39073                    x += options.letterSpacing * fontSize;
39074                  } else if (options.tracking) {
39075                    x += options.tracking / 1000 * fontSize;
39076                  }
39077                }
39078                return x;
39079              };
39080
39081              /**
39082               * Create a Path object that represents the given text.
39083               * @param  {string} text - The text to create.
39084               * @param  {number} [x=0] - Horizontal position of the beginning of the text.
39085               * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
39086               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
39087               * @param  {GlyphRenderOptions=} options
39088               * @return {opentype.Path}
39089               */
39090              Font.prototype.getPath = function(text, x, y, fontSize, options) {
39091                var fullPath = new Path();
39092                this.forEachGlyph(text, x, y, fontSize, options, function(
39093                  glyph,
39094                  gX,
39095                  gY,
39096                  gFontSize
39097                ) {
39098                  var glyphPath = glyph.getPath(gX, gY, gFontSize, options, this);
39099                  fullPath.extend(glyphPath);
39100                });
39101                return fullPath;
39102              };
39103
39104              /**
39105               * Create an array of Path objects that represent the glyphs of a given text.
39106               * @param  {string} text - The text to create.
39107               * @param  {number} [x=0] - Horizontal position of the beginning of the text.
39108               * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
39109               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
39110               * @param  {GlyphRenderOptions=} options
39111               * @return {opentype.Path[]}
39112               */
39113              Font.prototype.getPaths = function(text, x, y, fontSize, options) {
39114                var glyphPaths = [];
39115                this.forEachGlyph(text, x, y, fontSize, options, function(
39116                  glyph,
39117                  gX,
39118                  gY,
39119                  gFontSize
39120                ) {
39121                  var glyphPath = glyph.getPath(gX, gY, gFontSize, options, this);
39122                  glyphPaths.push(glyphPath);
39123                });
39124
39125                return glyphPaths;
39126              };
39127
39128              /**
39129               * Returns the advance width of a text.
39130               *
39131               * This is something different than Path.getBoundingBox() as for example a
39132               * suffixed whitespace increases the advanceWidth but not the bounding box
39133               * or an overhanging letter like a calligraphic 'f' might have a quite larger
39134               * bounding box than its advance width.
39135               *
39136               * This corresponds to canvas2dContext.measureText(text).width
39137               *
39138               * @param  {string} text - The text to create.
39139               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
39140               * @param  {GlyphRenderOptions=} options
39141               * @return advance width
39142               */
39143              Font.prototype.getAdvanceWidth = function(text, fontSize, options) {
39144                return this.forEachGlyph(text, 0, 0, fontSize, options, function() {});
39145              };
39146
39147              /**
39148               * Draw the text on the given drawing context.
39149               * @param  {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
39150               * @param  {string} text - The text to create.
39151               * @param  {number} [x=0] - Horizontal position of the beginning of the text.
39152               * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
39153               * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
39154               * @param  {GlyphRenderOptions=} options
39155               */
39156              Font.prototype.draw = function(ctx, text, x, y, fontSize, options) {
39157                this.getPath(text, x, y, fontSize, options).draw(ctx);
39158              };
39159
39160              /**
39161               * Draw the points of all glyphs in the text.
39162               * On-curve points will be drawn in blue, off-curve points will be drawn in red.
39163               * @param {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
39164               * @param {string} text - The text to create.
39165               * @param {number} [x=0] - Horizontal position of the beginning of the text.
39166               * @param {number} [y=0] - Vertical position of the *baseline* of the text.
39167               * @param {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
39168               * @param {GlyphRenderOptions=} options
39169               */
39170              Font.prototype.drawPoints = function(ctx, text, x, y, fontSize, options) {
39171                this.forEachGlyph(text, x, y, fontSize, options, function(
39172                  glyph,
39173                  gX,
39174                  gY,
39175                  gFontSize
39176                ) {
39177                  glyph.drawPoints(ctx, gX, gY, gFontSize);
39178                });
39179              };
39180
39181              /**
39182               * Draw lines indicating important font measurements for all glyphs in the text.
39183               * Black lines indicate the origin of the coordinate system (point 0,0).
39184               * Blue lines indicate the glyph bounding box.
39185               * Green line indicates the advance width of the glyph.
39186               * @param {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
39187               * @param {string} text - The text to create.
39188               * @param {number} [x=0] - Horizontal position of the beginning of the text.
39189               * @param {number} [y=0] - Vertical position of the *baseline* of the text.
39190               * @param {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
39191               * @param {GlyphRenderOptions=} options
39192               */
39193              Font.prototype.drawMetrics = function(ctx, text, x, y, fontSize, options) {
39194                this.forEachGlyph(text, x, y, fontSize, options, function(
39195                  glyph,
39196                  gX,
39197                  gY,
39198                  gFontSize
39199                ) {
39200                  glyph.drawMetrics(ctx, gX, gY, gFontSize);
39201                });
39202              };
39203
39204              /**
39205               * @param  {string}
39206               * @return {string}
39207               */
39208              Font.prototype.getEnglishName = function(name) {
39209                var translations = this.names[name];
39210                if (translations) {
39211                  return translations.en;
39212                }
39213              };
39214
39215              /**
39216               * Validate
39217               */
39218              Font.prototype.validate = function() {
39219                var _this = this;
39220
39221                function assert(predicate, message) {}
39222
39223                function assertNamePresent(name) {
39224                  var englishName = _this.getEnglishName(name);
39225                  assert(
39226                    englishName && englishName.trim().length > 0,
39227                    'No English ' + name + ' specified.'
39228                  );
39229                }
39230
39231                // Identification information
39232                assertNamePresent('fontFamily');
39233                assertNamePresent('weightName');
39234                assertNamePresent('manufacturer');
39235                assertNamePresent('copyright');
39236                assertNamePresent('version');
39237
39238                // Dimension information
39239                assert(this.unitsPerEm > 0, 'No unitsPerEm specified.');
39240              };
39241
39242              /**
39243               * Convert the font object to a SFNT data structure.
39244               * This structure contains all the necessary tables and metadata to create a binary OTF file.
39245               * @return {opentype.Table}
39246               */
39247              Font.prototype.toTables = function() {
39248                return sfnt.fontToTable(this);
39249              };
39250              /**
39251               * @deprecated Font.toBuffer is deprecated. Use Font.toArrayBuffer instead.
39252               */
39253              Font.prototype.toBuffer = function() {
39254                console.warn(
39255                  'Font.toBuffer is deprecated. Use Font.toArrayBuffer instead.'
39256                );
39257                return this.toArrayBuffer();
39258              };
39259              /**
39260               * Converts a `opentype.Font` into an `ArrayBuffer`
39261               * @return {ArrayBuffer}
39262               */
39263              Font.prototype.toArrayBuffer = function() {
39264                var sfntTable = this.toTables();
39265                var bytes = sfntTable.encode();
39266                var buffer = new ArrayBuffer(bytes.length);
39267                var intArray = new Uint8Array(buffer);
39268                for (var i = 0; i < bytes.length; i++) {
39269                  intArray[i] = bytes[i];
39270                }
39271
39272                return buffer;
39273              };
39274
39275              /**
39276               * Initiate a download of the OpenType font.
39277               */
39278              Font.prototype.download = function(fileName) {
39279                var familyName = this.getEnglishName('fontFamily');
39280                var styleName = this.getEnglishName('fontSubfamily');
39281                fileName =
39282                  fileName || familyName.replace(/\s/g, '') + '-' + styleName + '.otf';
39283                var arrayBuffer = this.toArrayBuffer();
39284
39285                if (isBrowser()) {
39286                  window.requestFileSystem =
39287                    window.requestFileSystem || window.webkitRequestFileSystem;
39288                  window.requestFileSystem(
39289                    window.TEMPORARY,
39290                    arrayBuffer.byteLength,
39291                    function(fs) {
39292                      fs.root.getFile(fileName, { create: true }, function(fileEntry) {
39293                        fileEntry.createWriter(function(writer) {
39294                          var dataView = new DataView(arrayBuffer);
39295                          var blob = new Blob([dataView], { type: 'font/opentype' });
39296                          writer.write(blob);
39297
39298                          writer.addEventListener(
39299                            'writeend',
39300                            function() {
39301                              // Navigating to the file will download it.
39302                              location.href = fileEntry.toURL();
39303                            },
39304                            false
39305                          );
39306                        });
39307                      });
39308                    },
39309                    function(err) {
39310                      throw new Error(err.name + ': ' + err.message);
39311                    }
39312                  );
39313                } else {
39314                  var fs = _dereq_('fs');
39315                  var buffer = arrayBufferToNodeBuffer(arrayBuffer);
39316                  fs.writeFileSync(fileName, buffer);
39317                }
39318              };
39319              /**
39320               * @private
39321               */
39322              Font.prototype.fsSelectionValues = {
39323                ITALIC: 0x001, //1
39324                UNDERSCORE: 0x002, //2
39325                NEGATIVE: 0x004, //4
39326                OUTLINED: 0x008, //8
39327                STRIKEOUT: 0x010, //16
39328                BOLD: 0x020, //32
39329                REGULAR: 0x040, //64
39330                USER_TYPO_METRICS: 0x080, //128
39331                WWS: 0x100, //256
39332                OBLIQUE: 0x200 //512
39333              };
39334
39335              /**
39336               * @private
39337               */
39338              Font.prototype.usWidthClasses = {
39339                ULTRA_CONDENSED: 1,
39340                EXTRA_CONDENSED: 2,
39341                CONDENSED: 3,
39342                SEMI_CONDENSED: 4,
39343                MEDIUM: 5,
39344                SEMI_EXPANDED: 6,
39345                EXPANDED: 7,
39346                EXTRA_EXPANDED: 8,
39347                ULTRA_EXPANDED: 9
39348              };
39349
39350              /**
39351               * @private
39352               */
39353              Font.prototype.usWeightClasses = {
39354                THIN: 100,
39355                EXTRA_LIGHT: 200,
39356                LIGHT: 300,
39357                NORMAL: 400,
39358                MEDIUM: 500,
39359                SEMI_BOLD: 600,
39360                BOLD: 700,
39361                EXTRA_BOLD: 800,
39362                BLACK: 900
39363              };
39364
39365              // The `fvar` table stores font variation axes and instances.
39366
39367              function addName(name, names) {
39368                var nameString = JSON.stringify(name);
39369                var nameID = 256;
39370                for (var nameKey in names) {
39371                  var n = parseInt(nameKey);
39372                  if (!n || n < 256) {
39373                    continue;
39374                  }
39375
39376                  if (JSON.stringify(names[nameKey]) === nameString) {
39377                    return n;
39378                  }
39379
39380                  if (nameID <= n) {
39381                    nameID = n + 1;
39382                  }
39383                }
39384
39385                names[nameID] = name;
39386                return nameID;
39387              }
39388
39389              function makeFvarAxis(n, axis, names) {
39390                var nameID = addName(axis.name, names);
39391                return [
39392                  { name: 'tag_' + n, type: 'TAG', value: axis.tag },
39393                  { name: 'minValue_' + n, type: 'FIXED', value: axis.minValue << 16 },
39394                  {
39395                    name: 'defaultValue_' + n,
39396                    type: 'FIXED',
39397                    value: axis.defaultValue << 16
39398                  },
39399                  { name: 'maxValue_' + n, type: 'FIXED', value: axis.maxValue << 16 },
39400                  { name: 'flags_' + n, type: 'USHORT', value: 0 },
39401                  { name: 'nameID_' + n, type: 'USHORT', value: nameID }
39402                ];
39403              }
39404
39405              function parseFvarAxis(data, start, names) {
39406                var axis = {};
39407                var p = new parse.Parser(data, start);
39408                axis.tag = p.parseTag();
39409                axis.minValue = p.parseFixed();
39410                axis.defaultValue = p.parseFixed();
39411                axis.maxValue = p.parseFixed();
39412                p.skip('uShort', 1); // reserved for flags; no values defined
39413                axis.name = names[p.parseUShort()] || {};
39414                return axis;
39415              }
39416
39417              function makeFvarInstance(n, inst, axes, names) {
39418                var nameID = addName(inst.name, names);
39419                var fields = [
39420                  { name: 'nameID_' + n, type: 'USHORT', value: nameID },
39421                  { name: 'flags_' + n, type: 'USHORT', value: 0 }
39422                ];
39423
39424                for (var i = 0; i < axes.length; ++i) {
39425                  var axisTag = axes[i].tag;
39426                  fields.push({
39427                    name: 'axis_' + n + ' ' + axisTag,
39428                    type: 'FIXED',
39429                    value: inst.coordinates[axisTag] << 16
39430                  });
39431                }
39432
39433                return fields;
39434              }
39435
39436              function parseFvarInstance(data, start, axes, names) {
39437                var inst = {};
39438                var p = new parse.Parser(data, start);
39439                inst.name = names[p.parseUShort()] || {};
39440                p.skip('uShort', 1); // reserved for flags; no values defined
39441
39442                inst.coordinates = {};
39443                for (var i = 0; i < axes.length; ++i) {
39444                  inst.coordinates[axes[i].tag] = p.parseFixed();
39445                }
39446
39447                return inst;
39448              }
39449
39450              function makeFvarTable(fvar, names) {
39451                var result = new table.Table('fvar', [
39452                  { name: 'version', type: 'ULONG', value: 0x10000 },
39453                  { name: 'offsetToData', type: 'USHORT', value: 0 },
39454                  { name: 'countSizePairs', type: 'USHORT', value: 2 },
39455                  { name: 'axisCount', type: 'USHORT', value: fvar.axes.length },
39456                  { name: 'axisSize', type: 'USHORT', value: 20 },
39457                  { name: 'instanceCount', type: 'USHORT', value: fvar.instances.length },
39458                  { name: 'instanceSize', type: 'USHORT', value: 4 + fvar.axes.length * 4 }
39459                ]);
39460                result.offsetToData = result.sizeOf();
39461
39462                for (var i = 0; i < fvar.axes.length; i++) {
39463                  result.fields = result.fields.concat(
39464                    makeFvarAxis(i, fvar.axes[i], names)
39465                  );
39466                }
39467
39468                for (var j = 0; j < fvar.instances.length; j++) {
39469                  result.fields = result.fields.concat(
39470                    makeFvarInstance(j, fvar.instances[j], fvar.axes, names)
39471                  );
39472                }
39473
39474                return result;
39475              }
39476
39477              function parseFvarTable(data, start, names) {
39478                var p = new parse.Parser(data, start);
39479                var tableVersion = p.parseULong();
39480                check.argument(
39481                  tableVersion === 0x00010000,
39482                  'Unsupported fvar table version.'
39483                );
39484                var offsetToData = p.parseOffset16();
39485                // Skip countSizePairs.
vendor: 4,372 bytes, lines 39486-39584
39486                p.skip('uShort', 1);
39487                var axisCount = p.parseUShort();
39488                var axisSize = p.parseUShort();
39489                var instanceCount = p.parseUShort();
39490                var instanceSize = p.parseUShort();
39491
39492                var axes = [];
39493                for (var i = 0; i < axisCount; i++) {
39494                  axes.push(
39495                    parseFvarAxis(data, start + offsetToData + i * axisSize, names)
39496                  );
39497                }
39498
39499                var instances = [];
39500                var instanceStart = start + offsetToData + axisCount * axisSize;
39501                for (var j = 0; j < instanceCount; j++) {
39502                  instances.push(
39503                    parseFvarInstance(data, instanceStart + j * instanceSize, axes, names)
39504                  );
39505                }
39506
39507                return { axes: axes, instances: instances };
39508              }
39509
39510              var fvar = { make: makeFvarTable, parse: parseFvarTable };
39511
39512              // The `GPOS` table contains kerning pairs, among other things.
39513
39514              var subtableParsers$1 = new Array(10); // subtableParsers[0] is unused
39515
39516              // https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-1-single-adjustment-positioning-subtable
39517              // this = Parser instance
39518              subtableParsers$1[1] = function parseLookup1() {
39519                var start = this.offset + this.relativeOffset;
39520                var posformat = this.parseUShort();
39521                if (posformat === 1) {
39522                  return {
39523                    posFormat: 1,
39524                    coverage: this.parsePointer(Parser.coverage),
39525                    value: this.parseValueRecord()
39526                  };
39527                } else if (posformat === 2) {
39528                  return {
39529                    posFormat: 2,
39530                    coverage: this.parsePointer(Parser.coverage),
39531                    values: this.parseValueRecordList()
39532                  };
39533                }
39534                check.assert(
39535                  false,
39536                  '0x' + start.toString(16) + ': GPOS lookup type 1 format must be 1 or 2.'
39537                );
39538              };
39539
39540              // https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-2-pair-adjustment-positioning-subtable
39541              subtableParsers$1[2] = function parseLookup2() {
39542                var start = this.offset + this.relativeOffset;
39543                var posFormat = this.parseUShort();
39544                check.assert(
39545                  posFormat === 1 || posFormat === 2,
39546                  '0x' + start.toString(16) + ': GPOS lookup type 2 format must be 1 or 2.'
39547                );
39548                var coverage = this.parsePointer(Parser.coverage);
39549                var valueFormat1 = this.parseUShort();
39550                var valueFormat2 = this.parseUShort();
39551                if (posFormat === 1) {
39552                  // Adjustments for Glyph Pairs
39553                  return {
39554                    posFormat: posFormat,
39555                    coverage: coverage,
39556                    valueFormat1: valueFormat1,
39557                    valueFormat2: valueFormat2,
39558                    pairSets: this.parseList(
39559                      Parser.pointer(
39560                        Parser.list(function() {
39561                          return {
39562                            // pairValueRecord
39563                            secondGlyph: this.parseUShort(),
39564                            value1: this.parseValueRecord(valueFormat1),
39565                            value2: this.parseValueRecord(valueFormat2)
39566                          };
39567                        })
39568                      )
39569                    )
39570                  };
39571                } else if (posFormat === 2) {
39572                  var classDef1 = this.parsePointer(Parser.classDef);
39573                  var classDef2 = this.parsePointer(Parser.classDef);
39574                  var class1Count = this.parseUShort();
39575                  var class2Count = this.parseUShort();
39576                  return {
39577                    // Class Pair Adjustment
39578                    posFormat: posFormat,
39579                    coverage: coverage,
39580                    valueFormat1: valueFormat1,
39581                    valueFormat2: valueFormat2,
39582                    classDef1: classDef1,
39583                    classDef2: classDef2,
39584                    class1Count: class1Count,
39585                    class2Count: class2Count,
39586                    classRecords: this.parseList(
39587                      class1Count,
39588                      Parser.list(class2Count, function() {
39589                        return {
39590                          value1: this.parseValueRecord(valueFormat1),
39591                          value2: this.parseValueRecord(valueFormat2)
39592                        };
39593                      })
39594                    )
39595                  };
39596                }
39597              };
39598
39599              subtableParsers$1[3] = function parseLookup3() {
39600                return { error: 'GPOS Lookup 3 not supported' };
39601              };
39602              subtableParsers$1[4] = function parseLookup4() {
39603                return { error: 'GPOS Lookup 4 not supported' };
39604              };
39605              subtableParsers$1[5] = function parseLookup5() {
39606                return { error: 'GPOS Lookup 5 not supported' };
39607              };
39608              subtableParsers$1[6] = function parseLookup6() {
39609                return { error: 'GPOS Lookup 6 n
39609ot supported' };
39610              };
39611              subtableParsers$1[7] = function parseLookup7() {
39612                return { error: 'GPOS Lookup 7 not supported' };
39613              };
39614              subtableParsers$1[8] = function parseLookup8() {
39615                return { error: 'GPOS Lookup 8 not supported' };
39616              };
39617              subtableParsers$1[9] = function parseLookup9() {
39618                return { error: 'GPOS Lookup 9 not supported' };
39619              };
39620
39621              // https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
39622              function parseGposTable(data, start) {
39623                start = start || 0;
39624                var p = new Parser(data, start);
39625                var tableVersion = p.parseVersion(1);
39626                check.argument(
39627                  tableVersion === 1 || tableVersion === 1.1,
39628                  'Unsupported GPOS table version ' + tableVersion
39629                );
39630
39631                if (tableVersion === 1) {
39632                  return {
39633                    version: tableVersion,
39634                    scripts: p.parseScriptList(),
39635                    features: p.parseFeatureList(),
39636                    lookups: p.parseLookupList(subtableParsers$1)
39637                  };
39638                } else {
39639                  return {
39640                    version: tableVersion,
39641                    scripts: p.parseScriptList(),
39642                    features: p.parseFeatureList(),
39643                    lookups: p.parseLookupList(subtableParsers$1),
39644                    variations: p.parseFeatureVariationsList()
39645                  };
39646                }
39647              }
39648
39649              // GPOS Writing //////////////////////////////////////////////
39650              // NOT SUPPORTED
39651              var subtableMakers$1 = new Array(10);
39652
39653              function makeGposTable(gpos) {
39654                return new table.Table('GPOS', [
39655                  { name: 'version', type: 'ULONG', value: 0x10000 },
39656                  {
39657                    name: 'scripts',
39658                    type: 'TABLE',
39659                    value: new table.ScriptList(gpos.scripts)
39660                  },
39661                  {
39662                    name: 'features',
39663                    type: 'TABLE',
39664                    value: new table.FeatureList(gpos.features)
39665                  },
39666                  {
39667                    name: 'lookups',
39668                    type: 'TABLE',
39669                    value: new table.LookupList(gpos.lookups, subtableMakers$1)
39670                  }
39671                ]);
39672              }
39673
39674              var gpos = { parse: parseGposTable, make: makeGposTable };
39675
39676              // The `kern` table contains kerning pairs.
39677
39678              function parseWindowsKernTable(p) {
39679                var pairs = {};
39680                // Skip nTables.
39681                p.skip('uShort');
39682                var subtableVersion = p.parseUShort();
39683                check.argument(
39684                  subtableVersion === 0,
39685                  'Unsupported kern sub-table version.'
39686                );
39687                // Skip subtableLength, subtableCoverage
39688                p.skip('uShort', 2);
39689                var nPairs = p.parseUShort();
39690                // Skip searchRange, entrySelector, rangeShift.
39691                p.skip('uShort', 3);
39692                for (var i = 0; i < nPairs; i += 1) {
39693                  var leftIndex = p.parseUShort();
39694                  var rightIndex = p.parseUShort();
39695                  var value = p.parseShort();
39696                  pairs[leftIndex + ',' + rightIndex] = value;
39697                }
39698                return pairs;
39699              }
39700
39701              function parseMacKernTable(p) {
39702                var pairs = {};
39703                // The Mac kern table stores the version as a fixed (32 bits) but we only loaded the first 16 bits.
39704                // Skip the rest.
39705                p.skip('uShort');
39706                var nTables = p.parseULong();
39707                //check.argument(nTables === 1, 'Only 1 subtable is supported (got ' + nTables + ').');
39708                if (nTables > 1) {
39709                  console.warn('Only the first kern subtable is supported.');
39710                }
39711                p.skip('uLong');
39712                var coverage = p.parseUShort();
39713                var subtableVersion = coverage & 0xff;
39714                p.skip('uShort');
39715                if (subtableVersion === 0) {
39716                  var nPairs = p.parseUShort();
39717                  // Skip searchRange, entrySelector, rangeShift.
39718                  p.skip('uShort', 3);
39719                  for (var i = 0; i < nPairs; i += 1) {
39720                    var leftIndex = p.parseUShort();
39721                    var rightIndex = p.parseUShort();
39722                    var value = p.parseShort();
39723                    pairs[leftIndex + ',' + rightIndex] = value;
39724                  }
39725                }
39726                return pairs;
39727              }
39728
39729              // Parse the `kern` table which contains kerning pairs.
39730              function parseKernTable(data, start) {
39731                var p = new parse.Parser(data, start);
39732                var tableVersion = p.parseUShort();
39733                if (tableVersion === 0) {
39734                  return parseWindowsKernTable(p);
39735                } else if (tableVersion === 1) {
39736                  return parseMacKernTable(p);
39737                } else {
39738                  throw new Error('Unsupported kern table version (' + tableVersion + ').');
39739                }
39740              }
39741
39742              var kern = { parse: parseKernTable };
39743
39744              // The `loca` table stores the offsets to the locations of the glyphs in the font.
39745
39746              // Parse the `loca` table. This table stores the offsets to the locations of the glyphs in the font,
39747              // relative to the beginning of the glyphData table.
39748              // The number of glyphs stored in the `loca` table is specified in the `maxp` table (under numGlyphs)
39749              // The loca table has two versions: a short version where offsets are stored as uShorts, and a long
39750              // version where offsets are stored as uLongs. The `head` table specifies which version to use
39751              // (under indexToLocFormat).
39752              function parseLocaTable(data, start, numGlyphs, shortVersion) {
39753                var p = new parse.Parser(data, start);
39754                var parseFn = shortVersion ? p.parseUShort : p.parseULong;
39755                // There is an extra entry after the last index element to compute the length of the last glyph.
39756                // That's why we use numGlyphs + 1.
39757                var glyphOffsets = [];
39758                for (var i = 0; i < numGlyphs + 1; i += 1) {
39759                  var glyphOffset = parseFn.call(p);
39760                  if (shortVersion) {
39761                    // The short table version stores the actual offset divided by 2.
39762                    glyphOffset *= 2;
39763                  }
39764
39765                  glyphOffsets.push(glyphOffset);
39766                }
39767
39768                return glyphOffsets;
39769              }
39770
39771              var loca = { parse: parseLocaTable };
39772
39773              // opentype.js
39774
39775              /**
39776               * The opentype library.
39777               * @namespace opentype
39778               */
39779
39780              // File loaders /////////////////////////////////////////////////////////
39781              /**
39782               * Loads a font from a file. The callback throws an error message as the first parameter if it fails
39783               * and the font as an ArrayBuffer in the second parameter if it succeeds.
39784               * @param  {string} path - The path of the file
39785               * @param  {Function} callback - The function to call when the font load completes
39786               */
39787              function loadFromFile(path, callback) {
39788                var fs = _dereq_('fs');
39789                fs.readFile(path, function(err, buffer) {
39790                  if (err) {
39791                    return callback(err.message);
39792                  }
39793
39794                  callback(null, nodeBufferToArrayBuffer(buffer));
39795                });
39796              }
39797              /**
39798               * Loads a font from a URL. The callback throws an error message as the first parameter if it fails
39799               * and the font as an ArrayBuffer in the second parameter if it succeeds.
39800               * @param  {string} url - The URL of the font file.
39801               * @param  {Function} callback - The function to call when the font load completes
39802               */
39803              function loadFromUrl(url, callback) {
39804                var request = new XMLHttpRequest();
39805                request.open('get', url, true);
39806                request.responseType = 'arraybuffer';
39807                request.onload = function() {
39808                  if (request.response) {
39809                    return callback(null, request.response);
39810                  } else {
39811                    return callback('Font could not be loaded: ' + request.statusText);
39812                  }
39813                };
39814
39815                request.onerror = function() {
39816                  callback('Font could not be loaded');
39817                };
39818
39819                request.send();
39820              }
39821
39822              // Table Directory Entries //////////////////////////////////////////////
39823              /**
vendor: 10,809 bytes, lines 39824-40074
39824               * Parses OpenType table entries.
39825               * @param  {DataView}
39826               * @param  {Number}
39827               * @return {Object[]}
39828               */
39829              function parseOpenTypeTableEntries(data, numTables) {
39830                var tableEntries = [];
39831                var p = 12;
39832                for (var i = 0; i < numTables; i += 1) {
39833                  var tag = parse.getTag(data, p);
39834                  var checksum = parse.getULong(data, p + 4);
39835                  var offset = parse.getULong(data, p + 8);
39836                  var length = parse.getULong(data, p + 12);
39837                  tableEntries.push({
39838                    tag: tag,
39839                    checksum: checksum,
39840                    offset: offset,
39841                    length: length,
39842                    compression: false
39843                  });
39844                  p += 16;
39845                }
39846
39847                return tableEntries;
39848              }
39849
39850              /**
39851               * Parses WOFF table entries.
39852               * @param  {DataView}
39853               * @param  {Number}
39854               * @return {Object[]}
39855               */
39856              function parseWOFFTableEntries(data, numTables) {
39857                var tableEntries = [];
39858                var p = 44; // offset to the first table directory entry.
39859                for (var i = 0; i < numTables; i += 1) {
39860                  var tag = parse.getTag(data, p);
39861                  var offset = parse.getULong(data, p + 4);
39862                  var compLength = parse.getULong(data, p + 8);
39863                  var origLength = parse.getULong(data, p + 12);
39864                  var compression = void 0;
39865                  if (compLength < origLength) {
39866                    compression = 'WOFF';
39867                  } else {
39868                    compression = false;
39869                  }
39870
39871                  tableEntries.push({
39872                    tag: tag,
39873                    offset: offset,
39874                    compression: compression,
39875                    compressedLength: compLength,
39876                    length: origLength
39877                  });
39878                  p += 20;
39879                }
39880
39881                return tableEntries;
39882              }
39883
39884              /**
39885               * @typedef TableData
39886               * @type Object
39887               * @property {DataView} data - The DataView
39888               * @property {number} offset - The data offset.
39889               */
39890
39891              /**
39892               * @param  {DataView}
39893               * @param  {Object}
39894               * @return {TableData}
39895               */
39896              function uncompressTable(data, tableEntry) {
39897                if (tableEntry.compression === 'WOFF') {
39898                  var inBuffer = new Uint8Array(
39899                    data.buffer,
39900                    tableEntry.offset + 2,
39901                    tableEntry.compressedLength - 2
39902                  );
39903                  var outBuffer = new Uint8Array(tableEntry.length);
39904                  tinyInflate(inBuffer, outBuffer);
39905                  if (outBuffer.byteLength !== tableEntry.length) {
39906                    throw new Error(
39907                      'Decompression error: ' +
39908                        tableEntry.tag +
39909                        " decompressed length doesn't match recorded length"
39910                    );
39911                  }
39912
39913                  var view = new DataView(outBuffer.buffer, 0);
39914                  return { data: view, offset: 0 };
39915                } else {
39916                  return { data: data, offset: tableEntry.offset };
39917                }
39918              }
39919
39920              // Public API ///////////////////////////////////////////////////////////
39921
39922              /**
39923               * Parse the OpenType file data (as an ArrayBuffer) and return a Font object.
39924               * Throws an error if the font could not be parsed.
39925               * @param  {ArrayBuffer}
39926               * @return {opentype.Font}
39927               */
39928              function parseBuffer(buffer) {
39929                var indexToLocFormat;
39930                var ltagTable;
39931
39932                // Since the constructor can also be called to create new fonts from scratch, we indicate this
39933                // should be an empty font that we'll fill with our own data.
39934                var font = new Font({ empty: true });
39935
39936                // OpenType fonts use big endian byte ordering.
39937                // We can't rely on typed array view types, because they operate with the endianness of the host computer.
39938                // Instead we use DataViews where we can specify endianness.
39939                var data = new DataView(buffer, 0);
39940                var numTables;
39941                var tableEntries = [];
39942                var signature = parse.getTag(data, 0);
39943                if (
39944                  signature === String.fromCharCode(0, 1, 0, 0) ||
39945                  signature === 'true' ||
39946                  signature === 'typ1'
39947                ) {
39948                  font.outlinesFormat = 'truetype';
39949                  numTables = parse.getUShort(data, 4);
39950                  tableEntries = parseOpenTypeTableEntries(data, numTables);
39951                } else if (signature === 'OTTO') {
39952                  font.outlinesFormat = 'cff';
39953                  numTables = parse.getUShort(data, 4);
39954                  tableEntries = parseOpenTypeTableEntries(data, numTables);
39955                } else if (signature === 'wOFF') {
39956                  var flavor = parse.getTag(data, 4);
39957                  if (flavor === String.fromCharCode(0, 1, 0, 0)) {
39958                    font.outlinesFormat = 'truetype';
39959                  } else if (flavor === 'OTTO') {
39960                    font.outlinesFormat = 'cff';
39961                  } else {
39962                    throw new Error('Unsupported OpenType flavor ' + signature);
39963                  }
39964
39965                  numTables = parse.getUShort(data, 12);
39966                  tableEntries = parseWOFFTableEntries(data, numTables);
39967                } else {
39968                  throw new Error('Unsupported OpenType signature ' + signature);
39969                }
39970
39971                var cffTableEntry;
39972                var fvarTableEntry;
39973                var glyfTableEntry;
39974                var gposTableEntry;
39975                var gsubTableEntry;
39976                var hmtxTableEntry;
39977                var kernTableEntry;
39978                var locaTableEntry;
39979                var nameTableEntry;
39980                var metaTableEntry;
39981                var p;
39982
39983                for (var i = 0; i < numTables; i += 1) {
39984                  var tableEntry = tableEntries[i];
39985                  var table = void 0;
39986                  switch (tableEntry.tag) {
39987                    case 'cmap':
39988                      table = uncompressTable(data, tableEntry);
39989                      font.tables.cmap = cmap.parse(table.data, table.offset);
39990                      font.encoding = new CmapEncoding(font.tables.cmap);
39991                      break;
39992                    case 'cvt ':
39993                      table = uncompressTable(data, tableEntry);
39994                      p = new parse.Parser(table.data, table.offset);
39995                      font.tables.cvt = p.parseShortList(tableEntry.length / 2);
39996                      break;
39997                    case 'fvar':
39998                      fvarTableEntry = tableEntry;
39999                      break;
40000                    case 'fpgm':
40001                      table = uncompressTable(data, tableEntry);
40002                      p = new parse.Parser(table.data, table.offset);
40003                      font.tables.fpgm = p.parseByteList(tableEntry.length);
40004                      break;
40005                    case 'head':
40006                      table = uncompressTable(data, tableEntry);
40007                      font.tables.head = head.parse(table.data, table.offset);
40008                      font.unitsPerEm = font.tables.head.unitsPerEm;
40009                      indexToLocFormat = font.tables.head.indexToLocFormat;
40010                      break;
40011                    case 'hhea':
40012                      table = uncompressTable(data, tableEntry);
40013                      font.tables.hhea = hhea.parse(table.data, table.offset);
40014                      font.ascender = font.tables.hhea.ascender;
40015                      font.descender = font.tables.hhea.descender;
40016                      font.numberOfHMetrics = font.tables.hhea.numberOfHMetrics;
40017                      break;
40018                    case 'hmtx':
40019                      hmtxTableEntry = tableEntry;
40020                      break;
40021                    case 'ltag':
40022                      table = uncompressTable(data, tableEntry);
40023                      ltagTable = ltag.parse(table.data, table.offset);
40024                      break;
40025                    case 'maxp':
40026                      table = uncompressTable(data, tableEntry);
40027                      font.tables.maxp = maxp.parse(table.data, table.offset);
40028                      font.numGlyphs = font.tables.maxp.numGlyphs;
40029                      break;
40030                    case 'name':
40031                      nameTableEntry = tableEntry;
40032                      break;
40033                    case 'OS/2':
40034                      table = uncompressTable(data, tableEntry);
40035                      font.tables.os2 = os2.parse(table.data, table.offset);
40036                      break;
40037                    case 'post':
40038                      table = uncompressTable(data, tableEntry);
40039                      font.tables.post = post.parse(table.data, table.offset);
40040                      font.glyphNames = new GlyphNames(font.tables.post);
40041                      break;
40042                    case 'prep':
40043                      table = uncompressTable(data, tableEntry);
40044                      p = new parse.Parser(table.data, table.offset);
40045                      font.tables.prep = p.parseByteList(tableEntry.length);
40046                      break;
40047                    case 'glyf':
40048                      glyfTableEntry = tableEntry;
40049                      break;
40050                    case 'loca':
40051                      locaTableEntry = tableEntry;
40052                      break;
40053                    case 'CFF ':
40054                      cffTableEntry = tableEntry;
40055                      break;
40056                    case 'kern':
40057                      kernTableEntry = tableEntry;
40058                      break;
40059                    case 'GPOS':
40060                      gposTableEntry = tableEntry;
40061                      break;
40062                    case 'GSUB':
40063                      gsubTableEntry = tableEntry;
40064                      break;
40065                    case 'meta':
40066                      metaTableEntry = tableEntry;
40067                      break;
40068                  }
40069                }
40070
40071                var nameTable = uncompressTable(data, nameTableEntry);
40072                font.tables.name = _name.parse(nameTable.data, nameTable.offset, ltagTable);
40073                font.names = font.tables.name;
40074
40075                if (glyfTableEntry && locaTableEntry) {
40076                  var shortVersion = indexToLocFormat === 0;
40077                  var locaTable = uncompressTable(data, locaTableEntry);
40078                  var locaOffsets = loca.parse(
40079                    locaTable.data,
40080                    locaTable.offset,
40081                    font.numGlyphs,
40082                    shortVersion
40083                  );
40084                  var glyfTable = uncompressTable(data, glyfTableEntry);
40085                  font.glyphs = glyf.parse(
40086                    glyfTable.data,
40087                    glyfTable.offset,
40088                    locaOffsets,
40089                    font
40090                  );
40091                } else if (cffTableEntry) {
40092                  var cffTable = uncompressTable(data, cffTableEntry);
40093                  cff.parse(cffTable.data, cffTable.offset, font);
40094                } else {
40095                  throw new Error("Font doesn't contain TrueType or CFF outlines.");
40096                }
40097
40098                var hmtxTable = uncompressTable(data, hmtxTableEntry);
40099                hmtx.parse(
40100                  hmtxTable.data,
40101                  hmtxTable.offset,
40102                  font.numberOfHMetrics,
40103                  font.numGlyphs,
40104                  font.glyphs
40105                );
40106                addGlyphNames(font);
40107
40108                if (kernTableEntry) {
40109                  var kernTable = uncompressTable(data, kernTableEntry);
40110                  font.kerningPairs = kern.parse(kernTable.data, kernTable.offset);
40111                } else {
40112                  font.kerningPairs = {};
40113                }
40114
40115                if (gposTableEntry) {
40116                  var gposTable = uncompressTable(data, gposTableEntry);
40117                  font.tables.gpos = gpos.parse(gposTable.data, gposTable.offset);
40118                  font.position.init();
40119                }
40120
40121                if (gsubTableEntry) {
40122                  var gsubTable = uncompressTable(data, gsubTableEntry);
40123                  font.tables.gsub = gsub.parse(gsubTable.data, gsubTable.offset);
40124                }
40125
40126                if (fvarTableEntry) {
40127                  var fvarTable = uncompressTable(data, fvarTableEntry);
40128                  font.tables.fvar = fvar.parse(
40129                    fvarTable.data,
40130                    fvarTable.offset,
40131                    font.names
40132                  );
40133                }
40134
40135                if (metaTableEntry) {
40136                  var metaTable = uncompressTable(data, metaTableEntry);
40137                  font.tables.meta = meta.parse(metaTable.data, metaTable.offset);
40138                  font.metas = font.tables.meta;
40139                }
40140
40141                return font;
40142              }
40143
40144              /**
40145               * Asynchronously load the font from a URL or a filesystem. When done, call the callback
40146               * with two arguments `(err, font)`. The `err` will be null on success,
40147               * the `font` is a Font object.
40148               * We use the node.js callback convention so that
40149               * opentype.js can integrate with frameworks like async.js.
40150               * @alias opentype.load
40151               * @param  {string} url - The URL of the font to load.
40152               * @param  {Function} callback - The callback.
40153               */
40154              function load(url, callback) {
40155                var isNode$$1 = typeof window === 'undefined';
40156                var loadFn = isNode$$1 ? loadFromFile : loadFromUrl;
40157                loadFn(url, function(err, arrayBuffer) {
40158                  if (err) {
40159                    return callback(err);
40160                  }
40161                  var font;
40162                  try {
40163                    font = parseBuffer(arrayBuffer);
40164                  } catch (e) {
40165                    return callback(e, null);
40166                  }
40167                  return callback(null, font);
40168                });
40169              }
40170
40171              /**
40172               * Synchronously load the font from a URL or file.
40173               * When done, returns the font object or throws an error.
40174               * @alias opentype.loadSync
40175               * @param  {string} url - The URL of the font to load.
40176               * @return {opentype.Font}
40177               */
40178              function loadSync(url) {
40179                var fs = _dereq_('fs');
40180                var buffer = fs.readFileSync(url);
40181                return parseBuffer(nodeBufferToArrayBuffer(buffer));
40182              }
40183
40184              exports.Font = Font;
40185              exports.Glyph = Glyph;
40186              exports.Path = Path;
40187              exports.BoundingBox = BoundingBox;
40188              exports._parse = parse;
40189              exports.parse = parseBuffer;
40190              exports.load = load;
40191              exports.loadSync = loadSync;
40192
40193              Object.defineProperty(exports, '__esModule', { value: true });
40194            });
40195          }.call(this, _dereq_('buffer').Buffer));
40196        },
40197        { buffer: 22, fs: 21 }
40198      ],
40199      35: [
vendor: 5,953 bytes, lines 40200-40349
40200        function(_dereq_, module, exports) {
40201          (function(process) {
40202            // .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1,
40203            // backported and transplited with Babel, with backwards-compat fixes
40204
40205            // Copyright Joyent, Inc. and other Node contributors.
40206            //
40207            // Permission is hereby granted, free of charge, to any person obtaining a
40208            // copy of this software and associated documentation files (the
40209            // "Software"), to deal in the Software without restriction, including
40210            // without limitation the rights to use, copy, modify, merge, publish,
40211            // distribute, sublicense, and/or sell copies of the Software, and to permit
40212            // persons to whom the Software is furnished to do so, subject to the
40213            // following conditions:
40214            //
40215            // The above copyright notice and this permission notice shall be included
40216            // in all copies or substantial portions of the Software.
40217            //
40218            // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
40219            // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40220            // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
40221            // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
40222            // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
40223            // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
40224            // USE OR OTHER DEALINGS IN THE SOFTWARE.
40225
40226            // resolves . and .. elements in a path array with directory names there
40227            // must be no slashes, empty elements, or device names (c:\) in the array
40228            // (so also no leading and trailing slashes - it does not distinguish
40229            // relative and absolute paths)
40230            function normalizeArray(parts, allowAboveRoot) {
40231              // if the path tries to go above the root, `up` ends up > 0
40232              var up = 0;
40233              for (var i = parts.length - 1; i >= 0; i--) {
40234                var last = parts[i];
40235                if (last === '.') {
40236                  parts.splice(i, 1);
40237                } else if (last === '..') {
40238                  parts.splice(i, 1);
40239                  up++;
40240                } else if (up) {
40241                  parts.splice(i, 1);
40242                  up--;
40243                }
40244              }
40245
40246              // if the path is allowed to go above the root, restore leading ..s
40247              if (allowAboveRoot) {
40248                for (; up--; up) {
40249                  parts.unshift('..');
40250                }
40251              }
40252
40253              return parts;
40254            }
40255
40256            // path.resolve([from ...], to)
40257            // posix version
40258            exports.resolve = function() {
40259              var resolvedPath = '',
40260                resolvedAbsolute = false;
40261
40262              for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
40263                var path = i >= 0 ? arguments[i] : process.cwd();
40264
40265                // Skip empty and invalid entries
40266                if (typeof path !== 'string') {
40267                  throw new TypeError('Arguments to path.resolve must be strings');
40268                } else if (!path) {
40269                  continue;
40270                }
40271
40272                resolvedPath = path + '/' + resolvedPath;
40273                resolvedAbsolute = path.charAt(0) === '/';
40274              }
40275
40276              // At this point the path should be resolved to a full absolute path, but
40277              // handle relative paths to be safe (might happen when process.cwd() fails)
40278
40279              // Normalize the path
40280              resolvedPath = normalizeArray(
40281                filter(resolvedPath.split('/'), function(p) {
40282                  return !!p;
40283                }),
40284                !resolvedAbsolute
40285              ).join('/');
40286
40287              return (resolvedAbsolute ? '/' : '') + resolvedPath || '.';
40288            };
40289
40290            // path.normalize(path)
40291            // posix version
40292            exports.normalize = function(path) {
40293              var isAbsolute = exports.isAbsolute(path),
40294                trailingSlash = substr(path, -1) === '/';
40295
40296              // Normalize the path
40297              path = normalizeArray(
40298                filter(path.split('/'), function(p) {
40299                  return !!p;
40300                }),
40301                !isAbsolute
40302              ).join('/');
40303
40304              if (!path && !isAbsolute) {
40305                path = '.';
40306              }
40307              if (path && trailingSlash) {
40308                path += '/';
40309              }
40310
40311              return (isAbsolute ? '/' : '') + path;
40312            };
40313
40314            // posix version
40315            exports.isAbsolute = function(path) {
40316              return path.charAt(0) === '/';
40317            };
40318
40319            // posix version
40320            exports.join = function() {
40321              var paths = Array.prototype.slice.call(arguments, 0);
40322              return exports.normalize(
40323                filter(paths, function(p, index) {
40324                  if (typeof p !== 'string') {
40325                    throw new TypeError('Arguments to path.join must be strings');
40326                  }
40327                  return p;
40328                }).join('/')
40329              );
40330            };
40331
40332            // path.relative(from, to)
40333            // posix version
40334            exports.relative = function(from, to) {
40335              from = exports.resolve(from).substr(1);
40336              to = exports.resolve(to).substr(1);
40337
40338              function trim(arr) {
40339                var start = 0;
40340                for (; start < arr.length; start++) {
40341                  if (arr[start] !== '') break;
40342                }
40343
40344                var end = arr.length - 1;
40345                for (; end >= 0; end--) {
40346                  if (arr[end] !== '') break;
40347                }
40348
40349                if (start > end) return [];
vendor: 10,259 bytes, lines 40350-40611
40350                return arr.slice(start, end - start + 1);
40351              }
40352
40353              var fromParts = trim(from.split('/'));
40354              var toParts = trim(to.split('/'));
40355
40356              var length = Math.min(fromParts.length, toParts.length);
40357              var samePartsLength = length;
40358              for (var i = 0; i < length; i++) {
40359                if (fromParts[i] !== toParts[i]) {
40360                  samePartsLength = i;
40361                  break;
40362                }
40363              }
40364
40365              var outputParts = [];
40366              for (var i = samePartsLength; i < fromParts.length; i++) {
40367                outputParts.push('..');
40368              }
40369
40370              outputParts = outputParts.concat(toParts.slice(samePartsLength));
40371
40372              return outputParts.join('/');
40373            };
40374
40375            exports.sep = '/';
40376            exports.delimiter = ':';
40377
40378            exports.dirname = function(path) {
40379              if (typeof path !== 'string') path = path + '';
40380              if (path.length === 0) return '.';
40381              var code = path.charCodeAt(0);
40382              var hasRoot = code === 47 /*/*/;
40383              var end = -1;
40384              var matchedSlash = true;
40385              for (var i = path.length - 1; i >= 1; --i) {
40386                code = path.charCodeAt(i);
40387                if (code === 47 /*/*/) {
40388                  if (!matchedSlash) {
40389                    end = i;
40390                    break;
40391                  }
40392                } else {
40393                  // We saw the first non-path separator
40394                  matchedSlash = false;
40395                }
40396              }
40397
40398              if (end === -1) return hasRoot ? '/' : '.';
40399              if (hasRoot && end === 1) {
40400                // return '//';
40401                // Backwards-compat fix:
40402                return '/';
40403              }
40404              return path.slice(0, end);
40405            };
40406
40407            function basename(path) {
40408              if (typeof path !== 'string') path = path + '';
40409
40410              var start = 0;
40411              var end = -1;
40412              var matchedSlash = true;
40413              var i;
40414
40415              for (i = path.length - 1; i >= 0; --i) {
40416                if (path.charCodeAt(i) === 47 /*/*/) {
40417                  // If we reached a path separator that was not part of a set of path
40418                  // separators at the end of the string, stop now
40419                  if (!matchedSlash) {
40420                    start = i + 1;
40421                    break;
40422                  }
40423                } else if (end === -1) {
40424                  // We saw the first non-path separator, mark this as the end of our
40425                  // path component
40426                  matchedSlash = false;
40427                  end = i + 1;
40428                }
40429              }
40430
40431              if (end === -1) return '';
40432              return path.slice(start, end);
40433            }
40434
40435            // Uses a mixed approach for backwards-compatibility, as ext behavior changed
40436            // in new Node.js versions, so only basename() above is backported here
40437            exports.basename = function(path, ext) {
40438              var f = basename(path);
40439              if (ext && f.substr(-1 * ext.length) === ext) {
40440                f = f.substr(0, f.length - ext.length);
40441              }
40442              return f;
40443            };
40444
40445            exports.extname = function(path) {
40446              if (typeof path !== 'string') path = path + '';
40447              var startDot = -1;
40448              var startPart = 0;
40449              var end = -1;
40450              var matchedSlash = true;
40451              // Track the state of characters (if any) we see before our first dot and
40452              // after any path separator we find
40453              var preDotState = 0;
40454              for (var i = path.length - 1; i >= 0; --i) {
40455                var code = path.charCodeAt(i);
40456                if (code === 47 /*/*/) {
40457                  // If we reached a path separator that was not part of a set of path
40458                  // separators at the end of the string, stop now
40459                  if (!matchedSlash) {
40460                    startPart = i + 1;
40461                    break;
40462                  }
40463                  continue;
40464                }
40465                if (end === -1) {
40466                  // We saw the first non-path separator, mark this as the end of our
40467                  // extension
40468                  matchedSlash = false;
40469                  end = i + 1;
40470                }
40471                if (code === 46 /*.*/) {
40472                  // If this is our first dot, mark it as the start of our extension
40473                  if (startDot === -1) startDot = i;
40474                  else if (preDotState !== 1) preDotState = 1;
40475                } else if (startDot !== -1) {
40476                  // We saw a non-dot and non-path separator before our dot, so we should
40477                  // have a good chance at having a non-empty extension
40478                  preDotState = -1;
40479                }
40480              }
40481
40482              if (
40483                startDot === -1 ||
40484                end === -1 ||
40485                // We saw a non-dot character immediately before the dot
40486                preDotState === 0 ||
40487                // The (right-most) trimmed path component is exactly '..'
40488                (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
40489              ) {
40490                return '';
40491              }
40492              return path.slice(startDot, end);
40493            };
40494
40495            function filter(xs, f) {
40496              if (xs.filter) return xs.filter(f);
40497              var res = [];
40498              for (var i = 0; i < xs.length; i++) {
40499                if (f(xs[i], i, xs)) res.push(xs[i]);
40500              }
40501              return res;
40502            }
40503
40504            // String.prototype.substr - negative index don't work in IE8
40505            var substr =
40506              'ab'.substr(-1) === 'b'
40507                ? function(str, start, len) {
40508                    return str.substr(start, len);
40509                  }
40510                : function(str, start, len) {
40511                    if (start < 0) start = str.length + start;
40512                    return str.substr(start, len);
40513                  };
40514          }.call(this, _dereq_('_process')));
40515        },
40516        { _process: 36 }
40517      ],
40518      36: [
40519        function(_dereq_, module, exports) {
40520          // shim for using process in browser
40521          var process = (module.exports = {});
40522
40523          // cached from whatever global is present so that test runners that stub it
40524          // don't break things.  But we need to wrap it in a try catch in case it is
40525          // wrapped in strict mode code which doesn't define any globals.  It's inside a
40526          // function because try/catches deoptimize in certain engines.
40527
40528          var cachedSetTimeout;
40529          var cachedClearTimeout;
40530
40531          function defaultSetTimout() {
40532            throw new Error('setTimeout has not been defined');
40533          }
40534          function defaultClearTimeout() {
40535            throw new Error('clearTimeout has not been defined');
40536          }
40537          (function() {
40538            try {
40539              if (typeof setTimeout === 'function') {
40540                cachedSetTimeout = setTimeout;
40541              } else {
40542                cachedSetTimeout = defaultSetTimout;
40543              }
40544            } catch (e) {
40545              cachedSetTimeout = defaultSetTimout;
40546            }
40547            try {
40548              if (typeof clearTimeout === 'function') {
40549                cachedClearTimeout = clearTimeout;
40550              } else {
40551                cachedClearTimeout = defaultClearTimeout;
40552              }
40553            } catch (e) {
40554              cachedClearTimeout = defaultClearTimeout;
40555            }
40556          })();
40557          function runTimeout(fun) {
40558            if (cachedSetTimeout === setTimeout) {
40559              //normal enviroments in sane situations
40560              return setTimeout(fun, 0);
40561            }
40562            // if setTimeout wasn't available but was latter defined
40563            if (
40564              (cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) &&
40565              setTimeout
40566            ) {
40567              cachedSetTimeout = setTimeout;
40568              return setTimeout(fun, 0);
40569            }
40570            try {
40571              // when when somebody has screwed with setTimeout but no I.E. maddness
40572              return cachedSetTimeout(fun, 0);
40573            } catch (e) {
40574              try {
40575                // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
40576                return cachedSetTimeout.call(null, fun, 0);
40577              } catch (e) {
40578                // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
40579                return cachedSetTimeout.call(this, fun, 0);
40580              }
40581            }
40582          }
40583          function runClearTimeout(marker) {
40584            if (cachedClearTimeout === clearTimeout) {
40585              //normal enviroments in sane situations
40586              return clearTimeout(marker);
40587            }
40588            // if clearTimeout wasn't available but was latter defined
40589            if (
40590              (cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) &&
40591              clearTimeout
40592            ) {
40593              cachedClearTimeout = clearTimeout;
40594              return clearTimeout(marker);
40595            }
40596            try {
40597              // when when somebody has screwed with setTimeout but no I.E. maddness
40598              return cachedClearTimeout(marker);
40599            } catch (e) {
40600              try {
40601                // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
40602                return cachedClearTimeout.call(null, marker);
40603              } catch (e) {
40604                // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
40605                // Some versions of I.E. have different rules for clearTimeout vs setTimeout
40606                return cachedClearTimeout.call(this, marker);
40607              }
40608            }
40609          }
40610          var queue = [];
40611          var draining = false;
40612          var currentQueue;
40613          var queueIndex = -1;
40614
40615          function cleanUpNextTick() {
40616            if (!draining || !currentQueue) {
40617              return;
40618            }
40619            draining = false;
40620            if (currentQueue.length) {
40621              queue = currentQueue.concat(queue);
40622            } else {
40623              queueIndex = -1;
40624            }
40625            if (queue.length) {
40626              drainQueue();
40627            }
40628          }
40629
40630          function drainQueue() {
40631            if (draining) {
40632              return;
40633            }
40634            var timeout = runTimeout(cleanUpNextTick);
40635            draining = true;
40636
40637            var len = queue.length;
40638            while (len) {
40639              currentQueue = queue;
40640              queue = [];
40641              while (++queueIndex < len) {
40642                if (currentQueue) {
40643                  currentQueue[queueIndex].run();
40644                }
40645              }
40646              queueIndex = -1;
40647              len = queue.length;
40648            }
40649            currentQueue = null;
40650            draining = false;
40651            runClearTimeout(timeout);
40652          }
40653
40654          process.nextTick = function(fun) {
40655            var args = new Array(arguments.length - 1);
40656            if (arguments.length > 1) {
40657              for (var i = 1; i < arguments.length; i++) {
40658                args[i - 1] = arguments[i];
40659              }
40660            }
40661            queue.push(new Item(fun, args));
40662            if (queue.length === 1 && !draining) {
40663              runTimeout(drainQueue);
40664            }
40665          };
40666
40667          // v8 likes predictible objects
40668          function Item(fun, array) {
40669            this.fun = fun;
40670            this.array = array;
40671          }
40672          Item.prototype.run = function() {
40673            this.fun.apply(null, this.array);
40674          };
40675          process.title = 'browser';
40676          process.browser = true;
40677          process.env = {};
40678          process.argv = [];
40679          process.version = ''; // empty string to avoid regexp issues
40680          process.versions = {};
40681
40682          function noop() {}
40683
40684          process.on = noop;
40685          process.addListener = noop;
40686          process.once = noop;
40687          process.off = noop;
40688          process.removeListener = noop;
40689          process.removeAllListeners = noop;
40690          process.emit = noop;
40691          process.prependListener = noop;
40692          process.prependOnceListener = noop;
40693
40694          process.listeners = function(name) {
40695            return [];
40696          };
40697
40698          process.binding = function(name) {
40699            throw new Error('process.binding is not supported');
40700          };
40701
40702          process.cwd = function() {
40703            return '/';
40704          };
40705          process.chdir = function(dir) {
40706            throw new Error('process.chdir is not supported');
40707          };
40708          process.umask = function() {
40709            return 0;
40710          };
40711        },
40712        {}
40713      ],
40714      37: [
40715        function(_dereq_, module, exports) {
40716          (function(self) {
40717            'use strict';
40718
40719            if (self.fetch) {
40720              return;
40721            }
40722
40723            var support = {
40724              searchParams: 'URLSearchParams' in self,
40725              iterable: 'Symbol' in self && 'iterator' in Symbol,
40726              blob:
40727                'FileReader' in self &&
40728                'Blob' in self &&
40729                (function() {
40730                  try {
40731                    new Blob();
40732                    return true;
40733                  } catch (e) {
40734                    return false;
40735                  }
40736                })(),
40737              formData: 'FormData' in self,
40738              arrayBuffer: 'ArrayBuffer' in self
40739            };
40740
40741            if (support.arrayBuffer) {
40742              var viewClasses = [
40743                '[object Int8Array]',
40744                '[object Uint8Array]',
40745                '[object Uint8ClampedArray]',
40746                '[object Int16Array]',
40747                '[object Uint16Array]',
40748                '[object Int32Array]',
40749                '[object Uint32Array]',
40750                '[object Float32Array]',
vendor: 5,930 bytes, lines 40751-40933
40751                '[object Float64Array]'
40752              ];
40753
40754              var isDataView = function(obj) {
40755                return obj && DataView.prototype.isPrototypeOf(obj);
40756              };
40757
40758              var isArrayBufferView =
40759                ArrayBuffer.isView ||
40760                function(obj) {
40761                  return (
40762                    obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
40763                  );
40764                };
40765            }
40766
40767            function normalizeName(name) {
40768              if (typeof name !== 'string') {
40769                name = String(name);
40770              }
40771              if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
40772                throw new TypeError('Invalid character in header field name');
40773              }
40774              return name.toLowerCase();
40775            }
40776
40777            function normalizeValue(value) {
40778              if (typeof value !== 'string') {
40779                value = String(value);
40780              }
40781              return value;
40782            }
40783
40784            // Build a destructive iterator for the value list
40785            function iteratorFor(items) {
40786              var iterator = {
40787                next: function() {
40788                  var value = items.shift();
40789                  return { done: value === undefined, value: value };
40790                }
40791              };
40792
40793              if (support.iterable) {
40794                iterator[Symbol.iterator] = function() {
40795                  return iterator;
40796                };
40797              }
40798
40799              return iterator;
40800            }
40801
40802            function Headers(headers) {
40803              this.map = {};
40804
40805              if (headers instanceof Headers) {
40806                headers.forEach(function(value, name) {
40807                  this.append(name, value);
40808                }, this);
40809              } else if (Array.isArray(headers)) {
40810                headers.forEach(function(header) {
40811                  this.append(header[0], header[1]);
40812                }, this);
40813              } else if (headers) {
40814                Object.getOwnPropertyNames(headers).forEach(function(name) {
40815                  this.append(name, headers[name]);
40816                }, this);
40817              }
40818            }
40819
40820            Headers.prototype.append = function(name, value) {
40821              name = normalizeName(name);
40822              value = normalizeValue(value);
40823              var oldValue = this.map[name];
40824              this.map[name] = oldValue ? oldValue + ',' + value : value;
40825            };
40826
40827            Headers.prototype['delete'] = function(name) {
40828              delete this.map[normalizeName(name)];
40829            };
40830
40831            Headers.prototype.get = function(name) {
40832              name = normalizeName(name);
40833              return this.has(name) ? this.map[name] : null;
40834            };
40835
40836            Headers.prototype.has = function(name) {
40837              return this.map.hasOwnProperty(normalizeName(name));
40838            };
40839
40840            Headers.prototype.set = function(name, value) {
40841              this.map[normalizeName(name)] = normalizeValue(value);
40842            };
40843
40844            Headers.prototype.forEach = function(callback, thisArg) {
40845              for (var name in this.map) {
40846                if (this.map.hasOwnProperty(name)) {
40847                  callback.call(thisArg, this.map[name], name, this);
40848                }
40849              }
40850            };
40851
40852            Headers.prototype.keys = function() {
40853              var items = [];
40854              this.forEach(function(value, name) {
40855                items.push(name);
40856              });
40857              return iteratorFor(items);
40858            };
40859
40860            Headers.prototype.values = function() {
40861              var items = [];
40862              this.forEach(function(value) {
40863                items.push(value);
40864              });
40865              return iteratorFor(items);
40866            };
40867
40868            Headers.prototype.entries = function() {
40869              var items = [];
40870              this.forEach(function(value, name) {
40871                items.push([name, value]);
40872              });
40873              return iteratorFor(items);
40874            };
40875
40876            if (support.iterable) {
40877              Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
40878            }
40879
40880            function consumed(body) {
40881              if (body.bodyUsed) {
40882                return Promise.reject(new TypeError('Already read'));
40883              }
40884              body.bodyUsed = true;
40885            }
40886
40887            function fileReaderReady(reader) {
40888              return new Promise(function(resolve, reject) {
40889                reader.onload = function() {
40890                  resolve(reader.result);
40891                };
40892                reader.onerror = function() {
40893                  reject(reader.error);
40894                };
40895              });
40896            }
40897
40898            function readBlobAsArrayBuffer(blob) {
40899              var reader = new FileReader();
40900              var promise = fileReaderReady(reader);
40901              reader.readAsArrayBuffer(blob);
40902              return promise;
40903            }
40904
40905            function readBlobAsText(blob) {
40906              var reader = new FileReader();
40907              var promise = fileReaderReady(reader);
40908              reader.readAsText(blob);
40909              return promise;
40910            }
40911
40912            function readArrayBufferAsText(buf) {
40913              var view = new Uint8Array(buf);
40914              var chars = new Array(view.length);
40915
40916              for (var i = 0; i < view.length; i++) {
40917                chars[i] = String.fromCharCode(view[i]);
40918              }
40919              return chars.join('');
40920            }
40921
40922            function bufferClone(buf) {
40923              if (buf.slice) {
40924                return buf.slice(0);
40925              } else {
40926                var view = new Uint8Array(buf.byteLength);
40927                view.set(new Uint8Array(buf));
40928                return view.buffer;
40929              }
40930            }
40931
40932            function Body() {
40933              this.bodyUsed = false;
vendor: 4,237 bytes, lines 40934-41039
40934
40935              this._initBody = function(body) {
40936                this._bodyInit = body;
40937                if (!body) {
40938                  this._bodyText = '';
40939                } else if (typeof body === 'string') {
40940                  this._bodyText = body;
40941                } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
40942                  this._bodyBlob = body;
40943                } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
40944                  this._bodyFormData = body;
40945                } else if (
40946                  support.searchParams &&
40947                  URLSearchParams.prototype.isPrototypeOf(body)
40948                ) {
40949                  this._bodyText = body.toString();
40950                } else if (support.arrayBuffer && support.blob && isDataView(body)) {
40951                  this._bodyArrayBuffer = bufferClone(body.buffer);
40952                  // IE 10-11 can't handle a DataView body.
40953                  this._bodyInit = new Blob([this._bodyArrayBuffer]);
40954                } else if (
40955                  support.arrayBuffer &&
40956                  (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))
40957                ) {
40958                  this._bodyArrayBuffer = bufferClone(body);
40959                } else {
40960                  throw new Error('unsupported BodyInit type');
40961                }
40962
40963                if (!this.headers.get('content-type')) {
40964                  if (typeof body === 'string') {
40965                    this.headers.set('content-type', 'text/plain;charset=UTF-8');
40966                  } else if (this._bodyBlob && this._bodyBlob.type) {
40967                    this.headers.set('content-type', this._bodyBlob.type);
40968                  } else if (
40969                    support.searchParams &&
40970                    URLSearchParams.prototype.isPrototypeOf(body)
40971                  ) {
40972                    this.headers.set(
40973                      'content-type',
40974                      'application/x-www-form-urlencoded;charset=UTF-8'
40975                    );
40976                  }
40977                }
40978              };
40979
40980              if (support.blob) {
40981                this.blob = function() {
40982                  var rejected = consumed(this);
40983                  if (rejected) {
40984                    return rejected;
40985                  }
40986
40987                  if (this._bodyBlob) {
40988                    return Promise.resolve(this._bodyBlob);
40989                  } else if (this._bodyArrayBuffer) {
40990                    return Promise.resolve(new Blob([this._bodyArrayBuffer]));
40991                  } else if (this._bodyFormData) {
40992                    throw new Error('could not read FormData body as blob');
40993                  } else {
40994                    return Promise.resolve(new Blob([this._bodyText]));
40995                  }
40996                };
40997
40998                this.arrayBuffer = function() {
40999                  if (this._bodyArrayBuffer) {
41000                    return consumed(this) || Promise.resolve(this._bodyArrayBuffer);
41001                  } else {
41002                    return this.blob().then(readBlobAsArrayBuffer);
41003                  }
41004                };
41005              }
41006
41007              this.text = function() {
41008                var rejected = consumed(this);
41009                if (rejected) {
41010                  return rejected;
41011                }
41012
41013                if (this._bodyBlob) {
41014                  return readBlobAsText(this._bodyBlob);
41015                } else if (this._bodyArrayBuffer) {
41016                  return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer));
41017                } else if (this._bodyFormData) {
41018                  throw new Error('could not read FormData body as text');
41019                } else {
41020                  return Promise.resolve(this._bodyText);
41021                }
41022              };
41023
41024              if (support.formData) {
41025                this.formData = function() {
41026                  return this.text().then(decode);
41027                };
41028              }
41029
41030              this.json = function() {
41031                return this.text().then(JSON.parse);
41032              };
41033
41034              return this;
41035            }
41036
41037            // HTTP methods whose capitalization should be normalized
41038            var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];
41039
vendor: 4,793 bytes, lines 41040-41166
41040            function normalizeMethod(method) {
41041              var upcased = method.toUpperCase();
41042              return methods.indexOf(upcased) > -1 ? upcased : method;
41043            }
41044
41045            function Request(input, options) {
41046              options = options || {};
41047              var body = options.body;
41048
41049              if (input instanceof Request) {
41050                if (input.bodyUsed) {
41051                  throw new TypeError('Already read');
41052                }
41053                this.url = input.url;
41054                this.credentials = input.credentials;
41055                if (!options.headers) {
41056                  this.headers = new Headers(input.headers);
41057                }
41058                this.method = input.method;
41059                this.mode = input.mode;
41060                if (!body && input._bodyInit != null) {
41061                  body = input._bodyInit;
41062                  input.bodyUsed = true;
41063                }
41064              } else {
41065                this.url = String(input);
41066              }
41067
41068              this.credentials = options.credentials || this.credentials || 'omit';
41069              if (options.headers || !this.headers) {
41070                this.headers = new Headers(options.headers);
41071              }
41072              this.method = normalizeMethod(options.method || this.method || 'GET');
41073              this.mode = options.mode || this.mode || null;
41074              this.referrer = null;
41075
41076              if ((this.method === 'GET' || this.method === 'HEAD') && body) {
41077                throw new TypeError('Body not allowed for GET or HEAD requests');
41078              }
41079              this._initBody(body);
41080            }
41081
41082            Request.prototype.clone = function() {
41083              return new Request(this, { body: this._bodyInit });
41084            };
41085
41086            function decode(body) {
41087              var form = new FormData();
41088              body
41089                .trim()
41090                .split('&')
41091                .forEach(function(bytes) {
41092                  if (bytes) {
41093                    var split = bytes.split('=');
41094                    var name = split.shift().replace(/\+/g, ' ');
41095                    var value = split.join('=').replace(/\+/g, ' ');
41096                    form.append(decodeURIComponent(name), decodeURIComponent(value));
41097                  }
41098                });
41099              return form;
41100            }
41101
41102            function parseHeaders(rawHeaders) {
41103              var headers = new Headers();
41104              // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
41105              // https://tools.ietf.org/html/rfc7230#section-3.2
41106              var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
41107              preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
41108                var parts = line.split(':');
41109                var key = parts.shift().trim();
41110                if (key) {
41111                  var value = parts.join(':').trim();
41112                  headers.append(key, value);
41113                }
41114              });
41115              return headers;
41116            }
41117
41118            Body.call(Request.prototype);
41119
41120            function Response(bodyInit, options) {
41121              if (!options) {
41122                options = {};
41123              }
41124
41125              this.type = 'default';
41126              this.status = options.status === undefined ? 200 : options.status;
41127              this.ok = this.status >= 200 && this.status < 300;
41128              this.statusText = 'statusText' in options ? options.statusText : 'OK';
41129              this.headers = new Headers(options.headers);
41130              this.url = options.url || '';
41131              this._initBody(bodyInit);
41132            }
41133
41134            Body.call(Response.prototype);
41135
41136            Response.prototype.clone = function() {
41137              return new Response(this._bodyInit, {
41138                status: this.status,
41139                statusText: this.statusText,
41140                headers: new Headers(this.headers),
41141                url: this.url
41142              });
41143            };
41144
41145            Response.error = function() {
41146              var response = new Response(null, { status: 0, statusText: '' });
41147              response.type = 'error';
41148              return response;
41149            };
41150
41151            var redirectStatuses = [301, 302, 303, 307, 308];
41152
41153            Response.redirect = function(url, status) {
41154              if (redirectStatuses.indexOf(status) === -1) {
41155                throw new RangeError('Invalid status code');
41156              }
41157
41158              return new Response(null, { status: status, headers: { location: url } });
41159            };
41160
41161            self.Headers = Headers;
41162            self.Request = Request;
41163            self.Response = Response;
41164
41165            self.fetch = function(input, init) {
41166              return new Promise(function(resolve, reject) {
41167                var request = new Request(input, init);
41168                var xhr = new XMLHttpRequest();
41169
41170                xhr.onload = function() {
41171                  var options = {
41172                    status: xhr.status,
41173                    statusText: xhr.statusText,
41174                    headers: parseHeaders(xhr.getAllResponseHeaders() || '')
41175                  };
41176                  options.url =
41177                    'responseURL' in xhr
41178                      ? xhr.responseURL
41179                      : options.headers.get('X-Request-URL');
41180                  var body = 'response' in xhr ? xhr.response : xhr.responseText;
41181                  resolve(new Response(body, options));
41182                };
41183
41184                xhr.onerror = function() {
41185                  reject(new TypeError('Network request failed'));
41186                };
41187
41188                xhr.ontimeout = function() {
41189                  reject(new TypeError('Network request failed'));
41190                };
41191
41192                xhr.open(request.method, request.url, true);
41193
41194                if (request.credentials === 'include') {
41195                  xhr.withCredentials = true;
41196                } else if (request.credentials === 'omit') {
41197                  xhr.withCredentials = false;
41198                }
41199
41200                if ('responseType' in xhr && support.blob) {
41201                  xhr.responseType = 'blob';
41202                }
41203
41204                request.headers.forEach(function(value, name) {
41205                  xhr.setRequestHeader(name, value);
41206                });
41207
41208                xhr.send(
41209                  typeof request._bodyInit === 'undefined' ? null : request._bodyInit
41210                );
41211              });
41212            };
41213            self.fetch.polyfill = true;
41214          })(typeof self !== 'undefined' ? self : this);
41215        },
41216        {}
41217      ],
41218      38: [
41219        function(_dereq_, module, exports) {
41220          'use strict';
41221          Object.defineProperty(exports, '__esModule', { value: true });
41222          exports.default = void 0;
41223
41224          var _main = _interopRequireDefault(_dereq_('../core/main'));
41225          var _color_conversion = _interopRequireDefault(
41226            _dereq_('../color/color_conversion')
41227          );
41228          function _interopRequireDefault(obj) {
41229            return obj && obj.__esModule ? obj : { default: obj };
41230          } /** //stores the original hsb values
41231           * @module Environment
41232           * @submodule Environment
41233           * @for p5
41234           * @requires core
41235           */
41236          var originalHSB; //stores values for color name exceptions
41237          var colorExceptions = [
41238            {
41239              h: 0,
41240              s: 0,
41241              b: 0.8275,
41242              name: 'gray'
41243            },
41244
41245            {
41246              h: 0,
41247              s: 0,
41248              b: 0.8627,
41249              name: 'gray'
41250            },
41251
41252            {
41253              h: 0,
41254              s: 0,
41255              b: 0.7529,
41256              name: 'gray'
41257            },
41258
41259            {
41260              h: 0.0167,
41261              s: 0.1176,
41262              b: 1,
41263              name: 'light pink'
41264            }
41265          ];
41266
41267          //stores values for color names
41268          var colorLookUp = [
41269            {
41270              h: 0,
41271              s: 0,
41272              b: 0,
41273              name: 'black'
41274            },
41275
41276            {
41277              h: 0,
41278              s: 0,
41279              b: 0.5,
41280              name: 'gray'
41281            },
41282
41283            {
41284              h: 0,
41285              s: 0,
41286              b: 1,
41287              name: 'white'
41288            },
41289
41290            {
41291              h: 0,
41292              s: 0.5,
41293              b: 0.5,
41294              name: 'dark maroon'
41295            },
41296
41297            {
41298              h: 0,
41299              s: 0.5,
41300              b: 1,
41301              name: 'salmon pink'
41302            },
41303
41304            {
41305              h: 0,
41306              s: 1,
41307              b: 0,
41308              name: 'black'
41309            },
41310
41311            {
41312              h: 0,
41313              s: 1,
41314              b: 0.5,
41315              name: 'dark red'
41316            },
41317
41318            {
41319              h: 0,
41320              s: 1,
41321              b: 1,
41322              name: 'red'
41323            },
41324
41325            {
41326              h: 5,
41327              s: 0,
41328              b: 1,
41329              name: 'very light peach'
41330            },
41331
41332            {
41333              h: 5,
41334              s: 0.5,
41335              b: 0.5,
41336              name: 'brown'
41337            },
41338
41339            {
41340              h: 5,
41341              s: 0.5,
41342              b: 1,
41343              name: 'peach'
41344            },
41345
41346            {
41347              h: 5,
41348              s: 1,
41349              b: 0.5,
41350              name: 'brick red'
41351            },
41352
41353            {
41354              h: 5,
41355              s: 1,
41356              b: 1,
41357              name: 'crimson'
41358            },
41359
41360            {
41361              h: 10,
41362              s: 0,
41363              b: 1,
41364              name: 'light peach'
41365            },
41366
41367            {
41368              h: 10,
41369              s: 0.5,
41370              b: 0.5,
41371              name: 'brown'
41372            },
41373
41374            {
41375              h: 10,
41376              s: 0.5,
41377              b: 1,
41378              name: 'light orange'
41379            },
41380
41381            {
41382              h: 10,
41383              s: 1,
41384              b: 0.5,
41385              name: 'brown'
41386            },
41387
41388            {
41389              h: 10,
41390              s: 1,
41391              b: 1,
41392              name: 'orange'
41393            },
41394
41395            {
41396              h: 15,
41397              s: 0,
41398              b: 1,
41399              name: 'very light yellow'
41400            },
41401
41402            {
41403              h: 15,
41404              s: 0.5,
41405              b: 0.5,
41406              name: 'olive green'
41407            },
41408
41409            {
41410              h: 15,
41411              s: 0.5,
41412              b: 1,
41413              name: 'light yellow'
41414            },
41415
41416            {
41417              h: 15,
41418              s: 1,
41419              b: 0,
41420              name: 'dark olive green'
41421            },
41422
41423            {
41424              h: 15,
41425              s: 1,
41426              b: 0.5,
41427              name: 'olive green'
41428            },
41429
41430            {
41431              h: 15,
41432              s: 1,
41433              b: 1,
41434              name: 'yellow'
41435            },
41436
41437            {
41438              h: 20,
41439              s: 0,
41440              b: 1,
41441              name: 'very light yellow'
41442            },
41443
41444            {
41445              h: 20,
41446              s: 0.5,
41447              b: 0.5,
41448              name: 'olive green'
41449            },
41450
41451            {
41452              h: 20,
41453              s: 0.5,
41454              b: 1,
41455              name: 'light yellow green'
41456            },
41457
41458            {
41459              h: 20,
41460              s: 1,
41461              b: 0,
41462              name: 'dark olive green'
41463            },
41464
41465            {
41466              h: 20,
41467              s: 1,
41468              b: 0.5,
41469              name: 'dark yellow green'
41470            },
41471
41472            {
41473              h: 20,
41474              s: 1,
41475              b: 1,
41476              name: 'yellow green'
41477            },
41478
41479            {
41480              h: 25,
41481              s: 0.5,
41482              b: 0.5,
41483              name: 'dark yellow green'
41484            },
41485
41486            {
41487              h: 25,
41488              s: 0.5,
41489              b: 1,
41490              name: 'light green'
41491            },
41492
41493            {
41494              h: 25,
41495              s: 1,
41496              b: 0.5,
41497              name: 'dark green'
41498            },
41499
41500            {
41501              h: 25,
41502              s: 1,
41503              b: 1,
41504              name: 'green'
41505            },
41506
41507            {
41508              h: 30,
41509              s: 0.5,
41510              b: 1,
41511              name: 'light green'
41512            },
41513
41514            {
41515              h: 30,
41516              s: 1,
41517              b: 0.5,
41518              name: 'dark green'
41519            },
41520
41521            {
41522              h: 30,
41523              s: 1,
41524              b: 1,
41525              name: 'green'
41526            },
41527
41528            {
41529              h: 35,
41530              s: 0,
41531              b: 0.5,
41532              name: 'light green'
41533            },
41534
41535            {
41536              h: 35,
41537              s: 0,
41538              b: 1,
41539              name: 'very light green'
41540            },
41541
41542            {
41543              h: 35,
41544              s: 0.5,
41545              b: 0.5,
41546              name: 'dark green'
41547            },
41548
41549            {
41550              h: 35,
41551              s: 0.5,
41552              b: 1,
41553              name: 'light green'
41554            },
41555
41556            {
41557              h: 35,
41558              s: 1,
41559              b: 0,
41560              name: 'very dark green'
41561            },
41562
41563            {
41564              h: 35,
41565              s: 1,
41566              b: 0.5,
41567              name: 'dark green'
41568            },
41569
41570            {
41571              h: 35,
41572              s: 1,
41573              b: 1,
41574              name: 'green'
41575            },
41576
41577            {
41578              h: 40,
41579              s: 0,
41580              b: 1,
41581              name: 'very light green'
41582            },
41583
41584            {
41585              h: 40,
41586              s: 0.5,
41587              b: 0.5,
41588              name: 'dark green'
41589            },
41590
41591            {
41592              h: 40,
41593              s: 0.5,
41594              b: 1,
41595              name: 'light green'
41596            },
41597
41598            {
41599              h: 40,
41600              s: 1,
41601              b: 0.5,
41602              name: 'dark green'
41603            },
41604
41605            {
41606              h: 40,
41607              s: 1,
41608              b: 1,
41609              name: 'green'
41610            },
41611
41612            {
41613              h: 45,
41614              s: 0.5,
41615              b: 1,
41616              name: 'light turquoise'
41617            },
41618
41619            {
41620              h: 45,
41621              s: 1,
41622              b: 0.5,
41623              name: 'dark turquoise'
41624            },
41625
41626            {
41627              h: 45,
41628              s: 1,
41629              b: 1,
41630              name: 'turquoise'
41631            },
41632
41633            {
41634              h: 50,
41635              s: 0,
41636              b: 1,
41637              name: 'light sky blue'
41638            },
41639
41640            {
41641              h: 50,
41642              s: 0.5,
41643              b: 0.5,
41644              name: 'dark cyan'
41645            },
41646
41647            {
41648              h: 50,
41649              s: 0.5,
41650              b: 1,
41651              name: 'light cyan'
41652            },
41653
41654            {
41655              h: 50,
41656              s: 1,
41657              b: 0.5,
41658              name: 'dark cyan'
41659            },
41660
41661            {
41662              h: 50,
41663              s: 1,
41664              b: 1,
41665              name: 'cyan'
41666            },
41667
41668            {
41669              h: 55,
41670              s: 0,
41671              b: 1,
41672              name: 'light sky blue'
41673            },
41674
41675            {
41676              h: 55,
41677              s: 0.5,
41678              b: 1,
41679              name: 'light sky blue'
41680            },
41681
41682            {
41683              h: 55,
41684              s: 1,
41685              b: 0.5,
41686              name: 'dark blue'
41687            },
41688
41689            {
41690              h: 55,
41691              s: 1,
41692              b: 1,
41693              name: 'sky blue'
41694            },
41695
41696            {
41697              h: 60,
41698              s: 0,
41699              b: 0.5,
41700              name: 'gray'
41701            },
41702
41703            {
41704              h: 60,
41705              s: 0,
41706              b: 1,
41707              name: 'very light blue'
41708            },
41709
41710            {
41711              h: 60,
41712              s: 0.5,
41713              b: 0.5,
41714              name: 'blue'
41715            },
41716
41717            {
41718              h: 60,
41719              s: 0.5,
41720              b: 1,
41721              name: 'light blue'
41722            },
41723
41724            {
41725              h: 60,
41726              s: 1,
41727              b: 0.5,
41728              name: 'navy blue'
41729            },
41730
41731            {
41732              h: 60,
41733              s: 1,
41734              b: 1,
41735              name: 'blue'
41736            },
41737
41738            {
41739              h: 65,
41740              s: 0,
41741              b: 1,
41742              name: 'lavender'
41743            },
41744
41745            {
41746              h: 65,
41747              s: 0.5,
41748              b: 0.5,
41749              name: 'navy blue'
41750            },
41751
41752            {
41753              h: 65,
41754              s: 0.5,
41755              b: 1,
41756              name: 'light purple'
41757            },
41758
41759            {
41760              h: 65,
41761              s: 1,
41762              b: 0.5,
41763              name: 'dark navy blue'
41764            },
41765
41766            {
41767              h: 65,
41768              s: 1,
41769              b: 1,
41770              name: 'blue'
41771            },
41772
41773            {
41774              h: 70,
41775              s: 0,
41776              b: 1,
41777              name: 'lavender'
41778            },
41779
41780            {
41781              h: 70,
41782              s: 0.5,
41783              b: 0.5,
41784              name: 'navy blue'
41785            },
41786
41787            {
41788              h: 70,
41789              s: 0.5,
41790              b: 1,
41791              name: 'lavender blue'
41792            },
41793
41794            {
41795              h: 70,
41796              s: 1,
41797              b: 0.5,
41798              name: 'dark navy blue'
41799            },
41800
41801            {
41802              h: 70,
41803              s: 1,
41804              b: 1,
41805              name: 'blue'
41806            },
41807
41808            {
41809              h: 75,
41810              s: 0.5,
41811              b: 1,
41812              name: 'lavender'
41813            },
41814
41815            {
41816              h: 75,
41817              s: 1,
41818              b: 0.5,
41819              name: 'dark purple'
41820            },
41821
41822            {
41823              h: 75,
41824              s: 1,
41825              b: 1,
41826              name: 'purple'
41827            },
41828
41829            {
41830              h: 80,
41831              s: 0.5,
41832              b: 1,
41833              name: 'pinkish purple'
41834            },
41835
41836            {
41837              h: 80,
41838              s: 1,
41839              b: 0.5,
41840              name: 'dark purple'
41841            },
41842
41843            {
41844              h: 80,
41845              s: 1,
41846              b: 1,
41847              name: 'purple'
41848            },
41849
41850            {
41851              h: 85,
41852              s: 0,
41853              b: 1,
41854              name: 'light pink'
41855            },
41856
41857            {
41858              h: 85,
41859              s: 0.5,
41860              b: 0.5,
41861              name: 'purple'
41862            },
41863
41864            {
41865              h: 85,
41866              s: 0.5,
41867              b: 1,
41868              name: 'light fuchsia'
41869            },
41870
41871            {
41872              h: 85,
41873              s: 1,
41874              b: 0.5,
41875              name: 'dark fuchsia'
41876            },
41877
41878            {
41879              h: 85,
41880              s: 1,
41881              b: 1,
41882              name: 'fuchsia'
41883            },
41884
41885            {
41886              h: 90,
41887              s: 0.5,
41888              b: 0.5,
41889              name: 'dark fuchsia'
41890            },
41891
41892            {
41893              h: 90,
41894              s: 0.5,
41895              b: 1,
41896              name: 'hot pink'
41897            },
41898
41899            {
41900              h: 90,
41901              s: 1,
41902              b: 0.5,
41903              name: 'dark fuchsia'
41904            },
41905
41906            {
41907              h: 90,
41908              s: 1,
41909              b: 1,
41910              name: 'fuchsia'
41911            },
41912
41913            {
41914              h: 95,
41915              s: 0,
41916              b: 1,
41917              name: 'pink'
41918            },
41919
41920            {
41921              h: 95,
41922              s: 0.5,
41923              b: 1,
41924              name: 'light pink'
41925            },
41926
41927            {
41928              h: 95,
41929              s: 1,
41930              b: 0.5,
41931              name: 'dark magenta'
41932            },
41933
41934            {
41935              h: 95,
41936              s: 1,
41937              b: 1,
41938              name: 'magenta'
41939            }
41940          ];
41941
41942          //returns text with color name
41943          function _calculateColor(hsb) {
41944            var colortext;
41945            //round hue
41946            if (hsb[0] !== 0) {
41947              hsb[0] = Math.round(hsb[0] * 100);
41948              var hue = hsb[0].toString().split('');
41949              var last = hue.length - 1;
41950              hue[last] = parseInt(hue[last]);
41951              //if last digit of hue is < 2.5 make it 0
41952              if (hue[last] < 2.5) {
41953                hue[last] = 0;
41954                //if last digit of hue is >= 2.5 and less than 7.5 make it 5
41955              } else if (hue[last] >= 2.5 && hue[last] < 7.5) {
41956                hue[last] = 5;
41957              }
41958              //if hue only has two digits
41959              if (hue.length === 2) {
41960                hue[0] = parseInt(hue[0]);
41961                //if last is greater than 7.5
41962                if (hue[last] >= 7.5) {
41963                  //add one to the tens
41964                  hue[last] = 0;
41965                  hue[0] = hue[0] + 1;
41966                }
41967                hsb[0] = hue[0] * 10 + hue[1];
41968              } else {
41969                if (hue[last] >= 7.5) {
41970                  hsb[0] = 10;
41971                } else {
41972         
41972         hsb[0] = hue[last];
41973                }
41974              }
41975            }
41976            //map brightness from 0 to 1
41977            hsb[2] = hsb[2] / 255;
41978            //round saturation and brightness
41979            for (var i = hsb.length - 1; i >= 1; i--) {
41980              if (hsb[i] <= 0.25) {
41981                hsb[i] = 0;
41982              } else if (hsb[i] > 0.25 && hsb[i] < 0.75) {
41983                hsb[i] = 0.5;
41984              } else {
41985                hsb[i] = 1;
41986              }
41987            }
41988            //after rounding, if the values are hue 0, saturation 0 and brightness 1
41989            //look at color exceptions which includes several tones from white to gray
41990            if (hsb[0] === 0 && hsb[1] === 0 && hsb[2] === 1) {
41991              //round original hsb values
41992              for (var _i = 2; _i >= 0; _i--) {
41993                originalHSB[_i] = Math.round(originalHSB[_i] * 10000) / 10000;
41994              }
41995              //compare with the values in the colorExceptions array
41996              for (var e = 0; e < colorExceptions.length; e++) {
41997                if (
41998                  colorExceptions[e].h === originalHSB[0] &&
41999                  colorExceptions[e].s === originalHSB[1] &&
42000                  colorExceptions[e].b === originalHSB[2]
42001                ) {
42002                  colortext = colorExceptions[e].name;
42003                  break;
42004                } else {
42005                  //if there is no match return white
42006                  colortext = 'white';
42007                }
42008              }
42009            } else {
42010              //otherwise, compare with values in colorLookUp
42011              for (var _i2 = 0; _i2 < colorLookUp.length; _i2++) {
42012                if (
42013                  colorLookUp[_i2].h === hsb[0] &&
42014                  colorLookUp[_i2].s === hsb[1] &&
42015                  colorLookUp[_i2].b === hsb[2]
42016                ) {
42017                  colortext = colorLookUp[_i2].name;
42018                  break;
42019                }
42020              }
42021            }
42022            return colortext;
42023          }
42024
42025          //gets rgba and returs a color name
42026          _main.default.prototype._rgbColorName = function(arg) {
42027            //conversts rgba to hsb
42028            var hsb = _color_conversion.default._rgbaToHSBA(arg);
42029            //stores hsb in global variable
42030            originalHSB = hsb;
42031            //calculate color name
42032            return _calculateColor([hsb[0], hsb[1], hsb[2]]);
42033          };
42034          var _default = _main.default;
42035          exports.default = _default;
42036        },
42037        { '../color/color_conversion': 44, '../core/main': 59 }
42038      ],
42039      39: [
42040        function(_dereq_, module, exports) {
42041          'use strict';
42042          Object.defineProperty(exports, '__esModule', { value: true });
42043          exports.default = void 0;
42044
42045          var _main = _interopRequireDefault(_dereq_('../core/main'));
42046          function _interopRequireDefault(obj) {
42047            return obj && obj.__esModule ? obj : { default: obj };
42048          }
42049          /**
42050           * @module Environment
42051           * @submodule Environment
42052           * @for p5
42053           * @requires core
42054           */ var descContainer = '_Description'; //Fallback container
42055          var fallbackDescId = '_fallbackDesc'; //Fallback description
42056          var fallbackTableId = '_fallbackTable'; //Fallback Table
42057          var fallbackTableElId = '_fte_'; //Fallback Table Element
42058          var labelContainer = '_Label'; //Label container
42059          var labelDescId = '_labelDesc'; //Label description
42060          var labelTableId = '_labelTable'; //Label Table
42061          var labelTableElId = '_lte_'; //Label Table Element
42062          /**
42063           * Creates a screen reader accessible description for the canvas.
42064           * The first parameter should be a string with a description of the canvas.
42065           * The second parameter is optional. If specified, it determines how the
42066           * description is displayed.
42067           *
42068           * <code class="language-javascript">describe(text, LABEL)</code> displays
42069           * the description to all users as a <a
42070           * href="https://en.wikipedia.org/wiki/Museum_label" target="_blank">
42071           * tombstone or exhibit label/caption</a> in a
42072           * <code class="language-javascript">&lt;div class="p5Label"&gt;&lt;/div&gt;</code>
42073           * adjacent to the canvas. You can style it as you wish in your CSS.
42074           *
42075           * <code class="language-javascript">describe(text, FALLBACK)</code> makes the
42076           * description accessible to screen-reader users only, in
42077           * <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility" target="_blank">
42078           * a sub DOM inside the canvas element</a>. If a second parameter is not
42079           * specified, by default, the description will only be available to
42080           * screen-reader users.
42081           *
42082           * @method describe
42083           * @param  {String} text      description of the canvas
42084           * @param  {Constant} [display] either LABEL or FALLBACK (Optional)
42085           *
42086           * @example
42087           * <div>
42088           * <code>
42089           * describe('pink square with red heart in the bottom right corner', LABEL);
42090           * background('pink');
42091           * fill('red');
42092           * noStroke();
42093           * ellipse(67, 67, 20, 20);
42094           * ellipse(83, 67, 20, 20);
42095           * triangle(91, 73, 75, 95, 59, 73);
42096           * </code>
42097           * </div>
42098           *
42099           * <div>
42100           * <code>
42101           * let x = 0;
42102           * function draw() {
42103           *   if (x > 100) {
42104           *     x = 0;
42105           *   }
42106           *   background(220);
42107           *   fill(0, 255, 0);
42108           *   ellipse(x, 50, 40, 40);
42109           *   x = x + 0.1;
42110           *   describe('green circle at x pos ' + round(x) + ' moving to the right');
42111           * }
42112           * </code>
42113           * </div>
42114           *
42115           */ _main.default.prototype.describe = function(text, display) {
42116            _main.default._validateParameters('describe', arguments);
42117            if (typeof text !== 'string') {
42118              return;
42119            }
42120            var cnvId = this.canvas.id;
42121            //calls function that adds punctuation for better screen reading
42122            text = _descriptionText(text);
42123            //if there is no dummyDOM
42124            if (!this.dummyDOM) {
42125              this.dummyDOM = document.getElementById(cnvId).parentNode;
42126            }
42127            if (!this.descriptions) {
42128              this.descriptions = {};
42129            }
42130            //check if html structure for description is ready
42131            if (this.descriptions.fallback) {
42132              //check if text is different from current description
42133              if (this.descriptions.fallback.innerHTML !== text) {
42134                //update description
42135                this.descriptions.fallback.innerHTML = text;
42136              }
42137            } else {
42138              //create fallback html structure
42139              this._describeHTML('fallback', text);
42140            }
42141            //if display is LABEL
42142            if (display === this.LABEL) {
42143              //check if html structure for label is ready
42144              if (this.descriptions.label) {
42145                //check if text is different from current label
42146                if (this.descriptions.label.innerHTML !== text) {
42147                  //update label description
42148                  this.descriptions.label.innerHTML = text;
42149                }
42150              } else {
42151                //create label html structure
42152                this._describeHTML('label', text);
42153              }
42154            }
42155          };
42156
42157          /**
42158           * This function creates a screen-reader accessible
42159           * description for elements —shapes or groups of shapes that create
42160           * meaning together— in the canvas. The first paramater should
42161           * be the name of the element. The second parameter should be a string
42162           * with a description of the element. The third parameter is optional.
42163           * If specified, it determines how the element description is displayed.
42164           *
42165           * <code class="language-javascript">describeElement(name, text, LABEL)</code>
42166           * displays the element description to all users as a
42167           * <a href="https://en.wikipedia.org/wiki/Museum_label" target="_blank">
42168           * tombstone or exhibit label/caption</a> in a
42169           * <code class="language-javascript">&lt;div class="p5Label"&gt;&lt;/div&gt;</code>
42170           * adjacent to the canvas. You can style it as you wish in your CSS.
42171           *
42172           * <code class="language-javascript">describeElement(name, text, FALLBACK)</code>
42173           * makes the element description accessible to screen-reader users
42174           * only, in <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility" target="_blank">
42175           * a sub DOM inside the canvas element</a>. If a second parameter is not
42176           * specified, by default, the element description will only be available
42177           * to screen-reader users.
42178           *
42179           * @method describeElement
42180           * @param  {String} name      name of the element
42181           * @param  {String} text      description of the element
42182           * @param  {Constant} [display] either LABEL or FALLBACK (Optional)
42183           *
42184           * @example
42185           * <div>
42186           * <code>
42187           * describe('Heart and yellow circle over pink background', LABEL);
42188           * noStroke();
42189           * background('pink');
42190           * describeElement('Circle', 'Yellow circle in the top left corner', LABEL);
42191           * fill('yellow');
42192           * ellipse(25, 25, 40, 40);
42193           * describeElement('Heart', 'red heart in the bottom right corner', LABEL);
42194           * fill('red');
42195           * ellipse(66.6, 66.6, 20, 20);
42196           * ellipse(83.2, 66.6, 20, 20);
42197           * triangle(91.2, 72.6, 75, 95, 58.6, 72.6);
42198           * </code>
42199           * </div>
42200           */
42201
42202          _main.default.prototype.describeElement = function(name, text, display) {
42203            _main.default._validateParameters('describeElement', arguments);
42204            if (typeof text !== 'string' || typeof name !== 'string') {
42205              return;
42206            }
42207            var cnvId = this.canvas.id;
42208            //calls function that adds punctuation for better screen reading
42209            text = _descriptionText(text);
42210            //calls function that adds punctuation for better screen reading
42211            var elementName = _elementName(name);
42212            //remove any special characters from name to use it as html id
42213            name = name.replace(/[^a-zA-Z0-9 ]/g, '');
42214            //store element description
42215            var inner = '<th scope="row">'
42216              .concat(elementName, '</th><td>')
42217              .concat(text, '</td>');
42218            //if there is no dummyDOM
42219            if (!this.dummyDOM) {
42220              this.dummyDOM = document.getElementById(cnvId).parentNode;
42221            }
42222            if (!this.descriptions) {
42223              this.descriptions = { fallbackElements: {} };
42224            } else if (!this.descriptions.fallbackElements) {
42225              this.descriptions.fallbackElements = {};
42226            }
42227            //check if html structure for element description is ready
42228            if (this.descriptions.fallbackElements[name]) {
42229              //if current element description is not the same as inner
42230              if (this.descriptions.fallbackElements[name].innerHTML !== inner) {
42231                //update element description
42232                this.descriptions.fallbackElements[name].innerHTML = inner;
42233              }
42234            } else {
42235              //create fallback html structure
42236              this._describeElementHTML('fallback', name, inner);
42237            }
42238            //if display is LABEL
42239            if (display === this.LABEL) {
42240              if (!this.descriptions.labelElements) {
42241                this.descriptions.labelElements = {};
42242              }
42243              //if html structure for label element description is ready
42244              if (this.descriptions.labelElements[name]) {
42245                //if label element description is different
42246                if (this.descriptions.labelElements[name].innerHTML !== inner) {
42247                  //update label element description
42248                  this.descriptions.labelElements[name].innerHTML = inner;
42249                }
42250              } else {
42251                //create label element html structure
42252                this._describeElementHTML('label', name, inner);
42253              }
42254            }
42255          };
42256
42257          /*
42258    *
42259    * Helper functions for describe() and describeElement().
42260    *
42261    */
42262
42263          // check that text is not LABEL or FALLBACK and ensure text ends with punctuation mark
42264          function _descriptionText(text) {
42265            if (text === 'label' || text === 'fallback') {
42266              throw new Error('description should not be LABEL or FALLBACK');
42267            }
42268            //if string does not end with '.'
42269            if (
42270              !text.endsWith('.') &&
42271              !text.endsWith(';') &&
42272              !text.endsWith(',') &&
42273              !text.endsWith('?') &&
42274              !text.endsWith('!')
42275            ) {
42276              //add '.' to the end of string
42277              text = text + '.';
42278            }
42279            return text;
42280          }
42281
42282          /*
42283   * Helper functions for describe()
42284   */
42285
42286          //creates HTML structure for canvas descriptions
42287          _main.default.prototype._describeHTML = function(type, text) {
42288            var cnvId = this.canvas.id;
42289            if (type === 'fallback') {
42290              //if there is no description container
42291              if (!this.dummyDOM.querySelector('#'.concat(cnvId + descContainer))) {
42292                //if there are no accessible outputs (see textOutput() and gridOutput())
42293                var html = '<div id="'
42294                  .concat(cnvId)
42295                  .concat(
42296                    descContainer,
42297                    '" role="region" aria-label="Canvas Description"><p id="'
42298                  )
42299                  .concat(cnvId)
42300                  .concat(fallbackDescId, '"></p></div>');
42301                if (!this.dummyDOM.querySelector('#'.concat(cnvId, 'accessibleOutput'))) {
42302                  //create description container + <p> for fallback description
42303                  this.dummyDOM.querySelector('#'.concat(cnvId)).innerHTML = html;
42304                } else {
42305                  //create description container + <p> for fallback description before outputs
42306                  this.dummyDOM
42307                    .querySelector('#'.concat(cnvId, 'accessibleOutput'))
42308                    .insertAdjacentHTML('beforebegin', html);
42309                }
42310              } else {
42311                //if describeElement() has already created the container and added a table of elements
42312                //create fallback description <p> before the table
42313                this.dummyDOM
42314                  .querySelector('#' + cnvId + fallbackTableId)
42315                  .insertAdjacentHTML(
42316                    'beforebegin',
42317                    '<p id="'.concat(cnvId + fallbackDescId, '"></p>')
42318                  );
42319              }
42320              //if the container for the description exists
42321              this.descriptions.fallback = this.dummyDOM.querySelector(
42322                '#'.concat(cnvId).concat(fallbackDescId)
42323              );
42324
42325              this.descriptions.fallback.innerHTML = text;
42326              return;
42327            } else if (type === 'label') {
42328              //if there is no label container
42329              if (!this.dummyDOM.querySelector('#'.concat(cnvId + labelContainer))) {
42330                var _html = '<div id="'
42331                  .concat(cnvId)
42332                  .concat(labelContainer, '" class="p5Label"><p id="')
42333                  .concat(cnvId)
42334                  .concat(labelDescId, '"></p></div>');
42335                //if there are no accessible outputs (see textOutput() and gridOutput())
42336                if (
42337                  !this.dummyDOM.querySelector('#'.concat(cnvId, 'accessibleOutputLabel'))
42338                ) {
42339                  //create label container + <p> for label description
42340                  this.dummyDOM
42341                    .querySelector('#' + cnvId)
42342      
42342              .insertAdjacentHTML('afterend', _html);
42343                } else {
42344                  //create label container + <p> for label description before outputs
42345                  this.dummyDOM
42346                    .querySelector('#'.concat(cnvId, 'accessibleOutputLabel'))
42347                    .insertAdjacentHTML('beforebegin', _html);
42348                }
42349              } else if (this.dummyDOM.querySelector('#'.concat(cnvId + labelTableId))) {
42350                //if describeElement() has already created the container and added a table of elements
42351                //create label description <p> before the table
42352                this.dummyDOM
42353                  .querySelector('#'.concat(cnvId + labelTableId))
42354                  .insertAdjacentHTML(
42355                    'beforebegin',
42356                    '<p id="'.concat(cnvId).concat(labelDescId, '"></p>')
42357                  );
42358              }
42359              this.descriptions.label = this.dummyDOM.querySelector(
42360                '#' + cnvId + labelDescId
42361              );
42362
42363              this.descriptions.label.innerHTML = text;
42364              return;
42365            }
42366          };
42367
42368          /*
42369    * Helper functions for describeElement().
42370    */
42371
42372          //check that name is not LABEL or FALLBACK and ensure text ends with colon
42373          function _elementName(name) {
42374            if (name === 'label' || name === 'fallback') {
42375              throw new Error('element name should not be LABEL or FALLBACK');
42376            }
42377            //check if last character of string n is '.', ';', or ','
42378            if (name.endsWith('.') || name.endsWith(';') || name.endsWith(',')) {
42379              //replace last character with ':'
42380              name = name.replace(/.$/, ':');
42381            } else if (!name.endsWith(':')) {
42382              //if string n does not end with ':'
42383              //add ':'' at the end of string
42384              name = name + ':';
42385            }
42386            return name;
42387          }
42388
42389          //creates HTML structure for element descriptions
42390          _main.default.prototype._describeElementHTML = function(type, name, text) {
42391            var cnvId = this.canvas.id;
42392            if (type === 'fallback') {
42393              //if there is no description container
42394              if (!this.dummyDOM.querySelector('#'.concat(cnvId + descContainer))) {
42395                //if there are no accessible outputs (see textOutput() and gridOutput())
42396                var html = '<div id="'
42397                  .concat(cnvId)
42398                  .concat(
42399                    descContainer,
42400                    '" role="region" aria-label="Canvas Description"><table id="'
42401                  )
42402                  .concat(cnvId)
42403                  .concat(
42404                    fallbackTableId,
42405                    '"><caption>Canvas elements and their descriptions</caption></table></div>'
42406                  );
42407                if (!this.dummyDOM.querySelector('#'.concat(cnvId, 'accessibleOutput'))) {
42408                  //create container + table for element descriptions
42409                  this.dummyDOM.querySelector('#' + cnvId).innerHTML = html;
42410                } else {
42411                  //create container + table for element descriptions before outputs
42412                  this.dummyDOM
42413                    .querySelector('#'.concat(cnvId, 'accessibleOutput'))
42414                    .insertAdjacentHTML('beforebegin', html);
42415                }
42416              } else if (!this.dummyDOM.querySelector('#' + cnvId + fallbackTableId)) {
42417                //if describe() has already created the container and added a description
42418                //and there is no table create fallback table for element description after
42419                //fallback description
42420                this.dummyDOM
42421                  .querySelector('#' + cnvId + fallbackDescId)
42422                  .insertAdjacentHTML(
42423                    'afterend',
42424                    '<table id="'
42425                      .concat(cnvId)
42426                      .concat(
42427                        fallbackTableId,
42428                        '"><caption>Canvas elements and their descriptions</caption></table>'
42429                      )
42430                  );
42431              }
42432              //create a table row for the element
42433              var tableRow = document.createElement('tr');
42434              tableRow.id = cnvId + fallbackTableElId + name;
42435              this.dummyDOM
42436                .querySelector('#' + cnvId + fallbackTableId)
42437                .appendChild(tableRow);
42438              //update element description
42439              this.descriptions.fallbackElements[name] = this.dummyDOM.querySelector(
42440                '#'
42441                  .concat(cnvId)
42442                  .concat(fallbackTableElId)
42443                  .concat(name)
42444              );
42445
42446              this.descriptions.fallbackElements[name].innerHTML = text;
42447              return;
42448            } else if (type === 'label') {
42449              //If display is LABEL creates a div adjacent to the canvas element with
42450              //a table, a row header cell with the name of the elements,
42451              //and adds the description of the element in adjecent cell.
42452              //if there is no label description container
42453              if (!this.dummyDOM.querySelector('#'.concat(cnvId + labelContainer))) {
42454                //if there are no accessible outputs (see textOutput() and gridOutput())
42455                var _html2 = '<div id="'
42456                  .concat(cnvId)
42457                  .concat(labelContainer, '" class="p5Label"><table id="')
42458                  .concat(cnvId)
42459                  .concat(labelTableId, '"></table></div>');
42460                if (
42461                  !this.dummyDOM.querySelector('#'.concat(cnvId, 'accessibleOutputLabel'))
42462                ) {
42463                  //create container + table for element descriptions
42464                  this.dummyDOM
42465                    .querySelector('#' + cnvId)
42466                    .insertAdjacentHTML('afterend', _html2);
42467                } else {
42468                  //create container + table for element descriptions before outputs
42469                  this.dummyDOM
42470                    .querySelector('#'.concat(cnvId, 'accessibleOutputLabel'))
42471                    .insertAdjacentHTML('beforebegin', _html2);
42472                }
42473              } else if (!this.dummyDOM.querySelector('#'.concat(cnvId + labelTableId))) {
42474                //if describe() has already created the label container and added a description
42475                //and there is no table create label table for element description after
42476                //label description
42477                this.dummyDOM
42478                  .querySelector('#' + cnvId + labelDescId)
42479                  .insertAdjacentHTML(
42480                    'afterend',
42481                    '<table id="'.concat(cnvId + labelTableId, '"></table>')
42482                  );
42483              }
42484              //create a table row for the element label description
42485              var _tableRow = document.createElement('tr');
42486              _tableRow.id = cnvId + labelTableElId + name;
42487              this.dummyDOM
42488                .querySelector('#' + cnvId + labelTableId)
42489                .appendChild(_tableRow);
42490              //update element label description
42491              this.descriptions.labelElements[name] = this.dummyDOM.querySelector(
42492                '#'
42493                  .concat(cnvId)
42494                  .concat(labelTableElId)
42495                  .concat(name)
42496              );
42497
42498              this.descriptions.labelElements[name].innerHTML = text;
42499            }
42500          };
42501          var _default = _main.default;
42502          exports.default = _default;
42503        },
42504        { '../core/main': 59 }
42505      ],
42506      40: [
42507        function(_dereq_, module, exports) {
42508          'use strict';
42509          Object.defineProperty(exports, '__esModule', { value: true });
42510          exports.default = void 0;
42511
42512          var _main = _interopRequireDefault(_dereq_('../core/main'));
42513          function _interopRequireDefault(obj) {
42514            return obj && obj.__esModule ? obj : { default: obj };
42515          } /** //the functions in this file support updating the grid output
42516           * @module Environment
42517           * @submodule Environment
42518           * @for p5
42519           * @requires core
42520           */
42521          //updates gridOutput
42522          _main.default.prototype._updateGridOutput = function(idT) {
42523            //if html structure is not there yet
42524            if (!this.dummyDOM.querySelector('#'.concat(idT, '_summary'))) {
42525              return;
42526            }
42527            var current = this._accessibleOutputs[idT];
42528            //create shape details list
42529            var innerShapeDetails = _gridShapeDetails(idT, this.ingredients.shapes);
42530            //create summary
42531            var innerSummary = _gridSummary(
42532              innerShapeDetails.numShapes,
42533              this.ingredients.colors.background,
42534              this.width,
42535              this.height
42536            );
42537
42538            //create grid map
42539            var innerMap = _gridMap(idT, this.ingredients.shapes);
42540            //if it is different from current summary
42541            if (innerSummary !== current.summary.innerHTML) {
42542              //update
42543              current.summary.innerHTML = innerSummary;
42544            }
42545            //if it is different from current map
42546            if (innerMap !== current.map.innerHTML) {
42547              //update
42548              current.map.innerHTML = innerMap;
42549            }
42550            //if it is different from current shape details
42551            if (innerShapeDetails.details !== current.shapeDetails.innerHTML) {
42552              //update
42553              current.shapeDetails.innerHTML = innerShapeDetails.details;
42554            }
42555            this._accessibleOutputs[idT] = current;
42556          };
42557
42558          //creates spatial grid that maps the location of shapes
42559          function _gridMap(idT, ingredients) {
42560            var shapeNumber = 0;
42561            var table = '';
42562            //create an array of arrays 10*10 of empty cells
42563            var cells = Array.apply(null, Array(10)).map(function() {});
42564            for (var r in cells) {
42565              cells[r] = Array.apply(null, Array(10)).map(function() {});
42566            }
42567            for (var x in ingredients) {
42568              for (var y in ingredients[x]) {
42569                var fill = void 0;
42570                if (x !== 'line') {
42571                  fill = '<a href="#'
42572                    .concat(idT, 'shape')
42573                    .concat(shapeNumber, '">')
42574                    .concat(ingredients[x][y].color, ' ')
42575                    .concat(x, '</a>');
42576                } else {
42577                  fill = '<a href="#'
42578                    .concat(idT, 'shape')
42579                    .concat(shapeNumber, '">')
42580                    .concat(ingredients[x][y].color, ' ')
42581                    .concat(x, ' midpoint</a>');
42582                }
42583                //if empty cell of location of shape is undefined
42584                if (!cells[ingredients[x][y].loc.locY][ingredients[x][y].loc.locX]) {
42585                  //fill it with shape info
42586                  cells[ingredients[x][y].loc.locY][ingredients[x][y].loc.locX] = fill;
42587                  //if a shape is already in that location
42588                } else {
42589                  //add it
42590                  cells[ingredients[x][y].loc.locY][ingredients[x][y].loc.locX] =
42591                    cells[ingredients[x][y].loc.locY][ingredients[x][y].loc.locX] +
42592                    '  ' +
42593                    fill;
42594                }
42595                shapeNumber++;
42596              }
42597            }
42598            //make table based on array
42599            for (var _r in cells) {
42600              var row = '<tr>';
42601              for (var c in cells[_r]) {
42602                row = row + '<td>';
42603                if (cells[_r][c] !== undefined) {
42604                  row = row + cells[_r][c];
42605                }
42606                row = row + '</td>';
42607              }
42608              table = table + row + '</tr>';
42609            }
42610            return table;
42611          }
42612
42613          //creates grid summary
42614          function _gridSummary(numShapes, background, width, height) {
42615            var text = ''
42616              .concat(background, ' canvas, ')
42617              .concat(width, ' by ')
42618              .concat(height, ' pixels, contains ')
42619              .concat(numShapes[0]);
42620
42621            if (numShapes[0] === 1) {
42622              text = ''.concat(text, ' shape: ').concat(numShapes[1]);
42623            } else {
42624              text = ''.concat(text, ' shapes: ').concat(numShapes[1]);
42625            }
42626            return text;
42627          }
42628
42629          //creates list of shapes
42630          function _gridShapeDetails(idT, ingredients) {
42631            var shapeDetails = '';
42632            var shapes = '';
42633            var totalShapes = 0;
42634            //goes trhough every shape type in ingredients
42635            for (var x in ingredients) {
42636              var shapeNum = 0;
42637              for (var y in ingredients[x]) {
42638                //it creates a line in a list
42639                var line = '<li id="'
42640                  .concat(idT, 'shape')
42641                  .concat(totalShapes, '">')
42642                  .concat(ingredients[x][y].color, ' ')
42643                  .concat(x, ',');
42644                if (x === 'line') {
42645                  line =
42646                    line +
42647                    ' location = '
42648                      .concat(ingredients[x][y].pos, ', length = ')
42649                      .concat(ingredients[x][y].length, ' pixels');
42650                } else {
42651                  line = line + ' location = '.concat(ingredients[x][y].pos);
42652                  if (x !== 'point') {
42653                    line = line + ', area = '.concat(ingredients[x][y].area, ' %');
42654                  }
42655                  line = line + '</li>';
42656                }
42657                shapeDetails = shapeDetails + line;
42658                shapeNum++;
42659                totalShapes++;
42660              }
42661              if (shapeNum > 1) {
42662                shapes = ''
42663                  .concat(shapes, ' ')
42664                  .concat(shapeNum, ' ')
42665                  .concat(x, 's');
42666              } else {
42667                shapes = ''
42668                  .concat(shapes, ' ')
42669                  .concat(shapeNum, ' ')
42670                  .concat(x);
42671              }
42672            }
42673            return { numShapes: [totalShapes, shapes], details: shapeDetails };
42674          }
42675          var _default = _main.default;
42676          exports.default = _default;
42677        },
42678        { '../core/main': 59 }
42679      ],
42680      41: [
42681        function(_dereq_, module, exports) {
42682          'use strict';
42683          Object.defineProperty(exports, '__esModule', { value: true });
42684          exports.default = void 0;
42685
42686          var _main = _interopRequireDefault(_dereq_('../core/main'));
42687          function _interopRequireDefault(obj) {
42688            return obj && obj.__esModule ? obj : { default: obj };
42689          }
42690          /**
42691           * @module Environment
42692           * @submodule Environment
42693           * @for p5
42694           * @requires core
42695           */ /**
42696           * <code class="language-javascript">textOutput()</code> creates a screenreader
42697           * accessible output that describes the shapes present on the canvas.
42698           * The general description of the canvas includes canvas size,
42699           * canvas color, and number of elements in the canvas
42700           * (example: 'Your output is a, 400 by 400 pixels, lavender blue
42701           * canvas containing the following 4 shapes:'). This description
42702           * is followed by a list of shapes where the color, position, and area
42703           * of each shape are described (example: "orange ellipse at top left
42704           * covering 1% of the canvas"). Each element can be selected to get
42705           * more details. A table of elements is also provided. In this table,
42706           * shape, color, location, coordinates and area are described
42707           * (example: "orange ellipse location=top left area=2").
42708           *
42709           * <code class="language-javascript">textOutput()</code> and <code class="language-javascript">texOutput(FALLBACK)</code>
42710           * make the output available in <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility" target="_blank">
42711           * a sub DOM inside the canvas element</a> which is accessible to screen readers.
42712           * <code class="language-javascript">textOutput(LABEL)</code> creates an
42713           * additional div with the output adjacent to the canvas, this is useful
42714           * for non-screen reader users that might want to display the output outside
42715           * of the canvas' sub DOM as they code. However, using LABEL will create
42716           * unnecessary redundancy for screen reader users. We recommend using LABEL
42717           * only as part of the development process of a sketch and removing it before
42718           * publishing or sharing with screen reader users.
42719           *
42720           * @method textOutput
42721           * @param  {Constant} [display] either FALLBACK or LABEL (Optional)
42722           *
42723           * @example
42724           * <div>
42725           * <code>
42726           * textOutput();
42727           * background(148, 196, 0);
42728           * fill(255, 0, 0);
42729           * ellipse(20, 20, 20, 20);
42730           * fill(0, 0, 255);
42731           * rect(50, 50, 50, 50);
42732           * </code>
42733           * </div>
42734           *
42735           *
42736           * <div>
42737           * <code>
42738           * let x = 0;
42739           * function draw() {
42740           *   textOutput();
42741           *   background(148, 196, 0);
42742           *   fill(255, 0, 0);
42743           *   ellipse(x, 20, 20, 20);
42744           *   fill(0, 0, 255);
42745           *   rect(50, 50, 50, 50);
42746           *   ellipse(20, 20, 20, 20);
42747           *   x += 0.1;
42748           * }
42749           * </code>
42750           * </div>
42751           *
42752           */ _main.default.prototype.textOutput = function(display) {
42753            _main.default._validateParameters('textOutput', arguments);
42754            //if textOutput is already true
42755            if (this._accessibleOutputs.text) {
42756              return;
42757            } else {
42758              //make textOutput true
42759              this._accessibleOutputs.text = true;
42760              //create output for fallback
42761              this._createOutput('textOutput', 'Fallback');
42762              if (display === this.LABEL) {
42763                //make textOutput label true
42764                this._accessibleOutputs.textLabel = true;
42765                //create output for label
42766                this._createOutput('textOutput', 'Label');
42767              }
42768            }
42769          };
42770
42771          /**
42772           * <code class="language-javascript">gridOutput()</code> lays out the
42773           * content of the canvas in the form of a grid (html table) based
42774           * on the spatial location of each shape. A brief
42775           * description of the canvas is available before the table output.
42776           * This description includes: color of the background, size of the canvas,
42777           * number of objects, and object types (example: "lavender blue canvas is
42778           * 200 by 200 and contains 4 objects - 3 ellipses 1 rectangle"). The grid
42779           * describes the content spatially, each element is placed on a cell of the
42780           * table depending on its position. Within each cell an element the color
42781           * and type of shape of that element are available (example: "orange ellipse").
42782           * These descriptions can be selected individually to get more details.
42783           * A list of elements where shape, color, location, and area are described
42784           * (example: "orange ellipse location=top left area=1%") is also available.
42785           *
42786           * <code class="language-javascript">gridOutput()</code> and <code class="language-javascript">gridOutput(FALLBACK)</code>
42787           * make the output available in <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility" target="_blank">
42788           * a sub DOM inside the canvas element</a> which is accessible to screen readers.
42789           * <code class="language-javascript">gridOutput(LABEL)</code> creates an
42790           * additional div with the output adjacent to the canvas, this is useful
42791           * for non-screen reader users that might want to display the output outside
42792           * of the canvas' sub DOM as they code. However, using LABEL will create
42793           * unnecessary redundancy for screen reader users. We recommend using LABEL
42794           * only as part of the development process of a sketch and removing it before
42795           * publishing or sharing with screen reader users.
42796           *
42797           * @method gridOutput
42798           * @param  {Constant} [display] either FALLBACK or LABEL (Optional)
42799           *
42800           * @example
42801           * <div>
42802           * <code>
42803           * gridOutput();
42804           * background(148, 196, 0);
42805           * fill(255, 0, 0);
42806           * ellipse(20, 20, 20, 20);
42807           * fill(0, 0, 255);
42808           * rect(50, 50, 50, 50);
42809           * </code>
42810           * </div>
42811           *
42812           *
42813           * <div>
42814           * <code>
42815           * let x = 0;
42816           * function draw() {
42817           *   gridOutput();
42818           *   background(148, 196, 0);
42819           *   fill(255, 0, 0);
42820           *   ellipse(x, 20, 20, 20);
42821           *   fill(0, 0, 255);
42822           *   rect(50, 50, 50, 50);
42823           *   ellipse(20, 20, 20, 20);
42824           *   x += 0.1;
42825           * }
42826           * </code>
42827           * </div>
42828           *
42829           */
42830
42831          _main.default.prototype.gridOutput = function(display) {
42832            _main.default._validateParameters('gridOutput', arguments);
42833            //if gridOutput is already true
42834            if (this._accessibleOutputs.grid) {
42835              return;
42836            } else {
42837              //make gridOutput true
42838              this._accessibleOutputs.grid = true;
42839              //create output for fallback
42840              this._createOutput('gridOutput', 'Fallback');
42841              if (display === this.LABEL) {
42842                //make gridOutput label true
42843                this._accessibleOutputs.gridLabel = true;
42844                //create output for label
42845                this._createOutput('gridOutput', 'Label');
42846              }
42847            }
42848          };
42849
42850          //helper function returns true when accessible outputs are true
42851          _main.default.prototype._addAccsOutput = function() {
42852            //if there are no accessible outputs create object with all false
42853            if (!this._accessibleOutputs) {
42854              this._accessibleOutputs = {
42855                text: false,
42856                grid: false,
42857                textLabel: false,
42858                gridLabel: false
42859              };
42860            }
42861            return this._accessibleOutputs.grid || this._accessibleOutputs.text;
42862          };
42863
42864          //helper function that creates html structure for accessible outputs
42865          _main.default.prototype._createOutput = function(type, display) {
42866            var cnvId = this.canvas.id;
42867            //if there are no ingredients create object. this object stores data for the outputs
42868            if (!this.ingredients) {
42869              this.ingredients = {
42870                shapes: {},
42871                colors: { background: 'white', fill: 'white', stroke: 'black' },
42872                pShapes: ''
42873              };
42874            }
42875            //if there is no dummyDOM create it
42876            if (!this.dummyDOM) {
42877              this.dummyDOM = document.getElementById(cnvId).parentNode;
42878            }
42879            var cIdT, container, inner;
42880            var query = '';
42881            if (display === 'Fallback') {
42882              cIdT = cnvId + type;
42883              container = cnvId + 'accessibleOutput';
42884              if (!this.dummyDOM.querySelector('#'.concat(container))) {
42885                //if there is no canvas description (see describe() and describeElement())
42886                if (!this.dummyDOM.querySelector('#'.concat(cnvId, '_Description'))) {
42887                  //create html structure inside of canvas
42888                  this.dummyDOM.querySelector(
42889                    '#'.concat(cnvId)
42890                  ).innerHTML = '<div id="'.concat(
42891                    container,
42892                    '" role="region" aria-label="Canvas Outputs"></div>'
42893                  );
42894                } else {
42895                  //create html structure after canvas description container
42896                  this.dummyDOM
42897                    .querySelector('#'.concat(cnvId, '_Description'))
42898                    .insertAdjacentHTML(
42899                      'afterend',
42900                      '<div id="'.concat(
42901                        container,
42902                        '" role="region" aria-label="Canvas Outputs"></div>'
42903                      )
42904                    );
42905                }
42906              }
42907            } else if (display === 'Label') {
42908              query = display;
42909              cIdT = cnvId + type + display;
42910              container = cnvId + 'accessibleOutput' + display;
42911              if (!this.dummyDOM.querySelector('#'.concat(container))) {
42912                //if there is no canvas description label (see describe() and describeElement())
42913                if (!this.dummyDOM.querySelector('#'.concat(cnvId, '_Label'))) {
42914                  //create html structure adjacent to canvas
42915                  this.dummyDOM
42916                    .querySelector('#'.concat(cnvId))
42917                    .insertAdjacentHTML(
42918                      'afterend',
42919                      '<div id="'.concat(container, '"></div>')
42920                    );
42921                } else {
42922                  //create html structure after canvas label
42923                  this.dummyDOM
42924                    .querySelector('#'.concat(cnvId, '_Label'))
42925                    .insertAdjacentHTML(
42926                      'afterend',
42927                      '<div id="'.concat(container, '"></div>')
42928                    );
42929                }
42930              }
42931            }
42932            //create an object to store the latest output. this object is used in _updateTextOutput() and _updateGridOutput()
42933            this._accessibleOutputs[cIdT] = {};
42934            if (type === 'textOutput') {
42935              query = '#'.concat(cnvId, 'gridOutput').concat(query); //query is used to check if gridOutput already exists
42936              inner = '<div id="'
42937                .concat(cIdT, '">Text Output<div id="')
42938                .concat(cIdT, 'Summary" aria-label="text output summary"><p id="')
42939                .concat(cIdT, '_summary"></p><ul id="')
42940                .concat(cIdT, '_list"></ul></div><table id="')
42941                .concat(
42942                  cIdT,
42943                  '_shapeDetails" summary="text output shape details"></table></div>'
42944                );
42945              //if gridOutput already exists
42946              if (this.dummyDOM.querySelector(query)) {
42947                //create textOutput before gridOutput
42948                this.dummyDOM.querySelector(query).insertAdjacentHTML('beforebegin', inner);
42949              } else {
42950                //create output inside of container
42951                this.dummyDOM.querySelector('#'.concat(container)).innerHTML = inner;
42952              }
42953              //store output html elements
42954              this._accessibleOutputs[cIdT].list = this.dummyDOM.querySelector(
42955                '#'.concat(cIdT, '_list')
42956              );
42957            } else if (type === 'gridOutput') {
42958              query = '#'.concat(cnvId, 'textOutput').concat(query); //query is used to check if textOutput already exists
42959              inner = '<div id="'
42960                .concat(cIdT, '">Grid Output<p id="')
42961                .concat(cIdT, '_summary" aria-label="grid output summary"><table id="')
42962                .concat(cIdT, '_map" summary="grid output content"></table><ul id="')
42963                .concat(
42964                  cIdT,
42965                  '_shapeDetails" aria-label="grid output shape details"></ul></div>'
42966                );
42967              //if textOutput already exists
42968              if (this.dummyDOM.querySelector(query)) {
42969                //create gridOutput after textOutput
42970                this.dummyDOM.querySelector(query).insertAdjacentHTML('afterend', inner);
42971              } else {
42972                //create output inside of container
42973                this.dummyDOM.querySelector('#'.concat(container)).innerHTML = inner;
42974              }
42975              //store output html elements
42976              this._accessibleOutputs[cIdT].map = this.dummyDOM.querySelector(
42977                '#'.concat(cIdT, '_map')
42978              );
42979            }
42980            this._accessibleOutputs[cIdT].shapeDetails = this.dummyDOM.querySelector(
42981              '#'.concat(cIdT, '_shapeDetails')
42982            );
42983
42984            this._accessibleOutputs[cIdT].summary = this.dummyDOM.querySelector(
42985              '#'.concat(cIdT, '_summary')
42986            );
42987          };
42988
42989          //this function is called at the end of setup and draw if using
42990          //accessibleOutputs and calls update functions of outputs
42991          _main.default.prototype._updateAccsOutput = function() {
42992            var cnvId = this.canvas.id;
42993            //if the shapes are not the same as before
42994            if (JSON.stringify(this.ingredients.shapes) !== this.ingredients.pShapes) {
42995              //save current shapes as string in pShapes
42996              this.ingredients.pShapes = JSON.stringify(this.ingredients.shapes);
42997              if (this._accessibleOutputs.text) {
42998                this._updateTextOutput(cnvId + 'textOutput');
42999              }
43000              if (this._accessibleOutputs.grid) {
43001                this._updateGridOutput(cnvId + 'gridOutput');
43002              }
43003              if (this._accessibleOutputs.textLabel) {
43004                this._updateTextOutput(cnvId + 'textOutputLabel');
43005              }
43006              if (this._accessibleOutputs.gridLabel) {
43007                this._updateGridOutput(cnvId + 'gridOutputLabel');
43008              }
43009            }
43010          };
43011
43012          //helper function that resets all ingredients when background is called
43013          //and saves background color name
43014          _main.default.prototype._accsBackground = function(args) {
43015            //save current shapes as string in pShapes
43016            this.ingredients.pShapes = JSON.stringify(this.ingredients.shapes);
43017            //empty shapes JSON
43018            this.ingredients.shapes = {};
43019            //update background different
43020            if (this.ingredients.colors.backgroundRGBA !== args) {
43021              this.ingredients.colors.backgroundRGBA = args;
43022              this.ingredients.colors.background = this._rgbColorName(args);
43023            }
43024          };
43025
43026          //helper function that gets fill and stroke of shapes
43027          _main.default.prototype._accsCanvasColors = function(f, args) {
43028            if (f === 'fill') {
43029              //update fill different
43030              if (this.ingredients.colors.fillRGBA !== args) {
43031                this.ingredients.colors.fillRGBA = args;
43032                this.ingredients.colors.fill = this._rgbColorName(args);
43033              }
43034            } else if (f === 'stroke') {
43035              //update stroke if different
43036              if (this.ingredients.colors.strokeRGBA !== args) {
43037                this.ingredients.colors.strokeRGBA = args;
43038                this.ingredients.colors.stroke = this._rgbColorName(args);
43039              }
43040            }
43041          };
43042
43043          //builds ingredients.shapes used for building outputs
43044          _main.default.prototype._accsOutput = function(f, args) {
43045            if (f === 'ellipse' && args[2] === args[3]) {
43046              f = 'circle';
43047            } else if (f === 'rectangle' && args[2] === args[3]) {
43048              f = 'square';
43049            }
43050            var include = {};
43051            var add = true;
43052            var middle = _getMiddle(f, args);
43053            if (f === 'line') {
43054              //make color stroke
43055              include.color = this.ingredients.colors.stroke;
43056              //get lenght
43057              include.length = Math.round(this.dist(args[0], args[1], args[2], args[3]));
43058              //get position of end points
43059              var p1 = _getPos([args[0], [1]], this.width, this.height);
43060              var p2 = _getPos([args[2], [3]], this.width, this.height);
43061              include.loc = _canvasLocator(middle, this.width, this.height);
43062              if (p1 === p2) {
43063                include.pos = 'at '.concat(p1);
43064              } else {
43065                include.pos = 'from '.concat(p1, ' to ').concat(p2);
43066              }
43067            } else {
43068              if (f === 'point') {
43069                //make color stroke
43070                include.color = this.ingredients.colors.stroke;
43071              } else {
43072                //make color fill
43073                include.color = this.ingredients.colors.fill;
43074                //get area of shape
43075                include.area = _getArea(f, args, this.width, this.height);
43076              }
43077              //get middle of shapes
43078              //calculate position using middle of shape
43079              include.pos = _getPos(middle, this.width, this.height);
43080              //calculate location using middle of shape
43081              include.loc = _canvasLocator(middle, this.width, this.height);
43082            }
43083            //if it is the first time this shape is created
43084            if (!this.ingredients.shapes[f]) {
43085              this.ingredients.shapes[f] = [include];
43086              //if other shapes of this type have been created
43087            } else if (this.ingredients.shapes[f] !== [include]) {
43088              //for every shape of this type
43089              for (var y in this.ingredients.shapes[f]) {
43090                //compare it with current shape and if it already exists make add false
43091                if (
43092                  JSON.stringify(this.ingredients.shapes[f][y]) === JSON.stringify(include)
43093                ) {
43094                  add = false;
43095                }
43096              }
43097              //add shape by pushing it to the end
43098              if (add === true) {
43099                this.ingredients.shapes[f].push(include);
43100              }
43101            }
43102          };
43103
43104          //gets middle point / centroid of shape
43105          function _getMiddle(f, args) {
43106            var x, y;
43107            if (
43108              f === 'rectangle' ||
43109              f === 'ellipse' ||
43110              f === 'arc' ||
43111              f === 'circle' ||
43112              f === 'square'
43113            ) {
43114              x = Math.round(args[0] + args[2] / 2);
43115              y = Math.round(args[1] + args[3] / 2);
43116            } else if (f === 'triangle') {
43117              x = (args[0] + args[2] + args[4]) / 3;
43118              y = (args[1] + args[3] + args[5]) / 3;
43119            } else if (f === 'quadrilateral') {
43120              x = (args[0] + args[2] + args[4] + args[6]) / 4;
43121              y = (args[1] + args[3] + args[5] + args[7]) / 4;
43122            } else if (f === 'line') {
43123              x = (args[0] + args[2]) / 2;
43124              y = (args[1] + args[3]) / 2;
43125            } else {
43126              x = args[0];
43127              y = args[1];
43128            }
43129            return [x, y];
43130          }
43131
43132          //gets position of shape in the canvas
43133          function _getPos(args, canvasWidth, canvasHeight) {
43134            if (args[0] < 0.4 * canvasWidth) {
43135              if (args[1] < 0.4 * canvasHeight) {
43136                return 'top left';
43137              } else if (args[1] > 0.6 * canvasHeight) {
43138                return 'bottom left';
43139              } else {
43140                return 'mid left';
43141              }
43142            } else if (args[0] > 0.6 * canvasWidth) {
43143              if (args[1] < 0.4 * canvasHeight) {
43144                return 'top right';
43145              } else if (args[1] > 0.6 * canvasHeight) {
43146                return 'bottom right';
43147              } else {
43148                return 'mid right';
43149              }
43150            } else {
43151              if (args[1] < 0.4 * canvasHeight) {
43152                return 'top middle';
43153              } else if (args[1] > 0.6 * canvasHeight) {
43154                return 'bottom middle';
43155              } else {
43156                return 'middle';
43157              }
43158            }
43159          }
43160
43161          //locates shape in a 10*10 grid
43162          function _canvasLocator(args, canvasWidth, canvasHeight) {
43163            var noRows = 10;
43164            var noCols = 10;
43165            var locX = Math.floor(args[0] / canvasWidth * noRows);
43166            var locY = Math.floor(args[1] / canvasHeight * noCols);
43167            if (locX === noRows) {
43168              locX = locX - 1;
43169            }
43170            if (locY === noCols) {
43171              locY = locY - 1;
43172            }
43173            return {
43174              locX: locX,
43175              locY: locY
43176            };
43177          }
43178
43179          //calculates area of shape
43180          function _getArea(objectType, shapeArgs, canvasWidth, canvasHeight) {
43181            var objectArea = 0;
43182            if (objectType === 'arc') {
43183              // area of full ellipse = PI * horizontal radius * vertical radius.
43184              // therefore, area of arc = difference bet. arc's start and end radians * horizontal radius * vertical radius.
43185              // the below expression is adjusted for negative values and differences in arc's start and end radians over PI*2
43186              var arcSizeInRadians =
43187                ((shapeArgs[5] - shapeArgs[4]) % (Math.PI * 2) + Math.PI * 2) %
43188                (Math.PI * 2);
43189              objectArea = arcSizeInRadians * shapeArgs[2] * shapeArgs[3] / 8;
43190              if (shapeArgs[6] === 'open' || shapeArgs[6] === 'chord') {
43191                // when the arc's mode is OPEN or CHORD, we need to account for the area of the triangle that is formed to close the arc
43192                // (Ax( By −  Cy) + Bx(Cy − Ay) + Cx(Ay − By ) )/2
43193                var Ax = shapeArgs[0];
43194                var Ay = shapeArgs[1];
43195                var Bx =
43196                  shapeArgs[0] + shapeArgs[2] / 2 * Math.cos(shapeArgs[4]).toFixed(2);
43197                var By =
43198                  shapeArgs[1] + shapeArgs[3] / 2 * Math.sin(shapeArgs[4]).toFixed(2);
43199                var Cx =
43200                  shapeArgs[0] + shapeArgs[2] / 2 * Math.cos(shapeArgs[5]).toFixed(2);
43201                var Cy =
43202                  shapeArgs[1] + shapeArgs[3] / 2 * Math.sin(shapeArgs[5]).toFixed(2);
43203                var areaOfExtraTriangle =
43204                  Math.abs(Ax * (By - Cy) + Bx * (Cy - Ay) + Cx * (Ay - By)) / 2;
43205                if (arcSizeInRadians > Math.PI) {
43206                  objectArea = objectArea + areaOfExtraTriangle;
43207                } else {
43208                  objectArea = objectArea - areaOfExtraTriangle;
43209                }
43210              }
43211            } else if (objectType === 'ellipse' || objectType === 'circle') {
43212              objectArea = 3.14 * shapeArgs[2] / 2 * shapeArgs[3] / 2;
43213            } else if (objectType === 'line') {
43214              objectArea = 0;
43215            } else if (objectType === 'point') {
43216              objectArea = 0;
43217            } else if (objectType === 'quadrilateral') {
43218              // ((x4+x1)*(y4-y1)+(x1+x2)*(y1-y2)+(x2+x3)*(y2-y3)+(x3+x4)*(y3-y4))/2
43219              objectArea =
43220                Math.abs(
43221                  (shapeArgs[6] + shapeArgs[0]) * (shapeArgs[7] - shapeArgs[1]) +
43222                    (shapeArgs[0] + shapeArgs[2]) * (shapeArgs[1] - shapeArgs[3]) +
43223                    (shapeArgs[2] + shapeArgs[4]) * (shapeArgs[3] - shapeArgs[5]) +
43224                    (shapeArgs[4] + shapeArgs[6]) * (shapeArgs[5] - shapeArgs[7])
43225                ) / 2;
43226            } else if (objectType === 'rectangle' || objectType === 'square') {
43227              objectArea = shapeArgs[2] * shapeArgs[3];
43228            } else if (objectType === 'triangle') {
43229              objectArea =
43230                Math.abs(
43231                  shapeArgs[0] * (shapeArgs[3] - shapeArgs[5]) +
43232                    shapeArgs[2] * (shapeArgs[5] - shapeArgs[1]) +
43233                    shapeArgs[4] * (shapeArgs[1] - shapeArgs[3])
43234                ) / 2;
43235              // (Ax( By −  Cy) + Bx(Cy − Ay) + Cx(Ay − By ))/2
43236            }
43237
43238            return Math.round(objectArea * 100 / (canvasWidth * canvasHeight));
43239          }
43240          var _default = _main.default;
43241          exports.default = _default;
43242        },
43243        { '../core/main': 59 }
43244      ],
43245      42: [
43246        function(_dereq_, module, exports) {
43247          'use strict';
43248          Object.defineProperty(exports, '__esModule', { value: true });
43249          exports.default = void 0;
43250
43251          var _main = _interopRequireDefault(_dereq_('../core/main'));
43252          function _interopRequireDefault(obj) {
43253            return obj && obj.__esModule ? obj : { default: obj };
43254          } /** //the functions in this file support updating the text output
43255           * @module Environment
43256           * @submodule Environment
43257           * @for p5
43258           * @requires core
43259           */
43260          //updates textOutput
43261          _main.default.prototype._updateTextOutput = function(idT) {
43262            //if html structure is not there yet
43263            if (!this.dummyDOM.querySelector('#'.concat(idT, '_summary'))) {
43264              return;
43265            }
43266            var current = this._accessibleOutputs[idT];
43267            //create shape list
43268            var innerList = _shapeList(idT, this.ingredients.shapes);
43269            //create output summary
43270            var innerSummary = _textSummary(
43271              innerList.numShapes,
43272              this.ingredients.colors.background,
43273              this.width,
43274              this.height
43275            );
43276
43277            //create shape details
43278            var innerShapeDetails = _shapeDetails(idT, this.ingredients.shapes);
43279            //if it is different from current summary
43280            if (innerSummary !== current.summary.innerHTML) {
43281              //update
43282              current.summary.innerHTML = innerSummary;
43283            }
43284            //if it is different from current shape list
43285            if (innerList.listShapes !== current.list.innerHTML) {
43286              //update
43287              current.list.innerHTML = innerList.listShapes;
43288            }
43289            //if it is different from current shape details
43290            if (innerShapeDetails !== current.shapeDetails.innerHTML) {
43291              //update
43292              current.shapeDetails.innerHTML = innerShapeDetails;
43293            }
43294            this._accessibleOutputs[idT] = current;
43295          };
43296
43297          //Builds textOutput summary
43298          function _textSummary(numShapes, background, width, height) {
43299            var text = 'Your output is a, '
43300              .concat(width, ' by ')
43301              .concat(height, ' pixels, ')
43302              .concat(background, ' canvas containing the following');
43303            if (numShapes === 1) {
43304              text = ''.concat(text, ' shape:');
43305            } else {
43306              text = ''.concat(text, ' ').concat(numShapes, ' shapes:');
43307            }
43308            return text;
43309          }
43310
43311          //Builds textOutput table with shape details
43312          function _shapeDetails(idT, ingredients) {
43313            var shapeDetails = '';
43314            var shapeNumber = 0;
43315            //goes trhough every shape type in ingredients
43316            for (var x in ingredients) {
43317              //and for every shape
43318              for (var y in ingredients[x]) {
43319                //it creates a table row
43320                var row = '<tr id="'
43321                  .concat(idT, 'shape')
43322                  .concat(shapeNumber, '"><th>')
43323                  .concat(ingredients[x][y].color, ' ')
43324                  .concat(x, '</th>');
43325                if (x === 'line') {
43326                  row =
43327                    row +
43328                    '<td>location = '
43329                      .concat(ingredients[x][y].pos, '</td><td>length = ')
43330                      .concat(ingredients[x][y].length, ' pixels</td></tr>');
43331                } else {
43332                  row = row + '<td>location = '.concat(ingredients[x][y].pos, '</td>');
43333                  if (x !== 'point') {
43334                    row = row + '<td> area = '.concat(ingredients[x][y].area, '%</td>');
43335                  }
43336                  row = row + '</tr>';
43337                }
43338                shapeDetails = shapeDetails + row;
43339                shapeNumber++;
43340              }
43341            }
43342            return shapeDetails;
43343          }
43344
43345          //Builds textOutput shape list
43346          function _shapeList(idT, ingredients) {
43347            var shapeList = '';
43348            var shapeNumber = 0;
43349            //goes trhough every shape type in ingredients
43350            for (var x in ingredients) {
43351              for (var y in ingredients[x]) {
43352                //it creates a line in a list
43353                var _line = '<li><a href="#'
43354                  .concat(idT, 'shape')
43355                  .concat(shapeNumber, '">')
43356                  .concat(ingredients[x][y].color, ' ')
43357                  .concat(x, '</a>');
43358                if (x === 'line') {
43359                  _line =
43360                    _line +
43361                    ', '
43362                      .concat(ingredients[x][y].pos, ', ')
43363                      .concat(ingredients[x][y].length, ' pixels long.</li>');
43364                } else {
43365                  _line = _line + ', at '.concat(ingredients[x][y].pos);
43366                  if (x !== 'point') {
43367                    _line =
43368                      _line +
43369                      ', covering '.concat(ingredients[x][y].area, '% of the canvas');
43370                  }
43371                  _line = _line + '.</li>';
43372                }
43373                shapeList = shapeList + _line;
43374                shapeNumber++;
43375              }
43376            }
43377            return { numShapes: shapeNumber, listShapes: shapeList };
43378          }
43379          var _default = _main.default;
43380          exports.default = _default;
43381        },
43382        { '../core/main': 59 }
43383      ],
43384      43: [
43385        function(_dereq_, module, exports) {
43386          'use strict';
43387          var _main = _interopRequireDefault(_dereq_('./core/main'));
43388          _dereq_('./core/constants');
43389          _dereq_('./core/environment');
43390          _dereq_('./core/friendly_errors/stacktrace');
43391          _dereq_('./core/friendly_errors/validate_params');
43392          _dereq_('./core/friendly_errors/file_errors');
43393          _dereq_('./core/friendly_errors/fes_core');
43394          _dereq_('./core/helpers');
43395          _dereq_('./core/legacy');
43396          _dereq_('./core/preload');
43397          _dereq_('./core/p5.Element');
43398          _dereq_('./core/p5.Graphics');
43399          _dereq_('./core/p5.Renderer');
43400          _dereq_('./core/p5.Renderer2D');
43401          _dereq_('./core/rendering');
43402          _dereq_('./core/shim');
43403          _dereq_('./core/structure');
43404          _dereq_('./core/transform');
43405          _dereq_('./core/shape/2d_primitives');
43406          _dereq_('./core/shape/attributes');
43407          _dereq_('./core/shape/curves');
43408          _dereq_('./core/shape/vertex');
43409
43410          _dereq_('./accessibility/outputs');
43411          _dereq_('./accessibility/textOutput');
43412          _dereq_('./accessibility/gridOutput');
43413          _dereq_('./accessibility/color_namer');
43414
43415          _dereq_('./color/color_conversion');
43416          _dereq_('./color/creating_reading');
43417          _dereq_('./color/p5.Color');
43418          _dereq_('./color/setting');
43419
43420          _dereq_('./data/p5.TypedDict');
43421          _dereq_('./data/local_storage.js');
43422
43423          _dereq_('./dom/dom');
43424
43425          _dereq_('./accessibility/describe');
43426
43427          _dereq_('./events/acceleration');
43428          _dereq_('./events/keyboard');
43429          _dereq_('./events/mouse');
43430          _dereq_('./events/touch');
43431
43432          _dereq_('./image/filters');
43433          _dereq_('./image/image');
43434          _dereq_('./image/loading_displaying');
43435          _dereq_('./image/p5.Image');
43436          _dereq_('./image/pixels');
43437
43438          _dereq_('./io/files');
43439          _dereq_('./io/p5.Table');
43440          _dereq_('./io/p5.TableRow');
43441          _dereq_('./io/p5.XML');
43442
43443          _dereq_('./math/calculation');
43444          _dereq_('./math/math');
43445          _dereq_('./math/noise');
43446          _dereq_('./math/p5.Vector');
43447          _dereq_('./math/random');
43448          _dereq_('./math/trigonometry');
43449
43450          _dereq_('./typography/attributes');
43451          _dereq_('./typography/loading_displaying');
43452          _dereq_('./typography/p5.Font');
43453
43454          _dereq_('./utilities/array_functions');
43455          _dereq_('./utilities/conversion');
43456          _dereq_('./utilities/string_functions');
43457          _dereq_('./utilities/time_date');
43458
43459          _dereq_('./webgl/3d_primitives');
43460          _dereq_('./webgl/interaction');
43461          _dereq_('./webgl/light');
43462          _dereq_('./webgl/loading');
43463          _dereq_('./webgl/material');
43464          _dereq_('./webgl/p5.Camera');
43465          _dereq_('./webgl/p5.Geometry');
43466          _dereq_('./webgl/p5.Matrix');
43467          _dereq_('./webgl/p5.RendererGL.Immediate');
43468          _dereq_('./webgl/p5.RendererGL');
43469          _dereq_('./webgl/p5.RendererGL.Retained');
43470          _dereq_('./webgl/p5.Shader');
43471          _dereq_('./webgl/p5.RenderBuffer');
43472          _dereq_('./webgl/p5.Texture');
43473          _dereq_('./webgl/text');
43474
43475          _dereq_('./core/init');
43476          function _interopRequireDefault(obj) {
43477            return obj && obj.__esModule ? obj : { default: obj };
43478          } // core
43479          //accessibility
43480          // color
43481          // data
43482          // DOM
43483          // accessibility
43484          // events
43485          // image
43486          // io
43487          // math
43488          // typography
43489          // utilities
43490          // webgl
43491          module.exports = _main.default;
43492        },
43493        {
43494          './accessibility/color_namer': 38,
43495          './accessibility/describe': 39,
43496          './accessibility/gridOutput': 40,
43497          './accessibility/outputs': 41,
43498          './accessibility/textOutput': 42,
43499          './color/color_conversion': 44,
43500          './color/creating_reading': 45,
43501          './color/p5.Color': 46,
43502          './color/setting': 47,
43503          './core/constants': 48,
43504          './core/environment': 49,
43505          './core/friendly_errors/fes_core': 51,
43506          './core/friendly_errors/file_errors': 52,
43507          './core/friendly_errors/stacktrace': 53,
43508          './core/friendly_errors/validate_params': 54,
43509          './core/helpers': 55,
43510          './core/init': 56,
43511          './core/legacy': 58,
43512          './core/main': 59,
43513          './core/p5.Element': 60,
43514          './core/p5.Graphics': 61,
43515          './core/p5.Renderer': 62,
43516          './core/p5.Renderer2D': 63,
43517          './core/preload': 64,
43518          './core/rendering': 65,
43519          './core/shape/2d_primitives': 66,
43520          './core/shape/attributes': 67,
43521          './core/shape/curves': 68,
43522          './core/shape/vertex': 69,
43523          './core/shim': 70,
43524          './core/structure': 71,
43525          './core/transform': 72,
43526          './data/local_storage.js': 73,
43527          './data/p5.TypedDict': 74,
43528          './dom/dom': 75,
43529          './events/acceleration': 76,
43530          './events/keyboard': 77,
43531          './events/mouse': 78,
43532          './events/touch': 79,
43533          './image/filters': 80,
43534          './image/image': 81,
43535          './image/loading_displaying': 82,
43536          './image/p5.Image': 83,
43537          './image/pixels': 84,
43538          './io/files': 85,
43539          './io/p5.Table': 86,
43540          './io/p5.TableRow': 87,
43541          './io/p5.XML': 88,
43542          './math/calculation': 89,
43543          './math/math': 90,
43544          './math/noise': 91,
43545          './math/p5.Vector': 92,
43546          './math/random': 93,
43547          './math/trigonometry': 94,
43548          './typography/attributes': 95,
43549          './typography/loading_displaying': 96,
43550          './typography/p5.Font': 97,
43551          './utilities/array_functions': 98,
43552          './utilities/conversion': 99,
43553          './utilities/string_functions': 100,
43554          './utilities/time_date': 101,
43555          './webgl/3d_primitives': 102,
43556          './webgl/interaction': 103,
43557          './webgl/light': 104,
43558          './webgl/loading': 105,
43559          './webgl/material': 106,
43560          './webgl/p5.Camera': 107,
43561          './webgl/p5.Geometry': 108,
43562          './webgl/p5.Matrix': 109,
43563          './webgl/p5.RenderBuffer': 110,
43564          './webgl/p5.RendererGL': 113,
43565          './webgl/p5.RendererGL.Immediate': 111,
43566          './webgl/p5.RendererGL.Retained': 112,
43567          './webgl/p5.Shader': 114,
43568          './webgl/p5.Texture': 115,
43569          './webgl/text': 116
43570        }
43571      ],
43572      44: [
43573        function(_dereq_, module, exports) {
43574          'use strict';
43575          Object.defineProperty(exports, '__esModule', { value: true });
43576          exports.default = void 0;
43577
43578          var _main = _interopRequireDefault(_dereq_('../core/main'));
43579          function _interopRequireDefault(obj) {
43580            return obj && obj.__esModule ? obj : { default: obj };
43581          }
43582          /**
43583           * @module Color
43584           * @submodule Color Conversion
43585           * @for p5
43586           * @requires core
43587           */ /**
43588           * Conversions adapted from <http://www.easyrgb.com/en/math.php>.
43589           *
43590           * In these functions, hue is always in the range [0, 1], just like all other
43591           * components are in the range [0, 1]. 'Brightness' and 'value' are used
43592           * interchangeably.
43593           */ _main.default.ColorConversion = {};
43594          /**
43595           * Convert an HSBA array to HSLA.
43596           */ _main.default.ColorConversion._hsbaToHSLA = function(hsba) {
43597            var hue = hsba[0];
43598            var sat = hsba[1];
43599            var val = hsba[2]; // Calculate lightness.
43600            var li = (2 - sat) * val / 2; // Convert saturation.
43601            if (li !== 0) {
43602              if (li === 1) {
43603                sat = 0;
43604              } else if (li < 0.5) {
43605                sat = sat / (2 - sat);
43606              } else {
43607                sat = sat * val / (2 - li * 2);
43608              }
43609            }
43610
43611            // Hue and alpha stay the same.
43612            return [hue, sat, li, hsba[3]];
43613          };
43614
43615          /**
43616           * Convert an HSBA array to RGBA.
43617           */
43618          _main.default.ColorConversion._hsbaToRGBA = function(hsba) {
43619            var hue = hsba[0] * 6; // We will split hue into 6 sectors.
43620            var sat = hsba[1];
43621            var val = hsba[2];
43622
43623            var RGBA = [];
43624
43625            if (sat === 0) {
43626              RGBA = [val, val, val, hsba[3]]; // Return early if grayscale.
43627            } else {
43628              var sector = Math.floor(hue);
43629              var tint1 = val * (1 - sat);
43630              var tint2 = val * (1 - sat * (hue - sector));
43631              var tint3 = val * (1 - sat * (1 + sector - hue));
43632              var red, green, blue;
43633              if (sector === 1) {
43634                // Yellow to green.
43635                red = tint2;
43636                green = val;
43637                blue = tint1;
43638              } else if (sector === 2) {
43639                // Green to cyan.
43640                red = tint1;
43641                green = val;
43642                blue = tint3;
43643              } else if (sector === 3) {
43644                // Cyan to blue.
43645                red = tint1;
43646                green = tint2;
43647                blue = val;
43648              } else if (sector === 4) {
43649                // Blue to magenta.
43650                red = tint3;
43651                green = tint1;
43652                blue = val;
43653              } else if (sector === 5) {
43654                // Magenta to red.
43655                red = val;
43656                green = tint1;
43657                blue = tint2;
43658              } else {
43659                // Red to yellow (sector could be 0 or 6).
43660                red = val;
43661                green = tint3;
43662                blue = tint1;
43663              }
43664              RGBA = [red, green, blue, hsba[3]];
43665            }
43666
43667            return RGBA;
43668          };
43669
43670          /**
43671           * Convert an HSLA array to HSBA.
43672           */
43673          _main.default.ColorConversion._hslaToHSBA = function(hsla) {
43674            var hue = hsla[0];
43675            var sat = hsla[1];
43676            var li = hsla[2];
43677
43678            // Calculate brightness.
43679            var val;
43680            if (li < 0.5) {
43681              val = (1 + sat) * li;
43682            } else {
43683              val = li + sat - li * sat;
43684            }
43685
43686            // Convert saturation.
43687            sat = 2 * (val - li) / val;
43688
43689            // Hue and alpha stay the same.
43690            return [hue, sat, val, hsla[3]];
43691          };
43692
43693          /**
43694           * Convert an HSLA array to RGBA.
43695           *
43696           * We need to change basis from HSLA to something that can be more easily be
43697           * projected onto RGBA. We will choose hue and brightness as our first two
43698           * components, and pick a convenient third one ('zest') so that we don't need
43699           * to calculate formal HSBA saturation.
43700           */
43701          _main.default.ColorConversion._hslaToRGBA = function(hsla) {
43702            var hue = hsla[0] * 6; // We will split hue into 6 sectors.
43703            var sat = hsla[1];
43704            var li = hsla[2];
43705
43706            var RGBA = [];
43707
43708            if (sat === 0) {
43709              RGBA = [li, li, li, hsla[3]]; // Return early if grayscale.
43710            } else {
43711              // Calculate brightness.
43712              var val;
43713              if (li < 0.5) {
43714                val = (1 + sat) * li;
43715              } else {
43716                val = li + sat - li * sat;
43717              }
43718
43719              // Define zest.
43720              var zest = 2 * li - val;
43721
43722              // Implement projection (project onto green by default).
43723              var hzvToRGB = function hzvToRGB(hue, zest, val) {
43724                if (hue < 0) {
43725                  // Hue must wrap to allow projection onto red and blue.
43726                  hue += 6;
43727                } else if (hue >= 6) {
43728                  hue -= 6;
43729                }
43730                if (hue < 1) {
43731                  // Red to yellow (increasing green).
43732                  return zest + (val - zest) * hue;
43733                } else if (hue < 3) {
43734                  // Yellow to cyan (greatest green).
43735                  return val;
43736                } else if (hue < 4) {
43737                  // Cyan to blue (decreasing green).
43738                  return zest + (val - zest) * (4 - hue);
43739                } else {
43740                  // Blue to red (least green).
43741                  return zest;
43742                }
43743              };
43744
43745              // Perform projections, offsetting hue as necessary.
43746              RGBA = [
43747                hzvToRGB(hue + 2, zest, val),
43748                hzvToRGB(hue, zest, val),
43749                hzvToRGB(hue - 2, zest, val),
43750                hsla[3]
43751              ];
43752            }
43753
43754            return RGBA;
43755          };
43756
43757          /**
43758           * Convert an RGBA array to HSBA.
43759           */
43760          _main.default.ColorConversion._rgbaToHSBA = function(rgba) {
43761            var red = rgba[0];
43762            var green = rgba[1];
43763            var blue = rgba[2];
43764
43765            var val = Math.max(red, green, blue);
43766            var chroma = val - Math.min(red, green, blue);
43767
43768            var hue, sat;
43769            if (chroma === 0) {
43770              // Return early if grayscale.
43771              hue = 0;
43772              sat = 0;
43773            } else {
43774              sat = chroma / val;
43775              if (red === val) {
43776                // Magenta to yellow.
43777                hue = (green - blue) / chroma;
43778              } else if (green === val) {
43779                // Yellow to cyan.
43780                hue = 2 + (blue - red) / chroma;
43781              } else if (blue === val) {
43782                // Cyan to magenta.
43783                hue = 4 + (red - green) / chroma;
43784              }
43785              if (hue < 0) {
43786                // Confine hue to the interval [0, 1).
43787                hue += 6;
43788              } else if (hue >= 6) {
43789                hue -= 6;
43790              }
43791            }
43792
43793            return [hue / 6, sat, val, rgba[3]];
43794          };
43795
43796          /**
43797           * Convert an RGBA array to HSLA.
43798           */
43799          _main.default.ColorConversion._rgbaToHSLA = function(rgba) {
43800            var red = rgba[0];
43801            var green = rgba[1];
43802            var blue = rgba[2];
43803
43804            var val = Math.max(red, green, blue);
43805            var min = Math.min(red, green, blue);
43806            var li = val + min; // We will halve this later.
43807            var chroma = val - min;
43808
43809            var hue, sat;
43810            if (chroma === 0) {
43811              // Return early if grayscale.
43812              hue = 0;
43813              sat = 0;
43814            } else {
43815              if (li < 1) {
43816                sat = chroma / li;
43817              } else {
43818                sat = chroma / (2 - li);
43819              }
43820              if (red === val) {
43821                // Magenta to yellow.
43822                hue = (green - blue) / chroma;
43823              } else if (green === val) {
43824                // Yellow to cyan.
43825                hue = 2 + (blue - red) / chroma;
43826              } else if (blue === val) {
43827                // Cyan to magenta.
43828                hue = 4 + (red - green) / chroma;
43829              }
43830              if (hue < 0) {
43831                // Confine hue to the interval [0, 1).
43832                hue += 6;
43833              } else if (hue >= 6) {
43834                hue -= 6;
43835              }
43836            }
43837
43838            return [hue / 6, sat, li / 2, rgba[3]];
43839          };
43840          var _default = _main.default.ColorConversion;
43841          exports.default = _default;
43842        },
43843        { '../core/main': 59 }
43844      ],
43845      45: [
43846        function(_dereq_, module, exports) {
43847          'use strict';
43848          function _typeof(obj) {
43849            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
43850              _typeof = function _typeof(obj) {
43851                return typeof obj;
43852              };
43853            } else {
43854              _typeof = function _typeof(obj) {
43855                return obj &&
43856                  typeof Symbol === 'function' &&
43857                  obj.constructor === Symbol &&
43858                  obj !== Symbol.prototype
43859                  ? 'symbol'
43860                  : typeof obj;
43861              };
43862            }
43863            return _typeof(obj);
43864          }
43865          Object.defineProperty(exports, '__esModule', { value: true });
43866          exports.default = void 0;
43867
43868          var _main = _interopRequireDefault(_dereq_('../core/main'));
43869          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
43870          _dereq_('./p5.Color');
43871          _dereq_('../core/friendly_errors/validate_params');
43872          _dereq_('../core/friendly_errors/file_errors');
43873          _dereq_('../core/friendly_errors/fes_core');
43874          function _getRequireWildcardCache() {
43875            if (typeof WeakMap !== 'function') return null;
43876            var cache = new WeakMap();
43877            _getRequireWildcardCache = function _getRequireWildcardCache() {
43878              return cache;
43879            };
43880            return cache;
43881          }
43882          function _interopRequireWildcard(obj) {
43883            if (obj && obj.__esModule) {
43884              return obj;
43885            }
43886            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
43887              return { default: obj };
43888            }
43889            var cache = _getRequireWildcardCache();
43890            if (cache && cache.has(obj)) {
43891              return cache.get(obj);
43892            }
43893            var newObj = {};
43894            var hasPropertyDescriptor =
43895              Object.defineProperty && Object.getOwnPropertyDescriptor;
43896            for (var key in obj) {
43897              if (Object.prototype.hasOwnProperty.call(obj, key)) {
43898                var desc = hasPropertyDescriptor
43899                  ? Object.getOwnPropertyDescriptor(obj, key)
43900                  : null;
43901                if (desc && (desc.get || desc.set)) {
43902                  Object.defineProperty(newObj, key, desc);
43903                } else {
43904                  newObj[key] = obj[key];
43905                }
43906              }
43907            }
43908            newObj.default = obj;
43909            if (cache) {
43910              cache.set(obj, newObj);
43911            }
43912            return newObj;
43913          }
43914          function _interopRequireDefault(obj) {
43915            return obj && obj.__esModule ? obj : { default: obj };
43916          }
43917          /**
43918           * @module Color
43919           * @submodule Creating & Reading
43920           * @for p5
43921           * @requires core
43922           * @requires constants
43923           */ /**
43924           * Extracts the alpha value from a color or pixel array.
43925           *
43926           * @method alpha
43927           * @param {p5.Color|Number[]|String} color <a href="#/p5.Color">p5.Color</a> object, color components,
43928           *                                         or CSS color
43929           * @return {Number} the alpha value
43930           *
43931           * @example
43932           * <div>
43933           * <code>
43934           * noStroke();
43935           * let c = color(0, 126, 255, 102);
43936           * fill(c);
43937           * rect(15, 15, 35, 70);
43938           * let value = alpha(c); // Sets 'value' to 102
43939           * fill(value);
43940           * rect(50, 15, 35, 70);
43941           * </code>
43942           * </div>
43943           *
43944           * @alt
43945           * Left half of canvas light blue and right half light charcoal grey.
43946           */ _main.default.prototype.alpha = function(c) {
43947            _main.default._validateParameters('alpha', arguments);
43948            return this.color(c)._getAlpha();
43949          };
43950
43951          /**
43952           * Extracts the blue value from a color or pixel array.
43953           *
43954           * @method blue
43955           * @param {p5.Color|Number[]|String} color <a href="#/p5.Color">p5.Color</a> object, color components,
43956           *                                         or CSS color
43957           * @return {Number} the blue value
43958           * @example
43959           * <div>
43960           * <code>
43961           * let c = color(175, 100, 220);
43962           * fill(c);
43963           * rect(15, 20, 35, 60); // Draw left rectangle
43964           * let blueValue = blue(c);
43965           * fill(0, 0, blueValue);
43966           * rect(50, 20, 35, 60); // Draw right rectangle
43967           * </code>
43968           * </div>
43969           *
43970           * @alt
43971           * Left half of canvas light purple and right half a royal blue.
43972           */
43973          _main.default.prototype.blue = function(c) {
43974            _main.default._validateParameters('blue', arguments);
43975            return this.color(c)._getBlue();
43976          };
43977
43978          /**
43979           * Extracts the HSB brightness value from a color or pixel array.
43980           *
43981           * @method brightness
43982           * @param {p5.Color|Number[]|String} color <a href="#/p5.Color">p5.Color</a> object, color components,
43983           *                                         or CSS color
43984           * @return {Number} the brightness value
43985           *
43986           * @example
43987           * <div>
43988           * <code>
43989           * noStroke();
43990           * colorMode(HSB, 255);
43991           * let c = color(0, 126, 255);
43992           * fill(c);
43993           * rect(15, 20, 35, 60);
43994           * let value = brightness(c); // Sets 'value' to 255
43995           * fill(value);
43996           * rect(50, 20, 35, 60);
43997           * </code>
43998           * </div>
43999           *
44000           * <div>
44001           * <code>
44002           * noStroke();
44003           * colorMode(HSB, 255);
44004           * let c = color('hsb(60, 100%, 50%)');
44005           * fill(c);
44006           * rect(15, 20, 35, 60);
44007           * let value = brightness(c); // A 'value' of 50% is 127.5
44008           * fill(value);
44009           * rect(50, 20, 35, 60);
44010           * </code>
44011           * </div>
44012           *
44013           * @alt
44014           * Left half of canvas salmon pink and the right half with it's brightness colored white.
44015           * Left half of canvas olive colored and the right half with it's brightness color gray.
44016           */
44017          _main.default.prototype.brightness = function(c) {
44018            _main.default._validateParameters('brightness', arguments);
44019            return this.color(c)._getBrightness();
44020          };
44021
44022          /**
44023           * Creates colors for storing in variables of the color datatype. The
44024           * parameters are interpreted as RGB or HSB values depending on the
44025           * current <a href="#/p5/colorMode">colorMode()</a>. The default mode is RGB values from 0 to 255
44026           * and, therefore, the function call color(255, 204, 0) will return a
44027           * bright yellow color.
44028           *
44029           * Note that if only one value is provided to <a href="#/p5/color">color()</a>, it will be interpreted
44030           * as a grayscale value. Add a second value, and it will be used for alpha
44031           * transparency. When three values are specified, they are interpreted as
44032           * either RGB or HSB values. Adding a fourth value applies alpha
44033           * transparency.
44034           *
44035           * If a single string argument is provided, RGB, RGBA and Hex CSS color
44036           * strings and all named color strings are supported. In this case, an alpha
44037           * number value as a second argument is not supported, the RGBA form should be
44038           * used.
44039           *
44040           * @method color
44041           * @param  {Number} gray number specifying value between white and black.
44042           * @param  {Number} [alpha] alpha value relative to current color range
44043           *                                 (default is 0-255)
44044           * @return {p5.Color} resulting color
44045           *
44046           * @example
44047           * <div>
44048           * <code>
44049           * let c = color(255, 204, 0);
44050           * fill(c);
44051           * noStroke();
44052           * rect(30, 20, 55, 55);
44053           * </code>
44054           * </div>
44055           *
44056           * <div>
44057           * <code>
44058           * let c = color(255, 204, 0);
44059           * fill(c);
44060           * noStroke();
44061           * ellipse(25, 25, 80, 80); // Draw left circle
44062           * // Using only one value generates a grayscale value.
44063           * c = color(65);
44064           * fill(c);
44065           * ellipse(75, 75, 80, 80);
44066           * </code>
44067           * </div>
44068           *
44069           * <div>
44070           * <code>
44071           * // You can use named SVG & CSS colors
44072           * let c = color('magenta');
44073           * fill(c);
44074           * noStroke();
44075           * rect(20, 20, 60, 60);
44076           * </code>
44077           * </div>
44078           *
44079           * <div>
44080           * <code>
44081           * // Example of hex color codes
44082           * noStroke();
44083           * let c = color('#0f0');
44084           * fill(c);
44085           * rect(0, 10, 45, 80);
44086           * c = color('#00ff00');
44087           * fill(c);
44088           * rect(55, 10, 45, 80);
44089           * </code>
44090           * </div>
44091           *
44092           * <div>
44093           * <code>
44094           * // RGB and RGBA color strings are also supported
44095           * // these all set to the same color (solid blue)
44096           * let c;
44097           * noStroke();
44098           * c = color('rgb(0,0,255)');
44099           * fill(c);
44100           * rect(10, 10, 35, 35); // Draw rectangle
44101           * c = color('rgb(0%, 0%, 100%)');
44102           * fill(c);
44103           * rect(55, 10, 35, 35); // Draw rectangle
44104           * c = color('rgba(0, 0, 255, 1)');
44105           * fill(c);
44106           * rect(10, 55, 35, 35); // Draw rectangle
44107           * c = color('rgba(0%, 0%, 100%, 1)');
44108           * fill(c);
44109           * rect(55, 55, 35, 35); // Draw rectangle
44110           * </code>
44111           * </div>
44112           *
44113           * <div>
44114           * <code>
44115           * // HSL color can also be specified by value
44116           * let c = color('hsl(160, 100%, 50%)');
44117           * noStroke();
44118           * fill(c);
44119           * rect(0, 10, 45, 80); // Draw rectangle
44120           * c = color('hsla(160, 100%, 50%, 0.5)');
44121           * fill(c);
44122           * rect(55, 10, 45, 80); // Draw rectangle
44123           * </code>
44124           * </div>
44125           *
44126           * <div>
44127           * <code>
44128           * // HSB color can also be specified
44129           * let c = color('hsb(160, 100%, 50%)');
44130           * noStroke();
44131           * fill(c);
44132           * rect(0, 10, 45, 80); // Draw rectangle
44133           * c = color('hsba(160, 100%, 50%, 0.5)');
44134           * fill(c);
44135           * rect(55, 10, 45, 80); // Draw rectangle
44136           * </code>
44137           * </div>
44138           *
44139           * <div>
44140           * <code>
44141           * noStroke();
44142           * let c = color(50, 55, 100);
44143           * fill(c);
44144           * rect(0, 10, 45, 80); // Draw left rect
44145           * colorMode(HSB, 100);
44146           * c = color(50, 55, 100);
44147           * fill(c);
44148           * rect(55, 10, 45, 80);
44149           * </code>
44150           * </div>
44151           *
44152           * @alt
44153           * Yellow rect in middle right of canvas, with 55 pixel width and height.
44154           * Yellow ellipse in top left of canvas, black ellipse in bottom right,both 80x80.
44155           * Bright fuchsia rect in middle of canvas, 60 pixel width and height.
44156           * Two bright green rects on opposite sides of the canvas, both 45x80.
44157           * Four blue rects in each corner of the canvas, each are 35x35.
44158           * Bright sea green rect on left and darker rect on right of canvas, both 45x80.
44159           * Dark green rect on left and lighter green rect on right of canvas, both 45x80.
44160           * Dark blue rect on left and light teal rect on right of canvas, both 45x80.
44161           */
44162
44163          /**
44164           * @method color
44165           * @param  {Number}        v1      red or hue value relative to
44166           *                                 the current color range
44167           * @param  {Number}        v2      green or saturation value
44168           *                                 relative to the current color range
44169           * @param  {Number}        v3      blue or brightness value
44170           *                                 relative to the current color range
44171           * @param  {Number}        [alpha]
44172           * @return {p5.Color}
44173           */
44174
44175          /**
44176           * @method color
44177           * @param  {String}        value   a color string
44178           * @return {p5.Color}
44179           */
44180
44181          /**
44182           * @method color
44183           * @param  {Number[]}      values  an array containing the red,green,blue &
44184           *                                 and alpha components of the color
44185           * @return {p5.Color}
44186           */
44187
44188          /**
44189           * @method color
44190           * @param  {p5.Color}     color
44191           * @return {p5.Color}
44192           */
44193          _main.default.prototype.color = function() {
44194            _main.default._validateParameters('color', arguments);
44195            if (arguments[0] instanceof _main.default.Color) {
44196              return arguments[0];
44196 // Do nothing if argument is already a color object.
44197            }
44198
44199            var args = arguments[0] instanceof Array ? arguments[0] : arguments;
44200            return new _main.default.Color(this, args);
44201          };
44202
44203          /**
44204           * Extracts the green value from a color or pixel array.
44205           *
44206           * @method green
44207           * @param {p5.Color|Number[]|String} color <a href="#/p5.Color">p5.Color</a> object, color components,
44208           *                                         or CSS color
44209           * @return {Number} the green value
44210           * @example
44211           * <div>
44212           * <code>
44213           * let c = color(20, 75, 200); // Define color 'c'
44214           * fill(c); // Use color variable 'c' as fill color
44215           * rect(15, 20, 35, 60); // Draw left rectangle
44216           *
44217           * let greenValue = green(c); // Get green in 'c'
44218           * print(greenValue); // Print "75.0"
44219           * fill(0, greenValue, 0); // Use 'greenValue' in new fill
44220           * rect(50, 20, 35, 60); // Draw right rectangle
44221           * </code>
44222           * </div>
44223           *
44224           * @alt
44225           * blue rect on left and green on right, both with black outlines & 35x60.
44226           */
44227          _main.default.prototype.green = function(c) {
44228            _main.default._validateParameters('green', arguments);
44229            return this.color(c)._getGreen();
44230          };
44231
44232          /**
44233           * Extracts the hue value from a color or pixel array.
44234           *
44235           * Hue exists in both HSB and HSL. This function will return the
44236           * HSB-normalized hue when supplied with an HSB color object (or when supplied
44237           * with a pixel array while the color mode is HSB), but will default to the
44238           * HSL-normalized hue otherwise. (The values will only be different if the
44239           * maximum hue setting for each system is different.)
44240           *
44241           * @method hue
44242           * @param {p5.Color|Number[]|String} color <a href="#/p5.Color">p5.Color</a> object, color components,
44243           *                                         or CSS color
44244           * @return {Number} the hue
44245           * @example
44246           * <div>
44247           * <code>
44248           * noStroke();
44249           * colorMode(HSB, 255);
44250           * let c = color(0, 126, 255);
44251           * fill(c);
44252           * rect(15, 20, 35, 60);
44253           * let value = hue(c); // Sets 'value' to "0"
44254           * fill(value);
44255           * rect(50, 20, 35, 60);
44256           * </code>
44257           * </div>
44258           *
44259           * @alt
44260           * salmon pink rect on left and black on right, both 35x60.
44261           */
44262          _main.default.prototype.hue = function(c) {
44263            _main.default._validateParameters('hue', arguments);
44264            return this.color(c)._getHue();
44265          };
44266
44267          /**
44268           * Blends two colors to find a third color somewhere between them. The amt
44269           * parameter is the amount to interpolate between the two values where 0.0
44270           * equal to the first color, 0.1 is very near the first color, 0.5 is halfway
44271           * in between, etc. An amount below 0 will be treated as 0. Likewise, amounts
44272           * above 1 will be capped at 1. This is different from the behavior of <a href="#/p5/lerp">lerp()</a>,
44273           * but necessary because otherwise numbers outside the range will produce
44274           * strange and unexpected colors.
44275           *
44276           * The way that colors are interpolated depends on the current color mode.
44277           *
44278           * @method lerpColor
44279           * @param  {p5.Color} c1  interpolate from this color
44280           * @param  {p5.Color} c2  interpolate to this color
44281           * @param  {Number}       amt number between 0 and 1
44282           * @return {p5.Color}     interpolated color
44283           *
44284           * @example
44285           * <div>
44286           * <code>
44287           * colorMode(RGB);
44288           * stroke(255);
44289           * background(51);
44290           * let from = color(218, 165, 32);
44291           * let to = color(72, 61, 139);
44292           * colorMode(RGB); // Try changing to HSB.
44293           * let interA = lerpColor(from, to, 0.33);
44294           * let interB = lerpColor(from, to, 0.66);
44295           * fill(from);
44296           * rect(10, 20, 20, 60);
44297           * fill(interA);
44298           * rect(30, 20, 20, 60);
44299           * fill(interB);
44300           * rect(50, 20, 20, 60);
44301           * fill(to);
44302           * rect(70, 20, 20, 60);
44303           * </code>
44304           * </div>
44305           *
44306           * @alt
44307           * 4 rects one tan, brown, brownish purple, purple, with white outlines & 20x60
44308           */
44309
44310          _main.default.prototype.lerpColor = function(c1, c2, amt) {
44311            _main.default._validateParameters('lerpColor', arguments);
44312            var mode = this._colorMode;
44313            var maxes = this._colorMaxes;
44314            var l0, l1, l2, l3;
44315            var fromArray, toArray;
44316
44317            if (mode === constants.RGB) {
44318              fromArray = c1.levels.map(function(level) {
44319                return level / 255;
44320              });
44321              toArray = c2.levels.map(function(level) {
44322                return level / 255;
44323              });
44324            } else if (mode === constants.HSB) {
44325              c1._getBrightness(); // Cache hsba so it definitely exists.
44326              c2._getBrightness();
44327              fromArray = c1.hsba;
44328              toArray = c2.hsba;
44329            } else if (mode === constants.HSL) {
44330              c1._getLightness();
44330 // Cache hsla so it definitely exists.
44331              c2._getLightness();
44332              fromArray = c1.hsla;
44333              toArray = c2.hsla;
44334            } else {
44335              throw new Error(''.concat(mode, 'cannot be used for interpolation.'));
44336            }
44337
44338            // Prevent extrapolation.
44339            amt = Math.max(Math.min(amt, 1), 0);
44340
44341            // Define lerp here itself if user isn't using math module.
44342            // Maintains the definition as found in math/calculation.js
44343            if (typeof this.lerp === 'undefined') {
44344              this.lerp = function(start, stop, amt) {
44345                return amt * (stop - start) + start;
44346              };
44347            }
44348
44349            // Perform interpolation.
44350            l0 = this.lerp(fromArray[0], toArray[0], amt);
44351            l1 = this.lerp(fromArray[1], toArray[1], amt);
44352            l2 = this.lerp(fromArray[2], toArray[2], amt);
44353            l3 = this.lerp(fromArray[3], toArray[3], amt);
44354
44355            // Scale components.
44356            l0 *= maxes[mode][0];
44357            l1 *= maxes[mode][1];
44358            l2 *= maxes[mode][2];
44359            l3 *= maxes[mode][3];
44360
44361            return this.color(l0, l1, l2, l3);
44362          };
44363
44364          /**
44365           * Extracts the HSL lightness value from a color or pixel array.
44366           *
44367           * @method lightness
44368           * @param {p5.Color|Number[]|String} color <a href="#/p5.Color">p5.Color</a> object, color components,
44369           *                                         or CSS color
44370           * @return {Number} the lightness
44371           *
44372           * @example
44373           * <div>
44374           * <code>
44375           * noStroke();
44376           * colorMode(HSL);
44377           * let c = color(156, 100, 50, 1);
44378           * fill(c);
44379           * rect(15, 20, 35, 60);
44380           * let value = lightness(c); // Sets 'value' to 50
44381           * fill(value);
44382           * rect(50, 20, 35, 60);
44383           * </code>
44384           * </div>
44385           *
44386           * @alt
44387           * light pastel green rect on left and dark grey rect on right, both 35x60.
44388           */
44389          _main.default.prototype.lightness = function(c) {
44390            _main.default._validateParameters('lightness', arguments);
44391            return this.color(c)._getLightness();
44392          };
44393
44394          /**
44395           * Extracts the red value from a color or pixel array.
44396           *
44397           * @method red
44398           * @param {p5.Color|Number[]|String} color <a href="#/p5.Color">p5.Color</a> object, color components,
44399           *                                         or CSS color
44400           * @return {Number} the red value
44401           * @example
44402           * <div>
44403           * <code>
44404           * let c = color(255, 204, 0); // Define color 'c'
44405           * fill(c); // Use color variable 'c' as fill color
44406           * rect(15, 20, 35, 60); // Draw left rectangle
44407           *
44408           * let redValue = red(c); // Get red in 'c'
44409           * print(redValue); // Print "255.0"
44410           * fill(redValue, 0, 0); // Use 'redValue' in new fill
44411           * rect(50, 20, 35, 60); // Draw right rectangle
44412           * </code>
44413           * </div>
44414           *
44415           * <div class="norender">
44416           * <code>
44417           * colorMode(RGB, 255); // Sets the range for red, green, and blue to 255
44418           * let c = color(127, 255, 0);
44419           * colorMode(RGB, 1); // Sets the range for red, green, and blue to 1
44420           * let myColor = red(c);
44421           * print(myColor); // 0.4980392156862745
44422           * </code>
44423           * </div>
44424           *
44425           * @alt
44426           * yellow rect on left and red rect on right, both with black outlines and 35x60.
44427           * grey canvas
44428           */
44429          _main.default.prototype.red = function(c) {
44430            _main.default._validateParameters('red', arguments);
44431            return this.color(c)._getRed();
44432          };
44433
44434          /**
44435           * Extracts the saturation value from a color or pixel array.
44436           *
44437           * Saturation is scaled differently in HSB and HSL. This function will return
44438           * the HSB saturation when supplied with an HSB color object (or when supplied
44439           * with a pixel array while the color mode is HSB), but will default to the
44440           * HSL saturation otherwise.
44441           *
44442           * @method saturation
44443           * @param {p5.Color|Number[]|String} color <a href="#/p5.Color">p5.Color</a> object, color components,
44444           *                                         or CSS color
44445           * @return {Number} the saturation value
44446           * @example
44447           * <div>
44448           * <code>
44449           * noStroke();
44450           * colorMode(HSB, 255);
44451           * let c = color(0, 126, 255);
44452           * fill(c);
44453           * rect(15, 20, 35, 60);
44454           * let value = saturation(c); // Sets 'value' to 126
44455           * fill(value);
44456           * rect(50, 20, 35, 60);
44457           * </code>
44458           * </div>
44459           *
44460           * @alt
44461           *deep pink rect on left and grey rect on right, both 35x60.
44462           */
44463          _main.default.prototype.saturation = function(c) {
44464            _main.default._validateParameters('saturation', arguments);
44465            return this.color(c)._getSaturation();
44466          };
44467          var _default = _main.default;
44468          exports.default = _default;
44469        },
44470        {
44471          '../core/constants': 48,
44472          '../core/friendly_errors/fes_core': 51,
44473          '../core/friendly_errors/file_errors': 52,
44474          '../core/friendly_errors/validate_params': 54,
44475          '../core/main': 59,
44476          './p5.Color': 46
44477        }
44478      ],
44479      46: [
44480        function(_dereq_, module, exports) {
44481          'use strict';
44482          function _typeof(obj) {
44483            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
44484              _typeof = function _typeof(obj) {
44485                return typeof obj;
44486              };
44487            } else {
44488              _typeof = function _typeof(obj) {
44489                return obj &&
44490                  typeof Symbol === 'function' &&
44491                  obj.constructor === Symbol &&
44492                  obj !== Symbol.prototype
44493                  ? 'symbol'
44494                  : typeof obj;
44495              };
44496            }
44497            return _typeof(obj);
44498          }
44499          Object.defineProperty(exports, '__esModule', { value: true });
44500          exports.default = void 0;
44501
44502          var _main = _interopRequireDefault(_dereq_('../core/main'));
44503          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
44504          var _color_conversion = _interopRequireDefault(_dereq_('./color_conversion'));
44505          function _getRequireWildcardCache() {
44506            if (typeof WeakMap !== 'function') return null;
44507            var cache = new WeakMap();
44508            _getRequireWildcardCache = function _getRequireWildcardCache() {
44509              return cache;
44510            };
44511            return cache;
44512          }
44513          function _interopRequireWildcard(obj) {
44514            if (obj && obj.__esModule) {
44515              return obj;
44516            }
44517            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
44518              return { default: obj };
44519            }
44520            var cache = _getRequireWildcardCache();
44521            if (cache && cache.has(obj)) {
44522              return cache.get(obj);
44523            }
44524            var newObj = {};
44525            var hasPropertyDescriptor =
44526              Object.defineProperty && Object.getOwnPropertyDescriptor;
44527            for (var key in obj) {
44528              if (Object.prototype.hasOwnProperty.call(obj, key)) {
44529                var desc = hasPropertyDescriptor
44530                  ? Object.getOwnPropertyDescriptor(obj, key)
44531                  : null;
44532                if (desc && (desc.get || desc.set)) {
44533                  Object.defineProperty(newObj, key, desc);
44534                } else {
44535                  newObj[key] = obj[key];
44536                }
44537              }
44538            }
44539            newObj.default = obj;
44540            if (cache) {
44541              cache.set(obj, newObj);
44542            }
44543            return newObj;
44544          }
44545          function _interopRequireDefault(obj) {
44546            return obj && obj.__esModule ? obj : { default: obj };
44547          }
44548          /**
44549           * @module Color
44550           * @submodule Creating & Reading
44551           * @for p5
44552           * @requires core
44553           * @requires constants
44554           * @requires color_conversion
44555           */ /**
44556           * Each color stores the color mode and level maxes that was applied at the
44557           * time of its construction. These are used to interpret the input arguments
44558           * (at construction and later for that instance of color) and to format the
44559           * output e.g. when <a href="#/p5/saturation">saturation()</a> is requested.
44560           *
44561           * Internally, we store an array representing the ideal RGBA values in floating
44562           * point form, normalized from 0 to 1. From this we calculate the closest
44563           * screen color (RGBA levels from 0 to 255) and expose this to the renderer.
44564           *
44565           * We also cache normalized, floating point components of the color in various
44566           * representations as they are calculated. This is done to prevent repeating a
44567           * conversion that has already been performed.
44568           *
44569           * @class p5.Color
44570           * @constructor
44571           */ _main.default.Color = function(pInst, vals) {
44572            // Record color mode and maxes at time of construction.
44573            this._storeModeAndMaxes(pInst._colorMode, pInst._colorMaxes); // Calculate normalized RGBA values.
44574            if (
44575              this.mode !== constants.RGB &&
44576              this.mode !== constants.HSL &&
44577              this.mode !== constants.HSB
44578            ) {
44579              throw new Error(''.concat(this.mode, ' is an invali
44579d colorMode.'));
44580            } else {
44581              this._array = _main.default.Color._parseInputs.apply(this, vals);
44582            }
44583
44584            // Expose closest screen color.
44585            this._calculateLevels();
44586            return this;
44587          };
44588
44589          /**
44590           * This function returns the color formatted as a string. This can be useful
44591           * for debugging, or for using p5.js with other libraries.
44592           *
44593           * @method toString
44594           * @param {String} [format] How the color string will be formatted.
44595           * Leaving this empty formats the string as rgba(r, g, b, a).
44596           * '#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.
44597           * 'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.
44598           * 'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.
44599           * 'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.
44600           * @return {String} the formatted string
44601           *
44602           * @example
44603           * <div>
44604           * <code>
44605           * createCanvas(200, 100);
44606           * let myColor;
44607           * stroke(255);
44608           * myColor = color(100, 100, 250);
44609           * fill(myColor);
44610           * rotate(HALF_PI);
44611           * text(myColor.toString(), 0, -5);
44612           * text(myColor.toString('#rrggbb'), 0, -30);
44613           * text(myColor.toString('rgba%'), 0, -55);
44614           * </code>
44615           * </div>
44616           *
44617           * <div>
44618           * <code>
44619           * let myColor = color(100, 130, 250);
44620           * text(myColor.toString('#rrggbb'), 25, 25);
44621           * </code>
44622           * </div>
44623           *
44624           * @alt
44625           * A canvas with 3 text representation of their color.
44626           */
44627          _main.default.Color.prototype.toString = function(format) {
44628            var a = this.levels;
44629            var f = this._array;
44630            var alpha = f[3]; // String representation uses normalized alpha
44631
44632            switch (format) {
44633              case '#rrggbb':
44634                return '#'.concat(
44635                  a[0] < 16 ? '0'.concat(a[0].toString(16)) : a[0].toString(16),
44636                  a[1] < 16 ? '0'.concat(a[1].toString(16)) : a[1].toString(16),
44637                  a[2] < 16 ? '0'.concat(a[2].toString(16)) : a[2].toString(16)
44638                );
44639
44640              case '#rrggbbaa':
44641                return '#'.concat(
44642                  a[0] < 16 ? '0'.concat(a[0].toString(16)) : a[0].toString(16),
44643                  a[1] < 16 ? '0'.concat(a[1].toString(16)) : a[1].toString(16),
44644                  a[2] < 16 ? '0'.concat(a[2].toString(16)) : a[2].toString(16),
44645                  a[3] < 16 ? '0'.concat(a[2].toString(16)) : a[3].toString(16)
44646                );
44647
44648              case '#rgb':
44649                return '#'.concat(
44650                  Math.round(f[0] * 15).toString(16),
44651                  Math.round(f[1] * 15).toString(16),
44652                  Math.round(f[2] * 15).toString(16)
44653                );
44654
44655              case '#rgba':
44656                return '#'.concat(
44657                  Math.round(f[0] * 15).toString(16),
44658                  Math.round(f[1] * 15).toString(16),
44659                  Math.round(f[2] * 15).toString(16),
44660                  Math.round(f[3] * 15).toString(16)
44661                );
44662
44663              case 'rgb':
44664                return 'rgb('.concat(a[0], ', ', a[1], ', ', a[2], ')');
44665
44666              case 'rgb%':
44667                return 'rgb('.concat(
44668                  (100 * f[0]).toPrecision(3),
44669                  '%, ',
44670                  (100 * f[1]).toPrecision(3),
44671                  '%, ',
44672                  (100 * f[2]).toPrecision(3),
44673                  '%)'
44674                );
44675
44676              case 'rgba%':
44677                return 'rgba('.concat(
44678                  (100 * f[0]).toPrecision(3),
44679                  '%, ',
44680                  (100 * f[1]).toPrecision(3),
44681                  '%, ',
44682                  (100 * f[2]).toPrecision(3),
44683                  '%, ',
44684                  (100 * f[3]).toPrecision(3),
44685                  '%)'
44686                );
44687
44688              case 'hsb':
44689              case 'hsv':
44690                if (!this.hsba)
44691                  this.hsba = _color_conversion.default._rgbaToHSBA(this._array);
44692                return 'hsb('.concat(
44693                  this.hsba[0] * this.maxes[constants.HSB][0],
44694                  ', ',
44695                  this.hsba[1] * this.maxes[constants.HSB][1],
44696                  ', ',
44697                  this.hsba[2] * this.maxes[constants.HSB][2],
44698                  ')'
44699                );
44700
44701              case 'hsb%':
44702              case 'hsv%':
44703                if (!this.hsba)
44704                  this.hsba = _color_conversion.default._rgbaToHSBA(this._array);
44705                return 'hsb('.concat(
44706                  (100 * this.hsba[0]).toPrecision(3),
44707                  '%, ',
44708                  (100 * this.hsba[1]).toPrecision(3),
44709                  '%, ',
44710                  (100 * this.hsba[2]).toPrecision(3),
44711                  '%)'
44712                );
44713
44714              case 'hsba':
44715              case 'hsva':
44716                if (!this.hsba)
44717                  this.hsba = _color_conversion.default._rgbaToHSBA(this._array);
44718                return 'hsba('.concat(
44719                  this.hsba[0] * this.maxes[constants.HSB][0],
44720                  ', ',
44721                  this.hsba[1] * this.maxes[constants.HSB][1],
44722                  ', ',
44723                  this.hsba[2] * this.maxes[constants.HSB][2],
44724                  ', ',
44725                  alpha,
44726                  ')'
44727                );
44728
44729              case 'hsba%':
44730              case 'hsva%':
44731                if (!this.hsba)
44732                  this.hsba = _color_conversion.default._rgbaToHSBA(this._array);
44733                return 'hsba('.concat(
44734                  (100 * this.hsba[0]).toPrecision(3),
44735                  '%, ',
44736                  (100 * this.hsba[1]).toPrecision(3),
44737                  '%, ',
44738                  (100 * this.hsba[2]).toPrecision(3),
44739                  '%, ',
44740                  (100 * alpha).toPrecision(3),
44741                  '%)'
44742                );
44743
44744              case 'hsl':
44745                if (!this.hsla)
44746                  this.hsla = _color_conversion.default._rgbaToHSLA(this._array);
44747                return 'hsl('.concat(
44748                  this.hsla[0] * this.maxes[constants.HSL][0],
44749                  ', ',
44750                  this.hsla[1] * this.maxes[constants.HSL][1],
44751                  ', ',
44752                  this.hsla[2] * this.maxes[constants.HSL][2],
44753                  ')'
44754                );
44755
44756              case 'hsl%':
44757                if (!this.hsla)
44758                  this.hsla = _color_conversion.default._rgbaToHSLA(this._array);
44759                return 'hsl('.concat(
44760                  (100 * this.hsla[0]).toPrecision(3),
44761                  '%, ',
44762                  (100 * this.hsla[1]).toPrecision(3),
44763                  '%, ',
44764                  (100 * this.hsla[2]).toPrecision(3),
44765                  '%)'
44766                );
44767
44768              case 'hsla':
44769                if (!this.hsla)
44770                  this.hsla = _color_conversion.default._rgbaToHSLA(this._array);
44771                return 'hsla('.concat(
44772                  this.hsla[0] * this.maxes[constants.HSL][0],
44773                  ', ',
44774                  this.hsla[1] * this.maxes[constants.HSL][1],
44775                  ', ',
44776                  this.hsla[2] * this.maxes[constants.HSL][2],
44777                  ', ',
44778                  alpha,
44779                  ')'
44780                );
44781
44782              case 'hsla%':
44783                if (!this.hsla)
44784                  this.hsla = _color_conversion.default._rgbaToHSLA(this._array);
44785                return 'hsl('.concat(
44786                  (100 * this.hsla[0]).toPrecision(3),
44787                  '%, ',
44788                  (100 * this.hsla[1]).toPrecision(3),
44789                  '%, ',
44790                  (100 * this.hsla[2]).toPrecision(3),
44791                  '%, ',
44792                  (100 * alpha).toPrecision(3),
44793                  '%)'
44794                );
44795
44796              case 'rgba':
44797              default:
44798                return 'rgba('.concat(a[0], ',', a[1], ',', a[2], ',', alpha, ')');
44799            }
44800          };
44801
44802          /**
44803           * The setRed function sets the red component of a color.
44804           * The range depends on your color mode, in the default RGB mode it's between 0 and 255.
44805           * @method setRed
44806           * @param {Number} red the new red value
44807           * @example
44808           * <div>
44809           * <code>
44810           * let backgroundColor;
44811           *
44812           * function setup() {
44813           *   backgroundColor = color(100, 50, 150);
44814           * }
44815           *
44816           * function draw() {
44817           *   backgroundColor.setRed(128 + 128 * sin(millis() / 1000));
44818           *   background(backgroundColor);
44819           * }
44820           * </code>
44821           * </div>
44822           *
44823           * @alt
44824           * canvas with gradually changing background color
44825           */
44826          _main.default.Color.prototype.setRed = function(new_red) {
44827            this._array[0] = new_red / this.maxes[constants.RGB][0];
44828            this._calculateLevels();
44829          };
44830
44831          /**
44832           * The setGreen function sets the green component of a color.
44833           * The range depends on your color mode, in the default RGB mode it's between 0 and 255.
44834           * @method setGreen
44835           * @param {Number} green the new green value
44836           * @example
44837           * <div>
44838           * <code>
44839           * let backgroundColor = color(100, 50, 150);
44840           * function draw() {
44841           *   backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));
44842           *   background(backgroundColor);
44843           * }
44844           * </code>
44845           * </div>
44846           *
44847           * @alt
44848           * canvas with gradually changing background color
44849           **/
44850          _main.default.Color.prototype.setGreen = function(new_green) {
44851            this._array[1] = new_green / this.maxes[constants.RGB][1];
44852            this._calculateLevels();
44853          };
44854
44855          /**
44856           * The setBlue function sets the blue component of a color.
44857           * The range depends on your color mode, in the default RGB mode it's between 0 and 255.
44858           * @method setBlue
44859           * @param {Number} blue the new blue value
44860           * @example
44861           * <div>
44862           * <code>
44863           * let backgroundColor = color(100, 50, 150);
44864           * function draw() {
44865           *   backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));
44866           *   background(backgroundColor);
44867           * }
44868           * </code>
44869           * </div>
44870           *
44871           * @alt
44872           * canvas with gradually changing background color
44873           **/
44874          _main.default.Color.prototype.setBlue = function(new_blue) {
44875            this._array[2] = new_blue / this.maxes[constants.RGB][2];
44876            this._calculateLevels();
44877          };
44878
44879          /**
44880           * The setAlpha function sets the transparency (alpha) value of a color.
44881           * The range depends on your color mode, in the default RGB mode it's between 0 and 255.
44882           * @method setAlpha
44883           * @param {Number} alpha the new alpha value
44884           * @example
44885           * <div>
44886           * <code>
44887           * function draw() {
44888           *   clear();
44889           *   background(200);
44890           *   squareColor = color(100, 50, 100);
44891           *   squareColor.setAlpha(128 + 128 * sin(millis() / 1000));
44892           *   fill(squareColor);
44893           *   rect(13, 13, width - 26, height - 26);
44894           * }
44895           * </code>
44896           * </div>
44897           *
44898           * @alt
44899           * a square with gradually changing opacity on a gray background
44900           **/
44901          _main.default.Color.prototype.setAlpha = function(new_alpha) {
44902            this._array[3] = new_alpha / this.maxes[this.mode][3];
44903            this._calculateLevels();
44904          };
44905
44906          // calculates and stores the closest screen levels
44907          _main.default.Color.prototype._calculateLevels = function() {
44908            var array = this._array;
44909            // (loop backwards for performance)
44910            var levels = (this.levels = new Array(array.length));
44911            for (var i = array.length - 1; i >= 0; --i) {
44912              levels[i] = Math.round(array[i] * 255);
44913            }
44914          };
44915
44916          _main.default.Color.prototype._getAlpha = function() {
44917            return this._array[3] * this.maxes[this.mode][3];
44918          };
44919
44920          // stores the color mode and maxes in this instance of Color
44921          // for later use (by _parseInputs())
44922          _main.default.Color.prototype._storeModeAndMaxes = function(new_mode, new_maxes) {
44923            this.mode = new_mode;
44924            this.maxes = new_maxes;
44925          };
44926
44927          _main.default.Color.prototype._getMode = function() {
44928            return this.mode;
44929          };
44930
44931          _main.default.Color.prototype._getMaxes = function() {
44932            return this.maxes;
44933          };
44934
44935          _main.default.Color.prototype._getBlue = function() {
44936            return this._array[2] * this.maxes[constants.RGB][2];
44937          };
44938
44939          _main.default.Color.prototype._getBrightness = function() {
44940            if (!this.hsba) {
44941              this.hsba = _color_conversion.default._rgbaToHSBA(this._array);
44942            }
44943            return this.hsba[2] * this.maxes[constants.HSB][2];
44944          };
44945
44946          _main.default.Color.prototype._getGreen = function() {
44947            return this._array[1] * this.maxes[constants.RGB][1];
44948          };
44949
44950          /**
44951           * Hue is the same in HSB and HSL, but the maximum value may be different.
44952           * This function will return the HSB-normalized saturation when supplied with
44953           * an HSB color object, but will default to the HSL-normalized saturation
44954           * otherwise.
44955           */
44956          _main.default.Color.prototype._getHue = function() {
44957            if (this.mode === constants.HSB) {
44958              if (!this.hsba) {
44959                this.hsba = _color_conversion.default._rgbaToHSBA(this._array);
44960              }
44961              return this.hsba[0] * this.maxes[constants.HSB][0];
44962            } else {
44963              if (!this.hsla) {
44964                this.hsla = _color_conversion.default._rgbaToHSLA(this._array);
44965              }
44966              return this.hsla[0] * this.maxes[constants.HSL][0];
44967            }
44968          };
44969
44970          _main.default.Color.prototype._getLightness = function() {
44971            if (!this.hsla) {
44972              this.hsla = _color_conversion.default._rgbaToHSLA(this._array);
44973            }
44974            return this.hsla[2] * this.maxes[constants.HSL][2];
44975          };
44976
44977          _main.default.Color.prototype._getRed = function() {
44978            return this._array[0] * this.maxes[constants.RGB][0];
44979          };
44980
44981          /**
44982           * Saturation is scaled differently in HSB and HSL. This function will return
44983           * the HSB saturation when supplied with an HSB color object, but will default
44984           * to the HSL saturation otherwise.
44985           */
44986          _main.default.Color.prototype._getSaturation = function() {
44987            if (this.mode === constants.HSB) {
44988              if (!this.hsba) {
44989                this.hsba = _color_conversion.default._rgbaToHSBA(this._array);
44990              }
44991              return this.hsba[1] * this.maxes[constants.HSB][1];
44992            } else {
44993              if (!this.hsla) {
44994                this.hsla = _color_conversion.default._rgbaToHSLA(this._array);
44995              }
44996              return this.hsla[1] * this.maxes[constants.HSL][1];
44997            }
44998          };
44999
45000          /**
45001           * CSS named colors.
45002           */
45003          var namedColors = {
45004            aliceblue: '#f0f8ff',
45005            antiquewhite: '#faebd7',
45006            aqua: '#00ffff',
45007            aquamarine: '#7fffd4',
45008            azure: '#f0ffff',
45009            beige: '#f5f5dc',
45010            bisque: '#ffe4c4',
45011            black: '#000000',
45012            blanchedalmond: '#ffebcd',
45013            blue: '#0000ff',
45014            blueviolet: '#8a2be2',
45015            brown: '#a52a2a',
45016            burlywood: '#deb887',
45017            cadetblue: '#5f9ea0',
45018            chartreuse: '#7fff00',
45019            chocolate: '#d2691e',
45020            coral: '#ff7f50',
45021            cornflowerblue: '#6495ed',
45022            cornsilk: '#fff8dc',
45023            crimson: '#dc143c',
45024            cyan: '#00ffff',
45025            darkblue: '#00008b',
45026            darkcyan: '#008b8b',
45027            darkgoldenrod: '#b8860b',
45028            darkgray: '#a9a9a9',
45029            darkgreen: '#006400',
45030            darkgrey: '#a9a9a9',
45031            darkkhaki: '#bdb76b',
45032            darkmagenta: '#8b008b',
45033            darkolivegreen: '#556b2f',
45034            darkorange: '#ff8c00',
45035            darkorchid: '#9932cc',
45036            darkred: '#8b0000',
45037            darksalmon: '#e9967a',
45038            darkseagreen: '#8fbc8f',
45039            darkslateblue: '#483d8b',
45040            darkslategray: '#2f4f4f',
45041            darkslategrey: '#2f4f4f',
45042            darkturquoise: '#00ced1',
45043            darkviolet: '#9400d3',
45044            deeppink: '#ff1493',
45045            deepskyblue: '#00bfff',
45046            dimgray: '#696969',
45047            dimgrey: '#696969',
45048            dodgerblue: '#1e90ff',
45049            firebrick: '#b22222',
45050            floralwhite: '#fffaf0',
45051            forestgreen: '#228b22',
45052            fuchsia: '#ff00ff',
45053            gainsboro: '#dcdcdc',
45054            ghostwhite: '#f8f8ff',
45055            gold: '#ffd700',
45056            goldenrod: '#daa520',
45057            gray: '#808080',
45058            green: '#008000',
45059            greenyellow: '#adff2f',
45060            grey: '#808080',
45061            honeydew: '#f0fff0',
45062            hotpink: '#ff69b4',
45063            indianred: '#cd5c5c',
45064            indigo: '#4b0082',
45065            ivory: '#fffff0',
45066            khaki: '#f0e68c',
45067            lavender: '#e6e6fa',
45068            lavenderblush: '#fff0f5',
45069            lawngreen: '#7cfc00',
45070            lemonchiffon: '#fffacd',
45071            lightblue: '#add8e6',
45072            lightcoral: '#f08080',
45073            lightcyan: '#e0ffff',
45074            lightgoldenrodyellow: '#fafad2',
45075            lightgray: '#d3d3d3',
45076            lightgreen: '#90ee90',
45077            lightgrey: '#d3d3d3',
45078            lightpink: '#ffb6c1',
45079            lightsalmon: '#ffa07a',
45080            lightseagreen: '#20b2aa',
45081            lightskyblue: '#87cefa',
45082            lightslategray: '#778899',
45083            lightslategrey: '#778899',
45084            lightsteelblue: '#b0c4de',
45085            lightyellow: '#ffffe0',
45086            lime: '#00ff00',
45087            limegreen: '#32cd32',
45088            linen: '#faf0e6',
45089            magenta: '#ff00ff',
45090            maroon: '#800000',
45091            mediumaquamarine: '#66cdaa',
45092            mediumblue: '#0000cd',
45093            mediumorchid: '#ba55d3',
45094            mediumpurple: '#9370db',
45095            mediumseagreen: '#3cb371',
45096            mediumslateblue: '#7b68ee',
45097            mediumspringgreen: '#00fa9a',
45098            mediumturquoise: '#48d1cc',
45099            mediumvioletred: '#c71585',
45100            midnightblue: '#191970',
45101            mintcream: '#f5fffa',
45102            mistyrose: '#ffe4e1',
45103            moccasin: '#ffe4b5',
45104            navajowhite: '#ffdead',
45105            navy: '#000080',
45106            oldlace: '#fdf5e6',
45107            olive: '#808000',
45108            olivedrab: '#6b8e23',
45109            orange: '#ffa500',
45110            orangered: '#ff4500',
45111            orchid: '#da70d6',
45112            palegoldenrod: '#eee8aa',
45113            palegreen: '#98fb98',
45114            paleturquoise: '#afeeee',
45115            palevioletred: '#db7093',
45116            papayawhip: '#ffefd5',
45117            peachpuff: '#ffdab9',
45118            peru: '#cd853f',
45119            pink: '#ffc0cb',
45120            plum: '#dda0dd',
45121            powderblue: '#b0e0e6',
45122            purple: '#800080',
45123            rebeccapurple: '#663399',
45124            red: '#ff0000',
45125            rosybrown: '#bc8f8f',
45126            royalblue: '#4169e1',
45127            saddlebrown: '#8b4513',
45128            salmon: '#fa8072',
45129            sandybrown: '#f4a460',
45130            seagreen: '#2e8b57',
45131            seashell: '#fff5ee',
45132            sienna: '#a0522d',
45133            silver: '#c0c0c0',
45134            skyblue: '#87ceeb',
45135            slateblue: '#6a5acd',
45136            slategray: '#708090',
45137            slategrey: '#708090',
45138            snow: '#fffafa',
45139            springgreen: '#00ff7f',
45140            steelblue: '#4682b4',
45141            tan: '#d2b48c',
45142            teal: '#008080',
45143            thistle: '#d8bfd8',
45144            tomato: '#ff6347',
45145            turquoise: '#40e0d0',
45146            violet: '#ee82ee',
45147            wheat: '#f5deb3',
45148            white: '#ffffff',
45149            whitesmoke: '#f5f5f5',
45150            yellow: '#ffff00',
45151            yellowgreen: '#9acd32'
45152          };
45153
45154          /**
45155           * These regular expressions are used to build up the patterns for matching
45156           * viable CSS color strings: fragmenting the regexes in this way increases the
45157           * legibility and comprehensibility of the code.
45158           *
45159           * Note that RGB values of .9 are not parsed by IE, but are supported here for
45160           * color string consistency.
45161           */
45162          var WHITESPACE = /\s*/; // Match zero or more whitespace characters.
45163          var INTEGER = /(\d{1,3})/; // Match integers: 79, 255, etc.
45164          var DECIMAL = /((?:\d+(?:\.\d+)?)|(?:\.\d+))/; // Match 129.6, 79, .9, etc.
45165          var PERCENT = new RegExp(''.concat(DECIMAL.source, '%')); // Match 12.9%, 79%, .9%, etc.
45166
45167          /**
45168           * Full color string patterns. The capture groups are necessary.
45169           */
45170          var colorPatterns = {
45171            // Match colors in format #XXX, e.g. #416.
45172            HEX3: /^#([a-f0-9])([a-f0-9])([a-f0-9])$/i,
45173
45174            // Match colors in format #XXXX, e.g. #5123.
45175            HEX4: /^#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])$/i,
45176
45177            // Match colors in format #XXXXXX, e.g. #b4d455.
45178            HEX6: /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i,
45179
45180            // Match colors in format #XXXXXXXX, e.g. #b4d45535.
45181            HEX8: /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i,
45182
45183            // Match colors in format rgb(R, G, B), e.g. rgb(255, 0, 128).
45184            RGB: new RegExp(
45185              [
45186                '^rgb\\(',
45187                INTEGER.source,
45188                ',',
45189                INTEGER.source,
45190                ',',
45191                INTEGER.source,
45192                '\\)$'
45193              ].join(WHITESPACE.source),
45194              'i'
45195            ),
45196
45197            // Match colors in format rgb(R%, G%, B%), e.g. rgb(100%, 0%, 28.9%).
45198            RGB_PERCENT: new RegExp(
45199              [
45200                '^rgb\\(',
45201                PERCENT.source,
45202                ',',
45203                PERCENT.source,
45204                ',',
45205                PERCENT.source,
45206                '\\)$'
45207              ].join(WHITESPACE.source),
45208              'i'
45209            ),
45210
45211            // Match colors in format rgb(R, G, B, A), e.g. rgb(255, 0, 128, 0.25).
45212            RGBA: new RegExp(
45213              [
45214                '^rgba\\(',
45215                INTEGER.source,
45216                ',',
45217                INTEGER.source,
45218                ',',
45219                INTEGER.source,
45220                ',',
45221                DECIMAL.source,
45222                '\\)$'
45223              ].join(WHITESPACE.source),
45224              'i'
45225            ),
45226
45227            // Match colors in format rgb(R%, G%, B%, A), e.g. rgb(100%, 0%, 28.9%, 0.5).
45228            RGBA_PERCENT: new RegExp(
45229              [
45230                '^rgba\\(',
45231                PERCENT.source,
45232                ',',
45233                PERCENT.source,
45234                ',',
45235                PERCENT.source,
45236                ',',
45237                DECIMAL.source,
45238                '\\)$'
45239              ].join(WHITESPACE.source),
45240              'i'
45241            ),
45242
45243            // Match colors in format hsla(H, S%, L%), e.g. hsl(100, 40%, 28.9%).
45244            HSL: new RegExp(
45245              [
45246                '^hsl\\(',
45247                INTEGER.source,
45248                ',',
45249                PERCENT.source,
45250                ',',
45251                PERCENT.source,
45252                '\\)$'
45253              ].join(WHITESPACE.source),
45254              'i'
45255            ),
45256
45257            // Match colors in format hsla(H, S%, L%, A), e.g. hsla(100, 40%, 28.9%, 0.5).
45258            HSLA: new RegExp(
45259              [
45260                '^hsla\\(',
45261                INTEGER.source,
45262                ',',
45263                PERCENT.source,
45264                ',',
45265                PERCENT.source,
45266                ',',
45267                DECIMAL.source,
45268                '\\)$'
45269              ].join(WHITESPACE.source),
45270              'i'
45271            ),
45272
45273            // Match colors in format hsb(H, S%, B%), e.g. hsb(100, 40%, 28.9%).
45274            HSB: new RegExp(
45275              [
45276                '^hsb\\(',
45277                INTEGER.source,
45278                ',',
45279                PERCENT.source,
45280                ',',
45281                PERCENT.source,
45282                '\\)$'
45283              ].join(WHITESPACE.source),
45284              'i'
45285            ),
45286
45287            // Match colors in format hsba(H, S%, B%, A), e.g. hsba(100, 40%, 28.9%, 0.5).
45288            HSBA: new RegExp(
45289              [
45290                '^hsba\\(',
45291                INTEGER.source,
45292                ',',
45293                PERCENT.source,
45294                ',',
45295                PERCENT.source,
45296                ',',
45297                DECIMAL.source,
45298                '\\)$'
45299              ].join(WHITESPACE.source),
45300              'i'
45301            )
45302          };
45303
45304          /**
45305           * For a number of different inputs, returns a color formatted as [r, g, b, a]
45306           * arrays, with each component normalized between 0 and 1.
45307           *
45308           * @private
45309           * @param {Array} [...args] An 'array-like' object that represents a list of
45310           *                          arguments
45311           * @return {Number[]}       a color formatted as [r, g, b, a]
45312           *                          Example:
45313           *                          input        ==> output
45314           *                          g            ==> [g, g, g, 255]
45315           *                          g,a          ==> [g, g, g, a]
45316           *                          r, g, b      ==> [r, g, b, 255]
45317           *                          r, g, b, a   ==> [r, g, b, a]
45318           *                          [g]          ==> [g, g, g, 255]
45319           *                          [g, a]       ==> [g, g, g, a]
45320           *                          [r, g, b]    ==> [r, g, b, 255]
45321           *                          [r, g, b, a] ==> [r, g, b, a]
45322           * @example
45323           * <div>
45324           * <code>
45325           * // todo
45326           * </code>
45327           * </div>
45328           *
45329           * @alt
45330           * //todo
45331           */
45332          _main.default.Color._parseInputs = function(r, g, b, a) {
45333            var numArgs = arguments.length;
45334            var mode = this.mode;
45335            var maxes = this.maxes[mode];
45336            var results = [];
45337            var i;
45338
45339            if (numArgs >= 3) {
45340              // Argument is a list of component values.
45341
45342              results[0] = r / maxes[0];
45343              results[1] = g / maxes[1];
45344              results[2] = b / maxes[2];
45345
45346              // Alpha may be undefined, so default it to 100%.
45347              if (typeof a === 'number') {
45348                results[3] = a / maxes[3];
45349              } else {
45350                results[3] = 1;
45351              }
45352
45353              // Constrain components to the range [0,1].
45354              // (loop backwards for performance)
45355              for (i = results.length - 1; i >= 0; --i) {
45356                var result = results[i];
45357                if (result < 0) {
45358                  results[i] = 0;
45359                } else if (result > 1) {
45360                  results[i] = 1;
45361                }
45362              }
45363
45364              // Convert to RGBA and return.
45365              if (mode === constants.HSL) {
45366                return _color_conversion.default._hslaToRGBA(results);
45367              } else if (mode === constants.HSB) {
45368                return _color_conversion.default._hsbaToRGBA(results);
45369              } else {
45370                return results;
45371              }
45372            } else if (numArgs === 1 && typeof r === 'string') {
45373              var str = r.trim().toLowerCase();
45374
45375              // Return if string is a named colour.
45376              if (namedColors[str]) {
45377                return _main.default.Color._parseInputs.call(this, namedColors[str]);
45378              }
45379
45380              // Try RGBA pattern matching.
45381              if (colorPatterns.HEX3.test(str)) {
45382                // #rgb
45383                results = colorPatterns.HEX3.exec(str)
45384                  .slice(1)
45385                  .map(function(color) {
45386                    return parseInt(color + color, 16) / 255;
45387                  });
45388                results[3] = 1;
45389                return results;
45390              } else if (colorPatterns.HEX6.test(str)) {
45391                // #rrggbb
45392                results = colorPatterns.HEX6.exec(str)
45393                  .slice(1)
45394                  .map(function(color) {
45395                    return parseInt(color, 16) / 255;
45396                  });
45397                results[3] = 1;
45398                return results;
45399              } else if (colorPatterns.HEX4.test(str)) {
45400                // #rgba
45401                results = colorPatterns.HEX4.exec(str)
45402                  .slice(1)
45403                  .map(function(color) {
45404                    return parseInt(color + color, 16) / 255;
45405                  });
45406                return results;
45407              } else if (colorPatterns.HEX8.test(str)) {
45408                // #rrggbbaa
45409                results = colorPatterns.HEX8.exec(str)
45410                  .slice(1)
45411                  .map(function(color) {
45412                    return parseInt(color, 16) / 255;
45413                  });
45414                return results;
45415              } else if (colorPatterns.RGB.test(str)) {
45416                // rgb(R,G,B)
45417                results = colorPatterns.RGB.exec(str)
45418                  .slice(1)
45419                  .map(function(color) {
45420                    return color / 255;
45421                  });
45422                results[3] = 1;
45423                return results;
45424              } else if (colorPatterns.RGB_PERCENT.test(str)) {
45425                // rgb(R%,G%,B%)
45426                results = colorPatterns.RGB_PERCENT.exec(str)
45427                  .slice(1)
45428                  .map(function(color) {
45429                    return parseFloat(color) / 100;
45430                  });
45431                results[3] = 1;
45432                return results;
45433              } else if (colorPatterns.RGBA.test(str)) {
45434                // rgba(R,G,B,A)
45435                results = colorPatterns.RGBA.exec(str)
45436                  .slice(1)
45437                  .map(function(color, idx) {
45438                    if (idx === 3) {
45439                      return parseFloat(color);
45440                    }
45441                    return color / 255;
45442                  });
45443                return results;
45444              } else if (colorPatterns.RGBA_PERCENT.test(str)) {
45445                // rgba(R%,G%,B%,A%)
45446                results = colorPatterns.RGBA_PERCENT.exec(str)
45447                  .slice(1)
45448                  .map(function(color, idx) {
45449                    if (idx === 3) {
45450                      return parseFloat(color);
45451                    }
45452                    return parseFloat(color) / 100;
45453                  });
45454                return results;
45455              }
45456
45457              // Try HSLA pattern matching.
45458              if (colorPatterns.HSL.test(str)) {
45459                // hsl(H,S,L)
45460                results = colorPatterns.HSL.exec(str)
45461                  .slice(1)
45462                  .map(function(color, idx) {
45463                    if (idx === 0) {
45464                      return parseInt(color, 10) / 360;
45465                    }
45466                    return parseInt(color, 10) / 100;
45467                  });
45468                results[3] = 1;
45469              } else if (colorPatterns.HSLA.test(str)) {
45470                // hsla(H,S,L,A)
45471                results = colorPatterns.HSLA.exec(str)
45472                  .slice(1)
45473                  .map(function(color, idx) {
45474                    if (idx === 0) {
45475                      return parseInt(color, 10) / 360;
45476                    } else if (idx === 3) {
45477                      return parseFloat(color);
45478                    }
45479                    return parseInt(color, 10) / 100;
45480                  });
45481              }
45482              results = results.map(function(value) {
45483                return Math.max(Math.min(value, 1), 0);
45484              });
45485              if (results.length) {
45486                return _color_conversion.default._hslaToRGBA(results);
45487              }
45488
45489              // Try HSBA pattern matching.
45490              if (colorPatterns.HSB.test(str)) {
45491                // hsb(H,S,B)
45492                results = colorPatterns.HSB.exec(str)
45493                  .slice(1)
45494                  .map(function(color, idx) {
45495                    if (idx === 0) {
45496                      return parseInt(color, 10) / 360;
45497                    }
45498                    return parseInt(color, 10) / 100;
45499                  });
45500                results[3] = 1;
45501              } else if (colorPatterns.HSBA.test(str)) {
45502                // hsba(H,S,B,A)
45503                results = colorPatterns.HSBA.exec(str)
45504                  .slice(1)
45505                  .map(function(color, idx) {
45506                    if (idx === 0) {
45507                      return parseInt(color, 10) / 360;
45508                    } else if (idx === 3) {
45509                      return parseFloat(color);
45510                    }
45511                    return parseInt(color, 10) / 100;
45512                  });
45513              }
45514
45515              if (results.length) {
45516                // (loop backwards for performance)
45517                for (i = results.length - 1; i >= 0; --i) {
45518                  results[i] = Math.max(Math.min(results[i], 1), 0);
45519                }
45520
45521                return _color_conversion.default._hsbaToRGBA(results);
45522              }
45523
45524              // Input did not match any CSS color pattern: default to white.
45525              results = [1, 1, 1, 1];
45526            } else if ((numArgs === 1 || numArgs === 2) && typeof r === 'number') {
45527              // 'Grayscale' mode.
45528
45529              /**
45530               * For HSB and HSL, interpret the gray level as a brightness/lightness
45531               * value (they are equivalent when chroma is zero). For RGB, normalize the
45532               * gray level according to the blue maximum.
45533               */
45534              results[0] = r / maxes[2];
45535              results[1] = r / maxes[2];
45536              results[2] = r / maxes[2];
45537
45538              // Alpha may be undefined, so default it to 100%.
45539              if (typeof g === 'number') {
45540                results[3] = g / maxes[3];
45541              } else {
45542                results[3] = 1;
45543              }
45544
45545              // Constrain components to the range [0,1].
45546              results = results.map(function(value) {
45547                return Math.max(Math.min(value, 1), 0);
45548              });
45549            } else {
45550              throw new Error(''.concat(arguments, 'is not a valid color representation.'));
45551            }
45552
45553            return results;
45554          };
45555          var _default = _main.default.Color;
45556          exports.default = _default;
45557        },
45558        { '../core/constants': 48, '../core/main': 59, './color_conversion': 44 }
45559      ],
45560      47: [
45561        function(_dereq_, module, exports) {
45562          'use strict';
45563          function _typeof(obj) {
45564            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
45565              _typeof = function _typeof(obj) {
45566                return typeof obj;
45567              };
45568            } else {
45569              _typeof = function _typeof(obj) {
45570                return obj &&
45571                  typeof Symbol === 'function' &&
45572                  obj.constructor === Symbol &&
45573                  obj !== Symbol.prototype
45574                  ? 'symbol'
45575                  : typeof obj;
45576              };
45577            }
45578            return _typeof(obj);
45579          }
45580          Object.defineProperty(exports, '__esModule', { value: true });
45581          exports.default = void 0;
45582
45583          var _main = _interopRequireDefault(_dereq_('../core/main'));
45584          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
45585          _dereq_('./p5.Color');
45586          function _getRequireWildcardCache() {
45587            if (typeof WeakMap !== 'function') return null;
45588            var cache = new WeakMap();
45589            _getRequireWildcardCache = function _getRequireWildcardCache() {
45590              return cache;
45591            };
45592            return cache;
45593          }
45594          function _interopRequireWildcard(obj) {
45595            if (obj && obj.__esModule) {
45596              return obj;
45597            }
45598            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
45599              return { default: obj };
45600            }
45601            var cache = _getRequireWildcardCache();
45602            if (cache && cache.has(obj)) {
45603              return cache.get(obj);
45604            }
45605            var newObj = {};
45606            var hasPropertyDescriptor =
45607              Object.defineProperty && Object.getOwnPropertyDescriptor;
45608            for (var key in obj) {
45609              if (Object.prototype.hasOwnProperty.call(obj, key)) {
45610                var desc = hasPropertyDescriptor
45611                  ? Object.getOwnPropertyDescriptor(obj, key)
45612                  : null;
45613                if (desc && (desc.get || desc.set)) {
45614                  Object.defineProperty(newObj, key, desc);
45615                } else {
45616                  newObj[key] = obj[key];
45617                }
45618              }
45619            }
45620            newObj.default = obj;
45621            if (cache) {
45622              cache.set(obj, newObj);
45623            }
45624            return newObj;
45625          }
45626          function _interopRequireDefault(obj) {
45627            return obj && obj.__esModule ? obj : { default: obj };
45628          } /**
45629           * @method background
45630           * @param {Number} gray   specifies a value between white and black
45631           * @param {Number} [a]
45632           * @chainable
45633           */ /**
45634           * @module Color
45635           * @submodule Setting
45636           * @for p5
45637           * @requires core
45638           * @requires constants
45639           */ /**
45640           * The <a href="#/p5/background">background()</a> function sets the color used
45641           * for the background of the p5.js canvas. The default background is transparent.
45642           * This function is typically used within <a href="#/p5/draw">draw()</a> to clear
45643           * the display window at the beginning of each frame, but it can be used inside
45644           * <a href="#/p5/setup">setup()</a> to set the background on the first frame of
45645           * animation or if the background need only be set once.
45646           *
45647           * The color is either specified in terms of the RGB, HSB, or HSL color depending
45648           * on the current <a href="#/p5/colorMode">
45648colorMode</a>. (The default color space
45649           * is RGB, with each value in the range from 0 to 255). The alpha range by default
45650           * is also 0 to 255.<br><br>
45651           *
45652           * If a single string argument is provided, RGB, RGBA and Hex CSS color strings
45653           * and all named color strings are supported. In this case, an alpha number
45654           * value as a second argument is not supported, the RGBA form should be used.
45655           *
45656           * A <a href="#/p5.Color">p5.Color</a> object can also be provided to set the background color.
45657           *
45658           * A <a href="#/p5.Image">p5.Image</a> can also be provided to set the background image.
45659           *
45660           * @method background
45661           * @param {p5.Color} color  any value created by the <a href="#/p5/color">color()</a> function
45662           * @chainable
45663           *
45664           * @example
45665           * <div>
45666           * <code>
45667           * // Grayscale integer value
45668           * background(51);
45669           * </code>
45670           * </div>
45671           *
45672           * <div>
45673           * <code>
45674           * // R, G & B integer values
45675           * background(255, 204, 0);
45676           * </code>
45677           * </div>
45678           *
45679           * <div>
45680           * <code>
45681           * // H, S & B integer values
45682           * colorMode(HSB);
45683           * background(255, 204, 100);
45684           * </code>
45685           * </div>
45686           *
45687           * <div>
45688           * <code>
45689           * // Named SVG/CSS color string
45690           * background('red');
45691           * </code>
45692           * </div>
45693           *
45694           * <div>
45695           * <code>
45696           * // three-digit hexadecimal RGB notation
45697           * background('#fae');
45698           * </code>
45699           * </div>
45700           *
45701           * <div>
45702           * <code>
45703           * // six-digit hexadecimal RGB notation
45704           * background('#222222');
45705           * </code>
45706           * </div>
45707           *
45708           * <div>
45709           * <code>
45710           * // integer RGB notation
45711           * background('rgb(0,255,0)');
45712           * </code>
45713           * </div>
45714           *
45715           * <div>
45716           * <code>
45717           * // integer RGBA notation
45718           * background('rgba(0,255,0, 0.25)');
45719           * </code>
45720           * </div>
45721           *
45722           * <div>
45723           * <code>
45724           * // percentage RGB notation
45725           * background('rgb(100%,0%,10%)');
45726           * </code>
45727           * </div>
45728           *
45729           * <div>
45730           * <code>
45731           * // percentage RGBA notation
45732           * background('rgba(100%,0%,100%,0.5)');
45733           * </code>
45734           * </div>
45735           *
45736           * <div>
45737           * <code>
45738           * // p5 Color object
45739           * background(color(0, 0, 255));
45740           * </code>
45741           * </div>
45742           *
45743           * @alt
45744           * canvas with darkest charcoal grey background.
45745           * canvas with yellow background.
45746           * canvas with royal blue background.
45747           * canvas with red background.
45748           * canvas with pink background.
45749           * canvas with black background.
45750           * canvas with bright green background.
45751           * canvas with soft green background.
45752           * canvas with red background.
45753           * canvas with light purple background.
45754           * canvas with blue background.
45755           */ /**
45756           * @method background
45757           * @param {String} colorstring color string, possible formats include: integer
45758           *                         rgb() or rgba(), percentage rgb() or rgba(),
45759           *                         3-digit hex, 6-digit hex
45760           * @param {Number} [a]         opacity of the background relative to current
45761           *                             color range (default is 0-255)
45762           * @chainable
45763           */
45764
45765          /**
45766           * @method background
45767           * @param {Number} v1     red or hue value (depending on the current color
45768           *                        mode)
45769           * @param {Number} v2     green or saturation value (depending on the current
45770           *                        color mode)
45771           * @param {Number} v3     blue or brightness value (depending on the current
45772           *                        color mode)
45773           * @param  {Number} [a]
45774           * @chainable
45775           */
45776
45777          /**
45778           * @method background
45779           * @param  {Number[]}      values  an array containing the red, green, blue
45780           *                                 and alpha components of the color
45781           * @chainable
45782           */
45783
45784          /**
45785           * @method background
45786           * @param {p5.Image} image     image created with <a href="#/p5/loadImage">loadImage()</a> or <a href="#/p5/createImage">createImage()</a>,
45787           *                             to set as background
45788           *                             (must be same size as the sketch window)
45789           * @param  {Number}  [a]
45790           * @chainable
45791           */
45792          _main.default.prototype.background = function() {
45793            var _this$_renderer;
45794            (_this$_renderer = this._renderer).background.apply(_this$_renderer, arguments);
45795            return this;
45796          };
45797
45798          /**
45799           * Clears the pixels within a buffer. This function only clears the canvas.
45800           * It will not clear objects created by createX() methods such as
45801           * <a href="#/p5/createVideo">createVideo()</a> or <a href="#/p5/createDiv">createDiv()</a>.
45802           * Unlike the main graphics context, pixels in additional graphics areas created
45803           * with <a href="#/p5/createGraphics">createGraphics()</a> can be entirely
45804           * or partially transparent. This function clears everything to make all of
45805           * the pixels 100% transparent.
45806           *
45807           * @method clear
45808           * @chainable
45809           * @example
45810           * <div>
45811           * <code>
45812           * // Clear the screen on mouse press.
45813           * function draw() {
45814           *   ellipse(mouseX, mouseY, 20, 20);
45815           * }
45816           * function mousePressed() {
45817           *   clear();
45818           *   background(128);
45819           * }
45820           * </code>
45821           * </div>
45822           *
45823           * @alt
45824           * small white ellipses are continually drawn at mouse's x and y coordinates.
45825           */
45826
45827          _main.default.prototype.clear = function() {
45828            this._renderer.clear();
45829            return this;
45830          };
45831
45832          /**
45833           * <a href="#/p5/colorMode">colorMode()</a> changes the way p5.js interprets
45834           * color data. By default, the parameters for <a href="#/p5/fill">fill()</a>,
45835           * <a href="#/p5/stroke">stroke()</a>, <a href="#/p5/background">background()</a>,
45836           * and <a href="#/p5/color">color()</a> are defined by values between 0 and 255
45837           * using the RGB color model. This is equivalent to setting colorMode(RGB, 255).
45838           * Setting colorMode(HSB) lets you use the HSB system instead. By default, this
45839           * is colorMode(HSB, 360, 100, 100, 1). You can also use HSL.
45840           *
45841           * Note: existing color objects remember the mode that they were created in,
45842           * so you can change modes as you like without affecting their appearance.
45843           *
45844           * @method colorMode
45845           * @param {Constant} mode   either RGB, HSB or HSL, corresponding to
45846           *                          Red/Green/Blue and Hue/Saturation/Brightness
45847           *                          (or Lightness)
45848           * @param {Number}  [max]  range for all values
45849           * @chainable
45850           *
45851           * @example
45852           * <div>
45853           * <code>
45854           * noStroke();
45855           * colorMode(RGB, 100);
45856           * for (let i = 0; i < 100; i++) {
45857           *   for (let j = 0; j < 100; j++) {
45858           *     stroke(i, j, 0);
45859           *     point(i, j);
45860           *   }
45861           * }
45862           * </code>
45863           * </div>
45864           *
45865           * <div>
45866           * <code>
45867           * noStroke();
45868           * colorMode(HSB, 100);
45869           * for (let i = 0; i < 100; i++) {
45870           *   for (let j = 0; j < 100; j++) {
45871           *     stroke(i, j, 100);
45872           *     point(i, j);
45873           *   }
45874           * }
45875           * </code>
45876           * </div>
45877           *
45878           * <div>
45879           * <code>
45880           * colorMode(RGB, 255);
45881           * let c = color(127, 255, 0);
45882           * colorMode(RGB, 1);
45883           * let myColor = c._getRed();
45884           * text(myColor, 10, 10, 80, 80);
45885           * </code>
45886           * </div>
45887           *
45888           * <div>
45889           * <code>
45890           * noFill();
45891           * colorMode(RGB, 255, 255, 255, 1);
45892           * background(255);
45893           * strokeWeight(4);
45894           * stroke(255, 0, 10, 0.3);
45895           * ellipse(40, 40, 50, 50);
45896           * ellipse(50, 50, 40, 40);
45897           * </code>
45898           * </div>
45899           *
45900           * @alt
45901           *Green to red gradient from bottom L to top R. shading originates from top left.
45902           *Rainbow gradient from left to right. Brightness increasing to white at top.
45903           *unknown image.
45904           *50x50 ellipse at middle L & 40x40 ellipse at center. Translucent pink outlines.
45905           */
45906
45907          /**
45908           * @method colorMode
45909           * @param {Constant} mode
45910           * @param {Number} max1     range for the red or hue depending on the
45911           *                              current color mode
45912           * @param {Number} max2     range for the green or saturation depending
45913           *                              on the current color mode
45914           * @param {Number} max3     range for the blue or brightness/lightness
45915           *                              depending on the current color mode
45916           * @param {Number} [maxA]   range for the alpha
45917           * @chainable
45918           */
45919          _main.default.prototype.colorMode = function(mode, max1, max2, max3, maxA) {
45920            _main.default._validateParameters('colorMode', arguments);
45921            if (
45922              mode === constants.RGB ||
45923              mode === constants.HSB ||
45924              mode === constants.HSL
45925            ) {
45926              // Set color mode.
45927              this._colorMode = mode;
45928
45929              // Set color maxes.
45930              var maxes = this._colorMaxes[mode];
45931              if (arguments.length === 2) {
45932                maxes[0] = max1; // Red
45933                maxes[1] = max1; // Green
45934                maxes[2] = max1; // Blue
45935                maxes[3] = max1; // Alpha
45936              } else if (arguments.length === 4) {
45937                maxes[0] = max1; // Red
45938                maxes[1] = max2; // Green
45939                maxes[2] = max3; // Blue
45940              } else if (arguments.length === 5) {
45941                maxes[0] = max1; // Red
45942                maxes[1] = max2; // Green
45943                maxes[2] = max3; // Blue
45944                maxes[3] = maxA; // Alpha
45945              }
45946            }
45947
45948            return this;
45949          };
45950
45951          /**
45952           * Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),
45953           * all shapes drawn after the fill command will be filled with the color orange.
45954           * This color is either specified in terms of the RGB or HSB color depending on
45955           * the current <a href="#/p5/colorMode">colorMode()</a>. (The default color space
45956           * is RGB, with each value in the range from 0 to 255). The alpha range by default
45957           * is also 0 to 255.
45958           *
45959           * If a single string argument is provided, RGB, RGBA and Hex CSS color strings
45960           * and all named color strings are supported. In this case, an alpha number
45961           * value as a second argument is not supported, the RGBA form should be used.
45962           *
45963           * A p5 <a href="#/p5.Color">Color</a> object can also be provided to set the fill color.
45964           *
45965           * @method fill
45966           * @param  {Number}        v1      red or hue value relative to
45967           *                                 the current color range
45968           * @param  {Number}        v2      green or saturation value
45969           *                                 relative to the current color range
45970           * @param  {Number}        v3      blue or brightness value
45971           *                                 relative to the current color range
45972           * @param  {Number}        [alpha]
45973           * @chainable
45974           * @example
45975           * <div>
45976           * <code>
45977           * // Grayscale integer value
45978           * fill(51);
45979           * rect(20, 20, 60, 60);
45980           * </code>
45981           * </div>
45982           *
45983           * <div>
45984           * <code>
45985           * // R, G & B integer values
45986           * fill(255, 204, 0);
45987           * rect(20, 20, 60, 60);
45988           * </code>
45989           * </div>
45990           *
45991           * <div>
45992           * <code>
45993           * // H, S & B integer values
45994           * colorMode(HSB);
45995           * fill(255, 204, 100);
45996           * rect(20, 20, 60, 60);
45997           * </code>
45998           * </div>
45999           *
46000           * <div>
46001           * <code>
46002           * // Named SVG/CSS color string
46003           * fill('red');
46004           * rect(20, 20, 60, 60);
46005           * </code>
46006           * </div>
46007           *
46008           * <div>
46009           * <code>
46010           * // three-digit hexadecimal RGB notation
46011           * fill('#fae');
46012           * rect(20, 20, 60, 60);
46013           * </code>
46014           * </div>
46015           *
46016           * <div>
46017           * <code>
46018           * // six-digit hexadecimal RGB notation
46019           * fill('#222222');
46020           * rect(20, 20, 60, 60);
46021           * </code>
46022           * </div>
46023           *
46024           * <div>
46025           * <code>
46026           * // integer RGB notation
46027           * fill('rgb(0,255,0)');
46028           * rect(20, 20, 60, 60);
46029           * </code>
46030           * </div>
46031           *
46032           * <div>
46033           * <code>
46034           * // integer RGBA notation
46035           * fill('rgba(0,255,0, 0.25)');
46036           * rect(20, 20, 60, 60);
46037           * </code>
46038           * </div>
46039           *
46040           * <div>
46041           * <code>
46042           * // percentage RGB notation
46043           * fill('rgb(100%,0%,10%)');
46044           * rect(20, 20, 60, 60);
46045           * </code>
46046           * </div>
46047           *
46048           * <div>
46049           * <code>
46050           * // percentage RGBA notation
46051           * fill('rgba(100%,0%,100%,0.5)');
46052           * rect(20, 20, 60, 60);
46053           * </code>
46054           * </div>
46055           *
46056           * <div>
46057           * <code>
46058           * // p5 Color object
46059           * fill(color(0, 0, 255));
46060           * rect(20, 20, 60, 60);
46061           * </code>
46062           * </div>
46063           *
46064           * @alt
46065           * 60x60 dark charcoal grey rect with black outline in center of canvas.
46066           * 60x60 yellow rect with black outline in center of canvas.
46067           * 60x60 royal blue rect with black outline in center of canvas.
46068           * 60x60 red rect with black outline in center of canvas.
46069           * 60x60 pink rect with black outline in center of canvas.
46070           * 60x60 black rect with black outline in center of canvas.
46071           * 60x60 light green rect with black outline in center of canvas.
46072           * 60x60 soft green rect with black outline in center of canvas.
46073           * 60x60 red rect with black outline in center of canvas.
46074           * 60x60 dark fuchsia rect with black outline in center of canvas.
46075           * 60x60 blue rect with black outline in center of canvas.
46076           */
46077
46078          /**
46079           * @method fill
46080           * @param  {String}        value   a color string
46081           * @chainable
46082           */
46083
46084          /**
46085           * @method fill
46086           * @param  {Number}        gray   a gray value
46087           * @param  {Number}        [alpha]
46088           * @chainable
46089           */
46090
46091          /**
46092           * @method fill
46093           * @param  {Number[]}      values  an array containing the red,green,blue &
46094           *                                 and alpha components of the color
46095           * @chainable
46096           */
46097
46098          /**
46099           * @method fill
46100           * @param  {p5.Color}      color   the fill color
46101           * @chainable
46102           */
46103          _main.default.prototype.fill = function() {
46104            var _this$_renderer2;
46105            this._renderer._setProperty('_fillSet', true);
46106            this._renderer._setProperty('_doFill', true);
46107            (_this$_renderer2 = this._renderer).fill.apply(_this$_renderer2, arguments);
46108            return this;
46109          };
46110
46111          /**
46112           * Disables filling geometry. If both <a href="#/p5/noStroke">noStroke()</a> and <a href="#/p5/noFill">noFill()</a> are called,
46113           * nothing will be drawn to the screen.
46114           *
46115           * @method noFill
46116           * @chainable
46117           * @example
46118           * <div>
46119           * <code>
46120           * rect(15, 10, 55, 55);
46121           * noFill();
46122           * rect(20, 20, 60, 60);
46123           * </code>
46124           * </div>
46125           *
46126           * <div modernizr='webgl'>
46127           * <code>
46128           * function setup() {
46129           *   createCanvas(100, 100, WEBGL);
46130           * }
46131           *
46132           * function draw() {
46133           *   background(0);
46134           *   noFill();
46135           *   stroke(100, 100, 240);
46136           *   rotateX(frameCount * 0.01);
46137           *   rotateY(frameCount * 0.01);
46138           *   box(45, 45, 45);
46139           * }
46140           * </code>
46141           * </div>
46142           *
46143           * @alt
46144           * white rect top middle and noFill rect center. Both 60x60 with black outlines.
46145           * black canvas with purple cube wireframe spinning
46146           */
46147          _main.default.prototype.noFill = function() {
46148            this._renderer._setProperty('_doFill', false);
46149            return this;
46150          };
46151
46152          /**
46153           * Disables drawing the stroke (outline). If both <a href="#/p5/noStroke">noStroke()</a> and <a href="#/p5/noFill">noFill()</a>
46154           * are called, nothing will be drawn to the screen.
46155           *
46156           * @method noStroke
46157           * @chainable
46158           * @example
46159           * <div>
46160           * <code>
46161           * noStroke();
46162           * rect(20, 20, 60, 60);
46163           * </code>
46164           * </div>
46165           *
46166           * <div modernizr='webgl'>
46167           * <code>
46168           * function setup() {
46169           *   createCanvas(100, 100, WEBGL);
46170           * }
46171           *
46172           * function draw() {
46173           *   background(0);
46174           *   noStroke();
46175           *   fill(240, 150, 150);
46176           *   rotateX(frameCount * 0.01);
46177           *   rotateY(frameCount * 0.01);
46178           *   box(45, 45, 45);
46179           * }
46180           * </code>
46181           * </div>
46182           *
46183           * @alt
46184           * 60x60 white rect at center. no outline.
46185           * black canvas with pink cube spinning
46186           */
46187          _main.default.prototype.noStroke = function() {
46188            this._renderer._setProperty('_doStroke', false);
46189            return this;
46190          };
46191
46192          /**
46193           * Sets the color used to draw lines and borders around shapes. This color
46194           * is either specified in terms of the RGB or HSB color depending on the
46195           * current <a href="#/p5/colorMode">colorMode()</a> (the default color space
46196           * is RGB, with each value in the range from 0 to 255). The alpha range by
46197           * default is also 0 to 255.
46198           *
46199           * If a single string argument is provided, RGB, RGBA and Hex CSS color
46200           * strings and all named color strings are supported. In this case, an alpha
46201           * number value as a second argument is not supported, the RGBA form should be
46202           * used.
46203           *
46204           * A p5 <a href="#/p5.Color">Color</a> object can also be provided to set the stroke color.
46205           *
46206           * @method stroke
46207           * @param  {Number}        v1      red or hue value relative to
46208           *                                 the current color range
46209           * @param  {Number}        v2      green or saturation value
46210           *                                 relative to the current color range
46211           * @param  {Number}        v3      blue or brightness value
46212           *                                 relative to the current color range
46213           * @param  {Number}        [alpha]
46214           * @chainable
46215           *
46216           * @example
46217           * <div>
46218           * <code>
46219           * // Grayscale integer value
46220           * strokeWeight(4);
46221           * stroke(51);
46222           * rect(20, 20, 60, 60);
46223           * </code>
46224           * </div>
46225           *
46226           * <div>
46227           * <code>
46228           * // R, G & B integer values
46229           * stroke(255, 204, 0);
46230           * strokeWeight(4);
46231           * rect(20, 20, 60, 60);
46232           * </code>
46233           * </div>
46234           *
46235           * <div>
46236           * <code>
46237           * // H, S & B integer values
46238           * colorMode(HSB);
46239           * strokeWeight(4);
46240           * stroke(255, 204, 100);
46241           * rect(20, 20, 60, 60);
46242           * </code>
46243           * </div>
46244           *
46245           * <div>
46246           * <code>
46247           * // Named SVG/CSS color string
46248           * stroke('red');
46249           * strokeWeight(4);
46250           * rect(20, 20, 60, 60);
46251           * </code>
46252           * </div>
46253           *
46254           * <div>
46255           * <code>
46256           * // three-digit hexadecimal RGB notation
46257           * stroke('#fae');
46258           * strokeWeight(4);
46259           * rect(20, 20, 60, 60);
46260           * </code>
46261           * </div>
46262           *
46263           * <div>
46264           * <code>
46265           * // six-digit hexadecimal RGB notation
46266           * stroke('#222222');
46267           * strokeWeight(4);
46268           * rect(20, 20, 60, 60);
46269           * </code>
46270           * </div>
46271           *
46272           * <div>
46273           * <code>
46274           * // integer RGB notation
46275           * stroke('rgb(0,255,0)');
46276           * strokeWeight(4);
46277           * rect(20, 20, 60, 60);
46278           * </code>
46279           * </div>
46280           *
46281           * <div>
46282           * <code>
46283           * // integer RGBA notation
46284           * stroke('rgba(0,255,0,0.25)');
46285           * strokeWeight(4);
46286           * rect(20, 20, 60, 60);
46287           * </code>
46288           * </div>
46289           *
46290           * <div>
46291           * <code>
46292           * // percentage RGB notation
46293           * stroke('rgb(100%,0%,10%)');
46294           * strokeWeight(4);
46295           * rect(20, 20, 60, 60);
46296           * </code>
46297           * </div>
46298           *
46299           * <div>
46300           * <code>
46301           * // percentage RGBA notation
46302           * stroke('rgba(100%,0%,100%,0.5)');
46303           * strokeWeight(4);
46304           * rect(20, 20, 60, 60);
46305           * </code>
46306           * </div>
46307           *
46308           * <div>
46309           * <code>
46310           * // p5 Color object
46311           * stroke(color(0, 0, 255));
46312           * strokeWeight(4);
46313           * rect(20, 20, 60, 60);
46314           * </code>
46315           * </div>
46316           *
46317           * @alt
46318           * 60x60 white rect at center. Dark charcoal grey outline.
46319           * 60x60 white rect at center. Yellow outline.
46320           * 60x60 white rect at center. Royal blue outline.
46321           * 60x60 white rect at center. Red outline.
46322           * 60x60 white rect at center. Pink outline.
46323           * 60x60 white rect at center. Black outline.
46324           * 60x60 white rect at center. Bright green outline.
46325           * 60x60 white rect at center. Soft green outline.
46326           * 60x60 white rect at center. Red outline.
46327           * 60x60 white rect at center. Dark fuchsia outline.
46328           * 60x60 white rect at center. Blue outline.
46329           */
46330
46331          /**
46332           * @method stroke
46333           * @param  {String}        value   a color string
46334           * @chainable
46335           */
46336
46337          /**
46338           * @method stroke
46339           * @param  {Number}        gray   a gray value
46340           * @param  {Number}        [alpha]
46341           * @chainable
46342           */
46343
46344          /**
46345           * @method stroke
46346           * @param  {Number[]}      values  an array containing the red,green,blue &
46347           *                                 and alpha components of the color
46348           * @chainable
46349           */
46350
46351          /**
46352           * @method stroke
46353           * @param  {p5.Color}      color   the stroke color
46354           * @chainable
46355           */
46356
46357          _main.default.prototype.stroke = function() {
46358            var _this$_renderer3;
46359            this._renderer._setProperty('_strokeSet', true);
46360            this._renderer._setProperty('_doStroke', true);
46361            (_this$_renderer3 = this._renderer).stroke.apply(_this$_renderer3, arguments);
46362            return this;
46363          };
46364
46365          /**
46366           * All drawing that follows <a href="#/p5/erase">erase()</a> will subtract from
46367           * the canvas.Erased areas will reveal the web page underneath the canvas.Erasing
46368           * can be canceled with <a href="#/p5/noErase">noErase()</a>.
46369           *
46370           * Drawing done with <a href="#/p5/image">image()</a> and <a href="#/p5/background">
46371           * background()</a> in between <a href="#/p5/erase">erase()</a> and
46372           * <a href="#/p5/noErase">noErase()</a> will not erase the canvas but works as usual.
46373           *
46374           * @method erase
46375           * @param  {Number}   [strengthFill]      A number (0-255) for the strength of erasing for a shape's fill.
46376           *                                        This will default to 255 when no argument is given, which
46377           *                                        is full strength.
46378           * @param  {Number}   [strengthStroke]    A number (0-255) for the strength of erasing for a shape's stroke.
46379           *                                        This will default to 255 when no argument is given, which
46380           *                                        is full strength.
46381           *
46382           * @chainable
46383           * @example
46384           * <div>
46385           * <code>
46386           * background(100, 100, 250);
46387           * fill(250, 100, 100);
46388           * rect(20, 20, 60, 60);
46389           * erase();
46390           * ellipse(25, 30, 30);
46391           * noErase();
46392           * </code>
46393           * </div>
46394           *
46395           * <div>
46396           * <code>
46397           * background(150, 250, 150);
46398           * fill(100, 100, 250);
46399           * rect(20, 20, 60, 60);
46400           * strokeWeight(5);
46401           * erase(150, 255);
46402           * triangle(50, 10, 70, 50, 90, 10);
46403           * noErase();
46404           * </code>
46405           * </div>
46406           *
46407           * <div>
46408           * <code>
46409           * function setup() {
46410           *   smooth();
46411           *   createCanvas(100, 100, WEBGL);
46412           *   // Make a &lt;p&gt; element and put it behind the canvas
46413           *   let p = createP('I am a dom element');
46414           *   p.center();
46415           *   p.style('font-size', '20px');
46416           *   p.style('text-align', 'center');
46417           *   p.style('z-index', '-9999');
46418           * }
46419           *
46420           * function draw() {
46421           *   background(250, 250, 150);
46422           *   fill(15, 195, 185);
46423           *   noStroke();
46424           *   sphere(30);
46425           *   erase();
46426           *   rotateY(frameCount * 0.02);
46427           *   translate(0, 0, 40);
46428           *   torus(15, 5);
46429           *   noErase();
46430           * }
46431           * </code>
46432           * </div>
46433           *
46434           * @alt
46435           * 60x60 centered pink rect, purple background. Elliptical area in top-left of rect is erased white.
46436           * 60x60 centered purple rect, mint green background. Triangle in top-right is partially erased with fully erased outline.
46437           * 60x60 centered teal sphere, yellow background. Torus rotating around sphere erases to reveal black text underneath.
46438           */
46439          _main.default.prototype.erase = function() {
46440            var opacityFill =
46441              arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 255;
46442            var opacityStroke =
46443              arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 255;
46444            this._renderer.erase(opacityFill, opacityStroke);
46445
46446            return this;
46447          };
46448
46449          /**
46450           * Ends erasing that was started with <a href="#/p5/erase">erase()</a>.
46451           * The <a href="#/p5/fill">fill()</a>, <a href="#/p5/stroke">stroke()</a>, and
46452           * <a href="#/p5/blendMode">blendMode()</a> settings will return to what they were
46453           * prior to calling <a href="#/p5/erase">erase()</a>.
46454           *
46455           * @method noErase
46456           * @chainable
46457           * @example
46458           * <div>
46459           * <code>
46460           * background(235, 145, 15);
46461           * noStroke();
46462           * fill(30, 45, 220);
46463           * rect(30, 10, 10, 80);
46464           * erase();
46465           * ellipse(50, 50, 60);
46466           * noErase();
46467           * rect(70, 10, 10, 80);
46468           * </code>
46469           * </div>
46470           *
46471           * @alt
46472           * Orange background, with two tall blue rectangles. A centered ellipse erased the first blue rect but not the second.
46473           */
46474
46475          _main.default.prototype.noErase = function() {
46476            this._renderer.noErase();
46477            return this;
46478          };
46479          var _default = _main.default;
46480          exports.default = _default;
46481        },
46482        { '../core/constants': 48, '../core/main': 59, './p5.Color': 46 }
46483      ],
46484      48: [
46485        function(_dereq_, module, exports) {
46486          'use strict';
46487          Object.defineProperty(exports, '__esModule', { value: true });
46488          exports.FILL = exports.STROKE = exports.CURVE = exports.BEZIER = exports.QUADRATIC = exports.LINEAR = exports._CTX_MIDDLE = exports._DEFAULT_LEADMULT = exports._DEFAULT_TEXT_FILL = exports.BOLDITALIC = exports.BOLD = exports.ITALIC = exports.NORMAL = exports.BLUR = exports.ERODE = exports.DILATE = exports.POSTERIZE = exports.INVERT = exports.OPAQUE = exports.GRAY = exports.THRESHOLD = exports.BURN = exports.DODGE = exports.SOFT_LIGHT = exports.HARD_LIGHT = exports.OVERLAY = exports.REPLACE = exports.SCREEN = exports.MULTIPLY = exports.EXCLUSION = exports.SUBTRACT = exports.DIFFERENCE = exports.LIGHTEST = exports.DARKEST = exports.ADD = exports.REMOVE = exports.BLEND = exports.UP_ARROW = exports.TAB = exports.SHIFT = exports.RIGHT_ARROW = exports.RETURN = exports.OPTION = exports.LEFT_ARROW = exports.ESCAPE = exports.ENTER = exports.DOWN_ARROW = exports.DELETE = exports.CONTROL = exports.BACKSPACE = exports.ALT = exports.AUTO = exports.HSL = exports.HSB = exports.RGB = exports.MITER = exports.BEVEL = exports.ROUND = exp
46488orts.SQUARE = exports.PROJECT = exports.PIE = exports.CHORD = exports.OPEN = exports.CLOSE = exports.TESS = exports.QUAD_STRIP = exports.QUADS = exports.TRIANGLE_STRIP = exports.TRIANGLE_FAN = exports.TRIANGLES = exports.LINE_LOOP = exports.LINE_STRIP = exports.LINES = exports.POINTS = exports.BASELINE = exports.BOTTOM = exports.TOP = exports.CENTER = exports.LEFT = exports.RIGHT = exports.RADIUS = exports.CORNERS = exports.CORNER = exports.RAD_TO_DEG = exports.DEG_TO_RAD = exports.RADIANS = exports.DEGREES = exports.TWO_PI = exports.TAU = exports.QUARTER_PI = exports.PI = exports.HALF_PI = exports.WAIT = exports.TEXT = exports.MOVE = exports.HAND = exports.CROSS = exports.ARROW = exports.WEBGL = exports.P2D = void 0;
46489          exports.FALLBACK = exports.LABEL = exports.AXES = exports.GRID = exports._DEFAULT_FILL = exports._DEFAULT_STROKE = exports.PORTRAIT = exports.LANDSCAPE = exports.MIRROR = exports.CLAMP = exports.REPEAT = exports.NEAREST = exports.IMAGE = exports.IMMEDIATE = exports.TEXTURE = void 0; /**
46490           * @module Constants
46491           * @submodule Constants
46492           * @for p5
46493           */
46494
46495          var _PI = Math.PI;
46496
46497          // GRAPHICS RENDERER
46498          /**
46499           * The default, two-dimensional renderer.
46500           * @property {String} P2D
46501           * @final
46502           */
46503          var P2D = 'p2d';
46504          /**
46505           * One of the two render modes in p5.js: P2D (default renderer) and WEBGL
46506           * Enables 3D render by introducing the third dimension: Z
46507           * @property {String} WEBGL
46508           * @final
46509           */ exports.P2D = P2D;
46510          var WEBGL = 'webgl';
46511
46512          // ENVIRONMENT
46513          /**
46514           * @property {String} ARROW
46515           * @final
46516           */ exports.WEBGL = WEBGL;
46517          var ARROW = 'default';
46518          /**
46519           * @property {String} CROSS
46520           * @final
46521           */ exports.ARROW = ARROW;
46522          var CROSS = 'crosshair';
46523          /**
46524           * @property {String} HAND
46525           * @final
46526           */ exports.CROSS = CROSS;
46527          var HAND = 'pointer';
46528          /**
46529           * @property {String} MOVE
46530           * @final
46531           */ exports.HAND = HAND;
46532          var MOVE = 'move';
46533          /**
46534           * @property {String} TEXT
46535           * @final
46536           */ exports.MOVE = MOVE;
46537          var TEXT = 'text';
46538          /**
46539           * @property {String} WAIT
46540           * @final
46541           */ exports.TEXT = TEXT;
46542          var WAIT = 'wait';
46543
46544          // TRIGONOMETRY
46545
46546          /**
46547           * HALF_PI is a mathematical constant with the value
46548           * 1.57079632679489661923. It is half the ratio of the
46549           * circumference of a circle to its diameter. It is useful in
46550           * combination with the trigonometric functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
46551           *
46552           * @property {Number} HALF_PI
46553           * @final
46554           *
46555           * @example
46556           * <div><code>
46557           * arc(50, 50, 80, 80, 0, HALF_PI);
46558           * </code></div>
46559           *
46560           * @alt
46561           * 80x80 white quarter-circle with curve toward bottom right of canvas.
46562           */ exports.WAIT = WAIT;
46563          var HALF_PI = _PI / 2;
46564          /**
46565           * PI is a mathematical constant with the value
46566           * 3.14159265358979323846. It is the ratio of the circumference
46567           * of a circle to its diameter. It is useful in combination with
46568           * the trigonometric functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
46569           *
46570           * @property {Number} PI
46571           * @final
46572           *
46573           * @example
46574           * <div><code>
46575           * arc(50, 50, 80, 80, 0, PI);
46576           * </code></div>
46577           *
46578           * @alt
46579           * white half-circle with curve toward bottom of canvas.
46580           */ exports.HALF_PI = HALF_PI;
46581          var PI = _PI;
46582          /**
46583           * QUARTER_PI is a mathematical constant with the value 0.7853982.
46584           * It is one quarter the ratio of the circumference of a circle to
46585           * its diameter. It is useful in combination with the trigonometric
46586           * functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
46587           *
46588           * @property {Number} QUARTER_PI
46589           * @final
46590           *
46591           * @example
46592           * <div><code>
46593           * arc(50, 50, 80, 80, 0, QUARTER_PI);
46594           * </code></div>
46595           *
46596           * @alt
46597           * white eighth-circle rotated about 40 degrees with curve bottom right canvas.
46598           */ exports.PI = PI;
46599          var QUARTER_PI = _PI / 4;
46600          /**
46601           * TAU is an alias for TWO_PI, a mathematical constant with the
46602           * value 6.28318530717958647693. It is twice the ratio of the
46603           * circumference of a circle to its diameter. It is useful in
46604           * combination with the trigonometric functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
46605           *
46606           * @property {Number} TAU
46607           * @final
46608           *
46609           * @example
46610           * <div><code>
46611           * arc(50, 50, 80, 80, 0, TAU);
46612           * </code></div>
46613           *
46614           * @alt
46615           * 80x80 white ellipse shape in center of canvas.
46616           */ exports.QUARTER_PI = QUARTER_PI;
46617          var TAU = _PI * 2;
46618          /**
46619           * TWO_PI is a mathematical constant with the value
46620           * 6.28318530717958647693. It is twice the ratio of the
46621           * circumference of a circle to its diameter. It is useful in
46622           * combination with the trigonometric functions <a href="#/p5/sin">sin()</a> and <a href="#/p5/cos">cos()</a>.
46623           *
46624           * @property {Number} TWO_PI
46625           * @final
46626           *
46627           * @example
46628           * <div><code>
46629           * arc(50, 50, 80, 80, 0, TWO_PI);
46630           * </code></div>
46631           *
46632           * @alt
46633           * 80x80 white ellipse shape in center of canvas.
46634           */ exports.TAU = TAU;
46635          var TWO_PI = _PI * 2;
46636          /**
46637           * Constant to be used with <a href="#/p5/angleMode">angleMode()</a> function, to set the mode which
46638           * p5.js interprates and calculates angles (either DEGREES or RADIANS).
46639           * @property {String} DEGREES
46640           * @final
46641           *
46642           * @example
46643           * <div class='norender'><code>
46644           * function setup() {
46645           *   angleMode(DEGREES);
46646           * }
46647           * </code></div>
46648           */ exports.TWO_PI = TWO_PI;
46649          var DEGREES = 'degrees';
46650          /**
46651           * Constant to be used with <a href="#/p5/angleMode">angleMode()</a> function, to set the mode which
46652           * p5.js interprates and calculates angles (either RADIANS or DEGREES).
46653           * @property {String} RADIANS
46654           * @final
46655           *
46656           * @example
46657           * <div class='norender'><code>
46658           * function setup() {
46659           *   angleMode(RADIANS);
46660           * }
46661           * </code></div>
46662           */ exports.DEGREES = DEGREES;
46663          var RADIANS = 'radians';
46664          exports.RADIANS = RADIANS;
46665          var DEG_TO_RAD = _PI / 180.0;
46666          exports.DEG_TO_RAD = DEG_TO_RAD;
46667          var RAD_TO_DEG = 180.0 / _PI;
46668
46669          // SHAPE
46670          /**
46671           * @property {String} CORNER
46672           * @final
46673           */ exports.RAD_TO_DEG = RAD_TO_DEG;
46674          var CORNER = 'corner';
46675          /**
46676           * @property {String} CORNERS
46677           * @final
46678           */ exports.CORNER = CORNER;
46679          var CORNERS = 'corners';
46680          /**
46681           * @property {String} RADIUS
46682           * @final
46683           */ exports.CORNERS = CORNERS;
46684          var RADIUS = 'radius';
46685          /**
46686           * @property {String} RIGHT
46687           * @final
46688           */ exports.RADIUS = RADIUS;
46689          var RIGHT = 'right';
46690          /**
46691           * @property {String} LEFT
46692           * @final
46693           */ exports.RIGHT = RIGHT;
46694          var LEFT = 'left';
46695          /**
46696           * @property {String} CENTER
46697           * @final
46698           */ exports.LEFT = LEFT;
46699          var CENTER = 'center';
46700          /**
46701           * @property {String} TOP
46702           * @final
46703           */ exports.CENTER = CENTER;
46704          var TOP = 'top';
46705          /**
46706           * @property {String} BOTTOM
46707           * @final
46708           */ exports.TOP = TOP;
46709          var BOTTOM = 'bottom';
46710          /**
46711           * @property {String} BASELINE
46712           * @final
46713           * @default alphabetic
46714           */ exports.BOTTOM = BOTTOM;
46715          var BASELINE = 'alphabetic';
46716          /**
46717           * @property {Number} POINTS
46718           * @final
46719           * @default 0x0000
46720           */ exports.BASELINE = BASELINE;
46721          var POINTS = 0x0000;
46722          /**
46723           * @property {Number} LINES
46724           * @final
46725           * @default 0x0001
46726           */ exports.POINTS = POINTS;
46727          var LINES = 0x0001;
46728          /**
46729           * @property {Number} LINE_STRIP
46730           * @final
46731           * @default 0x0003
46732           */ exports.LINES = LINES;
46733          var LINE_STRIP = 0x0003;
46734          /**
46735           * @property {Number} LINE_LOOP
46736           * @final
46737           * @default 0x0002
46738           */ exports.LINE_STRIP = LINE_STRIP;
46739          var LINE_LOOP = 0x0002;
46740          /**
46741           * @property {Number} TRIANGLES
46742           * @final
46743           * @default 0x0004
46744           */ exports.LINE_LOOP = LINE_LOOP;
46745          var TRIANGLES = 0x0004;
46746          /**
46747           * @property {Number} TRIANGLE_FAN
46748           * @final
46749           * @default 0x0006
46750           */ exports.TRIANGLES = TRIANGLES;
46751          var TRIANGLE_FAN = 0x0006;
46752          /**
46753           * @property {Number} TRIANGLE_STRIP
46754           * @final
46755           * @default 0x0005
46756           */ exports.TRIANGLE_FAN = TRIANGLE_FAN;
46757          var TRIANGLE_STRIP = 0x0005;
46758          /**
46759           * @property {String} QUADS
46760           * @final
46761           */ exports.TRIANGLE_STRIP = TRIANGLE_STRIP;
46762          var QUADS = 'quads';
46763          /**
46764           * @property {String} QUAD_STRIP
46765           * @final
46766           * @default quad_strip
46767           */ exports.QUADS = QUADS;
46768          var QUAD_STRIP = 'quad_strip';
46769          /**
46770           * @property {String} TESS
46771           * @final
46772           * @default tess
46773           */ exports.QUAD_STRIP = QUAD_STRIP;
46774          var TESS = 'tess';
46775          /**
46776           * @property {String} CLOSE
46777           * @final
46778           */ exports.TESS = TESS;
46779          var CLOSE = 'close';
46780          /**
46781           * @property {String} OPEN
46782           * @final
46783           */ exports.CLOSE = CLOSE;
46784          var OPEN = 'open';
46785          /**
46786           * @property {String} CHORD
46787           * @final
46788           */ exports.OPEN = OPEN;
46789          var CHORD = 'chord';
46790          /**
46791           * @property {String} PIE
46792           * @final
46793           */ exports.CHORD = CHORD;
46794          var PIE = 'pie';
46795          /**
46796           * @property {String} PROJECT
46797           * @final
46798           * @default square
46799           */ exports.PIE = PIE;
46800          var PROJECT = 'square'; // PEND: careful this is counterintuitive
46801          /**
46802           * @property {String} SQUARE
46803           * @final
46804           * @default butt
46805           */ exports.PROJECT = PROJECT;
46806          var SQUARE = 'butt';
46807          /**
46808           * @property {String} ROUND
46809           * @final
46810           */ exports.SQUARE = SQUARE;
46811          var ROUND = 'round';
46812          /**
46813           * @property {String} BEVEL
46814           * @final
46815           */ exports.ROUND = ROUND;
46816          var BEVEL = 'bevel';
46817          /**
46818           * @property {String} MITER
46819           * @final
46820           */ exports.BEVEL = BEVEL;
46821          var MITER = 'miter';
46822
46823          // COLOR
46824          /**
46825           * @property {String} RGB
46826           * @final
46827           */ exports.MITER = MITER;
46828          var RGB = 'rgb';
46829          /**
46830           * HSB (hue, saturation, brightness) is a type of color model.
46831           * You can learn more about it at
46832           * <a href="https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html">HSB</a>.
46833           *
46834           * @property {String} HSB
46835           * @final
46836           */ exports.RGB = RGB;
46837          var HSB = 'hsb';
46838          /**
46839           * @property {String} HSL
46840           * @final
46841           */ exports.HSB = HSB;
46842          var HSL = 'hsl';
46843
46844          // DOM EXTENSION
46845          /**
46846           * AUTO allows us to automatically set the width or height of an element (but not both),
46847           * based on the current height and width of the element. Only one parameter can
46848           * be passed to the <a href="/#/p5.Element/size">size</a> function as AUTO, at a time.
46849           *
46850           * @property {String} AUTO
46851           * @final
46852           */ exports.HSL = HSL;
46853          var AUTO = 'auto';
46854
46855          /**
46856           * @property {Number} ALT
46857           * @final
46858           */
46859          // INPUT
46860          exports.AUTO = AUTO;
46861          var ALT = 18;
46862          /**
46863           * @property {Number} BACKSPACE
46864           * @final
46865           */ exports.ALT = ALT;
46866          var BACKSPACE = 8;
46867          /**
46868           * @property {Number} CONTROL
46869           * @final
46870           */ exports.BACKSPACE = BACKSPACE;
46871          var CONTROL = 17;
46872          /**
46873           * @property {Number} DELETE
46874           * @final
46875           */ exports.CONTROL = CONTROL;
46876          var DELETE = 46;
46877          /**
46878           * @property {Number} DOWN_ARROW
46879           * @final
46880           */ exports.DELETE = DELETE;
46881          var DOWN_ARROW = 40;
46882          /**
46883           * @property {Number} ENTER
46884           * @final
46885           */ exports.DOWN_ARROW = DOWN_ARROW;
46886          var ENTER = 13;
46887          /**
46888           * @property {Number} ESCAPE
46889           * @final
46890           */ exports.ENTER = ENTER;
46891          var ESCAPE = 27;
46892          /**
46893           * @property {Number} LEFT_ARROW
46894           * @final
46895           */ exports.ESCAPE = ESCAPE;
46896          var LEFT_ARROW = 37;
46897          /**
46898           * @property {Number} OPTION
46899           * @final
46900           */ exports.LEFT_ARROW = LEFT_ARROW;
46901          var OPTION = 18;
46902          /**
46903           * @property {Number} RETURN
46904           * @final
46905           */ exports.OPTION = OPTION;
46906          var RETURN = 13;
46907          /**
46908           * @property {Number} RIGHT_ARROW
46909           * @final
46910           */ exports.RETURN = RETURN;
46911          var RIGHT_ARROW = 39;
46912          /**
46913           * @property {Number} SHIFT
46914           * @final
46915           */ exports.RIGHT_ARROW = RIGHT_ARROW;
46916          var SHIFT = 16;
46917          /**
46918           * @property {Number} TAB
46919           * @final
46920           */ exports.SHIFT = SHIFT;
46921          var TAB = 9;
46922          /**
46923           * @property {Number} UP_ARROW
46924           * @final
46925           */ exports.TAB = TAB;
46926          var UP_ARROW = 38;
46927
46928          // RENDERING
46929          /**
46930           * @property {String} BLEND
46931           * @final
46932           * @default source-over
46933           */ exports.UP_ARROW = UP_ARROW;
46934          var BLEND = 'source-over';
46935          /**
46936           * @property {String} REMOVE
46937           * @final
46938           * @default destination-out
46939           */ exports.BLEND = BLEND;
46940          var REMOVE = 'destination-out';
46941          /**
46942           * @property {String} ADD
46943           * @final
46944           * @default lighter
46945           */ exports.REMOVE = REMOVE;
46946          var ADD = 'lighter';
46947          //ADD: 'add', //
46948          //SUBTRACT: 'subtract', //
46949          /**
46950           * @property {String} DARKEST
46951           * @final
46952           */ exports.ADD = ADD;
46953          var DARKEST = 'darken';
46954          /**
46955           * @property {String} LIGHTEST
46956           * @final
46957           * @default lighten
46958           */ exports.DARKEST = DARKEST;
46959          var LIGHTEST = 'lighten';
46960          /**
46961           * @property {String} DIFFERENCE
46962           * @final
46963           */ exports.LIGHTEST = LIGHTEST;
46964          var DIFFERENCE = 'difference';
46965          /**
46966           * @property {String} SUBTRACT
46967           * @final
46968           */ exports.DIFFERENCE = DIFFERENCE;
46969          var SUBTRACT = 'subtract';
46970          /**
46971           * @property {String} EXCLUSION
46972           * @final
46973           */ exports.SUBTRACT = SUBTRACT;
46974          var EXCLUSION = 'exclusion';
46975          /**
46976           * @property {String} MULTIPLY
46977           * @final
46978           */ exports.EXCLUSION = EXCLUSION;
46979          var MULTIPLY = 'multiply';
46980          /**
46981           * @property {String} SCREEN
46982           * @final
46983           */ exports.MULTIPLY = MULTIPLY;
46984          var SCREEN = 'screen';
46985          /**
46986           * @property {String} REPLACE
46987           * @final
46988           * @default copy
46989           */ exports.SCREEN = SCREEN;
46990          var REPLACE = 'copy';
46991          /**
46992           * @property {String} OVERLAY
46993           * @final
46994           */ exports.REPLACE = REPLACE;
46995          var OVERLAY = 'overlay';
46996          /**
46997           * @property {String} HARD_LIGHT
46998           * @final
46999           */ exports.OVERLAY = OVERLAY;
47000          var HARD_LIGHT = 'hard-light';
47001          /**
47002           * @property {String} SOFT_LIGHT
47003           * @final
47004           */ exports.HARD_LIGHT = HARD_LIGHT;
47005          var SOFT_LIGHT = 'soft-light';
47006          /**
47007           * @property {String} DODGE
47008           * @final
47009           * @default color-dodge
47010           */ exports.SOFT_LIGHT = SOFT_LIGHT;
47011          var DODGE = 'color-dodge';
47012          /**
47013           * @property {String} BURN
47014           * @final
47015           * @default color-burn
47016           */ exports.DODGE = DODGE;
47017          var BURN = 'color-burn';
47018
47019          // FILTERS
47020          /**
47021           * @property {String} THRESHOLD
47022           * @final
47023           */ exports.BURN = BURN;
47024          var THRESHOLD = 'threshold';
47025          /**
47026           * @property {String} GRAY
47027           * @final
47028           */ exports.THRESHOLD = THRESHOLD;
47029          var GRAY = 'gray';
47030          /**
47031           * @property {String} OPAQUE
47032           * @final
47033           */ exports.GRAY = GRAY;
47034          var OPAQUE = 'opaque';
47035          /**
47036           * @property {String} INVERT
47037           * @final
47038           */ exports.OPAQUE = OPAQUE;
47039          var INVERT = 'invert';
47040          /**
47041           * @property {String} POSTERIZE
47042           * @final
47043           */ exports.INVERT = INVERT;
47044          var POSTERIZE = 'posterize';
47045          /**
47046           * @property {String} DILATE
47047           * @final
47048           */ exports.POSTERIZE = POSTERIZE;
47049          var DILATE = 'dilate';
47050          /**
47051           * @property {String} ERODE
47052           * @final
47053           */ exports.DILATE = DILATE;
47054          var ERODE = 'erode';
47055          /**
47056           * @property {String} BLUR
47057           * @final
47058           */ exports.ERODE = ERODE;
47059          var BLUR = 'blur';
47060
47061          // TYPOGRAPHY
47062          /**
47063           * @property {String} NORMAL
47064           * @final
47065           */ exports.BLUR = BLUR;
47066          var NORMAL = 'normal';
47067          /**
47068           * @property {String} ITALIC
47069           * @final
47070           */ exports.NORMAL = NORMAL;
47071          var ITALIC = 'italic';
47072          /**
47073           * @property {String} BOLD
47074           * @final
47075           */ exports.ITALIC = ITALIC;
47076          var BOLD = 'bold';
47077          /**
47078           * @property {String} BOLDITALIC
47079           * @final
47080           */ exports.BOLD = BOLD;
47081          var BOLDITALIC = 'bold italic';
47082
47083          // TYPOGRAPHY-INTERNAL
47084          exports.BOLDITALIC = BOLDITALIC;
47085          var _DEFAULT_TEXT_FILL = '#000000';
47086          exports._DEFAULT_TEXT_FILL = _DEFAULT_TEXT_FILL;
47087          var _DEFAULT_LEADMULT = 1.25;
47088          exports._DEFAULT_LEADMULT = _DEFAULT_LEADMULT;
47089          var _CTX_MIDDLE = 'middle';
47090
47091          // VERTICES
47092          /**
47093           * @property {String} LINEAR
47094           * @final
47095           */ exports._CTX_MIDDLE = _CTX_MIDDLE;
47096          var LINEAR = 'linear';
47097          /**
47098           * @property {String} QUADRATIC
47099           * @final
47100           */ exports.LINEAR = LINEAR;
47101          var QUADRATIC = 'quadratic';
47102          /**
47103           * @property {String} BEZIER
47104           * @final
47105           */ exports.QUADRATIC = QUADRATIC;
47106          var BEZIER = 'bezier';
47107          /**
47108           * @property {String} CURVE
47109           * @final
47110           */ exports.BEZIER = BEZIER;
47111          var CURVE = 'curve';
47112
47113          // WEBGL DRAWMODES
47114          /**
47115           * @property {String} STROKE
47116           * @final
47117           */ exports.CURVE = CURVE;
47118          var STROKE = 'stroke';
47119          /**
47120           * @property {String} FILL
47121           * @final
47122           */ exports.STROKE = STROKE;
47123          var FILL = 'fill';
47124          /**
47125           * @property {String} TEXTURE
47126           * @final
47127           */ exports.FILL = FILL;
47128          var TEXTURE = 'texture';
47129          /**
47130           * @property {String} IMMEDIATE
47131           * @final
47132           */ exports.TEXTURE = TEXTURE;
47133          var IMMEDIATE = 'immediate';
47134
47135          // WEBGL TEXTURE MODE
47136          // NORMAL already exists for typography
47137          /**
47138           * @property {String} IMAGE
47139           * @final
47140           */ exports.IMMEDIATE = IMMEDIATE;
47141          var IMAGE = 'image';
47142
47143          // WEBGL TEXTURE WRAP AND FILTERING
47144          // LINEAR already exists above
47145          /**
47146           * @property {String} NEAREST
47147           * @final
47148           */ exports.IMAGE = IMAGE;
47149          var NEAREST = 'nearest';
47150          /**
47151           * @property {String} REPEAT
47152           * @final
47153           */ exports.NEAREST = NEAREST;
47154          var REPEAT = 'repeat';
47155          /**
47156           * @property {String} CLAMP
47157           * @final
47158           */ exports.REPEAT = REPEAT;
47159          var CLAMP = 'clamp';
47160          /**
47161           * @property {String} MIRROR
47162           * @final
47163           */ exports.CLAMP = CLAMP;
47164          var MIRROR = 'mirror';
47165
47166          // DEVICE-ORIENTATION
47167          /**
47168           * @property {String} LANDSCAPE
47169           * @final
47170           */ exports.MIRROR = MIRROR;
47171          var LANDSCAPE = 'landscape';
47172          /**
47173           * @property {String} PORTRAIT
47174           * @final
47175           */ exports.LANDSCAPE = LANDSCAPE;
47176          var PORTRAIT = 'portrait';
47177
47178          // DEFAULTS
47179          exports.PORTRAIT = PORTRAIT;
47180          var _DEFAULT_STROKE = '#000000';
47181          exports._DEFAULT_STROKE = _DEFAULT_STROKE;
47182          var _DEFAULT_FILL = '#FFFFFF';
47183
47184          /**
47185           * @property {String} GRID
47186           * @final
47187           */ exports._DEFAULT_FILL = _DEFAULT_FILL;
47188          var GRID = 'grid';
47189
47190          /**
47191           * @property {String} AXES
47192           * @final
47193           */ exports.GRID = GRID;
47194          var AXES = 'axes';
47195
47196          /**
47197           * @property {String} LABEL
47198           * @final
47199           */ exports.AXES = AXES;
47200          var LABEL = 'label';
47201          /**
47202           * @property {String} FALLBACK
47203           * @final
47204           */ exports.LABEL = LABEL;
47205          var FALLBACK = 'fallback';
47206          exports.FALLBACK = FALLBACK;
47207        },
47208        {}
47209      ],
47210      49: [
47211        function(_dereq_, module, exports) {
47212          'use strict';
47213          function _typeof(obj) {
47214            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
47215              _typeof = function _typeof(obj) {
47216                return typeof obj;
47217              };
47218            } else {
47219              _typeof = function _typeof(obj) {
47220                return obj &&
47221                  typeof Symbol === 'function' &&
47222                  obj.constructor === Symbol &&
47223                  obj !== Symbol.prototype
47224                  ? 'symbol'
47225                  : typeof obj;
47226              };
47227            }
47228            return _typeof(obj);
47229          }
47230          Object.defineProperty(exports, '__esModule', { value: true });
47231          exports.default = void 0;
47232
47233          var _main = _interopRequireDefault(_dereq_('./main'));
47234          var C = _interopRequireWildcard(_dereq_('./constants'));
47235          function _getRequireWildcardCache() {
47236            if (typeof WeakMap !== 'function') return null;
47237            var cache = new WeakMap();
47238            _getRequireWildcardCache = function _getRequireWildcardCache() {
47239              return cache;
47240            };
47241            return cache;
47242          }
47243          function _interopRequireWildcard(obj) {
47244            if (obj && obj.__esModule) {
47245              return obj;
47246            }
47247            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
47248              return { default: obj };
47249            }
47250            var cache = _getRequireWildcardCache();
47251            if (cache && cache.has(obj)) {
47252              return cache.get(obj);
47253            }
47254            var newObj = {};
47255            var hasPropertyDescriptor =
47256              Object.defineProperty && Object.getOwnPropertyDescriptor;
47257            for (var key in obj) {
47258              if (Object.prototype.hasOwnProperty.call(obj, key)) {
47259                var desc = hasPropertyDescriptor
47260                  ? Object.getOwnPropertyDescriptor(obj, key)
47261                  : null;
47262                if (desc && (desc.get || desc.set)) {
47263                  Object.defineProperty(newObj, key, desc);
47264                } else {
47265                  newObj[key] = obj[key];
47266                }
47267              }
47268            }
47269            newObj.default = obj;
47270            if (cache) {
47271              cache.set(obj, newObj);
47272            }
47273            return newObj;
47274          }
47275          function _interopRequireDefault(obj) {
47276            return obj && obj.__esModule ? obj : { default: obj };
47277          }
47278          /**
47279           * @module Environment
47280           * @submodule Environment
47281           * @for p5
47282           * @requires core
47283           * @requires constants
47284           */ var standardCursors = [C.ARROW, C.CROSS, C.HAND, C.MOVE, C.TEXT, C.WAIT];
47285          _main.default.prototype._frameRate = 0;
47286          _main.default.prototype._lastFrameTime = window.performance.now();
47287          _main.default.prototype._targetFrameRate = 60;
47288
47289          var _windowPrint = window.print;
47290
47291          /**
47292           * The <a href="#/p5/print">print()</a> function writes to the console area of
47293           * your browser. This function is often helpful for looking at the data a program
47294           * is producing. This function creates a new line of text for each call to
47295           * the function. Individual elements can be separated with quotes ("") and joined
47296           * with the addition operator (+).
47297           *
47298           * Note that calling print() without any arguments invokes the window.print()
47299           * function which opens the browser's print dialog. To print a blank line
47300           * to console you can write print('\n').
47301           *
47302           * @method print
47303           * @param {Any} contents any combination of Number, String, Object, Boolean,
47304           *                       Array to print
47305           * @example
47306           * <div><code class='norender'>
47307           * let x = 10;
47308           * print('The value of x is ' + x);
47309           * // prints "The value of x is 10"
47310           * </code></div>
47311           *
47312           * @alt
47313           * default grey canvas
47314           */
47315          _main.default.prototype.print = function() {
47316            if (!arguments.length) {
47317              _windowPrint();
47318            } else {
47319              var _console;
47320              (_console = console).log.apply(_console, arguments);
47321            }
47322          };
47323
47324          /**
47325           * The system variable <a href="#/p5/frameCount">frameCount</a> contains the
47326           * number of frames that have been displayed since the program started. Inside
47327           * <a href="#/p5/setup">setup()</a> the value is 0, after the first iteration
47328           * of draw it is 1, etc.
47329           *
47330           * @property {Integer} frameCount
47331           * @readOnly
47332           * @example
47333           * <div><code>
47334           * function setup() {
47335           *   frameRate(30);
47336           *   textSize(30);
47337           *   textAlign(CENTER);
47338           * }
47339           *
47340           * function draw() {
47341           *   background(200);
47342           *   text(frameCount, width / 2, height / 2);
47343           * }
47344           * </code></div>
47345           *
47346           * @alt
47347           * numbers rapidly counting upward with frame count set to 30.
47348           */
47349          _main.default.prototype.frameCount = 0;
47350
47351          /**
47352           * The system variable <a href="#/p5/deltaTime">deltaTime</a> contains the time
47353           * difference between the beginning of the previous frame and the beginning
47354           * of the current frame in milliseconds.
47355           *
47356           * This variable is useful for creating time sensitive animation or physics
47357           * calculation that should stay constant regardless of frame rate.
47358           *
47359           * @property {Integer} deltaTime
47360           * @readOnly
47361           * @example
47362           * <div><code>
47363           * let rectX = 0;
47364           * let fr = 30; //starting FPS
47365           * let clr;
47366           *
47367           * function setup() {
47368           *   background(200);
47369           *   frameRate(fr); // Attempt to refresh at starting FPS
47370           *   clr = color(255, 0, 0);
47371           * }
47372           *
47373           * function draw() {
47374           *   background(200);
47375           *   rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime
47376           *
47377           *   if (rectX >= width) {
47378           *     // If you go off screen.
47379           *     if (fr === 30) {
47380           *       clr = color(0, 0, 255);
47381           *       fr = 10;
47382           *       frameRate(fr); // make frameRate 10 FPS
47383           *     } else {
47384           *       clr = color(255, 0, 0);
47385           *       fr = 30;
47386           *       frameRate(fr); // make frameRate 30 FPS
47387           *     }
47388           *     rectX = 0;
47389           *   }
47390           *   fill(clr);
47391           *   rect(rectX, 40, 20, 20);
47392           * }
47393           * </code></div>
47394           *
47395           * @alt
47396           * red rect moves left to right, followed by blue rect moving at the same speed
47397           * with a lower frame rate. Loops.
47398           */
47399          _main.default.prototype.deltaTime = 0;
47400
47401          /**
47402                                        * Confirms if the window a p5.js program is in is "focused," meaning that
47403                                        * the sketch will accept mouse or keyboard input. This variable is
47404                                        * "true" if the window is focused and "false" if not.
47405                                        *
47406                                        * @property {Boolean} focused
47407                                        * @readOnly
47408                                        * @example
47409                                        * <div><code>
47410                                        * // To demonstrate, put two windows side by side.
47411                                        * // Click on the window that the p5 sketch isn't in!
47412                                        * function draw() {
47413                                        *   background(200);
47414                                        *   noStroke();
47415                                        *   fill(0, 200, 0);
47416                                        *   ellipse(25, 25, 50, 50);
47417                                        *
47418                                        *   if (!focused) {
47419                                           // or "if (focused === false)"
47420                                        *     stroke(200, 0, 0);
47421                                        *     line(0, 0, 100, 100);
47422                                        *     line(100, 0, 0, 100);
47423                                        *   }
47424                                        * }
47425                                        * </code></div>
47426                                        *
47427                                        * @alt
47428                                        * green 50x50 ellipse at top left. Red X covers canvas when page focus changes
47429                                        */
47430          _main.default.prototype.focused = document.hasFocus();
47431
47432          /**
47433           * Sets the cursor to a predefined symbol or an image, or makes it visible
47434           * if already hidden. If you are trying to set an image as the cursor, the
47435           * recommended size is 16x16 or 32x32 pixels. The values for parameters x and y
47436           * must be less than the dimensions of the image.
47437           *
47438           * @method cursor
47439           * @param {String|Constant} type Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT
47440           *                               Native CSS properties: 'grab', 'progress', 'cell' etc.
47441           *                               External: path for cursor's images
47442           *                               (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)
47443           *                               For more information on Native CSS cursors and url visit:
47444           *                               https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
47445           * @param {Number}          [x]  the horizontal active spot of the cursor (must be less than 32)
47446           * @param {Number}          [y]  the vertical active spot of the cursor (must be less than 32)
47447           * @example
47448           * <div><code>
47449           * // Move the mouse across the quadrants
47450           * // to see the cursor change
47451           * function draw() {
47452           *   line(width / 2, 0, width / 2, height);
47453           *   line(0, height / 2, width, height / 2);
47454           *   if (mouseX < 50 && mouseY < 50) {
47455           *     cursor(CROSS);
47456           *   } else if (mouseX > 50 && mouseY < 50) {
47457           *     cursor('progress');
47458           *   } else if (mouseX > 50 && mouseY > 50) {
47459           *     cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');
47460           *   } else {
47461           *     cursor('grab');
47462           *   }
47463           * }
47464           * </code></div>
47465           *
47466           * @alt
47467           * canvas is divided into four quadrants. cursor on first is a cross, second is a progress,
47468           * third is a custom cursor using path to the cursor and fourth is a grab.
47469           */
47470          _main.default.prototype.cursor = function(type, x, y) {
47471            var cursor = 'auto';
47472            var canvas = this._curElement.elt;
47473            if (standardCursors.includes(type)) {
47474              // Standard css cursor
47475              cursor = type;
47476            } else if (typeof type === 'string') {
47477              var coords = '';
47478              if (x && y && typeof x === 'number' && typeof y === 'number') {
47479                // Note that x and y values must be unit-less positive integers < 32
47480                // https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
47481                coords = ''.concat(x, ' ').concat(y);
47482              }
47483              if (
47484                type.substring(0, 7) === 'http://' ||
47485                type.substring(0, 8) === 'https://'
47486              ) {
47487                // Image (absolute url)
47488                cursor = 'url('.concat(type, ') ').concat(coords, ', auto');
47489              } else if (/\.(cur|jpg|jpeg|gif|png|CUR|JPG|JPEG|GIF|PNG)$/.test(type)) {
47490                // Image file (relative path) - Separated for performance reasons
47491                cursor = 'url('.concat(type, ') ').concat(coords, ', auto');
47492              } else {
47493                // Any valid string for the css cursor property
47494                cursor = type;
47495              }
47496            }
47497            canvas.style.cursor = cursor;
47498          };
47499
47500          /**
47501    * Specifies the number of frames to be displayed every second. For example,
47502    * the function call frameRate(30) will attempt to refresh 30 times a second.
47503    * If the processor is not fast enough to maintain the specified rate, the
47504    * frame rate will not be achieved. Setting the frame rate within 
47505    * <a href="#/p5/setup">setup()</a> is recommended. The default frame rate is
47506    * based on the frame rate of the display (here also called "refresh rate"), 
47507    * which is set to 60 frames per second on most computers. A frame rate of 24
47508    * frames per second (usual for movies) or above will be enough for smooth 
47509    * animations. This is the same as setFrameRate(val).
47510    * 
47511    * Calling <a href="#/p5/frameRate">frameRate()</a> with no arguments returns
47512    * the current framerate. The draw function must run at least once before it will
47513    * return a value. This is the same as <a href="#/p5/getFrameRate">getFrameRate()</a>.
47514    *
47515    * Calling <a href="#/p5/frameRate">frameRate()</a> with arguments that are not
47516    * of the type numbers or are non positive also returns current framerate.
47517    *
47518    * @method frameRate
47519    * @param  {Number} fps number of frames to be displayed every second
47520    * @chainable
47521    *
47522    * @example
47523    *
47524    * <div><code>
47525    * let rectX = 0;
47526    * let fr = 30; //starting FPS
47527    * let clr;
47528    *
47529    * function setup() {
47530    *   background(200);
47531    *   frameRate(fr); // Attempt to refresh at starting FPS
47532    *   clr = color(255, 0, 0);
47533    * }
47534    *
47535    * function draw() {
47536    *   background(200);
47537    *   rectX = rectX += 1; // Move Rectangle
47538    *
47539    *   if (rectX >= width) {
47540       // If you go off screen.
47541    *     if (fr === 30) {
47542    *       clr = color(0, 0, 255);
47543    *       fr = 10;
47544    *       frameRate(fr); // make frameRate 10 FPS
47545    *     } else {
47546    *       clr = color(255, 0, 0);
47547    *       fr = 30;
47548    *       frameRate(fr); // make frameRate 30 FPS
47549    *     }
47550    *     rectX = 0;
47551    *   }
47552    *   fill(clr);
47553    *   rect(rectX, 40, 20, 20);
47554    * }
47555    * </code></div>
47556    *
47557    * @alt
47558    * blue rect moves left to right, followed by red rect moving faster. Loops.
47559    */
47560          /**
47561           * @method frameRate
47562           * @return {Number}       current frameRate
47563           */
47564          _main.default.prototype.frameRate = function(fps) {
47565            _main.default._validateParameters('frameRate', arguments);
47566            if (typeof fps !== 'number' || fps < 0) {
47567              return this._frameRate;
47568            } else {
47569              this._setProperty('_targetFrameRate', fps);
47570              if (fps === 0) {
47571                this._setProperty('_frameRate', fps);
47572              }
47573              return this;
47574            }
47575          };
47576
47577          /**
47578           * Returns the current framerate.
47579           *
47580           * @private
47581           * @return {Number} current frameRate
47582           */
47583          _main.default.prototype.getFrameRate = function() {
47584            return this.frameRate();
47585          };
47586
47587          /**
47588           * Specifies the number of frames to be displayed every second. For example,
47589           * the function call frameRate(30) will attempt to refresh 30 times a second.
47590           * If the processor is not fast enough to maintain the specified rate, the
47591           * frame rate will not be achieved. Setting the frame rate within <a href="#/p5/setup">setup()</a> is
47592           * recommended. The default rate is 60 frames per second.
47593           *
47594           * Calling <a href="#/p5/frameRate">frameRate()</a> with no arguments returns the current framerate.
47595           *
47596           * @private
47597           * @param {Number} [fps] number of frames to be displayed every second
47598           */
47599          _main.default.prototype.setFrameRate = function(fps) {
47600            return this.frameRate(fps);
47601          };
47602
47603          /**
47604           * Hides the cursor from view.
47605           *
47606           * @method noCursor
47607           * @example
47608           * <div><code>
47609           * function setup() {
47610           *   noCursor();
47611           * }
47612           *
47613           * function draw() {
47614           *   background(200);
47615           *   ellipse(mouseX, mouseY, 10, 10);
47616           * }
47617           * </code></div>
47618           *
47619           * @alt
47620           * cursor becomes 10x 10 white ellipse the moves with mouse x and y.
47621           */
47622          _main.default.prototype.noCursor = function() {
47623            this._curElement.elt.style.cursor = 'none';
47624          };
47625
47626          /**
47627           * System variable that stores the width of the screen display according to The
47628           * default <a href="#/p5/pixelDensity">pixelDensity</a>. This is used to run a
47629           * full-screen program on any display size. To return actual screen size,
47630           * multiply this by pixelDensity.
47631           *
47632           * @property {Number} displayWidth
47633           * @readOnly
47634           * @example
47635           * <div class="norender"><code>
47636           * createCanvas(displayWidth, displayHeight);
47637           * </code></div>
47638           *
47639           * @alt
47640           * This example does not render anything.
47641           */
47642          _main.default.prototype.displayWidth = screen.width;
47643
47644          /**
47645           * System variable that stores the height of the screen display according to The
47646           * default <a href="#/p5/pixelDensity">pixelDensity</a>. This is used to run a
47647           * full-screen program on any display size. To return actual screen size,
47648           * multiply this by pixelDensity.
47649           *
47650           * @property {Number} displayHeight
47651           * @readOnly
47652           * @example
47653           * <div class="norender"><code>
47654           * createCanvas(displayWidth, displayHeight);
47655           * </code></div>
47656           *
47657           * @alt
47658           * This example does not render anything.
47659           */
47660          _main.default.prototype.displayHeight = screen.height;
47661
47662          /**
47663           * System variable that stores the width of the inner window, it maps to
47664           * window.innerWidth.
47665           *
47666           * @property {Number} windowWidth
47667           * @readOnly
47668           * @example
47669           * <div class="norender"><code>
47670           * createCanvas(windowWidth, windowHeight);
47671           * </code></div>
47672           *
47673           * @alt
47674           * This example does not render anything.
47675           */
47676          _main.default.prototype.windowWidth = getWindowWidth();
47677          /**
47678           * System variable that stores the height of the inner window, it maps to
47679           * window.innerHeight.
47680           *
47681           * @property {Number} windowHeight
47682           * @readOnly
47683           * @example
47684           * <div class="norender"><code>
47685           * createCanvas(windowWidth, windowHeight);
47686           * </code></div>
47687           *
47688           * @alt
47689           * This example does not render anything.
47690           */
47691          _main.default.prototype.windowHeight = getWindowHeight();
47692
47693          /**
47694           * The <a href="#/p5/windowResized">windowResized()</a> function is called once
47695           * every time the browser window is resized. This is a good place to resize the
47696           * canvas or do any other adjustments to accommodate the new window size.
47697           *
47698           * @method windowResized
47699           * @example
47700           * <div class="norender"><code>
47701           * function setup() {
47702           *   createCanvas(windowWidth, windowHeight);
47703           * }
47704           *
47705           * function draw() {
47706           *   background(0, 100, 200);
47707           * }
47708           *
47709           * function windowResized() {
47710           *   resizeCanvas(windowWidth, windowHeight);
47711           * }
47712           * </code></div>
47713           * @alt
47714           * This example does not render anything.
47715           */
47716          _main.default.prototype._onresize = function(e) {
47717            this._setProperty('windowWidth', getWindowWidth());
47718            this._setProperty('windowHeight', getWindowHeight());
47719            var context = this._isGlobal ? window : this;
47720            var executeDefault;
47721            if (typeof context.windowResized === 'function') {
47722              executeDefault = context.windowResized(e);
47723              if (executeDefault !== undefined && !executeDefault) {
47724                e.preventDefault();
47725              }
47726            }
47727          };
47728
47729          function getWindowWidth() {
47730            return (
47731              window.innerWidth ||
47732              (document.documentElement && document.documentElement.clientWidth) ||
47733              (document.body && document.body.clientWidth) ||
47734              0
47735            );
47736          }
47737
47738          function getWindowHeight() {
47739            return (
47740              window.innerHeight ||
47741              (document.documentElement && document.documentElement.clientHeight) ||
47742              (document.body && document.body.clientHeight) ||
47743              0
47744            );
47745          }
47746
47747          /**
47748           * System variable that stores the width of the drawing canvas. This value
47749           * is set by the first parameter of the <a href="#/p5/createCanvas">createCanvas()</a> function.
47750           * For example, the function call createCanvas(320, 240) sets the width
47751           * variable to the value 320. The value of width defaults to 100 if
47752           * <a href="#/p5/createCanvas">createCanvas()</a> is not used in a program.
47753           *
47754           * @property {Number} width
47755           * @readOnly
47756           */
47757          _main.default.prototype.width = 0;
47758
47759          /**
47760           * System variable that stores the height of the drawing canvas. This value
47761           * is set by the second parameter of the <a href="#/p5/createCanvas">createCanvas()</a> function. For
47762           * example, the function call createCanvas(320, 240) sets the height
47763           * variable to the value 240. The value of height defaults to 100 if
47764           * <a href="#/p5/createCanvas">createCanvas()</a> is not used in a program.
47765           *
47766           * @property {Number} height
47767           * @readOnly
47768           */
47769          _main.default.prototype.height = 0;
47770
47771          /**
47772           * If argument is given, sets the sketch to fullscreen or not based on the
47773           * value of the argument. If no argument is given, returns the current
47774           * fullscreen state. Note that due to browser restrictions this can only
47775           * be called on user input, for example, on mouse press like the example
47776           * below.
47777           *
47778           * @method fullscreen
47779           * @param  {Boolean} [val] whether the sketch should be in fullscreen mode
47780           * or not
47781           * @return {Boolean} current fullscreen state
47782           * @example
47783           * <div>
47784           * <code>
47785           * // Clicking in the box toggles fullscreen on and off.
47786           * function setup() {
47787           *   background(200);
47788           * }
47789           * function mousePressed() {
47790           *   if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
47791           *     let fs = fullscreen();
47792           *     fullscreen(!fs);
47793           *   }
47794           * }
47795           * </code>
47796           * </div>
47797           *
47798           * @alt
47799           * This example does not render anything.
47800           */
47801          _main.default.prototype.fullscreen = function(val) {
47802            _main.default._validateParameters('fullscreen', arguments);
47803            // no arguments, return fullscreen or not
47804            if (typeof val === 'undefined') {
47805              return (
47806                document.fullscreenElement ||
47807                document.webkitFullscreenElement ||
47808                document.mozFullScreenElement ||
47809                document.msFullscreenElement
47810              );
47811            } else {
47812              // otherwise set to fullscreen or not
47813              if (val) {
47814                launchFullscreen(document.documentElement);
47815              } else {
47816                exitFullscreen();
47817              }
47818            }
47819          };
47820
47821          /**
47822           * Sets the pixel scaling for high pixel density displays. By default
47823           * pixel density is set to match display density, call pixelDensity(1)
47824           * to turn this off. Calling <a href="#/p5/pixelDensity">pixelDensity()</a> with no arguments returns
47825           * the current pixel density of the sketch.
47826           *
47827           * @method pixelDensity
47828           * @param  {Number} val whether or how much the sketch should scale
47829           * @chainable
47830           * @example
47831           * <div>
47832           * <code>
47833           * function setup() {
47834           *   pixelDensity(1);
47835           *   createCanvas(100, 100);
47836           *   background(200);
47837           *   ellipse(width / 2, height / 2, 50, 50);
47838           * }
47839           * </code>
47840           * </div>
47841           *
47842           * <div>
47843           * <code>
47844           * function setup() {
47845           *   pixelDensity(3.0);
47846           *   createCanvas(100, 100);
47847           *   background(200);
47848           *   ellipse(width / 2, height / 2, 50, 50);
47849           * }
47850           * </code>
47851           * </div>
47852           *
47853           * @alt
47854           * fuzzy 50x50 white ellipse with black outline in center of canvas.
47855           * sharp 50x50 white ellipse with black outline in center of canvas.
47856           */
47857          /**
47858           * @method pixelDensity
47859           * @returns {Number} current pixel density of the sketch
47860           */
47861          _main.default.prototype.pixelDensity = function(val) {
47862            _main.default._validateParameters('pixelDensity', arguments);
47863            var returnValue;
47864            if (typeof val === 'number') {
47865              if (val !== this._pixelDensity) {
47866                this._pixelDensity = val;
47867              }
47868              returnValue = this;
47869              this.resizeCanvas(this.width, this.height, true); // as a side effect, it will clear the canvas
47870            } else {
47871              returnValue = this._pixelDensity;
47872            }
47873            return returnValue;
47874          };
47875
47876          /**
47877           * Returns the pixel density of the current display the sketch is running on.
47878           *
47879           * @method displayDensity
47880           * @returns {Number} current pixel density of the display
47881           * @example
47882           * <div>
47883           * <code>
47884           * function setup() {
47885           *   let density = displayDensity();
47886           *   pixelDensity(density);
47887           *   createCanvas(100, 100);
47888           *   background(200);
47889           *   ellipse(width / 2, height / 2, 50, 50);
47890           * }
47891           * </code>
47892           * </div>
47893           *
47894           * @alt
47895           * 50x50 white ellipse with black outline in center of canvas.
47896           */
47897          _main.default.prototype.displayDensity = function() {
47898            return window.devicePixelRatio;
47899          };
47900
47901          function launchFullscreen(element) {
47902            var enabled =
47903              document.fullscreenEnabled ||
47904              document.webkitFullscreenEnabled ||
47905              document.mozFullScreenEnabled ||
47906              document.msFullscreenEnabled;
47907            if (!enabled) {
47908              throw new Error('Fullscreen not enabled in this browser.');
47909            }
47910            if (element.requestFullscreen) {
47911              element.requestFullscreen();
47912            } else if (element.mozRequestFullScreen) {
47913              element.mozRequestFullScreen();
47914            } else if (element.webkitRequestFullscreen) {
47915              element.webkitRequestFullscreen();
47916            } else if (element.msRequestFullscreen) {
47917              element.msRequestFullscreen();
47918            }
47919          }
47920
47921          function exitFullscreen() {
47922            if (document.exitFullscreen) {
47923              document.exitFullscreen();
47924            } else if (document.mozCancelFullScreen) {
47925              document.mozCancelFullScreen();
47926            } else if (document.webkitExitFullscreen) {
47927              document.webkitExitFullscreen();
47928            } else if (document.msExitFullscreen) {
47929              document.msExitFullscreen();
47930            }
47931          }
47932
47933          /**
47934           * Gets the current URL.
47935           * @method getURL
47936           * @return {String} url
47937           * @example
47938           * <div>
47939           * <code>
47940           * let url;
47941           * let x = 100;
47942           *
47943           * function setup() {
47944           *   fill(0);
47945           *   noStroke();
47946           *   url = getURL();
47947           * }
47948           *
47949           * function draw() {
47950           *   background(200);
47951           *   text(url, x, height / 2);
47952           *   x--;
47953           * }
47954           * </code>
47955           * </div>
47956           *
47957           * @alt
47958           * current url (http://p5js.org/reference/#/p5/getURL) moves right to left.
47959           */
47960          _main.default.prototype.getURL = function() {
47961            return location.href;
47962          };
47963          /**
47964           * Gets the current URL path as an array.
47965           * @method getURLPath
47966           * @return {String[]} path components
47967           * @example
47968           * <div class='norender'><code>
47969           * function setup() {
47970           *   let urlPath = getURLPath();
47971           *   for (let i = 0; i < urlPath.length; i++) {
47972           *     text(urlPath[i], 10, i * 20 + 20);
47973           *   }
47974           * }
47975           * </code></div>
47976           *
47977           * @alt
47978           * This example does not render anything.
47979           */
47980          _main.default.prototype.getURLPath = function() {
47981            return location.pathname.split('/').filter(function(v) {
47982              return v !== '';
47983            });
47984          };
47985          /**
47986           * Gets the current URL params as an Object.
47987           * @method getURLParams
47988           * @return {Object} URL params
47989           * @example
47990           * <div class='norender notest'>
47991           * <code>
47992           * // Example: http://p5js.org?year=2014&month=May&day=15
47993           *
47994           * function setup() {
47995           *   let params = getURLParams();
47996           *   text(params.day, 10, 20);
47997           *   text(params.month, 10, 40);
47998           *   text(params.year, 10, 60);
47999           * }
48000           * </code>
48001           * </div>
48002           *
48003           * @alt
48004           * This example does not render anything.
48005           */
48006          _main.default.prototype.getURLParams = function() {
48007            var re = /[?&]([^&=]+)(?:[&=])([^&=]+)/gim;
48008            var m;
48009            var v = {};
48010            while ((m = re.exec(location.search)) != null) {
48011              if (m.index === re.lastIndex) {
48012                re.lastIndex++;
48013              }
48014              v[m[1]] = m[2];
48015            }
48016            return v;
48017          };
48018          var _default = _main.default;
48019          exports.default = _default;
48020        },
48021        { './constants': 48, './main': 59 }
48022      ],
48023      50: [
48024        function(_dereq_, module, exports) {
48025          'use strict';
48026          Object.defineProperty(exports, '__esModule', { value: true });
48027          exports.default = void 0; // Different browsers may use different error strings for the same error.
48028          // Extracting info from them is much easier and cleaner if we have a predefined
48029          // lookup against which we try and match the errors obtained from the browser,
48030          // classify them into types and extract the required information. The contents
48031          // of this file serve as that lookup. The FES can use this to give a simplified
48032          // explanation for all kinds of errors.
48033          var strings = {
48034            ReferenceError: [
48035              {
48036                msg: '{{}} is not defined',
48037                type: 'NOTDEFINED',
48038                browser: 'all'
48039              },
48040
48041              {
48042                msg: "Can't find variable: {{}}",
48043                type: 'NOTDEFINED',
48044                browser: 'Safari'
48045              }
48046            ],
48047
48048            SyntaxError: [
48049              {
48050                msg: 'illegal character',
48051                type: 'INVALIDTOKEN',
48052                browser: 'Firefox'
48053              },
48054
48055              {
48056                msg: 'Invalid character',
48057                type: 'INVALIDTOKEN',
48058                browser: 'Safari'
48059              },
48060
48061              {
48062                msg: 'Invalid or unexpected token',
48063                type: 'INVALIDTOKEN',
48064                browser: 'Chrome'
48065              },
48066
48067              {
48068                msg: "Unexpected token '{{.}}'",
48069                type: 'UNEXPECTEDTOKEN',
48070                browser: 'Chrome'
48071              },
48072
48073              {
48074                msg: "expected {{.}}, got '{{.}}'",
48075                type: 'UNEXPECTEDTOKEN',
48076                browser: 'Chrome'
48077              }
48078            ],
48079
48080            TypeError: [
48081              {
48082                msg: '{{.}} is not a function',
48083                type: 'NOTFUNC',
48084                browser: 'all'
48085              }
48086            ]
48087          };
48088          var _default = strings;
48089          exports.default = _default;
48090        },
48091        {}
48092      ],
48093      51: [
48094        function(_dereq_, module, exports) {
48095          'use strict';
48096          Object.defineProperty(exports, '__esModule', { value: true });
48097          exports.default = void 0;
48098
48099          var _main = _interopRequireDefault(_dereq_('../main'));
48100          var _internationalization = _dereq_('../internationalization');
48101          function _interopRequireDefault(obj) {
48102            return obj && obj.__esModule ? obj : { default: obj };
48103          }
48104          function _slicedToArray(arr, i) {
48105            return (
48106              _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest()
48107            );
48108          }
48109          function _nonIterableRest() {
48110            throw new TypeError('Invalid attempt to destructure non-iterable instance');
48111          }
48112          function _iterableToArrayLimit(arr, i) {
48113            if (
48114              !(
48115                Symbol.iterator in Object(arr) ||
48116                Object.prototype.toString.call(arr) === '[object Arguments]'
48117              )
48118            ) {
48119              return;
48120            }
48121            var _arr = [];
48122            var _n = true;
48123            var _d = false;
48124            var _e = undefined;
48125            try {
48126              for (
48127                var _i = arr[Symbol.iterator](), _s;
48128                !(_n = (_s = _i.next()).done);
48129                _n = true
48130              ) {
48131                _arr.push(_s.value);
48132                if (i && _arr.length === i) break;
48133              }
48134            } catch (err) {
48135              _d = true;
48136              _e = err;
48137            } finally {
48138              try {
48139                if (!_n && _i['return'] != null) _i['return']();
48140              } finally {
48141                if (_d) throw _e;
48142              }
48143            }
48144            return _arr;
48145          }
48146          function _arrayWithHoles(arr) {
48147            if (Array.isArray(arr)) return arr;
48148          }
48149          function _typeof(obj) {
48150            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
48151              _typeof = function _typeof(obj) {
48152                return typeof obj;
48153              };
48154            } else {
48155              _typeof = function _typeof(obj) {
48156                return obj &&
48157                  typeof Symbol === 'function' &&
48158                  obj.constructor === Symbol &&
48159                  obj !== Symbol.prototype
48160                  ? 'symbol'
48161                  : typeof obj;
48162              };
48163            }
48164            return _typeof(obj);
48165          }
48166
48167          // p5.js blue, p5.js orange, auto dark green; fallback p5.js darkened magenta
48168          // See testColors below for all the color codes and names
48169          var typeColors = ['#2D7BB6', '#EE9900', '#4DB200', '#C83C00'];
48170          var misusedAtTopLevelCode = null;
48171          var defineMisusedAtTopLevelCode = null;
48172
48173          // the threshold for the maximum allowed levenshtein distance
48174          // used in misspelling detection
48175          var EDIT_DIST_THRESHOLD = 2;
48176
48177          // to enable or disable styling (color, font-size, etc. ) for fes messages
48178          var ENABLE_FES_STYLING = false;
48179
48180          if (typeof IS_MINIFIED !== 'undefined') {
48181            _main.default._friendlyError = _main.default._checkForUserDefinedFunctions = _main.default._fesErrorMonitor = function() {};
48182          } else {
48183            var doFriendlyWelcome = false; // TEMP until we get it all working LM
48184
48185            var errorTable = _dereq_('./browser_errors').default;
48186
48187            // -- Borrowed from jQuery 1.11.3 --
48188            var class2type = {};
48189            var _toString = class2type.toString;
48190            var names = [
48191              'Boolean',
48192              'Number',
48193              'String',
48194              'Function',
48195              'Array',
48196              'Date',
48197              'RegExp',
48198              'Object',
48199              'Error'
48200            ];
48201
48202            for (var n = 0; n < names.length; n++) {
48203              class2type['[object '.concat(names[n], ']')] = names[n].toLowerCase();
48204            }
48205            var getType = function getType(obj) {
48206              if (obj == null) {
48207                return ''.concat(obj);
48208              }
48209              return _typeof(obj) === 'object' || typeof obj === 'function'
48210                ? class2type[_toString.call(obj)] || 'object'
48211                : _typeof(obj);
48212            };
48213
48214            // -- End borrow --
48215
48216            // entry points into user-defined code
48217            var entryPoints = [
48218              'setup',
48219              'draw',
48220              'preload',
48221              'deviceMoved',
48222              'deviceTurned',
48223              'deviceShaken',
48224              'doubleClicked',
48225              'mousePressed',
48226              'mouseReleased',
48227              'mouseMoved',
48228              'mouseDragged',
48229              'mouseClicked',
48230              'mouseWheel',
48231              'touchStarted',
48232              'touchMoved',
48233              'touchEnded',
48234              'keyPressed',
48235              'keyReleased',
48236              'keyTyped',
48237              'windowResized'
48238            ];
48239
48240            var friendlyWelcome = function friendlyWelcome() {
48241              // p5.js brand - magenta: #ED225D
48242              //const astrixBgColor = 'transparent';
48243              //const astrixTxtColor = '#ED225D';
48244              //const welcomeBgColor = '#ED225D';
48245              //const welcomeTextColor = 'white';
48246              var welcomeMessage = (0, _internationalization.translator)('fes.pre', {
48247                message: (0, _internationalization.translator)('fes.welcome')
48248              });
48249
48250              console.log(
48251                '    _ \n' +
48252                  ' /\\| |/\\ \n' +
48253                  " \\ ` ' /  \n" +
48254                  ' / , . \\  \n' +
48255                  ' \\/|_|\\/ ' +
48256                  '\n\n' +
48257                  welcomeMessage
48258              );
48259            };
48260
48261            /**
48262             * Takes a message and a p5 function func, and adds a link pointing to
48263             * the reference documentation of func at the end of the message
48264             *
48265             * @method mapToReference
48266             * @private
48267             * @param {String} message the words to be said
48268             * @param {String} [func]    the name of the function to link
48269             *
48270             * @returns {String}
48271             */
48272            var mapToReference = function mapToReference(message, func) {
48273              var msgWithReference = '';
48274              if (func == null || func.substring(0, 4) === 'load') {
48275                msgWithReference = message;
48276              } else {
48277                var methodParts = func.split('.');
48278                var referenceSection =
48279                  methodParts.length > 1
48280                    ? ''.concat(methodParts[0], '.').concat(methodParts[1])
48281                    : 'p5';
48282
48283                var funcName =
48284                  methodParts.length === 1 ? func : methodParts.slice(2).join('/');
48285                msgWithReference = ''
48286                  .concat(message, ' (http://p5js.org/reference/#/')
48287                  .concat(referenceSection, '/')
48288                  .concat(funcName, ')');
48289              }
48290              return msgWithReference;
48291            };
48292
48293            /**
48294             * Prints out a fancy, colorful message to the console log
48295             *
48296             * @method report
48297             * @private
48298             * @param  {String}               message the words to be said
48299             * @param  {String}               [func]  the name of the function to link
48300             * @param  {Number|String} [color]   CSS color string or error type
48301             *
48302             * @return console logs
48303             */
48304            var report = function report(message, func, color) {
48305              // if p5._fesLogger is set ( i.e we are running tests ), use that
48306              // instead of console.log
48307              var log =
48308                _main.default._fesLogger == null
48309                  ? console.log.bind(console)
48310                  : _main.default._fesLogger;
48311
48312              if (doFriendlyWelcome) {
48313                friendlyWelcome();
48314                doFriendlyWelcome = false;
48315              }
48316              if ('undefined' === getType(color)) {
48317                color = '#B40033'; // dark magenta
48318              } else if (getType(color) === 'number') {
48319                // Type to color
48320                color = typeColors[color];
48321              }
48322
48323              // Add a link to the reference docs of func at the end of the message
48324              message = mapToReference(message, func);
48325              var style = [
48326                'color: '.concat(color),
48327                'font-family: Arial',
48328                'font-size: larger'
48329              ];
48330              var prefixedMsg = (0, _internationalization.translator)('fes.pre', {
48331                message: message
48332              });
48333
48334              if (ENABLE_FES_STYLING) {
48335                log('%c' + prefixedMsg, style.join(';'));
48336              } else {
48337                log(prefixedMsg);
48338              }
48339            };
48340            /**
48341             * This is a generic method that can be called from anywhere in the p5
48342             * library to alert users to a common error.
48343             *
48344             * @method _friendlyError
48345             * @private
48346             * @param  {Number} message message to be printed
48347             * @param  {String} [method] name of method
48348             * @param  {Number|String} [color]   CSS color string or error type (Optional)
48349             */
48350            _main.default._friendlyError = function(message, method, color) {
48351              report(message, method, color);
48352            };
48353
48354            /**
48355             * This is called internally if there is a error with autoplay.
48356             *
48357             * @method _friendlyAutoplayError
48358             * @private
48359             */
48360            _main.default._friendlyAutoplayError = function(src) {
48361              var message = (0, _internationalization.translator)('fes.autoplay', {
48362                src: src,
48363                link: 'https://developer.mozilla.org/docs/Web/Media/Autoplay_guide'
48364              });
48365
48366              console.log(
48367                (0, _internationalization.translator)('fes.pre', { message: message })
48368              );
48369            };
48370
48371            /**
48372             * An implementation of
48373             * https://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm to
48374             * compute the Levenshtein distance. It gives a measure of how dissimilar
48375             * two strings are. If the "distance" between them is small enough, it is
48376             * reasonable to think that one is the misspelled ver
48376sion of the other.
48377             * @method computeEditDistance
48378             * @private
48379             * @param {String} w1 the first word
48380             * @param {String} w2 the second word
48381             *
48382             * @returns {Number} the "distance" between the two words, a smaller value
48383             *                   indicates that the words are similar
48384             */
48385            var computeEditDistance = function computeEditDistance(w1, w2) {
48386              var l1 = w1.length,
48387                l2 = w2.length;
48388              if (l1 === 0) return w2;
48389              if (l2 === 0) return w1;
48390
48391              var prev = [];
48392              var cur = [];
48393
48394              for (var j = 0; j < l2 + 1; j++) {
48395                cur[j] = j;
48396              }
48397
48398              prev = cur;
48399
48400              for (var i = 1; i < l1 + 1; i++) {
48401                cur = [];
48402                for (var _j = 0; _j < l2 + 1; _j++) {
48403                  if (_j === 0) {
48404                    cur[_j] = i;
48405                  } else {
48406                    var a1 = w1[i - 1],
48407                      a2 = w2[_j - 1];
48408                    var temp = 999999;
48409                    var cost = a1.toLowerCase() === a2.toLowerCase() ? 0 : 1;
48410                    temp = temp > cost + prev[_j - 1] ? cost + prev[_j - 1] : temp;
48411                    temp = temp > 1 + cur[_j - 1] ? 1 + cur[_j - 1] : temp;
48412                    temp = temp > 1 + prev[_j] ? 1 + prev[_j] : temp;
48413                    cur[_j] = temp;
48414                  }
48415                }
48416                prev = cur;
48417              }
48418
48419              return cur[l2];
48420            };
48421
48422            /**
48423             * checks if the various functions such as setup, draw, preload have been
48424             * defined with capitalization mistakes
48425             * @method checkForUserDefinedFunctions
48426             * @private
48427             * @param {*} context The current default context. It's set to window in
48428             * "global mode" and to a p5 instance in "instance mode"
48429             */
48430            var checkForUserDefinedFunctions = function checkForUserDefinedFunctions(
48431              context
48432            ) {
48433              if (_main.default.disableFriendlyErrors) return;
48434
48435              // if using instance mode, this function would be called with the current
48436              // instance as context
48437              var instanceMode = context instanceof _main.default;
48438              context = instanceMode ? context : window;
48439              var fnNames = entryPoints;
48440
48441              var fxns = {};
48442              // lowercasename -> actualName mapping
48443              fnNames.forEach(function(symbol) {
48444                fxns[symbol.toLowerCase()] = symbol;
48445              });
48446
48447              for (
48448                var _i = 0, _Object$keys = Object.keys(context);
48449                _i < _Object$keys.length;
48450                _i++
48451              ) {
48452                var prop = _Object$keys[_i];
48453                var lowercase = prop.toLowerCase();
48454
48455                // check if the lowercase property name has an entry in fxns, if the
48456                // actual name with correct capitalization doesnt exist in context,
48457                // and if the user-defined symbol is of the type function
48458                if (
48459                  fxns[lowercase] &&
48460                  !context[fxns[lowercase]] &&
48461                  typeof context[prop] === 'function'
48462                ) {
48463                  var msg = (0, _internationalization.translator)(
48464                    'fes.checkUserDefinedFns',
48465                    {
48466                      name: prop,
48467                      actualName: fxns[lowercase]
48468                    }
48469                  );
48470
48471                  report(msg, fxns[lowercase]);
48472                }
48473              }
48474            };
48475
48476            /**
48477             * compares the the symbol caught in the ReferenceErrror to everything
48478             * in misusedAtTopLevel ( all public p5 properties ). The use of
48479             * misusedAtTopLevel here is for convenience as it was an array that was
48480             * already defined when spelling check was implemented. For this particular
48481             * use-case, it's a misnomer.
48482             *
48483             * @method handleMisspelling
48484             * @private
48485             * @param {String} errSym the symbol to whose spelling to check
48486             * @param {Error} error the ReferenceError object
48487             *
48488             * @returns {Boolean} a boolean value indicating if this error was likely due
48489             * to a mis-spelling
48490             */
48491            var handleMisspelling = function handleMisspelling(errSym, error) {
48492              if (!misusedAtTopLevelCode) {
48493                defineMisusedAtTopLevelCode();
48494              }
48495
48496              var distanceMap = {};
48497              var min = 999999;
48498              // compute the levenshtein distance for the symbol against all known
48499              // public p5 properties. Find the property with the minimum distance
48500              misusedAtTopLevelCode.forEach(function(symbol) {
48501                var dist = computeEditDistance(errSym, symbol.name);
48502                if (distanceMap[dist]) distanceMap[dist].push(symbol);
48503                else distanceMap[dist] = [symbol];
48504
48505                if (dist < min) min = dist;
48506              });
48507
48508              // if the closest match has more "distance" than the max allowed threshold
48509              if (min > Math.min(EDIT_DIST_THRESHOLD, errSym.length)) return false;
48510
48511              // Show a message only if the caught symbol and the matched property name
48512              // differ in their name ( either letter difference or difference of case )
48513              var matchedSymbols = distanceMap[min].filter(function(symbol) {
48514                return symbol.name !== errSym;
48515              });
48516
48517              if (matchedSymbols.length !== 0) {
48518                var parsed = _main.default._getErrorStackParser().parse(error);
48519                var locationObj;
48520                if (
48521                  parsed &&
48522                  parsed[0] &&
48523                  parsed[0].fileName &&
48524                  parsed[0].lineNumber &&
48525                  parsed[0].columnNumber
48526                ) {
48527                  locationObj = {
48528                    location: ''
48529                      .concat(parsed[0].fileName, ':')
48530                      .concat(parsed[0].lineNumber, ':')
48531                      .concat(parsed[0].columnNumber),
48532
48533                    file: parsed[0].fileName.split('/').slice(-1),
48534                    line: parsed[0].lineNumber
48535                  };
48536                }
48537
48538                var msg;
48539                if (matchedSymbols.length === 1) {
48540                  // To be used when there is only one closest match. The count parameter
48541                  // allows i18n to pick between the keys "fes.misspelling" and
48542                  // "fes.misspelling__plural"
48543                  msg = (0, _internationalization.translator)('fes.misspelling', {
48544                    name: errSym,
48545                    actualName: matchedSymbols[0].name,
48546                    type: matchedSymbols[0].type,
48547                    location: locationObj
48548                      ? (0, _internationalization.translator)('fes.location', locationObj)
48549                      : '',
48550                    count: matchedSymbols.length
48551                  });
48552                } else {
48553                  // To be used when there are multiple closest matches. Gives each
48554                  // suggestion on its own line, the function name followed by a link to
48555                  // reference documentation
48556                  var suggestions = matchedSymbols
48557                    .map(function(symbol) {
48558                      var message =
48559                        '▶️ ' + symbol.name + (symbol.type === 'function' ? '()' : '');
48560                      return mapToReference(message, symbol.name);
48561                    })
48562                    .join('\n');
48563
48564                  msg = (0, _internationalization.translator)('fes.misspelling', {
48565                    name: errSym,
48566                    suggestions: suggestions,
48567                    location: locationObj
48568                      ? (0, _internationalization.translator)('fes.location', locationObj)
48569                      : '',
48570                    count: matchedSymbols.length
48571                  });
48572                }
48573
48574                // If there is only one closest match, tell _friendlyError to also add
48575                // a link to the reference documentation. In case of multiple matches,
48576                // this is already done in the suggestions variable, one link for each
48577                // suggestion.
48578                report(
48579                  msg,
48580                  matchedSymbols.length === 1 ? matchedSymbols[0].name : undefined
48581                );
48582
48583                return true;
48584              }
48585              return false;
48586            };
48587
48588            /**
48589             * prints a friendly stacktrace which only includes user-written functions
48590             * and is easier for newcomers to understand
48591             * @method printFriendlyStack
48592             * @private
48593             * @param {Array} friendlyStack
48594             */
48595            var printFriendlyStack = function printFriendlyStack(friendlyStack) {
48596              var log =
48597                _main.default._fesLogger && typeof _main.default._fesLogger === 'function'
48598                  ? _main.default._fesLogger
48599                  : console.log.bind(console);
48600              if (friendlyStack.length > 1) {
48601                var stacktraceMsg = '';
48602                friendlyStack.forEach(function(frame, idx) {
48603                  var location = ''
48604                    .concat(frame.fileName, ':')
48605                    .concat(frame.lineNumber, ':')
48606                    .concat(frame.columnNumber);
48607
48608                  var frameMsg,
48609                    translationObj = {
48610                      func: frame.functionName,
48611                      line: frame.lineNumber,
48612                      location: location,
48613                      file: frame.fileName.split('/').slice(-1)
48614                    };
48615
48616                  if (idx === 0) {
48617                    frameMsg = (0, _internationalization.translator)(
48618                      'fes.globalErrors.stackTop',
48619                      translationObj
48620                    );
48621                  } else {
48622                    frameMsg = (0, _internationalization.translator)(
48623                      'fes.globalErrors.stackSubseq',
48624                      translationObj
48625                    );
48626                  }
48627                  stacktraceMsg += frameMsg;
48628                });
48629                log(stacktraceMsg);
48630              }
48631            };
48632
48633            /**
48634             * Takes a stacktrace array and filters out all frames that show internal p5
48635             * details. It also uses this processed stack to figure out if the error
48636             * error happened internally within the library, and if the error was due to
48637             * a non-loadX() method being used in preload
48638             * "Internally" here means that the error exact location of the error (the
48639             * top of the stack) is a piece of code write in the p5.js library (which may
48640             * or may not have been called from the user's sketch)
48641             *
48642             * @method processStack
48643             * @private
48644             * @param {Error} error
48645             * @param {Array} stacktrace
48646             *
48647             * @returns {Array} An array with two elements, [isInternal, friendlyStack]
48648             * isInternal: a boolean indicating if the error happened internally
48649             * friendlyStack: the simplified stacktrace, with internal details filtered
48650             */
48651            var processStack = function processStack(error, stacktrace) {
48652              // cannot process a stacktrace that doesn't exist
48653              if (!stacktrace) return [false, null];
48654
48655              stacktrace.forEach(function(frame) {
48656                frame.functionName = frame.functionName || '';
48657              });
48658
48659              // isInternal - Did this error happen inside the library
48660              var isInternal = false;
48661              var p5FileName, friendlyStack, currentEntryPoint;
48662              for (var i = stacktrace.length - 1; i >= 0; i--) {
48663                var splitted = stacktrace[i].functionName.split('.');
48664                if (entryPoints.includes(splitted[splitted.length - 1])) {
48665                  // remove everything below an entry point function (setup, draw, etc).
48666                  // (it's usually the internal initialization calls)
48667                  friendlyStack = stacktrace.slice(0, i + 1);
48668                  currentEntryPoint = splitted[splitted.length - 1];
48669                  for (var j = 0; j < i; j++) {
48670                    // Due to the current build process, all p5 functions have
48671                    // _main.default in their names in the final build. This is the
48672                    // easiest way to check if a function is inside the p5 library
48673                    if (stacktrace[j].functionName.search('_main.default') !== -1) {
48674                      isInternal = true;
48675                      p5FileName = stacktrace[j].fileName;
48676                      break;
48677                    }
48678                  }
48679                  break;
48680                }
48681              }
48682
48683              // in some cases ( errors in promises, callbacks, etc), no entry-point
48684              // function may be found in the stacktrace. In that case just use the
48685              // entire stacktrace for friendlyStack
48686              if (!friendlyStack) friendlyStack = stacktrace;
48687
48688              if (isInternal) {
48689                // the frameIndex property is added before the filter, so frameIndex
48690                // corresponds to the index of a frame in the original stacktrace.
48691                // Then we filter out all frames which belong to the file that contains
48692                // the p5 library
48693                friendlyStack = friendlyStack
48694                  .map(function(frame, index) {
48695                    frame.frameIndex = index;
48696                    return frame;
48697                  })
48698                  .filter(function(frame) {
48699                    return frame.fileName !== p5FileName;
48700                  });
48701
48702                // a weird case, if for some reason we can't identify the function called
48703                // from user's code
48704                if (friendlyStack.length === 0) return [true, null];
48705
48706                // get the function just above the topmost frame in the friendlyStack.
48707                // i.e the name of the library function called from user's code
48708                var func = stacktrace[friendlyStack[0].frameIndex - 1].functionName
48709                  .split('.')
48710                  .slice(-1)[0];
48711
48712                // Try and get the location (line no.) from the top element of the stack
48713                var locationObj;
48714                if (
48715                  friendlyStack[0].fileName &&
48716                  friendlyStack[0].lineNumber &&
48717                  friendlyStack[0].columnNumber
48718                ) {
48719                  locationObj = {
48720                    location: ''
48721                      .concat(friendlyStack[0].fileName, ':')
48722                      .concat(friendlyStack[0].lineNumber, ':')
48723                      .concat(friendlyStack[0].columnNumber),
48724                    file: friendlyStack[0].fileName.split('/').slice(-1),
48725                    line: friendlyStack[0].lineNumber
48726                  };
48727
48728                  // if already handled by another part of the FES, don't handle again
48729                  if (_main.default._fesLogCache[locationObj.location]) return [true, null];
48730                }
48731
48732                // Check if the error is due to a non loadX method being used incorrectly
48733                // in preload
48734                if (
48735                  currentEntryPoint === 'preload' &&
48736                  _main.default.prototype._preloadMethods[func] == null
48737                ) {
48738                  report(
48739                    (0, _internationalization.translator)('fes.wrongPreload', {
48740                      func: func,
48741                      location: locationObj
48742                        ? (0, _internationalization.translator)('fes.location', locationObj)
48743                        : '',
48744                      error: error.message
48745                    }),
48746
48747                    'preload'
48748                  );
48749                } else {
48750                  // Library error
48751                  report(
48752                    (0, _internationalization.translator)('fes.libraryError', {
48753                      func: func,
48754                      location: locationObj
48755                        ? (0, _internationalization.translator)('fes.location', locationObj)
48756                        : '',
48757                      error: error.message
48758                    }),
48759
48760                    func
48761                  );
48762                }
48763
48764                // Finally, if it's an internal error, print the friendlyStack
48765                // ( fesErrorMonitor won't handle this error )
48766                if (friendlyStack && friendlyStack.length) {
48767                  printFriendlyStack(friendlyStack);
48768                }
48769              }
48770              return [isInternal, friendlyStack];
48771            };
48772
48773            /**
48774             * The main function for handling global errors. Called when an error
48775             * happens and is responsible for detecting the type of error that
48776             * has happened and showing the appropriate message
48777             *
48778             * @method fesErrorMonitor
48779             * @private
48780             * @param {*} e The object to extract error details from
48781             */
48782            var fesErrorMonitor = function fesErrorMonitor(e) {
48783              if (_main.default.disableFriendlyErrors) return;
48784              // Try to get the error object from e
48785              var error;
48786              if (e instanceof Error) {
48787                error = e;
48788              } else if (e instanceof ErrorEvent) {
48789                error = e.error;
48790              } else if (e instanceof PromiseRejectionEvent) {
48791                error = e.reason;
48792                if (!(error instanceof Error)) return;
48793              }
48794              if (!error) return;
48795
48796              var stacktrace = _main.default._getErrorStackParser().parse(error);
48797              // process the stacktrace from the browser and simplify it to give
48798              // friendlyStack.
48799              var _processStack = processStack(error, stacktrace),
48800                _processStack2 = _slicedToArray(_processStack, 2),
48801                isInternal = _processStack2[0],
48802                friendlyStack = _processStack2[1];
48803
48804              // if this is an internal library error, the type of the error is not relevant,
48805              // only the user code that lead to it is.
48806              if (isInternal) {
48807                return;
48808              }
48809
48810              var errList = errorTable[error.name];
48811              if (!errList) return; // this type of error can't be handled yet
48812              var matchedError;
48813              var _iteratorNormalCompletion = true;
48814              var _didIteratorError = false;
48815              var _iteratorError = undefined;
48816              try {
48817                for (
48818                  var _iterator = errList[Symbol.iterator](), _step;
48819                  !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
48820                  _iteratorNormalCompletion = true
48821                ) {
48822                  var obj = _step.value;
48823                  var string = obj.msg;
48824                  // capture the primary symbol mentioned in the error
48825                  string = string.replace(new RegExp('{{}}', 'g'), '([a-zA-Z0-9_]+)');
48826                  string = string.replace(new RegExp('{{.}}', 'g'), '(.+)');
48827                  string = string.replace(new RegExp('{}', 'g'), '(?:[a-zA-Z0-9_]+)');
48828                  var matched = error.message.match(string);
48829
48830                  if (matched) {
48831                    matchedError = Object.assign({}, obj);
48832                    matchedError.match = matched;
48833                    break;
48834                  }
48835                }
48836              } catch (err) {
48837                _didIteratorError = true;
48838                _iteratorError = err;
48839              } finally {
48840                try {
48841                  if (!_iteratorNormalCompletion && _iterator.return != null) {
48842                    _iterator.return();
48843                  }
48844                } finally {
48845                  if (_didIteratorError) {
48846                    throw _iteratorError;
48847                  }
48848                }
48849              }
48850
48851              if (!matchedError) return;
48852
48853              // Try and get the location from the top element of the stack
48854              var locationObj;
48855              if (
48856                stacktrace &&
48857                stacktrace[0].fileName &&
48858                stacktrace[0].lineNumber &&
48859                stacktrace[0].columnNumber
48860              ) {
48861                locationObj = {
48862                  location: ''
48863                    .concat(stacktrace[0].fileName, ':')
48864                    .concat(stacktrace[0].lineNumber, ':')
48865                    .concat(stacktrace[0].columnNumber),
48866
48867                  file: stacktrace[0].fileName.split('/').slice(-1),
48868                  line: friendlyStack[0].lineNumber
48869                };
48870              }
48871
48872              switch (error.name) {
48873                case 'SyntaxError': {
48874                  // We can't really do much with syntax errors other than try to use
48875                  // a simpler framing of the error message. The stack isn't available
48876                  // for syntax errors
48877                  switch (matchedError.type) {
48878                    case 'INVALIDTOKEN': {
48879                      var url =
48880                        'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Illegal_character#What_went_wrong';
48881                      report(
48882                        (0, _internationalization.translator)(
48883                          'fes.globalErrors.syntax.invalidToken',
48884                          {
48885                            url: url
48886                          }
48887                        )
48888                      );
48889
48890                      break;
48891                    }
48892                    case 'UNEXPECTEDTOKEN': {
48893                      var _url =
48894                        'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Unexpected_token#What_went_wrong';
48895                      report(
48896                        (0, _internationalization.translator)(
48897                          'fes.globalErrors.syntax.unexpectedToken',
48898                          {
48899                            url: _url
48900                          }
48901                        )
48902                      );
48903
48904                      break;
48905                    }
48906                  }
48907
48908                  break;
48909                }
48910                case 'ReferenceError': {
48911                  switch (matchedError.type) {
48912                    case 'NOTDEFINED': {
48913                      var errSym = matchedError.match[1];
48914
48915                      if (errSym && handleMisspelling(errSym, error)) {
48916                        break;
48917                      }
48918
48919                      // if the flow gets this far, this is likely not a misspelling
48920                      // of a p5 property/function
48921                      var url1 = 'https://p5js.org/examples/data-variable-scope.html';
48922                      var url2 =
48923                        'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_Defined#What_went_wrong';
48924                      report(
48925                        (0, _internationalization.translator)(
48926                          'fes.globalErrors.reference.notDefined',
48927                          {
48928                            url1: url1,
48929                            url2: url2,
48930                            symbol: errSym,
48931                            location: locationObj
48932                              ? (0, _internationalization.translator)(
48933                                  'fes.location',
48934                                  locationObj
48935                                )
48936                              : ''
48937                          }
48938                        )
48939                      );
48940
48941                      if (friendlyStack) printFriendlyStack(friendlyStack);
48942                      break;
48943                    }
48944                  }
48945
48946                  break;
48947                }
48948
48949                case 'TypeError': {
48950                  switch (matchedError.type) {
48951                    case 'NOTFUNC': {
48952                      var _errSym = matchedError.match[1];
48953                      var splitSym = _errSym.split('.');
48954                      var _url2 =
48955                        'https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_a_function#What_went_wrong';
48956
48957                      // if errSym is aa.bb.cc , symbol would be cc and obj would aa.bb
48958                      var translationObj = {
48959                        url: _url2,
48960                        symbol: splitSym[splitSym.length - 1],
48961                        obj: splitSym.slice(0, splitSym.length - 1).join('.'),
48962                        location: locationObj
48963                          ? (0, _internationalization.translator)(
48964                              'fes.location',
48965                              locationObj
48966                            )
48967                          : ''
48968                      };
48969
48970                      // There are two cases to handle here. When the function is called
48971                      // as a property of an object and when it's called independently.
48972                      // Both have different explanations.
48973                      if (splitSym.length > 1) {
48974                        report(
48975                          (0, _internationalization.translator)(
48976                            'fes.globalErrors.type.notfuncObj',
48977                            translationObj
48978                          )
48979                        );
48980                      } else {
48981                        report(
48982                          (0, _internationalization.translator)(
48983                            'fes.globalErrors.type.notfunc',
48984                            translationObj
48985                          )
48986                        );
48987                      }
48988
48989                      if (friendlyStack) printFriendlyStack(friendlyStack);
48990                      break;
48991                    }
48992                  }
48993                }
48994              }
48995            };
48996
48997            _main.default._fesErrorMonitor = fesErrorMonitor;
48998            _main.default._checkForUserDefinedFunctions = checkForUserDefinedFunctions;
48999
49000            // logger for testing purposes.
49001            _main.default._fesLogger = null;
49002            _main.default._fesLogCache = {};
49003
49004            window.addEventListener('load', checkForUserDefinedFunctions, false);
49005            window.addEventListener('error', _main.default._fesErrorMonitor, false);
49006            window.addEventListener(
49007              'unhandledrejection',
49008              _main.default._fesErrorMonitor,
49009              false
49010            );
49011
49012            /**
49013             * Prints out all the colors in the color pallete with white text.
49014             * For color blindness testing.
49015             */
49016            /* function testColors() {
49017                                                                                              const str = 'A box of biscuits, a box of mixed biscuits and a biscuit mixer';
49018                                                                                              report(str, 'print', '#ED225D'); // p5.js magenta
49019                                                                                              report(str, 'print', '#2D7BB6'); // p5.js blue
49020                                                                                              report(str, 'print', '#EE9900'); // p5.js orange
49021                                                                                              report(str, 'print', '#A67F59'); // p5.js light brown
49022                                                                                              report(str, 'print', '#704F21'); // p5.js gold
49023                                                                                              report(str, 'print', '#1CC581'); // auto cyan
49024                                                                                              report(str, 'print', '#FF6625'); // auto orange
49025                                                                                              report(str, 'print', '#79EB22'); // auto green
49026                                                                                              report(str, 'print', '#B40033'); // p5.js darkened magenta
49027                                                                                              report(str, 'print', '#084B7F'); // p5.js darkened blue
49028                                                                                              report(str, 'print', '#945F00'); // p5.js darkened orange
49029                                                                                              report(str, 'print', '#6B441D'); // p5.js darkened brown
49030                                                                                              report(str, 'print', '#2E1B00'); // p5.js darkened gold
49031                                                                                              report(str, 'print', '#008851'); // auto dark cyan
49032                                                                                              report(str, 'print', '#C83C00'); // auto dark orange
49033                                                                                              report(str, 'print', '#4DB200'); // auto dark green
49034                                                                                            } */
49035          }
49036
49037          // This is a lazily-defined list of p5 symbols that may be
49038          // misused by beginners at top-level code, outside of setup/draw. We'd like
49039          // to detect these errors and help the user by suggesting they move them
49040          // into setup/draw.
49041          //
49042          // For more details, see https://github.com/processing/p5.js/issues/1121.
49043          misusedAtTopLevelCode = null;
49044          var FAQ_URL =
49045            'https://github.com/processing/p5.js/wiki/p5.js-overview#why-cant-i-assign-variables-using-p5-functions-and-variables-before-setup';
49046
49047          defineMisusedAtTopLevelCode = function defineMisusedAtTopLevelCode() {
49048            var uniqueNamesFound = {};
49049
49050            var getSymbols = function getSymbols(obj) {
49051              return Object.getOwnPropertyNames(obj)
49052                .filter(function(name) {
49053                  if (name[0] === '_') {
49054                    return false;
49055                  }
49056                  if (name in uniqueNamesFound) {
49057                    return false;
49058                  }
49059
49060                  uniqueNamesFound[name] = true;
49061
49062                  return true;
49063                })
49064                .map(function(name) {
49065                  var type;
49066
49067                  if (typeof obj[name] === 'function') {
49068                    type = 'function';
49069                  } else if (name === name.toUpperCase()) {
49070                    type = 'constant';
49071                  } else {
49072                    type = 'variable';
49073                  }
49074
49075                  return { name: name, type: type };
49076                });
49077            };
49078
49079            misusedAtTopLevelCode = [].concat(
49080              getSymbols(_main.default.prototype),
49081              // At present, p5 only adds its constants to p5.prototype during
49082              // construction, which may not have happened at the time a
49083              // ReferenceError is thrown, so we'll manually add them to our list.
49084              getSymbols(_dereq_('../constants'))
49085            );
49086
49087            // This will ultimately ensure that we report the most specific error
49088            // possible to the user, e.g. advising them about HALF_PI instead of PI
49089            // when their code misuses the former.
49090            misusedAtTopLevelCode.sort(function(a, b) {
49091              return b.name.length - a.name.length;
49092            });
49093          };
49094
49095          var helpForMisusedAtTopLevelCode = function helpForMisusedAtTopLevelCode(e, log) {
49096            if (!log) {
49097              log = console.log.bind(console);
49098            }
49099
49100            if (!misusedAtTopLevelCode) {
49101              defineMisusedAtTopLevelCode();
49102            }
49103
49104            // If we find that we're logging lots of false positives, we can
49105            // uncomment the following code to avoid displaying anything if the
49106            // user's code isn't likely to be using p5's global mode. (Note that
49107            // setup/draw are more likely to be defined due to JS function hoisting.)
49108            //
49109            //if (!('setup' in window || 'draw' in window)) {
49110            //  return;
49111            //}
49112
49113            misusedAtTopLevelCode.some(function(symbol) {
49114              // Note that while just checking for the occurrence of the
49115              // symbol name in the error message could result in false positives,
49116              // a more rigorous test is difficult because different browsers
49117              // log different messages, and the format of those messages may
49118              // change over time.
49119              //
49120              // For example, if the user uses 'PI' in their code, it may result
49121              // in any one of the following messages:
49122              //
49123              //   * 'PI' is undefined                           (Microsoft Edge)
49124              //   * ReferenceError: PI is undefined             (Firefox)
49125              //   * Uncaught ReferenceError: PI is not defined  (Chrome)
49126
49127              if (
49128                e.message &&
49129                e.message.match('\\W?'.concat(symbol.name, '\\W')) !== null
49130              ) {
49131                var symbolName =
49132                  symbol.type === 'function' ? ''.concat(symbol.name, '()') : symbol.name;
49133                if (typeof IS_MINIFIED !== 'undefined') {
49134                  log(
49135                    "Did you just try to use p5.js's "
49136                      .concat(symbolName, ' ')
49137                      .concat(
49138                        symbol.type,
49139                        "? If so, you may want to move it into your sketch's setup() function.\n\nFor more details, see: "
49140                      )
49141                      .concat(FAQ_URL)
49142                  );
49143                } else {
49144                  log(
49145                    (0, _internationalization.translator)('fes.misusedTopLevel', {
49146                      symbolName: symbolName,
49147                      symbolType: symbol.type,
49148                      link: FAQ_URL
49149                    })
49150                  );
49151                }
49152                return true;
49153              }
49154            });
49155          };
49156
49157          // Exposing this primarily for unit testing.
49158          _main.default.prototype._helpForMisusedAtTopLevelCode = helpForMisusedAtTopLevelCode;
49159
49160          if (document.readyState !== 'complete') {
49161            window.addEventListener('error', helpForMisusedAtTopLevelCode, false);
49162
49163            // Our job is only to catch ReferenceErrors that are thrown when
49164            // global (non-instance mode) p5 APIs are used at the top-level
49165            // scope of a file, so we'll unbind our error listener now to make
49166            // sure we don't log false positives later.
49167            window.addEventListener('load', function() {
49168              window.removeEventListener('error', helpForMisusedAtTopLevelCode, false);
49169            });
49170          }
49171          var _default = _main.default;
49172          exports.default = _default;
49173        },
49174        {
49175          '../constants': 48,
49176          '../internationalization': 57,
49177          '../main': 59,
49178          './browser_errors': 50
49179        }
49180      ],
49181      52: [
49182        function(_dereq_, module, exports) {
49183          'use strict';
49184          Object.defineProperty(exports, '__esModule', { value: true });
49185          exports.default = void 0;
49186
49187          var _main = _interopRequireDefault(_dereq_('../main'));
49188          var _internationalization = _dereq_('../internationalization');
49189          function _interopRequireDefault(obj) {
49190            return obj && obj.__esModule ? obj : { default: obj };
49191          }
49192          /**
49193           * @for p5
49194           * @requires core
49195           *
49196           * This file contains the part of the FES responsible for dealing with
49197           * file load errors
49198           */ if (typeof IS_MINIFIED !== 'undefined') {
49199            _main.default._friendlyFileLoadError = function() {};
49200          } else {
49201            // mapping used by `_friendlyFileLoadError`
49202            var fileLoadErrorCases = function fileLoadErrorCases(num, filePath) {
49203              var suggestion = (0, _internationalization.translator)(
49204                'fes.fileLoadError.suggestion',
49205                {
49206                  filePath: filePath,
49207                  link: 'https://github.com/processing/p5.js/wiki/Local-server'
49208                }
49209              );
49210
49211              switch (num) {
49212                case 0:
49213                  return {
49214                    message: (0, _internationalization.translator)(
49215                      'fes.fileLoadError.image',
49216                      {
49217                        suggestion: suggestion
49218                      }
49219                    ),
49220
49221                    method: 'loadImage'
49222                  };
49223
49224                case 1:
49225                  return {
49226                    message: (0, _internationalization.translator)(
49227                      'fes.fileLoadError.xml',
49228                      {
49229                        suggestion: suggestion
49230                      }
49231                    ),
49232
49233                    method: 'loadXML'
49234                  };
49235
49236                case 2:
49237                  return {
49238                    message: (0, _internationalization.translator)(
49239                      'fes.fileLoadError.table',
49240                      {
49241                        suggestion: suggestion
49242                      }
49243                    ),
49244
49245                    method: 'loadTable'
49246                  };
49247
49248                case 3:
49249                  return {
49250                    message: (0, _internationalization.translator)(
49251                      'fes.fileLoadError.strings',
49252                      {
49253                        suggestion: suggestion
49254                      }
49255                    ),
49256
49257                    method: 'loadStrings'
49258                  };
49259
49260                case 4:
49261                  return {
49262                    message: (0, _internationalization.translator)(
49263                      'fes.fileLoadError.font',
49264                      {
49265                        suggestion: suggestion
49266                      }
49267                    ),
49268
49269                    method: 'loadFont'
49270                  };
49271
49272                case 5:
49273                  return {
49274                    message: (0, _internationalization.translator)(
49275                      'fes.fileLoadError.json',
49276                      {
49277                        suggestion: suggestion
49278                      }
49279                    ),
49280
49281                    method: 'loadJSON'
49282                  };
49283
49284                case 6:
49285                  return {
49286                    message: (0, _internationalization.translator)(
49287                      'fes.fileLoadError.bytes',
49288                      {
49289                        suggestion: suggestion
49290                      }
49291                    ),
49292
49293                    method: 'loadBytes'
49294                  };
49295
49296                case 7:
49297                  return {
49298                    message: (0, _internationalization.translator)(
49299                      'fes.fileLoadError.large'
49300                    ),
49301                    method: 'loadX'
49302                  };
49303
49304                case 8:
49305                  return {
49306                    message: (0, _internationalization.translator)('fes.fileLoadError.gif'),
49307                    method: 'loadImage'
49308                  };
49309              }
49310            };
49311
49312            /**
49313             * This is called internally if there is a error during file loading.
49314             *
49315             * @method _friendlyFileLoadError
49316             * @private
49317             * @param  {Number} errorType
49318             * @param  {String} filePath
49319             */
49320            _main.default._friendlyFileLoadError = function(errorType, filePath) {
49321              var _fileLoadErrorCases = fileLoadErrorCases(errorType, filePath),
49322                message = _fileLoadErrorCases.message,
49323                method = _fileLoadErrorCases.method;
49324              _main.default._friendlyError(message, method, 3);
49325            };
49326          }
49327          var _default = _main.default;
49328          exports.default = _default;
49329        },
49330        { '../internationalization': 57, '../main': 59 }
49331      ],
49332      53: [
49333        function(_dereq_, module, exports) {
49334          'use strict';
49335          Object.defineProperty(exports, '__esModule', { value: true });
49336          exports.default = void 0;
49337
49338          var _main = _interopRequireDefault(_dereq_('../main'));
49339          function _interopRequireDefault(obj) {
49340            return obj && obj.__esModule ? obj : { default: obj };
49341          } /** // Borrow from stacktracejs https://github.com/stacktracejs/stacktrace.js with
49342           * @for p5
49343           * @requires core
49344           */
49345          // minor modifications. The license for the same and the code is included below
49346          // Copyright (c) 2017 Eric Wendelin and other contributors
49347          // Permission is hereby granted, free of charge, to any person obtaining a copy of
49348          // this software and associated documentation files (the "Software"), to deal in
49349          // the Software without restriction, including without limitation the rights to
49350          // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
49351          // of the Software, and to permit persons to whom the Software is furnished to do
49352          // so, subject to the following conditions:
49353          // The above copyright notice and this permission notice shall be included in all
49354          // copies or substantial portions of the Software.
49355          // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49356          // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49357          // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49358          // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49359          // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49360          // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
49361          // SOFTWARE.
49362          function ErrorStackParser() {
49363            'use strict';
49364
49365            var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
49366            var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
49367            var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code])?$/;
49368
49369            return {
49370              /**
49371               * Given an Error object, extract the most information from it.
49372               * @private
49373               * @param {Error} error object
49374               * @return {Array} of stack frames
49375               */
49376              parse: function ErrorStackParser$$parse(error) {
49377                if (
49378                  typeof error.stacktrace !== 'undefined' ||
49379                  typeof error['opera#sourceloc'] !== 'undefined'
49380                ) {
49381                  return this.parseOpera(error);
49382                } else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) {
49383                  return this.parseV8OrIE(error);
49384                } else if (error.stack) {
49385                  return this.parseFFOrSafari(error);
49386                } else {
49387                  // throw new Error('Cannot parse given Error object');
49388                }
49389              },
49390
49391              // Separate line and column numbers from a string of the form: (URI:Line:Column)
49392              extractLocation: function ErrorStackParser$$extractLocation(urlLike) {
49393                // Fail-fast but return locations like "(native)"
49394                if (urlLike.indexOf(':') === -1) {
49395                  return [urlLike];
49396                }
49397
49398                var regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
49399                var parts = regExp.exec(urlLike.replace(/[()]/g, ''));
49400                return [parts[1], parts[2] || undefined, parts[3] || undefined];
49401              },
49402
49403              parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) {
49404                var filtered = error.stack.split('\n').filter(function(line) {
49405                  return !!line.match(CHROME_IE_STACK_REGEXP);
49406                }, this);
49407
49408                return filtered.map(function(line) {
49409                  if (line.indexOf('(eval ') > -1) {
49410                    // Throw away eval information until we implement stacktrace.js/stackframe#8
49411                    line = line
49412                      .replace(/eval code/g, 'eval')
49413                      .replace(/(\(eval at [^()]*)|(\),.*$)/g, '');
49414                  }
49415                  var sanitizedLine = line.replace(/^\s+/, '').replace(/\(eval code/g, '(');
49416
49417                  // capture and preseve the parenthesized location "(/foo/my bar.js:12:87)" in
49418                  // case it has spaces in it, as the string is split on \s+ later on
49419                  var location = sanitizedLine.match(/ (\((.+):(\d+):(\d+)\)$)/);
49420
49421                  // remove the parenthesized location from the line, if it was matched
49422                  sanitizedLine = location
49423                    ? sanitizedLine.replace(location[0], '')
49424                    : sanitizedLine;
49425
49426                  var tokens = sanitizedLine.split(/\s+/).slice(1);
49427                  // if a location was matched, pass it to extractLocation() otherwise pop the last token
49428                  var locationParts = this.extractLocation(
49429                    location ? location[1] : tokens.pop()
49430                  );
49431
49432                  var functionName = tokens.join(' ') || undefined;
49433                  var fileName =
49434                    ['eval', '<anonymous>'].indexOf(locationParts[0]) > -1
49435                      ? undefined
49436                      : locationParts[0];
49437
49438                  return {
49439                    functionName: functionName,
49440                    fileName: fileName,
49441                    lineNumber: locationParts[1],
49442                    columnNumber: locationParts[2],
49443                    source: line
49444                  };
49445                }, this);
49446              },
49447
49448              parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) {
49449                var filtered = error.stack.split('\n').filter(function(line) {
49450                  return !line.match(SAFARI_NATIVE_CODE_REGEXP);
49451                }, this);
49452
49453                return filtered.map(function(line) {
49454                  // Throw away eval information until we implement stacktrace.js/stackframe#8
49455                  if (line.indexOf(' > eval') > -1) {
49456                    line = line.replace(
49457                      / line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,
49458                      ':$1'
49459                    );
49460                  }
49461
49462                  if (line.indexOf('@') === -1 && line.indexOf(':') === -1) {
49463                    // Safari eval frames only have function names and nothing else
49464                    return {
49465                      functionName: line
49466                    };
49467                  } else {
49468                    var functionNameRegex = /((.*".+"[^@]*)?[^@]*)(?:@)/;
49469                    var matches = line.match(functionNameRegex);
49470                    var functionName = matches && matches[1] ? matches[1] : undefined;
49471                    var locationParts = this.extractLocation(
49472                      line.replace(functionNameRegex, '')
49473                    );
49474
49475                    return {
49476                      functionName: functionName,
49477                      fileName: locationParts[0],
49478                      lineNumber: locationParts[1],
49479                      columnNumber: locationParts[2],
49480                      source: line
49481                    };
49482                  }
49483                }, this);
49484              },
49485
49486              parseOpera: function ErrorStackParser$$parseOpera(e) {
49487                if (
49488                  !e.stacktrace ||
49489                  (e.message.indexOf('\n') > -1 &&
49490                    e.message.split('\n').length > e.stacktrace.split('\n').length)
49491                ) {
49492                  return this.parseOpera9(e);
49493                } else if (!e.stack) {
49494                  return this.parseOpera10(e);
49495                } else {
49496                  return this.parseOpera11(e);
49497                }
49498              },
49499
49500              parseOpera9: function ErrorStackParser$$parseOpera9(e) {
49501                var lineRE = /Line (\d+).*script (?:in )?(\S+)/i;
49502                var lines = e.message.split('\n');
49503                var result = [];
49504
49505                for (var i = 2, len = lines.length; i < len; i += 2) {
49506                  var match = lineRE.exec(lines[i]);
49507                  if (match) {
49508                    result.push({
49509                      fileName: match[2],
49510                      lineNumber: match[1],
49511                      source: lines[i]
49512                    });
49513                  }
49514                }
49515
49516                return result;
49517              },
49518
49519              parseOpera10: function ErrorStackParser$$parseOpera10(e) {
49520                var lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i;
49521                var lines = e.stacktrace.split('\n');
49522                var result = [];
49523
49524                for (var i = 0, len = lines.length; i < len; i += 2) {
49525                  var match = lineRE.exec(lines[i]);
49526                  if (match) {
49527                    result.push({
49528                      functionName: match[3] || undefined,
49529                      fileName: match[2],
49530                      lineNumber: match[1],
49531                      source: lines[i]
49532                    });
49533                  }
49534                }
49535
49536                return result;
49537              },
49538
49539              // Opera 10.65+ Error.stack very similar to FF/Safari
49540              parseOpera11: function ErrorStackParser$$parseOpera11(error) {
49541                var filtered = error.stack.split('\n').filter(function(line) {
49542                  return (
49543                    !!line.match(FIREFOX_SAFARI_STACK_REGEXP) &&
49544                    !line.match(/^Error created at/)
49545                  );
49546                }, this);
49547
49548                return filtered.map(function(line) {
49549                  var tokens = line.split('@');
49550                  var locationParts = this.extractLocation(tokens.pop());
49551                  var functionCall = tokens.shift() || '';
49552                  var functionName =
49553                    functionCall
49554                      .replace(/<anonymous function(: (\w+))?>/, '$2')
49555                      .replace(/\([^)]*\)/g, '') || undefined;
49556                  var argsRaw;
49557                  if (functionCall.match(/\(([^)]*)\)/)) {
49558                    argsRaw = functionCall.replace(/^[^(]+\(([^)]*)\)$/, '$1');
49559                  }
49560                  var args =
49561                    argsRaw === undefined || argsRaw === '[arguments not available]'
49562                      ? undefined
49563                      : argsRaw.split(',');
49564
49565                  return {
49566                    functionName: functionName,
49567                    args: args,
49568                    fileName: locationParts[0],
49569                    lineNumber: locationParts[1],
49570                    columnNumber: locationParts[2],
49571                    source: line
49572                  };
49573                }, this);
49574              }
49575            };
49576          }
49577
49578          // End borrow
49579
49580          // wrapper exposing ErrorStackParser
49581          _main.default._getErrorStackParser = function getErrorStackParser() {
49582            return new ErrorStackParser();
49583          };
49584          var _default = _main.default;
49585          exports.default = _default;
49586        },
49587        { '../main': 59 }
49588      ],
49589      54: [
vendor: 4,501 bytes, lines 49590-49696
49590        function(_dereq_, module, exports) {
49591          'use strict';
49592          Object.defineProperty(exports, '__esModule', { value: true });
49593          exports.default = void 0;
49594
49595          var _main = _interopRequireDefault(_dereq_('../main'));
49596          var constants = _interopRequireWildcard(_dereq_('../constants'));
49597          var _internationalization = _dereq_('../internationalization');
49598          function _getRequireWildcardCache() {
49599            if (typeof WeakMap !== 'function') return null;
49600            var cache = new WeakMap();
49601            _getRequireWildcardCache = function _getRequireWildcardCache() {
49602              return cache;
49603            };
49604            return cache;
49605          }
49606          function _interopRequireWildcard(obj) {
49607            if (obj && obj.__esModule) {
49608              return obj;
49609            }
49610            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
49611              return { default: obj };
49612            }
49613            var cache = _getRequireWildcardCache();
49614            if (cache && cache.has(obj)) {
49615              return cache.get(obj);
49616            }
49617            var newObj = {};
49618            var hasPropertyDescriptor =
49619              Object.defineProperty && Object.getOwnPropertyDescriptor;
49620            for (var key in obj) {
49621              if (Object.prototype.hasOwnProperty.call(obj, key)) {
49622                var desc = hasPropertyDescriptor
49623                  ? Object.getOwnPropertyDescriptor(obj, key)
49624                  : null;
49625                if (desc && (desc.get || desc.set)) {
49626                  Object.defineProperty(newObj, key, desc);
49627                } else {
49628                  newObj[key] = obj[key];
49629                }
49630              }
49631            }
49632            newObj.default = obj;
49633            if (cache) {
49634              cache.set(obj, newObj);
49635            }
49636            return newObj;
49637          }
49638          function _interopRequireDefault(obj) {
49639            return obj && obj.__esModule ? obj : { default: obj };
49640          }
49641          function _classCallCheck(instance, Constructor) {
49642            if (!(instance instanceof Constructor)) {
49643              throw new TypeError('Cannot call a class as a function');
49644            }
49645          }
49646          function _possibleConstructorReturn(self, call) {
49647            if (call && (_typeof(call) === 'object' || typeof call === 'function')) {
49648              return call;
49649            }
49650            return _assertThisInitialized(self);
49651          }
49652          function _assertThisInitialized(self) {
49653            if (self === void 0) {
49654              throw new ReferenceError(
49655                "this hasn't been initialised - super() hasn't been called"
49656              );
49657            }
49658            return self;
49659          }
49660          function _inherits(subClass, superClass) {
49661            if (typeof superClass !== 'function' && superClass !== null) {
49662              throw new TypeError('Super expression must either be null or a function');
49663            }
49664            subClass.prototype = Object.create(superClass && superClass.prototype, {
49665              constructor: { value: subClass, writable: true, configurable: true }
49666            });
49667            if (superClass) _setPrototypeOf(subClass, superClass);
49668          }
49669          function _wrapNativeSuper(Class) {
49670            var _cache = typeof Map === 'function' ? new Map() : undefined;
49671            _wrapNativeSuper = function _wrapNativeSuper(Class) {
49672              if (Class === null || !_isNativeFunction(Class)) return Class;
49673              if (typeof Class !== 'function') {
49674                throw new TypeError('Super expression must either be null or a function');
49675              }
49676              if (typeof _cache !== 'undefined') {
49677                if (_cache.has(Class)) return _cache.get(Class);
49678                _cache.set(Class, Wrapper);
49679              }
49680              function Wrapper() {
49681                return _construct(Class, arguments, _getPrototypeOf(this).constructor);
49682              }
49683              Wrapper.prototype = Object.create(Class.prototype, {
49684                constructor: {
49685                  value: Wrapper,
49686                  enumerable: false,
49687                  writable: true,
49688                  configurable: true
49689                }
49690              });
49691              return _setPrototypeOf(Wrapper, Class);
49692            };
49693            return _wrapNativeSuper(Class);
49694          }
49695          function isNativeReflectConstruct() {
49696            if (typeof Reflect === 'undefined' || !Reflect.construct) return false;
49697            if (Reflect.construct.sham) return false;
49698            if (typeof Proxy === 'function') return true;
49699            try {
49700              Date.prototype.toString.call(Reflect.construct(Date, [], function() {}));
49701              return true;
49702            } catch (e) {
49703              return false;
49704            }
49705          }
49706          function _construct(Parent, args, Class) {
49707            if (isNativeReflectConstruct()) {
49708              _construct = Reflect.construct;
49709            } else {
49710              _construct = function _construct(Parent, args, Class) {
49711                var a = [null];
49712                a.push.apply(a, args);
49713                var Constructor = Function.bind.apply(Parent, a);
49714                var instance = new Constructor();
49715                if (Class) _setPrototypeOf(instance, Class.prototype);
49716                return instance;
49717              };
49718            }
49719            return _construct.apply(null, arguments);
49720          }
49721          function _isNativeFunction(fn) {
49722            return Function.toString.call(fn).indexOf('[native code]') !== -1;
49723          }
49724          function _setPrototypeOf(o, p) {
49725            _setPrototypeOf =
49726              Object.setPrototypeOf ||
49727              function _setPrototypeOf(o, p) {
49728                o.__proto__ = p;
49729                return o;
49730              };
49731            return _setPrototypeOf(o, p);
49732          }
49733          function _getPrototypeOf(o) {
49734            _getPrototypeOf = Object.setPrototypeOf
49735              ? Object.getPrototypeOf
49736              : function _getPrototypeOf(o) {
49737                  return o.__proto__ || Object.getPrototypeOf(o);
49738                };
49739            return _getPrototypeOf(o);
49740          }
49741          function _typeof(obj) {
49742            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
49743              _typeof = function _typeof(obj) {
49744                return typeof obj;
49745              };
49746            } else {
49747              _typeof = function _typeof(obj) {
49748                return obj &&
49749                  typeof Symbol === 'function' &&
49750                  obj.constructor === Symbol &&
49751                  obj !== Symbol.prototype
49752                  ? 'symbol'
49753                  : typeof obj;
49754              };
49755            }
49756            return _typeof(obj);
49757          }
49758
49759          if (typeof IS_MINIFIED !== 'undefined') {
49760            _main.default._validateParameters = _main.default._clearValidateParamsCache = function() {};
49761          } else {
49762            // for parameter validation
49763            var dataDoc = _dereq_('../../../docs/parameterData.json');
49764            var arrDoc = JSON.parse(JSON.stringify(dataDoc));
49765
49766            var docCache = {};
49767            var builtinTypes = new Set([
49768              'null',
49769              'number',
49770              'string',
49771              'boolean',
49772              'constant',
49773              'function',
49774              'any',
49775              'integer'
49776            ]);
49777
49778            var basicTypes = {
49779              number: true,
49780              boolean: true,
49781              string: true,
49782              function: true,
49783              undefined: true
49784            };
49785
49786            // reverse map of all constants
49787            var constantsReverseMap = {};
49788            for (var key in constants) {
49789              constantsReverseMap[constants[key]] = key;
49790            }
49791
49792            // mapping names of p5 types to their constructor function
49793            // p5Constructors:
49794            //    - Color: f()
49795            //    - Graphics: f()
49796            //    - Vector: f()
49797            // and so on
49798            var p5Constructors = {};
49799
49800            // For speedup over many runs. funcSpecificConstructors[func] only has the
49801            // constructors for types which were seen earlier as args of "func"
49802            var funcSpecificConstructors = {};
49803            window.addEventListener('load', function() {
49804              // Make a list of all p5 classes to be used for argument validation
49805              // This must be done only when everything has loaded otherwise we get
49806              // an empty array
49807              for (
49808                var _i = 0, _Object$keys = Object.keys(_main.default);
49809                _i < _Object$keys.length;
49810                _i++
49811              ) {
49812                var _key = _Object$keys[_i];
49813                // Get a list of all constructors in p5. They are functions whose names
49814                // start with a capital letter
49815                if (
49816                  typeof _main.default[_key] === 'function' &&
49817                  _key[0] !== _key[0].toLowerCase()
49818                ) {
49819                  p5Constructors[_key] = _main.default[_key];
49820                }
49821              }
49822            });
49823
49824            var argumentTree = {};
49825            // The following two functions are responsible for querying and inserting
49826            // into the argument tree. It stores the types of arguments that each
49827            // function has seen so far. It is used to query if a sequence of
49828            // arguments seen in validate parameters was seen before.
49829            // Lets consider that the following segment of code runs repeatedly, perhaps
49830            // in a loop or in draw()
49831            //   color(10, 10, 10);
49832            //   color(10, 10);
49833            //   color('r', 'g', 'b');
49834            // After the first of run the code segment, the argument tree looks like
49835            // - color
49836            //     - number
49837            //        - number
49838            //            - number
49839            //                - seen: true
49840            //            - seen: true
49841            //     - string
49842            //        - string
49843            //            - string
49844            //                - seen: true
49845            // seen: true signifies that this argument was also seen as the last
49846            // argument in a call. Now in the second run of the sketch, it would traverse
49847            // the existing tree and see seen: true, i.e this sequence was seen
49848            // before and so scoring can be skipped. This also prevents logging multiple
49849            // validation messages for the same thing.
49850
49851            // These two functions would be called repeatedly over and over again,
49852            // so they need to be as optimized for performance as possible
49853
49854            var addType = function addType(value, obj, func) {
49855              var type = _typeof(value);
49856              if (basicTypes[type]) {
49857                if (constantsReverseMap[value]) {
49858                  // check if the value is a p5 constant and if it is, we would want the
49859                  // value itself to be stored in the tree instead of the type
49860                  obj = obj[value] || (obj[value] = {});
49861                } else {
49862                  obj = obj[type] || (obj[type] = {});
49863                }
49864              } else if (value === null) {
49865                // typeof null -> "object". don't want that
49866                obj = obj['null'] || (obj['null'] = {});
49867              } else {
49868                // objects which are instances of p5 classes have nameless constructors.
49869                // native objects have a constructor named "Object". This check
49870                // differentiates between the two so that we dont waste time finding the
49871                // p5 class if we just have a native object
49872                if (value.constructor && value.constructor.name) {
49873                  obj = obj[value.constructor.name] || (obj[value.constructor.name] = {});
49874                  return obj;
49875                }
49876
49877                // constructors for types defined in p5 do not have a name property.
49878                // e.constructor.name gives "". Code in this segment is a workaround for it
49879
49880                // p5C will only have the name: constructor mapping for types
49881                // which were already seen as args of "func"
49882                var p5C = funcSpecificConstructors[func];
49883                // p5C would contain much fewer items than p5Constructors. if we find our
49884                // answer in p5C, we don't have to scan through p5Constructors
49885
49886                if (p5C === undefined) {
49887                  // if there isn't an entry yet for func
49888                  // make an entry of empty object
49889                  p5C = funcSpecificConstructors[func] = {};
49890                }
49891
49892                for (var _key2 in p5C) {
49893                  // search on the constructors we have already seen (smaller search space)
49894                  if (value instanceof p5C[_key2]) {
49895                    obj = obj[_key2] || (obj[_key2] = {});
49896                    return obj;
49897                  }
49898                }
49899
49900                for (var _key3 in p5Constructors) {
49901                  // if the above search didn't work, search on all p5 constructors
49902                  if (value instanceof p5Constructors[_key3]) {
49903                    obj = obj[_key3] || (obj[_key3] = {});
49904                    // if found, add to known constructors for this function
49905                    p5C[_key3] = p5Constructors[_key3];
49906                    return obj;
49907                  }
49908                }
49909                // nothing worked, put the type as is
49910                obj = obj[type] || (obj[type] = {});
49911              }
49912
49913              return obj;
49914            };
49915            var buildArgTypeCache = function buildArgTypeCache(func, arr) {
49916              // get the if an argument tree for current function already exists
49917              var obj = argumentTree[func];
49918              if (obj === undefined) {
49919                // if it doesn't, create an empty tree
49920                obj = argumentTree[func] = {};
49921              }
49922
49923              for (var i = 0, len = arr.length; i < len; ++i) {
49924                var value = arr[i];
49925                if (value instanceof Array) {
49926                  // an array is passed as an argument, expand it and get the type of
49927                  // each of its element. We distinguish the start of an array with 'as'
49928                  // or arraystart. This would help distinguish between the arguments
49929                  // (number, number, number) and (number, [number, number])
49930                  obj = obj['as'] || (obj['as'] = {});
49931                  for (var j = 0, lenA = value.length; j < lenA; ++j) {
49932                    obj = addType(value[j], obj, func);
49933                  }
49934                } else {
49935                  obj = addType(value, obj, func);
49936                }
49937              }
49938              return obj;
49939            };
49940
49941            // validateParameters() helper functions:
49942            // lookupParamDoc() for querying data.json
49943            var lookupParamDoc = function lookupParamDoc(func) {
49944              // look for the docs in the `data.json` datastructure
49945
49946              var ichDot = func.lastIndexOf('.');
49947              var funcName = func.substr(ichDot + 1);
49948              var funcClass = func.substr(0, ichDot) || 'p5';
49949
49950              var classitems = arrDoc;
49951              var queryResult = classitems[funcClass][funcName];
49952
49953              // different JSON structure for funct with multi-format
49954              var overloads = [];
49955              if (queryResult.hasOwnProperty('overloads')) {
49956                // add all the overloads
49957                for (var i = 0; i < queryResult.overloads.length; i++) {
49958                  overloads.push({ formats: queryResult.overloads[i].params });
49959                }
49960              } else {
49961                // no overloads, just add the main method definition
49962                overloads.push({ formats: queryResult.params || [] });
49963              }
49964
49965              // parse the parameter types for each overload
49966              var mapConstants = {};
49967              var maxParams = 0;
49968              overloads.forEach(function(overload) {
49969                var formats = overload.formats;
49970
49971                // keep a record of the maximum number of arguments
49972                // this method requires.
49973                if (maxParams < formats.length) {
49974                  maxParams = formats.length;
49975                }
49976
49977                // calculate the minimum number of arguments
49978                // this overload requires.
49979                var minParams = formats.length;
49980                while (minParams > 0 && formats[minParams - 1].optional) {
49981                  minParams--;
49982                }
49983                overload.minParams = minParams;
49984
49985                // loop through each parameter position, and parse its types
49986                formats.forEach(function(format) {
49987                  // split this parameter's types
49988                  format.types = format.type.split('|').map(function ct(type) {
49989                    // array
49990                    if (type.substr(type.length - 2, 2) === '[]') {
49991                      return {
49992                        name: type,
49993                        array: ct(type.substr(0, type.length - 2))
49994                      };
49995                    }
49996
49997                    var lowerType = type.toLowerCase();
49998
49999                    // contant
50000                    if (lowerType === 'constant') {
50001                      var constant;
50002                      if (mapConstants.hasOwnProperty(format.name)) {
50003                        constant = mapConstants[format.name];
50004                      } else {
50005                        // parse possible constant values from description
50006                        var myRe = /either\s+(?:[A-Z0-9_]+\s*,?\s*(?:or)?\s*)+/g;
50007                        var values = {};
50008                        var names = [];
50009
50010                        constant = mapConstants[format.name] = {
50011                          values: values,
50012                          names: names
50013                        };
50014
50015                        var myArray = myRe.exec(format.description);
50016                        if (func === 'endShape' && format.name === 'mode') {
50017                          values[constants.CLOSE] = true;
50018                          names.push('CLOSE');
50019                        } else {
50020                          var match = myArray[0];
50021                          var reConst = /[A-Z0-9_]+/g;
50022                          var matchConst;
50023                          while ((matchConst = reConst.exec(match)) !== null) {
50024                            var name = matchConst[0];
50025                            if (constants.hasOwnProperty(name)) {
50026                              values[constants[name]] = true;
50027                              names.push(name);
50028                            }
50029                          }
50030                        }
50031                      }
50032                      return {
50033                        name: type,
50034                        builtin: lowerType,
50035                        names: constant.names,
50036                        values: constant.values
50037                      };
50038                    }
50039
50040                    // function
50041                    if (lowerType.substr(0, 'function'.length) === 'function') {
50042                      lowerType = 'function';
50043                    }
50044                    // builtin
50045                    if (builtinTypes.has(lowerType)) {
50046                      return { name: type, builtin: lowerType };
50047                    }
50048
50049                    // find type's prototype
50050                    var t = window;
50051                    var typeParts = type.split('.');
50052
50053                    // special-case 'p5' since it may be non-global
50054                    if (typeParts[0] === 'p5') {
50055                      t = _main.default;
50056                      typeParts.shift();
50057                    }
50058
50059                    typeParts.forEach(function(p) {
50060                      t = t && t[p];
50061                    });
50062                    if (t) {
50063                      return { name: type, prototype: t };
50064                    }
50065
50066                    return { name: type, type: lowerType };
50067                  });
50068                });
50069              });
50070              return {
50071                overloads: overloads,
50072                maxParams: maxParams
50073              };
50074            };
50075
50076            var isNumber = function isNumber(param) {
50077              switch (_typeof(param)) {
50078                case 'number':
50079                  return true;
50080                case 'string':
50081                  return !isNaN(param);
50082                default:
50083                  return false;
50084              }
50085            };
50086
50087            var testParamType = function testParamType(param, type) {
50088              var isArray = param instanceof Array;
50089              var matches = true;
50090              if (type.array && isArray) {
50091                for (var i = 0; i < param.length; i++) {
50092                  var error = testParamType(param[i], type.array);
50093                  if (error) return error / 2; // half error for elements
50094                }
50095              } else if (type.prototype) {
50096                matches = param instanceof type.prototype;
50097              } else if (type.builtin) {
50098                switch (type.builtin) {
50099                  case 'number':
50100                    matches = isNumber(param);
50101                    break;
50102                  case 'integer':
50103                    matches = isNumber(param) && Number(param) === Math.floor(param);
50104                    break;
50105                  case 'boolean':
50106                  case 'any':
50107                    matches = true;
50108                    break;
50109                  case 'array':
50110                    matches = isArray;
50111                    break;
50112                  case 'string':
50113                    matches = /*typeof param === 'number' ||*/ typeof param === 'string';
50114                    break;
50115                  case 'constant':
50116                    matches = type.values.hasOwnProperty(param);
50117                    break;
50118                  case 'function':
50119                    matches = param instanceof Function;
50120                    break;
50121                  case 'null':
50122                    matches = param === null;
50123                    break;
50124                }
50125              } else {
50126                matches = _typeof(param) === type.t;
50127              }
50128              return matches ? 0 : 1;
50129            };
50130
50131            // testType() for non-object type parameter validation
50132            var testParamTypes = function testParamTypes(param, types) {
50133              var minScore = 9999;
50134              for (var i = 0; minScore > 0 && i < types.length; i++) {
50135                var score = testParamType(param, types[i]);
50136                if (minScore > score) minScore = score;
50137              }
50138              return minScore;
50139            };
50140
50141            // generate a score (higher is worse) for applying these args to
50142            // this overload.
50143            var scoreOverload = function scoreOverload(args, argCount, overload, minScore) {
50144              var score = 0;
50145              var formats = overload.formats;
50146              var minParams = overload.minParams;
50147
50148              // check for too few/many args
50149              // the score is double number of extra/missing args
50150              if (argCount < minParams) {
50151                score = (minParams - argCount) * 2;
50152              } else if (argCount > formats.length) {
50153                score = (argCount - formats.length) * 2;
50154              }
50155
50156              // loop through the formats, adding up the error score for each arg.
50157              // quit early if the score gets higher than the previous best overload.
50158              for (var p = 0; score <= minScore && p < formats.length; p++) {
50159                var arg = args[p];
50160                var format = formats[p];
50161                // '== null' checks for 'null' and typeof 'undefined'
50162                if (arg == null) {
50163                  // handle undefined args
50164                  if (!format.optional || p < minParams || p < argCount) {
50165                    score += 1;
50166                  }
50167                } else {
50168                  score += testParamTypes(arg, format.types);
50169                }
50170              }
50171              return score;
50172            };
50173
50174            // gets a list of errors for this overload
50175            var getOverloadErrors = function getOverloadErrors(args, argCount, overload) {
50176              var formats = overload.formats;
50177              var minParams = overload.minParams;
50178
50179              // check for too few/many args
50180              if (argCount < minParams) {
50181                return [
50182                  {
50183                    type: 'TOO_FEW_ARGUMENTS',
50184                    argCount: argCount,
50185                    minParams: minParams
50186                  }
50187                ];
50188              } else if (argCount > formats.length) {
50189                return [
50190                  {
50191                    type: 'TOO_MANY_ARGUMENTS',
50192                    argCount: argCount,
50193                    maxParams: formats.length
50194                  }
50195                ];
50196              }
50197
50198              var errorArray = [];
50199              for (var p = 0; p < formats.length; p++) {
50200                var arg = args[p];
50201                var format = formats[p];
50202                // '== null' checks for 'null' and typeof 'undefined'
50203                if (arg == null) {
50204                  // handle undefined args
50205                  if (!format.optional || p < minParams || p < argCount) {
50206                    errorArray.push({
50207                      type: 'EMPTY_VAR',
50208                      position: p,
50209                      format: format
50210                    });
50211                  }
50212                } else if (testParamTypes(arg, format.types) > 0) {
50213                  errorArray.push({
50214                    type: 'WRONG_TYPE',
50215                    position: p,
50216                    format: format,
50217                    arg: arg
50218                  });
50219                }
50220              }
50221
50222              return errorArray;
50223            };
50224
50225            // a custom error type, used by the mocha
50226            // tests when expecting validation errors
50227            _main.default.ValidationError = (function(name) {
50228              var err = /*#__PURE__*/ (function(_Error) {
50229                _inherits(err, _Error);
50230                function err(message, func, type) {
50231                  var _this;
50232                  _classCallCheck(this, err);
50233                  _this = _possibleConstructorReturn(this, _getPrototypeOf(err).call(this));
50234                  _this.message = message;
50235                  _this.func = func;
50236                  _this.type = type;
50237                  if ('captureStackTrace' in Error)
50238                    Error.captureStackTrace(_assertThisInitialized(_this), err);
50239                  else _this.stack = new Error().stack;
50240                  return _this;
50241                }
50242                return err;
50243              })(_wrapNativeSuper(Error));
50244
50245              err.prototype.name = name;
50246              return err;
50247            })('ValidationError');
50248
50249            // function for generating console.log() msg
50250            _main.default._friendlyParamError = function(errorObj, func) {
50251              var message;
50252              var translationObj;
50253
50254              function formatType() {
50255                var format = errorObj.format;
50256                return format.types
50257                  .map(function(type) {
50258                    return type.names ? type.names.join('|') : type.name;
50259                  })
50260                  .join('|');
50261              }
50262
50263              switch (errorObj.type) {
50264                case 'EMPTY_VAR': {
50265                  translationObj = {
50266                    func: func,
50267                    formatType: formatType(),
50268                    // It needs to be this way for i18next-extract to work. The comment
50269                    // specifies the values that the context can take so that it can
50270                    // statically prepare the translation files with them.
50271                    /* i18next-extract-mark-context-next-line ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"] */
50272                    position: (0, _internationalization.translator)('fes.positions.p', {
50273                      context: (errorObj.position + 1).toString(),
50274                      defaultValue: (errorObj.position + 1).toString()
50275                    }),
50276
50277                    link: '[https://p5js.org/examples/data-variable-scope.html]'
50278                  };
50279
50280                  break;
50281                }
50282                case 'WRONG_TYPE': {
50283                  var arg = errorObj.arg;
50284                  var argType =
50285                    arg instanceof Array
50286                      ? 'array'
50287                      : arg === null ? 'null' : arg.name || _typeof(arg);
50288
50289                  translationObj = {
50290                    func: func,
50291                    formatType: formatType(),
50292                    argType: argType,
50293                    /* i18next-extract-mark-context-next-line ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"] */
50294                    position: (0, _internationalization.translator)('fes.positions.p', {
50295                      context: (errorObj.position + 1).toString(),
50296                      defaultValue: (errorObj.position + 1).toString()
50297                    })
50298                  };
50299
50300                  break;
50301                }
50302                case 'TOO_FEW_ARGUMENTS': {
50303                  translationObj = {
50304                    func: func,
50305                    minParams: errorObj.minParams,
50306                    argCount: errorObj.argCount
50307                  };
50308
50309                  break;
50310                }
50311                case 'TOO_MANY_ARGUMENTS': {
50312                  translationObj = {
50313                    func: func,
50314                    maxParams: errorObj.maxParams,
50315                    argCount: errorObj.argCount
50316                  };
50317
50318                  break;
50319                }
50320              }
50321
50322              if (translationObj) {
50323                try {
50324                  // const re = /Function\.validateParameters.*[\r\n].*[\r\n].*\(([^)]*)/;
50325                  var myError = new Error();
50326                  var parsed = _main.default._getErrorStackParser().parse(myError);
50327                  if (
50328                    parsed[3] &&
50329                    parsed[3].functionName &&
50330                    parsed[3].functionName.includes('.') &&
50331                    _main.default.prototype[parsed[3].functionName.split('.').slice(-1)[0]]
50332                  ) {
50333                    return;
50334                  }
50335                  if (_main.default._throwValidationErrors) {
50336                    throw new _main.default.ValidationError(message, func, errorObj.type);
50337                  }
50338
50339                  // try to extract the location from where the function was called
50340                  if (
50341                    parsed[3] &&
50342                    parsed[3].fileName &&
50343                    parsed[3].lineNumber &&
50344                    parsed[3].columnNumber
50345                  ) {
50346                    var location = ''
50347                      .concat(parsed[3].fileName, ':')
50348                      .concat(parsed[3].lineNumber, ':')
50349                      .concat(parsed[3].columnNumber);
50350
50351                    translationObj.location = (0, _internationalization.translator)(
50352                      'fes.location',
50353                      {
50354                        location: location,
50355                        // for e.g. get "sketch.js" from "https://example.com/abc/sketch.js"
50356                        file: parsed[3].fileName.split('/').slice(-1),
50357                        line: parsed[3].lineNumber
50358                      }
50359                    );
50360
50361                    // tell fesErrorMonitor that we have already given a friendly message
50362                    // for this line, so it need not to do the same in case of an error
50363                    _main.default._fesLogCache[location] = true;
50364                  }
50365                } catch (err) {
50366                  if (err instanceof _main.default.ValidationError) {
50367                    throw err;
50368                  }
50369                }
50370
50371                translationObj.context = errorObj.type;
50372                // i18next-extract-mark-context-next-line ["EMPTY_VAR", "TOO_MANY_ARGUMENTS", "TOO_FEW_ARGUMENTS", "WRONG_TYPE"]
50373                message = (0, _internationalization.translator)(
50374                  'fes.friendlyParamError.type',
50375                  translationObj
50376                );
50377
50378                _main.default._friendlyError(''.concat(message, '.'), func, 3);
50379              }
50380            };
50381
50382            // if a function is called with some set of wrong arguments, and then called
50383            // again with the same set of arguments, the messages due to the second call
50384            // will be supressed. If two tests test on the same wrong arguments, the
50385            // second test won't see the validationError. clearing argumentTree solves it
50386            _main.default._clearValidateParamsCache = function clearValidateParamsCache() {
50387              for (
50388                var _i2 = 0, _Object$keys2 = Object.keys(argumentTree);
50389                _i2 < _Object$keys2.length;
50390                _i2++
50391              ) {
50392                var _key4 = _Object$keys2[_i2];
50393                delete argumentTree[_key4];
50394              }
50395            };
50396
50397            // allowing access to argumentTree for testing
50398            _main.default._getValidateParamsArgTree = function getValidateParamsArgTree() {
50399              return argumentTree;
50400            };
50401
50402            /**
50403             * Validates parameters
50404             * param  {String}               func    the name of the function
50405             * param  {Array}                args    user input arguments
50406             *
50407             * example:
50408             *  const a;
50409             *  ellipse(10,10,a,5);
50410             * console ouput:
50411             *  "It looks like ellipse received an empty variable in spot #2."
50412             *
50413             * example:
50414             *  ellipse(10,"foo",5,5);
50415             * console output:
50416             *  "ellipse was expecting a number for parameter #1,
50417             *           received "foo" instead."
50418             */
50419            _main.default._validateParameters = function validateParameters(func, args) {
50420              if (_main.default.disableFriendlyErrors) {
50421                return;
50421 // skip FES
50422              }
50423
50424              // query / build the argument type tree and check if this sequence
50425              // has already been seen before.
50426              var obj = buildArgTypeCache(func, args);
50427              if (obj.seen) {
50428                return;
50429              }
50430              // mark this sequence as seen
50431              obj.seen = true;
50432              // lookup the docs in the 'data.json' file
50433              var docs = docCache[func] || (docCache[func] = lookupParamDoc(func));
50434              var overloads = docs.overloads;
50435
50436              var argCount = args.length;
50437
50438              // the following line ignores trailing undefined arguments, commenting
50439              // it to resolve https://github.com/processing/p5.js/issues/4571
50440              // '== null' checks for 'null' and typeof 'undefined'
50441              // while (argCount > 0 && args[argCount - 1] == null) argCount--;
50442
50443              // find the overload with the best score
50444              var minScore = 99999;
50445              var minOverload;
50446              for (var i = 0; i < overloads.length; i++) {
50447                var score = scoreOverload(args, argCount, overloads[i], minScore);
50448                if (score === 0) {
50449                  return; // done!
50450                } else if (minScore > score) {
50451                  // this score is better that what we have so far...
50452                  minScore = score;
50453                  minOverload = i;
50454                }
50455              }
50456
50457              // this should _always_ be true here...
50458              if (minScore > 0) {
50459                // get the errors for the best overload
50460                var errorArray = getOverloadErrors(args, argCount, overloads[minOverload]);
50461
50462                // generate err msg
50463                for (var n = 0; n < errorArray.length; n++) {
50464                  _main.default._friendlyParamError(errorArray[n], func);
50465                }
50466              }
50467            };
50468            _main.default.prototype._validateParameters = _main.default.validateParameters;
50469          }
50470          var _default = _main.default;
50471          exports.default = _default;
50472        },
50473        {
50474          '../../../docs/parameterData.json': 1,
50475          '../constants': 48,
50476          '../internationalization': 57,
50477          '../main': 59
50478        }
50479      ],
50480      55: [
50481        function(_dereq_, module, exports) {
50482          'use strict';
50483          function _typeof(obj) {
50484            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
50485              _typeof = function _typeof(obj) {
50486                return typeof obj;
50487              };
50488            } else {
50489              _typeof = function _typeof(obj) {
50490                return obj &&
50491                  typeof Symbol === 'function' &&
50492                  obj.constructor === Symbol &&
50493                  obj !== Symbol.prototype
50494                  ? 'symbol'
50495                  : typeof obj;
50496              };
50497            }
50498            return _typeof(obj);
50499          }
50500          Object.defineProperty(exports, '__esModule', { value: true });
50501          exports.default = void 0;
50502
50503          var constants = _interopRequireWildcard(_dereq_('./constants'));
50504          function _getRequireWildcardCache() {
50505            if (typeof WeakMap !== 'function') return null;
50506            var cache = new WeakMap();
50507            _getRequireWildcardCache = function _getRequireWildcardCache() {
50508              return cache;
50509            };
50510            return cache;
50511          }
50512          function _interopRequireWildcard(obj) {
50513            if (obj && obj.__esModule) {
50514              return obj;
50515            }
50516            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
50517              return { default: obj };
50518            }
50519            var cache = _getRequireWildcardCache();
50520            if (cache && cache.has(obj)) {
50521              return cache.get(obj);
50522            }
50523            var newObj = {};
50524            var hasPropertyDescriptor =
50525              Object.defineProperty && Object.getOwnPropertyDescriptor;
50526            for (var key in obj) {
50527              if (Object.prototype.hasOwnProperty.call(obj, key)) {
50528                var desc = hasPropertyDescriptor
50529                  ? Object.getOwnPropertyDescriptor(obj, key)
50530                  : null;
50531                if (desc && (desc.get || desc.set)) {
50532                  Object.defineProperty(newObj, key, desc);
50533                } else {
50534                  newObj[key] = obj[key];
50535                }
50536              }
50537            }
50538            newObj.default = obj;
50539            if (cache) {
50540              cache.set(obj, newObj);
50541            }
50542            return newObj;
50543          }
50544          /**
50545           * @requires constants
50546           */ function modeAdjust(a, b, c, d, mode) {
50547            if (mode === constants.CORNER) {
50548              return { x: a, y: b, w: c, h: d };
50549            } else if (mode === constants.CORNERS) {
50550              return { x: a, y: b, w: c - a, h: d - b };
50551            } else if (mode === constants.RADIUS) {
50552              return { x: a - c, y: b - d, w: 2 * c, h: 2 * d };
50553            } else if (mode === constants.CENTER) {
50554              return { x: a - c * 0.5, y: b - d * 0.5, w: c, h: d };
50555            }
50556          }
50557          var _default = { modeAdjust: modeAdjust };
50558          exports.default = _default;
50559        },
50560        { './constants': 48 }
50561      ],
50562      56: [
50563        function(_dereq_, module, exports) {
50564          'use strict';
50565          var _main = _interopRequireDefault(_dereq_('../core/main'));
50566          var _internationalization = _dereq_('./internationalization');
50567          function _interopRequireDefault(obj) {
50568            return obj && obj.__esModule ? obj : { default: obj };
50569          }
50570
50571          /**
50572           * _globalInit
50573           *
50574           * TODO: ???
50575           * if sketch is on window
50576           * assume "global" mode
50577           * and instantiate p5 automatically
50578           * otherwise do nothing
50579           *
50580           * @private
50581           * @return {Undefined}
50582           */
50583          var _globalInit = function _globalInit() {
50584            // Could have been any property defined within the p5 constructor.
50585            // If that property is already a part of the global object,
50586            // this code has already run before, likely due to a duplicate import
50587            if (typeof window._setupDone !== 'undefined') {
50588              console.warn(
50589                'p5.js seems to have been imported multiple times. Please remove the duplicate import'
50590              );
50591
50592              return;
50593            }
50594
50595            if (!window.mocha) {
50596              // If there is a setup or draw function on the window
50597              // then instantiate p5 in "global" mode
50598              if (
50599                ((window.setup && typeof window.setup === 'function') ||
50600                  (window.draw && typeof window.draw === 'function')) &&
50601                !_main.default.instance
50602              ) {
50603                new _main.default();
50604              }
50605            }
50606          };
50607
50608          // make a promise that resolves when the document is ready
50609          var waitForDocumentReady = function waitForDocumentReady() {
50610            return new Promise(function(resolve, reject) {
50611              // if the page is ready, initialize p5 immediately
50612              if (document.readyState === 'complete') {
50613                resolve();
50614                // if the page is still loading, add an event listener
50615                // and initialize p5 as soon as it finishes loading
50616              } else {
50617                window.addEventListener('load', resolve, false);
50618              }
50619            });
50620          };
50621
50622          // only load translations if we're using the full, un-minified library
50623          var waitingForTranslator =
50624            typeof IS_MINIFIED === 'undefined'
50625              ? (0, _internationalization.initialize)()
50626              : Promise.resolve();
50627
50628          Promise.all([waitForDocumentReady(), waitingForTranslator]).then(_globalInit);
50629        },
50630        { '../core/main': 59, './internationalization': 57 }
50631      ],
50632      57: [
50633        function(_dereq_, module, exports) {
50634          'use strict';
50635          Object.defineProperty(exports, '__esModule', { value: true });
50636          exports.initialize = exports.translator = void 0;
50637          var _i18next = _interopRequireDefault(_dereq_('i18next'));
50638          var _i18nextBrowserLanguagedetector = _interopRequireDefault(
50639            _dereq_('i18next-browser-languagedetector')
50640          );
50641          function _interopRequireDefault(obj) {
50642            return obj && obj.__esModule ? obj : { default: obj };
50643          }
50644          function _classCallCheck(instance, Constructor) {
50645            if (!(instance instanceof Constructor)) {
50646              throw new TypeError('Cannot call a class as a function');
50647            }
50648          }
50649          function _defineProperties(target, props) {
50650            for (var i = 0; i < props.length; i++) {
50651              var descriptor = props[i];
50652              descriptor.enumerable = descriptor.enumerable || false;
50653              descriptor.configurable = true;
50654              if ('value' in descriptor) descriptor.writable = true;
50655              Object.defineProperty(target, descriptor.key, descriptor);
50656            }
50657          }
50658          function _createClass(Constructor, protoProps, staticProps) {
50659            if (protoProps) _defineProperties(Constructor.prototype, protoProps);
50660            if (staticProps) _defineProperties(Constructor, staticProps);
50661            return Constructor;
50662          }
50663
50664          var fallbackResources, languages;
50665          if (typeof IS_MINIFIED === 'undefined') {
50666            // internationalization is only for the unminified build
50667
50668            var translationsModule = _dereq_('../../translations');
50669            fallbackResources = translationsModule.default;
50670            languages = translationsModule.languages;
50671
50672            if (typeof P5_DEV_BUILD !== 'undefined') {
50673              // When the library is built in development mode ( using npm run dev )
50674              // we want to use the current translation files on the disk, which may have
50675              // been updated but not yet pushed to the CDN.
50676              var completeResources = _dereq_('../../translations/dev');
50677              for (
50678                var _i = 0, _Object$keys = Object.keys(completeResources);
50679                _i < _Object$keys.length;
50680                _i++
50681              ) {
50682                var language = _Object$keys[_i];
50683                // In es_translation, language is es and namespace is translation
50684                // In es_MX_translation, language is es-MX and namespace is translation
50685                var parts = language.split('_');
50686                var lng = parts.slice(0, parts.length - 1).join('-');
50687                var ns = parts[parts.length - 1];
50688
50689                fallbackResources[lng] = fallbackResources[lng] || {};
50690                fallbackResources[lng][ns] = completeResources[language];
50691              }
50692            }
50693          }
50694
50695          /**
50696           * This is our i18next "backend" plugin. It tries to fetch languages
50697           * from a CDN.
50698           */ var FetchResources = /*#__PURE__*/ (function() {
50699            function FetchResources(services, options) {
50700              _classCallCheck(this, FetchResources);
50701              this.init(services, options);
50702            }
50703
50704            // run fetch with a timeout. Automatically rejects on timeout
50705            // default timeout = 2000 ms
50706            _createClass(FetchResources, [
50707              {
50708                key: 'fetchWithTimeout',
50709                value: function fetchWithTimeout(url, options) {
50710                  var timeout =
50711                    arguments.length > 2 && arguments[2] !== undefined
50712                      ? arguments[2]
50713                      : 2000;
50714                  return Promise.race([
50715                    fetch(url, options),
50716                    new Promise(function(_, reject) {
50717                      return setTimeout(function() {
50718                        return reject(new Error('timeout'));
50719                      }, timeout);
50720                    })
50721                  ]);
50722                }
50723              },
50724              {
50725                key: 'init',
50726                value: function init(services) {
50727                  var options =
50728                    arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
50729                  this.services = services;
50730                  this.options = options;
50731                }
50732              },
50733              {
50734                key: 'read',
50735                value: function read(language, namespace, callback) {
50736                  var loadPath = this.options.loadPath;
50737
50738                  if (language === this.options.fallback) {
50739                    // if the default language of the user is the same as our inbuilt fallback,
50740                    // there's no need to fetch resources from the c
50740dn. This won't actually
50741                    // need to run when we use "partialBundledLanguages" in the init
50742                    // function.
50743                    callback(null, fallbackResources[language][namespace]);
50744                  } else if (languages.includes(language)) {
50745                    // The user's language is included in the list of languages
50746                    // that we so far added translations for.
50747
50748                    var url = this.services.interpolator.interpolate(loadPath, {
50749                      lng: language,
50750                      ns: namespace
50751                    });
50752
50753                    this.loadUrl(url, callback);
50754                  } else {
50755                    // We don't have translations for this language. i18next will use
50756                    // the default language instead.
50757                    callback('Not found', false);
50758                  }
50759                }
50760              },
50761              {
50762                key: 'loadUrl',
50763                value: function loadUrl(url, callback) {
50764                  this.fetchWithTimeout(url)
50765                    .then(
50766                      function(response) {
50767                        var ok = response.ok;
50768
50769                        if (!ok) {
50770                          // caught in the catch() below
50771                          throw new Error('failed loading '.concat(url));
50772                        }
50773                        return response.json();
50774                      },
50775                      function() {
50776                        // caught in the catch() below
50777                        throw new Error('failed loading '.concat(url));
50778                      }
50779                    )
50780                    .then(function(data) {
50781                      return callback(null, data);
50782                    })
50783                    .catch(callback);
50784                }
50785              }
50786            ]);
50787            return FetchResources;
50788          })();
50789
50790          FetchResources.type = 'backend';
50791
50792          /**
50793           * This is our translation function. Give it a key and
50794           * it will retreive the appropriate string
50795           * (within supported languages) according to the
50796           * user's browser's language settings.
50797           * @function translator
50798           * @param {String} key a key that corresponds to a message in our translation files
50799           * @param {Object} values values for use in the message under the given `key`
50800           * @returns {String} message (with values inserted) in the user's browser language
50801           * @private
50802           */
50803          var translator = function translator(key, values) {
50804            console.debug('p5.js translator called before translations were loaded');
50805
50806            // Certain FES functionality may trigger before translations are downloaded.
50807            // Using "partialBundledLanguages" option during initialization, we can
50808            // still use our fallback language to display messages
50809            _i18next.default.t(key, values); /* i18next-extract-disable-line */
50810          };
50811          // (We'll set this to a real value in the init function below!)
50812
50813          /**
50814           * Set up our translation function, with loaded languages
50815           */ exports.translator = translator;
50816          var initialize = function initialize() {
50817            var i18init = _i18next.default
50818              .use(_i18nextBrowserLanguagedetector.default)
50819              .use(FetchResources)
50820              .init({
50821                fallbackLng: 'en',
50822                nestingPrefix: '$tr(',
50823                nestingSuffix: ')',
50824                defaultNS: 'translation',
50825                returnEmptyString: false,
50826                interpolation: {
50827                  escapeValue: false
50828                },
50829
50830                detection: {
50831                  checkWhitelist: false,
50832
50833                  // prevent storing or locating language from cookie or localStorage
50834                  // more info on https://github.com/processing/p5.js/issues/4862
50835                  order: ['querystring', 'navigator', 'htmlTag', 'path', 'subdomain'],
50836                  caches: []
50837                },
50838
50839                backend: {
50840                  fallback: 'en',
50841                  loadPath:
50842                    'https://cdn.jsdelivr.net/npm/p5/translations/{{lng}}/{{ns}}.json'
50843                },
50844
50845                partialBundledLanguages: true,
50846                resources: fallbackResources
50847              })
50848              .then(
50849                function(translateFn) {
50850                  exports.translator = translator = translateFn;
50851                },
50852                function(e) {
50853                  return console.debug('Translations failed to load ('.concat(e, ')'));
50854                }
50855              );
50856
50857            // i18next.init() returns a promise that resolves when the translations
50858            // are loaded. We use this in core/init.js to hold p5 initialization until
50859            // we have the translation files.
50860            return i18init;
50861          };
50862          exports.initialize = initialize;
50863        },
50864        {
50865          '../../translations': 118,
50866          '../../translations/dev': undefined,
50867          i18next: 30,
50868          'i18next-browser-languagedetector': 27
50869        }
50870      ],
50871      58: [
50872        function(_dereq_, module, exports) {
50873          'use strict';
50874          Object.defineProperty(exports, '__esModule', { value: true });
50875          exports.default = void 0;
50876
50877          var _main = _interopRequireDefault(_dereq_('./main'));
50878          function _interopRequireDefault(obj) {
50879            return obj && obj.__esModule ? obj : { default: obj };
50880          }
50881          /**
50882           * @for p5
50883           * @requires core
50884           * These are functions that are part of the Processing API but are not part of
50885           * the p5.js API. In some cases they have a new name, in others, they are
50886           * removed completely. Not all unsupported Processing functions are listed here
50887           * but we try to include ones that a user coming from Processing might likely
50888           * call.
50889           */ _main.default.prototype.pushStyle = function() {
50890            throw new Error('pushStyle() not used, see push()');
50891          };
50892          _main.default.prototype.popStyle = function() {
50893            throw new Error('popStyle() not used, see pop()');
50894          };
50895
50896          _main.default.prototype.popMatrix = function() {
50897            throw new Error('popMatrix() not used, see pop()');
50898          };
50899
50900          _main.default.prototype.pushMatrix = function() {
50901            throw new Error('pushMatrix() not used, see push()');
50902          };
50903          var _default = _main.default;
50904          exports.default = _default;
50905        },
50906        { './main': 59 }
50907      ],
50908      59: [
50909        function(_dereq_, module, exports) {
50910          'use strict';
50911          function _typeof(obj) {
50912            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
50913              _typeof = function _typeof(obj) {
50914                return typeof obj;
50915              };
50916            } else {
50917              _typeof = function _typeof(obj) {
50918                return obj &&
50919                  typeof Symbol === 'function' &&
50920                  obj.constructor === Symbol &&
50921                  obj !== Symbol.prototype
50922                  ? 'symbol'
50923                  : typeof obj;
50924              };
50925            }
50926            return _typeof(obj);
50927          }
50928          Object.defineProperty(exports, '__esModule', { value: true });
50929          exports.default = void 0;
50930
50931          _dereq_('./shim');
50932
50933          var constants = _interopRequireWildcard(_dereq_('./constants'));
50934          function _getRequireWildcardCache() {
50935            if (typeof WeakMap !== 'function') return null;
50936            var cache = new WeakMap();
50937            _getRequireWildcardCache = function _getRequireWildcardCache() {
50938              return cache;
50939            };
50940            return cache;
50941          }
50942          function _interopRequireWildcard(obj) {
50943            if (obj && obj.__esModule) {
50944              return obj;
50945            }
50946            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
50947              return { default: obj };
50948            }
50949            var cache = _getRequireWildcardCache();
50950            if (cache && cache.has(obj)) {
50951              return cache.get(obj);
50952            }
50953            var newObj = {};
50954            var hasPropertyDescriptor =
50955              Object.defineProperty && Object.getOwnPropertyDescriptor;
50956            for (var key in obj) {
50957              if (Object.prototype.hasOwnProperty.call(obj, key)) {
50958                var desc = hasPropertyDescriptor
50959                  ? Object.getOwnPropertyDescriptor(obj, key)
50960                  : null;
50961                if (desc && (desc.get || desc.set)) {
50962                  Object.defineProperty(newObj, key, desc);
50963                } else {
50964                  newObj[key] = obj[key];
50965                }
50966              }
50967            }
50968            newObj.default = obj;
50969            if (cache) {
50970              cache.set(obj, newObj);
50971            }
50972            return newObj;
50973          }
50974          function _classCallCheck(instance, Constructor) {
50975            if (!(instance instanceof Constructor)) {
50976              throw new TypeError('Cannot call a class as a function');
50977            }
50978          }
50979          function _defineProperties(target, props) {
50980            for (var i = 0; i < props.length; i++) {
50981              var descriptor = props[i];
50982              descriptor.enumerable = descriptor.enumerable || false;
50983              descriptor.configurable = true;
50984              if ('value' in descriptor) descriptor.writable = true;
50985              Object.defineProperty(target, descriptor.key, descriptor);
50986            }
50987          }
50988          function _createClass(Constructor, protoProps, staticProps) {
50989            if (protoProps) _defineProperties(Constructor.prototype, protoProps);
50990            if (staticProps) _defineProperties(Constructor, staticProps);
50991            return Constructor;
50992          }
50993
50994          /**
50995           * This is the p5 instance constructor.
50996           *
50997           * A p5 instance holds all the properties and methods related to
50998           * a p5 sketch.  It expects an incoming sketch closure and it can also
50999           * take an optional node parameter for attaching the generated p5 canvas
51000           * to a node.  The sketch closure takes the newly created p5 instance as
51001           * its sole argument and may optionally set <a href="#/p5/preload">preload()</a>,
51002           * <a href="#/p5/setup">setup()</a>, and/or
51003           * <a href="#/p5/draw">draw()</a> properties on it for running a sketch.
51004           *
51005           * A p5 sketch can run in "global" or "instance" mode:
51006           * "global"   - all properties and methods are attached to the window
51007           * "instance" - all properties and methods are bound to this p5 object
51008           *
51009           * @class p5
51010           * @constructor
51011           * @param  {function}           sketch a closure that can set optional <a href="#/p5/preload">preload()</a>,
51012           *                              <a href="#/p5/setup">setup()</a>, and/or <a href="#/p5/draw">draw()</a> properties on the
51013           *                              given p5 instance
51014           * @param  {HTMLElement}        [node] element to attach canvas to
51015           * @return {p5}                 a p5 instance
51016           */ var p5 = /*#__PURE__*/ (function() {
51017            function p5(sketch, node, sync) {
51018              var _this = this;
51019              _classCallCheck(this, p5);
51020              //////////////////////////////////////////////
51021              // PUBLIC p5 PROPERTIES AND METHODS
51022              //////////////////////////////////////////////
51023
51024              /**
51025               * Called directly before <a href="#/p5/setup">setup()</a>, the <a href="#/p5/preload">preload()</a> function is used to handle
51026               * asynchronous loading of external files in a blocking way. If a preload
51027               * function is defined, <a href="#/p5/setup">setup()</a> will wait until any load calls within have
51028               * finished. Nothing besides load calls (<a href="#/p5/loadImage">loadImage</a>, <a href="#/p5/loadJSON">loadJSON</a>, <a href="#/p5/loadFont">loadFont</a>,
51029               * <a href="#/p5/loadStrings">loadStrings</a>, etc.) should be inside the preload function. If asynchronous
51030               * loading is preferred, the load methods can instead be called in <a href="#/p5/setup">setup()</a>
51031               * or anywhere else with the use of a callback parameter.
51032               *
51033               * By default the text "loading..." will be displayed. To make your own
51034               * loading page, include an HTML element with id "p5_loading" in your
51035               * page. More information <a href="http://bit.ly/2kQ6Nio">here</a>.
51036               *
51037               * @method preload
51038               * @example
51039               * <div><code>
51040               * let img;
51041               * let c;
51042               * function preload() {
51043               *   // preload() runs once
51044               *   img = loadImage('assets/laDefense.jpg');
51045               * }
51046               *
51047               * function setup() {
51048               *   // setup() waits until preload() is done
51049               *   img.loadPixels();
51050               *   // get color of middle pixel
51051               *   c = img.get(img.width / 2, img.height / 2);
51052               * }
51053               *
51054               * function draw() {
51055               *   background(c);
51056               *   image(img, 25, 25, 50, 50);
51057               * }
51058               * </code></div>
51059               *
51060               * @alt
51061               * nothing displayed
51062               *
51063               */
51064
51065              /**
51066               * The <a href="#/p5/setup">setup()</a> function is called once when the program starts. It's used to
51067               * define initial environment properties such as screen size and background
51068               * color and to load media such as images and fonts as the program starts.
51069               * There can only be one <a href="#/p5/setup">setup()</a> function for each program and it shouldn't
51070               * be called again after its initial execution.
51071               *
51072               * Note: Variables declared within <a href="#/p5/setup">setup()</a> are not accessible within other
51073               * functions, including <a href="#/p5/draw">draw()</a>.
51074               *
51075               * @method setup
51076               * @example
51077               * <div><code>
51078               * let a = 0;
51079               *
51080               * function setup() {
51081               *   background(0);
51082               *   noStroke();
51083               *   fill(102);
51084               * }
51085               *
51086               * function draw() {
51087               *   rect(a++ % width, 10, 2, 80);
51088               * }
51089               * </code></div>
51090               *
51091               * @alt
51092               * nothing displayed
51093               *
51094               */
51095
51096              /**
51097               * Called directly after <a href="#/p5/setup">setup()</a>, the <a href="#/p5/draw">draw()</a> function continuously executes
51098               * the lines of code contained inside its block until the program is stopped
51099               * or <a href="#/p5/noLoop">noLoop()</a> is called. Note if <a href="#/p5/noLoop">noLoop()</a> is called in <a href="#/p5/setup">setup()</a>, <a href="#/p5/draw">draw()</a> will
51100               * still be executed once before stopping. <a href="#/p5/draw">draw()</a> is called automatically and
51101               * should never be called explicitly.
51102               *
51103               * It should always be controlled with <a href="#/p5/noLoop">noLoop()</a>, <a href="#/p5/redraw">redraw()</a> and <a href="#/p5/loop">loop()</a>. After
51104               * <a href="#/p5/noLoop">noLoop()</a> stops the code in <a href="#/p5/draw">draw()</a> from executing, <a href="#/p5/redraw">redraw()</a> causes the
51105               * code inside <a href="#/p5/draw">draw()</a> to execute once, and <a href="#/p5/loop">loop()</a> will cause the code
51106               * inside <a href="#/p5/draw">draw()</a> to resume executing continuously.
51107               *
51108               * The number of times <a href="#/p5/draw">draw()</a> executes in each second may be controlled with
51109               * the <a href="#/p5/frameRate">frameRate()</a> function.
51110               *
51111               * There can only be one <a href="#/p5/draw">draw()</a> function for each sketch, and <a href="#/p5/draw">draw()</a> must
51112               * exist if you want the code to run continuously, or to process events such
51113               * as <a href="#/p5/mousePressed">mousePressed()</a>. Sometimes, you might have an empty call to <a href="#/p5/draw">draw()</a> in
51114               * your program, as shown in the above example.
51115               *
51116               * It is important to note that the drawing coordinate system will be reset
51117               * at the beginning of each <a href="#/p5/draw">draw()</a> call. If any transformations are performed
51118               * within <a href="#/p5/draw">draw()</a> (ex: scale, rotate, translate), their effects will be
51119               * undone at the beginning of <a href="#/p5/draw">draw()</a>, so transformations will not accumulate
51120               * over time. On the other hand, styling applied (ex: fill, stroke, etc) will
51121               * remain in effect.
51122               *
51123               * @method draw
51124               * @example
51125               * <div><code>
51126               * let yPos = 0;
51127               * function setup() {
51128               *   // setup() runs once
51129               *   frameRate(30);
51130               * }
51131               * function draw() {
51132               *   // draw() loops forever, until stopped
51133               *   background(204);
51134               *   yPos = yPos - 1;
51135               *   if (yPos < 0) {
51136               *     yPos = height;
51137               *   }
51138               *   line(0, yPos, width, yPos);
51139               * }
51140               * </code></div>
51141               *
51142               * @alt
51143               * nothing displayed
51144               *
51145               */
51146
51147              //////////////////////////////////////////////
51148              // PRIVATE p5 PROPERTIES AND METHODS
51149              //////////////////////////////////////////////
51150
51151              this._accessibleOutputs = {
51152                text: false,
51153                grid: false,
51154                textLabel: false,
51155                gridLabel: false
51156              };
51157
51158              this._setupDone = false;
51159              // for handling hidpi
51160              this._pixelDensity = Math.ceil(window.devicePixelRatio) || 1;
51161              this._userNode = node;
51162              this._curElement = null;
51163              this._elements = [];
51164              this._glAttributes = null;
51165              this._requestAnimId = 0;
51166              this._preloadCount = 0;
51167              this._isGlobal = false;
51168              this._loop = true;
51169              this._initializeInstanceVariables();
51170              this._defaultCanvasSize = {
51171                width: 100,
51172                height: 100
51173              };
51174
51175              this._events = {
51176                // keep track of user-events for unregistering later
51177                mousemove: null,
51178                mousedown: null,
51179                mouseup: null,
51180                dragend: null,
51181                dragover: null,
51182                click: null,
51183                dblclick: null,
51184                mouseover: null,
51185                mouseout: null,
51186                keydown: null,
51187                keyup: null,
51188                keypress: null,
51189                touchstart: null,
51190                touchmove: null,
51191                touchend: null,
51192                resize: null,
51193                blur: null
51194              };
51195
51196              this._millisStart = -1;
51197
51198              // States used in the custom random generators
51199              this._lcg_random_state = null;
51200              this._gaussian_previous = false;
51201
51202              this._events.wheel = null;
51203              this._loadingScreenId = 'p5_loading';
51204
51205              // Allows methods to be registered on an instance that
51206              // are instance-specific.
51207              this._registeredMethods = {};
51208              var methods = Object.getOwnPropertyNames(p5.prototype._registeredMethods);
51209              var _iteratorNormalCompletion = true;
51210              var _didIteratorError = false;
51211              var _iteratorError = undefined;
51212              try {
51213                for (
51214                  var _iterator = methods[Symbol.iterator](), _step;
51215                  !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
51216                  _iteratorNormalCompletion = true
51217                ) {
51218                  var prop = _step.value;
51219                  this._registeredMethods[prop] = p5.prototype._registeredMethods[
51220                    prop
51221                  ].slice();
51222                }
51223              } catch (err) {
51224                _didIteratorError = true;
51225                _iteratorError = err;
51226              } finally {
51227                try {
51228                  if (!_iteratorNormalCompletion && _iterator.return != null) {
51229                    _iterator.return();
51230                  }
51231                } finally {
51232                  if (_didIteratorError) {
51233                    throw _iteratorError;
51234                  }
51235                }
51236              }
51237
51238              if (window.DeviceOrientationEvent) {
51239                this._events.deviceorientation = null;
51240              }
51241              if (window.DeviceMotionEvent && !window._isNodeWebkit) {
51242                this._events.devicemotion = null;
51243              }
51244
51245              this._start = function() {
51246                // Find node if id given
51247                if (_this._userNode) {
51248                  if (typeof _this._userNode === 'string') {
51249                    _this._userNode = document.getElementById(_this._userNode);
51250                  }
51251                }
51252
51253                var context = _this._isGlobal ? window : _this;
51254                if (context.preload) {
51255                  // Setup loading screen
51256                  // Set loading screen into dom if not present
51257                  // Otherwise displays and removes user provided loading screen
51258                  var loadingScreen = document.getElementById(_this._loadingScreenId);
51259                  if (!loadingScreen) {
51260                    loadingScreen = document.createElement('div');
51261                    loadingScreen.innerHTML = 'Loading...';
51262                    loadingScreen.style.position = 'absolute';
51263                    loadingScreen.id = _this._loadingScreenId;
51264                    var _node = _this._userNode || document.body;
51265                    _node.appendChild(loadingScreen);
51266                  }
51267                  var _methods = _this._preloadMethods;
51268                  for (var method in _methods) {
51269                    // default to p5 if no object defined
51270                    _methods[method] = _methods[method] || p5;
51271                    var obj = _methods[method];
51272                    //it's p5, check if it's global or instance
51273                    if (obj === p5.prototype || obj === p5) {
51274                      if (_this._isGlobal) {
51275                        window[method] = _this._wrapPreload(_this, method);
51276                      }
51277                      obj = _this;
51278                    }
51279                    _this._registeredPreloadMethods[method] = obj[method];
51280                    obj[method] = _this._wrapPreload(obj, method);
51281                  }
51282
51283                  context.preload();
51284                  _this._runIfPreloadsAreDone();
51285                } else {
51286                  _this._setup();
51287                  _this._draw();
51288                }
51289              };
51290
51291              this._runIfPreloadsAreDone = function() {
51292                var context = this._isGlobal ? window : this;
51293                if (context._preloadCount === 0) {
51294                  var loadingScreen = document.getElementById(context._loadingScreenId);
51295                  if (loadingScreen) {
51296                    loadingScreen.parentNode.removeChild(loadingScreen);
51297                  }
51298                  if (!this._setupDone) {
51299                    this._lastFrameTime = window.performance.now();
51300                    context._setup();
51301                    context._draw();
51302                  }
51303                }
51304              };
51305
51306              this._decrementPreload = function() {
51307                var context = this._isGlobal ? window : this;
51308                if (typeof context.preload === 'function') {
51309                  context._setProperty('_preloadCount', context._preloadCount - 1);
51310                  context._runIfPreloadsAreDone();
51311                }
51312              };
51313
51314              this._wrapPreload = function(obj, fnName) {
51315                var _this2 = this;
51316                return function() {
51317                  //increment counter
51318                  _this2._incrementPreload();
51319                  //call original function
51320                  for (
51321                    var _len = arguments.length, args = new Array(_len), _key = 0;
51322                    _key < _len;
51323                    _key++
51324                  ) {
51325                    args[_key] = arguments[_key];
51326                  }
51327                  return _this2._registeredPreloadMethods[fnName].apply(obj, args);
51328                };
51329              };
51330
51331              this._incrementPreload = function() {
51332                var context = this._isGlobal ? window : this;
51333                context._setProperty('_preloadCount', context._preloadCount + 1);
51334              };
51335
51336              this._setup = function() {
51337                // Always create a default canvas.
51338                // Later on if the user calls createCanvas, this default one
51339                // will be replaced
51340                _this.createCanvas(
51341                  _this._defaultCanvasSize.width,
51342                  _this._defaultCanvasSize.height,
51343                  'p2d'
51344                );
51345
51346                // return preload functions to their normal vals if switched by preload
51347                var context = _this._isGlobal ? window : _this;
51348                if (typeof context.preload === 'function') {
51349                  for (var f in _this._preloadMethods) {
51350                    context[f] = _this._preloadMethods[f][f];
51351                    if (context[f] && _this) {
51352                      context[f] = context[f].bind(_this);
51353                    }
51354                  }
51355                }
51356
51357                // Record the time when sketch starts
51358                _this._millisStart = window.performance.now();
51359
51360                // Short-circuit on this, in case someone used the library in "global"
51361                // mode earlier
51362                if (typeof context.setup === 'function') {
51363                  context.setup();
51364                }
51365
51366                // unhide any hidden canvases that were created
51367                var canvases = document.getElementsByTagName('canvas');
51368                var _iteratorNormalCompletion2 = true;
51369                var _didIteratorError2 = false;
51370                var _iteratorError2 = undefined;
51371                try {
51372                  for (
51373                    var _iterator2 = canvases[Symbol.iterator](), _step2;
51374                    !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done);
51375                    _iteratorNormalCompletion2 = true
51376                  ) {
51377                    var k = _step2.value;
51378                    if (k.dataset.hidden === 'true') {
51379                      k.style.visibility = '';
51380                      delete k.dataset.hidden;
51381                    }
51382                  }
51383                } catch (err) {
51384                  _didIteratorError2 = true;
51385                  _iteratorError2 = err;
51386                } finally {
51387                  try {
51388                    if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
51389                      _iterator2.return();
51390                    }
51391                  } finally {
51392                    if (_didIteratorError2) {
51393                      throw _iteratorError2;
51394                    }
51395                  }
51396                }
51397
51398                _this._lastFrameTime = window.performance.now();
51399                _this._setupDone = true;
51400                if (_this._accessibleOutputs.grid || _this._accessibleOutputs.text) {
51401                  _this._updateAccsOutput();
51402                }
51403              };
51404
51405              this._draw = function() {
51406                var now = window.performance.now();
51407                var time_since_last = now - _this._lastFrameTime;
51408                var target_time_between_frames = 1000 / _this._targetFrameRate;
51409
51410                // only draw if we really need to; don't overextend the browser.
51411                // draw if we're within 5ms of when our next frame should paint
51412                // (this will prevent us from giving up opportunities to draw
51413                // again when it's really about time for us to do so). fixes an
51414                // issue where the frameRate is too low if our refresh loop isn't
51415                // in sync with the browser. note that we have to draw once even
51416                // if looping is off, so we bypass the time delay if that
51417                // is the case.
51418                var epsilon = 5;
51419                if (
51420                  !_this._loop ||
51421                  time_since_last >= target_time_between_frames - epsilon
51422                ) {
51423                  //mandatory update values(matrixs and stack)
51424                  _this.redraw();
51425                  _this._frameRate = 1000.0 / (now - _this._lastFrameTime);
51426                  _this.deltaTime = now - _this._lastFrameTime;
51427                  _this._setProperty('deltaTime', _this.deltaTime);
51428                  _this._lastFrameTime = now;
51429
51430                  // If the user is actually using mouse module, then update
51431                  // coordinates, otherwise skip. We can test this by simply
51432                  // checking if any of the mouse functions are available or not.
51433                  // NOTE : This reflects only in complete build or modular build.
51434                  if (typeof _this._updateMouseCoords !== 'undefined') {
51435                    _this._updateMouseCoords();
51436
51437                    //reset delta values so they reset even if there is no mouse event to set them
51438                    // for example if the mouse is outside the screen
51439                    _this._setProperty('movedX', 0);
51440                    _this._setProperty('movedY', 0);
51441                  }
51442                }
51443
51444                // get notified the next time the browser gives us
51445                // an opportunity to draw.
51446                if (_this._loop) {
51447                  _this._requestAnimId = window.requestAnimationFrame(_this._draw);
51448                }
51449              };
51450
51451              this._setProperty = function(prop, value) {
51452                _this[prop] = value;
51453                if (_this._isGlobal) {
51454                  window[prop] = value;
51455                }
51456              };
51457
51458              /**
51459               * Removes the entire p5 sketch. This will remove the canvas and any
51460               * elements created by p5.js. It will also stop the draw loop and unbind
51461               * any properties or methods from the window global scope. It will
51462               * leave a variable p5 in case you wanted to create a new p5 sketch.
51463               * If you like, you can set p5 = null to erase it. While all functions and
51464               * variables and objects created by the p5 library will be removed, any
51465               * other global variables created by your code will remain.
51466               *
51467               * @method remove
51468               * @example
51469               * <div class='norender'><code>
51470               * function draw() {
51471               *   ellipse(50, 50, 10, 10);
51472               * }
51473               *
51474               * function mousePressed() {
51475               *   remove(); // remove whole sketch on mouse press
51476               * }
51477               * </code></div>
51478               *
51479               * @alt
51480               * nothing displayed
51481               *
51482               */
51483              this.remove = function() {
51484                var loadingScreen = document.getElementById(_this._loadingScreenId);
51485                if (loadingScreen) {
51486                  loadingScreen.parentNode.removeChild(loadingScreen);
51487                  // Add 1 to preload counter to prevent the sketch ever executing setup()
51488                  _this._incrementPreload();
51489                }
51490                if (_this._curElement) {
51491                  // stop draw
51492                  _this._loop = false;
51493                  if (_this._requestAnimId) {
51494                    window.cancelAnimationFrame(_this._requestAnimId);
51495                  }
51496
51497                  // unregister events sketch-wide
51498                  for (var ev in _this._events) {
51499                    window.removeEventListener(ev, _this._events[ev]);
51500                  }
51501
51502                  // remove DOM elements created by p5, and listeners
51503                  var _iteratorNormalCompletion3 = true;
51504                  var _didIteratorError3 = false;
51505                  var _iteratorError3 = undefined;
51506                  try {
51507                    for (
51508                      var _iterator3 = _this._elements[Symbol.iterator](), _step3;
51509                      !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done);
51510                      _iteratorNormalCompletion3 = true
51511                    ) {
51512                      var e = _step3.value;
51513                      if (e.elt && e.elt.parentNode) {
51514                        e.elt.parentNode.removeChild(e.elt);
51515                      }
51516                      for (var elt_ev in e._events) {
51517                        e.elt.removeEventListener(elt_ev, e._events[elt_ev]);
51518                      }
51519                    }
51520
51521                    // call any registered remove functions
51522                  } catch (err) {
51523                    _didIteratorError3 = true;
51524                    _iteratorError3 = err;
51525                  } finally {
51526                    try {
51527                      if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
51528                        _iterator3.return();
51529                      }
51530                    } finally {
51531                      if (_didIteratorError3) {
51532                        throw _iteratorError3;
51533                      }
51534                    }
51535                  }
51536                  var self = _this;
51537                  _this._registeredMethods.remove.forEach(function(f) {
51538                    if (typeof f !== 'undefined') {
51539                      f.call(self);
51540                    }
51541                  });
51542                }
51543                // remove window bound properties and methods
51544                if (_this._isGlobal) {
51545                  for (var p in p5.prototype) {
51546                    try {
51547                      delete window[p];
51548                    } catch (x) {
51549                      window[p] = undefined;
51550                    }
51551                  }
51552                  for (var p2 in _this) {
51553                    if (_this.hasOwnProperty(p2)) {
51554                      try {
51555                        delete window[p2];
51556                      } catch (x) {
51557                        window[p2] = undefined;
51558                      }
51559                    }
51560                  }
51561                  p5.instance = null;
51562                }
51563              };
51564
51565              // call any registered init functions
51566              this._registeredMethods.init.forEach(function(f) {
51567                if (typeof f !== 'undefined') {
51568                  f.call(this);
51569                }
51570              }, this);
51571              // Set up promise preloads
51572              this._setupPromisePreloads();
51573
51574              var friendlyBindGlobal = this._createFriendlyGlobalFunctionBinder();
51575
51576              // If the user has created a global setup or draw function,
51577              // assume "global" mode and make everything global (i.e. on the window)
51578              if (!sketch) {
51579                this._isGlobal = true;
51580                p5.instance = this;
51581                // Loop through methods on the prototype and attach them to the window
51582                for (var p in p5.prototype) {
51583                  if (typeof p5.prototype[p] === 'function') {
51584                    var ev = p.substring(2);
51585                    if (!this._events.hasOwnProperty(ev)) {
51586                      if (Math.hasOwnProperty(p) && Math[p] === p5.prototype[p]) {
51587                        // Multiple p5 methods are just native Math functions. These can be
51588                        // called without any binding.
51589                        friendlyBindGlobal(p, p5.prototype[p]);
51590                      } else {
51591                        friendlyBindGlobal(p, p5.prototype[p].bind(this));
51592                      }
51593                    }
51594                  } else {
51595                    friendlyBindGlobal(p, p5.prototype[p]);
51596                  }
51597                }
51598                // Attach its properties to the window
51599                for (var p2 in this) {
51600                  if (this.hasOwnProperty(p2)) {
51601                    friendlyBindGlobal(p2, this[p2]);
51602                  }
51603                }
51604              } else {
51605                // Else, the user has passed in a sketch closure that may set
51606                // user-provided 'setup', 'draw', etc. properties on this instance of p5
51607                sketch(this);
51608
51609                // Run a check to see if the user has misspelled 'setup', 'draw', etc
51610                // detects capitalization mistakes only ( Setup, SETUP, MouseClicked, etc)
51611                p5._checkForUserDefinedFunctions(this);
51612              }
51613
51614              // Bind events to window (not using container div bc key events don't work)
51615
51616              for (var e in this._events) {
51617                var f = this['_on'.concat(e)];
51618                if (f) {
51619                  var m = f.bind(this);
51620                  window.addEventListener(e, m, { passive: false });
51621                  this._events[e] = m;
51622                }
51623              }
51624
51625              var focusHandler = function focusHandler() {
51626                _this._setProperty('focused', true);
51627              };
51628              var blurHandler = function blurHandler() {
51629                _this._setProperty('focused', false);
51630              };
51631              window.addEventListener('focus', focusHandler);
51632              window.addEventListener('blur', blurHandler);
51633              this.registerMethod('remove', function() {
51634                window.removeEventListener('focus', focusHandler);
51635                window.removeEventListener('blur', blurHandler);
51636              });
51637
51638              if (document.readyState === 'complete') {
51639                this._start();
51640              } else {
51641                window.addEventListener('load', this._start.bind(this), false);
51642              }
51643            }
51644            _createClass(p5, [
51645              {
51646                key: '_initializeInstanceVariables',
51647                value: function _initializeInstanceVariables() {
51648                  this._styles = [];
51649
51650                  this._bezierDetail = 20;
51651                  this._curveDetail = 20;
51652
51653                  this._colorMode = constants.RGB;
51654                  this._colorMaxes = {
51655                    rgb: [255, 255, 255, 255],
51656                    hsb: [360, 100, 100, 1],
51657                    hsl: [360, 100, 100, 1]
51658                  };
51659
51660                  this._downKeys = {}; //Holds the key codes of currently pressed keys
51661                }
51662              },
51663              {
51664                key: 'registerPreloadMethod',
51665                value: function registerPreloadMethod(fnString, obj) {
51666                  // obj = obj || p5.prototype;
51667                  if (!p5.prototype._preloadMethods.hasOwnProperty(fnString)) {
51668                    p5.prototype._preloadMethods[fnString] = obj;
51669                  }
51670                }
51671              },
51672              {
51673                key: 'registerMethod',
51674                value: function registerMethod(name, m) {
51675                  var target = this || p5.prototype;
51676                  if (!target._registeredMethods.hasOwnProperty(name)) {
51677                    target._registeredMethods[name] = [];
51678                  }
51679                  target._registeredMethods[name].push(m);
51680                }
51681
51682                // create a function which provides a standardized process for binding
51683                // globals; this is implemented as a factory primarily so that there's a
51684                // way to redefine what "global" means for the binding function so it
51685                // can be used in scenarios like unit testing where the window object
51686                // might not exist
51687              },
51688              {
51689                key: '_createFriendlyGlobalFunctionBinder',
51690                value: function _createFriendlyGlobalFunctionBinder() {
51691                  var options =
51692                    arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
51693                  var globalObject = options.globalObject || window;
51694                  var log = options.log || console.log.bind(console);
51695                  var propsToForciblyOverwrite = {
51696                    // p5.print actually always overwrites an existing global function,
51697                    // albeit one that is very unlikely to be used:
51698                    //
51699                    //   https://developer.mozilla.org/en-US/docs/Web/API/Window/print
51700                    print: true
51701                  };
51702
51703                  return function(prop, value) {
51704                    if (
51705                      !p5.disableFriendlyErrors &&
51706                      typeof IS_MINIFIED === 'undefined' &&
51707                      typeof value === 'function' &&
51708                      !(prop in p5.prototype._preloadMethods)
51709                    ) {
51710                      try {
51711                        // Because p5 has so many common function names, it's likely
51712                        // that users may accidentally overwrite global p5 functions with
51713                        // their own variables. Let's allow this but log a warning to
51714                        // help users who may be doing this unintentionally.
51715                        //
51716                        // For more information, see:
51717                        //
51718                        //   https://github.com/processing/p5.js/issues/1317
51719
51720                        if (prop in globalObject && !(prop in propsToForciblyOverwrite)) {
51721                          throw new Error('global "'.concat(prop, '" already exists'));
51722                        }
51723
51724                        // It's possible that this might throw an error because there
51725                        // are a lot of edge-cases in which `Object.defineProperty` might
51726                        // not succeed; since this functionality is only intended to
51727                        // help beginners anyways, we'll just catch such an exception
51728                        // if it occurs, and fall back to legacy behavior.
51729                        Object.defineProperty(globalObject, prop, {
51730                          configurable: true,
51731                          enumerable: true,
51732                          get: function get() {
51733                            return value;
51734                          },
51735                          set: function set(newValue) {
51736                            Object.defineProperty(globalObject, prop, {
51737                              configurable: true,
51738                              enumerable: true,
51739                              value: newValue,
51740                              writable: true
51741                            });
51742
51743                            log(
51744                              'You just changed the value of "'.concat(
51745                                prop,
51746                                '", which was a p5 function. This could cause problems later if you\'re not careful.'
51747                              )
51748                            );
51749                          }
51750                        });
51751                      } catch (e) {
51752                        log(
51753                          'p5 had problems creating the global function "'.concat(
51754                            prop,
51755                            '", possibly because your code is already using that name as a variable. You may want to rename your variable to something else.'
51756                          )
51757                        );
51758
51759                        globalObject[prop] = value;
51760                      }
51761                    } else {
51762                      globalObject[prop] = value;
51763                    }
51764                  };
51765                }
51766              }
51767            ]);
51768            return p5;
51769          })();
51770
51771          // This is a pointer to our global mode p5 instance, if we're in
51772          // global mode.
51773          p5.instance = null;
51774
51775          /**
51776           * Allows for the friendly error system (FES) to be turned off when creating a sketch,
51777           * which can give a significant boost to performance when needed.
51778           * See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>
51779           * disabling the friendly error system</a>.
51780           *
51781           * @property {Boolean} disableFriendlyErrors
51782           * @example
51783           * <div class="norender notest"><code>
51784           * p5.disableFriendlyErrors = true;
51785           *
51786           * function setup() {
51787           *   createCanvas(100, 50);
51788           * }
51789           * </code></div>
51790           */
51791          p5.disableFriendlyErrors = false;
51792
51793          // attach constants to p5 prototype
51794          for (var k in constants) {
51795            p5.prototype[k] = constants[k];
51796          }
51797
51798          // functions that cause preload to wait
51799          // more can be added by using registerPreloadMethod(func)
51800          p5.prototype._preloadMethods = {
51801            loadJSON: p5.prototype,
51802            loadImage: p5.prototype,
51803            loadStrings: p5.prototype,
51804            loadXML: p5.prototype,
51805            loadBytes: p5.prototype,
51806            loadTable: p5.prototype,
51807            loadFont: p5.prototype,
51808            loadModel: p5.prototype,
51809            loadShader: p5.prototype
51810          };
51811
51812          p5.prototype._registeredMethods = { init: [], pre: [], post: [], remove: [] };
51813
51814          p5.prototype._registeredPreloadMethods = {};
51815          var _default = p5;
51816          exports.default = _default;
51817        },
51818        { './constants': 48, './shim': 70 }
51819      ],
51820      60: [
51821        function(_dereq_, module, exports) {
51822          'use strict';
51823          Object.defineProperty(exports, '__esModule', { value: true });
51824          exports.default = void 0;
51825
51826          var _main = _interopRequireDefault(_dereq_('./main'));
51827          function _interopRequireDefault(obj) {
51828            return obj && obj.__esModule ? obj : { default: obj };
51829          }
51830          /**
51831           * @module DOM
51832           * @submodule DOM
51833           * @for p5.Element
51834           */ /**
51835           * Base class for all elements added to a sketch, including canvas,
51836           * graphics buffers, and other HTML elements. It is not called directly, but <a href="#/p5.Element">p5.Element</a>
51837           * objects are created by calling <a href="#/p5/createCanvas">createCanvas</a>, <a href="#/p5/createGraphics">createGraphics</a>,
51838           * <a href="#/p5/createDiv">createDiv</a>, <a href="#/p5/createImg">createImg</a>, <a href="#/p5/createInput">createInput</a>, etc.
51839           *
51840           * @class p5.Element
51841           * @constructor
51842           * @param {String} elt DOM node that is wrapped
51843           * @param {p5} [pInst] pointer to p5 instance
51844           */ _main.default.Element = function(elt, pInst) {
51845            /**
51846             * Underlying HTML element. All normal HTML methods can be called on this.
51847             * @example
51848             * <div>
51849             * <code>
51850             * function setup() {
51851             *   let c = createCanvas(50, 50);
51852             *   c.elt.style.border = '5px solid red';
51853             * }
51854             *
51855             * function draw() {
51856             *   background(220);
51857             * }
51858             * </code>
51859             * </div>
51860             *
51861             * @property elt
51862             * @readOnly
51863             */
51864            this.elt = elt;
51865            this._pInst = this._pixelsState = pInst;
51866            this._events = {};
51867            this.width = this.elt.offsetWidth;
51868            this.height = this.elt.offsetHeight;
51869          };
51870
51871          /**
51872           *
51873           * Attaches the element to the parent specified. A way of setting
51874           * the container for the element. Accepts either a string ID, DOM
51875           * node, or <a href="#/p5.Element">p5.Element</a>. If no arguments given, parent node is returned.
51876           * For more ways to position the canvas, see the
51877           * <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>
51878           * positioning the canvas</a> wiki page.
51879           *
51880           * @method parent
51881           * @param  {String|p5.Element|Object} parent the ID, DOM node, or <a href="#/p5.Element">p5.Element</a>
51882           *                         of desired parent element
51883           * @chainable
51884           *
51885           * @example
51886           * <div class="norender notest"><code>
51887           * // Add the following comment to html file.
51888           * // &lt;div id="myContainer">&lt;/div>
51889           *
51890           * // The js code
51891           * let cnv = createCanvas(100, 100);
51892           * cnv.parent('myContainer');
51893           * </code></div>
51894           *
51895           * <div class='norender'><code>
51896           * let div0 = createDiv('this is the parent');
51897           * let div1 = createDiv('this is the child');
51898           * div1.parent(div0); // use p5.Element
51899           * </code></div>
51900           *
51901           * <div class='norender'><code>
51902           * let div0 = createDiv('this is the parent');
51903           * div0.id('apples');
51904           * let div1 = createDiv('this is the child');
51905           * div1.parent('apples'); // use id
51906           * </code></div>
51907           *
51908           * <div class='norender notest'><code>
51909           * let elt = document.getElementById('myParentDiv');
51910           * let div1 = createDiv('this is the child');
51911           * div1.parent(elt); // use element from page
51912           * </code></div>
51913           *
51914           * @alt
51915           * no display.
51916           */
51917          /**
51918           * @method parent
51919           * @return {p5.Element}
51920           */
51921          _main.default.Element.prototype.parent = function(p) {
51922            if (typeof p === 'undefined') {
51923              return this.elt.parentNode;
51924            }
51925
51926            if (typeof p === 'string') {
51927              if (p[0] === '#') {
51928                p = p.substring(1);
51929              }
51930              p = document.getElementById(p);
51931            } else if (p instanceof _main.default.Element) {
51932              p = p.elt;
51933            }
51934            p.appendChild(this.elt);
51935            return this;
51936          };
51937
51938          /**
51939           *
51940           * Sets the ID of the element. If no ID argument is passed in, it instead
51941           * returns the current ID of the element.
51942           * Note that only one element can have a particular id in a page.
51943           * The <a href="#/p5.Element/class">.class()</a> function can be used
51944           * to identify multiple elements with the same class name.
51945           *
51946           * @method id
51947           * @param  {String} id ID of the element
51948           * @chainable
51949           *
51950           * @example
51951           * <div class='norender'><code>
51952           * function setup() {
51953           *   let cnv = createCanvas(100, 100);
51954           *   // Assigns a CSS selector ID to
51955           *   // the canvas element.
51956           *   cnv.id('mycanvas');
51957           * }
51958           * </code></div>
51959           *
51960           * @alt
51961           * no display.
51962           */
51963          /**
51964           * @method id
51965           * @return {String} the id of the element
51966           */
51967          _main.default.Element.prototype.id = function(id) {
51968            if (typeof id === 'undefined') {
51969              return this.elt.id;
51970            }
51971
51972            this.elt.id = id;
51973            this.width = this.elt.offsetWidth;
51974            this.height = this.elt.offsetHeight;
51975            return this;
51976          };
51977
51978          /**
51979           *
51980           * Adds given class to the element. If no class argument is passed in, it
51981           * instead returns a string containing the current class(es) of the element.
51982           *
51983           * @method class
51984           * @param  {String} class class to add
51985           * @chainable
51986           *
51987           * @example
51988           * <div class='norender'><code>
51989           * function setup() {
51990           *   let cnv = createCanvas(100, 100);
51991           *   // Assigns a CSS selector class 'small'
51992           *   // to the canvas element.
51993           *   cnv.class('small');
51994           * }
51995           * </code></div>
51996           *
51997           * @alt
51998           * no display.
51999           */
52000          /**
52001           * @method class
52002           * @return {String} the class of the element
52003           */
52004          _main.default.Element.prototype.class = function(c) {
52005            if (typeof c === 'undefined') {
52006              return this.elt.className;
52007            }
52008
52009            this.elt.className = c;
52010            return this;
52011          };
52012
52013          /**
52014           * The .<a href="#/p5.Element/mousePressed">mousePressed()</a> function is called
52015           * once after every time a mouse button is pressed over the element. Some mobile
52016           * browsers may also trigger this event on a touch screen, if the user performs
52017           * a quick tap. This can be used to attach element specific event listeners.
52018           *
52019           * @method mousePressed
52020           * @param  {Function|Boolean} fxn function to be fired when mouse is
52021           *                                pressed over the element.
52022           *                                if `false` is passed instead, the previously
52023           *                                firing function will no longer fire.
52024           * @chainable
52025           * @example
52026           * <div class='norender'><code>
52027           * let cnv, d, g;
52028           * function setup() {
52029           *   cnv = createCanvas(100, 100);
52030           *   cnv.mousePressed(changeGray); // attach listener for
52031           *   // canvas click only
52032           *   d = 10;
52033           *   g = 100;
52034           * }
52035           *
52036           * function draw() {
52037           *   background(g);
52038           *   ellipse(width / 2, height / 2, d, d);
52039           * }
52040           *
52041           * // this function fires with any click anywhere
52042           * function mousePressed() {
52043           *   d = d + 10;
52044           * }
52045           *
52046           * // this function fires only when cnv is clicked
52047           * function changeGray() {
52048           *   g = random(0, 255);
52049           * }
52050           * </code></div>
52051           *
52052           * @alt
52053           * no display.
52054           */
52055          _main.default.Element.prototype.mousePressed = function(fxn) {
52056            // Prepend the mouse property setters to the event-listener.
52057            // This is required so that mouseButton is set correctly prior to calling the callback (fxn).
52058            // For details, see https://github.com/processing/p5.js/issues/3087.
52059            var eventPrependedFxn = function eventPrependedFxn(event) {
52060              this._pInst._setProperty('mouseIsPressed', true);
52061              this._pInst._setMouseButton(event);
52062              // Pass along the return-value of the callback:
52063              return fxn.call(this);
52064            };
52065            // Pass along the event-prepended form of the callback.
52066            _main.default.Element._adjustListener('mousedown', eventPrependedFxn, this);
52067            return this;
52068          };
52069
52070          /**
52071           * The .<a href="#/p5.Element/doubleClicked">doubleClicked()</a> function is called once after every time a
52072           * mouse button is pressed twice over the element. This can be used to
52073           * attach element and action specific event listeners.
52074           *
52075           * @method doubleClicked
52076           * @param  {Function|Boolean} fxn function to be fired when mouse is
52077           *                                double clicked over the element.
52078           *                                if `false` is passed instead, the previously
52079           *                                firing function will no longer fire.
52080           * @return {p5.Element}
52081           * @example
52082           * <div class='norender'><code>
52083           * let cnv, d, g;
52084           * function setup() {
52085           *   cnv = createCanvas(100, 100);
52086           *   cnv.doubleClicked(changeGray); // attach listener for
52087           *   // canvas double click only
52088           *   d = 10;
52089           *   g = 100;
52090           * }
52091           *
52092           * function draw() {
52093           *   background(g);
52094           *   ellipse(width / 2, height / 2, d, d);
52095           * }
52096           *
52097           * // this function fires with any double click anywhere
52098           * function doubleClicked() {
52099           *   d = d + 10;
52100           * }
52101           *
52102           * // this function fires only when cnv is double clicked
52103           * function changeGray() {
52104           *   g = random(0, 255);
52105           * }
52106           * </code></div>
52107           *
52108           * @alt
52109           * no display.
52110           */
52111          _main.default.Element.prototype.doubleClicked = function(fxn) {
52112            _main.default.Element._adjustListener('dblclick', fxn, this);
52113            return this;
52114          };
52115
52116          /**
52117           * The <a href="#/p5.Element/mouseWheel">mouseWheel()</a> function is called
52118           * once after every time a mouse wheel is scrolled over the element. This can
52119           * be used to attach element specific event listeners.
52120           *
52121           * The function accepts a callback function as argument which will be executed
52122           * when the `wheel` event is triggered on the element, the callback function is
52123           * passed one argument `event`. The `event.deltaY` property returns negative
52124           * values if the mouse wheel is rotated up or away from the user and positive
52125           * in the other direction. The `event.deltaX` does the same as `event.deltaY`
52126           * except it reads the horizontal wheel scroll of the mouse wheel.
52127           *
52128           * On OS X with "natural" scrolling enabled, the `event.deltaY` values are
52129           * reversed.
52130           *
52131           * @method mouseWheel
52132           * @param  {Function|Boolean} fxn function to be fired when mouse is
52133           *                                scrolled over the element.
52134           *                                if `false` is passed instead, the previously
52135           *                                firing function will no longer fire.
52136           * @chainable
52137           * @example
52138           * <div class='norender'><code>
52139           * let cnv, d, g;
52140           * function setup() {
52141           *   cnv = createCanvas(100, 100);
52142           *   cnv.mouseWheel(changeSize); // attach listener for
52143           *   // activity on canvas only
52144           *   d = 10;
52145           *   g = 100;
52146           * }
52147           *
52148           * function draw() {
52149           *   background(g);
52150           *   ellipse(width / 2, height / 2, d, d);
52151           * }
52152           *
52153           * // this function fires with mousewheel movement
52154           * // anywhere on screen
52155           * function mouseWheel() {
52156           *   g = g + 10;
52157           * }
52158           *
52159           * // this function fires with mousewheel movement
52160           * // over canvas only
52161           * function changeSize(event) {
52162           *   if (event.deltaY > 0) {
52163           *     d = d + 10;
52164           *   } else {
52165           *     d = d - 10;
52166           *   }
52167           * }
52168           * </code></div>
52169           *
52170           * @alt
52171           * no display.
52172           */
52173          _main.default.Element.prototype.mouseWheel = function(fxn) {
52174            _main.default.Element._adjustListener('wheel', fxn, this);
52175            return this;
52176          };
52177
52178          /**
52179           * The <a href="#/p5.Element/mouseReleased">mouseReleased()</a> function is
52180           * called once after every time a mouse button is released over the element.
52181           * Some mobile browsers may also trigger this event on a touch screen, if the
52182           * user performs a quick tap. This can be used to attach element specific event listeners.
52183           *
52184           * @method mouseReleased
52185           * @param  {Function|Boolean} fxn function to be fired when mouse is
52186           *                                released over the element.
52187           *                                if `false` is passed instead, the previously
52188           *                                firing function will no longer fire.
52189           * @chainable
52190           * @example
52191           * <div class='norender'><code>
52192           * let cnv, d, g;
52193           * function setup() {
52194           *   cnv = createCanvas(100, 100);
52195           *   cnv.mouseReleased(changeGray); // attach listener for
52196           *   // activity on canvas only
52197           *   d = 10;
52198           *   g = 100;
52199           * }
52200           *
52201           * function draw() {
52202           *   background(g);
52203           *   ellipse(width / 2, height / 2, d, d);
52204           * }
52205           *
52206           * // this function fires after the mouse has been
52207           * // released
52208           * function mouseReleased() {
52209           *   d = d + 10;
52210           * }
52211           *
52212           * // this function fires after the mouse has been
52213           * // released while on canvas
52214           * function changeGray() {
52215           *   g = random(0, 255);
52216           * }
52217           * </code></div>
52218           *
52219           * @alt
52220           * no display.
52221           */
52222          _main.default.Element.prototype.mouseReleased = function(fxn) {
52223            _main.default.Element._adjustListener('mouseup', fxn, this);
52224            return this;
52225          };
52226
52227          /**
52228           * The .<a href="#/p5.Element/mouseClicked">mouseClicked()</a> function is
52229           * called once after a mouse button is pressed and released over the element.
52230           * Some mobile browsers may also trigger this event on a touch screen, if the
52231           * user performs a quick tap.This can be used to attach element specific event listeners.
52232           *
52233           * @method mouseClicked
52234           * @param  {Function|Boolean} fxn function to be fired when mouse is
52235           *                                clicked over the element.
52236           *                                if `false` is passed instead, the previously
52237           *                                firing function will no longer fire.
52238           * @chainable
52239           * @example
52240           * <div class="norender">
52241           * <code>
52242           * let cnv, d, g;
52243           * function setup() {
52244           *   cnv = createCanvas(100, 100);
52245           *   cnv.mouseClicked(changeGray); // attach listener for
52246           *   // activity on canvas only
52247           *   d = 10;
52248           *   g = 100;
52249           * }
52250           *
52251           * function draw() {
52252           *   background(g);
52253           *   ellipse(width / 2, height / 2, d, d);
52254           * }
52255           *
52256           * // this function fires after the mouse has been
52257           * // clicked anywhere
52258           * function mouseClicked() {
52259           *   d = d + 10;
52260           * }
52261           *
52262           * // this function fires after the mouse has been
52263           * // clicked on canvas
52264           * function changeGray() {
52265           *   g = random(0, 255);
52266           * }
52267           * </code>
52268           * </div>
52269           *
52270           * @alt
52271           * no display.
52272           */
52273          _main.default.Element.prototype.mouseClicked = function(fxn) {
52274            _main.default.Element._adjustListener('click', fxn, this);
52275            return this;
52276          };
52277
52278          /**
52279           * The .<a href="#/p5.Element/mouseMoved">mouseMoved()</a> function is called once every time a
52280           * mouse moves over the element. This can be used to attach an
52281           * element specific event listener.
52282           *
52283           * @method mouseMoved
52284           * @param  {Function|Boolean} fxn function to be fired when a mouse moves
52285           *                                over the element.
52286           *                                if `false` is passed instead, the previously
52287           *                                firing function will no longer fire.
52288           * @chainable
52289           * @example
52290           * <div class='norender'><code>
52291           * let cnv;
52292           * let d = 30;
52293           * let g;
52294           * function setup() {
52295           *   cnv = createCanvas(100, 100);
52296           *   cnv.mouseMoved(changeSize); // attach listener for
52297           *   // activity on canvas only
52298           *   d = 10;
52299           *   g = 100;
52300           * }
52301           *
52302           * function draw() {
52303           *   background(g);
52304           *   fill(200);
52305           *   ellipse(width / 2, height / 2, d, d);
52306           * }
52307           *
52308           * // this function fires when mouse moves anywhere on
52309           * // page
52310           * function mouseMoved() {
52311           *   g = g + 5;
52312           *   if (g > 255) {
52313           *     g = 0;
52314           *   }
52315           * }
52316           *
52317           * // this function fires when mouse moves over canvas
52318           * function changeSize() {
52319           *   d = d + 2;
52320           *   if (d > 100) {
52321           *     d = 0;
52322           *   }
52323           * }
52324           * </code></div>
52325           *
52326           * @alt
52327           * no display.
52328           */
52329          _main.default.Element.prototype.mouseMoved = function(fxn) {
52330            _main.default.Element._adjustListener('mousemove', fxn, this);
52331            return this;
52332          };
52333
52334          /**
52335           * The .<a href="#/p5.Element/mouseOver">mouseOver()</a> function is called once after every time a
52336           * mouse moves onto the element. This can be used to attach an
52337           * element specific event listener.
52338           *
52339           * @method mouseOver
52340           * @param  {Function|Boolean} fxn function to be fired when a mouse moves
52341           *                                onto the element.
52342           *                                if `false` is passed instead, the previously
52343           *                                firing function will no longer fire.
52344           * @chainable
52345           * @example
52346           * <div class='norender'><code>
52347           * let cnv;
52348           * let d;
52349           * function setup() {
52350           *   cnv = createCanvas(100, 100);
52351           *   cnv.mouseOver(changeGray);
52352           *   d = 10;
52353           * }
52354           *
52355           * function draw() {
52356           *   ellipse(width / 2, height / 2, d, d);
52357           * }
52358           *
52359           * function changeGray() {
52360           *   d = d + 10;
52361           *   if (d > 100) {
52362           *     d = 0;
52363           *   }
52364           * }
52365           * </code></div>
52366           *
52367           * @alt
52368           * no display.
52369           */
52370          _main.default.Element.prototype.mouseOver = function(fxn) {
52371            _main.default.Element._adjustListener('mouseover', fxn, this);
52372            return this;
52373          };
52374
52375          /**
52376           * The .<a href="#/p5.Element/mouseOut">mouseOut()</a> function is called once after every time a
52377           * mouse moves off the element. This can be used to attach an
52378           * element specific event listener.
52379           *
52380           * @method mouseOut
52381           * @param  {Function|Boolean} fxn function to be fired when a mouse
52382           *                                moves off of an element.
52383           *                                if `false` is passed instead, the previously
52384           *                                firing function will no longer fire.
52385           * @chainable
52386           * @example
52387           * <div class='norender'><code>
52388           * let cnv;
52389           * let d;
52390           * function setup() {
52391           *   cnv = createCanvas(100, 100);
52392           *   cnv.mouseOut(changeGray);
52393           *   d = 10;
52394           * }
52395           *
52396           * function draw() {
52397           *   ellipse(width / 2, height / 2, d, d);
52398           * }
52399           *
52400           * function changeGray() {
52401           *   d = d + 10;
52402           *   if (d > 100) {
52403           *     d = 0;
52404           *   }
52405           * }
52406           * </code></div>
52407           *
52408           * @alt
52409           * no display.
52410           */
52411          _main.default.Element.prototype.mouseOut = function(fxn) {
52412            _main.default.Element._adjustListener('mouseout', fxn, this);
52413            return this;
52414          };
52415
52416          /**
52417           * The .<a href="#/p5.Element/touchStarted">touchStarted()</a> function is called once after every time a touch is
52418           * registered. This can be used to attach element specific event listeners.
52419           *
52420           * @method touchStarted
52421           * @param  {Function|Boolean} fxn function to be fired when a touch
52422           *                                starts over the element.
52423           *                                if `false` is passed instead, the previously
52424           *                                firing function will no longer fire.
52425           * @chainable
52426           * @example
52427           * <div class='norender'><code>
52428           * let cnv;
52429           * let d;
52430           * let g;
52431           * function setup() {
52432           *   cnv = createCanvas(100, 100);
52433           *   cnv.touchStarted(changeGray); // attach listener for
52434           *   // canvas click only
52435           *   d = 10;
52436           *   g = 100;
52437           * }
52438           *
52439           * function draw() {
52440           *   background(g);
52441           *   ellipse(width / 2, height / 2, d, d);
52442           * }
52443           *
52444           * // this function fires with any touch anywhere
52445           * function touchStarted() {
52446           *   d = d + 10;
52447           * }
52448           *
52449           * // this function fires only when cnv is clicked
52450           * function changeGray() {
52451           *   g = random(0, 255);
52452           * }
52453           * </code></div>
52454           *
52455           * @alt
52456           * no display.
52457           */
52458          _main.default.Element.prototype.touchStarted = function(fxn) {
52459            _main.default.Element._adjustListener('touchstart', fxn, this);
52460            return this;
52461          };
52462
52463          /**
52464           * The .<a href="#/p5.Element/touchMoved">touchMoved()</a> function is called once after every time a touch move is
52465           * registered. This can be used to attach element specific event listeners.
52466           *
52467           * @method touchMoved
52468           * @param  {Function|Boolean} fxn function to be fired when a touch moves over
52469           *                                the element.
52470           *                                if `false` is passed instead, the previously
52471           *                                firing function will no longer fire.
52472           * @chainable
52473           * @example
52474           * <div class='norender'><code>
52475           * let cnv;
52476           * let g;
52477           * function setup() {
52478           *   cnv = createCanvas(100, 100);
52479           *   cnv.touchMoved(changeGray); // attach listener for
52480           *   // canvas click only
52481           *   g = 100;
52482           * }
52483           *
52484           * function draw() {
52485           *   background(g);
52486           * }
52487           *
52488           * // this function fires only when cnv is clicked
52489           * function changeGray() {
52490           *   g = random(0, 255);
52491           * }
52492           * </code></div>
52493           *
52494           * @alt
52495           * no display.
52496           */
52497          _main.default.Element.prototype.touchMoved = function(fxn) {
52498            _main.default.Element._adjustListener('touchmove', fxn, this);
52499            return this;
52500          };
52501
52502          /**
52503           * The .<a href="#/p5.Element/touchEnded">touchEnded()</a> function is called once after every time a touch is
52504           * registered. This can be used to attach element specific event listeners.
52505           *
52506           * @method touchEnded
52507           * @param  {Function|Boolean} fxn function to be fired when a touch ends
52508           *                                over the element.
52509           *                                if `false` is passed instead, the previously
52510           *                                firing function will no longer fire.
52511           * @chainable
52512           * @example
52513           * <div class='norender'><code>
52514           * let cnv;
52515           * let d;
52516           * let g;
52517           * function setup() {
52518           *   cnv = createCanvas(100, 100);
52519           *   cnv.touchEnded(changeGray); // attach listener for
52520           *   // canvas click only
52521           *   d = 10;
52522           *   g = 100;
52523           * }
52524           *
52525           * function draw() {
52526           *   background(g);
52527           *   ellipse(width / 2, height / 2, d, d);
52528           * }
52529           *
52530           * // this function fires with any touch anywhere
52531           * function touchEnded() {
52532           *   d = d + 10;
52533           * }
52534           *
52535           * // this function fires only when cnv is clicked
52536           * function changeGray() {
52537           *   g = random(0, 255);
52538           * }
52539           * </code></div>
52540           *
52541           * @alt
52542           * no display.
52543           */
52544          _main.default.Element.prototype.touchEnded = function(fxn) {
52545            _main.default.Element._adjustListener('touchend', fxn, this);
52546            return this;
52547          };
52548
52549          /**
52550           * The .<a href="#/p5.Element/dragOver">dragOver()</a> function is called once after every time a
52551           * file is dragged over the element. This can be used to attach an
52552           * element specific event listener.
52553           *
52554           * @method dragOver
52555           * @param  {Function|Boolean} fxn function to be fired when a file is
52556           *                                dragged over the element.
52557           *                                if `false` is passed instead, the previously
52558           *                                firing function will no longer fire.
52559           * @chainable
52560           * @example
52561           * <div><code>
52562           * // To test this sketch, simply drag a
52563           * // file over the canvas
52564           * function setup() {
52565           *   let c = createCanvas(100, 100);
52566           *   background(200);
52567           *   textAlign(CENTER);
52568           *   text('Drag file', width / 2, height / 2);
52569           *   c.dragOver(dragOverCallback);
52570           * }
52571           *
52572           * // This function will be called whenever
52573           * // a file is dragged over the canvas
52574           * function dragOverCallback() {
52575           *   background(240);
52576           *   text('Dragged over', width / 2, height / 2);
52577           * }
52578           * </code></div>
52579           * @alt
52580           * nothing displayed
52581           */
52582          _main.default.Element.prototype.dragOver = function(fxn) {
52583            _main.default.Element._adjustListener('dragover', fxn, this);
52584            return this;
52585          };
52586
52587          /**
52588           * The .dragLeave() function is called once after every time a
52589           * dragged file leaves the element area. This can be used to attach an
52590           * element specific event listener.
52591           *
52592           * @method dragLeave
52593           * @param  {Function|Boolean} fxn function to be fired when a file is
52594           *                                dragged off the element.
52595           *                                if `false` is passed instead, the previously
52596           *                                firing function will no longer fire.
52597           * @chainable
52598           * @example
52599           * <div><code>
52600           * // To test this sketch, simply drag a file
52601           * // over and then out of the canvas area
52602           * function setup() {
52603           *   let c = createCanvas(100, 100);
52604           *   background(200);
52605           *   textAlign(CENTER);
52606           *   text('Drag file', width / 2, height / 2);
52607           *   c.dragLeave(dragLeaveCallback);
52608           * }
52609           *
52610           * // This function will be called whenever
52611           * // a file is dragged out of the canvas
52612           * function dragLeaveCallback() {
52613           *   background(240);
52614           *   text('Dragged off', width / 2, height / 2);
52615           * }
52616           * </code></div>
52617           * @alt
52618           * nothing displayed
52619           */
52620          _main.default.Element.prototype.dragLeave = function(fxn) {
52621            _main.default.Element._adjustListener('dragleave', fxn, this);
52622            return this;
52623          };
52624
52625          // General handler for event attaching and detaching
52626          _main.default.Element._adjustListener = function(ev, fxn, ctx) {
52627            if (fxn === false) {
52628              _main.default.Element._detachListener(ev, ctx);
52629            } else {
52630              _main.default.Element._attachListener(ev, fxn, ctx);
52631            }
52632            return this;
52633          };
52634
52635          _main.default.Element._attachListener = function(ev, fxn, ctx) {
52636            // detach the old listener if there was one
52637            if (ctx._events[ev]) {
52638              _main.default.Element._detachListener(ev, ctx);
52639            }
52640            var f = fxn.bind(ctx);
52641            ctx.elt.addEventListener(ev, f, false);
52642            ctx._events[ev] = f;
52643          };
52644
52645          _main.default.Element._detachListener = function(ev, ctx) {
52646            var f = ctx._events[ev];
52647            ctx.elt.removeEventListener(ev, f, false);
52648            ctx._events[ev] = null;
52649          };
52650
52651          /**
52652           * Helper fxn for sharing pixel methods
52653           */
52654          _main.default.Element.prototype._setProperty = function(prop, value) {
52655            this[prop] = value;
52656          };
52657          var _default = _main.default.Element;
52658          exports.default = _default;
52659        },
52660        { './main': 59 }
52661      ],
52662      61: [
52663        function(_dereq_, module, exports) {
52664          'use strict';
52665          function _typeof(obj) {
52666            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
52667              _typeof = function _typeof(obj) {
52668                return typeof obj;
52669              };
52670            } else {
52671              _typeof = function _typeof(obj) {
52672                return obj &&
52673                  typeof Symbol === 'function' &&
52674                  obj.constructor === Symbol &&
52675                  obj !== Symbol.prototype
52676                  ? 'symbol'
52677                  : typeof obj;
52678              };
52679            }
52680            return _typeof(obj);
52681          }
52682          Object.defineProperty(exports, '__esModule', { value: true });
52683          exports.default = void 0;
52684
52685          var _main = _interopRequireDefault(_dereq_('./main'));
52686          var constants = _interopRequireWildcard(_dereq_('./constants'));
52687          function _getRequireWildcardCache() {
52688            if (typeof WeakMap !== 'function') return null;
52689            var cache = new WeakMap();
52690            _getRequireWildcardCache = function _getRequireWildcardCache() {
52691              return cache;
52692            };
52693            return cache;
52694          }
52695          function _interopRequireWildcard(obj) {
52696            if (obj && obj.__esModule) {
52697              return obj;
52698            }
52699            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
52700              return { default: obj };
52701            }
52702            var cache = _getRequireWildcardCache();
52703            if (cache && cache.has(obj)) {
52704              return cache.get(obj);
52705            }
52706            var newObj = {};
52707            var hasPropertyDescriptor =
52708              Object.defineProperty && Object.getOwnPropertyDescriptor;
52709            for (var key in obj) {
52710              if (Object.prototype.hasOwnProperty.call(obj, key)) {
52711                var desc = hasPropertyDescriptor
52712                  ? Object.getOwnPropertyDescriptor(obj, key)
52713                  : null;
52714                if (desc && (desc.get || desc.set)) {
52715                  Object.defineProperty(newObj, key, desc);
52716                } else {
52717                  newObj[key] = obj[key];
52718                }
52719              }
52720            }
52721            newObj.default = obj;
52722            if (cache) {
52723              cache.set(obj, newObj);
52724            }
52725            return newObj;
52726          }
52727          function _interopRequireDefault(obj) {
52728            return obj && obj.__esModule ? obj : { default: obj };
52729          }
52730          /**
52731           * @module Rendering
52732           * @submodule Rendering
52733           * @for p5
52734           */ /**
52735           * Thin wrapper around a renderer, to be used for creating a
52736           * graphics buffer object. Use this class if you need
52737           * to draw into an off-screen graphics buffer. The two parameters define the
52738           * width and height in pixels. The fields and methods for this class are
52739           * extensive, but mirror the normal drawing API for p5.
52740           *
52741           * @class p5.Graphics
52742           * @constructor
52743           * @extends p5.Element
52744           * @param {Number} w            width
52745           * @param {Number} h            height
52746           * @param {Constant} renderer   the renderer to use, either P2D or WEBGL
52747           * @param {p5} [pInst]          pointer to p5 instance
52748           */ _main.default.Graphics = function(w, h, renderer, pInst) {
52749            var r = renderer || constants.P2D;
52750
52751            this.canvas = document.createElement('canvas');
52752            var node = pInst._userNode || document.body;
52753            node.appendChild(this.canvas);
52754
52755            _main.default.Element.call(this, this.canvas, pInst);
52756
52757            // bind methods and props of p5 to the new object
52758            for (var p in _main.default.prototype) {
52759              if (!this[p]) {
52760                if (typeof _main.default.prototype[p] === 'function') {
52761                  this[p] = _main.default.prototype[p].bind(this);
52762                } else {
52763                  this[p] = _main.default.prototype[p];
52764                }
52765              }
52766            }
52767
52768            _main.default.prototype._initializeInstanceVariables.apply(this);
52769            this.width = w;
52770            this.height = h;
52771            this._pixelDensity = pInst._pixelDensity;
52772
52773            if (r === constants.WEBGL) {
52774              this._renderer = new _main.default.RendererGL(this.canvas, this, false);
52775            } else {
52776              this._renderer = new _main.default.Renderer2D(this.canvas, this, false);
52777            }
52778            pInst._elements.push(this);
52779
52780            Object.defineProperty(this, 'deltaTime', {
52781              get: function get() {
52782                return this._pInst.deltaTime;
52783              }
52784            });
52785
52786            this._renderer.resize(w, h);
52787            this._renderer._applyDefaults();
52788            return this;
52789          };
52790
52791          _main.default.Graphics.prototype = Object.create(_main.default.Element.prototype);
52792
52793          /**
52794           * Resets certain values such as those modified by functions in the Transform category
52795           * and in the Lights category that are not automatically reset
52796           * with graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior
52797           * of the standard canvas.
52798           *
52799           * @method reset
52800           * @example
52801           *
52802           * <div><code>
52803           * let pg;
52804           * function setup() {
52805           *   createCanvas(100, 100);
52806           *   background(0);
52807           *   pg = createGraphics(50, 100);
52808           *   pg.fill(0);
52809           *   frameRate(5);
52810           * }
52811           *
52812           * function draw() {
52813           *   image(pg, width / 2, 0);
52814           *   pg.background(255);
52815           *   // p5.Graphics object behave a bit differently in some cases
52816           *   // The normal canvas on the left resets the translate
52817           *   // with every loop through draw()
52818           *   // the graphics object on the right doesn't automatically reset
52819           *   // so translate() is additive and it moves down the screen
52820           *   rect(0, 0, width / 2, 5);
52821           *   pg.rect(0, 0, width / 2, 5);
52822           *   translate(0, 5, 0);
52823           *   pg.translate(0, 5, 0);
52824           * }
52825           * function mouseClicked() {
52826           *   // if you click you will see that
52827           *   // reset() resets the translate back to the initial state
52828           *   // of the Graphics object
52829           *   pg.reset();
52830           * }
52831           * </code></div>
52832           *
52833           * @alt
52834           * A white line on a black background stays still on the top-left half.
52835           * A black line animates from top to bottom on a white background on the right half.
52836           * When clicked, the black line starts back over at the top.
52837           */
52838          _main.default.Graphics.prototype.reset = function() {
52839            this._renderer.resetMatrix();
52840            if (this._renderer.isP3D) {
52841              this._renderer._update();
52842            }
52843          };
52844
52845          /**
52846           * Removes a Graphics object from the page and frees any resources
52847           * associated with it.
52848           *
52849           * @method remove
52850           *
52851           * @example
52852           * <div class='norender'><code>
52853           * let bg;
52854           * function setup() {
52855           *   bg = createCanvas(100, 100);
52856           *   bg.background(0);
52857           *   image(bg, 0, 0);
52858           *   bg.remove();
52859           * }
52860           * </code></div>
52861           *
52862           * <div><code>
52863           * let bg;
52864           * function setup() {
52865           *   pixelDensity(1);
52866           *   createCanvas(100, 100);
52867           *   stroke(255);
52868           *   fill(0);
52869           *
52870           *   // create and draw the background image
52871           *   bg = createGraphics(100, 100);
52872           *   bg.background(200);
52873           *   bg.ellipse(50, 50, 80, 80);
52874           * }
52875           * function draw() {
52876           *   let t = millis() / 1000;
52877           *   // draw the background
52878           *   if (bg) {
52879           *     image(bg, frameCount % 100, 0);
52880           *     image(bg, frameCount % 100 - 100, 0);
52881           *   }
52882           *   // draw the foreground
52883           *   let p = p5.Vector.fromAngle(t, 35).add(50, 50);
52884           *   ellipse(p.x, p.y, 30);
52885           * }
52886           * function mouseClicked() {
52887           *   // remove the background
52888           *   if (bg) {
52889           *     bg.remove();
52890           *     bg = null;
52891           *   }
52892           * }
52893           * </code></div>
52894           *
52895           * @alt
52896           * no image
52897           * a multi-colored circle moving back and forth over a scrolling background.
52898           */
52899          _main.default.Graphics.prototype.remove = function() {
52900            if (this.elt.parentNode) {
52901              this.elt.parentNode.removeChild(this.elt);
52902            }
52903            var idx = this._pInst._elements.indexOf(this);
52904            if (idx !== -1) {
52905              this._pInst._elements.splice(idx, 1);
52906            }
52907            for (var elt_ev in this._events) {
52908              this.elt.removeEventListener(elt_ev, this._events[elt_ev]);
52909            }
52910          };
52911          var _default = _main.default.Graphics;
52912          exports.default = _default;
52913        },
52914        { './constants': 48, './main': 59 }
52915      ],
52916      62: [
52917        function(_dereq_, module, exports) {
52918          'use strict';
52919          Object.defineProperty(exports, '__esModule', { value: true });
52920          exports.default = void 0;
52921
52922          var _main = _interopRequireDefault(_dereq_('./main'));
52923          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
52924          function _getRequireWildcardCache() {
52925            if (typeof WeakMap !== 'function') return null;
52926            var cache = new WeakMap();
52927            _getRequireWildcardCache = function _getRequireWildcardCache() {
52928              return cache;
52929            };
52930            return cache;
52931          }
52932          function _interopRequireWildcard(obj) {
52933            if (obj && obj.__esModule) {
52934              return obj;
52935            }
52936            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
52937              return { default: obj };
52938            }
52939            var cache = _getRequireWildcardCache();
52940            if (cache && cache.has(obj)) {
52941              return cache.get(obj);
52942            }
52943            var newObj = {};
52944            var hasPropertyDescriptor =
52945              Object.defineProperty && Object.getOwnPropertyDescriptor;
52946            for (var key in obj) {
52947              if (Object.prototype.hasOwnProperty.call(obj, key)) {
52948                var desc = hasPropertyDescriptor
52949                  ? Object.getOwnPropertyDescriptor(obj, key)
52950                  : null;
52951                if (desc && (desc.get || desc.set)) {
52952                  Object.defineProperty(newObj, key, desc);
52953                } else {
52954                  newObj[key] = obj[key];
52955                }
52956              }
52957            }
52958            newObj.default = obj;
52959            if (cache) {
52960              cache.set(obj, newObj);
52961            }
52962            return newObj;
52963          }
52964          function _interopRequireDefault(obj) {
52965            return obj && obj.__esModule ? obj : { default: obj };
52966          }
52967          function _typeof(obj) {
52968            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
52969              _typeof = function _typeof(obj) {
52970                return typeof obj;
52971              };
52972            } else {
52973              _typeof = function _typeof(obj) {
52974                return obj &&
52975                  typeof Symbol === 'function' &&
52976                  obj.constructor === Symbol &&
52977                  obj !== Symbol.prototype
52978                  ? 'symbol'
52979                  : typeof obj;
52980              };
52981            }
52982            return _typeof(obj);
52983          }
52984
52985          /**
52986           * Main graphics and rendering context, as well as the base API
52987           * implementation for p5.js "core". To be used as the superclass for
52988           * Renderer2D and Renderer3D classes, respectively.
52989           *
52990           * @class p5.Renderer
52991           * @constructor
52992           * @extends p5.Element
52993           * @param {String} elt DOM node that is wrapped
52994           * @param {p5} [pInst] pointer to p5 instance
52995           * @param {Boolean} [isMainCanvas] whether we're using it as main canvas
52996           */
52997          _main.default.Renderer = function(elt, pInst, isMainCanvas) {
52998            _main.default.Element.call(this, elt, pInst);
52999            this.canvas = elt;
53000            this._pixelsState = pInst;
53001            if (isMainCanvas) {
53002              this._isMainCanvas = true;
53003              // for pixel method sharing with pimage
53004              this._pInst._setProperty('_curElement', this);
53005              this._pInst._setProperty('canvas', this.canvas);
53006              this._pInst._setProperty('width', this.width);
53007              this._pInst._setProperty('height', this.height);
53008            } else {
53009              // hide if offscreen buffer by default
53010              this.canvas.style.display = 'none';
53011              this._styles = []; // non-main elt styles stored in p5.Renderer
53012            }
53013
53014            this._textSize = 12;
53015            this._textLeading = 15;
53016            this._textFont = 'sans-serif';
53017            this._textStyle = constants.NORMAL;
53018            this._textAscent = null;
53019            this._textDescent = null;
53020            this._textAlign = constants.LEFT;
53021            this._textBaseline = constants.BASELINE;
53022
53023            this._rectMode = constants.CORNER;
53024            this._ellipseMode = constants.CENTER;
53025            this._curveTightness = 0;
53026            this._imageMode = constants.CORNER;
53027
53028            this._tint = null;
53029            this._doStroke = true;
53030            this._doFill = true;
53031            this._strokeSet = false;
53032            this._fillSet = false;
53033          };
53034
53035          _main.default.Renderer.prototype = Object.create(_main.default.Element.prototype);
53036
53037          // the renderer should return a 'style' object that it wishes to
53038          // store on the push stack.
53039          _main.default.Renderer.prototype.push = function() {
53040            return {
53041              properties: {
53042                _doStroke: this._doStroke,
53043                _strokeSet: this._strokeSet,
53044                _doFill: this._doFill,
53045                _fillSet: this._fillSet,
53046                _tint: this._tint,
53047                _imageMode: this._imageMode,
53048                _rectMode: this._rectMode,
53049                _ellipseMode: this._ellipseMode,
53050                _textFont: this._textFont,
53051                _textLeading: this._textLeading,
53052                _textSize: this._textSize,
53053                _textAlign: this._textAlign,
53054                _textBaseline: this._textBaseline,
53055                _textStyle: this._textStyle
53056              }
53057            };
53058          };
53059
53060          // a pop() operation is in progress
53061          // the renderer is passed the 'style' object that it returned
53062          // from its push() method.
53063          _main.default.Renderer.prototype.pop = function(style) {
53064            if (style.properties) {
53065              // copy the style properties back into the renderer
53066              Object.assign(this, style.properties);
53067            }
53068          };
53069
53070          /**
53071           * Resize our canvas element.
53072           */
53073          _main.default.Renderer.prototype.resize = function(w, h) {
53074            this.width = w;
53075            this.height = h;
53076            this.elt.width = w * this._pInst._pixelDensity;
53077            this.elt.height = h * this._pInst._pixelDensity;
53078            this.elt.style.width = ''.concat(w, 'px');
53079            this.elt.style.height = ''.concat(h, 'px');
53080            if (this._isMainCanvas) {
53081              this._pInst._setProperty('width', this.width);
53082              this._pInst._setProperty('height', this.height);
53083            }
53084          };
53085
53086          _main.default.Renderer.prototype.get = function(x, y, w, h) {
53087            var pixelsState = this._pixelsState;
53088            var pd = pixelsState._pixelDensity;
53089            var canvas = this.canvas;
53090
53091            if (typeof x === 'undefined' && typeof y === 'undefined') {
53092              // get()
53093              x = y = 0;
53094              w = pixelsState.width;
53095              h = pixelsState.height;
53096            } else {
53097              x *= pd;
53098              y *= pd;
53099
53100              if (typeof w === 'undefined' && typeof h === 'undefined') {
53101                // get(x,y)
53102                if (x < 0 || y < 0 || x >= canvas.width || y >= canvas.height) {
53103                  return [0, 0, 0, 0];
53104                }
53105
53106                return this._getPixel(x, y);
53107              }
53108              // get(x,y,w,h)
53109            }
53110
53111            var region = new _main.default.Image(w, h);
53112            region.canvas
53113              .getContext('2d')
53114              .drawImage(canvas, x, y, w * pd, h * pd, 0, 0, w, h);
53115
53116            return region;
53117          };
53118
53119          _main.default.Renderer.prototype.textLeading = function(l) {
53120            if (typeof l === 'number') {
53121              this._setProperty('_textLeading', l);
53122              return this._pInst;
53123            }
53124
53125            return this._textLeading;
53126          };
53127
53128          _main.default.Renderer.prototype.textSize = function(s) {
53129            if (typeof s === 'number') {
53130              this._setProperty('_textSize', s);
53131              this._setProperty('_textLeading', s * constants._DEFAULT_LEADMULT);
53132              return this._applyTextProperties();
53133            }
53134
53135            return this._textSize;
53136          };
53137
53138          _main.default.Renderer.prototype.textStyle = function(s) {
53139            if (s) {
53140              if (
53141                s === constants.NORMAL ||
53142                s === constants.ITALIC ||
53143                s === constants.BOLD ||
53144                s === constants.BOLDITALIC
53145              ) {
53146                this._setProperty('_textStyle', s);
53147              }
53148
53149              return this._applyTextProperties();
53150            }
53151
53152            return this._textStyle;
53153          };
53154
53155          _main.default.Renderer.prototype.textAscent = function() {
53156            if (this._textAscent === null) {
53157              this._updateTextMetrics();
53158            }
53159            return this._textAscent;
53160          };
53161
53162          _main.default.Renderer.prototype.textDescent = function() {
53163            if (this._textDescent === null) {
53164              this._updateTextMetrics();
53165            }
53166            return this._textDescent;
53167          };
53168
53169          _main.default.Renderer.prototype.textAlign = function(h, v) {
53170            if (typeof h !== 'undefined') {
53171              this._setProperty('_textAlign', h);
53172
53173              if (typeof v !== 'undefined') {
53174                this._setProperty('_textBaseline', v);
53175              }
53176
53177              return this._applyTextProperties();
53178            } else {
53179              return {
53180                horizontal: this._textAlign,
53181                vertical: this._textBaseline
53182              };
53183            }
53184          };
53185
53186          _main.default.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
53187            var p = this._pInst;
53188            var cars;
53189            var n;
53190            var ii;
53191            var jj;
53192            var line;
53193            var testLine;
53194            var testWidth;
53195            var words;
53196            var totalHeight;
53197            var shiftedY;
53198            var finalMaxHeight = Number.MAX_VALUE;
53199
53200            if (!(this._doFill || this._doStroke)) {
53201              return;
53202            }
53203
53204            if (typeof str === 'undefined') {
53205              return;
53206            } else if (typeof str !== 'string') {
53207              str = str.toString();
53208            }
53209
53210            str = str.replace(/(\t)/g, '  ');
53211            cars = str.split('\n');
53212
53213            if (typeof maxWidth !== 'undefined') {
53214              totalHeight = 0;
53215              for (ii = 0; ii < cars.length; ii++) {
53216                line = '';
53217                words = cars[ii].split(' ');
53218                for (n = 0; n < words.length; n++) {
53219                  testLine = ''.concat(line + words[n], ' ');
53220                  testWidth = this.textWidth(testLine);
53221                  if (testWidth > maxWidth) {
53222                    var currentWord = words[n];
53223                    for (var index = 0; index < currentWord.length; index++) {
53224                      testLine = ''.concat(line + currentWord[index]);
53225                      testWidth = this.textWidth(testLine);
53226                      if (testWidth > maxWidth && line.length > 0) {
53227                        line = ''.concat(currentWord[index]);
53228                        totalHeight += p.textLeading();
53229                      } else {
53230                        line = testLine;
53231                      }
53232                    }
53233                    line = ''.concat(line, ' ');
53234                  } else {
53235                    line = testLine;
53236                  }
53237                }
53238                if (ii < cars.length - 1) {
53239                  totalHeight += p.textLeading();
53240                }
53241              }
53242
53243              if (this._rectMode === constants.CENTER) {
53244                x -= maxWidth / 2;
53245                y -= maxHeight / 2;
53246              }
53247
53248              switch (this._textAlign) {
53249                case constants.CENTER:
53250                  x += maxWidth / 2;
53251                  break;
53252                case constants.RIGHT:
53253                  x += maxWidth;
53254                  break;
53255              }
53256
53257              var baselineHacked = false;
53258              if (typeof maxHeight !== 'undefined') {
53259                switch (this._textBaseline) {
53260                  case constants.BOTTOM:
53261                    shiftedY = y + (maxHeight - totalHeight);
53262                    y = Math.max(shiftedY, y);
53263                    break;
53264                  case constants.CENTER:
53265                    shiftedY = y + (maxHeight - totalHeight) / 2;
53266                    y = Math.max(shiftedY, y);
53267                    break;
53268                  case constants.BASELINE:
53269                    baselineHacked = true;
53270                    this._textBaseline = constants.TOP;
53271                    break;
53272                }
53273
53274                // remember the max-allowed y-position for any line (fix to #928)
53275                finalMaxHeight = y + maxHeight - p.textAscent();
53276              }
53277
53278              for (ii = 0; ii < cars.length; ii++) {
53279                line = '';
53280                words = cars[ii].split(' ');
53281                for (n = 0; n < words.length; n++) {
53282                  testLine = ''.concat(line + words[n], ' ');
53283                  testWidth = this.textWidth(testLine);
53284                  if (testWidth > maxWidth) {
53285                    var _currentWord = words[n];
53286                    for (var _index = 0; _index < _currentWord.length; _index++) {
53287                      testLine = ''.concat(line + _currentWord[_index]);
53288                      testWidth = this.textWidth(testLine);
53289                      if (testWidth > maxWidth && line.length > 0) {
53290                        var lastChar = line.slice(-1);
53291                        var shouldAddHyphen = lastChar !== '\n' && lastChar !== ' ';
53292                        line = ''.concat(line).concat(shouldAddHyphen ? '-' : '');
53293
53294                        this._renderText(p, line, x, y, finalMaxHeight);
53295                        y += p.textLeading();
53296
53297                        line = ''.concat(_currentWord[_index]);
53298                      } else {
53299                        line = testLine;
53300                      }
53301                    }
53302                    line = ''.concat(line, ' ');
53303                  } else {
53304                    line = testLine;
53305                  }
53306                }
53307
53308                this._renderText(p, line, x, y, finalMaxHeight);
53309                y += p.textLeading();
53310
53311                if (baselineHacked) {
53312                  this._textBaseline = constants.BASELINE;
53313                }
53314              }
53315            } else {
53316              // Offset to account for vertically centering multiple lines of text - no
53317              // need to adjust anything for vertical align top or baseline
53318              var offset = 0;
53319
53320              var vAlign = p.textAlign().vertical;
53321              if (vAlign === constants.CENTER) {
53322                offset = (cars.length - 1) * p.textLeading() / 2;
53323              } else if (vAlign === constants.BOTTOM) {
53324                offset = (cars.length - 1) * p.textLeading();
53325              }
53326
53327              for (jj = 0; jj < cars.length; jj++) {
53328                this._renderText(p, cars[jj], x, y - offset, finalMaxHeight);
53329                y += p.textLeading();
53330              }
53331            }
53332
53333            return p;
53334          };
53335
53336          _main.default.Renderer.prototype._applyDefaults = function() {
53337            return this;
53338          };
53339
53340          /**
53341           * Helper fxn to check font type (system or otf)
53342           */
53343          _main.default.Renderer.prototype._isOpenType = function() {
53344            var f =
53345              arguments.length > 0 && arguments[0] !== undefined
53346                ? arguments[0]
53347                : this._textFont;
53348            return _typeof(f) === 'object' && f.font && f.font.supported;
53349          };
53350
53351          _main.default.Renderer.prototype._updateTextMetrics = function() {
53352            if (this._isOpenType()) {
53353              this._setProperty('_textAscent', this._textFont._textAscent());
53354              this._setProperty('_textDescent', this._textFont._textDescent());
53355              return this;
53356            }
53357
53358            // Adapted from http://stackoverflow.com/a/25355178
53359            var text = document.createElement('span');
53360            text.style.fontFamily = this._textFont;
53361            text.style.fontSize = ''.concat(this._textSize, 'px');
53362            text.innerHTML = 'ABCjgq|';
53363
53364            var block = document.createElement('div');
53365            block.style.display = 'inline-block';
53366            block.style.width = '1px';
53367            block.style.height = '0px';
53368
53369            var container = document.createElement('div');
53370            container.appendChild(text);
53371            container.appendChild(block);
53372
53373            container.style.height = '0px';
53374            container.style.overflow = 'hidden';
53375            document.body.appendChild(container);
53376
53377            block.style.verticalAlign = 'baseline';
53378            var blockOffset = calculateOffset(block);
53379            var textOffset = calculateOffset(text);
53380            var ascent = blockOffset[1] - textOffset[1];
53381
53382            block.style.verticalAlign = 'bottom';
53383            blockOffset = calculateOffset(block);
53384            textOffset = calculateOffset(text);
53385            var height = blockOffset[1] - textOffset[1];
53386            var descent = height - ascent;
53387
53388            document.body.removeChild(container);
53389
53390            this._setProperty('_textAscent', ascent);
53391            this._setProperty('_textDescent', descent);
53392
53393            return this;
53394          };
53395
53396          /**
53397           * Helper fxn to measure ascent and descent.
53398           * Adapted from http://stackoverflow.com/a/25355178
53399           */
53400          function calculateOffset(object) {
53401            var currentLeft = 0,
53402              currentTop = 0;
53403            if (object.offsetParent) {
53404              do {
53405                currentLeft += object.offsetLeft;
53406                currentTop += object.offsetTop;
53407              } while ((object = object.offsetParent));
53408            } else {
53409              currentLeft += object.offsetLeft;
53410              currentTop += object.offsetTop;
53411            }
53412            return [currentLeft, currentTop];
53413          }
53414          var _default = _main.default.Renderer;
53415          exports.default = _default;
53416        },
53417        { '../core/constants': 48, './main': 59 }
53418      ],
53419      63: [
53420        function(_dereq_, module, exports) {
53421          'use strict';
53422          function _typeof(obj) {
53423            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
53424              _typeof = function _typeof(obj) {
53425                return typeof obj;
53426              };
53427            } else {
53428              _typeof = function _typeof(obj) {
53429                return obj &&
53430                  typeof Symbol === 'function' &&
53431                  obj.constructor === Symbol &&
53432                  obj !== Symbol.prototype
53433                  ? 'symbol'
53434                  : typeof obj;
53435              };
53436            }
53437            return _typeof(obj);
53438          }
53439          Object.defineProperty(exports, '__esModule', { value: true });
53440          exports.default = void 0;
53441          var _main = _interopRequireDefault(_dereq_('./main'));
53442          var constants = _interopRequireWildcard(_dereq_('./constants'));
53443          var _filters = _interopRequireDefault(_dereq_('../image/filters'));
53444
53445          _dereq_('./p5.Renderer');
53446          function _getRequireWildcardCache() {
53447            if (typeof WeakMap !== 'function') return null;
53448            var cache = new WeakMap();
53449            _getRequireWildcardCache = function _getRequireWildcardCache() {
53450              return cache;
53451            };
53452            return cache;
53453          }
53454          function _interopRequireWildcard(obj) {
53455            if (obj && obj.__esModule) {
53456              return obj;
53457            }
53458            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
53459              return { default: obj };
53460            }
53461            var cache = _getRequireWildcardCache();
53462            if (cache && cache.has(obj)) {
53463              return cache.get(obj);
53464            }
53465            var newObj = {};
53466            var hasPropertyDescriptor =
53467              Object.defineProperty && Object.getOwnPropertyDescriptor;
53468            for (var key in obj) {
53469              if (Object.prototype.hasOwnProperty.call(obj, key)) {
53470                var desc = hasPropertyDescriptor
53471                  ? Object.getOwnPropertyDescriptor(obj, key)
53472                  : null;
53473                if (desc && (desc.get || desc.set)) {
53474                  Object.defineProperty(newObj, key, desc);
53475                } else {
53476                  newObj[key] = obj[key];
53477                }
53478              }
53479            }
53480            newObj.default = obj;
53481            if (cache) {
53482              cache.set(obj, newObj);
53483            }
53484            return newObj;
53485          }
53486          function _interopRequireDefault(obj) {
53487            return obj && obj.__esModule ? obj : { default: obj };
53488          }
53489
53490          /**
53491           * p5.Renderer2D
53492           * The 2D graphics canvas renderer class.
53493           * extends p5.Renderer
53494           */
53495          var styleEmpty = 'rgba(0,0,0,0)';
53496          // const alphaThreshold = 0.00125; // minimum visible
53497
53498          _main.default.Renderer2D = function(elt, pInst, isMainCanvas) {
53499            _main.default.Renderer.call(this, elt, pInst, isMainCanvas);
53500            this.drawingContext = this.canvas.getContext('2d');
53501            this._pInst._setProperty('drawingContext', this.drawingContext);
53502            return this;
53503          };
53504
53505          _main.default.Renderer2D.prototype = Object.create(
53506            _main.default.Renderer.prototype
53507          );
53508
53509          _main.default.Renderer2D.prototype._applyDefaults = function() {
53510            this._cachedFillStyle = this._cachedStrokeStyle = undefined;
53511            this._cachedBlendMode = constants.BLEND;
53512            this._setFill(constants._DEFAULT_FILL);
53513            this._setStroke(constants._DEFAULT_STROKE);
53514            this.drawingContext.lineCap = constants.ROUND;
53515            this.drawingContext.font = 'normal 12px sans-serif';
53516          };
53517
53518          _main.default.Renderer2D.prototype.resize = function(w, h) {
53519            _main.default.Renderer.prototype.resize.call(this, w, h);
53520            this.drawingContext.scale(this._pInst._pixelDensity, this._pInst._pixelDensity);
53521          };
53522
53523          //////////////////////////////////////////////
53524          // COLOR | Setting
53525          //////////////////////////////////////////////
53526
53527          _main.default.Renderer2D.prototype.background = function() {
53528            this.drawingContext.save();
53529            this.resetMatrix();
53530
53531            if (
53532              (arguments.length <= 0 ? undefined : arguments[0]) instanceof
53533              _main.default.Image
53534            ) {
53535              this._pInst.image(
53536                arguments.length <= 0 ? undefined : arguments[0],
53537                0,
53538                0,
53539                this.width,
53540                this.height
53541              );
53542            } else {
53543              var _this$_pInst;
53544              var curFill = this._getFill();
53545              // create background rect
53546              var color = (_this$_pInst = this._pInst).color.apply(_this$_pInst, arguments);
53547
53548              //accessible Outputs
53549              if (this._pInst._addAccsOutput()) {
53550                this._pInst._accsBackground(color.levels);
53551              }
53552
53553              var newFill = color.toString();
53554              this._setFill(newFill);
53555
53556              if (this._isErasing) {
53557                this.blendMode(this._cachedBlendMode);
53558              }
53559
53560              this.drawingContext.fillRect(0, 0, this.width, this.height);
53561              // reset fill
53562              this._setFill(curFill);
53563
53564              if (this._isErasing) {
53565                this._pInst.erase();
53566              }
53567            }
53568            this.drawingContext.restore();
53569          };
53570
53571          _main.default.Renderer2D.prototype.clear = function() {
53572            this.drawingContext.save();
53573            this.resetMatrix();
53574            this.drawingContext.clearRect(0, 0, this.width, this.height);
53575            this.drawingContext.restore();
53576          };
53577
53578          _main.default.Renderer2D.prototype.fill = function() {
53579            var _this$_pInst2;
53580            var color = (_this$_pInst2 = this._pInst).color.apply(_this$_pInst2, arguments);
53581            this._setFill(color.toString());
53582
53583            //accessible Outputs
53584            if (this._pInst._addAccsOutput()) {
53585              this._pInst._accsCanvasColors('fill', color.levels);
53586            }
53587          };
53588
53589          _main.default.Renderer2D.prototype.stroke = function() {
53590            var _this$_pInst3;
53591            var color = (_this$_pInst3 = this._pInst).color.apply(_this$_pInst3, arguments);
53592            this._setStroke(color.toString());
53593
53594            //accessible Outputs
53595            if (this._pInst._addAccsOutput()) {
53596              this._pInst._accsCanvasColors('stroke', color.levels);
53597            }
53598          };
53599
53600          _main.default.Renderer2D.prototype.erase = function(opacityFill, opacityStroke) {
53601            if (!this._isErasing) {
53602              // cache the fill style
53603              this._cachedFillStyle = this.drawingContext.fillStyle;
53604              var newFill = this._pInst.color(255, opacityFill).toString();
53605              this.drawingContext.fillStyle = newFill;
53606
53607              //cache the stroke style
53608              this._cachedStrokeStyle = this.drawingContext.strokeStyle;
53609              var newStroke = this._pInst.color(255, opacityStroke).toString();
53610              this.drawingContext.strokeStyle = newStroke;
53611
53612              //cache blendMode
53613              var tempBlendMode = this._cachedBlendMode;
53614              this.blendMode(constants.REMOVE);
53615              this._cachedBlendMode = tempBlendMode;
53616
53617              this._isErasing = true;
53618            }
53619          };
53620
53621          _main.default.Renderer2D.prototype.noErase = function() {
53622            if (this._isErasing) {
53623              this.drawingContext.fillStyle = this._cachedFillStyle;
53624              this.drawingContext.strokeStyle = this._cachedStrokeStyle;
53625
53626              this.blendMode(this._cachedBlendMode);
53627              this._isErasing = false;
53628            }
53629          };
53630
53631          //////////////////////////////////////////////
53632          // IMAGE | Loading & Displaying
53633          //////////////////////////////////////////////
53634
53635          _main.default.Renderer2D.prototype.image = function(
53636            img,
53637            sx,
53638            sy,
53639            sWidth,
53640            sHeight,
53641            dx,
53642            dy,
53643            dWidth,
53644            dHeight
53645          ) {
53646            var cnv;
53647            if (img.gifProperties) {
53648              img._animateGif(this._pInst);
53649            }
53650
53651            try {
53652              if (this._tint) {
53653                if (
53654                  _main.default.MediaElement &&
53655                  img instanceof _main.default.MediaElement
53656                ) {
53657                  img.loadPixels();
53658                }
53659                if (img.canvas) {
53660                  cnv = this._getTintedImageCanvas(img);
53661                }
53662              }
53663              if (!cnv) {
53664                cnv = img.canvas || img.elt;
53665              }
53666              var s = 1;
53667              if (img.width && img.width > 0) {
53668                s = cnv.width / img.width;
53669              }
53670              if (this._isErasing) {
53671                this.blendMode(this._cachedBlendMode);
53672              }
53673              this.drawingContext.drawImage(
53674                cnv,
53675                s * sx,
53676                s * sy,
53677                s * sWidth,
53678                s * sHeight,
53679                dx,
53680                dy,
53681                dWidth,
53682                dHeight
53683              );
53684
53685              if (this._isErasing) {
53686                this._pInst.erase();
53687              }
53688            } catch (e) {
53689              if (e.name !== 'NS_ERROR_NOT_AVAILABLE') {
53690                throw e;
53691              }
53692            }
53693          };
53694
53695          _main.default.Renderer2D.prototype._getTintedImageCanvas = function(img) {
53696            if (!img.canvas) {
53697              return img;
53698            }
53699            var pixels = _filters.default._toPixels(img.canvas);
53700            var tmpCanvas = document.createElement('canvas');
53701            tmpCanvas.width = img.canvas.width;
53702            tmpCanvas.height = img.canvas.height;
53703            var tmpCtx = tmpCanvas.getContext('2d');
53704            var id = tmpCtx.createImageData(img.canvas.width, img.canvas.height);
53705            var newPixels = id.data;
53706            for (var i = 0; i < pixels.length; i += 4) {
53707              var r = pixels[i];
53708              var g = pixels[i + 1];
53709              var b = pixels[i + 2];
53710              var a = pixels[i + 3];
53711              newPixels[i] = r * this._tint[0] / 255;
53712              newPixels[i + 1] = g * this._tint[1] / 255;
53713              newPixels[i + 2] = b * this._tint[2] / 255;
53714              newPixels[i + 3] = a * this._tint[3] / 255;
53715            }
53716            tmpCtx.putImageData(id, 0, 0);
53717            return tmpCanvas;
53718          };
53719
53720          //////////////////////////////////////////////
53721          // IMAGE | Pixels
53722          //////////////////////////////////////////////
53723
53724          _main.default.Renderer2D.prototype.blendMode = function(mode) {
53725            if (mode === constants.SUBTRACT) {
53726              console.warn('blendMode(SUBTRACT) only works in WEBGL mode.');
53727            } else if (
53728              mode === constants.BLEND ||
53729              mode === constants.REMOVE ||
53730              mode === constants.DARKEST ||
53731              mode === constants.LIGHTEST ||
53732              mode === constants.DIFFERENCE ||
53733              mode === constants.MULTIPLY ||
53734              mode === constants.EXCLUSION ||
53735              mode === constants.SCREEN ||
53736              mode === constants.REPLACE ||
53737              mode === constants.OVERLAY ||
53738              mode === constants.HARD_LIGHT ||
53739              mode === constants.SOFT_LIGHT ||
53740              mode === constants.DODGE ||
53741              mode === constants.BURN ||
53742              mode === constants.ADD
53743            ) {
53744              this._cachedBlendMode = mode;
53745              this.drawingContext.globalCompositeOperation = mode;
53746            } else {
53747              throw new Error('Mode '.concat(mode, ' not recognized.'));
53748            }
53749          };
53750
53751          _main.default.Renderer2D.prototype.blend = function() {
53752            var currBlend = this.drawingContext.globalCompositeOperation;
53753            for (
53754              var _len = arguments.length, args = new Array(_len), _key = 0;
53755              _key < _len;
53756              _key++
53757            ) {
53758              args[_key] = arguments[_key];
53759            }
53760            var blendMode = args[args.length - 1];
53761
53762            var copyArgs = Array.prototype.slice.call(args, 0, args.length - 1);
53763
53764            this.drawingContext.globalCompositeOperation = blendMode;
53765
53766            _main.default.prototype.copy.apply(this, copyArgs);
53767
53768            this.drawingContext.globalCompositeOperation = currBlend;
53769          };
53770
53771          // p5.Renderer2D.prototype.get = p5.Renderer.prototype.get;
53772          // .get() is not overridden
53773
53774          // x,y are canvas-relative (pre-scaled by _pixelDensity)
53775          _main.default.Renderer2D.prototype._getPixel = function(x, y) {
53776            var imageData, index;
53777            imageData = this.drawingContext.getImageData(x, y, 1, 1).data;
53778            index = 0;
53779            return [
53780              imageData[index + 0],
53781              imageData[index + 1],
53782              imageData[index + 2],
53783              imageData[index + 3]
53784            ];
53785          };
53786
53787          _main.default.Renderer2D.prototype.loadPixels = function() {
53788            var pixelsState = this._pixelsState; // if called by p5.Image
53789
53790            var pd = pixelsState._pixelDensity;
53791            var w = this.width * pd;
53792            var h = this.height * pd;
53793            var imageData = this.drawingContext.getImageData(0, 0, w, h);
53794            // @todo this should actually set pixels per object, so diff buffers can
53795            // have diff pixel arrays.
53796            pixelsState._setProperty('imageData', imageData);
53797            pixelsState._setProperty('pixels', imageData.data);
53798          };
53799
53800          _main.default.Renderer2D.prototype.set = function(x, y, imgOrCol) {
53801            // round down to get integer numbers
53802            x = Math.floor(x);
53803            y = Math.floor(y);
53804            var pixelsState = this._pixelsState;
53805            if (imgOrCol instanceof _main.default.Image) {
53806              this.drawingContext.save();
53807              this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);
53808              this.drawingContext.scale(
53809                pixelsState._pixelDensity,
53810                pixelsState._pixelDensity
53811              );
53812
53813              this.drawingContext.clearRect(x, y, imgOrCol.width, imgOrCol.height);
53814              this.drawingContext.drawImage(imgOrCol.canvas, x, y);
53815              this.drawingContext.restore();
53816            } else {
53817              var r = 0,
53818                g = 0,
53819                b = 0,
53820                a = 0;
53821              var idx =
53822                4 *
53823                (y * pixelsState._pixelDensity * (this.width * pixelsState._pixelDensity) +
53824                  x * pixelsState._pixelDensity);
53825              if (!pixelsState.imageData) {
53826                pixelsState.loadPixels.call(pixelsState);
53827              }
53828              if (typeof imgOrCol === 'number') {
53829                if (idx < pixelsState.pixels.length) {
53830                  r = imgOrCol;
53831                  g = imgOrCol;
53832                  b = imgOrCol;
53833                  a = 255;
53834                  //this.updatePixels.call(this);
53835                }
53836              } else if (imgOrCol instanceof Array) {
53837                if (imgOrCol.length < 4) {
53838                  throw new Error('pixel array must be of the form [R, G, B, A]');
53839                }
53840                if (idx < pixelsState.pixels.length) {
53841                  r = imgOrCol[0];
53842                  g = imgOrCol[1];
53843                  b = imgOrCol[2];
53844                  a = imgOrCol[3];
53845                  //this.updatePixels.call(this);
53846                }
53847              } else if (imgOrCol instanceof _main.default.Color) {
53848                if (idx < pixelsState.pixels.length) {
53849                  r = imgOrCol.levels[0];
53850                  g = imgOrCol.levels[1];
53851                  b = imgOrCol.levels[2];
53852                  a = imgOrCol.levels[3];
53853                  //this.updatePixels.call(this);
53854                }
53855              }
53856              // loop over pixelDensity * pixelDensity
53857              for (var i = 0; i < pixelsState._pixelDensity; i++) {
53858                for (var j = 0; j < pixelsState._pixelDensity; j++) {
53859                  // loop over
53860                  idx =
53861                    4 *
53862                    ((y * pixelsState._pixelDensity + j) *
53863                      this.width *
53864                      pixelsState._pixelDensity +
53865                      (x * pixelsState._pixelDensity + i));
53866                  pixelsState.pixels[idx] = r;
53867                  pixelsState.pixels[idx + 1] = g;
53868                  pixelsState.pixels[idx + 2] = b;
53869                  pixelsState.pixels[idx + 3] = a;
53870                }
53871              }
53872            }
53873          };
53874
53875          _main.default.Renderer2D.prototype.updatePixels = function(x, y, w, h) {
53876            var pixelsState = this._pixelsState;
53877            var pd = pixelsState._pixelDensity;
53878            if (x === undefined && y === undefined && w === undefined && h === undefined) {
53879              x = 0;
53880              y = 0;
53881              w = this.width;
53882              h = this.height;
53883            }
53884            x *= pd;
53885            y *= pd;
53886            w *= pd;
53887            h *= pd;
53888
53889            if (this.gifProperties) {
53890              this.gifProperties.frames[this.gifProperties.displayIndex].image =
53891                pixelsState.imageData;
53892            }
53893
53894            this.drawingContext.putImageData(pixelsState.imageData, x, y, 0, 0, w, h);
53895          };
53896
53897          //////////////////////////////////////////////
53898          // SHAPE | 2D Primitives
53899          //////////////////////////////////////////////
53900
53901          /**
53902           * Generate a cubic Bezier representing an arc on the unit circle of total
53903           * angle `size` radians, beginning `start` radians above the x-axis. Up to
53904           * four of these curves are combined to make a full arc.
53905           *
53906           * See www.joecridge.me/bezier.pdf for an explanation of the method.
53907           */
53908          _main.default.Renderer2D.prototype._acuteArcToBezier = function _acuteArcToBezier(
53909            start,
53910            size
53911          ) {
53912            // Evaluate constants.
53913            var alpha = size / 2.0,
53914              cos_alpha = Math.cos(alpha),
53915              sin_alpha = Math.sin(alpha),
53916              cot_alpha = 1.0 / Math.tan(alpha),
53917              // This is how far the arc needs to be rotated.
53918              phi = start + alpha,
53919              cos_phi = Math.cos(phi),
53920              sin_phi = Math.sin(phi),
53921              lambda = (4.0 - cos_alpha) / 3.0,
53922              mu = sin_alpha + (cos_alpha - lambda) * cot_alpha;
53923
53924            // Return rotated waypoints.
53925            return {
53926              ax: Math.cos(start).toFixed(7),
53927              ay: Math.sin(start).toFixed(7),
53928              bx: (lambda * cos_phi + mu * sin_phi).toFixed(7),
53929              by: (lambda * sin_phi - mu * cos_phi).toFixed(7),
53930              cx: (lambda * cos_phi - mu * sin_phi).toFixed(7),
53931              cy: (lambda * sin_phi + mu * cos_phi).toFixed(7),
53932              dx: Math.cos(start + size).toFixed(7),
53933              dy: Math.sin(start + size).toFixed(7)
53934            };
53935          };
53936
53937          /*
53938    * This function requires that:
53939    *
53940    *   0 <= start < TWO_PI
53941    *
53942    *   start <= stop < start + TWO_PI
53943    */
53944          _main.default.Renderer2D.prototype.arc = function(x, y, w, h, start, stop, mode) {
53945            var ctx = this.drawingContext;
53946            var rx = w / 2.0;
53947            var ry = h / 2.0;
53948            var epsilon = 0.00001; // Smallest visible angle on displays up to 4K.
53949            var arcToDraw = 0;
53950            var curves = [];
53951
53952            x += rx;
53953            y += ry;
53954
53955            // Create curves
53956            while (stop - start >= epsilon) {
53957              arcToDraw = Math.min(stop - start, constants.HALF_PI);
53958              curves.push(this._acuteArcToBezier(start, arcToDraw));
53959              start += arcToDraw;
53960            }
53961
53962            // Fill curves
53963            if (this._doFill) {
53964              ctx.beginPath();
53965              curves.forEach(function(curve, index) {
53966                if (index === 0) {
53967                  ctx.moveTo(x + curve.ax * rx, y + curve.ay * ry);
53968                }
53969                // prettier-ignore
53970                ctx.bezierCurveTo(x + curve.bx * rx, y + curve.by * ry,
53971      x + curve.cx * rx, y + curve.cy * ry,
53972      x + curve.dx * rx, y + curve.dy * ry);
53973              });
53974              if (mode === constants.PIE || mode == null) {
53975                ctx.lineTo(x, y);
53976              }
53977              ctx.closePath();
53978              ctx.fill();
53979            }
53980
53981            // Stroke curves
53982            if (this._doStroke) {
53983              ctx.beginPath();
53984              curves.forEach(function(curve, index) {
53985                if (index === 0) {
53986                  ctx.moveTo(x + curve.ax * rx, y + curve.ay * ry);
53987                }
53988                // prettier-ignore
53989                ctx.bezierCurveTo(x + curve.bx * rx, y + curve.by * ry,
53990      x + curve.cx * rx, y + curve.cy * ry,
53991      x + curve.dx * rx, y + curve.dy * ry);
53992              });
53993              if (mode === constants.PIE) {
53994                ctx.lineTo(x, y);
53995                ctx.closePath();
53996              } else if (mode === constants.CHORD) {
53997                ctx.closePath();
53998              }
53999              ctx.stroke();
54000            }
54001            return this;
54002          };
54003
54004          _main.default.Renderer2D.prototype.ellipse = function(args) {
54005            var ctx = this.drawingContext;
54006            var doFill = this._doFill,
54007              doStroke = this._doStroke;
54008            var x = parseFloat(args[0]),
54009              y = parseFloat(args[1]),
54010              w = parseFloat(args[2]),
54011              h = parseFloat(args[3]);
54012            if (doFill && !doStroke) {
54013              if (this._getFill() === styleEmpty) {
54014                return this;
54015              }
54016            } else if (!doFill && doStroke) {
54017              if (this._getStroke() === styleEmpty) {
54018                return this;
54019              }
54020            }
54021            var kappa = 0.5522847498,
54022              // control point offset horizontal
54023              ox = w / 2 * kappa,
54024              // control point offset vertical
54025              oy = h / 2 * kappa,
54026              // x-end
54027              xe = x + w,
54028              // y-end
54029              ye = y + h,
54030              // x-middle
54031              xm = x + w / 2,
54032              ym = y + h / 2; // y-middle
54033            ctx.beginPath();
54034            ctx.moveTo(x, ym);
54035            ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
54036            ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
54037            ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
54038            ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
54039            if (doFill) {
54040              ctx.fill();
54041            }
54042            if (doStroke) {
54043              ctx.stroke();
54044            }
54045          };
54046
54047          _main.default.Renderer2D.prototype.line = function(x1, y1, x2, y2) {
54048            var ctx = this.drawingContext;
54049            if (!this._doStroke) {
54050              return this;
54051            } else if (this._getStroke() === styleEmpty) {
54052              return this;
54053            }
54054            ctx.beginPath();
54055            ctx.moveTo(x1, y1);
54056            ctx.lineTo(x2, y2);
54057            ctx.stroke();
54058            return this;
54059          };
54060
54061          _main.default.Renderer2D.prototype.point = function(x, y) {
54062            var ctx = this.drawingContext;
54063            if (!this._doStroke) {
54064              return this;
54065            } else if (this._getStroke() === styleEmpty) {
54066              return this;
54067            }
54068            var s = this._getStroke();
54069            var f = this._getFill();
54070            x = Math.round(x);
54071            y = Math.round(y);
54072            // swapping fill color to stroke and back after for correct point rendering
54073            this._setFill(s);
54074            if (ctx.lineWidth > 1) {
54075              ctx.beginPath();
54076              ctx.arc(x, y, ctx.lineWidth / 2, 0, constants.TWO_PI, false);
54077              ctx.fill();
54078            } else {
54079              ctx.fillRect(x, y, 1, 1);
54080            }
54081            this._setFill(f);
54082          };
54083
54084          _main.default.Renderer2D.prototype.quad = function(
54085            x1,
54086            y1,
54087            x2,
54088            y2,
54089            x3,
54090            y3,
54091            x4,
54092            y4
54093          ) {
54094            var ctx = this.drawingContext;
54095            var doFill = this._doFill,
54096              doStroke = this._doStroke;
54097            if (doFill && !doStroke) {
54098              if (this._getFill() === styleEmpty) {
54099                return this;
54100              }
54101            } else if (!doFill && doStroke) {
54102              if (this._getStroke() === styleEmpty) {
54103                return this;
54104              }
54105            }
54106            ctx.beginPath();
54107            ctx.moveTo(x1, y1);
54108            ctx.lineTo(x2, y2);
54109            ctx.lineTo(x3, y3);
54110            ctx.lineTo(x4, y4);
54111            ctx.closePath();
54112            if (doFill) {
54113              ctx.fill();
54114            }
54115            if (doStroke) {
54116              ctx.stroke();
54117            }
54118            return this;
54119          };
54120
54121          _main.default.Renderer2D.prototype.rect = function(args) {
54122            var x = args[0];
54123            var y = args[1];
54124            var w = args[2];
54125            var h = args[3];
54126            var tl = args[4];
54127            var tr = args[5];
54128            var br = args[6];
54129            var bl = args[7];
54130            var ctx = this.drawingContext;
54131            var doFill = this._doFill,
54132              doStroke = this._doStroke;
54133            if (doFill && !doStroke) {
54134              if (this._getFill() === styleEmpty) {
54135                return this;
54136              }
54137            } else if (!doFill && doStroke) {
54138              if (this._getStroke() === styleEmpty) {
54139                return this;
54140              }
54141            }
54142            ctx.beginPath();
54143
54144            if (typeof tl === 'undefined') {
54145              // No rounded corners
54146              ctx.rect(x, y, w, h);
54147            } else {
54148              // At least one rounded corner
54149              // Set defaults when not specified
54150              if (typeof tr === 'undefined') {
54151                tr = tl;
54152              }
54153              if (typeof br === 'undefined') {
54154                br = tr;
54155              }
54156              if (typeof bl === 'undefined') {
54157                bl = br;
54158              }
54159
54160              // corner rounding must always be positive
54161              var absW = Math.abs(w);
54162              var absH = Math.abs(h);
54163              var hw = absW / 2;
54164              var hh = absH / 2;
54165
54166              // Clip radii
54167              if (absW < 2 * tl) {
54168                tl = hw;
54169              }
54170              if (absH < 2 * tl) {
54171                tl = hh;
54172              }
54173              if (absW < 2 * tr) {
54174                tr = hw;
54175              }
54176              if (absH < 2 * tr) {
54177                tr = hh;
54178              }
54179              if (absW < 2 * br) {
54180                br = hw;
54181              }
54182              if (absH < 2 * br) {
54183                br = hh;
54184              }
54185              if (absW < 2 * bl) {
54186                bl = hw;
54187              }
54188              if (absH < 2 * bl) {
54189                bl = hh;
54190              }
54191
54192              // Draw shape
54193              ctx.beginPath();
54194              ctx.moveTo(x + tl, y);
54195              ctx.arcTo(x + w, y, x + w, y + h, tr);
54196              ctx.arcTo(x + w, y + h, x, y + h, br);
54197              ctx.arcTo(x, y + h, x, y, bl);
54198              ctx.arcTo(x, y, x + w, y, tl);
54199              ctx.closePath();
54200            }
54201            if (this._doFill) {
54202              ctx.fill();
54203            }
54204            if (this._doStroke) {
54205              ctx.stroke();
54206            }
54207            return this;
54208          };
54209
54210          _main.default.Renderer2D.prototype.triangle = function(args) {
54211            var ctx = this.drawingContext;
54212            var doFill = this._doFill,
54213              doStroke = this._doStroke;
54214            var x1 = args[0],
54215              y1 = args[1];
54216            var x2 = args[2],
54217              y2 = args[3];
54218            var x3 = args[4],
54219              y3 = args[5];
54220            if (doFill && !doStroke) {
54221              if (this._getFill() === styleEmpty) {
54222                return this;
54223              }
54224            } else if (!doFill && doStroke) {
54225              if (this._getStroke() === styleEmpty) {
54226                return this;
54227              }
54228            }
54229            ctx.beginPath();
54230            ctx.moveTo(x1, y1);
54231            ctx.lineTo(x2, y2);
54232            ctx.lineTo(x3, y3);
54233            ctx.closePath();
54234            if (doFill) {
54235              ctx.fill();
54236            }
54237            if (doStroke) {
54238              ctx.stroke();
54239            }
54240          };
54241
54242          _main.default.Renderer2D.prototype.endShape = function(
54243            mode,
54244            vertices,
54245            isCurve,
54246            isBezier,
54247            isQuadratic,
54248            isContour,
54249            shapeKind
54250          ) {
54251            if (vertices.length === 0) {
54252              return this;
54253            }
54254            if (!this._doStroke && !this._doFill) {
54255              return this;
54256            }
54257            var closeShape = mode === constants.CLOSE;
54258            var v;
54259            if (closeShape && !isContour) {
54260              vertices.push(vertices[0]);
54261            }
54262            var i, j;
54263            var numVerts = vertices.length;
54264            if (isCurve && (shapeKind === constants.POLYGON || shapeKind === null)) {
54265              if (numVerts > 3) {
54266                var b = [],
54267                  s = 1 - this._curveTightness;
54268                this.drawingContext.beginPath();
54269                this.drawingContext.moveTo(vertices[1][0], vertices[1][1]);
54270                for (i = 1; i + 2 < numVerts; i++) {
54271                  v = vertices[i];
54272                  b[0] = [v[0], v[1]];
54273                  b[1] = [
54274                    v[0] + (s * vertices[i + 1][0] - s * vertices[i - 1][0]) / 6,
54275                    v[1] + (s * vertices[i + 1][1] - s * vertices[i - 1][1]) / 6
54276                  ];
54277
54278                  b[2] = [
54279                    vertices[i + 1][0] + (s * vertices[i][0] - s * vertices[i + 2][0]) / 6,
54280                    vertices[i + 1][1] + (s * vertices[i][1] - s * vertices[i + 2][1]) / 6
54281                  ];
54282
54283                  b[3] = [vertices[i + 1][0], vertices[i + 1][1]];
54284                  this.drawingContext.bezierCurveTo(
54285                    b[1][0],
54286                    b[1][1],
54287                    b[2][0],
54288                    b[2][1],
54289                    b[3][0],
54290                    b[3][1]
54291                  );
54292                }
54293                if (closeShape) {
54294                  this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);
54295                }
54296                this._doFillStrokeClose(closeShape);
54297              }
54298            } else if (
54299              isBezier &&
54300              (shapeKind === constants.POLYGON || shapeKind === null)
54301            ) {
54302              this.drawingContext.beginPath();
54303              for (i = 0; i < numVerts; i++) {
54304                if (vertices[i].isVert) {
54305                  if (vertices[i].moveTo) {
54306                    this.drawingContext.moveTo(vertices[i][0], vertices[i][1]);
54307                  } else {
54308                    this.drawingContext.lineTo(vertices[i][0], vertices[i][1]);
54309                  }
54310                } else {
54311                  this.drawingContext.bezierCurveTo(
54312                    vertices[i][0],
54313                    vertices[i][1],
54314                    vertices[i][2],
54315                    vertices[i][3],
54316                    vertices[i][4],
54317                    vertices[i][5]
54318                  );
54319                }
54320              }
54321              this._doFillStrokeClose(closeShape);
54322            } else if (
54323              isQuadratic &&
54324              (shapeKind === constants.POLYGON || shapeKind === null)
54325            ) {
54326              this.drawingContext.beginPath();
54327              for (i = 0; i < numVerts; i++) {
54328                if (vertices[i].isVert) {
54329                  if (vertices[i].moveTo) {
54330                    this.drawingContext.moveTo(vertices[i][0], vertices[i][1]);
54331                  } else {
54332                    this.drawingContext.lineTo(vertices[i][0], vertices[i][1]);
54333                  }
54334                } else {
54335                  this.drawingContext.quadraticCurveTo(
54336                    vertices[i][0],
54337                    vertices[i][1],
54338                    vertices[i][2],
54339                    vertices[i][3]
54340                  );
54341                }
54342              }
54343              this._doFillStrokeClose(closeShape);
54344            } else {
54345              if (shapeKind === constants.POINTS) {
54346                for (i = 0; i < numVerts; i++) {
54347                  v = vertices[i];
54348                  if (this._doStroke) {
54349                    this._pInst.stroke(v[6]);
54350                  }
54351                  this._pInst.point(v[0], v[1]);
54352                }
54353              } else if (shapeKind === constants.LINES) {
54354                for (i = 0; i + 1 < numVerts; i += 2) {
54355                  v = vertices[i];
54356                  if (this._doStroke) {
54357                    this._pInst.stroke(vertices[i + 1][6]);
54358                  }
54359                  this._pInst.line(v[0], v[1], vertices[i + 1][0], vertices[i + 1][1]);
54360                }
54361              } else if (shapeKind === constants.TRIANGLES) {
54362                for (i = 0; i + 2 < numVerts; i += 3) {
54363                  v = vertices[i];
54364                  this.drawingContext.beginPath();
54365                  this.drawingContext.moveTo(v[0], v[1]);
54366                  this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);
54367                  this.drawingContext.lineTo(vertices[i + 2][0], vertices[i + 2][1]);
54368                  this.drawingContext.closePath();
54369                  if (this._doFill) {
54370                    this._pInst.fill(vertices[i + 2][5]);
54371                    this.drawingContext.fill();
54372                  }
54373                  if (this._doStroke) {
54374                    this._pInst.stroke(vertices[i + 2][6]);
54375                    this.drawingContext.stroke();
54376                  }
54377                }
54378              } else if (shapeKind === constants.TRIANGLE_STRIP) {
54379                for (i = 0; i + 1 < numVerts; i++) {
54380                  v = vertices[i];
54381                  this.drawingContext.beginPath();
54382                  this.drawingContext.moveTo(vertices[i + 1][0], vertices[i + 1][1]);
54383                  this.drawingContext.lineTo(v[0], v[1]);
54384                  if (this._doStroke) {
54385                    this._pInst.stroke(vertices[i + 1][6]);
54386                  }
54387                  if (this._doFill) {
54388                    this._pInst.fill(vertices[i + 1][5]);
54389                  }
54390                  if (i + 2 < numVerts) {
54391                    this.drawingContext.lineTo(vertices[i + 2][0], vertices[i + 2][1]);
54392                    if (this._doStroke) {
54393                      this._pInst.stroke(vertices[i + 2][6]);
54394                    }
54395                    if (this._doFill) {
54396                      this._pInst.fill(vertices[i + 2][5]);
54397                    }
54398                  }
54399                  this._doFillStrokeClose(closeShape);
54400                }
54401              } else if (shapeKind === constants.TRIANGLE_FAN) {
54402                if (numVerts > 2) {
54403                  // For performance reasons, try to batch as many of the
54404                  // fill and stroke calls as possible.
54405                  this.drawingContext.beginPath();
54406                  for (i = 2; i < numVerts; i++) {
54407                    v = vertices[i];
54408                    this.drawingContext.moveTo(vertices[0][0], vertices[0][1]);
54409                    this.drawingContext.lineTo(vertices[i - 1][0], vertices[i - 1][1]);
54410                    this.drawingContext.lineTo(v[0], v[1]);
54411                    this.drawingContext.lineTo(vertices[0][0], vertices[0][1]);
54412                    // If the next colour is going to be different, stroke / fill now
54413                    if (i < numVerts - 1) {
54414                      if (
54415                        (this._doFill && v[5] !== vertices[i + 1][5]) ||
54416                        (this._doStroke && v[6] !== vertices[i + 1][6])
54417                      ) {
54418                        if (this._doFill) {
54419                          this._pInst.fill(v[5]);
54420                          this.drawingContext.fill();
54421                          this._pInst.fill(vertices[i + 1][5]);
54422                        }
54423                        if (this._doStroke) {
54424                          this._pInst.stroke(v[6]);
54425                          this.drawingContext.stroke();
54426                          this._pInst.stroke(vertices[i + 1][6]);
54427                        }
54428                        this.drawingContext.closePath();
54429                        this.drawingContext.beginPath(); // Begin the next one
54430                      }
54431                    }
54432                  }
54433                  this._doFillStrokeClose(closeShape);
54434                }
54435              } else if (shapeKind === constants.QUADS) {
54436                for (i = 0; i + 3 < numVerts; i += 4) {
54437                  v = vertices[i];
54438                  this.drawingContext.beginPath();
54439                  this.drawingContext.moveTo(v[0], v[1]);
54440                  for (j = 1; j < 4; j++) {
54441                    this.drawingContext.lineTo(vertices[i + j][0], vertices[i + j][1]);
54442                  }
54443                  this.drawingContext.lineTo(v[0], v[1]);
54444                  if (this._doFill) {
54445                    this._pInst.fill(vertices[i + 3][5]);
54446                  }
54447                  if (this._doStroke) {
54448                    this._pInst.stroke(vertices[i + 3][6]);
54449                  }
54450                  this._doFillStrokeClose(closeShape);
54451                }
54452              } else if (shapeKind === constants.QUAD_STRIP) {
54453                if (numVerts > 3) {
54454                  for (i = 0; i + 1 < numVerts; i += 2) {
54455                    v = vertices[i];
54456                    this.drawingContext.beginPath();
54457                    if (i + 3 < numVerts) {
54458                      this.drawingContext.moveTo(vertices[i + 2][0], vertices[i + 2][1]);
54459                      this.drawingContext.lineTo(v[0], v[1]);
54460                      this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);
54461                      this.drawingContext.lineTo(vertices[i + 3][0], vertices[i + 3][1]);
54462                      if (this._doFill) {
54463                        this._pInst.fill(vertices[i + 3][5]);
54464                      }
54465                      if (this._doStroke) {
54466                        this._pInst.stroke(vertices[i + 3][6]);
54467                      }
54468                    } else {
54469                      this.drawingContext.moveTo(v[0], v[1]);
54470                      this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);
54471                    }
54472                    this._doFillStrokeClose(closeShape);
54473                  }
54474                }
54475              } else {
54476                this.drawingContext.beginPath();
54477                this.drawingContext.moveTo(vertices[0][0], vertices[0][1]);
54478                for (i = 1; i < numVerts; i++) {
54479                  v = vertices[i];
54480                  if (v.isVert) {
54481                    if (v.moveTo) {
54482                      this.drawingContext.moveTo(v[0], v[1]);
54483                    } else {
54484                      this.drawingContext.lineTo(v[0], v[1]);
54485                    }
54486                  }
54487                }
54488                this._doFillStrokeClose(closeShape);
54489              }
54490            }
54491            isCurve = false;
54492            isBezier = false;
54493            isQuadratic = false;
54494            isContour = false;
54495            if (closeShape) {
54496              vertices.pop();
54497            }
54498
54499            return this;
54500          };
54501          //////////////////////////////////////////////
54502          // SHAPE | Attributes
54503          //////////////////////////////////////////////
54504
54505          _main.default.Renderer2D.prototype.strokeCap = function(cap) {
54506            if (
54507              cap === constants.ROUND ||
54508              cap === constants.SQUARE ||
54509              cap === constants.PROJECT
54510            ) {
54511              this.drawingContext.lineCap = cap;
54512            }
54513            return this;
54514          };
54515
54516          _main.default.Renderer2D.prototype.strokeJoin = function(join) {
54517            if (
54518              join === constants.ROUND ||
54519              join === constants.BEVEL ||
54520              join === constants.MITER
54521            ) {
54522              this.drawingContext.lineJoin = join;
54523            }
54524            return this;
54525          };
54526
54527          _main.default.Renderer2D.prototype.strokeWeight = function(w) {
54528            if (typeof w === 'undefined' || w === 0) {
54529              // hack because lineWidth 0 doesn't work
54530              this.drawingContext.lineWidth = 0.0001;
54531            } else {
54532              this.drawingContext.lineWidth = w;
54533            }
54534            return this;
54535          };
54536
54537          _main.default.Renderer2D.prototype._getFill = function() {
54538            if (!this._cachedFillStyle) {
54539              this._cachedFillStyle = this.drawingContext.fillStyle;
54540            }
54541            return this._cachedFillStyle;
54542          };
54543
54544          _main.default.Renderer2D.prototype._setFill = function(fillStyle) {
54545            if (fillStyle !== this._cachedFillStyle) {
54546              this.drawingContext.fillStyle = fillStyle;
54547              this._cachedFillStyle = fillStyle;
54548            }
54549          };
54550
54551          _main.default.Renderer2D.prototype._getStroke = function() {
54552            if (!this._cachedStrokeStyle) {
54553              this._cachedStrokeStyle = this.drawingContext.strokeStyle;
54554            }
54555            return this._cachedStrokeStyle;
54556          };
54557
54558          _main.default.Renderer2D.prototype._setStroke = function(strokeStyle) {
54559            if (strokeStyle !== this._cachedStrokeStyle) {
54560              this.drawingContext.strokeStyle = strokeStyle;
54561              this._cachedStrokeStyle = strokeStyle;
54562            }
54563          };
54564
54565          //////////////////////////////////////////////
54566          // SHAPE | Curves
54567          //////////////////////////////////////////////
54568          _main.default.Renderer2D.prototype.bezier = function(
54569            x1,
54570            y1,
54571            x2,
54572            y2,
54573            x3,
54574            y3,
54575            x4,
54576            y4
54577          ) {
54578            this._pInst.beginShape();
54579            this._pInst.vertex(x1, y1);
54580            this._pInst.bezierVertex(x2, y2, x3, y3, x4, y4);
54581            this._pInst.endShape();
54582            return this;
54583          };
54584
54585          _main.default.Renderer2D.prototype.curve = function(
54586            x1,
54587            y1,
54588            x2,
54589            y2,
54590            x3,
54591            y3,
54592            x4,
54593            y4
54594          ) {
54595            this._pInst.beginShape();
54596            this._pInst.curveVertex(x1, y1);
54597            this._pInst.curveVertex(x2, y2);
54598            this._pInst.curveVertex(x3, y3);
54599            this._pInst.curveVertex(x4, y4);
54600            this._pInst.endShape();
54601            return this;
54602          };
54603
54604          //////////////////////////////////////////////
54605          // SHAPE | Vertex
54606          //////////////////////////////////////////////
54607
54608          _main.default.Renderer2D.prototype._doFillStrokeClose = function(closeShape) {
54609            if (closeShape) {
54610              this.drawingContext.closePath();
54611            }
54612            if (this._doFill) {
54613              this.drawingContext.fill();
54614            }
54615            if (this._doStroke) {
54616              this.drawingContext.stroke();
54617            }
54618          };
54619
54620          //////////////////////////////////////////////
54621          // TRANSFORM
54622          //////////////////////////////////////////////
54623
54624          _main.default.Renderer2D.prototype.applyMatrix = function(a, b, c, d, e, f) {
54625            this.drawingContext.transform(a, b, c, d, e, f);
54626          };
54627
54628          _main.default.Renderer2D.prototype.resetMatrix = function() {
54629            this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);
54630            this.drawingContext.scale(this._pInst._pixelDensity, this._pInst._pixelDensity);
54631
54632            return this;
54633          };
54634
54635          _main.default.Renderer2D.prototype.rotate = function(rad) {
54636            this.drawingContext.rotate(rad);
54637          };
54638
54639          _main.default.Renderer2D.prototype.scale = function(x, y) {
54640            this.drawingContext.scale(x, y);
54641            return this;
54642          };
54643
54644          _main.default.Renderer2D.prototype.translate = function(x, y) {
54645            // support passing a vector as the 1st parameter
54646            if (x instanceof _main.default.Vector) {
54647              y = x.y;
54648              x = x.x;
54649            }
54650            this.drawingContext.translate(x, y);
54651            return this;
54652          };
54653
54654          //////////////////////////////////////////////
54655          // TYPOGRAPHY
54656          //
54657          //////////////////////////////////////////////
54658
54659          _main.default.Renderer2D.prototype.text = function(
54660            str,
54661            x,
54662            y,
54663            maxWidth,
54664            maxHeight
54665          ) {
54666            var baselineHacked;
54667
54668            // baselineHacked: (HACK)
54669            // A temporary fix to conform to Processing's implementation
54670            // of BASELINE vertical alignment in a bounding box
54671
54672            if (typeof maxWidth !== 'undefined') {
54673              if (this.drawingContext.textBaseline === constants.BASELINE) {
54674                baselineHacked = true;
54675                this.drawingContext.textBaseline = constants.TOP;
54676              }
54677            }
54678
54679            var p = _main.default.Renderer.prototype.text.apply(this, arguments);
54680
54681            if (baselineHacked) {
54682              this.drawingContext.textBaseline = constants.BASELINE;
54683            }
54684
54685            return p;
54686          };
54687
54688          _main.default.Renderer2D.prototype._renderText = function(p, line, x, y, maxY) {
54689            if (y >= maxY) {
54690              return; // don't render lines beyond our maxY position
54691            }
54692
54693            p.push(); // fix to #803
54694
54695            if (!this._isOpenType()) {
54696              // a system/browser font
54697
54698              // no stroke unless specified by user
54699              if (this._doStroke && this._strokeSet) {
54700                this.drawingContext.strokeText(line, x, y);
54701              }
54702
54703              if (this._doFill) {
54704                // if fill hasn't been set by user, use default text fill
54705                if (!this._fillSet) {
54706                  this._setFill(constants._DEFAULT_TEXT_FILL);
54707                }
54708
54709                this.drawingContext.fillText(line, x, y);
54710              }
54711            } else {
54712              // an opentype font, let it handle the rendering
54713
54714              this._textFont._renderPath(line, x, y, { renderer: this });
54715            }
54716
54717            p.pop();
54718            return p;
54719          };
54720
54721          _main.default.Renderer2D.prototype.textWidth = function(s) {
54722            if (this._isOpenType()) {
54723              return this._textFont._textWidth(s, this._textSize);
54724            }
54725
54726            return this.drawingContext.measureText(s).width;
54727          };
54728
54729          _main.default.Renderer2D.prototype._applyTextProperties = function() {
54730            var font;
54731            var p = this._pInst;
54732
54733            this._setProperty('_textAscent', null);
54734            this._setProperty('_textDescent', null);
54735
54736            font = this._textFont;
54737
54738            if (this._isOpenType()) {
54739              font = this._textFont.font.familyName;
54740              this._setProperty('_textStyle', this._textFont.font.styleName);
54741            }
54742
54743            this.drawingContext.font = ''
54744              .concat(this._textStyle || 'normal', ' ')
54745              .concat(this._textSize || 12, 'px ')
54746              .concat(font || 'sans-serif');
54747
54748            this.drawingContext.textAlign = this._textAlign;
54749            if (this._textBaseline === constants.CENTER) {
54750              this.drawingContext.textBaseline = constants._CTX_MIDDLE;
54751            } else {
54752              this.drawingContext.textBaseline = this._textBaseline;
54753            }
54754
54755            return p;
54756          };
54757
54758          //////////////////////////////////////////////
54759          // STRUCTURE
54760          //////////////////////////////////////////////
54761
54762          // a push() operation is in progress.
54763          // the renderer should return a 'style' object that it wishes to
54764          // store on the push stack.
54765          // derived renderers should call the base class' push() method
54766          // to fetch the base style object.
54767          _main.default.Renderer2D.prototype.push = function() {
54768            this.drawingContext.save();
54769
54770            // get the base renderer style
54771            return _main.default.Renderer.prototype.push.apply(this);
54772          };
54773
54774          // a pop() operation is in progress
54775          // the renderer is passed the 'style' object that it returned
54776          // from its push() method.
54777          // derived renderers should pass this object to their base
54778          // class' pop method
54779          _main.default.Renderer2D.prototype.pop = function(style) {
54780            this.drawingContext.restore();
54781            // Re-cache the fill / stroke state
54782            this._cachedFillStyle = this.drawingContext.fillStyle;
54783            this._cachedStrokeStyle = this.drawingContext.strokeStyle;
54784
54785            _main.default.Renderer.prototype.pop.call(this, style);
54786          };
54787          var _default = _main.default.Renderer2D;
54788          exports.default = _default;
54789        },
54790        { '../image/filters': 80, './constants': 48, './main': 59, './p5.Renderer': 62 }
54791      ],
54792      64: [
54793        function(_dereq_, module, exports) {
54794          'use strict';
54795
54796          var _main = _interopRequireDefault(_dereq_('./main'));
54797          function _interopRequireDefault(obj) {
54798            return obj && obj.__esModule ? obj : { default: obj };
54799          }
54800
54801          _main.default.prototype._promisePreloads = [
54802            /* Example object
54803                                            {
54804                                              target: p5.prototype, // The target object to have the method modified
54805                                              method: 'loadXAsync', // The name of the preload function to wrap
54806                                              addCallbacks: true,   // Whether to automatically handle the p5 callbacks
54807                                              legacyPreloadSetup: { // Optional object to generate a legacy-style preload
54808                                                method: 'loadX',    // The name of the legacy preload function to generate
54809                                                createBaseObject: function() {
54810                                                  return {};
54811                                                } // An optional function to create the base object for the legacy preload.
54812                                              }
54813                                            }
54814                                            */
54815          ];
54816
54817          _main.default.prototype.registerPromisePreload = function(setup) {
54818            _main.default.prototype._promisePreloads.push(setup);
54819          };
54820
54821          var initialSetupRan = false;
54822
54823          _main.default.prototype._setupPromisePreloads = function() {
54824            var _iteratorNormalCompletion = true;
54825            var _didIteratorError = false;
54826            var _iteratorError = undefined;
54827            try {
54828              for (
54829                var _iterator = this._promisePreloads[Symbol.iterator](), _step;
54830                !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
54831                _iteratorNormalCompletion = true
54832              ) {
54833                var preloadSetup = _step.value;
54834                var thisValue = this;
54835                var method = preloadSetup.method,
54836                  addCallbacks = preloadSetup.addCallbacks,
54837                  legacyPreloadSetup = preloadSetup.legacyPreloadSetup;
54838                // Get the target object that the preload gets assigned to by default,
54839                // that is the current object.
54840                var target = preloadSetup.target || this;
54841                var sourceFunction = target[method].bind(target);
54842                // If the target is the p5 prototype, then only set it up on the first run per page
54843                if (target === _main.default.prototype) {
54844                  if (initialSetupRan) {
54845                    continue;
54846                  }
54847                  thisValue = null;
54848                  sourceFunction = target[method];
54849                }
54850
54851                // Replace the original method with a wrapped version
54852                target[method] = this._wrapPromisePreload(
54853                  thisValue,
54854                  sourceFunction,
54855                  addCallbacks
54856                );
54857
54858                // If a legacy preload is required
54859                if (legacyPreloadSetup) {
54860                  // What is the name for this legacy preload
54861                  var legacyMethod = legacyPreloadSetup.method;
54862                  // Wrap the already wrapped Promise-returning method with the legacy setup
54863                  target[legacyMethod] = this._legacyPreloadGenerator(
54864                    thisValue,
54865                    legacyPreloadSetup,
54866                    target[method]
54867                  );
54868                }
54869              }
54870            } catch (err) {
54871              _didIteratorError = true;
54872              _iteratorError = err;
54873            } finally {
54874              try {
54875                if (!_iteratorNormalCompletion && _iterator.return != null) {
54876                  _iterator.return();
54877                }
54878              } finally {
54879                if (_didIteratorError) {
54880                  throw _iteratorError;
54881                }
54882              }
54883            }
54884            initialSetupRan = true;
54885          };
54886
54887          _main.default.prototype._wrapPromisePreload = function(
54888            thisValue,
54889            fn,
54890            addCallbacks
54891          ) {
54892            var replacementFunction = function replacementFunction() {
54893              var _this = this;
54894              // Uses the current preload counting mechanism for now.
54895              this._incrementPreload();
54896              // A variable for the callback function if specified
54897              var callback = null;
54898              // A variable for the errorCallback function if specified
54899              var errorCallback = null;
54900              for (
54901                var _len = arguments.length, args = new Array(_len), _key = 0;
54902                _key < _len;
54903                _key++
54904              ) {
54905                args[_key] = arguments[_key];
54906              }
54907              if (addCallbacks) {
54908                // Loop from the end of the args array, pulling up to two functions off of
54909                // the end and putting them in fns
54910                for (var i = args.length - 1; i >= 0 && !errorCallback; i--) {
54911                  if (typeof args[i] !== 'function') {
54912                    break;
54913                  }
54914                  errorCallback = callback;
54915                  callback = args.pop();
54916                }
54917              }
54918              // Call the underlying funciton and pass it to Promise.resolve,
54919              // so that even if it didn't return a promise we can still
54920              // act on the result as if it did.
54921              var promise = Promise.resolve(fn.apply(this, args));
54922              // Add the optional callbacks
54923              if (callback) {
54924                promise.then(callback);
54925              }
54926              if (errorCallback) {
54927                promise.catch(errorCallback);
54928              }
54929              // Decrement the preload counter only if the promise resolved
54930              promise.then(function() {
54931                return _this._decrementPreload();
54932              });
54933              // Return the original promise so that neither callback changes the result.
54934              return promise;
54935            };
54936            if (thisValue) {
54937              replacementFunction = replacementFunction.bind(thisValue);
54938            }
54939            return replacementFunction;
54940          };
54941
54942          var objectCreator = function objectCreator() {
54943            return {};
54944          };
54945
54946          _main.default.prototype._legacyPreloadGenerator = function(
54947            thisValue,
54948            legacyPreloadSetup,
54949            fn
54950          ) {
54951            // Create a function that will generate an object before the preload is
54952            // launched. For example, if the object should be an array or be an instance
54953            // of a specific class.
54954            var baseValueGenerator = legacyPreloadSetup.createBaseObject || objectCreator;
54955            var returnedFunction = function returnedFunction() {
54956              var _this2 = this;
54957              // Our then clause needs to run before setup, so we also increment the preload counter
54958              this._incrementPreload();
54959              // Generate the return value based on the generator.
54960              var returnValue = baseValueGenerator.apply(this, arguments);
54961              // Run the original wrapper
54962              fn.apply(this, arguments).then(function(data) {
54963                // Copy each key from the resolved value into returnValue
54964                Object.assign(returnValue, data);
54965                // Decrement the preload counter, to allow setup to continue.
54966                _this2._decrementPreload();
54967              });
54968              return returnValue;
54969            };
54970            if (thisValue) {
54971              returnedFunction = returnedFunction.bind(thisValue);
54972            }
54973            return returnedFunction;
54974          };
54975        },
54976        { './main': 59 }
54977      ],
54978      65: [
54979        function(_dereq_, module, exports) {
54980          'use strict';
54981          Object.defineProperty(exports, '__esModule', { value: true });
54982          exports.default = void 0;
54983
54984          var _main = _interopRequireDefault(_dereq_('./main'));
54985          var constants = _interopRequireWildcard(_dereq_('./constants'));
54986          _dereq_('./p5.Graphics');
54987          _dereq_('./p5.Renderer2D');
54988          _dereq_('../webgl/p5.RendererGL');
54989          function _getRequireWildcardCache() {
54990            if (typeof WeakMap !== 'function') return null;
54991            var cache = new WeakMap();
54992            _getRequireWildcardCache = function _getRequireWildcardCache() {
54993              return cache;
54994            };
54995            return cache;
54996          }
54997          function _interopRequireWildcard(obj) {
54998            if (obj && obj.__esModule) {
54999              return obj;
55000            }
55001            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
55002              return { default: obj };
55003            }
55004            var cache = _getRequireWildcardCache();
55005            if (cache && cache.has(obj)) {
55006              return cache.get(obj);
55007            }
55008            var newObj = {};
55009            var hasPropertyDescriptor =
55010              Object.defineProperty && Object.getOwnPropertyDescriptor;
55011            for (var key in obj) {
55012              if (Object.prototype.hasOwnProperty.call(obj, key)) {
55013                var desc = hasPropertyDescriptor
55014                  ? Object.getOwnPropertyDescriptor(obj, key)
55015                  : null;
55016                if (desc && (desc.get || desc.set)) {
55017                  Object.defineProperty(newObj, key, desc);
55018                } else {
55019                  newObj[key] = obj[key];
55020                }
55021              }
55022            }
55023            newObj.default = obj;
55024            if (cache) {
55025              cache.set(obj, newObj);
55026            }
55027            return newObj;
55028          }
55029          function _interopRequireDefault(obj) {
55030            return obj && obj.__esModule ? obj : { default: obj };
55031          }
55032          function _typeof(obj) {
55033            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
55034              _typeof = function _typeof(obj) {
55035                return typeof obj;
55036              };
55037            } else {
55038              _typeof = function _typeof(obj) {
55039                return obj &&
55040                  typeof Symbol === 'function' &&
55041                  obj.constructor === Symbol &&
55042                  obj !== Symbol.prototype
55043                  ? 'symbol'
55044                  : typeof obj;
55045              };
55046            }
55047            return _typeof(obj);
55048          }
55049          var defaultId = 'defaultCanvas0'; // this gets set again in createCanvas
55050          var defaultClass = 'p5Canvas';
55051
55052          /**
55053           * Creates a canvas element in the document, and sets the dimensions of it
55054           * in pixels. This method should be called only once at the start of setup.
55055           * Calling <a href="#/p5/createCanvas">createCanvas</a> more than once in a
55056           * sketch will result in very unpredictable behavior. If you want more than
55057           * one drawing canvas you could use <a href="#/p5/createGraphics">createGraphics</a>
55058           * (hidden by default but it can be shown).
55059           *
55060           * Important note: in 2D mode (i.e. when `p5.Renderer` is not set) the origin (0,0)
55061           * is positioned at the top left of the screen. In 3D mode (i.e. when `p5.Renderer`
55062           * is set to `WEBGL`), the origin is positioned at the center of the canvas.
55063           * See [this issue](https://github.com/processing/p5.js/issues/1545) for more information.
55064           *
55065           * The system variables width and height are set by the parameters passed to this
55066           * function. If <a href="#/p5/createCanvas">createCanvas()</a> is not used, the
55067           * window will be given a default size of 100x100 pixels.
55068           *
55069           * For more ways to position the canvas, see the
55070           * <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>
55071           * positioning the canvas</a> wiki page.
55072           *
55073           * @method createCanvas
55074           * @param  {Number} w width of the canvas
55075           * @param  {Number} h height of the canvas
55076           * @param  {Constant} [renderer] either P2D or WEBGL
55077           * @return {p5.Renderer}
55078           * @example
55079           * <div>
55080           * <code>
55081           * function setup() {
55082           *   createCanvas(100, 50);
55083           *   background(153);
55084           *   line(0, 0, width, height);
55085           * }
55086           * </code>
55087           * </div>
55088           *
55089           * @alt
55090           * Black line extending from top-left of canvas to bottom right.
55091           */
55092          _main.default.prototype.createCanvas = function(w, h, renderer) {
55093            _main.default._validateParameters('createCanvas', arguments);
55094            //optional: renderer, otherwise defaults to p2d
55095            var r = renderer || constants.P2D;
55096            var c;
55097
55098            if (r === constants.WEBGL) {
55099              c = document.getElementById(defaultId);
55100              if (c) {
55101                //if defaultCanvas already exists
55102                c.parentNode.removeChild(c); //replace the existing defaultCanvas
55103                var thisRenderer = this._renderer;
55104                this._elements = this._elements.filter(function(e) {
55105                  return e !== thisRenderer;
55106                });
55107              }
55108              c = document.createElement('canvas');
55109              c.id = defaultId;
55110              c.classList.add(defaultClass);
55111            } else {
55112              if (!this._defaultGraphicsCreated) {
55113                c = document.createElement('canvas');
55114                var i = 0;
55115                while (document.getElementById('defaultCanvas'.concat(i))) {
55116                  i++;
55117                }
55118                defaultId = 'defaultCanvas'.concat(i);
55119                c.id = defaultId;
55120                c.classList.add(defaultClass);
55121              } else {
55122                // resize the default canvas if new one is created
55123                c = this.canvas;
55124              }
55125            }
55126
55127            // set to invisible if still in setup (to prevent flashing with manipulate)
55128            if (!this._setupDone) {
55129              c.dataset.hidden = true; // tag to show later
55130              c.style.visibility = 'hidden';
55131            }
55132
55133            if (this._userNode) {
55134              // user input node case
55135              this._userNode.appendChild(c);
55136            } else {
55137              //create main element
55138              if (document.getElementsByTagName('main').length === 0) {
55139                var m = document.createElement('main');
55140                document.body.appendChild(m);
55141              }
55142              //append canvas to main
55143              document.getElementsByTagName('main')[0].appendChild(c);
55144            }
55145
55146            // Init our graphics renderer
55147            //webgl mode
55148            if (r === constants.WEBGL) {
55149              this._setProperty('_renderer', new _main.default.RendererGL(c, this, true));
55150              this._elements.push(this._renderer);
55151            } else {
55152              //P2D mode
55153              if (!this._defaultGraphicsCreated) {
55154                this._setProperty('_renderer', new _main.default.Renderer2D(c, this, true));
55155                this._defaultGraphicsCreated = true;
55156                this._elements.push(this._renderer);
55157              }
55158            }
55159            this._renderer.resize(w, h);
55160            this._renderer._applyDefaults();
55161            return this._renderer;
55162          };
55163
55164          /**
55165           * Resizes the canvas to given width and height. The canvas will be cleared
55166           * and draw will be called immediately, allowing the sketch to re-render itself
55167           * in the resized canvas.
55168           * @method resizeCanvas
55169           * @param  {Number} w width of the canvas
55170           * @param  {Number} h height of the canvas
55171           * @param  {Boolean} [noRedraw] don't redraw the canvas immediately
55172           * @example
55173           * <div class="norender"><code>
55174           * function setup() {
55175           *   createCanvas(windowWidth, windowHeight);
55176           * }
55177           *
55178           * function draw() {
55179           *   background(0, 100, 200);
55180           * }
55181           *
55182           * function windowResized() {
55183           *   resizeCanvas(windowWidth, windowHeight);
55184           * }
55185           * </code></div>
55186           *
55187           * @alt
55188           * No image displayed.
55189           */
55190          _main.default.prototype.resizeCanvas = function(w, h, noRedraw) {
55191            _main.default._validateParameters('resizeCanvas', arguments);
55192            if (this._renderer) {
55193              // save canvas properties
55194              var props = {};
55195              for (var key in this.drawingContext) {
55196                var val = this.drawingContext[key];
55197                if (_typeof(val) !== 'object' && typeof val !== 'function') {
55198                  props[key] = val;
55199                }
55200              }
55201              this._renderer.resize(w, h);
55202              this.width = w;
55203              this.height = h;
55204              // reset canvas properties
55205              for (var savedKey in props) {
55206                try {
55207                  this.drawingContext[savedKey] = props[savedKey];
55208                } catch (err) {
55209                  // ignore read-only property errors
55210                }
55211              }
55212              if (!noRedraw) {
55213                this.redraw();
55214              }
55215            }
55216            //accessible Outputs
55217            if (this._addAccsOutput()) {
55218              this._updateAccsOutput();
55219            }
55220          };
55221
55222          /**
55223           * Removes the default canvas for a p5 sketch that doesn't require a canvas
55224           * @method noCanvas
55225           * @example
55226           * <div>
55227           * <code>
55228           * function setup() {
55229           *   noCanvas();
55230           * }
55231           * </code>
55232           * </div>
55233           *
55234           * @alt
55235           * no image displayed
55236           */
55237          _main.default.prototype.noCanvas = function() {
55238            if (this.canvas) {
55239              this.canvas.parentNode.removeChild(this.canvas);
55240            }
55241          };
55242
55243          /**
55244           * Creates and returns a new p5.Renderer object. Use this class if you need
55245           * to draw into an off-screen graphics buffer. The two parameters define the
55246           * width and height in pixels.
55247           *
55248           * @method createGraphics
55249           * @param  {Number} w width of the offscreen graphics buffer
55250           * @param  {Number} h height of the offscreen graphics buffer
55251           * @param  {Constant} [renderer] either P2D or WEBGL
55252           *                               undefined defaults to p2d
55253           * @return {p5.Graphics} offscreen graphics buffer
55254           * @example
55255           * <div>
55256           * <code>
55257           * let pg;
55258           * function setup() {
55259           *   createCanvas(100, 100);
55260           *   pg = createGraphics(100, 100);
55261           * }
55262           *
55263           * function draw() {
55264           *   background(200);
55265           *   pg.background(100);
55266           *   pg.noStroke();
55267           *   pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);
55268           *   image(pg, 50, 50);
55269           *   image(pg, 0, 0, 50, 50);
55270           * }
55271           * </code>
55272           * </div>
55273           *
55274           * @alt
55275           * 4 grey squares alternating light and dark grey. White quarter circle mid-left.
55276           */
55277          _main.default.prototype.createGraphics = function(w, h, renderer) {
55278            _main.default._validateParameters('createGraphics', arguments);
55279            return new _main.default.Graphics(w, h, renderer, this);
55280          };
55281
55282          /**
55283           * Blends the pixels in the display window according to the defined mode.
55284           * There is a choice of the following modes to blend the source pixels (A)
55285           * with the ones of pixels already in the display window (B):
55286           * <ul>
55287           * <li><code>BLEND</code> - linear interpolation of colours: C =
55288           * A\*factor + B. <b>This is the default blending mode.</b></li>
55289           * <li><code>ADD</code> - sum of A and B</li>
55290           * <li><code>DARKEST</code> - only the darkest colour succeeds: C =
55291           * min(A\*factor, B).</li>
55292           * <li><code>LIGHTEST</code> - only the lightest colour succeeds: C =
55293           * max(A\*factor, B).</li>
55294           * <li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>
55295           * <li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less
55296           * extreme.</li>
55297           * <li><code>MULTIPLY</code> - multiply the colors, result will always be
55298           * darker.</li>
55299           * <li><code>SCREEN</code> - opposite multiply, uses inverse values of the
55300           * colors.</li>
55301           * <li><code>REPLACE</code> - the pixels entirely replace the others and
55302           * don't utilize alpha (transparency) values.</li>
55303           * <li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>
55304           * <li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN
55305           * </code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>
55306           * <li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%
55307           * gray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>
55308           * <li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and
55309           * <code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>
55310           * </li>
55311           * <li><code>DODGE</code> - lightens light tones and increases contrast,
55312           * ignores darks. <em>(2D)</em></li>
55313           * <li><code>BURN</code> - darker areas are applied, increasing contrast,
55314           * ignores lights. <em>(2D)</em></li>
55315           * <li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>
55316           * </ul>
55317           *
55318           * <em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>
55319           * <em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.
55320           *
55321           * @method blendMode
55322           * @param  {Constant} mode blend mode to set for canvas.
55323           *                either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,
55324           *                EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,
55325           *                SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT
55326           * @example
55327           * <div>
55328           * <code>
55329           * blendMode(LIGHTEST);
55330           * strokeWeight(30);
55331           * stroke(80, 150, 255);
55332           * line(25, 25, 75, 75);
55333           * stroke(255, 50, 50);
55334           * line(75, 25, 25, 75);
55335           * </code>
55336           * </div>
55337           *
55338           * <div>
55339           * <code>
55340           * blendMode(MULTIPLY);
55341           * strokeWeight(30);
55342           * stroke(80, 150, 255);
55343           * line(25, 25, 75, 75);
55344           * stroke(255, 50, 50);
55345           * line(75, 25, 25, 75);
55346           * </code>
55347           * </div>
55348           *
55349           * @alt
55350           * translucent image thick red & blue diagonal rounded lines intersecting center
55351           * Thick red & blue diagonal rounded lines intersecting center. dark at overlap
55352           */
55353          _main.default.prototype.blendMode = function(mode) {
55354            _main.default._validateParameters('blendMode', arguments);
55355            if (mode === constants.NORMAL) {
55356              // Warning added 3/26/19, can be deleted in future (1.0 release?)
55357              console.warn(
55358                'NORMAL has been deprecated for use in blendMode. defaulting to BLEND instead.'
55359              );
55360
55361              mode = constants.BLEND;
55362            }
55363            this._renderer.blendMode(mode);
55364          };
55365
55366          /**
55367           * The p5.js API provides a lot of functionality for creating graphics, but there is
55368           * some native HTML5 Canvas functionality that is not exposed by p5. You can still call
55369           * it directly using the variable `drawingContext`, as in the example shown. This is
55370           * the equivalent of calling `canvas.getContext('2d');` or `canvas.getContext('webgl');`.
55371           * See this
55372           * <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">
55373           * reference for the native canvas API</a> for possible drawing functions you can call.
55374           *
55375           * @property drawingContext
55376           * @example
55377           * <div>
55378           * <code>
55379           * function setup() {
55380           *   drawingContext.shadowOffsetX = 5;
55381           *   drawingContext.shadowOffsetY = -5;
55382           *   drawingContext.shadowBlur = 10;
55383           *   drawingContext.shadowColor = 'black';
55384           *   background(200);
55385           *   ellipse(width / 2, height / 2, 50, 50);
55386           * }
55387           * </code>
55388           * </div>
55389           *
55390           * @alt
55391           * white ellipse with shadow blur effect around edges
55392           */ var _default = _main.default;
55393          exports.default = _default;
55394        },
55395        {
55396          '../webgl/p5.RendererGL': 113,
55397          './constants': 48,
55398          './main': 59,
55399          './p5.Graphics': 61,
55400          './p5.Renderer2D': 63
55401        }
55402      ],
55403      66: [
55404        function(_dereq_, module, exports) {
55405          'use strict';
55406          function _typeof(obj) {
55407            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
55408              _typeof = function _typeof(obj) {
55409                return typeof obj;
55410              };
55411            } else {
55412              _typeof = function _typeof(obj) {
55413                return obj &&
55414                  typeof Symbol === 'function' &&
55415                  obj.constructor === Symbol &&
55416                  obj !== Symbol.prototype
55417                  ? 'symbol'
55418                  : typeof obj;
55419              };
55420            }
55421            return _typeof(obj);
55422          }
55423          Object.defineProperty(exports, '__esModule', { value: true });
55424          exports.default = void 0;
55425
55426          var _main = _interopRequireDefault(_dereq_('../main'));
55427          var constants = _interopRequireWildcard(_dereq_('../constants'));
55428          var _helpers = _interopRequireDefault(_dereq_('../helpers'));
55429          _dereq_('../friendly_errors/fes_core');
55430          _dereq_('../friendly_errors/file_errors');
55431          _dereq_('../friendly_errors/validate_params');
55432          function _getRequireWildcardCache() {
55433            if (typeof WeakMap !== 'function') return null;
55434            var cache = new WeakMap();
55435            _getRequireWildcardCache = function _getRequireWildcardCache() {
55436              return cache;
55437            };
55438            return cache;
55439          }
55440          function _interopRequireWildcard(obj) {
55441            if (obj && obj.__esModule) {
55442              return obj;
55443            }
55444            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
55445              return { default: obj };
55446            }
55447            var cache = _getRequireWildcardCache();
55448            if (cache && cache.has(obj)) {
55449              return cache.get(obj);
55450            }
55451            var newObj = {};
55452            var hasPropertyDescriptor =
55453              Object.defineProperty && Object.getOwnPropertyDescriptor;
55454            for (var key in obj) {
55455              if (Object.prototype.hasOwnProperty.call(obj, key)) {
55456                var desc = hasPropertyDescriptor
55457                  ? Object.getOwnPropertyDescriptor(obj, key)
55458                  : null;
55459                if (desc && (desc.get || desc.set)) {
55460                  Object.defineProperty(newObj, key, desc);
55461                } else {
55462                  newObj[key] = obj[key];
55463                }
55464              }
55465            }
55466            newObj.default = obj;
55467            if (cache) {
55468              cache.set(obj, newObj);
55469            }
55470            return newObj;
55471          }
55472          function _interopRequireDefault(obj) {
55473            return obj && obj.__esModule ? obj : { default: obj };
55474          }
55475          /**
55476           * @module Shape
55477           * @submodule 2D Primitives
55478           * @for p5
55479           * @requires core
55480           * @requires constants
55481           */ /**
55482           * This function does 3 things:
55483           *
55484           *   1. Bounds the desired start/stop angles for an arc (in radians) so that:
55485           *
55486           *          0 <= start < TWO_PI ;    start <= stop < start + TWO_PI
55487           *
55488           *      This means that the arc rendering functions don't have to be concerned
55489           *      with what happens if stop is smaller than start, or if the arc 'goes
55490           *      round more than once', etc.: they can just start at start and increase
55491           *      until stop and the correct arc will be drawn.
55492           *
55493           *   2. Optionally adjusts the angles within each quadrant to counter the naive
55494           *      scaling of the underlying ellipse up from the unit circle.  Without
55495           *      this, the angles become arbitrary when width != height: 45 degrees
55496           *      might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on
55497           *      a 'tall' ellipse.
55498           *
55499           *   3. Flags up when start and stop correspond to the same place on the
55500           *      underlying ellipse.  This is useful if you want to do something special
55501           *      there (like rendering a whole ellipse instead).
55502           */ _main.default.prototype._normalizeArcAngles = function(
55503            start,
55504            stop,
55505            width,
55506            height,
55507            correctForScaling
55508          ) {
55509            var epsilon = 0.00001; // Smallest visible angle on displays up to 4K.
55510            var separation;
55511
55512            // The order of the steps is important here: each one builds upon the
55513            // adjustments made in the steps that precede it.
55514
55515            // Constrain both start and stop to [0,TWO_PI).
55516            start = start - constants.TWO_PI * Math.floor(start / constants.TWO_PI);
55517            stop = stop - constants.TWO_PI * Math.floor(stop / constants.TWO_PI);
55518
55519            // Get the angular separation between the requested start and stop points.
55520            //
55521            // Technically this separation only matches what gets drawn if
55522            // correctForScaling is enabled.  We could add a more complicated calculation
55523            // for when the scaling is uncorrected (in which case the drawn points could
55524            // end up pushed together or pulled apart quite dramatically relative to what
55525            // was requested), but it would make things more opaque for little practical
55526            // benefit.
55527            //
55528            // (If you do disable correctForScaling and find that correspondToSamePoint
55529            // is set too aggressively, the easiest thing to do is probably to just make
55530            // epsilon smaller...)
55531            separation = Math.min(
55532              Math.abs(start - stop),
55533              constants.TWO_PI - Math.abs(start - stop)
55534            );
55535
55536            // Optionally adjust the angles to counter linear scaling.
55537            if (correctForScaling) {
55538              if (start <= constants.HALF_PI) {
55539                start = Math.atan(width / height * Math.tan(start));
55540              } else if (start > constants.HALF_PI && start <= 3 * constants.HALF_PI) {
55541                start = Math.atan(width / height * Math.tan(start)) + constants.PI;
55542              } else {
55543                start = Math.atan(width / height * Math.tan(start)) + constants.TWO_PI;
55544              }
55545              if (stop <= constants.HALF_PI) {
55546                stop = Math.atan(width / height * Math.tan(stop));
55547              } else if (stop > constants.HALF_PI && stop <= 3 * constants.HALF_PI) {
55548                stop = Math.atan(width / height * Math.tan(stop)) + constants.PI;
55549              } else {
55550                stop = Math.atan(width / height * Math.tan(stop)) + constants.TWO_PI;
55551              }
55552            }
55553
55554            // Ensure that start <= stop < start + TWO_PI.
55555            if (start > stop) {
55556              stop += constants.TWO_PI;
55557            }
55558
55559            return {
55560              start: start,
55561              stop: stop,
55562              correspondToSamePoint: separation < epsilon
55563            };
55564          };
55565
55566          /**
55567           * Draw an arc to the screen. If called with only x, y, w, h, start and stop,
55568           * the arc will be drawn and filled as an open pie segment. If a mode parameter
55569           * is provided, the arc will be filled like an open semi-circle (OPEN), a closed
55570           * semi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed
55571           * with the <a href="#/p5/ellipseMode">ellipseMode()</a> function.
55572           *
55573           * The arc is always drawn clockwise from wherever start falls to wherever stop
55574           * falls on the ellipse.Adding or subtracting TWO_PI to either angle does not
55575           * change where they fall. If both start and stop fall at the same place, a full
55576           * ellipse will be drawn. Be aware that the y-axis increases in the downward
55577           * direction, therefore angles are measured clockwise from the positive
55578           * x-direction ("3 o'clock").
55579           *
55580           * @method arc
55581           * @param  {Number} x      x-coordinate of the arc's ellipse
55582           * @param  {Number} y      y-coordinate of the arc's ellipse
55583           * @param  {Number} w      width of the arc's ellipse by default
55584           * @param  {Number} h      height of the arc's ellipse by default
55585           * @param  {Number} start  angle to start the arc, specified in radians
55586           * @param  {Number} stop   angle to stop the arc, specified in radians
55587           * @param  {Constant} [mode] optional parameter to determine the way of drawing
55588           *                         the arc. either CHORD, PIE or OPEN
55589           * @param  {Number} [detail] optional parameter for WebGL mode only. This is to
55590           *                         specify the number of vertices that makes up the
55591           *                         perimeter of the arc. Default value is 25.
55592           * @chainable
55593           *
55594           * @example
55595           * <div>
55596           * <code>
55597           * arc(50, 55, 50, 50, 0, HALF_PI);
55598           * noFill();
55599           * arc(50, 55, 60, 60, HALF_PI, PI);
55600           * arc(50, 55, 70, 70, PI, PI + QUARTER_PI);
55601           * arc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);
55602           * </code>
55603           * </div>
55604           *
55605           * <div>
55606           * <code>
55607           * arc(50, 50, 80, 80, 0, PI + QUARTER_PI);
55608           * </code>
55609           * </div>
55610           *
55611           * <div>
55612           * <code>
55613           * arc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);
55614           * </code>
55615           * </div>
55616           *
55617           * <div>
55618           * <code>
55619           * arc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);
55620           * </code>
55621           * </div>
55622           *
55623           * <div>
55624           * <code>
55625           * arc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);
55626           * </code>
55627           * </div>
55628           *
55629           * @alt
55630           *shattered outline of an ellipse with a quarter of a white circle bottom-right.
55631           *white ellipse with top right quarter missing.
55632           *white ellipse with black outline with top right missing.
55633           *white ellipse with top right missing with black outline around shape.
55634           *white ellipse with top right quarter missing with black outline around the shape.
55635           */
55636          _main.default.prototype.arc = function(x, y, w, h, start, stop, mode, detail) {
55637            _main.default._validateParameters('arc', arguments);
55638
55639            // if the current stroke and fill settings wouldn't result in something
55640            // visible, exit immediately
55641            if (!this._renderer._doStroke && !this._renderer._doFill) {
55642              return this;
55643            }
55644
55645            if (start === stop) {
55646              return this;
55647            }
55648
55649            start = this._toRadians(start);
55650            stop = this._toRadians(stop);
55651
55652            // p5 supports negative width and heights for ellipses
55653            w = Math.abs(w);
55654            h = Math.abs(h);
55655
55656            var vals = _helpers.default.modeAdjust(x, y, w, h, this._renderer._ellipseMode);
55657            var angles = this._normalizeArcAngles(start, stop, vals.w, vals.h, true);
55658
55659            if (angles.correspondToSamePoint) {
55660              // If the arc starts and ends at (near enough) the same place, we choose to
55661              // draw an ellipse instead.  This is preferable to faking an ellipse (by
55662              // making stop ever-so-slightly less than start + TWO_PI) because the ends
55663              // join up to each other rather than at a vertex at the centre (leaving
55664              // an unwanted spike in the stroke/fill).
55665              this._renderer.ellipse([vals.x, vals.y, vals.w, vals.h, detail]);
55666            } else {
55667              this._renderer.arc(
55668                vals.x,
55669                vals.y,
55670                vals.w,
55671                vals.h,
55672                angles.start, // [0, TWO_PI)
55673                angles.stop, // [start, start + TWO_PI)
55674                mode,
55675                detail
55676              );
55677
55678              //accessible Outputs
55679              if (this._accessibleOutputs.grid || this._accessibleOutputs.text) {
55680                this._accsOutput('arc', [
55681                  vals.x,
55682                  vals.y,
55683                  vals.w,
55684                  vals.h,
55685                  angles.start,
55686                  angles.stop,
55687                  mode
55688                ]);
55689              }
55690            }
55691
55692            return this;
55693          };
55694
55695          /**
55696           * Draws an ellipse (oval) to the screen. By default, the first two parameters
55697           * set the location of the center of the ellipse, and the third and fourth
55698           * parameters set the shape's width and height. If no height is specified, the
55699           * value of width is used for both the width and height. If a negative height or
55700           * width is specified, the absolute value is taken.
55701           *
55702           * An ellipse with equal width and height is a circle.The origin may be changed
55703           * with the <a href="#/p5/ellipseMode">ellipseMode()</a> function.
55704           *
55705           * @method ellipse
55706           * @param  {Number} x x-coordinate of the center of ellipse.
55707           * @param  {Number} y y-coordinate of the center of ellipse.
55708           * @param  {Number} w width of the ellipse.
55709           * @param  {Number} [h] height of the ellipse.
55710           * @chainable
55711           * @example
55712           * <div>
55713           * <code>
55714           * ellipse(56, 46, 55, 55);
55715           * </code>
55716           * </div>
55717           *
55718           * @alt
55719           *white ellipse with black outline in middle-right of canvas that is 55x55
55720           */
55721
55722          /**
55723           * @method ellipse
55724           * @param  {Number} x
55725           * @param  {Number} y
55726           * @param  {Number} w
55727           * @param  {Number} h
55728           * @param  {Integer} detail number of radial sectors to draw (for WebGL mode)
55729           */
55730          _main.default.prototype.ellipse = function(x, y, w, h, detailX) {
55731            _main.default._validateParameters('ellipse', arguments);
55732            return this._renderEllipse.apply(this, arguments);
55733          };
55734
55735          /**
55736           * Draws a circle to the screen. A circle is a simple closed shape. It is the set
55737           * of all points in a plane that are at a given distance from a given point,
55738           * the centre. This function is a special case of the ellipse() function, where
55739           * the width and height of the ellipse are the same. Height and width of the
55740           * ellipse correspond to the diameter of the circle. By default, the first two
55741           * parameters set the location of the centre of the circle, the third sets the
55742           * diameter of the circle.
55743           *
55744           * @method circle
55745           * @param  {Number} x  x-coordinate of the centre of the circle.
55746           * @param  {Number} y  y-coordinate of the centre of the circle.
55747           * @param  {Number} d  diameter of the circle.
55748           * @chainable
55749           * @example
55750           * <div>
55751           * <code>
55752           * // Draw a circle at location (30, 30) with a diameter of 20.
55753           * circle(30, 30, 20);
55754           * </code>
55755           * </div>
55756           *
55757           * @alt
55758           * white circle with black outline in mid of canvas that is 55x55.
55759           */
55760          _main.default.prototype.circle = function() {
55761            _main.default._validateParameters('circle', arguments);
55762            var args = Array.prototype.slice.call(arguments, 0, 2);
55763            args.push(arguments[2]);
55764            args.push(arguments[2]);
55765            return this._renderEllipse.apply(this, args);
55766          };
55767
55768          // internal method for drawing ellipses (without parameter validation)
55769          _main.default.prototype._renderEllipse = function(x, y, w, h, detailX) {
55770            // if the current stroke and fill settings wouldn't result in something
55771            // visible, exit immediately
55772            if (!this._renderer._doStroke && !this._renderer._doFill) {
55773              return this;
55774            }
55775
55776            // p5 supports negative width and heights for rects
55777            if (w < 0) {
55778              w = Math.abs(w);
55779            }
55780
55781            if (typeof h === 'undefined') {
55782              // Duplicate 3rd argument if only 3 given.
55783              h = w;
55784            } else if (h < 0) {
55785              h 
55785= Math.abs(h);
55786            }
55787
55788            var vals = _helpers.default.modeAdjust(x, y, w, h, this._renderer._ellipseMode);
55789            this._renderer.ellipse([vals.x, vals.y, vals.w, vals.h, detailX]);
55790
55791            //accessible Outputs
55792            if (this._accessibleOutputs.grid || this._accessibleOutputs.text) {
55793              this._accsOutput('ellipse', [vals.x, vals.y, vals.w, vals.h]);
55794            }
55795
55796            return this;
55797          };
55798
55799          /**
55800           * Draws a line (a direct path between two points) to the screen. If called with
55801           * only 4 parameters, it will draw a line in 2D with a default width of 1 pixel.
55802           * This width can be modified by using the <a href="#/p5/strokeWeight">
55803           * strokeWeight()</a> function. A line cannot be filled, therefore the <a
55804           * href="#/p5/fill">fill()</a> function will not affect the color of a line. So to
55805           * color a line, use the <a href="#/p5/stroke">stroke()</a> function.
55806           *
55807           * @method line
55808           * @param  {Number} x1 the x-coordinate of the first point
55809           * @param  {Number} y1 the y-coordinate of the first point
55810           * @param  {Number} x2 the x-coordinate of the second point
55811           * @param  {Number} y2 the y-coordinate of the second point
55812           * @chainable
55813           * @example
55814           * <div>
55815           * <code>
55816           * line(30, 20, 85, 75);
55817           * </code>
55818           * </div>
55819           *
55820           * <div>
55821           * <code>
55822           * line(30, 20, 85, 20);
55823           * stroke(126);
55824           * line(85, 20, 85, 75);
55825           * stroke(255);
55826           * line(85, 75, 30, 75);
55827           * </code>
55828           * </div>
55829           *
55830           * @alt
55831           * An example showing a line 78 pixels long running from mid-top to bottom-right of canvas.
55832           * An example showing 3 lines of various stroke sizes. Form top, bottom and right sides of a square.
55833           */
55834
55835          /**
55836           * @method line
55837           * @param  {Number} x1
55838           * @param  {Number} y1
55839           * @param  {Number} z1 the z-coordinate of the first point
55840           * @param  {Number} x2
55841           * @param  {Number} y2
55842           * @param  {Number} z2 the z-coordinate of the second point
55843           * @chainable
55844           */
55845          _main.default.prototype.line = function() {
55846            for (
55847              var _len = arguments.length, args = new Array(_len), _key = 0;
55848              _key < _len;
55849              _key++
55850            ) {
55851              args[_key] = arguments[_key];
55852            }
55853            _main.default._validateParameters('line', args);
55854
55855            if (this._renderer._doStroke) {
55856              var _this$_renderer;
55857              (_this$_renderer = this._renderer).line.apply(_this$_renderer, args);
55858            }
55859
55860            //accessible Outputs
55861            if (this._accessibleOutputs.grid || this._accessibleOutputs.text) {
55862              this._accsOutput('line', args);
55863            }
55864
55865            return this;
55866          };
55867
55868          /**
55869           * Draws a point, a coordinate in space at the dimension of one pixel.
55870           * The first parameter is the horizontal value for the point, the second
55871           * param is the vertical value for the point. The color of the point is
55872           * changed with the <a href="#/p5/stroke">stroke()</a> function. The size of the point
55873           * can be changed with the <a href="#/p5/strokeWeight">
55873strokeWeight()</a> function.
55874           *
55875           * @method point
55876           * @param  {Number} x the x-coordinate
55877           * @param  {Number} y the y-coordinate
55878           * @param  {Number} [z] the z-coordinate (for WebGL mode)
55879           * @chainable
55880           * @example
55881           * <div>
55882           * <code>
55883           * point(30, 20);
55884           * point(85, 20);
55885           * point(85, 75);
55886           * point(30, 75);
55887           * </code>
55888           * </div>
55889           *
55890           * <div>
55891           * <code>
55892           * point(30, 20);
55893           * point(85, 20);
55894           * stroke('purple'); // Change the color
55895           * strokeWeight(10); // Make the points 10 pixels in size
55896           * point(85, 75);
55897           * point(30, 75);
55898           * </code>
55899           * </div>
55900           *
55901           * <div>
55902           * <code>
55903           * let a = createVector(10, 10);
55904           * point(a);
55905           * let b = createVector(10, 20);
55906           * point(b);
55907           * point(createVector(20, 10));
55908           * point(createVector(20, 20));
55909           * </code>
55910           * </div>
55911           *
55912           * @alt
55913           * 4 points centered in the middle-right of the canvas.
55914           * 2 large points and 2 large purple points centered in the middle-right of the canvas.
55915           * Vertices of a square of length 10 pixels towards the top-left of the canvas.
55916           */
55917
55918          /**
55919           * @method point
55920           * @param {p5.Vector} coordinate_vector the coordinate vector
55921           * @chainable
55922           */
55923          _main.default.prototype.point = function() {
55924            for (
55925              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
55926              _key2 < _len2;
55927              _key2++
55928            ) {
55929              args[_key2] = arguments[_key2];
55930            }
55931            _main.default._validateParameters('point', args);
55932
55933            if (this._renderer._doStroke) {
55934              if (args.length === 1 && args[0] instanceof _main.default.Vector) {
55935                this._renderer.point.call(this._renderer, args[0].x, args[0].y, args[0].z);
55936              } else {
55937                var _this$_renderer2;
55938                (_this$_renderer2 = this._renderer).point.apply(_this$_renderer2, args);
55939                //accessible Outputs
55940                if (this._accessibleOutputs.grid || this._accessibleOutputs.text) {
55941                  this._accsOutput('point', args);
55942                }
55943              }
55944            }
55945
55946            return this;
55947          };
55948
55949          /**
55950           * Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is
55951           * similar to a rectangle, but the angles between its edges are not
55952           * constrained to ninety degrees. The first pair of parameters (x1,y1)
55953           * sets the first vertex and the subsequent pairs should proceed
55954           * clockwise or counter-clockwise around the defined shape.
55955           * z-arguments only work when quad() is used in WEBGL mode.
55956           *
55957           * @method quad
55958           * @param {Number} x1 the x-coordinate of the first point
55959           * @param {Number} y1 the y-coordinate of the first point
55960           * @param {Number} x2 the x-coordinate of the second point
55961           * @param {Number} y2 the y-coordinate of the second point
55962           * @param {Number} x3 the x-coordinate of the third point
55963           * @param {Number} y3 the y-coordinate of the third point
55964           * @param {Number} x4 the x-coordinate of the fourth point
55965           * @param {Number} y4 the y-coordinate of the fourth point
55966           * @chainable
55967           * @example
55968           * <div>
55969           * <code>
55970           * quad(38, 31, 86, 20, 69, 63, 30, 76);
55971           * </code>
55972           * </div>
55973           *
55974           * @alt
55975           *irregular white quadrilateral shape with black outline mid-right of canvas.
55976           */
55977          /**
55978           * @method quad
55979           * @param {Number} x1
55980           * @param {Number} y1
55981           * @param {Number} z1 the z-coordinate of the first point
55982           * @param {Number} x2
55983           * @param {Number} y2
55984           * @param {Number} z2 the z-coordinate of the second point
55985           * @param {Number} x3
55986           * @param {Number} y3
55987           * @param {Number} z3 the z-coordinate of the third point
55988           * @param {Number} x4
55989           * @param {Number} y4
55990           * @param {Number} z4 the z-coordinate of the fourth point
55991           * @chainable
55992           */
55993          _main.default.prototype.quad = function() {
55994            for (
55995              var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;
55996              _key3 < _len3;
55997              _key3++
55998            ) {
55999              args[_key3] = arguments[_key3];
56000            }
56001            _main.default._validateParameters('quad', args);
56002
56003            if (this._renderer._doStroke || this._renderer._doFill) {
56004              if (this._renderer.isP3D && args.length !== 12) {
56005                // if 3D and we weren't passed 12 args, assume Z is 0
56006                // prettier-ignore
56007                this._renderer.quad.call(
56008      this._renderer,
56009      args[0], args[1], 0,
56010      args[2], args[3], 0,
56011      args[4], args[5], 0,
56012      args[6], args[7], 0);
56013              } else {
56014                var _this$_renderer3;
56015                (_this$_renderer3 = this._renderer).quad.apply(_this$_renderer3, args);
56016                //accessibile outputs
56017                if (this._accessibleOutputs.grid || this._accessibleOutputs.text) {
56018                  this._accsOutput('quadrilateral', args);
56019                }
56020              }
56021            }
56022
56023            return this;
56024          };
56025
56026          /**
56027           * Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with
56028           * every angle at ninety degrees. By default, the first two parameters set
56029           * the location of the upper-left corner, the third sets the width, and the
56030           * fourth sets the height. The way these parameters are interpreted, may be
56031           * changed with the <a href="#/p5/rectMode">rectMode()</a> function.
56032           *
56033           * The fifth, sixth, seventh and eighth parameters, if specified,
56034           * determine corner radius for the top-left, top-right, lower-right and
56035           * lower-left corners, respectively. An omitted corner radius parameter is set
56036           * to the value of the previously specified radius value in the parameter list.
56037           *
56038           * @method rect
56039           * @param  {Number} x  x-coordinate of the rectangle.
56040           * @param  {Number} y  y-coordinate of the rectangle.
56041           * @param  {Number} w  width of the rectangle.
56042           * @param  {Number} [h]  height of the rectangle.
56043           * @param  {Number} [tl] optional radius of top-left corner.
56044           * @param  {Number} [tr] optional radius of top-right corner.
56045           * @param  {Number} [br] optional radius of bottom-right corner.
56046           * @param  {Number} [bl] optional radius of bottom-left corner.
56047           * @chainable
56048           * @example
56049           * <div>
56050           * <code>
56051           * // Draw a rectangle at location (30, 20) with a width and height of 55.
56052           * rect(30, 20, 55, 55);
56053           * </code>
56054           * </div>
56055           *
56056           * <div>
56057           * <code>
56058           * // Draw a rectangle with rounded corners, each having a radius of 20.
56059           * rect(30, 20, 55, 55, 20);
56060           * </code>
56061           * </div>
56062           *
56063           * <div>
56064           * <code>
56065           * // Draw a rectangle with rounded corners having the following radii:
56066           * // top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.
56067           * rect(30, 20, 55, 55, 20, 15, 10, 5);
56068           * </code>
56069           * </div>
56070           *
56071           * @alt
56072           * 55x55 white rect with black outline in mid-right of canvas.
56073           * 55x55 white rect with black outline and rounded edges in mid-right of canvas.
56074           * 55x55 white rect with black outline and rounded edges of different radii.
56075           */
56076
56077          /**
56078           * @method rect
56079           * @param  {Number} x
56080           * @param  {Number} y
56081           * @param  {Number} w
56082           * @param  {Number} h
56083           * @param  {Integer} [detailX] number of segments in the x-direction (for WebGL mode)
56084           * @param  {Integer} [detailY] number of segments in the y-direction (for WebGL mode)
56085           * @chainable
56086           */
56087          _main.default.prototype.rect = function() {
56088            _main.default._validateParameters('rect', arguments);
56089            return this._renderRect.apply(this, arguments);
56090          };
56091
56092          /**
56093           * Draws a square to the screen. A square is a four-sided shape with every angle
56094           * at ninety degrees, and equal side size. This function is a special case of the
56095           * rect() function, where the width and height are the same, and the parameter
56096           * is called "s" for side size. By default, the first two parameters set the
56097           * location of the upper-left corner, the third sets the side size of the square.
56098           * The way these parameters are interpreted, may be changed with the <a
56099           * href="#/p5/rectMode">rectMode()</a> function.
56100           *
56101           * The fourth, fifth, sixth and seventh parameters, if specified,
56102           * determine corner radius for the top-left, top-right, lower-right and
56103           * lower-left corners, respectively. An omitted corner radius parameter is set
56104           * to the value of the previously specified radius value in the parameter list.
56105           *
56106           * @method square
56107           * @param  {Number} x  x-coordinate of the square.
56108           * @param  {Number} y  y-coordinate of the square.
56109           * @param  {Number} s  side size of the square.
56110           * @param  {Number} [tl] optional radius of top-left corner.
56111           * @param  {Number} [tr] optional radius of top-right corner.
56112           * @param  {Number} [br] optional radius of bottom-right corner.
56113           * @param  {Number} [bl] optional radius of bottom-left corner.
56114           * @chainable
56115           * @example
56116           * <div>
56117           * <code>
56118           * // Draw a square at location (30, 20) with a side size of 55.
56119           * square(30, 20, 55);
56120           * </code>
56121           * </div>
56122           *
56123           * <div>
56124           * <code>
56125           * // Draw a square with rounded corners, each having a radius of 20.
56126           * square(30, 20, 55, 20);
56127           * </code>
56128           * </div>
56129           *
56130           * <div>
56131           * <code>
56132           * // Draw a square with rounded corners having the following radii:
56133           * // top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.
56134           * square(30, 20, 55, 20, 15, 10, 5);
56135           * </code>
56136           * </div>
56137           *
56138           * @alt
56139           * 55x55 white square with black outline in mid-right of canvas.
56140           * 55x55 white square with black outline and rounded edges in mid-right of canvas.
56141           * 55x55 white square with black outline and rounded edges of different radii.
56142           */
56143          _main.default.prototype.square = function(x, y, s, tl, tr, br, bl) {
56144            _main.default._validateParameters('square', arguments);
56145            // duplicate width for height in case of square
56146            return this._renderRect.call(this, x, y, s, s, tl, tr, br, bl);
56147          };
56148
56149          // internal method to have renderer draw a rectangle
56150          _main.default.prototype._renderRect = function() {
56151            if (this._renderer._doStroke || this._renderer._doFill) {
56152              // duplicate width for height in case only 3 arguments is provided
56153              if (arguments.length === 3) {
56154                arguments[3] = arguments[2];
56155              }
56156              var vals = _helpers.default.modeAdjust(
56157                arguments[0],
56158                arguments[1],
56159                arguments[2],
56160                arguments[3],
56161                this._renderer._rectMode
56162              );
56163
56164              var args = [vals.x, vals.y, vals.w, vals.h];
56165              // append the additional arguments (either cornder radii, or
56166              // segment details) to the argument list
56167              for (var i = 4; i < arguments.length; i++) {
56168                args[i] = arguments[i];
56169              }
56170              this._renderer.rect(args);
56171
56172              //accessible outputs
56173              if (this._accessibleOutputs.grid || this._accessibleOutputs.text) {
56174                this._accsOutput('rectangle', [vals.x, vals.y, vals.w, vals.h]);
56175              }
56176            }
56177
56178            return this;
56179          };
56180
56181          /**
56182           * Draws a triangle to the canvas. A triangle is a plane created by connecting
56183           * three points. The first two arguments specify the first point, the middle two
56184           * arguments specify the second point, and the last two arguments specify the
56185           * third point.
56186           *
56187           * @method triangle
56188           * @param  {Number} x1 x-coordinate of the first point
56189           * @param  {Number} y1 y-coordinate of the first point
56190           * @param  {Number} x2 x-coordinate of the second point
56191           * @param  {Number} y2 y-coordinate of the second point
56192           * @param  {Number} x3 x-coordinate of the third point
56193           * @param  {Number} y3 y-coordinate of the third point
56194           * @chainable
56195           * @example
56196           * <div>
56197           * <code>
56198           * triangle(30, 75, 58, 20, 86, 75);
56199           * </code>
56200           * </div>
56201           *
56202           *@alt
56203           * white triangle with black outline in mid-right of canvas.
56204           */
56205          _main.default.prototype.triangle = function() {
56206            for (
56207              var _len4 = arguments.length, args = new Array(_len4), _key4 = 0;
56208              _key4 < _len4;
56209              _key4++
56210            ) {
56211              args[_key4] = arguments[_key4];
56212            }
56213            _main.default._validateParameters('triangle', args);
56214
56215            if (this._renderer._doStroke || this._renderer._doFill) {
56216              this._renderer.triangle(args);
56217            }
56218
56219            //accessible outputs
56220            if (this._accessibleOutputs.grid || this._accessibleOutputs.text) {
56221              this._accsOutput('triangle', args);
56222            }
56223
56224            return this;
56225          };
56226          var _default = _main.default;
56227          exports.default = _default;
56228        },
56229        {
56230          '../constants': 48,
56231          '../friendly_errors/fes_core': 51,
56232          '../friendly_errors/file_errors': 52,
56233          '../friendly_errors/validate_params': 54,
56234          '../helpers': 55,
56235          '../main': 59
56236        }
56237      ],
56238      67: [
56239        function(_dereq_, module, exports) {
56240          'use strict';
56241          function _typeof(obj) {
56242            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
56243              _typeof = function _typeof(obj) {
56244                return typeof obj;
56245              };
56246            } else {
56247              _typeof = function _typeof(obj) {
56248                return obj &&
56249                  typeof Symbol === 'function' &&
56250                  obj.constructor === Symbol &&
56251                  obj !== Symbol.prototype
56252                  ? 'symbol'
56253                  : typeof obj;
56254              };
56255            }
56256            return _typeof(obj);
56257          }
56258          Object.defineProperty(exports, '__esModule', { value: true });
56259          exports.default = void 0;
56260
56261          var _main = _interopRequireDefault(_dereq_('../main'));
56262          var constants = _interopRequireWildcard(_dereq_('../constants'));
56263          function _getRequireWildcardCache() {
56264            if (typeof WeakMap !== 'function') return null;
56265            var cache = new WeakMap();
56266            _getRequireWildcardCache = function _getRequireWildcardCache() {
56267              return cache;
56268            };
56269            return cache;
56270          }
56271          function _interopRequireWildcard(obj) {
56272            if (obj && obj.__esModule) {
56273              return obj;
56274            }
56275            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
56276              return { default: obj };
56277            }
56278            var cache = _getRequireWildcardCache();
56279            if (cache && cache.has(obj)) {
56280              return cache.get(obj);
56281            }
56282            var newObj = {};
56283            var hasPropertyDescriptor =
56284              Object.defineProperty && Object.getOwnPropertyDescriptor;
56285            for (var key in obj) {
56286              if (Object.prototype.hasOwnProperty.call(obj, key)) {
56287                var desc = hasPropertyDescriptor
56288                  ? Object.getOwnPropertyDescriptor(obj, key)
56289                  : null;
56290                if (desc && (desc.get || desc.set)) {
56291                  Object.defineProperty(newObj, key, desc);
56292                } else {
56293                  newObj[key] = obj[key];
56294                }
56295              }
56296            }
56297            newObj.default = obj;
56298            if (cache) {
56299              cache.set(obj, newObj);
56300            }
56301            return newObj;
56302          }
56303          function _interopRequireDefault(obj) {
56304            return obj && obj.__esModule ? obj : { default: obj };
56305          }
56306          /**
56307           * @module Shape
56308           * @submodule Attributes
56309           * @for p5
56310           * @requires core
56311           * @requires constants
56312           */ /**
56313           * Modifies the location from which ellipses are drawn by changing the way in
56314           * which parameters given to <a href="#/p5/ellipse">ellipse()</a>,
56315           * <a href="#/p5/circle">circle()</a> and <a href="#/p5/arc">arc()</a> are interpreted.
56316           *
56317           * The default mode is CENTER, in which the first two parameters are interpreted
56318           * as the shape's center point's x and y coordinates respectively, while the third
56319           * and fourth parameters are its width and height.
56320           *
56321           * ellipseMode(RADIUS) also uses the first two parameters as the shape's center
56322           * point's x and y coordinates, but uses the third and fourth parameters to
56323           * specify half of the shapes's width and height.
56324           *
56325           * ellipseMode(CORNER) interprets the first two parameters as the upper-left
56326           * corner of the shape, while the third and fourth parameters are its width
56327           * and height.
56328           *
56329           * ellipseMode(CORNERS) interprets the first two parameters as the location of
56330           * one corner of the ellipse's bounding box, and the third and fourth parameters
56331           * as the location of the opposite corner.
56332           *
56333           * The parameter to this method must be written in ALL CAPS because they are
56334           * predefined as constants in ALL CAPS and Javascript is a case-sensitive language.
56335           *
56336           * @method ellipseMode
56337           * @param  {Constant} mode either CENTER, RADIUS, CORNER, or CORNERS
56338           * @chainable
56339           * @example
56340           * <div>
56341           * <code>
56342           * // Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses
56343           * ellipseMode(RADIUS);
56344           * fill(255);
56345           * ellipse(50, 50, 30, 30); // Outer white ellipse
56346           * ellipseMode(CENTER);
56347           * fill(100);
56348           * ellipse(50, 50, 30, 30); // Inner gray ellipse
56349           * </code>
56350           * </div>
56351           *
56352           * <div>
56353           * <code>
56354           * // Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses
56355           * ellipseMode(CORNER);
56356           * fill(255);
56357           * ellipse(25, 25, 50, 50); // Outer white ellipse
56358           * ellipseMode(CORNERS);
56359           * fill(100);
56360           * ellipse(25, 25, 50, 50); // Inner gray ellipse
56361           * </code>
56362           * </div>
56363           *
56364           * @alt
56365           * 60x60 white ellipse and 30x30 grey ellipse with black outlines at center.
56366           * 60x60 white ellipse and 30x30 grey ellipse top-right with black outlines.
56367           */ _main.default.prototype.ellipseMode = function(m) {
56368            _main.default._validateParameters('ellipseMode', arguments);
56369            if (
56370              m === constants.CORNER ||
56371              m === constants.CORNERS ||
56372              m === constants.RADIUS ||
56373              m === constants.CENTER
56374            ) {
56375              this._renderer._ellipseMode = m;
56376            }
56377            return this;
56378          };
56379
56380          /**
56381           * Draws all geometry with jagged (aliased) edges. Note that <a href="#/p5/smooth">smooth()</a> is
56382           * active by default in 2D mode, so it is necessary to call <a href="#/p5/noSmooth">noSmooth()</a> to disable
56383           * smoothing of geometry, images, and fonts. In 3D mode, <a href="#/p5/noSmooth">noSmooth()</a> is enabled
56384           * by default, so it is necessary to call <a href="#/p5/smooth">smooth()</a> if you would like
56385           * smooth (antialiased) edges on your geometry.
56386           *
56387           * @method noSmooth
56388           * @chainable
56389           * @example
56390           * <div>
56391           * <code>
56392           * background(0);
56393           * noStroke();
56394           * smooth();
56395           * ellipse(30, 48, 36, 36);
56396           * noSmooth();
56397           * ellipse(70, 48, 36, 36);
56398           * </code>
56399           * </div>
56400           *
56401           * @alt
56402           * 2 pixelated 36x36 white ellipses to left & right of center, black background
56403           */
56404          _main.default.prototype.noSmooth = function() {
56405            this.setAttributes('antialias', false);
56406            if (!this._renderer.isP3D) {
56407              if ('imageSmoothingEnabled' in this.drawingContext) {
56408                this.drawingContext.imageSmoothingEnabled = false;
56409              }
56410            }
56411            return this;
56412          };
56413
56414          /**
56415           * Modifies the location from which rectangles are drawn by changing the way
56416           * in which parameters given to <a href="#/p5/rect">rect()</a> are interpreted.
56417           *
56418           * The default mode is CORNER, which interprets the first two parameters as the
56419           * upper-left corner of the shape, while the third and fourth parameters are its
56420           * width and height.
56421           *
56422           * rectMode(CORNERS) interprets the first two parameters as the location of
56423           * one of the corners, and the third and fourth parameters as the location of
56424           * the diagonally opposite corner. Note, the rectangle is drawn between the
56425           * coordinates, so it is not neccesary that the first corner be the upper left
56426           * corner.
56427           *
56428           * rectMode(CENTER) interprets the first two parameters as the shape's center
56429           * point, while the third and fourth parameters are its width and height.
56430           *
56431           * rectMode(RADIUS) also uses the first two parameters as the shape's center
56432           * point, but uses the third and fourth parameters to specify half of the shape's
56433           * width and height respectively.
56434           *
56435           * The parameter to this method must be written in ALL CAPS because they are
56436           * predefined as constants in ALL CAPS and Javascript is a case-sensitive language.
56437           *
56438           * @method rectMode
56439           * @param  {Constant} mode either CORNER, CORNERS, CENTER, or RADIUS
56440           * @chainable
56441           * @example
56442           * <div>
56443           * <code>
56444           * rectMode(CORNER);
56445           * fill(255);
56446           * rect(25, 25, 50, 50); // Draw white rectangle using CORNER mode
56447           *
56448           * rectMode(CORNERS);
56449           * fill(100);
56450           * rect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode
56451           * </code>
56452           * </div>
56453           *
56454           * <div>
56455           * <code>
56456           * rectMode(RADIUS);
56457           * fill(255);
56458           * rect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode
56459           *
56460           * rectMode(CENTER);
56461           * fill(100);
56462           * rect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode
56463           * </code>
56464           * </div>
56465           *
56466           * @alt
56467           * 50x50 white rect at center and 25x25 grey rect in the top left of the other.
56468           * 50x50 white rect at center and 25x25 grey rect in the center of the other.
56469           */
56470          _main.default.prototype.rectMode = function(m) {
56471            _main.default._validateParameters('rectMode', arguments);
56472            if (
56473              m === constants.CORNER ||
56474              m === constants.CORNERS ||
56475              m === constants.RADIUS ||
56476              m === constants.CENTER
56477            ) {
56478              this._renderer._rectMode = m;
56479            }
56480            return this;
56481          };
56482
56483          /**
56484           * Draws all geometry with smooth (anti-aliased) edges. <a href="#/p5/smooth">smooth()</a> will also
56485           * improve image quality of resized images. Note that <a href="#/p5/smooth">smooth()</a> is active by
56486           * default in 2D mode; <a href="#/p5/noSmooth">noSmooth()</a> can be used to disable smoothing of geometry,
56487           * images, and fonts. In 3D mode, <a href="#/p5/noSmooth">noSmooth()</a> is enabled
56488           * by default, so it is necessary to call <a href="#/p5/smooth">smooth()</a> if you would like
56489           * smooth (antialiased) edges on your geometry.
56490           *
56491           * @method smooth
56492           * @chainable
56493           * @example
56494           * <div>
56495           * <code>
56496           * background(0);
56497           * noStroke();
56498           * smooth();
56499           * ellipse(30, 48, 36, 36);
56500           * noSmooth();
56501           * ellipse(70, 48, 36, 36);
56502           * </code>
56503           * </div>
56504           *
56505           * @alt
56506           * 2 pixelated 36x36 white ellipses one left one right of center. On black.
56507           */
56508          _main.default.prototype.smooth = function() {
56509            this.setAttributes('antialias', true);
56510            if (!this._renderer.isP3D) {
56511              if ('imageSmoothingEnabled' in this.drawingContext) {
56512                this.drawingContext.imageSmoothingEnabled = true;
56513              }
56514            }
56515            return this;
56516          };
56517
56518          /**
56519           * Sets the style for rendering line endings. These ends are either rounded,
56520           * squared or extended, each of which specified with the corresponding
56521           * parameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.
56522           *
56523           * The parameter to this method must be written in ALL CAPS because they are
56524           * predefined as constants in ALL CAPS and Javascript is a case-sensitive language.
56525           *
56526           * @method strokeCap
56527           * @param  {Constant} cap either ROUND, SQUARE or PROJECT
56528           * @chainable
56529           * @example
56530           * <div>
56531           * <code>
56532           * // Example of different strokeCaps
56533           * strokeWeight(12.0);
56534           * strokeCap(ROUND);
56535           * line(20, 30, 80, 30);
56536           * strokeCap(SQUARE);
56537           * line(20, 50, 80, 50);
56538           * strokeCap(PROJECT);
56539           * line(20, 70, 80, 70);
56540           * </code>
56541           * </div>
56542           *
56543           * @alt
56544           * 3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.
56545           */
56546          _main.default.prototype.strokeCap = function(cap) {
56547            _main.default._validateParameters('strokeCap', arguments);
56548            if (
56549              cap === constants.ROUND ||
56550              cap === constants.SQUARE ||
56551              cap === constants.PROJECT
56552            ) {
56553              this._renderer.strokeCap(cap);
56554            }
56555            return this;
56556          };
56557
56558          /**
56559           * Sets the style of the joints which connect line segments. These joints
56560           * are either mitered, beveled or rounded and specified with the
56561           * corresponding parameters MITER, BEVEL and ROUND. The default joint is
56562           * MITER.
56563           *
56564           * The parameter to this method must be written in ALL CAPS because they are
56565           * predefined as constants in ALL CAPS and Javascript is a case-sensitive language.
56566           *
56567           * @method strokeJoin
56568           * @param  {Constant} join either MITER, BEVEL, ROUND
56569           * @chainable
56570           * @example
56571           * <div>
56572           * <code>
56573           * // Example of MITER type of joints
56574           * noFill();
56575           * strokeWeight(10.0);
56576           * strokeJoin(MITER);
56577           * beginShape();
56578           * vertex(35, 20);
56579           * vertex(65, 50);
56580           * vertex(35, 80);
56581           * endShape();
56582           * </code>
56583           * </div>
56584           *
56585           * <div>
56586           * <code>
56587           * // Example of BEVEL type of joints
56588           * noFill();
56589           * strokeWeight(10.0);
56590           * strokeJoin(BEVEL);
56591           * beginShape();
56592           * vertex(35, 20);
56593           * vertex(65, 50);
56594           * vertex(35, 80);
56595           * endShape();
56596           * </code>
56597           * </div>
56598           *
56599           * <div>
56600           * <code>
56601           * // Example of ROUND type of joints
56602           * noFill();
56603           * strokeWeight(10.0);
56604           * strokeJoin(ROUND);
56605           * beginShape();
56606           * vertex(35, 20);
56607           * vertex(65, 50);
56608           * vertex(35, 80);
56609           * endShape();
56610           * </code>
56611           * </div>
56612           *
56613           * @alt
56614           * Right-facing arrowhead shape with pointed tip in center of canvas.
56615           * Right-facing arrowhead shape with flat tip in center of canvas.
56616           * Right-facing arrowhead shape with rounded tip in center of canvas.
56617           */
56618          _main.default.prototype.strokeJoin = function(join) {
56619            _main.default._validateParameters('strokeJoin', arguments);
56620            if (
56621              join === constants.ROUND ||
56622              join === constants.BEVEL ||
56623              join === constants.MITER
56624            ) {
56625              this._renderer.strokeJoin(join);
56626            }
56627            return this;
56628          };
56629
56630          /**
56631           * Sets the width of the stroke used for lines, points and the border around
56632           * shapes. All widths are set in units of pixels.
56633           *
56634           * @method strokeWeight
56635           * @param  {Number} weight the weight of the stroke (in pixels)
56636           * @chainable
56637           * @example
56638           * <div>
56639           * <code>
56640           * // Example of different stroke weights
56641           * strokeWeight(1); // Default
56642           * line(20, 20, 80, 20);
56643           * strokeWeight(4); // Thicker
56644           * line(20, 40, 80, 40);
56645           * strokeWeight(10); // Beastly
56646           * line(20, 70, 80, 70);
56647           * </code>
56648           * </div>
56649           *
56650           * @alt
56651           * 3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.
56652           */
56653          _main.default.prototype.strokeWeight = function(w) {
56654            _main.default._validateParameters('strokeWeight', arguments);
56655            this._renderer.strokeWeight(w);
56656            return this;
56657          };
56658          var _default = _main.default;
56659          exports.default = _default;
56660        },
56661        { '../constants': 48, '../main': 59 }
56662      ],
56663      68: [
56664        function(_dereq_, module, exports) {
56665          'use strict';
56666          Object.defineProperty(exports, '__esModule', { value: true });
56667          exports.default = void 0;
56668
56669          var _main = _interopRequireDefault(_dereq_('../main'));
56670          _dereq_('../friendly_errors/fes_core');
56671          _dereq_('../friendly_errors/file_errors');
56672          _dereq_('../friendly_errors/validate_params');
56673          function _interopRequireDefault(obj) {
56674            return obj && obj.__esModule ? obj : { default: obj };
56675          }
56676          /**
56677           * @module Shape
56678           * @submodule Curves
56679           * @for p5
56680           * @requires core
56681           */ /**
56682           * Draws a cubic Bezier curve on the screen. These curves are defined by a
56683           * series of anchor and control points. The first two parameters specify
56684           * the first anchor point and the last two parameters specify the other
56685           * anchor point, which become the first and last points on the curve. The
56686           * middle parameters specify the two control points which define the shape
56687           * of the curve. Approximately speaking, control points "pull" the curve
56688           * towards them.
56689           *
56690           * Bezier curves were developed by French automotive engineer Pierre Bezier,
56691           * and are commonly used in computer graphics to define gently sloping curves.
56692           * See also <a href="#/p5/curve">curve()</a>.
56693           *
56694           * @method bezier
56695           * @param  {Number} x1 x-coordinate for the first anchor point
56696           * @param  {Number} y1 y-coordinate for the first anchor point
56697           * @param  {Number} x2 x-coordinate for the first control point
56698           * @param  {Number} y2 y-coordinate for the first control point
56699           * @param  {Number} x3 x-coordinate for the second control point
56700           * @param  {Number} y3 y-coordinate for the second control point
56701           * @param  {Number} x4 x-coordinate for the second anchor point
56702           * @param  {Number} y4 y-coordinate for the second anchor point
56703           * @chainable
56704           * @example
56705           * <div>
56706           * <code>
56707           * noFill();
56708           * stroke(255, 102, 0);
56709           * line(85, 20, 10, 10);
56710           * line(90, 90, 15, 80);
56711           * stroke(0, 0, 0);
56712           * bezier(85, 20, 10, 10, 90, 90, 15, 80);
56713           * </code>
56714           * </div>
56715           *
56716           * <div>
56717           * <code>
56718           * background(0, 0, 0);
56719           * noFill();
56720           * stroke(255);
56721           * bezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);
56722           * </code>
56723           * </div>
56724           *
56725           * @alt
56726           * stretched black s-shape in center with orange lines extending from end points.
56727           * a white colored curve on black background from the upper-right corner to the lower right corner.
56728           */ /**
56729           * @method bezier
56730           * @param  {Number} x1
56731           * @param  {Number} y1
56732           * @param  {Number} z1 z-coordinate for the first anchor point
56733           * @param  {Number} x2
56734           * @param  {Number} y2
56735           * @param  {Number} z2 z-coordinate for the first control point
56736           * @param  {Number} x3
56737           * @param  {Number} y3
56738           * @param  {Number} z3 z-coordinate for the second control point
56739           * @param  {Number} x4
56740           * @param  {Number} y4
56741           * @param  {Number} z4 z-coordinate for the second anchor point
56742           * @chainable
56743           */ _main.default.prototype.bezier = function() {
56744            var _this$_renderer;
56745            for (
56746              var _len = arguments.length, args = new Array(_len), _key = 0;
56747              _key < _len;
56748              _key++
56749            ) {
56750              args[_key] = arguments[_key];
56751            }
56752            _main.default._validateParameters('bezier', args);
56753
56754            // if the current stroke and fill settings wouldn't result in something
56755            // visible, exit immediately
56756            if (!this._renderer._doStroke && !this._renderer._doFill) {
56757              return this;
56758            }
56759
56760            (_this$_renderer = this._renderer).bezier.apply(_this$_renderer, args);
56761
56762            return this;
56763          };
56764
56765          /**
56766           * Sets the resolution at which Bezier's curve is displayed. The default value is 20.
56767           *
56768           * Note, This function is only useful when using the WEBGL renderer
56769           * as the default canvas renderer does not use this information.
56770           *
56771           * @method bezierDetail
56772           * @param {Number} detail resolution of the curves
56773           * @chainable
56774           * @example
56775           * <div modernizr='webgl'>
56776           * <code>
56777           * function setup() {
56778           *   createCanvas(100, 100, WEBGL);
56779           *   noFill();
56780           *   bezierDetail(5);
56781           * }
56782           *
56783           * function draw() {
56784           *   background(200);
56785           *   // prettier-ignore
56786           *   bezier(-40, -40, 0,
56787           *           90, -40, 0,
56788           *          -90,  40, 0,
56789           *           40,  40, 0);
56790           * }
56791           * </code>
56792           * </div>
56793           *
56794           * @alt
56795           * stretched black s-shape with a low level of bezier detail
56796           */
56797          _main.default.prototype.bezierDetail = function(d) {
56798            _main.default._validateParameters('bezierDetail', arguments);
56799            this._bezierDetail = d;
56800            return this;
56801          };
56802
56803          /**
56804    * Given the x or y co-ordinate values of control and anchor points of a bezier
56805    * curve, it evaluates the x or y coordinate of the bezier at position t. The
56806    * parameters a and d are the x or y coordinates of first and last points on the
56807    * curve while b and c are of the control points.The final parameter t is the
56808    * position of the resultant point which is given between 0 and 1.
56809    * This can be done once with the x coordinates and a second time
56810    * with the y coordinates to get the location of a bezier curve at t.
56811    *
56812    * @method bezierPoint
56813    * @param {Number} a coordinate of first point on the curve
56814    * @param {Number} b coordinate of first control point
56815    * @param {Number} c coordinate of second control point
56816    * @param {Number} d coordinate of second point on the curve
56817    * @param {Number} t value between 0 and 1
56818    * @return {Number} the value of the Bezier at position t
56819    * @example
56820    * <div>
56821    * <code>
56822    * noFill();
56823    * let x1 = 85,
56824     x2 = 10,
56825     x3 = 90,
56826     x4 = 15;
56827    * let y1 = 20,
56828     y2 = 10,
56829     y3 = 90,
56830     y4 = 80;
56831    * bezier(x1, y1, x2, y2, x3, y3, x4, y4);
56832    * fill(255);
56833    * let steps = 10;
56834    * for (let i = 0; i <= steps; i++) {
56835    *   let t = i / steps;
56836    *   let x = bezierPoint(x1, x2, x3, x4, t);
56837    *   let y = bezierPoint(y1, y2, y3, y4, t);
56838    *   circle(x, y, 5);
56839    * }
56840    * </code>
56841    * </div>
56842    *
56843    * @alt
56844    * 10 points plotted on a given bezier at equal distances.
56845    */
56846          _main.default.prototype.bezierPoint = function(a, b, c, d, t) {
56847            _main.default._validateParameters('bezierPoint', arguments);
56848
56849            var adjustedT = 1 - t;
56850            return (
56851              Math.pow(adjustedT, 3) * a +
56852              3 * Math.pow(adjustedT, 2) * t * b +
56853              3 * adjustedT * Math.pow(t, 2) * c +
56854              Math.pow(t, 3) * d
56855            );
56856          };
56857
56858          /**
56859           * Evaluates the tangent to the Bezier at position t for points a, b, c, d.
56860           * The parameters a and d are the first and last points
56861           * on the curve, and b and c are the control points.
56862           * The final parameter t varies between 0 and 1.
56863           *
56864           * @method bezierTangent
56865           * @param {Number} a coordinate of first point on the curve
56866           * @param {Number} b coordinate of first control point
56867           * @param {Number} c coordinate of second control point
56868           * @param {Number} d coordinate of second point on the curve
56869           * @param {Number} t value between 0 and 1
56870           * @return {Number} the tangent at position t
56871           * @example
56872           * <div>
56873           * <code>
56874           * noFill();
56875           * bezier(85, 20, 10, 10, 90, 90, 15, 80);
56876           * let steps = 6;
56877           * fill(255);
56878           * for (let i = 0; i <= steps; i++) {
56879           *   let t = i / steps;
56880           *   // Get the location of the point
56881           *   let x = bezierPoint(85, 10, 90, 15, t);
56882           *   let y = bezierPoint(20, 10, 90, 80, t);
56883           *   // Get the tangent points
56884           *   let tx = bezierTangent(85, 10, 90, 15, t);
56885           *   let ty = bezierTangent(20, 10, 90, 80, t);
56886           *   // Calculate an angle from the tangent points
56887           *   let a = atan2(ty, tx);
56888           *   a += PI;
56889           *   stroke(255, 102, 0);
56890           *   line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);
56891           *   // The following line of code makes a line
56892           *   // inverse of the above line
56893           *   //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);
56894           *   stroke(0);
56895           *   ellipse(x, y, 5, 5);
56896           * }
56897           * </code>
56898           * </div>
56899           *
56900           * <div>
56901           * <code>
56902           * noFill();
56903           * bezier(85, 20, 10, 10, 90, 90, 15, 80);
56904           * stroke(255, 102, 0);
56905           * let steps = 16;
56906           * for (let i = 0; i <= steps; i++) {
56907           *   let t = i / steps;
56908           *   let x = bezierPoint(85, 10, 90, 15, t);
56909           *   let y = bezierPoint(20, 10, 90, 80, t);
56910           *   let tx = bezierTangent(85, 10, 90, 15, t);
56911           *   let ty = bezierTangent(20, 10, 90, 80, t);
56912           *   let a = atan2(ty, tx);
56913           *   a -= HALF_PI;
56914           *   line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);
56915           * }
56916           * </code>
56917           * </div>
56918           *
56919           * @alt
56920           * s-shaped line with 6 short orange lines showing the tangents at those points.
56921           * s-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.
56922           */
56923          _main.default.prototype.bezierTangent = function(a, b, c, d, t) {
56924            _main.default._validateParameters('bezierTangent', arguments);
56925
56926            var adjustedT = 1 - t;
56927            return (
56928              3 * d * Math.pow(t, 2) -
56929              3 * c * Math.pow(t, 2) +
56930              6 * c * adjustedT * t -
56931              6 * b * adjustedT * t +
56932              3 * b * Math.pow(adjustedT, 2) -
56933              3 * a * Math.pow(adjustedT, 2)
56934            );
56935          };
56936
56937          /**
56938           * Draws a curved line on the screen between two points, given as the
56939           * middle four parameters. The first two parameters are a control point, as
56940           * if the curve came from this point even though it's not drawn. The last
56941           * two parameters similarly describe the other control point. <br /><br />
56942           * Longer curves can be created by putting a series of <a href="#/p5/curve">curve()</a> functions
56943           * together or using <a href="#/p5/curveVertex">curveVertex()</a>. An additional function called
56944           * <a href="#/p5/curveTightness">curveTightness()</a> provides control for the visual quality of the curve.
56945           * The <a href="#/p5/curve">curve()</a> function is an implementation of Catmull-Rom splines.
56946           *
56947           * @method curve
56948           * @param  {Number} x1 x-coordinate for the beginning control point
56949           * @param  {Number} y1 y-coordinate for the beginning control point
56950           * @param  {Number} x2 x-coordinate for the first point
56951           * @param  {Number} y2 y-coordinate for the first point
56952           * @param  {Number} x3 x-coordinate for the second point
56953           * @param  {Number} y3 y-coordinate for the second point
56954           * @param  {Number} x4 x-coordinate for the ending control point
56955           * @param  {Number} y4 y-coordinate for the ending control point
56956           * @chainable
56957           * @example
56958           * <div>
56959           * <code>
56960           * noFill();
56961           * stroke(255, 102, 0);
56962           * curve(5, 26, 5, 26, 73, 24, 73, 61);
56963           * stroke(0);
56964           * curve(5, 26, 73, 24, 73, 61, 15, 65);
56965           * stroke(255, 102, 0);
56966           * curve(73, 24, 73, 61, 15, 65, 15, 65);
56967           * </code>
56968           * </div>
56969           *
56970           * <div>
56971           * <code>
56972           * // Define the curve points as JavaScript objects
56973           * let p1 = { x: 5, y: 26 };
56974           * let p2 = { x: 73, y: 24 };
56975           * let p3 = { x: 73, y: 61 };
56976           * let p4 = { x: 15, y: 65 };
56977           * noFill();
56978           * stroke(255, 102, 0);
56979           * curve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
56980           * stroke(0);
56981           * curve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
56982           * stroke(255, 102, 0);
56983           * curve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);
56984           * </code>
56985           * </div>
56986           *
56987           * <div>
56988           * <code>
56989           * noFill();
56990           * stroke(255, 102, 0);
56991           * curve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);
56992           * stroke(0);
56993           * curve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);
56994           * stroke(255, 102, 0);
56995           * curve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);
56996           * </code>
56997           * </div>
56998           *
56999           * @alt
57000           * horseshoe shape with orange ends facing left and black curved center.
57001           * horseshoe shape with orange ends facing left and black curved center.
57002           * curving black and orange lines.
57003           */
57004
57005          /**
57006           * @method curve
57007           * @param  {Number} x1
57008           * @param  {Number} y1
57009           * @param  {Number} z1 z-coordinate for the beginning control point
57010           * @param  {Number} x2
57011           * @param  {Number} y2
57012           * @param  {Number} z2 z-coordinate for the first point
57013           * @param  {Number} x3
57014           * @param  {Number} y3
57015           * @param  {Number} z3 z-coordinate for the second point
57016           * @param  {Number} x4
57017           * @param  {Number} y4
57018           * @param  {Number} z4 z-coordinate for the ending control point
57019           * @chainable
57020           */
57021          _main.default.prototype.curve = function() {
57022            for (
57023              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
57024              _key2 < _len2;
57025              _key2++
57026            ) {
57027              args[_key2] = arguments[_key2];
57028            }
57029            _main.default._validateParameters('curve', args);
57030
57031            if (this._renderer._doStroke) {
57032              var _this$_renderer2;
57033              (_this$_renderer2 = this._renderer).curve.apply(_this$_renderer2, args);
57034            }
57035
57036            return this;
57037          };
57038
57039          /**
57040           * Sets the resolution at which curves display. The default value is 20 while
57041           * the minimum value is 3.
57042           *
57043           * This function is only useful when using the WEBGL renderer
57044           * as the default canvas renderer does not use this
57045           * information.
57046           *
57047           * @method curveDetail
57048           * @param {Number} resolution resolution of the curves
57049           * @chainable
57050           * @example
57051           * <div modernizr='webgl'>
57052           * <code>
57053           * function setup() {
57054           *   createCanvas(100, 100, WEBGL);
57055           *
57056           *   curveDetail(5);
57057           * }
57058           * function draw() {
57059           *   background(200);
57060           *
57061           *   curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);
57062           * }
57063           * </code>
57064           * </div>
57065           *
57066           * @alt
57067           * white arch shape with a low level of curve detail.
57068           */
57069          _main.default.prototype.curveDetail = function(d) {
57070            _main.default._validateParameters('curveDetail', arguments);
57071            if (d < 3) {
57072              this._curveDetail = 3;
57073            } else {
57074              this._curveDetail = d;
57075            }
57076            return this;
57077          };
57078
57079          /**
57080           * Modifies the quality of forms created with <a href="#/p5/curve">curve()</a>
57081           * and <a href="#/p5/curveVertex">curveVertex()</a>.The parameter tightness
57082           * determines how the curve fits to the vertex points. The value 0.0 is the
57083           * default value for tightness (this value defines the curves to be Catmull-Rom
57084           * splines) and the value 1.0 connects all the points with straight lines.
57085           * Values within the range -5.0 and 5.0 will deform the curves but will leave
57086           * them recognizable and as values increase in magnitude, they will continue to deform.
57087           *
57088           * @method curveTightness
57089           * @param {Number} amount amount of deformation from the original vertices
57090           * @chainable
57091           * @example
57092           * <div>
57093           * <code>
57094           * // Move the mouse left and right to see the curve change
57095           * function setup() {
57096           *   createCanvas(100, 100);
57097           *   noFill();
57098           * }
57099           *
57100           * function draw() {
57101           *   background(204);
57102           *   let t = map(mouseX, 0, width, -5, 5);
57103           *   curveTightness(t);
57104           *   beginShape();
57105           *   curveVertex(10, 26);
57106           *   curveVertex(10, 26);
57107           *   curveVertex(83, 24);
57108           *   curveVertex(83, 61);
57109           *   curveVertex(25, 65);
57110           *   curveVertex(25, 65);
57111           *   endShape();
57112           * }
57113           * </code>
57114           * </div>
57115           *
57116           * @alt
57117           * Line shaped like right-facing arrow,points move with mouse-x and warp shape.
57118           */
57119          _main.default.prototype.curveTightness = function(t) {
57120            _main.default._validateParameters('curveTightness', arguments);
57121            this._renderer._curveTightness = t;
57122            return this;
57123          };
57124
57125          /**
57126           * Evaluates the curve at position t for points a, b, c, d.
57127           * The parameter t varies between 0 and 1, a and d are control points
57128           * of the curve, and b and c are the start and end points of the curve.
57129           * This can be done once with the x coordinates and a second time
57130           * with the y coordinates to get the location of a curve at t.
57131           *
57132           * @method curvePoint
57133           * @param {Number} a coordinate of first control point of the curve
57134           * @param {Number} b coordinate of first point
57135           * @param {Number} c coordinate of second point
57136           * @param {Number} d coordinate of second control point
57137           * @param {Number} t value between 0 and 1
57138           * @return {Number} bezier value at position t
57139           * @example
57140           * <div>
57141           * <code>
57142           * noFill();
57143           * curve(5, 26, 5, 26, 73, 24, 73, 61);
57144           * curve(5, 26, 73, 24, 73, 61, 15, 65);
57145           * fill(255);
57146           * ellipseMode(CENTER);
57147           * let steps = 6;
57148           * for (let i = 0; i <= steps; i++) {
57149           *   let t = i / steps;
57150           *   let x = curvePoint(5, 5, 73, 73, t);
57151           *   let y = curvePoint(26, 26, 24, 61, t);
57152           *   ellipse(x, y, 5, 5);
57153           *   x = curvePoint(5, 73, 73, 15, t);
57154           *   y = curvePoint(26, 24, 61, 65, t);
57155           *   ellipse(x, y, 5, 5);
57156           * }
57157           * </code>
57158           * </div>
57159           *
57160           *line hooking down to right-bottom with 13 5x5 white ellipse points
57161           */
57162          _main.default.prototype.curvePoint = function(a, b, c, d, t) {
57163            _main.default._validateParameters('curvePoint', arguments);
57164
57165            var t3 = t * t * t,
57166              t2 = t * t,
57167              f1 = -0.5 * t3 + t2 - 0.5 * t,
57168              f2 = 1.5 * t3 - 2.5 * t2 + 1.0,
57169              f3 = -1.5 * t3 + 2.0 * t2 + 0.5 * t,
57170              f4 = 0.5 * t3 - 0.5 * t2;
57171            return a * f1 + b * f2 + c * f3 + d * f4;
57172          };
57173
57174          /**
57175           * Evaluates the tangent to the curve at position t for points a, b, c, d.
57176           * The parameter t varies between 0 and 1, a and d are points on the curve,
57177           * and b and c are the control points.
57178           *
57179           * @method curveTangent
57180           * @param {Number} a coordinate of first control point
57181           * @param {Number} b coordinate of first point on the curve
57182           * @param {Number} c coordinate of second point on the curve
57183           * @param {Number} d coordinate of second conrol point
57184           * @param {Number} t value between 0 and 1
57185           * @return {Number} the tangent at position t
57186           * @example
57187           * <div>
57188           * <code>
57189           * noFill();
57190           * curve(5, 26, 73, 24, 73, 61, 15, 65);
57191           * let steps = 6;
57192           * for (let i = 0; i <= steps; i++) {
57193           *   let t = i / steps;
57194           *   let x = curvePoint(5, 73, 73, 15, t);
57195           *   let y = curvePoint(26, 24, 61, 65, t);
57196           *   //ellipse(x, y, 5, 5);
57197           *   let tx = curveTangent(5, 73, 73, 15, t);
57198           *   let ty = curveTangent(26, 24, 61, 65, t);
57199           *   let a = atan2(ty, tx);
57200           *   a -= PI / 2.0;
57201           *   line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);
57202           * }
57203           * </code>
57204           * </div>
57205           *
57206           * @alt
57207           * right curving line mid-right of canvas with 7 short lines radiating from it.
57208           */
57209          _main.default.prototype.curveTangent = function(a, b, c, d, t) {
57210            _main.default._validateParameters('curveTangent', arguments);
57211
57212            var t2 = t * t,
57213              f1 = -3 * t2 / 2 + 2 * t - 0.5,
57214              f2 = 9 * t2 / 2 - 5 * t,
57215              f3 = -9 * t2 / 2 + 4 * t + 0.5,
57216              f4 = 3 * t2 / 2 - t;
57217            return a * f1 + b * f2 + c * f3 + d * f4;
57218          };
57219          var _default = _main.default;
57220          exports.default = _default;
57221        },
57222        {
57223          '../friendly_errors/fes_core': 51,
57224          '../friendly_errors/file_errors': 52,
57225          '../friendly_errors/validate_params': 54,
57226          '../main': 59
57227        }
57228      ],
57229      69: [
57230        function(_dereq_, module, exports) {
57231          'use strict';
57232          function _typeof(obj) {
57233            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
57234              _typeof = function _typeof(obj) {
57235                return typeof obj;
57236              };
57237            } else {
57238              _typeof = function _typeof(obj) {
57239                return obj &&
57240                  typeof Symbol === 'function' &&
57241                  obj.constructor === Symbol &&
57242                  obj !== Symbol.prototype
57243                  ? 'symbol'
57244                  : typeof obj;
57245              };
57246            }
57247            return _typeof(obj);
57248          }
57249          Object.defineProperty(exports, '__esModule', { value: true });
57250          exports.default = void 0;
57251
57252          var _main = _interopRequireDefault(_dereq_('../main'));
57253          var constants = _interopRequireWildcard(_dereq_('../constants'));
57254          function _getRequireWildcardCache() {
57255            if (typeof WeakMap !== 'function') return null;
57256            var cache = new WeakMap();
57257            _getRequireWildcardCache = function _getRequireWildcardCache() {
57258              return cache;
57259            };
57260            return cache;
57261          }
57262          function _interopRequireWildcard(obj) {
57263            if (obj && obj.__esModule) {
57264              return obj;
57265            }
57266            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
57267              return { default: obj };
57268            }
57269            var cache = _getRequireWildcardCache();
57270            if (cache && cache.has(obj)) {
57271              return cache.get(obj);
57272            }
57273            var newObj = {};
57274            var hasPropertyDescriptor =
57275              Object.defineProperty && Object.getOwnPropertyDescriptor;
57276            for (var key in obj) {
57277              if (Object.prototype.hasOwnProperty.call(obj, key)) {
57278                var desc = hasPropertyDescriptor
57279                  ? Object.getOwnPropertyDescriptor(obj, key)
57280                  : null;
57281                if (desc && (desc.get || desc.set)) {
57282                  Object.defineProperty(newObj, key, desc);
57283                } else {
57284                  newObj[key] = obj[key];
57285                }
57286              }
57287            }
57288            newObj.default = obj;
57289            if (cache) {
57290              cache.set(obj, newObj);
57291            }
57292            return newObj;
57293          }
57294          function _interopRequireDefault(obj) {
57295            return obj && obj.__esModule ? obj : { default: obj };
57296          }
57297          /**
57298           * @module Shape
57299           * @submodule Vertex
57300           * @for p5
57301           * @requires core
57302           * @requires constants
57303           */ var shapeKind = null;
57304          var vertices = [];
57305          var contourVertices = [];
57306          var isBezier = false;
57307          var isCurve = false;
57308          var isQuadratic = false;
57309          var isContour = false;
57310          var isFirstContour = true;
57311
57312          /**
57313           * Use the <a href="#/p5/beginContour">beginContour()</a> and
57314           * <a href="#/p5/endContour">endContour()</a> functions to create negative shapes
57315           * within shapes such as the center of the letter 'O'. <a href="#/p5/beginContour">beginContour()</a>
57316           * begins recording vertices for the shape and <a href="#/p5/endContour">endContour()</a> stops recording.
57317           * The vertices that define a negative shape must "wind" in the opposite direction
57318           * from the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices
57319           * shape in counter-clockwise.
57320           *
57321           * These functions can only be used within a <a href="#/p5/beginShape">beginShape()</a>/<a href="#/p5/endShape">endShape()</a> pair and
57322           * transformations such as <a href="#/p5/translate">translate()</a>, <a href="#/p5/rotate">rotate()</a>, and <a href="#/p5/scale">scale()</a> do not work
57323           * within a <a href="#/p5/beginContour">beginContour()</a>/<a href="#/p5/endContour">endContour()</a> pair. It is also not possible to use
57324           * other shapes, such as <a href="#/p5/ellipse">ellipse()</a> or <a href="#/p5/rect">rect()</a> within.
57325           *
57326           * @method beginContour
57327           * @chainable
57328           * @example
57329           * <div>
57330           * <code>
57331           * translate(50, 50);
57332           * stroke(255, 0, 0);
57333           * beginShape();
57334           * // Exterior part of shape, clockwise winding
57335           * vertex(-40, -40);
57336           * vertex(40, -40);
57337           * vertex(40, 40);
57338           * vertex(-40, 40);
57339           * // Interior part of shape, counter-clockwise winding
57340           * beginContour();
57341           * vertex(-20, -20);
57342           * vertex(-20, 20);
57343           * vertex(20, 20);
57344           * vertex(20, -20);
57345           * endContour();
57346           * endShape(CLOSE);
57347           * </code>
57348           * </div>
57349           *
57350           * @alt
57351           * white rect and smaller grey rect with red outlines in center of canvas.
57352           */
57353          _main.default.prototype.beginContour = function() {
57354            contourVertices = [];
57355            isContour = true;
57356            return this;
57357          };
57358
57359          /**
57360           * Using the <a href="#/p5/beginShape">beginShape()</a> and <a href="#/p5/endShape">endShape()</a> functions allow creating more
57361           * complex forms. <a href="#/p5/beginShape">beginShape()</a> begins recording vertices for a shape and
57362           * <a href="#/p5/endShape">endShape()</a> stops recording. The value of the kind parameter tells it which
57363           * types of shapes to create from the provided vertices. With no mode
57364           * specified, the shape can be any irregular polygon.
57365           *
57366           * The parameters available for <a href="#/p5/beginShape">beginShape()</a> are POINTS, LINES, TRIANGLES,
57367           * TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP, and TESS (WebGL only). After calling the
57368           * <a href="#/p5/beginShape">beginShape()</a> function, a series of <a href="#/p5/vertex">vertex()</a> commands must follow. To stop
57369           * drawing the shape, call <a href="#/p5/endShape">endShape()</a>. Each shape will be outlined with the
57370           * current stroke color and filled with the fill color.
57371           *
57372           * Transformations such as <a href="#/p5/translate">translate()</a>, <a href="#/p5/rotate">rotate()</a>, and <a href="#/p5/scale">scale()</a> do not work
57373           * within <a href="#/p5/beginShape">beginShape()</a>. It is also not possible to use other shapes, such as
57374           * <a href="#/p5/ellipse">ellipse()</a> or <a href="#/p5/rect">rect()</a> within <a href="#/p5/beginShape">beginShape()</a>.
57375           *
57376           * @method beginShape
57377           * @param  {Constant} [kind] either POINTS, LINES, TRIANGLES, TRIANGLE_FAN
57378           *                                TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS
57379           * @chainable
57380           * @example
57381           * <div>
57382           * <code>
57383           * beginShape();
57384           * vertex(30, 20);
57385           * vertex(85, 20);
57386           * vertex(85, 75);
57387           * vertex(30, 75);
57388           * endShape(CLOSE);
57389           * </code>
57390           * </div>
57391           *
57392           * <div>
57393           * <code>
57394           * beginShape(POINTS);
57395           * vertex(30, 20);
57396           * vertex(85, 20);
57397           * vertex(85, 75);
57398           * vertex(30, 75);
57399           * endShape();
57400           * </code>
57401           * </div>
57402           *
57403           * <div>
57404           * <code>
57405           * beginShape(LINES);
57406           * vertex(30, 20);
57407           * vertex(85, 20);
57408           * vertex(85, 75);
57409           * vertex(30, 75);
57410           * endShape();
57411           * </code>
57412           * </div>
57413           *
57414           * <div>
57415           * <code>
57416           * noFill();
57417           * beginShape();
57418           * vertex(30, 20);
57419           * vertex(85, 20);
57420           * vertex(85, 75);
57421           * vertex(30, 75);
57422           * endShape();
57423           * </code>
57424           * </div>
57425           *
57426           * <div>
57427           * <code>
57428           * noFill();
57429           * beginShape();
57430           * vertex(30, 20);
57431           * vertex(85, 20);
57432           * vertex(85, 75);
57433           * vertex(30, 75);
57434           * endShape(CLOSE);
57435           * </code>
57436           * </div>
57437           *
57438           * <div>
57439           * <code>
57440           * beginShape(TRIANGLES);
57441           * vertex(30, 75);
57442           * vertex(40, 20);
57443           * vertex(50, 75);
57444           * vertex(60, 20);
57445           * vertex(70, 75);
57446           * vertex(80, 20);
57447           * endShape();
57448           * </code>
57449           * </div>
57450           *
57451           * <div>
57452           * <code>
57453           * beginShape(TRIANGLE_STRIP);
57454           * vertex(30, 75);
57455           * vertex(40, 20);
57456           * vertex(50, 75);
57457           * vertex(60, 20);
57458           * vertex(70, 75);
57459           * vertex(80, 20);
57460           * vertex(90, 75);
57461           * endShape();
57462           * </code>
57463           * </div>
57464           *
57465           * <div>
57466           * <code>
57467           * beginShape(TRIANGLE_FAN);
57468           * vertex(57.5, 50);
57469           * vertex(57.5, 15);
57470           * vertex(92, 50);
57471           * vertex(57.5, 85);
57472           * vertex(22, 50);
57473           * vertex(57.5, 15);
57474           * endShape();
57475           * </code>
57476           * </div>
57477           *
57478           * <div>
57479           * <code>
57480           * beginShape(QUADS);
57481           * vertex(30, 20);
57482           * vertex(30, 75);
57483           * vertex(50, 75);
57484           * vertex(50, 20);
57485           * vertex(65, 20);
57486           * vertex(65, 75);
57487           * vertex(85, 75);
57488           * vertex(85, 20);
57489           * endShape();
57490           * </code>
57491           * </div>
57492           *
57493           * <div>
57494           * <code>
57495           * beginShape(QUAD_STRIP);
57496           * vertex(30, 20);
57497           * vertex(30, 75);
57498           * vertex(50, 20);
57499           * vertex(50, 75);
57500           * vertex(65, 20);
57501           * vertex(65, 75);
57502           * vertex(85, 20);
57503           * vertex(85, 75);
57504           * endShape();
57505           * </code>
57506           * </div>
57507           *
57508           * <div>
57509           * <code>
57510           * beginShape();
57511           * vertex(20, 20);
57512           * vertex(40, 20);
57513           * vertex(40, 40);
57514           * vertex(60, 40);
57515           * vertex(60, 60);
57516           * vertex(20, 60);
57517           * endShape(CLOSE);
57518           * </code>
57519           * </div>
57520           *
57521           * @alt
57522           * white square-shape with black outline in middle-right of canvas.
57523           * 4 black points in a square shape in middle-right of canvas.
57524           * 2 horizontal black lines. In the top-right and bottom-right of canvas.
57525           * 3 line shape with horizontal on top, vertical in middle and horizontal bottom.
57526           * square line shape in middle-right of canvas.
57527           * 2 white triangle shapes mid-right canvas. left one pointing up and right down.
57528           * 5 horizontal interlocking and alternating white triangles in mid-right canvas.
57529           * 4 interlocking white triangles in 45 degree rotated square-shape.
57530           * 2 white rectangle shapes in mid-right canvas. Both 20x55.
57531           * 3 side-by-side white rectangles center rect is smaller in mid-right canvas.
57532           * Thick white l-shape with black outline mid-top-left of canvas.
57533           */
57534          _main.default.prototype.beginShape = function(kind) {
57535            _main.default._validateParameters('beginShape', arguments);
57536            if (this._renderer.isP3D) {
57537              var _this$_renderer;
57538              (_this$_renderer = this._renderer).beginShape.apply(
57539                _this$_renderer,
57540                arguments
57541              );
57542            } else {
57543              if (
57544                kind === constants.POINTS ||
57545                kind === constants.LINES ||
57546                kind === constants.TRIANGLES ||
57547                kind === constants.TRIANGLE_FAN ||
57548                kind === constants.TRIANGLE_STRIP ||
57549                kind === constants.QUADS ||
57550                kind === constants.QUAD_STRIP
57551              ) {
57552                shapeKind = kind;
57553              } else {
57554                shapeKind = null;
57555              }
57556
57557              vertices = [];
57558              contourVertices = [];
57559            }
57560            return this;
57561          };
57562
57563          /**
57564           * Specifies vertex coordinates for Bezier curves. Each call to
57565           * bezierVertex() defines the position of two control points and
57566           * one anchor point of a Bezier curve, adding a new segment to a
57567           * line or shape. For WebGL mode bezierVertex() can be used in 2D
57568           * as well as 3D mode. 2D mode expects 6 parameters, while 3D mode
57569           * expects 9 parameters (including z coordinates).
57570           *
57571           * The first time bezierVertex() is used within a <a href="#/p5/beginShape">beginShape()</a>
57572           * call, it must be prefaced with a call to <a href="#/p5/vertex">vertex()</a> to set the first anchor
57573           * point. This function must be used between <a href="#/p5/beginShape">beginShape()</a> and <a href="#/p5/endShape">endShape()</a>
57574           * and only when there is no MODE or POINTS parameter specified to
57575           * <a href="#/p5/beginShape">beginShape()</a>.
57576           *
57577           * @method bezierVertex
57578           * @param  {Number} x2 x-coordinate for the first control point
57579           * @param  {Number} y2 y-coordinate for the first control point
57580           * @param  {Number} x3 x-coordinate for the second control point
57581           * @param  {Number} y3 y-coordinate for the second control point
57582           * @param  {Number} x4 x-coordinate for the anchor point
57583           * @param  {Number} y4 y-coordinate for the anchor point
57584           * @chainable
57585           *
57586           * @example
57587           * <div>
57588           * <code>
57589           * noFill();
57590           * beginShape();
57591           * vertex(30, 20);
57592           * bezierVertex(80, 0, 80, 75, 30, 75);
57593           * endShape();
57594           * </code>
57595           * </div>
57596           *
57597           * <div>
57598           * <code>
57599           * beginShape();
57600           * vertex(30, 20);
57601           * bezierVertex(80, 0, 80, 75, 30, 75);
57602           * bezierVertex(50, 80, 60, 25, 30, 20);
57603           * endShape();
57604           * </code>
57605           * </div>
57606           *
57607           * <div>
57608           * <code>
57609           * function setup() {
57610           *   createCanvas(100, 100, WEBGL);
57611           *   setAttributes('antialias', true);
57612           * }
57613           * function draw() {
57614           *   orbitControl();
57615           *   background(50);
57616           *   strokeWeight(4);
57617           *   stroke(255);
57618           *   point(-25, 30);
57619           *   point(25, 30);
57620           *   point(25, -30);
57621           *   point(-25, -30);
57622           *
57623           *   strokeWeight(1);
57624           *   noFill();
57625           *
57626           *   beginShape();
57627           *   vertex(-25, 30);
57628           *   bezierVertex(25, 30, 25, -30, -25, -30);
57629           *   endShape();
57630           *
57631           *   beginShape();
57632           *   vertex(-25, 30, 20);
57633           *   bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);
57634           *   endShape();
57635           * }
57636           * </code>
57637           * </div>
57638           *
57639           * @alt
57640           * crescent-shaped line in middle of canvas. Points facing left.
57641           * white crescent shape in middle of canvas. Points facing left.
57642           * crescent shape in middle of canvas with another crescent shape on positive z-axis.
57643           */
57644
57645          /**
57646           * @method bezierVertex
57647           * @param  {Number} x2
57648           * @param  {Number} y2
57649           * @param  {Number} z2 z-coordinate for the first control point (for WebGL mode)
57650           * @param  {Number} x3
57651           * @param  {Number} y3
57652           * @param  {Number} z3 z-coordinate for the second control point (for WebGL mode)
57653           * @param  {Number} x4
57654           * @param  {Number} y4
57655           * @param  {Number}
57655 z4 z-coordinate for the anchor point (for WebGL mode)
57656           * @chainable
57657           */
57658          _main.default.prototype.bezierVertex = function() {
57659            for (
57660              var _len = arguments.length, args = new Array(_len), _key = 0;
57661              _key < _len;
57662              _key++
57663            ) {
57664              args[_key] = arguments[_key];
57665            }
57666            _main.default._validateParameters('bezierVertex', args);
57667            if (this._renderer.isP3D) {
57668              var _this$_renderer2;
57669              (_this$_renderer2 = this._renderer).bezierVertex.apply(
57670                _this$_renderer2,
57671                args
57672              );
57673            } else {
57674              if (vertices.length === 0) {
57675                _main.default._friendlyError(
57676                  'vertex() must be used once before calling bezierVertex()',
57677                  'bezierVertex'
57678                );
57679              } else {
57680                isBezier = true;
57681                var vert = [];
57682                for (var i = 0; i < args.length; i++) {
57683                  vert[i] = args[i];
57684                }
57685                vert.isVert = false;
57686                if (isContour) {
57687                  contourVertices.push(vert);
57688                } else {
57689                  vertices.push(vert);
57690                }
57691              }
57692            }
57693            return this;
57694          };
57695
57696          /**
57697           * Specifies vertex coordinates for curves. This function may only
57698           * be used between <a href="#/p5/beginShape">beginShape()</a> and <a href="#/p5/endShape">endShape()</a> and only when there
57699           * is no MODE parameter specified to <a href="#/p5/beginShape">beginShape()</a>.
57700           * For WebGL mode curveVertex() can be used in 2D as well as 3D mode.
57701           * 2D mode expects 2 parameters, while 3D mode expects 3 parameters.
57702           *
57703           * The first and last points in a series of curveVertex() lines will be used to
57704           * guide the beginning and end of a the curve. A minimum of four
57705           * points is required to draw a tiny curve between the second and
57706           * third points. Adding a fifth point with curveVertex() will draw
57707           * the curve between the second, third, and fourth points. The
57708           * curveVertex() function is an implementation of Catmull-Rom
57709           * splines.
57710           *
57711           * @method curveVertex
57712           * @param {Number} x x-coordinate of the vertex
57713           * @param {Number} y y-coordinate of the vertex
57714           * @chainable
57715           * @example
57716           * <div>
57717           * <code>
57718           * strokeWeight(5);
57719           * point(84, 91);
57720           * point(68, 19);
57721           * point(21, 17);
57722           * point(32, 91);
57723           * strokeWeight(1);
57724           *
57725           * noFill();
57726           * beginShape();
57727           * curveVertex(84, 91);
57728           * curveVertex(84, 91);
57729           * curveVertex(68, 19);
57730           * curveVertex(21, 17);
57731           * curveVertex(32, 91);
57732           * curveVertex(32, 91);
57733           * endShape();
57734           * </code>
57735           * </div>
57736           *
57737           * @alt
57738           * Upside-down u-shape line, mid canvas. left point extends beyond canvas view.
57739           */
57740
57741          /**
57742           * @method curveVertex
57743           * @param {Number} x
57744           * @param {Number} y
57745           * @param {Number} [z] z-coordinate of the vertex (for WebGL mode)
57746           * @chainable
57747           * @example
57748           * <div>
57749           * <code>
57750           * function setup() {
57751           *   createCanvas(100, 100, WEBGL);
57752           *   setAttributes('antialias', true);
57753           * }
57754           * function draw() {
57755           *   orbitControl();
57756           *   background(50);
57757           *   strokeWeight(4);
57758           *   stroke(255);
57759           *
57760           *   point(-25, 25);
57761           *   point(-25, 25);
57762           *   point(-25, -25);
57763           *   point(25, -25);
57764           *   point(25, 25);
57765           *   point(25, 25);
57766           *
57767           *   strokeWeight(1);
57768           *   noFill();
57769           *
57770           *   beginShape();
57771           *   curveVertex(-25, 25);
57772           *   curveVertex(-25, 25);
57773           *   curveVertex(-25, -25);
57774           *   curveVertex(25, -25);
57775           *   curveVertex(25, 25);
57776           *   curveVertex(25, 25);
57777           *   endShape();
57778           *
57779           *   beginShape();
57780           *   curveVertex(-25, 25, 20);
57781           *   curveVertex(-25, 25, 20);
57782           *   curveVertex(-25, -25, 20);
57783           *   curveVertex(25, -25, 20);
57784           *   curveVertex(25, 25, 20);
57785           *   curveVertex(25, 25, 20);
57786           *   endShape();
57787           * }
57788           * </code>
57789           * </div>
57790           *
57791           * @alt
57792           * Upside-down u-shape line, mid canvas with the same shape in positive z-axis.
57793           */
57794          _main.default.prototype.curveVertex = function() {
57795            for (
57796              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
57797              _key2 < _len2;
57798              _key2++
57799            ) {
57800              args[_key2] = arguments[_key2];
57801            }
57802            _main.default._validateParameters('curveVertex', args
57802);
57803            if (this._renderer.isP3D) {
57804              var _this$_renderer3;
57805              (_this$_renderer3 = this._renderer).curveVertex.apply(_this$_renderer3, args);
57806            } else {
57807              isCurve = true;
57808              this.vertex(args[0], args[1]);
57809            }
57810            return this;
57811          };
57812
57813          /**
57814           * Use the <a href="#/p5/beginContour">beginContour()</a> and <a href="#/p5/endContour">endContour()</a> functions to create negative
57815           * shapes within shapes such as the center of the letter 'O'. <a href="#/p5/beginContour">beginContour()</a>
57816           * begins recording vertices for the shape and <a href="#/p5/endContour">endContour()</a> stops recording.
57817           * The vertices that define a negative shape must "wind" in the opposite
57818           * direction from the exterior shape. First draw vertices for the exterior
57819           * clockwise order, then for internal shapes, draw vertices
57820           * shape in counter-clockwise.
57821           *
57822           * These functions can only be used within a <a href="#/p5/beginShape">beginShape()</a>/<a href="#/p5/endShape">endShape()</a> pair and
57823           * transformations such as <a href="#/p5/translate">translate()</a>, <a href="#/p5/rotate">rotate()</a>, and <a href="#/p5/scale">scale()</a> do not work
57824           * within a <a href="#/p5/beginContour">beginContour()</a>/<a href="#/p5/endContour">endContour()</a> pair. It is also not possible to use
57825           * other shapes, such as <a href="#/p5/ellipse">ellipse()</a> or <a href="#/p5/rect">rect()</a> within.
57826           *
57827           * @method endContour
57828           * @chainable
57829           * @example
57830           * <div>
57831           * <code>
57832           * translate(50, 50);
57833           * stroke(255, 0, 0);
57834           * beginShape();
57835           * // Exterior part of shape, clockwise winding
57836           * vertex(-40, -40);
57837           * vertex(40, -40);
57838           * vertex(40, 40);
57839           * vertex(-40, 40);
57840           * // Interior part of shape, counter-clockwise winding
57841           * beginContour();
57842           * vertex(-20, -20);
57843           * vertex(-20, 20);
57844           * vertex(20, 20);
57845           * vertex(20, -20);
57846           * endContour();
57847           * endShape(CLOSE);
57848           * </code>
57849           * </div>
57850           *
57851           * @alt
57852           * white rect and smaller grey rect with red outlines in center of canvas.
57853           */
57854          _main.default.prototype.endContour = function() {
57855            var vert = contourVertices[0].slice(); // copy all data
57856            vert.isVert = contourVertices[0].isVert;
57857            vert.moveTo = false;
57858            contourVertices.push(vert);
57859
57860            // prevent stray lines with multiple contours
57861            if (isFirstContour) {
57862              vertices.push(vertices[0]);
57863              isFirstContour = false;
57864            }
57865
57866            for (var i = 0; i < contourVertices.length; i++) {
57867              vertices.push(contourVertices[i]);
57868            }
57869            return this;
57870          };
57871
57872          /**
57873           * The <a href="#/p5/endShape">endShape()</a> function is the companion to <a href="#/p5/beginShape">beginShape()</a> and may only be
57874           * called after <a href="#/p5/beginShape">beginShape()</a>. When <a href="#/p5/endshape">endShape()</a> is called, all of image data
57875           * defined since the previous call to <a href="#/p5/beginShape">beginShape()</a> is written into the image
57876           * buffer. The constant CLOSE as the value for the MODE parameter to close
57877           * the shape (to connect the beginning and the end).
57878           *
57879           * @method endShape
57880           * @param  {Constant} [mode] use CLOSE to close the shape
57881           * @chainable
57882           * @example
57883           * <div>
57884           * <code>
57885           * noFill();
57886           *
57887           * beginShape();
57888           * vertex(20, 20);
57889           * vertex(45, 20);
57890           * vertex(45, 80);
57891           * endShape(CLOSE);
57892           *
57893           * beginShape();
57894           * vertex(50, 20);
57895           * vertex(75, 20);
57896           * vertex(75, 80);
57897           * endShape();
57898           * </code>
57899           * </div>
57900           *
57901           * @alt
57902           * Triangle line shape with smallest interior angle on bottom and upside-
57902down L.
57903           */
57904          _main.default.prototype.endShape = function(mode) {
57905            _main.default._validateParameters('endShape', arguments);
57906            if (this._renderer.isP3D) {
57907              this._renderer.endShape(
57908                mode,
57909                isCurve,
57910                isBezier,
57911                isQuadratic,
57912                isContour,
57913                shapeKind
57914              );
57915            } else {
57916              if (vertices.length === 0) {
57917                return this;
57918              }
57919              if (!this._renderer._doStroke && !this._renderer._doFill) {
57920                return this;
57921              }
57922
57923              var closeShape = mode === constants.CLOSE;
57924
57925              // if the shape is closed, the first element is also the last element
57926              if (closeShape && !isContour) {
57927                vertices.push(vertices[0]);
57928              }
57929
57930              this._renderer.endShape(
57931                mode,
57932                vertices,
57933                isCurve,
57934                isBezier,
57935                isQuadratic,
57936                isContour,
57937                shapeKind
57938              );
57939
57940              // Reset some settings
57941              isCurve = false;
57942              isBezier = false;
57943              isQuadratic = false;
57944              isContour = false;
57945              isFirstContour = true;
57946
57947              // If the shape is closed, the first element was added as last element.
57948              // We must remove it again to prevent the list of vertices from growing
57949              // over successive calls to endShape(CLOSE)
57950              if (closeShape) {
57951                vertices.pop();
57952              }
57953            }
57954            return this;
57955          };
57956
57957          /**
57958           * Specifies vertex coordinates for quadratic Bezier curves. Each call to
57959           * quadraticVertex() defines the position of one control points and one
57960           * anchor point of a Bezier curve, adding a new segment to a line or shape.
57961           * The first time quadraticVertex() is used within a <a href="#/p5/beginShape">beginShape()</a> call, it
57962           * must be prefaced with a call to <a href="#/p5/vertex">vertex()</a> to set the first anchor point.
57963           * For WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.
57964           * 2D mode expects 4 parameters, while 3D mode expects 6 parameters
57965           * (including z coordinates).
57966           *
57967           * This function must be used between <a href="#/p5/beginShape">beginShape()</a> and <a href="#/p5/endShape">endShape()</a>
57968           * and only when there is no MODE or POINTS parameter specified to
57969           * <a href="#/p5/beginShape">beginShape()</a>.
57970           *
57971           * @method quadraticVertex
57972           * @param  {Number} cx x-coordinate for the control point
57973           * @param  {Number} cy y-coordinate for the control point
57974           * @param  {Number} x3 x-coordinate for the anchor point
57975           * @param  {Number} y3 y-coordinate for the anchor point
57976           * @chainable
57977           *
57978           * @example
57979           * <div>
57980           * <code>
57981           * strokeWeight(5);
57982           * point(20, 20);
57983           * point(80, 20);
57984           * point(50, 50);
57985           *
57986           * noFill();
57987           * strokeWeight(1);
57988           * beginShape();
57989           * vertex(20, 20);
57990           * quadraticVertex(80, 20, 50, 50);
57991           * endShape();
57992           * </code>
57993           * </div>
57994           *
57995           * <div>
57996           * <code>
57997           * strokeWeight(5);
57998           * point(20, 20);
57999           * point(80, 20);
58000           * point(50, 50);
58001           *
58002           * point(20, 80);
58003           * point(80, 80);
58004           * point(80, 60);
58005           *
58006           * noFill();
58007           * strokeWeight(1);
58008           * beginShape();
58009           * vertex(20, 20);
58010           * quadraticVertex(80, 20, 50, 50);
58011           * quadraticVertex(20, 80, 80, 80);
58012           * vertex(80, 60);
58013           * endShape();
58014           * </code>
58015           * </div>
58016           *
58017           * @alt
58018           * arched-shaped black line with 4 pixel thick stroke weight.
58019           * backwards s-shaped black line with 4 pixel thick stroke weight.
58020           */
58021
58022          /**
58023           * @method quadraticVertex
58024           * @param  {Number} cx
58025           * @param  {Number} cy
58026           * @param  {Number} cz z-coordinate for the control point (for WebGL mode)
58027           * @param  {Number} x3
58028           * @param  {Number} y3
58029           * @param  {Number} z3 z-coordinate for the anchor point (for WebGL mode)
58030           * @chainable
58031           *
58032           * @example
58033           * <div>
58034           * <code>
58035           * function setup() {
58036           *   createCanvas(100, 100, WEBGL);
58037           *   setAttributes('antialias', true);
58038           * }
58039           * function draw() {
58040           *   orbitControl();
58041           *   background(50);
58042           *   strokeWeight(4);
58043           *   stroke(255);
58044           *
58045           *   point(-35, -35);
58046           *   point(35, -35);
58047           *   point(0, 0);
58048           *   point(-35, 35);
58049           *   point(35, 35);
58050           *   point(35, 10);
58051           *
58052           *   strokeWeight(1);
58053           *   noFill();
58054           *
58055           *   beginShape();
58056           *   vertex(-35, -35);
58057           *   quadraticVertex(35, -35, 0, 0);
58058           *   quadraticVertex(-35, 35, 35, 35);
58059           *   vertex(35, 10);
58060           *   endShape();
58061           *
58062           *   beginShape();
58063           *   vertex(-35, -35, 20);
58064           *   quadraticVertex(35, -35, 20, 0, 0, 20);
58065           *   quadraticVertex(-35, 35, 20, 35, 35, 20);
58066           *   vertex(35, 10, 20);
58067           *   endShape();
58068           * }
58069           * </code>
58070           * </div>
58071           *
58072           * @alt
58073           * backwards s-shaped black line with the same s-shaped line in postive z-axis.
58074           */
58075          _main.default.prototype.quadraticVertex = function() {
58076            for (
58077              var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;
58078              _key3 < _len3;
58079              _key3++
58080            ) {
58081              args[_key3] = arguments[_key3];
58082            }
58083            _main.default._validateParameters('quadraticVertex', args
58083);
58084            if (this._renderer.isP3D) {
58085              var _this$_renderer4;
58086              (_this$_renderer4 = this._renderer).quadraticVertex.apply(
58087                _this$_renderer4,
58088                args
58089              );
58090            } else {
58091              //if we're drawing a contour, put the points into an
58092              // array for inside drawing
58093              if (this._contourInited) {
58094                var pt = {};
58095                pt.x = args[0];
58096                pt.y = args[1];
58097                pt.x3 = args[2];
58098                pt.y3 = args[3];
58099                pt.type = constants.QUADRATIC;
58100                this._contourVertices.push(pt);
58101
58102                return this;
58103              }
58104              if (vertices.length > 0) {
58105                isQuadratic = true;
58106                var vert = [];
58107                for (var i = 0; i < args.length; i++) {
58108                  vert[i] = args[i];
58109                }
58110                vert.isVert = false;
58111                if (isContour) {
58112                  contourVertices.push(vert);
58113                } else {
58114                  vertices.push(vert);
58115                }
58116              } else {
58117                _main.default._friendlyError(
58118                  'vertex() must be used once before calling quadraticVertex()',
58119                  'quadraticVertex'
58120                );
58121              }
58122            }
58123            return this;
58124          };
58125
58126          /**
58127           * All shapes are constructed by connecting a series of vertices. <a href="#/p5/vertex">vertex()</a>
58128           * is used to specify the vertex coordinates for points, lines, triangles,
58129           * quads, and polygons. It is used exclusively within the <a href="#/p5/beginShape">beginShape()</a> and
58130           * <a href="#/p5/endShape">endShape()</a> functions.
58131           *
58132           * @method vertex
58133           * @param  {Number} x x-coordinate of the vertex
58134           * @param  {Number} y y-coordinate of the vertex
58135           * @chainable
58136           * @example
58137           * <div>
58138           * <code>
58139           * strokeWeight(3);
58140           * beginShape(POINTS);
58141           * vertex(30, 20);
58142           * vertex(85, 20);
58143           * vertex(85, 75);
58144           * vertex(30, 75);
58145           * endShape();
58146           * </code>
58147           * </div>
58148           *
58149           * <div>
58150           * <code>
58151           * createCanvas(100, 100, WEBGL);
58152           * background(240, 240, 240);
58153           * fill(237, 34, 93);
58154           * noStroke();
58155           * beginShape();
58156           * vertex(0, 35);
58157           * vertex(35, 0);
58158           * vertex(0, -35);
58159           * vertex(-35, 0);
58160           * endShape();
58161           * </code>
58162           * </div>
58163           *
58164           * <div>
58165           * <code>
58166           * createCanvas(100, 100, WEBGL);
58167           * background(240, 240, 240);
58168           * fill(237, 34, 93);
58169           * noStroke();
58170           * beginShape();
58171           * vertex(-10, 10);
58172           * vertex(0, 35);
58173           * vertex(10, 10);
58174           * vertex(35, 0);
58175           * vertex(10, -8);
58176           * vertex(0, -35);
58177           * vertex(-10, -8);
58178           * vertex(-35, 0);
58179           * endShape();
58180           * </code>
58181           * </div>
58182           *
58183           * <div>
58184           * <code>
58185           * strokeWeight(3);
58186           * stroke(237, 34, 93);
58187           * beginShape(LINES);
58188           * vertex(10, 35);
58189           * vertex(90, 35);
58190           * vertex(10, 65);
58191           * vertex(90, 65);
58192           * vertex(35, 10);
58193           * vertex(35, 90);
58194           * vertex(65, 10);
58195           * vertex(65, 90);
58196           * endShape();
58197           * </code>
58198           * </div>
58199           *
58200           * <div>
58201           * <code>
58202           * // Click to change the number of sides.
58203           * // In WebGL mode, custom shapes will only
58204           * // display hollow fill sections when
58205           * // all calls to vertex() use the same z-value.
58206           *
58207           * let sides = 3;
58208           * let angle, px, py;
58209           *
58210           * function setup() {
58211           *   createCanvas(100, 100, WEBGL);
58212           *   setAttributes('antialias', true);
58213           *   fill(237, 34, 93);
58214           *   strokeWeight(3);
58215           * }
58216           *
58217           * function draw() {
58218           *   background(200);
58219           *   rotateX(frameCount * 0.01);
58220           *   rotateZ(frameCount * 0.01);
58221           *   ngon(sides, 0, 0, 80);
58222           * }
58223           *
58224           * function mouseClicked() {
58225           *   if (sides > 6) {
58226           *     sides = 3;
58227           *   } else {
58228           *     sides++;
58229           *   }
58230           * }
58231           *
58232           * function ngon(n, x, y, d) {
58233           *   beginShape(TESS);
58234           *   for (let i = 0; i < n + 1; i++) {
58235           *     angle = TWO_PI / n * i;
58236           *     px = x + sin(angle) * d / 2;
58237           *     py = y - cos(angle) * d / 2;
58238           *     vertex(px, py, 0);
58239           *   }
58240           *   for (let i = 0; i < n + 1; i++) {
58241           *     angle = TWO_PI / n * i;
58242           *     px = x + sin(angle) * d / 4;
58243           *     py = y - cos(angle) * d / 4;
58244           *     vertex(px, py, 0);
58245           *   }
58246           *   endShape();
58247           * }
58248           * </code>
58249           * </div>
58250           * @alt
58251           * 4 black points in a square shape in middle-right of canvas.
58252           * 4 points making a diamond shape.
58253           * 8 points making a star.
58254           * 8 points making 4 lines.
58255           * A rotating 3D shape with a hollow section in the middle.
58256           */
58257          /**
58258           * @method vertex
58259           * @param  {Number} x
58260           * @param  {Number} y
58261           * @param  {Number} z   z-coordinate of the vertex
58262           * @param  {Number} [u] the vertex's texture u-coordinate
58263           * @param  {Number} [v] the vertex's texture v-coordinate
58264           * @chainable
58265           */
58266          _main.default.prototype.vertex = function(x, y, moveTo, u, v) {
58267            if (this._renderer.isP3D) {
58268              var _this$_renderer5;
58269              (_this$_renderer5 = this._renderer).vertex.apply(_this$_renderer5, arguments);
58270            } else {
58271              var vert = [];
58272              vert.isVert = true;
58273              vert[0] = x;
58274              vert[1] = y;
58275              vert[2] = 0;
58276              vert[3] = 0;
58277              vert[4] = 0;
58278              vert[5] = this._renderer._getFill();
58279              vert[6] = this._renderer._getStroke();
58280
58281              if (moveTo) {
58282                vert.moveTo = moveTo;
58283              }
58284              if (isContour) {
58285                if (contourVertices.length === 0) {
58286                  vert.moveTo = true;
58287                }
58288                contourVertices.push(vert);
58289              } else {
58290                vertices.push(vert);
58291              }
58292            }
58293            return this;
58294          };
58295          var _default = _main.default;
58296          exports.default = _default;
58297        },
58298        { '../constants': 48, '../main': 59 }
58299      ],
58300      70: [
58301        function(_dereq_, module, exports) {
58302          'use strict';
58303          function _typeof(obj) {
58304            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
58305              _typeof = function _typeof(obj) {
58306                return typeof obj;
58307              };
58308            } else {
58309              _typeof = function _typeof(obj) {
58310                return obj &&
58311                  typeof Symbol === 'function' &&
58312                  obj.constructor === Symbol &&
58313                  obj !== Symbol.prototype
58314                  ? 'symbol'
58315                  : typeof obj;
58316              };
58317            }
58318            return _typeof(obj);
58319          } // requestAnim shim layer by Paul Irish
58320          // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
58321          // http://my.opera.com/emoller/blog/2011/12/20/
58322          // requestanimationframe-for-smart-er-animating
58323          // requestAnimationFrame polyfill by Erik Möller
58324          // fixes from Paul Irish and Tino Zijdel
58325          window.requestAnimationFrame = (function() {
58326            return (
58327              window.requestAnimationFrame ||
58328              window.webkitRequestAnimationFrame ||
58329              window.mozRequestAnimationFrame ||
58330              window.oRequestAnimationFrame ||
58331              window.msRequestAnimationFrame ||
58332              function(callback, element) {
58333                // should '60' here be framerate?
58334                window.setTimeout(callback, 1000 / 60);
58335              }
58336            );
58337          })();
58338
58339          /**
58340           * shim for Uint8ClampedArray.slice
58341           * (allows arrayCopy to work with pixels[])
58342           * with thanks to http://halfpapstudios.com/blog/tag/html5-canvas/
58343           * Enumerable set to false to protect for...in from
58344           * Uint8ClampedArray.prototype pollution.
58345           */
58346          (function() {
58347            if (
58348              typeof Uint8ClampedArray !== 'undefined' &&
58349              !Uint8ClampedArray.prototype.slice
58350            ) {
58351              Object.defineProperty(Uint8ClampedArray.prototype, 'slice', {
58352                value: Array.prototype.slice,
58353                writable: true,
58354                configurable: true,
58355                enumerable: false
58356              });
58357            }
58358          })();
58359
58360          /**
58361           * this is implementation of Object.assign() which is unavailable in
58362           * IE11 and (non-Chrome) Android browsers.
58363           * The assign() method is used to copy the values of all enumerable
58364           * own properties from one or more source objects to a target object.
58365           * It will return the target object.
58366           * Modified from https://github.com/ljharb/object.assign
58367           */
58368          (function() {
58369            if (!Object.assign) {
58370              var keys = Object.keys;
58371              var defineProperty = Object.defineProperty;
58372              var canBeObject = function canBeObject(obj) {
58373                return typeof obj !== 'undefined' && obj !== null;
58374              };
58375              var hasSymbols =
58376                typeof Symbol === 'function' && _typeof(Symbol()) === 'symbol';
58377              var propIsEnumerable = Object.prototype.propertyIsEnumerable;
58378              var isEnumerableOn = function isEnumerableOn(obj) {
58379                return function isEnumerable(prop) {
58380                  return propIsEnumerable.call(obj, prop);
58381                };
58382              };
58383
58384              // per ES6 spec, this function has to have a length of 2
58385              var assignShim = function assign(target, source1) {
58386                if (!canBeObject(target)) {
58387                  throw new TypeError('target must be an object');
58388                }
58389                var objTarget = Object(target);
58390                var s, source, i, props;
58391                for (s = 1; s < arguments.length; ++s) {
58392                  source = Object(arguments[s]);
58393                  props = keys(source);
58394                  if (hasSymbols && Object.getOwnPropertySymbols) {
58395                    props.push.apply(
58396                      props,
58397                      Object.getOwnPropertySymbols(source).filter(isEnumerableOn(source))
58398                    );
58399                  }
58400                  for (i = 0; i < props.length; ++i) {
58401                    objTarget[props[i]] = source[props[i]];
58402                  }
58403                }
58404                return objTarget;
58405              };
58406
58407              defineProperty(Object, 'assign', {
58408                value: assignShim,
58409                configurable: true,
58410                enumerable: false,
58411                writable: true
58412              });
58413            }
58414          })();
58415        },
58416        {}
58417      ],
58418      71: [
58419        function(_dereq_, module, exports) {
58420          'use strict';
58421          Object.defineProperty(exports, '__esModule', { value: true });
58422          exports.default = void 0;
58423
58424          var _main = _interopRequireDefault(_dereq_('./main'));
58425          function _interopRequireDefault(obj) {
58426            return obj && obj.__esModule ? obj : { default: obj };
58427          }
58428          /**
58429           * @module Structure
58430           * @submodule Structure
58431           * @for p5
58432           * @requires core
58433           */ /**
58434                                                                                                                                                         * Stops p5.js from continuously executing the code within <a href="#/p5/draw">draw()</a>.
58435                                                                                                                                                         * If <a href="#/p5/loop">loop()</a> is called, the code in <a href="#/p5/draw">draw()</a>
58436                                                                                                                                                         * begins to run continuously again. If using <a href="#/p5/noLoop">noLoop()</a>
58437                                                                                                                                                         * in <a href="#/p5/setup">setup()</a>, it should be the last line inside the block.
58438                                                                                                                                                         *
58439                                                                                                                                                         * When <a href="#/p5/noLoop">noLoop()</a> is used, it's not possible to manipulate
58440                                                                                                                                                         * or access the screen inside event handling functions such as
58441                                                                                                                                                         * <a href="#/p5/mousePressed">mousePressed()</a> or
58442                                                                                                                                                         * <a href="#/p5/keyPressed">keyPressed()</a>. Instead, use those functions to
58443                                                                                                                                                         * call <a href="#/p5/redraw">redraw()</a> or <a href="#/p5/loop">loop()</a>,
58444                                                                                                                                                         * which will run <a href="#/p5/draw">draw()</a>, which can update the screen
58445                                                                                                                                                         * properly. This means that when <a href="#/p5/noLoop">noLoop()</a> has been
58446                                                                                                                                                         * called, no drawing can happen, and functions like <a href="#/p5/saveFrame">saveFrame()</a>
58447                                                                                                                                                         * or <a href="#/p5/loadPixels">loadPixels()</a> may not be used.
58448                                                                                                                                                         *
58449                                                                                                                                                         * Note that if the sketch is resized, <a href="#/p5/redraw">redraw()</a> will
58450                                                                                                                                                         * be called to update the sketch, even after <a href="#/p5/noLoop">noLoop()</a>
58451                                                                                                                                                         * has been specified. Otherwise, the sketch would enter an odd state until
58452                                                                                                                                                         * <a href="#/p5/loop">loop()</a> was called.
58453                                                                                                                                                         *
58454                                                                                                                                                         * Use <a href="#/p5/isLooping">isLooping()</a> to check current state of loop().
58455                                                                                                                                                         *
58456                                                                                                                                                         * @method noLoop
58457                                                                                                                                                         * @example
58458                                                                                                                                                         * <div>
58459                                                                                                                                                         * <code>
58460                                                                                                                                                         * function setup() {
58461                                                                                                                                                         *   createCanvas(100, 100);
58462                                                                                                                                                         *   background(200);
58463                                                                                                                                                         *   noLoop();
58464                                                                                                                                                         * }
58465                                                                                                                                                        
58466                                                                                                                                                         * function draw() {
58467                                                                                                                                                         *   line(10, 10, 90, 90);
58468                                                                                                                                                         * }
58469                                                                                                                                                         * </code>
58470                                                                                                                                                         * </div>
58471                                                                                                                                                         *
58472                                                                                                                                                         * <div>
58473                                                                                                                                                         * <code>
58474                                                                                                                                                         * let x = 0;
58475                                                                                                                                                         * function setup() {
58476                                                                                                                                                         *   createCanvas(100, 100);
58477                                                                                                                                                         * }
58478                                                                                                                                                         *
58479                                                                                                                                                         * function draw() {
58480                                                                                                                                                         *   background(204);
58481                                                                                                                                                         *   x = x + 0.1;
58482                                                                                                                                                         *   if (x > width) {
58483                                                                                                                                                         *     x = 0;
58484                                                                                                                                                         *   }
58485                                                                                                                                                         *   line(x, 0, x, height);
58486                                                                                                                                                         * }
58487                                                                                                                                                         *
58488                                                                                                                                                         * function mousePressed() {
58489                                                                                                                                                         *   noLoop();
58490                                                                                                                                                         * }
58491                                                                                                                                                         *
58492                                                                                                                                                         * function mouseReleased() {
58493                                                                                                                                                         *   loop();
58494                                                                                                                                                         * }
58495                                                                                                                                                         * </code>
58496                                                                                                                                                         * </div>
58497                                                                                                                                                         *
58498                                                                                                                                                         * @alt
58499                                                                                                                                                         * 113 pixel long line extending from top-left to bottom right of canvas.
58500                                                                                                                                                         * horizontal line moves slowly from left. Loops but stops on mouse press.
58501                                                                                                                                                         */ _main.default.prototype.noLoop = function() {
58502            this._loop = false;
58503          };
58504
58505          /**
58506           * By default, p5.js loops through draw() continuously, executing the code within
58507           * it. However, the <a href="#/p5/draw">draw()</a> loop may be stopped by calling
58508           * <a href="#/p5/noLoop">noLoop()</a>. In that case, the <a href="#/p5/draw">draw()</a>
58509           * loop can be resumed with loop().
58510           *
58511           * Avoid calling loop() from inside setup().
58512           *
58513           * Use <a href="#/p5/isLooping">isLooping()</a> to check current state of loop().
58514           *
58515           * @method loop
58516           * @example
58517           * <div>
58518           * <code>
58519           * let x = 0;
58520           * function setup() {
58521           *   createCanvas(100, 100);
58522           *   noLoop();
58523           * }
58524           *
58525           * function draw() {
58526           *   background(204);
58527           *   x = x + 0.1;
58528           *   if (x > width) {
58529           *     x = 0;
58530           *   }
58531           *   line(x, 0, x, height);
58532           * }
58533           *
58534           * function mousePressed() {
58535           *   loop();
58536           * }
58537           *
58538           * function mouseReleased() {
58539           *   noLoop();
58540           * }
58541           * </code>
58542           * </div>
58543           *
58544           * @alt
58545           * horizontal line moves slowly from left. Loops but stops on mouse press.
58546           */
58547          _main.default.prototype.loop = function() {
58548            if (!this._loop) {
58549              this._loop = true;
58550              if (this._setupDone) {
58551                this._draw();
58552              }
58553            }
58554          };
58555
58556          /**
58557           * By default, p5.js loops through <a href="#/p5/draw">draw()</a> continuously,
58558           * executing the code within it. If the sketch is stopped with
58559           * <a href="#/p5/noLoop">noLoop()</a> or resumed with <a href="#/p5/loop">loop()</a>,
58560           * isLooping() returns the current state for use within custom event handlers.
58561           *
58562           * @method isLooping
58563           * @example
58564           * <div>
58565           * <code>
58566           * let checkbox, button, colBG, colFill;
58567           *
58568           * function setup() {
58569           *   createCanvas(100, 100);
58570           *
58571           *   button = createButton('Colorize if loop()');
58572           *   button.position(0, 120);
58573           *   button.mousePressed(changeBG);
58574           *
58575           *   checkbox = createCheckbox('loop()', true);
58576           *   checkbox.changed(checkLoop);
58577           *
58578           *   colBG = color(0);
58579           *   colFill = color(255);
58580           * }
58581           *
58582           * function changeBG() {
58583           *   if (isLooping()) {
58584           *     colBG = color(random(255), random(255), random(255));
58585           *     colFill = color(random(255), random(255), random(255));
58586           *   }
58587           * }
58588           *
58589           * function checkLoop() {
58590           *   if (this.checked()) {
58591           *     loop();
58592           *   } else {
58593           *     noLoop();
58594           *   }
58595           * }
58596           *
58597           * function draw() {
58598           *   background(colBG);
58599           *   fill(colFill);
58600           *   ellipse(frameCount % width, height / 2, 50);
58601           * }
58602           * </code>
58603           * </div>
58604           *
58605           * @alt
58606           * Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().
58607           * Button colorizes sketch if isLooping().
58608           *
58609           */
58610          _main.default.prototype.isLooping = function() {
58611            return this._loop;
58612          };
58613
58614          /**
58615           * The <a href="#/p5/push">push()</a> function saves the current drawing style
58616           * settings and transformations, while <a href="#/p5/pop">pop()</a> restores these
58617           * settings. Note that these functions are always used together. They allow you to
58618           * change the style and transformation settings and later return to what you had.
58619           * When a new state is started with <a href="#/p5/push">push()</a>, it builds on
58620           * the current style and transform information. The <a href="#/p5/push">push()</a>
58621           * and <a href="#/p5/pop">pop()</a> functions can be embedded to provide more
58622           * control. (See the second example for a demonstration.)
58623           *
58624           * <a href="#/p5/push">push()</a> stores information related to the current transformation state
58625           * and style settings controlled by the following functions:
58626           * <a href="#/p5/fill">fill()</a>,
58627           * <a href="#/p5/noFill">noFill()</a>,
58628           * <a href="#/p5/noStroke">noStroke()</a>,
58629           * <a href="#/p5/stroke">stroke()</a>,
58630           * <a href="#/p5/tint">tint()</a>,
58631           * <a href="#/p5/noTint">noTint()</a>,
58632           * <a href="#/p5/strokeWeight">
58632strokeWeight()</a>,
58633           * <a href="#/p5/strokeCap">strokeCap()</a>,
58634           * <a href="#/p5/strokeJoin">strokeJoin()</a>,
58635           * <a href="#/p5/imageMode">imageMode()</a>,
58636           * <a href="#/p5/rectMode">rectMode()</a>,
58637           * <a href="#/p5/ellipseMode">ellipseMode()</a>,
58638           * <a href="#/p5/colorMode">colorMode()</a>,
58639           * <a href="#/p5/textAlign">textAlign()</a>,
58640           * <a href="#/p5/textFont">textFont()</a>,
58641           * <a href="#/p5/textSize">textSize()</a>,
58642           * <a href="#/p5/textLeading">textLeading()</a>,
58643           * <a href="#/p5/applyMatrix">applyMatrix()</a>,
58644           * <a href="#/p5/resetMatrix">resetMatrix()</a>,
58645           * <a href="#/p5/rotate">rotate()</a>,
58646           * <a href="#/p5/scale">scale()</a>,
58647           * <a href="#/p5/shearX">shearX()</a>,
58648           * <a href="#/p5/shearY">shearY()</a>,
58649           * <a href="#/p5/translate">translate()</a>,
58650           * <a href="#/p5/noiseSeed">noiseSeed()</a>.
58651           *
58652           * In WEBGL mode additional style settings are stored. These are controlled by the
58653           * following functions: <a href="#/p5/setCamera">setCamera()</a>,
58654           * <a href="#/p5/ambientLight">ambientLight()</a>,
58655           * <a href="#/p5/directionalLight">directionalLight()</a>,
58656           * <a href="#/p5/pointLight">pointLight()</a>, <a href="#/p5/texture">texture()</a>,
58657           * <a href="#/p5/specularMaterial">specularMaterial()</a>,
58658           * <a href="#/p5/shininess">shininess()</a>,
58659           * <a href="#/p5/normalMaterial">normalMaterial()</a>
58660           * and <a href="#/p5/shader">shader()</a>.
58661           *
58662           * @method push
58663           * @example
58664           * <div>
58665           * <code>
58666           * ellipse(0, 50, 33, 33); // Left circle
58667           *
58668           * push(); // Start a new drawing state
58669           * strokeWeight(10);
58670           * fill(204, 153, 0);
58671           * translate(50, 0);
58672           * ellipse(0, 50, 33, 33); // Middle circle
58673           * pop(); // Restore original state
58674           *
58675           * ellipse(100, 50, 33, 33); // Right circle
58676           * </code>
58677           * </div>
58678           *
58679           * <div>
58680           * <code>
58681           * ellipse(0, 50, 33, 33); // Left circle
58682           *
58683           * push(); // Start a new drawing state
58684           * strokeWeight(10);
58685           * fill(204, 153, 0);
58686           * ellipse(33, 50, 33, 33); // Left-middle circle
58687           *
58688           * push(); // Start another new drawing state
58689           * stroke(0, 102, 153);
58690           * ellipse(66, 50, 33, 33); // Right-middle circle
58691           * pop(); // Restore previous state
58692           *
58693           * pop(); // Restore original state
58694           *
58695           * ellipse(100, 50, 33, 33); // Right circle
58696           * </code>
58697           * </div>
58698           *
58699           * @alt
58700           * Gold ellipse + thick black outline @center 2 white ellipses on left and right.
58701           * 2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.
58702           */
58703          _main.default.prototype.push = function() {
58704            this._styles.push({
58705              props: {
58706                _colorMode: this._colorMode
58707              },
58708
58709              renderer: this._renderer.push()
58710            });
58711          };
58712
58713          /**
58714           * The <a href="#/p5/push">push()</a> function saves the current drawing style
58715           * settings and transformations, while <a href="#/p5/pop">pop()</a> restores
58716           * these settings. Note that these functions are always used together. They allow
58717           * you to change the style and transformation settings and later return to what
58718           * you had. When a new state is started with <a href="#/p5/push">push()</a>, it
58719           * builds on the current style and transform information. The <a href="#/p5/push">push()</a>
58720           * and <a href="#/p5/pop">pop()</a> functions can be embedded to provide more
58721           * control. (See the second example for a demonstration.)
58722           *
58723           * <a href="#/p5/push">push()</a> stores information related to the current transformation state
58724           * and style settings controlled by the following functions:
58725           * <a href="#/p5/fill">fill()</a>,
58726           * <a href="#/p5/noFill">noFill()</a>,
58727           * <a href="#/p5/noStroke">noStroke()</a>,
58728           * <a href="#/p5/stroke">stroke()</a>,
58729           * <a href="#/p5/tint">tint()</a>,
58730           * <a href="#/p5/noTint">noTint()</a>,
58731           * <a href="#/p5/strokeWeight">
58731strokeWeight()</a>,
58732           * <a href="#/p5/strokeCap">strokeCap()</a>,
58733           * <a href="#/p5/strokeJoin">strokeJoin()</a>,
58734           * <a href="#/p5/imageMode">imageMode()</a>,
58735           * <a href="#/p5/rectMode">rectMode()</a>,
58736           * <a href="#/p5/ellipseMode">ellipseMode()</a>,
58737           * <a href="#/p5/colorMode">colorMode()</a>,
58738           * <a href="#/p5/textAlign">textAlign()</a>,
58739           * <a href="#/p5/textFont">textFont()</a>,
58740           * <a href="#/p5/textSize">textSize()</a>,
58741           * <a href="#/p5/textLeading">textLeading()</a>,
58742           * <a href="#/p5/applyMatrix">applyMatrix()</a>,
58743           * <a href="#/p5/resetMatrix">resetMatrix()</a>,
58744           * <a href="#/p5/rotate">rotate()</a>,
58745           * <a href="#/p5/scale">scale()</a>,
58746           * <a href="#/p5/shearX">shearX()</a>,
58747           * <a href="#/p5/shearY">shearY()</a>,
58748           * <a href="#/p5/translate">translate()</a>,
58749           * <a href="#/p5/noiseSeed">noiseSeed()</a>.
58750           *
58751           * In WEBGL mode additional style settings are stored. These are controlled by
58752           * the following functions:
58753           * <a href="#/p5/setCamera">setCamera()</a>,
58754           * <a href="#/p5/ambientLight">ambientLight()</a>,
58755           * <a href="#/p5/directionalLight">directionalLight()</a>,
58756           * <a href="#/p5/pointLight">pointLight()</a>,
58757           * <a href="#/p5/texture">texture()</a>,
58758           * <a href="#/p5/specularMaterial">specularMaterial()</a>,
58759           * <a href="#/p5/shininess">shininess()</a>,
58760           * <a href="#/p5/normalMaterial">normalMaterial()</a> and
58761           * <a href="#/p5/shader">shader()</a>.
58762           *
58763           * @method pop
58764           * @example
58765           * <div>
58766           * <code>
58767           * ellipse(0, 50, 33, 33); // Left circle
58768           *
58769           * push(); // Start a new drawing state
58770           * translate(50, 0);
58771           * strokeWeight(10);
58772           * fill(204, 153, 0);
58773           * ellipse(0, 50, 33, 33); // Middle circle
58774           * pop(); // Restore original state
58775           *
58776           * ellipse(100, 50, 33, 33); // Right circle
58777           * </code>
58778           * </div>
58779           *
58780           * <div>
58781           * <code>
58782           * ellipse(0, 50, 33, 33); // Left circle
58783           *
58784           * push(); // Start a new drawing state
58785           * strokeWeight(10);
58786           * fill(204, 153, 0);
58787           * ellipse(33, 50, 33, 33); // Left-middle circle
58788           *
58789           * push(); // Start another new drawing state
58790           * stroke(0, 102, 153);
58791           * ellipse(66, 50, 33, 33); // Right-middle circle
58792           * pop(); // Restore previous state
58793           *
58794           * pop(); // Restore original state
58795           *
58796           * ellipse(100, 50, 33, 33); // Right circle
58797           * </code>
58798           * </div>
58799           *
58800           * @alt
58801           * Gold ellipse + thick black outline @center 2 white ellipses on left and right.
58802           * 2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.
58803           */
58804          _main.default.prototype.pop = function() {
58805            var style = this._styles.pop();
58806            if (style) {
58807              this._renderer.pop(style.renderer);
58808              Object.assign(this, style.props);
58809            } else {
58810              console.warn('pop() was called without matching push()');
58811            }
58812          };
58813
58814          /**
58815           * Executes the code within <a href="#/p5/draw">draw()</a> one time. This
58816           * function allows the program to update the display window only when necessary,
58817           * for example when an event registered by <a href="#/p5/mousePressed">mousePressed()</a>
58818           * or <a href="#/p5/keyPressed">keyPressed()</a> occurs.
58819           *
58820           * In structuring a program, it only makes sense to call <a href="#/p5/redraw">redraw()</a>
58821           * within events such as <a href="#/p5/mousePressed">mousePressed()</a>. This
58822           * is because <a href="#/p5/redraw">redraw()</a> does not run
58823           * <a href="#/p5/draw">draw()</a> immediately (it only sets a flag that indicates
58824           * an update is needed).
58825           *
58826           * The <a href="#/p5/redraw">redraw()</a> function does not work properly when
58827           * called inside <a href="#/p5/draw">draw()</a>.To enable/disable animations,
58828           * use <a href="#/p5/loop">loop()</a> and <a href="#/p5/noLoop">noLoop()</a>.
58829           *
58830           * In addition you can set the number of redraws per method call. Just
58831           * add an integer as single parameter for the number of redraws.
58832           *
58833           * @method redraw
58834           * @param  {Integer} [n] Redraw for n-times. The default value is 1.
58835           * @example
58836           * <div><code>
58837           * let x = 0;
58838           *
58839           * function setup() {
58840           *   createCanvas(100, 100);
58841           *   noLoop();
58842           * }
58843           *
58844           * function draw() {
58845           *   background(204);
58846           *   line(x, 0, x, height);
58847           * }
58848           *
58849           * function mousePressed() {
58850           *   x += 1;
58851           *   redraw();
58852           * }
58853           * </code>
58854           * </div>
58855           *
58856           * <div class='norender'>
58857           * <code>
58858           * let x = 0;
58859           *
58860           * function setup() {
58861           *   createCanvas(100, 100);
58862           *   noLoop();
58863           * }
58864           *
58865           * function draw() {
58866           *   background(204);
58867           *   x += 1;
58868           *   line(x, 0, x, height);
58869           * }
58870           *
58871           * function mousePressed() {
58872           *   redraw(5);
58873           * }
58874           * </code>
58875           * </div>
58876           *
58877           * @alt
58878           * black line on far left of canvas
58879           * black line on far left of canvas
58880           */
58881          _main.default.prototype.redraw = function(n) {
58882            if (this._inUserDraw || !this._setupDone) {
58883              return;
58884            }
58885
58886            var numberOfRedraws = parseInt(n);
58887            if (isNaN(numberOfRedraws) || numberOfRedraws < 1) {
58888              numberOfRedraws = 1;
58889            }
58890
58891            var context = this._isGlobal ? window : this;
58892            if (typeof context.draw === 'function') {
58893              if (typeof context.setup === 'undefined') {
58894                context.scale(context._pixelDensity, context._pixelDensity);
58895              }
58896              var callMethod = function callMethod(f) {
58897                f.call(context);
58898              };
58899              for (var idxRedraw = 0; idxRedraw < numberOfRedraws; idxRedraw++) {
58900                context.resetMatrix();
58901                if (this._accessibleOutputs.grid || this._accessibleOutputs.text) {
58902                  this._updateAccsOutput();
58903                }
58904                if (context._renderer.isP3D) {
58905                  context._renderer._update();
58906                }
58907                context._setProperty('frameCount', context.frameCount + 1);
58908                context._registeredMethods.pre.forEach(callMethod);
58909                this._inUserDraw = true;
58910                try {
58911                  context.draw();
58912                } finally {
58913                  this._inUserDraw = false;
58914                }
58915                context._registeredMethods.post.forEach(callMethod);
58916              }
58917            }
58918          };
58919
58920          /**
58921           * The `p5()` constructor enables you to activate "instance mode" instead of normal
58922           * "global mode". This is an advanced topic. A short description and example is
58923           * included below. Please see
58924           * <a target="blank" href="https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be">
58925           * Dan Shiffman's Coding Train video tutorial</a> or this
58926           * <a target="blank" href="https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace">tutorial page</a>
58927           * for more info.
58928           *
58929           * By default, all p5.js functions are in the global namespace (i.e. bound to the window
58930           * object), meaning you can call them simply `ellipse()`, `fill()`, etc. However, this
58931           * might be inconvenient if you are mixing with other JS libraries (synchronously or
58932           * asynchronously) or writing long programs of your own. p5.js currently supports a
58933           * way around this problem called "instance mode". In instance mode, all p5 functions
58934           * are bound up in a single variable instead of polluting your global namespace.
58935           *
58936           * Optionally, you can specify a default container for the canvas and any other elements
58937           * to append to with a second argument. You can give the ID of an element in your html,
58938           * or an html node itself.
58939           *
58940           * Note that creating instances like this also allows you to have more than one p5 sketch on
58941           * a single web page, as they will each be wrapped up with their own set up variables. Of
58942           * course, you could also use iframes to have multiple sketches in global mode.
58943           *
58944           * @method p5
58945           * @param {Object} sketch a function containing a p5.js sketch
58946           * @param {String|Object} node ID or pointer to HTML DOM node to contain sketch in
58947           * @example
58948           * <div class='norender'><code>
58949           * const s = p => {
58950           *   let x = 100;
58951           *   let y = 100;
58952           *
58953           *   p.setup = function() {
58954           *     p.createCanvas(700, 410);
58955           *   };
58956           *
58957           *   p.draw = function() {
58958           *     p.background(0);
58959           *     p.fill(255);
58960           *     p.rect(x, y, 50, 50);
58961           *   };
58962           * };
58963           *
58964           * new p5(s); // invoke p5
58965           * </code></div>
58966           *
58967           * @alt
58968           * white rectangle on black background
58969           */ var _default = _main.default;
58970          exports.default = _default;
58971        },
58972        { './main': 59 }
58973      ],
58974      72: [
58975        function(_dereq_, module, exports) {
58976          'use strict';
58977          Object.defineProperty(exports, '__esModule', { value: true });
58978          exports.default = void 0;
58979
58980          var _main = _interopRequireDefault(_dereq_('./main'));
58981          function _interopRequireDefault(obj) {
58982            return obj && obj.__esModule ? obj : { default: obj };
58983          }
58984          /**
58985           * @module Transform
58986           * @submodule Transform
58987           * @for p5
58988           * @requires core
58989           * @requires constants
58990           */ /**
58991           * Multiplies the current matrix by the one specified through the parameters.
58992           * This is a powerful operation that can perform the equivalent of translate,
58993           * scale, shear and rotate all at once. You can learn more about transformation
58994           * matrices on <a href="https://en.wikipedia.org/wiki/Transformation_matrix">
58995           * Wikipedia</a>.
58996           *
58997           * The naming of the arguments here follows the naming of the <a href=
58998           * "https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform">
58999           * WHATWG specification</a> and corresponds to a
59000           * transformation matrix of the
59001           * form:
59002           *
59003           * > <img style="max-width: 150px" src="assets/transformation-matrix.png"
59004           * alt="The transformation matrix used when applyMatrix is called"/>
59005           *
59006           * @method applyMatrix
59007           * @param  {Number} a numbers which define the 2x3 matrix to be multiplied
59008           * @param  {Number} b numbers which define the 2x3 matrix to be multiplied
59009           * @param  {Number} c numbers which define the 2x3 matrix to be multiplied
59010           * @param  {Number} d numbers which define the 2x3 matrix to be multiplied
59011           * @param  {Number} e numbers which define the 2x3 matrix to be multiplied
59012           * @param  {Number} f numbers which define the 2x3 matrix to be multiplied
59013           * @chainable
59014           * @example
59015           * <div>
59016           * <code>
59017           * function setup() {
59018           *   frameRate(10);
59019           *   rectMode(CENTER);
59020           * }
59021           *
59022           * function draw() {
59023           *   let step = frameCount % 20;
59024           *   background(200);
59025           *   // Equivalent to translate(x, y);
59026           *   applyMatrix(1, 0, 0, 1, 40 + step, 50);
59027           *   rect(0, 0, 50, 50);
59028           * }
59029           * </code>
59030           * </div>
59031           *
59032           * <div>
59033           * <code>
59034           * function setup() {
59035           *   frameRate(10);
59036           *   rectMode(CENTER);
59037           * }
59038           *
59039           * function draw() {
59040           *   let step = frameCount % 20;
59041           *   background(200);
59042           *   translate(50, 50);
59043           *   // Equivalent to scale(x, y);
59044           *   applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);
59045           *   rect(0, 0, 50, 50);
59046           * }
59047           * </code>
59048           * </div>
59049           *
59050           * <div>
59051           * <code>
59052           * function setup() {
59053           *   frameRate(10);
59054           *   rectMode(CENTER);
59055           * }
59056           *
59057           * function draw() {
59058           *   let step = frameCount % 20;
59059           *   let angle = map(step, 0, 20, 0, TWO_PI);
59060           *   let cos_a = cos(angle);
59061           *   let sin_a = sin(angle);
59062           *   background(200);
59063           *   translate(50, 50);
59064           *   // Equivalent to rotate(angle);
59065           *   applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);
59066           *   rect(0, 0, 50, 50);
59067           * }
59068           * </code>
59069           * </div>
59070           *
59071           * <div>
59072           * <code>
59073           * function setup() {
59074           *   frameRate(10);
59075           *   rectMode(CENTER);
59076           * }
59077           *
59078           * function draw() {
59079           *   let step = frameCount % 20;
59080           *   let angle = map(step, 0, 20, -PI / 4, PI / 4);
59081           *   background(200);
59082           *   translate(50, 50);
59083           *   // equivalent to shearX(angle);
59084           *   let shear_factor = 1 / tan(PI / 2 - angle);
59085           *   applyMatrix(1, 0, shear_factor, 1, 0, 0);
59086           *   rect(0, 0, 50, 50);
59087           * }
59088           * </code>
59089           * </div>
59090           *
59091           * <div modernizr='webgl'>
59092           * <code>
59093           * function setup() {
59094           *   createCanvas(100, 100, WEBGL);
59095           *   noFill();
59096           * }
59097           *
59098           * function draw() {
59099           *   background(200);
59100           *   rotateY(PI / 6);
59101           *   stroke(153);
59102           *   box(35);
59103           *   let rad = millis() / 1000;
59104           *   // Set rotation angles
59105           *   let ct = cos(rad);
59106           *   let st = sin(rad);
59107           *   // Matrix for rotation around the Y axis
59108           *   // prettier-ignore
59109           *   applyMatrix(  ct, 0.0,  st,  0.0,
59110           *                0.0, 1.0, 0.0,  0.0,
59111           *                -st, 0.0,  ct,  0.0,
59112           *                0.0, 0.0, 0.0,  1.0);
59113           *   stroke(255);
59114           *   box(50);
59115           * }
59116           * </code>
59117           * </div>
59118           *
59119           * @alt
59120           * A rectangle translating to the right
59121           * A rectangle shrinking to the center
59122           * A rectangle rotating clockwise about the center
59123           * A rectangle shearing
59124           */ _main.default.prototype.applyMatrix = function(a, b, c, d, e, f) {
59125            var _this$_renderer;
59126            (_this$_renderer = this._renderer).applyMatrix.apply(
59127              _this$_renderer,
59128              arguments
59129            );
59130            return this;
59131          };
59132
59133          /**
59134           * Replaces the current matrix with the identity matrix.
59135           *
59136           * @method resetMatrix
59137           * @chainable
59138           * @example
59139           * <div>
59140           * <code>
59141           * translate(50, 50);
59142           * applyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);
59143           * rect(0, 0, 20, 20);
59144           * // Note that the translate is also reset.
59145           * resetMatrix();
59146           * rect(0, 0, 20, 20);
59147           * </code>
59148           * </div>
59149           *
59150           * @alt
59151           * A rotated retangle in the center with another at the top left corner
59152           */
59153          _main.default.prototype.resetMatrix = function() {
59154            this._renderer.resetMatrix();
59155            return this;
59156          };
59157
59158          /**
59159           * Rotates a shape by the amount specified by the angle parameter. This
59160           * function accounts for <a href="#/p5/angleMode">angleMode</a>, so angles
59161           * can be entered in either RADIANS or DEGREES.
59162           *
59163           * Objects are always rotated around their relative position to the
59164           * origin and positive numbers rotate objects in a clockwise direction.
59165           * Transformations apply to everything that happens after and subsequent
59166           * calls to the function accumulates the effect. For example, calling
59167           * rotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).
59168           * All tranformations are reset when <a href="#/p5/draw">draw()</a> begins again.
59169           *
59170           * Technically, <a href="#/p5/rotate">rotate()</a> multiplies the current transformation matrix
59171           * by a rotation matrix. This function can be further controlled by
59172           * the <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a>.
59173           *
59174           * @method rotate
59175           * @param  {Number} angle the angle of rotation, specified in radians
59176           *                        or degrees, depending on current angleMode
59177           * @param  {p5.Vector|Number[]} [axis] (in 3d) the axis to rotate around
59178           * @chainable
59179           * @example
59180           * <div>
59181           * <code>
59182           * translate(width / 2, height / 2);
59183           * rotate(PI / 3.0);
59184           * rect(-26, -26, 52, 52);
59185           * </code>
59186           * </div>
59187           *
59188           * @alt
59189           * white 52x52 rect with black outline at center rotated counter 45 degrees
59190           */
59191          _main.default.prototype.rotate = function(angle, axis) {
59192            _main.default._validateParameters('rotate', arguments);
59193            this._renderer.rotate(this._toRadians(angle), axis);
59194            return this;
59195          };
59196
59197          /**
59198           * Rotates a shape around X axis by the amount specified in angle parameter.
59199           * The angles can be entered in either RADIANS or DEGREES.
59200           *
59201           * Objects are always rotated around their relative position to the
59202           * origin and positive numbers rotate objects in a clockwise direction.
59203           * All tranformations are reset when <a href="#/p5/draw">draw()</a> begins again.
59204           *
59205           * @method  rotateX
59206           * @param  {Number} angle the angle of rotation, specified in radians
59207           *                        or degrees, depending on current angleMode
59208           * @chainable
59209           * @example
59210           * <div modernizr='webgl'>
59211           * <code>
59212           * function setup() {
59213           *   createCanvas(100, 100, WEBGL);
59214           * }
59215           * function draw() {
59216           *   background(255);
59217           *   rotateX(millis() / 1000);
59218           *   box();
59219           * }
59220           * </code>
59221           * </div>
59222           *
59223           * @alt
59224           * 3d box rotating around the x axis.
59225           */
59226          _main.default.prototype.rotateX = function(angle) {
59227            this._assert3d('rotateX');
59228            _main.default._validateParameters('rotateX', arguments);
59229            this._renderer.rotateX(this._toRadians(angle));
59230            return this;
59231          };
59232
59233          /**
59234           * Rotates a shape around Y axis by the amount specified in angle parameter.
59235           * The angles can be entered in either RADIANS or DEGREES.
59236           *
59237           * Objects are always rotated around their relative position to the
59238           * origin and positive numbers rotate objects in a clockwise direction.
59239           * All tranformations are reset when <a href="#/p5/draw">draw()</a> begins again.
59240           *
59241           * @method rotateY
59242           * @param  {Number} angle the angle of rotation, specified in radians
59243           *                        or degrees, depending on current angleMode
59244           * @chainable
59245           * @example
59246           * <div modernizr='webgl'>
59247           * <code>
59248           * function setup() {
59249           *   createCanvas(100, 100, WEBGL);
59250           * }
59251           * function draw() {
59252           *   background(255);
59253           *   rotateY(millis() / 1000);
59254           *   box();
59255           * }
59256           * </code>
59257           * </div>
59258           *
59259           * @alt
59260           * 3d box rotating around the y axis.
59261           */
59262          _main.default.prototype.rotateY = function(angle) {
59263            this._assert3d('rotateY');
59264            _main.default._validateParameters('rotateY', arguments);
59265            this._renderer.rotateY(this._toRadians(angle));
59266            return this;
59267          };
59268
59269          /**
59270           * Rotates a shape around Z axis by the amount specified in angle parameter.
59271           * The angles can be entered in either RADIANS or DEGREES.
59272           *
59273           * This method works in WEBGL mode only.
59274           *
59275           * Objects are always rotated around their relative position to the
59276           * origin and positive numbers rotate objects in a clockwise direction.
59277           * All tranformations are reset when <a href="#/p5/draw">draw()</a> begins again.
59278           *
59279           * @method rotateZ
59280           * @param  {Number} angle the angle of rotation, specified in radians
59281           *                        or degrees, depending on current angleMode
59282           * @chainable
59283           * @example
59284           * <div modernizr='webgl'>
59285           * <code>
59286           * function setup() {
59287           *   createCanvas(100, 100, WEBGL);
59288           * }
59289           * function draw() {
59290           *   background(255);
59291           *   rotateZ(millis() / 1000);
59292           *   box();
59293           * }
59294           * </code>
59295           * </div>
59296           *
59297           * @alt
59298           * 3d box rotating around the z axis.
59299           */
59300          _main.default.prototype.rotateZ = function(angle) {
59301            this._assert3d('rotateZ');
59302            _main.default._validateParameters('rotateZ', arguments);
59303            this._renderer.rotateZ(this._toRadians(angle));
59304            return this;
59305          };
59306
59307          /**
59308           * Increases or decreases the size of a shape by expanding or contracting
59309           * vertices. Objects always scale from their relative origin to the
59310           * coordinate system. Scale values are specified as decimal percentages.
59311           * For example, the function call scale(2.0) increases the dimension of a
59312           * shape by 200%.
59313           *
59314           * Transformations apply to everything that happens after and subsequent
59315           * calls to the function multiply the effect. For example, calling scale(2.0)
59316           * and then scale(1.5) is the same as scale(3.0). If <a href="#/p5/scale">scale()</a> is called
59317           * within <a href="#/p5/draw">draw()</a>, the transformation is reset when the loop begins again.
59318           *
59319           * Using this function with the z parameter is only available in WEBGL mode.
59320           * This function can be further controlled with <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a>.
59321           *
59322           * @method scale
59323           * @param  {Number|p5.Vector|Number[]} s
59324           *                      percent to scale the object, or percentage to
59325           *                      scale the object in the x-axis if multiple arguments
59326           *                      are given
59327           * @param  {Number} [y] percent to scale the object in the y-axis
59328           * @param  {Number} [z] percent to scale the object in the z-axis (webgl only)
59329           * @chainable
59330           * @example
59331           * <div>
59332           * <code>
59333           * rect(30, 20, 50, 50);
59334           * scale(0.5);
59335           * rect(30, 20, 50, 50);
59336           * </code>
59337           * </div>
59338           *
59339           * <div>
59340           * <code>
59341           * rect(30, 20, 50, 50);
59342           * scale(0.5, 1.3);
59343           * rect(30, 20, 50, 50);
59344           * </code>
59345           * </div>
59346           *
59347           * @alt
59348           * white 52x52 rect with black outline at center rotated counter 45 degrees
59349           * 2 white rects with black outline- 1 50x50 at center. other 25x65 bottom left
59350           */
59351          /**
59352           * @method scale
59353           * @param  {p5.Vector|Number[]} scales per-axis percents to scale the object
59354           * @chainable
59355           */
59356          _main.default.prototype.scale = function(x, y, z) {
59357            _main.default._validateParameters('scale', arguments);
59358            // Only check for Vector argument type if Vector is available
59359            if (x instanceof _main.default.Vector) {
59360              var v = x;
59361              x = v.x;
59362              y = v.y;
59363              z = v.z;
59364            } else if (x instanceof Array) {
59365              var rg = x;
59366              x = rg[0];
59367              y = rg[1];
59368              z = rg[2] || 1;
59369            }
59370            if (isNaN(y)) {
59371              y = z = x;
59372            } else if (isNaN(z)) {
59373              z = 1;
59374            }
59375
59376            this._renderer.scale.call(this._renderer, x, y, z);
59377
59378            return this;
59379          };
59380
59381          /**
59382           * Shears a shape around the x-axis by the amount specified by the angle
59383           * parameter. Angles should be specified in the current angleMode.
59384           * Objects are always sheared around their relative position to the origin
59385           * and positive numbers shear objects in a clockwise direction.
59386           *
59387           * Transformations apply to everything that happens after and subsequent
59388           * calls to the function accumulates the effect. For example, calling
59389           * shearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).
59390           * If <a href="#/p5/shearX">shearX()</a> is called within the <a href="#/p5/draw">draw()</a>,
59391           * the transformation is reset when the loop begins again.
59392           *
59393           * Technically, <a href="#/p5/shearX">shearX()</a> multiplies the current
59394           * transformation matrix by a rotation matrix. This function can be further
59395           * controlled by the <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a> functions.
59396           *
59397           * @method shearX
59398           * @param  {Number} angle angle of shear specified in radians or degrees,
59399           *                        depending on current angleMode
59400           * @chainable
59401           * @example
59402           * <div>
59403           * <code>
59404           * translate(width / 4, height / 4);
59405           * shearX(PI / 4.0);
59406           * rect(0, 0, 30, 30);
59407           * </code>
59408           * </div>
59409           *
59410           * @alt
59411           * white irregular quadrilateral with black outline at top middle.
59412           */
59413          _main.default.prototype.shearX = function(angle) {
59414            _main.default._validateParameters('shearX', arguments);
59415            var rad = this._toRadians(angle);
59416            this._renderer.applyMatrix(1, 0, Math.tan(rad), 1, 0, 0);
59417            return this;
59418          };
59419
59420          /**
59421           * Shears a shape around the y-axis the amount specified by the angle
59422           * parameter. Angles should be specified in the current angleMode. Objects
59423           * are always sheared around their relative position to the origin and
59424           * positive numbers shear objects in a clockwise direction.
59425           *
59426           * Transformations apply to everything that happens after and subsequent
59427           * calls to the function accumulates the effect. For example, calling
59428           * shearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If
59429           * <a href="#/p5/shearY">shearY()</a> is called within the <a href="#/p5/draw">draw()</a>, the transformation is reset when
59430           * the loop begins again.
59431           *
59432           * Technically, <a href="#/p5/shearY">shearY()</a> multiplies the current transformation matrix by a
59433           * rotation matrix. This function can be further controlled by the
59434           * <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a> functions.
59435           *
59436           * @method shearY
59437           * @param  {Number} angle angle of shear specified in radians or degrees,
59438           *                        depending on current angleMode
59439           * @chainable
59440           * @example
59441           * <div>
59442           * <code>
59443           * translate(width / 4, height / 4);
59444           * shearY(PI / 4.0);
59445           * rect(0, 0, 30, 30);
59446           * </code>
59447           * </div>
59448           *
59449           * @alt
59450           * white irregular quadrilateral with black outline at middle bottom.
59451           */
59452          _main.default.prototype.shearY = function(angle) {
59453            _main.default._validateParameters('shearY', arguments);
59454            var rad = this._toRadians(angle);
59455            this._renderer.applyMatrix(1, Math.tan(rad), 0, 1, 0, 0);
59456            return this;
59457          };
59458
59459          /**
59460    * Specifies an amount to displace objects within the display window.
59461    * The x parameter specifies left/right translation, the y parameter
59462    * specifies up/down translation.
59463    *
59464    * Transformations are cumulative and apply to everything that happens after
59465    * and subsequent calls to the function accumulates the effect. For example,
59466    * calling translate(50, 0) and then translate(20, 0) is the same as
59467    * translate(70, 0). If <a href="#/p5/translate">translate()</a> is called within <a href="#/p5/draw">draw()</a>, the
59468    * transformation is reset when the loop begins again. This function can be
59469    * further controlled by using <a href="#/p5/push">push()</a> and <a href="#/p5/pop">pop()</a>.
59470    *
59471    * @method translate
59472    * @param  {Number} x left/right translation
59473    * @param  {Number} y up/down translation
59474    * @param  {Number} [z] forward/backward translation (webgl only)
59475    * @chainable
59476    * @example
59477    * <div>
59478    * <code>
59479    * translate(30, 20);
59480    * rect(0, 0, 55, 55);
59481    * </code>
59482    * </div>
59483    *
59484    * <div>
59485    * <code>
59486    * rect(0, 0, 55, 55); // Draw rect at original 0,0
59487    * translate(30, 20);
59488    * rect(0, 0, 55, 55); // Draw rect at new 0,0
59489    * translate(14, 14);
59490    * rect(0, 0, 55, 55); // Draw rect at new 0,0
59491    * </code>
59492    * </div>
59493    *
59494   
59495    * <div>
59496    * <code>
59497    * function draw() {
59498    *   background(200);
59499    *   rectMode(CENTER);
59500    *   translate(width / 2, height / 2);
59501    *   translate(p5.Vector.fromAngle(millis() / 1000, 40));
59502    *   rect(0, 0, 20, 20);
59503    * }
59504    * </code>
59505    * </div>
59506    *
59507    * @alt
59508    * white 55x55 rect with black outline at center right.
59509    * 3 white 55x55 rects with black outlines at top-l, center-r and bottom-r.
59510    * a 20x20 white rect moving in a circle around the canvas
59511    */
59512          /**
59513           * @method translate
59514           * @param  {p5.Vector} vector the vector to translate by
59515           * @chainable
59516           */
59517          _main.default.prototype.translate = function(x, y, z) {
59518            _main.default._validateParameters('translate', arguments);
59519            if (this._renderer.isP3D) {
59520              this._renderer.translate(x, y, z);
59521            } else {
59522              this._renderer.translate(x, y);
59523            }
59524            return this;
59525          };
59526          var _default = _main.default;
59527          exports.default = _default;
59528        },
59529        { './main': 59 }
59530      ],
59531      73: [
59532        function(_dereq_, module, exports) {
59533          'use strict';
59534
59535          var _main = _interopRequireDefault(_dereq_('../core/main'));
59536          function _interopRequireDefault(obj) {
59537            return obj && obj.__esModule ? obj : { default: obj };
59538          }
59539          function _toConsumableArray(arr) {
59540            return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
59541          }
59542          function _nonIterableSpread() {
59543            throw new TypeError('Invalid attempt to spread non-iterable instance');
59544          }
59545          function _iterableToArray(iter) {
59546            if (
59547              Symbol.iterator in Object(iter) ||
59548              Object.prototype.toString.call(iter) === '[object Arguments]'
59549            )
59550              return Array.from(iter);
59551          }
59552          function _arrayWithoutHoles(arr) {
59553            if (Array.isArray(arr)) {
59554              for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
59555                arr2[i] = arr[i];
59556              }
59557              return arr2;
59558            }
59559          }
59560          function _typeof(obj) {
59561            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
59562              _typeof = function _typeof(obj) {
59563                return typeof obj;
59564              };
59565            } else {
59566              _typeof = function _typeof(obj) {
59567                return obj &&
59568                  typeof Symbol === 'function' &&
59569                  obj.constructor === Symbol &&
59570                  obj !== Symbol.prototype
59571                  ? 'symbol'
59572                  : typeof obj;
59573              };
59574            }
59575            return _typeof(obj);
59576          }
59577          /**
59578           *
59579           * Stores a value in local storage under the key name.
59580           * Local storage is saved in the browser and persists
59581           * between browsing sessions and page reloads.
59582           * The key can be the name of the variable but doesn't
59583           * have to be. To retrieve stored items
59584           * see <a href="#/p5/getItem">getItem</a>.
59585           *
59586           * Sensitive data such as passwords or personal information
59587           * should not be stored in local storage.
59588           *
59589           * @method storeItem
59590           * @for p5
59591           * @param {String} key
59592           * @param {String|Number|Object|Boolean|p5.Color|p5.Vector} value
59593           *
59594           * @example
59595           * <div><code>
59596           * // Type to change the letter in the
59597           * // center of the canvas.
59598           * // If you reload the page, it will
59599           * // still display the last key you entered
59600           *
59601           * let myText;
59602           *
59603           * function setup() {
59604           *   createCanvas(100, 100);
59605           *   myText = getItem('myText');
59606           *   if (myText === null) {
59607           *     myText = '';
59608           *   }
59609           * }
59610           *
59611           * function draw() {
59612           *   textSize(40);
59613           *   background(255);
59614           *   text(myText, width / 2, height / 2);
59615           * }
59616           *
59617           * function keyPressed() {
59618           *   myText = key;
59619           *   storeItem('myText', myText);
59620           * }
59621           * </code></div>
59622           *
59623           * @alt
59624           * When you type the key name is displayed as black text on white background.
59625           * If you reload the page, the last letter typed is still displaying.
59626           */
59627          _main.default.prototype.storeItem = function(key, value) {
59628            if (typeof key !== 'string') {
59629              console.log(
59630                'The argument that you passed to storeItem() - '.concat(
59631                  key,
59632                  ' is not a string.'
59633                )
59634              );
59635            }
59636            if (key.endsWith('p5TypeID')) {
59637              console.log(
59638                'The argument that you passed to storeItem() - '.concat(
59639                  key,
59640                  " must not end with 'p5TypeID'."
59641                )
59642              );
59643            }
59644
59645            if (typeof value === 'undefined') {
59646              console.log('You cannot store undefined variables using storeItem().');
59647            }
59648            var type = _typeof(value);
59649            switch (type) {
59650              case 'number':
59651              case 'boolean':
59652                value = value.toString();
59653                break;
59654              case 'object':
59655                if (value instanceof _main.default.Color) {
59656                  type = 'p5.Color';
59657                } else if (value instanceof _main.default.Vector) {
59658                  type = 'p5.Vector';
59659                  var coord = [value.x, value.y, value.z];
59660                  value = coord;
59661                }
59662                value = JSON.stringify(value);
59663                break;
59664              case 'string':
59665              default:
59666                break;
59667            }
59668
59669            localStorage.setItem(key, value);
59670            var typeKey = ''.concat(key, 'p5TypeID');
59671            localStorage.setItem(typeKey, type);
59672          };
59673
59674          /**
59675           *
59676           * Returns the value of an item that was stored in local storage
59677           * using storeItem()
59678           *
59679           * @method getItem
59680           * @for p5
59681           * @param {String} key name that you wish to use to store in local storage
59682           * @return {Number|Object|String|Boolean|p5.Color|p5.Vector} Value of stored item
59683           *
59684           * @example
59685           * <div><code>
59686           * // Click the mouse to change
59687           * // the color of the background
59688           * // Once you have changed the color
59689           * // it will stay changed even when you
59690           * // reload the page.
59691           *
59692           * let myColor;
59693           *
59694           * function setup() {
59695           *   createCanvas(100, 100);
59696           *   myColor = getItem('myColor');
59697           * }
59698           *
59699           * function draw() {
59700           *   if (myColor !== null) {
59701           *     background(myColor);
59702           *   }
59703           * }
59704           *
59705           * function mousePressed() {
59706           *   myColor = color(random(255), random(255), random(255));
59707           *   storeItem('myColor', myColor);
59708           * }
59709           * </code></div>
59710           *
59711           * @alt
59712           * If you click, the canvas changes to a random color.
59713           * If you reload the page, the canvas is still the color it
59714           * was when the page was previously loaded.
59715           */
59716          _main.default.prototype.getItem = function(key) {
59717            var value = localStorage.getItem(key);
59718            var type = localStorage.getItem(''.concat(key, 'p5TypeID'));
59719            if (typeof type === 'undefined') {
59720              console.log(
59721                'Unable to determine type of item stored under '.concat(
59722                  key,
59723                  'in local storage. Did you save the item with something other than setItem()?'
59724                )
59725              );
59726            } else if (value !== null) {
59727              switch (type) {
59728                case 'number':
59729                  value = parseFloat(value);
59730                  break;
59731                case 'boolean':
59732                  value = value === 'true';
59733                  break;
59734                case 'object':
59735                  value = JSON.parse(value);
59736                  break;
59737                case 'p5.Color':
59738                  value = JSON.parse(value);
59739                  value = this.color.apply(this, _toConsumableArray(value.levels));
59740                  break;
59741                case 'p5.Vector':
59742                  value = JSON.parse(value);
59743                  value = this.createVector.apply(this, _toConsumableArray(value));
59744                  break;
59745                case 'string':
59746                default:
59747                  break;
59748              }
59749            }
59750            return value;
59751          };
59752
59753          /**
59754           *
59755           * Clears all local storage items set with storeItem()
59756           * for the current domain.
59757           *
59758           * @method clearStorage
59759           * @for p5
59760           *
59761           * @example
59762           * <div class="norender">
59763           * <code>
59764           * function setup() {
59765           *   let myNum = 10;
59766           *   let myBool = false;
59767           *   storeItem('myNum', myNum);
59768           *   storeItem('myBool', myBool);
59769           *   print(getItem('myNum')); // logs 10 to the console
59770           *   print(getItem('myBool')); // logs false to the console
59771           *   clearStorage();
59772           *   print(getItem('myNum')); // logs null to the console
59773           *   print(getItem('myBool')); // logs null to the console
59774           * }
59775           * </code></div>
59776           */
59777          _main.default.prototype.clearStorage = function() {
59778            localStorage.clear();
59779          };
59780
59781          /**
59782           *
59783           * Removes an item that was stored with storeItem()
59784           *
59785           * @method removeItem
59786           * @param {String} key
59787           * @for p5
59788           *
59789           * @example
59790           * <div class="norender">
59791           * <code>
59792           * function setup() {
59793           *   let myVar = 10;
59794           *   storeItem('myVar', myVar);
59795           *   print(getItem('myVar')); // logs 10 to the console
59796           *   removeItem('myVar');
59797           *   print(getItem('myVar')); // logs null to the console
59798           * }
59799           * </code></div>
59800           */
59801          _main.default.prototype.removeItem = function(key) {
59802            if (typeof key !== 'string') {
59803              console.log(
59804                'The argument that you passed to removeItem() - '.concat(
59805                  key,
59806                  ' is not a string.'
59807                )
59808              );
59809            }
59810            localStorage.removeItem(key);
59811            localStorage.removeItem(''.concat(key, 'p5TypeID'));
59812          };
59813        },
59814        { '../core/main': 59 }
59815      ],
59816      74: [
59817        function(_dereq_, module, exports) {
59818          'use strict';
59819          Object.defineProperty(exports, '__esModule', { value: true });
59820          exports.default = void 0;
59821
59822          var _main = _interopRequireDefault(_dereq_('../core/main'));
59823          function _interopRequireDefault(obj) {
59824            return obj && obj.__esModule ? obj : { default: obj };
59825          }
59826          /**
59827           * @module Data
59828           * @submodule Dictionary
59829           * @for p5.TypedDict
59830           * @requires core
59831           *
59832           * This module defines the p5 methods for the p5 Dictionary classes.
59833           * The classes StringDict and NumberDict are for storing and working
59834           * with key-value pairs.
59835           */ /**
59836           *
59837           * Creates a new instance of p5.StringDict using the key-value pair
59838           * or the object you provide.
59839           *
59840           * @method createStringDict
59841           * @for p5
59842           * @param {String} key
59843           * @param {String} value
59844           * @return {p5.StringDict}
59845           *
59846           * @example
59847           * <div class="norender">
59848           * <code>
59849           * function setup() {
59850           *   let myDictionary = createStringDict('p5', 'js');
59851           *   print(myDictionary.hasKey('p5')); // logs true to console
59852           *
59853           *   let anotherDictionary = createStringDict({ happy: 'coding' });
59854           *   print(anotherDictionary.hasKey('happy')); // logs true to console
59855           * }
59856           * </code></div>
59857           */ /**
59858           * @method createStringDict
59859           * @param {Object} object object
59860           * @return {p5.StringDict}
59861           */ _main.default.prototype.createStringDict = function(key, value) {
59862            _main.default._validateParameters('createStringDict', arguments);
59863            return new _main.default.StringDict(key, value);
59864          };
59865          /**
59866           *
59867           * Creates a new instance of <a href="#/p5.NumberDict">p5.NumberDict</a> using the key-value pair
59868           * or object you provide.
59869           *
59870           * @method createNumberDict
59871           * @for p5
59872           * @param {Number} key
59873           * @param {Number} value
59874           * @return {p5.NumberDict}
59875           *
59876           * @example
59877           * <div class="norender">
59878           * <code>
59879           * function setup() {
59880           *   let myDictionary = createNumberDict(100, 42);
59881           *   print(myDictionary.hasKey(100)); // logs true to console
59882           *
59883           *   let anotherDictionary = createNumberDict({ 200: 84 });
59884           *   print(anotherDictionary.hasKey(200)); // logs true to console
59885           * }
59886           * </code></div>
59887           */
59888          /**
59889           * @method createNumberDict
59890           * @param {Object} object object
59891           * @return {p5.NumberDict}
59892           */
59893
59894          _main.default.prototype.createNumberDict = function(key, value) {
59895            _main.default._validateParameters('createNumberDict', arguments);
59896            return new _main.default.NumberDict(key, value);
59897          };
59898
59899          /**
59900           *
59901           * Base class for all p5.Dictionary types. Specifically
59902           * typed Dictionary classes inherit from this class.
59903           *
59904           * @class p5.TypedDict
59905           * @constructor
59906           */
59907
59908          _main.default.TypedDict = function(key, value) {
59909            if (key instanceof Object) {
59910              this.data = key;
59911            } else {
59912              this.data = {};
59913              this.data[key] = value;
59914            }
59915            return this;
59916          };
59917
59918          /**
59919           * Returns the number of key-value pairs currently stored in the Dictionary.
59920           *
59921           * @method size
59922           * @return {Integer} the number of key-value pairs in the Dictionary
59923           *
59924           * @example
59925           * <div class="norender">
59926           * <code>
59927           * function setup() {
59928           *   let myDictionary = createNumberDict(1, 10);
59929           *   myDictionary.create(2, 20);
59930           *   myDictionary.create(3, 30);
59931           *   print(myDictionary.size()); // logs 3 to the console
59932           * }
59933           * </code></div>
59934           */
59935          _main.default.TypedDict.prototype.size = function() {
59936            return Object.keys(this.data).length;
59937          };
59938
59939          /**
59940           * Returns true if the given key exists in the Dictionary,
59941           * otherwise returns false.
59942           *
59943           * @method hasKey
59944           * @param {Number|String} key that you want to look up
59945           * @return {Boolean} whether that key exists in Dictionary
59946           *
59947           * @example
59948           * <div class="norender">
59949           * <code>
59950           * function setup() {
59951           *   let myDictionary = createStringDict('p5', 'js');
59952           *   print(myDictionary.hasKey('p5')); // logs true to console
59953           * }
59954           * </code></div>
59955           */
59956
59957          _main.default.TypedDict.prototype.hasKey = function(key) {
59958            return this.data.hasOwnProperty(key);
59959          };
59960
59961          /**
59962           * Returns the value stored at the given key.
59963           *
59964           * @method get
59965           * @param {Number|String} the key you want to access
59966           * @return {Number|String} the value stored at that key
59967           *
59968           * @example
59969           * <div class="norender">
59970           * <code>
59971           * function setup() {
59972           *   let myDictionary = createStringDict('p5', 'js');
59973           *   let myValue = myDictionary.get('p5');
59974           *   print(myValue === 'js'); // logs true to console
59975           * }
59976           * </code></div>
59977           */
59978
59979          _main.default.TypedDict.prototype.get = function(key) {
59980            if (this.data.hasOwnProperty(key)) {
59981              return this.data[key];
59982            } else {
59983              console.log(''.concat(key, ' does not exist in this Dictionary'));
59984            }
59985          };
59986
59987          /**
59988           * Updates the value associated with the given key in case it already exists
59989           * in the Dictionary. Otherwise a new key-value pair is added.
59990           *
59991           * @method set
59992           * @param {Number|String} key
59993           * @param {Number|String} value
59994           *
59995           * @example
59996           * <div class="norender">
59997           * <code>
59998           * function setup() {
59999           *   let myDictionary = createStringDict('p5', 'js');
60000           *   myDictionary.set('p5', 'JS');
60001           *   myDictionary.print(); // logs "key: p5 - value: JS" to console
60002           * }
60003           * </code></div>
60004           */
60005
60006          _main.default.TypedDict.prototype.set = function(key, value) {
60007            if (this._validate(value)) {
60008              this.data[key] = value;
60009            } else {
60010              console.log('Those values dont work for this dictionary type.');
60011            }
60012          };
60013
60014          /**
60015           * private helper function to handle the user passing in objects
60016           * during construction or calls to create()
60017           */
60018
60019          _main.default.TypedDict.prototype._addObj = function(obj) {
60020            for (var key in obj) {
60021              this.set(key, obj[key]);
60022            }
60023          };
60024
60025          /**
60026           * Creates a new key-value pair in the Dictionary.
60027           *
60028           * @method create
60029           * @param {Number|String} key
60030           * @param {Number|String} value
60031           *
60032           * @example
60033           * <div class="norender">
60034           * <code>
60035           * function setup() {
60036           *   let myDictionary = createStringDict('p5', 'js');
60037           *   myDictionary.create('happy', 'coding');
60038           *   myDictionary.print();
60039           *   // above logs "key: p5 - value: js, key: happy - value: coding" to console
60040           * }
60041           * </code></div>
60042           */
60043          /**
60044           * @method create
60045           * @param {Object} obj key/value pair
60046           */
60047
60048          _main.default.TypedDict.prototype.create = function(key, value) {
60049            if (key instanceof Object && typeof value === 'undefined') {
60050              this._addObj(key);
60051            } else if (typeof key !== 'undefined') {
60052              this.set(key, value);
60053            } else {
60054              console.log(
60055                'In order to create a new Dictionary entry you must pass ' +
60056                  'an object or a key, value pair'
60057              );
60058            }
60059          };
60060
60061          /**
60062           * Removes all previously stored key-value pairs from the Dictionary.
60063           *
60064           * @method clear
60065           * @example
60066           * <div class="norender">
60067           * <code>
60068           * function setup() {
60069           *   let myDictionary = createStringDict('p5', 'js');
60070           *   print(myDictionary.hasKey('p5')); // prints 'true'
60071           *   myDictionary.clear();
60072           *   print(myDictionary.hasKey('p5')); // prints 'false'
60073           * }
60074           * </code>
60075           * </div>
60076           */
60077
60078          _main.default.TypedDict.prototype.clear = function() {
60079            this.data = {};
60080          };
60081
60082          /**
60083           * Removes the key-value pair stored at the given key from the Dictionary.
60084           *
60085           * @method remove
60086           * @param {Number|String} key for the pair to remove
60087           *
60088           * @example
60089           * <div class="norender">
60090           * <code>
60091           * function setup() {
60092           *   let myDictionary = createStringDict('p5', 'js');
60093           *   myDictionary.create('happy', 'coding');
60094           *   myDictionary.print();
60095           *   // above logs "key: p5 - value: js, key: happy - value: coding" to console
60096           *   myDictionary.remove('p5');
60097           *   myDictionary.print();
60098           *   // above logs "key: happy value: coding" to console
60099           * }
60100           * </code></div>
60101           */
60102
60103          _main.default.TypedDict.prototype.remove = function(key) {
60104            if (this.data.hasOwnProperty(key)) {
60105              delete this.data[key];
60106            } else {
60107              throw new Error(''.concat(key, ' does not exist in this Dictionary'));
60108            }
60109          };
60110
60111          /**
60112           * Logs the set of items currently stored in the Dictionary to the console.
60113           *
60114           * @method print
60115           *
60116           * @example
60117           * <div class="norender">
60118           * <code>
60119           * function setup() {
60120           *   let myDictionary = createStringDict('p5', 'js');
60121           *   myDictionary.create('happy', 'coding');
60122           *   myDictionary.print();
60123           *   // above logs "key: p5 - value: js, key: happy - value: coding" to console
60124           * }
60125           * </code>
60126           * </div>
60127           */
60128
60129          _main.default.TypedDict.prototype.print = function() {
60130            for (var item in this.data) {
60131              console.log('key:'.concat(item, ' value:').concat(this.data[item]));
60132            }
60133          };
60134
60135          /**
60136           * Converts the Dictionary into a CSV file for local download.
60137           *
60138           * @method saveTable
60139           * @example
60140           * <div>
60141           * <code>
60142           * function setup() {
60143           *   createCanvas(100, 100);
60144           *   background(200);
60145           *   text('click here to save', 10, 10, 70, 80);
60146           * }
60147           *
60148           * function mousePressed() {
60149           *   if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
60150           *     createStringDict({
60151           *       john: 1940,
60152           *       paul: 1942,
60153           *       george: 1943,
60154           *       ringo: 1940
60155           *     }).saveTable('beatles');
60156           *   }
60157           * }
60158           * </code>
60159           * </div>
60160           */
60161
60162          _main.default.TypedDict.prototype.saveTable = function(filename) {
60163            var output = '';
60164
60165            for (var key in this.data) {
60166              output += ''.concat(key, ',').concat(this.data[key], '\n');
60167            }
60168
60169            var blob = new Blob([output], { type: 'text/csv' });
60170            _main.default.prototype.downloadFile(blob, filename || 'mycsv', 'csv');
60171          };
60172
60173          /**
60174           * Converts the Dictionary into a JSON file for local download.
60175           *
60176           * @method saveJSON
60177           * @example
60178           * <div>
60179           * <code>
60180           * function setup() {
60181           *   createCanvas(100, 100);
60182           *   background(200);
60183           *   text('click here to save', 10, 10, 70, 80);
60184           * }
60185           *
60186           * function mousePressed() {
60187           *   if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
60188           *     createStringDict({
60189           *       john: 1940,
60190           *       paul: 1942,
60191           *       george: 1943,
60192           *       ringo: 1940
60193           *     }).saveJSON('beatles');
60194           *   }
60195           * }
60196           * </code>
60197           * </div>
60198           */
60199
60200          _main.default.TypedDict.prototype.saveJSON = function(filename, opt) {
60201            _main.default.prototype.saveJSON(this.data, filename, opt);
60202          };
60203
60204          /**
60205           * private helper function to ensure that the user passed in valid
60206           * values for the Dictionary type
60207           */
60208
60209          _main.default.TypedDict.prototype._validate = function(value) {
60210            return true;
60211          };
60212
60213          /**
60214           *
60215           * A simple Dictionary class for Strings.
60216           *
60217           * @class p5.StringDict
60218           * @extends p5.TypedDict
60219           */
60220
60221          _main.default.StringDict = function() {
60222            for (
60223              var _len = arguments.length, args = new Array(_len), _key = 0;
60224              _key < _len;
60225              _key++
60226            ) {
60227              args[_key] = arguments[_key];
60228            }
60229            _main.default.TypedDict.apply(this, args);
60230          };
60231
60232          _main.default.StringDict.prototype = Object.create(
60233            _main.default.TypedDict.prototype
60234          );
60235
60236          _main.default.StringDict.prototype._validate = function(value) {
60237            return typeof value === 'string';
60238          };
60239
60240          /**
60241           *
60242           * A simple Dictionary class for Numbers.
60243           *
60244           * @class p5.NumberDict
60245           * @constructor
60246           * @extends p5.TypedDict
60247           */
60248
60249          _main.default.NumberDict = function() {
60250            for (
60251              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
60252              _key2 < _len2;
60253              _key2++
60254            ) {
60255              args[_key2] = arguments[_key2];
60256            }
60257            _main.default.TypedDict.apply(this, args);
60258          };
60259
60260          _main.default.NumberDict.prototype = Object.create(
60261            _main.default.TypedDict.prototype
60262          );
60263
60264          /**
60265           * private helper function to ensure that the user passed in valid
60266           * values for the Dictionary type
60267           */
60268
60269          _main.default.NumberDict.prototype._validate = function(value) {
60270            return typeof value === 'number';
60271          };
60272
60273          /**
60274           * Add the given number to the value currently stored at the given key.
60275           * The sum then replaces the value previously stored in the Dictionary.
60276           *
60277           * @method add
60278           * @param {Number} Key for the value you wish to add to
60279           * @param {Number} Number to add to the value
60280           * @example
60281           * <div class='norender'>
60282           * <code>
60283           * function setup() {
60284           *   let myDictionary = createNumberDict(2, 5);
60285           *   myDictionary.add(2, 2);
60286           *   print(myDictionary.get(2)); // logs 7 to console.
60287           * }
60288           * </code></div>
60289           *
60290           */
60291
60292          _main.default.NumberDict.prototype.add = function(key, amount) {
60293            if (this.data.hasOwnProperty(key)) {
60294              this.data[key] += amount;
60295            } else {
60296              console.log('The key - '.concat(key, ' does not exist in this dictionary.'));
60297            }
60298          };
60299
60300          /**
60301           * Subtract the given number from the value currently stored at the given key.
60302           * The difference then replaces the value previously stored in the Dictionary.
60303           *
60304           * @method sub
60305           * @param {Number}
60305 Key for the value you wish to subtract from
60306           * @param {Number} Number to subtract from the value
60307           * @example
60308           * <div class='norender'>
60309           * <code>
60310           * function setup() {
60311           *   let myDictionary = createNumberDict(2, 5);
60312           *   myDictionary.sub(2, 2);
60313           *   print(myDictionary.get(2)); // logs 3 to console.
60314           * }
60315           * </code></div>
60316           *
60317           */
60318
60319          _main.default.NumberDict.prototype.sub = function(key, amount) {
60320            this.add(key, -amount);
60321          };
60322
60323          /**
60324           * Multiply the given number with the value currently stored at the given key.
60325           * The product then replaces the value previously stored in the Dictionary.
60326           *
60327           * @method mult
60328           * @param {Number} Key for value you wish to multiply
60329           * @param {Number} Amount to multiply the value by
60330           * @example
60331           * <div class='norender'>
60332           * <code>
60333           * function setup() {
60334           *   let myDictionary = createNumberDict(2, 4);
60335           *   myDictionary.mult(2, 2);
60336           *   print(myDictionary.get(2)); // logs 8 to console.
60337           * }
60338           * </code></div>
60339           *
60340           */
60341
60342          _main.default.NumberDict.prototype.mult = function(key, amount) {
60343            if (this.data.hasOwnProperty(key)) {
60344              this.data[key] *= amount;
60345            } else {
60346              console.log('The key - '.concat(key, ' does not exist in this dictionary.'));
60347            }
60348          };
60349
60350          /**
60351           * Divide the given number with the value currently stored at the given key.
60352           * The quotient then replaces the value previously stored in the Dictionary.
60353           *
60354           * @method div
60355           * @param {Number} Key for value you wish to divide
60356           * @param {Number} Amount to divide the value by
60357           * @example
60358           * <div class='norender'>
60359           * <code>
60360           * function setup() {
60361           *   let myDictionary = createNumberDict(2, 8);
60362           *   myDictionary.div(2, 2);
60363           *   print(myDictionary.get(2)); // logs 4 to console.
60364           * }
60365           * </code></div>
60366           *
60367           */
60368
60369          _main.default.NumberDict.prototype.div = function(key, amount) {
60370            if (this.data.hasOwnProperty(key)) {
60371              this.data[key] /= amount;
60372            } else {
60373              console.log('The key - '.concat(key, ' does not exist in this dictionary.'));
60374            }
60375          };
60376
60377          /**
60378           * private helper function for finding lowest or highest value
60379           * the argument 'flip' is used to flip the comparison arrow
60380           * from 'less than' to 'greater than'
60381           */
60382
60383          _main.default.NumberDict.prototype._valueTest = function(flip) {
60384            if (Object.keys(this.data).length === 0) {
60385              throw new Error(
60386                'Unable to search for a minimum or maximum value on an empty NumberDict'
60387              );
60388            } else if (Object.keys(this.data).length === 1) {
60389              return this.data[Object.keys(this.data)[0]];
60390            } else {
60391              var result = this.data[Object.keys(this.data)[0]];
60392              for (var key in this.data) {
60393                if (this.data[key] * flip < result * flip) {
60394                  result = this.data[key];
60395                }
60396              }
60397              return result;
60398            }
60399          };
60400
60401          /**
60402           * Return the lowest number currently stored in the Dictionary.
60403           *
60404           * @method minValue
60405           * @return {Number}
60406           * @example
60407           * <div class='norender'>
60408           * <code>
60409           * function setup() {
60410           *   let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });
60411           *   let lowestValue = myDictionary.minValue(); // value is -10
60412           *   print(lowestValue);
60413           * }
60414           * </code></div>
60415           */
60416
60417          _main.default.NumberDict.prototype.minValue = function() {
60418            return this._valueTest(1);
60419          };
60420
60421          /**
60422           * Return the highest number currently stored in the Dictionary.
60423           *
60424           * @method maxValue
60425           * @return {Number}
60426           * @example
60427           * <div class='norender'>
60428           * <code>
60429           * function setup() {
60430           *   let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });
60431           *   let highestValue = myDictionary.maxValue(); // value is 3
60432           *   print(highestValue);
60433           * }
60434           * </code></div>
60435           */
60436
60437          _main.default.NumberDict.prototype.maxValue = function() {
60438            return this._valueTest(-1);
60439          };
60440
60441          /**
60442           * private helper function for finding lowest or highest key
60443           * the argument 'flip' is used to flip the comparison arrow
60444           * from 'less than' to 'greater than'
60445           */
60446
60447          _main.default.NumberDict.prototype._keyTest = function(flip) {
60448            if (Object.keys(this.data).length === 0) {
60449              throw new Error('Unable to use minValue on an empty NumberDict');
60450            } else if (Object.keys(this.data).length === 1) {
60451              return Object.keys(this.data)[0];
60452            } else {
60453              var result = Object.keys(this.data)[0];
60454              for (var i = 1; i < Object.keys(this.data).length; i++) {
60455                if (Object.keys(this.data)[i] * flip < result * flip) {
60456                  result = Object.keys(this.data)[i];
60457                }
60458              }
60459              return result;
60460            }
60461          };
60462
60463          /**
60464           * Return the lowest key currently used in the Dictionary.
60465           *
60466           * @method minKey
60467           * @return {Number}
60468           * @example
60469           * <div class='norender'>
60470           * <code>
60471           * function setup() {
60472           *   let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });
60473           *   let lowestKey = myDictionary.minKey(); // value is 1.2
60474           *   print(lowestKey);
60475           * }
60476           * </code></div>
60477           */
60478
60479          _main.default.NumberDict.prototype.minKey = function() {
60480            return this._keyTest(1);
60481          };
60482
60483          /**
60484           * Return the highest key currently used in the Dictionary.
60485           *
60486           * @method maxKey
60487           * @return {Number}
60488           * @example
60489           * <div class='norender'>
60490           * <code>
60491           * function setup() {
60492           *   let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });
60493           *   let highestKey = myDictionary.maxKey(); // value is 4
60494           *   print(highestKey);
60495           * }
60496           * </code></div>
60497           */
60498
60499          _main.default.NumberDict.prototype.maxKey = function() {
60500            return this._keyTest(-1);
60501          };
60502          var _default = _main.default.TypedDict;
60503          exports.default = _default;
60504        },
60505        { '../core/main': 59 }
60506      ],
60507      75: [
60508        function(_dereq_, module, exports) {
60509          'use strict';
60510          Object.defineProperty(exports, '__esModule', { value: true });
60511          exports.default = void 0;
60512
60513          var _main = _interopRequireDefault(_dereq_('../core/main'));
60514          function _interopRequireDefault(obj) {
60515            return obj && obj.__esModule ? obj : { default: obj };
60516          }
60517          function _typeof(obj) {
60518            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
60519              _typeof = function _typeof(obj) {
60520                return typeof obj;
60521              };
60522            } else {
60523              _typeof = function _typeof(obj) {
60524                return obj &&
60525                  typeof Symbol === 'function' &&
60526                  obj.constructor === Symbol &&
60527                  obj !== Symbol.prototype
60528                  ? 'symbol'
60529                  : typeof obj;
60530              };
60531            }
60532            return _typeof(obj);
60533          }
60534
60535          /**
60536           * Searches the page for the first element that matches the given CSS selector string (can be an
60537           * ID, class, tag name or a combination) and returns it as a <a href="#/p5.Element">p5.Element</a>.
60538           * The DOM node itself can be accessed with .elt.
60539           * Returns null if none found. You can also specify a container to search within.
60540           *
60541           * @method select
60542           * @param  {String} selectors CSS selector string of element to search for
60543           * @param  {String|p5.Element|HTMLElement} [container] CSS selector string, <a href="#/p5.Element">p5.Element</a>, or
60544           *                                             HTML element to search within
60545           * @return {p5.Element|null} <a href="#/p5.Element">p5.Element</a> containing node found
60546           * @example
60547           * <div><code>
60548           * function setup() {
60549           *   createCanvas(50, 50);
60550           *   background(30);
60551           *   // move canvas down and right
60552           *   select('canvas').position(10, 30);
60553           * }
60554           * </code></div>
60555           *
60556           * <div class="norender"><code>
60557           * // select using ID
60558           * let a = select('#container');
60559           * let b = select('#beep', '#container');
60560           * let c;
60561           * if (a) {
60562           *   // select using class
60563           *   c = select('.boop', a);
60564           * }
60565           * // select using CSS selector string
60566           * let d = select('#container #bleep');
60567           * let e = select('#container p');
60568           * [a, b, c, d, e]; // unused
60569           * </code></div>
60570           */
60571          _main.default.prototype.select = function(e, p) {
60572            _main.default._validateParameters('select', arguments);
60573            var container = this._getContainer(p);
60574            var res = container.querySelector(e);
60575            if (res) {
60576              return this._wrapElement(res);
60577            } else {
60578              return null;
60579            }
60580          };
60581
60582          /**
60583           * Searches the page for elements that match the given CSS selector string (can be an ID a class,
60584           * tag name or a combination) and returns them as <a href="#/p5.Element">p5.Element</a>s in
60585           * an array.
60586           * The DOM node itself can be accessed with .elt.
60587           * Returns an empty array if none found.
60588           * You can also specify a container to search within.
60589           *
60590           * @method selectAll
60591           * @param  {String} selectors CSS selector string of elements to search for
60592           * @param  {String|p5.Element|HTMLElement} [container] CSS selector string, <a href="#/p5.Element">p5.Element</a>
60593           *                                             , or HTML element to search within
60594           * @return {p5.Element[]} Array of <a href="#/p5.Element">p5.Element</a>s containing nodes found
60595           * @example
60596           * <div class='norender'><code>
60597           * function setup() {
60598           *   createButton('btn');
60599           *   createButton('2nd btn');
60600           *   createButton('3rd btn');
60601           *   let buttons = selectAll('button');
60602           *
60603           *   for (let i = 0; i < buttons.length; i++) {
60604           *     buttons[i].size(100, 100);
60605           *   }
60606           * }
60607           * </code></div>
60608           * <div class='norender'><code>
60609           * // these are all valid calls to selectAll()
60610           * let a = selectAll('.beep');
60611           * a = selectAll('div');
60612           * a = selectAll('button', '#container');
60613           *
60614           * let b = createDiv();
60615           * b.id('container');
60616           * let c = select('#container');
60617           * a = selectAll('p', c);
60618           * a = selectAll('#container p');
60619           *
60620           * let d = document.getElementById('container');
60621           * a = selectAll('.boop', d);
60622           * a = selectAll('#container .boop');
60623           * console.log(a);
60624           * </code></div>
60625           */
60626          _main.default.prototype.selectAll = function(e, p) {
60627            _main.default._validateParameters('selectAll', arguments);
60628            var arr = [];
60629            var container = this._getContainer(p);
60630            var res = container.querySelectorAll(e);
60631            if (res) {
60632              for (var j = 0; j < res.length; j++) {
60633                var obj = this._wrapElement(res[j]);
60634                arr.push(obj);
60635              }
60636            }
60637            return arr;
60638          };
60639
60640          /**
60641           * Helper function for select and selectAll
60642           */
60643          _main.default.prototype._getContainer = function(p) {
60644            var container = document;
60645            if (typeof p === 'string') {
60646              container = document.querySelector(p) || document;
60647            } else if (p instanceof _main.default.Element) {
60648              container = p.elt;
60649            } else if (p instanceof HTMLElement) {
60650              container = p;
60651            }
60652            return container;
60653          };
60654
60655          /**
60656           * Helper function for getElement and getElements.
60657           */
60658          _main.default.prototype._wrapElement = function(elt) {
60659            var children = Array.prototype.slice.call(elt.children);
60660            if (elt.tagName === 'INPUT' && elt.type === 'checkbox') {
60661              var converted = new _main.default.Element(elt, this);
60662              converted.checked = function() {
60663                if (arguments.length === 0) {
60664                  return this.elt.checked;
60665                } else if (arguments[0]) {
60666                  this.elt.checked = true;
60667                } else {
60668                  this.elt.checked = false;
60669                }
60670                return this;
60671              };
60672              return converted;
60673            } else if (elt.tagName === 'VIDEO' || elt.tagName === 'AUDIO') {
60674              return new _main.default.MediaElement(elt, this);
60675            } else if (elt.tagName === 'SELECT') {
60676              return this.createSelect(new _main.default.Element(elt, this));
60677            } else if (
60678              children.length > 0 &&
60679              children.every(function(c) {
60680                return c.tagName === 'INPUT' || c.tagName === 'LABEL';
60681              })
60682            ) {
60683              return this.createRadio(new _main.default.Element(elt, this));
60684            } else {
60685              return new _main.default.Element(elt, this);
60686            }
60687          };
60688
60689          /**
60690           * Removes all elements created by p5, except any canvas / graphics
60691           * elements created by <a href="#/p5/createCanvas">createCanvas</a> or <a href="#/p5/createGraphics">createGraphics</a>.
60692           * Event handlers are removed, and element is removed from the DOM.
60693           * @method removeElements
60694           * @example
60695           * <div class='norender'><code>
60696           * function setup() {
60697           *   createCanvas(100, 100);
60698           *   createDiv('this is some text');
60699           *   createP('this is a paragraph');
60700           * }
60701           * function mousePressed() {
60702           *   removeElements(); // this will remove the div and p, not canvas
60703           * }
60704           * </code></div>
60705           */
60706          _main.default.prototype.removeElements = function(e) {
60707            _main.default._validateParameters('removeElements', arguments);
60708            // el.remove splices from this._elements, so don't mix iteration with it
60709            var isNotCanvasElement = function isNotCanvasElement(el) {
60710              return !(el.elt instanceof HTMLCanvasElement);
60711            };
60712            var removeableElements = this._elements.filter(isNotCanvasElement);
60713            removeableElements.map(function(el) {
60714              return el.remove();
60715            });
60716          };
60717
60718          /**
60719           * The .<a href="#/p5.Element/changed">changed()</a> function is called when the value of an
60720           * element changes.
60721           * This can be used to attach an element specific event listener.
60722           *
60723           * @method changed
60724           * @param  {Function|Boolean} fxn function to be fired when the value of
60725           *                                an element changes.
60726           *                                if `false` is passed instead, the previously
60727           *                                firing function will no longer fire.
60728           * @chainable
60729           * @example
60730           * <div><code>
60731           * let sel;
60732           *
60733           * function setup() {
60734           *   textAlign(CENTER);
60735           *   background(200);
60736           *   sel = createSelect();
60737           *   sel.position(10, 10);
60738           *   sel.option('pear');
60739           *   sel.option('kiwi');
60740           *   sel.option('grape');
60741           *   sel.changed(mySelectEvent);
60742           * }
60743           *
60744           * function mySelectEvent() {
60745           *   let item = sel.value();
60746           *   background(200);
60747           *   text("it's a " + item + '!', 50, 50);
60748           * }
60749           * </code></div>
60750           *
60751           * <div><code>
60752           * let checkbox;
60753           * let cnv;
60754           *
60755           * function setup() {
60756           *   checkbox = createCheckbox(' fill');
60757           *   checkbox.changed(changeFill);
60758           *   cnv = createCanvas(100, 100);
60759           *   cnv.position(0, 30);
60760           *   noFill();
60761           * }
60762           *
60763           * function draw() {
60764           *   background(200);
60765           *   ellipse(50, 50, 50, 50);
60766           * }
60767           *
60768           * function changeFill() {
60769           *   if (checkbox.checked()) {
60770           *     fill(0);
60771           *   } else {
60772           *     noFill();
60773           *   }
60774           * }
60775           * </code></div>
60776           *
60777           * @alt
60778           * dropdown: pear, kiwi, grape. When selected text "its a" + selection shown.
60779           */
60780          _main.default.Element.prototype.changed = function(fxn) {
60781            _main.default.Element._adjustListener('change', fxn, this);
60782            return this;
60783          };
60784
60785          /**
60786           * The .<a href="#/p5.Element/input">input()</a> function is called when any user input is
60787           * detected with an element. The input event is often used
60788           * to detect keystrokes in a input element, or changes on a
60789           * slider element. This can be used to attach an element specific
60790           * event listener.
60791           *
60792           * @method input
60793           * @param  {Function|Boolean} fxn function to be fired when any user input is
60794           *                                detected within the element.
60795           *                                if `false` is passed instead, the previously
60796           *                                firing function will no longer fire.
60797           * @chainable
60798           * @example
60799           * <div class='norender'><code>
60800           * // Open your console to see the output
60801           * function setup() {
60802           *   let inp = createInput('');
60803           *   inp.input(myInputEvent);
60804           * }
60805           *
60806           * function myInputEvent() {
60807           *   console.log('you are typing: ', this.value());
60808           * }
60809           * </code></div>
60810           *
60811           * @alt
60812           * no display.
60813           */
60814          _main.default.Element.prototype.input = function(fxn) {
60815            _main.default.Element._adjustListener('input', fxn, this);
60816            return this;
60817          };
60818
60819          /**
60820           * Helpers for create methods.
60821           */
60822          function addElement(elt, pInst, media) {
60823            var node = pInst._userNode ? pInst._userNode : document.body;
60824            node.appendChild(elt);
60825            var c = media
60826              ? new _main.default.MediaElement(elt, pInst)
60827              : new _main.default.Element(elt, pInst);
60828            pInst._elements.push(c);
60829            return c;
60830          }
60831
60832          /**
60833           * Creates a `&lt;div&gt;&lt;/div&gt;` element in the DOM with given inner HTML.
60834           *
60835           * @method createDiv
60836           * @param  {String} [html] inner HTML for element created
60837           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
60838           * @example
60839           * <div class='norender'><code>
60840           * createDiv('this is some text');
60841           * </code></div>
60842           */
60843          _main.default.prototype.createDiv = function() {
60844            var html =
60845              arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
60846            var elt = document.createElement('div');
60847            elt.innerHTML = html;
60848            return addElement(elt, this);
60849          };
60850
60851          /**
60852           * Creates a `&lt;p&gt;&lt;/p&gt;` element in the DOM with given inner HTML. Used
60853           * for paragraph length text.
60854           *
60855           * @method createP
60856           * @param  {String} [html] inner HTML for element created
60857           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
60858           * @example
60859           * <div class='norender'><code>
60860           * createP('this is some text');
60861           * </code></div>
60862           */
60863          _main.default.prototype.createP = function() {
60864            var html =
60865              arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
60866            var elt = document.createElement('p');
60867            elt.innerHTML = html;
60868            return addElement(elt, this);
60869          };
60870
60871          /**
60872           * Creates a `&lt;span&gt;&lt;/span&gt;` element in the DOM with given inner HTML.
60873           *
60874           * @method createSpan
60875           * @param  {String} [html] inner HTML for element created
60876           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
60877           * @example
60878           * <div class='norender'><code>
60879           * createSpan('this is some text');
60880           * </code></div>
60881           */
60882          _main.default.prototype.createSpan = function() {
60883            var html =
60884              arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
60885            var elt = document.createElement('span');
60886            elt.innerHTML = html;
60887            return addElement(elt, this);
60888          };
60889
60890          /**
60891           * Creates an `&lt;img&gt;` element in the DOM with given src and
60892           * alternate text.
60893           *
60894           * @method createImg
60895           * @param  {String} src src path or url for image
60896           * @param  {String} alt <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes">alternate text</a> to be used if image does not load. You can use also an empty string (`""`) if that an image is not intended to be viewed.
60897           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
60898           * @example
60899           * <div class='norender'><code>
60900           * createImg(
60901           *   'https://p5js.org/assets/img/asterisk-01.png',
60902           *   'the p5 magenta asterisk'
60903           * );
60904           * </code></div>
60905           */
60906          /**
60907           * @method createImg
60908           * @param  {String} src
60909           * @param  {String} alt
60910           * @param  {String} crossOrigin <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes">crossOrigin property</a> of the `img` element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with `canvas`. if an empty string(`""`) is passed, CORS is not used
60911           * @param  {Function} [successCallback] callback to be called once image data is loaded with the <a href="#/p5.Element">p5.Element</a> as argument
60912           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
60913           */
60914          _main.default.prototype.createImg = function() {
60915            _main.default._validateParameters('createImg', arguments);
60916            var elt = document.createElement('img');
60917            var args = arguments;
60918            var self;
60919            if (args.length > 1 && typeof args[1] === 'string') {
60920              elt.alt = args[1];
60921            }
60922            if (args.length > 2 && typeof args[2] === 'string') {
60923              elt.crossOrigin = args[2];
60924            }
60925            elt.src = args[0];
60926            self = addElement(elt, this);
60927            elt.addEventListener('load', function() {
60928              self.width = elt.offsetWidth || elt.width;
60929              self.height = elt.offsetHeight || elt.height;
60930              var last = args[args.length - 1];
60931              if (typeof last === 'function') last(self);
60932            });
60933            return self;
60934          };
60935
60936          /**
60937           * Creates an `&lt;a&gt;&lt;/a&gt;` element in the DOM for including a hyperlink.
60938           *
60939           * @method createA
60940           * @param  {String} href       url of page to link to
60941           * @param  {String} html       inner html of link element to display
60942           * @param  {String} [target]   target where new link should open,
60943           *                             could be _blank, _self, _parent, _top.
60944           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
60945           * @example
60946           * <div class='norender'><code>
60947           * createA('http://p5js.org/', 'this is a link');
60948           * </code></div>
60949           */
60950          _main.default.prototype.createA = function(href, html, target) {
60951            _main.default._validateParameters('createA', arguments);
60952            var elt = document.createElement('a');
60953            elt.href = href;
60954            elt.innerHTML = html;
60955            if (target) elt.target = target;
60956            return addElement(elt, this);
60957          };
60958
60959          /** INPUT **/
60960
60961          /**
60962           * Creates a slider `&lt;input&gt;&lt;/input&gt;` element in the DOM.
60963           * Use .size() to set the display length of the slider.
60964           *
60965           * @method createSlider
60966           * @param  {Number} min minimum value of the slider
60967           * @param  {Number} max maximum value of the slider
60968           * @param  {Number} [value] default value of the slider
60969           * @param  {Number} [step] step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)
60970           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
60971           * @example
60972           * <div><code>
60973           * let slider;
60974           * function setup() {
60975           *   slider = createSlider(0, 255, 100);
60976           *   slider.position(10, 10);
60977           *   slider.style('width', '80px');
60978           * }
60979           *
60980           * function draw() {
60981           *   let val = slider.value();
60982           *   background(val);
60983           * }
60984           * </code></div>
60985           *
60986           * <div><code>
60987           * let slider;
60988           * function setup() {
60989           *   colorMode(HSB);
60990           *   slider = createSlider(0, 360, 60, 40);
60991           *   slider.position(10, 10);
60992           *   slider.style('width', '80px');
60993           * }
60994           *
60995           * function draw() {
60996           *   let val = slider.value();
60997           *   background(val, 100, 100, 1);
60998           * }
60999           * </code></div>
61000           */
61001          _main.default.prototype.createSlider = function(min, max, value, step) {
61002            _main.default._validateParameters('createSlider', arguments);
61003            var elt = document.createElement('input');
61004            elt.type = 'range';
61005            elt.min = min;
61006            elt.max = max;
61007            if (step === 0) {
61008              elt.step = 0.000000000000000001; // smallest valid step
61009            } else if (step) {
61010              elt.step = step;
61011            }
61012            if (typeof value === 'number') elt.value = value;
61013            return addElement(elt, this);
61014          };
61015
61016          /**
61017           * Creates a `&lt;button&gt;&lt;/button&gt;` element in the DOM.
61018           * Use .size() to set the display size of the button.
61019           * Use .mousePressed() to specify behavior on press.
61020           *
61021           * @method createButton
61022           * @param  {String} label label displayed on the button
61023           * @param  {String} [value] value of the button
61024           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
61025           * @example
61026           * <div class='norender'><code>
61027           * let button;
61028           * function setup() {
61029           *   createCanvas(100, 100);
61030           *   background(0);
61031           *   button = createButton('click me');
61032           *   button.position(19, 19);
61033           *   button.mousePressed(changeBG);
61034           * }
61035           *
61036           * function changeBG() {
61037           *   let val = random(255);
61038           *   background(val);
61039           * }
61040           * </code></div>
61041           */
61042          _main.default.prototype.createButton = function(label, value) {
61043            _main.default._validateParameters('createButton', arguments);
61044            var elt = document.createElement('button');
61045            elt.innerHTML = label;
61046            if (value) elt.value = value;
61047            return addElement(elt, this);
61048          };
61049
61050          /**
61051           * Creates a checkbox `&lt;input&gt;&lt;/input&gt;` element in the DOM.
61052           * Calling .checked() on a checkbox returns if it is checked or not
61053           *
61054           * @method createCheckbox
61055           * @param  {String} [label] label displayed after checkbox
61056           * @param  {boolean} [value] value of the checkbox; checked is true, unchecked is false
61057           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
61058           * @example
61059           * <div class='norender'><code>
61060           * let checkbox;
61061           *
61062           * function setup() {
61063           *   checkbox = createCheckbox('label', false);
61064           *   checkbox.changed(myCheckedEvent);
61065           * }
61066           *
61067           * function myCheckedEvent() {
61068           *   if (this.checked()) {
61069           *     console.log('Checking!');
61070           *   } else {
61071           *     console.log('Unchecking!');
61072           *   }
61073           * }
61074           * </code></div>
61075           */
61076          _main.default.prototype.createCheckbox = function() {
61077            _main.default._validateParameters('createCheckbox', arguments);
61078            var elt = document.createElement('div');
61079            var checkbox = document.createElement('input');
61080            checkbox.type = 'checkbox';
61081            elt.appendChild(checkbox);
61082            //checkbox must be wrapped in p5.Element before label so that label appears after
61083            var self = addElement(elt, this);
61084            self.checked = function() {
61085              var cb = self.elt.getElementsByTagName('input')[0];
61086              if (cb) {
61087                if (arguments.length === 0) {
61088                  return cb.checked;
61089                } else if (arguments[0]) {
61090                  cb.checked = true;
61091                } else {
61092                  cb.checked = false;
61093                }
61094              }
61095              return self;
61096            };
61097            this.value = function(val) {
61098              self.value = val;
61099              return this;
61100            };
61101            if (arguments[0]) {
61102              var ran = Math.random()
61103                .toString(36)
61104                .slice(2);
61105              var label = document.createElement('label');
61106              checkbox.setAttribute('id', ran);
61107              label.htmlFor = ran;
61108              self.value(arguments[0]);
61109              label.appendChild(document.createTextNode(arguments[0]));
61110              elt.appendChild(label);
61111            }
61112            if (arguments[1]) {
61113              checkbox.checked = true;
61114            }
61115            return self;
61116          };
61117
61118          /**
61119           * Creates a dropdown menu `&lt;select&gt;&lt;/select&gt;` element in the DOM.
61120           * It also helps to assign select-box methods to <a href="#/p5.Element">p5.Element</a> when selecting existing select box.
61121           * - `.option(name, [value])` can be used to set options for the select after it is created.
61122           * - `.value()` will return the currently selected option.
61123           * - `.selected()` will return current dropdown element which is an instance of <a href="#/p5.Element">p5.Element</a>
61124           * - `.selected(value)` can be used to make given option selected by default when the page first loads.
61125           * - `.disable()` marks whole of dropdown element as disabled.
61126           * - `.disable(value)` marks given option as disabled
61127           *
61128           * @method createSelect
61129           * @param {boolean} [multiple] true if dropdown should support multiple selections
61130           * @return {p5.Element}
61131           * @example
61132           * <div><code>
61133           * let sel;
61134           *
61135           * function setup() {
61136           *   textAlign(CENTER);
61137           *   background(200);
61138           *   sel = createSelect();
61139           *   sel.position(10, 10);
61140           *   sel.option('pear');
61141           *   sel.option('kiwi');
61142           *   sel.option('grape');
61143           *   sel.selected('kiwi');
61144           *   sel.changed(mySelectEvent);
61145           * }
61146           *
61147           * function mySelectEvent() {
61148           *   let item = sel.value();
61149           *   background(200);
61150           *   text('It is a ' + item + '!', 50, 50);
61151           * }
61152           * </code></div>
61153           *
61154           * <div><code>
61155           * let sel;
61156           *
61157           * function setup() {
61158           *   textAlign(CENTER);
61159           *   background(200);
61160           *   sel = createSelect();
61161           *   sel.position(10, 10);
61162           *   sel.option('oil');
61163           *   sel.option('milk');
61164           *   sel.option('bread');
61165           *   sel.disable('milk');
61166           * }
61167           * </code></div>
61168           */
61169          /**
61170           * @method createSelect
61171           * @param {Object} existing DOM select element
61172           * @return {p5.Element}
61173           */
61174
61175          _main.default.prototype.createSelect = function() {
61176            _main.default._validateParameters('createSelect', arguments);
61177            var self;
61178            var arg = arguments[0];
61179            if (
61180              arg instanceof _main.default.Element &&
61181              arg.elt instanceof HTMLSelectElement
61182            ) {
61183              // If given argument is p5.Element of select type
61184              self = arg;
61185              this.elt = arg.elt;
61186            } else if (arg instanceof HTMLSelectElement) {
61187              self = addElement(arg, this);
61188              this.elt = arg;
61189            } else {
61190              var elt = document.createElement('select');
61191              if (arg && typeof arg === 'boolean') {
61192                elt.setAttribute('multiple', 'true');
61193              }
61194              self = addElement(elt, this);
61195              this.elt = elt;
61196            }
61197            self.option = function(name, value) {
61198              var index;
61199
61200              // if no name is passed, return
61201              if (name === undefined) {
61202                return;
61203              }
61204              //see if there is already an option with this name
61205              for (var i = 0; i < this.elt.length; i += 1) {
61206                if (this.elt[i].innerHTML === name) {
61207                  index = i;
61208                  break;
61209                }
61210              }
61211              //if there is an option with this name we will modify it
61212              if (index !== undefined) {
61213                //if the user passed in false then delete that option
61214                if (value === false) {
61215                  this.elt.remove(index);
61216                } else {
61217                  // Update the option at index with the value
61218                  this.elt[index].value = value;
61219                }
61220              } else {
61221                //if it doesn't exist create it
61222                var opt = document.createElement('option');
61223                opt.innerHTML = name;
61224                opt.value = value === undefined ? name : value;
61225                this.elt.appendChild(opt);
61226                this._pInst._elements.push(opt);
61227              }
61228            };
61229
61230            self.selected = function(value) {
61231              // Update selected status of option
61232              if (value !== undefined) {
61233                for (var i = 0; i < this.elt.length; i += 1) {
61234                  if (this.elt[i].value.toString() === value.toString()) {
61235                    this.elt.selectedIndex = i;
61236                  }
61237                }
61238                return this;
61239              } else {
61240                if (this.elt.getAttribute('multiple')) {
61241                  var arr = [];
61242                  var _iteratorNormalCompletion = true;
61243                  var _didIteratorError = false;
61244                  var _iteratorError = undefined;
61245                  try {
61246                    for (
61247                      var _iterator = this.elt.selectedOptions[Symbol.iterator](), _step;
61248                      !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
61249                      _iteratorNormalCompletion = true
61250                    ) {
61251                      var selectedOption = _step.value;
61252                      arr.push(selectedOption.value);
61253                    }
61254                  } catch (err) {
61255                    _didIteratorError = true;
61256                    _iteratorError = err;
61257                  } finally {
61258                    try {
61259                      if (!_iteratorNormalCompletion && _iterator.return != null) {
61260                        _iterator.return();
61261                      }
61262                    } finally {
61263                      if (_didIteratorError) {
61264                        throw _iteratorError;
61265                      }
61266                    }
61267                  }
61268                  return arr;
61269                } else {
61270                  return this.elt.value;
61271                }
61272              }
61273            };
61274
61275            self.disable = function(value) {
61276              if (typeof value === 'string') {
61277                for (var i = 0; i < this.elt.length; i++) {
61278                  if (this.elt[i].value.toString() === value) {
61279                    this.elt[i].disabled = true;
61280                    this.elt[i].selected = false;
61281                  }
61282                }
61283              } else {
61284                this.elt.disabled = true;
61285              }
61286              return this;
61287            };
61288
61289            return self;
61290          };
61291
61292          /**
61293           * Creates a radio button element in the DOM.It also helps existing radio buttons
61294           * assign methods of <a href="#/p5.Element/">p5.Element</a>.
61295           * - `.option(value, [label])` can be used to create a new option for the
61296           *   element. If an option with a value already exists, it will be returned.
61297           *   Optionally, a label can be provided as second argument for the option.
61298           * - `.remove(value)` can be used to remove an option for the element.
61299           * - `.value()` method will return the currently selected value.
61300           * - `.selected()` method will return the currently selected input element.
61301           * - `.selected(value)` method will select the option and return it.
61302           * - `.disable(Boolean)` method will enable/disable the whole radio button element.
61303           *
61304           * @method createRadio
61305           * @param  {Object} containerElement An container HTML Element either a div
61306           * or span inside which all existing radio inputs will be considered as options.
61307           * @param {string} [name] A name parameter for each Input Element.
61308           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
61309           * @example
61310           * <div><code>
61311           * let radio;
61312           *
61313           * function setup() {
61314           *   radio = createRadio();
61315           *   radio.option('black');
61316           *   radio.option('white');
61317           *   radio.option('gray');
61318           *   radio.style('width', '60px');
61319           *   textAlign(CENTER);
61320           *   fill(255, 0, 0);
61321           * }
61322           *
61323           * function draw() {
61324           *   let val = radio.value();
61325           *   background(val);
61326           *   text(val, width / 2, height / 2);
61327           * }
61328           * </code></div>
61329           * <div><code>
61330           * let radio;
61331           *
61332           * function setup() {
61333           *   radio = createRadio();
61334           *   radio.option(1, 'apple');
61335           *   radio.option(2, 'bread');
61336           *   radio.option(3, 'juice');
61337           *   radio.style('width', '30px');
61338           *   textAlign(CENTER);
61339           * }
61340           *
61341           * function draw() {
61342           *   background(200);
61343           *   let val = radio.value();
61344           *   if (val) {
61345           *     text('item cost is $' + val, width / 2, height / 2);
61346           *   }
61347           * }
61348           * </code></div>
61349           */
61350          /**
61351           * @method createRadio
61352           * @param {String} name
61353           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
61354           */
61355          /**
61356           * @method createRadio
61357           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
61358           */
61359          _main.default.prototype.createRadio = function() {
61360            // Creates a div, adds each option as an individual input inside it.
61361            // If already given with a containerEl, will search for all input[radio]
61362            // it, create a p5.Element out of it, add options to it and return the p5.Element.
61363
61364            var radioElement;
61365            var name;
61366            var arg0 = arguments[0];
61367            // If existing radio Element is provided as argument 0
61368            if (arg0 instanceof HTMLDivElement || arg0 instanceof HTMLSpanElement) {
61369              radioElement = arg0;
61370              if (typeof arguments[1] === 'string') name = arguments[1];
61371            } else {
61372              if (typeof arg0 === 'string') name = arg0;
61373              radioElement = document.createElement('div');
61374            }
61375            this.elt = radioElement;
61376            var self = addElement(radioElement, this);
61377            self._name = name || 'radioOption';
61378
61379            // setup member functions
61380            var isRadioInput = function isRadioInput(el) {
61381              return el instanceof HTMLInputElement && el.type === 'radio';
61382            };
61383            var isNextLabel = function isNextLabel(el) {
61384              return el.nextElementSibling instanceof HTMLLabelElement;
61385            };
61386
61387            self._getOptionsArray = function() {
61388              return Array.from(this.elt.children).filter(isRadioInput);
61389            };
61390
61391            self.option = function(value, label) {
61392              // return an option with this value, create if not exists.
61393              var optionEl;
61394              var _iteratorNormalCompletion2 = true;
61395              var _didIteratorError2 = false;
61396              var _iteratorError2 = undefined;
61397              try {
61398                for (
61399                  var _iterator2 = self._getOptionsArray()[Symbol.iterator](), _step2;
61400                  !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done);
61401                  _iteratorNormalCompletion2 = true
61402                ) {
61403                  var option = _step2.value;
61404                  if (option.value === value) {
61405                    optionEl = option;
61406                    break;
61407                  }
61408                }
61409
61410                // Create a new option, add it to radioElement and return it.
61411              } catch (err) {
61412                _didIteratorError2 = true;
61413                _iteratorError2 = err;
61414              } finally {
61415                try {
61416                  if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
61417                    _iterator2.return();
61418                  }
61419                } finally {
61420                  if (_didIteratorError2) {
61421                    throw _iteratorError2;
61422                  }
61423                }
61424              }
61425              if (optionEl === undefined) {
61426                optionEl = document.createElement('input');
61427                optionEl.setAttribute('type', 'radio');
61428                optionEl.setAttribute('value', value);
61429                this.elt.appendChild(optionEl);
61430              }
61431
61432              // Check if label element exists, else create it
61433              var labelElement;
61434              if (!isNextLabel(optionEl)) {
61435                labelElement = document.createElement('label');
61436                optionEl.insertAdjacentElement('afterend', labelElement);
61437              } else {
61438                labelElement = optionEl.nextElementSibling;
61439              }
61440
61441              labelElement.innerHTML = label === undefined ? value : label;
61442              optionEl.setAttribute('name', self._name);
61443              return optionEl;
61444            };
61445
61446            self.remove = function(value) {
61447              var _iteratorNormalCompletion3 = true;
61448              var _didIteratorError3 = false;
61449              var _iteratorError3 = undefined;
61450              try {
61451                for (
61452                  var _iterator3 = self._getOptionsArray()[Symbol.iterator](), _step3;
61453                  !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done);
61454                  _iteratorNormalCompletion3 = true
61455                ) {
61456                  var optionEl = _step3.value;
61457                  if (optionEl.value === value) {
61458                    if (isNextLabel(optionEl)) optionEl.nextElementSibling.remove();
61459                    optionEl.remove();
61460                    return;
61461                  }
61462                }
61463              } catch (err) {
61464                _didIteratorError3 = true;
61465                _iteratorError3 = err;
61466              } finally {
61467                try {
61468                  if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
61469                    _iterator3.return();
61470                  }
61471                } finally {
61472                  if (_didIteratorError3) {
61473                    throw _iteratorError3;
61474                  }
61475                }
61476              }
61477            };
61478
61479            self.value = function() {
61480              var result = '';
61481              var _iteratorNormalCompletion4 = true;
61482              var _didIteratorError4 = false;
61483              var _iteratorError4 = undefined;
61484              try {
61485                for (
61486                  var _iterator4 = self._getOptionsArray()[Symbol.iterator](), _step4;
61487                  !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done);
61488                  _iteratorNormalCompletion4 = true
61489                ) {
61490                  var option = _step4.value;
61491                  if (option.checked) {
61492                    result = option.value;
61493                    break;
61494                  }
61495                }
61496              } catch (err) {
61497                _didIteratorError4 = true;
61498                _iteratorError4 = err;
61499              } finally {
61500                try {
61501                  if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
61502                    _iterator4.return();
61503                  }
61504                } finally {
61505                  if (_didIteratorError4) {
61506                    throw _iteratorError4;
61507                  }
61508                }
61509              }
61510              return result;
61511            };
61512
61513            self.selected = function(value) {
61514              var result = null;
61515              if (value === undefined) {
61516                var _iteratorNormalCompletion5 = true;
61517                var _didIteratorError5 = false;
61518                var _iteratorError5 = undefined;
61519                try {
61520                  for (
61521                    var _iterator5 = self._getOptionsArray()[Symbol.iterator](), _step5;
61522                    !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done);
61523                    _iteratorNormalCompletion5 = true
61524                  ) {
61525                    var option = _step5.value;
61526                    if (option.checked) {
61527                      result = option;
61528                      break;
61529                    }
61530                  }
61531                } catch (err) {
61532                  _didIteratorError5 = true;
61533                  _iteratorError5 = err;
61534                } finally {
61535                  try {
61536                    if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
61537                      _iterator5.return();
61538                    }
61539                  } finally {
61540                    if (_didIteratorError5) {
61541                      throw _iteratorError5;
61542                    }
61543                  }
61544                }
61545              } else {
61546                var _iteratorNormalCompletion6 = true;
61547                var _didIteratorError6 = false;
61548                var _iteratorError6 = undefined;
61549                try {
61550                  for (
61551                    var _iterator6 = self._getOptionsArray()[Symbol.iterator](), _step6;
61552                    !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done);
61553                    _iteratorNormalCompletion6 = true
61554                  ) {
61555                    var _option = _step6.value;
61556                    if (_option.value === value) {
61557                      _option.setAttribute('checked', true);
61558                      result = _option;
61559                    }
61560                  }
61561                } catch (err) {
61562                  _didIteratorError6 = true;
61563                  _iteratorError6 = err;
61564                } finally {
61565                  try {
61566                    if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
61567                      _iterator6.return();
61568                    }
61569                  } finally {
61570                    if (_didIteratorError6) {
61571                      throw _iteratorError6;
61572                    }
61573                  }
61574                }
61575              }
61576              return result;
61577            };
61578
61579            self.disable = function() {
61580              var shouldDisable =
61581                arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
61582              var _iteratorNormalCompletion7 = true;
61583              var _didIteratorError7 = false;
61584              var _iteratorError7 = undefined;
61585              try {
61586                for (
61587                  var _iterator7 = self._getOptionsArray()[Symbol.iterator](), _step7;
61588                  !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done);
61589                  _iteratorNormalCompletion7 = true
61590                ) {
61591                  var radioInput = _step7.value;
61592                  radioInput.setAttribute('disabled', shouldDisable);
61593                }
61594              } catch (err) {
61595                _didIteratorError7 = true;
61596                _iteratorError7 = err;
61597              } finally {
61598                try {
61599                  if (!_iteratorNormalCompletion7 && _iterator7.return != null) {
61600                    _iterator7.return();
61601                  }
61602                } finally {
61603                  if (_didIteratorError7) {
61604                    throw _iteratorError7;
61605                  }
61606                }
61607              }
61608            };
61609
61610            return self;
61611          };
61612
61613          /**
61614           * Creates a colorPicker element in the DOM for color input.
61615           * The .value() method will return a hex string (#rrggbb) of the color.
61616           * The .color() method will return a p5.Color object with the current chosen color.
61617           *
61618           * @method createColorPicker
61619           * @param {String|p5.Color} [value] default color of element
61620           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
61621           * @example
61622           * <div><code>
61623           * let colorPicker;
61624           * function setup() {
61625           *   createCanvas(100, 100);
61626           *   colorPicker = createColorPicker('#ed225d');
61627           *   colorPicker.position(0, height + 5);
61628           * }
61629           *
61630           * function draw() {
61631           *   background(colorPicker.color());
61632           * }
61633           * </code></div>
61634           * <div><code>
61635           * let inp1, inp2;
61636           * function setup() {
61637           *   createCanvas(100, 100);
61638           *   background('grey');
61639           *   inp1 = createColorPicker('#ff0000');
61640           *   inp1.position(0, height + 5);
61641           *   inp1.input(setShade1);
61642           *   inp2 = createColorPicker(color('yellow'));
61643           *   inp2.position(0, height + 30);
61644           *   inp2.input(setShade2);
61645           *   setMidShade();
61646           * }
61647           *
61648           * function setMidShade() {
61649           *   // Finding a shade between the two
61650           *   let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);
61651           *   fill(commonShade);
61652           *   rect(20, 20, 60, 60);
61653           * }
61654           *
61655           * function setShade1() {
61656           *   setMidShade();
61657           *   console.log('You are choosing shade 1 to be : ', this.value());
61658           * }
61659           * function setShade2() {
61660           *   setMidShade();
61661           *   console.log('You are choosing shade 2 to be : ', this.value());
61662           * }
61663           * </code></div>
61664           */
61665          _main.default.prototype.createColorPicker = function(value) {
61666            _main.default._validateParameters('createColorPicker', arguments);
61667            var elt = document.createElement('input');
61668            var self;
61669            elt.type = 'color';
61670            if (value) {
61671              if (value instanceof _main.default.Color) {
61672                elt.value = value.toString('#rrggbb');
61673              } else {
61674                _main.default.prototype._colorMode = 'rgb';
61675                _main.default.prototype._colorMaxes = {
61676                  rgb: [255, 255, 255, 255],
61677                  hsb: [360, 100, 100, 1],
61678                  hsl: [360, 100, 100, 1]
61679                };
61680
61681                elt.value = _main.default.prototype.color(value).toString('#rrggbb');
61682              }
61683            } else {
61684              elt.value = '#000000';
61685            }
61686            self = addElement(elt, this);
61687            // Method to return a p5.Color object for the given color.
61688            self.color = function() {
61689              if (value) {
61690                if (value.mode) {
61691                  _main.default.prototype._colorMode = value.mode;
61692                }
61693                if (value.maxes) {
61694                  _main.default.prototype._colorMaxes = value.maxes;
61695                }
61696              }
61697              return _main.default.prototype.color(this.elt.value);
61698            };
61699            return self;
61700          };
61701
61702          /**
61703           * Creates an `&lt;input&gt;&lt;/input&gt;` element in the DOM for text input.
61704           * Use .<a href="#/p5.Element/size">size()</a> to set the display length of the box.
61705           *
61706           * @method createInput
61707           * @param {String} value default value of the input box
61708           * @param {String} [type] type of text, ie text, password etc. Defaults to text.
61709           *   Needs a value to be specified first.
61710           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
61711           * @example
61712           * <div class='norender'><code>
61713           * function setup() {
61714           *   let inp = createInput('');
61715           *   inp.input(myInputEvent);
61716           * }
61717           *
61718           * function myInputEvent() {
61719           *   console.log('you are typing: ', this.value());
61720           * }
61721           * </code></div>
61722           */
61723          /**
61724           * @method createInput
61725           * @param {String} [value]
61726           * @return {p5.Element}
61727           */
61728          _main.default.prototype.createInput = function() {
61729            var value =
61730              arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
61731            var type =
61732              arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'text';
61733            _main.default._validateParameters('createInput', arguments);
61734            var elt = document.createElement('input');
61735            elt.setAttribute('value', value);
61736            elt.setAttribute('type', type);
61737            return addElement(elt, this);
61738          };
61739
61740          /**
61741           * Creates an `&lt;input&gt;&lt;/input&gt;` element in the DOM of type 'file'.
61742           * This allows users to select local files for use in a sketch.
61743           *
61744           * @method createFileInput
61745           * @param  {Function} callback callback function for when a file is loaded
61746           * @param  {Boolean} [multiple] optional, to allow multiple files to be selected
61747           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created DOM element
61748           * @example
61749           * <div><code>
61750           * let input;
61751           * let img;
61752           *
61753           * function setup() {
61754           *   input = createFileInput(handleFile);
61755           *   input.position(0, 0);
61756           * }
61757           *
61758           * function draw() {
61759           *   background(255);
61760           *   if (img) {
61761           *     image(img, 0, 0, width, height);
61762           *   }
61763           * }
61764           *
61765           * function handleFile(file) {
61766           *   print(file);
61767           *   if (file.type === 'image') {
61768           *     img = createImg(file.data, '');
61769           *     img.hide();
61770           *   } else {
61771           *     img = null;
61772           *   }
61773           * }
61774           * </code></div>
61775           */
61776          _main.default.prototype.createFileInput = function(callback) {
61777            var multiple =
61778              arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
61779            _main.default._validateParameters('createFileInput', arguments);
61780
61781            var handleFileSelect = function handleFileSelect(event) {
61782              var _iteratorNormalCompletion8 = true;
61783              var _didIteratorError8 = false;
61784              var _iteratorError8 = undefined;
61785              try {
61786                for (
61787                  var _iterator8 = event.target.files[Symbol.iterator](), _step8;
61788                  !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done);
61789                  _iteratorNormalCompletion8 = true
61790                ) {
61791                  var file = _step8.value;
61792                  _main.default.File._load(file, callback);
61793                }
61794              } catch (err) {
61795                _didIteratorError8 = true;
61796                _iteratorError8 = err;
61797              } finally {
61798                try {
61799                  if (!_iteratorNormalCompletion8 && _iterator8.return != null) {
61800                    _iterator8.return();
61801                  }
61802                } finally {
61803                  if (_didIteratorError8) {
61804                    throw _iteratorError8;
61805                  }
61806                }
61807              }
61808            };
61809
61810            // If File API's are not supported, throw Error
61811            if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
61812              console.log(
61813                'The File APIs are not fully supported in this browser. Cannot create element.'
61814              );
61815
61816              return;
61817            }
61818
61819            var fileInput = document.createElement('input');
61820            fileInput.setAttribute('type', 'file');
61821            if (multiple) fileInput.setAttribute('multiple', true);
61822            fileInput.addEventListener('change', handleFileSelect, false);
61823            return addElement(fileInput, this);
61824          };
61825
61826          /** VIDEO STUFF **/
61827
61828          // Helps perform similar tasks for media element methods.
61829          function createMedia(pInst, type, src, callback) {
61830            var elt = document.createElement(type);
61831
61832            // Create source elements from given sources
61833            src = src || '';
61834            if (typeof src === 'string') {
61835              src = [src];
61836            }
61837            var _iteratorNormalCompletion9 = true;
61838            var _didIteratorError9 = false;
61839            var _iteratorError9 = undefined;
61840            try {
61841              for (
61842                var _iterator9 = src[Symbol.iterator](), _step9;
61843                !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done);
61844                _iteratorNormalCompletion9 = true
61845              ) {
61846                var mediaSource = _step9.value;
61847                var sourceEl = document.createElement('source');
61848                sourceEl.setAttribute('src', mediaSource);
61849                elt.appendChild(sourceEl);
61850              }
61851
61852              // If callback is provided, attach to element
61853            } catch (err) {
61854              _didIteratorError9 = true;
61855              _iteratorError9 = err;
61856            } finally {
61857              try {
61858                if (!_iteratorNormalCompletion9 && _iterator9.return != null) {
61859                  _iterator9.return();
61860                }
61861              } finally {
61862                if (_didIteratorError9) {
61863                  throw _iteratorError9;
61864                }
61865              }
61866            }
61867            if (typeof callback === 'function') {
61868              var callbackHandler = function callbackHandler() {
61869                callback();
61870                elt.removeEventListener('canplaythrough', callbackHandler);
61871              };
61872              elt.addEventListener('canplaythrough', callbackHandler);
61873            }
61874
61875            var mediaEl = addElement(elt, pInst, true);
61876            mediaEl.loadedmetadata = false;
61877
61878            // set width and height onload metadata
61879            elt.addEventListener('loadedmetadata', function() {
61880              mediaEl.width = elt.videoWidth;
61881              mediaEl.height = elt.videoHeight;
61882
61883              // set elt width and height if not set
61884              if (mediaEl.elt.width === 0) mediaEl.elt.width = elt.videoWidth;
61885              if (mediaEl.elt.height === 0) mediaEl.elt.height = elt.videoHeight;
61886              if (mediaEl.presetPlaybackRate) {
61887                mediaEl.elt.playbackRate = mediaEl.presetPlaybackRate;
61888                delete mediaEl.presetPlaybackRate;
61889              }
61890              mediaEl.loadedmetadata = true;
61891            });
61892
61893            return mediaEl;
61894          }
61895
61896          /**
61897           * Creates an HTML5 `&lt;video&gt;` element in the DOM for simple playback
61898           * of audio/video. Shown by default, can be hidden with .<a href="#/p5.Element/hide">hide()</a>
61899           * and drawn into canvas using <a href="#/p5/image">image()</a>. The first parameter
61900           * can be either a single string path to a video file, or an array of string
61901           * paths to different formats of the same video. This is useful for ensuring
61902           * that your video can play across different browsers, as each supports
61903           * different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this
61904           * page</a> for further information about supported formats.
61905           *
61906           * @method createVideo
61907           * @param  {String|String[]} src path to a video file, or array of paths for
61908           *                             supporting different browsers
61909           * @param  {Function} [callback] callback function to be called upon
61910           *                             'canplaythrough' event fire, that is, when the
61911           *                             browser can play the media, and estimates that
61912           *                             enough data has been loaded to play the media
61913           *                             up to its end without having to stop for
61914           *                             further buffering of content
61915           * @return {p5.MediaElement}   pointer to video <a href="#/p5.Element">p5.Element</a>
61916           * @example
61917           * <div><code>
61918           * let vid;
61919           * function setup() {
61920           *   noCanvas();
61921           *
61922           *   vid = createVideo(
61923           *     ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],
61924           *     vidLoad
61925           *   );
61926           *
61927           *   vid.size(100, 100);
61928           * }
61929           *
61930           * // This function is called when the video loads
61931           * function vidLoad() {
61932           *   vid.loop();
61933           *   vid.volume(0);
61934           * }
61935           * </code></div>
61936           */
61937          _main.default.prototype.createVideo = function(src, callback) {
61938            _main.default._validateParameters('createVideo', arguments);
61939            return createMedia(this, 'video', src, callback);
61940          };
61941
61942          /** AUDIO STUFF **/
61943
61944          /**
61945           * Creates a hidden HTML5 `&lt;audio&gt;` element in the DOM for simple audio
61946           * playback. The first parameter can be either a single string path to a
61947           * audio file, or an array of string paths to different formats of the same
61948           * audio. This is useful for ensuring that your audio can play across
61949           * different browsers, as each supports different formats.
61950           * See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this
61951           * page for further information about supported formats</a>.
61952           *
61953           * @method createAudio
61954           * @param  {String|String[]} [src] path to an audio file, or array of paths
61955           *                             for supporting different browsers
61956           * @param  {Function} [callback] callback function to be called upon
61957           *                             'canplaythrough' event fire, that is, when the
61958           *                             browser can play the media, and estimates that
61959           *                             enough data has been loaded to play the media
61960           *                             up to its end without having to stop for
61961           *                             further buffering of content
61962           * @return {p5.MediaElement}   pointer to audio <a href="#/p5.Element">p5.Element</a>
61963           * @example
61964           * <div><code>
61965           * let ele;
61966           * function setup() {
61967           *   ele = createAudio('assets/beat.mp3');
61968           *
61969           *   // here we set the element to autoplay
61970           *   // The element will play as soon
61971           *   // as it is able to do so.
61972           *   ele.autoplay(true);
61973           * }
61974           * </code></div>
61975           */
61976          _main.default.prototype.createAudio = function(src, callback) {
61977            _main.default._validateParameters('createAudio', arguments);
61978            return createMedia(this, 'audio', src, callback);
61979          };
61980
61981          /** CAMERA STUFF **/
61982
61983          /**
61984           * @property {String} VIDEO
61985           * @final
61986           * @category Constants
61987           */
61988          _main.default.prototype.VIDEO = 'video';
61989          /**
61990           * @property {String} AUDIO
61991           * @final
61992           * @category Constants
61993           */
61994          _main.default.prototype.AUDIO = 'audio';
61995
61996          // from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
61997          // Older browsers might not implement mediaDevices at all, so we set an empty object first
61998          if (navigator.mediaDevices === undefined) {
61999            navigator.mediaDevices = {};
62000          }
62001
62002          // Some browsers partially implement mediaDevices. We can't just assign an object
62003          // with getUserMedia as it would overwrite existing properties.
62004          // Here, we will just add the getUserMedia property if it's missing.
62005          if (navigator.mediaDevices.getUserMedia === undefined) {
62006            navigator.mediaDevices.getUserMedia = function(constraints) {
62007              // First get ahold of the legacy getUserMedia, if present
62008              var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
62009
62010              // Some browsers just don't implement it - return a rejected promise with an error
62011              // to keep a consistent interface
62012              if (!getUserMedia) {
62013                return Promise.reject(
62014                  new Error('getUserMedia is not implemented in this browser')
62015                );
62016              }
62017
62018              // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
62019              return new Promise(function(resolve, reject) {
62020                getUserMedia.call(navigator, constraints, resolve, reject);
62021              });
62022            };
62023          }
62024
62025          /**
62026           * Creates a new HTML5 `&lt;video&gt;` element that contains the audio/video feed
62027           * from a webcam. The element is separate from the canvas and is displayed by
62028           * default. The element can be hidden using .<a href="#/p5.Element/hide">hide()</a>.
62029           * The feed can be drawn onto the canvas using <a href="#/p5/image">image()</a>.
62030           * The loadedmetadata property can be used to detect when the element has fully
62031           * loaded (see second example).
62032           *
62033           * More specific properties of the feed can be passing in a Constraints object.
62034           * See the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>
62035           * W3C spec</a> for possible properties. Note that not all of these are supported
62036           * by all browsers.
62037           *
62038           * <em>Security note</em>: A new browser security specification requires that
62039           * getUserMedia, which is behind <a href="#/p5/createCapture">createCapture()</a>,
62040           * only works when you're running the code locally, or on HTTPS. Learn more
62041           * <a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>
62042           * and <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.
62043           *
62044           * @method createCapture
62045           * @param  {String|Constant|Object}   type type of capture, either VIDEO or
62046           *                                   AUDIO if none specified, default both,
62047           *                                   or a Constraints object
62048           * @param  {Function}                 [callback] function to be called once
62049           *                                   stream has loaded
62050           * @return {p5.Element} capture video <a href="#/p5.Element">p5.Element</a>
62051           * @example
62052           * <div class='norender notest'>
62053           * <code>
62054           * let capture;
62055           *
62056           * function setup() {
62057           *   createCanvas(480, 480);
62058           *   capture = createCapture(VIDEO);
62059           *   capture.hide();
62060           * }
62061           *
62062           * function draw() {
62063           *   image(capture, 0, 0, width, width * capture.height / capture.width);
62064           *   filter(INVERT);
62065           * }
62066           * </code>
62067           * </div>
62068           *
62069           * <div class='norender notest'>
62070           * <code>
62071           * function setup() {
62072           *   createCanvas(480, 120);
62073           *   let constraints = {
62074           *     video: {
62075           *       mandatory: {
62076           *         minWidth: 1280,
62077           *         minHeight: 720
62078           *       },
62079           *       optional: [{ maxFrameRate: 10 }]
62080           *     },
62081           *     audio: true
62082           *   };
62083           *   createCapture(constraints, function(stream) {
62084           *     console.log(stream);
62085           *   });
62086           * }
62087           * </code>
62088           * </div>
62089           * <div class='norender notest'>
62090           * <code>
62091           * let capture;
62092           *
62093           * function setup() {
62094           *   createCanvas(640, 480);
62095           *   capture = createCapture(VIDEO);
62096           * }
62097           * function draw() {
62098           *   background(0);
62099           *   if (capture.loadedmetadata) {
62100           *     let c = capture.get(0, 0, 100, 100);
62101           *     image(c, 0, 0);
62102           *   }
62103           * }
62104           * </code>
62105           * </div>
62106           */
62107          _main.default.prototype.createCapture = function() {
62108            _main.default._validateParameters('createCapture', arguments);
62109
62110            // return if getUserMedia is not supported by browser
62111            if (!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia)) {
62112              throw new DOMException('getUserMedia not supported in this browser');
62113            }
62114
62115            var useVideo = true;
62116            var useAudio = true;
62117            var constraints;
62118            var callback;
62119            var _iteratorNormalCompletion10 = true;
62120            var _didIteratorError10 = false;
62121            var _iteratorError10 = undefined;
62122            try {
62123              for (
62124                var _iterator10 = arguments[Symbol.iterator](), _step10;
62125                !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done);
62126                _iteratorNormalCompletion10 = true
62127              ) {
62128                var arg = _step10.value;
62129                if (arg === _main.default.prototype.VIDEO) useAudio = false;
62130                else if (arg === _main.default.prototype.AUDIO) useVideo = false;
62131                else if (_typeof(arg) === 'object') constraints = arg;
62132                else if (typeof arg === 'function') callback = arg;
62133              }
62134            } catch (err) {
62135              _didIteratorError10 = true;
62136              _iteratorError10 = err;
62137            } finally {
62138              try {
62139                if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
62140                  _iterator10.return();
62141                }
62142              } finally {
62143                if (_didIteratorError10) {
62144                  throw _iteratorError10;
62145                }
62146              }
62147            }
62148            if (!constraints) constraints = { video: useVideo, audio: useAudio };
62149
62150            var domElement = document.createElement('video');
62151            // required to work in iOS 11 & up:
62152            domElement.setAttribute('playsinline', '');
62153
62154            navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
62155              try {
62156                if ('srcObject' in domElement) {
62157                  domElement.srcObject = stream;
62158                } else {
62159                  domElement.src = window.URL.createObjectURL(stream);
62160                }
62161              } catch (err) {
62162                domElement.src = stream;
62163              }
62164            }, console.log);
62165
62166            var videoEl = addElement(domElement, this, true);
62167            videoEl.loadedmetadata = false;
62168            // set width and height onload metadata
62169            domElement.addEventListener('loadedmetadata', function() {
62170              domElement.play();
62171              if (domElement.width) {
62172                videoEl.width = domElement.width;
62173                videoEl.height = domElement.height;
62174              } else {
62175                videoEl.width = videoEl.elt.width = domElement.videoWidth;
62176                videoEl.height = videoEl.elt.height = domElement.videoHeight;
62177              }
62178              videoEl.loadedmetadata = true;
62179
62180              if (callback) callback(domElement.srcObject);
62181            });
62182            return videoEl;
62183          };
62184
62185          /**
62186           * Creates element with given tag in the DOM with given content.
62187           *
62188           * @method createElement
62189           * @param  {String} tag tag for the new element
62190           * @param  {String} [content] html content to be inserted into the element
62191           * @return {p5.Element} pointer to <a href="#/p5.Element">p5.Element</a> holding created node
62192           * @example
62193           * <div class='norender'><code>
62194           * createElement('h2', 'im an h2 p5.element!');
62195           * </code></div>
62196           */
62197          _main.default.prototype.createElement = function(tag, content) {
62198            _main.default._validateParameters('createElement', arguments);
62199            var elt = document.createElement(tag);
62200            if (typeof content !== 'undefined') {
62201              elt.innerHTML = content;
62202            }
62203            return addElement(elt, this);
62204          };
62205
62206          // =============================================================================
62207          //                         p5.Element additions
62208          // =============================================================================
62209          /**
62210           *
62211           * Adds specified class to the element.
62212           *
62213           * @for p5.Element
62214           * @method addClass
62215           * @param  {String} class name of class to add
62216           * @chainable
62217           * @example
62218           * <div class='norender'><code>
62219           * let div = createDiv('div');
62220           * div.addClass('myClass');
62221           * </code></div>
62222           */
62223          _main.default.Element.prototype.addClass = function(c) {
62224            if (this.elt.className) {
62225              if (!this.hasClass(c)) {
62226                this.elt.className = this.elt.className + ' ' + c;
62227              }
62228            } else {
62229              this.elt.className = c;
62230            }
62231            return this;
62232          };
62233
62234          /**
62235           *
62236           * Removes specified class from the element.
62237           *
62238           * @method removeClass
62239           * @param  {String} class name of class to remove
62240           * @chainable
62241           * @example
62242           * <div class='norender'><code>
62243           * // In this example, a class is set when the div is created
62244           * // and removed when mouse is pressed. This could link up
62245           * // with a CSS style rule to toggle style properties.
62246           *
62247           * let div;
62248           *
62249           * function setup() {
62250           *   div = createDiv('div');
62251           *   div.addClass('myClass');
62252           * }
62253           *
62254           * function mousePressed() {
62255           *   div.removeClass('myClass');
62256           * }
62257           * </code></div>
62258           */
62259          _main.default.Element.prototype.removeClass = function(c) {
62260            // Note: Removing a class that does not exist does NOT throw an error in classList.remove method
62261            this.elt.classList.remove(c);
62262            return this;
62263          };
62264
62265          /**
62266           *
62267           * Checks if specified class already set to element
62268           *
62269           * @method hasClass
62270           * @returns {boolean} a boolean value if element has specified class
62271           * @param c {String} class name of class to check
62272           * @example
62273           * <div class='norender'><code>
62274           * let div;
62275           *
62276           * function setup() {
62277           *   div = createDiv('div');
62278           *   div.addClass('show');
62279           * }
62280           *
62281           * function mousePressed() {
62282           *   if (div.hasClass('show')) {
62283           *     div.addClass('show');
62284           *   } else {
62285           *     div.removeClass('show');
62286           *   }
62287           * }
62288           * </code></div>
62289           */
62290          _main.default.Element.prototype.hasClass = function(c) {
62291            return this.elt.classList.contains(c);
62292          };
62293
62294          /**
62295           *
62296           * Toggles element class
62297           *
62298           * @method toggleClass
62299           * @param c {String} class name to toggle
62300           * @chainable
62301           * @example
62302           * <div class='norender'><code>
62303           * let div;
62304           *
62305           * function setup() {
62306           *   div = createDiv('div');
62307           *   div.addClass('show');
62308           * }
62309           *
62310           * function mousePressed() {
62311           *   div.toggleClass('show');
62312           * }
62313           * </code></div>
62314           */
62315          _main.default.Element.prototype.toggleClass = function(c) {
62316            // classList also has a toggle() method, but we cannot use that yet as support is unclear.
62317            // See https://github.com/processing/p5.js/issues/3631
62318            // this.elt.classList.toggle(c);
62319            if (this.elt.classList.contains(c)) {
62320              this.elt.classList.remove(c);
62321            } else {
62322              this.elt.classList.add(c);
62323            }
62324            return this;
62325          };
62326
62327          /**
62328           *
62329           * Attaches the element  as a child to the parent specified.
62330           * Accepts either a string ID, DOM node, or <a href="#/p5.Element">p5.Element</a>.
62331           * If no argument is specified, an array of children DOM nodes is returned.
62332           *
62333           * @method child
62334           * @returns {Node[]} an array of child nodes
62335           * @example
62336           * <div class='norender'><code>
62337           * let div0 = createDiv('this is the parent');
62338           * let div1 = createDiv('this is the child');
62339           * div0.child(div1); // use p5.Element
62340           * </code></div>
62341           * <div class='norender'><code>
62342           * let div0 = createDiv('this is the parent');
62343           * let div1 = createDiv('this is the child');
62344           * div1.id('apples');
62345           * div0.child('apples'); // use id
62346           * </code></div>
62347           * <div class='norender notest'><code>
62348           * // this example assumes there is a div already on the page
62349           * // with id "myChildDiv"
62350           * let div0 = createDiv('this is the parent');
62351           * let elt = document.getElementById('myChildDiv');
62352           * div0.child(elt); // use element from page
62353           * </code></div>
62354           */
62355          /**
62356           * @method child
62357           * @param  {String|p5.Element} [child] the ID, DOM node, or <a href="#/p5.Element">p5.Element</a>
62358           *                         to add to the current element
62359           * @chainable
62360           */
62361          _main.default.Element.prototype.child = function(childNode) {
62362            if (typeof childNode === 'undefined') {
62363              return this.elt.childNodes;
62364            }
62365            if (typeof childNode === 'string') {
62366              if (childNode[0] === '#') {
62367                childNode = childNode.substring(1);
62368              }
62369              childNode = document.getElementById(childNode);
62370            } else if (childNode instanceof _main.default.Element) {
62371              childNode = childNode.elt;
62372            }
62373
62374            if (childNode instanceof HTMLElement) {
62375              this.elt.appendChild(childNode);
62376            }
62377            return this;
62378          };
62379
62380          /**
62381           * Centers a p5 Element either vertically, horizontally,
62382           * or both, relative to its parent or according to
62383           * the body if the Element has no parent. If no argument is passed
62384           * the Element is aligned both vertically and horizontally.
62385           *
62386           * @method center
62387           * @param  {String} [align]       passing 'vertical', 'horizontal' aligns element accordingly
62388           * @chainable
62389           *
62390           * @example
62391           * <div><code>
62392           * function setup() {
62393           *   let div = createDiv('').size(10, 10);
62394           *   div.style('background-color', 'orange');
62395           *   div.center();
62396           * }
62397           * </code></div>
62398           */
62399          _main.default.Element.prototype.center = function(align) {
62400            var style = this.elt.style.display;
62401            var hidden = this.elt.style.display === 'none';
62402            var parentHidden = this.parent().style.display === 'none';
62403            var pos = { x: this.elt.offsetLeft, y: this.elt.offsetTop };
62404
62405            if (hidden) this.show();
62406            if (parentHidden) this.parent().show();
62407            this.elt.style.display = 'block';
62408
62409            this.position(0, 0);
62410            var wOffset = Math.abs(this.parent().offsetWidth - this.elt.offsetWidth);
62411            var hOffset = Math.abs(this.parent().offsetHeight - this.elt.offsetHeight);
62412
62413            if (align === 'both' || align === undefined) {
62414              this.position(
62415                wOffset / 2 + this.parent().offsetLeft,
62416                hOffset / 2 + this.parent().offsetTop
62417              );
62418            } else if (align === 'horizontal') {
62419              this.position(wOffset / 2 + this.parent().offsetLeft, pos.y);
62420            } else if (align === 'vertical') {
62421              this.position(pos.x, hOffset / 2 + this.parent().offsetTop);
62422            }
62423
62424            this.style('display', style);
62425            if (hidden) this.hide();
62426            if (parentHidden) this.parent().hide();
62427
62428            return this;
62429          };
62430
62431          /**
62432           *
62433           * If an argument is given, sets the inner HTML of the element,
62434           * replacing any existing html. If true is included as a second
62435           * argument, html is appended instead of replacing existing html.
62436           * If no arguments are given, returns
62437           * the inner HTML of the element.
62438           *
62439           * @for p5.Element
62440           * @method html
62441           * @returns {String} the inner HTML of the element
62442           * @example
62443           * <div class='norender'><code>
62444           * let div = createDiv('').size(100, 100);
62445           * div.html('hi');
62446           * </code></div>
62447           * <div class='norender'><code>
62448           * let div = createDiv('Hello ').size(100, 100);
62449           * div.html('World', true);
62450           * </code></div>
62451           */
62452          /**
62453           * @method html
62454           * @param  {String} [html] the HTML to be placed inside the element
62455           * @param  {boolean} [append] whether to append HTML to existing
62456           * @chainable
62457           */
62458          _main.default.Element.prototype.html = function() {
62459            if (arguments.length === 0) {
62460              return this.elt.innerHTML;
62461            } else if (arguments[1]) {
62462              this.elt.insertAdjacentHTML('beforeend', arguments[0]);
62463              return this;
62464            } else {
62465              this.elt.innerHTML = arguments[0];
62466              return this;
62467            }
62468          };
62469
62470          /**
62471           *
62472           * Sets the position of the element. If no position type argument is given, the
62473           * position will be relative to (0, 0) of the window.
62474           * Essentially, this sets position:absolute and left and top
62475           * properties of style. If an optional third argument specifying position type is given,
62476           * the x and y coordinates will be interpreted based on the <a target="_blank"
62477           * href="https://developer.mozilla.org/en-US/docs/Web/CSS/position">positioning scheme</a>.
62478           * If no arguments given, the function returns the x and y position of the element.
62479           *
62480           * found documentation on how to be more specific with object type
62481           * https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literal
62481s-in-yuidoc
62482           *
62483           * @method position
62484           * @returns {Object} object of form { x: 0, y: 0 } containing the position of the element in an object
62485           * @example
62486           * <div><code class='norender'>
62487           * function setup() {
62488           *   let cnv = createCanvas(100, 100);
62489           *   // positions canvas 50px to the right and 100px
62490           *   // below upper left corner of the window
62491           *   cnv.position(50, 100);
62492           * }
62493           * </code></div>
62494           * <div><code class='norender'>
62495           * function setup() {
62496           *   let cnv = createCanvas(100, 100);
62497           *   // positions canvas 50px to the right and 100px
62498           *   // below upper left corner of the window
62499           *   cnv.position(0, 0, 'fixed');
62500           * }
62501           * </code></div>
62502           */
62503          /**
62504           * @method position
62505           * @param  {Number} [x] x-position relative to upper left of window (optional)
62506           * @param  {Number} [y] y-position relative to upper left of window (optional)
62507           * @param  {String} positionType it can be static, fixed, relative, sticky, initial or inherit (optional)
62508           * @chainable
62509           */
62510          _main.default.Element.prototype.position = function() {
62511            if (arguments.length === 0) {
62512              return { x: this.elt.offsetLeft, y: this.elt.offsetTop };
62513            } else {
62514              var positionType = 'absolute';
62515              if (
62516                arguments[2] === 'static' ||
62517                arguments[2] === 'fixed' ||
62518                arguments[2] === 'relative' ||
62519                arguments[2] === 'sticky' ||
62520                arguments[2] === 'initial' ||
62521                arguments[2] === 'inherit'
62522              ) {
62523                positionType = arguments[2];
62524              }
62525              this.elt.style.position = positionType;
62526              this.elt.style.left = arguments[0] + 'px';
62527              this.elt.style.top = arguments[1] + 'px';
62528              this.x = arguments[0];
62529              this.y = arguments[1];
62530              return this;
62531            }
62532          };
62533
62534          /* Helper method called by p5.Element.style() */
62535          _main.default.Element.prototype._translate = function() {
62536            this.elt.style.position = 'absolute';
62537            // save out initial non-translate transform styling
62538            var transform = '';
62539            if (this.elt.style.transform) {
62540              transform = this.elt.style.transform.replace(/translate3d\(.*\)/g, '');
62541              transform = transform.replace(/translate[X-Z]?\(.*\)/g, '');
62542            }
62543            if (arguments.length === 2) {
62544              this.elt.style.transform =
62545                'translate(' + arguments[0] + 'px, ' + arguments[1] + 'px)';
62546            } else if (arguments.length > 2) {
62547              this.elt.style.transform =
62548                'translate3d(' +
62549                arguments[0] +
62550                'px,' +
62551                arguments[1] +
62552                'px,' +
62553                arguments[2] +
62554                'px)';
62555              if (arguments.length === 3) {
62556                this.elt.parentElement.style.perspective = '1000px';
62557              } else {
62558                this.elt.parentElement.style.perspective = arguments[3] + 'px';
62559              }
62560            }
62561            // add any extra transform styling back on end
62562            this.elt.style.transform += transform;
62563            return this;
62564          };
62565
62566          /* Helper method called by p5.Element.style() */
62567          _main.default.Element.prototype._rotate = function() {
62568            // save out initial non-rotate transform styling
62569            var transform = '';
62570            if (this.elt.style.transform) {
62571              transform = this.elt.style.transform.replace(/rotate3d\(.*\)/g, '');
62572              transform = transform.replace(/rotate[X-Z]?\(.*\)/g, '');
62573            }
62574
62575            if (arguments.length === 1) {
62576              this.elt.style.transform = 'rotate(' + arguments[0] + 'deg)';
62577            } else if (arguments.length === 2) {
62578              this.elt.style.transform =
62579                'rotate(' + arguments[0] + 'deg, ' + arguments[1] + 'deg)';
62580            } else if (arguments.length === 3) {
62581              this.elt.style.transform = 'rotateX(' + arguments[0] + 'deg)';
62582              this.elt.style.transform += 'rotateY(' + arguments[1] + 'deg)';
62583              this.elt.style.transform += 'rotateZ(' + arguments[2] + 'deg)';
62584            }
62585            // add remaining transform back on
62586            this.elt.style.transform += transform;
62587            return this;
62588          };
62589
62590          /**
62591           * Sets the given style (css) property (1st arg) of the element with the
62592           * given value (2nd arg). If a single argument is given, .style()
62593           * returns the value of the given property; however, if the single argument
62594           * is given in css syntax ('text-align:center'), .style() sets the css
62595           * appropriately.
62596           *
62597           * @method style
62598           * @param  {String} property   property to be set
62599           * @returns {String} value of property
62600           * @example
62601           * <div><code class='norender'>
62602           * let myDiv = createDiv('I like pandas.');
62603           * myDiv.style('font-size', '18px');
62604           * myDiv.style('color', '#ff0000');
62605           * </code></div>
62606           * <div><code class='norender'>
62607           * let col = color(25, 23, 200, 50);
62608           * let button = createButton('button');
62609           * button.style('background-color', col);
62610           * button.position(10, 10);
62611           * </code></div>
62612           * <div><code class='norender'>
62613           * let myDiv;
62614           * function setup() {
62615           *   background(200);
62616           *   myDiv = createDiv('I like gray.');
62617           *   myDiv.position(20, 20);
62618           * }
62619           *
62620           * function draw() {
62621           *   myDiv.style('font-size', mouseX + 'px');
62622           * }
62623           * </code></div>
62624           */
62625          /**
62626           * @method style
62627           * @param  {String} property
62628           * @param  {String|p5.Color} value     value to assign to property
62629           * @return {String} current value of property, if no value is given as second argument
62630           * @chainable
62631           */
62632          _main.default.Element.prototype.style = function(prop, val) {
62633            var self = this;
62634
62635            if (val instanceof _main.default.Color) {
62636              val =
62637                'rgba(' +
62638                val.levels[0] +
62639                ',' +
62640                val.levels[1] +
62641                ',' +
62642                val.levels[2] +
62643                ',' +
62644                val.levels[3] / 255 +
62645                ')';
62646            }
62647
62648            if (typeof val === 'undefined') {
62649              if (prop.indexOf(':') === -1) {
62650                // no value set, so assume requesting a value
62651                var styles = window.getComputedStyle(self.elt);
62652                var style = styles.getPropertyValue(prop);
62653                return style;
62654              } else {
62655                // value set using `:` in a single line string
62656                var attrs = prop.split(';');
62657                for (var i = 0; i < attrs.length; i++) {
62658                  var parts = attrs[i].split(':');
62659                  if (parts[0] && parts[1]) {
62660                    this.elt.style[parts[0].trim()] = parts[1].trim();
62661                  }
62662                }
62663              }
62664            } else {
62665              // input provided as key,val pair
62666              this.elt.style[prop] = val;
62667              if (
62668                prop === 'width' ||
62669                prop === 'height' ||
62670                prop === 'left' ||
62671                prop === 'top'
62672              ) {
62673                var _styles = window.getComputedStyle(self.elt);
62674                var styleVal = _styles.getPropertyValue(prop);
62675                var numVal = styleVal.replace(/\D+/g, '');
62676                this[prop] = parseInt(numVal, 10);
62677              }
62678            }
62679            return this;
62680          };
62681
62682          /**
62683           *
62684           * Adds a new attribute or changes the value of an existing attribute
62685           * on the specified element. If no value is specified, returns the
62686           * value of the given attribute, or null if attribute is not set.
62687           *
62688           * @method attribute
62689           * @return {String} value of attribute
62690           *
62691           * @example
62692           * <div class='norender'><code>
62693           * let myDiv = createDiv('I like pandas.');
62694           * myDiv.attribute('align', 'center');
62695           * </code></div>
62696           */
62697          /**
62698           * @method attribute
62699           * @param  {String} attr       attribute to set
62700           * @param  {String} value      value to assign to attribute
62701           * @chainable
62702           */
62703          _main.default.Element.prototype.attribute = function(attr, value) {
62704            //handling for checkboxes and radios to ensure options get
62705            //attributes not divs
62706            if (
62707              this.elt.firstChild != null &&
62708              (this.elt.firstChild.type === 'checkbox' ||
62709                this.elt.firstChild.type === 'radio')
62710            ) {
62711              if (typeof value === 'undefined') {
62712                return this.elt.firstChild.getAttribute(attr);
62713              } else {
62714                for (var i = 0; i < this.elt.childNodes.length; i++) {
62715                  this.elt.childNodes[i].setAttribute(attr, value);
62716                }
62717              }
62718            } else if (typeof value === 'undefined') {
62719              return this.elt.getAttribute(attr);
62720            } else {
62721              this.elt.setAttribute(attr, value);
62722              return this;
62723            }
62724          };
62725
62726          /**
62727           *
62728           * Removes an attribute on the specified element.
62729           *
62730           * @method removeAttribute
62731           * @param  {String} attr       attribute to remove
62732           * @chainable
62733           *
62734           * @example
62735           * <div><code>
62736           * let button;
62737           * let checkbox;
62738           *
62739           * function setup() {
62740           *   checkbox = createCheckbox('enable', true);
62741           *   checkbox.changed(enableButton);
62742           *   button = createButton('button');
62743           *   button.position(10, 10);
62744           * }
62745           *
62746           * function enableButton() {
62747           *   if (this.checked()) {
62748           *     // Re-enable the button
62749           *     button.removeAttribute('disabled');
62750           *   } else {
62751           *     // Disable the button
62752           *     button.attribute('disabled', '');
62753           *   }
62754           * }
62755           * </code></div>
62756           */
62757          _main.default.Element.prototype.removeAttribute = function(attr) {
62758            if (
62759              this.elt.firstChild != null &&
62760              (this.elt.firstChild.type === 'checkbox' ||
62761                this.elt.firstChild.type === 'radio')
62762            ) {
62763              for (var i = 0; i < this.elt.childNodes.length; i++) {
62764                this.elt.childNodes[i].removeAttribute(attr);
62765              }
62766            }
62767            this.elt.removeAttribute(attr);
62768            return this;
62769          };
62770
62771          /**
62772           * Either returns the value of the element if no arguments
62773           * given, or sets the value of the element.
62774           *
62775           * @method value
62776           * @return {String|Number} value of the element
62777           * @example
62778           * <div class='norender'><code>
62779           * // gets the value
62780           * let inp;
62781           * function setup() {
62782           *   inp = createInput('');
62783           * }
62784           *
62785           * function mousePressed() {
62786           *   print(inp.value());
62787           * }
62788           * </code></div>
62789           * <div class='norender'><code>
62790           * // sets the value
62791           * let inp;
62792           * function setup() {
62793           *   inp = createInput('myValue');
62794           * }
62795           *
62796           * function mousePressed() {
62797           *   inp.value('myValue');
62798           * }
62799           * </code></div>
62800           */
62801          /**
62802           * @method value
62803           * @param  {String|Number}     value
62804           * @chainable
62805           */
62806          _main.default.Element.prototype.value = function() {
62807            if (arguments.length > 0) {
62808              this.elt.value = arguments[0];
62809              return this;
62810            } else {
62811              if (this.elt.type === 'range') {
62812                return parseFloat(this.elt.value);
62813              } else return this.elt.value;
62814            }
62815          };
62816
62817          /**
62818           *
62819           * Shows the current element. Essentially, setting display:block for the style.
62820           *
62821           * @method show
62822           * @chainable
62823           * @example
62824           * <div class='norender'><code>
62825           * let div = createDiv('div');
62826           * div.style('display', 'none');
62827           * div.show(); // turns display to block
62828           * </code></div>
62829           */
62830          _main.default.Element.prototype.show = function() {
62831            this.elt.style.display = 'block';
62832            return this;
62833          };
62834
62835          /**
62836           * Hides the current element. Essentially, setting display:none for the style.
62837           *
62838           * @method hide
62839           * @chainable
62840           * @example
62841           * <div class='norender'><code>
62842           * let div = createDiv('this is a div');
62843           * div.hide();
62844           * </code></div>
62845           */
62846          _main.default.Element.prototype.hide = function() {
62847            this.elt.style.display = 'none';
62848            return this;
62849          };
62850
62851          /**
62852           *
62853           * Sets the width and height of the element. AUTO can be used to
62854           * only adjust one dimension at a time. If no arguments are given, it
62855           * returns the width and height of the element in an object. In case of
62856           * elements which need to be loaded, such as images, it is recommended
62857           * to call the function after the element has finished loading.
62858           *
62859           * @method size
62860           * @return {Object} the width and height of the element in an object
62861           * @example
62862           * <div class='norender'><code>
62863           * let div = createDiv('this is a div');
62864           * div.size(100, 100);
62865           * let img = createImg(
62866           *   'assets/rockies.jpg',
62867           *   'A tall mountain with a small forest and field in front of it on a sunny day',
62868           *   '',
62869           *   () => {
62870           *     img.size(10, AUTO);
62871           *   }
62872           * );
62873           * </code></div>
62874           */
62875          /**
62876           * @method size
62877           * @param  {Number|Constant} w    width of the element, either AUTO, or a number
62878           * @param  {Number|Constant} [h] height of the element, either AUTO, or a number
62879           * @chainable
62880           */
62881          _main.default.Element.prototype.size = function(w, h) {
62882            if (arguments.length === 0) {
62883              return { width: this.elt.offsetWidth, height: this.elt.offsetHeight };
62884            } else {
62885              var aW = w;
62886              var aH = h;
62887              var AUTO = _main.default.prototype.AUTO;
62888              if (aW !== AUTO || aH !== AUTO) {
62889                if (aW === AUTO) {
62890                  aW = h * this.width / this.height;
62891                } else if (aH === AUTO) {
62892                  aH = w * this.height / this.width;
62893                }
62894                // set diff for cnv vs normal div
62895                if (this.elt instanceof HTMLCanvasElement) {
62896                  var j = {};
62897                  var k = this.elt.getContext('2d');
62898                  var prop;
62899                  for (prop in k) {
62900                    j[prop] = k[prop];
62901                  }
62902                  this.elt.setAttribute('width', aW * this._pInst._pixelDensity);
62903                  this.elt.setAttribute('height', aH * this._pInst._pixelDensity);
62904                  this.elt.style.width = aW + 'px';
62905                  this.elt.style.height = aH + 'px';
62906                  this._pInst.scale(this._pInst._pixelDensity, this._pInst._pixelDensity);
62907                  for (prop in j) {
62908                    this.elt.getContext('2d')[prop] = j[prop];
62909                  }
62910                } else {
62911                  this.elt.style.width = aW + 'px';
62912                  this.elt.style.height = aH + 'px';
62913                  this.elt.width = aW;
62914                  this.elt.height = aH;
62915                }
62916
62917                this.width = this.elt.offsetWidth;
62918                this.height = this.elt.offsetHeight;
62919
62920                if (this._pInst && this._pInst._curElement) {
62921                  // main canvas associated with p5 instance
62922                  if (this._pInst._curElement.elt === this.elt) {
62923                    this._pInst._setProperty('width', this.elt.offsetWidth);
62924                    this._pInst._setProperty('height', this.elt.offsetHeight);
62925                  }
62926                }
62927              }
62928              return this;
62929            }
62930          };
62931
62932          /**
62933           * Removes the element, stops all media streams, and deregisters all listeners.
62934           * @method remove
62935           * @example
62936           * <div class='norender'><code>
62937           * let myDiv = createDiv('this is some text');
62938           * myDiv.remove();
62939           * </code></div>
62940           */
62941          _main.default.Element.prototype.remove = function() {
62942            // stop all audios/videos and detach all devices like microphone/camera etc
62943            // used as input/output for audios/videos.
62944            if (this instanceof _main.default.MediaElement) {
62945              this.stop();
62946              var sources = this.elt.srcObject;
62947              if (sources !== null) {
62948                var tracks = sources.getTracks();
62949                tracks.forEach(function(track) {
62950                  track.stop();
62951                });
62952              }
62953            }
62954
62955            // delete the reference in this._pInst._elements
62956            var index = this._pInst._elements.indexOf(this);
62957            if (index !== -1) {
62958              this._pInst._elements.splice(index, 1);
62959            }
62960
62961            // deregister events
62962            for (var ev in this._events) {
62963              this.elt.removeEventListener(ev, this._events[ev]);
62964            }
62965            if (this.elt && this.elt.parentNode) {
62966              this.elt.parentNode.removeChild(this.elt);
62967            }
62968          };
62969
62970          /**
62971           * Registers a callback that gets called every time a file that is
62972           * dropped on the element has been loaded.
62973           * p5 will load every dropped file into memory and pass it as a p5.File object to the callback.
62974           * Multiple files dropped at the same time will result in multiple calls to the callback.
62975           *
62976           * You can optionally pass a second callback which will be registered to the raw
62977           * <a href="https://developer.mozilla.org/en-US/docs/Web/Events/drop">drop</a> event.
62978           * The callback will thus be provided the original
62979           * <a href="https://developer.mozilla.org/en-US/docs/Web/API/DragEvent">DragEvent</a>.
62980           * Dropping multiple files at the same time will trigger the second callback once per drop,
62981           * whereas the first callback will trigger for each loaded file.
62982           *
62983           * @method drop
62984           * @param  {Function} callback  callback to receive loaded file, called for each file dropped.
62985           * @param  {Function}
62985 [fxn]     callback triggered once when files are dropped with the drop event.
62986           * @chainable
62987           * @example
62988           * <div><code>
62989           * function setup() {
62990           *   let c = createCanvas(100, 100);
62991           *   background(200);
62992           *   textAlign(CENTER);
62993           *   text('drop file', width / 2, height / 2);
62994           *   c.drop(gotFile);
62995           * }
62996           *
62997           * function gotFile(file) {
62998           *   background(200);
62999           *   text('received file:', width / 2, height / 2);
63000           *   text(file.name, width / 2, height / 2 + 50);
63001           * }
63002           * </code></div>
63003           *
63004           * <div><code>
63005           * let img;
63006           *
63007           * function setup() {
63008           *   let c = createCanvas(100, 100);
63009           *   background(200);
63010           *   textAlign(CENTER);
63011           *   text('drop image', width / 2, height / 2);
63012           *   c.drop(gotFile);
63013           * }
63014           *
63015           * function draw() {
63016           *   if (img) {
63017           *     image(img, 0, 0, width, height);
63018           *   }
63019           * }
63020           *
63021           * function gotFile(file) {
63022           *   img = createImg(file.data, '').hide();
63023           * }
63024           * </code></div>
63025           *
63026           * @alt
63027           * Canvas turns into whatever image is dragged/dropped onto it.
63028           */
63029          _main.default.Element.prototype.drop = function(callback, fxn) {
63030            // Is the file stuff supported?
63031            if (window.File && window.FileReader && window.FileList && window.Blob) {
63032              if (!this._dragDisabled) {
63033                this._dragDisabled = true;
63034
63035                var preventDefault = function preventDefault(evt) {
63036                  evt.preventDefault();
63037                };
63038
63039                // If you want to be able to drop you've got to turn off
63040                // a lot of default behavior.
63041                // avoid `attachListener` here, since it overrides other handlers.
63042                this.elt.addEventListener('dragover', preventDefault);
63043
63044                // If this is a drag area we need to turn off the default behavior
63045                this.elt.addEventListener('dragleave', preventDefault);
63046              }
63047
63048              // Deal with the files
63049              _main.default.Element._attachListener(
63050                'drop',
63051                function(evt) {
63052                  evt.preventDefault();
63053                  // Call the second argument as a callback that receives the raw drop event
63054                  if (typeof fxn === 'function') {
63055                    fxn.call(this, evt);
63056                  }
63057                  // A FileList
63058                  var files = evt.dataTransfer.files;
63059
63060                  // Load each one and trigger the callback
63061                  for (var i = 0; i < files.length; i++) {
63062                    var f = files[i];
63063                    _main.default.File._load(f, callback);
63064                  }
63065                },
63066                this
63067              );
63068            } else {
63069              console.log('The File APIs are not fully supported in this browser.');
63070            }
63071
63072            return this;
63073          };
63074
63075          // =============================================================================
63076          //                         p5.MediaElement additions
63077          // =============================================================================
63078
63079          /**
63080           * Extends <a href="#/p5.Element">p5.Element</a> to handle audio and video. In addition to the methods
63081           * of <a href="#/p5.Element">p5.Element</a>, it also contains methods for controlling media. It is not
63082           * called directly, but <a href="#/p5.MediaElement">p5.MediaElement</a>s are created by calling <a href="#/p5/createVideo">createVideo</a>,
63083           * <a href="#/p5/createAudio">createAudio</a>, and <a href="#/p5/createCapture">createCapture</a>.
63084           *
63085           * @class p5.MediaElement
63086           * @constructor
63087           * @param {String} elt DOM node that is wrapped
63088           */
63089          _main.default.MediaElement = function(elt, pInst) {
63090            _main.default.Element.call(this, elt, pInst);
63091
63092            var self = this;
63093            this.elt.crossOrigin = 'anonymous';
63094
63095            this._prevTime = 0;
63096            this._cueIDCounter = 0;
63097            this._cues = [];
63098            this._pixelsState = this;
63099            this._pixelDensity = 1;
63100            this._modified = false;
63101
63102            /**
63103             * Path to the media element source.
63104             *
63105             * @property src
63106             * @return {String} src
63107             * @example
63108             * <div><code>
63109             * let ele;
63110             *
63111             * function setup() {
63112             *   background(250);
63113             *
63114             *   //p5.MediaElement objects are usually created
63115             *   //by calling the createAudio(), createVideo(),
63116             *   //and createCapture() functions.
63117             *
63118             *   //In this example we create
63119             *   //a new p5.MediaElement via createAudio().
63120             *   ele = createAudio('assets/beat.mp3');
63121             *
63122             *   //We'll set up our example so that
63123             *   //when you click on the text,
63124             *   //an alert box displays the MediaElement's
63125             *   //src field.
63126             *   textAlign(CENTER);
63127             *   text('Click Me!', width / 2, height / 2);
63128             * }
63129             *
63130             * function mouseClicked() {
63131             *   //here we test if the mouse is over the
63132             *   //canvas element when it's clicked
63133             *   if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {
63134             *     //Show our p5.MediaElement's src field
63135             *     alert(ele.src);
63136             *   }
63137             * }
63138             * </code></div>
63139             */
63140            Object.defineProperty(self, 'src', {
63141              get: function get() {
63142                var firstChildSrc = self.elt.children[0].src;
63143                var srcVal = self.elt.src === window.location.href ? '' : self.elt.src;
63144                var ret = firstChildSrc === window.location.href ? srcVal : firstChildSrc;
63145                return ret;
63146              },
63147              set: function set(newValue) {
63148                for (var i = 0; i < self.elt.children.length; i++) {
63149                  self.elt.removeChild(self.elt.children[i]);
63150                }
63151                var source = document.createElement('source');
63152                source.src = newValue;
63153                elt.appendChild(source);
63154                self.elt.src = newValue;
63155                self.modified = true;
63156              }
63157            });
63158
63159            // private _onended callback, set by the method: onended(callback)
63160            self._onended = function() {};
63161            self.elt.onended = function() {
63162              self._onended(self);
63163            };
63164          };
63165          _main.default.MediaElement.prototype = Object.create(
63166            _main.default.Element.prototype
63167          );
63168
63169          /**
63170           * Play an HTML5 media element.
63171           *
63172           * @method play
63173           * @chainable
63174           * @example
63175           * <div><code>
63176           * let ele;
63177           *
63178           * function setup() {
63179           *   //p5.MediaElement objects are usually created
63180           *   //by calling the createAudio(), createVideo(),
63181           *   //and createCapture() functions.
63182           *
63183           *   //In this example we create
63184           *   //a new p5.MediaElement via createAudio().
63185           *   ele = createAudio('assets/beat.mp3');
63186           *
63187           *   background(250);
63188           *   textAlign(CENTER);
63189           *   text('Click to Play!', width / 2, height / 2);
63190           * }
63191           *
63192           * function mouseClicked() {
63193           *   //here we test if the mouse is over the
63194           *   //canvas element when it's clicked
63195           *   if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {
63196           *     //Here we call the play() function on
63197           *     //the p5.MediaElement we created above.
63198           *     //This will start the audio sample.
63199           *     ele.play();
63200           *
63201           *     background(200);
63202           *     text('You clicked Play!', width / 2, height / 2);
63203           *   }
63204           * }
63205           * </code></div>
63206           */
63207          _main.default.MediaElement.prototype.play = function() {
63208            var _this = this;
63209            if (this.elt.currentTime === this.elt.duration) {
63210              this.elt.currentTime = 0;
63211            }
63212            var promise;
63213            if (this.elt.readyState > 1) {
63214              promise = this.elt.play();
63215            } else {
63216              // in Chrome, playback cannot resume after being stopped and must reload
63217              this.elt.load();
63218              promise = this.elt.play();
63219            }
63220            if (promise && promise.catch) {
63221              promise.catch(function(e) {
63222                // if it's an autoplay failure error
63223                if (e.name === 'NotAllowedError') {
63224                  _main.default._friendlyAutoplayError(_this.src
63224);
63225                } else {
63226                  // any other kind of error
63227                  console.error('Media play method encountered an unexpected error', e);
63228                }
63229              });
63230            }
63231            return this;
63232          };
63233
63234          /**
63235           * Stops an HTML5 media element (sets current time to zero).
63236           *
63237           * @method stop
63238           * @chainable
63239           * @example
63240           * <div><code>
63241           * //This example both starts
63242           * //and stops a sound sample
63243           * //when the user clicks the canvas
63244           *
63245           * //We will store the p5.MediaElement
63246           * //object in here
63247           * let ele;
63248           *
63249           * //while our audio is playing,
63250           * //this will be set to true
63251           * let sampleIsPlaying = false;
63252           *
63253           * function setup() {
63254           *   //Here we create a p5.MediaElement object
63255           *   //using the createAudio() function.
63256           *   ele = createAudio('assets/beat.mp3');
63257           *   background(200);
63258           *   textAlign(CENTER);
63259           *   text('Click to play!', width / 2, height / 2);
63260           * }
63261           *
63262           * function mouseClicked() {
63263           *   //here we test if the mouse is over the
63264           *   //canvas element when it's clicked
63265           *   if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {
63266           *     background(200);
63267           *
63268           *     if (sampleIsPlaying) {
63269           *       //if the sample is currently playing
63270           *       //calling the stop() function on
63271           *       //our p5.MediaElement will stop
63272           *       //it and reset its current
63273           *       //time to 0 (i.e. it will start
63274           *       //at the beginning the next time
63275           *       //you play it)
63276           *       ele.stop();
63277           *
63278           *       sampleIsPlaying = false;
63279           *       text('Click to play!', width / 2, height / 2);
63280           *     } else {
63281           *       //loop our sound element until we
63282           *       //call ele.stop() on it.
63283           *       ele.loop();
63284           *
63285           *       sampleIsPlaying = true;
63286           *       text('Click to stop!', width / 2, height / 2);
63287           *     }
63288           *   }
63289           * }
63290           * </code></div>
63291           */
63292          _main.default.MediaElement.prototype.stop = function() {
63293            this.elt.pause();
63294            this.elt.currentTime = 0;
63295            return this;
63296          };
63297
63298          /**
63299           * Pauses an HTML5 media element.
63300           *
63301           * @method pause
63302           * @chainable
63303           * @example
63304           * <div><code>
63305           * //This example both starts
63306           * //and pauses a sound sample
63307           * //when the user clicks the canvas
63308           *
63309           * //We will store the p5.MediaElement
63310           * //object in here
63311           * let ele;
63312           *
63313           * //while our audio is playing,
63314           * //this will be set to true
63315           * let sampleIsPlaying = false;
63316           *
63317           * function setup() {
63318           *   //Here we create a p5.MediaElement object
63319           *   //using the createAudio() function.
63320           *   ele = createAudio('assets/lucky_dragons.mp3');
63321           *   background(200);
63322           *   textAlign(CENTER);
63323           *   text('Click to play!', width / 2, height / 2);
63324           * }
63325           *
63326           * function mouseClicked() {
63327           *   //here we test if the mouse is over the
63328           *   //canvas element when it's clicked
63329           *   if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {
63330           *     background(200);
63331           *
63332           *     if (sampleIsPlaying) {
63333           *       //Calling pause() on our
63334           *       //p5.MediaElement will stop it
63335           *       //playing, but when we call the
63336           *       //loop() or play() functions
63337           *       //the sample will start from
63338           *       //where we paused it.
63339           *       ele.pause();
63340           *
63341           *       sampleIsPlaying = false;
63342           *       text('Click to resume!', width / 2, height / 2);
63343           *     } else {
63344           *       //loop our sound element until we
63345           *       //call ele.pause() on it.
63346           *       ele.loop();
63347           *
63348           *       sampleIsPlaying = true;
63349           *       text('Click to pause!', width / 2, height / 2);
63350           *     }
63351           *   }
63352           * }
63353           * </code></div>
63354           */
63355          _main.default.MediaElement.prototype.pause = function() {
63356            this.elt.pause();
63357            return this;
63358          };
63359
63360          /**
63361           * Set 'loop' to true for an HTML5 media element, and starts playing.
63362           *
63363           * @method loop
63364           * @chainable
63365           * @example
63366           * <div><code>
63367           * //Clicking the canvas will loop
63368           * //the audio sample until the user
63369           * //clicks again to stop it
63370           *
63371           * //We will store the p5.MediaElement
63372           * //object in here
63373           * let ele;
63374           *
63375           * //while our audio is playing,
63376           * //this will be set to true
63377           * let sampleIsLooping = false;
63378           *
63379           * function setup() {
63380           *   //Here we create a p5.MediaElement object
63381           *   //using the createAudio() function.
63382           *   ele = createAudio('assets/lucky_dragons.mp3');
63383           *   background(200);
63384           *   textAlign(CENTER);
63385           *   text('Click to loop!', width / 2, height / 2);
63386           * }
63387           *
63388           * function mouseClicked() {
63389           *   //here we test if the mouse is over the
63390           *   //canvas element when it's clicked
63391           *   if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {
63392           *     background(200);
63393           *
63394           *     if (!sampleIsLooping) {
63395           *       //loop our sound element until we
63396           *       //call ele.stop() on it.
63397           *       ele.loop();
63398           *
63399           *       sampleIsLooping = true;
63400           *       text('Click to stop!', width / 2, height / 2);
63401           *     } else {
63402           *       ele.stop();
63403           *
63404           *       sampleIsLooping = false;
63405           *       text('Click to loop!', width / 2, height / 2);
63406           *     }
63407           *   }
63408           * }
63409           * </code></div>
63410           */
63411          _main.default.MediaElement.prototype.loop = function() {
63412            this.elt.setAttribute('loop', true);
63413            this.play();
63414            return this;
63415          };
63416          /**
63417           * Set 'loop' to false for an HTML5 media element. Element will stop
63418           * when it reaches the end.
63419           *
63420           * @method noLoop
63421           * @chainable
63422           * @example
63423           * <div><code>
63424           * //This example both starts
63425           * //and stops loop of sound sample
63426           * //when the user clicks the canvas
63427           *
63428           * //We will store the p5.MediaElement
63429           * //object in here
63430           * let ele;
63431           * //while our audio is playing,
63432           * //this will be set to true
63433           * let sampleIsPlaying = false;
63434           *
63435           * function setup() {
63436           *   //Here we create a p5.MediaElement object
63437           *   //using the createAudio() function.
63438           *   ele = createAudio('assets/beat.mp3');
63439           *   background(200);
63440           *   textAlign(CENTER);
63441           *   text('Click to play!', width / 2, height / 2);
63442           * }
63443           *
63444           * function mouseClicked() {
63445           *   //here we test if the mouse is over the
63446           *   //canvas element when it's clicked
63447           *   if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {
63448           *     background(200);
63449           *
63450           *     if (sampleIsPlaying) {
63451           *       ele.noLoop();
63452           *       sampleIsPlaying = false;
63453           *       text('No more Loops!', width / 2, height / 2);
63454           *     } else {
63455           *       ele.loop();
63456           *       sampleIsPlaying = true;
63457           *       text('Click to stop looping!', width / 2, height / 2);
63458           *     }
63459           *   }
63460           * }
63461           * </code></div>
63462           */
63463          _main.default.MediaElement.prototype.noLoop = function() {
63464            this.elt.removeAttribute('loop');
63465            return this;
63466          };
63467
63468          /**
63469           * Sets up logic to check that autoplay succeeded.
63470           *
63471           * @method setupAutoplayFailDetection
63472           * @private
63473           */
63474          _main.default.MediaElement.prototype._setupAutoplayFailDetection = function() {
63475            var _this2 = this;
63476            var timeout = setTimeout(function() {
63477              return _main.default._friendlyAutoplayError(_this2.src);
63478            }, 500);
63479            this.elt.addEventListener(
63480              'play',
63481              function() {
63482                return clearTimeout(timeout);
63483              },
63484              {
63485                passive: true,
63486                once: true
63487              }
63488            );
63489          };
63490
63491          /**
63492           * Set HTML5 media element to autoplay or not. If no argument is specified, by
63493           * default it will autoplay.
63494           *
63495           * @method autoplay
63496           * @param {Boolean} shouldAutoplay whether the element should autoplay
63497           * @chainable
63498           * @example
63499           * <div><code>
63500           * let videoElement;
63501           * function setup() {
63502           *   noCanvas();
63503           *   videoElement = createVideo(['assets/small.mp4'], onVideoLoad);
63504           * }
63505           * function onVideoLoad() {
63506           *   // The media will play as soon as it is loaded.
63507           *   videoElement.autoplay();
63508           *   videoElement.volume(0);
63509           *   videoElement.size(100, 100);
63510           * }
63511           * </code></div>
63512           *
63513           * <div><code>
63514           * let videoElement;
63515           * function setup() {
63516           *   noCanvas();
63517           *   videoElement = createVideo(['assets/small.mp4'], onVideoLoad);
63518           * }
63519           * function onVideoLoad() {
63520           *   // The media will not play untill some explicitly triggered.
63521           *   videoElement.autoplay(false);
63522           *   videoElement.volume(0);
63523           *   videoElement.size(100, 100);
63524           * }
63525           *
63526           * function mouseClicked() {
63527           *   videoElement.play();
63528           * }
63529           * </code></div>
63530           *
63531           * @alt
63532           * An example of a video element which autoplays after it is loaded.
63533           * An example of a video element which waits for a trigger for playing.
63534           */
63535
63536          _main.default.MediaElement.prototype.autoplay = function(val) {
63537            var _this3 = this;
63538            var oldVal = this.elt.getAttribute('autoplay');
63539            this.elt.setAttribute('autoplay', val);
63540            // if we turned on autoplay
63541            if (val && !oldVal) {
63542              // bind method to this scope
63543              var setupAutoplayFailDetection = function setupAutoplayFailDetection() {
63544                return _this3._setupAutoplayFailDetection();
63545              };
63546              // if media is ready to play, schedule check now
63547              if (this.elt.readyState === 4) {
63548                setupAutoplayFailDetection();
63549              } else {
63550                // otherwise, schedule check whenever it is ready
63551                this.elt.addEventListener('canplay', setupAutoplayFailDetection, {
63552                  passive: true,
63553                  once: true
63554                });
63555              }
63556            }
63557
63558            return this;
63559          };
63560
63561          /**
63562           * Sets volume for this HTML5 media element. If no argument is given,
63563           * returns the current volume.
63564           *
63565           * @method volume
63566           * @return {Number} current volume
63567           *
63568           * @example
63569           * <div><code>
63570           * let ele;
63571           * function setup() {
63572           *   // p5.MediaElement objects are usually created
63573           *   // by calling the createAudio(), createVideo(),
63574           *   // and createCapture() functions.
63575           *   // In this example we create
63576           *   // a new p5.MediaElement via createAudio().
63577           *   ele = createAudio('assets/lucky_dragons.mp3');
63578           *   background(250);
63579           *   textAlign(CENTER);
63580           *   text('Click to Play!', width / 2, height / 2);
63581           * }
63582           * function mouseClicked() {
63583           *   // Here we call the volume() function
63584           *   // on the sound element to set its volume
63585           *   // Volume must be between 0.0 and 1.0
63586           *   ele.volume(0.2);
63587           *   ele.play();
63588           *   background(200);
63589           *   text('You clicked Play!', width / 2, height / 2);
63590           * }
63591           * </code></div>
63592           * <div><code>
63593           * let audio;
63594           * let counter = 0;
63595           *
63596           * function loaded() {
63597           *   audio.play();
63598           * }
63599           *
63600           * function setup() {
63601           *   audio = createAudio('assets/lucky_dragons.mp3', loaded);
63602           *   textAlign(CENTER);
63603           * }
63604           *
63605           * function draw() {
63606           *   if (counter === 0) {
63607           *     background(0, 255, 0);
63608           *     text('volume(0.9)', width / 2, height / 2);
63609           *   } else if (counter === 1) {
63610           *     background(255, 255, 0);
63611           *     text('volume(0.5)', width / 2, height / 2);
63612           *   } else if (counter === 2) {
63613           *     background(255, 0, 0);
63614           *     text('volume(0.1)', width / 2, height / 2);
63615           *   }
63616           * }
63617           *
63618           * function mousePressed() {
63619           *   counter++;
63620           *   if (counter === 0) {
63621           *     audio.volume(0.9);
63622           *   } else if (counter === 1) {
63623           *     audio.volume(0.5);
63624           *   } else if (counter === 2) {
63625           *     audio.volume(0.1);
63626           *   } else {
63627           *     counter = 0;
63628           *     audio.volume(0.9);
63629           *   }
63630           * }
63631           * </code>
63632           * </div>
63633           */
63634          /**
63635           * @method volume
63636           * @param {Number}            val volume between 0.0 and 1.0
63637           * @chainable
63638           */
63639          _main.default.MediaElement.prototype.volume = function(val) {
63640            if (typeof val === 'undefined') {
63641              return this.elt.volume;
63642            } else {
63643              this.elt.volume = val;
63644            }
63645          };
63646
63647          /**
63648           * If no arguments are given, returns the current playback speed of the
63649           * element. The speed parameter sets the speed where 2.0 will play the
63650           * element twice as fast, 0.5 will play at half the speed, and -1 will play
63651           * the element in normal speed in reverse.(Note that not all browsers support
63652           * backward playback and even if they do, playback might not be smooth.)
63653           *
63654           * @method speed
63655           * @return {Number} current playback speed of the element
63656           *
63657           * @example
63658           * <div class='norender notest'><code>
63659           * //Clicking the canvas will loop
63660           * //the audio sample until the user
63661           * //clicks again to stop it
63662           *
63663           * //We will store the p5.MediaElement
63664           * //object in here
63665           * let ele;
63666           * let button;
63667           *
63668           * function setup() {
63669           *   createCanvas(710, 400);
63670           *   //Here we create a p5.MediaElement object
63671           *   //using the createAudio() function.
63672           *   ele = createAudio('assets/beat.mp3');
63673           *   ele.loop();
63674           *   background(200);
63675           *
63676           *   button = createButton('2x speed');
63677           *   button.position(100, 68);
63678           *   button.mousePressed(twice_speed);
63679           *
63680           *   button = createButton('half speed');
63681           *   button.position(200, 68);
63682           *   button.mousePressed(half_speed);
63683           *
63684           *   button = createButton('reverse play');
63685           *   button.position(300, 68);
63686           *   button.mousePressed(reverse_speed);
63687           *
63688           *   button = createButton('STOP');
63689           *   button.position(400, 68);
63690           *   button.mousePressed(stop_song);
63691           *
63692           *   button = createButton('PLAY!');
63693           *   button.position(500, 68);
63694           *   button.mousePressed(play_speed);
63695           * }
63696           *
63697           * function twice_speed() {
63698           *   ele.speed(2);
63699           * }
63700           *
63701           * function half_speed() {
63702           *   ele.speed(0.5);
63703           * }
63704           *
63705           * function reverse_speed() {
63706           *   ele.speed(-1);
63707           * }
63708           *
63709           * function stop_song() {
63710           *   ele.stop();
63711           * }
63712           *
63713           * function play_speed() {
63714           *   ele.play();
63715           * }
63716           * </code></div>
63717           */
63718
63719          /**
63720           * @method speed
63721           * @param {Number} speed  speed multiplier for element playback
63722           * @chainable
63723           */
63724          _main.default.MediaElement.prototype.speed = function(val) {
63725            if (typeof val === 'undefined') {
63726              return this.presetPlaybackRate || this.elt.playbackRate;
63727            } else {
63728              if (this.loadedmetadata) {
63729                this.elt.playbackRate = val;
63730              } else {
63731                this.presetPlaybackRate = val;
63732              }
63733            }
63734          };
63735
63736          /**
63737           * If no arguments are given, returns the current time of the element.
63738           * If an argument is given the current time of the element is set to it.
63739           *
63740           * @method time
63741           * @return {Number} current time (in seconds)
63742           *
63743           * @example
63744           * <div><code>
63745           * let ele;
63746           * let beginning = true;
63747           * function setup() {
63748           *   //p5.MediaElement objects are usually created
63749           *   //by calling the createAudio(), createVideo(),
63750           *   //and createCapture() functions.
63751           *
63752           *   //In this example we create
63753           *   //a new p5.MediaElement via createAudio().
63754           *   ele = createAudio('assets/lucky_dragons.mp3');
63755           *   background(250);
63756           *   textAlign(CENTER);
63757           *   text('start at beginning', width / 2, height / 2);
63758           * }
63759           *
63760           * // this function fires with click anywhere
63761           * function mousePressed() {
63762           *   if (beginning === true) {
63763           *     // here we start the sound at the beginning
63764           *     // time(0) is not necessary here
63765           *     // as this produces the same result as
63766           *     // play()
63767           *     ele.play().time(0);
63768           *     background(200);
63769           *     text('jump 2 sec in', width / 2, height / 2);
63770           *     beginning = false;
63771           *   } else {
63772           *     // here we jump 2 seconds into the sound
63773           *     ele.play().time(2);
63774           *     background(250);
63775           *     text('start at beginning', width / 2, height / 2);
63776           *     beginning = true;
63777           *   }
63778           * }
63779           * </code></div>
63780           */
63781          /**
63782           * @method time
63783           * @param {Number} time time to jump to (in seconds)
63784           * @chainable
63785           */
63786          _main.default.MediaElement.prototype.time = function(val) {
63787            if (typeof val === 'undefined') {
63788              return this.elt.currentTime;
63789            } else {
63790              this.elt.currentTime = val;
63791              return this;
63792            }
63793          };
63794
63795          /**
63796           * Returns the duration of the HTML5 media element.
63797           *
63798           * @method duration
63799           * @return {Number} duration
63800           *
63801           * @example
63802           * <div><code>
63803           * let ele;
63804           * function setup() {
63805           *   //p5.MediaElement objects are usually created
63806           *   //by calling the createAudio(), createVideo(),
63807           *   //and createCapture() functions.
63808           *   //In this example we create
63809           *   //a new p5.MediaElement via createAudio().
63810           *   ele = createAudio('assets/doorbell.mp3');
63811           *   background(250);
63812           *   textAlign(CENTER);
63813           *   text('Click to know the duration!', 10, 25, 70, 80);
63814           * }
63815           * function mouseClicked() {
63816           *   ele.play();
63817           *   background(200);
63818           *   //ele.duration dislpays the duration
63819           *   text(ele.duration() + ' seconds', width / 2, height / 2);
63820           * }
63821           * </code></div>
63822           */
63823          _main.default.MediaElement.prototype.duration = function() {
63824            return this.elt.duration;
63825          };
63826          _main.default.MediaElement.prototype.pixels = [];
63827          _main.default.MediaElement.prototype._ensureCanvas = function() {
63828            if (!this.canvas) {
63829              this.canvas = document.createElement('canvas');
63830              this.drawingContext = this.canvas.getContext('2d');
63831              this.setModified(true);
63832            }
63833            if (this.loadedmetadata) {
63834              // wait for metadata for w/h
63835              if (this.canvas.width !== this.elt.width) {
63836                this.canvas.width = this.elt.width;
63837                this.canvas.height = this.elt.height;
63838                this.width = this.canvas.width;
63839                this.height = this.canvas.height;
63840              }
63841
63842              this.drawingContext.drawImage(
63843                this.elt,
63844                0,
63845                0,
63846                this.canvas.width,
63847                this.canvas.height
63848              );
63849
63850              this.setModified(true);
63851            }
63852          };
63853          _main.default.MediaElement.prototype.loadPixels = function() {
63854            this._ensureCanvas();
63855            return _main.default.Renderer2D.prototype.loadPixels.apply(this, arguments);
63856          };
63857          _main.default.MediaElement.prototype.updatePixels = function(x, y, w, h) {
63858            if (this.loadedmetadata) {
63859              // wait for metadata
63860              this._ensureCanvas();
63861              _main.default.Renderer2D.prototype.updatePixels.call(this, x, y, w, h);
63862            }
63863            this.setModified(true);
63864            return this;
63865          };
63866          _main.default.MediaElement.prototype.get = function() {
63867            this._ensureCanvas();
63868            return _main.default.Renderer2D.prototype.get.apply(this, arguments);
63869          };
63870          _main.default.MediaElement.prototype._getPixel = function() {
63871            this.loadPixels();
63872            return _main.default.Renderer2D.prototype._getPixel.apply(this, arguments);
63873          };
63874
63875          _main.default.MediaElement.prototype.set = function(x, y, imgOrCol) {
63876            if (this.loadedmetadata) {
63877              // wait for metadata
63878              this._ensureCanvas();
63879              _main.default.Renderer2D.prototype.set.call(this, x, y, imgOrCol);
63880              this.setModified(true);
63881            }
63882          };
63883          _main.default.MediaElement.prototype.copy = function() {
63884            this._ensureCanvas();
63885            _main.default.prototype.copy.apply(this, arguments);
63886          };
63887          _main.default.MediaElement.prototype.mask = function() {
63888            this.loadPixels();
63889            this.setModified(true);
63890            _main.default.Image.prototype.mask.apply(this, arguments);
63891          };
63892          /**
63893           * helper method for web GL mode to figure out if the element
63894           * has been modified and might need to be re-uploaded to texture
63895           * memory between frames.
63896           * @method isModified
63897           * @private
63898           * @return {boolean} a boolean indicating whether or not the
63899           * image has been updated or modified since last texture upload.
63900           */
63901          _main.default.MediaElement.prototype.isModified = function() {
63902            return this._modified;
63903          };
63904          /**
63905           * helper method for web GL mode to indicate that an element has been
63906           * changed or unchanged since last upload. gl texture upload will
63907           * set this value to false after uploading the texture; or might set
63908           * it to true if metadata has become available but there is no actual
63909           * texture data available yet..
63910           * @method setModified
63911           * @param {boolean} val sets whether or not the element has been
63912           * modified.
63913           * @private
63914           */
63915          _main.default.MediaElement.prototype.setModified = function(value) {
63916            this._modified = value;
63917          };
63918          /**
63919           * Schedule an event to be called when the audio or video
63920           * element reaches the end. If the element is looping,
63921           * this will not be called. The element is passed in
63922           * as the argument to the onended callback.
63923           *
63924           * @method  onended
63925           * @param  {Function} callback function to call when the
63926           *                             soundfile has ended. The
63927           *                             media element will be passed
63928           *                             in as the argument to the
63929           *                             callback.
63930           * @chainable
63931           * @example
63932           * <div><code>
63933           * function setup() {
63934           *   let audioEl = createAudio('assets/beat.mp3');
63935           *   audioEl.showControls();
63936           *   audioEl.onended(sayDone);
63937           * }
63938           *
63939           * function sayDone(elt) {
63940           *   alert('done playing ' + elt.src);
63941           * }
63942           * </code></div>
63943           */
63944          _main.default.MediaElement.prototype.onended = function(callback) {
63945            this._onended = callback;
63946            return this;
63947          };
63948
63949          /*** CONNECT TO WEB AUDIO API / p5.sound.js ***/
63950
63951          /**
63952           * Send the audio output of this element to a specified audioNode or
63953           * p5.sound object. If no element is provided, connects to p5's main
63954           * output. That connection is established when this method is first called.
63955           * All connections are removed by the .disconnect() method.
63956           *
63957           * This method is meant to be used with the p5.sound.js addon library.
63958           *
63959           * @method  connect
63960           * @param  {AudioNode|Object} audioNode AudioNode from the Web Audio API,
63961           * or an object from the p5.sound library
63962           */
63963          _main.default.MediaElement.prototype.connect = function(obj) {
63964            var audioContext, mainOutput;
63965
63966            // if p5.sound exists, same audio context
63967            if (typeof _main.default.prototype.getAudioContext === 'function') {
63968              audioContext = _main.default.prototype.getAudioContext();
63969              mainOutput = _main.default.soundOut.input;
63970            } else {
63971              try {
63972                audioContext = obj.context;
63973                mainOutput = audioContext.destination;
63974              } catch (e) {
63975                throw 'connect() is meant to be used with Web Audio API or p5.sound.js';
63976              }
63977            }
63978
63979            // create a Web Audio MediaElementAudioSourceNode if none already exists
63980            if (!this.audioSourceNode) {
63981              this.audioSourceNode = audioContext.createMediaElementSource(this.elt);
63982
63983              // connect to main output when this method is first called
63984              this.audioSourceNode.connect(mainOutput);
63985            }
63986
63987            // connect to object if provided
63988            if (obj) {
63989              if (obj.input) {
63990                this.audioSourceNode.connect(obj.input);
63991              } else {
63992                this.audioSourceNode.connect(obj);
63993              }
63994            } else {
63995              // otherwise connect to main output of p5.sound / AudioContext
63996              this.audioSourceNode.connect(mainOutput);
63997            }
63998          };
63999
64000          /**
64001           * Disconnect all Web Audio routing, including to main output.
64002           * This is useful if you want to re-route the output through
64003           * audio effects, for example.
64004           *
64005           * @method  disconnect
64006           */
64007          _main.default.MediaElement.prototype.disconnect = function() {
64008            if (this.audioSourceNode) {
64009              this.audioSourceNode.disconnect();
64010            } else {
64011              throw 'nothing to disconnect';
64012            }
64013          };
64014
64015          /*** SHOW / HIDE CONTROLS ***/
64016
64017          /**
64018           * Show the default MediaElement controls, as determined by the web browser.
64019           *
64020           * @method  showControls
64021           * @example
64022           * <div><code>
64023           * let ele;
64024           * function setup() {
64025           *   //p5.MediaElement objects are usually created
64026           *   //by calling the createAudio(), createVideo(),
64027           *   //and createCapture() functions.
64028           *   //In this example we create
64029           *   //a new p5.MediaElement via createAudio()
64030           *   ele = createAudio('assets/lucky_dragons.mp3');
64031           *   background(200);
64032           *   textAlign(CENTER);
64033           *   text('Click to Show Controls!', 10, 25, 70, 80);
64034           * }
64035           * function mousePressed() {
64036           *   ele.showControls();
64037           *   background(200);
64038           *   text('Controls Shown', width / 2, height / 2);
64039           * }
64040           * </code></div>
64041           */
64042          _main.default.MediaElement.prototype.showControls = function() {
64043            // must set style for the element to show on the page
64044            this.elt.style['text-align'] = 'inherit';
64045            this.elt.controls = true;
64046          };
64047
64048          /**
64049           * Hide the default mediaElement controls.
64050           * @method hideControls
64051           * @example
64052           * <div><code>
64053           * let ele;
64054           * function setup() {
64055           *   //p5.MediaElement objects are usually created
64056           *   //by calling the createAudio(), createVideo(),
64057           *   //and createCapture() functions.
64058           *   //In this example we create
64059           *   //a new p5.MediaElement via createAudio()
64060           *   ele = createAudio('assets/lucky_dragons.mp3');
64061           *   ele.showControls();
64062           *   background(200);
64063           *   textAlign(CENTER);
64064           *   text('Click to hide Controls!', 10, 25, 70, 80);
64065           * }
64066           * function mousePressed() {
64067           *   ele.hideControls();
64068           *   background(200);
64069           *   text('Controls hidden', width / 2, height / 2);
64070           * }
64071           * </code></div>
64072           */
64073          _main.default.MediaElement.prototype.hideControls = function() {
64074            this.elt.controls = false;
64075          };
64076
64077          /*** SCHEDULE EVENTS ***/
64078
64079          // Cue inspired by JavaScript setTimeout, and the
64080          // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org
64081          var Cue = function Cue(callback, time, id, val) {
64082            this.callback = callback;
64083            this.time = time;
64084            this.id = id;
64085            this.val = val;
64086          };
64087
64088          /**
64089           * Schedule events to trigger every time a MediaElement
64090           * (audio/video) reaches a playback cue point.
64091           *
64092           * Accepts a callback function, a time (in seconds) at which to trigger
64093           * the callback, and an optional parameter for the callback.
64094           *
64095           * Time will be passed as the first parameter to the callback function,
64096           * and param will be the second parameter.
64097           *
64098           * @method  addCue
64099           * @param {Number}   time     Time in seconds, relative to this media
64100           *                             element's playback. For example, to trigger
64101           *                             an event every time playback reaches two
64102           *                             seconds, pass in the number 2. This will be
64103           *                             passed as the first parameter to
64104           *                             the callback function.
64105           * @param {Function} callback Name of a function that will be
64106           *                             called at the given time. The callback will
64107           *                             receive time and (optionally) param as its
64108           *                             two parameters.
64109           * @param {Object} [value]    An object to be passed as the
64110           *                             second parameter to the
64111           *                             callback function.
64112           * @return {Number} id ID of this cue,
64113           *                     useful for removeCue(id)
64114           * @example
64115           * <div><code>
64116           * //
64117           * //
64118           * function setup() {
64119           *   createCanvas(200, 200);
64120           *
64121           *   let audioEl = createAudio('assets/beat.mp3');
64122           *   audioEl.showControls();
64123           *
64124           *   // schedule three calls to changeBackground
64125           *   audioEl.addCue(0.5, changeBackground, color(255, 0, 0));
64126           *   audioEl.addCue(1.0, changeBackground, color(0, 255, 0));
64127           *   audioEl.addCue(2.5, changeBackground, color(0, 0, 255));
64128           *   audioEl.addCue(3.0, changeBackground, color(0, 255, 255));
64129           *   audioEl.addCue(4.2, changeBackground, color(255, 255, 0));
64130           *   audioEl.addCue(5.0, changeBackground, color(255, 255, 0));
64131           * }
64132           *
64133           * function changeBackground(val) {
64134           *   background(val);
64135           * }
64136           * </code></div>
64137           */
64138          _main.default.MediaElement.prototype.addCue = function(time, callback, val) {
64139            var id = this._cueIDCounter++;
64140
64141            var cue = new Cue(callback, time, id, val);
64142            this._cues.push(cue);
64143
64144            if (!this.elt.ontimeupdate) {
64145              this.elt.ontimeupdate = this._onTimeUpdate.bind(this);
64146            }
64147
64148            return id;
64149          };
64150
64151          /**
64152           * Remove a callback based on its ID. The ID is returned by the
64153           * addCue method.
64154           * @method removeCue
64155           * @param  {Number} id ID of the cue, as returned by addCue
64156           * @example
64157           * <div><code>
64158           * let audioEl, id1, id2;
64159           * function setup() {
64160           *   background(255, 255, 255);
64161           *   audioEl = createAudio('assets/beat.mp3');
64162           *   audioEl.showControls();
64163           *   // schedule five calls to changeBackground
64164           *   id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));
64165           *   audioEl.addCue(1.0, changeBackground, color(0, 255, 0));
64166           *   audioEl.addCue(2.5, changeBackground, color(0, 0, 255));
64167           *   audioEl.addCue(3.0, changeBackground, color(0, 255, 255));
64168           *   id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));
64169           *   text('Click to remove first and last Cue!', 10, 25, 70, 80);
64170           * }
64171           * function mousePressed() {
64172           *   audioEl.removeCue(id1);
64173           *   audioEl.removeCue(id2);
64174           * }
64175           * function changeBackground(val) {
64176           *   background(val);
64177           * }
64178           * </code></div>
64179           */
64180          _main.default.MediaElement.prototype.removeCue = function(id) {
64181            for (var i = 0; i < this._cues.length; i++) {
64182              if (this._cues[i].id === id) {
64183                console.log(id);
64184                this._cues.splice(i, 1);
64185              }
64186            }
64187
64188            if (this._cues.length === 0) {
64189              this.elt.ontimeupdate = null;
64190            }
64191          };
64192
64193          /**
64194           * Remove all of the callbacks that had originally been scheduled
64195           * via the addCue method.
64196           * @method  clearCues
64197           * @param  {Number} id ID of the cue, as returned by addCue
64198           * @example
64199           * <div><code>
64200           * let audioEl;
64201           * function setup() {
64202           *   background(255, 255, 255);
64203           *   audioEl = createAudio('assets/beat.mp3');
64204           *   //Show the default MediaElement controls, as determined by the web browser
64205           *   audioEl.showControls();
64206           *   // schedule calls to changeBackground
64207           *   background(200);
64208           *   text('Click to change Cue!', 10, 25, 70, 80);
64209           *   audioEl.addCue(0.5, changeBackground, color(255, 0, 0));
64210           *   audioEl.addCue(1.0, changeBackground, color(0, 255, 0));
64211           *   audioEl.addCue(2.5, changeBackground, color(0, 0, 255));
64212           *   audioEl.addCue(3.0, changeBackground, color(0, 255, 255));
64213           *   audioEl.addCue(4.2, changeBackground, color(255, 255, 0));
64214           * }
64215           * function mousePressed() {
64216           *   // here we clear the scheduled callbacks
64217           *   audioEl.clearCues();
64218           *   // then we add some more callbacks
64219           *   audioEl.addCue(1, changeBackground, color(2, 2, 2));
64220           *   audioEl.addCue(3, changeBackground, color(255, 255, 0));
64221           * }
64222           * function changeBackground(val) {
64223           *   background(val);
64224           * }
64225           * </code></div>
64226           */
64227          _main.default.MediaElement.prototype.clearCues = function() {
64228            this._cues = [];
64229            this.elt.ontimeupdate = null;
64230          };
64231
64232          // private method that checks for cues to be fired if events
64233          // have been scheduled using addCue(callback, time).
64234          _main.default.MediaElement.prototype._onTimeUpdate = function() {
64235            var playbackTime = this.time();
64236
64237            for (var i = 0; i < this._cues.length; i++) {
64238              var callbackTime = this._cues[i].time;
64239              var val = this._cues[i].val;
64240
64241              if (this._prevTime < callbackTime && callbackTime <= playbackTime) {
64242                // pass the scheduled callbackTime as parameter to the callback
64243                this._cues[i].callback(val);
64244              }
64245            }
64246
64247            this._prevTime = playbackTime;
64248          };
64249
64250          /**
64251           * Base class for a file.
64252           * Used for Element.drop and createFileInput.
64253           *
64254           * @class p5.File
64255           * @constructor
64256           * @param {File} file File that is wrapped
64257           */
64258          _main.default.File = function(file, pInst) {
64259            /**
64260             * Underlying File object. All normal File methods can be called on this.
64261             *
64262             * @property file
64263             */
64264            this.file = file;
64265
64266            this._pInst = pInst;
64267
64268            // Splitting out the file type into two components
64269            // This makes determining if image or text etc simpler
64270            var typeList = file.type.split('/');
64271            /**
64272             * File type (image, text, etc.)
64273             *
64274             * @property type
64275             */
64276            this.type = typeList[0];
64277            /**
64278             * File subtype (usually the file extension jpg, png, xml, etc.)
64279             *
64280             * @property subtype
64281             */
64282            this.subtype = typeList[1];
64283            /**
64284             * File name
64285             *
64286             * @property name
64287             */
64288            this.name = file.name;
64289            /**
64290             * File size
64291             *
64292             * @property size
64293             */
64294            this.size = file.size;
64295
64296            /**
64297             * URL string containing either image data, the text contents of the file or
64298             * a parsed object if file is JSON and p5.XML if XML
64299             *
64300             * @property data
64301             */
64302            this.data = undefined;
64303          };
64304
64305          _main.default.File._createLoader = function(theFile, callback) {
64306            var reader = new FileReader();
64307            reader.onload = function(e) {
64308              var p5file = new _main.default.File(theFile);
64309              if (p5file.file.type === 'application/json') {
64310                // Parse JSON and store the result in data
64311                p5file.data = JSON.parse(e.target.result);
64312              } else if (p5file.file.type === 'text/xml') {
64313                // Parse XML, wrap it in p5.XML and store the result in data
64314                var parser = new DOMParser();
64315                var xml = parser.parseFromString(e.target.result, 'text/xml');
64316                p5file.data = new _main.default.XML(xml.documentElement);
64317              } else {
64318                p5file.data = e.target.result;
64319              }
64320              callback(p5file);
64321            };
64322            return reader;
64323          };
64324
64325          _main.default.File._load = function(f, callback) {
64326            // Text or data?
64327            // This should likely be improved
64328            if (/^text\//.test(f.type) || f.type === 'application/json') {
64329              _main.default.File._createLoader(f, callback).readAsText(f);
64330            } else if (!/^(video|audio)\//.test(f.type)) {
64331              _main.default.File._createLoader(f, callback).readAsDataURL(f);
64332            } else {
64333              var file = new _main.default.File(f);
64334              file.data = URL.createObjectURL(f);
64335              callback(file);
64336            }
64337          };
64338          var _default = _main.default;
64339          exports.default = _default;
64340        },
64341        { '../core/main': 59 }
64342      ],
64343      76: [
64344        function(_dereq_, module, exports) {
64345          'use strict';
64346          function _typeof(obj) {
64347            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
64348              _typeof = function _typeof(obj) {
64349                return typeof obj;
64350              };
64351            } else {
64352              _typeof = function _typeof(obj) {
64353                return obj &&
64354                  typeof Symbol === 'function' &&
64355                  obj.constructor === Symbol &&
64356                  obj !== Symbol.prototype
64357                  ? 'symbol'
64358                  : typeof obj;
64359              };
64360            }
64361            return _typeof(obj);
64362          }
64363          Object.defineProperty(exports, '__esModule', { value: true });
64364          exports.default = void 0;
64365
64366          var _main = _interopRequireDefault(_dereq_('../core/main'));
64367          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
64368          function _getRequireWildcardCache() {
64369            if (typeof WeakMap !== 'function') return null;
64370            var cache = new WeakMap();
64371            _getRequireWildcardCache = function _getRequireWildcardCache() {
64372              return cache;
64373            };
64374            return cache;
64375          }
64376          function _interopRequireWildcard(obj) {
64377            if (obj && obj.__esModule) {
64378              return obj;
64379            }
64380            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
64381              return { default: obj };
64382            }
64383            var cache = _getRequireWildcardCache();
64384            if (cache && cache.has(obj)) {
64385              return cache.get(obj);
64386            }
64387            var newObj = {};
64388            var hasPropertyDescriptor =
64389              Object.defineProperty && Object.getOwnPropertyDescriptor;
64390            for (var key in obj) {
64391              if (Object.prototype.hasOwnProperty.call(obj, key)) {
64392                var desc = hasPropertyDescriptor
64393                  ? Object.getOwnPropertyDescriptor(obj, key)
64394                  : null;
64395                if (desc && (desc.get || desc.set)) {
64396                  Object.defineProperty(newObj, key, desc);
64397                } else {
64398                  newObj[key] = obj[key];
64399                }
64400              }
64401            }
64402            newObj.default = obj;
64403            if (cache) {
64404              cache.set(obj, newObj);
64405            }
64406            return newObj;
64407          }
64408          function _interopRequireDefault(obj) {
64409            return obj && obj.__esModule ? obj : { default: obj };
64410          }
64411          /**
64412           * @module Events
64413           * @submodule Acceleration
64414           * @for p5
64415           * @requires core
64416           */ /**
64417           * The system variable deviceOrientation always contains the orientation of
64418           * the device. The value of this variable will either be set 'landscape'
64419           * or 'portrait'. If no data is available it will be set to 'undefined'.
64420           * either LANDSCAPE or PORTRAIT.
64421           *
64422           * @property {Constant} deviceOrientation
64423           * @readOnly
64424           */ _main.default.prototype.deviceOrientation =
64425            window.innerWidth / window.innerHeight > 1.0 ? 'landscape' : 'portrait';
64426          /**
64427           * The system variable accelerationX always contains the acceleration of the
64428           * device along the x axis. Value is represented as meters per second squared.
64429           *
64430           * @property {Number} accelerationX
64431           * @readOnly
64432           * @example
64433           * <div>
64434           * <code>
64435           * // Move a touchscreen device to register
64436           * // acceleration changes.
64437           * function draw() {
64438           *   background(220, 50);
64439           *   fill('magenta');
64440           *   ellipse(width / 2, height / 2, accelerationX);
64441           * }
64442           * </code>
64443           * </div>
64444           * @alt
64445           * Magnitude of device acceleration is displayed as ellipse size
64446           */
64447          _main.default.prototype.accelerationX = 0;
64448
64449          /**
64450           * The system variable accelerationY always contains the acceleration of the
64451           * device along the y axis. Value is represented as meters per second squared.
64452           *
64453           * @property {Number} accelerationY
64454           * @readOnly
64455           * @example
64456           * <div>
64457           * <code>
64458           * // Move a touchscreen device to register
64459           * // acceleration changes.
64460           * function draw() {
64461           *   background(220, 50);
64462           *   fill('magenta');
64463           *   ellipse(width / 2, height / 2, accelerationY);
64464           * }
64465           * </code>
64466           * </div>
64467           * @alt
64468           * Magnitude of device acceleration is displayed as ellipse size
64469           */
64470          _main.default.prototype.accelerationY = 0;
64471
64472          /**
64473           * The system variable accelerationZ always contains the acceleration of the
64474           * device along the z axis. Value is represented as meters per second squared.
64475           *
64476           * @property {Number} accelerationZ
64477           * @readOnly
64478           *
64479           * @example
64480           * <div>
64481           * <code>
64482           * // Move a touchscreen device to register
64483           * // acceleration changes.
64484           * function draw() {
64485           *   background(220, 50);
64486           *   fill('magenta');
64487           *   ellipse(width / 2, height / 2, accelerationZ);
64488           * }
64489           * </code>
64490           * </div>
64491           *
64492           * @alt
64493           * Magnitude of device acceleration is displayed as ellipse size
64494           */
64495          _main.default.prototype.accelerationZ = 0;
64496
64497          /**
64498           * The system variable pAccelerationX always contains the acceleration of the
64499           * device along the x axis in the frame previous to the current frame. Value
64500           * is represented as meters per second squared.
64501           *
64502           * @property {Number} pAccelerationX
64503           * @readOnly
64504           */
64505          _main.default.prototype.pAccelerationX = 0;
64506
64507          /**
64508           * The system variable pAccelerationY always contains the acceleration of the
64509           * device along the y axis in the frame previous to the current frame. Value
64510           * is represented as meters per second squared.
64511           *
64512           * @property {Number} pAccelerationY
64513           * @readOnly
64514           */
64515          _main.default.prototype.pAccelerationY = 0;
64516
64517          /**
64518           * The system variable pAccelerationZ always contains the acceleration of the
64519           * device along the z axis in the frame previous to the current frame. Value
64520           * is represented as meters per second squared.
64521           *
64522           * @property {Number} pAccelerationZ
64523           * @readOnly
64524           */
64525          _main.default.prototype.pAccelerationZ = 0;
64526
64527          /**
64528           * _updatePAccelerations updates the pAcceleration values
64529           *
64530           * @private
64531           */
64532          _main.default.prototype._updatePAccelerations = function() {
64533            this._setProperty('pAccelerationX', this.accelerationX);
64534            this._setProperty('pAccelerationY', this.accelerationY);
64535            this._setProperty('pAccelerationZ', this.accelerationZ);
64536          };
64537
64538          /**
64539           * The system variable rotationX always contains the rotation of the
64540           * device along the x axis. If the sketch <a href="#/p5/angleMode">
64541           * angleMode()</a> is set to DEGREES, the value will be -180 to 180. If
64542           * it is set to RADIANS, the value will be -PI to PI.
64543           *
64544           * Note: The order the rotations are called is important, ie. if used
64545           * together, it must be called in the order Z-X-Y or there might be
64546           * unexpected behaviour.
64547           *
64548           * @property {Number} rotationX
64549           * @readOnly
64550           * @example
64551           * <div>
64552           * <code>
64553           * function setup() {
64554           *   createCanvas(100, 100, WEBGL);
64555           * }
64556           *
64557           * function draw() {
64558           *   background(200);
64559           *   //rotateZ(radians(rotationZ));
64560           *   rotateX(radians(rotationX));
64561           *   //rotateY(radians(rotationY));
64562           *   box(200, 200, 200);
64563           * }
64564           * </code>
64565           * </div>
64566           * @alt
64567           * red horizontal line right, green vertical line bottom. black background.
64568           */
64569          _main.default.prototype.rotationX = 0;
64570
64571          /**
64572           * The system variable rotationY always contains the rotation of the
64573           * device along the y axis. If the sketch <a href="#/p5/angleMode">
64574           * angleMode()</a> is set to DEGREES, the value will be -90 to 90. If
64575           * it is set to RADIANS, the value will be -PI/2 to PI/2.
64576           *
64577           * Note: The order the rotations are called is important, ie. if used
64578           * together, it must be called in the order Z-X-Y or there might be
64579           * unexpected behaviour.
64580           *
64581           * @property {Number} rotationY
64582           * @readOnly
64583           * @example
64584           * <div>
64585           * <code>
64586           * function setup() {
64587           *   createCanvas(100, 100, WEBGL);
64588           * }
64589           *
64590           * function draw() {
64591           *   background(200);
64592           *   //rotateZ(radians(rotationZ));
64593           *   //rotateX(radians(rotationX));
64594           *   rotateY(radians(rotationY));
64595           *   box(200, 200, 200);
64596           * }
64597           * </code>
64598           * </div>
64599           * @alt
64600           * red horizontal line right, green vertical line bottom. black background.
64601           */
64602          _main.default.prototype.rotationY = 0;
64603
64604          /**
64605           * The system variable rotationZ always contains the rotation of the
64606           * device along the z axis. If the sketch <a href="#/p5/angleMode">
64607           * angleMode()</a> is set to DEGREES, the value will be 0 to 360. If
64608           * it is set to RADIANS, the value will be 0 to 2*PI.
64609           *
64610           * Unlike rotationX and rotationY, this variable is available for devices
64611           * with a built-in compass only.
64612           *
64613           * Note: The order the rotations are called is important, ie. if used
64614           * together, it must be called in the order Z-X-Y or there might be
64615           * unexpected behaviour.
64616           *
64617           * @example
64618           * <div>
64619           * <code>
64620           * function setup() {
64621           *   createCanvas(100, 100, WEBGL);
64622           * }
64623           *
64624           * function draw() {
64625           *   background(200);
64626           *   rotateZ(radians(rotationZ));
64627           *   //rotateX(radians(rotationX));
64628           *   //rotateY(radians(rotationY));
64629           *   box(200, 200, 200);
64630           * }
64631           * </code>
64632           * </div>
64633           *
64634           * @property {Number} rotationZ
64635           * @readOnly
64636           *
64637           * @alt
64638           * red horizontal line right, green vertical line bottom. black background.
64639           */
64640          _main.default.prototype.rotationZ = 0;
64641
64642          /**
64643           * The system variable pRotationX always contains the rotation of the
64644           * device along the x axis in the frame previous to the current frame.
64645           * If the sketch <a href="#/p5/angleMode"> angleMode()</a> is set to DEGREES,
64646           * the value will be -180 to 180. If it is set to RADIANS, the value will
64647           * be -PI to PI.
64648           *
64649           * pRotationX can also be used with rotationX to determine the rotate
64650           * direction of the device along the X-axis.
64651           * @example
64652           * <div class='norender'>
64653           * <code>
64654           * // A simple if statement looking at whether
64655           * // rotationX - pRotationX < 0 is true or not will be
64656           * // sufficient for determining the rotate direction
64657           * // in most cases.
64658           *
64659           * // Some extra logic is needed to account for cases where
64660           * // the angles wrap around.
64661           * let rotateDirection = 'clockwise';
64662           *
64663           * // Simple range conversion to make things simpler.
64664           * // This is not absolutely necessary but the logic
64665           * // will be different in that case.
64666           *
64667           * let rX = rotationX + 180;
64668           * let pRX = pRotationX + 180;
64669           *
64670           * if ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {
64671           *   rotateDirection = 'clockwise';
64672           * } else if (rX - pRX < 0 || rX - pRX > 270) {
64673           *   rotateDirection = 'counter-clockwise';
64674           * }
64675           *
64676           * print(rotateDirection);
64677           * </code>
64678           * </div>
64679           *
64680           * @alt
64681           * no image to display.
64682           *
64683           * @property {Number} pRotationX
64684           * @readOnly
64685           */
64686          _main.default.prototype.pRotationX = 0;
64687
64688          /**
64689           * The system variable pRotationY always contains the rotation of the
64690           * device along the y axis in the frame previous to the current frame.
64691           * If the sketch <a href="#/p5/angleMode"> angleMode()</a> is set to DEGREES,
64692           * the value will be -90 to 90. If it is set to RADIANS, the value will
64693           * be -PI/2 to PI/2.
64694           *
64695           * pRotationY can also be used with rotationY to determine the rotate
64696           * direction of the device along the Y-axis.
64697           * @example
64698           * <div class='norender'>
64699           * <code>
64700           * // A simple if statement looking at whether
64701           * // rotationY - pRotationY < 0 is true or not will be
64702           * // sufficient for determining the rotate direction
64703           * // in most cases.
64704           *
64705           * // Some extra logic is needed to account for cases where
64706           * // the angles wrap around.
64707           * let rotateDirection = 'clockwise';
64708           *
64709           * // Simple range conversion to make things simpler.
64710           * // This is not absolutely necessary but the logic
64711           * // will be different in that case.
64712           *
64713           * let rY = rotationY + 180;
64714           * let pRY = pRotationY + 180;
64715           *
64716           * if ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {
64717           *   rotateDirection = 'clockwise';
64718           * } else if (rY - pRY < 0 || rY - pRY > 270) {
64719           *   rotateDirection = 'counter-clockwise';
64720           * }
64721           * print(rotateDirection);
64722           * </code>
64723           * </div>
64724           *
64725           * @alt
64726           * no image to display.
64727           *
64728           * @property {Number} pRotationY
64729           * @readOnly
64730           */
64731          _main.default.prototype.pRotationY = 0;
64732
64733          /**
64734           * The system variable pRotationZ always contains the rotation of the
64735           * device along the z axis in the frame previous to the current frame.
64736           * If the sketch <a href="#/p5/angleMode"> angleMode()</a> is set to DEGREES,
64737           * the value will be 0 to 360. If it is set to RADIANS, the value will
64738           * be 0 to 2*PI.
64739           *
64740           * pRotationZ can also be used with rotationZ to determine the rotate
64741           * direction of the device along the Z-axis.
64742           * @example
64743           * <div class='norender'>
64744           * <code>
64745           * // A simple if statement looking at whether
64746           * // rotationZ - pRotationZ < 0 is true or not will be
64747           * // sufficient for determining the rotate direction
64748           * // in most cases.
64749           *
64750           * // Some extra logic is needed to account for cases where
64751           * // the angles wrap around.
64752           * let rotateDirection = 'clockwise';
64753           *
64754           * if (
64755           *   (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||
64756           *   rotationZ - pRotationZ < -270
64757           * ) {
64758           *   rotateDirection = 'clockwise';
64759           * } else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {
64760           *   rotateDirection = 'counter-clockwise';
64761           * }
64762           * print(rotateDirection);
64763           * </code>
64764           * </div>
64765           *
64766           * @alt
64767           * no image to display.
64768           *
64769           * @property {Number} pRotationZ
64770           * @readOnly
64771           */
64772          _main.default.prototype.pRotationZ = 0;
64773
64774          var startAngleX = 0;
64775          var startAngleY = 0;
64776          var startAngleZ = 0;
64777
64778          var rotateDirectionX = 'clockwise';
64779          var rotateDirectionY = 'clockwise';
64780          var rotateDirectionZ = 'clockwise';
64781
64782          _main.default.prototype.pRotateDirectionX = undefined;
64783          _main.default.prototype.pRotateDirectionY = undefined;
64784          _main.default.prototype.pRotateDirectionZ = undefined;
64785
64786          _main.default.prototype._updatePRotations = function() {
64787            this._setProperty('pRotationX', this.rotationX);
64788            this._setProperty('pRotationY', this.rotationY);
64789            this._setProperty('pRotationZ', this.rotationZ);
64790          };
64791
64792          /**
64793           * When a device is rotated, the axis that triggers the <a href="#/p5/deviceTurned">deviceTurned()</a>
64794           * method is stored in the turnAxis variable. The turnAxis variable is only defined within
64795           * the scope of deviceTurned().
64796           * @property {String} turnAxis
64797           * @readOnly
64798           * @example
64799           * <div>
64800           * <code>
64801           * // Run this example on a mobile device
64802           * // Rotate the device by 90 degrees in the
64803           * // X-axis to change the value.
64804           *
64805           * let value = 0;
64806           * function draw() {
64807           *   fill(value);
64808           *   rect(25, 25, 50, 50);
64809           * }
64810           * function deviceTurned() {
64811           *   if (turnAxis === 'X') {
64812           *     if (value === 0) {
64813           *       value = 255;
64814           *     }
64814 else if (value === 255) {
64815           *       value = 0;
64816           *     }
64817           *   }
64818           * }
64819           * </code>
64820           * </div>
64821           *
64822           * @alt
64823           * 50x50 black rect in center of canvas. turns white on mobile when device turns
64824           * 50x50 black rect in center of canvas. turns white on mobile when x-axis turns
64825           */
64826          _main.default.prototype.turnAxis = undefined;
64827
64828          var move_threshold = 0.5;
64829          var shake_threshold = 30;
64830
64831          /**
64832           * The <a href="#/p5/setMoveThreshold">setMoveThreshold()</a> function is used to set the movement threshold for
64833           * the <a href="#/p5/deviceMoved">deviceMoved()</a> function. The default threshold is set to 0.5.
64834           *
64835           * @method setMoveThreshold
64836           * @param {number} value The threshold value
64837           * @example
64838           * <div class="norender">
64839           * <code>
64840           * // Run this example on a mobile device
64841           * // You will need to move the device incrementally further
64842           * // the closer the square's color gets to white in order to change the value.
64843           *
64844           * let value = 0;
64845           * let threshold = 0.5;
64846           * function setup() {
64847           *   setMoveThreshold(threshold);
64848           * }
64849           * function draw() {
64850           *   fill(value);
64851           *   rect(25, 25, 50, 50);
64852           * }
64853           * function deviceMoved() {
64854           *   value = value + 5;
64855           *   threshold = threshold + 0.1;
64856           *   if (value > 255) {
64857           *     value = 0;
64858           *     threshold = 30;
64859           *   }
64860           *   setMoveThreshold(threshold);
64861           * }
64862           * </code>
64863           * </div>
64864           *
64865           * @alt
64866           * 50x50 black rect in center of canvas. turns white on mobile when device moves
64867           */
64868
64869          _main.default.prototype.setMoveThreshold = function(val) {
64870            _main.default._validateParameters('setMoveThreshold', arguments);
64871            move_threshold = val;
64872          };
64873
64874          /**
64875           * The <a href="#/p5/setShakeThreshold">setShakeThreshold()</a> function is used to set the movement threshold for
64876           * the <a href="#/p5/deviceShaken">deviceShaken()</a> function. The default threshold is set to 30.
64877           *
64878           * @method setShakeThreshold
64879           * @param {number} value The threshold value
64880           * @example
64881           * <div class="norender">
64882           * <code>
64883           * // Run this example on a mobile device
64884           * // You will need to shake the device more firmly
64885           * // the closer the box's fill gets to white in order to change the value.
64886           *
64887           * let value = 0;
64888           * let threshold = 30;
64889           * function setup() {
64890           *   setShakeThreshold(threshold);
64891           * }
64892           * function draw() {
64893           *   fill(value);
64894           *   rect(25, 25, 50, 50);
64895           * }
64896           * function deviceMoved() {
64897           *   value = value + 5;
64898           *   threshold = threshold + 5;
64899           *   if (value > 255) {
64900           *     value = 0;
64901           *     threshold = 30;
64902           *   }
64903           *   setShakeThreshold(threshold);
64904           * }
64905           * </code>
64906           * </div>
64907           *
64908           * @alt
64909           * 50x50 black rect in center of canvas. turns white on mobile when device
64910           * is being shaked
64911           */
64912
64913          _main.default.prototype.setShakeThreshold = function(val) {
64914            _main.default._validateParameters('setShakeThreshold', arguments);
64915            shake_threshold = val;
64916          };
64917
64918          /**
64919           * The <a href="#/p5/deviceMoved">deviceMoved()</a> function is called when the device is moved by more than
64920           * the threshold value along X, Y or Z axis. The default threshold is set to 0.5.
64921           * The threshold value can be changed using <a href="https://p5js.org/reference/#/p5/setMoveThreshold">setMoveThreshold()</a>.
64922           *
64923           * @method deviceMoved
64924           * @example
64925           * <div class="norender">
64926           * <code>
64927           * // Run this example on a mobile device
64928           * // Move the device around
64929           * // to change the value.
64930           *
64931           * let value = 0;
64932           * function draw() {
64933           *   fill(value);
64934           *   rect(25, 25, 50, 50);
64935           * }
64936           * function deviceMoved() {
64937           *   value = value + 5;
64938           *   if (value > 255) {
64939           *     value = 0;
64940           *   }
64941           * }
64942           * </code>
64943           * </div>
64944           *
64945           * @alt
64946           * 50x50 black rect in center of canvas. turns white on mobile when device moves
64947           */
64948
64949          /**
64950           * The <a href="#/p5/deviceTurned">deviceTurned()</a> function is called when the device rotates by
64951           * more than 90 degrees continuously.
64952           *
64953           * The axis that triggers the <a href="#/p5/deviceTurned">deviceTurned()</a> method is stored in the turnAxis
64954           * variable. The <a href="#/p5/deviceTurned">deviceTurned()</a> method can be locked to trigger on any axis:
64955           * X, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.
64956           *
64957           * @method deviceTurned
64958           * @example
64959           * <div class="norender">
64960           * <code>
64961           * // Run this example on a mobile device
64962           * // Rotate the device by 90 degrees
64963           * // to change the value.
64964           *
64965           * let value = 0;
64966           * function draw() {
64967           *   fill(value);
64968           *   rect(25, 25, 50, 50);
64969           * }
64970           * function deviceTurned() {
64971           *   if (value === 0) {
64972           *     value = 255;
64973           *   }
64973 else if (value === 255) {
64974           *     value = 0;
64975           *   }
64976           * }
64977           * </code>
64978           * </div>
64979           * <div>
64980           * <code>
64981           * // Run this example on a mobile device
64982           * // Rotate the device by 90 degrees in the
64983           * // X-axis to change the value.
64984           *
64985           * let value = 0;
64986           * function draw() {
64987           *   fill(value);
64988           *   rect(25, 25, 50, 50);
64989           * }
64990           * function deviceTurned() {
64991           *   if (turnAxis === 'X') {
64992           *     if (value === 0) {
64993           *       value = 255;
64994           *     } else if (value === 255) {
64995           *       value = 0;
64996           *     }
64997           *   }
64998           * }
64999           * </code>
65000           * </div>
65001           *
65002           * @alt
65003           * 50x50 black rect in center of canvas. turns white on mobile when device turns
65004           * 50x50 black rect in center of canvas. turns white on mobile when x-axis turns
65005           */
65006
65007          /**
65008           * The <a href="#/p5/deviceShaken">deviceShaken()</a> function is called when the device total acceleration
65009           * changes of accelerationX and accelerationY values is more than
65010           * the threshold value. The default threshold is set to 30.
65011           * The threshold value can be changed using <a href="https://p5js.org/reference/#/p5/setShakeThreshold">setShakeThreshold()</a>.
65012           *
65013           * @method deviceShaken
65014           * @example
65015           * <div class="norender">
65016           * <code>
65017           * // Run this example on a mobile device
65018           * // Shake the device to change the value.
65019           *
65020           * let value = 0;
65021           * function draw() {
65022           *   fill(value);
65023           *   rect(25, 25, 50, 50);
65024           * }
65025           * function deviceShaken() {
65026           *   value = value + 5;
65027           *   if (value > 255) {
65028           *     value = 0;
65029           *   }
65030           * }
65031           * </code>
65032           * </div>
65033           *
65034           * @alt
65035           * 50x50 black rect in center of canvas. turns white on mobile when device shakes
65036           */
65037
65038          _main.default.prototype._ondeviceorientation = function(e) {
65039            this._updatePRotations();
65040            if (this._angleMode === constants.radians) {
65041              e.beta = e.beta * (_PI / 180.0);
65042              e.gamma = e.gamma * (_PI / 180.0);
65043              e.alpha = e.alpha * (_PI / 180.0);
65044            }
65045            this._setProperty('rotationX', e.beta);
65046            this._setProperty('rotationY', e.gamma);
65047            this._setProperty('rotationZ', e.alpha);
65048            this._handleMotion();
65049          };
65050          _main.default.prototype._ondevicemotion = function(e) {
65051            this._updatePAccelerations();
65052            this._setProperty('accelerationX', e.acceleration.x * 2);
65053            this._setProperty('accelerationY', e.acceleration.y * 2);
65054            this._setProperty('accelerationZ', e.acceleration.z * 2);
65055            this._handleMotion();
65056          };
65057          _main.default.prototype._handleMotion = function() {
65058            if (window.orientation === 90 || window.orientation === -90) {
65059              this._setProperty('deviceOrientation', 'landscape');
65060            } else if (window.orientation === 0) {
65061              this._setProperty('deviceOrientation', 'portrait');
65062            } else if (window.orientation === undefined) {
65063              this._setProperty('deviceOrientation', 'undefined');
65064            }
65065            var context = this._isGlobal ? window : this;
65066            if (typeof context.deviceMoved === 'function') {
65067              if (
65068                Math.abs(this.accelerationX - this.pAccelerationX) > move_threshold ||
65069                Math.abs(this.accelerationY - this.pAccelerationY) > move_threshold ||
65070                Math.abs(this.accelerationZ - this.pAccelerationZ) > move_threshold
65071              ) {
65072                context.deviceMoved();
65073              }
65074            }
65075
65076            if (typeof context.deviceTurned === 'function') {
65077              // The angles given by rotationX etc is from range -180 to 180.
65078              // The following will convert them to 0 to 360 for ease of calculation
65079              // of cases when the angles wrapped around.
65080              // _startAngleX will be converted back at the end and updated.
65081              var wRX = this.rotationX + 180;
65082              var wPRX = this.pRotationX + 180;
65083              var wSAX = startAngleX + 180;
65084              if ((wRX - wPRX > 0 && wRX - wPRX < 270) || wRX - wPRX < -270) {
65085                rotateDirectionX = 'clockwise';
65086              } else if (wRX - wPRX < 0 || wRX - wPRX > 270) {
65087                rotateDirectionX = 'counter-clockwise';
65088              }
65089              if (rotateDirectionX !== this.pRotateDirectionX) {
65090                wSAX = wRX;
65091              }
65092              if (Math.abs(wRX - wSAX) > 90 && Math.abs(wRX - wSAX) < 270) {
65093                wSAX = wRX;
65094                this._setProperty('turnAxis', 'X');
65095                context.deviceTurned();
65096              }
65097              this.pRotateDirectionX = rotateDirectionX;
65098              startAngleX = wSAX - 180;
65099
65100              // Y-axis is identical to X-axis except for changing some names.
65101              var wRY = this.rotationY + 180;
65102              var wPRY = this.pRotationY + 180;
65103              var wSAY = startAngleY + 180;
65104              if ((wRY - wPRY > 0 && wRY - wPRY < 270) || wRY - wPRY < -270) {
65105                rotateDirectionY = 'clockwise';
65106              } else if (wRY - wPRY < 0 || wRY - this.pRotationY > 270) {
65107                rotateDirectionY = 'counter-clockwise';
65108              }
65109              if (rotateDirectionY !== this.pRotateDirectionY) {
65110                wSAY = wRY;
65111              }
65112              if (Math.abs(wRY - wSAY) > 90 && Math.abs(wRY - wSAY) < 270) {
65113                wSAY = wRY;
65114                this._setProperty('turnAxis', 'Y');
65115                context.deviceTurned();
65116              }
65117              this.pRotateDirectionY = rotateDirectionY;
65118              startAngleY = wSAY - 180;
65119
65120              // Z-axis is already in the range 0 to 360
65121              // so no conversion is needed.
65122              if (
65123                (this.rotationZ - this.pRotationZ > 0 &&
65124                  this.rotationZ - this.pRotationZ < 270) ||
65125                this.rotationZ - this.pRotationZ < -270
65126              ) {
65127                rotateDirectionZ = 'clockwise';
65128              } else if (
65129                this.rotationZ - this.pRotationZ < 0 ||
65130                this.rotationZ - this.pRotationZ > 270
65131              ) {
65132                rotateDirectionZ = 'counter-clockwise';
65133              }
65134              if (rotateDirectionZ !== this.pRotateDirectionZ) {
65135                startAngleZ = this.rotationZ;
65136              }
65137              if (
65138                Math.abs(this.rotationZ - startAngleZ) > 90 &&
65139                Math.abs(this.rotationZ - startAngleZ) < 270
65140              ) {
65141                startAngleZ = this.rotationZ;
65142                this._setProperty('turnAxis', 'Z');
65143                context.deviceTurned();
65144              }
65145              this.pRotateDirectionZ = rotateDirectionZ;
65146              this._setProperty('turnAxis', undefined);
65147            }
65148            if (typeof context.deviceShaken === 'function') {
65149              var accelerationChangeX;
65150              var accelerationChangeY;
65151              // Add accelerationChangeZ if acceleration change on Z is needed
65152              if (this.pAccelerationX !== null) {
65153                accelerationChangeX = Math.abs(this.accelerationX - this.pAccelerationX);
65154                accelerationChangeY = Math.abs(this.accelerationY - this.pAccelerationY);
65155              }
65156              if (accelerationChangeX + accelerationChangeY > shake_threshold) {
65157                context.deviceShaken();
65158              }
65159            }
65160          };
65161          var _default = _main.default;
65162          exports.default = _default;
65163        },
65164        { '../core/constants': 48, '../core/main': 59 }
65165      ],
65166      77: [
65167        function(_dereq_, module, exports) {
65168          'use strict';
65169          Object.defineProperty(exports, '__esModule', { value: true });
65170          exports.default = void 0;
65171
65172          var _main = _interopRequireDefault(_dereq_('../core/main'));
65173          function _interopRequireDefault(obj) {
65174            return obj && obj.__esModule ? obj : { default: obj };
65175          }
65176          /**
65177           * @module Events
65178           * @submodule Keyboard
65179           * @for p5
65180           * @requires core
65181           */ /**
65182           * The boolean system variable <a href="#/p5/keyIsPressed">keyIsPressed</a> is true if any key is pressed
65183           * and false if no keys are pressed.
65184           *
65185           * @property {Boolean} keyIsPressed
65186           * @readOnly
65187           * @example
65188           * <div>
65189           * <code>
65190           * function draw() {
65191           *   if (keyIsPressed === true) {
65192           *     fill(0);
65193           *   } else {
65194           *     fill(255);
65195           *   }
65196           *   rect(25, 25, 50, 50);
65197           * }
65198           * </code>
65199           * </div>
65200           *
65201           * @alt
65202           * 50x50 white rect that turns black on keypress.
65203           */ _main.default.prototype.isKeyPressed = false;
65204          _main.default.prototype.keyIsPressed = false; // khan
65205          /**
65206           * The system variable key always contains the value of the most recent
65207           * key on the keyboard that was typed. To get the proper capitalization, it
65208           * is best to use it within <a href="#/p5/keyTyped">keyTyped()</a>. For non-ASCII keys, use the <a href="#/p5/keyCode">keyCode</a>
65209           * variable.
65210           *
65211           * @property {String} key
65212           * @readOnly
65213           * @example
65214           * <div><code>
65215           * // Click any key to display it!
65216           * // (Not Guaranteed to be Case Sensitive)
65217           * function setup() {
65218           *   fill(245, 123, 158);
65219           *   textSize(50);
65220           * }
65221           *
65222           * function draw() {
65223           *   background(200);
65224           *   text(key, 33, 65); // Display last key pressed.
65225           * }
65226           * </code></div>
65227           *
65228           * @alt
65229           * canvas displays any key value that is pressed in pink font.
65230           */
65231          _main.default.prototype.key = '';
65232
65233          /**
65234           * The variable keyCode is used to detect special keys such as BACKSPACE,
65235           * DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,
65236           * DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.
65237           * You can also check for custom keys by looking up the keyCode of any key
65238           * on a site like this: <a href="http://keycode.info/">keycode.info</a>.
65239           *
65240           * @property {Integer} keyCode
65241           * @readOnly
65242           * @example
65243           * <div><code>
65244           * let fillVal = 126;
65245           * function draw() {
65246           *   fill(fillVal);
65247           *   rect(25, 25, 50, 50);
65248           * }
65249           *
65250           * function keyPressed() {
65251           *   if (keyCode === UP_ARROW) {
65252           *     fillVal = 255;
65253           *   } else if (keyCode === DOWN_ARROW) {
65254           *     fillVal = 0;
65255           *   }
65256           * }
65257           * </code></div>
65258           * <div><code>
65259           * function draw() {}
65260           * function keyPressed() {
65261           *   background('yellow');
65262           *   text(`${key} ${keyCode}`, 10, 40);
65263           *   print(key, ' ', keyCode);
65264           * }
65265           * </code></div>
65266           * @alt
65267           * Grey rect center. turns white when up arrow pressed and black when down
65268           * Display key pressed and its keyCode in a yellow box
65269           */
65270          _main.default.prototype.keyCode = 0;
65271
65272          /**
65273           * The <a href="#/p5/keyPressed">keyPressed()</a> function is called once every time a key is pressed. The
65274           * keyCode for the key that was pressed is stored in the <a href="#/p5/keyCode">keyCode</a> variable.
65275           *
65276           * For non-ASCII keys, use the keyCode variable. You can check if the keyCode
65277           * equals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,
65278           * OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.
65279           *
65280           * For ASCII keys, the key that was pressed is stored in the key variable. However, it
65281           * does not distinguish between uppercase and lowercase. For this reason, it
65282           * is recommended to use <a href="#/p5/keyTyped">keyTyped()</a> to read the key variable, in which the
65283           * case of the variable will be distinguished.
65284           *
65285           * Because of how operating systems handle key repeats, holding down a key
65286           * may cause multiple calls to <a href="#/p5/keyTyped">keyTyped()</a> (and <a href="#/p5/keyReleased">keyReleased()</a> as well). The
65287           * rate of repeat is set by the operating system and how each computer is
65288           * configured.<br><br>
65289           * Browsers may have different default
65290           * behaviors attached to various key events. To prevent any default
65291           * behavior for this event, add "return false" to the end of the method.
65292           *
65293           * @method keyPressed
65294           * @example
65295           * <div>
65296           * <code>
65297           * let value = 0;
65298           * function draw() {
65299           *   fill(value);
65300           *   rect(25, 25, 50, 50);
65301           * }
65302           * function keyPressed() {
65303           *   if (value === 0) {
65304           *     value = 255;
65305           *   } else {
65306           *     value = 0;
65307           *   }
65308           * }
65309           * </code>
65310           * </div>
65311           * <div>
65312           * <code>
65313           * let value = 0;
65314           * function draw() {
65315           *   fill(value);
65316           *   rect(25, 25, 50, 50);
65317           * }
65318           * function keyPressed() {
65319           *   if (keyCode === LEFT_ARROW) {
65320           *     value = 255;
65321           *   } else if (keyCode === RIGHT_ARROW) {
65322           *     value = 0;
65323           *   }
65324           * }
65325           * </code>
65326           * </div>
65327           * <div class="norender">
65328           * <code>
65329           * function keyPressed() {
65330           *   // Do something
65331           *   return false; // prevent any default behaviour
65332           * }
65333           * </code>
65334           * </div>
65335           *
65336           * @alt
65337           * black rect center. turns white when key pressed and black when released
65338           * black rect center. turns white when left arrow pressed and black when right.
65339           */
65340          _main.default.prototype._onkeydown = function(e) {
65341            if (this._downKeys[e.which]) {
65342              // prevent multiple firings
65343              return;
65344            }
65345            this._setProperty('isKeyPressed', true);
65346            this._setProperty('keyIsPressed', true);
65347            this._setProperty('keyCode', e.which);
65348            this._downKeys[e.which] = true;
65349            this._setProperty('key', e.key || String.fromCharCode(e.which) || e.which);
65350            var context = this._isGlobal ? window : this;
65351            if (typeof context.keyPressed === 'function' && !e.charCode) {
65352              var executeDefault = context.keyPressed(e);
65353              if (executeDefault === false) {
65354                e.preventDefault();
65355              }
65356            }
65357          };
65358          /**
65359           * The <a href="#/p5/keyReleased">keyReleased()</a> function is called once every time a key is released.
65360           * See <a href="#/p5/key">key</a> and <a href="#/p5/keyCode">keyCode</a> for more information.<br><br>
65361           * Browsers may have different default
65362           * behaviors attached to various key events. To prevent any default
65363           * behavior for this event, add "return false" to the end of the method.
65364           *
65365           * @method keyReleased
65366           * @example
65367           * <div>
65368           * <code>
65369           * let value = 0;
65370           * function draw() {
65371           *   fill(value);
65372           *   rect(25, 25, 50, 50);
65373           * }
65374           * function keyReleased() {
65375           *   if (value === 0) {
65376           *     value = 255;
65377           *   } else {
65378           *     value = 0;
65379           *   }
65380           *   return false; // prevent any default behavior
65381           * }
65382           * </code>
65383           * </div>
65384           *
65385           * @alt
65386           * black rect center. turns white when key pressed and black when pressed again
65387           */
65388          _main.default.prototype._onkeyup = function(e) {
65389            this._downKeys[e.which] = false;
65390
65391            if (!this._areDownKeys()) {
65392              this._setProperty('isKeyPressed', false);
65393              this._setProperty('keyIsPressed', false);
65394            }
65395
65396            this._setProperty('_lastKeyCodeTyped', null);
65397
65398            this._setProperty('key', e.key || String.fromCharCode(e.which) || e.which);
65399            this._setProperty('keyCode', e.which);
65400
65401            var context = this._isGlobal ? window : this;
65402            if (typeof context.keyReleased === 'function') {
65403              var executeDefault = context.keyReleased(e);
65404              if (executeDefault === false) {
65405                e.preventDefault();
65406              }
65407            }
65408          };
65409
65410          /**
65411           * The <a href="#/p5/keyTyped">keyTyped()</a> function is called once every time a key is pressed, but
65412           * action keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect
65413           * a keyCode for one of these keys, use the <a href="#/p5/keyPressed">keyPressed()</a> function instead.
65414           * The most recent key typed will be stored in the key variable.
65415           *
65416           * Because of how operating systems handle key repeats, holding down a key
65417           * will cause multiple calls to <a href="#/p5/keyTyped">keyTyped()</a> (and <a href="#/p5/keyReleased">keyReleased()</a> as well). The
65418           * rate of repeat is set by the operating system and how each computer is
65419           * configured.<br><br>
65420           * Browsers may have different default behaviors attached to various key
65421           * events. To prevent any default behavior for this event, add "return false"
65422           * to the end of the method.
65423           *
65424           * @method keyTyped
65425           * @example
65426           * <div>
65427           * <code>
65428           * let value = 0;
65429           * function draw() {
65430           *   fill(value);
65431           *   rect(25, 25, 50, 50);
65432           * }
65433           * function keyTyped() {
65434           *   if (key === 'a') {
65435           *     value = 255;
65436           *   } else if (key === 'b') {
65437           *     value = 0;
65438           *   }
65439           *   // uncomment to prevent any default behavior
65440           *   // return false;
65441           * }
65442           * </code>
65443           * </div>
65444           *
65445           * @alt
65446           * black rect center. turns white when 'a' key typed and black when 'b' pressed
65447           */
65448          _main.default.prototype._onkeypress = function(e) {
65449            if (e.which === this._lastKeyCodeTyped) {
65450              // prevent multiple firings
65451              return;
65452            }
65453            this._setProperty('_lastKeyCodeTyped', e.which); // track last keyCode
65454            this._setProperty('key', e.key || String.fromCharCode(e.which) || e.which);
65455
65456            var context = this._isGlobal ? window : this;
65457            if (typeof context.keyTyped === 'function') {
65458              var executeDefault = context.keyTyped(e);
65459              if (executeDefault === false) {
65460                e.preventDefault();
65461              }
65462            }
65463          };
65464          /**
65465           * The onblur function is called when the user is no longer focused
65466           * on the p5 element. Because the keyup events will not fire if the user is
65467           * not focused on the element we must assume all keys currently down have
65468           * been released.
65469           */
65470          _main.default.prototype._onblur = function(e) {
65471            this._downKeys = {};
65472          };
65473
65474          /**
65475           * The <a href="#/p5/keyIsDown">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.
65476           * It can be used if you have an object that moves, and you want several keys
65477           * to be able to affect its behaviour simultaneously, such as moving a
65478           * sprite diagonally. You can put in any number representing the keyCode of
65479           * the key, or use any of the variable <a href="#/p5/keyCode">keyCode</a> names listed
65480           * <a href="http://p5js.org/reference/#p5/keyCode">here</a>.
65481           *
65482           * @method keyIsDown
65483           * @param {Number}          code The key to check for.
65484           * @return {Boolean}        whether key is down or not
65485           * @example
65486           * <div><code>
65487           * let x = 100;
65488           * let y = 100;
65489           *
65490           * function setup() {
65491           *   createCanvas(512, 512);
65492           *   fill(255, 0, 0);
65493           * }
65494           *
65495           * function draw() {
65496           *   if (keyIsDown(LEFT_ARROW)) {
65497           *     x -= 5;
65498           *   }
65499           *
65500           *   if (keyIsDown(RIGHT_ARROW)) {
65501           *     x += 5;
65502           *   }
65503           *
65504           *   if (keyIsDown(UP_ARROW)) {
65505           *     y -= 5;
65506           *   }
65507           *
65508           *   if (keyIsDown(DOWN_ARROW)) {
65509           *     y += 5;
65510           *   }
65511           *
65512           *   clear();
65513           *   ellipse(x, y, 50, 50);
65514           * }
65515           * </code></div>
65516           *
65517           * <div><code>
65518           * let diameter = 50;
65519           *
65520           * function setup() {
65521           *   createCanvas(512, 512);
65522           * }
65523           *
65524           * function draw() {
65525           *   // 107 and 187 are keyCodes for "+"
65526           *   if (keyIsDown(107) || keyIsDown(187)) {
65527           *     diameter += 1;
65528           *   }
65529           *
65530           *   // 109 and 189 are keyCodes for "-"
65531           *   if (keyIsDown(109) || keyIsDown(189)) {
65532           *     diameter -= 1;
65533           *   }
65534           *
65535           *   clear();
65536           *   fill(255, 0, 0);
65537           *   ellipse(50, 50, diameter, diameter);
65538           * }
65539           * </code></div>
65540           *
65541           * @alt
65542           * 50x50 red ellipse moves left, right, up and down with arrow presses.
65543           * 50x50 red ellipse gets bigger or smaller when + or - are pressed.
65544           */
65545          _main.default.prototype.keyIsDown = function(code) {
65546            _main.default._validateParameters('keyIsDown', arguments);
65547            return this._downKeys[code] || false;
65548          };
65549
65550          /**
65551    * The _areDownKeys function returns a boolean true if any keys pressed
65552    * and a false if no keys are currently pressed.
65553   
65554    * Helps avoid instances where multiple keys are pressed simultaneously and
65555    * releasing a single key will then switch the
65556    * keyIsPressed property to true.
65557    * @private
65558   **/
65559          _main.default.prototype._areDownKeys = function() {
65560            for (var key in this._downKeys) {
65561              if (this._downKeys.hasOwnProperty(key) && this._downKeys[key] === true) {
65562                return true;
65563              }
65564            }
65565            return false;
65566          };
65567          var _default = _main.default;
65568          exports.default = _default;
65569        },
65570        { '../core/main': 59 }
65571      ],
65572      78: [
65573        function(_dereq_, module, exports) {
65574          'use strict';
65575          function _typeof(obj) {
65576            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
65577              _typeof = function _typeof(obj) {
65578                return typeof obj;
65579              };
65580            } else {
65581              _typeof = function _typeof(obj) {
65582                return obj &&
65583                  typeof Symbol === 'function' &&
65584                  obj.constructor === Symbol &&
65585                  obj !== Symbol.prototype
65586                  ? 'symbol'
65587                  : typeof obj;
65588              };
65589            }
65590            return _typeof(obj);
65591          }
65592          Object.defineProperty(exports, '__esModule', { value: true });
65593          exports.default = void 0;
65594
65595          var _main = _interopRequireDefault(_dereq_('../core/main'));
65596          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
65597          function _getRequireWildcardCache() {
65598            if (typeof WeakMap !== 'function') return null;
65599            var cache = new WeakMap();
65600            _getRequireWildcardCache = function _getRequireWildcardCache() {
65601              return cache;
65602            };
65603            return cache;
65604          }
65605          function _interopRequireWildcard(obj) {
65606            if (obj && obj.__esModule) {
65607              return obj;
65608            }
65609            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
65610              return { default: obj };
65611            }
65612            var cache = _getRequireWildcardCache();
65613            if (cache && cache.has(obj)) {
65614              return cache.get(obj);
65615            }
65616            var newObj = {};
65617            var hasPropertyDescriptor =
65618              Object.defineProperty && Object.getOwnPropertyDescriptor;
65619            for (var key in obj) {
65620              if (Object.prototype.hasOwnProperty.call(obj, key)) {
65621                var desc = hasPropertyDescriptor
65622                  ? Object.getOwnPropertyDescriptor(obj, key)
65623                  : null;
65624                if (desc && (desc.get || desc.set)) {
65625                  Object.defineProperty(newObj, key, desc);
65626                } else {
65627                  newObj[key] = obj[key];
65628                }
65629              }
65630            }
65631            newObj.default = obj;
65632            if (cache) {
65633              cache.set(obj, newObj);
65634            }
65635            return newObj;
65636          }
65637          function _interopRequireDefault(obj) {
65638            return obj && obj.__esModule ? obj : { default: obj };
65639          }
65640          /**
65641           * @module Events
65642           * @submodule Mouse
65643           * @for p5
65644           * @requires core
65645           * @requires constants
65646           */ /**
65647           *
65648           * The variable movedX contains the horizontal movement of the mouse since the last frame
65649           * @property {Number} movedX
65650           * @readOnly
65651           * @example
65652           * <div class="notest">
65653           * <code>
65654           * let x = 50;
65655           * function setup() {
65656           *   rectMode(CENTER);
65657           * }
65658           *
65659           * function draw() {
65660           *   if (x > 48) {
65661           *     x -= 2;
65662           *   } else if (x < 48) {
65663           *     x += 2;
65664           *   }
65665           *   x += floor(movedX / 5);
65666           *   background(237, 34, 93);
65667           *   fill(0);
65668           *   rect(x, 50, 50, 50);
65669           * }
65670           * </code>
65671           * </div>
65672           * @alt
65673           * box moves left and right according to mouse movement then slowly back towards the center
65674           */ _main.default.prototype.movedX = 0;
65675          /**
65676           * The variable movedY contains the vertical movement of the mouse since the last frame
65677           * @property {Number} movedY
65678           * @readOnly
65679           * @example
65680           * <div class="notest">
65681           * <code>
65682           * let y = 50;
65683           * function setup() {
65684           *   rectMode(CENTER);
65685           * }
65686           *
65687           * function draw() {
65688           *   if (y > 48) {
65689           *     y -= 2;
65690           *   } else if (y < 48) {
65691           *     y += 2;
65692           *   }
65693           *   y += floor(movedY / 5);
65694           *   background(237, 34, 93);
65695           *   fill(0);
65696           *   rect(y, 50, 50, 50);
65697           * }
65698           * </code>
65699           * </div>
65700           * @alt
65701           * box moves up and down according to mouse movement then slowly back towards the center
65702           */ _main.default.prototype.movedY = 0;
65703          /*
65704                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * This is a flag which is false until the first time
65705                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * we receive a mouse event. The pmouseX and pmouseY
65706                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * values will match the mouseX and mouseY values until
65707                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * this interaction takes place.
65708                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               */
65709          _main.default.prototype._hasMouseInteracted = false;
65710
65711          /**
65712           * The system variable mouseX always contains the current horizontal
65713           * position of the mouse, relative to (0, 0) of the canvas. The value at
65714           * the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.
65715           * If touch is used instead of mouse input, mouseX will hold the x value
65716           * of the most recent touch point.
65717           *
65718           * @property {Number} mouseX
65719           * @readOnly
65720           *
65721           * @example
65722           * <div>
65723           * <code>
65724           * // Move the mouse across the canvas
65725           * function draw() {
65726           *   background(244, 248, 252);
65727           *   line(mouseX, 0, mouseX, 100);
65728           * }
65729           * </code>
65730           * </div>
65731           *
65732           * @alt
65733           * horizontal black line moves left and right with mouse x-position
65734           */
65735          _main.default.prototype.mouseX = 0;
65736
65737          /**
65738           * The system variable mouseY always contains the current vertical
65739           * position of the mouse, relative to (0, 0) of the canvas. The value at
65740           * the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.
65741           * If touch is used instead of mouse input, mouseY will hold the y value
65742           * of the most recent touch point.
65743           *
65744           * @property {Number} mouseY
65745           * @readOnly
65746           *
65747           * @example
65748           * <div>
65749           * <code>
65750           * // Move the mouse across the canvas
65751           * function draw() {
65752           *   background(244, 248, 252);
65753           *   line(0, mouseY, 100, mouseY);
65754           * }
65755           * </code>
65756           * </div>
65757           *
65758           * @alt
65759           * vertical black line moves up and down with mouse y-position
65760           */
65761          _main.default.prototype.mouseY = 0;
65762
65763          /**
65764           * The system variable pmouseX always contains the horizontal position of
65765           * the mouse or finger in the frame previous to the current frame, relative to
65766           * (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and
65767           * (-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX
65768           * value at the start of each touch event.
65769           *
65770           * @property {Number} pmouseX
65771           * @readOnly
65772           *
65773           * @example
65774           * <div>
65775           * <code>
65776           * // Move the mouse across the canvas to leave a trail
65777           * function setup() {
65778           *   //slow down the frameRate to make it more visible
65779           *   frameRate(10);
65780           * }
65781           *
65782           * function draw() {
65783           *   background(244, 248, 252);
65784           *   line(mouseX, mouseY, pmouseX, pmouseY);
65785           *   print(pmouseX + ' -> ' + mouseX);
65786           * }
65787           * </code>
65788           * </div>
65789           *
65790           * @alt
65791           * line trail is created from cursor movements. faster movement make longer line.
65792           */
65793          _main.default.prototype.pmouseX = 0;
65794
65795          /**
65796           * The system variable pmouseY always contains the vertical position of
65797           * the mouse or finger in the frame previous to the current frame, relative to
65798           * (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and
65799           * (-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY
65800           * value at the start of each touch event.
65801           *
65802           * @property {Number} pmouseY
65803           * @readOnly
65804           *
65805           * @example
65806           * <div>
65807           * <code>
65808           * function draw() {
65809           *   background(237, 34, 93);
65810           *   fill(0);
65811           *   //draw a square only if the mouse is not moving
65812           *   if (mouseY === pmouseY && mouseX === pmouseX) {
65813           *     rect(20, 20, 60, 60);
65814           *   }
65815           *
65816           *   print(pmouseY + ' -> ' + mouseY);
65817           * }
65818           * </code>
65819           * </div>
65820           *
65821           * @alt
65822           * 60x60 black rect center, fuchsia background. rect flickers on mouse movement
65823           */
65824          _main.default.prototype.pmouseY = 0;
65825
65826          /**
65827           * The system variable winMouseX always contains the current horizontal
65828           * position of the mouse, relative to (0, 0) of the window.
65829           *
65830           * @property {Number} winMouseX
65831           * @readOnly
65832           *
65833           * @example
65834           * <div>
65835           * <code>
65836           * let myCanvas;
65837           *
65838           * function setup() {
65839           *   //use a variable to store a pointer to the canvas
65840           *   myCanvas = createCanvas(100, 100);
65841           *   let body = document.getElementsByTagName('body')[0];
65842           *   myCanvas.parent(body);
65843           * }
65844           *
65845           * function draw() {
65846           *   background(237, 34, 93);
65847           *   fill(0);
65848           *
65849           *   //move the canvas to the horizontal mouse position
65850           *   //relative to the window
65851           *   myCanvas.position(winMouseX + 1, windowHeight / 2);
65852           *
65853           *   //the y of the square is relative to the canvas
65854           *   rect(20, mouseY, 60, 60);
65855           * }
65856           * </code>
65857           * </div>
65858           *
65859           * @alt
65860           * 60x60 black rect y moves with mouse y and fuchsia canvas moves with mouse x
65861           */
65862          _main.default.prototype.winMouseX = 0;
65863
65864          /**
65865           * The system variable winMouseY always contains the current vertical
65866           * position of the mouse, relative to (0, 0) of the window.
65867           *
65868           * @property {Number} winMouseY
65869           * @readOnly
65870           *
65871           * @example
65872           * <div>
65873           * <code>
65874           * let myCanvas;
65875           *
65876           * function setup() {
65877           *   //use a variable to store a pointer to the canvas
65878           *   myCanvas = createCanvas(100, 100);
65879           *   let body = document.getElementsByTagName('body')[0];
65880           *   myCanvas.parent(body);
65881           * }
65882           *
65883           * function draw() {
65884           *   background(237, 34, 93);
65885           *   fill(0);
65886           *
65887           *   //move the canvas to the vertical mouse position
65888           *   //relative to the window
65889           *   myCanvas.position(windowWidth / 2, winMouseY + 1);
65890           *
65891           *   //the x of the square is relative to the canvas
65892           *   rect(mouseX, 20, 60, 60);
65893           * }
65894           * </code>
65895           * </div>
65896           *
65897           * @alt
65898           * 60x60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y
65899           */
65900          _main.default.prototype.winMouseY = 0;
65901
65902          /**
65903           * The system variable pwinMouseX always contains the horizontal position
65904           * of the mouse in the frame previous to the current frame, relative to
65905           * (0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX
65906           * value at the start of each touch event.
65907           *
65908           * @property {Number} pwinMouseX
65909           * @readOnly
65910           *
65911           * @example
65912           * <div>
65913           * <code>
65914           * let myCanvas;
65915           *
65916           * function setup() {
65917           *   //use a variable to store a pointer to the canvas
65918           *   myCanvas = createCanvas(100, 100);
65919           *   noStroke();
65920           *   fill(237, 34, 93);
65921           * }
65922           *
65923           * function draw() {
65924           *   clear();
65925           *   //the difference between previous and
65926           *   //current x position is the horizontal mouse speed
65927           *   let speed = abs(winMouseX - pwinMouseX);
65928           *   //change the size of the circle
65929           *   //according to the horizontal speed
65930           *   ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);
65931           *   //move the canvas to the mouse position
65932           *   myCanvas.position(winMouseX + 1, winMouseY + 1);
65933           * }
65934           * </code>
65935           * </div>
65936           *
65937           * @alt
65938           * fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed
65939           */
65940          _main.default.prototype.pwinMouseX = 0;
65941
65942          /**
65943           * The system variable pwinMouseY always contains the vertical position of
65944           * the mouse in the frame previous to the current frame, relative to (0, 0)
65945           * of the window. Note: pwinMouseY will be reset to the current winMouseY
65946           * value at the start of each touch event.
65947           *
65948           * @property {Number} pwinMouseY
65949           * @readOnly
65950           *
65951           * @example
65952           * <div>
65953           * <code>
65954           * let myCanvas;
65955           *
65956           * function setup() {
65957           *   //use a variable to store a pointer to the canvas
65958           *   myCanvas = createCanvas(100, 100);
65959           *   noStroke();
65960           *   fill(237, 34, 93);
65961           * }
65962           *
65963           * function draw() {
65964           *   clear();
65965           *   //the difference between previous and
65966           *   //current y position is the vertical mouse speed
65967           *   let speed = abs(winMouseY - pwinMouseY);
65968           *   //change the size of the circle
65969           *   //according to the vertical speed
65970           *   ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);
65971           *   //move the canvas to the mouse position
65972           *   myCanvas.position(winMouseX + 1, winMouseY + 1);
65973           * }
65974           * </code>
65975           * </div>
65976           *
65977           * @alt
65978           * fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed
65979           */
65980          _main.default.prototype.pwinMouseY = 0;
65981
65982          /**
65983           * Processing automatically tracks if the mouse button is pressed and which
65984           * button is pressed. The value of the system variable mouseButton is either
65985           * LEFT, RIGHT, or CENTER depending on which button was pressed last.
65986           * Warning: different browsers may track mouseButton differently.
65987           *
65988           * @property {Constant} mouseButton
65989           * @readOnly
65990           *
65991           * @example
65992           * <div>
65993           * <code>
65994           * function draw() {
65995           *   background(237, 34, 93);
65996           *   fill(0);
65997           *
65998           *   if (mouseIsPressed) {
65999           *     if (mouseButton === LEFT) {
66000           *       ellipse(50, 50, 50, 50);
66001           *     }
66002           *     if (mouseButton === RIGHT) {
66003           *       rect(25, 25, 50, 50);
66004           *     }
66005           *     if (mouseButton === CENTER) {
66006           *       triangle(23, 75, 50, 20, 78, 75);
66007           *     }
66008           *   }
66009           *
66010           *   print(mouseButton);
66011           * }
66012           * </code>
66013           * </div>
66014           *
66015           * @alt
66016           * 50x50 black ellipse appears on center of fuchsia canvas on mouse click/press.
66017           */
66018          _main.default.prototype.mouseButton = 0;
66019
66020          /**
66021           * The boolean system variable mouseIsPressed is true if the mouse is pressed
66022           * and false if not.
66023           *
66024           * @property {Boolean} mouseIsPressed
66025           * @readOnly
66026           *
66027           * @example
66028           * <div>
66029           * <code>
66030           * function draw() {
66031           *   background(237, 34, 93);
66032           *   fill(0);
66033           *
66034           *   if (mouseIsPressed) {
66035           *     ellipse(50, 50, 50, 50);
66036           *   } else {
66037           *     rect(25, 25, 50, 50);
66038           *   }
66039           *
66040           *   print(mouseIsPressed);
66041           * }
66042           * </code>
66043           * </div>
66044           *
66045           * @alt
66046           * black 50x50 rect becomes ellipse with mouse click/press. fuchsia background.
66047           */
66048          _main.default.prototype.mouseIsPressed = false;
66049
66050          _main.default.prototype._updateNextMouseCoords = function(e) {
66051            if (this._curElement !== null && (!e.touches || e.touches.length > 0)) {
66052              var mousePos = getMousePos(this._curElement.elt, this.width, this.height, e);
66053
66054              this._setProperty('movedX', e.movementX);
66055              this._setProperty('movedY', e.movementY);
66056              this._setProperty('mouseX', mousePos.x);
66057              this._setProperty('mouseY', mousePos.y);
66058              this._setProperty('winMouseX', mousePos.winX);
66059              this._setProperty('winMouseY', mousePos.winY);
66060            }
66061            if (!this._hasMouseInteracted) {
66062              // For first draw, make previous and next equal
66063              this._updateMouseCoords();
66064              this._setProperty('_hasMouseInteracted', true);
66065            }
66066          };
66067
66068          _main.default.prototype._updateMouseCoords = function() {
66069            this._setProperty('pmouseX', this.mouseX);
66070            this._setProperty('pmouseY', this.mouseY);
66071            this._setProperty('pwinMouseX', this.winMouseX);
66072            this._setProperty('pwinMouseY', this.winMouseY);
66073
66074            this._setProperty('_pmouseWheelDeltaY', this._mouseWheelDeltaY);
66075          };
66076
66077          function getMousePos(canvas, w, h, evt) {
66078            if (evt && !evt.clientX) {
66079              // use touches if touch and not mouse
66080              if (evt.touches) {
66081                evt = evt.touches[0];
66082              } else if (evt.changedTouches) {
66083                evt = evt.changedTouches[0];
66084              }
66085            }
66086            var rect = canvas.getBoundingClientRect();
66087            var sx = canvas.scrollWidth / w || 1;
66088            var sy = canvas.scrollHeight / h || 1;
66089            return {
66090              x: (evt.clientX - rect.left) / sx,
66091              y: (evt.clientY - rect.top) / sy,
66092              winX: evt.clientX,
66093              winY: evt.clientY,
66094              id: evt.identifier
66095            };
66096          }
66097
66098          _main.default.prototype._setMouseButton = function(e) {
66099            if (e.button === 1) {
66100              this._setProperty('mouseButton', constants.CENTER);
66101            } else if (e.button === 2) {
66102              this._setProperty('mouseButton', constants.RIGHT);
66103            } else {
66104              this._setProperty('mouseButton', constants.LEFT);
66105            }
66106          };
66107
66108          /**
66109           * The <a href="#/p5/mouseMoved">mouseMoved()</a> function is called every time the mouse moves and a mouse
66110           * button is not pressed.<br><br>
66111           * Browsers may have different default
66112           * behaviors attached to various mouse events. To prevent any default
66113           * behavior for this event, add "return false" to the end of the method.
66114           *
66115           * @method mouseMoved
66116           * @param  {Object} [event] optional MouseEvent callback argument.
66117           * @example
66118           * <div>
66119           * <code>
66120           * // Move the mouse across the page
66121           * // to change its value
66122           *
66123           * let value = 0;
66124           * function draw() {
66125           *   fill(value);
66126           *   rect(25, 25, 50, 50);
66127           * }
66128           * function mouseMoved() {
66129           *   value = value + 5;
66130           *   if (value > 255) {
66131           *     value = 0;
66132           *   }
66133           * }
66134           * </code>
66135           * </div>
66136           *
66137           * <div class="norender">
66138           * <code>
66139           * function mouseMoved() {
66140           *   ellipse(mouseX, mouseY, 5, 5);
66141           *   // prevent default
66142           *   return false;
66143           * }
66144           * </code>
66145           * </div>
66146           *
66147           * <div class="norender">
66148           * <code>
66149           * // returns a MouseEvent object
66150           * // as a callback argument
66151           * function mouseMoved(event) {
66152           *   console.log(event);
66153           * }
66154           * </code>
66155           * </div>
66156           *
66157           * @alt
66158           * black 50x50 rect becomes lighter with mouse movements until white then resets
66159           * no image displayed
66160           */
66161
66162          /**
66163           * The <a href="#/p5/mouseDragged">mouseDragged()</a> function is called once every time the mouse moves and
66164           * a mouse button is pressed. If no <a href="#/p5/mouseDragged">mouseDragged()</a> function is defined, the
66165           * <a href="#/p5/touchMoved">touchMoved()</a> function will be called instead if it is defined.<br><br>
66166           * Browsers may have different default
66167           * behaviors attached to various mouse events. To prevent any default
66168           * behavior for this event, add "return false" to the end of the method.
66169           *
66170           * @method mouseDragged
66171           * @param  {Object} [event] optional MouseEvent callback argument.
66172           * @example
66173           * <div>
66174           * <code>
66175           * // Drag the mouse across the page
66176           * // to change its value
66177           *
66178           * let value = 0;
66179           * function draw() {
66180           *   fill(value);
66181           *   rect(25, 25, 50, 50);
66182           * }
66183           * function mouseDragged() {
66184           *   value = value + 5;
66185           *   if (value > 255) {
66186           *     value = 0;
66187           *   }
66188           * }
66189           * </code>
66190           * </div>
66191           *
66192           * <div class="norender">
66193           * <code>
66194           * function mouseDragged() {
66195           *   ellipse(mouseX, mouseY, 5, 5);
66196           *   // prevent default
66197           *   return false;
66198           * }
66199           * </code>
66200           * </div>
66201           *
66202           * <div class="norender">
66203           * <code>
66204           * // returns a MouseEvent object
66205           * // as a callback argument
66206           * function mouseDragged(event) {
66207           *   console.log(event);
66208           * }
66209           * </code>
66210           * </div>
66211           *
66212           * @alt
66213           * black 50x50 rect turns lighter with mouse click and drag until white, resets
66214           * no image displayed
66215           */
66216          _main.default.prototype._onmousemove = function(e) {
66217            var context = this._isGlobal ? window : this;
66218            var executeDefault;
66219            this._updateNextMouseCoords(e);
66220            if (!this.mouseIsPressed) {
66221              if (typeof context.mouseMoved === 'function') {
66222                executeDefault = context.mouseMoved(e);
66223                if (executeDefault === false) {
66224                  e.preventDefault();
66225                }
66226              }
66227            } else {
66228              if (typeof context.mouseDragged === 'function') {
66229                executeDefault = context.mouseDragged(e);
66230                if (executeDefault === false) {
66231                  e.preventDefault();
66232                }
66233              } else if (typeof context.touchMoved === 'function') {
66234                executeDefault = context.touchMoved(e);
66235                if (executeDefault === false) {
66236                  e.preventDefault();
66237                }
66238              }
66239            }
66240          };
66241
66242          /**
66243           * The <a href="#/p5/mousePressed">mousePressed()</a> function is called once after every time a mouse button
66244           * is pressed. The mouseButton variable (see the related reference entry)
66245           * can be used to determine which button has been pressed. If no
66246           * <a href="#/p5/mousePressed">mousePressed()</a> function is defined, the <a href="#/p5/touchStarted">touchStarted()</a> function will be
66247           * called instead if it is defined.<br><br>
66248           * Browsers may have different default
66249           * behaviors attached to various mouse events. To prevent any default
66250           * behavior for this event, add "return false" to the end of the method.
66251           *
66252           * @method mousePressed
66253           * @param  {Object} [event] optional MouseEvent callback argument.
66254           * @example
66255           * <div>
66256           * <code>
66257           * // Click within the image to change
66258           * // the value of the rectangle
66259           *
66260           * let value = 0;
66261           * function draw() {
66262           *   fill(value);
66263           *   rect(25, 25, 50, 50);
66264           * }
66265           * function mousePressed() {
66266           *   if (value === 0) {
66267           *     value = 255;
66268           *   } else {
66269           *     value = 0;
66270           *   }
66271           * }
66272           * </code>
66273           * </div>
66274           *
66275           * <div class="norender">
66276           * <code>
66277           * function mousePressed() {
66278           *   ellipse(mouseX, mouseY, 5, 5);
66279           *   // prevent default
66280           *   return false;
66281           * }
66282           * </code>
66283           * </div>
66284           *
66285           * <div class="norender">
66286           * <code>
66287           * // returns a MouseEvent object
66288           * // as a callback argument
66289           * function mousePressed(event) {
66290           *   console.log(event);
66291           * }
66292           * </code>
66293           * </div>
66294           *
66295           * @alt
66296           * black 50x50 rect turns white with mouse click/press.
66297           * no image displayed
66298           */
66299          _main.default.prototype._onmousedown = function(e) {
66300            var context = this._isGlobal ? window : this;
66301            var executeDefault;
66302            this._setProperty('mouseIsPressed', true);
66303            this._setMouseButton(e);
66304            this._updateNextMouseCoords(e);
66305
66306            if (typeof context.mousePressed === 'function') {
66307              executeDefault = context.mousePressed(e);
66308              if (executeDefault === false) {
66309                e.preventDefault();
66310              }
66311              // only safari needs this manual fallback for consistency
66312            } else if (
66313              navigator.userAgent.toLowerCase().includes('safari') &&
66314              typeof context.touchStarted === 'function'
66315            ) {
66316              executeDefault = context.touchStarted(e);
66317              if (executeDefault === false) {
66318                e.preventDefault();
66319              }
66320            }
66321          };
66322
66323          /**
66324           * The <a href="#/p5/mouseReleased">mouseReleased()</a> function is called every time a mouse button is
66325           * released. If no <a href="#/p5/mouseReleased">mouseReleased()</a> function is defined, the <a href="#/p5/touchEnded">touchEnded()</a>
66326           * function will be called instead if it is defined.<br><br>
66327           * Browsers may have different default
66328           * behaviors attached to various mouse events. To prevent any default
66329           * behavior for this event, add "return false" to the end of the method.
66330           *
66331           * @method mouseReleased
66332           * @param  {Object} [event] optional MouseEvent callback argument.
66333           * @example
66334           * <div>
66335           * <code>
66336           * // Click within the image to change
66337           * // the value of the rectangle
66338           * // after the mouse has been clicked
66339           *
66340           * let value = 0;
66341           * function draw() {
66342           *   fill(value);
66343           *   rect(25, 25, 50, 50);
66344           * }
66345           * function mouseReleased() {
66346           *   if (value === 0) {
66347           *     value = 255;
66348           *   } else {
66349           *     value = 0;
66350           *   }
66351           * }
66352           * </code>
66353           * </div>
66354           *
66355           * <div class="norender">
66356           * <code>
66357           * function mouseReleased() {
66358           *   ellipse(mouseX, mouseY, 5, 5);
66359           *   // prevent default
66360           *   return false;
66361           * }
66362           * </code>
66363           * </div>
66364           *
66365           * <div class="norender">
66366           * <code>
66367           * // returns a MouseEvent object
66368           * // as a callback argument
66369           * function mouseReleased(event) {
66370           *   console.log(event);
66371           * }
66372           * </code>
66373           * </div>
66374           *
66375           * @alt
66376           * black 50x50 rect turns white with mouse click/press.
66377           * no image displayed
66378           */
66379          _main.default.prototype._onmouseup = function(e) {
66380            var context = this._isGlobal ? window : this;
66381            var executeDefault;
66382            this._setProperty('mouseIsPressed', false);
66383            if (typeof context.mouseReleased === 'function') {
66384              executeDefault = context.mouseReleased(e);
66385              if (executeDefault === false) {
66386                e.preventDefault();
66387              }
66388            } else if (typeof context.touchEnded === 'function') {
66389              executeDefault = context.touchEnded(e);
66390              if (executeDefault === false) {
66391                e.preventDefault();
66392              }
66393            }
66394          };
66395
66396          _main.default.prototype._ondragend = _main.default.prototype._onmouseup;
66397          _main.default.prototype._ondragover = _main.default.prototype._onmousemove;
66398
66399          /**
66400           * The <a href="#/p5/mouseClicked">mouseClicked()</a> function is called once after a mouse button has been
66401           * pressed and then released.<br><br>
66402           * Browsers handle clicks differently, so this function is only guaranteed to be
66403           * run when the left mouse button is clicked. To handle other mou
66403se buttons
66404           * being pressed or released, see <a href="#/p5/mousePressed">mousePressed()</a> or <a href="#/p5/mouseReleased">mouseReleased()</a>.<br><br>
66405           * Browsers may have different default
66406           * behaviors attached to various mouse events. To prevent any default
66407           * behavior for this event, add "return false" to the end of the method.
66408           *
66409           * @method mouseClicked
66410           * @param  {Object} [event] optional MouseEvent callback argument.
66411           * @example
66412           * <div>
66413           * <code>
66414           * // Click within the image to change
66415           * // the value of the rectangle
66416           * // after the mouse has been clicked
66417           *
66418           * let value = 0;
66419           * function draw() {
66420           *   fill(value);
66421           *   rect(25, 25, 50, 50);
66422           * }
66423           *
66424           * function mouseClicked() {
66425           *   if (value === 0) {
66426           *     value = 255;
66427           *   } else {
66428           *     value = 0;
66429           *   }
66430           * }
66431           * </code>
66432           * </div>
66433           *
66434           * <div class="norender">
66435           * <code>
66436           * function mouseClicked() {
66437           *   ellipse(mouseX, mouseY, 5, 5);
66438           *   // prevent default
66439           *   return false;
66440           * }
66441           * </code>
66442           * </div>
66443           *
66444           * <div class="norender">
66445           * <code>
66446           * // returns a MouseEvent object
66447           * // as a callback argument
66448           * function mouseClicked(event) {
66449           *   console.log(event);
66450           * }
66451           * </code>
66452           * </div>
66453           *
66454           * @alt
66455           * black 50x50 rect turns white with mouse click/press.
66456           * no image displayed
66457           */
66458          _main.default.prototype._onclick = function(e) {
66459            var context = this._isGlobal ? window : this;
66460            if (typeof context.mouseClicked === 'function') {
66461              var executeDefault = context.mouseClicked(e);
66462              if (executeDefault === false) {
66463                e.preventDefault();
66464              }
66465            }
66466          };
66467
66468          /**
66469           * The <a href="#/p5/doubleClicked">doubleClicked()</a> function is executed every time a event
66470           * listener has detected a dblclick event which is a part of the
66471           * DOM L3 specification. The doubleClicked event is fired when a
66472           * pointing device button (usually a mouse's primary button)
66473           * is clicked twice on a single element. For more info on the
66474           * dblclick event refer to mozilla's documentation here:
66475           * https://developer.mozilla.org/en-US/docs/Web/Events/dblclick
66476           *
66477           * @method doubleClicked
66478           * @param  {Object} [event] optional MouseEvent callback argument.
66479           * @example
66480           * <div>
66481           * <code>
66482           * // Click within the image to change
66483           * // the value of the rectangle
66484           * // after the mouse has been double clicked
66485           *
66486           * let value = 0;
66487           * function draw() {
66488           *   fill(value);
66489           *   rect(25, 25, 50, 50);
66490           * }
66491           *
66492           * function doubleClicked() {
66493           *   if (value === 0) {
66494           *     value = 255;
66495           *   } else {
66496           *     value = 0;
66497           *   }
66498           * }
66499           * </code>
66500           * </div>
66501           *
66502           * <div class="norender">
66503           * <code>
66504           * function doubleClicked() {
66505           *   ellipse(mouseX, mouseY, 5, 5);
66506           *   // prevent default
66507           *   return false;
66508           * }
66509           * </code>
66510           * </div>
66511           *
66512           * <div class="norender">
66513           * <code>
66514           * // returns a MouseEvent object
66515           * // as a callback argument
66516           * function doubleClicked(event) {
66517           *   console.log(event);
66518           * }
66519           * </code>
66520           * </div>
66521           *
66522           * @alt
66523           * black 50x50 rect turns white with mouse doubleClick/press.
66524           * no image displayed
66525           */
66526
66527          _main.default.prototype._ondblclick = function(e) {
66528            var context = this._isGlobal ? window : this;
66529            if (typeof context.doubleClicked === 'function') {
66530              var executeDefault = context.doubleClicked(e);
66531              if (executeDefault === false) {
66532                e.preventDefault();
66533              }
66534            }
66535          };
66536
66537          /**
66538           * For use with WebGL orbitControl.
66539           * @property {Number} _mouseWheelDeltaY
66540           * @readOnly
66541           * @private
66542           */
66543          _main.default.prototype._mouseWheelDeltaY = 0;
66544
66545          /**
66546           * For use with WebGL orbitControl.
66547           * @property {Number} _pmouseWheelDeltaY
66548           * @readOnly
66549           * @private
66550           */
66551          _main.default.prototype._pmouseWheelDeltaY = 0;
66552
66553          /**
66554           * The function <a href="#/p5/mouseWheel">mouseWheel()</a> is executed every time a vertical mouse wheel
66555           * event is detected either triggered by an actual mouse wheel or by a
66556           * touchpad.<br><br>
66557           * The event.delta property returns the amount the mouse wheel
66558           * have scrolled. The values can be positive or negative depending on the
66559           * scroll direction (on OS X with "natural" scrolling enabled, the signs
66560           * are inverted).<br><br>
66561           * Browsers may have different default behaviors attached to various
66562           * mouse events. To prevent any default behavior for this event, add
66563           * "return false" to the end of the method.<br><br>
66564           * Due to the current support of the "wheel" event on Safari, the function
66565           * may only work as expected if "return false" is included while using Safari.
66566           *
66567           * @method mouseWheel
66568           * @param  {Object} [event] optional WheelEvent callback argument.
66569           *
66570           * @example
66571           * <div>
66572           * <code>
66573           * let pos = 25;
66574           *
66575           * function draw() {
66576           *   background(237, 34, 93);
66577           *   fill(0);
66578           *   rect(25, pos, 50, 50);
66579           * }
66580           *
66581           * function mouseWheel(event) {
66582           *   print(event.delta);
66583           *   //move the square according to the vertical scroll amount
66584           *   pos += event.delta;
66585           *   //uncomment to block page scrolling
66586           *   //return false;
66587           * }
66588           * </code>
66589           * </div>
66590           *
66591           * @alt
66592           * black 50x50 rect moves up and down with vertical scroll. fuchsia background
66593           */
66594          _main.default.prototype._onwheel = function(e) {
66595            var context = this._isGlobal ? window : this;
66596            this._setProperty('_mouseWheelDeltaY', e.deltaY);
66597            if (typeof context.mouseWheel === 'function') {
66598              e.delta = e.deltaY;
66599              var executeDefault = context.mouseWheel(e);
66600              if (executeDefault === false) {
66601                e.preventDefault();
66602              }
66603            }
66604          };
66605
66606          /**
66607           * The function <a href="#/p5/requestPointerLock">requestPointerLock()</a>
66608           * locks the pointer to its current position and makes it invisible.
66609           * Use <a href="#/p5/movedX">movedX</a> and <a href="#/p5/movedY">movedY</a> to get the difference the mouse was moved since
66610           * the last call of draw.
66611           * Note that not all browsers support this feature.
66612           * This enables you to create experiences that aren't limited by the mouse moving out of the screen
66613           * even if it is repeatedly moved into one direction.
66614           * For example, a first person perspective experience.
66615           *
66616           * @method requestPointerLock
66617           * @example
66618           * <div class="notest">
66619           * <code>
66620           * let cam;
66621           * function setup() {
66622           *   createCanvas(100, 100, WEBGL);
66623           *   requestPointerLock();
66624           *   cam = createCamera();
66625           * }
66626           *
66627           * function draw() {
66628           *   background(255);
66629           *   cam.pan(-movedX * 0.001);
66630           *   cam.tilt(movedY * 0.001);
66631           *   sphere(25);
66632           * }
66633           * </code>
66634           * </div>
66635           *
66636           * @alt
66637           * 3D scene moves according to mouse mouse movement in a first person perspective
66638           */
66639          _main.default.prototype.requestPointerLock = function() {
66640            // pointer lock object forking for cross browser
66641            var canvas = this._curElement.elt;
66642            canvas.requestPointerLock =
66643              canvas.requestPointerLock || canvas.mozRequestPointerLock;
66644            if (!canvas.requestPointerLock) {
66645              console.log('requestPointerLock is not implemented in this browser');
66646              return false;
66647            }
66648            canvas.requestPointerLock();
66649            return true;
66650          };
66651
66652          /**
66653           * The function <a href="#/p5/exitPointerLock">exitPointerLock()</a>
66654           * exits a previously triggered <a href="#/p5/requestPointerLock">pointer Lock</a>
66655           * for example to make ui elements usable etc
66656           *
66657           * @method exitPointerLock
66658           * @example
66659           * <div class="notest">
66660           * <code>
66661           * //click the canvas to lock the pointer
66662           * //click again to exit (otherwise escape)
66663           * let locked = false;
66664           * function draw() {
66665           *   background(237, 34, 93);
66666           * }
66667           * function mouseClicked() {
66668           *   if (!locked) {
66669           *     locked = true;
66670           *     requestPointerLock();
66671           *   } else {
66672           *     exitPointerLock();
66673           *     locked = false;
66674           *   }
66675           * }
66676           * </code>
66677           * </div>
66678           *
66679           * @alt
66680           * cursor gets locked / unlocked on mouse-click
66681           */
66682          _main.default.prototype.exitPointerLock = function() {
66683            document.exitPointerLock();
66684          };
66685          var _default = _main.default;
66686          exports.default = _default;
66687        },
66688        { '../core/constants': 48, '../core/main': 59 }
66689      ],
66690      79: [
66691        function(_dereq_, module, exports) {
66692          'use strict';
66693          Object.defineProperty(exports, '__esModule', { value: true });
66694          exports.default = void 0;
66695
66696          var _main = _interopRequireDefault(_dereq_('../core/main'));
66697          function _interopRequireDefault(obj) {
66698            return obj && obj.__esModule ? obj : { default: obj };
66699          }
66700          /**
66701           * @module Events
66702           * @submodule Touch
66703           * @for p5
66704           * @requires core
66705           */ /**
66706           * The system variable touches[] contains an array of the positions of all
66707           * current touch points, relative to (0, 0) of the canvas, and IDs identifying a
66708           * unique touch as it moves. Each element in the array is an object with x, y,
66709           * and id properties.
66710           *
66711           * The touches[] array is not supported on Safari and IE on touch-based
66712           * desktops (laptops).
66713           *
66714           * @property {Object[]} touches
66715           * @readOnly
66716           *
66717           * @example
66718           * <div>
66719           * <code>
66720           * // On a touchscreen device, touch
66721           * // the canvas using one or more fingers
66722           * // at the same time
66723           * function draw() {
66724           *   clear();
66725           *   let display = touches.length + ' touches';
66726           *   text(display, 5, 10);
66727           * }
66728           * </code>
66729           * </div>
66730           *
66731           * @alt
66732           * Number of touches currently registered are displayed on the canvas
66733           */ _main.default.prototype.touches = [];
66734          _main.default.prototype._updateTouchCoords = function(e) {
66735            if (this._curElement !== null) {
66736              var touches = [];
66737              for (var i = 0; i < e.touches.length; i++) {
66738                touches[i] = getTouchInfo(
66739                  this._curElement.elt,
66740                  this.width,
66741                  this.height,
66742                  e,
66743                  i
66744                );
66745              }
66746              this._setProperty('touches', touches);
66747            }
66748          };
66749
66750          function getTouchInfo(canvas, w, h, e) {
66751            var i = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
66752            var rect = canvas.getBoundingClientRect();
66753            var sx = canvas.scrollWidth / w || 1;
66754            var sy = canvas.scrollHeight / h || 1;
66755            var touch = e.touches[i] || e.changedTouches[i];
66756            return {
66757              x: (touch.clientX - rect.left) / sx,
66758              y: (touch.clientY - rect.top) / sy,
66759              winX: touch.clientX,
66760              winY: touch.clientY,
66761              id: touch.identifier
66762            };
66763          }
66764
66765          /**
66766           * The touchStarted() function is called once after every time a touch is
66767           * registered. If no <a href="#/p5/touchStarted">touchStarted()</a> function is defined, the <a href="#/p5/mousePressed">mousePressed()</a>
66768           * function will be called instead if it is defined.<br><br>
66769           * Browsers may have different default behaviors attached to various touch
66770           * events. To prevent any default behavior for this event, add "return false"
66771           * to the end of the method.
66772           *
66773           * @method touchStarted
66774           * @param  {Object} [event] optional TouchEvent callback argument.
66775           * @example
66776           * <div>
66777           * <code>
66778           * // Touch within the image to change
66779           * // the value of the rectangle
66780           *
66781           * let value = 0;
66782           * function draw() {
66783           *   fill(value);
66784           *   rect(25, 25, 50, 50);
66785           * }
66786           * function touchStarted() {
66787           *   if (value === 0) {
66788           *     value = 255;
66789           *   } else {
66790           *     value = 0;
66791           *   }
66792           * }
66793           * </code>
66794           * </div>
66795           *
66796           * <div class="norender">
66797           * <code>
66798           * function touchStarted() {
66799           *   ellipse(mouseX, mouseY, 5, 5);
66800           *   // prevent default
66801           *   return false;
66802           * }
66803           * </code>
66804           * </div>
66805           *
66806           * <div class="norender">
66807           * <code>
66808           * // returns a TouchEvent object
66809           * // as a callback argument
66810           * function touchStarted(event) {
66811           *   console.log(event);
66812           * }
66813           * </code>
66814           * </div>
66815           *
66816           * @alt
66817           * 50x50 black rect turns white with touch event.
66818           * no image displayed
66819           */
66820          _main.default.prototype._ontouchstart = function(e) {
66821            var context = this._isGlobal ? window : this;
66822            var executeDefault;
66823            this._setProperty('mouseIsPressed', true);
66824            this._updateTouchCoords(e);
66825            this._updateNextMouseCoords(e);
66826            this._updateMouseCoords(); // reset pmouseXY at the start of each touch event
66827
66828            if (typeof context.touchStarted === 'function') {
66829              executeDefault = context.touchStarted(e);
66830              if (executeDefault === false) {
66831                e.preventDefault();
66832              }
66833              // only safari needs this manual fallback for consistency
66834            } else if (
66835              navigator.userAgent.toLowerCase().includes('safari') &&
66836              typeof context.mousePressed === 'function'
66837            ) {
66838              executeDefault = context.mousePressed(e);
66839              if (executeDefault === false) {
66840                e.preventDefault();
66841              }
66842            }
66843          };
66844
66845          /**
66846           * The <a href="#/p5/touchMoved">touchMoved()</a> function is called every time a touch move is registered.
66847           * If no <a href="#/p5/touchMoved">touchMoved()</a> function is defined, the <a href="#/p5/mouseDragged">mouseDragged()</a> function will
66848           * be called instead if it is defined.<br><br>
66849           * Browsers may have different default behaviors attached to various touch
66850           * events. To prevent any default behavior for this event, add "return false"
66851           * to the end of the method.
66852           *
66853           * @method touchMoved
66854           * @param  {Object} [event] optional TouchEvent callback argument.
66855           * @example
66856           * <div>
66857           * <code>
66858           * // Move your finger across the page
66859           * // to change its value
66860           *
66861           * let value = 0;
66862           * function draw() {
66863           *   fill(value);
66864           *   rect(25, 25, 50, 50);
66865           * }
66866           * function touchMoved() {
66867           *   value = value + 5;
66868           *   if (value > 255) {
66869           *     value = 0;
66870           *   }
66871           * }
66872           * </code>
66873           * </div>
66874           *
66875           * <div class="norender">
66876           * <code>
66877           * function touchMoved() {
66878           *   ellipse(mouseX, mouseY, 5, 5);
66879           *   // prevent default
66880           *   return false;
66881           * }
66882           * </code>
66883           * </div>
66884           *
66885           * <div class="norender">
66886           * <code>
66887           * // returns a TouchEvent object
66888           * // as a callback argument
66889           * function touchMoved(event) {
66890           *   console.log(event);
66891           * }
66892           * </code>
66893           * </div>
66894           *
66895           * @alt
66896           * 50x50 black rect turns lighter with touch until white. resets
66897           * no image displayed
66898           */
66899          _main.default.prototype._ontouchmove = function(e) {
66900            var context = this._isGlobal ? window : this;
66901            var executeDefault;
66902            this._updateTouchCoords(e);
66903            this._updateNextMouseCoords(e);
66904            if (typeof context.touchMoved === 'function') {
66905              executeDefault = context.touchMoved(e);
66906              if (executeDefault === false) {
66907                e.preventDefault();
66908              }
66909            } else if (typeof context.mouseDragged === 'function') {
66910              executeDefault = context.mouseDragged(e);
66911              if (executeDefault === false) {
66912                e.preventDefault();
66913              }
66914            }
66915          };
66916
66917          /**
66918           * The <a href="#/p5/touchEnded">touchEnded()</a> function is called every time a touch ends. If no
66919           * <a href="#/p5/touchEnded">touchEnded()</a> function is defined, the <a href="#/p5/mouseReleased">mouseReleased()</a> function will be
66920           * called instead if it is defined.<br><br>
66921           * Browsers may have different default behaviors attached to various touch
66922           * events. To prevent any default behavior for this event, add "return false"
66923           * to the end of the method.
66924           *
66925           * @method touchEnded
66926           * @param  {Object} [event] optional TouchEvent callback argument.
66927           * @example
66928           * <div>
66929           * <code>
66930           * // Release touch within the image to
66931           * // change the value of the rectangle
66932           *
66933           * let value = 0;
66934           * function draw() {
66935           *   fill(value);
66936           *   rect(25, 25, 50, 50);
66937           * }
66938           * function touchEnded() {
66939           *   if (value === 0) {
66940           *     value = 255;
66941           *   } else {
66942           *     value = 0;
66943           *   }
66944           * }
66945           * </code>
66946           * </div>
66947           *
66948           * <div class="norender">
66949           * <code>
66950           * function touchEnded() {
66951           *   ellipse(mouseX, mouseY, 5, 5);
66952           *   // prevent default
66953           *   return false;
66954           * }
66955           * </code>
66956           * </div>
66957           *
66958           * <div class="norender">
66959           * <code>
66960           * // returns a TouchEvent object
66961           * // as a callback argument
66962           * function touchEnded(event) {
66963           *   console.log(event);
66964           * }
66965           * </code>
66966           * </div>
66967           *
66968           * @alt
66969           * 50x50 black rect turns white with touch.
66970           * no image displayed
66971           */
66972          _main.default.prototype._ontouchend = function(e) {
66973            this._setProperty('mouseIsPressed', false);
66974            this._updateTouchCoords(e);
66975            this._updateNextMouseCoords(e);
66976            var context = this._isGlobal ? window : this;
66977            var executeDefault;
66978            if (typeof context.touchEnded === 'function') {
66979              executeDefault = context.touchEnded(e);
66980              if (executeDefault === false) {
66981                e.preventDefault();
66982              }
66983            } else if (typeof context.mouseReleased === 'function') {
66984              executeDefault = context.mouseReleased(e);
66985              if (executeDefault === false) {
66986                e.preventDefault();
66987              }
66988            }
66989          };
66990          var _default = _main.default;
66991          exports.default = _default;
66992        },
66993        { '../core/main': 59 }
66994      ],
66995      80: [
66996        function(_dereq_, module, exports) {
66997          'use strict';
66998          Object.defineProperty(exports, '__esModule', { value: true });
66999          exports.default = void 0; /*global ImageData:false */
67000
67001          /**
67002           * This module defines the filters for use with image buffers.
67003           *
67004           * This module is basically a collection of functions stored in an object
67005           * as opposed to modules. The functions are destructive, modifying
67006           * the passed in canvas rather than creating a copy.
67007           *
67008           * Generally speaking users of this module will use the Filters.apply method
67009           * on a canvas to create an effect.
67010           *
67011           * A number of functions are borrowed/adapted from
67012           * http://www.html5rocks.com/en/tutorials/canvas/imagefilters/
67013           * or the java processing implementation.
67014           */
67015
67016          var Filters = {};
67017
67018          /*
67019                   * Helper functions
67020                   */
67021
67022          /**
67023           * Returns the pixel buffer for a canvas
67024           *
67025           * @private
67026           *
67027           * @param  {Canvas|ImageData} canvas the canvas to get pixels from
67028           * @return {Uint8ClampedArray}       a one-dimensional array containing
67029           *                                   the data in thc RGBA order, with integer
67030           *                                   values between 0 and 255
67031           */
67032          Filters._toPixels = function(canvas) {
67033            if (canvas instanceof ImageData) {
67034              return canvas.data;
67035            } else {
67036              return canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height)
67037                .data;
67038            }
67039          };
67040
67041          /**
67042           * Returns a 32 bit number containing ARGB data at ith pixel in the
67043           * 1D array containing pixels data.
67044           *
67045           * @private
67046           *
67047           * @param  {Uint8ClampedArray} data array returned by _toPixels()
67048           * @param  {Integer}           i    index of a 1D Image Array
67049           * @return {Integer}                32 bit integer value representing
67050           *                                  ARGB value.
67051           */
67052          Filters._getARGB = function(data, i) {
67053            var offset = i * 4;
67054            return (
67055              ((data[offset + 3] << 24) & 0xff000000) |
67056              ((data[offset] << 16) & 0x00ff0000) |
67057              ((data[offset + 1] << 8) & 0x0000ff00) |
67058              (data[offset + 2] & 0x000000ff)
67059            );
67060          };
67061
67062          /**
67063           * Modifies pixels RGBA values to values contained in the data object.
67064           *
67065           * @private
67066           *
67067           * @param {Uint8ClampedArray} pixels array returned by _toPixels()
67068           * @param {Int32Array}        data   source 1D array where each value
67069           *                                   represents ARGB values
67070           */
67071          Filters._setPixels = function(pixels, data) {
67072            var offset = 0;
67073            for (var i = 0, al = pixels.length; i < al; i++) {
67074              offset = i * 4;
67075              pixels[offset + 0] = (data[i] & 0x00ff0000) >>> 16;
67076              pixels[offset + 1] = (data[i] & 0x0000ff00) >>> 8;
67077              pixels[offset + 2] = data[i] & 0x000000ff;
67078              pixels[offset + 3] = (data[i] & 0xff000000) >>> 24;
67079            }
67080          };
67081
67082          /**
67083           * Returns the ImageData object for a canvas
67084           * https://developer.mozilla.org/en-US/docs/Web/API/ImageData
67085           *
67086           * @private
67087           *
67088           * @param  {Canvas|ImageData} canvas canvas to get image data from
67089           * @return {ImageData}               Holder of pixel data (and width and
67090           *                                   height) for a canvas
67091           */
67092          Filters._toImageData = function(canvas) {
67093            if (canvas instanceof ImageData) {
67094              return canvas;
67095            } else {
67096              return canvas
67097                .getContext('2d')
67098                .getImageData(0, 0, canvas.width, canvas.height);
67099            }
67100          };
67101
67102          /**
67103           * Returns a blank ImageData object.
67104           *
67105           * @private
67106           *
67107           * @param  {Integer} width
67108           * @param  {Integer} height
67109           * @return {ImageData}
67110           */
67111          Filters._createImageData = function(width, height) {
67112            Filters._tmpCanvas = document.createElement('canvas');
67113            Filters._tmpCtx = Filters._tmpCanvas.getContext('2d');
67114            return this._tmpCtx.createImageData(width, height);
67115          };
67116
67117          /**
67118           * Applys a filter function to a canvas.
67119           *
67120           * The difference between this and the actual filter functions defined below
67121           * is that the filter functions generally modify the pixel buffer but do
67122           * not actually put that data back to the canvas (where it would actually
67123           * update what is visible). By contrast this method does make the changes
67124           * actually visible in the canvas.
67125           *
67126           * The apply method is the method that callers of this module would generally
67127           * use. It has been separated from the actual filters to support an advanced
67128           * use case of creating a filter chain that executes without actually updating
67129           * the canvas in between everystep.
67130           *
67131           * @private
67132           * @param  {HTMLCanvasElement} canvas [description]
67133           * @param  {function(ImageData,Object)} func   [description]
67134           * @param  {Object} filterParam  [description]
67135           */
67136          Filters.apply = function(canvas, func, filterParam) {
67137            var pixelsState = canvas.getContext('2d');
67138            var imageData = pixelsState.getImageData(0, 0, canvas.width, canvas.height);
67139
67140            //Filters can either return a new ImageData object, or just modify
67141            //the one they received.
67142            var newImageData = func(imageData, filterParam);
67143            if (newImageData instanceof ImageData) {
67144              pixelsState.putImageData(
67145                newImageData,
67146                0,
67147                0,
67148                0,
67149                0,
67150                canvas.width,
67151                canvas.height
67152              );
67153            } else {
67154              pixelsState.putImageData(imageData, 0, 0, 0, 0, canvas.width, canvas.height);
67155            }
67156          };
67157
67158          /*
67159    * Filters
67160    */
67161
67162          /**
67163           * Converts the image to black and white pixels depending if they are above or
67164           * below the threshold defined by the level parameter. The parameter must be
67165           * between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.
67166           *
67167           * Borrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/
67168           *
67169           * @private
67170           * @param  {Canvas} canvas
67171           * @param  {Float} level
67172           */
67173          Filters.threshold = function(canvas, level) {
67174            var pixels = Filters._toPixels(canvas);
67175
67176            if (level === undefined) {
67177              level = 0.5;
67178            }
67179            var thresh = Math.floor(level * 255);
67180
67181            for (var i = 0; i < pixels.length; i += 4) {
67182              var r = pixels[i];
67183              var g = pixels[i + 1];
67184              var b = pixels[i + 2];
67185              var gray = 0.2126 * r + 0.7152 * g + 0.0722 * b;
67186              var val = void 0;
67187              if (gray >= thresh) {
67188                val = 255;
67189              } else {
67190                val = 0;
67191              }
67192              pixels[i] = pixels[i + 1] = pixels[i + 2] = val;
67193            }
67194          };
67195
67196          /**
67197           * Converts any colors in the image to grayscale equivalents.
67198           * No parameter is used.
67199           *
67200           * Borrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/
67201           *
67202           * @private
67203           * @param {Canvas} canvas
67204           */
67205          Filters.gray = function(canvas) {
67206            var pixels = Filters._toPixels(canvas);
67207
67208            for (var i = 0; i < pixels.length; i += 4) {
67209              var r = pixels[i];
67210              var g = pixels[i + 1];
67211              var b = pixels[i + 2];
67212
67213              // CIE luminance for RGB
67214              var gray = 0.2126 * r + 0.7152 * g + 0.0722 * b;
67215              pixels[i] = pixels[i + 1] = pixels[i + 2] = gray;
67216            }
67217          };
67218
67219          /**
67220           * Sets the alpha channel to entirely opaque. No parameter is used.
67221           *
67222           * @private
67223           * @param {Canvas} canvas
67224           */
67225          Filters.opaque = function(canvas) {
67226            var pixels = Filters._toPixels(canvas);
67227
67228            for (var i = 0; i < pixels.length; i += 4) {
67229              pixels[i + 3] = 255;
67230            }
67231
67232            return pixels;
67233          };
67234
67235          /**
67236           * Sets each pixel to its inverse value. No parameter is used.
67237           * @private
67238           * @param  {Canvas} canvas
67239           */
67240          Filters.invert = function(canvas) {
67241            var pixels = Filters._toPixels(canvas);
67242
67243            for (var i = 0; i < pixels.length; i += 4) {
67244              pixels[i] = 255 - pixels[i];
67245              pixels[i + 1] = 255 - pixels[i + 1];
67246              pixels[i + 2] = 255 - pixels[i + 2];
67247            }
67248          };
67249
67250          /**
67251           * Limits each channel of the image to the number of colors specified as
67252           * the parameter. The parameter can be set to values between 2 and 255, but
67253           * results are most noticeable in the lower ranges.
67254           *
67255           * Adapted from java based processing implementation
67256           *
67257           * @private
67258           * @param  {Canvas} canvas
67259           * @param  {Integer} level
67260           */
67261          Filters.posterize = function(canvas, level) {
67262            var pixels = Filters._toPixels(canvas);
67263
67264            if (level < 2 || level > 255) {
67265              throw new Error(
67266                'Level must be greater than 2 and less than 255 for posterize'
67267              );
67268            }
67269
67270            var levels1 = level - 1;
67271            for (var i = 0; i < pixels.length; i += 4) {
67272              var rlevel = pixels[i];
67273              var glevel = pixels[i + 1];
67274              var blevel = pixels[i + 2];
67275
67276              pixels[i] = ((rlevel * level) >> 8) * 255 / levels1;
67277              pixels[i + 1] = ((glevel * level) >> 8) * 255 / levels1;
67278              pixels[i + 2] = ((blevel * level) >> 8) * 255 / levels1;
67279            }
67280          };
67281
67282          /**
67283           * reduces the bright areas in an image
67284           * @private
67285           * @param  {Canvas} canvas
67286           */
67287          Filters.dilate = function(canvas) {
67288            var pixels = Filters._toPixels(canvas);
67289            var currIdx = 0;
67290            var maxIdx = pixels.length ? pixels.length / 4 : 0;
67291            var out = new Int32Array(maxIdx);
67292            var currRowIdx, maxRowIdx, colOrig, colOut, currLum;
67293
67294            var idxRight, idxLeft, idxUp, idxDown;
67295            var colRight, colLeft, colUp, colDown;
67296            var lumRight, lumLeft, lumUp, lumDown;
67297
67298            while (currIdx < maxIdx) {
67299              currRowIdx = currIdx;
67300              maxRowIdx = currIdx + canvas.width;
67301              while (currIdx < maxRowIdx) {
67302                colOrig = colOut = Filters._getARGB(pixels, currIdx);
67303                idxLeft = currIdx - 1;
67304                idxRight = currIdx + 1;
67305                idxUp = currIdx - canvas.width;
67306                idxDown = currIdx + canvas.width;
67307
67308                if (idxLeft < currRowIdx) {
67309                  idxLeft = currIdx;
67310                }
67311                if (idxRight >= maxRowIdx) {
67312                  idxRight = currIdx;
67313                }
67314                if (idxUp < 0) {
67315                  idxUp = 0;
67316                }
67317                if (idxDown >= maxIdx) {
67318                  idxDown = currIdx;
67319                }
67320                colUp = Filters._getARGB(pixels, idxUp);
67321                colLeft = Filters._getARGB(pixels, idxLeft);
67322                colDown = Filters._getARGB(pixels, idxDown);
67323                colRight = Filters._getARGB(pixels, idxRight);
67324
67325                //compute luminance
67326                currLum =
67327                  77 * ((colOrig >> 16) & 0xff) +
67328                  151 * ((colOrig >> 8) & 0xff) +
67329                  28 * (colOrig & 0xff);
67330                lumLeft =
67331                  77 * ((colLeft >> 16) & 0xff) +
67332                  151 * ((colLeft >> 8) & 0xff) +
67333                  28 * (colLeft & 0xff);
67334                lumRight =
67335                  77 * ((colRight >>
67335 16) & 0xff) +
67336                  151 * ((colRight >> 8) & 0xff) +
67337                  28 * (colRight & 0xff);
67338                lumUp =
67339                  77 * ((colUp >> 16) & 0xff) +
67340                  151 * ((colUp >> 8) & 0xff) +
67341                  28 * (colUp & 0xff);
67342                lumDown =
67343                  77 * ((colDown >> 16) & 0xff) +
67344                  151 * ((colDown >> 8) & 0xff) +
67345                  28 * (colDown & 0xff);
67346
67347                if (lumLeft > currLum) {
67348                  colOut = colLeft;
67349                  currLum = lumLeft;
67350                }
67351                if (lumRight > currLum) {
67352                  colOut = colRight;
67353                  currLum = lumRight;
67354                }
67355                if (lumUp > currLum) {
67356                  colOut = colUp;
67357                  currLum = lumUp;
67358                }
67359                if (lumDown > currLum) {
67360                  colOut = colDown;
67361                  currLum = lumDown;
67362                }
67363                out[currIdx++] = colOut;
67364              }
67365            }
67366            Filters._setPixels(pixels, out);
67367          };
67368
67369          /**
67370           * increases the bright areas in an image
67371           * @private
67372           * @param  {Canvas} canvas
67373           */
67374          Filters.erode = function(canvas) {
67375            var pixels = Filters._toPixels(canvas);
67376            var currIdx = 0;
67377            var maxIdx = pixels.length ? pixels.length / 4 : 0;
67378            var out = new Int32Array(maxIdx);
67379            var currRowIdx, maxRowIdx, colOrig, colOut, currLum;
67380            var idxRight, idxLeft, idxUp, idxDown;
67381            var colRight, colLeft, colUp, colDown;
67382            var lumRight, lumLeft, lumUp, lumDown;
67383
67384            while (currIdx < maxIdx) {
67385              currRowIdx = currIdx;
67386              maxRowIdx = currIdx + canvas.width;
67387              while (currIdx < maxRowIdx) {
67388                colOrig = colOut = Filters._getARGB(pixels, currIdx);
67389                idxLeft = currIdx - 1;
67390                idxRight = currIdx + 1;
67391                idxUp = currIdx - canvas.width;
67392                idxDown = currIdx + canvas.width;
67393
67394                if (idxLeft < currRowIdx) {
67395                  idxLeft = currIdx;
67396                }
67397                if (idxRight >= maxRowIdx) {
67398                  idxRight = currIdx;
67399                }
67400                if (idxUp < 0) {
67401                  idxUp = 0;
67402                }
67403                if (idxDown >= maxIdx) {
67404                  idxDown = currIdx;
67405                }
67406                colUp = Filters._getARGB(pixels, idxUp);
67407                colLeft = Filters._getARGB(pixels, idxLeft);
67408                colDown = Filters._getARGB(pixels, idxDown);
67409                colRight = Filters._getARGB(pixels, idxRight);
67410
67411                //compute luminance
67412                currLum =
67413                  77 * ((colOrig >> 16) & 0xff) +
67414                  151 * ((colOrig >> 8) & 0xff) +
67415                  28 * (colOrig & 0xff);
67416                lumLeft =
67417                  77 * ((colLeft >> 16) & 0xff) +
67418                  151 * ((colLeft >> 8) & 0xff) +
67419                  28 * (colLeft & 0xff);
67420                lumRight =
67421                  77 * ((colRight >>
67421 16) & 0xff) +
67422                  151 * ((colRight >> 8) & 0xff) +
67423                  28 * (colRight & 0xff);
67424                lumUp =
67425                  77 * ((colUp >> 16) & 0xff) +
67426                  151 * ((colUp >> 8) & 0xff) +
67427                  28 * (colUp & 0xff);
67428                lumDown =
67429                  77 * ((colDown >> 16) & 0xff) +
67430                  151 * ((colDown >> 8) & 0xff) +
67431                  28 * (colDown & 0xff);
67432
67433                if (lumLeft < currLum) {
67434                  colOut = colLeft;
67435                  currLum = lumLeft;
67436                }
67437                if (lumRight < currLum) {
67438                  colOut = colRight;
67439                  currLum = lumRight;
67440                }
67441                if (lumUp < currLum) {
67442                  colOut = colUp;
67443                  currLum = lumUp;
67444                }
67445                if (lumDown < currLum) {
67446                  colOut = colDown;
67447                  currLum = lumDown;
67448                }
67449
67450                out[currIdx++] = colOut;
67451              }
67452            }
67453            Filters._setPixels(pixels, out);
67454          };
67455
67456          // BLUR
67457
67458          // internal kernel stuff for the gaussian blur filter
67459          var blurRadius;
67460          var blurKernelSize;
67461          var blurKernel;
67462          var blurMult;
67463
67464          /*
67465               * Port of https://github.com/processing/processing/blob/
67466               * main/core/src/processing/core/PImage.java#L1250
67467               *
67468               * Optimized code for building the blur kernel.
67469               * further optimized blur code (approx. 15% for radius=20)
67470               * bigger speed gains for larger radii (~30%)
67471               * added support for various image types (ALPHA, RGB, ARGB)
67472               * [toxi 050728]
67473               */
67474          function buildBlurKernel(r) {
67475            var radius = (r * 3.5) | 0;
67476            radius = radius < 1 ? 1 : radius < 248 ? radius : 248;
67477
67478            if (blurRadius !== radius) {
67479              blurRadius = radius;
67480              blurKernelSize = (1 + blurRadius) << 1;
67481              blurKernel = new Int32Array(blurKernelSize);
67482              blurMult = new Array(blurKernelSize);
67483              for (var l = 0; l < blurKernelSize; l++) {
67484                blurMult[l] = new Int32Array(256);
67485              }
67486
67487              var bk, bki;
67488              var bm, bmi;
67489
67490              for (var i = 1, radiusi = radius - 1; i < radius; i++) {
67491                blurKernel[radius + i] = blurKernel[radiusi] = bki = radiusi * radiusi;
67492                bm = blurMult[radius + i];
67493                bmi = blurMult[radiusi--];
67494                for (var j = 0; j < 256; j++) {
67495                  bm[j] = bmi[j] = bki * j;
67496                }
67497              }
67498              bk = blurKernel[radius] = radius * radius;
67499              bm = blurMult[radius];
67500
67501              for (var k = 0; k < 256; k++) {
67502                bm[k] = bk * k;
67503              }
67504            }
67505          }
67506
67507          // Port of https://github.com/processing/processing/blob/
67508          // main/core/src/processing/core/PImage.java#L1433
67509          function blurARGB(canvas, radius) {
67510            var pixels = Filters._toPixels(canvas);
67511            var width = canvas.width;
67512            var height = canvas.height;
67513            var numPackedPixels = width * height;
67514            var argb = new Int32Array(numPackedPixels);
67515            for (var j = 0; j < numPackedPixels; j++) {
67516              argb[j] = Filters._getARGB(pixels, j);
67517            }
67518            var sum, cr, cg, cb, ca;
67519            var read, ri, ym, ymi, bk0;
67520            var a2 = new Int32Array(numPackedPixels);
67521            var r2 = new Int32Array(numPackedPixels);
67522            var g2 = new Int32Array(numPackedPixels);
67523            var b2 = new Int32Array(numPackedPixels);
67524            var yi = 0;
67525            buildBlurKernel(radius);
67526            var x, y, i;
67527            var bm;
67528            for (y = 0; y < height; y++) {
67529              for (x = 0; x < width; x++) {
67530                cb = cg = cr = ca = sum = 0;
67531                read = x - blurRadius;
67532                if (read < 0) {
67533                  bk0 = -read;
67534                  read = 0;
67535                } else {
67536                  if (read >= width) {
67537                    break;
67538                  }
67539                  bk0 = 0;
67540                }
67541                for (i = bk0; i < blurKernelSize; i++) {
67542                  if (read >= width) {
67543                    break;
67544                  }
67545                  var c = argb[read + yi];
67546                  bm = blurMult[i];
67547                  ca += bm[(c & -16777216) >>> 24];
67548                  cr += bm[(c & 16711680) >> 16];
67549                  cg += bm[(c & 65280) >> 8];
67550                  cb += bm[c & 255];
67551                  sum += blurKernel[i];
67552                  read++;
67553                }
67554                ri = yi + x;
67555                a2[ri] = ca / sum;
67556                r2[ri] = cr / sum;
67557                g2[ri] = cg / sum;
67558                b2[ri] = cb / sum;
67559              }
67560              yi += width;
67561            }
67562            yi = 0;
67563            ym = -blurRadius;
67564            ymi = ym * width;
67565            for (y = 0; y < height; y++) {
67566              for (x = 0; x < width; x++) {
67567                cb = cg = cr = ca = sum = 0;
67568                if (ym < 0) {
67569                  bk0 = ri = -ym;
67570                  read = x;
67571                } else {
67572                  if (ym >= height) {
67573                    break;
67574                  }
67575                  bk0 = 0;
67576                  ri = ym;
67577                  read = x + ymi;
67578                }
67579                for (i = bk0; i < blurKernelSize; i++) {
67580                  if (ri >= height) {
67581                    break;
67582                  }
67583                  bm = blurMult[i];
67584                  ca += bm[a2[read]];
67585                  cr += bm[r2[read]];
67586                  cg += bm[g2[read]];
67587                  cb += bm[b2[read]];
67588                  sum += blurKernel[i];
67589                  ri++;
67590                  read += width;
67591                }
67592                argb[x + yi] =
67593                  ((ca / sum) << 24) | ((cr / sum) << 16) | ((cg / sum) << 8) | (cb / sum);
67594              }
67595              yi += width;
67596              ymi += width;
67597              ym++;
67598            }
67599            Filters._setPixels(pixels, argb);
67600          }
67601
67602          Filters.blur = function(canvas, radius) {
67603            blurARGB(canvas, radius);
67604          };
67605          var _default = Filters;
67606          exports.default = _default;
67607        },
67608        {}
67609      ],
67610      81: [
67611        function(_dereq_, module, exports) {
67612          'use strict';
67613          Object.defineProperty(exports, '__esModule', { value: true });
67614          exports.default = void 0;
67615
67616          var _main = _interopRequireDefault(_dereq_('../core/main'));
67617          var _omggif = _interopRequireDefault(_dereq_('omggif'));
67618          function _interopRequireDefault(obj) {
67619            return obj && obj.__esModule ? obj : { default: obj };
67620          }
67621          function _toConsumableArray(arr) {
67622            return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
67623          }
67624          function _nonIterableSpread() {
67625            throw new TypeError('Invalid attempt to spread non-iterable instance');
67626          }
67627          function _iterableToArray(iter) {
67628            if (
67629              Symbol.iterator in Object(iter) ||
67630              Object.prototype.toString.call(iter) === '[object Arguments]'
67631            )
67632              return Array.from(iter);
67633          }
67634          function _arrayWithoutHoles(arr) {
67635            if (Array.isArray(arr)) {
67636              for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
67637                arr2[i] = arr[i];
67638              }
67639              return arr2;
67640            }
67641          }
67642
67643          /**
67644           * Creates a new <a href="#/p5.Image">p5.Image</a> (the datatype for storing images). This provides a
67645           * fresh buffer of pixels to play with. Set the size of the buffer with the
67646           * width and height parameters.
67647           *
67648           * .<a href="#/p5.Image/pixels">pixels</a> gives access to an array containing the values for all the pixels
67649           * in the display window.
67650           * These values are numbers. This array is the size (including an appropriate
67651           * factor for the <a href="#/p5/pixelDensity">pixelDensity</a>) of the display window x4,
67652           * representing the R, G, B, A values in order for each pixel, moving from
67653           * left to right across each row, then down each column. See .<a href="#/p5.Image/pixels">pixels</a> for
67654           * more info. It may also be simpler to use <a href="#/p5.Image/set">set()</a> or <a href="#/p5.Image/get">get()</a>.
67655           *
67656           * Before accessing the pixels of an image, the data must loaded with the
67657           * <a href="#/p5.Image/loadPixels">loadPixels()</a> function. After the array data has been modified, the
67658           * <a href="#/p5.Image/updatePixels">updatePixels()</a> function must be run to update the changes.
67659           *
67660           * @method createImage
67661           * @param  {Integer} width  width in pixels
67662           * @param  {Integer} height height in pixels
67663           * @return {p5.Image}       the <a href="#/p5.Image">p5.Image</a> object
67664           * @example
67665           * <div>
67666           * <code>
67667           * let img = createImage(66, 66);
67668           * img.loadPixels();
67669           * for (let i = 0; i < img.width; i++) {
67670           *   for (let j = 0; j < img.height; j++) {
67671           *     img.set(i, j, color(0, 90, 102));
67672           *   }
67673           * }
67674           * img.updatePixels();
67675           * image(img, 17, 17);
67676           * </code>
67677           * </div>
67678           *
67679           * <div>
67680           * <code>
67681           * let img = createImage(66, 66);
67682           * img.loadPixels();
67683           * for (let i = 0; i < img.width; i++) {
67684           *   for (let j = 0; j < img.height; j++) {
67685           *     img.set(i, j, color(0, 90, 102, (i % img.width) * 2));
67686           *   }
67687           * }
67688           * img.updatePixels();
67689           * image(img, 17, 17);
67690           * image(img, 34, 34);
67691           * </code>
67692           * </div>
67693           *
67694           * <div>
67695           * <code>
67696           * let pink = color(255, 102, 204);
67697           * let img = createImage(66, 66);
67698           * img.loadPixels();
67699           * let d = pixelDensity();
67700           * let halfImage = 4 * (img.width * d) * (img.height / 2 * d);
67701           * for (let i = 0; i < halfImage; i += 4) {
67702           *   img.pixels[i] = red(pink);
67703           *   img.pixels[i + 1] = green(pink);
67704           *   img.pixels[i + 2] = blue(pink);
67705           *   img.pixels[i + 3] = alpha(pink);
67706           * }
67707           * img.updatePixels();
67708           * image(img, 17, 17);
67709           * </code>
67710           * </div>
67711           *
67712           * @alt
67713           * 66x66 dark turquoise rect in center of canvas.
67714           * 2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas
67715           * no image displayed
67716           */
67717          _main.default.prototype.createImage = function(width, height) {
67718            _main.default._validateParameters('createImage', arguments);
67719            return new _main.default.Image(width, height);
67720          };
67721
67722          /**
67723           *  Save the current canvas as an image. The browser will either save the
67724           *  file immediately, or prompt the user with a dialogue window.
67725           *
67726           *  @method saveCanvas
67727           *  @param  {p5.Element|HTMLCanvasElement} selectedCanvas   a variable
67728           *                                  representing a specific html5 canvas (optional)
67729           *  @param  {String} [filename]
67730           *  @param  {String} [extension]      'jpg' or 'png'
67731           *
67732           *  @example
67733           * <div class='norender notest'><code>
67734           * function setup() {
67735           *   let c = createCanvas(100, 100);
67736           *   background(255, 0, 0);
67737           *   saveCanvas(c, 'myCanvas', 'jpg');
67738           * }
67739           * </code></div>
67740           * <div class='norender notest'><code>
67741           * // note that this example has the same result as above
67742           * // if no canvas is specified, defaults to main canvas
67743           * function setup() {
67744           *   let c = createCanvas(100, 100);
67745           *   background(255, 0, 0);
67746           *   saveCanvas('myCanvas', 'jpg');
67747           *
67748           *   // all of the following are valid
67749           *   saveCanvas(c, 'myCanvas', 'jpg');
67750           *   saveCanvas(c, 'myCanvas.jpg');
67751           *   saveCanvas(c, 'myCanvas');
67752           *   saveCanvas(c);
67753           *   saveCanvas('myCanvas', 'png');
67754           *   saveCanvas('myCanvas');
67755           *   saveCanvas();
67756           * }
67757           * </code></div>
67758           *
67759           * @alt
67760           * no image displayed
67761           * no image displayed
67762           * no image displayed
67763           */
67764          /**
67765           *  @method saveCanvas
67766           *  @param  {String} [filename]
67767           *  @param  {String} [extension]
67768           */
67769          _main.default.prototype.saveCanvas = function() {
67770            _main.default._validateParameters('saveCanvas', arguments);
67771
67772            // copy arguments to array
67773            var args = [].slice.call(arguments);
67774            var htmlCanvas, filename, extension;
67775
67776            if (arguments[0] instanceof HTMLCanvasElement) {
67777              htmlCanvas = arguments[0];
67778              args.shift();
67779            } else if (arguments[0] instanceof _main.default.Element) {
67780              htmlCanvas = arguments[0].elt;
67781              args.shift();
67782            } else {
67783              htmlCanvas = this._curElement && this._curElement.elt;
67784            }
67785
67786            if (args.length >= 1) {
67787              filename = args[0];
67788            }
67789            if (args.length >= 2) {
67790              extension = args[1];
67791            }
67792
67793            extension =
67794              extension ||
67795              _main.default.prototype._checkFileExtension(filename, extension)[1] ||
67796              'png';
67797
67798            var mimeType;
67799            switch (extension) {
67800              default:
67801                //case 'png':
67802                mimeType = 'image/png';
67803                break;
67804              case 'jpeg':
67805              case 'jpg':
67806                mimeType = 'image/jpeg';
67807                break;
67808            }
67809
67810            htmlCanvas.toBlob(function(blob) {
67811              _main.default.prototype.downloadFile(blob, filename, extension);
67812            }, mimeType);
67813          };
67814
67815          _main.default.prototype.saveGif = function(pImg, filename) {
67816            var props = pImg.gifProperties;
67817
67818            //convert loopLimit back into Netscape Block formatting
67819            var loopLimit = props.loopLimit;
67820            if (loopLimit === 1) {
67821              loopLimit = null;
67822            } else if (loopLimit === null) {
67823              loopLimit = 0;
67824            }
67825            var buffer = new Uint8Array(pImg.width * pImg.height * props.numFrames);
67826
67827            var allFramesPixelColors = [];
67828
67829            // Used to determine the occurrence of unique palettes and the frames
67830            // which use them
67831            var paletteFreqsAndFrames = {};
67832
67833            // Pass 1:
67834            //loop over frames and get the frequency of each palette
67835            for (var i = 0; i < props.numFrames; i++) {
67836              var paletteSet = new Set();
67837              var data = props.frames[i].image.data;
67838              var dataLength = data.length;
67839              // The color for each pixel in this frame ( for easier lookup later )
67840              var pixelColors = new Uint32Array(pImg.width * pImg.height);
67841              for (var j = 0, k = 0; j < dataLength; j += 4, k++) {
67842                var r = data[j + 0];
67843                var g = data[j + 1];
67844                var b = data[j + 2];
67845                var color = (r << 16) | (g << 8) | (b << 0);
67846                paletteSet.add(color);
67847
67848                // What color does this pixel have in this frame ?
67849                pixelColors[k] = color;
67850              }
67851
67852              // A way to put use the entire palette as an object key
67853              var paletteStr = _toConsumableArray(paletteSet)
67854                .sort()
67855                .toString();
67856              if (paletteFreqsAndFrames[paletteStr] === undefined) {
67857                paletteFreqsAndFrames[paletteStr] = { freq: 1, frames: [i] };
67858              } else {
67859                paletteFreqsAndFrames[paletteStr].freq += 1;
67860                paletteFreqsAndFrames[paletteStr].frames.push(i);
67861              }
67862
67863              allFramesPixelColors.push(pixelColors);
67864            }
67865
67866            var framesUsingGlobalPalette = [];
67867
67868            // Now to build the global palette
67869            // Sort all the unique palettes in descending order of their occurence
67870            var palettesSortedByFreq = Object.keys(paletteFreqsAndFrames).sort(function(
67871              a,
67872              b
67873            ) {
67874              return paletteFreqsAndFrames[b].freq - paletteFreqsAndFrames[a].freq;
67875            });
67876
67877            // The initial global palette is the one with the most occurence
67878            var globalPalette = palettesSortedByFreq[0].split(',').map(function(a) {
67879              return parseInt(a);
67880            });
67881
67882            framesUsingGlobalPalette = framesUsingGlobalPalette.concat(
67883              paletteFreqsAndFrames[globalPalette].frames
67884            );
67885
67886            var globalPaletteSet = new Set(globalPalette);
67887
67888            // Build a more complete global palette
67889            // Iterate over the remaining palettes in the order of
67890            // their occurence and see if the colors in this palette which are
67891            // not in the global palette can be added there, while keeping the length
67892            // of the global palette <= 256
67893            for (var _i = 1; _i < palettesSortedByFreq.length; _i++) {
67894              var palette = palettesSortedByFreq[_i].split(',').map(function(a) {
67895                return parseInt(a);
67896              });
67897
67898              var difference = palette.filter(function(x) {
67899                return !globalPaletteSet.has(x);
67900              });
67901              if (globalPalette.length + difference.length <= 256) {
67902                for (var _j = 0; _j < difference.length; _j++) {
67903                  globalPalette.push(difference[_j]);
67904                  globalPaletteSet.add(difference[_j]);
67905                }
67906
67907                // All frames using this palette now use the global palette
67908                framesUsingGlobalPalette = framesUsingGlobalPalette.concat(
67909                  paletteFreqsAndFrames[palettesSortedByFreq[_i]].frames
67910                );
67911              }
67912            }
67913
67914            framesUsingGlobalPalette = new Set(framesUsingGlobalPalette);
67915
67916            // Build a lookup table of the index of each color in the global palette
67917            // Maps a color to its index
67918            var globalIndicesLookup = {};
67919            for (var _i2 = 0; _i2 < globalPalette.length; _i2++) {
67920              if (!globalIndicesLookup[globalPalette[_i2]]) {
67921                globalIndicesLookup[globalPalette[_i2]] = _i2;
67922              }
67923            }
67924
67925            // force palette to be power of 2
67926            var powof2 = 1;
67927            while (powof2 < globalPalette.length) {
67928              powof2 <<= 1;
67929            }
67930            globalPalette.length = powof2;
67931
67932            // global opts
67933            var opts = {
67934              loop: loopLimit,
67935              palette: new Uint32Array(globalPalette)
67936            };
67937
67938            var gifWriter = new _omggif.default.GifWriter(
67939              buffer,
67940              pImg.width,
67941              pImg.height,
67942              opts
67943            );
67944            var previousFrame = {};
67945
67946            // Pass 2
67947            // Determine if the frame needs a local palette
67948            // Also apply transparency optimization. This function will often blow up
67949            // the size of a GIF if not for transparency. If a pixel in one frame has
67950            // the same color in the previous frame, that pixel can be marked as
67951            // transparent. We decide one particular color as transparent and make all
67952            // transparent pixels take this color. This helps in later in compression.
67953            var _loop = function _loop(_i3) {
67954              var localPaletteRequired = !framesUsingGlobalPalette.has(_i3);
67955              var palette = localPaletteRequired ? [] : globalPalette;
67956              var pixelPaletteIndex = new Uint8Array(pImg.width * pImg.height);
67957
67958              // Lookup table mapping color to its indices
67959              var colorIndicesLookup = {};
67960
67961              // All the colors that cannot be marked transparent in this frame
67962              var cannotBeTransparent = new Set();
67963
67964              for (var _k = 0; _k < allFramesPixelColors[_i3].length; _k++) {
67965                var _color = allFramesPixelColors[_i3][_k];
67966                if (localPaletteRequired) {
67967                  if (colorIndicesLookup[_color] === undefined) {
67968                    colorIndicesLookup[_color] = palette.length;
67969                    palette.push(_color);
67970                  }
67971                  pixelPaletteIndex[_k] = colorIndicesLookup[_color];
67972                } else {
67973                  pixelPaletteIndex[_k] = globalIndicesLookup[_color];
67974                }
67975
67976                if (_i3 > 0) {
67977                  // If even one pixel of this color has changed in this frame
67978                  // from the previous frame, we cannot mark it as transparent
67979                  if (allFramesPixelColors[_i3 - 1][_k] !== _color) {
67980                    cannotBeTransparent.add(_color);
67981                  }
67982                }
67983              }
67984
67985              var frameOpts = {};
67986
67987              // Transparency optimization
67988              var canBeTransparent = palette.filter(function(a) {
67989                return !cannotBeTransparent.has(a);
67990              });
67991              if (canBeTransparent.length > 0) {
67992                // Select a color to mark as transparent
67993                var transparent = canBeTransparent[0];
67994                var transparentIndex = localPaletteRequired
67995                  ? colorIndicesLookup[transparent]
67996                  : globalIndicesLookup[transparent];
67997                if (_i3 > 0) {
67998                  for (var _k2 = 0; _k2 < allFramesPixelColors[_i3].length; _k2++) {
67999                    // If this pixel in this frame has the same color in previous frame
68000                    if (
68001                      allFramesPixelColors[_i3 - 1][_k2] === allFramesPixelColors[_i3][_k2]
68002                    ) {
68003                      pixelPaletteIndex[_k2] = transparentIndex;
68004                    }
68005                  }
68006                  frameOpts.transparent = transparentIndex;
68007                  // If this frame has any transparency, do not dispose the previous frame
68008                  previousFrame.frameOpts.disposal = 1;
68009                }
68010              }
68011              frameOpts.delay = props.frames[_i3].delay / 10; // Move timing back into GIF formatting
68012              if (localPaletteRequired) {
68013                // force palette to be power of 2
68014                var _powof = 1;
68015                while (_powof < palette.length) {
68016                  _powof <<= 1;
68017                }
68018                palette.length = _powof;
68019                frameOpts.palette = new Uint32Array(palette);
68020              }
68021              if (_i3 > 0) {
68022                // add the frame that came before the current one
68023                gifWriter.addFrame(
68024                  0,
68025                  0,
68026                  pImg.width,
68027                  pImg.height,
68028                  previousFrame.pixelPaletteIndex,
68029                  previousFrame.frameOpts
68030                );
68031              }
68032              // previous frame object should now have details of this frame
68033              previousFrame = {
68034                pixelPaletteIndex: pixelPaletteIndex,
68035                frameOpts: frameOpts
68036              };
68037            };
68038            for (var _i3 = 0; _i3 < props.numFrames; _i3++) {
68039              _loop(_i3);
68040            }
68041
68042            previousFrame.frameOpts.disposal = 1;
68043            // add the last frame
68044            gifWriter.addFrame(
68045              0,
68046              0,
68047              pImg.width,
68048              pImg.height,
68049              previousFrame.pixelPaletteIndex,
68050              previousFrame.frameOpts
68051            );
68052
68053            var extension = 'gif';
68054            var blob = new Blob([buffer.slice(0, gifWriter.end())], {
68055              type: 'image/gif'
68056            });
68057
68058            _main.default.prototype.downloadFile(blob, filename, extension);
68059          };
68060
68061          /**
68062    *  Capture a sequence of frames that can be used to create a movie.
68063    *  Accepts a callback. For example, you may wish to send the frames
68064    *  to a server where they can be stored or converted into a movie.
68065    *  If no callback is provided, the browser will pop up save dialogues in an
68066    *  attempt to download all of the images that have just been created. With the
68067    *  callback provided the image data isn't saved by default but instead passed
68068    *  as an argument to the callback function as an array of objects, with the
68069    *  size of array equal to the total number of frames.
68070    *
68071    *  Note that <a href="#/p5.Image/saveFrames">saveFrames()</a> will only save the first 15 frames of an animation.
68072    *  To export longer animations, you might look into a library like
68073    *  <a href="https://github.com/spite/ccapture.js/">ccapture.js</a>.
68074    *
68075    *  @method saveFrames
68076    *  @param  {String}   filename
68077    *  @param  {String}   extension 'jpg' or 'png'
68078    *  @param  {Number}   duration  Duration in seconds to save the frames for.
68079    *  @param  {Number}   framerate  Framerate to save the frames in.
68080    *  @param  {function(Array)} [callback] A callback function that will be executed
68081                                     to handle the image data. This function
68082                                     should accept an array as argument. The
68083                                     array will contain the specified number of
68084                                     frames of objects. Each object has three
68085                                     properties: imageData - an
68086                                     image/octet-stream, filename and extension.
68087    *  @example
68088    *  <div><code>
68089    * function draw() {
68090    *   background(mouseX);
68091    * }
68092    *
68093    * function mousePressed() {
68094    *   saveFrames('out', 'png', 1, 25, data => {
68095    *     print(data);
68096    *   });
68097    * }
68098   </code></div>
68099    *
68100    * @alt
68101    * canvas background goes from light to dark with mouse x.
68102    */
68103          _main.default.prototype.saveFrames = function(
68104            fName,
68105            ext,
68106            _duration,
68107            _fps,
68108            callback
68109          ) {
68110            _main.default._validateParameters('saveFrames', arguments);
68111            var duration = _duration || 3;
68112            duration = _main.default.prototype.constrain(duration, 0, 15);
68113            duration = duration * 1000;
68114            var fps = _fps || 15;
68115            fps = _main.default.prototype.constrain(fps, 0, 22);
68116            var count = 0;
68117
68118            var makeFrame = _main.default.prototype._makeFrame;
68119            var cnv = this._curElement.elt;
68120            var frames = [];
68121            var frameFactory = setInterval(function() {
68122              frames.push(makeFrame(fName + count, ext, cnv));
68123              count++;
68124            }, 1000 / fps);
68125
68126            setTimeout(function() {
68127              clearInterval(frameFactory);
68128              if (callback) {
68129                callback(frames);
68130              } else {
68131                var _iteratorNormalCompletion = true;
68132                var _didIteratorError = false;
68133                var _iteratorError = undefined;
68134                try {
68135                  for (
68136                    var _iterator = frames[Symbol.iterator](), _step;
68137                    !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
68138                    _iteratorNormalCompletion = true
68139                  ) {
68140                    var f = _step.value;
68141                    _main.default.prototype.downloadFile(f.imageData, f.filename, f.ext);
68142                  }
68143                } catch (err) {
68144                  _didIteratorError = true;
68145                  _iteratorError = err;
68146                } finally {
68147                  try {
68148                    if (!_iteratorNormalCompletion && _iterator.return != null) {
68149                      _iterator.return();
68150                    }
68151                  } finally {
68152                    if (_didIteratorError) {
68153                      throw _iteratorError;
68154                    }
68155                  }
68156                }
68157              }
68158              frames = []; // clear frames
68159            }, duration + 0.01);
68160          };
68161
68162          _main.default.prototype._makeFrame = function(filename, extension, _cnv) {
68163            var cnv;
68164            if (this) {
68165              cnv = this._curElement.elt;
68166            } else {
68167              cnv = _cnv;
68168            }
68169            var mimeType;
68170            if (!extension) {
68171              extension = 'png';
68172              mimeType = 'image/png';
68173            } else {
68174              switch (extension.toLowerCase()) {
68175                case 'png':
68176                  mimeType = 'image/png';
68177                  break;
68178                case 'jpeg':
68179                  mimeType = 'image/jpeg';
68180                  break;
68181                case 'jpg':
68182                  mimeType = 'image/jpeg';
68183                  break;
68184                default:
68185                  mimeType = 'image/png';
68186                  break;
68187              }
68188            }
68189            var downloadMime = 'image/octet-stream';
68190            var imageData = cnv.toDataURL(mimeType);
68191            imageData = imageData.replace(mimeType, downloadMime);
68192
68193            var thisFrame = {};
68194            thisFrame.imageData = imageData;
68195            thisFrame.filename = filename;
68196            thisFrame.ext = extension;
68197            return thisFrame;
68198          };
68199          var _default = _main.default;
68200          exports.default = _default;
68201        },
68202        { '../core/main': 59, omggif: 33 }
68203      ],
68204      82: [
68205        function(_dereq_, module, exports) {
68206          'use strict';
68207          function _typeof(obj) {
68208            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
68209              _typeof = function _typeof(obj) {
68210                return typeof obj;
68211              };
68212            } else {
68213              _typeof = function _typeof(obj) {
68214                return obj &&
68215                  typeof Symbol === 'function' &&
68216                  obj.constructor === Symbol &&
68217                  obj !== Symbol.prototype
68218                  ? 'symbol'
68219                  : typeof obj;
68220              };
68221            }
68222            return _typeof(obj);
68223          }
68224          Object.defineProperty(exports, '__esModule', { value: true });
68225          exports.default = void 0;
68226
68227          var _main = _interopRequireDefault(_dereq_('../core/main'));
68228          var _filters = _interopRequireDefault(_dereq_('./filters'));
68229          var _helpers = _interopRequireDefault(_dereq_('../core/helpers'));
68230          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
68231          var _omggif = _interopRequireDefault(_dereq_('omggif'));
68232
68233          _dereq_('../core/friendly_errors/validate_params');
68234          _dereq_('../core/friendly_errors/file_errors');
68235          _dereq_('../core/friendly_errors/fes_core');
68236          function _getRequireWildcardCache() {
68237            if (typeof WeakMap !== 'function') return null;
68238            var cache = new WeakMap();
68239            _getRequireWildcardCache = function _getRequireWildcardCache() {
68240              return cache;
68241            };
68242            return cache;
68243          }
68244          function _interopRequireWildcard(obj) {
68245            if (obj && obj.__esModule) {
68246              return obj;
68247            }
68248            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
68249              return { default: obj };
68250            }
68251            var cache = _getRequireWildcardCache();
68252            if (cache && cache.has(obj)) {
68253              return cache.get(obj);
68254            }
68255            var newObj = {};
68256            var hasPropertyDescriptor =
68257              Object.defineProperty && Object.getOwnPropertyDescriptor;
68258            for (var key in obj) {
68259              if (Object.prototype.hasOwnProperty.call(obj, key)) {
68260                var desc = hasPropertyDescriptor
68261                  ? Object.getOwnPropertyDescriptor(obj, key)
68262                  : null;
68263                if (desc && (desc.get || desc.set)) {
68264                  Object.defineProperty(newObj, key, desc);
68265                } else {
68266                  newObj[key] = obj[key];
68267                }
68268              }
68269            }
68270            newObj.default = obj;
68271            if (cache) {
68272              cache.set(obj, newObj);
68273            }
68274            return newObj;
68275          }
68276          function _interopRequireDefault(obj) {
68277            return obj && obj.__esModule ? obj : { default: obj };
68278          }
68279          /**
68280           * @module Image
68281           * @submodule Loading & Displaying
68282           * @for p5
68283           * @requires core
68284           */ /**
68285                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * Loads an image from a path and creates a <a href="#/p5.Image">p5.Image</a> from it.
68286                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *
68287                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * The image may not be immediately available for rendering.
68288                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * If you want to ensure that the image is ready before doing
68289                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * anything with it, place the <a href="#/p5/loadImage">loadImage()</a> call in <a href="#/p5/preload">preload()</a>.
68290                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * You may also supply a callback function to handle the image when it's ready.
68291                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *
68292                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * The path to the image should be relative to the HTML file
68293                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * that links in your sketch. Loading an image from a URL or other
68294                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
68294                                                                                                                                                                                                                                                                                                                     * remote location may be blocked due to your browser's built-in
68295                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * security.
68296                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
68297                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * You can also pass in a string of a base64 encoded image as an alternative to the file path.
68298                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * Remember to add "data:image/png;base64," in front of the string.
68299                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *
68300                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * @method loadImage
68301                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * @param  {String} path Path of the image to be loaded
68302                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * @param  {function(p5.Image)} [successCallback] Function to be called once
68303                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *                                the image is loaded. Will be passed the
68304                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *                                <a href="#/p5.Image">p5.Image</a>.
68305                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * @param  {function(Event)}    [failureCallback] called with event error if
68306                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *                                the image fails to load.
68307                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * @return {p5.Image}             the <a href="#/p5.Image">p5.Image</a> object
68308                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * @example
68309                                                                                                                                                                                                                                                                                                                                                                                                                                                       
68309                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * <div>
68310                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * <code>
68311                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * let img;
68312                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * function preload() {
68313                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *   img = loadImage('assets/laDefense.jpg');
68314                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * }
68315                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * function setup() {
68316                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *   image(img, 0, 0);
68317                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * }
68318                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * </code>
68319                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * </div>
68320                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * <div>
68321                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * <code>
68322                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * function setup() {
68323                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *   // here we use a callback to display the image after loading
68324                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
68324                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *   loadImage('assets/laDefense.jpg', img => {
68325                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *     image(img, 0, 0);
68326                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *   });
68327                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * }
68328                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * </code>
68329                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * </div>
68330                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       *
68331                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * @alt
68332                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * image of the underside of a white umbrella and grided ceililng above
68333                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       * image of the underside of a white umbrella and grided ceililng above
68334                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       */ _main.default.prototype.loadImage = function(
68335            path,
68336            successCallback,
68337            failureCallback
68338          ) {
68339            _main.default._validateParameters('loadImage', arguments);
68340            var pImg = new _main.default.Image(1, 1, this);
68341            var self = this;
68342
68343            var req = new Request(path, {
68344              method: 'GET',
68345              mode: 'cors'
68346            });
68347
68348            fetch(path, req).then(function(response) {
68349              // GIF section
68350              var contentType = response.headers.get('content-type');
68351              if (contentType === null) {
68352                console.warn(
68353                  'The image you loaded does not have a Content-Type header. If you are using the online editor consider reuploading the asset.'
68354                );
68355              }
68356              if (contentType && contentType.includes('image/gif')) {
68357                response.arrayBuffer().then(
68358                  function(arrayBuffer) {
68359                    if (arrayBuffer) {
68360                      var byteArray = new Uint8Array(arrayBuffer);
68361                      _createGif(
68362                        byteArray,
68363                        pImg,
68364                        successCallback,
68365                        failureCallback,
68366                        function(pImg) {
68367                          self._decrementPreload();
68368                        }.bind(self)
68369                      );
68370                    }
68371                  },
68372                  function(e) {
68373                    if (typeof failureCallback === 'function') {
68374                      failureCallback(e);
68375                    } else {
68376                      console.error(e);
68377                    }
68378                  }
68379                );
68380              } else {
68381                // Non-GIF Section
68382                var img = new Image();
68383
68384                img.onload = function() {
68385                  pImg.width = pImg.canvas.width = img.width;
68386                  pImg.height = pImg.canvas.height = img.height;
68387
68388                  // Draw the image into the backing canvas of the p5.Image
68389                  pImg.drawingContext.drawImage(img, 0, 0);
68390                  pImg.modified = true;
68391                  if (typeof successCallback === 'function') {
68392                    successCallback(pImg);
68393                  }
68394                  self._decrementPreload();
68395                };
68396
68397                img.onerror = function(e) {
68398                  _main.default._friendlyFileLoadError(0, img.src);
68399                  if (typeof failureCallback === 'function') {
68400                    failureCallback(e);
68401                  } else {
68402                    console.error(e);
68403                  }
68404                };
68405
68406                // Set crossOrigin in case image is served with CORS headers.
68407                // This will let us draw to the canvas without tainting it.
68408                // See https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
68409                // When using data-uris the file will be loaded locally
68410                // so we don't need to worry about crossOrigin with base64 file types.
68411                if (path.indexOf('data:image/') !== 0) {
68412                  img.crossOrigin = 'Anonymous';
68413                }
68414                // start loading the image
68415                img.src = path;
68416              }
68417              pImg.modified = true;
68418            });
68419            return pImg;
68420          };
68421
68422          /**
68423           * Helper function for loading GIF-based images
68424           */
68425          function _createGif(
68426            arrayBuffer,
68427            pImg,
68428            successCallback,
68429            failureCallback,
68430            finishCallback
68431          ) {
68432            var gifReader = new _omggif.default.GifReader(arrayBuffer);
68433            pImg.width = pImg.canvas.width = gifReader.width;
68434            pImg.height = pImg.canvas.height = gifReader.height;
68435            var frames = [];
68436            var numFrames = gifReader.numFrames();
68437            var framePixels = new Uint8ClampedArray(pImg.width * pImg.height * 4);
68438            if (numFrames > 1) {
68439              var loadGIFFrameIntoImage = function loadGIFFrameIntoImage(
68440                frameNum,
68441                gifReader
68442              ) {
68443                try {
68444                  gifReader.decodeAndBlitFrameRGBA(frameNum, framePixels);
68445                } catch (e) {
68446                  _main.default._friendlyFileLoadError(8, pImg.src);
68447                  if (typeof failureCallback === 'function') {
68448                    failureCallback(e);
68449                  } else {
68450                    console.error(e);
68451                  }
68452                }
68453              };
68454              for (var j = 0; j < numFrames; j++) {
68455                var frameInfo = gifReader.frameInfo(j);
68456                // Some GIFs are encoded so that they expect the previous frame
68457                // to be under the current frame. This can occur at a sub-frame level
68458                // There are possible disposal codes but I didn't encounter any
68459                if (gifReader.frameInfo(j).disposal === 1 && j > 0) {
68460                  pImg.drawingContext.putImageData(frames[j - 1].image, 0, 0
68460);
68461                } else {
68462                  pImg.drawingContext.clearRect(0, 0, pImg.width, pImg.height);
68463                  framePixels = new Uint8ClampedArray(pImg.width * pImg.height * 4);
68464                }
68465                loadGIFFrameIntoImage(j, gifReader);
68466                var imageData = new ImageData(framePixels, pImg.width, pImg.height);
68467                pImg.drawingContext.putImageData(imageData, 0, 0);
68468                frames.push({
68469                  image: pImg.drawingContext.getImageData(0, 0, pImg.width, pImg.height),
68470                  delay: frameInfo.delay * 10 //GIF stores delay in one-hundredth of a second, shift to ms
68471                });
68472              }
68473
68474              //Uses Netscape block encoding
68475              //to repeat forever, this will be 0
68476              //to repeat just once, this will be null
68477              //to repeat N times (1<N), should contain integer for loop number
68478              //this is changed to more usable values for us
68479              //to repeat forever, loopCount = null
68480              //everything else is just the number of loops
68481              var loopLimit = gifReader.loopCount();
68482              if (loopLimit === null) {
68483                loopLimit = 1;
68484              } else if (loopLimit === 0) {
68485                loopLimit = null;
68486              }
68487
68488              // we used the pImg for painting and saving during load
68489              // so we have to reset it to the first frame
68490              pImg.drawingContext.putImageData(frames[0].image, 0, 0);
68491
68492              pImg.gifProperties = {
68493                displayIndex: 0,
68494                loopLimit: loopLimit,
68495                loopCount: 0,
68496                frames: frames,
68497                numFrames: numFrames,
68498                playing: true,
68499                timeDisplayed: 0,
68500                lastChangeTime: 0
68501              };
68502            }
68503
68504            if (typeof successCallback === 'function') {
68505              successCallback(pImg);
68506            }
68507            finishCallback();
68508          }
68509
68510          /**
68511           * Validates clipping params. Per drawImage spec sWidth and sHight cannot be
68512           * negative or greater than image intrinsic width and height
68513           * @private
68514           * @param {Number} sVal
68515           * @param {Number} iVal
68516           * @returns {Number}
68517           * @private
68518           */
68519          function _sAssign(sVal, iVal) {
68520            if (sVal > 0 && sVal < iVal) {
68521              return sVal;
68522            } else {
68523              return iVal;
68524            }
68525          }
68526
68527          /**
68528           * Draw an image to the p5.js canvas.
68529           *
68530           * This function can be used with different numbers of parameters. The
68531           * simplest use requires only three parameters: img, x, and y—where (x, y) is
68532           * the position of the image. Two more parameters can optionally be added to
68533           * specify the width and height of the image.
68534           *
68535           * This function can also be used with all eight Number parameters. To
68536           * differentiate between all these parameters, p5.js uses the language of
68537           * "destination rectangle" (which corresponds to "dx", "dy", etc.) and "source
68538           * image" (which corresponds to "sx", "sy", etc.) below. Specifying the
68539           * "source image" dimensions can be useful when you want to display a
68540           * subsection of the source image instead of the whole thing. Here's a diagram
68541           * to explain further:
68542           * <img src="assets/drawImage.png"></img>
68543           *
68544           * @method image
68545           * @param  {p5.Image|p5.Element} img    the image to display
68546           * @param  {Number}   x     the x-coordinate of the top-left corner of the image
68547           * @param  {Number}   y     the y-coordinate of the top-left corner of the image
68548           * @param  {Number}   [width]  the width to draw the image
68549           * @param  {Number}   [height] the height to draw the image
68550           * @example
68551           * <div>
68552           * <code>
68553           * let img;
68554           * function preload() {
68555           *   img = loadImage('assets/laDefense.jpg');
68556           * }
68557           * function setup() {
68558           *   // Top-left corner of the img is at (0, 0)
68559           *   // Width and height are the img's original width and height
68560           *   image(img, 0, 0);
68561           * }
68562           * </code>
68563           * </div>
68564           * <div>
68565           * <code>
68566           * let img;
68567           * function preload() {
68568           *   img = loadImage('assets/laDefense.jpg');
68569           * }
68570           * function setup() {
68571           *   background(50);
68572           *   // Top-left corner of the img is at (10, 10)
68573           *   // Width and height are 50 x 50
68574           *   image(img, 10, 10, 50, 50);
68575           * }
68576           * </code>
68577           * </div>
68578           * <div>
68579           * <code>
68580           * function setup() {
68581           *   // Here, we use a callback to display the image after loading
68582           *   loadImage('assets/laDefense.jpg', img => {
68583           *     image(img, 0, 0);
68584           *   });
68585           * }
68586           * </code>
68587           * </div>
68588           * <div>
68589           * <code>
68590           * let img;
68591           * function preload() {
68592           *   img = loadImage('assets/gradient.png');
68593           * }
68594           * function setup() {
68595           *   // 1. Background image
68596           *   // Top-left corner of the img is at (0, 0)
68597           *   // Width and height are the img's original width and height, 100 x 100
68598           *   image(img, 0, 0);
68599           *   // 2. Top right image
68600           *   // Top-left corner of destination rectangle is at (50, 0)
68601           *   // Destination rectangle width and height are 40 x 20
68602           *   // The next parameters are relative to the source image:
68603           *   // - Starting at position (50, 50) on the source image, capture a 50 x 50
68604           *   // subsection
68605           *   // - Draw this subsection to fill the dimensions of the destination rectangle
68606           *   image(img, 50, 0, 40, 20, 50, 50, 50, 50);
68607           * }
68608           * </code>
68609           * </div>
68610           * @alt
68611           * image of the underside of a white umbrella and gridded ceiling above
68612           * image of the underside of a white umbrella and gridded ceiling above
68613           */
68614          /**
68615           * @method image
68616           * @param  {p5.Image|p5.Element} img
68617           * @param  {Number}   dx     the x-coordinate of the destination
68618           *                           rectangle in which to draw the source image
68619           * @param  {Number}   dy     the y-coordinate of the destination
68620           *                           rectangle in which to draw the source image
68621           * @param  {Number}   dWidth  the width of the destination rectangle
68622           * @param  {Number}   dHeight the height of the destination rectangle
68623           * @param  {Number}   sx     the x-coordinate of the subsection of the source
68624           * image to draw into the destination rectangle
68625           * @param  {Number}   sy     the y-coordinate of the subsection of the source
68626           * image to draw into the destination rectangle
68627           * @param {Number}    [sWidth] the width of the subsection of the
68628           *                           source image to draw into the destination
68629           *                           rectangle
68630           * @param {Number}    [sHeight] the height of the subsection of the
68631           *                            source image to draw into the destination rectangle
68632           */
68633          _main.default.prototype.image = function(
68634            img,
68635            dx,
68636            dy,
68637            dWidth,
68638            dHeight,
68639            sx,
68640            sy,
68641            sWidth,
68642            sHeight
68643          ) {
68644            // set defaults per spec: https://goo.gl/3ykfOq
68645
68646            _main.default._validateParameters('image', arguments);
68647
68648            var defW = img.width;
68649            var defH = img.height;
68650
68651            if (img.elt && img.elt.videoWidth && !img.canvas) {
68652              // video no canvas
68653              defW = img.elt.videoWidth;
68654              defH = img.elt.videoHeight;
68655            }
68656
68657            var _dx = dx;
68658            var _dy = dy;
68659            var _dw = dWidth || defW;
68660            var _dh = dHeight || defH;
68661            var _sx = sx || 0;
68662            var _sy = sy || 0;
68663            var _sw = sWidth || defW;
68664            var _sh = sHeight || defH;
68665
68666            _sw = _sAssign(_sw, defW);
68667            _sh = _sAssign(_sh, defH);
68668
68669            // This part needs cleanup and unit tests
68670            // see issues https://github.com/processing/p5.js/issues/1741
68671            // and https://github.com/processing/p5.js/issues/1673
68672            var pd = 1;
68673
68674            if (img.elt && !img.canvas && img.elt.style.width) {
68675              //if img is video and img.elt.size() has been used and
68676              //no width passed to image()
68677              if (img.elt.videoWidth && !dWidth) {
68678                pd = img.elt.videoWidth;
68679              } else {
68680                //all other cases
68681                pd = img.elt.width;
68682              }
68683              pd /= parseInt(img.elt.style.width, 10);
68684            }
68685
68686            _sx *= pd;
68687            _sy *= pd;
68688            _sh *= pd;
68689            _sw *= pd;
68690
68691            var vals = _helpers.default.modeAdjust(
68692              _dx,
68693              _dy,
68694              _dw,
68695              _dh,
68696              this._renderer._imageMode
68697            );
68698
68699            // tint the image if there is a tint
68700            this._renderer.image(img, _sx, _sy, _sw, _sh, vals.x, vals.y, vals.w, vals.h);
68701          };
68702
68703          /**
68704           * Sets the fill value for displaying images. Images can be tinted to
68705           * specified colors or made transparent by including an alpha value.
68706           *
68707           * To apply transparency to an image without affecting its color, use
68708           * white as the tint color and specify an alpha value. For instance,
68709           * tint(255, 128) will make an image 50% transparent (assuming the default
68710           * alpha range of 0-255, which can be changed with <a href="#/p5/colorMode">colorMode()</a>).
68711           *
68712           * The value for the gray parameter must be less than or equal to the current
68713           * maximum value as specified by <a href="#/p5/colorMode">colorMode()</a>. The default maximum value is
68714           * 255.
68715           *
68716           * @method tint
68717           * @param  {Number}        v1      red or hue value relative to
68718           *                                 the current color range
68719           * @param  {Number}        v2      green or saturation value
68720           *                                 relative to the current color range
68721           * @param  {Number}        v3      blue or brightness value
68722           *                                 relative to the current color range
68723           * @param  {Number}        [alpha]
68724           *
68725           * @example
68726           * <div>
68727           * <code>
68728           * let img;
68729           * function preload() {
68730           *   img = loadImage('assets/laDefense.jpg');
68731           * }
68732           * function setup() {
68733           *   image(img, 0, 0);
68734           *   tint(0, 153, 204); // Tint blue
68735           *   image(img, 50, 0);
68736           * }
68737           * </code>
68738           * </div>
68739           *
68740           * <div>
68741           * <code>
68742           * let img;
68743           * function preload() {
68744           *   img = loadImage('assets/laDefense.jpg');
68745           * }
68746           * function setup() {
68747           *   image(img, 0, 0);
68748           *   tint(0, 153, 204, 126); // Tint blue and set transparency
68749           *   image(img, 50, 0);
68750           * }
68751           * </code>
68752           * </div>
68753           *
68754           * <div>
68755           * <code>
68756           * let img;
68757           * function preload() {
68758           *   img = loadImage('assets/laDefense.jpg');
68759           * }
68760           * function setup() {
68761           *   image(img, 0, 0);
68762           *   tint(255, 126); // Apply transparency without changing color
68763           *   image(img, 50, 0);
68764           * }
68765           * </code>
68766           * </div>
68767           *
68768           * @alt
68769           * 2 side by side images of umbrella and ceiling, one image with blue tint
68770           * Images of umbrella and ceiling, one half of image with blue tint
68771           * 2 side by side images of umbrella and ceiling, one image translucent
68772           */
68773
68774          /**
68775           * @method tint
68776           * @param  {String}        value   a color string
68777           */
68778
68779          /**
68780           * @method tint
68781           * @param  {Number}        gray   a gray value
68782           * @param  {Number}        [alpha]
68783           */
68784
68785          /**
68786           * @method tint
68787           * @param  {Number[]}      values  an array containing the red,green,blue &
68788           *                                 and alpha components of the color
68789           */
68790
68791          /**
68792           * @method tint
68793           * @param  {p5.Color}      color   the tint color
68794           */
68795          _main.default.prototype.tint = function() {
68796            for (
68797              var _len = arguments.length, args = new Array(_len), _key = 0;
68798              _key < _len;
68799              _key++
68800            ) {
68801              args[_key] = arguments[_key];
68802            }
68803            _main.default._validateParameters('tint', args);
68804            var c = this.color.apply(this, args);
68805            this._renderer._tint = c.levels;
68806          };
68807
68808          /**
68809           * Removes the current fill value for displaying images and reverts to
68810           * displaying images with their original hues.
68811           *
68812           * @method noTint
68813           * @example
68814           * <div>
68815           * <code>
68816           * let img;
68817           * function preload() {
68818           *   img = loadImage('assets/bricks.jpg');
68819           * }
68820           * function setup() {
68821           *   tint(0, 153, 204); // Tint blue
68822           *   image(img, 0, 0);
68823           *   noTint(); // Disable tint
68824           *   image(img, 50, 0);
68825           * }
68826           * </code>
68827           * </div>
68828           *
68829           * @alt
68830           * 2 side by side images of bricks, left image with blue tint
68831           */
68832          _main.default.prototype.noTint = function() {
68833            this._renderer._tint = null;
68834          };
68835
68836          /**
68837           * Apply the current tint color to the input image, return the resulting
68838           * canvas.
68839           *
68840           * @private
68841           * @param {p5.Image} The image to be tinted
68842           * @return {canvas} The resulting tinted canvas
68843           */
68844          _main.default.prototype._getTintedImageCanvas = function(img) {
68845            if (!img.canvas) {
68846              return img;
68847            }
68848            var pixels = _filters.default._toPixels(img.canvas);
68849            var tmpCanvas = document.createElement('canvas');
68850            tmpCanvas.width = img.canvas.width;
68851            tmpCanvas.height = img.canvas.height;
68852            var tmpCtx = tmpCanvas.getContext('2d');
68853            var id = tmpCtx.createImageData(img.canvas.width, img.canvas.height);
68854            var newPixels = id.data;
68855
68856            for (var i = 0; i < pixels.length; i += 4) {
68857              var r = pixels[i];
68858              var g = pixels[i + 1];
68859              var b = pixels[i + 2];
68860              var a = pixels[i + 3];
68861
68862              newPixels[i] = r * this._renderer._tint[0] / 255;
68863              newPixels[i + 1] = g * this._renderer._tint[1] / 255;
68864              newPixels[i + 2] = b * this._renderer._tint[2] / 255;
68865              newPixels[i + 3] = a * this._renderer._tint[3] / 255;
68866            }
68867
68868            tmpCtx.putImageData(id, 0, 0);
68869            return tmpCanvas;
68870          };
68871
68872          /**
68873           * Set image mode. Modifies the location from which images are drawn by
68874           * changing the way in which parameters given to <a href="#/p5/image">image()</a> are interpreted.
68875           * The default mode is imageMode(CORNER), which interprets the second and
68876           * third parameters of <a href="#/p5/image">image()</a> as the upper-left corner of the image. If
68877           * two additional parameters are specified, they are used to set the image's
68878           * width and height.
68879           *
68880           * imageMode(CORNERS) interprets the second and third parameters of <a href="#/p5/image">image()</a>
68881           * as the location of one corner, and the fourth and fifth parameters as the
68882           * opposite corner.
68883           *
68884           * imageMode(CENTER) interprets the second and third parameters of <a href="#/p5/image">image()</a>
68885           * as the image's center point. If two additional parameters are specified,
68886           * they are used to set the image's width and height.
68887           *
68888           * @method imageMode
68889           * @param {Constant} mode either CORNER, CORNERS, or CENTER
68890           * @example
68891           *
68892           * <div>
68893           * <code>
68894           * let img;
68895           * function preload() {
68896           *   img = loadImage('assets/bricks.jpg');
68897           * }
68898           * function setup() {
68899           *   imageMode(CORNER);
68900           *   image(img, 10, 10, 50, 50);
68901           * }
68902           * </code>
68903           * </div>
68904           *
68905           * <div>
68906           * <code>
68907           * let img;
68908           * function preload() {
68909           *   img = loadImage('assets/bricks.jpg');
68910           * }
68911           * function setup() {
68912           *   imageMode(CORNERS);
68913           *   image(img, 10, 10, 90, 40);
68914           * }
68915           * </code>
68916           * </div>
68917           *
68918           * <div>
68919           * <code>
68920           * let img;
68921           * function preload() {
68922           *   img = loadImage('assets/bricks.jpg');
68923           * }
68924           * function setup() {
68925           *   imageMode(CENTER);
68926           *   image(img, 50, 50, 80, 80);
68927           * }
68928           * </code>
68929           * </div>
68930           *
68931           * @alt
68932           * small square image of bricks
68933           * horizontal rectangle image of bricks
68934           * large square image of bricks
68935           */
68936          _main.default.prototype.imageMode = function(m) {
68937            _main.default._validateParameters('imageMode', arguments);
68938            if (
68939              m === constants.CORNER ||
68940              m === constants.CORNERS ||
68941              m === constants.CENTER
68942            ) {
68943              this._renderer._imageMode = m;
68944            }
68945          };
68946          var _default = _main.default;
68947          exports.default = _default;
68948        },
68949        {
68950          '../core/constants': 48,
68951          '../core/friendly_errors/fes_core': 51,
68952          '../core/friendly_errors/file_errors': 52,
68953          '../core/friendly_errors/validate_params': 54,
68954          '../core/helpers': 55,
68955          '../core/main': 59,
68956          './filters': 80,
68957          omggif: 33
68958        }
68959      ],
68960      83: [
68961        function(_dereq_, module, exports) {
68962          'use strict';
68963          Object.defineProperty(exports, '__esModule', { value: true });
68964          exports.default = void 0;
68965
68966          var _main = _interopRequireDefault(_dereq_('../core/main'));
68967          var _filters = _interopRequireDefault(_dereq_('./filters'));
68968          function _interopRequireDefault(obj) {
68969            return obj && obj.__esModule ? obj : { default: obj };
68970          }
68971          /**
68972           * @module Image
68973           * @submodule Image
68974           * @requires core
68975           * @requires constants
68976           * @requires filters
68977           */ /**
68978           * This module defines the <a href="#/p5.Image">p5.Image</a> class and P5 methods for
68979           * drawing images to the main display canvas.
68980           */ /*
68981                                                                                                                                                                   * Class methods
68982                                                                                                                                                                   */ /**
68983           * Creates a new <a href="#/p5.Image">p5.Image</a>. A <a href="#/p5.Image">p5.Image</a> is a canvas backed representation of an
68984           * image.
68985           *
68986           * p5 can display .gif, .jpg and .png images. Images may be displayed
68987           * in 2D and 3D space. Before an image is used, it must be loaded with the
68988           * <a href="#/p5/loadImage">loadImage()</a> function. The <a href="#/p5.Image">p5.Image</a> class contains fields for the width and
68989           * height of the image, as well as an array called <a href="#/p5.Image/pixels">pixels[]</a> that contains the
68990           * values for every pixel in the image.
68991           *
68992           * The methods described below allow easy access to the image's pixels and
68993           * alpha channel and simplify the process of compositing.
68994           *
68995           * Before using the <a href="#/p5.Image/pixels">pixels[]</a> array, be sure to use the <a href="#/p5.Image/loadPixels">loadPixels()</a> method on
68996           * the image to make sure that the pixel data is properly loaded.
68997           * @example
68998           * <div><code>
68999           * function setup() {
69000           *   let img = createImage(100, 100); // same as new p5.Image(100, 100);
69001           *   img.loadPixels();
69002           *   createCanvas(100, 100);
69003           *   background(0);
69004           *
69005           *   // helper for writing color to array
69006           *   function writeColor(image, x, y, red, green, blue, alpha) {
69007           *     let index = (x + y * width) * 4;
69008           *     image.pixels[index] = red;
69009           *     image.pixels[index + 1] = green;
69010           *     image.pixels[index + 2] = blue;
69011           *     image.pixels[index + 3] = alpha;
69012           *   }
69013           *
69014           *   let x, y;
69015           *   // fill with random colors
69016           *   for (y = 0;
69016 y < img.height; y++) {
69017           *     for (x = 0; x < img.width; x++) {
69018           *       let red = random(255);
69019           *       let green = random(255);
69020           *       let blue = random(255);
69021           *       let alpha = 255;
69022           *       writeColor(img, x, y, red, green, blue, alpha);
69023           *     }
69024           *   }
69025           *
69026           *   // draw a red line
69027           *   y = 0;
69028           *   for (x = 0; x < img.width; x++) {
69029           *     writeColor(img, x, y, 255, 0, 0, 255);
69030           *   }
69031           *
69032           *   // draw a green line
69033           *   y = img.height - 1;
69034           *   for (x = 0; x < img.width; x++) {
69035           *     writeColor(img, x, y, 0, 255, 0, 255);
69036           *   }
69037           *
69038           *   img.updatePixels();
69039           *   image(img, 0, 0);
69040           * }
69041           * </code></div>
69042           *
69043           * @class p5.Image
69044           * @constructor
69045           * @param {Number} width
69046           * @param {Number} height
69047           */ _main.default.Image = function(width, height) {
69048            /**
69049             * Image width.
69050             * @property {Number} width
69051             * @readOnly
69052             * @example
69053             * <div><code>
69054             * let img;
69055             * function preload() {
69056             *   img = loadImage('assets/rockies.jpg');
69057             * }
69058             *
69059             * function setup() {
69060             *   createCanvas(100, 100);
69061             *   image(img, 0, 0);
69062             *   for (let i = 0; i < img.width; i++) {
69063             *     let c = img.get(i, img.height / 2);
69064             *     stroke(c);
69065             *     line(i, height / 2, i, height);
69066             *   }
69067             * }
69068             * </code></div>
69069             *
69070             * @alt
69071             * rocky mountains in top and horizontal lines in corresponding colors in bottom.
69072             *
69073             */ this.width = width;
69074            /**
69075             * Image height.
69076             * @property {Number} height
69077             * @readOnly
69078             * @example
69079             * <div><code>
69080             * let img;
69081             * function preload() {
69082             *   img = loadImage('assets/rockies.jpg');
69083             * }
69084             *
69085             * function setup() {
69086             *   createCanvas(100, 100);
69087             *   image(img, 0, 0);
69088             *   for (let i = 0; i < img.height; i++) {
69089             *     let c = img.get(img.width / 2, i);
69090             *     stroke(c);
69091             *     line(0, i, width / 2, i);
69092             *   }
69093             * }
69094             * </code></div>
69095             *
69096             * @alt
69097             * rocky mountains on right and vertical lines in corresponding colors on left.
69098             *
69099             */ this.height = height;
69100            this.canvas = document.createElement('canvas');
69101            this.canvas.width = this.width;
69102            this.canvas.height = this.height;
69103            this.drawingContext = this.canvas.getContext('2d');
69104            this._pixelsState = this;
69105            this._pixelDensity = 1;
69106            //Object for working with GIFs, defaults to null
69107            this.gifProperties = null;
69108            //For WebGL Texturing only: used to determine whether to reupload texture to GPU
69109            this._modified = false;
69110            /**
69111             * Array containing the values for all the pixels in the display window.
69112             * These values are numbers. This array is the size (include an appropriate
69113             * factor for pixelDensity) of the display window x4,
69114             * representing the R, G, B, A values in order for each pixel, moving from
69115             * left to right across each row, then down each column. Retina and other
69116             * high density displays may have more pixels (by a factor of
69117             * pixelDensity^2).
69118             * For example, if the image is 100x100 pixels, there will be 40,000. With
69119             * pixelDensity = 2, there will be 160,000. The first four values
69120             * (indices 0-3) in the array will be the R, G, B, A values of the pixel at
69121             * (0, 0). The second four values (indices 4-7) will contain the R, G, B, A
69122             * values of the pixel at (1, 0). More generally, to set values for a pixel
69123             * at (x, y):
69124             * ```javascript
69125             * let d = pixelDensity();
69126             * for (let i = 0; i < d; i++) {
69127             *   for (let j = 0; j < d; j++) {
69128             *     // loop over
69129             *     index = 4 * ((y * d + j) * width * d + (x * d + i
69129));
69130             *     pixels[index] = r;
69131             *     pixels[index+1] = g;
69132             *     pixels[index+2] = b;
69133             *     pixels[index+3] = a;
69134             *   }
69135             * }
69136             * ```
69137             *
69138             * Before accessing this array, the data must loaded with the <a href="#/p5.Image/loadPixels">loadPixels()</a>
69139             * function. After the array data has been modified, the <a href="#/p5.Image/updatePixels">updatePixels()</a>
69140             * function must be run to update the changes.
69141             * @property {Number[]} pixels
69142             * @example
69143             * <div>
69144             * <code>
69145             * let img = createImage(66, 66);
69146             * img.loadPixels();
69147             * for (let i = 0; i < img.width; i++) {
69148             *   for (let j = 0; j < img.height; j++) {
69149             *     img.set(i, j, color(0, 90, 102));
69150             *   }
69151             * }
69152             * img.updatePixels();
69153             * image(img, 17, 17);
69154             * </code>
69155             * </div>
69156             * <div>
69157             * <code>
69158             * let pink = color(255, 102, 204);
69159             * let img = createImage(66, 66);
69160             * img.loadPixels();
69161             * for (let i = 0; i < 4 * (width * height / 2); i += 4) {
69162             *   img.pixels[i] = red(pink);
69163             *   img.pixels[i + 1] = green(pink);
69164             *   img.pixels[i + 2] = blue(pink);
69165             *   img.pixels[i + 3] = alpha(pink);
69166             * }
69167             * img.updatePixels();
69168             * image(img, 17, 17);
69169             * </code>
69170             * </div>
69171             *
69172             * @alt
69173             * 66x66 turquoise rect in center of canvas
69174             * 66x66 pink rect in center of canvas
69175             *
69176             */
69177            this.pixels = [];
69178          };
69179
69180          /**
69181           * Helper function for animating GIF-based images with time
69182           */
69183          _main.default.Image.prototype._animateGif = function(pInst) {
69184            var props = this.gifProperties;
69185            var curTime = pInst._lastFrameTime + pInst.deltaTime;
69186            if (props.lastChangeTime === 0) {
69187              props.lastChangeTime = curTime;
69188            }
69189            if (props.playing) {
69190              props.timeDisplayed = curTime - props.lastChangeTime;
69191              var curDelay = props.frames[props.displayIndex].delay;
69192              if (props.timeDisplayed >= curDelay) {
69193                //GIF is bound to 'realtime' so can skip frames
69194                var skips = Math.floor(props.timeDisplayed / curDelay);
69195                props.timeDisplayed = 0;
69196                props.lastChangeTime = curTime;
69197                props.displayIndex += skips;
69198                props.loopCount = Math.floor(props.displayIndex / props.numFrames);
69199                if (props.loopLimit !== null && props.loopCount >= props.loopLimit) {
69200                  props.playing = false;
69201                } else {
69202                  var ind = props.displayIndex % props.numFrames;
69203                  this.drawingContext.putImageData(props.frames[ind].image, 0, 0);
69204                  props.displayIndex = ind;
69205                  this.setModified(true);
69206                }
69207              }
69208            }
69209          };
69210
69211          /**
69212           * Helper fxn for sharing pixel methods
69213           */
69214          _main.default.Image.prototype._setProperty = function(prop, value) {
69215            this[prop] = value;
69216            this.setModified(true);
69217          };
69218
69219          /**
69220           * Loads the pixels data for this image into the [pixels] attribute.
69221           *
69222           * @method loadPixels
69223           * @example
69224           * <div><code>
69225           * let myImage;
69226           * let halfImage;
69227           *
69228           * function preload() {
69229           *   myImage = loadImage('assets/rockies.jpg');
69230           * }
69231           *
69232           * function setup() {
69233           *   myImage.loadPixels();
69234           *   halfImage = 4 * myImage.width * myImage.height / 2;
69235           *   for (let i = 0; i < halfImage; i++) {
69236           *     myImage.pixels[i + halfImage] = myImage.pixels[i];
69237           *   }
69238           *   myImage.updatePixels();
69239           * }
69240           *
69241           * function draw() {
69242           *   image(myImage, 0, 0, width, height);
69243           * }
69244           * </code></div>
69245           *
69246           * @alt
69247           * 2 images of rocky mountains vertically stacked
69248           */
69249          _main.default.Image.prototype.loadPixels = function() {
69250            _main.default.Renderer2D.prototype.loadPixels.call(this);
69251            this.setModified(true);
69252          };
69253
69254          /**
69255           * Updates the backing canvas for this image with the contents of
69256           * the [pixels] array.
69257           *
69258           * If this image is an animated GIF then the pixels will be updated
69259           * in the frame that is currently displayed.
69260           *
69261           * @method updatePixels
69262           * @param {Integer} x x-offset of the target update area for the
69263           *                              underlying canvas
69264           * @param {Integer} y y-offset of the target update area for the
69265           *                              underlying canvas
69266           * @param {Integer} w height of the target update area for the
69267           *                              underlying canvas
69268           * @param {Integer} h height of the target update area for the
69269           *                              underlying canvas
69270           * @example
69271           * <div><code>
69272           * let myImage;
69273           * let halfImage;
69274           *
69275           * function preload() {
69276           *   myImage = loadImage('assets/rockies.jpg');
69277           * }
69278           *
69279           * function setup() {
69280           *   myImage.loadPixels();
69281           *   halfImage = 4 * myImage.width * myImage.height / 2;
69282           *   for (let i = 0; i < halfImage; i++) {
69283           *     myImage.pixels[i + halfImage] = myImage.pixels[i];
69284           *   }
69285           *   myImage.updatePixels();
69286           * }
69287           *
69288           * function draw() {
69289           *   image(myImage, 0, 0, width, height);
69290           * }
69291           * </code></div>
69292           *
69293           * @alt
69294           * 2 images of rocky mountains vertically stacked
69295           */
69296          /**
69297           * @method updatePixels
69298           */
69299          _main.default.Image.prototype.updatePixels = function(x, y, w, h) {
69300            _main.default.Renderer2D.prototype.updatePixels.call(this, x, y, w, h);
69301            this.setModified(true);
69302          };
69303
69304          /**
69305           * Get a region of pixels from an image.
69306           *
69307           * If no params are passed, the whole image is returned.
69308           * If x and y are the only params passed a single pixel is extracted.
69309           * If all params are passed a rectangle region is extracted and a <a href="#/p5.Image">p5.Image</a>
69310           * is returned.
69311           *
69312           * @method get
69313           * @param  {Number}               x x-coordinate of the pixel
69314           * @param  {Number}               y y-coordinate of the pixel
69315           * @param  {Number}               w width
69316           * @param  {Number}               h height
69317           * @return {p5.Image}             the rectangle <a href="#/p5.Image">p5.Image</a>
69318           * @example
69319           * <div><code>
69320           * let myImage;
69321           * let c;
69322           *
69323           * function preload() {
69324           *   myImage = loadImage('assets/rockies.jpg');
69325           * }
69326           *
69327           * function setup() {
69328           *   background(myImage);
69329           *   noStroke();
69330           *   c = myImage.get(60, 90);
69331           *   fill(c);
69332           *   rect(25, 25, 50, 50);
69333           * }
69334           *
69335           * //get() returns color here
69336           * </code></div>
69337           *
69338           * @alt
69339           * image of rocky mountains with 50x50 green rect in front
69340           */
69341          /**
69342           * @method get
69343           * @return {p5.Image}      the whole <a href="#/p5.Image">p5.Image</a>
69344           */
69345          /**
69346           * @method get
69347           * @param  {Number}        x
69348           * @param  {Number}        y
69349           * @return {Number[]}      color of pixel at x,y in array format [R, G, B, A]
69350           */
69351          _main.default.Image.prototype.get = function(x, y, w, h) {
69352            _main.default._validateParameters('p5.Image.get', arguments);
69353            return _main.default.Renderer2D.prototype.get.apply(this, arguments);
69354          };
69355
69356          _main.default.Image.prototype._getPixel =
69357            _main.default.Renderer2D.prototype._getPixel;
69358
69359          /**
69360           * Set the color of a single pixel or write an image into
69361           * this <a href="#/p5.Image">p5.Image</a>.
69362           *
69363           * Note that for a large number of pixels this will
69364           * be slower than directly manipulating the pixels array
69365           * and then calling <a href="#/p5.Image/updatePixels">updatePixels()</a>.
69366           *
69367           * @method set
69368           * @param {Number}              x x-coordinate of the pixel
69369           * @param {Number}              y y-coordinate of the pixel
69370           * @param {Number|Number[]|Object}   a grayscale value | pixel array |
69371           *                                a <a href="#/p5.Color">p5.Color</a> | image to copy
69372           * @example
69373           * <div>
69374           * <code>
69375           * let img = createImage(66, 66);
69376           * img.loadPixels();
69377           * for (let i = 0; i < img.width; i++) {
69378           *   for (let j = 0;
69378 j < img.height; j++) {
69379           *     img.set(i, j, color(0, 90, 102, (i % img.width) * 2));
69380           *   }
69381           * }
69382           * img.updatePixels();
69383           * image(img, 17, 17);
69384           * image(img, 34, 34);
69385           * </code>
69386           * </div>
69387           *
69388           * @alt
69389           * 2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas
69390           */
69391          _main.default.Image.prototype.set = function(x, y, imgOrCol) {
69392            _main.default.Renderer2D.prototype.set.call(this, x, y, imgOrCol);
69393            this.setModified(true);
69394          };
69395
69396          /**
69397    * Resize the image to a new width and height. To make the image scale
69398    * proportionally, use 0 as the value for the wide or high parameter.
69399    * For instance, to make the width of an image 150 pixels, and change
69400    * the height using the same proportion, use resize(150, 0).
69401    *
69402    * @method resize
69403    * @param {Number} width the resized image width
69404    * @param {Number} height the resized image height
69405    * @example
69406    * <div><code>
69407    * let img;
69408    *
69409    * function preload() {
69410    *   img = loadImage('assets/rockies.jpg');
69411    * }
69412   
69413    * function draw() {
69414    *   image(img, 0, 0);
69415    * }
69416    *
69417    * function mousePressed() {
69418    *   img.resize(50, 100);
69419    * }
69420    * </code></div>
69421    *
69422    * @alt
69423    * image of rocky mountains. zoomed in
69424    */
69425          _main.default.Image.prototype.resize = function(width, height) {
69426            // Copy contents to a temporary canvas, resize the original
69427            // and then copy back.
69428            //
69429            // There is a faster approach that involves just one copy and swapping the
69430            // this.canvas reference. We could switch to that approach if (as i think
69431            // is the case) there an expectation that the user would not hold a
69432            // reference to the backing canvas of a p5.Image. But since we do not
69433            // enforce that at the moment, I am leaving in the slower, but safer
69434            // implementation.
69435
69436            // auto-resize
69437            if (width === 0 && height === 0) {
69438              width = this.canvas.width;
69439              height = this.canvas.height;
69440            } else if (width === 0) {
69441              width = this.canvas.width * height / this.canvas.height;
69442            } else if (height === 0) {
69443              height = this.canvas.height * width / this.canvas.width;
69444            }
69445
69446            width = Math.floor(width);
69447            height = Math.floor(height);
69448
69449            var tempCanvas = document.createElement('canvas');
69450            tempCanvas.width = width;
69451            tempCanvas.height = height;
69452
69453            if (this.gifProperties) {
69454              var props = this.gifProperties;
69455              //adapted from github.com/LinusU/resize-image-data
69456              var nearestNeighbor = function nearestNeighbor(src, dst) {
69457                var pos = 0;
69458                for (var y = 0; y < dst.height; y++) {
69459                  for (var x = 0; x < dst.width; x++) {
69460                    var srcX = Math.floor(x * src.width / dst.width);
69461                    var srcY = Math.floor(y * src.height / dst.height);
69462                    var srcPos = (srcY * src.width + srcX) * 4;
69463                    dst.data[pos++] = src.data[srcPos++]; // R
69464                    dst.data[pos++] = src.data[srcPos++]; // G
69465                    dst.data[pos++] = src.data[srcPos++]; // B
69466                    dst.data[pos++] = src.data[srcPos++]; // A
69467                  }
69468                }
69469              };
69470              for (var i = 0; i < props.numFrames; i++) {
69471                var resizedImageData = this.drawingContext.createImageData(width, height);
69472
69473                nearestNeighbor(props.frames[i].image, resizedImageData);
69474                props.frames[i].image = resizedImageData;
69475              }
69476            }
69477
69478            // prettier-ignore
69479            tempCanvas.getContext('2d').drawImage(
69480  this.canvas,
69481  0, 0, this.canvas.width, this.canvas.height,
69482  0, 0, tempCanvas.width, tempCanvas.height);
69483
69484            // Resize the original canvas, which will clear its contents
69485            this.canvas.width = this.width = width;
69486            this.canvas.height = this.height = height;
69487
69488            //Copy the image back
69489
69490            // prettier-ignore
69491            this.drawingContext.drawImage(
69492  tempCanvas,
69493  0, 0, width, height,
69494  0, 0, width, height);
69495
69496            if (this.pixels.length > 0) {
69497              this.loadPixels();
69498            }
69499
69500            this.setModified(true);
69501          };
69502
69503          /**
69504           * Copies a region of pixels from one image to another. If no
69505           * srcImage is specified this is used as the source. If the source
69506           * and destination regions aren't the same size, it will
69507           * automatically resize source pixels to fit the specified
69508           * target region.
69509           *
69510           * @method copy
69511           * @param  {p5.Image|p5.Element} srcImage source image
69512           * @param  {Integer} sx X coordinate of the source's upper left corner
69513           * @param  {Integer} sy Y coordinate of the source's upper left corner
69514           * @param  {Integer} sw source image width
69515           * @param  {Integer} sh source image height
69516           * @param  {Integer} dx X coordinate of the destination's upper left corner
69517           * @param  {Integer} dy Y coordinate of the destination's upper left corner
69518           * @param  {Integer} dw destination image width
69519           * @param  {Integer} dh destination image height
69520           * @example
69521           * <div><code>
69522           * let photo;
69523           * let bricks;
69524           * let x;
69525           * let y;
69526           *
69527           * function preload() {
69528           *   photo = loadImage('assets/rockies.jpg');
69529           *   bricks = loadImage('assets/bricks.jpg');
69530           * }
69531           *
69532           * function setup() {
69533           *   x = bricks.width / 2;
69534           *   y = bricks.height / 2;
69535           *   photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);
69536           *   image(photo, 0, 0);
69537           * }
69538           * </code></div>
69539           *
69540           * @alt
69541           * image of rocky mountains and smaller image on top of bricks at top left
69542           */
69543          /**
69544           * @method copy
69545           * @param  {Integer} sx
69546           * @param  {Integer} sy
69547           * @param  {Integer} sw
69548           * @param  {Integer} sh
69549           * @param  {Integer} dx
69550           * @param  {Integer} dy
69551           * @param  {Integer} dw
69552           * @param  {Integer} dh
69553           */
69554          _main.default.Image.prototype.copy = function() {
69555            for (
69556              var _len = arguments.length, args = new Array(_len), _key = 0;
69557              _key < _len;
69558              _key++
69559            ) {
69560              args[_key] = arguments[_key];
69561            }
69562            _main.default.prototype.copy.apply(this, args);
69563          };
69564
69565          /**
69566           * Masks part of an image from displaying by loading another
69567           * image and using its alpha channel as an alpha channel for
69568           * this image.
69569           *
69570           * @method mask
69571           * @param {p5.Image} srcImage source image
69572           * @example
69573           * <div><code>
69574           * let photo, maskImage;
69575           * function preload() {
69576           *   photo = loadImage('assets/rockies.jpg');
69577           *   maskImage = loadImage('assets/mask2.png');
69578           * }
69579           *
69580           * function setup() {
69581           *   createCanvas(100, 100);
69582           *   photo.mask(maskImage);
69583           *   image(photo, 0, 0);
69584           * }
69585           * </code></div>
69586           *
69587           * @alt
69588           * image of rocky mountains with white at right
69589           *
69590           * http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
69591           */
69592          // TODO: - Accept an array of alpha values.
69593          //       - Use other channels of an image. p5 uses the
69594          //       blue channel (which feels kind of arbitrary). Note: at the
69595          //       moment this method does not match native processing's original
69596          //       functionality exactly.
69597          _main.default.Image.prototype.mask = function(p5Image) {
69598            if (p5Image === undefined) {
69599              p5Image = this;
69600            }
69601            var currBlend = this.drawingContext.globalCompositeOperation;
69602
69603            var scaleFactor = 1;
69604            if (p5Image instanceof _main.default.Renderer) {
69605              scaleFactor = p5Image._pInst._pixelDensity;
69606            }
69607
69608            var copyArgs = [
69609              p5Image,
69610              0,
69611              0,
69612              scaleFactor * p5Image.width,
69613              scaleFactor * p5Image.height,
69614              0,
69615              0,
69616              this.width,
69617              this.height
69618            ];
69619
69620            this.drawingContext.globalCompositeOperation = 'destination-in';
69621            _main.default.Image.prototype.copy.apply(this, copyArgs);
69622            this.drawingContext.globalCompositeOperation = currBlend;
69623            this.setModified(true);
69624          };
69625
69626          /**
69627           * Applies an image filter to a <a href="#/p5.Image">p5.Image</a>
69628           *
69629           * @method filter
69630           * @param  {Constant} filterType  either THRESHOLD, GRAY, OPAQUE, INVERT,
69631           *                                POSTERIZE, ERODE, DILATE or BLUR.
69632           *                                See Filters.js for docs on
69633           *                                each available filter
69634           * @param  {Number} [filterParam] an optional parameter unique
69635           *                                to each filter, see above
69636           * @example
69637           * <div><code>
69638           * let photo1;
69639           * let photo2;
69640           *
69641           * function preload() {
69642           *   photo1 = loadImage('assets/rockies.jpg');
69643           *   photo2 = loadImage('assets/rockies.jpg');
69644           * }
69645           *
69646           * function setup() {
69647           *   photo2.filter(GRAY);
69648           *   image(photo1, 0, 0);
69649           *   image(photo2, width / 2, 0);
69650           * }
69651           * </code></div>
69652           *
69653           * @alt
69654           * 2 images of rocky mountains left one in color, right in black and white
69655           */
69656          _main.default.Image.prototype.filter = function(operation, value) {
69657            _filters.default.apply(this.canvas, _filters.default[operation], value);
69658            this.setModified(true);
69659          };
69660
69661          /**
69662           * Copies a region of pixels from one image to another, using a specified
69663           * blend mode to do the operation.
69664           *
69665           * @method blend
69666           * @param  {p5.Image} srcImage source image
69667           * @param  {Integer} sx X coordinate of the source's upper left corner
69668           * @param  {Integer} sy Y coordinate of the source's upper left corner
69669           * @param  {Integer} sw source image width
69670           * @param  {Integer} sh source image height
69671           * @param  {Integer} dx X coordinate of the destination's upper left corner
69672           * @param  {Integer} dy Y coordinate of the destination's upper left corner
69673           * @param  {Integer} dw destination image width
69674           * @param  {Integer} dh destination image height
69675           * @param  {Constant} blendMode the blend mode. either
69676           *     BLEND, DARKEST, LIGHTEST, DIFFERENCE,
69677           *     MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,
69678           *     SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.
69679           *
69680           * Available blend modes are: normal | multiply | screen | overlay |
69681           *            darken | lighten | color-dodge | color-burn | hard-light |
69682           *            soft-light | difference | exclusion | hue | saturation |
69683           *            color | luminosity
69684           *
69685           * http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
69686           * @example
69687           * <div><code>
69688           * let mountains;
69689           * let bricks;
69690           *
69691           * function preload() {
69692           *   mountains = loadImage('assets/rockies.jpg');
69693           *   bricks = loadImage('assets/bricks_third.jpg');
69694           * }
69695           *
69696           * function setup() {
69697           *   mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);
69698           *   image(mountains, 0, 0);
69699           *   image(bricks, 0, 0);
69700           * }
69701           * </code></div>
69702           * <div><code>
69703           * let mountains;
69704           * let bricks;
69705           *
69706           * function preload() {
69707           *   mountains = loadImage('assets/rockies.jpg');
69708           *   bricks = loadImage('assets/bricks_third.jpg');
69709           * }
69710           *
69711           * function setup() {
69712           *   mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);
69713           *   image(mountains, 0, 0);
69714           *   image(bricks, 0, 0);
69715           * }
69716           * </code></div>
69717           * <div><code>
69718           * let mountains;
69719           * let bricks;
69720           *
69721           * function preload() {
69722           *   mountains = loadImage('assets/rockies.jpg');
69723           *   bricks = loadImage('assets/bricks_third.jpg');
69724           * }
69725           *
69726           * function setup() {
69727           *   mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);
69728           *   image(mountains, 0, 0);
69729           *   image(bricks, 0, 0);
69730           * }
69731           * </code></div>
69732           *
69733           * @alt
69734           * image of rocky mountains. Brick images on left and right. Right overexposed
69735           * image of rockies. Brickwall images on left and right. Right mortar transparent
69736           * image of rockies. Brickwall images on left and right. Right translucent
69737           */
69738          /**
69739           * @method blend
69740           * @param  {Integer} sx
69741           * @param  {Integer} sy
69742           * @param  {Integer} sw
69743           * @param  {Integer} sh
69744           * @param  {Integer} dx
69745           * @param  {Integer} dy
69746           * @param  {Integer} dw
69747           * @param  {Integer} dh
69748           * @param  {Constant} blendMode
69749           */
69750          _main.default.Image.prototype.blend = function() {
69751            for (
69752              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
69753              _key2 < _len2;
69754              _key2++
69755            ) {
69756              args[_key2] = arguments[_key2];
69757            }
69758            _main.default._validateParameters('p5.Image.blend', arguments);
69759            _main.default.prototype.blend.apply(this, args);
69760            this.setModified(true);
69761          };
69762
69763          /**
69764           * helper method for web GL mode to indicate that an image has been
69765           * changed or unchanged since last upload. gl texture upload will
69766           * set this value to false after uploading the texture.
69767           * @method setModified
69768           * @param {boolean} val sets whether or not the image has been
69769           * modified.
69770           * @private
69771           */
69772          _main.default.Image.prototype.setModified = function(val) {
69773            this._modified = val; //enforce boolean?
69774          };
69775
69776          /**
69777           * helper method for web GL mode to figure out if the image
69778           * has been modified and might need to be re-uploaded to texture
69779           * memory between frames.
69780           * @method isModified
69781           * @private
69782           * @return {boolean} a boolean indicating whether or not the
69783           * image has been updated or modified since last texture upload.
69784           */
69785          _main.default.Image.prototype.isModified = function() {
69786            return this._modified;
69787          };
69788
69789          /**
69790           * Saves the image to a file and force the browser to download it.
69791           * Accepts two strings for filename and file extension
69792           * Supports png (default), jpg, and gif
69793           *<br><br>
69794           * Note that the file will only be downloaded as an animated GIF
69795           * if the p5.Image was loaded from a GIF file.
69796           * @method save
69797           * @param {String} filename give your file a name
69798           * @param  {String} extension 'png' or 'jpg'
69799           * @example
69800           * <div><code>
69801           * let photo;
69802           *
69803           * function preload() {
69804           *   photo = loadImage('assets/rockies.jpg');
69805           * }
69806           *
69807           * function draw() {
69808 
69808          *   image(photo, 0, 0);
69809           * }
69810           *
69811           * function keyTyped() {
69812           *   if (key === 's') {
69813           *     photo.save('photo', 'png');
69814           *   }
69815           * }
69816           * </code></div>
69817           *
69818           * @alt
69819           * image of rocky mountains.
69820           */
69821          _main.default.Image.prototype.save = function(filename, extension) {
69822            if (this.gifProperties) {
69823              _main.default.prototype.saveGif(this, filename);
69824            } else {
69825              _main.default.prototype.saveCanvas(this.canvas, filename, extension);
69826            }
69827          };
69828
69829          // GIF Section
69830          /**
69831           * Starts an animated GIF over at the beginning state.
69832           *
69833           * @method reset
69834           * @example
69835           * <div><code>
69836           * let gif;
69837           *
69838           * function preload() {
69839           *   gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');
69840           * }
69841           *
69842           * function draw() {
69843           *   background(255);
69844           *   // The GIF file that we loaded only loops once
69845           *   // so it freezes on the last frame after playing through
69846           *   image(gif, 0, 0);
69847           * }
69848           *
69849           * function mousePressed() {
69850           *   // Click to reset the GIF and begin playback from start
69851           *   gif.reset();
69852           * }
69853           * </code></div>
69854           * @alt
69855           * Animated image of a cartoon face that winks once and then freezes
69856           * When you click it animates again, winks once and freezes
69857           */
69858          _main.default.Image.prototype.reset = function() {
69859            if (this.gifProperties) {
69860              var props = this.gifProperties;
69861              props.playing = true;
69862              props.timeSinceStart = 0;
69863              props.timeDisplayed = 0;
69864              props.lastChangeTime = 0;
69865              props.loopCount = 0;
69866              props.displayIndex = 0;
69867              this.drawingContext.putImageData(props.frames[0].image, 0, 0);
69868            }
69869          };
69870
69871          /**
69872           * Gets the index for the frame that is currently visible in an animated GIF.
69873           *
69874           * @method getCurrentFrame
69875           * @return {Number}       The index for the currently displaying frame in animated GIF
69876           * @example
69877           * <div><code>
69878           * let gif;
69879           *
69880           * function preload() {
69881           *   gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
69882           * }
69883           *
69884           * function draw() {
69885           *   let frame = gif.getCurrentFrame();
69886           *   image(gif, 0, 0);
69887           *   text(frame, 10, 90);
69888           * }
69889           * </code></div>
69890           * @alt
69891           * Animated image of a cartoon eye looking around and then
69892           * looking outwards, in the lower-left hand corner a number counts
69893           * up quickly to 124 and then starts back over at 0
69894           */
69895          _main.default.Image.prototype.getCurrentFrame = function() {
69896            if (this.gifProperties) {
69897              var props = this.gifProperties;
69898              return props.displayIndex % props.numFrames;
69899            }
69900          };
69901
69902          /**
69903           * Sets the index of the frame that is currently visible in an animated GIF
69904           *
69905           * @method setFrame
69906           * @param {Number}       index the index for the frame that should be displayed
69907           * @example
69908           * <div><code>
69909           * let gif;
69910           *
69911           * function preload() {
69912           *   gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
69913           * }
69914           *
69915           * // Move your mouse up and down over canvas to see the GIF
69916           * // frames animate
69917           * function draw() {
69918           *   gif.pause();
69919           *   image(gif, 0, 0);
69920           *   // Get the highest frame number which is the number of frames - 1
69921           *   let maxFrame = gif.numFrames() - 1;
69922           *   // Set the current frame that is mapped to be relative to mouse position
69923           *   let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));
69924           *   gif.setFrame(frameNumber);
69925           * }
69926           * </code></div>
69927           * @alt
69928           * A still image of a cartoon eye that looks around when you move your mouse
69929           * up and down over the canvas
69930           */
69931          _main.default.Image.prototype.setFrame = function(index) {
69932            if (this.gifProperties) {
69933              var props = this.gifProperties;
69934              if (index < props.numFrames && index >= 0) {
69935                props.timeDisplayed = 0;
69936                props.lastChangeTime = 0;
69937                props.displayIndex = index;
69938                this.drawingContext.putImageData(props.frames[index].image, 0, 0);
69939              } else {
69940                console.log(
69941                  'Cannot set GIF to a frame number that is higher than total number of frames or below zero.'
69942                );
69943              }
69944            }
69945          };
69946
69947          /**
69948           * Returns the number of frames in an animated GIF
69949           *
69950           * @method numFrames
69951           * @return {Number}
69952           * @example     The number of frames in the animated GIF
69953           * <div><code>
69954           * let gif;
69955           *
69956           * function preload() {
69957           *   gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
69958           * }
69959           *
69960           * // Move your mouse up and down over canvas to see the GIF
69961           * // frames animate
69962           * function draw() {
69963           *   gif.pause();
69964           *   image(gif, 0, 0);
69965           *   // Get the highest frame number which is the number of frames - 1
69966           *   let maxFrame = gif.numFrames() - 1;
69967           *   // Set the current frame that is mapped to be relative to mouse position
69968           *   let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));
69969           *   gif.setFrame(frameNumber);
69970           * }
69971           * </code></div>
69972           * @alt
69973           * A still image of a cartoon eye that looks around when you move your mouse
69974           * up and down over the canvas
69975           */
69976          _main.default.Image.prototype.numFrames = function() {
69977            if (this.gifProperties) {
69978              return this.gifProperties.numFrames;
69979            }
69980          };
69981
69982          /**
69983           * Plays an animated GIF that was paused with
69984           * <a href="#/p5.Image/pause">pause()</a>
69985           *
69986           * @method play
69987           * @example
69988           * <div><code>
69989           * let gif;
69990           *
69991           * function preload() {
69992           *   gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');
69993           * }
69994           *
69995           * function draw() {
69996           *   background(255);
69997           *   image(gif, 0, 0);
69998           * }
69999           *
70000           * function mousePressed() {
70001           *   gif.pause();
70002           * }
70003           *
70004           * function mouseReleased() {
70005           *   gif.play();
70006           * }
70007           * </code></div>
70008           * @alt
70009           * An animated GIF of a drawing of small child with
70010           * hair blowing in the wind, when you click the image
70011           * freezes when you release it animates again
70012           */
70013          _main.default.Image.prototype.play = function() {
70014            if (this.gifProperties) {
70015              this.gifProperties.playing = true;
70016            }
70017          };
70018
70019          /**
70020           * Pauses an animated GIF.
70021           *
70022           * @method pause
70023           * @example
70024           * <div><code>
70025           * let gif;
70026           *
70027           * function preload() {
70028           *   gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');
70029           * }
70030           *
70031           * function draw() {
70032           *   background(255);
70033           *   image(gif, 0, 0);
70034           * }
70035           *
70036           * function mousePressed() {
70037           *   gif.pause();
70038           * }
70039           *
70040           * function mouseReleased() {
70041           *   gif.play();
70042           * }
70043           * </code></div>
70044           * @alt
70045           * An animated GIF of a drawing of small child with
70046           * hair blowing in the wind, when you click the image
70047           * freezes when you release it animates again
70048           */
70049          _main.default.Image.prototype.pause = function() {
70050            if (this.gifProperties) {
70051              this.gifProperties.playing = false;
70052            }
70053          };
70054
70055          /**
70056           * Changes the delay between frames in an animated GIF. There is an optional second parameter that
70057           * indicates an index for a specific frame that should have its delay modified. If no index is given, all frames
70058           * will have the new delay.
70059           *
70060           * @method delay
70061           * @param {Number}    d the amount in milliseconds to delay between switching frames
70062           * @param {Number}    [index] the index of the frame that should have the new delay value {optional}
70063           * @example
70064           * <div><code>
70065           * let gifFast, gifSlow;
70066           *
70067           * function preload() {
70068           *   gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
70069           *   gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');
70070           * }
70071           *
70072           * function setup() {
70073           *   gifFast.resize(width / 2, height / 2);
70074           *   gifSlow.resize(width / 2, height / 2);
70075           *
70076           *   //Change the delay here
70077           *   gifFast.delay(10);
70078           *   gifSlow.delay(100);
70079           * }
70080           *
70081           * function draw() {
70082           *   background(255);
70083           *   image(gifFast, 0, 0);
70084           *   image(gifSlow, width / 2, 0);
70085           * }
70086           * </code></div>
70087           * @alt
70088           * Two animated gifs of cartoon eyes looking around
70089           * The gif on the left animates quickly, on the right
70090           * the animation is much slower
70091           */
70092          _main.default.Image.prototype.delay = function(d, index) {
70093            if (this.gifProperties) {
70094              var props = this.gifProperties;
70095              if (index < props.numFrames && index >= 0) {
70096                props.frames[index].delay = d;
70097              } else {
70098                // change all frames
70099                var _iteratorNormalCompletion = true;
70100                var _didIteratorError = false;
70101                var _iteratorError = undefined;
70102                try {
70103                  for (
70104                    var _iterator = props.frames[Symbol.iterator](), _step;
70105                    !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
70106                    _iteratorNormalCompletion = true
70107                  ) {
70108                    var frame = _step.value;
70109                    frame.delay = d;
70110                  }
70111                } catch (err) {
70112                  _didIteratorError = true;
70113                  _iteratorError = err;
70114                } finally {
70115                  try {
70116                    if (!_iteratorNormalCompletion && _iterator.return != null) {
70117                      _iterator.return();
70118                    }
70119                  } finally {
70120                    if (_didIteratorError) {
70121                      throw _iteratorError;
70122                    }
70123                  }
70124                }
70125              }
70126            }
70127          };
70128          var _default = _main.default.Image;
70129          exports.default = _default;
70130        },
70131        { '../core/main': 59, './filters': 80 }
70132      ],
70133      84: [
70134        function(_dereq_, module, exports) {
70135          'use strict';
70136          Object.defineProperty(exports, '__esModule', { value: true });
70137          exports.default = void 0;
70138
70139          var _main = _interopRequireDefault(_dereq_('../core/main'));
70140          var _filters = _interopRequireDefault(_dereq_('./filters'));
70141          _dereq_('../color/p5.Color');
70142          function _interopRequireDefault(obj) {
70143            return obj && obj.__esModule ? obj : { default: obj };
70144          }
70145          /**
70146           * @module Image
70147           * @submodule Pixels
70148           * @for p5
70149           * @requires core
70150           */ /**
70151           * <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
70152           * /Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>
70153           * containing the values for all the pixels in the display window.
70154           * These values are numbers. This array is the size (include an appropriate
70155           * factor for <a href="#/p5/pixelDensity">pixelDensity</a>) of the display window x4,
70156           * representing the R, G, B, A values in order for each pixel, mov
70156ing from
70157           * left to right across each row, then down each column. Retina and other
70158           * high density displays will have more pixels[] (by a factor of
70159           * pixelDensity^2).
70160           * For example, if the image is 100x100 pixels, there will be 40,000. On a
70161           * retina display, there will be 160,000.
70162           *
70163           * The first four values (indices 0-3) in the array will be the R, G, B, A
70164           * values of the pixel at (0, 0). The second four values (indices 4-7) will
70165           * contain the R, G, B, A values of the pixel at (1, 0). More generally, to
70166           * set values for a pixel at (x, y):
70167           * ```javascript
70168           * let d = pixelDensity();
70169           * for (let i = 0; i < d; i++) {
70170           *   for (let j = 0; j < d; j++) {
70171           *     // loop over
70172           *     index = 4 * ((y * d + j) * width * d + (x * d + i));
70173           *     pixels[index] = r;
70174           *     pixels[index+1] = g;
70175           *     pixels[index+2] = b;
70176           *     pixels[index+3] = a;
70177           *   }
70178           * }
70179           * ```
70180           * While the above method is complex, it is flexible enough to work with
70181           * any pixelDensity. Note that <a href="#/p5/set">set()</a> will automatically take care of
70182           * setting all the appropriate values in <a href="#/p5/pixels">pixels[]</a> for a given (x, y) at
70183           * any pixelDensity, but the performance may not be as fast when lots of
70184           * modifications are made to the pixel array.
70185           *
70186           * Before accessing this array, the data must loaded with the <a href="#/p5/loadPixels">loadPixels()</a>
70187           * function. After the array data has been modified, the <a href="#/p5/updatePixels">updatePixels()</a>
70188           * function must be run to update the changes.
70189           *
70190           * Note that this is not a standard javascript array.  This means that
70191           * standard javascript functions such as <a href="#/p5/slice">slice()</a> or
70192           * <a href="#/p5/arrayCopy">arrayCopy()</a> do not
70193           * work.
70194           *
70195           * @property {Number[]} pixels
70196           * @example
70197           * <div>
70198           * <code>
70199           * let pink = color(255, 102, 204);
70200           * loadPixels();
70201           * let d = pixelDensity();
70202           * let halfImage = 4 * (width * d) * (height / 2 * d);
70203           * for (let i = 0; i < halfImage; i += 4) {
70204           *   pixels[i] = red(pink);
70205           *   pixels[i + 1] = green(pink);
70206           *   pixels[i + 2] = blue(pink);
70207           *   pixels[i + 3] = alpha(pink);
70208           * }
70209           * updatePixels();
70210           * </code>
70211           * </div>
70212           *
70213           * @alt
70214           * top half of canvas pink, bottom grey
70215           */ _main.default.prototype.pixels = []; /**
70216           * Copies a region of pixels from one image to another, using a specified
70217           * blend mode to do the operation.
70218           *
70219           * @method blend
70220           * @param  {p5.Image} srcImage source image
70221           * @param  {Integer} sx X coordinate of the source's upper left corner
70222           * @param  {Integer} sy Y coordinate of the source's upper left corner
70223           * @param  {Integer} sw source image width
70224           * @param  {Integer} sh source image height
70225           * @param  {Integer} dx X coordinate of the destination's upper left corner
70226           * @param  {Integer} dy Y coordinate of the destination's upper left corner
70227           * @param  {Integer} dw destination image width
70228           * @param  {Integer} dh destination image height
70229           * @param  {Constant} blendMode the blend mode. either
70230           *     BLEND, DARKEST, LIGHTEST, DIFFERENCE,
70231           *     MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,
70232           *     SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.
70233           *
70234           * @example
70235           * <div><code>
70236           * let img0;
70237           * let img1;
70238           *
70239           * function preload() {
70240           *   img0 = loadImage('assets/rockies.jpg');
70241           *   img1 = loadImage('assets/bricks_third.jpg');
70242           * }
70243           *
70244           * function setup() {
70245           *   background(img0);
70246           *   image(img1, 0, 0);
70247           *   blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);
70248           * }
70249           * </code></div>
70250           * <div><code>
70251           * let img0;
70252           * let img1;
70253           *
70254           * function preload() {
70255           *   img0 = loadImage('assets/rockies.jpg');
70256           *   img1 = loadImage('assets/bricks_third.jpg');
70257           * }
70258           *
70259           * function setup() {
70260           *   background(img0);
70261           *   image(img1, 0, 0);
70262           *   blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);
70263           * }
70264           * </code></div>
70265           * <div><code>
70266           * let img0;
70267           * let img1;
70268           *
70269           * function preload() {
70270           *   img0 = loadImage('assets/rockies.jpg');
70271           *   img1 = loadImage('assets/bricks_third.jpg');
70272           * }
70273           *
70274           * function setup() {
70275           *   background(img0);
70276           *   image(img1, 0, 0);
70277           *   blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);
70278           * }
70279           * </code></div>
70280           *
70281           * @alt
70282           * image of rocky mountains. Brick images on left and right. Right overexposed
70283           * image of rockies. Brickwall images on left and right. Right mortar transparent
70284           * image of rockies. Brickwall images on left and right. Right translucent
70285           *
70286           */
70287          /**
70288           * @method blend
70289           * @param  {Integer} sx
70290           * @param  {Integer} sy
70291           * @param  {Integer} sw
70292           * @param  {Integer} sh
70293           * @param  {Integer} dx
70294           * @param  {Integer} dy
70295           * @param  {Integer} dw
70296           * @param  {Integer} dh
70297           * @param  {Constant} blendMode
70298           */
70299          _main.default.prototype.blend = function() {
70300            for (
70301              var _len = arguments.length, args = new Array(_len), _key = 0;
70302              _key < _len;
70303              _key++
70304            ) {
70305              args[_key] = arguments[_key];
70306            }
70307            _main.default._validateParameters('blend', args);
70308            if (this._renderer) {
70309              var _this$_renderer;
70310              (_this$_renderer = this._renderer).blend.apply(_this$_renderer, args);
70311            } else {
70312              _main.default.Renderer2D.prototype.blend.apply(this, args);
70313            }
70314          };
70315
70316          /**
70317           * Copies a region of the canvas to another region of the canvas
70318           * and copies a region of pixels from an image used as the srcImg parameter
70319           * into the canvas srcImage is specified this is used as the source. If
70320           * the source and destination regions aren't the same size, it will
70321           * automatically resize source pixels to fit the specified
70322           * target region.
70323           *
70324           * @method copy
70325           * @param  {p5.Image|p5.Element} srcImage source image
70326           * @param  {Integer} sx X coordinate of the source's upper left corner
70327           * @param  {Integer} sy Y coordinate of the source's upper left corner
70328           * @param  {Integer} sw source image width
70329           * @param  {Integer} sh source image height
70330           * @param  {Integer} dx X coordinate of the destination's upper left corner
70331           * @param  {Integer} dy Y coordinate of the destination's upper left corner
70332           * @param  {Integer} dw destination image width
70333           * @param  {Integer} dh destination image height
70334           *
70335           * @example
70336           * <div><code>
70337           * let img;
70338           *
70339           * function preload() {
70340           *   img = loadImage('assets/rockies.jpg');
70341           * }
70342           *
70343           * function setup() {
70344           *   background(img);
70345           *   copy(img, 7, 22, 10, 10, 35, 25, 50, 50);
70346           *   stroke(255);
70347           *   noFill();
70348           *   // Rectangle shows area being copied
70349           *   rect(7, 22, 10, 10);
70350           * }
70351           * </code></div>
70352           *
70353           * @alt
70354           * image of rocky mountains. Brick images on left and right. Right overexposed
70355           * image of rockies. Brickwall images on left and right. Right mortar transparent
70356           * image of rockies. Brickwall images on left and right. Right translucent
70357           */
70358          /**
70359           * @method copy
70360           * @param  {Integer} sx
70361           * @param  {Integer} sy
70362           * @param  {Integer} sw
70363           * @param  {Integer} sh
70364           * @param  {Integer} dx
70365           * @param  {Integer} dy
70366           * @param  {Integer} dw
70367           * @param  {Integer} dh
70368           */
70369          _main.default.prototype.copy = function() {
70370            for (
70371              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
70372              _key2 < _len2;
70373              _key2++
70374            ) {
70375              args[_key2] = arguments[_key2];
70376            }
70377            _main.default._validateParameters('copy', args);
70378
70379            var srcImage, sx, sy, sw, sh, dx, dy, dw, dh;
70380            if (args.length === 9) {
70381              srcImage = args[0];
70382              sx = args[1];
70383              sy = args[2];
70384              sw = args[3];
70385              sh = args[4];
70386              dx = args[5];
70387              dy = args[6];
70388              dw = args[7];
70389              dh = args[8];
70390            } else if (args.length === 8) {
70391              srcImage = this;
70392              sx = args[0];
70393              sy = args[1];
70394              sw = args[2];
70395              sh = args[3];
70396              dx = args[4];
70397              dy = args[5];
70398              dw = args[6];
70399              dh = args[7];
70400            } else {
70401              throw new Error('Signature not supported');
70402            }
70403
70404            _main.default.prototype._copyHelper(
70405              this,
70406              srcImage,
70407              sx,
70408              sy,
70409              sw,
70410              sh,
70411              dx,
70412              dy,
70413              dw,
70414              dh
70415            );
70416          };
70417
70418          _main.default.prototype._copyHelper = function(
70419            dstImage,
70420            srcImage,
70421            sx,
70422            sy,
70423            sw,
70424            sh,
70425            dx,
70426            dy,
70427            dw,
70428            dh
70429          ) {
70430            srcImage.loadPixels();
70431            var s = srcImage.canvas.width / srcImage.width;
70432            // adjust coord system for 3D when renderer
70433            // ie top-left = -width/2, -height/2
70434            var sxMod = 0;
70435            var syMod = 0;
70436            if (srcImage._renderer && srcImage._renderer.isP3D) {
70437              sxMod = srcImage.width / 2;
70438              syMod = srcImage.height / 2;
70439            }
70440            if (dstImage._renderer && dstImage._renderer.isP3D) {
70441              _main.default.RendererGL.prototype.image.call(
70442                dstImage._renderer,
70443                srcImage,
70444                sx + sxMod,
70445                sy + syMod,
70446                sw,
70447                sh,
70448                dx,
70449                dy,
70450                dw,
70451                dh
70452              );
70453            } else {
70454              dstImage.drawingContext.drawImage(
70455                srcImage.canvas,
70456                s * (sx + sxMod),
70457                s * (sy + syMod),
70458                s * sw,
70459                s * sh,
70460                dx,
70461                dy,
70462                dw,
70463                dh
70464              );
70465            }
70466          };
70467
70468          /**
70469           * Applies a filter to the canvas. The presets options are:
70470           *
70471           * THRESHOLD
70472           * Converts the image to black and white pixels depending if they are above or
70473           * below the threshold defined by the level parameter. The parameter must be
70474           * between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.
70475           *
70476           * GRAY
70477           * Converts any colors in the image to grayscale equivalents. No parameter
70478           * is used.
70479           *
70480           * OPAQUE
70481           * Sets the alpha channel to entirely opaque. No parameter is used.
70482           *
70483           * INVERT
70484           * Sets each pixel to its inverse value. No parameter is used.
70485           *
70486           * POSTERIZE
70487           * Limits each channel of the image to the number of colors specified as the
70488           * parameter. The parameter can be set to values between 2 and 255, but
70489           * results are most noticeable in the lower ranges.
70490           *
70491           * BLUR
70492           * Executes a Gaussian blur with the level parameter specifying the extent
70493           * of the blurring. If no parameter is used, the blur is equivalent to
70494           * Gaussian blur of radius 1. Larger values increase the blur.
70495           *
70496           * ERODE
70497           * Reduces the light areas. No parameter is used.
70498           *
70499           * DILATE
70500           * Increases the light areas. No parameter is used.
70501           *
70502           * filter() does not work in WEBGL mode.
70503           * A similar effect can be achieved in WEBGL mode using custom
70504           * shaders. Adam Ferriss has written
70505           * a <a href="https://github.com/aferriss/p5jsShaderExamples"
70506           * target='_blank'>selection of shader examples</a> that contains many
70507           * of the effects present in the filter examples.
70508           *
70509           * @method filter
70510           * @param  {Constant} filterType  either THRESHOLD, GRAY, OPAQUE, INVERT,
70511           *                                POSTERIZE, BLUR, ERODE, DILATE or BLUR.
70512           *                                See Filters.js for docs on
70513           *                                each available filter
70514           * @param  {Number} [filterParam] an optional parameter unique
70515           *                                to each filter, see above
70516           *
70517           * @example
70518           * <div>
70519           * <code>
70520           * let img;
70521           * function preload() {
70522           *   img = loadImage('assets/bricks.jpg');
70523           * }
70524           * function setup() {
70525           *   image(img, 0, 0);
70526           *   filter(THRESHOLD);
70527           * }
70528           * </code>
70529           * </div>
70530           *
70531           * <div>
70532           * <code>
70533           * let img;
70534           * function preload() {
70535           *   img = loadImage('assets/bricks.jpg');
70536           * }
70537           * function setup() {
70538           *   image(img, 0, 0);
70539           *   filter(GRAY);
70540           * }
70541           * </code>
70542           * </div>
70543           *
70544           * <div>
70545           * <code>
70546           * let img;
70547           * function preload() {
70548           *   img = loadImage('assets/bricks.jpg');
70549           * }
70550           * function setup() {
70551           *   image(img, 0, 0);
70552           *   filter(OPAQUE);
70553           * }
70554           * </code>
70555           * </div>
70556           *
70557           * <div>
70558           * <code>
70559           * let img;
70560           * function preload() {
70561           *   img = loadImage('assets/bricks.jpg');
70562           * }
70563           * function setup() {
70564           *   image(img, 0, 0);
70565           *   filter(INVERT);
70566           * }
70567           * </code>
70568           * </div>
70569           *
70570           * <div>
70571           * <code>
70572           * let img;
70573           * function preload() {
70574           *   img = loadImage('assets/bricks.jpg');
70575           * }
70576           * function setup() {
70577           *   image(img, 0, 0);
70578           *   filter(POSTERIZE, 3);
70579           * }
70580           * </code>
70581           * </div>
70582           *
70583           * <div>
70584           * <code>
70585           * let img;
70586           * function preload() {
70587           *   img = loadImage('assets/bricks.jpg');
70588           * }
70589           * function setup() {
70590           *   image(img, 0, 0);
70591           *   filter(DILATE);
70592           * }
70593           * </code>
70594           * </div>
70595           *
70596           * <div>
70597           * <code>
70598           * let img;
70599           * function preload() {
70600           *   img = loadImage('assets/bricks.jpg');
70601           * }
70602           * function setup() {
70603           *   image(img, 0, 0);
70604           *   filter(BLUR, 3);
70605           * }
70606           * </code>
70607           * </div>
70608           *
70609           * <div>
70610           * <code>
70611           * let img;
70612           * function preload() {
70613           *   img = loadImage('assets/bricks.jpg');
70614           * }
70615           * function setup() {
70616           *   image(img, 0, 0);
70617           *   filter(ERODE);
70618           * }
70619           * </code>
70620           * </div>
70621           *
70622           * @alt
70623           * black and white image of a brick wall.
70624           * greyscale image of a brickwall
70625           * image of a brickwall
70626           * jade colored image of a brickwall
70627           * red and pink image of a brickwall
70628           * image of a brickwall
70629           * blurry image of a brickwall
70630           * image of a brickwall
70631           * image of a brickwall with less detail
70632           */
70633          _main.default.prototype.filter = function(operation, value) {
70634            _main.default._validateParameters('filter', arguments);
70635            if (this.canvas !== undefined) {
70636              _filters.default.apply(this.canvas, _filters.default[operation], value);
70637            } else {
70638              _filters.default.apply(this.elt, _filters.default[operation], value);
70639            }
70640          };
70641
70642          /**
70643           * Get a region of pixels, or a single pixel, from the canvas.
70644           *
70645           * Returns an array of [R,G,B,A] values for any pixel or grabs a section of
70646           * an image. If no parameters are specified, the entire image is returned.
70647           * Use the x and y parameters to get the value of one pixel. Get a section of
70648           * the display window by specifying additional w and h parameters. When
70649           * getting an image, the x and y parameters define the coordinates for the
70650           * upper-left corner of the image, regardless of the current <a href="#/p5/imageMode">imageMode()</a>.
70651           *
70652           * Getting the color of a single pixel with get(x, y) is easy, but not as fast
70653           * as grabbing the data directly from <a href="#/p5/pixels">pixels[]</a>. The equivalent statement to
70654           * get(x, y) using <a href="#/p5/pixels">pixels[]</a> with pixel density d is
70655           * ```javascript
70656           * let x, y, d; // set these to the coordinates
70657           * let off = (y * width + x) * d * 4;
70658           * let components = [
70659           *   pixels[off],
70660           *   pixels[off + 1],
70661           *   pixels[off + 2],
70662           *   pixels[off + 3]
70663           * ];
70664           * print(components);
70665           * ```
70666           * See the reference for <a href="#/p5/pixels">pixels[]</a> for more information.
70667           *
70668           * If you want to extract an array of colors or a subimage from an p5.Image object,
70669           * take a look at <a href="#/p5.Image/get">p5.Image.get()</a>
70670           *
70671           * @method get
70672           * @param  {Number}         x x-coordinate of the pixel
70673           * @param  {Number}         y y-coordinate of the pixel
70674           * @param  {Number}         w width
70675           * @param  {Number}         h height
70676           * @return {p5.Image}       the rectangle <a href="#/p5.Image">p5.Image</a>
70677           * @example
70678           * <div>
70679           * <code>
70680           * let img;
70681           * function preload() {
70682           *   img = loadImage('assets/rockies.jpg');
70683           * }
70684           * function setup() {
70685           *   image(img, 0, 0);
70686           *   let c = get();
70687           *   image(c, width / 2, 0);
70688           * }
70689           * </code>
70690           * </div>
70691           *
70692           * <div>
70693           * <code>
70694           * let img;
70695           * function preload() {
70696           *   img = loadImage('assets/rockies.jpg');
70697           * }
70698           * function setup() {
70699           *   image(img, 0, 0);
70700           *   let c = get(50, 90);
70701           *   fill(c);
70702           *   noStroke();
70703           *   rect(25, 25, 50, 50);
70704           * }
70705           * </code>
70706           * </div>
70707           *
70708           * @alt
70709           * 2 images of the rocky mountains, side-by-side
70710           * Image of the rocky mountains with 50x50 green rect in center of canvas
70711           */
70712          /**
70713           * @method get
70714           * @return {p5.Image}      the whole <a href="#/p5.Image">p5.Image</a>
70715           */
70716          /**
70717           * @method get
70718           * @param  {Number}        x
70719           * @param  {Number}        y
70720           * @return {Number[]}      color of pixel at x,y in array format [R, G, B, A]
70721           */
70722          _main.default.prototype.get = function(x, y, w, h) {
70723            var _this$_renderer2;
70724            _main.default._validateParameters('get', arguments);
70725            return (_this$_renderer2 = this._renderer).get.apply(
70726              _this$_renderer2,
70727              arguments
70728            );
70729          };
70730
70731          /**
70732           * Loads the pixel data for the display window into the <a href="#/p5/pixels">pixels[]</a> array. This
70733           * function must always be called before reading from or writing to <a href="#/p5/pixels">pixels[]</a>.
70734           * Note that only changes made with <a href="#/p5/set">set()</a> or direct manipulation of <a href="#/p5/pixels">pixels[]</a>
70735           * will occur.
70736           *
70737           * @method loadPixels
70738           * @example
70739           * <div>
70740           * <code>
70741           * let img;
70742           * function preload() {
70743           *   img = loadImage('assets/rockies.jpg');
70744           * }
70745           *
70746           * function setup() {
70747           *   image(img, 0, 0, width, height);
70748           *   let d = pixelDensity();
70749           *   let halfImage = 4 * (width * d) * (height * d / 2);
70750           *   loadPixels();
70751           *   for (let i = 0; i < halfImage; i++) {
70752           *     pixels[i + halfImage] = pixels[i];
70753           *   }
70754           *   updatePixels();
70755           * }
70756           * </code>
70757           * </div>
70758           *
70759           * @alt
70760           * two images of the rocky mountains. one on top, one on bottom of canvas.
70761           */
70762          _main.default.prototype.loadPixels = function() {
70763            for (
70764              var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;
70765              _key3 < _len3;
70766              _key3++
70767            ) {
70768              args[_key3] = arguments[_key3];
70769            }
70770            _main.default._validateParameters('loadPixels', args);
70771            this._renderer.loadPixels();
70772          };
70773
70774          /**
70775           * Changes the color of any pixel, or writes an image directly to the
70776           * display window.
70777           * The x and y parameters specify the pixel to change and the c parameter
70778           * specifies the color value. This can be a <a href="#/p5.Color">p5.Color</a> object, or [R, G, B, A]
70779           * pixel array. It can also be a single grayscale value.
70780           * When setting an image, the x and y parameters define the coordinates for
70781           * the upper-left corner of the image, regardless of the current <a href="#/p5/imageMode">imageMode()</a>.
70782           *
70783           * After using <a href="#/p5/set">set()</a>, you must call <a href="#/p5/updatePixels">updatePixels()</a> for your changes to appear.
70784           * This should be called once all pixels have been set, and must be called before
70785           * calling .<a href="#/p5/get">get()</a> or drawing the image.
70786           *
70787           * Setting the color of a single pixel with set(x, y) is easy, but not as
70788           * fast as putting the data directly into <a href="#/p5/pixels">pixels[]</a>. Setting the <a href="#/p5/pixels">pixels[]</a>
70789           * values directly may be complicated when working with a retina display,
70790           * but will perform better when lots of pixels need to be set directly on
70791           * every loop. See the reference for <a href="#/p5/pixels">pixels[]</a> for more information.
70792           *
70793           * @method set
70794           * @param {Number}              x x-coordinate of the pixel
70795           * @param {Number}              y y-coordinate of the pixel
70796           * @param {Number|Number[]|Object} c insert a grayscale value | a pixel array |
70797           *                                a <a href="#/p5.Color">p5.Color</a> object | a <a href="#/p5.Image">p5.Image</a> to copy
70798           * @example
70799           * <div>
70800           * <code>
70801           * let black = color(0);
70802           * set(30, 20, black);
70803           * set(85, 20, black);
70804           * set(85, 75, black);
70805           * set(30, 75, black);
70806           * updatePixels();
70807           * </code>
70808           * </div>
70809           *
70810           * <div>
70811           * <code>
70812           * for (let i = 30; i < width - 15; i++) {
70813           *   for (let j = 20; j < height - 25; j++) {
70814           *     let c = color(204 - j, 153 - i, 0);
70815           *     set(i, j, c);
70816           *   }
70817           * }
70818           * updatePixels();
70819           * </code>
70820           * </div>
70821           *
70822           * <div>
70823           * <code>
70824           * let img;
70825           * function preload() {
70826           *   img = loadImage('assets/rockies.jpg');
70827           * }
70828           *
70829           * function setup() {
70830           *   set(0, 0, img);
70831           *   updatePixels();
70832           *   line(0, 0, width, height);
70833           *   line(0, height, width, 0);
70834           * }
70835           * </code>
70836           * </div>
70837           *
70838           * @alt
70839           * 4 black points in the shape of a square middle-right of canvas.
70840           * square with orangey-brown gradient lightening at bottom right.
70841           * image of the rocky mountains. with lines like an 'x' through the center.
70842           */
70843          _main.default.prototype.set = function(x, y, imgOrCol) {
70844            this._renderer.set(x, y, imgOrCol);
70845          };
70846          /**
70847           * Updates the display window with the data in the <a href="#/p5/pixels">pixels[]</a> array.
70848           * Use in conjunction with <a href="#/p5/loadPixels">loadPixels()</a>. If you're only reading pixels from
70849           * the array, there's no need to call <a href="#/p5/updatePixels">updatePixels()</a> — updating is only
70850           * necessary to apply changes. <a href="#/p5/updatePixels">updatePixels()</a> should be called anytime the
70851           * pixels array is manipulated or <a href="#/p5/set">set()</a> is called, and only changes made with
70852           * <a href="#/p5/set">set()</a> or direct changes to <a href="#/p5/pixels">pixels[]</a> will occur.
70853           *
70854           * @method updatePixels
70855           * @param  {Number} [x]    x-coordinate of the upper-left corner of region
70856           *                         to update
70857           * @param  {Number} [y]    y-coordinate of the upper-left corner of region
70858           *                         to update
70859           * @param  {Number} [w]    width of region to update
70860           * @param  {Number} [h]    height of region to update
70861           * @example
70862           * <div>
70863           * <code>
70864           * let img;
70865           * function preload() {
70866           *   img = loadImage('assets/rockies.jpg');
70867           * }
70868           *
70869           * function setup() {
70870           *   image(img, 0, 0, width, height);
70871           *   let d = pixelDensity();
70872           *   let halfImage = 4 * (width * d) * (height * d / 2);
70873           *   loadPixels();
70874           *   for (let i = 0; i < halfImage; i++) {
70875           *     pixels[i + halfImage] = pixels[i];
70876           *   }
70877           *   updatePixels();
70878           * }
70879           * </code>
70880           * </div>
70881           * @alt
70882           * two images of the rocky mountains. one on top, one on bottom of canvas.
70883           */
70884          _main.default.prototype.updatePixels = function(x, y, w, h) {
70885            _main.default._validateParameters('updatePixels', arguments);
70886            // graceful fail - if loadPixels() or set() has not been called, pixel
70887            // array will be empty, ignore call to updatePixels()
70888            if (this.pixels.length === 0) {
70889              return;
70890            }
70891            this._renderer.updatePixels(x, y, w, h);
70892          };
70893          var _default = _main.default;
70894          exports.default = _default;
70895        },
70896        { '../color/p5.Color': 46, '../core/main': 59, './filters': 80 }
70897      ],
70898      85: [
vendor: 4,587 bytes, lines 70899-70939
70899        function(_dereq_, module, exports) {
70900          'use strict';
70901          Object.defineProperty(exports, '__esModule', { value: true });
70902          exports.default = void 0;
70903
70904          var _main = _interopRequireDefault(_dereq_('../core/main'));
70905          _dereq_('whatwg-fetch');
70906          _dereq_('es6-promise/auto');
70907          var _fetchJsonp = _interopRequireDefault(_dereq_('fetch-jsonp'));
70908          var _fileSaver = _interopRequireDefault(_dereq_('file-saver'));
70909          _dereq_('../core/friendly_errors/validate_params');
70910          _dereq_('../core/friendly_errors/file_errors');
70911          _dereq_('../core/friendly_errors/fes_core');
70912          function _interopRequireDefault(obj) {
70913            return obj && obj.__esModule ? obj : { default: obj };
70914          }
70915          function _typeof(obj) {
70916            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
70917              _typeof = function _typeof(obj) {
70918                return typeof obj;
70919              };
70920            } else {
70921              _typeof = function _typeof(obj) {
70922                return obj &&
70923                  typeof Symbol === 'function' &&
70924                  obj.constructor === Symbol &&
70925                  obj !== Symbol.prototype
70926                  ? 'symbol'
70927                  : typeof obj;
70928              };
70929            }
70930            return _typeof(obj);
70931          }
70932
70933          /**
70934                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * Loads a JSON file from a file or a URL, and returns an Object.
70935                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * Note that even if the JSON file contains an Array, an Object will be
70936                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * returned with index numbers as keys.
70937                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
70938                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * This method is asynchronous, meaning it may not finish before the next
70939                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * line in your sketch is executed. JSONP is supported via a polyfill and 
70939you
70940                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * can pass in as the second argument an object with definitions of the json
70941                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * callback following the syntax specified <a href="https://github.com/camsong/
70942                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * fetch-jsonp">here</a>.
70943                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
70944                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * This method is suitable for fetching files up to size of 64MB.
70945                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @method loadJSON
70946                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @param  {String}        path       name of the file or url to load
70947                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @param  {Object}        [jsonpOptions] options object for jsonp related settings
70948                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @param  {String}        [datatype] "json" or "jsonp"
70949                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @param  {function}      [callback] function to be executed after
70950                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *                                    <a href="#/p5/loadJSON">loadJSON()</a> completes, data is passed
70951                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *                                    in as first argument
70952                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @param  {function}      [errorCallback] function to be executed if
70953                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *                                    there is an error, response is passed
70954                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *                                    in as first argument
70955                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @return {Object|Array}             JSON data
70956                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @example
70957                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
70958                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * Calling <a href="#/p5/loadJSON">loadJSON()</a> inside <a href="#/p5/preload">preload()</a> guarantees to complete the
70959                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * operation before <a href="#/p5/setup">setup()</a> and <a href="#/p5/draw">draw()</a> are called.
70960                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
70961                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * <div><code>
70962                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * // Examples use USGS Earthquake API:
70963                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * //   https://earthquake.usgs.gov/fdsnws/event/1/#methods
70964                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * let earthquakes;
70965                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * function preload() {
70966                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   // Get the most recent earthquake in the database
70967                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   let url =
70968                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +
70969                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *     'summary/all_day.geojson';
70970                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   earthquakes = loadJSON(url);
70971  
70971                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             * }
70972                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
70973                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * function setup() {
70974                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   noLoop();
70975                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * }
70976                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
70977                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * function draw() {
70978                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   background(200);
70979                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   // Get the magnitude and name of the earthquake out of the loaded JSON
70980                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   let earthquakeMag = earthquakes.features[0].properties.mag;
70981                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   let earthquakeName = earthquakes.features[0].properties.place;
70982                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);
70983                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   textAlign(CENTER);
70984                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   text(earthquakeName, 0, height - 30, width, 30
70984);
70985                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * }
70986                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * </code></div>
70987                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
70988                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * Outside of preload(), you may supply a callback function to handle the
70989                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * object:
70990                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * <div><code>
70991                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * function setup() {
70992                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   noLoop();
70993                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   let url =
70994                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +
70995                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *     'summary/all_day.geojson';
70996                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   loadJSON(url, drawEarthquake);
70997                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * }
70998                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
70999                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * function draw() {
71000                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   background(200);
71001                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * }
71002                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
71003                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * function drawEarthquake(earthquakes) {
71004                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   // Get the magnitude and name of the earthquake out of the loaded JSON
71005                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   let earthquakeMag = earthquakes.features[0].properties.mag;
71006                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   let earthquakeName = earthquakes.features[0].properties.place;
71007                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);
71008                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   textAlign(CENTER);
71009                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *   text(earthquakeName, 0, height - 30, width, 30
71009);
71010                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * }
71011                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * </code></div>
71012                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               *
71013                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * @alt
71014                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * 50x50 ellipse that changes from black to white depending on the current humidity
71015                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               * 50x50 ellipse that changes from black to white depending on the current humidity
71016                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               */
71017          /**
71018           * @method loadJSON
71019           * @param  {String}        path
71020           * @param  {String}        datatype
71021           * @param  {function}      [callback]
71022           * @param  {function}      [errorCallback]
71023           * @return {Object|Array}
71024           */
71025          /**
71026           * @method loadJSON
71027           * @param  {String}        path
71028           * @param  {function}      callback
71029           * @param  {function}      [errorCallback]
71030           * @return {Object|Array}
71031           */
71032          _main.default.prototype.loadJSON = function() {
71033            for (
71034              var _len = arguments.length, args = new Array(_len), _key = 0;
71035              _key < _len;
71036              _key++
71037            ) {
71038              args[_key] = arguments[_key];
71039            }
71040            _main.default._validateParameters('loadJSON', args);
71041            var path = args[0];
71042            var callback;
71043            var errorCallback;
71044            var options;
71045
71046            var ret = {}; // object needed for preload
71047            var t = 'json';
71048
71049            // check for explicit data type argument
71050            for (var i = 1; i < args.length; i++) {
71051              var arg = args[i];
71052              if (typeof arg === 'string') {
71053                if (arg === 'jsonp' || arg === 'json') {
71054                  t = arg;
71055                }
71056              } else if (typeof arg === 'function') {
71057                if (!callback) {
71058                  callback = arg;
71059                } else {
71060                  errorCallback = arg;
71061                }
71062              } else if (
71063                _typeof(arg) === 'object' &&
71064                (arg.hasOwnProperty('jsonpCallback') ||
71065                  arg.hasOwnProperty('jsonpCallbackFunction'))
71066              ) {
71067                t = 'jsonp';
71068                options = arg;
71069              }
71070            }
71071
71072            var self = this;
71073            this.httpDo(
71074              path,
71075              'GET',
71076              options,
71077              t,
71078              function(resp) {
71079                for (var k in resp) {
71080                  ret[k] = resp[k];
71081                }
71082                if (typeof callback !== 'undefined') {
71083                  callback(resp);
71084                }
71085
71086                self._decrementPreload();
71087              },
71088              function(err) {
71089                // Error handling
71090                _main.default._friendlyFileLoadError(5, path);
71091
71092                if (errorCallback) {
71093                  errorCallback(err);
71094                } else {
71095                  throw err;
71096                }
71097              }
71098            );
71099
71100            return ret;
71101          };
71102
71103          /**
71104    * Reads the contents of a file and creates a String array of its individual
71105    * lines. If the name of the file is used as the parameter, as in the above
71106    * example, the file must be located in the sketch directory/folder.
71107    *
71108    * Alternatively, the file maybe be loaded from anywhere on the local
71109    * computer using an absolute path (something that starts with / on Unix and
71110    * Linux, or a drive letter on Windows), or the filename parameter can be a
71111    * URL for a file found on a network.
71112    *
71113    * This method is asynchronous, meaning it may not finish before the next
71114    * line in your sketch is executed.
71115    *
71116    * This method is suitable for fetching files up to size of 64MB.
71117    * @method loadStrings
71118    * @param  {String}   filename   name of the file or url to load
71119    * @param  {function} [callback] function to be executed after <a href="#/p5/loadStrings">loadStrings()</a>
71120    *                               completes, Array is passed in as first
71121    *                               argument
71122    * @param  {function} [errorCallback] function to be executed if
71123    *                               there is an error, response is passed
71124    *                               in as first argument
71125    * @return {String[]}            Array of Strings
71126    * @example
71127    *
71128    * Calling loadStrings() inside <a href="#/p5/preload">preload()</a> guarantees to complete the
71129    * operation before <a href="#/p5/setup">setup()</a> and <a href="#/p5/draw">draw()</a> are called.
71130    *
71131    * <div><code>
71132    * let result;
71133    * function preload() {
71134    *   result = loadStrings('assets/test.txt');
71135    * }
71136   
71137    * function setup() {
71138    *   background(200);
71139    *   text(random(result), 10, 10, 80, 80);
71140    * }
71141    * </code></div>
71142    *
71143    * Outside of preload(), you may supply a callback function to handle the
71144    * object:
71145    *
71146    * <div><code>
71147    * function setup() {
71148    *   loadStrings('assets/test.txt', pickString);
71149    * }
71150    *
71151    * function pickString(result) {
71152    *   background(200);
71153    *   text(random(result), 10, 10, 80, 80);
71154    * }
71155    * </code></div>
71156    *
71157    * @alt
71158    * randomly generated text from a file, for example "i smell like butter"
71159    * randomly generated text from a file, for example "i have three feet"
71160    */
71161          _main.default.prototype.loadStrings = function() {
71162            for (
71163              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
71164              _key2 < _len2;
71165              _key2++
71166            ) {
71167              args[_key2] = arguments[_key2];
71168            }
71169            _main.default._validateParameters('loadStrings', args);
71170
71171            var ret = [];
71172            var callback, errorCallback;
71173
71174            for (var i = 1; i < args.length; i++) {
71175              var arg = args[i];
71176              if (typeof arg === 'function') {
71177                if (typeof callback === 'undefined') {
71178                  callback = arg;
71179                } else if (typeof errorCallback === 'undefined') {
71180                  errorCallback = arg;
71181                }
71182              }
71183            }
71184
71185            var self = this;
71186            _main.default.prototype.httpDo.call(
71187              this,
71188              args[0],
71189              'GET',
71190              'text',
71191              function(data) {
71192                // split lines handling mac/windows/linux endings
71193                var lines = data
71194                  .replace(/\r\n/g, '\r')
71195                  .replace(/\n/g, '\r')
71196                  .split(/\r/);
71197
71198                // safe insert approach which will not blow up stack when inserting
71199                // >100k lines, but still be faster than iterating line-by-line. based on
71200                // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#Examples
71201                var QUANTUM = 32768;
71202                for (var _i = 0, len = lines.length; _i < len; _i += QUANTUM) {
71203                  Array.prototype.push.apply(
71204                    ret,
71205                    lines.slice(_i, Math.min(_i + QUANTUM, len))
71206                  );
71207                }
71208
71209                if (typeof callback !== 'undefined') {
71210                  callback(ret);
71211                }
71212
71213                self._decrementPreload();
71214              },
71215              function(err) {
71216                // Error handling
71217                _main.default._friendlyFileLoadError(3, arguments[0]);
71218
71219                if (errorCallback) {
71220                  errorCallback(err);
71221                } else {
71222                  throw err;
71223                }
71224              }
71225            );
71226
71227            return ret;
71228          };
71229
71230          /**
71231           * Reads the contents of a file or URL and creates a <a href="#/p5.Table">p5.Table</a> object with
71232           * its values. If a file is specified, it must be located in the sketch's
71233           * "data" folder. The filename parameter can also be a URL to a file found
71234           * online. By default, the file is assumed to be comma-separated (in CSV
71235           * format). Table only looks for a header row if the 'header' option is
71236           * included.
71237           *
71238           * This method is asynchronous, meaning it may not finish before the next
71239           * line in your sketch is executed. Calling <a href="#/p5/loadTable">loadTable()</a> inside <a href="#/p5/preload">preload()</a>
71240           * guarantees to complete the operation before <a href="#/p5/setup">setup()</a> and <a href="#/p5/draw">draw()</a> are called.
71241           * Outside of <a href="#/p5/preload">preload()</a>, you may supply a callback function to handle the
71242           * object:
71243           *
71244           * All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.
71245           * @method loadTable
71246           * @param  {String}         filename    name of the file or URL to load
71247           * @param  {String}         [extension] parse the table by comma-separated values "csv", semicolon-separated
71248           *                                      values "ssv", or tab-separated values "tsv"
71249           * @param  {String}         [header]    "header" to indicate table has header row
71250           * @param  {function}       [callback]  function to be executed after
71251           *                                      <a href="#/p5/loadTable">loadTable()</a> completes. On success, the
71252           *                                      <a href="#/p5.Table">Table</a> object is passed in as the
71253           *                                      first argument.
71254           * @param  {function}  [errorCallback]  function to be executed if
71255           *                                      there is an error, response is passed
71256           *                                      in as first argument
71257           * @return {Object}                     <a href="#/p5.Table">Table</a>
71257 object containing data
71258           *
71259           * @example
71260           * <div class='norender'>
71261           * <code>
71262           * // Given the following CSV file called "mammals.csv"
71263           * // located in the project's "assets" folder:
71264           * //
71265           * // id,species,name
71266           * // 0,Capra hircus,Goat
71267           * // 1,Panthera pardus,Leopard
71268           * // 2,Equus zebra,Zebra
71269           *
71270           * let table;
71271           *
71272           * function preload() {
71273           *   //my table is comma separated value "csv"
71274           *   //and has a header specifying the columns labels
71275           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
71276           *   //the file can be remote
71277           *   //table = loadTable("http://p5js.org/reference/assets/mammals.csv",
71278           *   //                  "csv", "header");
71279           * }
71280           *
71281           * function setup() {
71282           *   //count the columns
71283           *   print(table.getRowCount() + ' total rows in table');
71284           *   print(table.getColumnCount() + ' total columns in table');
71285           *
71286           *   print(table.getColumn('name'));
71287           *   //["Goat", "Leopard", "Zebra"]
71288           *
71289           *   //cycle through the table
71290           *   for (let r = 0; r < table.getRowCount(); r++)
71291           *     for (let c = 0; c < table.getColumnCount(); c++) {
71292           *       print(table.getString(r, c));
71293           *     }
71294           * }
71295           * </code>
71296           * </div>
71297           *
71298           * @alt
71299           * randomly generated text from a file, for example "i smell like butter"
71300           * randomly generated text from a file, for example "i have three feet"
71301           */
71302          _main.default.prototype.loadTable = function(path) {
71303            // p5._validateParameters('loadTable', arguments);
71304            var callback;
71305            var errorCallback;
71306            var options = [];
71307            var header = false;
71308            var ext = path.substring(path.lastIndexOf('.') + 1, path.length);
71309
71310            var sep;
71311            if (ext === 'csv') {
71312              sep = ',';
71313            } else if (ext === 'ssv') {
71314              sep = ';';
71315            } else if (ext === 'tsv') {
71316              sep = '\t';
71317            }
71318
71319            for (var i = 1; i < arguments.length; i++) {
71320              if (typeof arguments[i] === 'function') {
71321                if (typeof callback === 'undefined') {
71322                  callback = arguments[i];
71323                } else if (typeof errorCallback === 'undefined') {
71324                  errorCallback = arguments[i];
71325                }
71326              } else if (typeof arguments[i] === 'string') {
71327                options.push(arguments[i]);
71328                if (arguments[i] === 'header') {
71329                  header = true;
71330                }
71331                if (arguments[i] === 'csv') {
71332                  sep = ',';
71333                } else if (arguments[i] === 'ssv') {
71334                  sep = ';';
71335                } else if (arguments[i] === 'tsv') {
71336                  sep = '\t';
71337                }
71338              }
71339            }
71340
71341            var t = new _main.default.Table();
71342
71343            var self = this;
71344            this.httpDo(
71345              path,
71346              'GET',
71347              'table',
71348              function(resp) {
71349                var state = {};
71350
71351                // define constants
71352                var PRE_TOKEN = 0,
71353                  MID_TOKEN = 1,
71354                  POST_TOKEN = 2,
71355                  POST_RECORD = 4;
71356
71357                var QUOTE = '"',
71358                  CR = '\r',
71359                  LF = '\n';
71360
71361                var records = [];
71362                var offset = 0;
71363                var currentRecord = null;
71364                var currentChar;
71365
71366                var tokenBegin = function tokenBegin() {
71367                  state.currentState = PRE_TOKEN;
71368                  state.token = '';
71369                };
71370
71371                var tokenEnd = function tokenEnd() {
71372                  currentRecord.push(state.token);
71373                  tokenBegin();
71374                };
71375
71376                var recordBegin = function recordBegin() {
71377                  state.escaped = false;
71378                  currentRecord = [];
71379                  tokenBegin();
71380                };
71381
71382                var recordEnd = function recordEnd() {
71383                  state.currentState = POST_RECORD;
71384                  records.push(currentRecord);
71385                  currentRecord = null;
71386                };
71387
71388                for (;;) {
71389                  currentChar = resp[offset++];
71390
71391                  // EOF
71392                  if (currentChar == null) {
71393                    if (state.escaped) {
71394                      throw new Error('Unclosed quote in file.');
71395                    }
71396                    if (currentRecord) {
71397                      tokenEnd();
71398                      recordEnd();
71399                      break;
71400                    }
71401                  }
71402                  if (currentRecord === null) {
71403                    recordBegin();
71404                  }
71405
71406                  // Handle opening quote
71407                  if (state.currentState === PRE_TOKEN) {
71408                    if (currentChar === QUOTE) {
71409                      state.escaped = true;
71410                      state.currentState = MID_TOKEN;
71411                      continue;
71412                    }
71413                    state.currentState = MID_TOKEN;
71414                  }
71415
71416                  // mid-token and escaped, look for sequences and end quote
71417                  if (state.currentState === MID_TOKEN && state.escaped) {
71418                    if (currentChar === QUOTE) {
71419                      if (resp[offset] === QUOTE) {
71420                        state.token += QUOTE;
71421                        offset++;
71422                      } else {
71423                        state.escaped = false;
71424                        state.currentState = POST_TOKEN;
71425                      }
71426                    } else if (currentChar === CR) {
71427                      continue;
71428                    } else {
71429                      state.token += currentChar;
71430                    }
71431                    continue;
71432                  }
71433
71434                  // fall-through: mid-token or post-token, not escaped
71435                  if (currentChar === CR) {
71436                    if (resp[offset] === LF) {
71437                      offset++;
71438                    }
71439                    tokenEnd();
71440                    recordEnd();
71441                  } else if (currentChar === LF) {
71442                    tokenEnd();
71443                    recordEnd();
71444                  } else if (currentChar === sep) {
71445                    tokenEnd();
71446                  } else if (state.currentState === MID_TOKEN) {
71447                    state.token += currentChar;
71448                  }
71449                }
71450
71451                // set up column names
71452                if (header) {
71453                  t.columns = records.shift();
71454                } else {
71455                  for (var _i2 = 0; _i2 < records[0].length; _i2++) {
71456                    t.columns[_i2] = 'null';
71457                  }
71458                }
71459                var row;
71460                for (var _i3 = 0; _i3 < records.length; _i3++) {
71461                  //Handles row of 'undefined' at end of some CSVs
71462                  if (records[_i3].length === 1) {
71463                    if (records[_i3][0] === 'undefined' || records[_i3][0] === '') {
71464                      continue;
71465                    }
71466                  }
71467                  row = new _main.default.TableRow();
71468                  row.arr = records[_i3];
71469                  row.obj = makeObject(records[_i3], t.columns);
71470                  t.addRow(row);
71471                }
71472                if (typeof callback === 'function') {
71473                  callback(t);
71474                }
71475
71476                self._decrementPreload();
71477              },
71478              function(err) {
71479                // Error handling
71480                _main.default._friendlyFileLoadError(2, path);
71481
71482                if (errorCallback) {
71483                  errorCallback(err);
71484                } else {
71485                  console.error(err);
71486                }
71487              }
71488            );
71489
71490            return t;
71491          };
71492
71493          // helper function to turn a row into a JSON object
71494          function makeObject(row, headers) {
71495            var ret = {};
71496            headers = headers || [];
71497            if (typeof headers === 'undefined') {
71498              for (var j = 0; j < row.length; j++) {
71499                headers[j.toString()] = j;
71500              }
71501            }
71502            for (var i = 0; i < headers.length; i++) {
71503              var key = headers[i];
71504              var val = row[i];
71505              ret[key] = val;
71506            }
71507            return ret;
71508          }
71509
71510          /**
71511           * Reads the contents of a file and creates an XML object with its values.
71512           * If the name of the file is used as the parameter, as in the above example,
71513           * the file must be located in the sketch directory/folder.
71514           *
71515           * Alternatively, the file maybe be loaded from anywhere on the local
71516           * computer using an absolute path (something that starts with / on Unix and
71517           * Linux, or a drive letter on Windows), or the filename parameter can be a
71518           * URL for a file found on a network.
71519           *
71520           * This method is asynchronous, meaning it may not finish before the next
71521           * line in your sketch is executed. Calling <a href="#/p5/loadXML">loadXML()</a> inside <a href="#/p5/preload">preload()</a>
71522           * guarantees to complete the operation before <a href="#/p5/setup">setup()</a> and <a href="#/p5/draw">draw()</a> are called.
71523           *
71524           * Outside of <a href="#/p5/preload">preload()</a>, you may supply a callback function to handle the
71525           * object.
71526           *
71527           * This method is suitable for fetching files up to size of 64MB.
71528           * @method loadXML
71529           * @param  {String}   filename   name of the file or URL to load
71530           * @param  {function} [callback] function to be executed after <a href="#/p5/loadXML">loadXML()</a>
71531           *                               completes, XML object is passed in as
71532           *                               first argument
71533           * @param  {function} [errorCallback] function to be executed if
71534           *                               there is an error, response is passed
71535           *                               in as first argument
71536           * @return {Object}              XML object containing data
71537           * @example
71538           * <div class='norender'><code>
71539           * // The following short XML file called "mammals.xml" is parsed
71540           * // in the code below.
71541           * //
71542           * // <?xml version="1.0"?>
71543           * // &lt;mammals&gt;
71544           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
71545           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
71546           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
71547           * // &lt;/mammals&gt;
71548           *
71549           * let xml;
71550           *
71551           * function preload() {
71552           *   xml = loadXML('assets/mammals.xml');
71553           * }
71554           *
71555           * function setup() {
71556           *   let children = xml.getChildren('animal');
71557           *
71558           *   for (let i = 0; i < children.length; i++) {
71559           *     let id = children[i].getNum('id');
71560           *     let coloring = children[i].getString('species');
71561           *     let name = children[i].getContent();
71562           *     print(id + ', ' + coloring + ', ' + name);
71563           *   }
71564           * }
71565           *
71566           * // Sketch prints:
71567           * // 0, Capra hircus, Goat
71568           * // 1, Panthera pardus, Leopard
71569           * // 2, Equus zebra, Zebra
71570           * </code></div>
71571           *
71572           * @alt
71573           * no image displayed
71574           */
71575          _main.default.prototype.loadXML = function() {
71576            for (
71577              var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;
71578              _key3 < _len3;
71579              _key3++
71580            ) {
71581              args[_key3] = arguments[_key3];
71582            }
71583            var ret = new _main.default.XML();
71584            var callback, errorCallback;
71585
71586            for (var i = 1; i < args.length; i++) {
71587              var arg = args[i];
71588              if (typeof arg === 'function') {
71589                if (typeof callback === 'undefined') {
71590                  callback = arg;
71591                } else if (typeof errorCallback === 'undefined') {
71592                  errorCallback = arg;
71593                }
71594              }
71595            }
71596
71597            var self = this;
71598            this.httpDo(
71599              args[0],
71600              'GET',
71601              'xml',
71602              function(xml) {
71603                for (var key in xml) {
71604                  ret[key] = xml[key];
71605                }
71606                if (typeof callback !== 'undefined') {
71607                  callback(ret);
71608                }
71609
71610                self._decrementPreload();
71611              },
71612              function(err) {
71613                // Error handling
71614                _main.default._friendlyFileLoadError(1, arguments[0]);
71615
71616                if (errorCallback) {
71617                  errorCallback(err);
71618                } else {
71619                  throw err;
71620                }
71621              }
71622            );
71623
71624            return ret;
71625          };
71626
71627          /**
71628           * This method is suitable for fetching files up to size of 64MB.
71629           * @method loadBytes
71630           * @param {string}   file            name of the file or URL to load
71631           * @param {function} [callback]      function to be executed after <a href="#/p5/loadBytes">loadBytes()</a>
71632           *                                    completes
71633           * @param {function} [errorCallback] function to be executed if there
71634           *                                    is an error
71635           * @returns {Object} an object whose 'bytes' property will be the loaded buffer
71636           *
71637           * @example
71638           * <div class='norender'><code>
71639           * let data;
71640           *
71641           * function preload() {
71642           *   data = loadBytes('assets/mammals.xml');
71643           * }
71644           *
71645           * function setup() {
71646           *   for (let i = 0; i < 5; i++) {
71647           *     console.log(data.bytes[i].toString(16));
71648           *   }
71649           * }
71650           * </code></div>
71651           *
71652           * @alt
71653           * no image displayed
71654           */
71655          _main.default.prototype.loadBytes = function(file, callback, errorCallback) {
71656            var ret = {};
71657
71658            var self = this;
71659            this.httpDo(
71660              file,
71661              'GET',
71662              'arrayBuffer',
71663              function(arrayBuffer) {
71664                ret.bytes = new Uint8Array(arrayBuffer);
71665
71666                if (typeof callback === 'function') {
71667                  callback(ret);
71668                }
71669
71670                self._decrementPreload();
71671              },
71672              function(err) {
71673                // Error handling
71674                _main.default._friendlyFileLoadError(6, file);
71675
71676                if (errorCallback) {
71677                  errorCallback(err);
71678                } else {
71679                  throw err;
71680                }
71681              }
71682            );
71683
71684            return ret;
71685          };
71686
71687          /**
71688    * Method for executing an HTTP GET request. If data type is not specified,
71689    * p5 will try to guess based on the URL, defaulting to text. This is equivalent to
71690    * calling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return
71691    * a Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer
71692    * which can be used to initialize typed arrays (such as Uint8Array).
71693    *
71694    * @method httpGet
71695    * @param  {String}        path       name of the file or url to load
71696    * @param  {String}        [datatype] "json", "jsonp", "binary", "arrayBuffer",
71697    *                                    "xml", or "text"
71698    * @param  {Object|Boolean} [data]    param data passed sent with request
71699    * @param  {function}      [callback] function to be executed after
71700    *                                    <a href="#/p5/httpGet">httpGet()</a> completes, data is passed in
71701    *                                    as first argument
71702    * @param  {function}      [errorCallback] function to be executed if
71703    *                                    there is an error, response is passed
71704    *                                    in as first argument
71705    * @return {Promise} A promise that resolves with the data when the operation
71706    *                   completes successfully or rejects with the error after
71707    *                   one occurs.
71708    * @example
71709    * <div class='norender'><code>
71710    * // Examples use USGS Earthquake API:
71711    * //   https://earthquake.usgs.gov/fdsnws/event/1/#methods
71712    * let earthquakes;
71713    * function preload() {
71714    *   // Get the most recent earthquake in the database
71715    *   let url =
71716       'https://earthquake.usgs.gov/fdsnws/event/1/query?' +
71717    *     'format=geojson&limit=1&orderby=time';
71718    *   httpGet(url, 'jsonp', false, function(response) {
71719    *     // when the HTTP request completes, populate the variable that holds the
71720    *     // earthquake data used in the visualization.
71721    *     earthquakes = response;
71722    *   });
71723    * }
71724    *
71725    * function draw() {
71726    *   if (!earthquakes) {
71727    *     // Wait until the earthquake data has loaded before drawing.
71728    *     return;
71729    *   }
71730    *   background(200);
71731    *   // Get the magnitude and name of the earthquake out of the loaded JSON
71732    *   let earthquakeMag = earthquakes.features[0].properties.mag;
71733    *   let earthquakeName = earthquakes.features[0].properties.place;
71734    *   ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);
71735    *   textAlign(CENTER);
71736    *   text(earthquakeName, 0, height - 30, width, 30);
71737    *   noLoop();
71738    * }
71739    * </code></div>
71740    */
71741          /**
71742           * @method httpGet
71743           * @param  {String}        path
71744           * @param  {Object|Boolean} data
71745           * @param  {function}      [callback]
71746           * @param  {function}      [errorCallback]
71747           * @return {Promise}
71748           */
71749          /**
71750           * @method httpGet
71751           * @param  {String}        path
71752           * @param  {function}      callback
71753           * @param  {function}      [errorCallback]
71754           * @return {Promise}
71755           */
71756          _main.default.prototype.httpGet = function() {
71757            _main.default._validateParameters('httpGet', arguments);
71758
71759            var args = Array.prototype.slice.call(arguments);
71760            args.splice(1, 0, 'GET');
71761            return _main.default.prototype.httpDo.apply(this, args);
71762          };
71763
71764          /**
71765           * Method for executing an HTTP POST request. If data type is not specified,
71766           * p5 will try to guess based on the URL, defaulting to text. This is equivalent to
71767           * calling <code>httpDo(path, 'POST')</code>.
71768           *
71769           * @method httpPost
71770           * @param  {String}        path       name of the file or url to load
71771           * @param  {String}        [datatype] "json", "jsonp", "xml", or "text".
71772           *                                    If omitted, <a href="#/p5/httpPost">httpPost()</a> will guess.
71773           * @param  {Object|Boolean} [data]    param data passed sent with request
71774           * @param  {function}      [callback] function to be executed after
71775           *                                    <a href="#/p5/httpPost">httpPost()</a> completes, data is passed in
71776           *                                    as first argument
71777           * @param  {function}      [errorCallback] function to be executed if
71778           *                                    there is an error, response is passed
71779           *                                    in as first argument
71780           * @return {Promise} A promise that resolves with the data when the operation
71781           *                   completes successfully or rejects with the error after
71782           *                   one occurs.
71783           *
71784           * @example
71785           * <div>
71786           * <code>
71787           * // Examples use jsonplaceholder.typicode.com for a Mock Data API
71788           *
71789           * let url = 'https://jsonplaceholder.typicode.com/posts';
71790           * let postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };
71791           *
71792           * function setup() {
71793           *   createCanvas(100, 100);
71794           *   background(200);
71795           * }
71796           *
71797           * function mousePressed() {
71798           *   httpPost(url, 'json', postData, function(result) {
71799           *     strokeWeight(2);
71800           *     text(result.body, mouseX, mouseY);
71801           *   });
71802           * }
71803           * </code>
71804           * </div>
71805           *
71806           * <div><code>
71807           * let url = 'ttps://invalidURL'; // A bad URL that will cause errors
71808           * let postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };
71809           *
71810           * function setup() {
71811           *   createCanvas(100, 100);
71812           *   background(200);
71813           * }
71814           *
71815           * function mousePressed() {
71816           *   httpPost(
71817           *     url,
71818           *     'json',
71819           *     postData,
71820           *     function(result) {
71821           *       // ... won't be called
71822           *     },
71823           *     function(error) {
71824           *       strokeWeight(2);
71825           *       text(error.toString(), mouseX, mouseY);
71826           *     }
71827           *   );
71828           * }
71829           * </code></div>
71830           */
71831          /**
71832           * @method httpPost
71833           * @param  {String}        path
71834           * @param  {Object|Boolean} data
71835           * @param  {function}      [callback]
71836           * @param  {function}      [errorCallback]
71837           * @return {Promise}
71838           */
71839          /**
71840           * @method httpPost
71841           * @param  {String}        path
71842           * @param  {function}      callback
71843           * @param  {function}      [errorCallback]
71844           * @return {Promise}
71845           */
71846          _main.default.prototype.httpPost = function() {
71847            _main.default._validateParameters('httpPost', arguments);
71848
71849            var args = Array.prototype.slice.call(arguments);
71850            args.splice(1, 0, 'POST');
71851            return _main.default.prototype.httpDo.apply(this, args);
71852          };
71853
71854          /**
71855           * Method for executing an HTTP request. If data type is not specified,
71856           * p5 will try to guess based on the URL, defaulting to text.<br><br>
71857           * For more advanced use, you may also pass in the path as the first argument
71858           * and a object as the second argument, the signature follows the one specified
71859           * in the Fetch API specification.
71860           * This method is suitable for fetching files up to size of 64MB when "GET" is used.
71861           *
71862           * @method httpDo
71863           * @param  {String}        path       name of the file or url to load
71864           * @param  {String}        [method]   either "GET", "POST", or "PUT",
71865           *                                    defaults to "GET"
71866           * @param  {String}        [datatype] "json", "jsonp", "xml", or "text"
71867           * @param  {Object}        [data]     param data passed sent with request
71868           * @param  {function}      [callback] function to be executed after
71869           *                                    <a href="#/p5/httpGet">httpGet()</a> completes, data is passed in
71870           *                                    as first argument
71871           * @param  {function}      [errorCallback] function to be executed if
71872           *                                    there is an error, response is passed
71873           *                                    in as first argument
71874           * @return {Promise} A promise that resolves with the data when the operation
71875           *                   completes successfully or rejects with the error after
71876           *                   one occurs.
71877           *
71878           * @example
71879           * <div>
71880           * <code>
71881           * // Examples use USGS Earthquake API:
71882           * // https://earthquake.usgs.gov/fdsnws/event/1/#methods
71883           *
71884           * // displays an animation of all USGS earthquakes
71885           * let earthquakes;
71886           * let eqFeatureIndex = 0;
71887           *
71888           * function preload() {
71889           *   let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';
71890           *   httpDo(
71891           *     url,
71892           *     {
71893           *       method: 'GET',
71894           *       // Other Request options, like special headers for apis
71895           *       headers: { authorization: 'Bearer secretKey' }
71896           *     },
71897           *     function(res) {
71898           *       earthquakes = res;
71899           *     }
71900           *   );
71901           * }
71902           *
71903           * function draw() {
71904           *   // wait until the data is loaded
71905           *   if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {
71906           *     return;
71907           *   }
71908           *   clear();
71909           *
71910           *   let feature = earthquakes.features[eqFeatureIndex];
71911           *   let mag = feature.properties.mag;
71912           *   let rad = mag / 11 * ((width + height) / 2);
71913           *   fill(255, 0, 0, 100);
71914           *   ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);
71915           *
71916           *   if (eqFeatureIndex >= earthquakes.features.length) {
71917           *     eqFeatureIndex = 0;
71918           *   } else {
71919           *     eqFeatureIndex += 1;
71920           *   }
71921           * }
71922           * </code>
71923           * </div>
71924           */
71925          /**
71926           * @method httpDo
71927           * @param  {String}        path
71928           * @param  {Object}        options   Request object options as documented in the
71929           *                                    "fetch" API
71930           * <a href="https://developer.mozilla.org/en/docs/Web/API/Fetch_API">reference</a>
71931           * @param  {function}      [callback]
71932           * @param  {function}      [errorCallback]
71933           * @return {Promise}
71934           */
71935          _main.default.prototype.httpDo = function() {
71936            var type;
71937            var callback;
71938            var errorCallback;
71939            var request;
71940            var promise;
71941            var jsonpOptions = {};
71942            var cbCount = 0;
71943            var contentType = 'text/plain';
71944            // Trim the callbacks off the end to get an idea of how many arguments are passed
71945            for (var i = arguments.length - 1; i > 0; i--) {
71946              if (
71947                typeof (i < 0 || arguments.length <= i ? undefined : arguments[i]) ===
71948                'function'
71949              ) {
71950                cbCount++;
71951              } else {
71952                break;
71953              }
71954            }
71955            // The number of arguments minus callbacks
71956            var argsCount = arguments.length - cbCount;
71957            var path = arguments.length <= 0 ? undefined : arguments[0];
71958            if (
71959              argsCount === 2 &&
71960              typeof path === 'string' &&
71961              _typeof(arguments.length <= 1 ? undefined : arguments[1]) === 'object'
71962            ) {
71963              // Intended for more advanced use, pass in Request parameters directly
71964              request = new Request(path, arguments.length <= 1 ? undefined : arguments[1]);
71965              callback = arguments.length <= 2 ? undefined : arguments[2];
71966              errorCallback = arguments.length <= 3 ? undefined : arguments[3];
71967            } else {
71968              // Provided with arguments
71969              var method = 'GET';
71970              var data;
71971
71972              for (var j = 1; j < arguments.length; j++) {
71973                var a = j < 0 || arguments.length <= j ? undefined : arguments[j];
71974                if (typeof a === 'string') {
71975                  if (a === 'GET' || a === 'POST' || a === 'PUT' || a === 'DELETE') {
71976                    method = a;
71977                  } else if (
71978                    a === 'json' ||
71979                    a === 'jsonp' ||
71980                    a === 'binary' ||
71981                    a === 'arrayBuffer' ||
71982                    a === 'xml' ||
71983                    a === 'text' ||
71984                    a === 'table'
71985                  ) {
71986                    type = a;
71987                  } else {
71988                    data = a;
71989                  }
71990                } else if (typeof a === 'number') {
71991                  data = a.toString();
71992                } else if (_typeof(a) === 'object') {
71993                  if (
71994                    a.hasOwnProperty('jsonpCallback') ||
71995                    a.hasOwnProperty('jsonpCallbackFunction')
71996                  ) {
71997                    for (var attr in a) {
71998                      jsonpOptions[attr] = a[attr];
71999                    }
72000                  } else if (a instanceof _main.default.XML) {
72001                    data = a.serialize();
72002                    contentType = 'application/xml';
72003                  } else {
72004                    data = JSON.stringify(a);
72005                    contentType = 'application/json';
72006                  }
72007                } else if (typeof a === 'function') {
72008                  if (!callback) {
72009                    callback = a;
72010                  } else {
72011                    errorCallback = a;
72012                  }
72013                }
72014              }
72015
72016              var headers =
72017                method === 'GET'
72018                  ? new Headers()
72019                  : new Headers({ 'Content-Type': contentType });
72020
72021              request = new Request(path, {
72022                method: method,
72023                mode: 'cors',
72024                body: data,
72025                headers: headers
72026              });
72027            }
72028            // do some sort of smart type checking
72029            if (!type) {
72030              if (path.includes('json')) {
72031                type = 'json';
72032              } else if (path.includes('xml')) {
72033                type = 'xml';
72034              } else {
72035                type = 'text';
72036              }
72037            }
72038
72039            if (type === 'jsonp') {
72040              promise = (0, _fetchJsonp.default)(path, jsonpOptions);
72041            } else {
72042              promise = fetch(request);
72043            }
72044            promise = promise.then(function(res) {
72045              if (!res.ok) {
72046                var err = new Error(res.body);
72047                err.status = res.status;
72048                err.ok = false;
72049                throw err;
72050              } else {
72051                var fileSize = 0;
72052                if (type !== 'jsonp') {
72053                  fileSize = res.headers.get('content-length');
72054                }
72055                if (fileSize && fileSize > 64000000) {
72056                  _main.default._friendlyFileLoadError(7, path);
72057                }
72058                switch (type) {
72059                  case 'json':
72060                  case 'jsonp':
72061                    return res.json();
72062                  case 'binary':
72063                    return res.blob();
72064                  case 'arrayBuffer':
72065                    return res.arrayBuffer();
72066                  case 'xml':
72067                    return res.text().then(function(text) {
72068                      var parser = new DOMParser();
72069                      var xml = parser.parseFromString(text, 'text/xml');
72070                      return new _main.default.XML(xml.documentElement);
72071                    });
72072                  default:
72073                    return res.text();
72074                }
72075              }
72076            });
72077            promise.then(callback || function() {});
72078            promise.catch(errorCallback || console.error);
72079            return promise;
72080          };
72081
72082          /**
72083           * @module IO
72084           * @submodule Output
72085           * @for p5
72086           */
72087
72088          window.URL = window.URL || window.webkitURL;
72089
72090          // private array of p5.PrintWriter objects
72091          _main.default.prototype._pWriters = [];
72092
72093          /**
72094           * @method createWriter
72095           * @param {String} name name of the file to be created
72096           * @param {String} [extension]
72097           * @return {p5.PrintWriter}
72098           * @example
72099           * <div>
72100           * <code>
72101           * function setup() {
72102           *   createCanvas(100, 100);
72103           *   background(200);
72104           *   text('click here to save', 10, 10, 70, 80);
72105           * }
72106           *
72107           * function mousePressed() {
72108           *   if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
72109           *     const writer = createWriter('squares.txt');
72110           *     for (let i = 0; i < 10; i++) {
72111           *       writer.print(i * i);
72112           *     }
72113           *     writer.close();
72114           *     writer.clear();
72115           *   }
72116           * }
72117           * </code>
72118           * </div>
72119           */
72120          _main.default.prototype.createWriter = function(name, extension) {
72121            var newPW;
72122            // check that it doesn't already exist
72123            for (var i in _main.default.prototype._pWriters) {
72124              if (_main.default.prototype._pWriters[i].name === name) {
72125                // if a p5.PrintWriter w/ this name already exists...
72126                // return p5.prototype._pWriters[i]; // return it w/ contents intact.
72127                // or, could return a new, empty one with a unique name:
72128                newPW = new _main.default.PrintWriter(name + this.millis(), extension);
72129                _main.default.prototype._pWriters.push(newPW);
72130                return newPW;
72131              }
72132            }
72133            newPW = new _main.default.PrintWriter(name, extension);
72134            _main.default.prototype._pWriters.push(newPW);
72135            return newPW;
72136          };
72137
72138          /**
72139           *  @class p5.PrintWriter
72140           *  @param  {String}     filename
72141           *  @param  {String}     [extension]
72142           */
72143          _main.default.PrintWriter = function(filename, extension) {
72144            var self = this;
72145            this.name = filename;
72146            this.content = '';
72147            //Changed to write because it was being overloaded by function below.
72148            /**
72149             * Writes data to the PrintWriter stream
72150             * @method write
72151             * @param {Array} data all data to be written by the PrintWriter
72152             * @example
72153             * <div class="norender notest">
72154             * <code>
72155             * // creates a file called 'newFile.txt'
72156             * let writer = createWriter('newFile.txt');
72157             * // write 'Hello world!'' to the file
72158             * writer.write(['Hello world!']);
72159             * // close the PrintWriter and save the file
72160             * writer.close();
72161             * </code>
72162             * </div>
72163             * <div class='norender notest'>
72164             * <code>
72165             * // creates a file called 'newFile2.txt'
72166             * let writer = createWriter('newFile2.txt');
72167             * // write 'apples,bananas,123' to the file
72168             * writer.write(['apples', 'bananas', 123]);
72169             * // close the PrintWriter and save the file
72170             * writer.close();
72171             * </code>
72172             * </div>
72173             * <div class='norender notest'>
72174             * <code>
72175             * // creates a file called 'newFile3.txt'
72176             * let writer = createWriter('newFile3.txt');
72177             * // write 'My name is: Teddy' to the file
72178             * writer.write('My name is:');
72179             * writer.write(' Teddy');
72180             * // close the PrintWriter and save the file
72181             * writer.close();
72182             * </code>
72183             * </div>
72184             * <div>
72185             * <code>
72186             * function setup() {
72187             *   createCanvas(100, 100);
72188             *   button = createButton('SAVE FILE');
72189             *   button.position(21, 40);
72190             *   button.mousePressed(createFile);
72191             * }
72192             *
72193             * function createFile() {
72194             *   // creates a file called 'newFile.txt'
72195             *   let writer = createWriter('newFile.txt');
72196             *   // write 'Hello world!'' to the file
72197             *   writer.write(['Hello world!']);
72198             *   // close the PrintWriter and save the file
72199             *   writer.close();
72200             * }
72201             * </code>
72202             * </div>
72203             */
72204            this.write = function(data) {
72205              this.content += data;
72206            };
72207            /**
72208             * Writes data to the PrintWriter stream, and adds a new line at the end
72209             * @method print
72210             * @param {Array} data all data to be printed by the PrintWriter
72211             * @example
72212             * <div class='norender notest'>
72213             * <code>
72214             * // creates a file called 'newFile.txt'
72215             * let writer = createWriter('newFile.txt');
72216             * // creates a file containing
72217             * //  My name is:
72218             * //  Teddy
72219             * writer.print('My name is:');
72220             * writer.print('Teddy');
72221             * // close the PrintWriter and save the file
72222             * writer.close();
72223             * </code>
72224             * </div>
72225             * <div class='norender notest'>
72226             * <code>
72227             * let writer;
72228             *
72229             * function setup() {
72230             *   createCanvas(400, 400);
72231             *   // create a PrintWriter
72232             *   writer = createWriter('newFile.txt');
72233             * }
72234             *
72235             * function draw() {
72236             *   writer.print([mouseX, mouseY]);
72237             * }
72238             *
72239             * function mouseClicked() {
72240             *   writer.close();
72241             * }
72242             * </code>
72243             * </div>
72244             */
72245            this.print = function(data) {
72246              this.content += ''.concat(data, '\n');
72247            };
72248            /**
72249             * Clears the data already written to the PrintWriter object
72250             * @method clear
72251             * @example
72252             * <div class ="norender notest"><code>
72253             * // create writer object
72254             * let writer = createWriter('newFile.txt');
72255             * writer.write(['clear me']);
72256             * // clear writer object here
72257             * writer.clear();
72258             * // close writer
72259             * writer.close();
72260             * </code></div>
72261             * <div>
72262             * <code>
72263             * function setup() {
72264             *   button = createButton('CLEAR ME');
72265             *   button.position(21, 40);
72266             *   button.mousePressed(createFile);
72267             * }
72268             *
72269             * function createFile() {
72270             *   let writer = createWriter('newFile.txt');
72271             *   writer.write(['clear me']);
72272             *   writer.clear();
72273             *   writer.close();
72274             * }
72275             * </code>
72276             * </div>
72277             *
72278             */
72279            this.clear = function() {
72280              this.content = '';
72281            };
72282            /**
72283             * Closes the PrintWriter
72284             * @method close
72285             * @example
72286             * <div class="norender notest">
72287             * <code>
72288             * // create a file called 'newFile.txt'
72289             * let writer = createWriter('newFile.txt');
72290             * // close the PrintWriter and save the file
72291             * writer.close();
72292             * </code>
72293             * </div>
72294             * <div class='norender notest'>
72295             * <code>
72296             * // create a file called 'newFile2.txt'
72297             * let writer = createWriter('newFile2.txt');
72298             * // write some data to the file
72299             * writer.write([100, 101, 102]);
72300             * // close the PrintWriter and save the file
72301             * writer.close();
72302             * </code>
72303             * </div>
72304             */
72305            this.close = function() {
72306              // convert String to Array for the writeFile Blob
72307              var arr = [];
72308              arr.push(this.content);
72309              _main.default.prototype.writeFile(arr, filename, extension);
72310              // remove from _pWriters array and delete self
72311              for (var i in _main.default.prototype._pWriters) {
72312                if (_main.default.prototype._pWriters[i].name === this.name) {
72313                  // remove from _pWriters array
72314                  _main.default.prototype._pWriters.splice(i, 1);
72315                }
72316              }
72317              self.clear();
72318              self = {};
72319            };
72320          };
72321
72322          /**
72323           * @module IO
72324           * @submodule Output
72325           * @for p5
72326           */
72327
72328          // object, filename, options --> saveJSON, saveStrings,
72329          // filename, [extension] [canvas] --> saveImage
72330
72331          /**
72332           *  Saves a given element(image, text, json, csv, wav, or html) to the client's
72333           *  computer. The first parameter can be a pointer to element we want to save.
72334           *  The element can be one of <a href="#/p5.Element">p5.Element</a>,an Array of
72335           *  Strings, an Array of JSON, a JSON object, a <a href="#/p5.Table">p5.Table
72336           *  </a>, a <a href="#/p5.Image">p5.Image</a>, or a p5.SoundFile (requires
72337           *  p5.sound). The second parameter is a filename (including extension).The
72338           *  third parameter is for options specific to this type of object. This method
72339           *  will save a file that fits the given parameters.
72340           *  If it is called without specifying an element, by default it will save the
72341           *  whole canvas as an image file. You can optionally specify a filename as
72342           *  the first parameter in such a case.
72343           *  **Note that it is not recommended to
72344           *  call this method within draw, as it will open a new save dialog on every
72345           *  render.**
72346           *
72347           * @method save
72348           * @param  {Object|String} [objectOrFilename]  If filename is provided, will
72349           *                                             save canvas as an image with
72350           *                                             either png or jpg extension
72351           *                                             depending on the filename.
72352           *                                             If object is provided, will
72353           *                                             save depending on the object
72354           *                                             and filename (see examples
72355           *                                             above).
72356           * @param  {String} [filename] If an object is provided as the first
72357           *                               parameter, then the second parameter
72358           *                               indicates the filename,
72359           *                               and should include an appropriate
72360           *                               file extension (see examples above).
72361           * @param  {Boolean|String} [options]  Additional options depend on
72362           *                            filetype. For example, when saving JSON,
72363           *                            <code>true</code> indicates that the
72364           *                            output will be optimized for filesize,
72365           *                            rather than readability.
72366           *
72367           * @example
72368           * <div class="norender"><code>
72369           * // Saves the canvas as an image
72370           * cnv = createCanvas(300, 300);
72371           * save(cnv, 'myCanvas.jpg');
72372           *
72373           * // Saves the canvas as an image by default
72374           * save('myCanvas.jpg');
72375           * </code></div>
72376           *
72377           *  <div class="norender"><code>
72378           * // Saves p5.Image as an image
72379           
72379* img = createImage(10, 10);
72380           * save(img, 'myImage.png');
72381           * </code></div>
72382           *
72383           * <div class="norender"><code>
72384           * // Saves p5.Renderer object as an image
72385           * obj = createGraphics(100, 100);
72386           * save(obj, 'myObject.png');
72387           * </code></div>
72388           *
72389           * <div class="norender"><code>
72390           * let myTable = new p5.Table();
72391           * // Saves table as html file
72392           * save(myTable, 'myTable.html');
72393           *
72394           * // Comma Separated Values
72395           * save(myTable, 'myTable.csv');
72396           *
72397           * // Tab Separated Values
72398           * save(myTable, 'myTable.tsv');
72399           * </code></div>
72400           *
72401           * <div class="norender"><code>
72402           * let myJSON = { a: 1, b: true };
72403           *
72404           * // Saves pretty JSON
72405           * save(myJSON, 'my.json');
72406           *
72407           * // Optimizes JSON filesize
72408           * save(myJSON, 'my.json', true);
72409           * </code></div>
72410           *
72411           * <div class="norender"><code>
72412           * // Saves array of strings to text file with line breaks after each item
72413           * let arrayOfStrings = ['a', 'b'];
72414           * save(arrayOfStrings, 'my.txt');
72415           * </code></div>
72416           *
72417           * @alt
72418           * An example for saving a canvas as an image.
72419           * An example for saving a p5.Image element as an image.
72420           * An example for saving a p5.Renderer element.
72421           * An example showing how to save a table in formats of HTML, CSV and TSV.
72422           * An example for saving JSON to a txt file with some extra arguments.
72423           * An example for saving an array of strings to text file with line breaks.
72424           */
72425
72426          _main.default.prototype.save = function(object, _filename, _options) {
72427            // parse the arguments and figure out which things we are saving
72428            var args = arguments;
72429            // =================================================
72430            // OPTION 1: saveCanvas...
72431
72432            // if no arguments are provided, save canvas
72433            var cnv = this._curElement ? this._curElement.elt : this.elt;
72434            if (args.length === 0) {
72435              _main.default.prototype.saveCanvas(cnv);
72436              return;
72437            } else if (
72438              args[0] instanceof _main.default.Renderer ||
72439              args[0] instanceof _main.default.Graphics
72440            ) {
72441              // otherwise, parse the arguments
72442
72443              // if first param is a p5Graphics, then saveCanvas
72444              _main.default.prototype.saveCanvas(args[0].elt, args[1], args[2]);
72445              return;
72446            } else if (args.length === 1 && typeof args[0] === 'string') {
72447              // if 1st param is String and only one arg, assume it is canvas filename
72448              _main.default.prototype.saveCanvas(cnv, args[0]);
72449            } else {
72450              // =================================================
72451              // OPTION 2: extension clarifies saveStrings vs. saveJSON
72452              var extension = _checkFileExtension(args[1], args[2])[1];
72453              switch (extension) {
72454                case 'json':
72455                  _main.default.prototype.saveJSON(args[0], args[1], args[2]);
72456                  return;
72457                case 'txt':
72458                  _main.default.prototype.saveStrings(args[0], args[1], args[2]);
72459                  return;
72460                // =================================================
72461                // OPTION 3: decide based on object...
72462                default:
72463                  if (args[0] instanceof Array) {
72464                    _main.default.prototype.saveStrings(args[0], args[1], args[2]);
72465                  } else if (args[0] instanceof _main.default.Table) {
72466                    _main.default.prototype.saveTable(args[0], args[1], args[2]);
72467                  } else if (args[0] instanceof _main.default.Image) {
72468                    _main.default.prototype.saveCanvas(args[0].canvas, args[1]);
72469                  } else if (args[0] instanceof _main.default.SoundFile) {
72470                    _main.default.prototype.saveSound(args[0], args[1], args[2], args[3]);
72471                  }
72472              }
72473            }
72474          };
72475
72476          /**
72477           *  Writes the contents of an Array or a JSON object to a .json file.
72478           *  The file saving process and location of the saved file will
72479           *  vary between web browsers.
72480           *
72481           *  @method saveJSON
72482           *  @param  {Array|Object} json
72483           *  @param  {String} filename
72484           *  @param  {Boolean} [optimize]   If true, removes line breaks
72485           *                                 and spaces from the output
72486           *                                 file to optimize filesize
72487           *                                 (but not readability).
72488           *  @example
72489           * <div><code>
72490           * let json = {}; // new  JSON Object
72491           *
72492           * json.id = 0;
72493           * json.species = 'Panthera leo';
72494           * json.name = 'Lion';
72495           *
72496           * function setup() {
72497           *   createCanvas(100, 100);
72498           *   background(200);
72499           *   text('click here to save', 10, 10, 70, 80);
72500           * }
72501           *
72502           * function mousePressed() {
72503           *   if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
72504           *     saveJSON(json, 'lion.json');
72505           *   }
72506           * }
72507           *
72508           * // saves the following to a file called "lion.json":
72509           * // {
72510           * //   "id": 0,
72511           * //   "species": "Panthera leo",
72512           * //   "name": "Lion"
72513           * // }
72514           * </code></div>
72515           *
72516           * @alt
72517           * no image displayed
72518           */
72519          _main.default.prototype.saveJSON = function(json, filename, opt) {
72520            _main.default._validateParameters('saveJSON', arguments);
72521            var stringify;
72522            if (opt) {
72523              stringify = JSON.stringify(json);
72524            } else {
72525              stringify = JSON.stringify(json, undefined, 2);
72526            }
72527            this.saveStrings(stringify.split('\n'), filename, 'json');
72528          };
72529
72530          _main.default.prototype.saveJSONObject = _main.default.prototype.saveJSON;
72531          _main.default.prototype.saveJSONArray = _main.default.prototype.saveJSON;
72532
72533          /**
72534           *  Writes an array of Strings to a text file, one line per String.
72535           *  The file saving process and location of the saved file will
72536           *  vary between web browsers.
72537           *
72538           *  @method saveStrings
72539           *  @param  {String[]} list   string array to be written
72540           *  @param  {String} filename filename for output
72541           *  @param  {String} [extension] the filename's extension
72542           *  @param  {Boolean} [isCRLF] if true, change line-break to CRLF
72543           *  @example
72544           * <div><code>
72545           * let words = 'apple bear cat dog';
72546           *
72547           * // .split() outputs an Array
72548           * let list = split(words, ' ');
72549           *
72550           * function setup() {
72551           *   createCanvas(100, 100);
72552           *   background(200);
72553           *   text('click here to save', 10, 10, 70, 80);
72554           * }
72555           *
72556           * function mousePressed() {
72557           *   if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
72558           *     saveStrings(list, 'nouns.txt');
72559           *   }
72560           * }
72561           *
72562           * // Saves the following to a file called 'nouns.txt':
72563           * //
72564           * // apple
72565           * // bear
72566           * // cat
72567           * // dog
72568           * </code></div>
72569           *
72570           * @alt
72571           * no image displayed
72572           */
72573          _main.default.prototype.saveStrings = function(
72574            list,
72575            filename,
72576            extension,
72577            isCRLF
72578          ) {
72579            _main.default._validateParameters('saveStrings', arguments);
72580            var ext = extension || 'txt';
72581            var pWriter = this.createWriter(filename, ext);
72582            for (var i = 0; i < list.length; i++) {
72583              isCRLF ? pWriter.write(list[i] + '\r\n') : pWriter.write(list[i] + '\n');
72584            }
72585            pWriter.close();
72586            pWriter.clear();
72587          };
72588
72589          // =======
72590          // HELPERS
72591          // =======
72592
72593          function escapeHelper(content) {
72594            return content
72595              .replace(/&/g, '&amp;')
72596              .replace(/</g, '&lt;')
72597              .replace(/>/g, '&gt;')
72598              .replace(/"/g, '&quot;')
72599              .replace(/'/g, '&#039;');
72600          }
72601
72602          /**
72603           *  Writes the contents of a <a href="#/p5.Table">Table</a> object to a file. Defaults to a
72604           *  text file with comma-separated-values ('csv') but can also
72605           *  use tab separation ('tsv'), or generate an HTML table ('html').
72606           *  The file saving process and location of the saved file will
72607           *  vary between web browsers.
72608           *
72609           *  @method saveTable
72610           *  @param  {p5.Table} Table  the <a href="#/p5.Table">Table</a> object to save to a file
72611           *  @param  {String} filename the filename to which the Table should be saved
72612           *  @param  {String} [options]  can be one of "tsv", "csv", or "html"
72613           *  @example
72614           *  <div><code>
72615           * let table;
72616           *
72617           * function setup() {
72618           *   table = new p5.Table();
72619           *
72620           *   table.addColumn('id');
72621           *   table.addColumn('species');
72622           *   table.addColumn('name');
72623           *
72624           *   let newRow = table.addRow();
72625           *   newRow.setNum('id', table.getRowCount() - 1);
72626           *   newRow.setString('species', 'Panthera leo');
72627           *   newRow.setString('name', 'Lion');
72628           *
72629           *   // To save, un-comment next line then click 'run'
72630           *   // saveTable(table, 'new.csv');
72631           * }
72632           *
72633           * // Saves the following to a file called 'new.csv':
72634           * // id,species,name
72635           * // 0,Panthera leo,Lion
72636           * </code></div>
72637           *
72638           * @alt
72639           * no image displayed
72640           */
72641          _main.default.prototype.saveTable = function(table, filename, options) {
72642            _main.default._validateParameters('saveTable', arguments);
72643            var ext;
72644            if (options === undefined) {
72645              ext = filename.substring(filename.lastIndexOf('.') + 1, filename.length);
72646            } else {
72647              ext = options;
72648            }
72649            var pWriter = this.createWriter(filename, ext);
72650
72651            var header = table.columns;
72652
72653            var sep = ','; // default to CSV
72654            if (ext === 'tsv') {
72655              sep = '\t';
72656            }
72657            if (ext !== 'html') {
72658              // make header if it has values
72659              if (header[0] !== '0') {
72660                for (var h = 0; h < header.length; h++) {
72661                  if (h < header.length - 1) {
72662                    pWriter.write(header[h] + sep);
72663                  } else {
72664                    pWriter.write(header[h]);
72665                  }
72666                }
72667                pWriter.write('\n');
72668              }
72669
72670              // make rows
72671              for (var i = 0; i < table.rows.length; i++) {
72672                var j = void 0;
72673                for (j = 0; j < table.rows[i].arr.length; j++) {
72674                  if (j < table.rows[i].arr.length - 1) {
72675                    //double quotes should be inserted in csv only if c
72675ontains comma separated single value
72676                    if (ext === 'csv' && table.rows[i].arr[j].includes(',')) {
72677                      pWriter.write('"' + table.rows[i].arr[j] + '"' + sep);
72678                    } else {
72679                      pWriter.write(table.rows[i].arr[j] + sep);
72680                    }
72681                  } else {
72682                    //double quotes should be inserted in csv only if contains comma separated single value
72683                    if (ext === 'csv' && table.rows[i].arr[j].includes(',')) {
72684                      pWriter.write('"' + table.rows[i].arr[j] + '"');
72685                    } else {
72686                      pWriter.write(table.rows[i].arr[j]);
72687                    }
72688                  }
72689                }
72690                pWriter.write('\n');
72691              }
72692            } else {
72693              // otherwise, make HTML
72694              pWriter.print('<html>');
72695              pWriter.print('<head>');
72696              var str = '  <meta http-equiv="content-type" content';
72697              str += '="text/html;charset=utf-8" />';
72698              pWriter.print(str);
72699              pWriter.print('</head>');
72700
72701              pWriter.print('<body>');
72702              pWriter.print('  <table>');
72703
72704              // make header if it has values
72705              if (header[0] !== '0') {
72706                pWriter.print('    <tr>');
72707                for (var k = 0; k < header.length; k++) {
72708                  var e = escapeHelper(header[k]);
72709                  pWriter.print('      <td>'.concat(e));
72710                  pWriter.print('      </td>');
72711                }
72712                pWriter.print('    </tr>');
72713              }
72714
72715              // make rows
72716              for (var row = 0; row < table.rows.length; row++) {
72717                pWriter.print('    <tr>');
72718                for (var col = 0; col < table.columns.length; col++) {
72719                  var entry = table.rows[row].getString(col);
72720                  var htmlEntry = escapeHelper(entry);
72721                  pWriter.print('      <td>'.concat(htmlEntry));
72722                  pWriter.print('      </td>');
72723                }
72724                pWriter.print('    </tr>');
72725              }
72726              pWriter.print('  </table>');
72727              pWriter.print('</body>');
72728              pWriter.print('</html>');
72729            }
72730            // close and clear the pWriter
72731            pWriter.close();
72732            pWriter.clear();
72733          }; // end saveTable()
72734
72735          /**
72736           *  Generate a blob of file data as a url to prepare for download.
72737           *  Accepts an array of data, a filename, and an extension (optional).
72738           *  This is a private function because it does not do any formatting,
72739           *  but it is used by <a href="#/p5/saveStrings">
72739saveStrings</a>, <a href="#/p5/saveJSON">saveJSON</a>, <a href="#/p5/saveTable">saveTable</a> etc.
72740           *
72741           *  @param  {Array} dataToDownload
72742           *  @param  {String} filename
72743           *  @param  {String} [extension]
72744           *  @private
72745           */
72746          _main.default.prototype.writeFile = function(
72747            dataToDownload,
72748            filename,
72749            extension
72750          ) {
72751            var type = 'application/octet-stream';
72752            if (_main.default.prototype._isSafari()) {
72753              type = 'text/plain';
72754            }
72755            var blob = new Blob(dataToDownload, {
72756              type: type
72757            });
72758
72759            _main.default.prototype.downloadFile(blob, filename, extension);
72760          };
72761
72762          /**
72763           *  Forces download. Accepts a url to filedata/blob, a filename,
72764           *  and an extension (optional).
72765           *  This is a private function because it does not do any formatting,
72766           *  but it is used by <a href="#/p5/saveStrings">saveStrings</a>, <a href="#/p5/saveJSON">saveJSON</a>, <a href="#/p5/saveTable">saveTable</a> etc.
72767           *
72768           *  @method downloadFile
72769           *  @private
72770           *  @param  {String|Blob} data    either an href generated by createObjectURL,
72771           *                                or a Blob object containing the data
72772           *  @param  {String} [filename]
72773           *  @param  {String} [extension]
72774           */
72775          _main.default.prototype.downloadFile = function(data, fName, extension) {
72776            var fx = _checkFileExtension(fName, extension);
72777            var filename = fx[0];
72778
72779            if (data instanceof Blob) {
72780              _fileSaver.default.saveAs(data, filename);
72781              return;
72782            }
72783
72784            var a = document.createElement('a');
72785            a.href = data;
72786            a.download = filename;
72787
72788            // Firefox requires the link to be added to the DOM before click()
72789            a.onclick = function(e) {
72790              destroyClickedElement(e);
72791              e.stopPropagation();
72792            };
72793
72794            a.style.display = 'none';
72795            document.body.appendChild(a);
72796
72797            // Safari will open this file in the same page as a confusing Blob.
72798            if (_main.default.prototype._isSafari()) {
72799              var aText = 'Hello, Safari user! To download this file...\n';
72800              aText += '1. Go to File --> Save As.\n';
72801              aText += '2. Choose "Page Source" as the Format.\n';
72802              aText += '3. Name it with this extension: ."'.concat(fx[1], '"');
72803              alert(aText);
72804            }
72805            a.click();
72806          };
72807
72808          /**
72809           *  Returns a file extension, or another string
72810           *  if the provided parameter has no extension.
72811           *
72812           *  @param   {String} filename
72813           *  @param   {String} [extension]
72814           *  @return  {String[]} [fileName, fileExtension]
72815           *
72816           *  @private
72817           */
72818          function _checkFileExtension(filename, extension) {
72819            if (!extension || extension === true || extension === 'true') {
72820              extension = '';
72821            }
72822            if (!filename) {
72823              filename = 'untitled';
72824            }
72825            var ext = '';
72826            // make sure the file will have a name, see if filename needs extension
72827            if (filename && filename.includes('.')) {
72828              ext = filename.split('.').pop();
72829            }
72830            // append extension if it doesn't exist
72831            if (extension) {
72832              if (ext !== extension) {
72833                ext = extension;
72834                filename = ''.concat(filename, '.').concat(ext);
72835              }
72836            }
72837            return [filename, ext];
72838          }
72839          _main.default.prototype._checkFileExtension = _checkFileExtension;
72840
72841          /**
72842           *  Returns true if the browser is Safari, false if not.
72843           *  Safari makes trouble for downloading files.
72844           *
72845           *  @return  {Boolean} [description]
72846           *  @private
72847           */
72848          _main.default.prototype._isSafari = function() {
72849            var x = Object.prototype.toString.call(window.HTMLElement);
72850            return x.indexOf('Constructor') > 0;
72851          };
72852
72853          /**
72854           *  Helper function, a callback for download that deletes
72855           *  an invisible anchor element from the DOM once the file
72856           *  has been automatically downloaded.
72857           *
72858           *  @private
72859           */
72860          function destroyClickedElement(event) {
72861            document.body.removeChild(event.target);
72862          }
72863          var _default = _main.default;
72864          exports.default = _default;
72865        },
72866        {
72867          '../core/friendly_errors/fes_core': 51,
72868          '../core/friendly_errors/file_errors': 52,
72869          '../core/friendly_errors/validate_params': 54,
72870          '../core/main': 59,
72871          'es6-promise/auto': 23,
72872          'fetch-jsonp': 25,
72873          'file-saver': 26,
72874          'whatwg-fetch': 37
72875        }
72876      ],
72877      86: [
72878        function(_dereq_, module, exports) {
72879          'use strict';
72880          Object.defineProperty(exports, '__esModule', { value: true });
72881          exports.default = void 0;
72882
72883          var _main = _interopRequireDefault(_dereq_('../core/main'));
72884          function _interopRequireDefault(obj) {
72885            return obj && obj.__esModule ? obj : { default: obj };
72886          } /**
72887           *  <a href="#/p5.Table">Table</a> objects store data with multiple rows and columns, much
72888           *  like in a traditional spreadsheet. Tables can be generated from
72889           *  scratch, dynamically, or using data from an existing file.
72890           *
72891           *  @class p5.Table
72892           *  @constructor
72893           *  @param  {p5.TableRow[]}     [rows] An array of p5.TableRow objects
72894           */ /**
72895           * @module IO
72896           * @submodule Table
72897           * @requires core
72898           */ /**
72899           *  Table Options
72900           *  Generic class for handling tabular data, typically from a
72901           *  CSV, TSV, or other sort of spreadsheet file.
72902           *  CSV files are
72903           *  <a href="http://en.wikipedia.org/wiki/Comma-separated_values">
72904           *  comma separated values</a>, often with the data in quotes. TSV
72905           *  files use tabs as separators, and usually don't bother with the
72906           *  quotes.
72907           *  File names should end with .csv if they're comma separated.
72908           *  A rough "spec" for CSV can be found
72909           *  <a href="http://tools.ietf.org/html/rfc4180">here</a>.
72910           *  To load files, use the <a href="#/p5/loadTable">loadTable</a> method.
72911           *  To save tables to your computer, use the <a href="#/p5/save">save</a> method
72912           *   or the <a href="#/p5/saveTable">saveTable</a> method.
72913           *
72914           *  Possible options include:
72915           *  <ul>
72916           *  <li>csv - parse the table as comma-separated values
72917           *  <li>tsv - parse the table as tab-separated values
72918           *  <li>header - this table has a header (title) row
72919           *  </ul>
72920           */
72921          _main.default.Table = function(rows) {
72922            /**
72923             * An array containing the names of the columns in the table, if the "header" the table is
72924             * loaded with the "header" parameter.
72925             * @property columns {String[]}
72926             * @example
72927             * <div class="norender">
72928             * <code>
72929             * // Given the CSV file "mammals.csv"
72930             * // in the project's "assets" folder:
72931             * //
72932             * // id,species,name
72933             * // 0,Capra hircus,Goat
72934             * // 1,Panthera pardus,Leopard
72935             * // 2,Equus zebra,Zebra
72936             *
72937             * let table;
72938             *
72939             * function preload() {
72940             *   //my table is comma separated value "csv"
72941             *   //and has a header specifying the columns labels
72942             *   table = loadTable('assets/mammals.csv', 'csv', 'header');
72943             * }
72944             *
72945             * function setup() {
72946             *   //print the column names
72947             *   for (let c = 0; c < table.getColumnCount(); c++) {
72948             *     print('column ' + c + ' is named ' + table.columns[c]);
72949             *   }
72950             * }
72951             * </code>
72952             * </div>
72953             */
72954            this.columns = [];
72955
72956            /**
72957             * An array containing the <a href="#/p5.Table">p5.TableRow</a> objects that make up the
72958             * rows of the table. The same result as calling <a href="#/p5/getRows">getRows()</a>
72959             * @property rows {p5.TableRow[]}
72960             */
72961            this.rows = [];
72962          };
72963
72964          /**
72965           *  Use <a href="#/p5/addRow">addRow()</a> to add a new row of data to a <a href="#/p5.Table">p5.Table</a> object. By default,
72966           *  an empty row is created. Typically, you would store a reference to
72967           *  the new row in a TableRow object (see newRow in the example above),
72968           *  and then set individual values using <a href="#/p5/set">set()</a>.
72969           *
72970           *  If a <a href="#/p5.TableRow">p5.TableRow</a> object is included as a parameter, then that row is
72971           *  duplicated and added to the table.
72972           *
72973           *  @method  addRow
72974           *  @param   {p5.TableRow} [row] row to be added to the table
72975           *  @return  {p5.TableRow} the row that was added
72976           *
72977           * @example
72978           * <div class="norender">
72979           * <code>
72980           * // Given the CSV file "mammals.csv"
72981           * // in the project's "assets" folder:
72982           * //
72983           * // id,species,name
72984           * // 0,Capra hircus,Goat
72985           * // 1,Panthera pardus,Leopard
72986           * // 2,Equus zebra,Zebra
72987           *
72988           * let table;
72989           *
72990           * function preload() {
72991           *   //my table is comma separated value "csv"
72992           *   //and has a header specifying the columns labels
72993           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
72994           * }
72995           *
72996           * function setup() {
72997           *   //add a row
72998           *   let newRow = table.addRow();
72999           *   newRow.setString('id', table.getRowCount() - 1);
73000           *   newRow.setString('species', 'Canis Lupus');
73001           *   newRow.setString('name', 'Wolf');
73002           *
73003           *   //print the results
73004           *   for (let r = 0; r < table.getRowCount(); r++)
73005           *     for (let c = 0; c < table.getColumnCount(); c++)
73006           *       print(table.getString(r, c));
73007           * }
73008           * </code>
73009           * </div>
73010           *
73011           * @alt
73012           * no image displayed
73013           */
73014          _main.default.Table.prototype.addRow = function(row) {
73015            // make sure it is a valid TableRow
73016            var r = row || new _main.default.TableRow();
73017
73018            if (typeof r.arr === 'undefined' || typeof r.obj === 'undefined') {
73019              //r = new p5.prototype.TableRow(r);
73020              throw new Error('invalid TableRow: '.concat(r));
73021            }
73022            r.table = this;
73023            this.rows.push(r);
73024            return r;
73025          };
73026
73027          /**
73028           * Removes a row from the table object.
73029           *
73030           * @method  removeRow
73031           * @param   {Integer} id ID number of the row to remove
73032           *
73033           * @example
73034           * <div class="norender">
73035           * <code>
73036           * // Given the CSV file "mammals.csv"
73037           * // in the project's "assets" folder:
73038           * //
73039           * // id,species,name
73040           * // 0,Capra hircus,Goat
73041           * // 1,Panthera pardus,Leopard
73042           * // 2,Equus zebra,Zebra
73043           *
73044           * let table;
73045           *
73046           * function preload() {
73047           *   //my table is comma separated value "csv"
73048           *   //and has a header specifying the columns labels
73049           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73050           * }
73051           *
73052           * function setup() {
73053           *   //remove the first row
73054           *   table.removeRow(0);
73055           *
73056           *   //print the results
73057           *   for (let r = 0; r < table.getRowCount(); r++)
73058           *     for (let c = 0; c < table.getColumnCount(); c++)
73059           *       print(table.getString(r, c));
73060           * }
73061           * </code>
73062           * </div>
73063           *
73064           * @alt
73065           * no image displayed
73066           */
73067          _main.default.Table.prototype.removeRow = function(id) {
73068            this.rows[id].table = null; // remove reference to table
73069            var chunk = this.rows.splice(id + 1, this.rows.length);
73070            this.rows.pop();
73071            this.rows = this.rows.concat(chunk);
73072          };
73073
73074          /**
73075           * Returns a reference to the specified <a href="#/p5.TableRow">p5.TableRow</a>. The reference
73076           * can then be used to get and set values of the selected row.
73077           *
73078           * @method  getRow
73079           * @param  {Integer}   rowID ID number of the row to get
73080           * @return {p5.TableRow} <a href="#/p5.TableRow">p5.TableRow</a> object
73081           *
73082           * @example
73083           * <div class="norender">
73084           * <code>
73085           * // Given the CSV file "mammals.csv"
73086           * // in the project's "assets" folder:
73087           * //
73088           * // id,species,name
73089           * // 0,Capra hircus,Goat
73090           * // 1,Panthera pardus,Leopard
73091           * // 2,Equus zebra,Zebra
73092           *
73093           * let table;
73094           *
73095           * function preload() {
73096           *   //my table is comma separated value "csv"
73097           *   //and has a header specifying the columns labels
73098           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73099           * }
73100           *
73101           * function setup() {
73102           *   let row = table.getRow(1);
73103           *   //print it column by column
73104           *   //note: a row is an object, not an array
73105           *   for (let c = 0; c < table.getColumnCount(); c++) {
73106           *     print(row.getString(c));
73107           *   }
73108           * }
73109           * </code>
73110           * </div>
73111           *
73112           *@alt
73113           * no image displayed
73114           */
73115          _main.default.Table.prototype.getRow = function(r) {
73116            return this.rows[r];
73117          };
73118
73119          /**
73120           *  Gets all rows from the table. Returns an array of <a href="#/p5.TableRow">p5.TableRow</a>s.
73121           *
73122           *  @method  getRows
73123           *  @return {p5.TableRow[]}   Array of <a href="#/p5.TableRow">p5.TableRow</a>s
73124           *
73125           * @example
73126           * <div class="norender">
73127           * <code>
73128           * // Given the CSV file "mammals.csv"
73129           * // in the project's "assets" folder:
73130           * //
73131           * // id,species,name
73132           * // 0,Capra hircus,Goat
73133           * // 1,Panthera pardus,Leopard
73134           * // 2,Equus zebra,Zebra
73135           *
73136           * let table;
73137           *
73138           * function preload() {
73139           *   //my table is comma separated value "csv"
73140           *   //and has a header specifying the columns labels
73141           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73142           * }
73143           *
73144           * function setup() {
73145           *   let rows = table.getRows();
73146           *
73147           *   //warning: rows is an array of objects
73148           *   for (let r = 0; r < rows.length; r++) {
73149           *     rows[r].set('name', 'Unicorn');
73150           *   }
73151           *
73152           *   //print the results
73153           *   for (let r = 0; r < table.getRowCount(); r++)
73154           *     for (let c = 0; c < table.getColumnCount(); c++)
73155           *       print(table.getString(r, c));
73156           * }
73157           * </code>
73158           * </div>
73159           *
73160           * @alt
73161           * no image displayed
73162           */
73163          _main.default.Table.prototype.getRows = function() {
73164            return this.rows;
73165          };
73166
73167          /**
73168           *  Finds the first row in the Table that contains the value
73169           *  provided, and returns a reference to that row. Even if
73170           *  multiple rows are possible matches, only the first matching
73171           *  row is returned. The column to search may be specified by
73172           *  either its ID or title.
73173           *
73174           *  @method  findRow
73175           *  @param  {String} value  The value to match
73176           *  @param  {Integer|String} column ID number or title of the
73177           *                                 column to search
73178           *  @return {p5.TableRow}
73179           *
73180           * @example
73181           * <div class="norender">
73182           * <code>
73183           * // Given the CSV file "mammals.csv"
73184           * // in the project's "assets" folder:
73185           * //
73186           * // id,species,name
73187           * // 0,Capra hircus,Goat
73188           * // 1,Panthera pardus,Leopard
73189           * // 2,Equus zebra,Zebra
73190           *
73191           * let table;
73192           *
73193           * function preload() {
73194           *   //my table is comma separated value "csv"
73195           *   //and has a header specifying the columns labels
73196           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73197           * }
73198           *
73199           * function setup() {
73200           *   //find the animal named zebra
73201           *   let row = table.findRow('Zebra', 'name');
73202           *   //find the corresponding species
73203           *   print(row.getString('species'));
73204           * }
73205           * </code>
73206           * </div>
73207           *
73208           * @alt
73209           * no image displayed
73210           */
73211          _main.default.Table.prototype.findRow = function(value, column) {
73212            // try the Object
73213            if (typeof column === 'string') {
73214              for (var i = 0; i < this.rows.length; i++) {
73215                if (this.rows[i].obj[column] === value) {
73216                  return this.rows[i];
73217                }
73218              }
73219            } else {
73220              // try the Array
73221              for (var j = 0; j < this.rows.length; j++) {
73222                if (this.rows[j].arr[column] === value) {
73223                  return this.rows[j];
73224                }
73225              }
73226            }
73227            // otherwise...
73228            return null;
73229          };
73230
73231          /**
73232           *  Finds the rows in the Table that contain the value
73233           *  provided, and returns references to those rows. Returns an
73234           *  Array, so for must be used to iterate through all the rows,
73235           *  as shown in the example above. The column to search may be
73236           *  specified by either its ID or title.
73237           *
73238           *  @method  findRows
73239           *  @param  {String} value  The value to match
73240           *  @param  {Integer|String} column ID number or title of the
73241           *                                 column to search
73242           *  @return {p5.TableRow[]}        An Array of TableRow objects
73243           *
73244           * @example
73245           * <div class="norender">
73246           * <code>
73247           * // Given the CSV file "mammals.csv"
73248           * // in the project's "assets" folder:
73249           * //
73250           * // id,species,name
73251           * // 0,Capra hircus,Goat
73252           * // 1,Panthera pardus,Leopard
73253           * // 2,Equus zebra,Zebra
73254           *
73255           * let table;
73256           *
73257           * function preload() {
73258           *   //my table is comma separated value "csv"
73259           *   //and has a header specifying the columns labels
73260           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73261           * }
73262           *
73263           * function setup() {
73264           *   //add another goat
73265           *   let newRow = table.addRow();
73266           *   newRow.setString('id', table.getRowCount() - 1);
73267           *   newRow.setString('species', 'Scape Goat');
73268           *   newRow.setString('name', 'Goat');
73269           *
73270           *   //find the rows containing animals named Goat
73271           *   let rows = table.findRows('Goat', 'name');
73272           *   print(rows.length + ' Goats found');
73273           * }
73274           * </code>
73275           * </div>
73276           *
73277           *@alt
73278           * no image displayed
73279           */
73280          _main.default.Table.prototype.findRows = function(value, column) {
73281            var ret = [];
73282            if (typeof column === 'string') {
73283              for (var i = 0; i < this.rows.length; i++) {
73284                if (this.rows[i].obj[column] === value) {
73285                  ret.push(this.rows[i]);
73286                }
73287              }
73288            } else {
73289              // try the Array
73290              for (var j = 0; j < this.rows.length; j++) {
73291                if (this.rows[j].arr[column] === value) {
73292                  ret.push(this.rows[j]);
73293                }
73294              }
73295            }
73296            return ret;
73297          };
73298
73299          /**
73300           * Finds the first row in the Table that matches the regular
73301           * expression provided, and returns a reference to that row.
73302           * Even if multiple rows are possible matches, only the first
73303           * matching row is returned. The column to search may be
73304           * specified by either its ID or title.
73305           *
73306           * @method  matchRow
73307           * @param  {String|RegExp} regexp The regular expression to match
73308           * @param  {String|Integer} column The column ID (number) or
73309           *                                  title (string)
73310           * @return {p5.TableRow}        TableRow object
73311           *
73312           * @example
73313           * <div class="norender">
73314           * <code>
73315           * // Given the CSV file "mammals.csv"
73316           * // in the project's "assets" folder:
73317           * //
73318           * // id,species,name
73319           * // 0,Capra hircus,Goat
73320           * // 1,Panthera pardus,Leopard
73321           * // 2,Equus zebra,Zebra
73322           *
73323           * let table;
73324           *
73325           * function preload() {
73326           *   //my table is comma separated value "csv"
73327           *   //and has a header specifying the columns labels
73328           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73329           * }
73330           *
73331           * function setup() {
73332           *   //Search using specified regex on a given column, return TableRow object
73333           *   let mammal = table.matchRow(new RegExp('ant'), 1);
73334           *   print(mammal.getString(1));
73335           *   //Output "Panthera pardus"
73336           * }
73337           * </code>
73338           * </div>
73339           */
73340          _main.default.Table.prototype.matchRow = function(regexp, column) {
73341            if (typeof column === 'number') {
73342              for (var j = 0; j < this.rows.length; j++) {
73343                if (this.rows[j].arr[column].match(regexp)) {
73344                  return this.rows[j];
73345                }
73346              }
73347            } else {
73348              for (var i = 0; i < this.rows.length; i++) {
73349                if (this.rows[i].obj[column].match(regexp)) {
73350                  return this.rows[i];
73351                }
73352              }
73353            }
73354            return null;
73355          };
73356
73357          /**
73358           * Finds the rows in the Table that match the regular expression provided,
73359           * and returns references to those rows. Returns an array, so for must be
73360           * used to iterate through all the rows, as shown in the example. The
73361           * column to search may be specified by either its ID or title.
73362           *
73363           * @method  matchRows
73364           * @param  {String} regexp The regular expression to match
73365           * @param  {String|Integer} [column] The column ID (number) or
73366           *                                  title (string)
73367           * @return {p5.TableRow[]}          An Array of TableRow objects
73368           * @example
73369           * <div class="norender">
73370           * <code>
73371           * let table;
73372           *
73373           * function setup() {
73374           *   table = new p5.Table();
73375           *
73376           *   table.addColumn('name');
73377           *   table.addColumn('type');
73378           *
73379           *   let newRow = table.addRow();
73380           *   newRow.setString('name', 'Lion');
73381           *   newRow.setString('type', 'Mammal');
73382           *
73383           *   newRow = table.addRow();
73384           *   newRow.setString('name', 'Snake');
73385           *   newRow.setString('type', 'Reptile');
73386           *
73387           *   newRow = table.addRow();
73388           *   newRow.setString('name', 'Mosquito');
73389           *   newRow.setString('type', 'Insect');
73390           *
73391           *   newRow = table.addRow();
73392           *   newRow.setString('name', 'Lizard');
73393           *   newRow.setString('type', 'Reptile');
73394           *
73395           *   let rows = table.matchRows('R.*', 'type');
73396           *   for (let i = 0; i < rows.length; i++) {
73397           *     print(rows[i].getString('name') + ': ' + rows[i].getString('type'));
73398           *   }
73399           * }
73400           * // Sketch prints:
73401           * // Snake: Reptile
73402           * // Lizard: Reptile
73403           * </code>
73404           * </div>
73405           */
73406          _main.default.Table.prototype.matchRows = function(regexp, column) {
73407            var ret = [];
73408            if (typeof column === 'number') {
73409              for (var j = 0; j < this.rows.length; j++) {
73410                if (this.rows[j].arr[column].match(regexp)) {
73411                  ret.push(this.rows[j]);
73412                }
73413              }
73414            } else {
73415              for (var i = 0; i < this.rows.length; i++) {
73416                if (this.rows[i].obj[column].match(regexp)) {
73417                  ret.push(this.rows[i]);
73418                }
73419              }
73420            }
73421            return ret;
73422          };
73423
73424          /**
73425           *  Retrieves all values in the specified column, and returns them
73426           *  as an array. The column may be specified by either its ID or title.
73427           *
73428           *  @method  getColumn
73429           *  @param  {String|Number} column String or Number of the column to return
73430           *  @return {Array}       Array of column values
73431           *
73432           * @example
73433           * <div class="norender">
73434           * <code>
73435           * // Given the CSV file "mammals.csv"
73436           * // in the project's "assets" folder:
73437           * //
73438           * // id,species,name
73439           * // 0,Capra hircus,Goat
73440           * // 1,Panthera pardus,Leopard
73441           * // 2,Equus zebra,Zebra
73442           *
73443           * let table;
73444           *
73445           * function preload() {
73446           *   //my table is comma separated value "csv"
73447           *   //and has a header specifying the columns labels
73448           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73449           * }
73450           *
73451           * function setup() {
73452           *   //getColumn returns an array that can be printed directly
73453           *   print(table.getColumn('species'));
73454           *   //outputs ["Capra hircus", "Panthera pardus", "Equus zebra"]
73455           * }
73456           * </code>
73457           * </div>
73458           *
73459           *@alt
73460           * no image displayed
73461           */
73462          _main.default.Table.prototype.getColumn = function(value) {
73463            var ret = [];
73464            if (typeof value === 'string') {
73465              for (var i = 0; i < this.rows.length; i++) {
73466                ret.push(this.rows[i].obj[value]);
73467              }
73468            } else {
73469              for (var j = 0; j < this.rows.length; j++) {
73470                ret.push(this.rows[j].arr[value]);
73471              }
73472            }
73473            return ret;
73474          };
73475
73476          /**
73477           *  Removes all rows from a Table. While all rows are removed,
73478           *  columns and column titles are maintained.
73479           *
73480           *  @method  clearRows
73481           *
73482           * @example
73483           * <div class="norender">
73484           * <code>
73485           * // Given the CSV file "mammals.csv"
73486           * // in the project's "assets" folder:
73487           * //
73488           * // id,species,name
73489           * // 0,Capra hircus,Goat
73490           * // 1,Panthera pardus,Leopard
73491           * // 2,Equus zebra,Zebra
73492           *
73493           * let table;
73494           *
73495           * function preload() {
73496           *   //my table is comma separated value "csv"
73497           *   //and has a header specifying the columns labels
73498           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73499           * }
73500           *
73501           * function setup() {
73502           *   table.clearRows();
73503           *   print(table.getRowCount() + ' total rows in table');
73504           *   print(table.getColumnCount() + ' total columns in table');
73505           * }
73506           * </code>
73507           * </div>
73508           *
73509           *@alt
73510           * no image displayed
73511           */
73512          _main.default.Table.prototype.clearRows = function() {
73513            delete this.rows;
73514            this.rows = [];
73515          };
73516
73517          /**
73518           *  Use <a href="#/p5/addColumn">addColumn()</a> to add a new column to a <a href="#/p5.Table">Table</a> object.
73519           *  Typically, you will want to specify a title, so the column
73520           *  may be easily referenced later by name. (If no title is
73521           *  specified, the new column's title will be null.)
73522           *
73523           *  @method  addColumn
73524           *  @param {String} [title] title of the given column
73525           *
73526           * @example
73527           * <div class="norender">
73528           * <code>
73529           * // Given the CSV file "mammals.csv"
73530           * // in the project's "assets" folder:
73531           * //
73532           * // id,species,name
73533           * // 0,Capra hircus,Goat
73534           * // 1,Panthera pardus,Leopard
73535           * // 2,Equus zebra,Zebra
73536           *
73537           * let table;
73538           *
73539           * function preload() {
73540           *   //my table is comma separated value "csv"
73541           *   //and has a header specifying the columns labels
73542           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73543           * }
73544           *
73545           * function setup() {
73546           *   table.addColumn('carnivore');
73547           *   table.set(0, 'carnivore', 'no');
73548           *   table.set(1, 'carnivore', 'yes');
73549           *   table.set(2, 'carnivore', 'no');
73550           *
73551           *   //print the results
73552           *   for (let r = 0; r < table.getRowCount(); r++)
73553           *     for (let c = 0; c < table.getColumnCount(); c++)
73554           *       print(table.getString(r, c));
73555           * }
73556           * </code>
73557           * </div>
73558           *
73559           *@alt
73560           * no image displayed
73561           */
73562          _main.default.Table.prototype.addColumn = function(title) {
73563            var t = title || null;
73564            this.columns.push(t);
73565          };
73566
73567          /**
73568           *  Returns the total number of columns in a Table.
73569           *
73570           *  @method  getColumnCount
73571           *  @return {Integer} Number of columns in this table
73572           * @example
73573           * <div>
73574           * <code>
73575           * // given the cvs file "blobs.csv" in /assets directory
73576           * // ID, Name, Flavor, Shape, Color
73577           * // Blob1, Blobby, Sweet, Blob, Pink
73578           * // Blob2, Saddy, Savory, Blob, Blue
73579           *
73580           * let table;
73581           *
73582           * function preload() {
73583           *   table = loadTable('assets/blobs.csv');
73584           * }
73585           *
73586           * function setup() {
73587           *   createCanvas(200, 100);
73588           *   textAlign(CENTER);
73589           *   background(255);
73590           * }
73591           *
73592           * function draw() {
73593           *   let numOfColumn = table.getColumnCount();
73594           *   text('There are ' + numOfColumn + ' columns in the table.', 100, 50);
73595           * }
73596           * </code>
73597           * </div>
73598           */
73599          _main.default.Table.prototype.getColumnCount = function() {
73600            return this.columns.length;
73601          };
73602
73603          /**
73604           *  Returns the total number of rows in a Table.
73605           *
73606           *  @method  getRowCount
73607           *  @return {Integer} Number of rows in this table
73608           * @example
73609           * <div>
73610           * <code>
73611           * // given the cvs file "blobs.csv" in /assets directory
73612           * //
73613           * // ID, Name, Flavor, Shape, Color
73614           * // Blob1, Blobby, Sweet, Blob, Pink
73615           * // Blob2, Saddy, Savory, Blob, Blue
73616           *
73617           * let table;
73618           *
73619           * function preload() {
73620           *   table = loadTable('assets/blobs.csv');
73621           * }
73622           *
73623           * function setup() {
73624           *   createCanvas(200, 100);
73625           *   textAlign(CENTER);
73626           *   background(255);
73627           * }
73628           *
73629           * function draw() {
73630           *   text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);
73631           * }
73632           * </code>
73633           * </div>
73634           */
73635          _main.default.Table.prototype.getRowCount = function() {
73636            return this.rows.length;
73637          };
73638
73639          /**
73640           *  Removes any of the specified characters (or "tokens").
73641           *
73642           *  If no column is specified, then the values in all columns and
73643           *  rows are processed. A specific column may be referenced by
73644           *  either its ID or title.
73645           *
73646           *  @method  removeTokens
73647           *  @param  {String} chars  String listing characters to be removed
73648           *  @param  {String|Integer} [column] Column ID (number)
73649           *                                   or name (string)
73650           *
73651           * @example
73652           * <div class="norender"><code>
73653           * function setup() {
73654           *   let table = new p5.Table();
73655           *
73656           *   table.addColumn('name');
73657           *   table.addColumn('type');
73658           *
73659           *   let newRow = table.addRow();
73660           *   newRow.setString('name', '   $Lion  ,');
73661           *   newRow.setString('type', ',,,Mammal');
73662           *
73663           *   newRow = table.addRow();
73664           *   newRow.setString('name', '$Snake  ');
73665           *   newRow.setString('type', ',,,Reptile');
73666           *
73667           *   table.removeTokens(',$ ');
73668           *   print(table.getArray());
73669           * }
73670           *
73671           * // prints:
73672           * //  0  "Lion"   "Mamal"
73673           * //  1  "Snake"  "Reptile"
73674           * </code></div>
73675           */
73676          _main.default.Table.prototype.removeTokens = function(ch
73676ars, column) {
73677            var escape = function escape(s) {
73678              return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
73679            };
73680            var charArray = [];
73681            for (var i = 0; i < chars.length; i++) {
73682              charArray.push(escape(chars.charAt(i)));
73683            }
73684            var regex = new RegExp(charArray.join('|'), 'g');
73685
73686            if (typeof column === 'undefined') {
73687              for (var c = 0; c < this.columns.length; c++) {
73688                for (var d = 0; d < this.rows.length; d++) {
73689                  var s = this.rows[d].arr[c];
73690                  s = s.replace(regex, '');
73691                  this.rows[d].arr[c] = s;
73692                  this.rows[d].obj[this.columns[c]] = s;
73693                }
73694              }
73695            } else if (typeof column === 'string') {
73696              for (var j = 0; j < this.rows.length; j++) {
73697                var val = this.rows[j].obj[column];
73698                val = val.replace(regex, '');
73699                this.rows[j].obj[column] = val;
73700                var pos = this.columns.indexOf(column);
73701                this.rows[j].arr[pos] = val;
73702              }
73703            } else {
73704              for (var k = 0; k < this.rows.length; k++) {
73705                var str = this.rows[k].arr[column];
73706                str = str.replace(regex, '');
73707                this.rows[k].arr[column] = str;
73708                this.rows[k].obj[this.columns[column]] = str;
73709              }
73710            }
73711          };
73712
73713          /**
73714           *  Trims leading and trailing whitespace, such as spaces and tabs,
73715           *  from String table values. If no column is specified, then the
73716           *  values in all columns and rows are trimmed. A specific column
73717           *  may be referenced by either its ID or title.
73718           *
73719           *  @method  trim
73720           *  @param  {String|Integer} [column] Column ID (number)
73721           *                                   or name (string)
73722           * @example
73723           * <div class="norender"><code>
73724           * function setup() {
73725           *   let table = new p5.Table();
73726           *
73727           *   table.addColumn('name');
73728           *   table.addColumn('type');
73729           *
73730           *   let newRow = table.addRow();
73731           *   newRow.setString('name', '   Lion  ,');
73732           *   newRow.setString('type', ' Mammal  ');
73733           *
73734           *   newRow = table.addRow();
73735           *   newRow.setString('name', '  Snake  ');
73736           *   newRow.setString('type', '  Reptile  ');
73737           *
73738           *   table.trim();
73739           *   print(table.getArray());
73740           * }
73741           *
73742           * // prints:
73743           * //  0  "Lion"   "Mamal"
73744           * //  1  "Snake"  "Reptile"
73745           * </code></div>
73746           */
73747          _main.default.Table.prototype.trim = function(column) {
73748            var regex = new RegExp(' ', 'g');
73749
73750            if (typeof column === 'undefined') {
73751              for (var c = 0; c < this.columns.length; c++) {
73752                for (var d = 0; d < this.rows.length; d++) {
73753                  var s = this.rows[d].arr[c];
73754                  s = s.replace(regex, '');
73755                  this.rows[d].arr[c] = s;
73756                  this.rows[d].obj[this.columns[c]] = s;
73757                }
73758              }
73759            } else if (typeof column === 'string') {
73760              for (var j = 0; j < this.rows.length; j++) {
73761                var val = this.rows[j].obj[column];
73762                val = val.replace(regex, '');
73763                this.rows[j].obj[column] = val;
73764                var pos = this.columns.indexOf(column);
73765                this.rows[j].arr[pos] = val;
73766              }
73767            } else {
73768              for (var k = 0; k < this.rows.length; k++) {
73769                var str = this.rows[k].arr[column];
73770                str = str.replace(regex, '');
73771                this.rows[k].arr[column] = str;
73772                this.rows[k].obj[this.columns[column]] = str;
73773              }
73774            }
73775          };
73776
73777          /**
73778           *  Use <a href="#/p5/removeColumn">removeColumn()</a> to remove an existing column from a Table
73779           *  object. The column to be removed may be identified by either
73780           *  its title (a String) or its index value (an int).
73781           *  removeColumn(0) would remove the first column, removeColumn(1)
73782           *  would remove the second column, and so on.
73783           *
73784           *  @method  removeColumn
73785           *  @param  {String|Integer} column columnName (string) or ID (number)
73786           *
73787           * @example
73788           * <div class="norender">
73789           * <code>
73790           * // Given the CSV file "mammals.csv"
73791           * // in the project's "assets" folder:
73792           * //
73793           * // id,species,name
73794           * // 0,Capra hircus,Goat
73795           * // 1,Panthera pardus,Leopard
73796           * // 2,Equus zebra,Zebra
73797           *
73798           * let table;
73799           *
73800           * function preload() {
73801           *   //my table is comma separated value "csv"
73802           *   //and has a header specifying the columns labels
73803           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73804           * }
73805           *
73806           * function setup() {
73807           *   table.removeColumn('id');
73808           *   print(table.getColumnCount());
73809           * }
73810           * </code>
73811           * </div>
73812           *
73813           *@alt
73814           * no image displayed
73815           */
73816          _main.default.Table.prototype.removeColumn = function(c) {
73817            var cString;
73818            var cNumber;
73819            if (typeof c === 'string') {
73820              // find the position of c in the columns
73821              cString = c;
73822              cNumber = this.columns.indexOf(c);
73823            } else {
73824              cNumber = c;
73825              cString = this.columns[c];
73826            }
73827
73828            var chunk = this.columns.splice(cNumber + 1, this.columns.length);
73829            this.columns.pop();
73830            this.columns = this.columns.concat(chunk);
73831
73832            for (var i = 0; i < this.rows.length; i++) {
73833              var tempR = this.rows[i].arr;
73834              var chip = tempR.splice(cNumber + 1, tempR.length);
73835              tempR.pop();
73836              this.rows[i].arr = tempR.concat(chip);
73837              delete this.rows[i].obj[cString];
73838            }
73839          };
73840
73841          /**
73842           * Stores a value in the Table's specified row and column.
73843           * The row is specified by its ID, while the column may be specified
73844           * by either its ID or title.
73845           *
73846           * @method  set
73847           * @param {Integer} row row ID
73848           * @param {String|Integer} column column ID (Number)
73849           *                               or title (String)
73850           * @param {String|Number} value  value to assign
73851           *
73852           * @example
73853           * <div class="norender">
73854           * <code>
73855           * // Given the CSV file "mammals.csv"
73856           * // in the project's "assets" folder:
73857           * //
73858           * // id,species,name
73859           * // 0,Capra hircus,Goat
73860           * // 1,Panthera pardus,Leopard
73861           * // 2,Equus zebra,Zebra
73862           *
73863           * let table;
73864           *
73865           * function preload() {
73866           *   //my table is comma separated value "csv"
73867           *   //and has a header specifying the columns labels
73868           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73869           * }
73870           *
73871           * function setup() {
73872           *   table.set(0, 'species', 'Canis Lupus');
73873           *   table.set(0, 'name', 'Wolf');
73874           *
73875           *   //print the results
73876           *   for (let r = 0; r < table.getRowCount(); r++)
73877           *     for (let c = 0; c < table.getColumnCount(); c++)
73878           *       print(table.getString(r, c));
73879           * }
73880           * </code>
73881           * </div>
73882           *
73883           *@alt
73884           * no image displayed
73885           */
73886          _main.default.Table.prototype.set = function(row, column, value) {
73887            this.rows[row].set(column, value);
73888          };
73889
73890          /**
73891           * Stores a Float value in the Table's specified row and column.
73892           * The row is specified by its ID, while the column may be specified
73893           * by either its ID or title.
73894           *
73895           * @method setNum
73896           * @param {Integer} row row ID
73897           * @param {String|Integer} column column ID (Number)
73898           *                               or title (String)
73899           * @param {Number} value  value to assign
73900           *
73901           * @example
73902           * <div class="norender">
73903           * <code>
73904           * // Given the CSV file "mammals.csv"
73905           * // in the project's "assets" folder:
73906           * //
73907           * // id,species,name
73908           * // 0,Capra hircus,Goat
73909           * // 1,Panthera pardus,Leopard
73910           * // 2,Equus zebra,Zebra
73911           *
73912           * let table;
73913           *
73914           * function preload() {
73915           *   //my table is comma separated value "csv"
73916           *   //and has a header specifying the columns labels
73917           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73918           * }
73919           *
73920           * function setup() {
73921           *   table.setNum(1, 'id', 1);
73922           *
73923           *   print(table.getColumn(0));
73924           *   //["0", 1, "2"]
73925           * }
73926           * </code>
73927           * </div>
73928           *
73929           *@alt
73930           * no image displayed
73931           */
73932          _main.default.Table.prototype.setNum = function(row, column, value) {
73933            this.rows[row].setNum(column, value);
73934          };
73935
73936          /**
73937           * Stores a String value in the Table's specified row and column.
73938           * The row is specified by its ID, while the column may be specified
73939           * by either its ID or title.
73940           *
73941           * @method  setString
73942           * @param {Integer} row row ID
73943           * @param {String|Integer} column column ID (Number)
73944           *                               or title (String)
73945           * @param {String} value  value to assign
73946           * @example
73947           * <div class="norender"><code>
73948           * // Given the CSV file "mammals.csv" in the project's "assets" folder:
73949           * //
73950           * // id,species,name
73951           * // 0,Capra hircus,Goat
73952           * // 1,Panthera pardus,Leopard
73953           * // 2,Equus zebra,Zebra
73954           *
73955           * let table;
73956           *
73957           * function preload() {
73958           *   //my table is comma separated value "csv"
73959           *   //and has a header specifying the columns labels
73960           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
73961           * }
73962           *
73963           * function setup() {
73964           *   //add a row
73965           *   let newRow = table.addRow();
73966           *   newRow.setString('id', table.getRowCount() - 1);
73967           *   newRow.setString('species', 'Canis Lupus');
73968           *   newRow.setString('name', 'Wolf');
73969           *
73970           *   print(table.getArray());
73971           * }
73972           * </code></div>
73973           *
73974           * @alt
73975           * no image displayed
73976           */
73977          _main.default.Table.prototype.setString = function(row, column, value) {
73978            this.rows[row].setString(column, value);
73979          };
73980
73981          /**
73982           * Retrieves a value from the Table's specified row and column.
73983           * The row is specified by its ID, while the column may be specified by
73984           * either its ID or title.
73985           *
73986           * @method  get
73987           * @param {Integer} row row ID
73988           * @param  {String|Integer} column columnName (string) or
73989           *                                   ID (number)
73990           * @return {String|Number}
73991           *
73992           * @example
73993           * <div class="norender">
73994           * <code>
73995           * // Given the CSV file "mammals.csv"
73996           * // in the project's "assets" folder:
73997           * //
73998           * // id,species,name
73999           * // 0,Capra hircus,Goat
74000           * // 1,Panthera pardus,Leopard
74001           * // 2,Equus zebra,Zebra
74002           *
74003           * let table;
74004           *
74005           * function preload() {
74006           *   //my table is comma separated value "csv"
74007           *   //and has a header specifying the columns labels
74008           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74009           * }
74010           *
74011           * function setup() {
74012           *   print(table.get(0, 1));
74013           *   //Capra hircus
74014           *   print(table.get(0, 'species'));
74015           *   //Capra hircus
74016           * }
74017           * </code>
74018           * </div>
74019           *
74020           *@alt
74021           * no image displayed
74022           */
74023          _main.default.Table.prototype.get = function(row, column) {
74024            return this.rows[row].get(column);
74025          };
74026
74027          /**
74028           * Retrieves a Float value from the Table's specified row and column.
74029           * The row is specified by its ID, while the column may be specified by
74030           * either its ID or title.
74031           *
74032           * @method  getNum
74033           * @param {Integer} row row ID
74034           * @param  {String|Integer} column columnName (string) or
74035           *                                   ID (number)
74036           * @return {Number}
74037           *
74038           * @example
74039           * <div class="norender">
74040           * <code>
74041           * // Given the CSV file "mammals.csv"
74042           * // in the project's "assets" folder:
74043           * //
74044           * // id,species,name
74045           * // 0,Capra hircus,Goat
74046           * // 1,Panthera pardus,Leopard
74047           * // 2,Equus zebra,Zebra
74048           *
74049           * let table;
74050           *
74051           * function preload() {
74052           *   //my table is comma separated value "csv"
74053           *   //and has a header specifying the columns labels
74054           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74055           * }
74056           *
74057           * function setup() {
74058           *   print(table.getNum(1, 0) + 100);
74059           *   //id 1 + 100 = 101
74060           * }
74061           * </code>
74062           * </div>
74063           *
74064           *@alt
74065           * no image displayed
74066           */
74067          _main.default.Table.prototype.getNum = function(row, column) {
74068            return this.rows[row].getNum(column);
74069          };
74070
74071          /**
74072           * Retrieves a String value from the Table's specified row and column.
74073           * The row is specified by its ID, while the column may be specified by
74074           * either its ID or title.
74075           *
74076           * @method  getString
74077           * @param {Integer} row row ID
74078           * @param  {String|Integer} column columnName (string) or
74079           *                                   ID (number)
74080           * @return {String}
74081           *
74082           * @example
74083           * <div class="norender">
74084           * <code>
74085           * // Given the CSV file "mammals.csv"
74086           * // in the project's "assets" folder:
74087           * //
74088           * // id,species,name
74089           * // 0,Capra hircus,Goat
74090           * // 1,Panthera pardus,Leopard
74091           * // 2,Equus zebra,Zebra
74092           *
74093           * let table;
74094           *
74095           * function preload() {
74096           *   // table is comma separated value "CSV"
74097           *   // and has specifiying header for column labels
74098           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74099           * }
74100           *
74101           * function setup() {
74102           *   print(table.getString(0, 0)); // 0
74103           *   print(table.getString(0, 1)); // Capra hircus
74104           *   print(table.getString(0, 2)); // Goat
74105           *   print(table.getString(1, 0)); // 1
74106           *   print(table.getString(1, 1)); // Panthera pardus
74107           *   print(table.getString(1, 2)); // Leopard
74108           *   print(table.getString(2, 0)); // 2
74109           *   print(table.getString(2, 1)); // Equus zebra
74110           *   print(table.getString(2, 2)); // Zebra
74111           * }
74112           * </code>
74113           * </div>
74114           *
74115           *@alt
74116           * no image displayed
74117           */
74118
74119          _main.default.Table.prototype.getString = function(row, column) {
74120            return this.rows[row].getString(column);
74121          };
74122
74123          /**
74124           * Retrieves all table data and returns as an object. If a column name is
74125           * passed in, each row object will be s
74125tored with that attribute as its
74126           * title.
74127           *
74128           * @method  getObject
74129           * @param {String} [headerColumn] Name of the column which should be used to
74130           *                              title each row object (optional)
74131           * @return {Object}
74132           *
74133           * @example
74134           * <div class="norender">
74135           * <code>
74136           * // Given the CSV file "mammals.csv"
74137           * // in the project's "assets" folder:
74138           * //
74139           * // id,species,name
74140           * // 0,Capra hircus,Goat
74141           * // 1,Panthera pardus,Leopard
74142           * // 2,Equus zebra,Zebra
74143           *
74144           * let table;
74145           *
74146           * function preload() {
74147           *   //my table is comma separated value "csv"
74148           *   //and has a header specifying the columns labels
74149           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74150           * }
74151           *
74152           * function setup() {
74153           *   let tableObject = table.getObject();
74154           *
74155           *   print(tableObject);
74156           *   //outputs an object
74157           * }
74158           * </code>
74159           * </div>
74160           *
74161           *@alt
74162           * no image displayed
74163           */
74164          _main.default.Table.prototype.getObject = function(headerColumn) {
74165            var tableObject = {};
74166            var obj, cPos, index;
74167
74168            for (var i = 0; i < this.rows.length; i++) {
74169              obj = this.rows[i].obj;
74170
74171              if (typeof headerColumn === 'string') {
74172                cPos = this.columns.indexOf(headerColumn); // index of columnID
74173                if (cPos >= 0) {
74174                  index = obj[headerColumn];
74175                  tableObject[index] = obj;
74176                } else {
74177                  throw new Error(
74178                    'This table has no column named "'.concat(headerColumn, '"')
74179                  );
74180                }
74181              } else {
74182                tableObject[i] = this.rows[i].obj;
74183              }
74184            }
74185            return tableObject;
74186          };
74187
74188          /**
74189           * Retrieves all table data and returns it as a multidimensional array.
74190           *
74191           * @method  getArray
74192           * @return {Array}
74193           *
74194           * @example
74195           * <div class="norender">
74196           * <code>
74197           * // Given the CSV file "mammals.csv"
74198           * // in the project's "assets" folder
74199           * //
74200           * // id,species,name
74201           * // 0,Capra hircus,Goat
74202           * // 1,Panthera pardus,Leoperd
74203           * // 2,Equus zebra,Zebra
74204           *
74205           * let table;
74206           *
74207           * function preload() {
74208           *   // table is comma separated value "CSV"
74209           *   // and has specifiying header for column labels
74210           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74211           * }
74212           *
74213           * function setup() {
74214           *   let tableArray = table.getArray();
74215           *   for (let i = 0; i < tableArray.length; i++) {
74216           *     print(tableArray[i]);
74217           *   }
74218           * }
74219           * </code>
74220           * </div>
74221           *
74222           *@alt
74223           * no image displayed
74224           */
74225          _main.default.Table.prototype.getArray = function() {
74226            var tableArray = [];
74227            for (var i = 0; i < this.rows.length; i++) {
74228              tableArray.push(this.rows[i].arr);
74229            }
74230            return tableArray;
74231          };
74232          var _default = _main.default;
74233          exports.default = _default;
74234        },
74235        { '../core/main': 59 }
74236      ],
74237      87: [
74238        function(_dereq_, module, exports) {
74239          'use strict';
74240          Object.defineProperty(exports, '__esModule', { value: true });
74241          exports.default = void 0;
74242
74243          var _main = _interopRequireDefault(_dereq_('../core/main'));
74244          function _interopRequireDefault(obj) {
74245            return obj && obj.__esModule ? obj : { default: obj };
74246          }
74247          /**
74248           * @module IO
74249           * @submodule Table
74250           * @requires core
74251           */ /**
74252           *  A TableRow object represents a single row of data values,
74253           *  stored in columns, from a table.
74254           *
74255           *  A Table Row contains both an ordered array, and an unordered
74256           *  JSON object.
74257           *
74258           *  @class p5.TableRow
74259           *  @constructor
74260           *  @param {String} [str]       optional: populate the row with a
74261           *                              string of values, separated by the
74262           *                              separator
74263           *  @param {String} [separator] comma separated values (csv) by default
74264           */ _main.default.TableRow = function(str, separator) {
74265            var arr = [];
74266            var obj = {};
74267            if (str) {
74268              separator = separator || ',';
74269              arr = str.split(separator);
74270            }
74271            for (var i = 0; i < arr.length; i++) {
74272              var key = i;
74273              var val = arr[i];
74274              obj[key] = val;
74275            }
74276            this.arr = arr;
74277            this.obj = obj;
74278            this.table = null;
74279          };
74280
74281          /**
74282           *  Stores a value in the TableRow's specified column.
74283           *  The column may be specified by either its ID or title.
74284           *
74285           *  @method  set
74286           *  @param {String|Integer} column Column ID (Number)
74287           *                                or Title (String)
74288           *  @param {String|Number} value  The value to be stored
74289           *
74290           * @example
74291           * <div class="norender"><code>
74292           * // Given the CSV file "mammals.csv" in the project's "assets" folder:
74293           * //
74294           * // id,species,name
74295           * // 0,Capra hircus,Goat
74296           * // 1,Panthera pardus,Leopard
74297           * // 2,Equus zebra,Zebra
74298           *
74299           * let table;
74300           *
74301           * function preload() {
74302           *   //my table is comma separated value "csv"
74303           *   //and has a header specifying the columns labels
74304           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74305           * }
74306           *
74307           * function setup() {
74308           *   let rows = table.getRows();
74309           *   for (let r = 0; r < rows.length; r++) {
74310           *     rows[r].set('name', 'Unicorn');
74311           *   }
74312           *
74313           *   //print the results
74314           *   print(table.getArray());
74315           * }
74316           * </code></div>
74317           *
74318           * @alt
74319           * no image displayed
74320           */
74321          _main.default.TableRow.prototype.set = function(column, value) {
74322            // if typeof column is string, use .obj
74323            if (typeof column === 'string') {
74324              var cPos = this.table.columns.indexOf(column); // index of columnID
74325              if (cPos >= 0) {
74326                this.obj[column] = value;
74327                this.arr[cPos] = value;
74328              } else {
74329                throw new Error('This table has no column named "'.concat(column, '"'));
74330              }
74331            } else {
74332              // if typeof column is number, use .arr
74333              if (column < this.table.columns.length) {
74334                this.arr[column] = value;
74335                var cTitle = this.table.columns[column];
74336                this.obj[cTitle] = value;
74337              } else {
74338                throw new Error(
74339                  'Column #'.concat(column, ' is out of the range of this table')
74340                );
74341              }
74342            }
74343          };
74344
74345          /**
74346           *  Stores a Float value in the TableRow's specified column.
74347           *  The column may be specified by either its ID or title.
74348           *
74349           *  @method  setNum
74350           *  @param {String|Integer} column Column ID (Number)
74351           *                                or Title (String)
74352           *  @param {Number|String} value  The value to be stored
74353           *                                as a Float
74354           * @example
74355           * <div class="norender"><code>
74356           * // Given the CSV file "mammals.csv" in the project's "assets" folder:
74357           * //
74358           * // id,species,name
74359           * // 0,Capra hircus,Goat
74360           * // 1,Panthera pardus,Leopard
74361           * // 2,Equus zebra,Zebra
74362           *
74363           * let table;
74364           *
74365           * function preload() {
74366           *   //my table is comma separated value "csv"
74367           *   //and has a header specifying the columns labels
74368           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74369           * }
74370           *
74371           * function setup() {
74372           *   let rows = table.getRows();
74373           *   for (let r = 0; r < rows.length; r++) {
74374           *     rows[r].setNum('id', r + 10);
74375           *   }
74376           *
74377           *   print(table.getArray());
74378           * }
74379           * </code></div>
74380           *
74381           * @alt
74382           * no image displayed
74383           */
74384          _main.default.TableRow.prototype.setNum = function(column, value) {
74385            var floatVal = parseFloat(value);
74386            this.set(column, floatVal);
74387          };
74388
74389          /**
74390           *  Stores a String value in the TableRow's specified column.
74391           *  The column may be specified by either its ID or title.
74392           *
74393           *  @method  setString
74394           *  @param {String|Integer} column Column ID (Number)
74395           *                                or Title (String)
74396           *  @param {String|Number|Boolean|Object} value  The value to be stored
74397           *                                as a String
74398           * @example
74399           * <div class="norender"><code>
74400           * // Given the CSV file "mammals.csv" in the project's "assets" folder:
74401           * //
74402           * // id,species,name
74403           * // 0,Capra hircus,Goat
74404           * // 1,Panthera pardus,Leopard
74405           * // 2,Equus zebra,Zebra
74406           *
74407           * let table;
74408           *
74409           * function preload() {
74410           *   //my table is comma separated value "csv"
74411           *   //and has a header specifying the columns labels
74412           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74413           * }
74414           *
74415           * function setup() {
74416           *   let rows = table.getRows();
74417           *   for (let r = 0; r < rows.length; r++) {
74418           *     let name = rows[r].getString('name');
74419           *     rows[r].setString('name', 'A ' + name + ' named George');
74420           *   }
74421           *
74422           *   print(table.getArray());
74423           * }
74424           * </code></div>
74425           *
74426           * @alt
74427           * no image displayed
74428           */
74429          _main.default.TableRow.prototype.setString = function(column, value) {
74430            var stringVal = value.toString();
74431            this.set(column, stringVal);
74432          };
74433
74434          /**
74435           *  Retrieves a value from the TableRow's specified column.
74436           *  The column may be specified by either its ID or title.
74437           *
74438           *  @method  get
74439           *  @param  {String|Integer} column columnName (string) or
74440           *                                   ID (number)
74441           *  @return {String|Number}
74442           *
74443           * @example
74444           * <div class="norender"><code>
74445           * // Given the CSV file "mammals.csv" in the project's "assets" folder:
74446           * //
74447           * // id,species,name
74448           * // 0,Capra hircus,Goat
74449           * // 1,Panthera pardus,Leopard
74450           * // 2,Equus zebra,Zebra
74451           *
74452           * let table;
74453           *
74454           * function preload() {
74455           *   //my table is comma separated value "csv"
74456           *   //and has a header specifying the columns labels
74457           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74458           * }
74459           *
74460           * function setup() {
74461           *   let names = [];
74462           *   let rows = table.getRows();
74463           *   for (let r = 0; r < rows.length; r++) {
74464           *     names.push(rows[r].get('name'));
74465           *   }
74466           *
74467           *   print(names);
74468           * }
74469           * </code></div>
74470           *
74471           * @alt
74472           * no image displayed
74473           */
74474          _main.default.TableRow.prototype.get = function(column) {
74475            if (typeof column === 'string') {
74476              return this.obj[column];
74477            } else {
74478              return this.arr[column];
74479            }
74480          };
74481
74482          /**
74483           *  Retrieves a Float value from the TableRow's specified
74484           *  column. The column may be specified by either its ID or
74485           *  title.
74486           *
74487           *  @method  getNum
74488           *  @param  {String|Integer} column columnName (string) or
74489           *                                   ID (number)
74490           *  @return {Number}  Float Floating point number
74491           * @example
74492           * <div class="norender"><code>
74493           * // Given the CSV file "mammals.csv" in the project's "assets" folder:
74494           * //
74495           * // id,species,name
74496           * // 0,Capra hircus,Goat
74497           * // 1,Panthera pardus,Leopard
74498           * // 2,Equus zebra,Zebra
74499           *
74500           * let table;
74501           *
74502           * function preload() {
74503           *   //my table is comma separated value "csv"
74504           *   //and has a header specifying the columns labels
74505           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74506           * }
74507           *
74508           * function setup() {
74509           *   let rows = table.getRows();
74510           *   let minId = Infinity;
74511           *   let maxId = -Infinity;
74512           *   for (let r = 0; r < rows.length; r++) {
74513           *     let id = rows[r].getNum('id');
74514           *     minId = min(minId, id);
74515           *     maxId = min(maxId, id);
74516           *   }
74517           *   print('minimum id = ' + minId + ', maximum id = ' + maxId);
74518           * }
74519           * </code></div>
74520           *
74521           * @alt
74522           * no image displayed
74523           */
74524          _main.default.TableRow.prototype.getNum = function(column) {
74525            var ret;
74526            if (typeof column === 'string') {
74527              ret = parseFloat(this.obj[column]);
74528            } else {
74529              ret = parseFloat(this.arr[column]);
74530            }
74531
74532            if (ret.toString() === 'NaN') {
74533              throw 'Error: '.concat(this.obj[column], ' is NaN (Not a Number)');
74534            }
74535            return ret;
74536          };
74537
74538          /**
74539           *  Retrieves an String value from the TableRow's specified
74540           *  column. The column may be specified by either its ID or
74541           *  title.
74542           *
74543           *  @method  getString
74544           *  @param  {String|Integer} column columnName (string) or
74545           *                                   ID (number)
74546           *  @return {String}  String
74547           * @example
74548           * <div class="norender"><code>
74549           * // Given the CSV file "mammals.csv" in the project's "assets" folder:
74550           * //
74551           * // id,species,name
74552           * // 0,Capra hircus,Goat
74553           * // 1,Panthera pardus,Leopard
74554           * // 2,Equus zebra,Zebra
74555           *
74556           * let table;
74557           *
74558           * function preload() {
74559           *   //my table is comma separated value "csv"
74560           *   //and has a header specifying the columns labels
74561           *   table = loadTable('assets/mammals.csv', 'csv', 'header');
74562           * }
74563           *
74564           * function setup() {
74565           *   let rows = table.getRows();
74566           *   let longest = '';
74567           *   for (let r = 0; r < rows.length; r++) {
74568           *     let species = rows[r].getString('species');
74569           *     if (longest.length < species.length) {
74570           *       longest = species;
74571           *     }
74572           *   }
74573           *
74574           *   print('longest: ' + longest);
74575           * }
74576           * </code></div>
74577           *
74578           * @alt
74579           * no image displayed
74580           */
74581          _main.default.TableRow.prototype.getString = function(column) {
74582            if (typeof column === 'string') {
74583              return this.obj[column].toString();
74584            } else {
74585              return this.arr[column].toString();
74586            }
74587          };
74588          var _default = _main.default;
74589          exports.default = _default;
74590        },
74591        { '../core/main': 59 }
74592      ],
74593      88: [
74594        function(_dereq_, module, exports) {
74595          'use strict';
74596          Object.defineProperty(exports, '__esModule', { value: true });
74597          exports.default = void 0;
74598
74599          var _main = _interopRequireDefault(_dereq_('../core/main'));
74600          function _interopRequireDefault(obj) {
74601            return obj && obj.__esModule ? obj : { default: obj };
74602          }
74603          /**
74604           * @module IO
74605           * @submodule Input
74606           * @requires core
74607           */ /**
74608           * XML is a representation of an XML object, able to parse XML code. Use
74609           * <a href="#/p5/loadXML">loadXML()</a> to load external XML files and create XML objects.
74610           *
74611           * @class p5.XML
74612           * @constructor
74613           * @example
74614           * <div class='norender'><code>
74615           * // The following short XML file called "mammals.xml" is parsed
74616           * // in the code below.
74617           * //
74618           * // <?xml version="1.0"?>
74619           * // &lt;mammals&gt;
74620           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
74621           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
74622           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
74623           * // &lt;/mammals&gt;
74624           *
74625           * let xml;
74626           *
74627           * function preload() {
74628           *   xml = loadXML('assets/mammals.xml');
74629           * }
74630           *
74631           * function setup() {
74632           *   let children = xml.getChildren('animal');
74633           *
74634           *   for (let i = 0; i < children.length; i++) {
74635           *     let id = children[i].getNum('id');
74636           *     let coloring = children[i].getString('species');
74637           *     let name = children[i].getContent();
74638           *     print(id + ', ' + coloring + ', ' + name);
74639           *   }
74640           * }
74641           *
74642           * // Sketch prints:
74643           * // 0, Capra hircus, Goat
74644           * // 1, Panthera pardus, Leopard
74645           * // 2, Equus zebra, Zebra
74646           * </code></div>
74647           *
74648           * @alt
74649           * no image displayed
74650           */ _main.default.XML = function(DOM) {
74651            if (!DOM) {
74652              var xmlDoc = document.implementation.createDocument(null, 'doc');
74653              this.DOM = xmlDoc.createElement('root');
74654            } else {
74655              this.DOM = DOM;
74656            }
74657          };
74658
74659          /**
74660           * Gets a copy of the element's parent. Returns the parent as another
74661           * <a href="#/p5.XML">p5.XML</a> object.
74662           *
74663           * @method getParent
74664           * @return {p5.XML}   element parent
74665           * @example
74666           * <div class='norender'><code>
74667           * // The following short XML file called "mammals.xml" is parsed
74668           * // in the code below.
74669           * //
74670           * // <?xml version="1.0"?>
74671           * // &lt;mammals&gt;
74672           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
74673           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
74674           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
74675           * // &lt;/mammals&gt;
74676           *
74677           * let xml;
74678           *
74679           * function preload() {
74680           *   xml = loadXML('assets/mammals.xml');
74681           * }
74682           *
74683           * function setup() {
74684           *   let children = xml.getChildren('animal');
74685           *   let parent = children[1].getParent();
74686           *   print(parent.getName());
74687           * }
74688           *
74689           * // Sketch prints:
74690           * // mammals
74691           * </code></div>
74692           */
74693          _main.default.XML.prototype.getParent = function() {
74694            return new _main.default.XML(this.DOM.parentElement);
74695          };
74696
74697          /**
74698           *  Gets the element's full name, which is returned as a String.
74699           *
74700           * @method getName
74701           * @return {String} the name of the node
74702           * @example&lt;animal
74703           * <div class='norender'><code>
74704           * // The following short XML file called "mammals.xml" is parsed
74705           * // in the code below.
74706           * //
74707           * // <?xml version="1.0"?>
74708           * // &lt;mammals&gt;
74709           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
74710           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
74711           * //   &lt;animal id="2" species="Equus zebra">
74711Zebra&lt;/animal&gt;
74712           * // &lt;/mammals&gt;
74713           *
74714           * let xml;
74715           *
74716           * function preload() {
74717           *   xml = loadXML('assets/mammals.xml');
74718           * }
74719           *
74720           * function setup() {
74721           *   print(xml.getName());
74722           * }
74723           *
74724           * // Sketch prints:
74725           * // mammals
74726           * </code></div>
74727           */
74728          _main.default.XML.prototype.getName = function() {
74729            return this.DOM.tagName;
74730          };
74731
74732          /**
74733           * Sets the element's name, which is specified as a String.
74734           *
74735           * @method setName
74736           * @param {String} the new name of the node
74737           * @example&lt;animal
74738           * <div class='norender'><code>
74739           * // The following short XML file called "mammals.xml" is parsed
74740           * // in the code below.
74741           * //
74742           * // <?xml version="1.0"?>
74743           * // &lt;mammals&gt;
74744           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
74745           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
74746           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
74747           * // &lt;/mammals&gt;
74748           *
74749           * let xml;
74750           *
74751           * function preload() {
74752           *   xml = loadXML('assets/mammals.xml');
74753           * }
74754           *
74755           * function setup() {
74756           *   print(xml.getName());
74757           *   xml.setName('fish');
74758           *   print(xml.getName());
74759           * }
74760           *
74761           * // Sketch prints:
74762           * // mammals
74763           * // fish
74764           * </code></div>
74765           */
74766          _main.default.XML.prototype.setName = function(name) {
74767            var content = this.DOM.innerHTML;
74768            var attributes = this.DOM.attributes;
74769            var xmlDoc = document.implementation.createDocument(null, 'default');
74770            var newDOM = xmlDoc.createElement(name);
74771            newDOM.innerHTML = content;
74772            for (var i = 0; i < attributes.length; i++) {
74773              newDOM.setAttribute(attributes[i].nodeName, attributes.nodeValue);
74774            }
74775            this.DOM = newDOM;
74776          };
74777
74778          /**
74779           * Checks whether or not the element has any children, and returns the result
74780           * as a boolean.
74781           *
74782           * @method hasChildren
74783           * @return {boolean}
74784           * @example&lt;animal
74785           * <div class='norender'><code>
74786           * // The following short XML file called "mammals.xml" is parsed
74787           * // in the code below.
74788           * //
74789           * // <?xml version="1.0"?>
74790           * // &lt;mammals&gt;
74791           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
74792           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
74793           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
74794           * // &lt;/mammals&gt;
74795           *
74796           * let xml;
74797           *
74798           * function preload() {
74799           *   xml = loadXML('assets/mammals.xml');
74800           * }
74801           *
74802           * function setup() {
74803           *   print(xml.hasChildren());
74804           * }
74805           *
74806           * // Sketch prints:
74807           * // true
74808           * </code></div>
74809           */
74810          _main.default.XML.prototype.hasChildren = function() {
74811            return this.DOM.children.length > 0;
74812          };
74813
74814          /**
74815           * Get the names of all of the element's children, and returns the names as an
74816           * array of Strings. This is the same as looping through and calling <a href="#/p5.XML/getName">getName()</a>
74817           * on each child element individually.
74818           *
74819           * @method listChildren
74820           * @return {String[]} names of the children of the element
74821           * @example&lt;animal
74822           * <div class='norender'><code>
74823           * // The following short XML file called "mammals.xml" is parsed
74824           * // in the code below.
74825           * //
74826           * // <?xml version="1.0"?>
74827           * // &lt;mammals&gt;
74828           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
74829           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
74830           * //   &lt;animal id="2" species="Equus zebra">
74830Zebra&lt;/animal&gt;
74831           * // &lt;/mammals&gt;
74832           *
74833           * let xml;
74834           *
74835           * function preload() {
74836           *   xml = loadXML('assets/mammals.xml');
74837           * }
74838           *
74839           * function setup() {
74840           *   print(xml.listChildren());
74841           * }
74842           *
74843           * // Sketch prints:
74844           * // ["animal", "animal", "animal"]
74845           * </code></div>
74846           */
74847          _main.default.XML.prototype.listChildren = function() {
74848            var arr = [];
74849            for (var i = 0; i < this.DOM.childNodes.length; i++) {
74850              arr.push(this.DOM.childNodes[i].nodeName);
74851            }
74852            return arr;
74853          };
74854
74855          /**
74856           * Returns all of the element's children as an array of <a href="#/p5.XML">p5.XML</a> objects. When
74857           * the name parameter is specified, then it will return all children that match
74858           * that name.
74859           *
74860           * @method getChildren
74861           * @param {String} [name] element name
74862           * @return {p5.XML[]} children of the element
74863           * @example&lt;animal
74864           * <div class='norender'><code>
74865           * // The following short XML file called "mammals.xml" is parsed
74866           * // in the code below.
74867           * //
74868           * // <?xml version="1.0"?>
74869           * // &lt;mammals&gt;
74870           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
74871           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
74872           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
74873           * // &lt;/mammals&gt;
74874           *
74875           * let xml;
74876           *
74877           * function preload() {
74878           *   xml = loadXML('assets/mammals.xml');
74879           * }
74880           *
74881           * function setup() {
74882           *   let animals = xml.getChildren('animal');
74883           *
74884           *   for (let i = 0; i < animals.length; i++) {
74885           *     print(animals[i].getContent());
74886           *   }
74887           * }
74888           *
74889           * // Sketch prints:
74890           * // "Goat"
74891           * // "Leopard"
74892           * // "Zebra"
74893           * </code></div>
74894           */
74895          _main.default.XML.prototype.getChildren = function(param) {
74896            if (param) {
74897              return elementsToP5XML(this.DOM.getElementsByTagName(param));
74898            } else {
74899              return elementsToP5XML(this.DOM.children);
74900            }
74901          };
74902
74903          function elementsToP5XML(elements) {
74904            var arr = [];
74905            for (var i = 0; i < elements.length; i++) {
74906              arr.push(new _main.default.XML(elements[i]));
74907            }
74908            return arr;
74909          }
74910
74911          /**
74912           * Returns the first of the element's children that matches the name parameter
74913           * or the child of the given index.It returns undefined if no matching
74914           * child is found.
74915           *
74916           * @method getChild
74917           * @param {String|Integer} name element name or index
74918           * @return {p5.XML}
74919           * @example&lt;animal
74920           * <div class='norender'><code>
74921           * // The following short XML file called "mammals.xml" is parsed
74922           * // in the code below.
74923           * //
74924           * // <?xml version="1.0"?>
74925           * // &lt;mammals&gt;
74926           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
74927           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
74928           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
74929           * // &lt;/mammals&gt;
74930           *
74931           * let xml;
74932           *
74933           * function preload() {
74934           *   xml = loadXML('assets/mammals.xml');
74935           * }
74936           *
74937           * function setup() {
74938           *   let firstChild = xml.getChild('animal');
74939           *   print(firstChild.getContent());
74940           * }
74941           *
74942           * // Sketch prints:
74943           * // "Goat"
74944           * </code></div>
74945           * <div class='norender'><code>
74946           * let xml;
74947           *
74948           * function preload() {
74949           *   xml = loadXML('assets/mammals.xml');
74950           * }
74951           *
74952           * function setup() {
74953           *   let secondChild = xml.getChild(1);
74954           *   print(secondChild.getContent());
74955           * }
74956           *
74957           * // Sketch prints:
74958           * // "Leopard"
74959           * </code></div>
74960           */
74961          _main.default.XML.prototype.getChild = function(param) {
74962            if (typeof param === 'string') {
74963              var _iteratorNormalCompletion = true;
74964              var _didIteratorError = false;
74965              var _iteratorError = undefined;
74966              try {
74967                for (
74968                  var _iterator = this.DOM.children[Symbol.iterator](), _step;
74969                  !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
74970                  _iteratorNormalCompletion = true
74971                ) {
74972                  var child = _step.value;
74973                  if (child.tagName === param) return new _main.default.XML(child);
74974                }
74975              } catch (err) {
74976                _didIteratorError = true;
74977                _iteratorError = err;
74978              } finally {
74979                try {
74980                  if (!_iteratorNormalCompletion && _iterator.return != null) {
74981                    _iterator.return();
74982                  }
74983                } finally {
74984                  if (_didIteratorError) {
74985                    throw _iteratorError;
74986                  }
74987                }
74988              }
74989            } else {
74990              return new _main.default.XML(this.DOM.children[param]);
74991            }
74992          };
74993
74994          /**
74995           * Appends a new child to the element. The child can be specified with
74996           * either a String, which will be used as the new tag's name, or as a
74997           * reference to an existing <a href="#/p5.XML">p5.XML</a> object.
74998           * A reference to the newly created child is returned as an <a href="#/p5.XML">p5.XML</a> object.
74999           *
75000           * @method addChild
75001           * @param {p5.XML} node a <a href="#/p5.XML">p5.XML</a> Object which will be the child to be added
75002           * @example
75003           * <div class='norender'><code>
75004           * // The following short XML file called "mammals.xml" is parsed
75005           * // in the code below.
75006           * //
75007           * // <?xml version="1.0"?>
75008           * // &lt;mammals&gt;
75009           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75010           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75011           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
75012           * // &lt;/mammals&gt;
75013           *
75014           * let xml;
75015           *
75016           * function preload() {
75017           *   xml = loadXML('assets/mammals.xml');
75018           * }
75019           *
75020           * function setup() {
75021           *   let child = new p5.XML();
75022           *   child.setName('animal');
75023           *   child.setAttribute('id', '3');
75024           *   child.setAttribute('species', 'Ornithorhynchus anatinus');
75025           *   child.setContent('Platypus');
75026           *   xml.addChild(child);
75027           *
75028           *   let animals = xml.getChildren('animal');
75029           *   print(animals[animals.length - 1].getContent());
75030           * }
75031           *
75032           * // Sketch prints:
75033           * // "Goat"
75034           * // "Leopard"
75035           * // "Zebra"
75036           * </code></div>
75037           */
75038          _main.default.XML.prototype.addChild = function(node) {
75039            if (node instanceof _main.default.XML) {
75040              this.DOM.appendChild(node.DOM);
75041            } else {
75042              // PEND
75043            }
75044          };
75045
75046          /**
75047           * Removes the element specified by name or index.
75048           *
75049           * @method removeChild
75050           * @param {String|Integer} name element name or index
75051           * @example
75052           * <div class='norender'><code>
75053           * // The following short XML file called "mammals.xml" is parsed
75054           * // in the code below.
75055           * //
75056           * // <?xml version="1.0"?>
75057           * // &lt;mammals&gt;
75058           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75059           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75060           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
75061           * // &lt;/mammals&gt;
75062           *
75063           * let xml;
75064           *
75065           * function preload() {
75066           *   xml = loadXML('assets/mammals.xml');
75067           * }
75068           *
75069           * function setup() {
75070           *   xml.removeChild('animal');
75071           *   let children = xml.getChildren();
75072           *   for (let i = 0; i < children.length; i++) {
75073           *     print(children[i].getContent());
75074           *   }
75075           * }
75076           *
75077           * // Sketch prints:
75078           * // "Leopard"
75079           * // "Zebra"
75080           * </code></div>
75081           * <div class='norender'><code>
75082           * let xml;
75083           *
75084           * function preload() {
75085           *   xml = loadXML('assets/mammals.xml');
75086           * }
75087           *
75088           * function setup() {
75089           *   xml.removeChild(1);
75090           *   let children = xml.getChildren();
75091           *   for (let i = 0; i < children.length; i++) {
75092           *     print(children[i].getContent());
75093           *   }
75094           * }
75095           *
75096           * // Sketch prints:
75097           * // "Goat"
75098           * // "Zebra"
75099           * </code></div>
75100           */
75101          _main.default.XML.prototype.removeChild = function(param) {
75102            var ind = -1;
75103            if (typeof param === 'string') {
75104              for (var i = 0; i < this.DOM.children.length; i++) {
75105                if (this.DOM.children[i].tagName === param) {
75106                  ind = i;
75107                  break;
75108                }
75109              }
75110            } else {
75111              ind = param;
75112            }
75113            if (ind !== -1) {
75114              this.DOM.removeChild(this.DOM.children[ind]);
75115            }
75116          };
75117
75118          /**
75119           * Counts the specified element's number of attributes, returned as an Number.
75120           *
75121           * @method getAttributeCount
75122           * @return {Integer}
75123           * @example
75124           * <div class='norender'><code>
75125           * // The following short XML file called "mammals.xml" is parsed
75126           * // in the code below.
75127           * //
75128           * // <?xml version="1.0"?>
75129           * // &lt;mammals&gt;
75130           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75131           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75132           * //   &lt;animal id="2" species="Equus zebra">
75132Zebra&lt;/animal&gt;
75133           * // &lt;/mammals&gt;
75134           *
75135           * let xml;
75136           *
75137           * function preload() {
75138           *   xml = loadXML('assets/mammals.xml');
75139           * }
75140           *
75141           * function setup() {
75142           *   let firstChild = xml.getChild('animal');
75143           *   print(firstChild.getAttributeCount());
75144           * }
75145           *
75146           * // Sketch prints:
75147           * // 2
75148           * </code></div>
75149           */
75150          _main.default.XML.prototype.getAttributeCount = function() {
75151            return this.DOM.attributes.length;
75152          };
75153
75154          /**
75155           * Gets all of the specified element's attributes, and returns them as an
75156           * array of Strings.
75157           *
75158           * @method listAttributes
75159           * @return {String[]} an array of strings containing the names of attributes
75160           * @example
75161           * <div class='norender'><code>
75162           * // The following short XML file called "mammals.xml" is parsed
75163           * // in the code below.
75164           * //
75165           * // <?xml version="1.0"?>
75166           * // &lt;mammals&gt;
75167           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75168           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75169           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
75170           * // &lt;/mammals&gt;
75171           *
75172           * let xml;
75173           *
75174           * function preload() {
75175           *   xml = loadXML('assets/mammals.xml');
75176           * }
75177           *
75178           * function setup() {
75179           *   let firstChild = xml.getChild('animal');
75180           *   print(firstChild.listAttributes());
75181           * }
75182           *
75183           * // Sketch prints:
75184           * // ["id", "species"]
75185           * </code></div>
75186           */
75187          _main.default.XML.prototype.listAttributes = function() {
75188            var arr = [];
75189            var _iteratorNormalCompletion2 = true;
75190            var _didIteratorError2 = false;
75191            var _iteratorError2 = undefined;
75192            try {
75193              for (
75194                var _iterator2 = this.DOM.attributes[Symbol.iterator](), _step2;
75195                !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done);
75196                _iteratorNormalCompletion2 = true
75197              ) {
75198                var attribute = _step2.value;
75199                arr.push(attribute.nodeName);
75200              }
75201            } catch (err) {
75202              _didIteratorError2 = true;
75203              _iteratorError2 = err;
75204            } finally {
75205              try {
75206                if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
75207                  _iterator2.return();
75208                }
75209              } finally {
75210                if (_didIteratorError2) {
75211                  throw _iteratorError2;
75212                }
75213              }
75214            }
75215
75216            return arr;
75217          };
75218
75219          /**
75220           *  Checks whether or not an element has the specified attribute.
75221           *
75222           * @method hasAttribute
75223           * @param {String} the attribute to be checked
75224           * @return {boolean} true if attribute found else false
75225           * @example
75226           * <div class='norender'><code>
75227           * // The following short XML file called "mammals.xml" is parsed
75228           * // in the code below.
75229           * //
75230           * // <?xml version="1.0"?>
75231           * // &lt;mammals&gt;
75232           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75233           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75234           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
75235           * // &lt;/mammals&gt;
75236           *
75237           * let xml;
75238           *
75239           * function preload() {
75240           *   xml = loadXML('assets/mammals.xml');
75241           * }
75242           *
75243           * function setup() {
75244           *   let firstChild = xml.getChild('animal');
75245           *   print(firstChild.hasAttribute('species'));
75246           *   print(firstChild.hasAttribute('color'));
75247           * }
75248           *
75249           * // Sketch prints:
75250           * // true
75251           * // false
75252           * </code></div>
75253           */
75254          _main.default.XML.prototype.hasAttribute = function(name) {
75255            var obj = {};
75256            var _iteratorNormalCompletion3 = true;
75257            var _didIteratorError3 = false;
75258            var _iteratorError3 = undefined;
75259            try {
75260              for (
75261                var _iterator3 = this.DOM.attributes[Symbol.iterator](), _step3;
75262                !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done);
75263                _iteratorNormalCompletion3 = true
75264              ) {
75265                var attribute = _step3.value;
75266                obj[attribute.nodeName] = attribute.nodeValue;
75267              }
75268            } catch (err) {
75269              _didIteratorError3 = true;
75270              _iteratorError3 = err;
75271            } finally {
75272              try {
75273                if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
75274                  _iterator3.return();
75275                }
75276              } finally {
75277                if (_didIteratorError3) {
75278                  throw _iteratorError3;
75279                }
75280              }
75281            }
75282
75283            return obj[name] ? true : false;
75284          };
75285
75286          /**
75287           * Returns an attribute value of the element as an Number. If the defaultValue
75288           * parameter is specified and the attribute doesn't exist, then defaultValue
75289           * is returned. If no defaultValue is specified and the attribute doesn't
75290           * exist, the value 0 is returned.
75291           *
75292           * @method getNum
75293           * @param {String} name            the non-null full name of the attribute
75294           * @param {Number} [defaultValue]  the default value of the attribute
75295           * @return {Number}
75296           * @example
75297           * <div class='norender'><code>
75298           * // The following short XML file called "mammals.xml" is parsed
75299           * // in the code below.
75300           * //
75301           * // <?xml version="1.0"?>
75302           * // &lt;mammals&gt;
75303           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75304           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75305           * //   &lt;animal id="2" species="Equus zebra">
75305Zebra&lt;/animal&gt;
75306           * // &lt;/mammals&gt;
75307           *
75308           * let xml;
75309           *
75310           * function preload() {
75311           *   xml = loadXML('assets/mammals.xml');
75312           * }
75313           *
75314           * function setup() {
75315           *   let firstChild = xml.getChild('animal');
75316           *   print(firstChild.getNum('id'));
75317           * }
75318           *
75319           * // Sketch prints:
75320           * // 0
75321           * </code></div>
75322           */
75323          _main.default.XML.prototype.getNum = function(name, defaultValue) {
75324            var obj = {};
75325            var _iteratorNormalCompletion4 = true;
75326            var _didIteratorError4 = false;
75327            var _iteratorError4 = undefined;
75328            try {
75329              for (
75330                var _iterator4 = this.DOM.attributes[Symbol.iterator](), _step4;
75331                !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done);
75332                _iteratorNormalCompletion4 = true
75333              ) {
75334                var attribute = _step4.value;
75335                obj[attribute.nodeName] = attribute.nodeValue;
75336              }
75337            } catch (err) {
75338              _didIteratorError4 = true;
75339              _iteratorError4 = err;
75340            } finally {
75341              try {
75342                if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
75343                  _iterator4.return();
75344                }
75345              } finally {
75346                if (_didIteratorError4) {
75347                  throw _iteratorError4;
75348                }
75349              }
75350            }
75351
75352            return Number(obj[name]) || defaultValue || 0;
75353          };
75354
75355          /**
75356           * Returns an attribute value of the element as an String. If the defaultValue
75357           * parameter is specified and the attribute doesn't exist, then defaultValue
75358           * is returned. If no defaultValue is specified and the attribute doesn't
75359           * exist, null is returned.
75360           *
75361           * @method getString
75362           * @param {String} name            the non-null full name of the attribute
75363           * @param {Number} [defaultValue]  the default value of the attribute
75364           * @return {String}
75365           * @example
75366           * <div class='norender'><code>
75367           * // The following short XML file called "mammals.xml" is parsed
75368           * // in the code below.
75369           * //
75370           * // <?xml version="1.0"?>
75371           * // &lt;mammals&gt;
75372           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75373           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75374           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
75375           * // &lt;/mammals&gt;
75376           *
75377           * let xml;
75378           *
75379           * function preload() {
75380           *   xml = loadXML('assets/mammals.xml');
75381           * }
75382           *
75383           * function setup() {
75384           *   let firstChild = xml.getChild('animal');
75385           *   print(firstChild.getString('species'));
75386           * }
75387           *
75388           * // Sketch prints:
75389           * // "Capra hircus"
75390           * </code></div>
75391           */
75392          _main.default.XML.prototype.getString = function(name, defaultValue) {
75393            var obj = {};
75394            var _iteratorNormalCompletion5 = true;
75395            var _didIteratorError5 = false;
75396            var _iteratorError5 = undefined;
75397            try {
75398              for (
75399                var _iterator5 = this.DOM.attributes[Symbol.iterator](), _step5;
75400                !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done);
75401                _iteratorNormalCompletion5 = true
75402              ) {
75403                var attribute = _step5.value;
75404                obj[attribute.nodeName] = attribute.nodeValue;
75405              }
75406            } catch (err) {
75407              _didIteratorError5 = true;
75408              _iteratorError5 = err;
75409            } finally {
75410              try {
75411                if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
75412                  _iterator5.return();
75413                }
75414              } finally {
75415                if (_didIteratorError5) {
75416                  throw _iteratorError5;
75417                }
75418              }
75419            }
75420
75421            return obj[name] ? String(obj[name]) : defaultValue || null;
75422          };
75423
75424          /**
75425           * Sets the content of an element's attribute. The first parameter specifies
75426           * the attribute name, while the second specifies the new content.
75427           *
75428           * @method setAttribute
75429           * @param {String} name            the full name of the attribute
75430           * @param {Number|String|Boolean} value  the value of the attribute
75431           * @example
75432           * <div class='norender'><code>
75433           * // The following short XML file called "mammals.xml" is parsed
75434           * // in the code below.
75435           * //
75436           * // <?xml version="1.0"?>
75437           * // &lt;mammals&gt;
75438           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75439           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75440           * //   &lt;animal id="2" species="Equus zebra">
75440Zebra&lt;/animal&gt;
75441           * // &lt;/mammals&gt;
75442           *
75443           * let xml;
75444           *
75445           * function preload() {
75446           *   xml = loadXML('assets/mammals.xml');
75447           * }
75448           *
75449           * function setup() {
75450           *   let firstChild = xml.getChild('animal');
75451           *   print(firstChild.getString('species'));
75452           *   firstChild.setAttribute('species', 'Jamides zebra');
75453           *   print(firstChild.getString('species'));
75454           * }
75455           *
75456           * // Sketch prints:
75457           * // "Capra hircus"
75458           * // "Jamides zebra"
75459           * </code></div>
75460           */
75461          _main.default.XML.prototype.setAttribute = function(name, value) {
75462            this.DOM.setAttribute(name, value);
75463          };
75464
75465          /**
75466           * Returns the content of an element. If there is no such content,
75467           * defaultValue is returned if specified, otherwise null is returned.
75468           *
75469           * @method getContent
75470           * @param {String} [defaultValue] value returned if no content is found
75471           * @return {String}
75472           * @example
75473           * <div class='norender'><code>
75474           * // The following short XML file called "mammals.xml" is parsed
75475           * // in the code below.
75476           * //
75477           * // <?xml version="1.0"?>
75478           * // &lt;mammals&gt;
75479           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75480           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75481           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
75482           * // &lt;/mammals&gt;
75483           *
75484           * let xml;
75485           *
75486           * function preload() {
75487           *   xml = loadXML('assets/mammals.xml');
75488           * }
75489           *
75490           * function setup() {
75491           *   let firstChild = xml.getChild('animal');
75492           *   print(firstChild.getContent());
75493           * }
75494           *
75495           * // Sketch prints:
75496           * // "Goat"
75497           * </code></div>
75498           */
75499          _main.default.XML.prototype.getContent = function(defaultValue) {
75500            var str;
75501            str = this.DOM.textContent;
75502            str = str.replace(/\s\s+/g, ',');
75503            return str || defaultValue || null;
75504          };
75505
75506          /**
75507           * Sets the element's content.
75508           *
75509           * @method setContent
75510           * @param {String} text the new content
75511           * @example
75512           * <div class='norender'><code>
75513           * // The following short XML file called "mammals.xml" is parsed
75514           * // in the code below.
75515           * //
75516           * // <?xml version="1.0"?>
75517           * // &lt;mammals&gt;
75518           * //   &lt;animal id="0" species="Capra hircus">Goat&lt;/animal&gt;
75519           * //   &lt;animal id="1" species="Panthera pardus">Leopard&lt;/animal&gt;
75520           * //   &lt;animal id="2" species="Equus zebra">Zebra&lt;/animal&gt;
75521           * // &lt;/mammals&gt;
75522           *
75523           * let xml;
75524           *
75525           * function preload() {
75526           *   xml = loadXML('assets/mammals.xml');
75527           * }
75528           *
75529           * function setup() {
75530           *   let firstChild = xml.getChild('animal');
75531           *   print(firstChild.getContent());
75532           *   firstChild.setContent('Mountain Goat');
75533           *   print(firstChild.getContent());
75534           * }
75535           *
75536           * // Sketch prints:
75537           * // "Goat"
75538           * // "Mountain Goat"
75539           * </code></div>
75540           */
75541          _main.default.XML.prototype.setContent = function(content) {
75542            if (!this.DOM.children.length) {
75543              this.DOM.textContent = content;
75544            }
75545          };
75546
75547          /**
75548           * Serializes the element into a string. This function is useful for preparing
75549           * the content to be sent over a http request or saved to file.
75550           *
75551           * @method serialize
75552           * @return {String} Serialized string of the element
75553           * @example
75554           * <div class='norender'><code>
75555           * let xml;
75556           *
75557           * function preload() {
75558           *   xml = loadXML('assets/mammals.xml');
75559           * }
75560           *
75561           * function setup() {
75562           *   print(xml.serialize());
75563           * }
75564           *
75565           * // Sketch prints:
75566           * // <mammals>
75567           * //   <animal id="0" species="Capra hircus">Goat</animal>
75568           * //   <animal id="1" species="Panthera pardus">Leopard</animal>
75569           * //   <animal id="2" species="Equus zebra">
75569Zebra</animal>
75570           * // </mammals>
75571           * </code></div>
75572           */
75573          _main.default.XML.prototype.serialize = function() {
75574            var xmlSerializer = new XMLSerializer();
75575            return xmlSerializer.serializeToString(this.DOM);
75576          };
75577          var _default = _main.default;
75578          exports.default = _default;
75579        },
75580        { '../core/main': 59 }
75581      ],
75582      89: [
75583        function(_dereq_, module, exports) {
75584          'use strict';
75585          Object.defineProperty(exports, '__esModule', { value: true });
75586          exports.default = void 0;
75587
75588          var _main = _interopRequireDefault(_dereq_('../core/main'));
75589          function _interopRequireDefault(obj) {
75590            return obj && obj.__esModule ? obj : { default: obj };
75591          }
75592          /**
75593           * @module Math
75594           * @submodule Calculation
75595           * @for p5
75596           * @requires core
75597           */ /**
75598           * Calculates the absolute value (magnitude) of a number. Maps to Math.abs().
75599           * The absolute value of a number is always positive.
75600           *
75601           * @method abs
75602           * @param  {Number} n number to compute
75603           * @return {Number}   absolute value of given number
75604           * @example
75605           * <div class = "norender"><code>
75606           * function setup() {
75607           *   let x = -3;
75608           *   let y = abs(x);
75609           *
75610           *   print(x); // -3
75611           *   print(y); // 3
75612           * }
75613           * </code></div>
75614           *
75615           * @alt
75616           * no image displayed
75617           */ _main.default.prototype.abs = Math.abs; /**
75618           * Calculates the closest int value that is greater than or equal to the
75619           * value of the parameter. Maps to Math.ceil(). For example, ceil(9.03)
75620           * returns the value 10.
75621           *
75622           * @method ceil
75623           * @param  {Number} n number to round up
75624           * @return {Integer}   rounded up number
75625           * @example
75626           * <div><code>
75627           * function draw() {
75628           *   background(200);
75629           *   // map, mouseX between 0 and 5.
75630           *   let ax = map(mouseX, 0, 100, 0, 5);
75631           *   let ay = 66;
75632           *
75633           *   //Get the ceiling of the mapped number.
75634           *   let bx = ceil(map(mouseX, 0, 100, 0, 5));
75635           *   let by = 33;
75636           *
75637           *   // Multiply the mapped numbers by 20 to more easily
75638           *   // see the changes.
75639           *   stroke(0);
75640           *   fill(0);
75641           *   line(0, ay, ax * 20, ay);
75642           *   line(0, by, bx * 20, by);
75643           *
75644           *   // Reformat the float returned by map and draw it.
75645           *   noStroke();
75646           *   text(nfc(ax, 2), ax, ay - 5);
75647           *   text(nfc(bx, 1), bx, by - 5);
75648           * }
75649           * </code></div>
75650           *
75651           * @alt
75652           * 2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals
75653           */
75654          _main.default.prototype.ceil = Math.ceil;
75655
75656          /**
75657           * Constrains a value between a minimum and maximum value.
75658           *
75659           * @method constrain
75660           * @param  {Number} n    number to constrain
75661           * @param  {Number} low  minimum limit
75662           * @param  {Number} high maximum limit
75663           * @return {Number}      constrained number
75664           * @example
75665           * <div><code>
75666           * function draw() {
75667           *   background(200);
75668           *
75669           *   let leftWall = 25;
75670           *   let rightWall = 75;
75671           *
75672           *   // xm is just the mouseX, while
75673           *   // xc is the mouseX, but constrained
75674           *   // between the leftWall and rightWall!
75675           *   let xm = mouseX;
75676           *   let xc = constrain(mouseX, leftWall, rightWall);
75677           *
75678           *   // Draw the walls.
75679           *   stroke(150);
75680           *   line(leftWall, 0, leftWall, height);
75681           *   line(rightWall, 0, rightWall, height);
75682           *
75683           *   // Draw xm and xc as circles.
75684           *   noStroke();
75685           *   fill(150);
75686           *   ellipse(xm, 33, 9, 9); // Not Constrained
75687           *   fill(0);
75688           *   ellipse(xc, 66, 9, 9); // Constrained
75689           * }
75690           * </code></div>
75691           *
75692           * @alt
75693           * 2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines
75694           */
75695          _main.default.prototype.constrain = function(n, low, high) {
75696            _main.default._validateParameters('constrain', arguments);
75697            return Math.max(Math.min(n, high), low);
75698          };
75699
75700          /**
75701           * Calculates the distance between two points, in either two or three dimensions.
75702           *
75703           * @method dist
75704           * @param  {Number} x1 x-coordinate of the first point
75705           * @param  {Number} y1 y-coordinate of the first point
75706           * @param  {Number} x2 x-coordinate of the second point
75707           * @param  {Number} y2 y-coordinate of the second point
75708           * @return {Number}    distance between the two points
75709           *
75710           * @example
75711           * <div><code>
75712           * // Move your mouse inside the canvas to see the
75713           * // change in distance between two points!
75714           * function draw() {
75715           *   background(200);
75716           *   fill(0);
75717           *
75718           *   let x1 = 10;
75719           *   let y1 = 90;
75720           *   let x2 = mouseX;
75721           *   let y2 = mouseY;
75722           *
75723           *   line(x1, y1, x2, y2);
75724           *   ellipse(x1, y1, 7, 7);
75725           *   ellipse(x2, y2, 7, 7);
75726           *
75727           *   // d is the length of the line
75728           *   // the distance from point 1 to point 2.
75729           *   let d = dist(x1, y1, x2, y2);
75730           *
75731           *   // Let's write d along the line we are drawing!
75732           *   push();
75733           *   translate((x1 + x2) / 2, (y1 + y2) / 2);
75734           *   rotate(atan2(y2 - y1, x2 - x1));
75735           *   text(nfc(d, 1), 0, -5);
75736           *   pop();
75737           *   // Fancy!
75738           * }
75739           * </code></div>
75740           *
75741           * @alt
75742           * 2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.
75743           */
75744          /**
75745           * @method dist
75746           * @param  {Number} x1
75747           * @param  {Number} y1
75748           * @param  {Number} z1 z-coordinate of the first point
75749           * @param  {Number} x2
75750           * @param  {Number} y2
75751           * @param  {Number} z2 z-coordinate of the second point
75752           * @return {Number}    distance between the two points
75753           */
75754          _main.default.prototype.dist = function() {
75755            for (
75756              var _len = arguments.length, args = new Array(_len), _key = 0;
75757              _key < _len;
75758              _key++
75759            ) {
75760              args[_key] = arguments[_key];
75761            }
75762            _main.default._validateParameters('dist', args);
75763            if (args.length === 4) {
75764              //2D
75765              return hypot(args[2] - args[0], args[3] - args[1]);
75766            } else if (args.length === 6) {
75767              //3D
75768              return hypot(args[3] - args[0], args[4] - args[1], args[5] - args[2]);
75769            }
75770          };
75771
75772          /**
75773           * Returns Euler's number e (2.71828...) raised to the power of the n
75774           * parameter. Maps to Math.exp().
75775           *
75776           * @method exp
75777           * @param  {Number} n exponent to raise
75778           * @return {Number}   e^n
75779           * @example
75780           * <div><code>
75781           * function draw() {
75782           *   background(200);
75783           *
75784           *   // Compute the exp() function with a value between 0 and 2
75785           *   let xValue = map(mouseX, 0, width, 0, 2);
75786           *   let yValue = exp(xValue);
75787           *
75788           *   let y = map(yValue, 0, 8, height, 0);
75789           *
75790           *   let legend = 'exp (' + nfc(xValue, 3) + ')\n= ' + nf(yValue, 1, 4);
75791           *   stroke(150);
75792           *   line(mouseX, y, mouseX, height);
75793           *   fill(0);
75794           *   text(legend, 5, 15);
75795           *   noStroke();
75796           *   ellipse(mouseX, y, 7, 7);
75797           *
75798           *   // Draw the exp(x) curve,
75799           *   // over the domain of x from 0 to 2
75800           *   noFill();
75801           *   stroke(0);
75802           *   beginShape();
75803           *   for (let x = 0; x < width; x++) {
75804           *     xValue = map(x, 0, width, 0, 2);
75805           *     yValue = exp(xValue);
75806           *     y = map(yValue, 0, 8, height, 0);
75807           *     vertex(x, y);
75808           *   }
75809           *
75810           *   endShape();
75811           *   line(0, 0, 0, height);
75812           *   line(0, height - 1, width, height - 1);
75813           * }
75814           * </code></div>
75815           *
75816           * @alt
75817           * ellipse moves along a curve with mouse x. e^n displayed.
75818           */
75819          _main.default.prototype.exp = Math.exp;
75820
75821          /**
75822           * Calculates the closest int value that is less than or equal to the
75823           * value of the parameter. Maps to Math.floor().
75824           *
75825           * @method floor
75826           * @param  {Number} n number to round down
75827           * @return {Integer}  rounded down number
75828           * @example
75829           * <div><code>
75830           * function draw() {
75831           *   background(200);
75832           *   //map, mouseX between 0 and 5.
75833           *   let ax = map(mouseX, 0, 100, 0, 5);
75834           *   let ay = 66;
75835           *
75836           *   //Get the floor of the mapped number.
75837           *   let bx = floor(map(mouseX, 0, 100, 0, 5));
75838           *   let by = 33;
75839           *
75840           *   // Multiply the mapped numbers by 20 to more easily
75841           *   // see the changes.
75842           *   stroke(0);
75843           *   fill(0);
75844           *   line(0, ay, ax * 20, ay);
75845           *   line(0, by, bx * 20, by);
75846           *
75847           *   // Reformat the float returned by map and draw it.
75848           *   noStroke();
75849           *   text(nfc(ax, 2), ax, ay - 5);
75850           *   text(nfc(bx, 1), bx, by - 5);
75851           * }
75852           * </code></div>
75853           *
75854           * @alt
75855           * 2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals
75856           */
75857          _main.default.prototype.floor = Math.floor;
75858
75859          /**
75860           * Calculates a number between two numbers at a specific increment. The amt
75861           * parameter is the amount to interpolate between the two values where 0.0
75862           * equal to the first point, 0.1 is very near the first point, 0.5 is
75863           * half-way in between, and 1.0 is equal to the second point. If the
75864           * value of amt is more than 1.0 or less than 0.0, the number will be
75865           * calculated accordingly in the ratio of the two given numbers. The lerp
75866           * function is convenient for creating motion along a straight
75867           * path and for drawing dotted lines.
75868           *
75869           * @method lerp
75870           * @param  {Number} start first value
75871           * @param  {Number} stop  second value
75872           * @param  {Number} amt   number
75873           * @return {Number}       lerped value
75874           * @example
75875           * <div><code>
75876           * function setup() {
75877           *   background(200);
75878           *   let a = 20;
75879           *   let b = 80;
75880           *   let c = lerp(a, b, 0.2);
75881           *   let d = lerp(a, b, 0.5);
75882           *   let e = lerp(a, b, 0.8);
75883           *
75884           *   let y = 50;
75885           *
75886           *   strokeWeight(5);
75887           *   stroke(0); // Draw the original points in black
75888           *   point(a, y);
75889           *   point(b, y);
75890           *
75891           *   stroke(100); // Draw the lerp points in gray
75892           *   point(c, y);
75893           *   point(d, y);
75894           *   point(e, y);
75895           * }
75896           * </code></div>
75897           *
75898           * @alt
75899           * 5 points horizontally staggered mid-canvas. mid 3 are grey, outer black
75900           */
75901          _main.default.prototype.lerp = function(start, stop, amt) {
75902            _main.default._validateParameters('lerp', arguments);
75903            return amt * (stop - start) + start;
75904          };
75905
75906          /**
75907    * Calculates the natural logarithm (the base-e logarithm) of a number. This
75908    * function expects the n parameter to be a value greater than 0.0. Maps to
75909    * Math.log().
75910    *
75911    * @method log
75912    * @param  {Number} n number greater than 0
75913    * @return {Number}   natural logarithm of n
75914    * @example
75915    * <div><code>
75916    * function draw() {
75917    *   background(200);
75918    *   let maxX = 2.8;
75919    *   let maxY = 1.5;
75920    *
75921    *   // Compute the natural log of a value between 0 and maxX
75922    *   let xValue = map(mouseX, 0, width, 0, maxX);
75923    *   let yValue, y;
75924    *   if (xValue > 0) {
75925       // Cannot take the log of a negative number.
75926    *     yValue = log(xValue);
75927    *     y = map(yValue, -maxY, maxY, height, 0);
75928    *
75929    *     // Display the calculation occurring.
75930    *     let legend = 'log(' + nf(xValue, 1, 2) + ')\n= ' + nf(yValue, 1, 3);
75931    *     stroke(150);
75932    *     line(mouseX, y, mouseX, height);
75933    *     fill(0);
75934    *     text(legend, 5, 15);
75935    *     noStroke();
75936    *     ellipse(mouseX, y, 7, 7);
75937    *   }
75938    *
75939    *   // Draw the log(x) curve,
75940    *   // over the domain of x from 0 to maxX
75941    *   noFill();
75942    *   stroke(0);
75943    *   beginShape();
75944    *   for (let x = 0; x < width; x++) {
75945    *     xValue = map(x, 0, width, 0, maxX);
75946    *     yValue = log(xValue);
75947    *     y = map(yValue, -maxY, maxY, height, 0);
75948    *     vertex(x, y);
75949    *   }
75950    *   endShape();
75951    *   line(0, 0, 0, height);
75952    *   line(0, height / 2, width, height / 2);
75953    * }
75954    * </code></div>
75955    *
75956    * @alt
75957    * ellipse moves along a curve with mouse x. natural logarithm of n displayed.
75958    */
75959          _main.default.prototype.log = Math.log;
75960
75961          /**
75962           * Calculates the magnitude (or length) of a vector. A vector is a direction
75963           * in space commonly used in computer graphics and linear algebra. Because it
75964           * has no "start" position, the magnitude of a vector can be thought of as
75965           * the distance from the coordinate 0,0 to its x,y value. Therefore, <a href="#/p5/mag">mag()</a> is
75966           * a shortcut for writing dist(0, 0, x, y).
75967           *
75968           * @method mag
75969           * @param  {Number} a first value
75970           * @param  {Number} b second value
75971           * @return {Number}   magnitude of vector from (0,0) to (a,b)
75972           * @example
75973           * <div><code>
75974           * function setup() {
75975           *   let x1 = 20;
75976           *   let x2 = 80;
75977           *   let y1 = 30;
75978           *   let y2 = 70;
75979           *
75980           *   line(0, 0, x1, y1);
75981           *   print(mag(x1, y1)); // Prints "36.05551275463989"
75982           *   line(0, 0, x2, y1);
75983           *   print(mag(x2, y1)); // Prints "85.44003745317531"
75984           *   line(0, 0, x1, y2);
75985           *   print(mag(x1, y2)); // Prints "72.80109889280519"
75986           *   line(0, 0, x2, y2);
75987           *   print(mag(x2, y2)); // Prints "106.3014581273465"
75988           * }
75989           * </code></div>
75990           *
75991           * @alt
75992           * 4 lines of different length radiate from top left of canvas.
75993           */
75994          _main.default.prototype.mag = function(x, y) {
75995            _main.default._validateParameters('mag', arguments);
75996            return hypot(x, y);
75997          };
75998
75999          /**
76000    * Re-maps a number from one range to another.
76001    *
76002    * In the first example above, the number 25 is converted from a value in the
76003    * range of 0 to 100 into a value that ranges from the left edge of the
76004    * window (0) to the right edge (width).
76005    *
76006    * @method map
76007    * @param  {Number} value  the incoming value to be converted
76008    * @param  {Number} start1 lower bound of the value's current range
76009    * @param  {Number} stop1  upper bound of the value's current range
76010    * @param  {Number} start2 lower bound of the value's target range
76011    * @param  {Number} stop2  upper bound of the value's target range
76012    * @param  {Boolean} [withinBounds] constrain the value to the newly mapped range
76013    * @return {Number}        remapped number
76014    * @example
76015    *   <div><code>
76016    * let value = 25;
76017    * let m = map(value, 0, 100, 0, width);
76018    * ellipse(m, 50, 10, 10);
76019   </code></div>
76020    *
76021    *   <div><code>
76022    * function setup() {
76023    *   noStroke();
76024    * }
76025    *
76026    * function draw() {
76027    *   background(204);
76028    *   let x1 = map(mouseX, 0, width, 25, 75);
76029    *   ellipse(x1, 25, 25, 25);
76030    *   //This ellipse is constrained to the 0-100 range
76031    *   //after setting withinBounds to true
76032    *   let x2 = map(mouseX, 0, width, 0, 100, true);
76033    *   ellipse(x2, 75, 25, 25);
76034    * }
76035   </code></div>
76036    *
76037    * @alt
76038    * 10 by 10 white ellipse with in mid left canvas
76039    * 2 25 by 25 white ellipses move with mouse x. Bottom has more range from X
76040    */
76041          _main.default.prototype.map = function(
76042            n,
76043            start1,
76044            stop1,
76045            start2,
76046            stop2,
76047            withinBounds
76048          ) {
76049            _main.default._validateParameters('map', arguments);
76050            var newval = (n - start1) / (stop1 - start1) * (stop2 - start2) + start2;
76051            if (!withinBounds) {
76052              return newval;
76053            }
76054            if (start2 < stop2) {
76055              return this.constrain(newval, start2, stop2);
76056            } else {
76057              return this.constrain(newval, stop2, start2);
76058            }
76059          };
76060
76061          /**
76062           * Determines the largest value in a sequence of numbers, and then returns
76063           * that value. <a href="#/p5/max">max()</a> accepts any number of Number parameters, or an Array
76064           * of any length.
76065           *
76066           * @method max
76067           * @param  {Number} n0 Number to compare
76068           * @param  {Number} n1 Number to compare
76069           * @return {Number}             maximum Number
76070           * @example
76071           * <div><code>
76072           * function setup() {
76073           *   // Change the elements in the array and run the sketch
76074           *   // to show how max() works!
76075           *   let numArray = [2, 1, 5, 4, 8, 9];
76076           *   fill(0);
76077           *   noStroke();
76078           *   text('Array Elements', 0, 10);
76079           *   // Draw all numbers in the array
76080           *   let spacing = 15;
76081           *   let elemsY = 25;
76082           *   for (let i = 0; i < numArray.length; i++) {
76083           *     text(numArray[i], i * spacing, elemsY);
76084           *   }
76085           *   let maxX = 33;
76086           *   let maxY = 80;
76087           *   // Draw the Maximum value in the array.
76088           *   textSize(32);
76089           *   text(max(numArray), maxX, maxY);
76090           * }
76091           * </code></div>
76092           *
76093           * @alt
76094           * Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9
76095           */
76096          /**
76097           * @method max
76098           * @param  {Number[]} nums Numbers to compare
76099           * @return {Number}
76100           */
76101          _main.default.prototype.max = function() {
76102            for (
76103              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
76104              _key2 < _len2;
76105              _key2++
76106            ) {
76107              args[_key2] = arguments[_key2];
76108            }
76109            if (args[0] instanceof Array) {
76110              return Math.max.apply(null, args[0]);
76111            } else {
76112              return Math.max.apply(null, args);
76113            }
76114          };
76115
76116          /**
76117           * Determines the smallest value in a sequence of numbers, and then returns
76118           * that value. <a href="#/p5/min">min()</a> accepts any number of Number parameters, or an Array
76119           * of any length.
76120           *
76121           * @method min
76122           * @param  {Number} n0 Number to compare
76123           * @param  {Number} n1 Number to compare
76124           * @return {Number}             minimum Number
76125           * @example
76126           * <div><code>
76127           * function setup() {
76128           *   // Change the elements in the array and run the sketch
76129           *   // to show how min() works!
76130           *   let numArray = [2, 1, 5, 4, 8, 9];
76131           *   fill(0);
76132           *   noStroke();
76133           *   text('Array Elements', 0, 10);
76134           *   // Draw all numbers in the array
76135           *   let spacing = 15;
76136           *   let elemsY = 25;
76137           *   for (let i = 0; i < numArray.length; i++) {
76138           *     text(numArray[i], i * spacing, elemsY);
76139           *   }
76140           *   let maxX = 33;
76141           *   let maxY = 80;
76142           *   // Draw the Minimum value in the array.
76143           *   textSize(32);
76144           *   text(min(numArray), maxX, maxY);
76145           * }
76146           * </code></div>
76147           *
76148           * @alt
76149           * Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1
76150           */
76151          /**
76152           * @method min
76153           * @param  {Number[]} nums Numbers to compare
76154           * @return {Number}
76155           */
76156          _main.default.prototype.min = function() {
76157            for (
76158              var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;
76159              _key3 < _len3;
76160              _key3++
76161            ) {
76162              args[_key3] = arguments[_key3];
76163            }
76164            if (args[0] instanceof Array) {
76165              return Math.min.apply(null, args[0]);
76166            } else {
76167              return Math.min.apply(null, args);
76168            }
76169          };
76170
76171          /**
76172           * Normalizes a number from another range into a value between 0 and 1.
76173           * Identical to map(value, low, high, 0, 1).
76174           * Numbers outside of the range are not clamped to 0 and 1, because
76175           * out-of-range values are often intentional and useful. (See the example above.)
76176           *
76177           * @method norm
76178           * @param  {Number} value incoming value to be normalized
76179           * @param  {Number} start lower bound of the value's current range
76180           * @param  {Number} stop  upper bound of the value's current range
76181           * @return {Number}       normalized number
76182           * @example
76183           * <div><code>
76184           * function draw() {
76185           *   background(200);
76186           *   let currentNum = mouseX;
76187           *   let lowerBound = 0;
76188           *   let upperBound = width; //100;
76189           *   let normalized = norm(currentNum, lowerBound, upperBound);
76190           *   let lineY = 70;
76191           *   stroke(3);
76192           *   line(0, lineY, width, lineY);
76193           *   //Draw an ellipse mapped to the non-normalized value.
76194           *   noStroke();
76195           *   fill(50);
76196           *   let s = 7; // ellipse size
76197           *   ellipse(currentNum, lineY, s, s);
76198           *
76199           *   // Draw the guide
76200           *   let guideY = lineY + 15;
76201           *   text('0', 0, guideY);
76202           *   textAlign(RIGHT);
76203           *   text('100', width, guideY);
76204           *
76205           *   // Draw the normalized value
76206           *   textAlign(LEFT);
76207           *   fill(0);
76208           *   textSize(32);
76209           *   let normalY = 40;
76210           *   let normalX = 20;
76211           *   text(normalized, normalX, normalY);
76212           * }
76213           * </code></div>
76214           *
76215           * @alt
76216           * ellipse moves with mouse. 0 shown left & 100 right and updating values center
76217           */
76218          _main.default.prototype.norm = function(n, start, stop) {
76219            _main.default._validateParameters('norm', arguments);
76220            return this.map(n, start, stop, 0, 1);
76221          };
76222
76223          /**
76224           * Facilitates exponential expressions. The <a href="#/p5/pow">pow()</a>
76224 function is an efficient
76225           * way of multiplying numbers by themselves (or their reciprocals) in large
76226           * quantities. For example, pow(3, 5) is equivalent to the expression
76227           * 3 &times; 3 &times; 3 &times; 3 &times; 3 and pow(3, -5) is equivalent to 1 /
76228           * 3 &times; 3 &times; 3 &times; 3 &times; 3. Maps to
76229           * Math.pow().
76230           *
76231           * @method pow
76232           * @param  {Number} n base of the exponential expression
76233           * @param  {Number} e power by which to raise the base
76234           * @return {Number}   n^e
76235           * @example
76236           * <div><code>
76237           * function setup() {
76238           *   //Exponentially increase the size of an ellipse.
76239           *   let eSize = 3; // Original Size
76240           *   let eLoc = 10; // Original Location
76241           *
76242           *   ellipse(eLoc, eLoc, eSize, eSize);
76243           *
76244           *   ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));
76245           *
76246           *   ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));
76247           *
76248           *   ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));
76249           * }
76250           * </code></div>
76251           *
76252           * @alt
76253           * small to large ellipses radiating from top left of canvas
76254           */
76255          _main.default.prototype.pow = Math.pow;
76256
76257          /**
76258           * Calculates the integer closest to the n parameter. For example,
76259           * round(133.8) returns the value 134. Maps to Math.round().
76260           *
76261           * @method round
76262           * @param  {Number} n number to round
76263           * @param  {Number} [decimals] number of decimal places to round to, default is 0
76264           * @return {Integer}  rounded number
76265           * @example
76266           * <div><code>
76267           * let x = round(3.7);
76268           * text(x, width / 2, height / 2);
76269           * </code></div>
76270           * <div><code>
76271           * let x = round(12.782383, 2);
76272           * text(x, width / 2, height / 2);
76273           * </code></div>
76274           * <div><code>
76275           * function draw() {
76276           *   background(200);
76277           *   //map, mouseX between 0 and 5.
76278           *   let ax = map(mouseX, 0, 100, 0, 5);
76279           *   let ay = 66;
76280           *
76281           *   // Round the mapped number.
76282           *   let bx = round(map(mouseX, 0, 100, 0, 5));
76283           *   let by = 33;
76284           *
76285           *   // Multiply the mapped numbers by 20 to more easily
76286           *   // see the changes.
76287           *   stroke(0);
76288           *   fill(0);
76289           *   line(0, ay, ax * 20, ay);
76290           *   line(0, by, bx * 20, by);
76291           *
76292           *   // Reformat the float returned by map and draw it.
76293           *   noStroke();
76294           *   text(nfc(ax, 2), ax, ay - 5);
76295           *   text(nfc(bx, 1), bx, by - 5);
76296           * }
76297           * </code></div>
76298           *
76299           * @alt
76300           * "3" written in middle of canvas
76301           * "12.78" written in middle of canvas
76302           * horizontal center line squared values displayed on top and regular on bottom.
76303           */
76304          _main.default.prototype.round = function(n, decimals) {
76305            if (!decimals) {
76306              return Math.round(n);
76307            }
76308            return Number(Math.round(n + 'e' + decimals) + 'e-' + decimals);
76309          };
76310
76311          /**
76312           * Squares a number (multiplies a number by itself). The result is always a
76313           * positive number, as multiplying two negative numbers always yields a
76314           * positive result. For example, -1 * -1 = 1.
76315           *
76316           * @method sq
76317           * @param  {Number} n number to square
76318           * @return {Number}   squared number
76319           * @example
76320           * <div><code>
76321           * function draw() {
76322           *   background(200);
76323           *   let eSize = 7;
76324           *   let x1 = map(mouseX, 0, width, 0, 10);
76325           *   let y1 = 80;
76326           *   let x2 = sq(x1);
76327           *   let y2 = 20;
76328           *
76329           *   // Draw the non-squared.
76330           *   line(0, y1, width, y1);
76331           *   ellipse(x1, y1, eSize, eSize);
76332           *
76333           *   // Draw the squared.
76334           *   line(0, y2, width, y2);
76335           *   ellipse(x2, y2, eSize, eSize);
76336           *
76337           *   // Draw dividing line.
76338           *   stroke(100);
76339           *   line(0, height / 2, width, height / 2);
76340           *
76341           *   // Draw text.
76342           *   let spacing = 15;
76343           *   noStroke();
76344           *   fill(0);
76345           *   text('x = ' + x1, 0, y1 + spacing);
76346           *   text('sq(x) = ' + x2, 0, y2 + spacing);
76347           * }
76348           * </code></div>
76349           *
76350           * @alt
76351           * horizontal center line squared values displayed on top and regular on bottom.
76352           */
76353          _main.default.prototype.sq = function(n) {
76354            return n * n;
76355          };
76356
76357          /**
76358           * Calculates the square root of a number. The square root of a number is
76359           * always positive, even though there may be a valid negative root. The
76360           * square root s of number a is such that s*s = a. It is the opposite of
76361           * squaring. Maps to Math.sqrt().
76362           *
76363           * @method sqrt
76364           * @param  {Number} n non-negative number to square root
76365           * @return {Number}   square root of number
76366           * @example
76367           * <div><code>
76368           * function draw() {
76369           *   background(200);
76370           *   let eSize = 7;
76371           *   let x1 = mouseX;
76372           *   let y1 = 80;
76373           *   let x2 = sqrt(x1);
76374           *   let y2 = 20;
76375           *
76376           *   // Draw the non-squared.
76377           *   line(0, y1, width, y1);
76378           *   ellipse(x1, y1, eSize, eSize);
76379           *
76380           *   // Draw the squared.
76381           *   line(0, y2, width, y2);
76382           *   ellipse(x2, y2, eSize, eSize);
76383           *
76384           *   // Draw dividing line.
76385           *   stroke(100);
76386           *   line(0, height / 2, width, height / 2);
76387           *
76388           *   // Draw text.
76389           *   noStroke();
76390           *   fill(0);
76391           *   let spacing = 15;
76392           *   text('x = ' + x1, 0, y1 + spacing);
76393           *   text('sqrt(x) = ' + x2, 0, y2 + spacing);
76394           * }
76395           * </code></div>
76396           *
76397           * @alt
76398           * horizontal center line squareroot values displayed on top and regular on bottom.
76399           */
76400          _main.default.prototype.sqrt = Math.sqrt;
76401
76402          // Calculate the length of the hypotenuse of a right triangle
76403          // This won't under- or overflow in intermediate steps
76404          // https://en.wikipedia.org/wiki/Hypot
76405          function hypot(x, y, z) {
76406            // Use the native implementation if it's available
76407            if (typeof Math.hypot === 'function') {
76408              return Math.hypot.apply(null, arguments);
76409            }
76410
76411            // Otherwise use the V8 implementation
76412            // https://github.com/v8/v8/blob/8cd3cf297287e581a49e487067f5cbd991b27123/src/js/math.js#L217
76413            var length = arguments.length;
76414            var args = [];
76415            var max = 0;
76416            for (var i = 0; i < length; i++) {
76417              var n = arguments[i];
76418              n = +n;
76419              if (n === Infinity || n === -Infinity) {
76420                return Infinity;
76421              }
76422              n = Math.abs(n);
76423              if (n > max) {
76424                max = n;
76425              }
76426              args[i] = n;
76427            }
76428
76429            if (max === 0) {
76430              max = 1;
76431            }
76432            var sum = 0;
76433            var compensation = 0;
76434            for (var j = 0; j < length; j++) {
76435              var m = args[j] / max;
76436              var summand = m * m - compensation;
76437              var preliminary = sum + summand;
76438              compensation = preliminary - sum - summand;
76439              sum = preliminary;
76440            }
76441            return Math.sqrt(sum) * max;
76442          }
76443
76444          /**
76445           * Calculates the fractional part of a number.
76446           *
76447           * @method fract
76448           * @param {Number} num Number whose fractional part needs to be found out
76449           * @returns {Number} fractional part of x, i.e, {x}
76450           * @example
76451           * <div>
76452           * <code>
76453           * function setup() {
76454           *   createCanvas(windowWidth, windowHeight);
76455           *   fill(0);
76456           *   text(7345.73472742, 0, 50);
76457           *   text(fract(7345.73472742), 0, 100);
76458           *   text(1.4215e-15, 150, 50);
76459           *   text(fract(1.4215e-15), 150, 100);
76460           * }
76461           * </code>
76462           * </div>
76463           * @alt
76464           * 2 rows of numbers, the first row having 8 numbers and the second having the fractional parts of those numbers.
76465           */
76466          _main.default.prototype.fract = function(toConvert) {
76467            _main.default._validateParameters('fract', arguments);
76468            var sign = 0;
76469            var num = Number(toConvert);
76470            if (isNaN(num) || Math.abs(num) === Infinity) {
76471              return num;
76472            } else if (num < 0) {
76473              num = -num;
76474              sign = 1;
76475            }
76476            if (String(num).includes('.') && !String(num).includes('e')) {
76477              var toFract = String(num);
76478              toFract = Number('0' + toFract.slice(toFract.indexOf('.')));
76479              return Math.abs(sign - toFract);
76480            } else if (num < 1) {
76481              return Math.abs(sign - num);
76482            } else {
76483              return 0;
76484            }
76485          };
76486          var _default = _main.default;
76487          exports.default = _default;
76488        },
76489        { '../core/main': 59 }
76490      ],
76491      90: [
76492        function(_dereq_, module, exports) {
76493          'use strict';
76494          Object.defineProperty(exports, '__esModule', { value: true });
76495          exports.default = void 0;
76496
76497          var _main = _interopRequireDefault(_dereq_('../core/main'));
76498          function _interopRequireDefault(obj) {
76499            return obj && obj.__esModule ? obj : { default: obj };
76500          }
76501          /**
76502           * @module Math
76503           * @submodule Vector
76504           * @for p5
76505           * @requires core
76506           */ /**
76507           * Creates a new <a href="#/p5.Vector">p5.Vector</a> (the datatype for storing vectors). This provides a
76508           * two or three dimensional vector, specifically a Euclidean (also known as
76509           * geometric) vector. A vector is an entity that has both magnitude and
76510           * direction.
76511           *
76512           * @method createVector
76513           * @param {Number} [x] x component of the vector
76514           * @param {Number} [y] y component of the vector
76515           * @param {Number} [z] z component of the vector
76516           * @return {p5.Vector}
76517           * @example
76518           * <div><code>
76519           * let v1;
76520           * function setup() {
76521           *   createCanvas(100, 100);
76522           *   stroke(255, 0, 255);
76523           *   v1 = createVector(width / 2, height / 2);
76524           * }
76525           *
76526           * function draw() {
76527           *   background(255);
76528           *   line(v1.x, v1.y, mouseX, mouseY);
76529           * }
76530           * </code></div>
76531           *
76532           * @alt
76533           * draws a line from center of canvas to mouse pointer position.
76534           */ _main.default.prototype.createVector = function(x, y, z) {
76535            if (this instanceof _main.default) {
76536              return new _main.default.Vector(this, arguments);
76537            } else {
76538              return new _main.default.Vector(x, y, z);
76539            }
76540          };
76541          var _default = _main.default;
76542          exports.default = _default;
76543        },
76544        { '../core/main': 59 }
76545      ],
76546      91: [
76547        function(_dereq_, module, exports) {
76548          'use strict';
76549          Object.defineProperty(exports, '__esModule', { value: true });
76550          exports.default = void 0;
76551
76552          var _main = _interopRequireDefault(_dereq_('../core/main'));
76553          function _interopRequireDefault(obj) {
76554            return obj && obj.__esModule ? obj : { default: obj };
76555          } //////////////////////////////////////////////////////////////
76556          // http://mrl.nyu.edu/~perlin/noise/
76557          // Adapting from PApplet.java
76558          // which was adapted from toxi
76559          // which was adapted from the german demo group farbrausch
76560          // as used in their demo "art": http://www.farb-rausch.de/fr010src.zip
76561          // someday we might consider using "improved noise"
76562          // http://mrl.nyu.edu/~perlin/paper445.pdf
76563          // See: https://github.com/shiffman/The-Nature-of-Code-Examples-p5.js/
76564          //      blob/main/introduction/Noise1D/noise.js
76565          /**
76566           * @module Math
76567           * @submodule Noise
76568           * @for p5
76569           * @requires core
76570           */ var PERLIN_YWRAPB = 4;
76571          var PERLIN_YWRAP = 1 << PERLIN_YWRAPB;
76572          var PERLIN_ZWRAPB = 8;
76573          var PERLIN_ZWRAP = 1 << PERLIN_ZWRAPB;
76574          var PERLIN_SIZE = 4095;
76575          var perlin_octaves = 4; // default to medium smooth
76576          var perlin_amp_falloff = 0.5; // 50% reduction/octave
76577          var scaled_cosine = function scaled_cosine(i) {
76578            return 0.5 * (1.0 - Math.cos(i * Math.PI));
76579          };
76580          var perlin; // will be initialized lazily by noise() or noiseSeed()
76581          /**
76582           * Returns the Perlin noise value at specified coordinates. Perlin noise is
76583           * a random sequence generator producing a more naturally ordered, harmonic
76584           * succession of numbers compared to the standard <b>random()</b> function.
76585           * It was invented by Ken Perlin in the 1980s and been used since in
76586           * graphical applications to produce procedural textures, natural motion,
76587           * shapes, terrains etc.<br /><br /> The main difference to the
76588           * <b>random()</b> function is that Perlin noise is defined in an infinite
76589           * n-dimensional space where each pair of coordinates corresponds to a
76590           * fixed semi-random value (fixed only for the lifespan of the program; see
76591           * the <a href="#/p5/noiseSeed">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,
76592           * depending on the number of coordinates given. The resulting value will
76593           * always be between 0.0 and 1.0. The noise value can be animated by moving
76594           * through the noise space as demonstrated in the example above. The 2nd
76595           * and 3rd dimension can also be interpreted as time.<br /><br />The actual
76596           * noise is structured similar to an audio signal, in respect to the
76597           * function's use of frequencies. Similar to the concept of harmonics in
76598           * physics, perlin noise is computed over several octaves which are added
76599           * together for the final result. <br /><br />Another way to adjust the
76600           * character of the resulting sequence is the scale of the input
76601           * coordinates. As the function works within an infinite space the value of
76602           * the coordinates doesn't matter as such, only the distance between
76603           * successive coordinates does (eg. when using <b>noise()</b> within a
76604           * loop). As a general rule the smaller the difference between coordinates,
76605           * the smoother the resulting noise sequence will be. Steps of 0.005-0.03
76606           * work best for most applications, but this will differ depending on use.
76607           *
76608           * @method noise
76609           * @param  {Number} x   x-coordinate in noise space
76610           * @param  {Number} [y] y-coordinate in noise space
76611           * @param  {Number} [z] z-coordinate in noise space
76612           * @return {Number}     Perlin noise value (between 0 and 1) at specified
76613           *                      coordinates
76614           * @example
76615           * <div>
76616           * <code>
76617           * let xoff = 0.0;
76618           *
76619           * function draw() {
76620           *   background(204);
76621           *   xoff = xoff + 0.01;
76622           *   let n = noise(xoff) * width;
76623           *   line(n, 0, n, height);
76624           * }
76625           * </code>
76626           * </div>
76627           * <div>
76628           * <code>let noiseScale=0.02;
76629           *
76630           * function draw() {
76631           *   background(0);
76632           *   for (let x=0; x < width; x++) {
76633           *     let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);
76634           *     stroke(noiseVal*255);
76635           *     line(x, mouseY+noiseVal*80, x, height);
76636           *   }
76637           * }
76638           * </code>
76639           * </div>
76640           *
76641           * @alt
76642           * vertical line moves left to right with updating noise values.
76643           * horizontal wave pattern effected by mouse x-position & updating noise values.
76644           */ _main.default.prototype.noise = function(x) {
76645            var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
76646            var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
76647            if (perlin == null) {
76648              perlin = new Array(PERLIN_SIZE + 1);
76649              for (var i = 0; i < PERLIN_SIZE + 1; i++) {
76650                perlin[i] = Math.random();
76651              }
76652            }
76653
76654            if (x < 0) {
76655              x = -x;
76656            }
76657            if (y < 0) {
76658              y = -y;
76659            }
76660            if (z < 0) {
76661              z = -z;
76662            }
76663
76664            var xi = Math.floor(x),
76665              yi = Math.floor(y),
76666              zi = Math.floor(z);
76667            var xf = x - xi;
76668            var yf = y - yi;
76669            var zf = z - zi;
76670            var rxf, ryf;
76671
76672            var r = 0;
76673            var ampl = 0.5;
76674
76675            var n1, n2, n3;
76676
76677            for (var o = 0; o < perlin_octaves; o++) {
76678              var of = xi + (yi << PERLIN_YWRAPB) + (zi << PERLIN_ZWRAPB);
76679
76680              rxf = scaled_cosine(xf);
76681              ryf = scaled_cosine(yf);
76682
76683              n1 = perlin[of & PERLIN_SIZE];
76684              n1 += rxf * (perlin[(of + 1) & PERLIN_SIZE] - n1);
76685              n2 = perlin[(of + PERLIN_YWRAP) & PERLIN_SIZE];
76686              n2 += rxf * (perlin[(of + PERLIN_YWRAP + 1) & PERLIN_SIZE] - n2);
76687              n1 += ryf * (n2 - n1);
76688
76689              of += PERLIN_ZWRAP;
76690              n2 = perlin[of & PERLIN_SIZE];
76691              n2 += rxf * (perlin[(of + 1) & PERLIN_SIZE] - n2);
76692              n3 = perlin[(of + PERLIN_YWRAP) & PERLIN_SIZE];
76693              n3 += rxf * (perlin[(of + PERLIN_YWRAP + 1) & PERLIN_SIZE] - n3);
76694              n2 += ryf * (n3 - n2);
76695
76696              n1 += scaled_cosine(zf) * (n2 - n1);
76697
76698              r += n1 * ampl;
76699              ampl *= perlin_amp_falloff;
76700              xi <<= 1;
76701              xf *= 2;
76702              yi <<= 1;
76703              yf *= 2;
76704              zi <<= 1;
76705              zf *= 2;
76706
76707              if (xf >= 1.0) {
76708                xi++;
76709                xf--;
76710              }
76711              if (yf >= 1.0) {
76712                yi++;
76713                yf--;
76714              }
76715              if (zf >= 1.0) {
76716                zi++;
76717                zf--;
76718              }
76719            }
76720            return r;
76721          };
76722
76723          /**
76724           *
76725           * Adjusts the character and level of detail produced by the Perlin noise
76726           * function. Similar to harmonics in physics, noise is computed over
76727           * several octaves. Lower octaves contribute more to the output signal and
76728           * as such define the overall intensity of the noise, whereas higher octaves
76729           * create finer grained details in the noise sequence.
76730           *
76731           * By default, noise is computed over 4 octaves with each octave contributing
76732           * exactly half than its predecessor, starting at 50% strength for the 1st
76733           * octave. This falloff amount can be changed by adding an additional function
76734           * parameter. Eg. a falloff factor of 0.75 means each octave will now have
76735           * 75% impact (25% less) of the previous lower octave. Any value between
76736           * 0.0 and 1.0 is valid, however note that values greater than 0.5 might
76737           * result in greater than 1.0 values returned by <b>noise()</b>.
76738           *
76739           * By changing these parameters, the signal created by the <b>noise()</b>
76740           * function can be adapted to fit very specific needs and characteristics.
76741           *
76742           * @method noiseDetail
76743           * @param {Number} lod number of octaves to be used by the noise
76744           * @param {Number} falloff falloff factor for each octave
76745           * @example
76746           * <div>
76747           * <code>
76748           * let noiseVal;
76749           * let noiseScale = 0.02;
76750           *
76751           * function setup() {
76752           *   createCanvas(100, 100);
76753           * }
76754           *
76755           * function draw() {
76756           *   background(0);
76757           *   for (let y = 0; y < height; y++) {
76758           *     for (let x = 0; x < width / 2; x++) {
76759           *       noiseDetail(2, 0.2);
76760           *       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);
76761           *       stroke(noiseVal * 255);
76762           *       point(x, y);
76763           *       noiseDetail(8, 0.65);
76764           *       noiseVal = noise(
76765           *         (mouseX + x + width / 2) * noiseScale,
76766           *         (mouseY + y) * noiseScale
76767           *       );
76768           *       stroke(noiseVal * 255);
76769           *       point(x + width / 2, y);
76770           *     }
76771           *   }
76772           * }
76773           * </code>
76774           * </div>
76775           *
76776           * @alt
76777           * 2 vertical grey smokey patterns affected my mouse x-position and noise.
76778           */
76779          _main.default.prototype.noiseDetail = function(lod, falloff) {
76780            if (lod > 0) {
76781              perlin_octaves = lod;
76782            }
76783            if (falloff > 0) {
76784              perlin_amp_falloff = falloff;
76785            }
76786          };
76787
76788          /**
76789           * Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>
76790           * produces different results each time the program is run. Set the
76791           * <b>value</b> parameter to a constant to return the same pseudo-random
76792           * numbers each time the software is run.
76793           *
76794           * @method noiseSeed
76795           * @param {Number} seed   the seed value
76796           * @example
76797           * <div>
76798           * <code>let xoff = 0.0;
76799           *
76800           * function setup() {
76801           *   noiseSeed(99);
76802           *   stroke(0, 10);
76803           * }
76804           *
76805           * function draw() {
76806           *   xoff = xoff + .01;
76807           *   let n = noise(xoff) * width;
76808           *   line(n, 0, n, height);
76809           * }
76810           * </code>
76811           * </div>
76812           *
76813           * @alt
76814           * vertical grey lines drawing in pattern affected by noise.
76815           */
76816          _main.default.prototype.noiseSeed = function(seed) {
76817            // Linear Congruential Generator
76818            // Variant of a Lehman Generator
76819            var lcg = (function() {
76820              // Set to values from http://en.wikipedia.org/wiki/Numerical_Recipes
76821              // m is basically chosen to be large (as it is the max period)
76822              // and for its relationships to a and c
76823              var m = 4294967296;
76824              // a - 1 should be divisible by m's prime factors
76825              var a = 1664525;
76826              // c and m should be co-prime
76827              var c = 1013904223;
76828              var seed, z;
76829              return {
76830                setSeed: function setSeed(val) {
76831                  // pick a random seed if val is undefined or null
76832                  // the >>> 0 casts the seed to an unsigned 32-bit integer
76833                  z = seed = (val == null ? Math.random() * m : val) >>> 0;
76834                },
76835                getSeed: function getSeed() {
76836                  return seed;
76837                },
76838                rand: function rand() {
76839                  // define the recurrence relationship
76840                  z = (a * z + c) % m;
76841                  // return a float in [0, 1)
76842                  // if z = m then z / m = 0 therefore (z % m) / m < 1 always
76843                  return z / m;
76844                }
76845              };
76846            })();
76847
76848            lcg.setSeed(seed);
76849            perlin = new Array(PERLIN_SIZE + 1);
76850            for (var i = 0; i < PERLIN_SIZE + 1; i++) {
76851              perlin[i] = lcg.rand();
76852            }
76853          };
76854          var _default = _main.default;
76855          exports.default = _default;
76856        },
76857        { '../core/main': 59 }
76858      ],
76859      92: [
76860        function(_dereq_, module, exports) {
76861          'use strict';
76862          function _typeof(obj) {
76863            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
76864              _typeof = function _typeof(obj) {
76865                return typeof obj;
76866              };
76867            } else {
76868              _typeof = function _typeof(obj) {
76869                return obj &&
76870                  typeof Symbol === 'function' &&
76871                  obj.constructor === Symbol &&
76872                  obj !== Symbol.prototype
76873                  ? 'symbol'
76874                  : typeof obj;
76875              };
76876            }
76877            return _typeof(obj);
76878          }
76879          Object.defineProperty(exports, '__esModule', { value: true });
76880          exports.default = void 0;
76881
76882          var _main = _interopRequireDefault(_dereq_('../core/main'));
76883          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
76884          function _getRequireWildcardCache() {
76885            if (typeof WeakMap !== 'function') return null;
76886            var cache = new WeakMap();
76887            _getRequireWildcardCache = function _getRequireWildcardCache() {
76888              return cache;
76889            };
76890            return cache;
76891          }
76892          function _interopRequireWildcard(obj) {
76893            if (obj && obj.__esModule) {
76894              return obj;
76895            }
76896            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
76897              return { default: obj };
76898            }
76899            var cache = _getRequireWildcardCache();
76900            if (cache && cache.has(obj)) {
76901              return cache.get(obj);
76902            }
76903            var newObj = {};
76904            var hasPropertyDescriptor =
76905              Object.defineProperty && Object.getOwnPropertyDescriptor;
76906            for (var key in obj) {
76907              if (Object.prototype.hasOwnProperty.call(obj, key)) {
76908                var desc = hasPropertyDescriptor
76909                  ? Object.getOwnPropertyDescriptor(obj, key)
76910                  : null;
76911                if (desc && (desc.get || desc.set)) {
76912                  Object.defineProperty(newObj, key, desc);
76913                } else {
76914                  newObj[key] = obj[key];
76915                }
76916              }
76917            }
76918            newObj.default = obj;
76919            if (cache) {
76920              cache.set(obj, newObj);
76921            }
76922            return newObj;
76923          }
76924          function _interopRequireDefault(obj) {
76925            return obj && obj.__esModule ? obj : { default: obj };
76926          }
76927          /**
76928           * @module Math
76929           * @submodule Vector
76930           * @requires constants
76931           */ /**
76932           * A class to describe a two or three dimensional vector, specifically
76933           * a Euclidean (also known as geometric) vector. A vector is an entity
76934           * that has both magnitude and direction. The datatype, however, stores
76935           * the components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude
76936           * and direction can be accessed via the methods <a href="#/p5.Vector/mag">mag()</a> and <a href="#/p5.Vector/heading">heading()</a>.
76937           *
76938           * In many of the p5.js examples, you will see <a href="#/p5.Vector">p5.Vector</a> used to describe a
76939           * position, velocity, or acceleration. For example, if you consider a rectangle
76940           * moving across the screen, at any given instant it has a position (a vector
76941           * that points from the origin to its location), a velocity (the rate at which
76942           * the object's position changes per time unit, expressed as a vector), and
76943           * acceleration (the rate at which the object's velocity changes per time
76944           * unit, expressed as a vector).
76945           *
76946           * Since vectors represent groupings of values, we cannot simply use
76947           * traditional addition/multiplication/etc. Instead, we'll need to do some
76948           * "vector" math, which is made easy by the methods inside the <a href="#/p5.Vector">p5.Vector</a> class.
76949           *
76950           * @class p5.Vector
76951           * @constructor
76952           * @param {Number} [x] x component of the vector
76953           * @param {Number} [y] y component of the vector
76954           * @param {Number} [z] z component of the vector
76955           * @example
76956           * <div>
76957           * <code>
76958           * let v1 = createVector(40, 50);
76959           * let v2 = createVector(40, 50);
76960           *
76961           * ellipse(v1.x, v1.y, 50, 50);
76962           * ellipse(v2.x, v2.y, 50, 50);
76963           * v1.add(v2);
76964           * ellipse(v1.x, v1.y, 50, 50);
76965           * </code>
76966           * </div>
76967           *
76968           * @alt
76969           * 2 white ellipses. One center-left the other bottom right and off canvas
76970           */ _main.default.Vector = function Vector() {
76971            var x, y, z;
76972            // This is how it comes in with createVector()
76973            if (arguments[0] instanceof _main.default) {
76974              // save reference to p5 if passed in
76975              this.p5 = arguments[0];
76976              x = arguments[1][0] || 0;
76977              y = arguments[1][1] || 0;
76978              z = arguments[1][2] || 0;
76979              // This is what we'll get with new p5.Vector()
76980            } else {
76981              x = arguments[0] || 0;
76982              y = arguments[1] || 0;
76983              z = arguments[2] || 0;
76984            }
76985            /**
76986             * The x component of the vector
76987             * @property x {Number}
76988             */
76989            this.x = x;
76990            /**
76991             * The y component of the vector
76992             * @property y {Number}
76993             */
76994            this.y = y;
76995            /**
76996             * The z component of the vector
76997             * @property z {Number}
76998             */
76999            this.z = z;
77000          };
77001
77002          /**
77003           * Returns a string representation of a vector v by calling String(v)
77004           * or v.toString(). This method is useful for logging vectors in the
77005           * console.
77006           * @method  toString
77007           * @return {String}
77008           * @example
77009           * <div class = "norender">
77010           * <code>
77011           * function setup() {
77012           *   let v = createVector(20, 30);
77013           *   print(String(v)); // prints "p5.Vector Object : [20, 30, 0]"
77014           * }
77015           * </code>
77016           * </div>
77017           *
77018           * <div>
77019           * <code>
77020           * function draw() {
77021           *   background(240);
77022           *
77023           *   let v0 = createVector(0, 0);
77024           *   let v1 = createVector(mouseX, mouseY);
77025           *   drawArrow(v0, v1, 'black');
77026           *
77027           *   noStroke();
77028           *   text(v1.toString(), 10, 25, 90, 75);
77029           * }
77030           *
77031           * // draw an arrow for a vector at a given base position
77032           * function drawArrow(base, vec, myColor) {
77033           *   push();
77034           *   stroke(myColor);
77035           *   strokeWeight(3);
77036           *   fill(myColor);
77037           *   translate(base.x, base.y);
77038           *   line(0, 0, vec.x, vec.y);
77039           *   rotate(vec.heading());
77040           *   let arrowSize = 7;
77041           *   translate(vec.mag() - arrowSize, 0);
77042           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
77043           *   pop();
77044           * }
77045           * </code>
77046           * </div>
77047           */
77048          _main.default.Vector.prototype.toString = function p5VectorToString() {
77049            return 'p5.Vector Object : ['
77050              .concat(this.x, ', ')
77051              .concat(this.y, ', ')
77052              .concat(this.z, ']');
77053          };
77054
77055          /**
77056           * Sets the x, y, and z component of the vector using two or three separate
77057           * variables, the data from a <a href="#/p5.Vector">p5.Vector</a>, or the values from a float array.
77058           * @method set
77059           * @param {Number} [x] the x component of the vector
77060           * @param {Number} [y] the y component of the vector
77061           * @param {Number} [z] the z component of the vector
77062           * @chainable
77063           * @example
77064           * <div class="norender">
77065           * <code>
77066           * function setup() {
77067           *   let v = createVector(1, 2, 3);
77068           *   v.set(4, 5, 6); // Sets vector to [4, 5, 6]
77069           *
77070           *   let v1 = createVector(0, 0, 0);
77071           *   let arr = [1, 2, 3];
77072           *   v1.set(arr); // Sets vector to [1, 2, 3]
77073           * }
77074           * </code>
77075           * </div>
77076           *
77077           * <div>
77078           * <code>
77079           * let v0, v1;
77080           * function setup() {
77081           *   createCanvas(100, 100);
77082           *
77083           *   v0 = createVector(0, 0);
77084           *   v1 = createVector(50, 50);
77085           * }
77086           *
77087           * function draw() {
77088           *   background(240);
77089           *
77090           *   drawArrow(v0, v1, 'black');
77091           *   v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));
77092           *
77093           *   noStroke();
77094           *   text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);
77095           * }
77096           *
77097           * // draw an arrow for a vector at a given base position
77098           * function drawArrow(base, vec, myColor) {
77099           *   push();
77100           *   stroke(myColor);
77101           *   strokeWeight(3);
77102           *   fill(myColor);
77103           *   translate(base.x, base.y);
77104           *   line(0, 0, vec.x, vec.y);
77105           *   rotate(vec.heading());
77106           *   let arrowSize = 7;
77107           *   translate(vec.mag() - arrowSize, 0);
77108           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
77109           *   pop();
77110           * }
77111           * </code>
77112           * </div>
77113           */
77114          /**
77115           * @method set
77116           * @param {p5.Vector|Number[]} value the vector to set
77117           * @chainable
77118           */
77119          _main.default.Vector.prototype.set = function set(x, y, z) {
77120            if (x instanceof _main.default.Vector) {
77121              this.x = x.x || 0;
77122              this.y = x.y || 0;
77123              this.z = x.z || 0;
77124              return this;
77125            }
77126            if (x instanceof Array) {
77127              this.x = x[0] || 0;
77128              this.y = x[1] || 0;
77129              this.z = x[2] || 0;
77130              return this;
77131            }
77132            this.x = x || 0;
77133            this.y = y || 0;
77134            this.z = z || 0;
77135            return this;
77136          };
77137
77138          /**
77139           * Gets a copy of the vector, returns a <a href="#/p5.Vector">p5.Vector</a> object.
77140           *
77141           * @method copy
77142           * @return {p5.Vector} the copy of the <a href="#/p5.Vector">p5.Vector</a> object
77143           * @example
77144           * <div class="norender">
77145           * <code>
77146           * let v1 = createVector(1, 2, 3);
77147           * let v2 = v1.copy();
77148           * print(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);
77149           * // Prints "true"
77150           * </code>
77151           * </div>
77152           */
77153          _main.default.Vector.prototype.copy = function copy() {
77154            if (this.p5) {
77155              return new _main.default.Vector(this.p5, [this.x, this.y, this.z]);
77156            } else {
77157              return new _main.default.Vector(this.x, this.y, this.z);
77158            }
77159          };
77160
77161          /**
77162           * Adds x, y, and z components to a vector, adds one vector to another, or
77163           * adds two independent vectors together. The version of the method that adds
77164           * two vectors together is a static method and returns a <a href="#/p5.Vector">p5.Vector</a>, the others
77165           * acts directly on the vector. Additionally, you may provide arguments to this function as an array.
77166           * See the examples for more context.
77167           *
77168           * @method add
77169           * @param  {Number} x   the x component of the vector to be added
77170           * @param  {Number} [y] the y component of the vector to be added
77171           * @param  {Number} [z] the z component of the vector to be added
77172           * @chainable
77173           * @example
77174           * <div class="norender">
77175           * <code>
77176           * let v = createVector(1, 2, 3);
77177           * v.add(4, 5, 6);
77178           * // v's components are set to [5, 7, 9]
77179           * </code>
77180           * </div>
77181           *
77182           * <div class="norender">
77183           * <code>
77184           * let v = createVector(1, 2, 3);
77185           * // Provide arguments as an array
77186           * let arr = [4, 5, 6];
77187           * v.add(arr);
77188           * // v's components are set to [5, 7, 9]
77189           * </code>
77190           * </div>
77191           *
77192           * <div class="norender">
77193           * <code>
77194           * // Static method
77195           * let v1 = createVector(1, 2, 3);
77196           * let v2 = createVector(2, 3, 4);
77197           *
77198           * let v3 = p5.Vector.add(v1, v2);
77199           * // v3 has components [3, 5, 7]
77200           * print(v3);
77201           * </code>
77202           * </div>
77203           *
77204           * <div>
77205           * <code>
77206           * // red vector + blue vector = purple vector
77207           * function draw() {
77208           *   background(240);
77209           *
77210           *   let v0 = createVector(0, 0);
77211           *   let v1 = createVector(mouseX, mouseY);
77212           *   drawArrow(v0, v1, 'red');
77213           *
77214           *   let v2 = createVector(-30, 20);
77215           *   drawArrow(v1, v2, 'blue');
77216           *
77217           *   let v3 = p5.Vector.add(v1, v2);
77218           *   drawArrow(v0, v3, 'purple');
77219           * }
77220           *
77221           * // draw an arrow for a vector at a given base position
77222           * function drawArrow(base, vec, myColor) {
77223           *   push();
77224           *   stroke(myColor);
77225           *   strokeWeight(3);
77226           *   fill(myColor);
77227           *   translate(base.x, base.y);
77228           *   line(0, 0, vec.x, vec.y);
77229           *   rotate(vec.heading());
77230           *   let arrowSize = 7;
77231           *   translate(vec.mag() - arrowSize, 0);
77232           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
77233           *   pop();
77234           * }
77235           * </code>
77236           * </div>
77237           */
77238          /**
77239           * @method add
77240           * @param  {p5.Vector|Number[]} value the vector to add
77241           * @chainable
77242           */
77243          _main.default.Vector.prototype.add = function add(x, y, z) {
77244            if (x instanceof _main.default.Vector) {
77245              this.x += x.x || 0;
77246              this.y += x.y || 0;
77247              this.z += x.z || 0;
77248              return this;
77249            }
77250            if (x instanceof Array) {
77251              this.x += x[0] || 0;
77252              this.y += x[1] || 0;
77253              this.z += x[2] || 0;
77254              return this;
77255            }
77256            this.x += x || 0;
77257            this.y += y || 0;
77258            this.z += z || 0;
77259            return this;
77260          };
77261
77262          /// HELPERS FOR REMAINDER METHOD
77263          var calculateRemainder2D = function calculateRemainder2D(xComponent, yComponent) {
77264            if (xComponent !== 0) {
77265              this.x = this.x % xComponent;
77266            }
77267            if (yComponent !== 0) {
77268              this.y = this.y % yComponent;
77269            }
77270            return this;
77271          };
77272
77273          var calculateRemainder3D = function calculateRemainder3D(
77274            xComponent,
77275            yComponent,
77276            zComponent
77277          ) {
77278            if (xComponent !== 0) {
77279              this.x = this.x % xComponent;
77280            }
77281            if (yComponent !== 0) {
77282              this.y = this.y % yComponent;
77283            }
77284            if (zComponent !== 0) {
77285              this.z = this.z % zComponent;
77286            }
77287            return this;
77288          };
77289          /**
77290           * Gives remainder of a vector when it is divided by another vector.
77291           * See examples for more context.
77292           *
77293           * @method rem
77294           * @param {Number} x the x component of divisor vector
77295           * @param {Number} y the y component of divisor vector
77296           * @param {Number} z the z component of divisor vector
77297           * @chainable
77298           * @example
77299           * <div class='norender'>
77300           * <code>
77301           * let v = createVector(3, 4, 5);
77302           * v.rem(2, 3, 4);
77303           * // v's components are set to [1, 1, 1]
77304           * </code>
77305           * </div>
77306           * <div class="norender">
77307           * <code>
77308           * // Static method
77309           * let v1 = createVector(3, 4, 5);
77310           * let v2 = createVector(2, 3, 4);
77311           *
77312           * let v3 = p5.Vector.rem(v1, v2);
77313           * // v3 has components [1, 1, 1]
77314           * print(v3);
77315           * </code>
77316           * </div>
77317           */
77318          /**
77319           * @method rem
77320           * @param {p5.Vector | Number[]}  value  divisor vector
77321           * @chainable
77322           */
77323          _main.default.Vector.prototype.rem = function rem(x, y, z) {
77324            if (x instanceof _main.default.Vector) {
77325              if (Number.isFinite(x.x) && Number.isFinite(x.y) && Number.isFinite(x.z)) {
77326                var xComponent = parseFloat(x.x);
77327                var yComponent = parseFloat(x.y);
77328                var zComponent = parseFloat(x.z);
77329                calculateRemainder3D.call(this, xComponent, yComponent, zComponent);
77330              }
77331            } else if (x instanceof Array) {
77332              if (
77333                x.every(function(element) {
77334                  return Number.isFinite(element);
77335                })
77336              ) {
77337                if (x.length === 2) {
77338                  calculateRemainder2D.call(this, x[0], x[1]);
77339                }
77340                if (x.length === 3) {
77341                  calculateRemainder3D.call(this, x[0], x[1], x[2]);
77342                }
77343              }
77344            } else if (arguments.length === 1) {
77345              if (Number.isFinite(arguments[0]) && arguments[0] !== 0) {
77346                this.x = this.x % arguments[0];
77347                this.y = this.y % arguments[0];
77348                this.z = this.z % arguments[0];
77349                return this;
77350              }
77351            } else if (arguments.length === 2) {
77352              var vectorComponents = Array.prototype.slice.call(arguments);
77353              if (
77354                vectorComponents.every(function(element) {
77355                  return Number.isFinite(element);
77356                })
77357              ) {
77358                if (vectorComponents.length === 2) {
77359                  calculateRemainder2D.call(this, vectorComponents[0], vectorComponents[1]);
77360                }
77361              }
77362            } else if (arguments.length === 3) {
77363              var _vectorComponents = Array.prototype.slice.call(arguments);
77364              if (
77365                _vectorComponents.every(function(element) {
77366                  return Number.isFinite(element);
77367                })
77368              ) {
77369                if (_vectorComponents.length === 3) {
77370                  calculateRemainder3D.call(
77371                    this,
77372                    _vectorComponents[0],
77373                    _vectorComponents[1],
77374                    _vectorComponents[2]
77375                  );
77376                }
77377              }
77378            }
77379          };
77380
77381          /**
77382           * Subtracts x, y, and z components from a vector, subtracts one vector from
77383           * another, or subtracts two independent vectors. The version of the method
77384           * that subtracts two vectors is a static method and returns a <a href="#/p5.Vector">p5.Vector</a>, the
77385           * other acts directly on the vector. Additionally, you may provide arguments to this function as an array.
77386           * See the examples for more context.
77387           *
77388           * @method sub
77389           * @param  {Number} x   the x component of the vector to subtract
77390           * @param  {Number} [y] the y component of the vector to subtract
77391           * @param  {Number} [z] the z component of the vector to subtract
77392           * @chainable
77393           * @example
77394           * <div class="norender">
77395           * <code>
77396           * let v = createVector(4, 5, 6);
77397           * v.sub(1, 1, 1);
77398           * // v's components are set to [3, 4, 5]
77399           * </code>
77400           * </div>
77401           *
77402           * <div class="norender">
77403           * <code>
77404           * let v = createVector(4, 5, 6);
77405           * // Provide arguments as an array
77406           * let arr = [1, 1, 1];
77407           * v.sub(arr);
77408           * // v's components are set to [3, 4, 5]
77409           * </code>
77410           * </div>
77411           *
77412           * <div class="norender">
77413           * <code>
77414           * // Static method
77415           * let v1 = createVector(2, 3, 4);
77416           * let v2 = createVector(1, 2, 3);
77417           *
77418           * let v3 = p5.Vector.sub(v1, v2);
77419           * // v3 has components [1, 1, 1]
77420           * print(v3);
77421           * </code>
77422           * </div>
77423           *
77424           * <div>
77425           * <code>
77426           * // red vector - blue vector = purple vector
77427           * function draw() {
77428           *   background(240);
77429           *
77430           *   let v0 = createVector(0, 0);
77431           *   let v1 = createVector(70, 50);
77432           *   drawArrow(v0, v1, 'red');
77433           *
77434           *   let v2 = createVector(mouseX, mouseY);
77435           *   drawArrow(v0, v2, 'blue');
77436           *
77437           *   let v3 = p5.Vector.sub(v1, v2);
77438           *   drawArrow(v2, v3, 'purple');
77439           * }
77440           *
77441           * // draw an arrow for a vector at a given base position
77442           * function drawArrow(base, vec, myColor) {
77443           *   push();
77444           *   stroke(myColor);
77445           *   strokeWeight(3);
77446           *   fill(myColor);
77447           *   translate(base.x, base.y);
77448           *   line(0, 0, vec.x, vec.y);
77449           *   rotate(vec.heading());
77450           *   let arrowSize = 7;
77451           *   translate(vec.mag() - arrowSize, 0);
77452           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
77453           *   pop();
77454           * }
77455           * </code>
77456           * </div>
77457           */
77458          /**
77459           * @method sub
77460           * @param  {p5.Vector|Number[]} value the vector to subtract
77461           * @chainable
77462           */
77463          _main.default.Vector.prototype.sub = function sub(x, y, z) {
77464            if (x instanceof _main.default.Vector) {
77465              this.x -= x.x || 0;
77466              this.y -= x.y || 0;
77467              this.z -= x.z || 0;
77468              return this;
77469            }
77470            if (x instanceof Array) {
77471              this.x -= x[0] || 0;
77472              this.y -= x[1] || 0;
77473              this.z -= x[2] || 0;
77474              return this;
77475            }
77476            this.x -= x || 0;
77477            this.y -= y || 0;
77478            this.z -= z || 0;
77479            return this;
77480          };
77481
77482          /**
77483           * Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies
77484           * the x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,
77485           * and z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,
77486           * the x, y, z components of both vectors are multiplied by each other
77487           * (for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method
77488           * creates a new <a href="#/p5.Vector">p5.Vector</a> while the non static version acts on the vector
77489           * directly. Additionally, you may provide arguments to this function as an array.
77490           * See the examples for more context.
77491           *
77492           * @method mult
77493           * @param  {Number} n The number to multiply with the vector
77494           * @chainable
77495           * @example
77496           * <div class="norender">
77497           * <code>
77498           * let v = createVector(1, 2, 3);
77499           * v.mult(2);
77500           * // v's components are set to [2, 4, 6]
77501           * </code>
77502           * </div>
77503           *
77504           * <div class="norender">
77505           * <code>
77506           * let v0 = createVector(1, 2, 3);
77507           * let v1 = createVector(2, 3, 4);
77508           * v0.mult(v1); // v0's components are set to [2, 6, 12]
77509           * </code>
77510           * </div>
77511           *
77512           * <div class="norender">
77513           * <code>
77514           * let v0 = createVector(1, 2, 3);
77515           * // Provide arguments as an array
77516           * let arr = [2, 3, 4];
77517           * v0.mult(arr); // v0's components are set to [2, 6, 12]
77518           * </code>
77519           * </div>
77520           *
77521           * <div class="norender">
77522           * <code>
77523           * let v0 = createVector(1, 2, 3);
77524           * let v1 = createVector(2, 3, 4);
77525           * const result = p5.Vector.mult(v0, v1);
77526           * print(result); // result's components are set to [2, 6, 12]
77527           * </code>
77528           * </div>
77529           *
77530           * <div class="norender">
77531           * <code>
77532           * // Static method
77533           * let v1 = createVector(1, 2, 3);
77534           * let v2 = p5.Vector.mult(v1, 2);
77535           * // v2 has components [2, 4, 6]
77536           * print(v2);
77537           * </code>
77538           * </div>
77539           *
77540           * <div>
77541           * <code>
77542           * function draw() {
77543           *   background(240);
77544           *
77545           *   let v0 = createVector(50, 50);
77546           *   let v1 = createVector(25, -25);
77547           *   drawArrow(v0, v1, 'red');
77548           *
77549           *   let num = map(mouseX, 0, width, -2, 2, true);
77550           *   let v2 = p5.Vector.mult(v1, num);
77551           *   drawArrow(v0, v2, 'blue');
77552           *
77553           *   noStroke();
77554           *   text('multiplied by ' + num.toFixed(2), 5, 90);
77555           * }
77556           *
77557           * // draw an arrow for a vector at a given base position
77558           * function drawArrow(base, vec, myColor) {
77559           *   push();
77560           *   stroke(myColor);
77561           *   strokeWeight(3);
77562           *   fill(myColor);
77563           *   translate(base.x, base.y);
77564           *   line(0, 0, vec.x, vec.y);
77565           *   rotate(vec.heading());
77566           *   let arrowSize = 7;
77567           *   translate(vec.mag() - arrowSize, 0);
77568           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
77569           *   pop();
77570           * }
77571           * </code>
77572           * </div>
77573           */
77574
77575          /**
77576           * @method mult
77577           * @param  {Number} x The number to multiply with the x component of the vector
77578           * @param  {Number} y The number to multiply with the y component of the vector
77579           * @param  {Number} [z] The number to multiply with the z component of the vector
77580           * @chainable
77581           */
77582
77583          /**
77584           * @method mult
77585           * @param  {Number[]} arr The array to multiply with the components of the vector
77586           * @chainable
77587           */
77588
77589          /**
77590           * @method mult
77591           * @param  {p5.Vector} v The vector to multiply with the components of the original vector
77592           * @chainable
77593           */
77594
77595          _main.default.Vector.prototype.mult = function mult(x, y, z) {
77596            if (x instanceof _main.default.Vector) {
77597              // new p5.Vector will check that values are valid upon construction but it's possible
77598              // that someone could change the value of a component after creation, which is why we still
77599              // perform this check
77600              if (
77601                Number.isFinite(x.x) &&
77602                Number.isFinite(x.y) &&
77603                Number.isFinite(x.z) &&
77604                typeof x.x === 'number' &&
77605                typeof x.y === 'number' &&
77606                typeof x.z === 'number'
77607              ) {
77608                this.x *= x.x;
77609                this.y *= x.y;
77610                this.z *= x.z;
77611              } else {
77612                console.warn(
77613                  'p5.Vector.prototype.mult:',
77614                  'x contains components that are either undefined or not finite numbers'
77615                );
77616              }
77617              return this;
77618            }
77619            if (x instanceof Array) {
77620              if (
77621                x.every(function(element) {
77622                  return Number.isFinite(element);
77623                }) &&
77624                x.every(function(element) {
77625                  return typeof element === 'number';
77626                })
77627              ) {
77628                if (x.length === 1) {
77629                  this.x *= x[0];
77630                  this.y *= x[0];
77631                  this.z *= x[0];
77632                } else if (x.length === 2) {
77633                  this.x *= x[0];
77634                  this.y *= x[1];
77635                } else if (x.length === 3) {
77636                  this.x *= x[0];
77637                  this.y *= x[1];
77638                  this.z *= x[2];
77639                }
77640              } else {
77641                console.warn(
77642                  'p5.Vector.prototype.mult:',
77643                  'x contains elements that are either undefined or not finite numbers'
77644                );
77645              }
77646              return this;
77647            }
77648
77649            var vectorComponents = Array.prototype.slice.call(arguments);
77650            if (
77651              vectorComponents.every(function(element) {
77652                return Number.isFinite(element);
77653              }) &&
77654              vectorComponents.every(function(element) {
77655                return typeof element === 'number';
77656              })
77657            ) {
77658              if (arguments.length === 1) {
77659                this.x *= x;
77660                this.y *= x;
77661                this.z *= x;
77662              }
77663              if (arguments.length === 2) {
77664                this.x *= x;
77665                this.y *= y;
77666              }
77667              if (arguments.length === 3) {
77668                this.x *= x;
77669                this.y *= y;
77670                this.z *= z;
77671              }
77672            } else {
77673              console.warn(
77674                'p5.Vector.prototype.mult:',
77675                'x, y, or z arguments are either undefined or not a finite number'
77676              );
77677            }
77678
77679            return this;
77680          };
77681
77682          /**
77683           * Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and
77684           * z components of two vectors against each other. When dividing a vector by a scalar, the x, y,
77685           * and z components of the vector are all divided by the scalar. When dividing a vector by a vector,
77686           * the x, y, z components of the source vector are treated as the dividend, and the x, y, z components
77687           * of the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).
77688           * The static version of this method creates a
77689           * new <a href="#/p5.Vector">p5.Vector</a> while the non static version acts on the vector directly.
77690           * Additionally, you may provide arguments to this function as an array.
77691           * See the examples for more context.
77692           *
77693           * @method div
77694           * @param  {number}    n The number to divide the vector by
77695           * @chainable
77696           * @example
77697           * <div class="norender">
77698           * <code>
77699           * let v = createVector(6, 4, 2);
77700           * v.div(2); //v's components are set to [3, 2, 1]
77701           * </code>
77702           * </div>
77703           *
77704           * <div class="norender">
77705           * <code>
77706           * let v0 = createVector(9, 4, 2);
77707           * let v1 = createVector(3, 2, 4);
77708           * v0.div(v1); // v0's components are set to [3, 2, 0.5]
77709           * </code>
77710           * </div>
77711           *
77712           * <div class="norender">
77713           * <code>
77714           * let v0 = createVector(9, 4, 2);
77715           * // Provide arguments as an array
77716           * let arr = [3, 2, 4];
77717           * v0.div(arr); // v0's components are set to [3, 2, 0.5]
77718           * </code>
77719           * </div>
77720           *
77721           * <div class="norender">
77722           * <code>
77723           * let v0 = createVector(9, 4, 2);
77724           * let v1 = createVector(3, 2, 4);
77725           * let result = p5.Vector.div(v0, v1);
77726           * print(result); // result's components are set to [3, 2, 0.5]
77727           * </code>
77728           * </div>
77729           *
77730           * <div class="norender">
77731           * <code>
77732           * // Static method
77733           * let v1 = createVector(6, 4, 2);
77734           * let v2 = p5.Vector.div(v1, 2);
77735           * // v2 has components [3, 2, 1]
77736           * print(v2);
77737           * </code>
77738           * </div>
77739           *
77740           * <div>
77741           * <code>
77742           * function draw() {
77743           *   background(240);
77744           *
77745           *   let v0 = createVector(0, 100);
77746           *   let v1 = createVector(50, -50);
77747           *   drawArrow(v0, v1, 'red');
77748           *
77749           *   let num = map(mouseX, 0, width, 10, 0.5, true);
77750           *   let v2 = p5.Vector.div(v1, num);
77751           *   drawArrow(v0, v2, 'blue');
77752           *
77753           *   noStroke();
77754           *   text('divided by ' + num.toFixed(2), 10, 90);
77755           * }
77756           *
77757           * // draw an arrow for a vector at a given base position
77758           * function drawArrow(base, vec, myColor) {
77759           *   push();
77760           *   stroke(myColor);
77761           *   strokeWeight(3);
77762           *   fill(myColor);
77763           *   translate(base.x, base.y);
77764           *   line(0, 0, vec.x, vec.y);
77765           *   rotate(vec.heading());
77766           *   let arrowSize = 7;
77767           *   translate(vec.mag() - arrowSize, 0);
77768           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
77769           *   pop();
77770           * }
77771           * </code>
77772           * </div>
77773           */
77774
77775          /**
77776           * @method div
77777           * @param  {Number} x The number to divide with the x component of the vector
77778           * @param  {Number} y The number to divide with the y component of the vector
77779           * @param  {Number} [z] The number to divide with the z component of the vector
77780           * @chainable
77781           */
77782
77783          /**
77784           * @method div
77785           * @param  {Number[]} arr The array to divide the components of the vector by
77786           * @chainable
77787           */
77788
77789          /**
77790           * @method div
77791           * @param  {p5.Vector} v The vector to divide the components of the original vector by
77792           * @chainable
77793           */
77794          _main.default.Vector.prototype.div = function div(x, y, z) {
77795            if (x instanceof _main.default.Vector) {
77796              // new p5.Vector will check that values are valid upon construction but it's possible
77797              // that someone could change the value of a component after creation, which is why we still
77798              // perform this check
77799              if (
77800                Number.isFinite(x.x) &&
77801                Number.isFinite(x.y) &&
77802                Number.isFinite(x.z) &&
77803                typeof x.x === 'number' &&
77804                typeof x.y === 'number' &&
77805                typeof x.z === 'number'
77806              ) {
77807                if (x.x === 0 || x.y === 0 || x.z === 0) {
77808                  console.warn('p5.Vector.prototype.div:', 'divi
77808de by 0');
77809                  return this;
77810                }
77811                this.x /= x.x;
77812                this.y /= x.y;
77813                this.z /= x.z;
77814              } else {
77815                console.warn(
77816                  'p5.Vector.prototype.div:',
77817                  'x contains components that are either undefined or not finite numbers'
77818                );
77819              }
77820              return this;
77821            }
77822            if (x instanceof Array) {
77823              if (
77824                x.every(function(element) {
77825                  return Number.isFinite(element);
77826                }) &&
77827                x.every(function(element) {
77828                  return typeof element === 'number';
77829                })
77830              ) {
77831                if (
77832                  x.some(function(element) {
77833                    return element === 0;
77834                  })
77835                ) {
77836                  console.warn('p5.Vector.prototype.div:', 'divide by 0');
77837                  return this;
77838                }
77839
77840                if (x.length === 1) {
77841                  this.x /= x[0];
77842                  this.y /= x[0];
77843                  this.z /= x[0];
77844                } else if (x.length === 2) {
77845                  this.x /= x[0];
77846                  this.y /= x[1];
77847                } else if (x.length === 3) {
77848                  this.x /= x[0];
77849                  this.y /= x[1];
77850                  this.z /= x[2];
77851                }
77852              } else {
77853                console.warn(
77854                  'p5.Vector.prototype.div:',
77855                  'x contains components that are either undefined or not finite numbers'
77856                );
77857              }
77858
77859              return this;
77860            }
77861
77862            var vectorComponents = Array.prototype.slice.call(arguments);
77863            if (
77864              vectorComponents.every(function(element) {
77865                return Number.isFinite(element);
77866              }) &&
77867              vectorComponents.every(function(element) {
77868                return typeof element === 'number';
77869              })
77870            ) {
77871              if (
77872                vectorComponents.some(function(element) {
77873                  return element === 0;
77874                })
77875              ) {
77876                console.warn('p5.Vector.prototype.div:', 'divide by 0');
77877                return this;
77878              }
77879
77880              if (arguments.length === 1) {
77881                this.x /= x;
77882                this.y /= x;
77883                this.z /= x;
77884              }
77885              if (arguments.length === 2) {
77886                this.x /= x;
77887                this.y /= y;
77888              }
77889              if (arguments.length === 3) {
77890                this.x /= x;
77891                this.y /= y;
77892                this.z /= z;
77893              }
77894            } else {
77895              console.warn(
77896                'p5.Vector.prototype.div:',
77897                'x, y, or z arguments are either undefined or not a finite number'
77898              );
77899            }
77900
77901            return this;
77902          };
77903          /**
77904           * Calculates the magnitude (length) of the vector and returns the result as
77905           * a float (this is simply the equation sqrt(x\*x + y\*y + z\*z).)
77906           *
77907           * @method mag
77908           * @return {Number} magnitude of the vector
77909           * @example
77910           * <div>
77911           * <code>
77912           * function draw() {
77913           *   background(240);
77914           *
77915           *   let v0 = createVector(0, 0);
77916           *   let v1 = createVector(mouseX, mouseY);
77917           *   drawArrow(v0, v1, 'black');
77918           *
77919           *   noStroke();
77920           *   text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);
77921           * }
77922           *
77923           * // draw an arrow for a vector at a given base position
77924           * function drawArrow(base, vec, myColor) {
77925           *   push();
77926           *   stroke(myColor);
77927           *   strokeWeight(3);
77928           *   fill(myColor);
77929           *   translate(base.x, base.y);
77930           *   line(0, 0, vec.x, vec.y);
77931           *   rotate(vec.heading());
77932           *   let arrowSize = 7;
77933           *   translate(vec.mag() - arrowSize, 0);
77934           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
77935           *   pop();
77936           * }
77937           * </code>
77938           * </div>
77939           * <div class="norender">
77940           * <code>
77941           * let v = createVector(20.0, 30.0, 40.0);
77942           * let m = v.mag();
77943           * print(m); // Prints "53.85164807134504"
77944           * </code>
77945           * </div>
77946           */
77947          _main.default.Vector.prototype.mag = function mag() {
77948            return Math.sqrt(this.magSq());
77949          };
77950
77951          /**
77952           * Calculates the squared magnitude of the vector and returns the result
77953           * as a float (this is simply the equation <em>(x\*x + y\*y + z\*z)</em>.)
77954           * Faster if the real length is not required in the
77955           * case of comparing vectors, etc.
77956           *
77957           * @method magSq
77958           * @return {number} squared magnitude of the vector
77959           * @example
77960           * <div class="norender">
77961           * <code>
77962           * // Static method
77963           * let v1 = createVector(6, 4, 2);
77964           * print(v1.magSq()); // Prints "56"
77965           * </code>
77966           * </div>
77967           *
77968           * <div>
77969           * <code>
77970           * function draw() {
77971           *   background(240);
77972           *
77973           *   let v0 = createVector(0, 0);
77974           *   let v1 = createVector(mouseX, mouseY);
77975           *   drawArrow(v0, v1, 'black');
77976           *
77977           *   noStroke();
77978           *   text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);
77979           * }
77980           *
77981           * // draw an arrow for a vector at a given base position
77982           * function drawArrow(base, vec, myColor) {
77983           *   push();
77984           *   stroke(myColor);
77985           *   strokeWeight(3);
77986           *   fill(myColor);
77987           *   translate(base.x, base.y);
77988           *   line(0, 0, vec.x, vec.y);
77989           *   rotate(vec.heading());
77990           *   let arrowSize = 7;
77991           *   translate(vec.mag() - arrowSize, 0);
77992           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
77993           *   pop();
77994           * }
77995           * </code>
77996           * </div>
77997           */
77998          _main.default.Vector.prototype.magSq = function magSq() {
77999            var x = this.x;
78000            var y = this.y;
78001            var z = this.z;
78002            return x * x + y * y + z * z;
78003          };
78004
78005          /**
78006           * Calculates the dot product of two vectors. The version of the method
78007           * that computes the dot product of two independent vectors is a static
78008           * method. See the examples for more context.
78009           *
78010           * @method dot
78011           * @param  {Number} x   x component of the vector
78012           * @param  {Number} [y] y component of the vector
78013           * @param  {Number} [z] z component of the vector
78014           * @return {Number}       the dot product
78015           *
78016           * @example
78017           * <div class="norender">
78018           * <code>
78019           * let v1 = createVector(1, 2, 3);
78020           * let v2 = createVector(2, 3, 4);
78021           *
78022           * print(v1.dot(v2)); // Prints "20"
78023           * </code>
78024           * </div>
78025           *
78026           * <div class="norender">
78027           * <code>
78028           * //Static method
78029           * let v1 = createVector(1, 2, 3);
78030           * let v2 = createVector(3, 2, 1);
78031           * print(p5.Vector.dot(v1, v2)); // Prints "10"
78032           * </code>
78033           * </div>
78034           */
78035          /**
78036           * @method dot
78037           * @param  {p5.Vector} value value component of the vector or a <a href="#/p5.Vector">p5.Vector</a>
78038           * @return {Number}
78039           */
78040          _main.default.Vector.prototype.dot = function dot(x, y, z) {
78041            if (x instanceof _main.default.Vector) {
78042              return this.dot(x.x, x.y, x.z);
78043            }
78044            return this.x * (x || 0) + this.y * (y || 0) + this.z * (z || 0);
78045          };
78046
78047          /**
78048           * Calculates and returns a vector composed of the cross product between
78049           * two vectors. Both the static and non static methods return a new <a href="#/p5.Vector">p5.Vector</a>.
78050           * See the examples for more context.
78051           *
78052           * @method cross
78053           * @param  {p5.Vector} v <a href="#/p5.Vector">p5.Vector</a> to be crossed
78054           * @return {p5.Vector}   <a href="#/p5.Vector">p5.Vector</a> composed of cross product
78055           * @example
78056           * <div class="norender">
78057           * <code>
78058           * let v1 = createVector(1, 2, 3);
78059           * let v2 = createVector(1, 2, 3);
78060           *
78061           * let v = v1.cross(v2); // v's components are [0, 0, 0]
78062           * print(v);
78063           * </code>
78064           * </div>
78065           *
78066           * <div class="norender">
78067           * <code>
78068           * // Static method
78069           * let v1 = createVector(1, 0, 0);
78070           * let v2 = createVector(0, 1, 0);
78071           *
78072           * let crossProduct = p5.Vector.cross(v1, v2);
78073           * // crossProduct has components [0, 0, 1]
78074           * print(crossProduct);
78075           * </code>
78076           * </div>
78077           */
78078          _main.default.Vector.prototype.cross = function cross(v) {
78079            var x = this.y * v.z - this.z * v.y;
78080            var y = this.z * v.x - this.x * v.z;
78081            var z = this.x * v.y - this.y * v.x;
78082            if (this.p5) {
78083              return new _main.default.Vector(this.p5, [x, y, z]);
78084            } else {
78085              return new _main.default.Vector(x, y, z);
78086            }
78087          };
78088
78089          /**
78090           * Calculates the Euclidean distance between two points (considering a
78091           * point as a vector object).
78092           *
78093           * @method dist
78094           * @param  {p5.Vector} v the x, y, and z coordinates of a <a href="#/p5.Vector">p5.Vector</a>
78095           * @return {Number}      the distance
78096           * @example
78097           * <div class="norender">
78098           * <code>
78099           * let v1 = createVector(1, 0, 0);
78100           * let v2 = createVector(0, 1, 0);
78101           *
78102           * let distance = v1.dist(v2); // distance is 1.4142...
78103           * print(distance);
78104           * </code>
78105           * </div>
78106           *
78107           * <div class="norender">
78108           * <code>
78109           * // Static method
78110           * let v1 = createVector(1, 0, 0);
78111           * let v2 = createVector(0, 1, 0);
78112           *
78113           * let distance = p5.Vector.dist(v1, v2);
78114           * // distance is 1.4142...
78115           * print(distance);
78116           * </code>
78117           * </div>
78118           *
78119           * <div>
78120           * <code>
78121           * function draw() {
78122           *   background(240);
78123           *
78124           *   let v0 = createVector(0, 0);
78125           *
78126           *   let v1 = createVector(70, 50);
78127           *   drawArrow(v0, v1, 'red');
78128           *
78129           *   let v2 = createVector(mouseX, mouseY);
78130           *   drawArrow(v0, v2, 'blue');
78131           *
78132           *   noStroke();
78133           *   text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);
78134           * }
78135           *
78136           * // draw an arrow for a vector at a given base position
78137           * function drawArrow(base, vec, myColor) {
78138           *   push();
78139           *   stroke(myColor);
78140           *   strokeWeight(3);
78141           *   fill(myColor);
78142           *   translate(base.x, base.y);
78143           *   line(0, 0, vec.x, vec.y);
78144           *   rotate(vec.heading());
78145           *   let arrowSize = 7;
78146           *   translate(vec.mag() - arrowSize, 0);
78147           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78148           *   pop();
78149           * }
78150           * </code>
78151           * </div>
78152           */
78153          _main.default.Vector.prototype.dist = function dist(v) {
78154            return v
78155              .copy()
78156              .sub(this)
78157              .mag();
78158          };
78159
78160          /**
78161           * Normalize the vector to length 1 (make it a unit vector).
78162           *
78163           * @method normalize
78164           * @return {p5.Vector} normalized <a href="#/p5.Vector">p5.Vector</a>
78165           * @example
78166           * <div class="norender">
78167           * <code>
78168           * let v = createVector(10, 20, 2);
78169           * // v has components [10.0, 20.0, 2.0]
78170           * v.normalize();
78171           * // v's components are set to
78172           * // [0.4454354, 0.8908708, 0.089087084]
78173           * </code>
78174           * </div>
78175           * <div>
78176           * <code>
78177           * function draw() {
78178           *   background(240);
78179           *
78180           *   let v0 = createVector(50, 50);
78181           *   let v1 = createVector(mouseX - 50, mouseY - 50);
78182           *
78183           *   drawArrow(v0, v1, 'red');
78184           *   v1.normalize();
78185           *   drawArrow(v0, v1.mult(35), 'blue');
78186           *
78187           *   noFill();
78188           *   ellipse(50, 50, 35 * 2);
78189           * }
78190           *
78191           * // draw an arrow for a vector at a given base position
78192           * function drawArrow(base, vec, myColor) {
78193           *   push();
78194           *   stroke(myColor);
78195           *   strokeWeight(3);
78196           *   fill(myColor);
78197           *   translate(base.x, base.y);
78198           *   line(0, 0, vec.x, vec.y);
78199           *   rotate(vec.heading());
78200           *   let arrowSize = 7;
78201           *   translate(vec.mag() - arrowSize, 0);
78202           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78203           *   pop();
78204           * }
78205           * </code>
78206           * </div>
78207           */
78208          _main.default.Vector.prototype.normalize = function normalize() {
78209            var len = this.mag();
78210            // here we multiply by the reciprocal instead of calling 'div()'
78211            // since div duplicates this zero check.
78212            if (len !== 0) this.mult(1 / len);
78213            return this;
78214          };
78215
78216          /**
78217           * Limit the magnitude of this vector to the value used for the <b>max</b>
78218           * parameter.
78219           *
78220           * @method limit
78221           * @param  {Number}    max the maximum magnitude for the vector
78222           * @chainable
78223           * @example
78224           * <div class="norender">
78225           * <code>
78226           * let v = createVector(10, 20, 2);
78227           * // v has components [10.0, 20.0, 2.0]
78228           * v.limit(5);
78229           * // v's components are set to
78230           * // [2.2271771, 4.4543543, 0.4454354]
78231           * </code>
78232           * </div>
78233           * <div>
78234           * <code>
78235           * function draw() {
78236           *   background(240);
78237           *
78238           *   let v0 = createVector(50, 50);
78239           *   let v1 = createVector(mouseX - 50, mouseY - 50);
78240           *
78241           *   drawArrow(v0, v1, 'red');
78242           *   drawArrow(v0, v1.limit(35), 'blue');
78243           *
78244           *   noFill();
78245           *   ellipse(50, 50, 35 * 2);
78246           * }
78247           *
78248           * // draw an arrow for a vector at a given base position
78249           * function drawArrow(base, vec, myColor) {
78250           *   push();
78251           *   stroke(myColor);
78252           *   strokeWeight(3);
78253           *   fill(myColor);
78254           *   translate(base.x, base.y);
78255           *   line(0, 0, vec.x, vec.y);
78256           *   rotate(vec.heading());
78257           *   let arrowSize = 7;
78258           *   translate(vec.mag() - arrowSize, 0);
78259           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78260           *   pop();
78261           * }
78262           * </code>
78263           * </div>
78264           */
78265          _main.default.Vector.prototype.limit = function limit(max) {
78266            var mSq = this.magSq();
78267            if (mSq > max * max) {
78268              this.div(Math.sqrt(mSq)) //normalize it
78269                .mult(max);
78270            }
78271            return this;
78272          };
78273
78274          /**
78275           * Set the magnitude of this vector to the value used for the <b>len</b>
78276           * parameter.
78277           *
78278           * @method setMag
78279           * @param  {number}    len the new length for this vector
78280           * @chainable
78281           * @example
78282           * <div class="norender">
78283           * <code>
78284           * let v = createVector(10, 20, 2);
78285           * // v has components [10.0, 20.0, 2.0]
78286           * v.setMag(10);
78287           * // v's components are set to [6.0, 8.0, 0.0]
78288           * </code>
78289           * </div>
78290           *
78291           * <div>
78292           * <code>
78293           * function draw() {
78294           *   background(240);
78295           *
78296           *   let v0 = createVector(0, 0);
78297           *   let v1 = createVector(50, 50);
78298           *
78299           *   drawArrow(v0, v1, 'red');
78300           *
78301           *   let length = map(mouseX, 0, width, 0, 141, true);
78302           *   v1.setMag(length);
78303           *   drawArrow(v0, v1, 'blue');
78304           *
78305           *   noStroke();
78306           *   text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);
78307           * }
78308           *
78309           * // draw an arrow for a vector at a given base position
78310           * function drawArrow(base, vec, myColor) {
78311           *   push();
78312           *   stroke(myColor);
78313           *   strokeWeight(3);
78314           *   fill(myColor);
78315           *   translate(base.x, base.y);
78316           *   line(0, 0, vec.x, vec.y);
78317           *   rotate(vec.heading());
78318           *   let arrowSize = 7;
78319           *   translate(vec.mag() - arrowSize, 0);
78320           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78321           *   pop();
78322           * }
78323           * </code>
78324           * </div>
78325           */
78326          _main.default.Vector.prototype.setMag = function setMag(n) {
78327            return this.normalize().mult(n);
78328          };
78329
78330          /**
78331           * Calculate the angle of rotation for this vector(only 2D vectors).
78332           * p5.Vectors created using <a src="#/p5/createVector">createVector()</a>
78333           * will take the current <a = src="#/p5/angleMode">angleMode</a> into consideration, and give the angle
78334           * in radians or degree accordingly.
78335           *
78336           * @method heading
78337           * @return {Number} the angle of rotation
78338           * @example
78339           * <div class = "norender">
78340           * <code>
78341           * function setup() {
78342           *   let v1 = createVector(30, 50);
78343           *   print(v1.heading()); // 1.0303768265243125
78344           *
78345           *   v1 = createVector(40, 50);
78346           *   print(v1.heading());
78346 // 0.8960553845713439
78347           *
78348           *   v1 = createVector(30, 70);
78349           *   print(v1.heading()); // 1.1659045405098132
78350           * }
78351           * </code>
78352           * </div>
78353           *
78354           * <div>
78355           * <code>
78356           * function draw() {
78357           *   background(240);
78358           *
78359           *   let v0 = createVector(50, 50);
78360           *   let v1 = createVector(mouseX - 50, mouseY - 50);
78361           *
78362           *   drawArrow(v0, v1, 'black');
78363           *
78364           *   let myHeading = v1.heading();
78365           *   noStroke();
78366           *   text(
78367           *     'vector heading: ' +
78368           *       myHeading.toFixed(2) +
78369           *       ' radians or ' +
78370           *       degrees(myHeading).toFixed(2) +
78371           *       ' degrees',
78372           *     10,
78373           *     50,
78374           *     90,
78375           *     50
78376           *   );
78377           * }
78378           *
78379           * // draw an arrow for a vector at a given base position
78380           * function drawArrow(base, vec, myColor) {
78381           *   push();
78382           *   stroke(myColor);
78383           *   strokeWeight(3);
78384           *   fill(myColor);
78385           *   translate(base.x, base.y);
78386           *   line(0, 0, vec.x, vec.y);
78387           *   rotate(vec.heading());
78388           *   let arrowSize = 7;
78389           *   translate(vec.mag() - arrowSize, 0);
78390           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78391           *   pop();
78392           * }
78393           * </code>
78394           * </div>
78395           */
78396          _main.default.Vector.prototype.heading = function heading() {
78397            var h = Math.atan2(this.y, this.x);
78398            if (this.p5) return this.p5._fromRadians(h);
78399            return h;
78400          };
78401
78402          /**
78403           * Rotate the vector to a specific angle (only 2D vectors), magnitude remains the
78404           * same
78405           *
78406           * @method setHeading
78407           * @param  {number}    angle the angle of rotation
78408           * @chainable
78409           * @example
78410           * <div class="norender">
78411           * <code>
78412           * let v = createVector(10.0, 20.0);
78413           * // result of v.heading() is 1.1071487177940904
78414           * v.setHeading(Math.PI);
78415           * // result of v.heading() is now 3.141592653589793
78416           * </code>
78417           * </div>
78418           */
78419
78420          _main.default.Vector.prototype.setHeading = function setHeading(a) {
78421            var m = this.mag();
78422            this.x = m * Math.cos(a);
78423            this.y = m * Math.sin(a);
78424            return this;
78425          };
78426
78427          /**
78428           * Rotate the vector by an angle (only 2D vectors), magnitude remains the
78429           * same
78430           *
78431           * @method rotate
78432           * @param  {number}    angle the angle of rotation
78433           * @chainable
78434           * @example
78435           * <div class="norender">
78436           * <code>
78437           * let v = createVector(10.0, 20.0);
78438           * // v has components [10.0, 20.0, 0.0]
78439           * v.rotate(HALF_PI);
78440           * // v's components are set to [-20.0, 9.999999, 0.0]
78441           * </code>
78442           * </div>
78443           *
78444           * <div>
78445           * <code>
78446           * let angle = 0;
78447           * function draw() {
78448           *   background(240);
78449           *
78450           *   let v0 = createVector(50, 50);
78451           *   let v1 = createVector(50, 0);
78452           *
78453           *   drawArrow(v0, v1.rotate(angle), 'black');
78454           *   angle += 0.01;
78455           * }
78456           *
78457           * // draw an arrow for a vector at a given base position
78458           * function drawArrow(base, vec, myColor) {
78459           *   push();
78460           *   stroke(myColor);
78461           *   strokeWeight(3);
78462           *   fill(myColor);
78463           *   translate(base.x, base.y);
78464           *   line(0, 0, vec.x, vec.y);
78465           *   rotate(vec.heading());
78466           *   let arrowSize = 7;
78467           *   translate(vec.mag() - arrowSize, 0);
78468           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78469           *   pop();
78470           * }
78471           * </code>
78472           * </div>
78473           */
78474          _main.default.Vector.prototype.rotate = function rotate(a) {
78475            var newHeading = this.heading() + a;
78476            if (this.p5) newHeading = this.p5._toRadians(newHeading);
78477            var mag = this.mag();
78478            this.x = Math.cos(newHeading) * mag;
78479            this.y = Math.sin(newHeading) * mag;
78480            return this;
78481          };
78482
78483          /**
78484           * Calculates and returns the angle (in radians) between two vectors.
78485           * @method angleBetween
78486           * @param  {p5.Vector}    value the x, y, and z components of a <a href="#/p5.Vector">p5.Vector</a>
78487           * @return {Number}       the angle between (in radians)
78488           * @example
78489           * <div class="norender">
78490           * <code>
78491           * let v1 = createVector(1, 0, 0);
78492           * let v2 = createVector(0, 1, 0);
78493           *
78494           * let angle = v1.angleBetween(v2);
78495           * // angle is PI/2
78496           * print(angle);
78497           * </code>
78498           * </div>
78499           *
78500           * <div>
78501           * <code>
78502           * function draw() {
78503           *   background(240);
78504           *   let v0 = createVector(50, 50);
78505           *
78506           *   let v1 = createVector(50, 0);
78507           *   drawArrow(v0, v1, 'red');
78508           *
78509           *   let v2 = createVector(mouseX - 50, mouseY - 50);
78510           *   drawArrow(v0, v2, 'blue');
78511           *
78512           *   let angleBetween = v1.angleBetween(v2);
78513           *   noStroke();
78514           *   text(
78515           *     'angle between: ' +
78516           *       angleBetween.toFixed(2) +
78517           *       ' radians or ' +
78518           *       degrees(angleBetween).toFixed(2) +
78519           *       ' degrees',
78520           *     10,
78521           *     50,
78522           *     90,
78523           *     50
78524           *   );
78525           * }
78526           *
78527           * // draw an arrow for a vector at a given base position
78528           * function drawArrow(base, vec, myColor) {
78529           *   push();
78530           *   stroke(myColor);
78531           *   strokeWeight(3);
78532           *   fill(myColor);
78533           *   translate(base.x, base.y);
78534           *   line(0, 0, vec.x, vec.y);
78535           *   rotate(vec.heading());
78536           *   let arrowSize = 7;
78537           *   translate(vec.mag() - arrowSize, 0);
78538           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78539           *   pop();
78540           * }
78541           * </code>
78542           * </div>
78543           */
78544
78545          _main.default.Vector.prototype.angleBetween = function angleBetween(v) {
78546            var dotmagmag = this.dot(v) / (this.mag() * v.mag());
78547            // Mathematically speaking: the dotmagmag variable will be between -1 and 1
78548            // inclusive. Practically though it could be slightly outside this range due
78549            // to floating-point rounding issues. This can make Math.acos return NaN.
78550            //
78551            // Solution: we'll clamp the value to the -1,1 range
78552            var angle;
78553            angle = Math.acos(Math.min(1, Math.max(-1, dotmagmag)));
78554            angle = angle * Math.sign(this.cross(v).z || 1);
78555            if (this.p5) {
78556              angle = this.p5._fromRadians(angle);
78557            }
78558            return angle;
78559          };
78560          /**
78561           * Linear interpolate the vector to another vector
78562           *
78563           * @method lerp
78564           * @param  {Number}    x   the x component
78565           * @param  {Number}    y   the y component
78566           * @param  {Number}    z   the z component
78567           * @param  {Number}    amt the amount of interpolation; some value between 0.0
78568           *                         (old vector) and 1.0 (new vector). 0.9 is very near
78569           *                         the new vector. 0.5 is halfway in between.
78570           * @chainable
78571           *
78572           * @example
78573           * <div class="norender">
78574           * <code>
78575           * let v = createVector(1, 1, 0);
78576           *
78577           * v.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]
78578           * </code>
78579           * </div>
78580           *
78581           * <div class="norender">
78582           * <code>
78583           * let v1 = createVector(0, 0, 0);
78584           * let v2 = createVector(100, 100, 0);
78585           *
78586           * let v3 = p5.Vector.lerp(v1, v2, 0.5);
78587           * // v3 has components [50,50,0]
78588           * print(v3);
78589           * </code>
78590           * </div>
78591           *
78592           * <div>
78593           * <code>
78594           * let step = 0.01;
78595           * let amount = 0;
78596           *
78597           * function draw() {
78598           *   background(240);
78599           *   let v0 = createVector(0, 0);
78600           *
78601           *   let v1 = createVector(mouseX, mouseY);
78602           *   drawArrow(v0, v1, 'red');
78603           *
78604           *   let v2 = createVector(90, 90);
78605           *   drawArrow(v0, v2, 'blue');
78606           *
78607           *   if (amount > 1 || amount < 0) {
78608           *     step *= -1;
78609           *   }
78610           *   amount += step;
78611           *   let v3 = p5.Vector.lerp(v1, v2, amount);
78612           *
78613           *   drawArrow(v0, v3, 'purple');
78614           * }
78615           *
78616           * // draw an arrow for a vector at a given base position
78617           * function drawArrow(base, vec, myColor) {
78618           *   push();
78619           *   stroke(myColor);
78620           *   strokeWeight(3);
78621           *   fill(myColor);
78622           *   translate(base.x, base.y);
78623           *   line(0, 0, vec.x, vec.y);
78624           *   rotate(vec.heading());
78625           *   let arrowSize = 7;
78626           *   translate(vec.mag() - arrowSize, 0);
78627           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78628           *   pop();
78629           * }
78630           * </code>
78631           * </div>
78632           */
78633          /**
78634           * @method lerp
78635           * @param  {p5.Vector} v   the <a href="#/p5.Vector">p5.Vector</a> to lerp to
78636           * @param  {Number}    amt
78637           * @chainable
78638           */
78639          _main.default.Vector.prototype.lerp = function lerp(x, y, z, amt) {
78640            if (x instanceof _main.default.Vector) {
78641              return this.lerp(x.x, x.y, x.z, y);
78642            }
78643            this.x += (x - this.x) * amt || 0;
78644            this.y += (y - this.y) * amt || 0;
78645            this.z += (z - this.z) * amt || 0;
78646            return this;
78647          };
78648
78649          /**
78650           * Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D
78651           * This method acts on the vector directly
78652           *
78653           * @method reflect
78654           * @param  {p5.Vector} surfaceNormal   the <a href="#/p5.Vector">p5.Vector</a> to reflect about, will be normalized by this method
78655           * @chainable
78656           * @example
78657           * <div class="norender">
78658           * <code>
78659           * let v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward
78660           * let n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)
78661           * v.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]
78662           * </code>
78663           * </div>
78664           *
78665           * <div>
78666           * <code>
78667           * function draw() {
78668           *   background(240);
78669           *
78670           *   let v0 = createVector(0, 0);
78671           *   let v1 = createVector(mouseX, mouseY);
78672           *   drawArrow(v0, v1, 'red');
78673           *
78674           *   let n = createVector(0, -30);
78675           *   drawArrow(v1, n, 'blue');
78676           *
78677           *   let r = v1.copy();
78678           *   r.reflect(n);
78679           *   drawArrow(v1, r, 'purple');
78680           * }
78681           *
78682           * // draw an arrow for a vector at a given base position
78683           * function drawArrow(base, vec, myColor) {
78684           *   push();
78685           *   stroke(myColor);
78686           *   strokeWeight(3);
78687           *   fill(myColor);
78688           *   translate(base.x, base.y);
78689           *   line(0, 0, vec.x, vec.y);
78690           *   rotate(vec.heading());
78691           *   let arrowSize = 7;
78692           *   translate(vec.mag() - arrowSize, 0);
78693           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78694           *   pop();
78695           * }
78696           * </code>
78697           * </div>
78698           */
78699          _main.default.Vector.prototype.reflect = function reflect(surfaceNormal) {
78700            surfaceNormal.normalize();
78701            return this.sub(surfaceNormal.mult(2 * this.dot(surfaceNormal)));
78702          };
78703
78704          /**
78705           * Return a representation of this vector as a float array. This is only
78706           * for temporary use. If used in any other fashion, the contents should be
78707           * copied by using the <b>p5.Vector.<a href="#/p5.Vector/copy">copy()</a></b> method to copy into your own
78708           * array.
78709           *
78710           * @method array
78711           * @return {Number[]} an Array with the 3 values
78712           * @example
78713           * <div class = "norender">
78714           * <code>
78715           * function setup() {
78716           *   let v = createVector(20, 30);
78717           *   print(v.array()); // Prints : Array [20, 30, 0]
78718           * }
78719           * </code>
78720           * </div>
78721           *
78722           * <div class="norender">
78723           * <code>
78724           * let v = createVector(10.0, 20.0, 30.0);
78725           * let f = v.array();
78726           * print(f[0]); // Prints "10.0"
78727           * print(f[1]); // Prints "20.0"
78728           * print(f[2]); // Prints "30.0"
78729           * </code>
78730           * </div>
78731           */
78732          _main.default.Vector.prototype.array = function array() {
78733            return [this.x || 0, this.y || 0, this.z || 0];
78734          };
78735
78736          /**
78737           * Equality check against a <a href="#/p5.Vector">p5.Vector</a>
78738           *
78739           * @method equals
78740           * @param {Number} [x] the x component of the vector
78741           * @param {Number} [y] the y component of the vector
78742           * @param {Number} [z] the z component of the vector
78743           * @return {Boolean} whether the vectors are equals
78744           * @example
78745           * <div class = "norender">
78746           * <code>
78747           * let v1 = createVector(5, 10, 20);
78748           * let v2 = createVector(5, 10, 20);
78749           * let v3 = createVector(13, 10, 19);
78750           *
78751           * print(v1.equals(v2.x, v2.y, v2.z)); // true
78752           * print(v1.equals(v3.x, v3.y, v3.z)); // false
78753           * </code>
78754           * </div>
78755           *
78756           * <div class="norender">
78757           * <code>
78758           * let v1 = createVector(10.0, 20.0, 30.0);
78759           * let v2 = createVector(10.0, 20.0, 30.0);
78760           * let v3 = createVector(0.0, 0.0, 0.0);
78761           * print(v1.equals(v2)); // true
78762           * print(v1.equals(v3)); // false
78763           * </code>
78764           * </div>
78765           */
78766          /**
78767           * @method equals
78768           * @param {p5.Vector|Array} value the vector to compare
78769           * @return {Boolean}
78770           */
78771          _main.default.Vector.prototype.equals = function equals(x, y, z) {
78772            var a, b, c;
78773            if (x instanceof _main.default.Vector) {
78774              a = x.x || 0;
78775              b = x.y || 0;
78776              c = x.z || 0;
78777            } else if (x instanceof Array) {
78778              a = x[0] || 0;
78779              b = x[1] || 0;
78780              c = x[2] || 0;
78781            } else {
78782              a = x || 0;
78783              b = y || 0;
78784              c = z || 0;
78785            }
78786            return this.x === a && this.y === b && this.z === c;
78787          };
78788
78789          // Static Methods
78790
78791          /**
78792           * Make a new 2D vector from an angle
78793           *
78794           * @method fromAngle
78795           * @static
78796           * @param {Number}     angle the desired angle, in radians (unaffected by <a href="#/p5/angleMode">angleMode</a>)
78797           * @param {Number}     [length] the length of the new vector (defaults to 1)
78798           * @return {p5.Vector}       the new <a href="#/p5.Vector">p5.Vector</a> object
78799           * @example
78800           * <div>
78801           * <code>
78802           * function draw() {
78803           *   background(200);
78804           *
78805           *   // Create a variable, proportional to the mouseX,
78806           *   // varying from 0-360, to represent an angle in degrees.
78807           *   let myDegrees = map(mouseX, 0, width, 0, 360);
78808           *
78809           *   // Display that variable in an onscreen text.
78810           *   // (Note the nfc() function to truncate additional decimal places,
78811           *   // and the "\xB0" character for the degree symbol.)
78812           *   let readout = 'angle = ' + nfc(myDegrees, 1) + '\xB0';
78813           *   noStroke();
78814           *   fill(0);
78815           *   text(readout, 5, 15);
78816           *
78817           *   // Create a p5.Vector using the fromAngle function,
78818           *   // and extract its x and y components.
78819           *   let v = p5.Vector.fromAngle(radians(myDegrees), 30);
78820           *   let vx = v.x;
78821           *   let vy = v.y;
78822           *
78823           *   push();
78824           *   translate(width / 2, height / 2);
78825           *   noFill();
78826           *   stroke(150);
78827           *   line(0, 0, 30, 0);
78828           *   stroke(0);
78829           *   line(0, 0, vx, vy);
78830           *   pop();
78831           * }
78832           * </code>
78833           * </div>
78834           */
78835          _main.default.Vector.fromAngle = function fromAngle(angle, length) {
78836            if (typeof length === 'undefined') {
78837              length = 1;
78838            }
78839            return new _main.default.Vector(
78840              length * Math.cos(angle),
78841              length * Math.sin(angle),
78842              0
78843            );
78844          };
78845
78846          /**
78847           * Make a new 3D vector from a pair of ISO spherical angles
78848           *
78849           * @method fromAngles
78850           * @static
78851           * @param {Number}     theta    the polar angle, in radians (zero is up)
78852           * @param {Number}     phi      the azimuthal angle, in radians
78853           *                               (zero is out of the screen)
78854           * @param {Number}     [length] the length of the new vector (defaults to 1)
78855           * @return {p5.Vector}          the new <a href="#/p5.Vector">p5.Vector</a> object
78856           * @example
78857           * <div modernizr='webgl'>
78858           * <code>
78859           * function setup() {
78860           *   createCanvas(100, 100, WEBGL);
78861           *   fill(255);
78862           *   noStroke();
78863           * }
78864           * function draw() {
78865           *   background(255);
78866           *
78867           *   let t = millis() / 1000;
78868           *
78869           *   // add three point lights
78870           *   pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));
78871           *   pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));
78872           *   pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));
78873           *
78874           *   sphere(35);
78875           * }
78876           * </code>
78877           * </div>
78878           */
78879          _main.default.Vector.fromAngles = function(theta, phi, length) {
78880            if (typeof length === 'undefined') {
78881              length = 1;
78882            }
78883            var cosPhi = Math.cos(phi);
78884            var sinPhi = Math.sin(phi);
78885            var cosTheta = Math.cos(theta);
78886            var sinTheta = Math.sin(theta);
78887
78888            return new _main.default.Vector(
78889              length * sinTheta * sinPhi,
78890              -length * cosTheta,
78891              length * sinTheta * cosPhi
78892            );
78893          };
78894
78895          /**
78896           * Make a new 2D unit vector from a random angle
78897           *
78898           * @method random2D
78899           * @static
78900           * @return {p5.Vector} the new <a href="#/p5.Vector">p5.Vector</a> object
78901           * @example
78902           * <div class="norender">
78903           * <code>
78904           * let v = p5.Vector.random2D();
78905           * // May make v's attributes something like:
78906           * // [0.61554617, -0.51195765, 0.0] or
78907           * // [-0.4695841, -0.14366731, 0.0] or
78908           * // [0.6091097, -0.22805278, 0.0]
78909           * print(v);
78910           * </code>
78911           * </div>
78912           *
78913           * <div>
78914           * <code>
78915           * function setup() {
78916           *   frameRate(1);
78917           * }
78918           *
78919           * function draw() {
78920           *   background(240);
78921           *
78922           *   let v0 = createVector(50, 50);
78923           *   let v1 = p5.Vector.random2D();
78924           *   drawArrow(v0, v1.mult(50), 'black');
78925           * }
78926           *
78927           * // draw an arrow for a vector at a given base position
78928           * function drawArrow(base, vec, myColor) {
78929           *   push();
78930           *   stroke(myColor);
78931           *   strokeWeight(3);
78932           *   fill(myColor);
78933           *   translate(base.x, base.y);
78934           *   line(0, 0, vec.x, vec.y);
78935           *   rotate(vec.heading());
78936           *   let arrowSize = 7;
78937           *   translate(vec.mag() - arrowSize, 0);
78938           *   triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
78939           *   pop();
78940           * }
78941           * </code>
78942           * </div>
78943           */
78944          _main.default.Vector.random2D = function random2D() {
78945            return this.fromAngle(Math.random() * constants.TWO_PI);
78946          };
78947
78948          /**
78949           * Make a new random 3D unit vector.
78950           *
78951           * @method random3D
78952           * @static
78953           * @return {p5.Vector} the new <a href="#/p5.Vector">p5.Vector</a> object
78954           * @example
78955           * <div class="norender">
78956           * <code>
78957           * let v = p5.Vector.random3D();
78958           * // May make v's attributes something like:
78959           * // [0.61554617, -0.51195765, 0.599168] or
78960           * // [-0.4695841, -0.14366731, -0.8711202] or
78961           * // [0.6091097, -0.22805278, -0.7595902]
78962           * print(v);
78963           * </code>
78964           * </div>
78965           */
78966          _main.default.Vector.random3D = function random3D() {
78967            var angle = Math.random() * constants.TWO_PI;
78968            var vz = Math.random() * 2 - 1;
78969            var vzBase = Math.sqrt(1 - vz * vz);
78970            var vx = vzBase * Math.cos(angle);
78971            var vy = vzBase * Math.sin(angle);
78972            return new _main.default.Vector(vx, vy, vz);
78973          };
78974
78975          // Adds two vectors together and returns a new one.
78976          /**
78977           * @method add
78978           * @static
78979           * @param  {p5.Vector} v1 a <a href="#/p5.Vector">p5.Vector</a> to add
78980           * @param  {p5.Vector} v2 a <a href="#/p5.Vector">p5.Vector</a> to add
78981           * @param  {p5.Vector} [target] the vector to receive the result (Optional)
78982           * @return {p5.Vector} the resulting <a href="#/p5.Vector">p5.Vector</a>
78983           */
78984
78985          _main.default.Vector.add = function add(v1, v2, target) {
78986            if (!target) {
78987              target = v1.copy();
78988              if (arguments.length === 3) {
78989                _main.default._friendlyError(
78990                  'The target parameter is undefined, it should be of type p5.Vector',
78991                  'p5.Vector.add'
78992                );
78993              }
78994            } else {
78995              target.set(v1);
78996            }
78997            target.add(v2);
78998            return target;
78999          };
79000
79001          // Returns a vector remainder when it is divided by another vector
79002          /**
79003           * @method rem
79004           * @static
79005           * @param  {p5.Vector} v1 dividend <a href="#/p5.Vector">p5.Vector</a>
79006           * @param  {p5.Vector} v2 divisor <a href="#/p5.Vector">p5.Vector</a>
79007           */
79008          /**
79009           * @method rem
79010           * @static
79011           * @param  {p5.Vector} v1
79012           * @param  {p5.Vector} v2
79013           * @return {p5.Vector} the resulting <a href="#/p5.Vector">p5.Vector</a>
79014           */
79015          _main.default.Vector.rem = function rem(v1, v2) {
79016            if (v1 instanceof _main.default.Vector && v2 instanceof _main.default.Vector) {
79017              var target = v1.copy();
79018              target.rem(v2);
79019              return target;
79020            }
79021          };
79022
79023          /*
79024    * Subtracts one <a href="#/p5.Vector">p5.Vector</a> from another and returns a new one.  The second
79025    * vector (v2) is subtracted from the first (v1), resulting in v1-v2.
79026    */
79027          /**
79028           * @method sub
79029           * @static
79030           * @param  {p5.Vector} v1 a <a href="#/p5.Vector">p5.Vector</a> to subtract from
79031           * @param  {p5.Vector} v2 a <a href="#/p5.Vector">p5.Vector</a> to subtract
79032           * @param  {p5.Vector} [target] the vector to receive the result (Optional)
79033           * @return {p5.Vector} the resulting <a href="#/p5.Vector">p5.Vector</a>
79034           */
79035
79036          _main.default.Vector.sub = function sub(v1, v2, target) {
79037            if (!target) {
79038              target = v1.copy();
79039              if (arguments.length === 3) {
79040                _main.default._friendlyError(
79041                  'The target parameter is undefined, it should be of type p5.Vector',
79042                  'p5.Vector.sub'
79043                );
79044              }
79045            } else {
79046              target.set(v1);
79047            }
79048            target.sub(v2);
79049            return target;
79050          };
79051
79052          /**
79053           * Multiplies a vector by a scalar and returns a new vector.
79054           */
79055
79056          /**
79057           * @method mult
79058           * @static
79059           * @param  {Number} x
79060           * @param  {Number} y
79061           * @param  {Number} [z]
79062           * @return {p5.Vector} The resulting new <a href="#/p5.Vector">p5.Vector</a>
79063           */
79064
79065          /**
79066           * @method mult
79067           * @static
79068           * @param  {p5.Vector} v
79069           * @param  {Number}  n
79070           * @param  {p5.Vector} [target] the vector to receive the result (Optional)
79071           */
79072
79073          /**
79074           * @method mult
79075           * @static
79076           * @param  {p5.Vector} v0
79077           * @param  {p5.Vector} v1
79078           * @param  {p5.Vector} [target]
79079           */
79080
79081          /**
79082           * @method mult
79083           * @static
79084           * @param  {p5.Vector} v0
79085           * @param  {Number[]} arr
79086           * @param  {p5.Vector} [target]
79087           */
79088          _main.default.Vector.mult = function mult(v, n, target) {
79089            if (!target) {
79090              target = v.copy();
79091              if (arguments.length === 3) {
79092                _main.default._friendlyError(
79093                  'The target parameter is undefined, it should be of type p5.Vector',
79094                  'p5.Vector.mult'
79095                );
79096              }
79097            } else {
79098              target.set(v);
79099            }
79100            target.mult(n);
79101            return target;
79102          };
79103
79104          /**
79105           * Divides a vector by a scalar and returns a new vector.
79106           */
79107
79108          /**
79109           * @method div
79110           * @static
79111           * @param  {Number} x
79112           * @param  {Number} y
79113           * @param  {Number} [z]
79114           * @return {p5.Vector} The resulting new <a href="#/p5.Vector">p5.Vector</a>
79115           */
79116
79117          /**
79118           * @method div
79119           * @static
79120           * @param  {p5.Vector} v
79121           * @param  {Number}  n
79122           * @param  {p5.Vector} [target] the vector to receive the result (Optional)
79123           */
79124
79125          /**
79126           * @method div
79127           * @static
79128           * @param  {p5.Vector} v0
79129           * @param  {p5.Vector} v1
79130           * @param  {p5.Vector} [target]
79131           */
79132
79133          /**
79134           * @method div
79135           * @static
79136           * @param  {p5.Vector} v0
79137           * @param  {Number[]} arr
79138           * @param  {p5.Vector} [target]
79139           */
79140          _main.default.Vector.div = function div(v, n, target) {
79141            if (!target) {
79142              target = v.copy();
79143
79144              if (arguments.length === 3) {
79145                _main.default._friendlyError(
79146                  'The target parameter is undefined, it should be of type p5.Vector',
79147                  'p5.Vector.div'
79148                );
79149              }
79150            } else {
79151              target.set(v);
79152            }
79153            target.div(n);
79154            return target;
79155          };
79156
79157          /**
79158           * Calculates the dot product of two vectors.
79159           */
79160          /**
79161           * @method dot
79162           * @static
79163           * @param  {p5.Vector} v1 the first <a href="#/p5.Vector">p5.Vector</a>
79164           * @param  {p5.Vector} v2 the second <a href="#/p5.Vector">p5.Vector</a>
79165           * @return {Number}     the dot product
79166           */
79167          _main.default.Vector.dot = function dot(v1, v2) {
79168            return v1.dot(v2);
79169          };
79170
79171          /**
79172           * Calculates the cross product of two vectors.
79173           */
79174          /**
79175           * @method cross
79176           * @static
79177           * @param  {p5.Vector} v1 the first <a href="#/p5.Vector">p5.Vector</a>
79178           * @param  {p5.Vector} v2 the second <a href="#/p5.Vector">p5.Vector</a>
79179           * @return {Number}     the cross product
79180           */
79181          _main.default.Vector.cross = function cross(v1, v2) {
79182            return v1.cross(v2);
79183          };
79184
79185          /**
79186           * Calculates the Euclidean distance between two points (considering a
79187           * point as a vector object).
79188           */
79189          /**
79190           * @method dist
79191           * @static
79192           * @param  {p5.Vector} v1 the first <a href="#/p5.Vector">p5.Vector</a>
79193           * @param  {p5.Vector} v2 the second <a href="#/p5.Vector">p5.Vector</a>
79194           * @return {Number}     the distance
79195           */
79196          _main.default.Vector.dist = function dist(v1, v2) {
79197            return v1.dist(v2);
79198          };
79199
79200          /**
79201           * Linear interpolate a vector to another vector and return the result as a
79202           * new vector.
79203           */
79204          /**
79205           * @method lerp
79206           * @static
79207           * @param {p5.Vector} v1
79208           * @param {p5.Vector} v2
79209           * @param {Number} amt
79210           * @param {p5.Vector} [target] the vector to receive the result (Optional)
79211           * @return {p5.Vector}      the lerped value
79212           */
79213          _main.default.Vector.lerp = function lerp(v1, v2, amt, target) {
79214            if (!target) {
79215              target = v1.copy();
79216              if (arguments.length === 4) {
79217                _main.default._friendlyError(
79218                  'The target parameter is undefined, it should be of type p5.Vector',
79219                  'p5.Vector.lerp'
79220                );
79221              }
79222            } else {
79223              target.set(v1);
79224            }
79225            target.lerp(v2, amt);
79226            return target;
79227          };
79228
79229          /**
79230           * @method mag
79231           * @param {p5.Vector} vecT the vector to return the magnitude of
79232           * @return {Number}        the magnitude of vecT
79233           * @static
79234           */
79235          _main.default.Vector.mag = function mag(vecT) {
79236            var x = vecT.x,
79237              y = vecT.y,
79238              z = vecT.z;
79239            var magSq = x * x + y * y + z * z;
79240            return Math.sqrt(magSq);
79241          };
79242          var _default = _main.default.Vector;
79243          exports.default = _default;
79244        },
79245        { '../core/constants': 48, '../core/main': 59 }
79246      ],
79247      93: [
79248        function(_dereq_, module, exports) {
79249          'use strict';
79250          Object.defineProperty(exports, '__esModule', { value: true });
79251          exports.default = void 0;
79252
79253          var _main = _interopRequireDefault(_dereq_('../core/main'));
79254          function _interopRequireDefault(obj) {
79255            return obj && obj.__esModule ? obj : { default: obj };
79256          } /** // variables used for random number generators
79257           * @module Math
79258           * @submodule Random
79259           * @for p5
79260           * @requires core
79261           */
79262          var randomStateProp = '_lcg_random_state'; // Set to values from http://en.wikipedia.org/wiki/Numerical_Recipes
79263          // m is basically chosen to be large (as it is the max period)
79264          // and for its relationships to a and c
79265          var m = 4294967296; // a - 1 should be divisible by m's prime factors
79266          var a = 1664525; // c and m should be co-prime
79267          var c = 1013904223;
79268          var y2 = 0;
79269
79270          // Linear Congruential Generator that stores its state at instance[stateProperty]
79271          _main.default.prototype._lcg = function(stateProperty) {
79272            // define the recurrence relationship
79273            this[stateProperty] = (a * this[stateProperty] + c) % m;
79274            // return a float in [0, 1)
79275            // we've just used % m, so / m is always < 1
79276            return this[stateProperty] / m;
79277          };
79278
79279          _main.default.prototype._lcgSetSeed = function(stateProperty, val) {
79280            // pick a random seed if val is undefined or null
79281            // the >>> 0 casts the seed to an unsigned 32-bit integer
79282            this[stateProperty] = (val == null ? Math.random() * m : val) >>> 0;
79283          };
79284
79285          /**
79286           * Sets the seed value for <a href="#/p5/random">random()</a>.
79287           *
79288           * By default, <a href="#/p5/random">random()</a> produces different results each time the program
79289           * is run. Set the seed parameter to a constant to return the same
79290           * pseudo-random numbers each time the software is run.
79291           *
79292           * @method randomSeed
79293           * @param {Number} seed   the seed value
79294           * @example
79295           * <div>
79296           * <code>
79297           * randomSeed(99);
79298           * for (let i = 0; i < 100; i++) {
79299           *   let r = random(0, 255);
79300           *   stroke(r);
79301           *   line(i, 0, i, 100);
79302           * }
79303           * </code>
79304           * </div>
79305           *
79306           * @alt
79307           * many vertical lines drawn in white, black or grey.
79308           */
79309          _main.default.prototype.randomSeed = function(seed) {
79310            this._lcgSetSeed(randomStateProp, seed);
79311            this._gaussian_previous = false;
79312          };
79313
79314          /**
79315           * Return a random floating-point number.
79316           *
79317           * Takes either 0, 1 or 2 arguments.
79318           *
79319           * If no argument is given, returns a random number from 0
79320           * up to (but not including) 1.
79321           *
79322           * If one argument is given and it is a number, returns a random number from 0
79323           * up to (but not including) the number.
79324           *
79325           * If one argument is given and it is an array, returns a random element from
79326           * that array.
79327           *
79328           * If two arguments are given, returns a random number from the
79329           * first argument up to (but not including) the second argument.
79330           *
79331           * @method random
79332           * @param  {Number} [min]   the lower bound (inclusive)
79333           * @param  {Number} [max]   the upper bound (exclusive)
79334           * @return {Number} the random number
79335           * @example
79336           * <div>
79337           * <code>
79338           * for (let i = 0; i < 100; i++) {
79339           *   let r = random(50);
79340           *   stroke(r * 5);
79341           *   line(50, i, 50 + r, i);
79342           * }
79343           * </code>
79344           * </div>
79345           * <div>
79346           * <code>
79347           * for (let i = 0; i < 100; i++) {
79348           *   let r = random(-50, 50);
79349           *   line(50, i, 50 + r, i);
79350           * }
79351           * </code>
79352           * </div>
79353           * <div>
79354           * <code>
79355           * // Get a random element from an array using the random(Array) syntax
79356           * let words = ['apple', 'bear', 'cat', 'dog'];
79357           * let word = random(words); // select random word
79358           * text(word, 10, 50); // draw the word
79359           * </code>
79360           * </div>
79361           *
79362           * @alt
79363           * 100 horizontal lines from center canvas to right. size+fill change each time
79364           * 100 horizontal lines from center of canvas. height & side change each render
79365           * word displayed at random. Either apple, bear, cat, or dog
79366           */
79367          /**
79368           * @method random
79369           * @param  {Array} choices   the array to choose from
79370           * @return {*} the random element from the array
79371           * @example
79372           */
79373          _main.default.prototype.random = function(min, max) {
79374            _main.default._validateParameters('random', arguments);
79375            var rand;
79376
79377            if (this[randomStateProp] != null) {
79378              rand = this._lcg(randomStateProp);
79379            } else {
79380              rand = Math.random();
79381            }
79382            if (typeof min === 'undefined') {
79383              return rand;
79384            } else if (typeof max === 'undefined') {
79385              if (min instanceof Array) {
79386                return min[Math.floor(rand * min.length)];
79387              } else {
79388                return rand * min;
79389              }
79390            } else {
79391              if (min > max) {
79392                var tmp = min;
79393                min = max;
79394                max = tmp;
79395              }
79396
79397              return rand * (max - min) + min;
79398            }
79399          };
79400
79401          /**
79402           *
79403           * Returns a random number fitting a Gaussian, or
79404           * normal, distribution. There is theoretically no minimum or maximum
79405           * value that <a href="#/p5/randomGaussian">randomGaussian()</a> might return. Rather, there is
79406           * just a very low probability that values far from the mean will be
79407           * returned; and a higher probability that numbers near the mean will
79408           * be returned.
79409           *
79410           * Takes either 0, 1 or 2 arguments.<br>
79411           * If no args, returns a mean of 0 and standard deviation of 1.<br>
79412           * If one arg, that arg is the mean (standard deviation is 1).<br>
79413           * If two args, first is mean, second is standard deviation.
79414           *
79415           * @method randomGaussian
79416           * @param  {Number} [mean]  the mean
79417           * @param  {Number} [sd]    the standard deviation
79418           * @return {Number} the random number
79419           * @example
79420           * <div>
79421           * <code>
79422           * for (let y = 0; y < 100; y++) {
79423           *   let x = randomGaussian(50, 15);
79424           *   line(50, y, x, y);
79425           * }
79426           * </code>
79427           * </div>
79428           * <div>
79429           * <code>
79430           * let distribution = new Array(360);
79431           *
79432           * function setup() {
79433           *   createCanvas(100, 100);
79434           *   for (let i = 0; i < distribution.length; i++) {
79435           *     distribution[i] = floor(randomGaussian(0, 15));
79436           *   }
79437           * }
79438           *
79439           * function draw() {
79440           *   background(204);
79441           *
79442           *   translate(width / 2, width / 2);
79443           *
79444           *   for (let i = 0; i < distribution.length; i++) {
79445           *     rotate(TWO_PI / distribution.length);
79446           *     stroke(0);
79447           *     let dist = abs(distribution[i]);
79448           *     line(0, 0, dist, 0);
79449           *   }
79450           * }
79451           * </code>
79452           * </div>
79453           * @alt
79454           * 100 horizontal lines from center of canvas. height & side change each render
79455           * black lines radiate from center of canvas. size determined each render
79456           */
79457          _main.default.prototype.randomGaussian = function(mean) {
79458            var sd = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
79459            var y1, x1, x2, w;
79460            if (this._gaussian_previous) {
79461              y1 = y2;
79462              this._gaussian_previous = false;
79463            } else {
79464              do {
79465                x1 = this.random(2) - 1;
79466                x2 = this.random(2) - 1;
79467                w = x1 * x1 + x2 * x2;
79468              } while (w >= 1);
79469              w = Math.sqrt(-2 * Math.log(w) / w);
79470              y1 = x1 * w;
79471              y2 = x2 * w;
79472              this._gaussian_previous = true;
79473            }
79474
79475            var m = mean || 0;
79476            return y1 * sd + m;
79477          };
79478          var _default = _main.default;
79479          exports.default = _default;
79480        },
79481        { '../core/main': 59 }
79482      ],
79483      94: [
79484        function(_dereq_, module, exports) {
79485          'use strict';
79486          function _typeof(obj) {
79487            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
79488              _typeof = function _typeof(obj) {
79489                return typeof obj;
79490              };
79491            } else {
79492              _typeof = function _typeof(obj) {
79493                return obj &&
79494                  typeof Symbol === 'function' &&
79495                  obj.constructor === Symbol &&
79496                  obj !== Symbol.prototype
79497                  ? 'symbol'
79498                  : typeof obj;
79499              };
79500            }
79501            return _typeof(obj);
79502          }
79503          Object.defineProperty(exports, '__esModule', { value: true });
79504          exports.default = void 0;
79505
79506          var _main = _interopRequireDefault(_dereq_('../core/main'));
79507          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
79508          function _getRequireWildcardCache() {
79509            if (typeof WeakMap !== 'function') return null;
79510            var cache = new WeakMap();
79511            _getRequireWildcardCache = function _getRequireWildcardCache() {
79512              return cache;
79513            };
79514            return cache;
79515          }
79516          function _interopRequireWildcard(obj) {
79517            if (obj && obj.__esModule) {
79518              return obj;
79519            }
79520            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
79521              return { default: obj };
79522            }
79523            var cache = _getRequireWildcardCache();
79524            if (cache && cache.has(obj)) {
79525              return cache.get(obj);
79526            }
79527            var newObj = {};
79528            var hasPropertyDescriptor =
79529              Object.defineProperty && Object.getOwnPropertyDescriptor;
79530            for (var key in obj) {
79531              if (Object.prototype.hasOwnProperty.call(obj, key)) {
79532                var desc = hasPropertyDescriptor
79533                  ? Object.getOwnPropertyDescriptor(obj, key)
79534                  : null;
79535                if (desc && (desc.get || desc.set)) {
79536                  Object.defineProperty(newObj, key, desc);
79537                } else {
79538                  newObj[key] = obj[key];
79539                }
79540              }
79541            }
79542            newObj.default = obj;
79543            if (cache) {
79544              cache.set(obj, newObj);
79545            }
79546            return newObj;
79547          }
79548          function _interopRequireDefault(obj) {
79549            return obj && obj.__esModule ? obj : { default: obj };
79550          }
79551          /**
79552           * @module Math
79553           * @submodule Trigonometry
79554           * @for p5
79555           * @requires core
79556           * @requires constants
79557           */ /*
79558                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * all DEGREES/RADIANS conversion should be done in the p5 instance
79559                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * if possible, using the p5._toRadians(), p5._fromRadians() methods.
79560                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */ _main.default.prototype._angleMode =
79561            constants.RADIANS;
79562          /**
79563           * The inverse of <a href="#/p5/cos">cos()</a>, returns the arc cosine of a value.
79564           * This function expects the values in the range of -1 to 1 and values are returned in
79565           * the range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the
79566           * angle mode is DEGREES.
79567           *
79568           * @method acos
79569           * @param  {Number} value the value whose arc cosine is to be returned
79570           * @return {Number}       the arc cosine of the given value
79571           *
79572           * @example
79573           * <div class= “norender">
79574           * <code>
79575           * let a = PI;
79576           * let c = cos(a);
79577           * let ac = acos(c);
79578           * // Prints: "3.1415927 : -1.0 : 3.1415927"
79579           * print(a + ' : ' + c + ' : ' + ac);
79580           * </code>
79581           * </div>
79582           *
79583           * <div class= “norender">
79584           * <code>
79585           * let a = PI + PI / 4.0;
79586           * let c = cos(a);
79587           * let ac = acos(c);
79588           * // Prints: "3.926991 : -0.70710665 : 2.3561943"
79589           * print(a + ' : ' + c + ' : ' + ac);
79590           * </code>
79591           * </div>
79592           */ _main.default.prototype.acos = function(ratio) {
79593            return this._fromRadians(Math.acos(ratio));
79594          };
79595
79596          /**
79597           * The inverse of <a href="#/p5/sin">sin()</a>, returns the arc sine of a value.
79598           * This function expects the values in the range of -1 to 1 and values are returned
79599           * in the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle
79600           * mode is DEGREES.
79601           *
79602           * @method asin
79603           * @param  {Number} value the value whose arc sine is to be returned
79604           * @return {Number}       the arc sine of the given value
79605           *
79606           * @example
79607           * <div class= “norender">
79608           * <code>
79609           * let a = PI / 3.0;
79610           * let s = sin(a);
79611           * let as = asin(s);
79612           * // Prints: "1.0471975 : 0.86602540 : 1.0471975"
79613           * print(a + ' : ' + s + ' : ' + as);
79614           * </code>
79615           * </div>
79616           *
79617           * <div class= “norender">
79618           * <code>
79619           * let a = PI + PI / 3.0;
79620           * let s = sin(a);
79621           * let as = asin(s);
79622           * // Prints: "4.1887902 : -0.86602540 : -1.0471975"
79623           * print(a + ' : ' + s + ' : ' + as);
79624           * </code>
79625           * </div>
79626           */
79627          _main.default.prototype.asin = function(ratio) {
79628            return this._fromRadians(Math.asin(ratio));
79629          };
79630
79631          /**
79632           * The inverse of <a href="#/p5/tan">tan()</a>, returns the arc tangent of a value.
79633           * This function expects the values in the range of -Infinity to Infinity (exclusive) and
79634           * values are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or
79635           * -90 to 90 if the angle mode is DEGREES.
79636           *
79637           * @method atan
79638           * @param  {Number} value the value whose arc tangent is to be returned
79639           * @return {Number}       the arc tangent of the given value
79640           *
79641           * @example
79642           * <div class= “norender">
79643           * <code>
79644           * let a = PI / 3.0;
79645           * let t = tan(a);
79646           * let at = atan(t);
79647           * // Prints: "1.0471975 : 1.7320508 : 1.0471975"
79648           * print(a + ' : ' + t + ' : ' + at);
79649           * </code>
79650           * </div>
79651           *
79652           * <div class= “norender">
79653           * <code>
79654           * let a = PI + PI / 3.0;
79655           * let t = tan(a);
79656           * let at = atan(t);
79657           * // Prints: "4.1887902 : 1.7320508 : 1.0471975"
79658           * print(a + ' : ' + t + ' : ' + at);
79659           * </code>
79660           * </div>
79661           */
79662          _main.default.prototype.atan = function(ratio) {
79663            return this._fromRadians(Math.atan(ratio));
79664          };
79665
79666          /**
79667           * Calculates the angle (in radians) from a specified point to the coordinate
79668           * origin as measured from the positive x-axis. Values are returned as a
79669           * float in the range from PI to -PI if the angleMode is RADIANS or 180 to
79670           * -180 if the angleMode is DEGREES. The atan2<a href="#/p5/">()</a> function is
79671           * most often used for orienting geometry to the position of the cursor.
79672           *
79673           * Note: The y-coordinate of the point is the first parameter, and the
79674           * x-coordinate is the second parameter, due the the structure of calculating
79675           * the tangent.
79676           *
79677           * @method atan2
79678           * @param  {Number} y y-coordinate of the point
79679           * @param  {Number} x x-coordinate of the point
79680           * @return {Number}   the arc tangent of the given point
79681           *
79682           * @example
79683           * <div>
79684           * <code>
79685           * function draw() {
79686           *   background(204);
79687           *   translate(width / 2, height / 2);
79688           *   let a = atan2(mouseY - height / 2, mouseX - width / 2);
79689           *   rotate(a);
79690           *   rect(-30, -5, 60, 10);
79691           * }
79692           * </code>
79693           * </div>
79694           *
79695           * @alt
79696           * 60 by 10 rect at center of canvas rotates with mouse movements
79697           */
79698          _main.default.prototype.atan2 = function(y, x) {
79699            return this._fromRadians(Math.atan2(y, x));
79700          };
79701
79702          /**
79703           * Calculates the cosine of an angle. This function takes into account the
79704           * current <a href="#/p5/angleMode">angleMode</a>. Values are returned in the range -1 to 1.
79705           *
79706           * @method cos
79707           * @param  {Number} angle the angle
79708           * @return {Number}       the cosine of the angle
79709           *
79710           * @example
79711           * <div>
79712           * <code>
79713           * let a = 0.0;
79714           * let inc = TWO_PI / 25.0;
79715           * for (let i = 0; i < 25; i++) {
79716           *   line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);
79717           *   a = a + inc;
79718           * }
79719           * </code>
79720           * </div>
79721           *
79722           * @alt
79723           * vertical black lines form wave patterns, extend-down on left and right side
79724           */
79725          _main.default.prototype.cos = function(angle) {
79726            return Math.cos(this._toRadians(angle));
79727          };
79728
79729          /**
79730           * Calculates the sine of an angle. This function takes into account the
79731           * current <a href="#/p5/angleMode">angleMode</a>. Values are returned in the range -1 to 1.
79732           *
79733           * @method sin
79734           * @param  {Number} angle the angle
79735           * @return {Number}       the sine of the angle
79736           *
79737           * @example
79738           * <div>
79739           * <code>
79740           * let a = 0.0;
79741           * let inc = TWO_PI / 25.0;
79742           * for (let i = 0; i < 25; i++) {
79743           *   line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);
79744           *   a = a + inc;
79745           * }
79746           * </code>
79747           * </div>
79748           *
79749           * @alt
79750           * vertical black lines extend down and up from center to form wave pattern
79751           */
79752          _main.default.prototype.sin = function(angle) {
79753            return Math.sin(this._toRadians(angle));
79754          };
79755
79756          /**
79757           * Calculates the tangent of an angle. This function takes into account
79758           * the current <a href="#/p5/angleMode">angleMode</a>. Values are returned in the range of all real numbers.
79759           *
79760           * @method tan
79761           * @param  {Number} angle the angle
79762           * @return {Number}       the tangent of the angle
79763           *
79764           * @example
79765           * <div>
79766           * <code>
79767           * let a = 0.0;
79768           * let inc = TWO_PI / 50.0;
79769           * for (let i = 0; i < 100; i = i + 2) {
79770           *   line(i, 50, i, 50 + tan(a) * 2.0);
79771           *   a = a + inc;
79772           * }
79773           * </code>
79774           *
79775           * @alt
79776           * vertical black lines end down and up from center to form spike pattern
79777           */
79778          _main.default.prototype.tan = function(angle) {
79779            return Math.tan(this._toRadians(angle));
79780          };
79781
79782          /**
79783           * Converts a radian measurement to its corresponding value in degrees.
79784           * Radians and degrees are two ways of measuring the same thing. There are
79785           * 360 degrees in a circle and 2*PI radians in a circle. For example,
79786           * 90° = PI/2 = 1.5707964. This function does not take into account the
79787           * current <a href="#/p5/angleMode">angleMode</a>.
79788           *
79789           * @method degrees
79790           * @param  {Number} radians the radians value to convert to degrees
79791           * @return {Number}         the converted angle
79792           *
79793           * @example
79794           * <div class= “norender">
79795           * <code>
79796           * let rad = PI / 4;
79797           * let deg = degrees(rad);
79798           * print(rad + ' radians is ' + deg + ' degrees');
79799           * // Prints: 0.7853981633974483 radians is 45 degrees
79800           * </code>
79801           * </div>
79802           */
79803          _main.default.prototype.degrees = function(angle) {
79804            return angle * constants.RAD_TO_DEG;
79805          };
79806
79807          /**
79808           * Converts a degree measurement to its corresponding value in radians.
79809           * Radians and degrees are two ways of measuring the same thing. There are
79810           * 360 degrees in a circle and 2*PI radians in a circle. For example,
79811           * 90° = PI/2 = 1.5707964. This function does not take into account the
79812           * current <a href="#/p5/angleMode">angleMode</a>.
79813           *
79814           * @method radians
79815           * @param  {Number} degrees the degree value to convert to radians
79816           * @return {Number}         the converted angle
79817           *
79818           * @example
79819           * <div class= “norender">
79820           * <code>
79821           * let deg = 45.0;
79822           * let rad = radians(deg);
79823           * print(deg + ' degrees is ' + rad + ' radians');
79824           * // Prints: 45 degrees is 0.7853981633974483 radians
79825           * </code>
79826           * </div>
79827           */
79828          _main.default.prototype.radians = function(angle) {
79829            return angle * constants.DEG_TO_RAD;
79830          };
79831
79832          /**
79833           * Sets the current mode of p5 to given mode. Default mode is RADIANS.
79834           *
79835           * @method angleMode
79836           * @param {Constant} mode either RADIANS or DEGREES
79837           *
79838           * @example
79839           * <div>
79840           * <code>
79841           * function draw() {
79842           *   background(204);
79843           *   angleMode(DEGREES); // Change the mode to DEGREES
79844           *   let a = atan2(mouseY - height / 2, mouseX - width / 2);
79845           *   translate(width / 2, height / 2);
79846           *   push();
79847           *   rotate(a);
79848           *   rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees
79849           *   pop();
79850           *   angleMode(RADIANS); // Change the mode to RADIANS
79851           *   rotate(a); // variable a stays the same
79852           *   rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians
79853           * }
79854           * </code>
79855           * </div>
79856           *
79857           * @alt
79858           * 40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.
79859           *
79860           */
79861          _main.default.prototype.angleMode = function(mode) {
79862            if (mode === constants.DEGREES || mode === constants.RADIANS) {
79863              this._angleMode = mode;
79864            }
79865          };
79866
79867          /**
79868           * converts angles from the current angleMode to RADIANS
79869           *
79870           * @method _toRadians
79871           * @private
79872           * @param {Number} angle
79873           * @returns {Number}
79874           */
79875          _main.default.prototype._toRadians = function(angle) {
79876            if (this._angleMode === constants.DEGREES) {
79877              return angle * constants.DEG_TO_RAD;
79878            }
79879            return angle;
79880          };
79881
79882          /**
79883           * converts angles from the current angleMode to DEGREES
79884           *
79885           * @method _toDegrees
79886           * @private
79887           * @param {Number} angle
79888           * @returns {Number}
79889           */
79890          _main.default.prototype._toDegrees = function(angle) {
79891            if (this._angleMode === constants.RADIANS) {
79892              return angle * constants.RAD_TO_DEG;
79893            }
79894            return angle;
79895          };
79896
79897          /**
79898           * converts angles from RADIANS into the current angleMode
79899           *
79900           * @method _fromRadians
79901           * @private
79902           * @param {Number} angle
79903           * @returns {Number}
79904           */
79905          _main.default.prototype._fromRadians = function(angle) {
79906            if (this._angleMode === constants.DEGREES) {
79907              return angle * constants.RAD_TO_DEG;
79908            }
79909            return angle;
79910          };
79911          var _default = _main.default;
79912          exports.default = _default;
79913        },
79914        { '../core/constants': 48, '../core/main': 59 }
79915      ],
79916      95: [
79917        function(_dereq_, module, exports) {
79918          'use strict';
79919          Object.defineProperty(exports, '__esModule', { value: true });
79920          exports.default = void 0;
79921
79922          var _main = _interopRequireDefault(_dereq_('../core/main'));
79923          function _interopRequireDefault(obj) {
79924            return obj && obj.__esModule ? obj : { default: obj };
79925          }
79926          /**
79927           * @module Typography
79928           * @submodule Attributes
79929           * @for p5
79930           * @requires core
79931           * @requires constants
79932           */ /**
79933           * Sets the current alignment for drawing text. Accepts two
79934           * arguments: horizAlign (LEFT, CENTER, or RIGHT) and
79935           * vertAlign (TOP, BOTTOM, CENTER, or BASELINE).
79936           *
79937           * The horizAlign parameter is in reference to the x value
79938           * of the <a href="#/p5/text">text()</a> function, while the vertAlign parameter
79939           * is in reference to the y value.
79940           *
79941           * So if you write textAlign(LEFT), you are aligning the left
79942           * edge of your text to the x value you give in <a href="#/p5/text">text()</a>.
79943           * If you write textAlign(RIGHT, TOP), you are aligning the right edge
79944           * of your text to the x value and the top of edge of the text
79945           * to the y value.
79946           *
79947           * @method textAlign
79948           * @param {Constant} horizAlign horizontal alignment, either LEFT,
79949           *                            CENTER, or RIGHT
79950           * @param {Constant} [vertAlign] vertical alignment, either TOP,
79951           *                            BOTTOM, CENTER, or BASELINE
79952           * @chainable
79953           * @example
79954           * <div>
79955           * <code>
79956           * textSize(16);
79957           * textAlign(RIGHT);
79958           * text('ABCD', 50, 30);
79959           * textAlign(CENTER);
79960           * text('EFGH', 50, 50);
79961           * textAlign(LEFT);
79962           * text('IJKL', 50, 70);
79963           * </code>
79964           * </div>
79965           *
79966           * <div>
79967           * <code>
79968           * textSize(16);
79969           * strokeWeight(0.5);
79970           *
79971           * line(0, 12, width, 12);
79972           * textAlign(CENTER, TOP);
79973           * text('TOP', 0, 12, width);
79974           *
79975           * line(0, 37, width, 37);
79976           * textAlign(CENTER, CENTER);
79977           * text('CENTER', 0, 37, width);
79978           *
79979           * line(0, 62, width, 62);
79980           * textAlign(CENTER, BASELINE);
79981           * text('BASELINE', 0, 62, width);
79982           *
79983           * line(0, 87, width, 87);
79984           * textAlign(CENTER, BOTTOM);
79985           * text('BOTTOM', 0, 87, width);
79986           * </code>
79987           * </div>
79988           *
79989           * @alt
79990           * Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.
79991           * The names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.
79992           */ /**
79993           * @method textAlign
79994           * @return {Object}
79995           */ _main.default.prototype.textAlign = function(horizAlign, vertAlign) {
79996            var _this$_renderer;
79997            _main.default._validateParameters('textAlign', arguments);
79998            return (_this$_renderer = this._renderer).textAlign.apply(
79999              _this$_renderer,
80000              arguments
80001            );
80002          };
80003
80004          /**
80005           * Sets/gets the spacing, in pixels, between lines of text. This setting will be
80006           * used in all subsequent calls to the <a href="#/p5/text">text()</a> function.
80007           *
80008           * @method textLeading
80009           * @param {Number} leading the size in pixels for spacing between lines
80010           * @chainable
80011           *
80012           * @example
80013           * <div>
80014           * <code>
80015           * let lines = 'L1\nL2\nL3'; // "\n" is a "new line" character
80016           * textSize(12);
80017           *
80018           * textLeading(10);
80019           * text(lines, 10, 25);
80020           *
80021           * textLeading(20);
80022           * text(lines, 40, 25);
80023           *
80024           * textLeading(30);
80025           * text(lines, 70, 25);
80026           * </code>
80027           * </div>
80028           *
80029           * @alt
80030           * A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set
80031           */
80032          /**
80033           * @method textLeading
80034           * @return {Number}
80035           */
80036          _main.default.prototype.textLeading = function(theLeading) {
80037            var _this$_renderer2;
80038            _main.default._validateParameters('textLeading', arguments);
80039            return (_this$_renderer2 = this._renderer).textLeading.apply(
80040              _this$_renderer2,
80041              arguments
80042            );
80043          };
80044
80045          /**
80046           * Sets/gets the current font size. This size will be used in all subsequent
80047           * calls to the <a href="#/p5/text">text()</a> function. Font size is measured in pixels.
80048           *
80049           * @method textSize
80050           * @param {Number} theSize the size of the letters in units of pixels
80051           * @chainable
80052           *
80053           * @example
80054           * <div>
80055           * <code>
80056           * textSize(12);
80057           * text('Font Size 12', 10, 30);
80058           * textSize(14);
80059           * text('Font Size 14', 10, 60);
80060           * textSize(16);
80061           * text('Font Size 16', 10, 90);
80062           * </code>
80063           * </div>
80064           *
80065           * @alt
80066           * 'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large
80067           */
80068          /**
80069           * @method textSize
80070           * @return {Number}
80071           */
80072          _main.default.prototype.textSize = function(theSize) {
80073            var _this$_renderer3;
80074            _main.default._validateParameters('textSize', arguments);
80075            return (_this$_renderer3 = this._renderer).textSize.apply(
80076              _this$_renderer3,
80077              arguments
80078            );
80079          };
80080
80081          /**
80082           * Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.
80083           * Note: this may be is overridden by CSS styling. For non-system fonts
80084           * (opentype, truetype, etc.) please load styled fonts instead.
80085           *
80086           * @method textStyle
80087           * @param {Constant} theStyle styling for text, either NORMAL,
80088           *                            ITALIC, BOLD or BOLDITALIC
80089           * @chainable
80090           * @example
80091           * <div>
80092           * <code>
80093           * strokeWeight(0);
80094           * textSize(12);
80095           * textStyle(NORMAL);
80096           * text('Font Style Normal', 10, 15);
80097           * textStyle(ITALIC);
80098           * text('Font Style Italic', 10, 40);
80099           * textStyle(BOLD);
80100           * text('Font Style Bold', 10, 65);
80101           * textStyle(BOLDITALIC);
80102           * text('Font Style Bold Italic', 10, 90);
80103           * </code>
80104           * </div>
80105           *
80106           * @alt
80107           * Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.
80108           */
80109          /**
80110           * @method textStyle
80111           * @return {String}
80112           */
80113          _main.default.prototype.textStyle = function(theStyle) {
80114            var _this$_renderer4;
80115            _main.default._validateParameters('textStyle', arguments);
80116            return (_this$_renderer4 = this._renderer).textStyle.apply(
80117              _this$_renderer4,
80118              arguments
80119            );
80120          };
80121
80122          /**
80123           * Calculates and returns the width of any character or text str
80123ing.
80124           *
80125           * @method textWidth
80126           * @param {String} theText the String of characters to measure
80127           * @return {Number} the calculated width
80128           * @example
80129           * <div>
80130           * <code>
80131           * textSize(28);
80132           *
80133           * let aChar = 'P';
80134           * let cWidth = textWidth(aChar);
80135           * text(aChar, 0, 40);
80136           * line(cWidth, 0, cWidth, 50);
80137           *
80138           * let aString = 'p5.js';
80139           * let sWidth = textWidth(aString);
80140           * text(aString, 0, 85);
80141           * line(sWidth, 50, sWidth, 100);
80142           * </code>
80143           * </div>
80144           *
80145           * @alt
80146           * Letter P and p5.js are displayed with vertical lines at end.
80147           */
80148          _main.default.prototype.textWidth = function() {
80149            var _this$_renderer5;
80150            for (
80151              var _len = arguments.length, args = new Array(_len), _key = 0;
80152              _key < _len;
80153              _key++
80154            ) {
80155              args[_key] = arguments[_key];
80156            }
80157            args[0] += '';
80158            _main.default._validateParameters('textWidth', args);
80159            if (args[0].length === 0) {
80160              return 0;
80161            }
80162            return (_this$_renderer5 = this._renderer).textWidth.apply(
80163              _this$_renderer5,
80164              args
80165            );
80166          };
80167
80168          /**
80169           * Returns the ascent of the current font at its current size. The ascent
80170           * represents the distance, in pixels, of the tallest character above
80171           * the baseline.
80172           * @method textAscent
80173           * @return {Number}
80174           * @example
80175           * <div>
80176           * <code>
80177           * let base = height * 0.75;
80178           * let scalar = 0.8; // Different for each font
80179           *
80180           * textSize(32); // Set initial text size
80181           * let asc = textAscent() * scalar; // Calc ascent
80182           * line(0, base - asc, width, base - asc);
80183           * text('dp', 0, base); // Draw text on baseline
80184           *
80185           * textSize(64); // Increase text size
80186           * asc = textAscent() * scalar; // Recalc ascent
80187           * line(40, base - asc, width, base - asc);
80188           * text('dp', 40, base); // Draw text on baseline
80189           * </code>
80190           * </div>
80191           */
80192          _main.default.prototype.textAscent = function() {
80193            for (
80194              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
80195              _key2 < _len2;
80196              _key2++
80197            ) {
80198              args[_key2] = arguments[_key2];
80199            }
80200            _main.default._validateParameters('textAscent', args);
80201            return this._renderer.textAscent();
80202          };
80203
80204          /**
80205           * Returns the descent of the current font at its current size. The descent
80206           * represents the distance, in pixels, of the character with the longest
80207           * descender below the baseline.
80208           * @method textDescent
80209           * @return {Number}
80210           * @example
80211           * <div>
80212           * <code>
80213           * let base = height * 0.75;
80214           * let scalar = 0.8; // Different for each font
80215           *
80216           * textSize(32); // Set initial text size
80217           * let desc = textDescent() * scalar; // Calc ascent
80218           * line(0, base + desc, width, base + desc);
80219           * text('dp', 0, base); // Draw text on baseline
80220           *
80221           * textSize(64); // Increase text size
80222           * desc = textDescent() * scalar; // Recalc ascent
80223           * line(40, base + desc, width, base + desc);
80224           * text('dp', 40, base); // Draw text on baseline
80225           * </code>
80226           * </div>
80227           */
80228          _main.default.prototype.textDescent = function() {
80229            for (
80230              var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;
80231              _key3 < _len3;
80232              _key3++
80233            ) {
80234              args[_key3] = arguments[_key3];
80235            }
80236            _main.default._validateParameters('textDescent', args);
80237            return this._renderer.textDescent();
80238          };
80239
80240          /**
80241           * Helper function to measure ascent and descent.
80242           */
80243          _main.default.prototype._updateTextMetrics = function() {
80244            return this._renderer._updateTextMetrics();
80245          };
80246          var _default = _main.default;
80247          exports.default = _default;
80248        },
80249        { '../core/main': 59 }
80250      ],
80251      96: [
80252        function(_dereq_, module, exports) {
80253          'use strict';
80254          function _typeof(obj) {
80255            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
80256              _typeof = function _typeof(obj) {
80257                return typeof obj;
80258              };
80259            } else {
80260              _typeof = function _typeof(obj) {
80261                return obj &&
80262                  typeof Symbol === 'function' &&
80263                  obj.constructor === Symbol &&
80264                  obj !== Symbol.prototype
80265                  ? 'symbol'
80266                  : typeof obj;
80267              };
80268            }
80269            return _typeof(obj);
80270          }
80271          Object.defineProperty(exports, '__esModule', { value: true });
80272          exports.default = void 0;
80273
80274          var _main = _interopRequireDefault(_dereq_('../core/main'));
80275          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
80276          var opentype = _interopRequireWildcard(_dereq_('opentype.js'));
80277
80278          _dereq_('../core/friendly_errors/validate_params');
80279          _dereq_('../core/friendly_errors/file_errors');
80280          _dereq_('../core/friendly_errors/fes_core');
80281          function _getRequireWildcardCache() {
80282            if (typeof WeakMap !== 'function') return null;
80283            var cache = new WeakMap();
80284            _getRequireWildcardCache = function _getRequireWildcardCache() {
80285              return cache;
80286            };
80287            return cache;
80288          }
80289          function _interopRequireWildcard(obj) {
80290            if (obj && obj.__esModule) {
80291              return obj;
80292            }
80293            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
80294              return { default: obj };
80295            }
80296            var cache = _getRequireWildcardCache();
80297            if (cache && cache.has(obj)) {
80298              return cache.get(obj);
80299            }
80300            var newObj = {};
80301            var hasPropertyDescriptor =
80302              Object.defineProperty && Object.getOwnPropertyDescriptor;
80303            for (var key in obj) {
80304              if (Object.prototype.hasOwnProperty.call(obj, key)) {
80305                var desc = hasPropertyDescriptor
80306                  ? Object.getOwnPropertyDescriptor(obj, key)
80307                  : null;
80308                if (desc && (desc.get || desc.set)) {
80309                  Object.defineProperty(newObj, key, desc);
80310                } else {
80311                  newObj[key] = obj[key];
80312                }
80313              }
80314            }
80315            newObj.default = obj;
80316            if (cache) {
80317              cache.set(obj, newObj);
80318            }
80319            return newObj;
80320          }
80321          function _interopRequireDefault(obj) {
80322            return obj && obj.__esModule ? obj : { default: obj };
80323          }
80324          /**
80325           * @module Typography
80326           * @submodule Loading & Displaying
80327           * @for p5
80328           * @requires core
80329           */ /**
80330           * Loads an opentype font file (.otf, .ttf) from a file or a URL,
80331           * and returns a PFont Object. This method is asynchronous,
80332           * meaning it may not finish before the next line in your sketch
80333           * is executed.
80334           *
80335           * The path to the font should be relative to the HTML file
80336           * that links in your sketch. Loading fonts from a URL or other
80337           * remote location may be blocked due to your browser's built-in
80338           * security.
80339           *
80340           * @method loadFont
80341           * @param  {String}        path       name of the file or url to load
80342           * @param  {Function}      [callback] function to be executed after
80343           *                                    <a href="#/p5/loadFont">loadFont()</a> completes
80344           * @param  {Function}      [onError]  function to be executed if
80345           *                                    an error occurs
80346           * @return {p5.Font}                  <a href="#/p5.Font">p5.Font</a> object
80347           * @example
80348           *
80349           * Calling loadFont() inside <a href="#/p5/preload">preload()</a> guarantees
80350           * that the load operation will have completed before <a href="#/p5/setup">setup()</a>
80351           * and <a href="#/p5/draw">draw()</a> are called.
80352           *
80353           * <div><code>
80354           * let myFont;
80355           * function preload() {
80356           *   myFont = loadFont('assets/inconsolata.otf');
80357           * }
80358           *
80359           * function setup() {
80360           *   fill('#ED225D');
80361           *   textFont(myFont);
80362           *   textSize(36);
80363           *   text('p5*js', 10, 50);
80364           * }
80365           * </code></div>
80366           *
80367           * Outside of <a href="#/p5/preload">preload()</a>, you may supply a
80368           * callback function to handle the object:
80369           *
80370           * <div><code>
80371           * function setup() {
80372           *   loadFont('assets/inconsolata.otf', drawText);
80373           * }
80374           *
80375           * function drawText(font) {
80376           *   fill('#ED225D');
80377           *   textFont(font, 36);
80378           *   text('p5*js', 10, 50);
80379           * }
80380           * </code></div>
80381           *
80382           * You can also use the font filename string (without the file extension) to
80383           * style other HTML elements.
80384           *
80385           * <div><code>
80386           * function preload() {
80387           *   loadFont('assets/inconsolata.otf');
80388           * }
80389           *
80390           * function setup() {
80391           *   let myDiv = createDiv('hello there');
80392           *   myDiv.style('font-family', 'Inconsolata');
80393           * }
80394           * </code></div>
80395           *
80396           * @alt
80397           * p5*js in p5's theme dark pink
80398           * p5*js in p5's theme dark pink
80399           */ _main.default.prototype.loadFont = function(path, onSuccess, onError) {
80400            _main.default._validateParameters('loadFont', arguments);
80401            var p5Font = new _main.default.Font(this);
80402
80403            var self = this;
80404            opentype.load(path, function(err, font) {
80405              if (err) {
80406                _main.default._friendlyFileLoadError(4, path);
80407                if (typeof onError !== 'undefined') {
80408                  return onError(err);
80409                }
80410                console.error(err, path);
80411                return;
80412              }
80413
80414              p5Font.font = font;
80415
80416              if (typeof onSuccess !== 'undefined') {
80417                onSuccess(p5Font);
80418              }
80419
80420              self._decrementPreload();
80421
80422              // check that we have an acceptable font type
80423              var validFontTypes = ['ttf', 'otf', 'woff', 'woff2'];
80424
80425              var fileNoPath = path
80426                .split('\\')
80427                .pop()
80428                .split('/')
80429                .pop();
80430
80431              var lastDotIdx = fileNoPath.lastIndexOf('.');
80432              var fontFamily;
80433              var newStyle;
80434              var fileExt = lastDotIdx < 1 ? null : fileNoPath.substr(lastDotIdx + 1);
80435
80436              // if so, add it to the DOM (name-only) for use with DOM module
80437              if (validFontTypes.includes(fileExt)) {
80438                fontFamily = fileNoPath.substr(0, lastDotIdx);
80439                newStyle = document.createElement('style');
80440                newStyle.appendChild(
80441                  document.createTextNode(
80442                    '\n@font-face {\nfont-family: '
80443                      .concat(fontFamily, ';\nsrc: url(')
80444                      .concat(path, ');\n}\n')
80445                  )
80446                );
80447
80448                document.head.appendChild(newStyle);
80449              }
80450            });
80451
80452            return p5Font;
80453          };
80454
80455          /**
80456           * Draws text to the screen. Displays the information specified in the first
80457           * parameter on the screen in the position specified by the additional
80458           * parameters. A default font will be used unless a font is set with the
80459           * <a href="#/p5/textFont">textFont()</a> function and a default size will be
80460           * used unless a font is set with <a href="#/p5/textSize">textSize()</a>. Change
80461           * the color of the text with the <a href="#/p5/fill">fill()</a> function. Change
80462           * the outline of the text with the <a href="#/p5/stroke">stroke()</a> and
80463           * <a href="#/p5/strokeWeight">
80463strokeWeight()</a> functions.
80464           *
80465           * The text displays in relation to the <a href="#/p5/textAlign">textAlign()</a>
80466           * function, which gives the option to draw to the left, right, and center of the
80467           * coordinates.
80468           *
80469           * The x2 and y2 parameters define a rectangular area to display within and
80470           * may only be used with string data. When these parameters are specified,
80471           * they are interpreted based on the current <a href="#/p5/rectMode">rectMode()</a>
80472           * setting. Text that does not fit completely within the rectangle specified will
80473           * not be drawn to the screen. If x2 and y2 are not specified, the baseline
80474           * alignment is the default, which means that the text will be drawn upwards
80475           * from x and y.
80476           *
80477           * <b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font
80478           * using the <a href="#/p5/loadFont">loadFont()</a> method (see the example above).
80479           * <a href="#/p5/stroke">stroke()</a> currently has no effect in webgl mode.
80480           *
80481           * @method text
80482           * @param {String|Object|Array|Number|Boolean} str the alphanumeric
80483           *                                             symbols to be displayed
80484           * @param {Number} x   x-coordinate of text
80485           * @param {Number} y   y-coordinate of text
80486           * @param {Number} [x2]  by default, the width of the text box,
80487           *                     see <a href="#/p5/rectMode">rectMode()</a> for more info
80488           * @param {Number} [y2]  by default, the height of the text box,
80489           *                     see <a href="#/p5/rectMode">rectMode()</a> for more info
80490           * @chainable
80491           * @example
80492           * <div>
80493           * <code>
80494           * textSize(32);
80495           * text('word', 10, 30);
80496           * fill(0, 102, 153);
80497           * text('word', 10, 60);
80498           * fill(0, 102, 153, 51);
80499           * text('word', 10, 90);
80500           * </code>
80501           * </div>
80502           * <div>
80503           * <code>
80504           * let s = 'The quick brown fox jumped over the lazy dog.';
80505           * fill(50);
80506           * text(s, 10, 10, 70, 80); // Text wraps within text box
80507           * </code>
80508           * </div>
80509           *
80510           * <div modernizr='webgl'>
80511           * <code>
80512           * let inconsolata;
80513           * function preload() {
80514           *   inconsolata = loadFont('assets/inconsolata.otf');
80515           * }
80516           * function setup() {
80517           *   createCanvas(100, 100, WEBGL);
80518           *   textFont(inconsolata);
80519           *   textSize(width / 3);
80520           *   textAlign(CENTER, CENTER);
80521           * }
80522           * function draw() {
80523           *   background(0);
80524           *   let time = millis();
80525           *   rotateX(time / 1000);
80526           *   rotateZ(time / 1234);
80527           *   text('p5.js', 0, 0);
80528           * }
80529           * </code>
80530           * </div>
80531           *
80532           * @alt
80533           * 'word' displayed 3 times going from black, blue to translucent blue
80534           * The text 'The quick brown fox jumped over the lazy dog' displayed.
80535           * The text 'p5.js' spinning in 3d
80536           */
80537          _main.default.prototype.text = function(str, x, y, maxWidth, maxHeight) {
80538            var _this$_renderer;
80539            _main.default._validateParameters('text', arguments);
80540            return !(this._renderer._doFill || this._renderer._doStroke)
80541              ? this
80542              : (_this$_renderer = this._renderer).text.apply(_this$_renderer, arguments);
80543          };
80544
80545          /**
80546    * Sets the current font that will be drawn with the <a href="#/p5/text">text()</a> function.
80547    *
80548    * <b>WEBGL</b>: Only fonts loaded via <a href="#/p5/loadFont">loadFont()</a> are supported.
80549    *
80550    * @method textFont
80551    * @return {Object} the current font
80552    *
80553    * @example
80554    * <div>
80555    * <code>
80556    * fill(0);
80557    * textSize(12);
80558    * textFont('Georgia');
80559    * text('Georgia', 12, 30);
80560    * textFont('Helvetica');
80561    * text('Helvetica', 12, 60);
80562    * </code>
80563    * </div>
80564    * <div>
80565    * <code>
80566    * let fontRegular, fontItalic, fontBold;
80567    * function preload() {
80568    *   fontRegular = loadFont('assets/Regular.otf');
80569    *   fontItalic = loadFont('assets/Italic.ttf');
80570    *   fontBold = loadFont('assets/Bold.ttf');
80571    * }
80572    * function setup() {
80573    *   background(210);
80574    *   fill(0)
80575       .strokeWeight(0)
80576       .textSize(10);
80577    *   textFont(fontRegular);
80578    *   text('Font Style Normal', 10, 30);
80579    *   textFont(fontItalic);
80580    *   text('Font Style Italic', 10, 50);
80581    *   textFont(fontBold);
80582    *   text('Font Style Bold', 10, 70);
80583    * }
80584    * </code>
80585    * </div>
80586    *
80587    * @alt
80588    * word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica
80589    * words Font Style Normal displayed normally, Italic in italic and bold in bold
80590    */
80591          /**
80592           * @method textFont
80593           * @param {Object|String} font a font loaded via <a href="#/p5/loadFont">loadFont()</a>,
80594           * or a String representing a <a href="https://mzl.la/2dOw8WD">web safe font</a>
80595           * (a font that is generally available across all systems)
80596           * @param {Number} [size] the font size to use
80597           * @chainable
80598           */
80599          _main.default.prototype.textFont = function(theFont, theSize) {
80600            _main.default._validateParameters('textFont', arguments);
80601            if (arguments.length) {
80602              if (!theFont) {
80603                throw new Error('null font passed to textFont');
80604              }
80605
80606              this._renderer._setProperty('_textFont', theFont);
80607
80608              if (theSize) {
80609                this._renderer._setProperty('_textSize', theSize);
80610                this._renderer._setProperty(
80611                  '_textLeading',
80612                  theSize * constants._DEFAULT_LEADMULT
80613                );
80614              }
80615
80616              return this._renderer._applyTextProperties();
80617            }
80618
80619            return this._renderer._textFont;
80620          };
80621          var _default = _main.default;
80622          exports.default = _default;
80623        },
80624        {
80625          '../core/constants': 48,
80626          '../core/friendly_errors/fes_core': 51,
80627          '../core/friendly_errors/file_errors': 52,
80628          '../core/friendly_errors/validate_params': 54,
80629          '../core/main': 59,
80630          'opentype.js': 34
80631        }
80632      ],
80633      97: [
80634        function(_dereq_, module, exports) {
80635          'use strict';
80636          Object.defineProperty(exports, '__esModule', { value: true });
80637          exports.default = void 0;
80638
80639          var _main = _interopRequireDefault(_dereq_('../core/main'));
80640          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
80641          function _getRequireWildcardCache() {
80642            if (typeof WeakMap !== 'function') return null;
80643            var cache = new WeakMap();
80644            _getRequireWildcardCache = function _getRequireWildcardCache() {
80645              return cache;
80646            };
80647            return cache;
80648          }
80649          function _interopRequireWildcard(obj) {
80650            if (obj && obj.__esModule) {
80651              return obj;
80652            }
80653            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
80654              return { default: obj };
80655            }
80656            var cache = _getRequireWildcardCache();
80657            if (cache && cache.has(obj)) {
80658              return cache.get(obj);
80659            }
80660            var newObj = {};
80661            var hasPropertyDescriptor =
80662              Object.defineProperty && Object.getOwnPropertyDescriptor;
80663            for (var key in obj) {
80664              if (Object.prototype.hasOwnProperty.call(obj, key)) {
80665                var desc = hasPropertyDescriptor
80666                  ? Object.getOwnPropertyDescriptor(obj, key)
80667                  : null;
80668                if (desc && (desc.get || desc.set)) {
80669                  Object.defineProperty(newObj, key, desc);
80670                } else {
80671                  newObj[key] = obj[key];
80672                }
80673              }
80674            }
80675            newObj.default = obj;
80676            if (cache) {
80677              cache.set(obj, newObj);
80678            }
80679            return newObj;
80680          }
80681          function _interopRequireDefault(obj) {
80682            return obj && obj.__esModule ? obj : { default: obj };
80683          }
80684          function _typeof(obj) {
80685            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
80686              _typeof = function _typeof(obj) {
80687                return typeof obj;
80688              };
80689            } else {
80690              _typeof = function _typeof(obj) {
80691                return obj &&
80692                  typeof Symbol === 'function' &&
80693                  obj.constructor === Symbol &&
80694                  obj !== Symbol.prototype
80695                  ? 'symbol'
80696                  : typeof obj;
80697              };
80698            }
80699            return _typeof(obj);
80700          }
80701
80702          /**
80703           * Base class for font handling
80704           * @class p5.Font
80705           * @constructor
80706           * @param {p5} [pInst] pointer to p5 instance
80707           */
80708          _main.default.Font = function(p) {
80709            this.parent = p;
80710
80711            this.cache = {};
80712
80713            /**
80714             * Underlying opentype font implementation
80715             * @property font
80716             */
80717            this.font = undefined;
80718          };
80719
80720          /**
80721           * Returns a tight bounding box for the given text string using this
80722           * font
80723           *
80724           * @method textBounds
80725           * @param  {String} line     a line of text
80726           * @param  {Number} x        x-position
80727           * @param  {Number} y        y-position
80728           * @param  {Number} [fontSize] font size to use (optional) Default is 12.
80729           * @param  {Object} [options] opentype options (optional)
80730           *                            opentype fonts contains alignment and baseline options.
80731           *                            Default is 'LEFT' and 'alphabetic'
80732           *
80733           * @return {Object}          a rectangle object with properties: x, y, w, h
80734           *
80735           * @example
80736           * <div>
80737           * <code>
80738           * let font;
80739           * let textString = 'Lorem ipsum dolor sit amet.';
80740           * function preload() {
80741           *   font = loadFont('./assets/Regular.otf');
80742           * }
80743           * function setup() {
80744           *   background(210);
80745           *
80746           *   let bbox = font.textBounds(textString, 10, 30, 12);
80747           *   fill(255);
80748           *   stroke(0);
80749           *   rect(bbox.x, bbox.y, bbox.w, bbox.h);
80750           *   fill(0);
80751           *   noStroke();
80752           *
80753           *   textFont(font);
80754           *   textSize(12);
80755           *   text(textString, 10, 30);
80756           * }
80757           * </code>
80758           * </div>
80759           *
80760           * @alt
80761           *words Lorem ipsum dol go off canvas and contained by white bounding box
80762           */
80763          _main.default.Font.prototype.textBounds = function(str) {
80764            var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
80765            var y = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
80766            var fontSize = arguments.length > 3 ? arguments[3] : undefined;
80767            var opts = arguments.length > 4 ? arguments[4] : undefined;
80768            // Check cache for existing bounds. Take into consideration the text alignment
80769            // settings. Default alignment should match opentype's origin: left-aligned &
80770            // alphabetic baseline.
80771            var p = (opts && opts.renderer && opts.renderer._pInst) || this.parent;
80772
80773            var ctx = p._renderer.drawingContext;
80774            var alignment = ctx.textAlign || constants.LEFT;
80775            var baseline = ctx.textBaseline || constants.BASELINE;
80776            var cacheResults = false;
80777            var result;
80778            var key;
80779
80780            fontSize = fontSize || p._renderer._textSize;
80781
80782            // NOTE: cache disabled for now pending further discussion of #3436
80783            if (cacheResults) {
80784              key = cacheKey('textBounds', str, x, y, fontSize, alignment, baseline);
80785              result = this.cache[key];
80786            }
80787
80788            if (!result) {
80789              var minX = [];
80790              var minY;
80791              var maxX = [];
80792              var maxY;
80793              var pos;
80794              var xCoords = [];
80795              xCoords[0] = [];
80796              var yCoords = [];
80797              var scale = this._scale(fontSize);
80798              var lineHeight = p._renderer.textLeading();
80799              var lineCount = 0;
80800
80801              this.font.forEachGlyph(str, x, y, fontSize, opts, function(
80802                glyph,
80803                gX,
80804                gY,
80805                gFontSize
80806              ) {
80807                var gm = glyph.getMetrics();
80808                if (glyph.index === 0 || glyph.index === 10) {
80809                  lineCount += 1;
80810                  xCoords[lineCount] = [];
80811                } else {
80812                  xCoords[lineCount].push(gX + gm.xMin * scale);
80813                  xCoords[lineCount].push(gX + gm.xMax * scale);
80814                  yCoords.push(gY + lineCount * lineHeight + -gm.yMin * scale);
80815                  yCoords.push(gY + lineCount * lineHeight + -gm.yMax * scale);
80816                }
80817              });
80818
80819              if (xCoords[lineCount].length > 0) {
80820                minX[lineCount] = Math.min.apply(null, xCoords[lineCount]);
80821                maxX[lineCount] = Math.max.apply(null, xCoords[lineCount]);
80822              }
80823
80824              var finalMaxX = 0;
80825              for (var i = 0; i <= lineCount; i++) {
80826                minX[i] = Math.min.apply(null, xCoords[i]);
80827                maxX[i] = Math.max.apply(null, xCoords[i]);
80828                var lineLength = maxX[i] - minX[i];
80829                if (lineLength > finalMaxX) {
80830                  finalMaxX = lineLength;
80831                }
80832              }
80833
80834              var finalMinX = Math.min.apply(null, minX);
80835              minY = Math.min.apply(null, yCoords);
80836              maxY = Math.max.apply(null, yCoords);
80837
80838              result = {
80839                x: finalMinX,
80840                y: minY,
80841                h: maxY - minY,
80842                w: finalMaxX,
80843                advance: finalMinX - x
80844              };
80845
80846              // Bounds are now calculated, so shift the x & y to match alignment settings
80847              pos = this._handleAlignment(
80848                p._renderer,
80849                str,
80850                result.x,
80851                result.y,
80852                result.w + result.advance
80853              );
80854
80855              result.x = pos.x;
80856              result.y = pos.y;
80857
80858              if (cacheResults) {
80859                this.cache[key] = result;
80860              }
80861            }
80862
80863            return result;
80864          };
80865
80866          /**
80867           * Computes an array of points following the path for specified text
80868           *
80869           * @method textToPoints
80870           * @param  {String} txt     a line of text
80871           * @param  {Number} x        x-position
80872           * @param  {Number} y        y-position
80873           * @param  {Number} fontSize font size to use (optional)
80874           * @param  {Object} [options] an (optional) object that can contain:
80875           *
80876           * <br>sampleFactor - the ratio of path-length to number of samples
80877           * (default=.1); higher values yield more points and are therefore
80878           * more precise
80879           *
80880           * <br>simplifyThreshold - if set to a non-zero value, collinear points will be
80881           * be removed from the polygon; the value represents the threshold angle to use
80882           * when determining whether two edges are collinear
80883           *
80884           * @return {Array}  an array of points, each with x, y, alpha (the path angle)
80885           * @example
80886           * <div>
80887           * <code>
80888           * let font;
80889           * function preload() {
80890           *   font = loadFont('assets/inconsolata.otf');
80891           * }
80892           *
80893           * let points;
80894           * let bounds;
80895           * function setup() {
80896           *   createCanvas(100, 100);
80897           *   stroke(0);
80898           *   fill(255, 104, 204);
80899           *
80900           *   points = font.textToPoints('p5', 0, 0, 10, {
80901           *     sampleFactor: 5,
80902           *     simplifyThreshold: 0
80903           *   });
80904           *   bounds = font.textBounds(' p5 ', 0, 0, 10);
80905           * }
80906           *
80907           * function draw() {
80908           *   background(255);
80909           *   beginShape();
80910           *   translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);
80911           *   for (let i = 0; i < points.length; i++) {
80912           *     let p = points[i];
80913           *     vertex(
80914           *       p.x * width / bounds.w +
80915           *         sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,
80916           *       p.y * height / bounds.h
80917           *     );
80918           *   }
80919           *   endShape(CLOSE);
80920           * }
80921           * </code>
80922           * </div>
80923           */
80924          _main.default.Font.prototype.textToPoints = function(
80925            txt,
80926            x,
80927            y,
80928            fontSize,
80929            options
80930          ) {
80931            var xoff = 0;
80932            var result = [];
80933            var glyphs = this._getGlyphs(txt);
80934
80935            function isSpace(i) {
80936              return (
80937                (glyphs[i].name && glyphs[i].name === 'space') ||
80938                (txt.length === glyphs.length && txt[i] === ' ') ||
80939                (glyphs[i].index && glyphs[i].index === 3)
80940              );
80941            }
80942
80943            fontSize = fontSize || this.parent._renderer._textSize;
80944
80945            for (var i = 0; i < glyphs.length; i++) {
80946              if (!isSpace(i)) {
80947                // fix to #1817, #2069
80948
80949                var gpath = glyphs[i].getPath(x, y, fontSize),
80950                  paths = splitPaths(gpath.commands);
80951
80952                for (var j = 0; j < paths.length; j++) {
80953                  var pts = pathToPoints(paths[j], options);
80954
80955                  for (var k = 0; k < pts.length; k++) {
80956                    pts[k].x += xoff;
80957                    result.push(pts[k]);
80958                  }
80959                }
80960              }
80961
80962              xoff += glyphs[i].advanceWidth * this._scale(fontSize);
80963            }
80964
80965            return result;
80966          };
80967
80968          // ----------------------------- End API ------------------------------
80969
80970          /**
80971           * Returns the set of opentype glyphs for the supplied string.
80972           *
80973           * Note that there is not a strict one-to-one mapping between characters
80974           * and glyphs, so the list of returned glyphs can be larger or smaller
80975           *  than the length of the given string.
80976           *
80977           * @private
80978           * @param  {String} str the string to be converted
80979           * @return {Array}     the opentype glyphs
80980           */
80981          _main.default.Font.prototype._getGlyphs = function(str) {
80982            return this.font.stringToGlyphs(str);
80983          };
80984
80985          /**
80986           * Returns an opentype path for the supplied string and position.
80987           *
80988           * @private
80989           * @param  {String} line     a line of text
80990           * @param  {Number} x        x-position
80991           * @param  {Number} y        y-position
80992           * @param  {Object} options opentype options (optional)
80993           * @return {Object}     the opentype path
80994           */
80995          _main.default.Font.prototype._getPath = function(line, x, y, options) {
80996            var p = (options && options.renderer && options.renderer._pInst) || this.parent,
80997              renderer = p._renderer,
80998              pos = this._handleAlignment(renderer, line, x, y);
80999
81000            return this.font.getPath(line, pos.x, pos.y, renderer._textSize, options);
81001          };
81002
81003          /*
81004    * Creates an SVG-formatted path-data string
81005    * (See http://www.w3.org/TR/SVG/paths.html#PathData)
81006    * from the given opentype path or string/position
81007    *
81008    * @param  {Object} path    an opentype path, OR the following:
81009    *
81010    * @param  {String} line     a line of text
81011    * @param  {Number} x        x-position
81012    * @param  {Number} y        y-position
81013    * @param  {Object} options opentype options (optional), set options.decimals
81014    * to set the decimal precision of the path-data
81015    *
81016    * @return {Object}     this p5.Font object
81017    */
81018          _main.default.Font.prototype._getPathData = function(line, x, y, options) {
81019            var decimals = 3;
81020
81021            // create path from string/position
81022            if (typeof line === 'string' && arguments.length > 2) {
81023              line = this._getPath(line, x, y, options);
81024            } else if (_typeof(x) === 'object') {
81025              // handle options specified in 2nd arg
81026              options = x;
81027            }
81028
81029            // handle svg arguments
81030            if (options && typeof options.decimals === 'number') {
81031              decimals = options.decimals;
81032            }
81033
81034            return line.toPathData(decimals);
81035          };
81036
81037          /*
81038    * Creates an SVG <path> element, as a string,
81039    * from the given opentype path or string/position
81040    *
81041    * @param  {Object} path    an opentype path, OR the following:
81042    *
81043    * @param  {String} line     a line of text
81044    * @param  {Number} x        x-position
81045    * @param  {Number} y        y-position
81046    * @param  {Object} options opentype options (optional), set options.decimals
81047    * to set the decimal precision of the path-data in the <path> element,
81048    *  options.fill to set the fill color for the <path> element,
81049    *  options.stroke to set the stroke color for the <path> element,
81050    *  options.strokeWidth to set the strokeWidth for the <path> element.
81051    *
81052    * @return {Object}     this p5.Font object
81053    */
81054          _main.default.Font.prototype._getSVG = function(line, x, y, options) {
81055            var decimals = 3;
81056
81057            // create path from string/position
81058            if (typeof line === 'string' && arguments.length > 2) {
81059              line = this._getPath(line, x, y, options);
81060            } else if (_typeof(x) === 'object') {
81061              // handle options specified in 2nd arg
81062              options = x;
81063            }
81064
81065            // handle svg arguments
81066            if (options) {
81067              if (typeof options.decimals === 'number') {
81068                decimals = options.decimals;
81069              }
81070              if (typeof options.strokeWidth === 'number') {
81071                line.strokeWidth = options.strokeWidth;
81072              }
81073              if (typeof options.fill !== 'undefined') {
81074                line.fill = options.fill;
81075              }
81076              if (typeof options.stroke !== 'undefined') {
81077                line.stroke = options.stroke;
81078              }
81079            }
81080
81081            return line.toSVG(decimals);
81082          };
81083
81084          /*
81085    * Renders an opentype path or string/position
81086    * to the current graphics context
81087    *
81088    * @param  {Object} path    an opentype path, OR the following:
81089    *
81090    * @param  {String} line     a line of text
81091    * @param  {Number} x        x-position
81092    * @param  {Number} y        y-position
81093    * @param  {Object} options opentype options (optional)
81094    *
81095    * @return {p5.Font}     this p5.Font object
81096    */
81097          _main.default.Font.prototype._renderPath = function(line, x, y, options) {
81098            var pdata;
81099            var pg = (options && options.renderer) || this.parent._renderer;
81100            var ctx = pg.drawingContext;
81101
81102            if (_typeof(line) === 'object' && line.commands) {
81103              pdata = line.commands;
81104            } else {
81105              //pos = handleAlignment(p, ctx, line, x, y);
81106              pdata = this._getPath(line, x, y, options).commands;
81107            }
81108
81109            ctx.beginPath();
81110            var _iteratorNormalCompletion = true;
81111            var _didIteratorError = false;
81112            var _iteratorError = undefined;
81113            try {
81114              for (
81115                var _iterator = pdata[Symbol.iterator](), _step;
81116                !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
81117                _iteratorNormalCompletion = true
81118              ) {
81119                var cmd = _step.value;
81120                if (cmd.type === 'M') {
81121                  ctx.moveTo(cmd.x, cmd.y);
81122                } else if (cmd.type === 'L') {
81123                  ctx.lineTo(cmd.x, cmd.y);
81124                } else if (cmd.type === 'C') {
81125                  ctx.bezierCurveTo(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
81126                } else if (cmd.type === 'Q') {
81127                  ctx.quadraticCurveTo(cmd.x1, cmd.y1, cmd.x, cmd.y);
81128                } else if (cmd.type === 'Z') {
81129                  ctx.closePath();
81130                }
81131              }
81132
81133              // only draw stroke if manually set by user
81134            } catch (err) {
81135              _didIteratorError = true;
81136              _iteratorError = err;
81137            } finally {
81138              try {
81139                if (!_iteratorNormalCompletion && _iterator.return != null) {
81140                  _iterator.return();
81141                }
81142              } finally {
81143                if (_didIteratorError) {
81144                  throw _iteratorError;
81145                }
81146              }
81147            }
81148            if (pg._doStroke && pg._strokeSet) {
81149              ctx.stroke();
81150            }
81151
81152            if (pg._doFill) {
81153              // if fill hasn't been set by user, use default-text-fill
81154              if (!pg._fillSet) {
81155                pg._setFill(constants._DEFAULT_TEXT_FILL);
81156              }
81157              ctx.fill();
81158            }
81159
81160            return this;
81161          };
81162
81163          _main.default.Font.prototype._textWidth = function(str, fontSize) {
81164            return this.font.getAdvanceWidth(str, fontSize);
81165          };
81166
81167          _main.default.Font.prototype._textAscent = function(fontSize) {
81168            return this.font.ascender * this._scale(fontSize);
81169          };
81170
81171          _main.default.Font.prototype._textDescent = function(fontSize) {
81172            return -this.font.descender * this._scale(fontSize);
81173          };
81174
81175          _main.default.Font.prototype._scale = function(fontSize) {
81176            return 1 / this.font.unitsPerEm * (fontSize || this.parent._renderer._textSize);
81177          };
81178
81179          _main.default.Font.prototype._handleAlignment = function(
81180            renderer,
81181            line,
81182            x,
81183            y,
81184            textWidth
81185          ) {
81186            var fontSize = renderer._textSize;
81187
81188            if (typeof textWidth === 'undefined') {
81189              textWidth = this._textWidth(line, fontSize);
81190            }
81191
81192            switch (renderer._textAlign) {
81193              case constants.CENTER:
81194                x -= textWidth / 2;
81195                break;
81196              case constants.RIGHT:
81197                x -= textWidth;
81198                break;
81199            }
81200
81201            switch (renderer._textBaseline) {
81202              case constants.TOP:
81203                y += this._textAscent(fontSize);
81204                break;
81205              case constants.CENTER:
81206                y += this._textAscent(fontSize) / 2;
81207                break;
81208              case constants.BOTTOM:
81209                y -= this._textDescent(fontSize);
81210                break;
81211            }
81212
81213            return { x: x, y: y };
81214          };
81215
81216          // path-utils
81217
81218          function pathToPoints(cmds, options) {
81219            var opts = parseOpts(options, {
81220              sampleFactor: 0.1,
81221              simplifyThreshold: 0
81222            });
81223
81224            var // total-length
81225              len = pointAtLength(cmds, 0, 1),
81226              t = len / (len * opts.sampleFactor),
81227              pts = [];
81228
81229            for (var i = 0; i < len; i += t) {
81230              pts.push(pointAtLength(cmds, i));
81231            }
81232
81233            if (opts.simplifyThreshold) {
81234              simplify(pts, opts.simplifyThreshold);
81235            }
81236
81237            return pts;
81238          }
81239
81240          function simplify(pts) {
81241            var angle =
81242              arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
81243            var num = 0;
81244            for (var i = pts.length - 1; pts.length > 3 && i >= 0; --i) {
81245              if (collinear(at(pts, i - 1), at(pts, i), at(pts, i + 1), angle)) {
81246                // Remove the middle point
81247                pts.splice(i % pts.length, 1);
81248                num++;
81249              }
81250            }
81251            return num;
81252          }
81253
81254          function splitPaths(cmds) {
81255            var paths = [];
81256            var current;
81257            for (var i = 0; i < cmds.length; i++) {
81258              if (cmds[i].type === 'M') {
81259                if (current) {
81260                  paths.push(current);
81261                }
81262                current = [];
81263              }
81264              current.push(cmdToArr(cmds[i]));
81265            }
81266            paths.push(current);
81267
81268            return paths;
81269          }
81270
81271          function cmdToArr(cmd) {
81272            var arr = [cmd.type];
81273            if (cmd.type === 'M' || cmd.type === 'L') {
81274              // moveto or lineto
81275              arr.push(cmd.x, cmd.y);
81276            } else if (cmd.type === 'C') {
81277              arr.push(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
81278            } else if (cmd.type === 'Q') {
81279              arr.push(cmd.x1, cmd.y1, cmd.x, cmd.y);
81280            }
81281            // else if (cmd.type === 'Z') { /* no-op */ }
81282            return arr;
81283          }
81284
81285          function parseOpts(options, defaults) {
81286            if (_typeof(options) !== 'object') {
81287              options = defaults;
81288            } else {
81289              for (var key in defaults) {
81290                if (typeof options[key] === 'undefined') {
81291                  options[key] = defaults[key];
81292                }
81293              }
81294            }
81295            return options;
81296          }
81297
81298          //////////////////////// Helpers ////////////////////////////
81299
81300          function at(v, i) {
81301            var s = v.length;
81302            return v[i < 0 ? i % s + s : i % s];
81303          }
81304
81305          function collinear(a, b, c, thresholdAngle) {
81306            if (!thresholdAngle) {
81307              return areaTriangle(a, b, c) === 0;
81308            }
81309
81310            if (typeof collinear.tmpPoint1 === 'undefined') {
81311              collinear.tmpPoint1 = [];
81312              collinear.tmpPoint2 = [];
81313            }
81314
81315            var ab = collinear.tmpPoint1,
81316              bc = collinear.tmpPoint2;
81317            ab.x = b.x - a.x;
81318            ab.y = b.y - a.y;
81319            bc.x = c.x - b.x;
81320            bc.y = c.y - b.y;
81321
81322            var dot = ab.x * bc.x + ab.y * bc.y,
81323              magA = Math.sqrt(ab.x * ab.x + ab.y * ab.y),
81324              magB = Math.sqrt(bc.x * bc.x + bc.y * bc.y),
81325              angle = Math.acos(dot / (magA * magB));
81326
81327            return angle < thresholdAngle;
81328          }
81329
81330          function areaTriangle(a, b, c) {
81331            return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
81332          }
81333
81334          // Portions of below code copyright 2008 Dmitry Baranovskiy (via MIT license)
81335
81336          function findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
81337            var t1 = 1 - t;
81338            var t13 = Math.pow(t1, 3);
81339            var t12 = Math.pow(t1, 2);
81340            var t2 = t * t;
81341            var t3 = t2 * t;
81342            var x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x;
81343            var y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y;
81344            var mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x);
81345            var my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y);
81346            var nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x);
81347            var ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y);
81348            var ax = t1 * p1x + t * c1x;
81349            var ay = t1 * p1y + t * c1y;
81350            var cx = t1 * c2x + t * p2x;
81351            var cy = t1 * c2y + t * p2y;
81352            var alpha = 90 - Math.atan2(mx - nx, my - ny) * 180 / Math.PI;
81353
81354            if (mx > nx || my < ny) {
81355              alpha += 180;
81356            }
81357
81358            return {
81359              x: x,
81360              y: y,
81361              m: { x: mx, y: my },
81362              n: { x: nx, y: ny },
81363              start: { x: ax, y: ay },
81364              end: { x: cx, y: cy },
81365              alpha: alpha
81366            };
81367          }
81368
81369          function getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {
81370            return length == null
81371              ? bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y)
81372              : findDotsAtSegment(
81373                  p1x,
81374                  p1y,
81375                  c1x,
81376                  c1y,
81377                  c2x,
81378                  c2y,
81379                  p2x,
81380                  p2y,
81381                  getTatLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length)
81382                );
81383          }
81384
81385          function pointAtLength(path, length, istotal) {
81386            path = path2curve(path);
81387            var x;
81388            var y;
81389            var p;
81390            var l;
81391            var sp = '';
81392            var subpaths = {};
81393            var point;
81394            var len = 0;
81395            for (var i = 0, ii = path.length; i < ii; i++) {
81396              p = path[i];
81397              if (p[0] === 'M') {
81398                x = +p[1];
81399                y = +p[2];
81400              } else {
81401                l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
81402                if (len + l > length) {
81403                  if (!istotal) {
81404                    point = getPointAtSegmentLength(
81405                      x,
81406                      y,
81407                      p[1],
81408                      p[2],
81409                      p[3],
81410                      p[4],
81411                      p[5],
81412                      p[6],
81413                      length - len
81414                    );
81415
81416                    return { x: point.x, y: point.y, alpha: point.alpha };
81417                  }
81418                }
81419                len += l;
81420                x = +p[5];
81421                y = +p[6];
81422              }
81423              sp += p.shift() + p;
81424            }
81425            subpaths.end = sp;
81426
81427            point = istotal
81428              ? len
81429              : findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);
81430
81431            if (point.alpha) {
81432              point = { x: point.x, y: point.y, alpha: point.alpha };
81433            }
81434
81435            return point;
81436          }
81437
81438          function pathToAbsolute(pathArray) {
81439            var res = [],
81440              x = 0,
81441              y = 0,
81442              mx = 0,
81443              my = 0,
81444              start = 0;
81445            if (!pathArray) {
81446              // console.warn("Unexpected state: undefined pathArray"); // shouldn't happen
81447              return res;
81448            }
81449            if (pathArray[0][0] === 'M') {
81450              x = +pathArray[0][1];
81451              y = +pathArray[0][2];
81452              mx = x;
81453              my = y;
81454              start++;
81455              res[0] = ['M', x, y];
81456            }
81457
81458            var dots;
81459
81460            var crz =
81461              pathArray.length === 3 &&
81462              pathArray[0][0] === 'M' &&
81463              pathArray[1][0].toUpperCase() === 'R' &&
81464              pathArray[2][0].toUpperCase() === 'Z';
81465
81466            for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {
81467              res.push((r = []));
81468              pa = pathArray[i];
81469              if (pa[0] !== String.prototype.toUpperCase.call(pa[0])) {
81470                r[0] = String.prototype.toUpperCase.call(pa[0]);
81471                switch (r[0]) {
81472                  case 'A':
81473                    r[1] = pa[1];
81474                    r[2] = pa[2];
81475                    r[3] = pa[3];
81476                    r[4] = pa[4];
81477                    r[5] = pa[5];
81478                    r[6] = +(pa[6] + x);
81479                    r[7] = +(pa[7] + y);
81480                    break;
81481                  case 'V':
81482                    r[1] = +pa[1] + y;
81483                    break;
81484                  case 'H':
81485                    r[1] = +pa[1] + x;
81486                    break;
81487                  case 'R':
81488                    dots = [x, y].concat(pa.slice(1));
81489                    for (var j = 2, jj = dots.length; j < jj; j++) {
81490                      dots[j] = +dots[j] + x;
81491                      dots[++j] = +dots[j] + y;
81492                    }
81493                    res.pop();
81494                    res = res.concat(catmullRom2bezier(dots, crz));
81495                    break;
81496                  case 'M':
81497                    mx = +pa[1] + x;
81498                    my = +pa[2] + y;
81499                    break;
81500                  default:
81501                    for (var _j = 1, _jj = pa.length; _j < _jj; _j++) {
81502                      r[_j] = +pa[_j] + (_j % 2 ? x : y);
81503                    }
81504                }
81505              } else if (pa[0] === 'R') {
81506                dots = [x, y].concat(pa.slice(1));
81507                res.pop();
81508                res = res.concat(catmullRom2bezier(dots, crz));
81509                r = ['R'].concat(pa.slice(-2));
81510              } else {
81511                for (var k = 0, kk = pa.length; k < kk; k++) {
81512                  r[k] = pa[k];
81513                }
81514              }
81515              switch (r[0]) {
81516                case 'Z':
81517                  x = mx;
81518                  y = my;
81519                  break;
81520                case 'H':
81521                  x = r[1];
81522                  break;
81523                case 'V':
81524                  y = r[1];
81525                  break;
81526                case 'M':
81527                  mx = r[r.length - 2];
81528                  my = r[r.length - 1];
81529                  break;
81530                default:
81531                  x = r[r.length - 2];
81532                  y = r[r.length - 1];
81533              }
81534            }
81535            return res;
81536          }
81537
81538          function path2curve(path, path2) {
81539            var p = pathToAbsolute(path),
81540              p2 = path2 && pathToAbsolute(path2);
81541            var attrs = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null };
81542            var attrs2 = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null };
81543            var pcoms1 = []; // path commands of original path p
81544            var pcoms2 = []; // path commands of original path p2
81545            var ii;
81546
81547            var processPath = function processPath(path, d, pcom) {
81548                var nx;
81549                var ny;
81550                var tq = { T: 1, Q: 1 };
81551                if (!path) {
81552                  return ['C', d.x, d.y, d.x, d.y, d.x, d.y];
81553                }
81554                if (!(path[0] in tq)) {
81555                  d.qx = d.qy = null;
81556                }
81557                switch (path[0]) {
81558                  case 'M':
81559                    d.X = path[1];
81560                    d.Y = path[2];
81561                    break;
81562                  case 'A':
81563                    path = ['C'].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1))));
81564                    break;
81565                  case 'S':
81566                    if (pcom === 'C' || pcom === 'S') {
81567                      nx = d.x * 2 - d.bx;
81568                      ny = d.y * 2 - d.by;
81569                    } else {
81570                      nx = d.x;
81571                      ny = d.y;
81572                    }
81573                    path = ['C', nx, ny].concat(path.slice(1));
81574                    break;
81575                  case 'T':
81576                    if (pcom === 'Q' || pcom === 'T') {
81577                      d.qx = d.x * 2 - d.qx;
81578                      d.qy = d.y * 2 - d.qy;
81579                    } else {
81580                      d.qx = d.x;
81581                      d.qy = d.y;
81582                    }
81583                    path = ['C'].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
81584                    break;
81585                  case 'Q':
81586                    d.qx = path[1];
81587                    d.qy = path[2];
81588                    path = ['C'].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
81589
81590                    break;
81591                  case 'L':
81592                    path = ['C'].concat(l2c(d.x, d.y, path[1], path[2]));
81593                    break;
81594                  case 'H':
81595                    path = ['C'].concat(l2c(d.x, d.y, path[1], d.y));
81596                    break;
81597                  case 'V':
81598                    path = ['C'].concat(l2c(d.x, d.y, d.x, path[1]));
81599                    break;
81600                  case 'Z':
81601                    path = ['C'].concat(l2c(d.x, d.y, d.X, d.Y));
81602                    break;
81603                }
81604
81605                return path;
81606              },
81607              fixArc = function fixArc(pp, i) {
81608                if (pp[i].length > 7) {
81609                  pp[i].shift();
81610                  var pi = pp[i];
81611                  while (pi.length) {
81612                    pcoms1[i] = 'A';
81613                    if (p2) {
81614                      pcoms2[i] = 'A';
81615                    }
81616                    pp.splice(i++, 0, ['C'].concat(pi.splice(0, 6)));
81617                  }
81618                  pp.splice(i, 1);
81619                  ii = Math.max(p.length, (p2 && p2.length) || 0);
81620                }
81621              },
81622              fixM = function fixM(path1, path2, a1, a2, i) {
81623                if (path1 && path2 && path1[i][0] === 'M' && path2[i][0] !== 'M') {
81624                  path2.splice(i, 0, ['M', a2.x, a2.y]);
81625                  a1.bx = 0;
81626                  a1.by = 0;
81627                  a1.x = path1[i][1];
81628                  a1.y = path1[i][2];
81629                  ii = Math.max(p.length, (p2 && p2.length) || 0);
81630                }
81631              };
81632
81633            var pfirst = ''; // temporary holder for original path command
81634            var pcom = ''; // holder for previous path command of original path
81635
81636            ii = Math.max(p.length, (p2 && p2.length) || 0);
81637            for (var i = 0; i < ii; i++) {
81638              if (p[i]) {
81639                pfirst = p[i][0];
81640              } // save current path command
81641
81642              if (pfirst !== 'C') {
81643                pcoms1[i] = pfirst; // Save current path command
81644                if (i) {
81645                  pcom = pcoms1[i - 1];
81646                } // Get previous path command pcom
81647              }
81648              p[i] = processPath(p[i], attrs, pcom);
81649
81650              if (pcoms1[i] !== 'A' && pfirst === 'C') {
81651                pcoms1[i] = 'C';
81652              }
81653
81654              fixArc(p, i);
81654 // fixArc adds also the right amount of A:s to pcoms1
81655
81656              if (p2) {
81657                // the same procedures is done to p2
81658                if (p2[i]) {
81659                  pfirst = p2[i][0];
81660                }
81661                if (pfirst !== 'C') {
81662                  pcoms2[i] = pfirst;
81663                  if (i) {
81664                    pcom = pcoms2[i - 1];
81665                  }
81666                }
81667                p2[i] = processPath(p2[i], attrs2, pcom);
81668
81669                if (pcoms2[i] !== 'A' && pfirst === 'C') {
81670                  pcoms2[i] = 'C';
81671                }
81672
81673                fixArc(p2, i);
81674              }
81675              fixM(p, p2, attrs, attrs2, i);
81676              fixM(p2, p, attrs2, attrs, i);
81677              var seg = p[i],
81678                seg2 = p2 && p2[i],
81679                seglen = seg.length,
81680                seg2len = p2 && seg2.length;
81681              attrs.x = seg[seglen - 2];
81682              attrs.y = seg[seglen - 1];
81683              attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x;
81684              attrs.by = parseFloat(seg[seglen - 3]) || attrs.y;
81685              attrs2.bx = p2 && (parseFloat(seg2[seg2len - 4]) || attrs2.x);
81686              attrs2.by = p2 && (parseFloat(seg2[seg2len - 3]) || attrs2.y);
81687              attrs2.x = p2 && seg2[seg2len - 2];
81688              attrs2.y = p2 && seg2[seg2len - 1];
81689            }
81690
81691            return p2 ? [p, p2] : p;
81692          }
81693
81694          function a2c(x1, y1, rx, ry, angle, lac, sweep_flag, x2, y2, recursive) {
81695            // for more information of where this Math came from visit:
81696            // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
81697            var PI = Math.PI;
81698
81699            var _120 = PI * 120 / 180;
81700            var f1;
81701            var f2;
81702            var cx;
81703            var cy;
81704            var rad = PI / 180 * (+angle || 0);
81705            var res = [];
81706            var xy;
81707
81708            var rotate = function rotate(x, y, rad) {
81709              var X = x * Math.cos(rad) - y * Math.sin(rad),
81710                Y = x * Math.sin(rad) + y * Math.cos(rad);
81711              return { x: X, y: Y };
81712            };
81713
81714            if (!recursive) {
81715              xy = rotate(x1, y1, -rad);
81716              x1 = xy.x;
81717              y1 = xy.y;
81718              xy = rotate(x2, y2, -rad);
81719              x2 = xy.x;
81720              y2 = xy.y;
81721              var x = (x1 - x2) / 2;
81722              var y = (y1 - y2) / 2;
81723              var h = x * x / (rx * rx) + y * y / (ry * ry);
81724              if (h > 1) {
81725                h = Math.sqrt(h);
81726                rx = h * rx;
81727                ry = h * ry;
81728              }
81729              var rx2 = rx * rx,
81730                ry2 = ry * ry;
81731              var k =
81732                (lac === sweep_flag ? -1 : 1) *
81733                Math.sqrt(
81734                  Math.abs(
81735                    (rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)
81736                  )
81737                );
81738
81739              cx = k * rx * y / ry + (x1 + x2) / 2;
81740              cy = k * -ry * x / rx + (y1 + y2) / 2;
81741              f1 = Math.asin(((y1 - cy) / ry).toFixed(9));
81742              f2 = Math.asin(((y2 - cy) / ry).toFixed(9));
81743
81744              f1 = x1 < cx ? PI - f1 : f1;
81745              f2 = x2 < cx ? PI - f2 : f2;
81746
81747              if (f1 < 0) {
81748                f1 = PI * 2 + f1;
81749              }
81750              if (f2 < 0) {
81751                f2 = PI * 2 + f2;
81752              }
81753
81754              if (sweep_flag && f1 > f2) {
81755                f1 = f1 - PI * 2;
81756              }
81757              if (!sweep_flag && f2 > f1) {
81758                f2 = f2 - PI * 2;
81759              }
81760            } else {
81761              f1 = recursive[0];
81762              f2 = recursive[1];
81763              cx = recursive[2];
81764              cy = recursive[3];
81765            }
81766            var df = f2 - f1;
81767            if (Math.abs(df) > _120) {
81768              var f2old = f2,
81769                x2old = x2,
81770                y2old = y2;
81771              f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
81772              x2 = cx + rx * Math.cos(f2);
81773              y2 = cy + ry * Math.sin(f2);
81774              res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [
81775                f2,
81776                f2old,
81777                cx,
81778                cy
81779              ]);
81780            }
81781            df = f2 - f1;
81782            var c1 = Math.cos(f1),
81783              s1 = Math.sin(f1),
81784              c2 = Math.cos(f2),
81785              s2 = Math.sin(f2),
81786              t = Math.tan(df / 4),
81787              hx = 4 / 3 * rx * t,
81788              hy = 4 / 3 * ry * t,
81789              m1 = [x1, y1],
81790              m2 = [x1 + hx * s1, y1 - hy * c1],
81791              m3 = [x2 + hx * s2, y2 - hy * c2],
81792              m4 = [x2, y2];
81793            m2[0] = 2 * m1[0] - m2[0];
81794            m2[1] = 2 * m1[1] - m2[1];
81795            if (recursive) {
81796              return [m2, m3, m4].concat(res);
81797            } else {
81798              res = [m2, m3, m4]
81799                .concat(res)
81800                .join()
81801                .split(',');
81802              var newres = [];
81803              for (var i = 0, ii = res.length; i < ii; i++) {
81804                newres[i] =
81805                  i % 2
81806                    ? rotate(res[i - 1], res[i], rad).y
81807                    : rotate(res[i], res[i + 1], rad).x;
81808              }
81809              return newres;
81810            }
81811          }
81812
81813          // http://schepers.cc/getting-to-the-point
81814          function catmullRom2bezier(crp, z) {
81815            var d = [];
81816            for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {
81817              var p = [
81818                {
81819                  x: +crp[i - 2],
81820                  y: +crp[i - 1]
81821                },
81822
81823                {
81824                  x: +crp[i],
81825                  y: +crp[i + 1]
81826                },
81827
81828                {
81829                  x: +crp[i + 2],
81830                  y: +crp[i + 3]
81831                },
81832
81833                {
81834                  x: +crp[i + 4],
81835                  y: +crp[i + 5]
81836                }
81837              ];
81838
81839              if (z) {
81840                if (!i) {
81841                  p[0] = {
81842                    x: +crp[iLen - 2],
81843                    y: +crp[iLen - 1]
81844                  };
81845                } else if (iLen - 4 === i) {
81846                  p[3] = {
81847                    x: +crp[0],
81848                    y: +crp[1]
81849                  };
81850                } else if (iLen - 2 === i) {
81851                  p[2] = {
81852                    x: +crp[0],
81853                    y: +crp[1]
81854                  };
81855
81856                  p[3] = {
81857                    x: +crp[2],
81858                    y: +crp[3]
81859                  };
81860                }
81861              } else {
81862                if (iLen - 4 === i) {
81863                  p[3] = p[2];
81864                } else if (!i) {
81865                  p[0] = {
81866                    x: +crp[i],
81867                    y: +crp[i + 1]
81868                  };
81869                }
81870              }
81871              d.push([
81872                'C',
81873                (-p[0].x + 6 * p[1].x + p[2].x) / 6,
81874                (-p[0].y + 6 * p[1].y + p[2].y) / 6,
81875                (p[1].x + 6 * p[2].x - p[3].x) / 6,
81876                (p[1].y + 6 * p[2].y - p[3].y) / 6,
81877                p[2].x,
81878                p[2].y
81879              ]);
81880            }
81881
81882            return d;
81883          }
81884
81885          function l2c(x1, y1, x2, y2) {
81886            return [x1, y1, x2, y2, x2, y2];
81887          }
81888
81889          function q2c(x1, y1, ax, ay, x2, y2) {
81890            var _13 = 1 / 3,
81891              _23 = 2 / 3;
81892            return [
81893              _13 * x1 + _23 * ax,
81894              _13 * y1 + _23 * ay,
81895              _13 * x2 + _23 * ax,
81896              _13 * y2 + _23 * ay,
81897              x2,
81898              y2
81899            ];
81900          }
81901
81902          function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) {
81903            if (z == null) {
81904              z = 1;
81905            }
81906            z = z > 1 ? 1 : z < 0 ? 0 : z;
81907            var z2 = z / 2;
81908            var n = 12;
81909            var Tvalues = [
81910              -0.1252,
81911              0.1252,
81912              -0.3678,
81913              0.3678,
81914              -0.5873,
81915              0.5873,
81916              -0.7699,
81917              0.7699,
81918              -0.9041,
81919              0.9041,
81920              -0.9816,
81921              0.9816
81922            ];
81923
81924            var sum = 0;
81925            var Cvalues = [
81926              0.2491,
81927              0.2491,
81928              0.2335,
81929              0.2335,
81930              0.2032,
81931              0.2032,
81932              0.1601,
81933              0.1601,
81934              0.1069,
81935              0.1069,
81936              0.0472,
81937              0.0472
81938            ];
81939
81940            for (var i = 0; i < n; i++) {
81941              var ct = z2 * Tvalues[i] + z2,
81942                xbase = base3(ct, x1, x2, x3, x4),
81943                ybase = base3(ct, y1, y2, y3, y4),
81944                comb = xbase * xbase + ybase * ybase;
81945              sum += Cvalues[i] * Math.sqrt(comb);
81946            }
81947            return z2 * sum;
81948          }
81949
81950          function getTatLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) {
81951            if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) {
81952              return;
81953            }
81954            var t = 1;
81955            var step = t / 2;
81956            var t2 = t - step;
81957            var l;
81958            var e = 0.01;
81959            l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);
81960            while (Math.abs(l - ll) > e) {
81961              step /= 2;
81962              t2 += (l < ll ? 1 : -1) * step;
81963              l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);
81964            }
81965            return t2;
81966          }
81967
81968          function base3(t, p1, p2, p3, p4) {
81969            var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,
81970              t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
81971            return t * t2 - 3 * p1 + 3 * p2;
81972          }
81973
81974          function cacheKey() {
81975            var hash = '';
81976            for (var i = arguments.length - 1; i >= 0; --i) {
81977              hash += '\uFF1F'.concat(
81978                i < 0 || arguments.length <= i ? undefined : arguments[i]
81979              );
81980            }
81981            return hash;
81982          }
81983          var _default = _main.default;
81984          exports.default = _default;
81985        },
81986        { '../core/constants': 48, '../core/main': 59 }
81987      ],
81988      98: [
81989        function(_dereq_, module, exports) {
81990          'use strict';
81991          Object.defineProperty(exports, '__esModule', { value: true });
81992          exports.default = void 0;
81993
81994          var _main = _interopRequireDefault(_dereq_('../core/main'));
81995          function _interopRequireDefault(obj) {
81996            return obj && obj.__esModule ? obj : { default: obj };
81997          }
81998          /**
81999           * @module Data
82000           * @submodule Array Functions
82001           * @for p5
82002           * @requires core
82003           */ /**
82004           * Adds a value to the end of an array. Extends the length of
82005           * the array by one. Maps to Array.push().
82006           *
82007           * @method append
82008           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push">array.push(value)</a> instead.
82009           * @param {Array} array Array to append
82010           * @param {any} value to be added to the Array
82011           * @return {Array} the array that was appended to
82012           * @example
82013           * <div class='norender'><code>
82014           * function setup() {
82015           *   let myArray = ['Mango', 'Apple', 'Papaya'];
82016           *   print(myArray); // ['Mango', 'Apple', 'Papaya']
82017           *
82018           *   append(myArray, 'Peach');
82019           *   print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']
82020           * }
82021           * </code></div>
82022           */ _main.default.prototype.append = function(array, value) {
82023            array.push(value);
82024            return array;
82025          };
82026
82027          /**
82028           * Copies an array (or part of an array) to another array. The src array is
82029           * copied to the dst array, beginning at the position specified by
82030           * srcPosition and into the position specified by dstPosition. The number of
82031           * elements to copy is determined by length. Note that copying values
82032           * overwrites existing values in the destination array. To append values
82033           * instead of overwriting them, use <a href="#/p5/concat">concat()</a>.
82034           *
82035           * The simplified version with only two arguments, arrayCopy(src, dst),
82036           * copies an entire array to another of the same size. It is equivalent to
82037           * arrayCopy(src, 0, dst, 0, src.length).
82038           *
82039           * Using this function is far more efficient for copying array data than
82040           * iterating through a for() loop and copying each element individually.
82041           *
82042           * @method arrayCopy
82043           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin">arr1.copyWithin(arr2)</a> instead.
82044           * @param {Array}  src           the source Array
82045           * @param {Integer} srcPosition  starting position in the source Array
82046           * @param {Array}  dst           the destination Array
82047           * @param {Integer} dstPosition   starting position in the destination Array
82048           * @param {Integer} length        number of Array elements to be copied
82049           *
82050           * @example
82051           * <div class='norender'><code>
82052           * let src = ['A', 'B', 'C'];
82053           * let dst = [1, 2, 3];
82054           * let srcPosition = 1;
82055           * let dstPosition = 0;
82056           * let length = 2;
82057           *
82058           * print(src); // ['A', 'B', 'C']
82059           * print(dst); // [ 1 ,  2 ,  3 ]
82060           *
82061           * arrayCopy(src, srcPosition, dst, dstPosition, length);
82062           * print(dst); // ['B', 'C', 3]
82063           * </code></div>
82064           */
82065          /**
82066           * @method arrayCopy
82067           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin">arr1.copyWithin(arr2)</a> instead.
82068           * @param {Array}  src
82069           * @param {Array}  dst
82070           * @param {Integer} [length]
82071           */
82072          _main.default.prototype.arrayCopy = function(
82073            src,
82074            srcPosition,
82075            dst,
82076            dstPosition,
82077            length
82078          ) {
82079            // the index to begin splicing from dst array
82080            var start;
82081            var end;
82082
82083            if (typeof length !== 'undefined') {
82084              end = Math.min(length, src.length);
82085              start = dstPosition;
82086              src = src.slice(srcPosition, end + srcPosition);
82087            } else {
82088              if (typeof dst !== 'undefined') {
82089                // src, dst, length
82090                // rename  so we don't get confused
82091                end = dst;
82092                end = Math.min(end, src.length);
82093              } else {
82094                // src, dst
82095                end = src.length;
82096              }
82097
82098              start = 0;
82099              // rename  so we don't get confused
82100              dst = srcPosition;
82101              src = src.slice(0, end);
82102            }
82103
82104            // Since we are not returning the array and JavaScript is pass by reference
82105            // we must modify the actual values of the array
82106            // instead of reassigning arrays
82107            Array.prototype.splice.apply(dst, [start, end].concat(src));
82108          };
82109
82110          /**
82111           * Concatenates two arrays, maps to Array.concat(). Does not modify the
82112           * input arrays.
82113           *
82114           * @method concat
82115           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">arr1.concat(arr2)</a> instead.
82116           * @param {Array} a first Array to concatenate
82117           * @param {Array} b second Array to concatenate
82118           * @return {Array} concatenated array
82119           *
82120           * @example
82121           * <div class = 'norender'><code>
82122           * function setup() {
82123           *   let arr1 = ['A', 'B', 'C'];
82124           *   let arr2 = [1, 2, 3];
82125           *
82126           *   print(arr1); // ['A','B','C']
82127           *   print(arr2); // [1,2,3]
82128           *
82129           *   let arr3 = concat(arr1, arr2);
82130           *
82131           *   print(arr1); // ['A','B','C']
82132           *   print(arr2); // [1, 2, 3]
82133           *   print(arr3); // ['A','B','C', 1, 2, 3]
82134           * }
82135           * </code></div>
82136           */
82137          _main.default.prototype.concat = function(list0, list1) {
82138            return list0.concat(list1);
82139          };
82140
82141          /**
82142           * Reverses the order of an array, maps to Array.reverse()
82143           *
82144           * @method reverse
82145           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse">array.reverse()</a> instead.
82146           * @param {Array} list Array to reverse
82147           * @return {Array} the reversed list
82148           * @example
82149           * <div class='norender'><code>
82150           * function setup() {
82151           *   let myArray = ['A', 'B', 'C'];
82152           *   print(myArray); // ['A','B','C']
82153           *
82154           *   reverse(myArray);
82155           *   print(myArray); // ['C','B','A']
82156           * }
82157           * </code></div>
82158           */
82159          _main.default.prototype.reverse = function(list) {
82160            return list.reverse();
82161          };
82162
82163          /**
82164           * Decreases an array by one element and returns the shortened array,
82165           * maps to Array.pop().
82166           *
82167           * @method shorten
82168           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop">array.pop()</a> instead.
82169           * @param  {Array} list Array to shorten
82170           * @return {Array} shortened Array
82171           * @example
82172           * <div class = 'norender'><code>
82173           * function setup() {
82174           *   let myArray = ['A', 'B', 'C'];
82175           *   print(myArray); // ['A', 'B', 'C']
82176           *   let newArray = shorten(myArray);
82177           *   print(myArray); // ['A','B','C']
82178           *   print(newArray); // ['A','B']
82179           * }
82180           * </code></div>
82181           */
82182          _main.default.prototype.shorten = function(list) {
82183            list.pop();
82184            return list;
82185          };
82186
82187          /**
82188           * Randomizes the order of the elements of an array. Implements
82189           * <a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>
82190           * Fisher-Yates Shuffle Algorithm</a>.
82191           *
82192           * @method shuffle
82193           * @param  {Array}   array  Array to shuffle
82194           * @param  {Boolean} [bool] modify passed array
82195           * @return {Array}   shuffled Array
82196           * @example
82197           * <div><code>
82198           * function setup() {
82199           *   let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];
82200           *   print(regularArr);
82201           *   shuffle(regularArr, true); // force modifications to passed array
82202           *   print(regularArr);
82203           *
82204           *   // By default shuffle() returns a shuffled cloned array:
82205           *   let newArr = shuffle(regularArr);
82206           *   print(regularArr);
82207           *   print(newArr);
82208           * }
82209           * </code></div>
82210           */
82211          _main.default.prototype.shuffle = function(arr, bool) {
82212            var isView = ArrayBuffer && ArrayBuffer.isView && ArrayBuffer.isView(arr);
82213            arr = bool || isView ? arr : arr.slice();
82214
82215            var rnd,
82216              tmp,
82217              idx = arr.length;
82218            while (idx > 1) {
82219              rnd = (this.random(0, 1) * idx) | 0;
82220
82221              tmp = arr[--idx];
82222              arr[idx] = arr[rnd];
82223              arr[rnd] = tmp;
82224            }
82225
82226            return arr;
82227          };
82228
82229          /**
82230           * Sorts an array of numbers from smallest to largest, or puts an array of
82231           * words in alphabetical order. The original array is not modified; a
82232           * re-ordered array is returned. The count parameter states the number of
82233           * elements to sort. For example, if there are 12 elements in an array and
82234           * count is set to 5, only the first 5 elements in the array will be sorted.
82235           *
82236           * @method sort
82237           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">array.sort()</a> instead.
82238           * @param {Array} list Array to sort
82239           * @param {Integer} [count] number of elements to sort, starting from 0
82240           * @return {Array} the sorted list
82241           *
82242           * @example
82243           * <div class = 'norender'><code>
82244           * function setup() {
82245           *   let words = ['banana', 'apple', 'pear', 'lime'];
82246           *   print(words); // ['banana', 'apple', 'pear', 'lime']
82247           *   let count = 4; // length of array
82248           *
82249           *   words = sort(words, count);
82250           *   print(words); // ['apple', 'banana', 'lime', 'pear']
82251           * }
82252           * </code></div>
82253           * <div class = 'norender'><code>
82254           * function setup() {
82255           *   let numbers = [2, 6, 1, 5, 14, 9, 8, 12];
82256           *   print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]
82257           *   let count = 5; // Less than the length of the array
82258           *
82259           *   numbers = sort(numbers, count);
82260           *   print(numbers); // [1,2,5,6,14,9,8,12]
82261           * }
82262           * </code></div>
82263           */
82264          _main.default.prototype.sort = function(list, count) {
82265            var arr = count ? list.slice(0, Math.min(count, list.length)) : list;
82266            var rest = count ? list.slice(Math.min(count, list.length)) : [];
82267            if (typeof arr[0] === 'string') {
82268              arr = arr.sort();
82269            } else {
82270              arr = arr.sort(function(a, b) {
82271                return a - b;
82272              });
82273            }
82274            return arr.concat(rest);
82275          };
82276
82277          /**
82278           * Inserts a value or an array of values into an existing array. The first
82279           * parameter specifies the initial array to be modified, and the second
82280           * parameter defines the data to be inserted. The third parameter is an index
82281           * value which specifies the array position from which to insert data.
82282           * (Remember that array index numbering starts at zero, so the first position
82283           * is 0, the second position is 1, and so on.)
82284           *
82285           * @method splice
82286           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">array.splice()</a> instead.
82287           * @param {Array}  list Array to splice into
82288           * @param {any}    value value to be spliced in
82289           * @param {Integer} position in the array from which to insert data
82290           * @return {Array} the list
82291           *
82292           * @example
82293           * <div class = 'norender'><code>
82294           * function setup() {
82295           *   let myArray = [0, 1, 2, 3, 4];
82296           *   let insArray = ['A', 'B', 'C'];
82297           *   print(myArray); // [0, 1, 2, 3, 4]
82298           *   print(insArray); // ['A','B','C']
82299           *
82300           *   splice(myArray, insArray, 3);
82301           *   print(myArray); // [0,1,2,'A','B','C',3,4]
82302           * }
82303           * </code></div>
82304           */
82305          _main.default.prototype.splice = function(list, value, index) {
82306            // note that splice returns spliced elements and not an array
82307            Array.prototype.splice.apply(list, [index, 0].concat(value));
82308
82309            return list;
82310          };
82311
82312          /**
82313           * Extracts an array of elements from an existing array. The list parameter
82314           * defines the array from which the elements will be copied, and the start
82315           * and count parameters specify which elements to extract. If no count is
82316           * given, elements will be extracted from the start to the end of the array.
82317           * When specifying the start, remember that the first array element is 0.
82318           * This function does not change the source array.
82319           *
82320           * @method subset
82321           * @deprecated Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">array.slice()</a> instead.
82322           * @param  {Array}  list    Array to extract from
82323           * @param  {Integer} start   position to begin
82324           * @param  {Integer} [count] number of values to extract
82325           * @return {Array}          Array of extracted elements
82326           *
82327           * @example
82328           * <div class = 'norender'><code>
82329           * function setup() {
82330           *   let myArray = [1, 2, 3, 4, 5];
82331           *   print(myArray); // [1, 2, 3, 4, 5]
82332           *
82333           *   let sub1 = subset(myArray, 0, 3);
82334           *   let sub2 = subset(myArray, 2, 2);
82335           *   print(sub1); // [1,2,3]
82336           *   print(sub2); // [3,4]
82337           * }
82338           * </code></div>
82339           */
82340          _main.default.prototype.subset = function(list, start, count) {
82341            if (typeof count !== 'undefined') {
82342              return list.slice(start, start + count);
82343            } else {
82344              return list.slice(start, list.length);
82345            }
82346          };
82347          var _default = _main.default;
82348          exports.default = _default;
82349        },
82350        { '../core/main': 59 }
82351      ],
82352      99: [
82353        function(_dereq_, module, exports) {
82354          'use strict';
82355          Object.defineProperty(exports, '__esModule', { value: true });
82356          exports.default = void 0;
82357
82358          var _main = _interopRequireDefault(_dereq_('../core/main'));
82359          function _interopRequireDefault(obj) {
82360            return obj && obj.__esModule ? obj : { default: obj };
82361          }
82362          /**
82363           * @module Data
82364           * @submodule Conversion
82365           * @for p5
82366           * @requires core
82367           */ /**
82368           * Converts a string to its floating point representation. The contents of a
82369           * string must resemble a number, or NaN (not a number) will be returned.
82370           * For example, float("1234.56") evaluates to 1234.56, but float("giraffe")
82371           * will return NaN.
82372           *
82373           * When an array of values is passed in, then an array of floats of the same
82374           * length is returned.
82375           *
82376           * @method float
82377           * @param {String}  str float string to parse
82378           * @return {Number}     floating point representation of string
82379           * @example
82380           * <div><code>
82381           * let str = '20';
82382           * let diameter = float(str);
82383           * ellipse(width / 2, height / 2, diameter, diameter);
82384           * </code></div>
82385           * <div class='norender'><code>
82386           * print(float('10.31')); // 10.31
82387           * print(float('Infinity')); // Infinity
82388           * print(float('-Infinity')); // -Infinity
82389           * </code></div>
82390           *
82391           * @alt
82392           * 20 by 20 white ellipse in the center of the canvas
82393           */ _main.default.prototype.float = function(str) {
82394            if (str instanceof Array) {
82395              return str.map(parseFloat);
82396            }
82397            return parseFloat(str);
82398          };
82399
82400          /**
82401           * Converts a boolean, string, or float to its integer representation.
82402           * When an array of values is passed in, then an int array of the same length
82403           * is returned.
82404           *
82405           * @method int
82406           * @param {String|Boolean|Number}       n value to parse
82407           * @param {Integer}       [radix] the radix to convert to (default: 10)
82408           * @return {Number}                     integer representation of value
82409           *
82410           * @example
82411           * <div class='norender'><code>
82412           * print(int('10')); // 10
82413           * print(int(10.31)); // 10
82414           * print(int(-10)); // -10
82415           * print(int(true)); // 1
82416           * print(int(false)); // 0
82417           * print(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]
82418           * print(int(Infinity)); // Infinity
82419           * print(int('-Infinity')); // -Infinity
82420           * </code></div>
82421           */
82422          /**
82423           * @method int
82424           * @param {Array} ns                    values to parse
82425           * @return {Number[]}                   integer representation of values
82426           */
82427          _main.default.prototype.int = function(n) {
82428            var radix =
82429              arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
82430            if (n === Infinity || n === 'Infinity') {
82431              return Infinity;
82432            } else if (n === -Infinity || n === '-Infinity') {
82433              return -Infinity;
82434            } else if (typeof n === 'string') {
82435              return parseInt(n, radix);
82436            } else if (typeof n === 'number') {
82437              return n | 0;
82438            } else if (typeof n === 'boolean') {
82439              return n ? 1 : 0;
82440            } else if (n instanceof Array) {
82441              return n.map(function(n) {
82442                return _main.default.prototype.int(n, radix);
82443              });
82444            }
82445          };
82446
82447          /**
82448           * Converts a boolean, string or number to its string representation.
82449           * When an array of values is passed in, then an array of strings of the same
82450           * length is returned.
82451           *
82452           * @method str
82453           * @param {String|Boolean|Number|Array} n value to parse
82454           * @return {String}
82454                     string representation of value
82455           * @example
82456           * <div class='norender'><code>
82457           * print(str('10')); // "10"
82458           * print(str(10.31)); // "10.31"
82459           * print(str(-10)); // "-10"
82460           * print(str(true)); // "true"
82461           * print(str(false)); // "false"
82462           * print(str([true, '10.3', 9.8])); // [ "true", "10.3", "9.8" ]
82463           * </code></div>
82464           */
82465          _main.default.prototype.str = function(n) {
82466            if (n instanceof Array) {
82467              return n.map(_main.default.prototype.str);
82468            } else {
82469              return String(n);
82470            }
82471          };
82472
82473          /**
82474           * Converts a number or string to its boolean representation.
82475           * For a number, any non-zero value (positive or negative) evaluates to true,
82476           * while zero evaluates to false. For a string, the value "true" evaluates to
82477           * true, while any other value evaluates to false. When an array of number or
82478           * string values is passed in, then a array of booleans of the same length is
82479           * returned.
82480           *
82481           * @method boolean
82482           * @param {String|Boolean|Number|Array} n value to parse
82483           * @return {Boolean}                    boolean representation of value
82484           * @example
82485           * <div class='norender'><code>
82486           * print(boolean(0)); // false
82487           * print(boolean(1)); // true
82488           * print(boolean('true')); // true
82489           * print(boolean('abcd')); // false
82490           * print(boolean([0, 12, 'true'])); // [false, true, true]
82491           * </code></div>
82492           */
82493          _main.default.prototype.boolean = function(n) {
82494            if (typeof n === 'number') {
82495              return n !== 0;
82496            } else if (typeof n === 'string') {
82497              return n.toLowerCase() === 'true';
82498            } else if (typeof n === 'boolean') {
82499              return n;
82500            } else if (n instanceof Array) {
82501              return n.map(_main.default.prototype.boolean);
82502            }
82503          };
82504
82505          /**
82506           * Converts a number, string representation of a number, or boolean to its byte
82507           * representation. A byte can be only a whole number between -128 and 127, so
82508           * when a value outside of this range is converted, it wraps around to the
82509           * corresponding byte representation. When an array of number, string or boolean
82510           * values is passed in, then an array of bytes the same length is returned.
82511           *
82512           * @method byte
82513           * @param {String|Boolean|Number}       n value to parse
82514           * @return {Number}                     byte representation of value
82515           *
82516           * @example
82517           * <div class='norender'><code>
82518           * print(byte(127)); // 127
82519           * print(byte(128)); // -128
82520           * print(byte(23.4)); // 23
82521           * print(byte('23.4')); // 23
82522           * print(byte('hello')); // NaN
82523           * print(byte(true)); // 1
82524           * print(byte([0, 255, '100'])); // [0, -1, 100]
82525           * </code></div>
82526           */
82527          /**
82528           * @method byte
82529           * @param {Array} ns                   values to parse
82530           * @return {Number[]}                  array of byte representation of values
82531           */
82532          _main.default.prototype.byte = function(n) {
82533            var nn = _main.default.prototype.int(n, 10);
82534            if (typeof nn === 'number') {
82535              return (nn + 128) % 256 - 128;
82536            } else if (nn instanceof Array) {
82537              return nn.map(_main.default.prototype.byte);
82538            }
82539          };
82540
82541          /**
82542           * Converts a number or string to its corresponding single-character
82543           * string representation. If a string parameter is provided, it is first
82544           * parsed as an integer and then translated into a single-character string.
82545           * When an array of number or string values is passed in, then an array of
82546           * single-character strings of the same length is returned.
82547           *
82548           * @method char
82549           * @param {String|Number}       n value to parse
82550           * @return {String}
82550             string representation of value
82551           *
82552           * @example
82553           * <div class='norender'><code>
82554           * print(char(65)); // "A"
82555           * print(char('65')); // "A"
82556           * print(char([65, 66, 67])); // [ "A", "B", "C" ]
82557           * print(join(char([65, 66, 67]), '')); // "ABC"
82558           * </code></div>
82559           */
82560          /**
82561           * @method char
82562           * @param {Array} ns              values to parse
82563           * @return {String[]}             array of string representation of values
82564           */
82565          _main.default.prototype.char = function(n) {
82566            if (typeof n === 'number' && !isNaN(n)) {
82567              return String.fromCharCode(n);
82568            } else if (n instanceof Array) {
82569              return n.map(_main.default.prototype.char);
82570            } else if (typeof n === 'string') {
82571              return _main.default.prototype.char(parseInt(n, 10));
82572            }
82573          };
82574
82575          /**
82576           * Converts a single-character string to its corresponding integer
82577           * representation. When an array of single-character string values is passed
82578           * in, then an array of integers of the same length is returned.
82579           *
82580           * @method unchar
82581           * @param {String} n     value to parse
82582           * @return {Number}      integer representation of value
82583           *
82584           * @example
82585           * <div class='norender'><code>
82586           * print(unchar('A')); // 65
82587           * print(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]
82588           * print(unchar(split('ABC', ''))); // [ 65, 66, 67 ]
82589           * </code></div>
82590           */
82591          /**
82592           * @method unchar
82593           * @param {Array} ns       values to parse
82594           * @return {Number[]}      integer representation of values
82595           */
82596          _main.default.prototype.unchar = function(n) {
82597            if (typeof n === 'string' && n.length === 1) {
82598              return n.charCodeAt(0);
82599            } else if (n instanceof Array) {
82600              return n.map(_main.default.prototype.unchar);
82601            }
82602          };
82603
82604          /**
82605           * Converts a number to a string in its equivalent hexadecimal notation. If a
82606           * second parameter is passed, it is used to set the number of characters to
82607           * generate in the hexadecimal notation. When an array is passed in, an
82608           * array of strings in hexadecimal notation of the same length is returned.
82609           *
82610           * @method hex
82611           * @param {Number} n     value to parse
82612           * @param {Number} [digits]
82613           * @return {String}      hexadecimal string representation of value
82614           *
82615           * @example
82616           * <div class='norender'><code>
82617           * print(hex(255)); // "000000FF"
82618           * print(hex(255, 6)); // "0000FF"
82619           * print(hex([0, 127, 255], 6)); // [ "000000", "00007F", "0000FF" ]
82620           * print(Infinity); // "FFFFFFFF"
82621           * print(-Infinity); // "00000000"
82622           * </code></div>
82623           */
82624          /**
82625           * @method hex
82626           * @param {Number[]} ns    array of values to parse
82627           * @param {Number} [digits]
82628           * @return {String[]}      hexadecimal string representation of values
82629           */
82630          _main.default.prototype.hex = function(n, digits) {
82631            digits = digits === undefined || digits === null ? (digits = 8) : digits;
82632            if (n instanceof Array) {
82633              return n.map(function(n) {
82634                return _main.default.prototype.hex(n, digits);
82635              });
82636            } else if (n === Infinity || n === -Infinity) {
82637              var c = n === Infinity ? 'F' : '0';
82638              return c.repeat(digits);
82639            } else if (typeof n === 'number') {
82640              if (n < 0) {
82641                n = 0xffffffff + n + 1;
82642              }
82643              var hex = Number(n)
82644                .toString(16)
82645                .toUpperCase();
82646              while (hex.length < digits) {
82647                hex = '0'.concat(hex);
82648              }
82649              if (hex.length >= digits) {
82650                hex = hex.substring(hex.length - digits, hex.length);
82651              }
82652              return hex;
82653            }
82654          };
82655
82656          /**
82657           * Converts a string representation of a hexadecimal number to its equivalent
82658           * integer value. When an array of strings in hexadecimal notation is passed
82659           * in, an array of integers of the same length is returned.
82660           *
82661           * @method unhex
82662           * @param {String} n value to parse
82663           * @return {Number}      integer representation of hexadecimal value
82664           *
82665           * @example
82666           * <div class='norender'><code>
82667           * print(unhex('A')); // 10
82668           * print(unhex('FF')); // 255
82669           * print(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]
82670           * </code></div>
82671           */
82672          /**
82673           * @method unhex
82674           * @param {Array} ns values to parse
82675           * @return {Number[]}      integer representations of hexadecimal value
82676           */
82677          _main.default.prototype.unhex = function(n) {
82678            if (n instanceof Array) {
82679              return n.map(_main.default.prototype.unhex);
82680            } else {
82681              return parseInt('0x'.concat(n), 16);
82682            }
82683          };
82684          var _default = _main.default;
82685          exports.default = _default;
82686        },
82687        { '../core/main': 59 }
82688      ],
82689      100: [
82690        function(_dereq_, module, exports) {
82691          'use strict';
82692          Object.defineProperty(exports, '__esModule', { value: true });
82693          exports.default = void 0;
82694
82695          var _main = _interopRequireDefault(_dereq_('../core/main'));
82696          _dereq_('../core/friendly_errors/validate_params');
82697          _dereq_('../core/friendly_errors/file_errors');
82698          _dereq_('../core/friendly_errors/fes_core');
82699          function _interopRequireDefault(obj) {
82700            return obj && obj.__esModule ? obj : { default: obj };
82701          } /** //return p5; //LM is this a mistake?
82702           * @module Data
82703           * @submodule String Functions
82704           * @for p5
82705           * @requires core
82706           */
82707          /**
82708           * Combines an array of Strings into one String, each separated by the
82709           * character(s) used for the separator parameter. To join arrays of ints or
82710           * floats, it's necessary to first convert them to Strings using <a href="#/p5/nf">nf()</a> or
82711           * nfs().
82712           *
82713           * @method join
82714           * @param  {Array}  list      array of Strings to be joined
82715           * @param  {String} separator String to be placed between each item
82716           * @return {String}           joined String
82717           * @example
82718           * <div>
82719           * <code>
82720           * let array = ['Hello', 'world!'];
82721           * let separator = ' ';
82722           * let message = join(array, separator);
82723           * text(message, 5, 50);
82724           * </code>
82725           * </div>
82726           *
82727           * @alt
82728           * "hello world!" displayed middle left of canvas.
82729           */ _main.default.prototype.join = function(list, separator) {
82730            _main.default._validateParameters('join', arguments);
82731            return list.join(separator);
82732          };
82733
82734          /**
82735           * This function is used to apply a regular expression to a piece of text,
82736           * and return matching groups (elements found inside parentheses) as a
82737           * String array. If there are no matches, a null value will be returned.
82738           * If no groups are specified in the regular expression, but the sequence
82739           * matches, an array of length 1 (with the matched text as the first element
82740           * of the array) will be returned.
82741           *
82742           * To use the function, first check to see if the result is null. If the
82743           * result is null, then the sequence did not match at all. If the sequence
82744           * did match, an array is returned.
82745           *
82746           * If there are groups (specified by sets of parentheses) in the regular
82747           * expression, then the contents of each will be returned in the array.
82748           * Element [0] of a regular expression match returns the entire matching
82749           * string, and the match groups start at element [1] (the first group is [1],
82750           * the second [2], and so on).
82751           *
82752           * @method match
82753           * @param  {String} str    the String to be searched
82754           * @param  {String} regexp the regexp to be used for matching
82755           * @return {String[]}      Array of Strings found
82756           * @example
82757           * <div>
82758           * <code>
82759           * let string = 'Hello p5js*!';
82760           * let regexp = 'p5js\\*';
82761           * let m = match(string, regexp);
82762           * text(m, 5, 50);
82763           * </code>
82764           * </div>
82765           *
82766           * @alt
82767           * "p5js*" displayed middle left of canvas.
82768           */
82769          _main.default.prototype.match = function(str, reg) {
82770            _main.default._validateParameters('match', arguments);
82771            return str.match(reg);
82772          };
82773
82774          /**
82775           * This function is used to apply a regular expression to a piece of text,
82776           * and return a list of matching groups (elements found inside parentheses)
82777           * as a two-dimensional String array. If there are no matches, a null value
82778           * will be returned. If no groups are specified in the regular expression,
82779           * but the sequence matches, a two dimensional array is still returned, but
82780           * the second dimension is only of length one.
82781           *
82782           * To use the function, first check to see if the result is null. If the
82783           * result is null, then the sequence did not match at all. If the sequence
82784           * did match, a 2D array is returned.
82785           *
82786           * If there are groups (specified by sets of parentheses) in the regular
82787           * expression, then the contents of each will be returned in the array.
82788           * Assuming a loop with counter variable i, element [i][0] of a regular
82789           * expression match returns the entire matching string, and the match groups
82790           * start at element [i][1] (the first group is [i][1], the second [i][2],
82791           * and so on).
82792           *
82793           * @method matchAll
82794           * @param  {String} str    the String to be searched
82795           * @param  {String} regexp the regexp to be used for matching
82796           * @return {String[]}         2d Array of Strings found
82797           * @example
82798           * <div class="norender">
82799           * <code>
82800           * let string = 'Hello p5js*! Hello world!';
82801           * let regexp = 'Hello';
82802           * matchAll(string, regexp);
82803           * </code>
82804           * </div>
82805           */
82806          _main.default.prototype.matchAll = function(str, reg) {
82807            _main.default._validateParameters('matchAll', arguments);
82808            var re = new RegExp(reg, 'g');
82809            var match = re.exec(str);
82810            var matches = [];
82811            while (match !== null) {
82812              matches.push(match);
82813              // matched text: match[0]
82814              // match start: match.index
82815              // capturing group n: match[n]
82816              match = re.exec(str);
82817            }
82818            return matches;
82819          };
82820
82821          /**
82822           * Utility function for formatting numbers into strings. There are two
82823           * versions: one for formatting floats, and one for formatting ints.
82824           * The values for the digits, left, and right parameters should always
82825           * be positive integers.
82826           * (NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter
82827           * if greater than the current length of the number.
82828           * For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123
82829           * (integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than
82830           * the result will be 123.200.
82831           *
82832           * @method nf
82833           * @param {Number|String}       num      the Number to format
82834           * @param {Integer|String}      [left]   number of digits to the left of the
82835           *                                decimal point
82836           * @param {Integer|String}      [right]  number of digits to the right of the
82837           *                                decimal point
82838           * @return {String}               formatted String
82839           *
82840           * @example
82841           * <div>
82842           * <code>
82843           * let myFont;
82844           * function preload() {
82845           *   myFont = loadFont('assets/fonts/inconsolata.ttf');
82846           * }
82847           * function setup() {
82848           *   background(200);
82849           *   let num1 = 321;
82850           *   let num2 = -1321;
82851           *
82852           *   noStroke();
82853           *   fill(0);
82854           *   textFont(myFont);
82855           *   textSize(22);
82856           *
82857           *   text(nf(num1, 4, 2), 10, 30);
82858           *   text(nf(num2, 4, 2), 10, 80);
82859           *   // Draw dividing line
82860           *   stroke(120);
82861           *   line(0, 50, width, 50);
82862           * }
82863           * </code>
82864           * </div>
82865           *
82866           * @alt
82867           * "0321.00" middle top, -1321.00" middle bottom canvas
82868           */
82869          /**
82870           * @method nf
82871           * @param {Array}        nums     the Numbers to format
82872           * @param {Integer|String}      [left]
82873           * @param {Integer|String}      [right]
82874           * @return {String[]}                formatted Strings
82875           */
82876          _main.default.prototype.nf = function(nums, left, right) {
82877            _main.default._validateParameters('nf', arguments);
82878            if (nums instanceof Array) {
82879              return nums.map(function(x) {
82880                return doNf(x, left, right);
82881              });
82882            } else {
82883              var typeOfFirst = Object.prototype.toString.call(nums);
82884              if (typeOfFirst === '[object Arguments]') {
82885                if (nums.length === 3) {
82886                  return this.nf(nums[0], nums[1], nums[2]);
82887                } else if (nums.length === 2) {
82888                  return this.nf(nums[0], nums[1]);
82889                } else {
82890                  return this.nf(nums[0]);
82891                }
82892              } else {
82893                return doNf(nums, left, right);
82894              }
82895            }
82896          };
82897
82898          function doNf(num, left, right) {
82899            var neg = num < 0;
82900            var n = neg ? num.toString().substring(1) : num.toString();
82901            var decimalInd = n.indexOf('.');
82902            var intPart = decimalInd !== -1 ? n.substring(0, decimalInd) : n;
82903            var decPart = decimalInd !== -1 ? n.substring(decimalInd + 1) : '';
82904            var str = neg ? '-' : '';
82905            if (typeof right !== 'undefined') {
82906              var decimal = '';
82907              if (decimalInd !== -1 || right - decPart.length > 0) {
82908                decimal = '.';
82909              }
82910              if (decPart.length > right) {
82911                decPart = decPart.substring(0, right);
82912              }
82913              for (var i = 0; i < left - intPart.length; i++) {
82914                str += '0';
82915              }
82916              str += intPart;
82917              str += decimal;
82918              str += decPart;
82919              for (var j = 0; j < right - decPart.length; j++) {
82920                str += '0';
82921              }
82922              return str;
82923            } else {
82924              for (var k = 0; k < Math.max(left - intPart.length, 0); k++) {
82925                str += '0';
82926              }
82927              str += n;
82928              return str;
82929            }
82930          }
82931
82932          /**
82933           * Utility function for formatting numbers into strings and placing
82934           * appropriate commas to mark units of 1000. There are two versions: one
82935           * for formatting ints, and one for formatting an array of ints. The value
82936           * for the right parameter should always be a positive integer.
82937           *
82938           * @method nfc
82939           * @param  {Number|String}   num     the Number to format
82940           * @param  {Integer|String}  [right] number of digits to the right of the
82941           *                                  decimal point
82942           * @return {String}           formatted String
82943           *
82944           * @example
82945           * <div>
82946           * <code>
82947           * function setup() {
82948           *   background(200);
82949           *   let num = 11253106.115;
82950           *   let numArr = [1, 1, 2];
82951           *
82952           *   noStroke();
82953           *   fill(0);
82954           *   textSize(12);
82955           *
82956           *   // Draw formatted numbers
82957           *   text(nfc(num, 4), 10, 30);
82958           *   text(nfc(numArr, 2), 10, 80);
82959           *
82960           *   // Draw dividing line
82961           *   stroke(120);
82962           *   line(0, 50, width, 50);
82963           * }
82964           * </code>
82965           * </div>
82966           *
82967           * @alt
82968           * "11,253,106.115" top middle and "1.00,1.00,2.00" displayed bottom mid
82969           */
82970          /**
82971           * @method nfc
82972           * @param  {Array}    nums     the Numbers to format
82973           * @param  {Integer|String}  [right]
82974           * @return {String[]}           formatted Strings
82975           */
82976          _main.default.prototype.nfc = function(num, right) {
82977            _main.default._validateParameters('nfc', arguments);
82978            if (num instanceof Array) {
82979              return num.map(function(x) {
82980                return doNfc(x, right);
82981              });
82982            } else {
82983              return doNfc(num, right);
82984            }
82985          };
82986          function doNfc(num, right) {
82987            num = num.toString();
82988            var dec = num.indexOf('.');
82989            var rem = dec !== -1 ? num.substring(dec) : '';
82990            var n = dec !== -1 ? num.substring(0, dec) : num;
82991            n = n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
82992            if (right === 0) {
82993              rem = '';
82994            } else if (typeof right !== 'undefined') {
82995              if (right > rem.length) {
82996                rem += dec === -1 ? '.' : '';
82997                var len = right - rem.length + 1;
82998                for (var i = 0; i < len; i++) {
82999                  rem += '0';
83000                }
83001              } else {
83002                rem = rem.substring(0, right + 1);
83003              }
83004            }
83005            return n + rem;
83006          }
83007
83008          /**
83009           * Utility function for formatting numbers into strings. Similar to <a href="#/p5/nf">nf()</a> but
83010           * puts a "+" in front of positive numbers and a "-" in front of negative
83011           * numbers. There are two versions: one for formatting floats, and one for
83012           * formatting ints. The values for left, and right parameters
83013           * should always be positive integers.
83014           *
83015           * @method nfp
83016           * @param {Number} num      the Number to format
83017           * @param {Integer}      [left]   number of digits to the left of the decimal
83018           *                                point
83019           * @param {Integer}      [right]  number of digits to the right of the
83020           *                                decimal point
83021           * @return {String}         formatted String
83022           *
83023           * @example
83024           * <div>
83025           * <code>
83026           * function setup() {
83027           *   background(200);
83028           *   let num1 = 11253106.115;
83029           *   let num2 = -11253106.115;
83030           *
83031           *   noStroke();
83032           *   fill(0);
83033           *   textSize(12);
83034           *
83035           *   // Draw formatted numbers
83036           *   text(nfp(num1, 4, 2), 10, 30);
83037           *   text(nfp(num2, 4, 2), 10, 80);
83038           *
83039           *   // Draw dividing line
83040           *   stroke(120);
83041           *   line(0, 50, width, 50);
83042           * }
83043           * </code>
83044           * </div>
83045           *
83046           * @alt
83047           * "+11253106.11" top middle and "-11253106.11" displayed bottom middle
83048           */
83049          /**
83050           * @method nfp
83051           * @param {Number[]} nums      the Numbers to format
83052           * @param {Integer}      [left]
83053           * @param {Integer}      [right]
83054           * @return {String[]}         formatted Strings
83055           */
83056          _main.default.prototype.nfp = function() {
83057            for (
83058              var _len = arguments.length, args = new Array(_len), _key = 0;
83059              _key < _len;
83060              _key++
83061            ) {
83062              args[_key] = arguments[_key];
83063            }
83064            _main.default._validateParameters('nfp', args);
83065            var nfRes = _main.default.prototype.nf.apply(this, args);
83066            if (nfRes instanceof Array) {
83067              return nfRes.map(addNfp);
83068            } else {
83069              return addNfp(nfRes);
83070            }
83071          };
83072
83073          function addNfp(num) {
83074            return parseFloat(num) > 0 ? '+'.concat(num.toString()) : num.toString();
83075          }
83076
83077          /**
83078           * Utility function for formatting numbers into strings. Similar to <a href="#/p5/nf">nf()</a> but
83079           * puts an additional "_" (space) in front of positive numbers just in case to align it with negative
83080           * numbers which includes "-" (minus) sign.
83081           * The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative
83082           * number with some negative number (See the example to get a clear picture).
83083           * There are two versions: one for formatting float, and one for formatting int.
83084           * The values for the digits, left, and right parameters should always be positive integers.
83085           * (IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.
83086           * (NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter
83087           * if greater than the current length of the number.
83088           * For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123
83089           * (integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than
83090           * the result will be 123.200.
83091           *
83092           * @method nfs
83093           * @param {Number}       num      the Number to format
83094           * @param {Integer}      [left]   number of digits to the left of the decimal
83095           *                                point
83096           * @param {Integer}      [right]  number of digits to the right of the
83097           *                                decimal point
83098           * @return {String}         formatted String
83099           *
83100           * @example
83101           * <div>
83102           * <code>
83103           * let myFont;
83104           * function preload() {
83105           *   myFont = loadFont('assets/fonts/inconsolata.ttf');
83106           * }
83107           * function setup() {
83108           *   background(200);
83109           *   let num1 = 321;
83110           *   let num2 = -1321;
83111           *
83112           *   noStroke();
83113           *   fill(0);
83114           *   textFont(myFont);
83115           *   textSize(22);
83116           *
83117           *   // nfs() aligns num1 (positive number) with num2 (negative number) by
83118           *   // adding a blank space in front of the num1 (positive number)
83119           *   // [left = 4] in num1 add one 0 in front, to align the digits with num2
83120           *   // [right = 2] in num1 and num2 adds two 0's after both numbers
83121           *   // To see the differences check the example of nf() too.
83122           *   text(nfs(num1, 4, 2), 10, 30);
83123           *   text(nfs(num2, 4, 2), 10, 80);
83124           *   // Draw dividing line
83125           *   stroke(120);
83126           *   line(0, 50, width, 50);
83127           * }
83128           * </code>
83129           * </div>
83130           *
83131           * @alt
83132           * "0321.00" top middle and "-1321.00" displayed bottom middle
83133           */
83134          /**
83135           * @method nfs
83136           * @param {Array}        nums     the Numbers to format
83137           * @param {Integer}      [left]
83138           * @param {Integer}      [right]
83139           * @return {String[]}         formatted Strings
83140           */
83141          _main.default.prototype.nfs = function() {
83142            for (
83143              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
83144              _key2 < _len2;
83145              _key2++
83146            ) {
83147              args[_key2] = arguments[_key2];
83148            }
83149            _main.default._validateParameters('nfs', args);
83150            var nfRes = _main.default.prototype.nf.apply(this, args);
83151            if (nfRes instanceof Array) {
83152              return nfRes.map(addNfs);
83153            } else {
83154              return addNfs(nfRes);
83155            }
83156          };
83157
83158          function addNfs(num) {
83159            return parseFloat(num) >= 0 ? ' '.concat(num.toString()) : num.toString();
83160          }
83161
83162          /**
83163           * The <a href="#/p5/split">split()</a> function maps to String.split(), it breaks a String into
83164           * pieces using a character or string as the delimiter. The delim parameter
83165           * specifies the character or characters that mark the boundaries between
83166           * each piece. A String[] array is returned that contains each of the pieces.
83167           *
83168           * The <a href="#/p5/splitTokens">splitTokens()</a> function works in a similar fashion, except that it
83169           * splits using a range of characters instead of a specific character or
83170           * sequence.
83171           *
83172           * @method split
83173           * @param  {String} value the String to be split
83174           * @param  {String} delim the String used to separate the data
83175           * @return {String[]}  Array of Strings
83176           * @example
83177           * <div>
83178           * <code>
83179           * let names = 'Pat,Xio,Alex';
83180           * let splitString = split(names, ',');
83181           * text(splitString[0], 5, 30);
83182           * text(splitString[1], 5, 50);
83183           * text(splitString[2], 5, 70);
83184           * </code>
83185           * </div>
83186           *
83187           * @alt
83188           * "pat" top left, "Xio" mid left and "Alex" displayed bottom left
83189           */
83190          _main.default.prototype.split = function(str, delim) {
83191            _main.default._validateParameters('split', arguments);
83192            return str.split(delim);
83193          };
83194
83195          /**
83196           * The <a href="#/p5/splitTokens">splitTokens()</a> function splits a String at one or many character
83197           * delimiters or "tokens." The delim parameter specifies the character or
83198           * characters to be used as a boundary.
83199           *
83200           * If no delim characters are specified, any whitespace character is used to
83201           * split. Whitespace characters include tab (\t), line feed (\n), carriage
83202           * return (\r), form feed (\f), and space.
83203           *
83204           * @method splitTokens
83205           * @param  {String} value   the String to be split
83206           * @param  {String} [delim] list of individual Strings that will be used as
83207           *                          separators
83208           * @return {String[]}          Array of Strings
83209           * @example
83210           * <div class = "norender">
83211           * <code>
83212           * function setup() {
83213           *   let myStr = 'Mango, Banana, Lime';
83214           *   let myStrArr = splitTokens(myStr, ',');
83215           *
83216           *   print(myStrArr); // prints : ["Mango"," Banana"," Lime"]
83217           * }
83218           * </code>
83219           * </div>
83220           */
83221          _main.default.prototype.splitTokens = function(value, delims) {
83222            _main.default._validateParameters('splitTokens', arguments);
83223            var d;
83224            if (typeof delims !== 'undefined') {
83225              var str = delims;
83226              var sqc = /\]/g.exec(str);
83227              var sqo = /\[/g.exec(str);
83228              if (sqo && sqc) {
83229                str = str.slice(0, sqc.index) + str.slice(sqc.index + 1);
83230                sqo = /\[/g.exec(str);
83231                str = str.slice(0, sqo.index) + str.slice(sqo.index + 1);
83232                d = new RegExp('[\\['.concat(str, '\\]]'), 'g');
83233              } else if (sqc) {
83234                str = str.slice(0, sqc.index) + str.slice(sqc.index + 1);
83235                d = new RegExp('['.concat(str, '\\]]'), 'g');
83236              } else if (sqo) {
83237                str = str.slice(0, sqo.index) + str.slice(sqo.index + 1);
83238                d = new RegExp('['.concat(str, '\\[]'), 'g');
83239              } else {
83240                d = new RegExp('['.concat(str, ']'), 'g');
83241              }
83242            } else {
83243              d = /\s/g;
83244            }
83245            return value.split(d).filter(function(n) {
83246              return n;
83247            });
83248          };
83249
83250          /**
83251           * Removes whitespace characters from the beginning and end of a String. In
83252           * addition to standard whitespace characters such as space, carriage return,
83253           * and tab, this function also removes the Unicode "nbsp" character.
83254           *
83255           * @method trim
83256           * @param  {String} str a String to be trimmed
83257           * @return {String}       a trimmed String
83258           *
83259           * @example
83260           * <div>
83261           * <code>
83262           * let string = trim('  No new lines\n   ');
83263           * text(string + ' here', 2, 50);
83264           * </code>
83265           * </div>
83266           *
83267           * @alt
83268           * "No new lines here" displayed center canvas
83269           */
83270          /**
83271           * @method trim
83272           * @param  {Array} strs an Array of Strings to be trimmed
83273           * @return {String[]}   an Array of trimmed Strings
83274           */
83275          _main.default.prototype.trim = function(str) {
83276            _main.default._validateParameters('trim', arguments);
83277            if (str instanceof Array) {
83278              return str.map(this.trim);
83279            } else {
83280              return str.trim();
83281            }
83282          };
83283          var _default = _main.default;
83284          exports.default = _default;
83285        },
83286        {
83287          '../core/friendly_errors/fes_core': 51,
83288          '../core/friendly_errors/file_errors': 52,
83289          '../core/friendly_errors/validate_params': 54,
83290          '../core/main': 59
83291        }
83292      ],
83293      101: [
83294        function(_dereq_, module, exports) {
83295          'use strict';
83296          Object.defineProperty(exports, '__esModule', { value: true });
83297          exports.default = void 0;
83298
83299          var _main = _interopRequireDefault(_dereq_('../core/main'));
83300          function _interopRequireDefault(obj) {
83301            return obj && obj.__esModule ? obj : { default: obj };
83302          }
83303          /**
83304           * @module IO
83305           * @submodule Time & Date
83306           * @for p5
83307           * @requires core
83308           */ /**
83309           * p5.js communicates with the clock on your computer. The <a href="#/p5/day">day()</a> function
83310           * returns the current day as a value from 1 - 31.
83311           *
83312           * @method day
83313           * @return {Integer} the current day
83314           * @example
83315           * <div>
83316           * <code>
83317           * let d = day();
83318           * text('Current day: \n' + d, 5, 50);
83319           * </code>
83320           * </div>
83321           *
83322           * @alt
83323           * Current day is displayed
83324           */ _main.default.prototype.day = function() {
83325            return new Date().getDate();
83326          };
83327
83328          /**
83329           * p5.js communicates with the clock on your computer. The <a href="#/p5/hour">hour()</a> function
83330           * returns the current hour as a value from 0 - 23.
83331           *
83332           * @method hour
83333           * @return {Integer} the current hour
83334           * @example
83335           * <div>
83336           * <code>
83337           * let h = hour();
83338           * text('Current hour:\n' + h, 5, 50);
83339           * </code>
83340           * </div>
83341           *
83342           * @alt
83343           * Current hour is displayed
83344           */
83345          _main.default.prototype.hour = function() {
83346            return new Date().getHours();
83347          };
83348
83349          /**
83350           * p5.js communicates with the clock on your computer. The <a href="#/p5/minute">minute()</a> function
83351           * returns the current minute as a value from 0 - 59.
83352           *
83353           * @method minute
83354           * @return {Integer} the current minute
83355           * @example
83356           * <div>
83357           * <code>
83358           * let m = minute();
83359           * text('Current minute: \n' + m, 5, 50);
83360           * </code>
83361           * </div>
83362           *
83363           * @alt
83364           * Current minute is displayed
83365           */
83366          _main.default.prototype.minute = function() {
83367            return new Date().getMinutes();
83368          };
83369
83370          /**
83371           * Returns the number of milliseconds (thousandths of a second) since
83372           * starting the sketch (when `setup()` is called). This information is often
83373           * used for timing events and animation sequences.
83374           *
83375           * @method millis
83376           * @return {Number} the number of milliseconds since starting the sketch
83377           * @example
83378           * <div>
83379           * <code>
83380           * let millisecond = millis();
83381           * text('Milliseconds \nrunning: \n' + millisecond, 5, 40);
83382           * </code>
83383           * </div>
83384           *
83385           * @alt
83386           * number of milliseconds since sketch has started displayed
83387           */
83388          _main.default.prototype.millis = function() {
83389            if (this._millisStart === -1) {
83390              // Sketch has not started
83391              return 0;
83392            } else {
83393              return window.performance.now() - this._millisStart;
83394            }
83395          };
83396
83397          /**
83398           * p5.js communicates with the clock on your computer. The <a href="#/p5/month">month()</a> function
83399           * returns the current month as a value from 1 - 12.
83400           *
83401           * @method month
83402           * @return {Integer} the current month
83403           * @example
83404           * <div>
83405           * <code>
83406           * let m = month();
83407           * text('Current month: \n' + m, 5, 50);
83408           * </code>
83409           * </div>
83410           *
83411           * @alt
83412           * Current month is displayed
83413           */
83414          _main.default.prototype.month = function() {
83415            //January is 0!
83416            return new Date().getMonth() + 1;
83417          };
83418
83419          /**
83420           * p5.js communicates with the clock on your computer. The <a href="#/p5/second">second()</a> function
83421           * returns the current second as a value from 0 - 59.
83422           *
83423           * @method second
83424           * @return {Integer} the current second
83425           * @example
83426           * <div>
83427           * <code>
83428           * let s = second();
83429           * text('Current second: \n' + s, 5, 50);
83430           * </code>
83431           * </div>
83432           *
83433           * @alt
83434           * Current second is displayed
83435           */
83436          _main.default.prototype.second = function() {
83437            return new Date().getSeconds();
83438          };
83439
83440          /**
83441           * p5.js communicates with the clock on your computer. The <a href="#/p5/year">year()</a> function
83442           * returns the current year as an integer (2014, 2015, 2016, etc).
83443           *
83444           * @method year
83445           * @return {Integer} the current year
83446           * @example
83447           * <div>
83448           * <code>
83449           * let y = year();
83450           * text('Current year: \n' + y, 5, 50);
83451           * </code>
83452           * </div>
83453           *
83454           * @alt
83455           * Current year is displayed
83456           */
83457          _main.default.prototype.year = function() {
83458            return new Date().getFullYear();
83459          };
83460          var _default = _main.default;
83461          exports.default = _default;
83462        },
83463        { '../core/main': 59 }
83464      ],
83465      102: [
83466        function(_dereq_, module, exports) {
83467          'use strict';
83468          function _typeof(obj) {
83469            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
83470              _typeof = function _typeof(obj) {
83471                return typeof obj;
83472              };
83473            } else {
83474              _typeof = function _typeof(obj) {
83475                return obj &&
83476                  typeof Symbol === 'function' &&
83477                  obj.constructor === Symbol &&
83478                  obj !== Symbol.prototype
83479                  ? 'symbol'
83480                  : typeof obj;
83481              };
83482            }
83483            return _typeof(obj);
83484          }
83485          Object.defineProperty(exports, '__esModule', { value: true });
83486          exports.default = void 0;
83487
83488          var _main = _interopRequireDefault(_dereq_('../core/main'));
83489          _dereq_('./p5.Geometry');
83490          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
83491          function _getRequireWildcardCache() {
83492            if (typeof WeakMap !== 'function') return null;
83493            var cache = new WeakMap();
83494            _getRequireWildcardCache = function _getRequireWildcardCache() {
83495              return cache;
83496            };
83497            return cache;
83498          }
83499          function _interopRequireWildcard(obj) {
83500            if (obj && obj.__esModule) {
83501              return obj;
83502            }
83503            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
83504              return { default: obj };
83505            }
83506            var cache = _getRequireWildcardCache();
83507            if (cache && cache.has(obj)) {
83508              return cache.get(obj);
83509            }
83510            var newObj = {};
83511            var hasPropertyDescriptor =
83512              Object.defineProperty && Object.getOwnPropertyDescriptor;
83513            for (var key in obj) {
83514              if (Object.prototype.hasOwnProperty.call(obj, key)) {
83515                var desc = hasPropertyDescriptor
83516                  ? Object.getOwnPropertyDescriptor(obj, key)
83517                  : null;
83518                if (desc && (desc.get || desc.set)) {
83519                  Object.defineProperty(newObj, key, desc);
83520                } else {
83521                  newObj[key] = obj[key];
83522                }
83523              }
83524            }
83525            newObj.default = obj;
83526            if (cache) {
83527              cache.set(obj, newObj);
83528            }
83529            return newObj;
83530          }
83531          function _interopRequireDefault(obj) {
83532            return obj && obj.__esModule ? obj : { default: obj };
83533          }
83534          /**
83535           * @module Shape
83536           * @submodule 3D Primitives
83537           * @for p5
83538           * @requires core
83539           * @requires p5.Geometry
83540           */ /**
83541           * Draw a plane with given a width and height
83542           * @method plane
83543           * @param  {Number} [width]    width of the plane
83544           * @param  {Number} [height]   height of the plane
83545           * @param  {Integer} [detailX]  Optional number of triangle
83546           *                             subdivisions in x-dimension
83547           * @param {Integer} [detailY]   Optional number of triangle
83548           *                             subdivisions in y-dimension
83549           * @chainable
83550           * @example
83551           * <div>
83552           * <code>
83553           * // draw a plane
83554           * // with width 50 and height 50
83555           * function setup() {
83556           *   createCanvas(100, 100, WEBGL);
83557           * }
83558           *
83559           * function draw() {
83560           *   background(200);
83561           *   plane(50, 50);
83562           * }
83563           * </code>
83564           * </div>
83565           *
83566           * @alt
83567           * Nothing displayed on canvas
83568           * Rotating interior view of a box with sides that change color.
83569           * 3d red and green gradient.
83570           * Rotating interior view of a cylinder with sides that change color.
83571           * Rotating view of a cylinder with sides that change color.
83572           * 3d red and green gradient.
83573           * rotating view of a multi-colored cylinder with concave sides.
83574           */ _main.default.prototype.plane = function(width, height, detailX, detailY) {
83575            this._assert3d('plane');
83576            _main.default._validateParameters('plane', arguments);
83577            if (typeof width === 'undefined') {
83578              width = 50;
83579            }
83580            if (typeof height === 'undefined') {
83581              height = width;
83582            }
83583
83584            if (typeof detailX === 'undefined') {
83585              detailX = 1;
83586            }
83587            if (typeof detailY === 'undefined') {
83588              detailY = 1;
83589            }
83590
83591            var gId = 'plane|'.concat(detailX, '|').concat(detailY);
83592
83593            if (!this._renderer.geometryInHash(gId)) {
83594              var _plane = function _plane() {
83595                var u, v, p;
83596                for (var i = 0; i <= this.detailY; i++) {
83597                  v = i / this.detailY;
83598                  for (var j = 0; j <= this.detailX; j++) {
83599                    u = j / this.detailX;
83600                    p = new _main.default.Vector(u - 0.5, v - 0.5, 0);
83601                    this.vertices.push(p);
83602                    this.uvs.push(u, v);
83603                  }
83604                }
83605              };
83606              var planeGeom = new _main.default.Geometry(detailX, detailY, _plane);
83607              planeGeom.computeFaces().computeNormals();
83608              if (detailX <= 1 && detailY <= 1) {
83609                planeGeom._makeTriangleEdges()._edgesToVertices();
83610              } else if (this._renderer._doStroke) {
83611                console.log(
83612                  'Cannot draw stroke on plane objects with more' +
83613                    ' than 1 detailX or 1 detailY'
83614                );
83615              }
83616              this._renderer.createBuffers(gId, planeGeom);
83617            }
83618
83619            this._renderer.drawBuffersScaled(gId, width, height, 1);
83620            return this;
83621          };
83622
83623          /**
83624           * Draw a box with given width, height and depth
83625           * @method  box
83626           * @param  {Number} [width]     width of the box
83627           * @param  {Number} [Height]    height of the box
83628           * @param  {Number} [depth]     depth of the box
83629           * @param {Integer} [detailX]  Optional number of triangle
83630           *                            subdivisions in x-dimension
83631           * @param {Integer} [detailY]  Optional number of triangle
83632           *                            subdivisions in y-dimension
83633           * @chainable
83634           * @example
83635           * <div>
83636           * <code>
83637           * // draw a spinning box
83638           * // with width, height and depth of 50
83639           * function setup() {
83640           *   createCanvas(100, 100, WEBGL);
83641           * }
83642           *
83643           * function draw() {
83644           *   background(200);
83645           *   rotateX(frameCount * 0.01);
83646           *   rotateY(frameCount * 0.01);
83647           *   box(50);
83648           * }
83649           * </code>
83650           * </div>
83651           */
83652          _main.default.prototype.box = function(width, height, depth, detailX, detailY) {
83653            this._assert3d('box');
83654            _main.default._validateParameters('box', arguments);
83655            if (typeof width === 'undefined') {
83656              width = 50;
83657            }
83658            if (typeof height === 'undefined') {
83659              height = width;
83660            }
83661            if (typeof depth === 'undefined') {
83662              depth = height;
83663            }
83664
83665            var perPixelLighting =
83666              this._renderer.attributes && this._renderer.attributes.perPixelLighting;
83667            if (typeof detailX === 'undefined') {
83668              detailX = perPixelLighting ? 1 : 4;
83669            }
83670            if (typeof detailY === 'undefined') {
83671              detailY = perPixelLighting ? 1 : 4;
83672            }
83673
83674            var gId = 'box|'.concat(detailX, '|').concat(detailY);
83675            if (!this._renderer.geometryInHash(gId)) {
83676              var _box = function _box() {
83677                var cubeIndices = [
83678                  [0, 4, 2, 6], // -1, 0, 0],// -x
83679                  [1, 3, 5, 7], // +1, 0, 0],// +x
83680                  [0, 1, 4, 5], // 0, -1, 0],// -y
83681                  [2, 6, 3, 7], // 0, +1, 0],// +y
83682                  [0, 2, 1, 3], // 0, 0, -1],// -z
83683                  [4, 5, 6, 7] // 0, 0, +1] // +z
83684                ];
83685                //using strokeIndices instead of faces for strokes
83686                //to avoid diagonal stroke lines across face of box
83687                this.strokeIndices = [
83688                  [0, 1],
83689                  [1, 3],
83690                  [3, 2],
83691                  [6, 7],
83692                  [8, 9],
83693                  [9, 11],
83694                  [14, 15],
83695                  [16, 17],
83696                  [17, 19],
83697                  [18, 19],
83698                  [20, 21],
83699                  [22, 23]
83700                ];
83701
83702                for (var i = 0; i < cubeIndices.length; i++) {
83703                  var cubeIndex = cubeIndices[i];
83704                  var v = i * 4;
83705                  for (var j = 0; j < 4; j++) {
83706                    var d = cubeIndex[j];
83707                    //inspired by lightgl:
83708                    //https://github.com/evanw/lightgl.js
83709                    //octants:https://en.wikipedia.org/wiki/Octant_(solid_geometry)
83710                    var octant = new _main.default.Vector(
83711                      ((d & 1) * 2 - 1) / 2,
83712                      ((d & 2) - 1) / 2,
83713                      ((d & 4) / 2 - 1) / 2
83714                    );
83715
83716                    this.vertices.push(octant);
83717                    this.uvs.push(j & 1, (j & 2) / 2);
83718                  }
83719                  this.faces.push([v, v + 1, v + 2]);
83720                  this.faces.push([v + 2, v + 1, v + 3]);
83721                }
83722              };
83723              var boxGeom = new _main.default.Geometry(detailX, detailY, _box);
83724              boxGeom.computeNormals();
83725              if (detailX <= 4 && detailY <= 4) {
83726                boxGeom._makeTriangleEdges()._edgesToVertices();
83727              } else if (this._renderer._doStroke) {
83728                console.log(
83729                  'Cannot draw stroke on box objects with more' +
83730                    ' than 4 detailX or 4 detailY'
83731                );
83732              }
83733              //initialize our geometry buffer with
83734              //the key val pair:
83735              //geometry Id, Geom object
83736              this._renderer.createBuffers(gId, boxGeom);
83737            }
83738            this._renderer.drawBuffersScaled(gId, width, height, depth);
83739
83740            return this;
83741          };
83742
83743          /**
83744           * Draw a sphere with given radius.
83745           *
83746           * DetailX and detailY determines the number of subdivisions in the x-dimension
83747           * and the y-dimension of a sphere. More subdivisions make the sphere seem
83748           * smoother. The recommended maximum values are both 24. Using a value greater
83749           * than 24 may cause a warning or slow down the browser.
83750           * @method sphere
83751           * @param  {Number} [radius]          radius of circle
83752           * @param  {Integer} [detailX]        optional number of subdivisions in x-dimension
83753           * @param  {Integer} [detailY]        optional number of subdivisions in y-dimension
83754           *
83755           * @chainable
83756           * @example
83757           * <div>
83758           * <code>
83759           * // draw a sphere with radius 40
83760           * function setup() {
83761           *   createCanvas(100, 100, WEBGL);
83762           * }
83763           *
83764           * function draw() {
83765           *   background(205, 102, 94);
83766           *   sphere(40);
83767           * }
83768           * </code>
83769           * </div>
83770           *
83771           * @example
83772           * <div>
83773           * <code>
83774           * let detailX;
83775           * // slide to see how detailX works
83776           * function setup() {
83777           *   createCanvas(100, 100, WEBGL);
83778           *   detailX = createSlider(3, 24, 3);
83779           *   detailX.position(10, height + 5);
83780           *   detailX.style('width', '80px');
83781           * }
83782           *
83783           * function draw() {
83784           *   background(205, 105, 94);
83785           *   rotateY(millis() / 1000);
83786           *   sphere(40, detailX.value(), 16);
83787           * }
83788           * </code>
83789           * </div>
83790           *
83791           * @example
83792           * <div>
83793           * <code>
83794           * let detailY;
83795           * // slide to see how detailY works
83796           * function setup() {
83797           *   createCanvas(100, 100, WEBGL);
83798           *   detailY = createSlider(3, 16, 3);
83799           *   detailY.position(10, height + 5);
83800           *   detailY.style('width', '80px');
83801           * }
83802           *
83803           * function draw() {
83804           *   background(205, 105, 94);
83805           *   rotateY(millis() / 1000);
83806           *   sphere(40, 16, detailY.value());
83807           * }
83808           * </code>
83809           * </div>
83810           */
83811          _main.default.prototype.sphere = function(radius, detailX, detailY) {
83812            this._assert3d('sphere');
83813            _main.default._validateParameters('sphere', arguments);
83814            if (typeof radius === 'undefined') {
83815              radius = 50;
83816            }
83817            if (typeof detailX === 'undefined') {
83818              detailX = 24;
83819            }
83820            if (typeof detailY === 'undefined') {
83821              detailY = 16;
83822            }
83823
83824            this.ellipsoid(radius, radius, radius, detailX, detailY);
83825
83826            return this;
83827          };
83828
83829          /**
83830           * @private
83831           * Helper function for creating both cones and cylinders
83832           * Will only generate well-defined geometry when bottomRadius, height > 0
83833           * and topRadius >= 0
83834           * If topRadius == 0, topCap should be false
83835           */
83836          var _truncatedCone = function _truncatedCone(
83837            bottomRadius,
83838            topRadius,
83839            height,
83840            detailX,
83841            detailY,
83842            bottomCap,
83843            topCap
83844          ) {
83845            bottomRadius = bottomRadius <= 0 ? 1 : bottomRadius;
83846            topRadius = topRadius < 0 ? 0 : topRadius;
83847            height = height <= 0 ? bottomRadius : height;
83848            detailX = detailX < 3 ? 3 : detailX;
83849            detailY = detailY < 1 ? 1 : detailY;
83850            bottomCap = bottomCap === undefined ? true : bottomCap;
83851            topCap = topCap === undefined ? topRadius !== 0 : topCap;
83852            var start = bottomCap ? -2 : 0;
83853            var end = detailY + (topCap ? 2 : 0);
83854            //ensure constant slant for interior vertex normals
83855            var slant = Math.atan2(bottomRadius - topRadius, height);
83856            var sinSlant = Math.sin(slant);
83857            var cosSlant = Math.cos(slant);
83858            var yy, ii, jj;
83859            for (yy = start; yy <= end; ++yy) {
83860              var v = yy / detailY;
83861              var y = height * v;
83862              var ringRadius = void 0;
83863              if (yy < 0) {
83864                //for the bottomCap edge
83865                y = 0;
83866                v = 0;
83867                ringRadius = bottomRadius;
83868              } else if (yy > detailY) {
83869                //for the topCap edge
83870                y = height;
83871                v = 1;
83872                ringRadius = topRadius;
83873              } else {
83874                //for the middle
83875                ringRadius = bottomRadius + (topRadius - bottomRadius) * v;
83876              }
83877              if (yy === -2 || yy === detailY + 2) {
83878                //center of bottom or top caps
83879                ringRadius = 0;
83880              }
83881
83882              y -= height / 2; //shift coordiate origin to the center of object
83883              for (ii = 0; ii < detailX; ++ii) {
83884                var u = ii / (detailX - 1);
83885                var ur = 2 * Math.PI * u;
83886                var sur = Math.sin(ur);
83887                var cur = Math.cos(ur);
83888
83889                //VERTICES
83890                this.vertices.push(
83891                  new _main.default.Vector(sur * ringRadius, y, cur * ringRadius)
83892                );
83893
83894                //VERTEX NORMALS
83895                var vertexNormal = void 0;
83896                if (yy < 0) {
83897                  vertexNormal = new _main.default.Vector(0, -1, 0);
83898                } else if (yy > detailY && topRadius) {
83899                  vertexNormal = new _main.default.Vector(0, 1, 0);
83900                } else {
83901                  vertexNormal = new _main.default.Vector(
83902                    sur * cosSlant,
83903                    sinSlant,
83904                    cur * cosSlant
83905                  );
83906                }
83907                this.vertexNormals.push(vertexNormal);
83908                //UVs
83909                this.uvs.push(u, v);
83910              }
83911            }
83912
83913            var startIndex = 0;
83914            if (bottomCap) {
83915              for (jj = 0; jj < detailX; ++jj) {
83916                var nextjj = (jj + 1) % detailX;
83917                this.faces.push([
83918                  startIndex + jj,
83919                  startIndex + detailX + nextjj,
83920                  startIndex + detailX + jj
83921                ]);
83922              }
83923              startIndex += detailX * 2;
83924            }
83925            for (yy = 0; yy < detailY; ++yy) {
83926              for (ii = 0; ii < detailX; ++ii) {
83927                var nextii = (ii + 1) % detailX;
83928                this.faces.push([
83929                  startIndex + ii,
83930                  startIndex + nextii,
83931                  startIndex + detailX + nextii
83932                ]);
83933
83934                this.faces.push([
83935                  startIndex + ii,
83936                  startIndex + detailX + nextii,
83937                  startIndex + detailX + ii
83938                ]);
83939              }
83940              startIndex += detailX;
83941            }
83942            if (topCap) {
83943              startIndex += detailX;
83944              for (ii = 0; ii < detailX; ++ii) {
83945                this.faces.push([
83946                  startIndex + ii,
83947                  startIndex + (ii + 1) % detailX,
83948                  startIndex + detailX
83949                ]);
83950              }
83951            }
83952          };
83953
83954          /**
83955           * Draw a cylinder with given radius and height
83956           *
83957           * DetailX and detailY determines the number of subdivisions in the x-dimension
83958           * and the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.
83959           * The recommended maximum value for detailX is 24. Using a value greater than 24
83960           * may cause a warning or slow down the browser.
83961           *
83962           * @method cylinder
83963           * @param  {Number}  [radius]    radius of the surface
83964           * @param  {Number}  [height]    height of the cylinder
83965           * @param  {Integer} [detailX]   number of subdivisions in x-dimension;
83966           *                               default is 24
83967           * @param  {Integer} [detailY]   number of subdivisions in y-dimension;
83968           *                               default is 1
83969           * @param  {Boolean} [bottomCap] whether to draw the bottom of the cylinder
83970           * @param  {Boolean} [topCap]    whether to draw the top of the cylinder
83971           * @chainable
83972           * @example
83973           * <div>
83974           * <code>
83975           * // draw a spinning cylinder
83976           * // with radius 20 and height 50
83977           * function setup() {
83978           *   createCanvas(100, 100, WEBGL);
83979           * }
83980           *
83981           * function draw() {
83982           *   background(205, 105, 94);
83983           *   rotateX(frameCount * 0.01);
83984           *   rotateZ(frameCount * 0.01);
83985           *   cylinder(20, 50);
83986           * }
83987           * </code>
83988           * </div>
83989           *
83990           * @example
83991           * <div>
83992           * <code>
83993           * // slide to see how detailX works
83994           * let detailX;
83995           * function setup() {
83996           *   createCanvas(100, 100, WEBGL);
83997           *   detailX = createSlider(3, 24, 3);
83998           *   detailX.position(10, height + 5);
83999           *   detailX.style('width', '80px');
84000           * }
84001           *
84002           * function draw() {
84003           *   background(205, 105, 94);
84004           *   rotateY(millis() / 1000);
84005           *   cylinder(20, 75, detailX.value(), 1);
84006           * }
84007           * </code>
84008           * </div>
84009           *
84010           * @example
84011           * <div>
84012           * <code>
84013           * // slide to see how detailY works
84014           * let detailY;
84015           * function setup() {
84016           *   createCanvas(100, 100, WEBGL);
84017           *   detailY = createSlider(1, 16, 1);
84018           *   detailY.position(10, height + 5);
84019           *   detailY.style('width', '80px');
84020           * }
84021           *
84022           * function draw() {
84023           *   background(205, 105, 94);
84024           *   rotateY(millis() / 1000);
84025           *   cylinder(20, 75, 16, detailY.value());
84026           * }
84027           * </code>
84028           * </div>
84029           */
84030          _main.default.prototype.cylinder = function(
84031            radius,
84032            height,
84033            detailX,
84034            detailY,
84035            bottomCap,
84036            topCap
84037          ) {
84038            this._assert3d('cylinder');
84039            _main.default._validateParameters('cylinder', arguments);
84040            if (typeof radius === 'undefined') {
84041              radius = 50;
84042            }
84043            if (typeof height === 'undefined') {
84044              height = radius;
84045            }
84046            if (typeof detailX === 'undefined') {
84047              detailX = 24;
84048            }
84049            if (typeof detailY === 'undefined') {
84050              detailY = 1;
84051            }
84052            if (typeof topCap === 'undefined') {
84053              topCap = true;
84054            }
84055            if (typeof bottomCap === 'undefined') {
84056              bottomCap = true;
84057            }
84058
84059            var gId = 'cylinder|'
84060              .concat(detailX, '|')
84061              .concat(detailY, '|')
84062              .concat(bottomCap, '|')
84063              .concat(topCap);
84064            if (!this._renderer.geometryInHash(gId)) {
84065              var cylinderGeom = new _main.default.Geometry(detailX, detailY);
84066              _truncatedCone.call(
84067                cylinderGeom,
84068                1,
84069                1,
84070                1,
84071                detailX,
84072                detailY,
84073                bottomCap,
84074                topCap
84075              );
84076
84077              // normals are computed in call to _truncatedCone
84078              if (detailX <= 24 && detailY <= 16) {
84079                cylinderGeom._makeTriangleEdges()._edgesToVertices();
84080              } else if (this._renderer._doStroke) {
84081                console.log(
84082                  'Cannot draw stroke on cylinder objects with more' +
84083                    ' than 24 detailX or 16 detailY'
84084                );
84085              }
84086              this._renderer.createBuffers(gId, cylinderGeom);
84087            }
84088
84089            this._renderer.drawBuffersScaled(gId, radius, height, radius);
84090
84091            return this;
84092          };
84093
84094          /**
84095           * Draw a cone with given radius and height
84096           *
84097           * DetailX and detailY determine the number of subdivisions in the x-dimension and
84098           * the y-dimension of a cone. More subdivisions make the cone seem smoother. The
84099           * recommended maximum value for detailX is 24. Using a value greater than 24
84100           * may cause a warning or slow down the browser.
84101           * @method cone
84102           * @param  {Number}  [radius]  radius of the bottom surface
84103           * @param  {Number}  [height]  height of the cone
84104           * @param  {Integer} [detailX] number of segments,
84105           *                             the more segments the smoother geometry
84106           *                             default is 24
84107           * @param  {Integer} [detailY] number of segments,
84108           *                             the more segments the smoother geometry
84109           *                             default is 1
84110           * @param  {Boolean} [cap]     whether to draw the base of the cone
84111           * @chainable
84112           * @example
84113           * <div>
84114           * <code>
84115           * // draw a spinning cone
84116           * // with radius 40 and height 70
84117           * function setup() {
84118           *   createCanvas(100, 100, WEBGL);
84119           * }
84120           *
84121           * function draw() {
84122           *   background(200);
84123           *   rotateX(frameCount * 0.01);
84124           *   rotateZ(frameCount * 0.01);
84125           *   cone(40, 70);
84126           * }
84127           * </code>
84128           * </div>
84129           *
84130           * @example
84131           * <div>
84132           * <code>
84133           * // slide to see how detailx works
84134           * let detailX;
84135           * function setup() {
84136           *   createCanvas(100, 100, WEBGL);
84137           *   detailX = createSlider(3, 16, 3);
84138           *   detailX.position(10, height + 5);
84139           *   detailX.style('width', '80px');
84140           * }
84141           *
84142           * function draw() {
84143           *   background(205, 102, 94);
84144           *   rotateY(millis() / 1000);
84145           *   cone(30, 65, detailX.value(), 16);
84146           * }
84147           * </code>
84148           * </div>
84149           *
84150           * @example
84151           * <div>
84152           * <code>
84153           * // slide to see how detailY works
84154           * let detailY;
84155           * function setup() {
84156           *   createCanvas(100, 100, WEBGL);
84157           *   detailY = createSlider(3, 16, 3);
84158           *   detailY.position(10, height + 5);
84159           *   detailY.style('width', '80px');
84160           * }
84161           *
84162           * function draw() {
84163           *   background(205, 102, 94);
84164           *   rotateY(millis() / 1000);
84165           *   cone(30, 65, 16, detailY.value());
84166           * }
84167           * </code>
84168           * </div>
84169           */
84170          _main.default.prototype.cone = function(radius, height, detailX, detailY, cap) {
84171            this._assert3d('cone');
84172            _main.default._validateParameters('cone', arguments);
84173            if (typeof radius === 'undefined') {
84174              radius = 50;
84175            }
84176            if (typeof height === 'undefined') {
84177              height = radius;
84178            }
84179            if (typeof detailX === 'undefined') {
84180              detailX = 24;
84181            }
84182            if (typeof detailY === 'undefined') {
84183              detailY = 1;
84184            }
84185            if (typeof cap === 'undefined') {
84186              cap = true;
84187            }
84188
84189            var gId = 'cone|'
84190              .concat(detailX, '|')
84191              .concat(detailY, '|')
84192              .concat(cap);
84193            if (!this._renderer.geometryInHash(gId)) {
84194              var coneGeom = new _main.default.Geometry(detailX, detailY);
84195              _truncatedCone.call(coneGeom, 1, 0, 1, detailX, detailY, cap, false);
84196              if (detailX <= 24 && detailY <= 16) {
84197                coneGeom._makeTriangleEdges()._edgesToVertices();
84198              } else if (this._renderer._doStroke) {
84199                console.log(
84200                  'Cannot draw stroke on cone objects with more' +
84201                    ' than 24 detailX or 16 detailY'
84202                );
84203              }
84204              this._renderer.createBuffers(gId, coneGeom);
84205            }
84206
84207            this._renderer.drawBuffersScaled(gId, radius, height, radius);
84208
84209            return this;
84210          };
84211
84212          /**
84213           * Draw an ellipsoid with given radius
84214           *
84215           * DetailX and detailY determine the number of subdivisions in the x-dimension and
84216           * the y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.
84217           * Avoid detail number above 150, it may crash the browser.
84218           * @method ellipsoid
84219           * @param  {Number} [radiusx]         x-radius of ellipsoid
84220           * @param  {Number} [radiusy]         y-radius of ellipsoid
84221           * @param  {Number} [radiusz]         z-radius of ellipsoid
84222           * @param  {Integer} [detailX]        number of segments,
84223           *                                    the more segments the smoother geometry
84224           *                                    default is 24. Avoid detail number above
84225           *                                    150, it may crash the browser.
84226           * @param  {Integer} [detailY]        number of segments,
84227           *                                    the more segments the smoother geometry
84228           *                                    default is 16. Avoid detail number above
84229           *                                    150, it may crash the browser.
84230           * @chainable
84231           * @example
84232           * <div>
84233           * <code>
84234           * // draw an ellipsoid
84235           * // with radius 30, 40 and 40.
84236           * function setup() {
84237           *   createCanvas(100, 100, WEBGL);
84238           * }
84239           *
84240           * function draw() {
84241           *   background(205, 105, 94);
84242           *   ellipsoid(30, 40, 40);
84243           * }
84244           * </code>
84245           * </div>
84246           *
84247           * @example
84248           * <div>
84249           * <code>
84250           * // slide to see how detailX works
84251           * let detailX;
84252           * function setup() {
84253           *   createCanvas(100, 100, WEBGL);
84254           *   detailX = createSlider(2, 24, 12);
84255           *   detailX.position(10, height + 5);
84256           *   detailX.style('width', '80px');
84257           * }
84258           *
84259           * function draw() {
84260           *   background(205, 105, 94);
84261           *   rotateY(millis() / 1000);
84262           *   ellipsoid(30, 40, 40, detailX.value(), 8);
84263           * }
84264           * </code>
84265           * </div>
84266           *
84267           * @example
84268           * <div>
84269           * <code>
84270           * // slide to see how detailY works
84271           * let detailY;
84272           * function setup() {
84273           *   createCanvas(100, 100, WEBGL);
84274           *   detailY = createSlider(2, 24, 6);
84275           *   detailY.position(10, height + 5);
84276           *   detailY.style('width', '80px');
84277           * }
84278           *
84279           * function draw() {
84280           *   background(205, 105, 9);
84281           *   rotateY(millis() / 1000);
84282           *   ellipsoid(30, 40, 40, 12, detailY.value());
84283           * }
84284           * </code>
84285           * </div>
84286           */
84287          _main.default.prototype.ellipsoid = function(
84288            radiusX,
84289            radiusY,
84290            radiusZ,
84291            detailX,
84292            detailY
84293          ) {
84294            this._assert3d('ellipsoid');
84295            _main.default._validateParameters('ellipsoid', arguments);
84296            if (typeof radiusX === 'undefined') {
84297              radiusX = 50;
84298            }
84299            if (typeof radiusY === 'undefined') {
84300              radiusY = radiusX;
84301            }
84302            if (typeof radiusZ === 'undefined') {
84303              radiusZ = radiusX;
84304            }
84305
84306            if (typeof detailX === 'undefined') {
84307              detailX = 24;
84308            }
84309            if (typeof detailY === 'undefined') {
84310              detailY = 16;
84311            }
84312
84313            var gId = 'ellipsoid|'.concat(detailX, '|').concat(detailY);
84314
84315            if (!this._renderer.geometryInHash(gId)) {
84316              var _ellipsoid = function _ellipsoid() {
84317                for (var i = 0; i <= this.detailY; i++) {
84318                  var v = i / this.detailY;
84319                  var phi = Math.PI * v - Math.PI / 2;
84320                  var cosPhi = Math.cos(phi);
84321                  var sinPhi = Math.sin(phi);
84322
84323                  for (var j = 0; j <= this.detailX; j++) {
84324                    var u = j / this.detailX;
84325                    var theta = 2 * Math.PI * u;
84326                    var cosTheta = Math.cos(theta);
84327                    var sinTheta = Math.sin(theta);
84328                    var p = new _main.default.Vector(
84329                      cosPhi * sinTheta,
84330                      sinPhi,
84331                      cosPhi * cosTheta
84332                    );
84333                    this.vertices.push(p);
84334                    this.vertexNormals.push(p);
84335                    this.uvs.push(u, v);
84336                  }
84337                }
84338              };
84339              var ellipsoidGeom = new _main.default.Geometry(detailX, detailY, _ellipsoid);
84340              ellipsoidGeom.computeFaces();
84341              if (detailX <= 24 && detailY <= 24) {
84342                ellipsoidGeom._makeTriangleEdges()._edgesToVertices();
84343              } else if (this._renderer._doStroke) {
84344                console.log(
84345                  'Cannot draw stroke on ellipsoids with more' +
84346                    ' than 24 detailX or 24 detailY'
84347                );
84348              }
84349              this._renderer.createBuffers(gId, ellipsoidGeom);
84350            }
84351
84352            this._renderer.drawBuffersScaled(gId, radiusX, radiusY, radiusZ);
84353
84354            return this;
84355          };
84356
84357          /**
84358           * Draw a torus with given radius and tube radius
84359           *
84360           * DetailX and detailY determine the number of subdivisions in the x-dimension and
84361           * the y-dimension of a torus. More subdivisions make the torus appear to be smoother.
84362           * The default and maximum values for detailX and detailY are 24 and 16, respectively.
84363           * Setting them to relatively small values like 4 and 6 allows you to create new
84364           * shapes other than a torus.
84365           * @method torus
84366           * @param  {Number} [radius]      radius of the whole ring
84367           * @param  {Number} [tubeRadius]  radius of the tube
84368           * @param  {Integer} [detailX]    number of segments in x-dimension,
84369           *                                the more segments the smoother geometry
84370           *                                default is 24
84371           * @param  {Integer} [detailY]    number of segments in y-dimension,
84372           *                                the more segments the smoother geometry
84373           *                                default is 16
84374           * @chainable
84375           * @example
84376           * <div>
84377           * <code>
84378           * // draw a spinning torus
84379           * // with ring radius 30 and tube radius 15
84380           * function setup() {
84381           *   createCanvas(100, 100, WEBGL);
84382           * }
84383           *
84384           * function draw() {
84385           *   background(205, 102, 94);
84386           *   rotateX(frameCount * 0.01);
84387           *   rotateY(frameCount * 0.01);
84388           *   torus(30, 15);
84389           * }
84390           * </code>
84391           * </div>
84392           *
84393           * @example
84394           * <div>
84395           * <code>
84396           * // slide to see how detailX works
84397           * let detailX;
84398           * function setup() {
84399           *   createCanvas(100, 100, WEBGL);
84400           *   detailX = createSlider(3, 24, 3);
84401           *   detailX.position(10, height + 5);
84402           *   detailX.style('width', '80px');
84403           * }
84404           *
84405           * function draw() {
84406           *   background(205, 102, 94);
84407           *   rotateY(millis() / 1000);
84408           *   torus(30, 15, detailX.value(), 12);
84409           * }
84410           * </code>
84411           * </div>
84412           *
84413           * @example
84414           * <div>
84415           * <code>
84416           * // slide to see how detailY works
84417           * let detailY;
84418           * function setup() {
84419           *   createCanvas(100, 100, WEBGL);
84420           *   detailY = createSlider(3, 16, 3);
84421           *   detailY.position(10, height + 5);
84422           *   detailY.style('width', '80px');
84423           * }
84424           *
84425           * function draw() {
84426           *   background(205, 102, 94);
84427           *   rotateY(millis() / 1000);
84428           *   torus(30, 15, 16, detailY.value());
84429           * }
84430           * </code>
84431           * </div>
84432           */
84433          _main.default.prototype.torus = function(radius, tubeRadius, detailX, detailY) {
84434            this._assert3d('torus');
84435            _main.default._validateParameters('torus', arguments);
84436            if (typeof radius === 'undefined') {
84437              radius = 50;
84438            } else if (!radius) {
84439              return; // nothing to draw
84440            }
84441
84442            if (typeof tubeRadius === 'undefined') {
84443              tubeRadius = 10;
84444            } else if (!tubeRadius) {
84445              return; // nothing to draw
84446            }
84447
84448            if (typeof detailX === 'undefined') {
84449              detailX = 24;
84450            }
84451            if (typeof detailY === 'undefined') {
84452              detailY = 16;
84453            }
84454
84455            var tubeRatio = (tubeRadius / radius).toPrecision(4);
84456            var gId = 'torus|'
84457              .concat(tubeRatio, '|')
84458              .concat(detailX, '|')
84459              .concat(detailY);
84460
84461            if (!this._renderer.geometryInHash(gId)) {
84462              var _torus = function _torus() {
84463                for (var i = 0; i <= this.detailY; i++) {
84464                  var v = i / this.detailY;
84465                  var phi = 2 * Math.PI * v;
84466                  var cosPhi = Math.cos(phi);
84467                  var sinPhi = Math.sin(phi);
84468                  var r = 1 + tubeRatio * cosPhi;
84469
84470                  for (var j = 0; j <= this.detailX; j++) {
84471                    var u = j / this.detailX;
84472                    var theta = 2 * Math.PI * u;
84473                    var cosTheta = Math.cos(theta);
84474                    var sinTheta = Math.sin(theta);
84475
84476                    var p = new _main.default.Vector(
84477                      r * cosTheta,
84478                      r * sinTheta,
84479                      tubeRatio * sinPhi
84480                    );
84481
84482                    var n = new _main.default.Vector(
84483                      cosPhi * cosTheta,
84484                      cosPhi * sinTheta,
84485                      sinPhi
84486                    );
84487
84488                    this.vertices.push(p);
84489                    this.vertexNormals.push(n);
84490                    this.uvs.push(u, v);
84491                  }
84492                }
84493              };
84494              var torusGeom = new _main.default.Geometry(detailX, detailY, _torus);
84495              torusGeom.computeFaces();
84496              if (detailX <= 24 && detailY <= 16) {
84497                torusGeom._makeTriangleEdges()._edgesToVertices();
84498              } else if (this._renderer._doStroke) {
84499                console.log(
84500                  'Cannot draw strokes on torus object with more' +
84501                    ' than 24 detailX or 16 detailY'
84502                );
84503              }
84504              this._renderer.createBuffers(gId, torusGeom);
84505            }
84506            this._renderer.drawBuffersScaled(gId, radius, radius, radius);
84507
84508            return this;
84509          };
84510
84511          ///////////////////////
84512          /// 2D primitives
84513          /////////////////////////
84514
84515          /**
84516           * Draws a point, a coordinate in space at the dimension of one pixel,
84517           * given x, y and z coordinates. The color of the point is determined
84518           * by the current stroke, while the point size is determined by current
84519           * stroke weight.
84520           * @private
84521           * @param {Number} x x-coordinate of point
84522           * @param {Number} y y-coordinate of point
84523           * @param {Number} z z-coordinate of point
84524           * @chainable
84525           * @example
84526           * <div>
84527           * <code>
84528           * function setup() {
84529           *   createCanvas(100, 100, WEBGL);
84530           * }
84531           *
84532           * function draw() {
84533           *   background(50);
84534           *   stroke(255);
84535           *   strokeWeight(4);
84536           *   point(25, 0);
84537           *   strokeWeight(3);
84538           *   point(-25, 0);
84539           *   strokeWeight(2);
84540           *   point(0, 25);
84541           *   strokeWeight(1);
84542           *   point(0, -25);
84543           * }
84544           * </code>
84545           * </div>
84546           */
84547          _main.default.RendererGL.prototype.point = function(x, y, z) {
84548            if (typeof z === 'undefined') {
84549              z = 0;
84550            }
84551
84552            var _vertex = [];
84553            _vertex.push(new _main.default.Vector(x, y, z));
84554            this._drawPoints(_vertex, this.immediateMode.buffers.point);
84555
84556            return this;
84557          };
84558
84559          _main.default.RendererGL.prototype.triangle = function(args) {
84560            var x1 = args[0],
84561              y1 = args[1];
84562            var x2 = args[2],
84563              y2 = args[3];
84564            var x3 = args[4],
84565              y3 = args[5];
84566
84567            var gId = 'tri';
84568            if (!this.geometryInHash(gId)) {
84569              var _triangle = function _triangle() {
84570                var vertices = [];
84571                vertices.push(new _main.default.Vector(0, 0, 0));
84572                vertices.push(new _main.default.Vector(0, 1, 0));
84573                vertices.push(new _main.default.Vector(1, 0, 0));
84574                this.strokeIndices = [[0, 1], [1, 2], [2, 0]];
84575                this.vertices = vertices;
84576                this.faces = [[0, 1, 2]];
84577                this.uvs = [0, 0, 0, 1, 1, 1];
84578              };
84579              var triGeom = new _main.default.Geometry(1, 1, _triangle);
84580              triGeom._makeTriangleEdges()._edgesToVertices();
84581              triGeom.computeNormals();
84582              this.createBuffers(gId, triGeom);
84583            }
84584
84585            // only one triangle is cached, one point is at the origin, and the
84586            // two adjacent sides are tne unit vectors along the X & Y axes.
84587            //
84588            // this matrix multiplication transforms those two unit vectors
84589            // onto the required vector prior to rendering, and moves the
84590            // origin appropriately.
84591            var uMVMatrix = this.uMVMatrix.copy();
84592            try {
84593              // prettier-ignore
84594              var mult = new _main.default.Matrix([
84595    x2 - x1, y2 - y1, 0, 0, // the resulting unit X-axis
84596    x3 - x1, y3 - y1, 0, 0, // the resulting unit Y-axis
84597    0, 0, 1, 0, // the resulting unit Z-axis (unchanged)
84598    x1, y1, 0, 1 // the resulting origin
84599    ]).mult(this.uMVMatrix);
84600
84601              this.uMVMatrix = mult;
84602
84603              this.drawBuffers(gId);
84604            } finally {
84605              this.uMVMatrix = uMVMatrix;
84606            }
84607
84608            return this;
84609          };
84610
84611          _main.default.RendererGL.prototype.ellipse = function(args) {
84612            this.arc(
84613              args[0],
84614              args[1],
84615              args[2],
84616              args[3],
84617              0,
84618              constants.TWO_PI,
84619              constants.OPEN,
84620              args[4]
84621            );
84622          };
84623
84624          _main.default.RendererGL.prototype.arc = function(args) {
84625            var x = arguments[0];
84626            var y = arguments[1];
84627            var width = arguments[2];
84628            var height = arguments[3];
84629            var start = arguments[4];
84630            var stop = arguments[5];
84631            var mode = arguments[6];
84632            var detail = arguments[7] || 25;
84633
84634            var shape;
84635            var gId;
84636
84637            // check if it is an ellipse or an arc
84638            if (Math.abs(stop - start) >= constants.TWO_PI) {
84639              shape = 'ellipse';
84640              gId = ''.concat(shape, '|').concat(detail, '|');
84641            } else {
84642              shape = 'arc';
84643              gId = ''
84644                .concat(shape, '|')
84645                .concat(start, '|')
84646                .concat(stop, '|')
84647                .concat(mode, '|')
84648                .concat(detail, '|');
84649            }
84650
84651            if (!this.geometryInHash(gId)) {
84652              var _arc = function _arc() {
84653                this.strokeIndices = [];
84654
84655                // if the start and stop angles are not the same, push vertices to the array
84656                if (start.toFixed(10) !== stop.toFixed(10)) {
84657                  // if the mode specified is PIE or null, push the mid point of the arc in vertices
84658                  if (mode === constants.PIE || typeof mode === 'undefined') {
84659                    this.vertices.push(new _main.default.Vector(0.5, 0.5, 0));
84660                    this.uvs.push([0.5, 0.5]);
84661                  }
84662
84663                  // vertices for the perimeter of the circle
84664                  for (var i = 0; i <= detail; i++) {
84665                    var u = i / detail;
84666                    var theta = (stop - start) * u + start;
84667
84668                    var _x = 0.5 + Math.cos(theta) / 2;
84669                    var _y = 0.5 + Math.sin(theta) / 2;
84670
84671                    this.vertices.push(new _main.default.Vector(_x, _y, 0));
84672                    this.uvs.push([_x, _y]);
84673
84674                    if (i < detail - 1) {
84675                      this.faces.push([0, i + 1, i + 2]);
84676                      this.strokeIndices.push([i + 1, i + 2]);
84677                    }
84678                  }
84679
84680                  // check the mode specified in order to push vertices and faces, different for each mode
84681                  switch (mode) {
84682                    case constants.PIE:
84683                      this.faces.push([
84684                        0,
84685                        this.vertices.length - 2,
84686                        this.vertices.length - 1
84687                      ]);
84688
84689                      this.strokeIndices.push([0, 1]);
84690                      this.strokeIndices.push([
84691                        this.vertices.length - 2,
84692                        this.vertices.length - 1
84693                      ]);
84694
84695                      this.strokeIndices.push([0, this.vertices.length - 1]);
84696                      break;
84697
84698                    case constants.CHORD:
84699                      this.strokeIndices.push([0, 1]);
84700                      this.strokeIndices.push([0, this.vertices.length - 1]);
84701                      break;
84702
84703                    case constants.OPEN:
84704                      this.strokeIndices.push([0, 1]);
84705                      break;
84706
84707                    default:
84708                      this.faces.push([
84709                        0,
84710                        this.vertices.length - 2,
84711                        this.vertices.length - 1
84712                      ]);
84713
84714                      this.strokeIndices.push([
84715                        this.vertices.length - 2,
84716                        this.vertices.length - 1
84717                      ]);
84718                  }
84719                }
84720              };
84721
84722              var arcGeom = new _main.default.Geometry(detail, 1, _arc);
84723              arcGeom.computeNormals();
84724
84725              if (detail <= 50) {
84726                arcGeom._makeTriangleEdges()._edgesToVertices(arcGeom);
84727              } else if (this._renderer._doStroke) {
84728                console.log('Cannot stroke ${shape} with more than 50 detail');
84729              }
84730
84731              this.createBuffers(gId, arcGeom);
84732            }
84733
84734            var uMVMatrix = this.uMVMatrix.copy();
84735
84736            try {
84737              this.uMVMatrix.translate([x, y, 0]);
84738              this.uMVMatrix.scale(width, height, 1);
84739
84740              this.drawBuffers(gId);
84741            } finally {
84742              this.uMVMatrix = uMVMatrix;
84743            }
84744
84745            return this;
84746          };
84747
84748          _main.default.RendererGL.prototype.rect = function(args) {
84749            var perPixelLighting = this._pInst._glAttributes.perPixelLighting;
84750            var x = args[0];
84751            var y = args[1];
84752            var width = args[2];
84753            var height = args[3];
84754            var detailX = args[4] || (perPixelLighting ? 1 : 24);
84755            var detailY = args[5] || (perPixelLighting ? 1 : 16);
84756            var gId = 'rect|'.concat(detailX, '|').concat(detailY);
84757            if (!this.geometryInHash(gId)) {
84758              var _rect = function _rect() {
84759                for (var i = 0; i <= this.detailY; i++) {
84760                  var v = i / this.detailY;
84761                  for (var j = 0; j <= this.detailX; j++) {
84762                    var u = j / this.detailX;
84763                    var p = new _main.default.Vector(u, v, 0);
84764                    this.vertices.push(p);
84765                    this.uvs.push(u, v);
84766                  }
84767                }
84768                // using stroke indices to avoid stroke over face(s) of rectangle
84769                if (detailX > 0 && detailY > 0) {
84770                  this.strokeIndices = [
84771                    [0, detailX],
84772                    [detailX, (detailX + 1) * (detailY + 1) - 1],
84773                    [(detailX + 1) * (detailY + 1) - 1, (detailX + 1) * detailY],
84774                    [(detailX + 1) * detailY, 0]
84775                  ];
84776                }
84777              };
84778              var rectGeom = new _main.default.Geometry(detailX, detailY, _rect);
84779              rectGeom
84780                .computeFaces()
84781                .computeNormals()
84782                ._makeTriangleEdges()
84783                ._edgesToVertices();
84784              this.createBuffers(gId, rectGeom);
84785            }
84786
84787            // only a single rectangle (of a given detail) is cached: a square with
84788            // opposite corners at (0,0) & (1,1).
84789            //
84790            // before rendering, this square is scaled & moved to the required location.
84791            var uMVMatrix = this.uMVMatrix.copy();
84792            try {
84793              this.uMVMatrix.translate([x, y, 0]);
84794              this.uMVMatrix.scale(width, height, 1);
84795
84796              this.drawBuffers(gId);
84797            } finally {
84798              this.uMVMatrix = uMVMatrix;
84799            }
84800            return this;
84801          };
84802
84803          // prettier-ignore
84804          _main.default.RendererGL.prototype.quad = function (x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) {
84805  var gId = "quad|".concat(
84806  x1, "|").concat(y1, "|").concat(z1, "|").concat(x2, "|").concat(y2, "|").concat(z2, "|").concat(x3, "|").concat(y3, "|").concat(z3, "|").concat(x4, "|").concat(y4, "|").concat(z4);
84807  if (!this.geometryInHash(gId)) {
84808    var _quad = function _quad() {
84809      this.vertices.push(new _main.default.Vector(x1, y1, z1));
84810      this.vertices.push(new _main.default.Vector(x2, y2, z2));
84811      this.vertices.push(new _main.default.Vector(x3, y3, z3));
84812      this.vertices.push(new _main.default.Vector(x4, y4, z4));
84813      this.uvs.push(0, 0, 1, 0, 1, 1, 0, 1);
84814      this.strokeIndices = [[0, 1], [1, 2], [2, 3], [3, 0]];
84815    };
84816    var quadGeom = new _main.default.Geometry(2, 2, _quad);
84817    quadGeom.
84818    computeNormals().
84819    _makeTriangleEdges().
84820    _edgesToVertices();
84821    quadGeom.faces = [[0, 1, 2], [2, 3, 0]];
84822    this.createBuffers(gId, quadGeom);
84823  }
84824  this.drawBuffers(gId);
84825  return this;
84826};
84827
84828          //this implementation of bezier curve
84829          //is based on Bernstein polynomial
84830          // pretier-ignore
84831          _main.default.RendererGL.prototype.bezier = function(
84832            x1,
84833            y1,
84834            z1, // x2
84835            x2, // y2
84836            y2, // x3
84837            z2, // y3
84838            x3, // x4
84839            y3, // y4
84840            z3,
84841            x4,
84842            y4,
84843            z4
84844          ) {
84845            if (arguments.length === 8) {
84846              y4 = y3;
84847              x4 = x3;
84848              y3 = z2;
84849              x3 = y2;
84850              y2 = x2;
84851              x2 = z1;
84852              z1 = z2 = z3 = z4 = 0;
84853            }
84854            var bezierDetail = this._pInst._bezierDetail || 20; //value of Bezier detail
84855            this.beginShape();
84856            for (var i = 0; i <= bezierDetail; i++) {
84857              var c1 = Math.pow(1 - i / bezierDetail, 3);
84858              var c2 = 3 * (i / bezierDetail) * Math.pow(1 - i / bezierDetail, 2);
84859              var c3 = 3 * Math.pow(i / bezierDetail, 2) * (1 - i / bezierDetail);
84860              var c4 = Math.pow(i / bezierDetail, 3);
84861              this.vertex(
84862                x1 * c1 + x2 * c2 + x3 * c3 + x4 * c4,
84863                y1 * c1 + y2 * c2 + y3 * c3 + y4 * c4,
84864                z1 * c1 + z2 * c2 + z3 * c3 + z4 * c4
84865              );
84866            }
84867            this.endShape();
84868            return this;
84869          };
84870
84871          // pretier-ignore
84872          _main.default.RendererGL.prototype.curve = function(
84873            x1,
84874            y1,
84875            z1, // x2
84876            x2, // y2
84877            y2, // x3
84878            z2, // y3
84879            x3, // x4
84880            y3, // y4
84881            z3,
84882            x4,
84883            y4,
84884            z4
84885          ) {
84886            if (arguments.length === 8) {
84887              x4 = x3;
84888              y4 = y3;
84889              x3 = y2;
84890              y3 = x2;
84891              x2 = z1;
84892              y2 = x2;
84893              z1 = z2 = z3 = z4 = 0;
84894            }
84895            var curveDetail = this._pInst._curveDetail;
84896            this.beginShape();
84897            for (var i = 0; i <= curveDetail; i++) {
84898              var c1 = Math.pow(i / curveDetail, 3) * 0.5;
84899              var c2 = Math.pow(i / curveDetail, 2) * 0.5;
84900              var c3 = i / curveDetail * 0.5;
84901              var c4 = 0.5;
84902              var vx =
84903                c1 * (-x1 + 3 * x2 - 3 * x3 + x4) +
84904                c2 * (2 * x1 - 5 * x2 + 4 * x3 - x4) +
84905                c3 * (-x1 + x3) +
84906                c4 * (2 * x2);
84907              var vy =
84908                c1 * (-y1 + 3 * y2 - 3 * y3 + y4) +
84909                c2 * (2 * y1 - 5 * y2 + 4 * y3 - y4) +
84910                c3 * (-y1 + y3) +
84911                c4 * (2 * y2);
84912              var vz =
84913                c1 * (-z1 + 3 * z2 - 3 * z3 + z4) +
84914                c2 * (2 * z1 - 5 * z2 + 4 * z3 - z4) +
84915                c3 * (-z1 + z3) +
84916                c4 * (2 * z2);
84917              this.vertex(vx, vy, vz);
84918            }
84919            this.endShape();
84920            return this;
84921          };
84922
84923          /**
84924           * Draw a line given two points
84925           * @private
84926           * @param {Number} x0 x-coordinate of first vertex
84927           * @param {Number} y0 y-coordinate of first vertex
84928           * @param {Number} z0 z-coordinate of first vertex
84929           * @param {Number} x1 x-coordinate of second vertex
84930           * @param {Number} y1 y-coordinate of second vertex
84931           * @param {Number} z1 z-coordinate of second vertex
84932           * @chainable
84933           * @example
84934           * <div>
84935           * <code>
84936           * //draw a line
84937           * function setup() {
84938           *   createCanvas(100, 100, WEBGL);
84939           * }
84940           *
84941           * function draw() {
84942           *   background(200);
84943           *   rotateX(frameCount * 0.01);
84944           *   rotateY(frameCount * 0.01);
84945           *   // Use fill instead of stroke to change the color of shape.
84946           *   fill(255, 0, 0);
84947           *   line(10, 10, 0, 60, 60, 20);
84948           * }
84949           * </code>
84950           * </div>
84951           */
84952          _main.default.RendererGL.prototype.line = function() {
84953            if (arguments.length === 6) {
84954              this.beginShape(constants.LINES);
84955              this.vertex(
84956                arguments.length <= 0 ? undefined : arguments[0],
84957                arguments.length <= 1 ? undefined : arguments[1],
84958                arguments.length <= 2 ? undefined : arguments[2]
84959              );
84960              this.vertex(
84961                arguments.length <= 3 ? undefined : arguments[3],
84962                arguments.length <= 4 ? undefined : arguments[4],
84963                arguments.length <= 5 ? undefined : arguments[5]
84964              );
84965              this.endShape();
84966            } else if (arguments.length === 4) {
84967              this.beginShape(constants.LINES);
84968              this.vertex(
84969                arguments.length <= 0 ? undefined : arguments[0],
84970                arguments.length <= 1 ? undefined : arguments[1],
84971                0
84972              );
84973              this.vertex(
84974                arguments.length <= 2 ? undefined : arguments[2],
84975                arguments.length <= 3 ? undefined : arguments[3],
84976                0
84977              );
84978              this.endShape();
84979            }
84980            return this;
84981          };
84982
84983          _main.default.RendererGL.prototype.bezierVertex = function() {
84984            if (this.immediateMode._bezierVertex.length === 0) {
84985              throw Error('vertex() must be used once before calling bezierVertex()');
84986            } else {
84987              var w_x = [];
84988              var w_y = [];
84989              var w_z = [];
84990              var t, _x, _y, _z, i;
84991              var argLength = arguments.length;
84992
84993              t = 0;
84994
84995              if (
84996                this._lookUpTableBezier.length === 0 ||
84997                this._lutBezierDetail !== this._pInst._curveDetail
84998              ) {
84999                this._lookUpTableBezier = [];
85000                this._lutBezierDetail = this._pInst._curveDetail;
85001                var step = 1 / this._lutBezierDetail;
85002                var start = 0;
85003                var end = 1;
85004                var j = 0;
85005                while (start < 1) {
85006                  t = parseFloat(start.toFixed(6));
85007                  this._lookUpTableBezier[j] = this._bezierCoefficients(t);
85008                  if (end.toFixed(6) === step.toFixed(6)) {
85009                    t = parseFloat(end.toFixed(6)) + parseFloat(start.toFixed(6));
85010                    ++j;
85011                    this._lookUpTableBezier[j] = this._bezierCoefficients(t);
85012                    break;
85013                  }
85014                  start += step;
85015                  end -= step;
85016                  ++j;
85017                }
85018              }
85019
85020              var LUTLength = this._lookUpTableBezier.length;
85021
85022              if (argLength === 6) {
85023                this.isBezier = true;
85024
85025                w_x = [
85026                  this.immediateMode._bezierVertex[0],
85027                  arguments.length <= 0 ? undefined : arguments[0],
85028                  arguments.length <= 2 ? undefined : arguments[2],
85029                  arguments.length <= 4 ? undefined : arguments[4]
85030                ];
85031                w_y = [
85032                  this.immediateMode._bezierVertex[1],
85033                  arguments.length <= 1 ? undefined : arguments[1],
85034                  arguments.length <= 3 ? undefined : arguments[3],
85035                  arguments.length <= 5 ? undefined : arguments[5]
85036                ];
85037
85038                for (i = 0; i < LUTLength; i++) {
85039                  _x =
85040                    w_x[0] * this._lookUpTableBezier[i][0] +
85041                    w_x[1] * this._lookUpTableBezier[i][1] +
85042                    w_x[2] * this._lookUpTableBezier[i][2] +
85043                    w_x[3] * this._lookUpTableBezier[i][3];
85044                  _y =
85045                    w_y[0] * this._lookUpTableBezier[i][0] +
85046                    w_y[1] * this._lookUpTableBezier[i][1] +
85047                    w_y[2] * this._lookUpTableBezier[i][2] +
85048                    w_y[3] * this._lookUpTableBezier[i][3];
85049                  this.vertex(_x, _y);
85050                }
85051                this.immediateMode._bezierVertex[0] =
85052                  arguments.length <= 4 ? undefined : arguments[4];
85053                this.immediateMode._bezierVertex[1] =
85054                  arguments.length <= 5 ? undefined : arguments[5];
85055              } else if (argLength === 9) {
85056                this.isBezier = true;
85057
85058                w_x = [
85059                  this.immediateMode._bezierVertex[0],
85060                  arguments.length <= 0 ? undefined : arguments[0],
85061                  arguments.length <= 3 ? undefined : arguments[3],
85062                  arguments.length <= 6 ? undefined : arguments[6]
85063                ];
85064                w_y = [
85065                  this.immediateMode._bezierVertex[1],
85066                  arguments.length <= 1 ? undefined : arguments[1],
85067                  arguments.length <= 4 ? undefined : arguments[4],
85068                  arguments.length <= 7 ? undefined : arguments[7]
85069                ];
85070                w_z = [
85071                  this.immediateMode._bezierVertex[2],
85072                  arguments.length <= 2 ? undefined : arguments[2],
85073                  arguments.length <= 5 ? undefined : arguments[5],
85074                  arguments.length <= 8 ? undefined : arguments[8]
85075                ];
85076                for (i = 0; i < LUTLength; i++) {
85077                  _x =
85078                    w_x[0] * this._lookUpTableBezier[i][0] +
85079                    w_x[1] * this._lookUpTableBezier[i][1] +
85080                    w_x[2] * this._lookUpTableBezier[i][2] +
85081                    w_x[3] * this._lookUpTableBezier[i][3];
85082                  _y =
85083                    w_y[0] * this._lookUpTableBezier[i][0] +
85084                    w_y[1] * this._lookUpTableBezier[i][1] +
85085                    w_y[2] * this._lookUpTableBezier[i][2] +
85086                    w_y[3] * this._lookUpTableBezier[i][3];
85087                  _z =
85088                    w_z[0] * this._lookUpTableBezier[i][0] +
85089                    w_z[1] * this._lookUpTableBezier[i][1] +
85090                    w_z[2] * this._lookUpTableBezier[i][2] +
85091                    w_z[3] * this._lookUpTableBezier[i][3];
85092                  this.vertex(_x, _y, _z);
85093                }
85094                this.immediateMode._bezierVertex[0] =
85095                  arguments.length <= 6 ? undefined : arguments[6];
85096                this.immediateMode._bezierVertex[1] =
85097                  arguments.length <= 7 ? undefined : arguments[7];
85098                this.immediateMode._bezierVertex[2] =
85099                  arguments.length <= 8 ? undefined : arguments[8];
85100              }
85101            }
85102          };
85103
85104          _main.default.RendererGL.prototype.quadraticVertex = function() {
85105            if (this.immediateMode._quadraticVertex.length === 0) {
85106              throw Error('vertex() must be used once before calling quadraticVertex()');
85107            } else {
85108              var w_x = [];
85109              var w_y = [];
85110              var w_z = [];
85111              var t, _x, _y, _z, i;
85112              var argLength = arguments.length;
85113
85114              t = 0;
85115
85116              if (
85117                this._lookUpTableQuadratic.length === 0 ||
85118                this._lutQuadraticDetail !== this._pInst._curveDetail
85119              ) {
85120                this._lookUpTableQuadratic = [];
85121                this._lutQuadraticDetail = this._pInst._curveDetail;
85122                var step = 1 / this._lutQuadraticDetail;
85123                var start = 0;
85124                var end = 1;
85125                var j = 0;
85126                while (start < 1) {
85127                  t = parseFloat(start.toFixed(6));
85128                  this._lookUpTableQuadratic[j] = this._quadraticCoefficients(t);
85129                  if (end.toFixed(6) === step.toFixed(6)) {
85130                    t = parseFloat(end.toFixed(6)) + parseFloat(start.toFixed(6));
85131                    ++j;
85132                    this._lookUpTableQuadratic[j] = this._quadraticCoefficients(t);
85133                    break;
85134                  }
85135                  start += step;
85136                  end -= step;
85137                  ++j;
85138                }
85139              }
85140
85141              var LUTLength = this._lookUpTableQuadratic.length;
85142
85143              if (argLength === 4) {
85144                this.isQuadratic = true;
85145
85146                w_x = [
85147                  this.immediateMode._quadraticVertex[0],
85148                  arguments.length <= 0 ? undefined : arguments[0],
85149                  arguments.length <= 2 ? undefined : arguments[2]
85150                ];
85151                w_y = [
85152                  this.immediateMode._quadraticVertex[1],
85153                  arguments.length <= 1 ? undefined : arguments[1],
85154                  arguments.length <= 3 ? undefined : arguments[3]
85155                ];
85156
85157                for (i = 0; i < LUTLength; i++) {
85158                  _x =
85159                    w_x[0] * this._lookUpTableQuadratic[i][0] +
85160                    w_x[1] * this._lookUpTableQuadratic[i][1] +
85161                    w_x[2] * this._lookUpTableQuadratic[i][2];
85162                  _y =
85163                    w_y[0] * this._lookUpTableQuadratic[i][0] +
85164                    w_y[1] * this._lookUpTableQuadratic[i][1] +
85165                    w_y[2] * this._lookUpTableQuadratic[i][2];
85166                  this.vertex(_x, _y);
85167                }
85168
85169                this.immediateMode._quadraticVertex[0] =
85170                  arguments.length <= 2 ? undefined : arguments[2];
85171                this.immediateMode._quadraticVertex[1] =
85172                  arguments.length <= 3 ? undefined : arguments[3];
85173              } else if (argLength === 6) {
85174                this.isQuadratic = true;
85175
85176                w_x = [
85177                  this.immediateMode._quadraticVertex[0],
85178                  arguments.length <= 0 ? undefined : arguments[0],
85179                  arguments.length <= 3 ? undefined : arguments[3]
85180                ];
85181                w_y = [
85182                  this.immediateMode._quadraticVertex[1],
85183                  arguments.length <= 1 ? undefined : arguments[1],
85184                  arguments.length <= 4 ? undefined : arguments[4]
85185                ];
85186                w_z = [
85187                  this.immediateMode._quadraticVertex[2],
85188                  arguments.length <= 2 ? undefined : arguments[2],
85189                  arguments.length <= 5 ? undefined : arguments[5]
85190                ];
85191
85192                for (i = 0; i < LUTLength; i++) {
85193                  _x =
85194                    w_x[0] * this._lookUpTableQuadratic[i][0] +
85195                    w_x[1] * this._lookUpTableQuadratic[i][1] +
85196                    w_x[2] * this._lookUpTableQuadratic[i][2];
85197                  _y =
85198                    w_y[0] * this._lookUpTableQuadratic[i][0] +
85199                    w_y[1] * this._lookUpTableQuadratic[i][1] +
85200                    w_y[2] * this._lookUpTableQuadratic[i][2];
85201                  _z =
85202                    w_z[0] * this._lookUpTableQuadratic[i][0] +
85203                    w_z[1] * this._lookUpTableQuadratic[i][1] +
85204                    w_z[2] * this._lookUpTableQuadratic[i][2];
85205                  this.vertex(_x, _y, _z);
85206                }
85207
85208                this.immediateMode._quadraticVertex[0] =
85209                  arguments.length <= 3 ? undefined : arguments[3];
85210                this.immediateMode._quadraticVertex[1] =
85211                  arguments.length <= 4 ? undefined : arguments[4];
85212                this.immediateMode._quadraticVertex[2] =
85213                  arguments.length <= 5 ? undefined : arguments[5];
85214              }
85215            }
85216          };
85217
85218          _main.default.RendererGL.prototype.curveVertex = function() {
85219            var w_x = [];
85220            var w_y = [];
85221            var w_z = [];
85222            var t, _x, _y, _z, i;
85223            t = 0;
85224            var argLength = arguments.length;
85225
85226            if (
85227              this._lookUpTableBezier.length === 0 ||
85228              this._lutBezierDetail !== this._pInst._curveDetail
85229            ) {
85230              this._lookUpTableBezier = [];
85231              this._lutBezierDetail = this._pInst._curveDetail;
85232              var step = 1 / this._lutBezierDetail;
85233              var start = 0;
85234              var end = 1;
85235              var j = 0;
85236              while (start < 1) {
85237                t = parseFloat(start.toFixed(6));
85238                this._lookUpTableBezier[j] = this._bezierCoefficients(t);
85239                if (end.toFixed(6) === step.toFixed(6)) {
85240                  t = parseFloat(end.toFixed(6)) + parseFloat(start.toFixed(6));
85241                  ++j;
85242                  this._lookUpTableBezier[j] = this._bezierCoefficients(t);
85243                  break;
85244                }
85245                start += step;
85246                end -= step;
85247                ++j;
85248              }
85249            }
85250
85251            var LUTLength = this._lookUpTableBezier.length;
85252
85253            if (argLength === 2) {
85254              this.immediateMode._curveVertex.push(
85255                arguments.length <= 0 ? undefined : arguments[0]
85256              );
85257              this.immediateMode._curveVertex.push(
85258                arguments.length <= 1 ? undefined : arguments[1]
85259              );
85260              if (this.immediateMode._curveVertex.length === 8) {
85261                this.isCurve = true;
85262                w_x = this._bezierToCatmull([
85263                  this.immediateMode._curveVertex[0],
85264                  this.immediateMode._curveVertex[2],
85265                  this.immediateMode._curveVertex[4],
85266                  this.immediateMode._curveVertex[6]
85267                ]);
85268
85269                w_y = this._bezierToCatmull([
85270                  this.immediateMode._curveVertex[1],
85271                  this.immediateMode._curveVertex[3],
85272                  this.immediateMode._curveVertex[5],
85273                  this.immediateMode._curveVertex[7]
85274                ]);
85275
85276                for (i = 0; i < LUTLength; i++) {
85277                  _x =
85278                    w_x[0] * this._lookUpTableBezier[i][0] +
85279                    w_x[1] * this._lookUpTableBezier[i][1] +
85280                    w_x[2] * this._lookUpTableBezier[i][2] +
85281                    w_x[3] * this._lookUpTableBezier[i][3];
85282                  _y =
85283                    w_y[0] * this._lookUpTableBezier[i][0] +
85284                    w_y[1] * this._lookUpTableBezier[i][1] +
85285                    w_y[2] * this._lookUpTableBezier[i][2] +
85286                    w_y[3] * this._lookUpTableBezier[i][3];
85287                  this.vertex(_x, _y);
85288                }
85289                for (i = 0; i < argLength; i++) {
85290                  this.immediateMode._curveVertex.shift();
85291                }
85292              }
85293            } else if (argLength === 3) {
85294              this.immediateMode._curveVertex.push(
85295                arguments.length <= 0 ? undefined : arguments[0]
85296              );
85297              this.immediateMode._curveVertex.push(
85298                arguments.length <= 1 ? undefined : arguments[1]
85299              );
85300              this.immediateMode._curveVertex.push(
85301                arguments.length <= 2 ? undefined : arguments[2]
85302              );
85303              if (this.immediateMode._curveVertex.length === 12) {
85304                this.isCurve = true;
85305                w_x = this._bezierToCatmull([
85306                  this.immediateMode._curveVertex[0],
85307                  this.immediateMode._curveVertex[3],
85308                  this.immediateMode._curveVertex[6],
85309                  this.immediateMode._curveVertex[9]
85310                ]);
85311
85312                w_y = this._bezierToCatmull([
85313                  this.immediateMode._curveVertex[1],
85314                  this.immediateMode._curveVertex[4],
85315                  this.immediateMode._curveVertex[7],
85316                  this.immediateMode._curveVertex[10]
85317                ]);
85318
85319                w_z = this._bezierToCatmull([
85320                  this.immediateMode._curveVertex[2],
85321                  this.immediateMode._curveVertex[5],
85322                  this.immediateMode._curveVertex[8],
85323                  this.immediateMode._curveVertex[11]
85324                ]);
85325
85326                for (i = 0; i < LUTLength; i++) {
85327                  _x =
85328                    w_x[0] * this._lookUpTableBezier[i][0] +
85329                    w_x[1] * this._lookUpTableBezier[i][1] +
85330                    w_x[2] * this._lookUpTableBezier[i][2] +
85331                    w_x[3] * this._lookUpTableBezier[i][3];
85332                  _y =
85333                    w_y[0] * this._lookUpTableBezier[i][0] +
85334                    w_y[1] * this._lookUpTableBezier[i][1] +
85335                    w_y[2] * this._lookUpTableBezier[i][2] +
85336                    w_y[3] * this._lookUpTableBezier[i][3];
85337                  _z =
85338                    w_z[0] * this._lookUpTableBezier[i][0] +
85339                    w_z[1] * this._lookUpTableBezier[i][1] +
85340                    w_z[2] * this._lookUpTableBezier[i][2] +
85341                    w_z[3] * this._lookUpTableBezier[i][3];
85342                  this.vertex(_x, _y, _z);
85343                }
85344                for (i = 0; i < argLength; i++) {
85345                  this.immediateMode._curveVertex.shift();
85346                }
85347              }
85348            }
85349          };
85350
85351          _main.default.RendererGL.prototype.image = function(
85352            img,
85353            sx,
85354            sy,
85355            sWidth,
85356            sHeight,
85357            dx,
85358            dy,
85359            dWidth,
85360            dHeight
85361          ) {
85362            if (this._isErasing) {
85363              this.blendMode(this._cachedBlendMode);
85364            }
85365
85366            this._pInst.push();
85367
85368            this._pInst.noLights();
85369
85370            this._pInst.texture(img);
85371            this._pInst.textureMode(constants.NORMAL);
85372
85373            var u0 = 0;
85374            if (sx <= img.width) {
85375              u0 = sx / img.width;
85376            }
85377
85378            var u1 = 1;
85379            if (sx + sWidth <= img.width) {
85380              u1 = (sx + sWidth) / img.width;
85381            }
85382
85383            var v0 = 0;
85384            if (sy <= img.height) {
85385              v0 = sy / img.height;
85386            }
85387
85388            var v1 = 1;
85389            if (sy + sHeight <= img.height) {
85390              v1 = (sy + sHeight) / img.height;
85391            }
85392
85393            this.beginShape();
85394            this.vertex(dx, dy, 0, u0, v0);
85395            this.vertex(dx + dWidth, dy, 0, u1, v0);
85396            this.vertex(dx + dWidth, dy + dHeight, 0, u1, v1);
85397            this.vertex(dx, dy + dHeight, 0, u0, v1);
85398            this.endShape(constants.CLOSE);
85399
85400            this._pInst.pop();
85401
85402            if (this._isErasing) {
85403              this.blendMode(constants.REMOVE);
85404            }
85405          };
85406          var _default = _main.default;
85407          exports.default = _default;
85408        },
85409        { '../core/constants': 48, '../core/main': 59, './p5.Geometry': 108 }
85410      ],
85411      103: [
85412        function(_dereq_, module, exports) {
85413          'use strict';
85414          function _typeof(obj) {
85415            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
85416              _typeof = function _typeof(obj) {
85417                return typeof obj;
85418              };
85419            } else {
85420              _typeof = function _typeof(obj) {
85421                return obj &&
85422                  typeof Symbol === 'function' &&
85423                  obj.constructor === Symbol &&
85424                  obj !== Symbol.prototype
85425                  ? 'symbol'
85426                  : typeof obj;
85427              };
85428            }
85429            return _typeof(obj);
85430          }
85431          Object.defineProperty(exports, '__esModule', { value: true });
85432          exports.default = void 0;
85433
85434          var _main = _interopRequireDefault(_dereq_('../core/main'));
85435          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
85436          function _getRequireWildcardCache() {
85437            if (typeof WeakMap !== 'function') return null;
85438            var cache = new WeakMap();
85439            _getRequireWildcardCache = function _getRequireWildcardCache() {
85440              return cache;
85441            };
85442            return cache;
85443          }
85444          function _interopRequireWildcard(obj) {
85445            if (obj && obj.__esModule) {
85446              return obj;
85447            }
85448            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
85449              return { default: obj };
85450            }
85451            var cache = _getRequireWildcardCache();
85452            if (cache && cache.has(obj)) {
85453              return cache.get(obj);
85454            }
85455            var newObj = {};
85456            var hasPropertyDescriptor =
85457              Object.defineProperty && Object.getOwnPropertyDescriptor;
85458            for (var key in obj) {
85459              if (Object.prototype.hasOwnProperty.call(obj, key)) {
85460                var desc = hasPropertyDescriptor
85461                  ? Object.getOwnPropertyDescriptor(obj, key)
85462                  : null;
85463                if (desc && (desc.get || desc.set)) {
85464                  Object.defineProperty(newObj, key, desc);
85465                } else {
85466                  newObj[key] = obj[key];
85467                }
85468              }
85469            }
85470            newObj.default = obj;
85471            if (cache) {
85472              cache.set(obj, newObj);
85473            }
85474            return newObj;
85475          }
85476          function _interopRequireDefault(obj) {
85477            return obj && obj.__esModule ? obj : { default: obj };
85478          } /** // implementation based on three.js 'orbitControls':
85479           * @module Lights, Camera
85480           * @submodule Interaction
85481           * @for p5
85482           * @requires core
85483           */ /**
85484           * Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking
85485           * and dragging will rotate the camera position about the center of the sketch,
85486           * right-clicking and dragging will pan the camera position without rotation,
85487           * and using the mouse wheel (scrolling) will move the camera closer or further
85488           * from the center of the sketch. This function can be called with parameters
85489           * dictating sensitivity to mouse movement along the X and Y axes.  Calling
85490           * this function without parameters is equivalent to calling orbitControl(1,1).
85491           * To reverse direction of movement in either axis, enter a negative number
85492           * for sensitivity.
85493           * @method orbitControl
85494           * @for p5
85495           * @param  {Number} [sensitivityX] sensitivity to mouse movement along X axis
85496           * @param  {Number} [sensitivityY] sensitivity to mouse movement along Y axis
85497           * @param  {Number} [sensitivityZ] sensitivity to scroll movement along Z axis
85498           * @chainable
85499           * @example
85500           * <div>
85501           * <code>
85502           * function setup() {
85503           *   createCanvas(100, 100, WEBGL);
85504           *   normalMaterial();
85505           * }
85506           * function draw() {
85507           *   background(200);
85508           *   orbitControl();
85509           *   rotateY(0.5);
85510           *   box(30, 50);
85511           * }
85512           * </code>
85513           * </div>
85514           *
85515           * @alt
85516           * Camera orbits around a box when mouse is hold-clicked & then moved.
85517           */
85518          // https://github.com/mrdoob/three.js/blob/dev/examples/js/control
85518s/OrbitControls.js
85519          _main.default.prototype.orbitControl = function(
85520            sensitivityX,
85521            sensitivityY,
85522            sensitivityZ
85523          ) {
85524            this._assert3d('orbitControl');
85525            _main.default._validateParameters('orbitControl', arguments);
85526
85527            // If the mouse is not in bounds of the canvas, disable all behaviors:
85528            var mouseInCanvas =
85529              this.mouseX < this.width &&
85530              this.mouseX > 0 &&
85531              this.mouseY < this.height &&
85532              this.mouseY > 0;
85533            if (!mouseInCanvas) return;
85534
85535            var cam = this._renderer._curCamera;
85536
85537            if (typeof sensitivityX === 'undefined') {
85538              sensitivityX = 1;
85539            }
85540            if (typeof sensitivityY === 'undefined') {
85541              sensitivityY = sensitivityX;
85542            }
85543            if (typeof sensitivityZ === 'undefined') {
85544              sensitivityZ = 0.5;
85545            }
85546
85547            // default right-mouse and mouse-wheel behaviors (context menu and scrolling,
85548            // respectively) are disabled here to allow use of those events for panning and
85549            // zooming
85550
85551            // disable context menu for canvas element and add 'contextMenuDisabled'
85552            // flag to p5 instance
85553            if (this.contextMenuDisabled !== true) {
85554              this.canvas.oncontextmenu = function() {
85555                return false;
85556              };
85557              this._setProperty('contextMenuDisabled', true);
85558            }
85559
85560            // disable default scrolling behavior on the canvas element and add
85561            // 'wheelDefaultDisabled' flag to p5 instance
85562            if (this.wheelDefaultDisabled !== true) {
85563              this.canvas.onwheel = function() {
85564                return false;
85565              };
85566              this._setProperty('wheelDefaultDisabled', true);
85567            }
85568
85569            var scaleFactor = this.height < this.width ? this.height : this.width;
85570
85571            // ZOOM if there is a change in mouseWheelDelta
85572            if (this._mouseWheelDeltaY !== this._pmouseWheelDeltaY) {
85573              // zoom according to direction of mouseWheelDeltaY rather than value
85574              if (this._mouseWheelDeltaY > 0) {
85575                this._renderer._curCamera._orbit(0, 0, sensitivityZ * scaleFactor);
85576              } else {
85577                this._renderer._curCamera._orbit(0, 0, -sensitivityZ * scaleFactor);
85578              }
85579            }
85580
85581            if (this.mouseIsPressed) {
85582              // ORBIT BEHAVIOR
85583              if (this.mouseButton === this.LEFT) {
85584                var deltaTheta = -sensitivityX * (this.mouseX - this.pmouseX) / scaleFactor;
85585                var deltaPhi = sensitivityY * (this.mouseY - this.pmouseY) / scaleFactor;
85586                this._renderer._curCamera._orbit(deltaTheta, deltaPhi, 0);
85587              } else if (this.mouseButton === this.RIGHT) {
85588                // PANNING BEHAVIOR along X/Z camera axes and restricted to X/Z plane
85589                // in world space
85590                var local = cam._getLocalAxes();
85591
85592                // normalize portions along X/Z axes
85593                var xmag = Math.sqrt(local.x[0] * local.x[0] + local.x[2] * local.x[2]);
85594                if (xmag !== 0) {
85595                  local.x[0] /= xmag;
85596                  local.x[2] /= xmag;
85597                }
85598
85599                // normalize portions along X/Z axes
85600                var ymag = Math.sqrt(local.y[0] * local.y[0] + local.y[2] * local.y[2]);
85601                if (ymag !== 0) {
85602                  local.y[0] /= ymag;
85603                  local.y[2] /= ymag;
85604                }
85605
85606                // move along those vectors by amount controlled by mouseX, pmouseY
85607                var dx = -1 * sensitivityX * (this.mouseX - this.pmouseX);
85608                var dz = -1 * sensitivityY * (this.mouseY - this.pmouseY);
85609
85610                // restrict movement to XZ plane in world space
85611                cam.setPosition(
85612                  cam.eyeX + dx * local.x[0] + dz * local.z[0],
85613                  cam.eyeY,
85614                  cam.eyeZ + dx * local.x[2] + dz * local.z[2]
85615                );
85616              }
85617            }
85618            return this;
85619          };
85620
85621          /**
85622           * debugMode() helps visualize 3D space by adding a grid to indicate where the
85623           * ‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z
85624           * directions. This function can be called without parameters to create a
85625           * default grid and axes icon, or it can be called according to the examples
85626           * above to customize the size and position of the grid and/or axes icon.  The
85627           * grid is drawn using the most recently set stroke color and weight.  To
85628           * specify these parameters, add a call to stroke() and strokeWeight(
85628)
85629           * just before the end of the draw() loop.
85630           *
85631           * By default, the grid will run through the origin (0,0,0) of the sketch
85632           * along the XZ plane
85633           * and the axes icon will be offset from the origin.  Both the grid and axes
85634           * icon will be sized according to the current canvas size.  Note that because the
85635           * grid runs parallel to the default camera view, it is often helpful to use
85636           * debugMode along with orbitControl to allow full view of the grid.
85637           * @method debugMode
85638           * @example
85639           * <div>
85640           * <code>
85641           * function setup() {
85642           *   createCanvas(100, 100, WEBGL);
85643           *   camera(0, -30, 100, 0, 0, 0, 0, 1, 0);
85644           *   normalMaterial();
85645           *   debugMode();
85646           * }
85647           *
85648           * function draw() {
85649           *   background(200);
85650           *   orbitControl();
85651           *   box(15, 30);
85652           *   // Press the spacebar to turn debugMode off!
85653           *   if (keyIsDown(32)) {
85654           *     noDebugMode();
85655           *   }
85656           * }
85657           * </code>
85658           * </div>
85659           * @alt
85660           * a 3D box is centered on a grid in a 3D sketch. an icon
85661           * indicates the direction of each axis: a red line points +X,
85662           * a green line +Y, and a blue line +Z. the grid and icon disappear when the
85663           * spacebar is pressed.
85664           *
85665           * @example
85666           * <div>
85667           * <code>
85668           * function setup() {
85669           *   createCanvas(100, 100, WEBGL);
85670           *   camera(0, -30, 100, 0, 0, 0, 0, 1, 0);
85671           *   normalMaterial();
85672           *   debugMode(GRID);
85673           * }
85674           *
85675           * function draw() {
85676           *   background(200);
85677           *   orbitControl();
85678           *   box(15, 30);
85679           * }
85680           * </code>
85681           * </div>
85682           * @alt
85683           * a 3D box is centered on a grid in a 3D sketch.
85684           *
85685           * @example
85686           * <div>
85687           * <code>
85688           * function setup() {
85689           *   createCanvas(100, 100, WEBGL);
85690           *   camera(0, -30, 100, 0, 0, 0, 0, 1, 0);
85691           *   normalMaterial();
85692           *   debugMode(AXES);
85693           * }
85694           *
85695           * function draw() {
85696           *   background(200);
85697           *   orbitControl();
85698           *   box(15, 30);
85699           * }
85700           * </code>
85701           * </div>
85702           * @alt
85703           * a 3D box is centered in a 3D sketch. an icon
85704           * indicates the direction of each axis: a red line points +X,
85705           * a green line +Y, and a blue line +Z.
85706           *
85707           * @example
85708           * <div>
85709           * <code>
85710           * function setup() {
85711           *   createCanvas(100, 100, WEBGL);
85712           *   camera(0, -30, 100, 0, 0, 0, 0, 1, 0);
85713           *   normalMaterial();
85714           *   debugMode(GRID, 100, 10, 0, 0, 0);
85715           * }
85716           *
85717           * function draw() {
85718           *   background(200);
85719           *   orbitControl();
85720           *   box(15, 30);
85721           * }
85722           * </code>
85723           * </div>
85724           * @alt
85725           * a 3D box is centered on a grid in a 3D sketch
85726           *
85727           * @example
85728           * <div>
85729           * <code>
85730           * function setup() {
85731           *   createCanvas(100, 100, WEBGL);
85732           *   camera(0, -30, 100, 0, 0, 0, 0, 1, 0);
85733           *   normalMaterial();
85734           *   debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);
85735           * }
85736           *
85737           * function draw() {
85738           *   noStroke();
85739           *   background(200);
85740           *   orbitControl();
85741           *   box(15, 30);
85742           *   // set the stroke color and weight for the grid!
85743           *   stroke(255, 0, 150);
85744           *   strokeWeight(0.8);
85745           * }
85746           * </code>
85747           * </div>
85748           * @alt
85749           * a 3D box is centered on a grid in a 3D sketch. an icon
85750           * indicates the direction of each axis: a red line points +X,
85751           * a green line +Y, and a blue line +Z.
85752           */
85753
85754          /**
85755           * @method debugMode
85756           * @param {Constant} mode either GRID or AXES
85757           */
85758
85759          /**
85760           * @method debugMode
85761           * @param {Constant} mode
85762           * @param {Number} [gridSize] size of one side of the grid
85763           * @param {Number} [gridDivisions] number of divisions in the grid
85764           * @param {Number} [xOff] X axis offset from origin (0,0,0)
85765           * @param {Number} [yOff] Y axis offset from origin (0,0,0)
85766           * @param {Number} [zOff] Z axis offset from origin (0,0,0)
85767           */
85768
85769          /**
85770           * @method debugMode
85771           * @param {Constant} mode
85772           * @param {Number} [axesSize] size of axes icon
85773           * @param {Number} [xOff]
85774           * @param {Number} [yOff]
85775           * @param {Number} [zOff]
85776           */
85777
85778          /**
85779           * @method debugMode
85780           * @param {Number} [gridSize]
85781           * @param {Number} [gridDivisions]
85782           * @param {Number} [gridXOff]
85783           * @param {Number} [gridYOff]
85784           * @param {Number} [gridZOff]
85785           * @param {Number} [axesSize]
85786           * @param {Number} [axesXOff]
85787           * @param {Number} [axesYOff]
85788           * @param {Number} [axesZOff]
85789           */
85790
85791          _main.default.prototype.debugMode = function() {
85792            this._assert3d('debugMode');
85793            for (
85794              var _len = arguments.length, args = new Array(_len), _key = 0;
85795              _key < _len;
85796              _key++
85797            ) {
85798              args[_key] = arguments[_key];
85799            }
85800            _main.default._validateParameters('debugMode', args);
85801
85802            // start by removing existing 'post' registered debug methods
85803            for (var i = this._registeredMethods.post.length - 1; i >= 0; i--) {
85804              // test for equality...
85805              if (
85806                this._registeredMethods.post[i].toString() === this._grid().toString() ||
85807                this._registeredMethods.post[i].toString() === this._axesIcon().toString()
85808              ) {
85809                this._registeredMethods.post.splice(i, 1);
85810              }
85811            }
85812
85813            // then add new debugMode functions according to the argument list
85814            if (args[0] === constants.GRID) {
85815              this.registerMethod(
85816                'post',
85817                this._grid.call(this, args[1], args[2], args[3], args[4], args[5])
85818              );
85819            } else if (args[0] === constants.AXES) {
85820              this.registerMethod(
85821                'post',
85822                this._axesIcon.call(this, args[1], args[2], args[3], args[4])
85823              );
85824            } else {
85825              this.registerMethod(
85826                'post',
85827                this._grid.call(this, args[0], args[1], args[2], args[3], args[4])
85828              );
85829
85830              this.registerMethod(
85831                'post',
85832                this._axesIcon.call(this, args[5], args[6], args[7], args[8])
85833              );
85834            }
85835          };
85836
85837          /**
85838           * Turns off debugMode() in a 3D sketch.
85839           * @method noDebugMode
85840           * @example
85841           * <div>
85842           * <code>
85843           * function setup() {
85844           *   createCanvas(100, 100, WEBGL);
85845           *   camera(0, -30, 100, 0, 0, 0, 0, 1, 0);
85846           *   normalMaterial();
85847           *   debugMode();
85848           * }
85849           *
85850           * function draw() {
85851           *   background(200);
85852           *   orbitControl();
85853           *   box(15, 30);
85854           *   // Press the spacebar to turn debugMode off!
85855           *   if (keyIsDown(32)) {
85856           *     noDebugMode();
85857           *   }
85858           * }
85859           * </code>
85860           * </div>
85861           * @alt
85862           * a 3D box is centered on a grid in a 3D sketch. an icon
85863           * indicates the direction of each axis: a red line points +X,
85864           * a green line +Y, and a blue line +Z. the grid and icon disappear when the
85865           * spacebar is pressed.
85866           */
85867          _main.default.prototype.noDebugMode = function() {
85868            this._assert3d('noDebugMode');
85869
85870            // start by removing existing 'post' registered debug methods
85871            for (var i = this._registeredMethods.post.length - 1; i >= 0; i--) {
85872              // test for equality...
85873              if (
85874                this._registeredMethods.post[i].toString() === this._grid().toString() ||
85875                this._registeredMethods.post[i].toString() === this._axesIcon().toString()
85876              ) {
85877                this._registeredMethods.post.splice(i, 1);
85878              }
85879            }
85880          };
85881
85882          /**
85883           * For use with debugMode
85884           * @private
85885           * @method _grid
85886           * @param {Number}
85886 [size] size of grid sides
85887           * @param {Number} [div] number of grid divisions
85888           * @param {Number} [xOff] offset of grid center from origin in X axis
85889           * @param {Number} [yOff] offset of grid center from origin in Y axis
85890           * @param {Number} [zOff] offset of grid center from origin in Z axis
85891           */
85892          _main.default.prototype._grid = function(size, numDivs, xOff, yOff, zOff) {
85893            if (typeof size === 'undefined') {
85894              size = this.width / 2;
85895            }
85896            if (typeof numDivs === 'undefined') {
85897              // ensure at least 2 divisions
85898              numDivs = Math.round(size / 30) < 4 ? 4 : Math.round(size / 30);
85899            }
85900            if (typeof xOff === 'undefined') {
85901              xOff = 0;
85902            }
85903            if (typeof yOff === 'undefined') {
85904              yOff = 0;
85905            }
85906            if (typeof zOff === 'undefined') {
85907              zOff = 0;
85908            }
85909
85910            var spacing = size / numDivs;
85911            var halfSize = size / 2;
85912
85913            return function() {
85914              this.push();
85915              this.stroke(
85916                this._renderer.curStrokeColor[0] * 255,
85917                this._renderer.curStrokeColor[1] * 255,
85918                this._renderer.curStrokeColor[2] * 255
85919              );
85920
85921              this._renderer.uMVMatrix.set(
85922                this._renderer._curCamera.cameraMatrix.mat4[0],
85923                this._renderer._curCamera.cameraMatrix.mat4[1],
85924                this._renderer._curCamera.cameraMatrix.mat4[2],
85925                this._renderer._curCamera.cameraMatrix.mat4[3],
85926                this._renderer._curCamera.cameraMatrix.mat4[4],
85927                this._renderer._curCamera.cameraMatrix.mat4[5],
85928                this._renderer._curCamera.cameraMatrix.mat4[6],
85929                this._renderer._curCamera.cameraMatrix.mat4[7],
85930                this._renderer._curCamera.cameraMatrix.mat4[8],
85931                this._renderer._curCamera.cameraMatrix.mat4[9],
85932                this._renderer._curCamera.cameraMatrix.mat4[10],
85933                this._renderer._curCamera.cameraMatrix.mat4[11],
85934                this._renderer._curCamera.cameraMatrix.mat4[12],
85935                this._renderer._curCamera.cameraMatrix.mat4[13],
85936                this._renderer._curCamera.cameraMatrix.mat4[14],
85937                this._renderer._curCamera.cameraMatrix.mat4[15]
85938              );
85939
85940              // Lines along X axis
85941              for (var q = 0; q <= numDivs; q++) {
85942                this.beginShape(this.LINES);
85943                this.vertex(-halfSize + xOff, yOff, q * spacing - halfSize + zOff);
85944                this.vertex(+halfSize + xOff, yOff, q * spacing - halfSize + zOff);
85945                this.endShape();
85946              }
85947
85948              // Lines along Z axis
85949              for (var i = 0; i <= numDivs; i++) {
85950                this.beginShape(this.LINES);
85951                this.vertex(i * spacing - halfSize + xOff, yOff, -halfSize + zOff);
85952                this.vertex(i * spacing - halfSize + xOff, yOff, +halfSize + zOff);
85953                this.endShape();
85954              }
85955
85956              this.pop();
85957            };
85958          };
85959
85960          /**
85961           * For use with debugMode
85962           * @private
85963           * @method _axesIcon
85964           * @param {Number} [size] size of axes icon lines
85965           * @param {Number} [xOff] offset of icon from origin in X axis
85966           * @param {Number} [yOff] offset of icon from origin in Y axis
85967           * @param {Number} [zOff] offset of icon from origin in Z axis
85968           */
85969          _main.default.prototype._axesIcon = function(size, xOff, yOff, zOff) {
85970            if (typeof size === 'undefined') {
85971              size = this.width / 20 > 40 ? this.width / 20 : 40;
85972            }
85973            if (typeof xOff === 'undefined') {
85974              xOff = -this.width / 4;
85975            }
85976            if (typeof yOff === 'undefined') {
85977              yOff = xOff;
85978            }
85979            if (typeof zOff === 'undefined') {
85980              zOff = xOff;
85981            }
85982
85983            return function() {
85984              this.push();
85985              this._renderer.uMVMatrix.set(
85986                this._renderer._curCamera.cameraMatrix.mat4[0],
85987                this._renderer._curCamera.cameraMatrix.mat4[1],
85988                this._renderer._curCamera.cameraMatrix.mat4[2],
85989                this._renderer._curCamera.cameraMatrix.mat4[3],
85990                this._renderer._curCamera.cameraMatrix.mat4[4],
85991                this._renderer._curCamera.cameraMatrix.mat4[5],
85992                this._renderer._curCamera.cameraMatrix.mat4[6],
85993                this._renderer._curCamera.cameraMatrix.mat4[7],
85994                this._renderer._curCamera.cameraMatrix.mat4[8],
85995                this._renderer._curCamera.cameraMatrix.mat4[9],
85996                this._renderer._curCamera.cameraMatrix.mat4[10],
85997                this._renderer._curCamera.cameraMatrix.mat4[11],
85998                this._renderer._curCamera.cameraMatrix.mat4[12],
85999                this._renderer._curCamera.cameraMatrix.mat4[13],
86000                this._renderer._curCamera.cameraMatrix.mat4[14],
86001                this._renderer._curCamera.cameraMatrix.mat4[15]
86002              );
86003
86004              // X axis
86005              this.strokeWeight(2);
86006              this.stroke(255, 0, 0);
86007              this.beginShape(this.LINES);
86008              this.vertex(xOff, yOff, zOff);
86009              this.vertex(xOff + size, yOff, zOff);
86010              this.endShape();
86011              // Y axis
86012              this.stroke(0, 255, 0);
86013              this.beginShape(this.LINES);
86014              this.vertex(xOff, yOff, zOff);
86015              this.vertex(xOff, yOff + size, zOff);
86016              this.endShape();
86017              // Z axis
86018              this.stroke(0, 0, 255);
86019              this.beginShape(this.LINES);
86020              this.vertex(xOff, yOff, zOff);
86021              this.vertex(xOff, yOff, zOff + size);
86022              this.endShape();
86023              this.pop();
86024            };
86025          };
86026          var _default = _main.default;
86027          exports.default = _default;
86028        },
86029        { '../core/constants': 48, '../core/main': 59 }
86030      ],
86031      104: [
86032        function(_dereq_, module, exports) {
86033          'use strict';
86034          Object.defineProperty(exports, '__esModule', { value: true });
86035          exports.default = void 0;
86036
86037          var _main = _interopRequireDefault(_dereq_('../core/main'));
86038          function _interopRequireDefault(obj) {
86039            return obj && obj.__esModule ? obj : { default: obj };
86040          } /**
86041           * @method ambientLight
86042           * @param  {String}        value   a color string
86043           * @chainable
86044           */ /**
86045           * @module Lights, Camera
86046           * @submodule Lights
86047           * @for p5
86048           * @requires core
86049           */ /**
86050           * Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.
86051           * It has no particular source.
86052           * @method ambientLight
86053           * @param  {Number}        v1      red or hue value relative to
86054           *                                 the current color range
86055           * @param  {Number}        v2      green or saturation value
86056           *                                 relative to the current color range
86057           * @param  {Number}        v3      blue or brightness value
86058           *                                 relative to the current color range
86059           * @param  {Number}        [alpha] the alpha value
86060           * @chainable
86061           *
86062           * @example
86063           * <div>
86064           * <code>
86065           * createCanvas(100, 100, WEBGL);
86066           * ambientLight(0);
86067           * ambientMaterial(250);
86068           * sphere(40);
86069           * </code>
86070           * </div>
86071           * <div>
86072           * <code>
86073           * function setup() {
86074           *   createCanvas(100, 100, WEBGL);
86075           * }
86076           * function draw() {
86077           *   background(51);
86078           *   ambientLight(100); // white light
86079           *   ambientMaterial(255, 102, 94); // magenta material
86080           *   box(30);
86081           * }
86082           * </code>
86083           * </div>
86084           * @alt
86085           * evenly distributed light across a sphere
86086           * evenly distributed light across a rotating sphere
86087           */
86088          /**
86089           * @method ambientLight
86090           * @param  {Number}        gray   a gray value
86091           * @param  {Number}        [alpha]
86092           * @chainable
86093           */
86094
86095          /**
86096           * @method ambientLight
86097           * @param  {Number[]}      values  an array containing the red,green,blue &
86098           *                                 and alpha components of the color
86099           * @chainable
86100           */
86101
86102          /**
86103           * @method ambientLight
86104           * @param  {p5.Color}      color   the ambient light color
86105           * @chainable
86106           */
86107          _main.default.prototype.ambientLight = function(v1, v2, v3, a) {
86108            this._assert3d('ambientLight');
86109            _main.default._validateParameters('ambientLight', arguments);
86110            var color = this.color.apply(this, arguments);
86111
86112            this._renderer.ambientLightColors.push(
86113              color._array[0],
86114              color._array[1],
86115              color._array[2]
86116            );
86117
86118            this._renderer._enableLighting = true;
86119
86120            return this;
86121          };
86122
86123          /**
86124           * Set's the color of the specular highlight when using a specular material and
86125           * specular light.
86126           *
86127           * This method can be combined with specularMaterial() and shininess()
86128           * functions to set specular highlights. The default color is white, ie
86129           * (255, 255, 255), which is used if this method is not called before
86130           * specularMaterial(). If this method is called without specularMaterial(),
86131           * There will be no effect.
86132           *
86133           * Note: specularColor is equivalent to the processing function
86134           * <a href="https://processing.org/reference/lightSpecular_.html">lightSpecular</a>.
86135           *
86136           * @method specularColor
86137           * @param  {Number}        v1      red or hue value relative to
86138           *                                 the current color range
86139           * @param  {Number}        v2      green or saturation value
86140           *                                 relative to the current color range
86141           * @param  {Number}        v3      blue or brightness value
86142           *                                 relative to the current color range
86143           * @chainable
86144           * @example
86145           * <div>
86146           * <code>
86147           * function setup() {
86148           *   createCanvas(100, 100, WEBGL);
86149           *   noStroke();
86150           * }
86151           *
86152           * function draw() {
86153           *   background(0);
86154           *   shininess(20);
86155           *   ambientLight(50);
86156           *   specularColor(255, 0, 0);
86157           *   pointLight(255, 0, 0, 0, -50, 50);
86158           *   specularColor(0, 255, 0);
86159           *   pointLight(0, 255, 0, 0, 50, 50);
86160           *   specularMaterial(255);
86161           *   sphere(40);
86162           * }
86163           * </code>
86164           * </div>
86165           *
86166           * @alt
86167           * different specular light sources from top and bottom of canvas
86168           */
86169
86170          /**
86171           * @method specularColor
86172           * @param  {String}        value   a color string
86173           * @chainable
86174           */
86175
86176          /**
86177           * @method specularColor
86178           * @param  {Number}        gray   a gray value
86179           * @chainable
86180           */
86181
86182          /**
86183           * @method specularColor
86184           * @param  {Number[]}      values  an array containing the red,green,blue &
86185           *                                 and alpha components of the color
86186           * @chainable
86187           */
86188
86189          /**
86190           * @method specularColor
86191           * @param  {p5.Color}      color   the ambient light color
86192           * @chainable
86193           */
86194          _main.default.prototype.specularColor = function(v1, v2, v3) {
86195            this._assert3d('specularColor');
86196            _main.default._validateParameters('specularColor', arguments);
86197            var color = this.color.apply(this, arguments);
86198
86199            this._renderer.specularColors = [
86200              color._array[0],
86201              color._array[1],
86202              color._array[2]
86203            ];
86204
86205            return this;
86206          };
86207
86208          /**
86209           * Creates a directional light with a color and a direction
86210           *
86211           * A maximum of 5 directionalLight can be active at one time
86212           * @method directionalLight
86213           * @param  {Number}    v1       red or hue value (depending on the current
86214           * color mode),
86215           * @param  {Number}    v2       green or saturation value
86216           * @param  {Number}    v3       blue or brightness value
86217           * @param  {p5.Vector} position the direction of the light
86218           * @chainable
86219           * @example
86220           * <div>
86221           * <code>
86222           * function setup() {
86223           *   createCanvas(100, 100, WEBGL);
86224           * }
86225           * function draw() {
86226           *   background(0);
86227           *   //move your mouse to change light direction
86228           *   let dirX = (mouseX / width - 0.5) * 2;
86229           *   let dirY = (mouseY / height - 0.5) * 2;
86230           *   directionalLight(250, 250, 250, -dirX, -dirY, -1);
86231           *   noStroke();
86232           *   sphere(40);
86233           * }
86234           * </code>
86235           * </div>
86236           *
86237           * @alt
86238           * light source on canvas changeable with mouse position
86239           */
86240
86241          /**
86242           * @method directionalLight
86243           * @param  {Number[]|String|p5.Color} color   color Array, CSS color string,
86244           *                                             or <a href="#/p5.Color">p5.Color</a> value
86245           * @param  {Number}                   x       x axis direction
86246           * @param  {Number}                   y       y axis direction
86247           * @param  {Number}                   z       z axis direction
86248           * @chainable
86249           */
86250
86251          /**
86252           * @method directionalLight
86253           * @param  {Number[]|String|p5.Color} color
86254           * @param  {p5.Vector}                position
86255           * @chainable
86256           */
86257
86258          /**
86259           * @method directionalLight
86260           * @param  {Number}    v1
86261           * @param  {Number}    v2
86262           * @param  {Number}    v3
86263           * @param  {Number}    x
86264           * @param  {Number}    y
86265           * @param  {Number}    z
86266           * @chainable
86267           */
86268          _main.default.prototype.directionalLight = function(v1, v2, v3, x, y, z) {
86269            this._assert3d('directionalLight');
86270            _main.default._validateParameters('directionalLight', arguments);
86271
86272            //@TODO: check parameters number
86273            var color;
86274            if (v1 instanceof _main.default.Color) {
86275              color = v1;
86276            } else {
86277              color = this.color(v1, v2, v3);
86278            }
86279
86280            var _x, _y, _z;
86281            var v = arguments[arguments.length - 1];
86282            if (typeof v === 'number') {
86283              _x = arguments[arguments.length - 3];
86284              _y = arguments[arguments.length - 2];
86285              _z = arguments[arguments.length - 1];
86286            } else {
86287              _x = v.x;
86288              _y = v.y;
86289              _z = v.z;
86290            }
86291
86292            // normalize direction
86293            var l = Math.sqrt(_x * _x + _y * _y + _z * _z);
86294            this._renderer.directionalLightDirections.push(_x / l, _y / l, _z / l);
86295
86296            this._renderer.directionalLightDiffuseColors.push(
86297              color._array[0],
86298              color._array[1],
86299              color._array[2]
86300            );
86301
86302            Array.prototype.push.apply(
86303              this._renderer.directionalLightSpecularColors,
86304              this._renderer.specularColors
86305            );
86306
86307            this._renderer._enableLighting = true;
86308
86309            return this;
86310          };
86311
86312          /**
86313           * Creates a point light with a color and a light position
86314           *
86315           * A maximum of 5 pointLight can be active at one time
86316           * @method pointLight
86317           * @param  {Number}    v1       red or hue value (depending on the current
86318           * color mode),
86319           * @param  {Number}    v2       green or saturation value
86320           * @param  {Number}    v3       blue or brightness value
86321           * @param  {Number}    x        x axis position
86322           * @param  {Number}    y        y axis position
86323           * @param  {Number}    z        z axis position
86324           * @chainable
86325           * @example
86326           * <div>
86327           * <code>
86328           * function setup() {
86329           *   createCanvas(100, 100, WEBGL);
86330           * }
86331           * function draw() {
86332           *   background(0);
86333           *   //move your mouse to change light position
86334           *   let locX = mouseX - width / 2;
86335           *   let locY = mouseY - height / 2;
86336           *   // to set the light position,
86337           *   // think of the world's coordinate as:
86338           *   // -width/2,-height/2 -------- width/2,-height/2
86339           *   //                |            |
86340           *   //                |     0,0    |
86341           *   //                |            |
86342           *   // -width/2,height/2--------width/2,height/2
86343           *   pointLight(250, 250, 250, locX, locY, 50);
86344           *   noStroke();
86345           *   sphere(40);
86346           * }
86347           * </code>
86348           * </div>
86349           *
86350           * @alt
86351           * spot light on canvas changes position with mouse
86352           */
86353
86354          /**
86355           * @method pointLight
86356           * @param  {Number}    v1
86357           * @param  {Number}    v2
86358           * @param  {Number}    v3
86359           * @param  {p5.Vector} position the position of the light
86360           * @chainable
86361           */
86362
86363          /**
86364           * @method pointLight
86365           * @param  {Number[]|String|p5.Color} color   color Array, CSS color string,
86366           * or <a href="#/p5.Color">p5.Color</a> value
86367           * @param  {Number}                   x
86368           * @param  {Number}                   y
86369           * @param  {Number}                   z
86370           * @chainable
86371           */
86372
86373          /**
86374           * @method pointLight
86375           * @param  {Number[]|String|p5.Color} color
86376           * @param  {p5.Vector}                position
86377           * @chainable
86378           */
86379          _main.default.prototype.pointLight = function(v1, v2, v3, x, y, z) {
86380            this._assert3d('pointLight');
86381            _main.default._validateParameters('pointLight', arguments);
86382
86383            //@TODO: check parameters number
86384            var color;
86385            if (v1 instanceof _main.default.Color) {
86386              color = v1;
86387            } else {
86388              color = this.color(v1, v2, v3);
86389            }
86390
86391            var _x, _y, _z;
86392            var v = arguments[arguments.length - 1];
86393            if (typeof v === 'number') {
86394              _x = arguments[arguments.length - 3];
86395              _y = arguments[arguments.length - 2];
86396              _z = arguments[arguments.length - 1];
86397            } else {
86398              _x = v.x;
86399              _y = v.y;
86400              _z = v.z;
86401            }
86402
86403            this._renderer.pointLightPositions.push(_x, _y, _z);
86404            this._renderer.pointLightDiffuseColors.push(
86405              color._array[0],
86406              color._array[1],
86407              color._array[2]
86408            );
86409
86410            Array.prototype.push.apply(
86411              this._renderer.pointLightSpecularColors,
86412              this._renderer.specularColors
86413            );
86414
86415            this._renderer._enableLighting = true;
86416
86417            return this;
86418          };
86419
86420          /**
86421           * Sets the default ambient and directional light. The defaults are <a href="#/p5/ambientLight">ambientLight(128, 128, 128)</a> and <a href="#/p5/directionalLight">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href="#/p5/draw">draw()</a> to remain persistent in a looping program. Placing them in the <a href="#/p5/setup">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.
86422           * @method lights
86423           * @chainable
86424           * @example
86425           * <div>
86426           * <code>
86427           * function setup() {
86428           *   createCanvas(100, 100, WEBGL);
86429           * }
86430           * function draw() {
86431           *   background(0);
86432           *   lights();
86433           *   rotateX(millis() / 1000);
86434           *   rotateY(millis() / 1000);
86435           *   rotateZ(millis() / 1000);
86436           *   box();
86437           * }
86438           * </code>
86439           * </div>
86440           *
86441           * @alt
86442           * the light is partially ambient and partially directional
86443           */
86444          _main.default.prototype.lights = function() {
86445            this._assert3d('lights');
86446            this.ambientLight(128, 128, 128);
86447            this.directionalLight(128, 128, 128, 0, 0, -1);
86448            return this;
86449          };
86450
86451          /**
86452           * Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.
86453           * The default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:
86454           *
86455           * d = distance from light position to vertex position
86456           *
86457           * falloff = 1 / (CONSTANT + d \* LINEAR + ( d \* d ) \* QUADRATIC)
86458           *
86459           * @method lightFalloff
86460           * @param {Number} constant   constant value for determining falloff
86461           * @param {Number} linear     linear value for determining falloff
86462           * @param {Number} quadratic  quadratic value for determining falloff
86463           * @chainable
86464           * @example
86465           * <div>
86466           * <code>
86467           * function setup() {
86468           *   createCanvas(100, 100, WEBGL);
86469           *   noStroke();
86470           * }
86471           * function draw() {
86472           *   background(0);
86473           *   let locX = mouseX - width / 2;
86474           *   let locY = mouseY - height / 2;
86475           *   translate(-25, 0, 0);
86476           *   lightFalloff(1, 0, 0);
86477           *   pointLight(250, 250, 250, locX, locY, 50);
86478           *   sphere(20);
86479           *   translate(50, 0, 0);
86480           *   lightFalloff(0.9, 0.01, 0);
86481           *   pointLight(250, 250, 250, locX, locY, 50);
86482           *   sphere(20);
86483           * }
86484           * </code>
86485           * </div>
86486           *
86487           * @alt
86488           * Two spheres with different falloff values show different intensity of light
86489           */
86490          _main.default.prototype.lightFalloff = function(
86491            constantAttenuation,
86492            linearAttenuation,
86493            quadraticAttenuation
86494          ) {
86495            this._assert3d('lightFalloff');
86496            _main.default._validateParameters('lightFalloff', arguments);
86497
86498            if (constantAttenuation < 0) {
86499              constantAttenuation = 0;
86500              console.warn(
86501                'Value of constant argument in lightFalloff() should be never be negative. Set to 0.'
86502              );
86503            }
86504
86505            if (linearAttenuation < 0) {
86506              linearAttenuation = 0;
86507              console.warn(
86508                'Value of linear argument in lightFalloff() should be never be negative. Set to 0.'
86509              );
86510            }
86511
86512            if (quadraticAttenuation < 0) {
86513              quadraticAttenuation = 0;
86514              console.warn(
86515                'Value of quadratic argument in lightFalloff() should be never be negative. Set to 0.'
86516              );
86517            }
86518
86519            if (
86520              constantAttenuation === 0 &&
86521              linearAttenuation === 0 &&
86522              quadraticAttenuation === 0
86523            ) {
86524              constantAttenuation = 1;
86525              console.warn(
86526                'Either one of the three arguments in lightFalloff() should be greater than zero. Set constant argument to 1.'
86527              );
86528            }
86529
86530            this._renderer.constantAttenuation = constantAttenuation;
86531            this._renderer.linearAttenuation = linearAttenuation;
86532            this._renderer.quadraticAttenuation = quadraticAttenuation;
86533
86534            return this;
86535          };
86536
86537          /**
86538           * Creates a spotlight with a given color, position, direction of light,
86539           * angle and concentration. Here, angle refers to the opening or aperture
86540           * of the cone of the spotlight, and concentration is used to focus the
86541           * light towards the center. Both angle and concentration are optional, but if
86542           * you want to provide concentration, you will also have to specify the angle.
86543           *
86544           * A maximum of 5 spotLight can be active at one time
86545           * @method spotLight
86546           * @param  {Number}    v1       red or hue value (depending on the current
86547           * color mode),
86548           * @param  {Number}    v2       green or saturation value
86549           * @param  {Number}    v3       blue or brightness value
86550           * @param  {Number}    x        x axis position
86551           * @param  {Number}    y        y axis position
86552           * @param  {Number}    z        z axis position
86553           * @param  {Number}    rx       x axis direction of light
86554           * @param  {Number}    ry       y axis direction of light
86555           * @param  {Number}    rz       z axis direction of light
86556           * @param  {Number}    [angle]  optional parameter for angle. Defaults to PI/3
86557           * @param  {Number}    [conc]   optional parameter for concentration. Defaults to 100
86558           * @chainable
86559           *
86560           * @example
86561           * <div>
86562           * <code>
86563           * function setup() {
86564           *   createCanvas(100, 100, WEBGL);
86565           * }
86566           * function draw() {
86567           *   background(0);
86568           *   //move your mouse to change light position
86569           *   let locX = mouseX - width / 2;
86570           *   let locY = mouseY - height / 2;
86571           *   // to set the light position,
86572           *   // think of the world's coordinate as:
86573           *   // -width/2,-height/2 -------- width/2,-height/2
86574           *   //                |            |
86575           *   //                |     0,0    |
86576           *   //                |            |
86577           *   // -width/2,height/2--------width/2,height/2
86578           *   ambientLight(50);
86579           *   spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);
86580           *   noStroke();
86581           *   sphere(40);
86582           * }
86583           * </code>
86584           * </div>
86585           *
86586           * @alt
86587           * Spot light on a sphere which changes position with mouse
86588           */
86589          /**
86590           * @method spotLight
86591           * @param  {Number[]|String|p5.Color} color color Array, CSS color string,
86592           * or <a href="#/p5.Color">p5.Color</a> value
86593           * @param  {p5.Vector}                position the position of the light
86594           * @param  {p5.Vector}                direction the direction of the light
86595           * @param  {Number}                   [angle]
86596           * @param  {Number}                   [conc]
86597           */
86598          /**
86599           * @method spotLight
86600           * @param  {Number}     v1
86601           * @param  {Number}     v2
86602           * @param  {Number}     v3
86603           * @param  {p5.Vector}  position
86604           * @param  {p5.Vector}  direction
86605           * @param  {Number}     [angle]
86606           * @param  {Number}     [conc]
86607           */
86608          /**
86609           * @method spotLight
86610           * @param  {Number[]|String|p5.Color} color
86611           * @param  {Number}                   x
86612           * @param  {Number}                   y
86613           * @param  {Number}                   z
86614           * @param  {p5.Vector}                direction
86615           * @param  {Number}                   [angle]
86616           * @param  {Number}                   [conc]
86617           */
86618          /**
86619           * @method spotLight
86620           * @param  {Number[]|String|p5.Color} color
86621           * @param  {p5.Vector}                position
86622           * @param  {Number}                   rx
86623           * @param  {Number}                   ry
86624           * @param  {Number}                   rz
86625           * @param  {Number}                   [angle]
86626           * @param  {Number}                   [conc]
86627           */
86628          /**
86629           * @method spotLight
86630           * @param  {Number}     v1
86631           * @param  {Number}     v2
86632           * @param  {Number}     v3
86633           * @param  {Number}     x
86634           * @param  {Number}     y
86635           * @param  {Number}     z
86636           * @param  {p5.Vector}  direction
86637           * @param  {Number}     [angle]
86638           * @param  {Number}     [conc]
86639           */
86640          /**
86641           * @method spotLight
86642           * @param  {Number}     v1
86643           * @param  {Number}     v2
86644           * @param  {Number}     v3
86645           * @param  {p5.Vector}  position
86646           * @param  {Number}     rx
86647           * @param  {Number}     ry
86648           * @param  {Number}     rz
86649           * @param  {Number}     [angle]
86650           * @param  {Number}     [conc]
86651           */
86652          /**
86653           * @method spotLight
86654           * @param  {Number[]|String|p5.Color} color
86655           * @param  {Number}                   x
86656           * @param  {Number}                   y
86657           * @param  {Number}                   z
86658           * @param  {Number}                   rx
86659           * @param  {Number}                   ry
86660           * @param  {Number}                   rz
86661           * @param  {Number}                   [angle]
86662           * @param  {Number}                   [conc]
86663           */
86664          _main.default.prototype.spotLight = function(
86665            v1,
86666            v2,
86667            v3,
86668            x,
86669            y,
86670            z,
86671            nx,
86672            ny,
86673            nz,
86674            angle,
86675            concentration
86676          ) {
86677            this._assert3d('spotLight');
86678            _main.default._validateParameters('spotLight', arguments);
86679
86680            var color, position, direction;
86681            var length = arguments.length;
86682
86683            switch (length) {
86684              case 11:
86685              case 10:
86686                color = this.color(v1, v2, v3);
86687                position = new _main.default.Vector(x, y, z);
86688                direction = new _main.default.Vector(nx, ny, nz);
86689                break;
86690
86691              case 9:
86692                if (v1 instanceof _main.default.Color) {
86693                  color = v1;
86694                  position = new _main.default.Vector(v2, v3, x);
86695                  direction = new _main.default.Vector(y, z, nx);
86696                  angle = ny;
86697                  concentration = nz;
86698                } else if (x instanceof _main.default.Vector) {
86699                  color = this.color(v1, v2, v3);
86700                  position = x;
86701                  direction = new _main.default.Vector(y, z, nx);
86702                  angle = ny;
86703                  concentration = nz;
86704                } else if (nx instanceof _main.default.Vector) {
86705                  color = this.color(v1, v2, v3);
86706                  position = new _main.default.Vector(x, y, z);
86707                  direction = nx;
86708                  angle = ny;
86709                  concentration = nz;
86710                } else {
86711                  color = this.color(v1, v2, v3);
86712                  position = new _main.default.Vector(x, y, z);
86713                  direction = new _main.default.Vector(nx, ny, nz);
86714                }
86715                break;
86716
86717              case 8:
86718                if (v1 instanceof _main.default.Color) {
86719                  color = v1;
86720                  position = new _main.default.Vector(v2, v3, x);
86721                  direction = new _main.default.Vector(y, z, nx);
86722                  angle = ny;
86723                } else if (x instanceof _main.default.Vector) {
86724                  color = this.color(v1, v2, v3);
86725                  position = x;
86726                  direction = new _main.default.Vector(y, z, nx);
86727                  angle = ny;
86728                } else {
86729                  color = this.color(v1, v2, v3);
86730                  position = new _main.default.Vector(x, y, z);
86731                  direction = nx;
86732                  angle = ny;
86733                }
86734                break;
86735
86736              case 7:
86737                if (
86738                  v1 instanceof _main.default.Color &&
86739                  v2 instanceof _main.default.Vector
86740                ) {
86741                  color = v1;
86742                  position = v2;
86743                  direction = new _main.default.Vector(v3, x, y);
86744                  angle = z;
86745                  concentration = nx;
86746                } else if (
86747                  v1 instanceof _main.default.Color &&
86748                  y instanceof _main.default.Vector
86749                ) {
86750                  color = v1;
86751                  position = new _main.default.Vector(v2, v3, x);
86752                  direction = y;
86753                  angle = z;
86754                  concentration = nx;
86755                } else if (
86756                  x instanceof _main.default.Vector &&
86757                  y instanceof _main.default.Vector
86758                ) {
86759                  color = this.color(v1, v2, v3);
86760                  position = x;
86761                  direction = y;
86762                  angle = z;
86763                  concentration = nx;
86764                } else if (v1 instanceof _main.default.Color) {
86765                  color = v1;
86766                  position = new _main.default.Vector(v2, v3, x);
86767                  direction = new _main.default.Vector(y, z, nx);
86768                } else if (x instanceof _main.default.Vector) {
86769                  color = this.color(v1, v2, v3);
86770                  position = x;
86771                  direction = new _main.default.Vector(y, z, nx);
86772                } else {
86773                  color = this.color(v1, v2, v3);
86774                  position = new _main.default.Vector(x, y, z);
86775                  direction = nx;
86776                }
86777                break;
86778
86779              case 6:
86780                if (
86781                  x instanceof _main.default.Vector &&
86782                  y instanceof _main.default.Vector
86783                ) {
86784                  color = this.color(v1, v2, v3);
86785                  position = x;
86786                  direction = y;
86787                  angle = z;
86788                } else if (
86789                  v1 instanceof _main.default.Color &&
86790                  y instanceof _main.default.Vector
86791                ) {
86792                  color = v1;
86793                  position = new _main.default.Vector(v2, v3, x);
86794                  direction = y;
86795                  angle = z;
86796                } else if (
86797                  v1 instanceof _main.default.Color &&
86798                  v2 instanceof _main.default.Vector
86799                ) {
86800                  color = v1;
86801                  position = v2;
86802                  direction = new _main.default.Vector(v3, x, y);
86803                  angle = z;
86804                }
86805                break;
86806
86807              case 5:
86808                if (
86809                  v1 instanceof _main.default.Color &&
86810                  v2 instanceof _main.default.Vector &&
86811                  v3 instanceof _main.default.Vector
86812                ) {
86813                  color = v1;
86814                  position = v2;
86815                  direction = v3;
86816                  angle = x;
86817                  concentration = y;
86818                } else if (
86819                  x instanceof _main.default.Vector &&
86820                  y instanceof _main.default.Vector
86821                ) {
86822                  color = this.color(v1, v2, v3);
86823                  position = x;
86824                  direction = y;
86825                } else if (
86826                  v1 instanceof _main.default.Color &&
86827                  y instanceof _main.default.Vector
86828                ) {
86829                  color = v1;
86830                  position = new _main.default.Vector(v2, v3, x);
86831                  direction = y;
86832                } else if (
86833                  v1 instanceof _main.default.Color &&
86834                  v2 instanceof _main.default.Vector
86835                ) {
86836                  color = v1;
86837                  position = v2;
86838                  direction = new _main.default.Vector(v3, x, y);
86839                }
86840                break;
86841
86842              case 4:
86843                color = v1;
86844                position = v2;
86845                direction = v3;
86846                angle = x;
86847                break;
86848
86849              case 3:
86850                color = v1;
86851                position = v2;
86852                direction = v3;
86853                break;
86854
86855              default:
86856                console.warn(
86857                  'Sorry, input for spotlight() is not in prescribed format. Too '.concat(
86858                    length < 3 ? 'few' : 'many',
86859                    ' arguments were provided'
86860                  )
86861                );
86862
86863                return this;
86864            }
86865
86866            this._renderer.spotLightDiffuseColors.push(
86867              color._array[0],
86868              color._array[1],
86869              color._array[2]
86870            );
86871
86872            Array.prototype.push.apply(
86873              this._renderer.spotLightSpecularColors,
86874              this._renderer.specularColors
86875            );
86876
86877            this._renderer.spotLightPositions.push(position.x, position.y, position.z);
86878            direction.normalize();
86879            this._renderer.spotLightDirections.push(direction.x, direction.y, direction.z);
86880
86881            if (angle === undefined) {
86882              angle = Math.PI / 3;
86883            }
86884
86885            if (concentration !== undefined && concentration < 1) {
86886              concentration = 1;
86887              console.warn(
86888                'Value of concentration needs to be greater than 1. Setting it to 1'
86889              );
86890            } else if (concentration === undefined) {
86891              concentration = 100;
86892            }
86893
86894            angle = this._renderer._pInst._toRadians(angle);
86895            this._renderer.spotLightAngle.push(Math.cos(angle));
86896            this._renderer.spotLightConc.push(concentration);
86897
86898            this._renderer._enableLighting = true;
86899
86900            return this;
86901          };
86902
86903          /**
86904           * This function will remove all the lights from the sketch for the
86905           * subsequent materials rendered. It affects all the subsequent methods.
86906           * Calls to lighting methods made after noLights() will re-enable
86906 lights
86907           * in the sketch.
86908           * @method noLights
86909           * @chainable
86910           * @example
86911           * <div>
86912           * <code>
86913           * function setup() {
86914           *   createCanvas(100, 100, WEBGL);
86915           * }
86916           * function draw() {
86917           *   background(0);
86918           *   noStroke();
86919           *
86920           *   ambientLight(150, 0, 0);
86921           *   translate(-25, 0, 0);
86922           *   ambientMaterial(250);
86923           *   sphere(20);
86924           *
86925           *   noLights();
86926           *   ambientLight(0, 150, 0);
86927           *   translate(50, 0, 0);
86928           *   ambientMaterial(250);
86929           *   sphere(20);
86930           * }
86931           * </code>
86932           * </div>
86933           *
86934           * @alt
86935           * Two spheres showing different colors
86936           */
86937          _main.default.prototype.noLights = function() {
86938            this._assert3d('noLights');
86939            _main.default._validateParameters('noLights', arguments);
86940
86941            this._renderer._enableLighting = false;
86942
86943            this._renderer.ambientLightColors.length = 0;
86944            this._renderer.specularColors = [1, 1, 1];
86945
86946            this._renderer.directionalLightDirections.length = 0;
86947            this._renderer.directionalLightDiffuseColors.length = 0;
86948            this._renderer.directionalLightSpecularColors.length = 0;
86949
86950            this._renderer.pointLightPositions.length = 0;
86951            this._renderer.pointLightDiffuseColors.length = 0;
86952            this._renderer.pointLightSpecularColors.length = 0;
86953
86954            this._renderer.spotLightPositions.length = 0;
86955            this._renderer.spotLightDirections.length = 0;
86956            this._renderer.spotLightDiffuseColors.length = 0;
86957            this._renderer.spotLightSpecularColors.length = 0;
86958            this._renderer.spotLightAngle.length = 0;
86959            this._renderer.spotLightConc.length = 0;
86960
86961            this._renderer.constantAttenuation = 1;
86962            this._renderer.linearAttenuation = 0;
86963            this._renderer.quadraticAttenuation = 0;
86964            this._renderer._useShininess = 1;
86965
86966            return this;
86967          };
86968          var _default = _main.default;
86969          exports.default = _default;
86970        },
86971        { '../core/main': 59 }
86972      ],
86973      105: [
86974        function(_dereq_, module, exports) {
86975          'use strict';
86976          Object.defineProperty(exports, '__esModule', { value: true });
86977          exports.default = void 0;
86978
86979          var _main = _interopRequireDefault(_dereq_('../core/main'));
86980          _dereq_('./p5.Geometry');
86981          function _interopRequireDefault(obj) {
86982            return obj && obj.__esModule ? obj : { default: obj };
86983          }
86984          /**
86985           * @module Shape
86986           * @submodule 3D Models
86987           * @for p5
86988           * @requires core
86989           * @requires p5.Geometry
86990           */ /**
86991           * Load a 3d model from an OBJ or STL file.
86992           *
86993           * <a href="#/p5/loadModel">loadModel()</a> should be placed inside of <a href="#/p5/preload">preload()</a>.
86994           * This allows the model to load fully before the rest of your code is run.
86995           *
86996           * One of the limitations of the OBJ and STL format is that it doesn't have a built-in
86997           * sense of scale. This means that models exported from different programs might
86998           * be very different sizes. If your model isn't displaying, try calling
86999           * <a href="#/p5/loadModel">loadModel()</a> with the normalized parameter set to true. This will resize the
87000           * model to a scale appropriate for p5. You can also make additional changes to
87001           * the final size of your model with the <a href="#/p5/scale">scale()</a> function.
87002           *
87003           * Also, the support for colored STL files is not present. STL files with color will be
87004           * rendered without color properties.
87005           *
87006           * @method loadModel
87007           * @param  {String} path              Path of the model to be loaded
87008           * @param  {Boolean} normalize        If true, scale the model to a
87009           *                                      standardized size when loading
87010           * @param  {function(p5.Geometry)} [successCallback] Function to be called
87011           *                                     once the model is loaded. Will be passed
87012           *                                     the 3D model object.
87013           * @param  {function(Event)} [failureCallback] called with event error if
87014           *                                         the model fails to load.
87015           * @param  {String} [fileType]          The file extension of the model
87016           *                                      (<code>.stl</code>, <code>.obj</code>).
87017           * @return {p5.Geometry} the <a href="#/p5.Geometry">p5.Geometry</a> object
87018           *
87019           * @example
87020           * <div>
87021           * <code>
87022           * //draw a spinning octahedron
87023           * let octahedron;
87024           *
87025           * function preload() {
87026           *   octahedron = loadModel('assets/octahedron.obj');
87027           * }
87028           *
87029           * function setup() {
87030           *   createCanvas(100, 100, WEBGL);
87031           * }
87032           *
87033           * function draw() {
87034           *   background(200);
87035           *   rotateX(frameCount * 0.01);
87036           *   rotateY(frameCount * 0.01);
87037           *   model(octahedron);
87038           * }
87039           * </code>
87040           * </div>
87041           *
87042           * @alt
87043           * Vertically rotating 3-d octahedron.
87044           *
87045           * @example
87046           * <div>
87047           * <code>
87048           * //draw a spinning teapot
87049           * let teapot;
87050           *
87051           * function preload() {
87052           *   // Load model with normalise parameter set to true
87053           *   teapot = loadModel('assets/teapot.obj', true);
87054           * }
87055           *
87056           * function setup() {
87057           *   createCanvas(100, 100, WEBGL);
87058           * }
87059           *
87060           * function draw() {
87061           *   background(200);
87062           *   scale(0.4); // Scaled to make model fit into canvas
87063           *   rotateX(frameCount * 0.01);
87064           *   rotateY(frameCount * 0.01);
87065           *   normalMaterial(); // For effect
87066           *   model(teapot);
87067           * }
87068           * </code>
87069           * </div>
87070           *
87071           * @alt
87072           * Vertically rotating 3-d teapot with red, green and blue gradient.
87073           */ /**
87074           * @method loadModel
87075           * @param  {String} path
87076           * @param  {function(p5.Geometry)} [successCallback]
87077           * @param  {function(Event)} [failureCallback]
87078           * @param  {String} [fileType]
87079           * @return {p5.Geometry} the <a href="#/p5.Geometry">p5.Geometry</a> object
87080           */ _main.default.prototype.loadModel = function(path) {
87081            _main.default._validateParameters('loadModel', arguments);
87082            var normalize;
87083            var successCallback;
87084            var failureCallback;
87085            var fileType = path.slice(-4);
87086            if (typeof arguments[1] === 'boolean') {
87087              normalize = arguments[1];
87088              successCallback = arguments[2];
87089              failureCallback = arguments[3];
87090              if (typeof arguments[4] !== 'undefined') {
87091                fileType = arguments[4];
87092              }
87093            } else {
87094              normalize = false;
87095              successCallback = arguments[1];
87096              failureCallback = arguments[2];
87097              if (typeof arguments[3] !== 'undefined') {
87098                fileType = arguments[3];
87099              }
87100            }
87101
87102            var model = new _main.default.Geometry();
87103            model.gid = ''.concat(path, '|').concat(normalize);
87104            var self = this;
87105
87106            if (fileType.match(/\.stl$/i)) {
87107              this.httpDo(
87108                path,
87109                'GET',
87110                'arrayBuffer',
87111                function(arrayBuffer) {
87112                  parseSTL(model, arrayBuffer);
87113
87114                  if (normalize) {
87115                    model.normalize();
87116                  }
87117                  self._decrementPreload();
87118                  if (typeof successCallback === 'function') {
87119                    successCallback(model);
87120                  }
87121                },
87122                failureCallback
87123              );
87124            } else if (fileType.match(/\.obj$/i)) {
87125              this.loadStrings(
87126                path,
87127                function(strings) {
87128                  parseObj(model, strings);
87129
87130                  if (normalize) {
87131                    model.normalize();
87132                  }
87133
87134                  self._decrementPreload();
87135                  if (typeof successCallback === 'function') {
87136                    successCallback(model);
87137                  }
87138                },
87139                failureCallback
87140              );
87141            } else {
87142              _main.default._friendlyFileLoadError(3, path);
87143
87144              if (failureCallback) {
87145                failureCallback();
87146              } else {
87147                console.error(
87148                  'Sorry, the file type is invalid. Only OBJ and STL files are supported.'
87149                );
87150              }
87151            }
87152            return model;
87153          };
87154
87155          /**
87156           * Parse OBJ lines into model. For reference, this is what a simple model of a
87157           * square might look like:
87158           *
87159           * v -0.5 -0.5 0.5
87160           * v -0.5 -0.5 -0.5
87161           * v -0.5 0.5 -0.5
87162           * v -0.5 0.5 0.5
87163           *
87164           * f 4 3 2 1
87165           */
87166          function parseObj(model, lines) {
87167            // OBJ allows a face to specify an index for a vertex (in the above example),
87168            // but it also allows you to specify a custom combination of vertex, UV
87169            // coordinate, and vertex normal. So, "3/4/3" would mean, "use vertex 3 with
87170            // UV coordinate 4 and vertex normal 3". In WebGL, every vertex with different
87171            // parameters must be a different vertex, so loadedVerts is used to
87172            // temporarily store the parsed vertices, normals, etc., and indexedVerts is
87173            // used to map a specific combination (keyed on, for example, the string
87174            // "3/4/3"), to the actual index of the newly created vertex in the final
87175            // object.
87176            var loadedVerts = {
87177              v: [],
87178              vt: [],
87179              vn: []
87180            };
87181
87182            var indexedVerts = {};
87183
87184            for (var line = 0; line < lines.length; ++line) {
87185              // Each line is a separate object (vertex, face, vertex normal, etc)
87186              // For each line, split it into tokens on whitespace. The first token
87187              // describes the type.
87188              var tokens = lines[line].trim().split(/\b\s+/);
87189
87190              if (tokens.length > 0) {
87191                if (tokens[0] === 'v' || tokens[0] === 'vn') {
87192                  // Check if this line describes a vertex or vertex normal.
87193                  // It will have three numeric parameters.
87194                  var vertex = new _main.default.Vector(
87195                    parseFloat(tokens[1]),
87196                    parseFloat(tokens[2]),
87197                    parseFloat(tokens[3])
87198                  );
87199
87200                  loadedVerts[tokens[0]].push(vertex);
87201                } else if (tokens[0] === 'vt') {
87202                  // Check if this line describes a texture coordinate.
87203                  // It will have two numeric parameters.
87204                  var texVertex = [parseFloat(tokens[1]), parseFloat(tokens[2])];
87205                  loadedVerts[tokens[0]].push(texVertex);
87206                } else if (tokens[0] === 'f') {
87207                  // Check if this line describes a face.
87208                  // OBJ faces can have more than three points. Triangulate points.
87209                  for (var tri = 3; tri < tokens.length; ++tri) {
87210                    var face = [];
87211
87212                    var vertexTokens = [1, tri - 1, tri];
87213
87214                    for (var tokenInd = 0; tokenInd < vertexTokens.length; ++tokenInd) {
87215                      // Now, convert the given token into an index
87216                      var vertString = tokens[vertexTokens[tokenInd]];
87217                      var vertIndex = 0;
87218
87219                      // TODO: Faces can technically use negative numbers to refer to the
87220                      // previous nth vertex. I haven't seen this used in practice, but
87221                      // it might be good to implement this in the future.
87222
87223                      if (indexedVerts[vertString] !== undefined) {
87224                        vertIndex = indexedVerts[vertString];
87225                      } else {
87226                        var vertParts = vertString.split('/');
87227                        for (var i = 0; i < vertParts.length; i++) {
87228                          vertParts[i] = parseInt(vertParts[i]) - 1;
87229                        }
87230
87231                        vertIndex = indexedVerts[vertString] = model.vertices.length;
87232                        model.vertices.push(loadedVerts.v[vertParts[0]].copy());
87233                        if (loadedVerts.vt[vertParts[1]]) {
87234                          model.uvs.push(loadedVerts.vt[vertParts[1]].slice());
87235                        } else {
87236                          model.uvs.push([0, 0]);
87237                        }
87238
87239                        if (loadedVerts.vn[vertParts[2]]) {
87240                          model.vertexNormals.push(loadedVerts.vn[vertParts[2]].copy());
87241                        }
87242                      }
87243
87244                      face.push(vertIndex);
87245                    }
87246
87247                    if (face[0] !== face[1] && face[0] !== face[2] && face[1] !== face[2]) {
87248                      model.faces.push(face);
87249                    }
87250                  }
87251                }
87252              }
87253            }
87254            // If the model doesn't have normals, compute the normals
87255            if (model.vertexNormals.length === 0) {
87256              model.computeNormals();
87257            }
87258
87259            return model;
87260          }
87261
87262          /**
87263           * STL files can be of two types, ASCII and Binary,
87264           *
87265           * We need to convert the arrayBuffer to an array of str
87265ings,
87266           * to parse it as an ASCII file.
87267           */
87268          function parseSTL(model, buffer) {
87269            if (isBinary(buffer)) {
87270              parseBinarySTL(model, buffer);
87271            } else {
87272              var reader = new DataView(buffer);
87273
87274              if (!('TextDecoder' in window)) {
87275                console.warn(
87276                  'Sorry, ASCII STL loading only works in browsers that support TextDecoder (https://caniuse.com/#feat=textencoder)'
87277                );
87278
87279                return model;
87280              }
87281
87282              var decoder = new TextDecoder('utf-8');
87283              var lines = decoder.decode(reader);
87284              var lineArray = lines.split('\n');
87285              parseASCIISTL(model, lineArray);
87286            }
87287            return model;
87288          }
87289
87290          /**
87291           * This function checks if the file is in ASCII format or in Binary format
87292           *
87293           * It is done by searching keyword `solid` at the start of the file.
87294           *
87295           * An ASCII STL data must begin with `solid` as the first six bytes.
87296           * However, ASCII STLs lacking the SPACE after the `d` are known to be
87297           * plentiful. So, check the first 5 bytes for `solid`.
87298           *
87299           * Several encodings, such as UTF-8, precede the text with up to 5 bytes:
87300           * https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding
87301           * Search for `solid` to start anywhere after those prefixes.
87302           */
87303          function isBinary(data) {
87304            var reader = new DataView(data);
87305
87306            // US-ASCII ordinal values for `s`, `o`, `l`, `i`, `d`
87307            var solid = [115, 111, 108, 105, 100];
87308            for (var off = 0; off < 5; off++) {
87309              // If "solid" text is matched to the current offset, declare it to be an ASCII STL.
87310              if (matchDataViewAt(solid, reader, off)) return false;
87311            }
87312
87313            // Couldn't find "solid" text at the beginning; it is binary STL.
87314            return true;
87315          }
87316
87317          /**
87318           * This function matches the `query` at the provided `offset`
87319           */
87320          function matchDataViewAt(query, reader, offset) {
87321            // Check if each byte in query matches the corresponding byte from the current offset
87322            for (var i = 0, il = query.length; i < il; i++) {
87323              if (query[i] !== reader.getUint8(offset + i, false)) return false;
87324            }
87325
87326            return true;
87327          }
87328
87329          /**
87330           * This function parses the Binary STL files.
87331           * https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL
87332           *
87333           * Currently there is no support for the colors provided in STL files.
87334           */
87335          function parseBinarySTL(model, buffer) {
87336            var reader = new DataView(buffer);
87337
87338            // Number of faces is present following the header
87339            var faces = reader.getUint32(80, true);
87340            var r,
87341              g,
87342              b,
87343              hasColors = false,
87344              colors;
87345            var defaultR, defaultG, defaultB;
87346
87347            // Binary files contain 80-byte header, which is generally ignored.
87348            for (var index = 0; index < 80 - 10; index++) {
87349              // Check for `COLOR=`
87350              if (
87351                reader.getUint32(index, false) === 0x434f4c4f /*COLO*/ &&
87352                reader.getUint8(index + 4) === 0x52 /*'R'*/ &&
87353                reader.getUint8(index + 5) === 0x3d /*'='*/
87354              ) {
87355                hasColors = true;
87356                colors = [];
87357
87358                defaultR = reader.getUint8(index + 6) / 255;
87359                defaultG = reader.getUint8(index + 7) / 255;
87360                defaultB = reader.getUint8(index + 8) / 255;
87361                // To be used when color support is added
87362                // alpha = reader.getUint8(index + 9) / 255;
87363              }
87364            }
87365            var dataOffset = 84;
87366            var faceLength = 12 * 4 + 2;
87367
87368            // Iterate the faces
87369            for (var face = 0; face < faces; face++) {
87370              var start = dataOffset + face * faceLength;
87371              var normalX = reader.getFloat32(start, true);
87372              var normalY = reader.getFloat32(start + 4, true);
87373              var normalZ = reader.getFloat32(start + 8, true);
87374
87375              if (hasColors) {
87376                var packedColor = reader.getUint16(start + 48, true);
87377
87378                if ((packedColor & 0x8000) === 0) {
87379                  // facet has its own unique color
87380                  r = (packedColor & 0x1f) / 31;
87381                  g = ((packedColor >> 5) & 0x1f) / 31;
87382                  b = ((packedColor >> 10) & 0x1f) / 31;
87383                } else {
87384                  r = defaultR;
87385                  g = defaultG;
87386                  b = defaultB;
87387                }
87388              }
87389              var newNormal = new _main.default.Vector(normalX, normalY, normalZ);
87390
87391              for (var i = 1; i <= 3; i++) {
87392                var vertexstart = start + i * 12;
87393
87394                var newVertex = new _main.default.Vector(
87395                  reader.getFloat32(vertexstart, true),
87396                  reader.getFloat32(vertexstart + 4, true),
87397                  reader.getFloat32(vertexstart + 8, true)
87398                );
87399
87400                model.vertices.push(newVertex);
87401                model.vertexNormals.push(newNormal);
87402
87403                if (hasColors) {
87404                  colors.push(r, g, b);
87405                }
87406              }
87407
87408              model.faces.push([3 * face, 3 * face + 1, 3 * face + 2]);
87409              model.uvs.push([0, 0], [0, 0], [0, 0]);
87410            }
87411            if (hasColors) {
87412              // add support for colors here.
87413            }
87414            return model;
87415          }
87416
87417          /**
87418           * ASCII STL file starts with `solid 'nameOfFile'`
87419           * Then contain the normal of the face, starting with `facet normal`
87420           * Next contain a keyword indicating the start of face vertex, `outer loop`
87421           * Next comes the three vertex, starting with `vertex x y z`
87422           * Vertices ends with `endloop`
87423           * Face ends with `endfacet`
87424           * Next face starts with `facet normal`
87425           * The end of the file is indicated by `endsolid`
87426           */
87427          function parseASCIISTL(model, lines) {
87428            var state = '';
87429            var curVertexIndex = [];
87430            var newNormal, newVertex;
87431
87432            for (var iterator = 0; iterator < lines.length; ++iterator) {
87433              var line = lines[iterator].trim();
87434              var parts = line.split(' ');
87435
87436              for (var partsiterator = 0; partsiterator < parts.length; ++partsiterator) {
87437                if (parts[partsiterator] === '') {
87438                  // Ignoring multiple whitespaces
87439                  parts.splice(partsiterator, 1);
87440                }
87441              }
87442
87443              if (parts.length === 0) {
87444                // Remove newline
87445                continue;
87446              }
87447
87448              switch (state) {
87449                case '': // First run
87450                  if (parts[0] !== 'solid') {
87451                    // Invalid state
87452                    console.error(line);
87453                    console.error(
87454                      'Invalid state "'.concat(parts[0], '", should be "solid"')
87455                    );
87456                    return;
87457                  } else {
87458                    state = 'solid';
87459                  }
87460                  break;
87461
87462                case 'solid': // First face
87463                  if (parts[0] !== 'facet' || parts[1] !== 'normal') {
87464                    // Invalid state
87465                    console.error(line);
87466                    console.error(
87467                      'Invalid state "'.concat(parts[0], '", should be "facet normal"')
87468                    );
87469
87470                    return;
87471                  } else {
87472                    // Push normal for first face
87473                    newNormal = new _main.default.Vector(
87474                      parseFloat(parts[2]),
87475                      parseFloat(parts[3]),
87476                      parseFloat(parts[4])
87477                    );
87478
87479                    model.vertexNormals.push(newNormal, newNormal, newNormal);
87480                    state = 'facet normal';
87481                  }
87482                  break;
87483
87484                case 'facet normal': // After normal is defined
87485                  if (parts[0] !== 'outer' || parts[1] !== 'loop') {
87486                    // Invalid State
87487                    console.error(line);
87488                    console.error(
87489                      'Invalid state "'.concat(parts[0], '", should be "outer loop"')
87490                    );
87491                    return;
87492                  } else {
87493                    // Next should be vertices
87494                    state = 'vertex';
87495                  }
87496                  break;
87497
87498                case 'vertex':
87499                  if (parts[0] === 'vertex') {
87500                    //Vertex of triangle
87501                    newVertex = new _main.default.Vector(
87502                      parseFloat(parts[1]),
87503                      parseFloat(parts[2]),
87504                      parseFloat(parts[3])
87505                    );
87506
87507                    model.vertices.push(newVertex);
87508                    model.uvs.push([0, 0]);
87509                    curVertexIndex.push(model.vertices.indexOf(newVertex));
87510                  } else if (parts[0] === 'endloop') {
87511                    // End of vertices
87512                    model.faces.push(curVertexIndex);
87513                    curVertexIndex = [];
87514                    state = 'endloop';
87515                  } else {
87516                    // Invalid State
87517                    console.error(line);
87518                    console.error(
87519                      'Invalid state "'.concat(
87520                        parts[0],
87521                        '", should be "vertex" or "endloop"'
87522                      )
87523                    );
87524
87525                    return;
87526                  }
87527                  break;
87528
87529                case 'endloop':
87530                  if (parts[0] !== 'endfacet') {
87531                    // End of face
87532                    console.error(line);
87533                    console.error(
87534                      'Invalid state "'.concat(parts[0], '", should be "endfacet"')
87535                    );
87536                    return;
87537                  } else {
87538                    state = 'endfacet';
87539                  }
87540                  break;
87541
87542                case 'endfacet':
87543                  if (parts[0] === 'endsolid') {
87544                    // End of solid
87545                  } else if (parts[0] === 'facet' && parts[1] === 'normal') {
87546                    // Next face
87547                    newNormal = new _main.default.Vector(
87548                      parseFloat(parts[2]),
87549                      parseFloat(parts[3]),
87550                      parseFloat(parts[4])
87551                    );
87552
87553                    model.vertexNormals.push(newNormal, newNormal, newNormal);
87554                    state = 'facet normal';
87555                  } else {
87556                    // Invalid State
87557                    console.error(line);
87558                    console.error(
87559                      'Invalid state "'.concat(
87560                        parts[0],
87561                        '", should be "endsolid" or "facet normal"'
87562                      )
87563                    );
87564
87565                    return;
87566                  }
87567                  break;
87568
87569                default:
87570                  console.error('Invalid state "'.concat(state, '"'));
87571                  break;
87572              }
87573            }
87574            return model;
87575          }
87576
87577          /**
87578           * Render a 3d model to the screen.
87579           *
87580           * @method model
87581           * @param  {p5.Geometry} model Loaded 3d model to be rendered
87582           * @example
87583           * <div>
87584           * <code>
87585           * //draw a spinning octahedron
87586           * let octahedron;
87587           *
87588           * function preload() {
87589           *   octahedron = loadModel('assets/octahedron.obj');
87590           * }
87591           *
87592           * function setup() {
87593           *   createCanvas(100, 100, WEBGL);
87594           * }
87595           *
87596           * function draw() {
87597           *   background(200);
87598           *   rotateX(frameCount * 0.01);
87599           *   rotateY(frameCount * 0.01);
87600           *   model(octahedron);
87601           * }
87602           * </code>
87603           * </div>
87604           *
87605           * @alt
87606           * Vertically rotating 3-d octahedron.
87607           */
87608          _main.default.prototype.model = function(model) {
87609            this._assert3d('model');
87610            _main.default._validateParameters('model', arguments);
87611            if (model.vertices.length > 0) {
87612              if (!this._renderer.geometryInHash(model.gid)) {
87613                model._makeTriangleEdges()._edgesToVertices();
87614                this._renderer.createBuffers(model.gid, model);
87615              }
87616
87617              this._renderer.drawBuffers(model.gid);
87618            }
87619          };
87620          var _default = _main.default;
87621          exports.default = _default;
87622        },
87623        { '../core/main': 59, './p5.Geometry': 108 }
87624      ],
87625      106: [
87626        function(_dereq_, module, exports) {
87627          'use strict';
87628          function _typeof(obj) {
87629            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
87630              _typeof = function _typeof(obj) {
87631                return typeof obj;
87632              };
87633            } else {
87634              _typeof = function _typeof(obj) {
87635                return obj &&
87636                  typeof Symbol === 'function' &&
87637                  obj.constructor === Symbol &&
87638                  obj !== Symbol.prototype
87639                  ? 'symbol'
87640                  : typeof obj;
87641              };
87642            }
87643            return _typeof(obj);
87644          }
87645          Object.defineProperty(exports, '__esModule', { value: true });
87646          exports.default = void 0;
87647
87648          var _main = _interopRequireDefault(_dereq_('../core/main'));
87649          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
87650          _dereq_('./p5.Texture');
87651          function _getRequireWildcardCache() {
87652            if (typeof WeakMap !== 'function') return null;
87653            var cache = new WeakMap();
87654            _getRequireWildcardCache = function _getRequireWildcardCache() {
87655              return cache;
87656            };
87657            return cache;
87658          }
87659          function _interopRequireWildcard(obj) {
87660            if (obj && obj.__esModule) {
87661              return obj;
87662            }
87663            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
87664              return { default: obj };
87665            }
87666            var cache = _getRequireWildcardCache();
87667            if (cache && cache.has(obj)) {
87668              return cache.get(obj);
87669            }
87670            var newObj = {};
87671            var hasPropertyDescriptor =
87672              Object.defineProperty && Object.getOwnPropertyDescriptor;
87673            for (var key in obj) {
87674              if (Object.prototype.hasOwnProperty.call(obj, key)) {
87675                var desc = hasPropertyDescriptor
87676                  ? Object.getOwnPropertyDescriptor(obj, key)
87677                  : null;
87678                if (desc && (desc.get || desc.set)) {
87679                  Object.defineProperty(newObj, key, desc);
87680                } else {
87681                  newObj[key] = obj[key];
87682                }
87683              }
87684            }
87685            newObj.default = obj;
87686            if (cache) {
87687              cache.set(obj, newObj);
87688            }
87689            return newObj;
87690          }
87691          function _interopRequireDefault(obj) {
87692            return obj && obj.__esModule ? obj : { default: obj };
87693          }
87694          /**
87695           * @module Lights, Camera
87696           * @submodule Material
87697           * @for p5
87698           * @requires core
87699           */ /**
87700           * Loads a custom shader from the provided vertex and fragment
87701           * shader paths. The shader files are loaded asynchronously in the
87702           * background, so this method should be used in <a href="#/p5/preload">preload()</a>.
87703           *
87704           * For now, there are three main types of shaders. p5 will automatically
87705           * supply appropriate vertices, normals, colors, and lighting attributes
87706           * if the parameters defined in the shader match the names.
87707           *
87708           * @method loadShader
87709           * @param {String} vertFilename path to file containing vertex shader
87710           * source code
87711           * @param {String} fragFilename path to file containing fragment shader
87712           * source code
87713           * @param {function} [callback] callback to be executed after loadShader
87714           * completes. On success, the Shader object is passed as the first argument.
87715           * @param {function} [errorCallback] callback to be executed when an error
87716           * occurs inside loadShader. On error, the error is passed as the first
87717           * argument.
87718           * @return {p5.Shader} a shader object created from the provided
87719           * vertex and fragment shader files.
87720           *
87721           * @example
87722           * <div modernizr='webgl'>
87723           * <code>
87724           * let mandel;
87725           * function preload() {
87726           *   // load the shader definitions from files
87727           *   mandel = loadShader('assets/shader.vert', 'assets/shader.frag');
87728           * }
87729           * function setup() {
87730           *   createCanvas(100, 100, WEBGL);
87731           *   // use the shader
87732           *   shader(mandel);
87733           *   noStroke();
87734           *   mandel.setUniform('p', [-0.74364388703, 0.13182590421]);
87735           * }
87736           *
87737           * function draw() {
87738           *   mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));
87739           *   quad(-1, -1, 1, -1, 1, 1, -1, 1);
87740           * }
87741           * </code>
87742           * </div>
87743           *
87744           * @alt
87745           * zooming Mandelbrot set. a colorful, infinitely detailed fractal.
87746           */ _main.default.prototype.loadShader = function(
87747            vertFilename,
87748            fragFilename,
87749            callback,
87750            errorCallback
87751          ) {
87752            _main.default._validateParameters('loadShader', arguments);
87753            if (!errorCallback) {
87754              errorCallback = console.error;
87755            }
87756
87757            var loadedShader = new _main.default.Shader();
87758
87759            var self = this;
87760            var loadedFrag = false;
87761            var loadedVert = false;
87762
87763            var onLoad = function onLoad() {
87764              self._decrementPreload();
87765              if (callback) {
87766                callback(loadedShader);
87767              }
87768            };
87769
87770            this.loadStrings(
87771              vertFilename,
87772              function(result) {
87773                loadedShader._vertSrc = result.join('\n');
87774                loadedVert = true;
87775                if (loadedFrag) {
87776                  onLoad();
87777                }
87778              },
87779              errorCallback
87780            );
87781
87782            this.loadStrings(
87783              fragFilename,
87784              function(result) {
87785                loadedShader._fragSrc = result.join('\n');
87786                loadedFrag = true;
87787                if (loadedVert) {
87788                  onLoad();
87789                }
87790              },
87791              errorCallback
87792            );
87793
87794            return loadedShader;
87795          };
87796
87797          /**
87798           * @method createShader
87799           * @param {String} vertSrc source code for the vertex shader
87800           * @param {String} fragSrc source code for the fragment shader
87801           * @returns {p5.Shader} a shader object created from the provided
87802           * vertex and fragment shaders.
87803           *
87804           * @example
87805           * <div modernizr='webgl'>
87806           * <code>
87807           * // the 'varying's are shared between both vertex & fragment shaders
87808           * let varying = 'precision highp float; varying vec2 vPos;';
87809           *
87810           * // the vertex shader is called for each vertex
87811           * let vs =
87812           *   varying +
87813           *   'attribute vec3 aPosition;' +
87814           *   'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';
87815           *
87816           * // the fragment shader is called for each pixel
87817           * let fs =
87818           *   varying +
87819           *   'uniform vec2 p;' +
87820           *   'uniform float r;' +
87821           *   'const int I = 500;' +
87822           *   'void main() {' +
87823           *   '  vec2 c = p + vPos * r, z = c;' +
87824           *   '  float n = 0.0;' +
87825           *   '  for (int i = I; i > 0; i --) {' +
87826           *   '    if(z.x*z.x+z.y*z.y > 4.0) {' +
87827           *   '      n = float(i)/float(I);' +
87828           *   '      break;' +
87829           *   '    }' +
87830           *   '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +
87831           *   '  }' +
87832           *   '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +
87833           *   '}';
87834           *
87835           * let mandel;
87836           * function setup() {
87837           *   createCanvas(100, 100, WEBGL);
87838           *
87839           *   // create and initialize the shader
87840           *   mandel = createShader(vs, fs);
87841           *   shader(mandel);
87842           *   noStroke();
87843           *
87844           *   // 'p' is the center point of the Mandelbrot image
87845           *   mandel.setUniform('p', [-0.74364388703, 0.13182590421]);
87846           * }
87847           *
87848           * function draw() {
87849           *   // 'r' is the size of the image in Mandelbrot-space
87850           *   mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));
87851           *   quad(-1, -1, 1, -1, 1, 1, -1, 1);
87852           * }
87853           * </code>
87854           * </div>
87855           *
87856           * @alt
87857           * zooming Mandelbrot set. a colorful, infinitely detailed fractal.
87858           */
87859          _main.default.prototype.createShader = function(vertSrc, fragSrc) {
87860            this._assert3d('createShader');
87861            _main.default._validateParameters('createShader', arguments);
87862            return new _main.default.Shader(this._renderer, vertSrc, fragSrc);
87863          };
87864
87865          /**
87866           * The <a href="#/p5/shader">shader()</a> function lets the user provide a custom shader
87867           * to fill in shapes in WEBGL mode. Users can create their
87868           * own shaders by loading vertex and fragment shaders with
87869           * <a href="#/p5/loadShader">loadShader()</a>.
87870           *
87871           * @method shader
87872           * @chainable
87873           * @param {p5.Shader} [s] the desired <a href="#/p5.Shader">p5.Shader</a> to use for rendering
87874           * shapes.
87875           *
87876           * @example
87877           * <div modernizr='webgl'>
87878           * <code>
87879           * // Click within the image to toggle
87880           * // the shader used by the quad shape
87881           * // Note: for an alternative approach to the same example,
87882           * // involving changing uniforms please refer to:
87883           * // https://p5js.org/reference/#/p5.Shader/setUniform
87884           *
87885           * let redGreen;
87886           * let orangeBlue;
87887           * let showRedGreen = false;
87888           *
87889           * function preload() {
87890           *   // note that we are using two instances
87891           *   // of the same vertex and fragment shaders
87892           *   redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');
87893           *   orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');
87894           * }
87895           *
87896           * function setup() {
87897           *   createCanvas(100, 100, WEBGL);
87898           *
87899           *   // initialize the colors for redGreen shader
87900           *   shader(redGreen);
87901           *   redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);
87902           *   redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);
87903           *
87904           *   // initialize the colors for orangeBlue shader
87905           *   shader(orangeBlue);
87906           *   orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);
87907           *   orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);
87908           *
87909           *   noStroke();
87910           * }
87911           *
87912           * function draw() {
87913           *   // update the offset values for each shader,
87914           *   // moving orangeBlue in vertical and redGreen
87915           *   // in horizontal direction
87916           *   orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);
87917           *   redGreen.setUniform('offset', [sin(millis() / 2000), 1]);
87918           *
87919           *   if (showRedGreen === true) {
87920           *     shader(redGreen);
87921           *   } else {
87922           *     shader(orangeBlue);
87923           *   }
87924           *   quad(-1, -1, 1, -1, 1, 1, -1, 1);
87925           * }
87926           *
87927           * function mouseClicked() {
87928           *   showRedGreen = !showRedGreen;
87929           * }
87930           * </code>
87931           * </div>
87932           *
87933           * @alt
87934           * canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.
87935           */
87936          _main.default.prototype.shader = function(s) {
87937            this._assert3d('shader');
87938            _main.default._validateParameters('shader', arguments);
87939
87940            if (s._renderer === undefined) {
87941              s._renderer = this._renderer;
87942            }
87943
87944            if (s.isStrokeShader()) {
87945              this._renderer.userStrokeShader = s;
87946            } else {
87947              this._renderer.userFillShader = s;
87948              this._renderer._useNormalMaterial = false;
87949            }
87950
87951            s.init();
87952
87953            return this;
87954          };
87955
87956          /**
87957           * This function restores the default shaders in WEBGL mode. Code that runs
87958           * after resetShader() will not be affected by previously defined
87959           * shaders. Should be run after <a href="#/p5/shader">shader()</a>.
87960           *
87961           * @method resetShader
87962           * @chainable
87963           */
87964          _main.default.prototype.resetShader = function() {
87965            this._renderer.userFillShader = this._renderer.userStrokeShader = null;
87966            return this;
87967          };
87968
87969          /**
87970           * Normal material for geometry is a material that is not affected by light.
87971           * It is not reflective and is a placeholder material often used for debugging.
87972           * Surfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.
87973           * You can view all possible materials in this
87974           * <a href="https://p5js.org/examples/3d-materials.html">example</a>.
87975           * @method normalMaterial
87976           * @chainable
87977           * @example
87978           * <div>
87979           * <code>
87980           * function setup() {
87981           *   createCanvas(100, 100, WEBGL);
87982           * }
87983           *
87984           * function draw() {
87985           *   background(200);
87986           *   normalMaterial();
87987           *   sphere(40);
87988           * }
87989           * </code>
87990           * </div>
87991           * @alt
87992           * Red, green and blue gradient.
87993           */
87994          _main.default.prototype.normalMaterial = function() {
87995            this._assert3d('normalMaterial');
87996            for (
87997              var _len = arguments.length, args = new Array(_len), _key = 0;
87998              _key < _len;
87999              _key++
88000            ) {
88001              args[_key] = arguments[_key];
88002            }
88003            _main.default._validateParameters('normalMaterial', args);
88004            this._renderer.drawMode = constants.FILL;
88005            this._renderer._useSpecularMaterial = false;
88006            this._renderer._useEmissiveMaterial = false;
88007            this._renderer._useNormalMaterial = true;
88008            this._renderer.curFillColor = [1, 1, 1, 1];
88009            this._renderer._setProperty('_doFill', true);
88010            this.noStroke();
88011            return this;
88012          };
88013
88014          /**
88015           * Texture for geometry.  You can view other possible materials in this
88016           * <a href="https://p5js.org/examples/3d-materials.html">example</a>.
88017           * @method texture
88018           * @param {p5.Image|p5.MediaElement|p5.Graphics} tex 2-dimensional graphics
88019           *                    to render as texture
88020           * @chainable
88021           * @example
88022           * <div>
88023           * <code>
88024           * let img;
88025           * function preload() {
88026           *   img = loadImage('assets/laDefense.jpg');
88027           * }
88028           *
88029           * function setup() {
88030           *   createCanvas(100, 100, WEBGL);
88031           * }
88032           *
88033           * function draw() {
88034           *   background(0);
88035           *   rotateZ(frameCount * 0.01);
88036           *   rotateX(frameCount * 0.01);
88037           *   rotateY(frameCount * 0.01);
88038           *   //pass image as texture
88039           *   texture(img);
88040           *   box(200, 200, 200);
88041           * }
88042           * </code>
88043           * </div>
88044           *
88045           * <div>
88046           * <code>
88047           * let pg;
88048           *
88049           * function setup() {
88050           *   createCanvas(100, 100, WEBGL);
88051           *   pg = createGraphics(200, 200);
88052           *   pg.textSize(75);
88053           * }
88054           *
88055           * function draw() {
88056           *   background(0);
88057           *   pg.background(255);
88058           *   pg.text('hello!', 0, 100);
88059           *   //pass image as texture
88060           *   texture(pg);
88061           *   rotateX(0.5);
88062           *   noStroke();
88063           *   plane(50);
88064           * }
88065           * </code>
88066           * </div>
88067           *
88068           * <div>
88069           * <code>
88070           * let vid;
88071           * function preload() {
88072           *   vid = createVideo('assets/fingers.mov');
88073           *   vid.hide();
88074           * }
88075           * function setup() {
88076           *   createCanvas(100, 100, WEBGL);
88077           * }
88078           *
88079           * function draw() {
88080           *   background(0);
88081           *   //pass video frame as texture
88082           *   texture(vid);
88083           *   rect(-40, -40, 80, 80);
88084           * }
88085           *
88086           * function mousePressed() {
88087           *   vid.loop();
88088           * }
88089           * </code>
88090           * </div>
88091           *
88092           * @alt
88093           * Rotating view of many images umbrella and grid roof on a 3d plane
88094           * black canvas
88095           * black canvas
88096           */
88097          _main.default.prototype.texture = function(tex) {
88098            this._assert3d('texture');
88099            _main.default._validateParameters('texture', arguments);
88100            if (tex.gifProperties) {
88101              tex._animateGif(this);
88102            }
88103
88104            this._renderer.drawMode = constants.TEXTURE;
88105            this._renderer._useSpecularMaterial = false;
88106            this._renderer._useEmissiveMaterial = false;
88107            this._renderer._useNormalMaterial = false;
88108            this._renderer._tex = tex;
88109            this._renderer._setProperty('_doFill', true);
88110
88111            return this;
88112          };
88113
88114          /**
88115           * Sets the coordinate space for texture mapping. The default mode is IMAGE
88116           * which refers to the actual coordinates of the image.
88117           * NORMAL refers to a normalized space of values ranging from 0 to 1.
88118           * This function only works in WEBGL mode.
88119           *
88120           * With IMAGE, if an image is 100 x 200 pixels, mapping the image onto the entire
88121           * size of a quad would require the points (0,0) (100, 0) (100,200) (0,200).
88122           * The same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).
88123           * @method  textureMode
88124           * @param {Constant} mode either IMAGE or NORMAL
88125           * @example
88126           * <div>
88127           * <code>
88128           * let img;
88129           *
88130           * function preload() {
88131           *   img = loadImage('assets/laDefense.jpg');
88132           * }
88133           *
88134           * function setup() {
88135           *   createCanvas(100, 100, WEBGL);
88136           * }
88137           *
88138           * function draw() {
88139           *   texture(img);
88140           *   textureMode(NORMAL);
88141           *   beginShape();
88142           *   vertex(-50, -50, 0, 0);
88143           *   vertex(50, -50, 1, 0);
88144           *   vertex(50, 50, 1, 1);
88145           *   vertex(-50, 50, 0, 1);
88146           *   endShape();
88147           * }
88148           * </code>
88149           * </div>
88150           *
88151           * @alt
88152           * the underside of a white umbrella and gridded ceiling above
88153           *
88154           * <div>
88155           * <code>
88156           * let img;
88157           *
88158           * function preload() {
88159           *   img = loadImage('assets/laDefense.jpg');
88160           * }
88161           *
88162           * function setup() {
88163           *   createCanvas(100, 100, WEBGL);
88164           * }
88165           *
88166           * function draw() {
88167           *   texture(img);
88168           *   textureMode(NORMAL);
88169           *   beginShape();
88170           *   vertex(-50, -50, 0, 0);
88171           *   vertex(50, -50, img.width, 0);
88172           *   vertex(50, 50, img.width, img.height);
88173           *   vertex(-50, 50, 0, img.height);
88174           *   endShape();
88175           * }
88176           * </code>
88177           * </div>
88178           *
88179           * @alt
88180           * the underside of a white umbrella and gridded ceiling above
88181           */
88182          _main.default.prototype.textureMode = function(mode) {
88183            if (mode !== constants.IMAGE && mode !== constants.NORMAL) {
88184              console.warn(
88185                'You tried to set '.concat(
88186                  mode,
88187                  ' textureMode only supports IMAGE & NORMAL '
88188                )
88189              );
88190            } else {
88191              this._renderer.textureMode = mode;
88192            }
88193          };
88194
88195          /**
88196           * Sets the global texture wrapping mode. This controls how textures behave
88197           * when their uv's go outside of the 0 - 1 range. There are three options:
88198           * CLAMP, REPEAT, and MIRROR.
88199           *
88200           * CLAMP causes the pixels at the edge of the texture to extend to the bounds
88201           * REPEAT causes the texture to tile repeatedly until reaching the bounds
88202           * MIRROR works similarly to REPEAT but it flips the texture with every new tile
88203           *
88204           * REPEAT & MIRROR are only available if the texture
88205           * is a power of two size (128, 256, 512, 1024, etc.).
88206           *
88207           * This method will affect all textures in your sketch until a subsequent
88208           * textureWrap call is made.
88209           *
88210           * If only one argument is provided, it will be applied to both the
88211           * horizontal and vertical axes.
88212           * @method textureWrap
88213           * @param {Constant} wrapX either CLAMP, REPEAT, or MIRROR
88214           * @param {Constant} [wrapY] either CLAMP, REPEAT, or MIRROR
88215           * @example
88216           * <div>
88217           * <code>
88218           * let img;
88219           * function preload() {
88220           *   img = loadImage('assets/rockies128.jpg');
88221           * }
88222           *
88223           * function setup() {
88224           *   createCanvas(100, 100, WEBGL);
88225           *   textureWrap(MIRROR);
88226           * }
88227           *
88228           * function draw() {
88229           *   background(0);
88230           *
88231           *   let dX = mouseX;
88232           *   let dY = mouseY;
88233           *
88234           *   let u = lerp(1.0, 2.0, dX);
88235           *   let v = lerp(1.0, 2.0, dY);
88236           *
88237           *   scale(width / 2);
88238           *
88239           *   texture(img);
88240           *
88241           *   beginShape(TRIANGLES);
88242           *   vertex(-1, -1, 0, 0, 0);
88243           *   vertex(1, -1, 0, u, 0);
88244           *   vertex(1, 1, 0, u, v);
88245           *
88246           *   vertex(1, 1, 0, u, v);
88247           *   vertex(-1, 1, 0, 0, v);
88248           *   vertex(-1, -1, 0, 0, 0);
88249           *   endShape();
88250           * }
88251           * </code>
88252           * </div>
88253           *
88254           * @alt
88255           * an image of the rocky mountains repeated in mirrored tiles
88256           */
88257          _main.default.prototype.textureWrap = function(wrapX) {
88258            var wrapY =
88259              arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : wrapX;
88260            this._renderer.textureWrapX = wrapX;
88261            this._renderer.textureWrapY = wrapY;
88262
88263            var textures = this._renderer.textures;
88264            for (var i = 0; i < textures.length; i++) {
88265              textures[i].setWrapMode(wrapX, wrapY);
88266            }
88267          };
88268
88269          /**
88270           * Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.
88271           * For example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.
88272           * Here's an <a href="https://p5js.org/examples/3d-materials.html">example containing all possible materials</a>.
88273           * @method  ambientMaterial
88274           * @param  {Number} v1  gray value, red or hue value
88275           *                         (depending on the current color mode),
88276           * @param  {Number} [v2] green or saturation value
88277           * @param  {Number} [v3] blue or brightness value
88278           * @chainable
88279           * @example
88280           * <div>
88281           * <code>
88282           * function setup() {
88283           *   createCanvas(100, 100, WEBGL);
88284           * }
88285           * function draw() {
88286           *   background(0);
88287           *   noStroke();
88288           *   ambientLight(200);
88289           *   ambientMaterial(70, 130, 230);
88290           *   sphere(40);
88291           * }
88292           * </code>
88293           * </div>
88294           * <div>
88295           * <code>
88296           * // ambientLight is both red and blue (magenta),
88297           * // so object only reflects it's red and blue components
88298           * function setup() {
88299           *   createCanvas(100, 100, WEBGL);
88300           * }
88301           * function draw() {
88302           *   background(70);
88303           *   ambientLight(100); // white light
88304           *   ambientMaterial(255, 0, 255); // pink material
88305           *   box(30);
88306           * }
88307           * </code>
88308           * </div>
88309           * <div>
88310           * <code>
88311           * // ambientLight is green. Since object does not contain
88312           * // green, it does not reflect any light
88313           * function setup() {
88314           *   createCanvas(100, 100, WEBGL);
88315           * }
88316           * function draw() {
88317           *   background(70);
88318           *   ambientLight(0, 255, 0); // green light
88319           *   ambientMaterial(255, 0, 255); // pink material
88320           *   box(30);
88321           * }
88322           * </code>
88323           * </div>
88324           * @alt
88325           * radiating light source from top right of canvas
88326           * box reflecting only red and blue light
88327           * box reflecting no light
88328           */
88329          /**
88330           * @method  ambientMaterial
88331           * @param  {Number[]|String|p5.Color} color  color, color Array, or CSS color string
88332           * @chainable
88333           */
88334          _main.default.prototype.ambientMaterial = function(v1, v2, v3) {
88335            this._assert3d('ambientMaterial');
88336            _main.default._validateParameters('ambientMaterial', arguments);
88337
88338            var color = _main.default.prototype.color.apply(this, arguments);
88339            this._renderer.curFillColor = color._array;
88340            this._renderer._useSpecularMaterial = false;
88341            this._renderer._useEmissiveMaterial = false;
88342            this._renderer._useNormalMaterial = false;
88343            this._renderer._enableLighting = true;
88344            this._renderer._tex = null;
88345
88346            return this;
88347          };
88348
88349          /**
88350           * Sets the emissive color of the material used for geometry drawn to
88351           * the screen. This is a misnomer in the sense that the material does not
88352           * actually emit light that effects surrounding polygons. Instead,
88353           * it gives the appearance that the object is glowing. An emissive material
88354           * will display at full strength even if there is no light for it to reflect.
88355           * @method emissiveMaterial
88356           * @param  {Number} v1  gray value, red or hue value
88357           *                         (depending on the current color mode),
88358           * @param  {Number} [v2] green or saturation value
88359           * @param  {Number} [v3] blue or brightness value
88360           * @param  {Number} [a]  opacity
88361           * @chainable
88362           * @example
88363           * <div>
88364           * <code>
88365           * function setup() {
88366           *   createCanvas(100, 100, WEBGL);
88367           * }
88368           * function draw() {
88369           *   background(0);
88370           *   noStroke();
88371           *   ambientLight(0);
88372           *   emissiveMaterial(130, 230, 0);
88373           *   sphere(40);
88374           * }
88375           * </code>
88376           * </div>
88377           *
88378           * @alt
88379           * radiating light source from top right of canvas
88380           */
88381          /**
88382           * @method  emissiveMaterial
88383           * @param  {Number[]|String|p5.Color} color  color, color Array, or CSS color string
88384           * @chainable
88385           */
88386          _main.default.prototype.emissiveMaterial = function(v1, v2, v3, a) {
88387            this._assert3d('emissiveMaterial');
88388            _main.default._validateParameters('emissiveMaterial', arguments);
88389
88390            var color = _main.default.prototype.color.apply(this, arguments);
88391            this._renderer.curFillColor = color._array;
88392            this._renderer._useSpecularMaterial = false;
88393            this._renderer._useEmissiveMaterial = true;
88394            this._renderer._useNormalMaterial = false;
88395            this._renderer._enableLighting = true;
88396            this._renderer._tex = null;
88397
88398            return this;
88399          };
88400
88401          /**
88402           * Specular material for geometry with a given color. Specular material is a shiny reflective material.
88403           * Like ambient material it also defines the color the object reflects under ambient lighting.
88404           * For example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.
88405           * For all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.
88406           * Here's an <a href="https://p5js.org/examples/3d-materials.html">example containing all possible materials</a>.
88407           *
88408           * @method specularMaterial
88409           * @param  {Number} gray number specifying value between white and black.
88410           * @param  {Number} [alpha] alpha value relative to current color range
88411           *                                 (default is 0-255)
88412           * @chainable
88413           */
88414
88415          /**
88416           * @method specularMaterial
88417           * @param  {Number}        v1      red or hue value relative to
88418           *                                 the current color range
88419           * @param  {Number}        v2      green or saturation value
88420           *                                 relative to the current color range
88421           * @param  {Number}        v3      blue or brightness value
88422           *                                 relative to the current color range
88423           * @param  {Number}        [alpha]
88424           * @chainable
88425           *
88426           * @example
88427           * <div>
88428           * <code>
88429           * function setup() {
88430           *   createCanvas(100, 100, WEBGL);
88431           * }
88432           * function draw() {
88433           *   background(0);
88434           *   ambientLight(50);
88435           *   pointLight(250, 250, 250, 100, 100, 30);
88436           *   specularMaterial(250);
88437           *   sphere(40);
88438           * }
88439           * </code>
88440           * </div>
88441           * @alt
88442           * diffused radiating light source from top right of canvas
88443           */
88444
88445          /**
88446           * @method specularMaterial
88447           * @param  {Number[]|String|p5.Color} color color Array, or CSS color string
88448           * @chainable
88449           */
88450          _main.default.prototype.specularMaterial = function(v1, v2, v3, alpha) {
88451            this._assert3d('specularMaterial');
88452            _main.default._validateParameters('specularMaterial', arguments);
88453
88454            var color = _main.default.prototype.color.apply(this, arguments);
88455            this._renderer.curFillColor = color._array;
88456            this._renderer._useSpecularMaterial = true;
88457            this._renderer._useEmissiveMaterial = false;
88458            this._renderer._useNormalMaterial = false;
88459            this._renderer._enableLighting = true;
88460            this._renderer._tex = null;
88461
88462            return this;
88463          };
88464
88465          /**
88466           * Sets the amount of gloss in the surface of shapes.
88467           * Used in combination with specularMaterial() in setting
88468           * the material properties of shapes. The default and minimum value is 1.
88469           * @method shininess
88470           * @param {Number} shine Degree of Shininess.
88471           *                       Defaults to 1.
88472           * @chainable
88473           * @example
88474           * <div>
88475           * <code>
88476           * function setup() {
88477           *   createCanvas(100, 100, WEBGL);
88478           * }
88479           * function draw() {
88480           *   background(0);
88481           *   noStroke();
88482           *   let locX = mouseX - width / 2;
88483           *   let locY = mouseY - height / 2;
88484           *   ambientLight(60, 60, 60);
88485           *   pointLight(255, 255, 255, locX, locY, 50);
88486           *   specularMaterial(250);
88487           *   translate(-25, 0, 0);
88488           *   shininess(1);
88489           *   sphere(20);
88490           *   translate(50, 0, 0);
88491           *   shininess(20);
88492           *   sphere(20);
88493           * }
88494           * </code>
88495           * </div>
88496           * @alt
88497           * Shininess on Camera changes position with mouse
88498           */
88499          _main.default.prototype.shininess = function(shine) {
88500            this._assert3d('shininess');
88501            _main.default._validateParameters('shininess', arguments);
88502
88503            if (shine < 1) {
88504              shine = 1;
88505            }
88506            this._renderer._useShininess = shine;
88507            return this;
88508          };
88509
88510          /**
88511           * @private blends colors according to color components.
88512           * If alpha value is less than 1, or non-standard blendMode
88513           * we need to enable blending on our gl context.
88514           * @param  {Number[]} color [description]
88515           * @return {Number[]]}  Normalized numbers array
88516           */
88517          _main.default.RendererGL.prototype._applyColorBlend = function(colors) {
88518            var gl = this.GL;
88519
88520            var isTexture = this.drawMode === constants.TEXTURE;
88521            var doBlend = isTexture || colors[colors.length - 1] < 1.0 || this._isErasing;
88522
88523            if (doBlend !== this._isBlending) {
88524              if (
88525                doBlend ||
88526                (this.curBlendMode !== constants.BLEND &&
88527                  this.curBlendMode !== constants.ADD)
88528              ) {
88529                gl.enable(gl.BLEND);
88530              } else {
88531                gl.disable(gl.BLEND);
88532              }
88533              gl.depthMask(true);
88534              this._isBlending = doBlend;
88535            }
88536            this._applyBlendMode();
88537            return colors;
88538          };
88539
88540          /**
88541           * @private sets blending in gl context to curBlendMode
88542           * @param  {Number[]} color [description]
88543           * @return {Number[]]}  Normalized numbers array
88544           */
88545          _main.default.RendererGL.prototype._applyBlendMode = function() {
88546            if (this._cachedBlendMode === this.curBlendMode) {
88547              return;
88548            }
88549            var gl = this.GL;
88550            switch (this.curBlendMode) {
88551              case constants.BLEND:
88552              case constants.ADD:
88553                gl.blendEquation(gl.FUNC_ADD);
88554                gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
88555                break;
88556              case constants.REMOVE:
88557                gl.blendEquation(gl.FUNC_REVERSE_SUBTRACT);
88558                gl.blendFunc(gl.SRC_ALPHA, gl.DST_ALPHA);
88559                break;
88560              case constants.MULTIPLY:
88561                gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
88562                gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ONE, gl.ONE);
88563                break;
88564              case constants.SCREEN:
88565                gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
88566                gl.blendFuncSeparate(gl.ONE_MINUS_DST_COLOR, gl.ONE, gl.ONE, gl.ONE);
88567                break;
88568              case constants.EXCLUSION:
88569                gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
88570                gl.blendFuncSeparate(
88571                  gl.ONE_MINUS_DST_COLOR,
88572                  gl.ONE_MINUS_SRC_COLOR,
88573                  gl.ONE,
88574                  gl.ONE
88575                );
88576
88577                break;
88578              case constants.REPLACE:
88579                gl.blendEquation(gl.FUNC_ADD);
88580                gl.blendFunc(gl.ONE, gl.ZERO);
88581                break;
88582              case constants.SUBTRACT:
88583                gl.blendEquationSeparate(gl.FUNC_REVERSE_SUBTRACT, gl.FUNC_ADD);
88584                gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE);
88585                break;
88586              case constants.DARKEST:
88587                if (this.blendExt) {
88588                  gl.blendEquationSeparate(this.blendExt.MIN_EXT, gl.FUNC_ADD);
88589                  gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE);
88590                } else {
88591                  console.warn(
88592                    'blendMode(DARKEST) does not work in your browser in WEBGL mode.'
88593                  );
88594                }
88595                break;
88596              case constants.LIGHTEST:
88597                if (this.blendExt) {
88598                  gl.blendEquationSeparate(this.blendExt.MAX_EXT, gl.FUNC_ADD);
88599                  gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE);
88600                } else {
88601                  console.warn(
88602                    'blendMode(LIGHTEST) does not work in your browser in WEBGL mode.'
88603                  );
88604                }
88605                break;
88606              default:
88607                console.error(
88608                  'Oops! Somehow RendererGL set curBlendMode to an unsupported mode.'
88609                );
88610
88611                break;
88612            }
88613
88614            if (!this._isErasing) {
88615              this._cachedBlendMode = this.curBlendMode;
88616            }
88617          };
88618          var _default = _main.default;
88619          exports.default = _default;
88620        },
88621        { '../core/constants': 48, '../core/main': 59, './p5.Texture': 115 }
88622      ],
88623      107: [
88624        function(_dereq_, module, exports) {
88625          'use strict';
88626          Object.defineProperty(exports, '__esModule', { value: true });
88627          exports.default = void 0;
88628
88629          var _main = _interopRequireDefault(_dereq_('../core/main'));
88630          function _interopRequireDefault(obj) {
88631            return obj && obj.__esModule ? obj : { default: obj };
88632          } /** ////////////////////////////////////////////////////////////////////////////////
88633           * @module Lights, Camera
88634           * @submodule Camera
88635           * @requires core
88636           */
88637          // p5.Prototype Methods
88638          ////////////////////////////////////////////////////////////////////////////////
88639          /**
88640           * Sets the camera position for a 3D sketch. Parameters for this function define
88641           * the position for the camera, the center of the sketch (where the camera is
88642           * pointing), and an up direction (the orientation of the camera).
88643           *
88644           * This function simulates the movements of the camera, allowing objects to be
88645           * viewed from various angles. Remember, it does not move the objects themselves
88646           * but the camera instead. For example when centerX value is positive, the camera
88647           * is rotating to the right side of the sketch, so the object would seem like
88648           * moving to the left.
88649           *
88650           * See this <a href = "https://www.openprocessing.org/sketch/740258">example</a>
88651           * to view the position of your camera.
88652           *
88653           * When called with no arguments, this function creates a default camera
88654           * equivalent to
88655           * camera(0, 0, (height/2.0) / tan(PI*30.0 / 180.0), 0, 0, 0, 0, 1, 0);
88656           * @method camera
88657           * @constructor
88658           * @for p5
88659           * @param  {Number} [x]        camera position value on x axis
88660           * @param  {Number} [y]        camera position value on y axis
88661           * @param  {Number} [z]        camera position value on z axis
88662           * @param  {Number} [centerX]  x coordinate representing center of the sketch
88663           * @param  {Number} [centerY]  y coordinate representing center of the sketch
88664           * @param  {Number} [centerZ]  z coordinate representing center of the sketch
88665           * @param  {Number} [upX]      x component of direction 'up' from camera
88666           * @param  {Number} [upY]      y component of direction 'up' from camera
88667           * @param  {Number} [upZ]      z component of direction 'up' from camera
88668           * @chainable
88669           * @example
88670           * <div>
88671           * <code>
88672           * function setup() {
88673           *   createCanvas(100, 100, WEBGL);
88674           * }
88675           * function draw() {
88676           *   background(204);
88677           *   //move the camera away from the plane by a sin wave
88678           *   camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);
88679           *   plane(10, 10);
88680           * }
88681           * </code>
88682           * </div>
88683           *
88684           * @example
88685           * <div>
88686           * <code>
88687           * //move slider to see changes!
88688           * //sliders control the first 6 parameters of camera()
88689           * let sliderGroup = [];
88690           * let X;
88691           * let Y;
88692           * let Z;
88693           * let centerX;
88694           * let centerY;
88695           * let centerZ;
88696           * let h = 20;
88697           *
88698           * function setup() {
88699           *   createCanvas(100, 100, WEBGL);
88700           *   //create sliders
88701           *   for (var i = 0; i < 6; i++) {
88702           *     if (i === 2) {
88703           *       sliderGroup[i] = createSlider(10, 400, 200);
88704           *     } else {
88705           *       sliderGroup[i] = createSlider(-400, 400, 0);
88706           *     }
88707           *     h = map(i, 0, 6, 5, 85);
88708           *     sliderGroup[i].position(10, height + h);
88709           *     sliderGroup[i].style('width', '80px');
88710           *   }
88711           * }
88712           *
88713           * function draw() {
88714           *   background(60);
88715           *   // assigning sliders' value to each parameters
88716           *   X = sliderGroup[0].value();
88717           *   Y = sliderGroup[1].value();
88718           *   Z = sliderGroup[2].value();
88719           *   centerX = sliderGroup[3].value();
88720           *   centerY = sliderGroup[4].value();
88721           *   centerZ = sliderGroup[5].value();
88722           *   camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);
88723           *   stroke(255);
88724           *   fill(255, 102, 94);
88725           *   box(85);
88726           * }
88727           * </code>
88728           * </div>
88729           * @alt
88730           * White square repeatedly grows to fill canvas and then shrinks.
88731           * An interactive example of a red cube with 3 sliders for moving it across x, y,
88732           * z axis and 3 sliders for shifting it's center.
88733           */ _main.default.prototype.camera = function() {
88734            var _this$_renderer$_curC;
88735            this._assert3d('camera');
88736            for (
88737              var _len = arguments.length, args = new Array(_len), _key = 0;
88738              _key < _len;
88739              _key++
88740            ) {
88741              args[_key] = arguments[_key];
88742            }
88743            _main.default._validateParameters('camera', args);
88744            (_this$_renderer$_curC = this._renderer._curCamera).camera.apply(
88745              _this$_renderer$_curC,
88746              args
88747            );
88748            return this;
88749          };
88750
88751          /**
88752           * Sets a perspective projection for the camera in a 3D sketch. This projection
88753           * represents depth through foreshortening: objects that are close to the camera
88754           * appear their actual size while those that are further away from the camera
88755           * appear smaller. The parameters to this function define the viewing frustum
88756           * (the truncated pyramid within which objects are seen by the camera) through
88757           * vertical field of view, aspect ratio (usually width/height), and near and far
88758           * clipping planes.
88759           *
88760           * When called with no arguments, the defaults
88761           * provided are equivalent to
88762           * perspective(PI/3.0, width/height, eyeZ/10.0, eyeZ*10.0), where eyeZ
88763           * is equal to ((height/2.0) / tan(PI*60.0/360.0));
88764           * @method  perspective
88765           * @for p5
88766           * @param  {Number} [fovy]   camera frustum vertical field of view,
88767           *                           from bottom to top of view, in <a href="#/p5/angleMode">angleMode</a> units
88768           * @param  {Number} [aspect] camera frustum aspect ratio
88769           * @param  {Number} [near]   frustum near plane length
88770           * @param  {Number} [far]    frustum far plane length
88771           * @chainable
88772           * @example
88773           * <div>
88774           * <code>
88775           * //drag the mouse to look around!
88776           * function setup() {
88777           *   createCanvas(100, 100, WEBGL);
88778           *   perspective(PI / 3.0, width / height, 0.1, 500);
88779           * }
88780           * function draw() {
88781           *   background(200);
88782           *   orbitControl();
88783           *   normalMaterial();
88784           *
88785           *   rotateX(-0.3);
88786           *   rotateY(-0.2);
88787           *   translate(0, 0, -50);
88788           *
88789           *   push();
88790           *   translate(-15, 0, sin(frameCount / 30) * 95);
88791           *   box(30);
88792           *   pop();
88793           *   push();
88794           *   translate(15, 0, sin(frameCount / 30 + PI) * 95);
88795           *   box(30);
88796           *   pop();
88797           * }
88798           * </code>
88799           * </div>
88800           *
88801           * @alt
88802           * two colored 3D boxes move back and forth, rotating as mouse is dragged.
88803           */
88804          _main.default.prototype.perspective = function() {
88805            var _this$_renderer$_curC2;
88806            this._assert3d('perspective');
88807            for (
88808              var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;
88809              _key2 < _len2;
88810              _key2++
88811            ) {
88812              args[_key2] = arguments[_key2];
88813            }
88814            _main.default._validateParameters('perspective', args);
88815            (_this$_renderer$_curC2 = this._renderer._curCamera).perspective.apply(
88816              _this$_renderer$_curC2,
88817              args
88818            );
88819            return this;
88820          };
88821
88822          /**
88823           * Sets an orthographic projection for the camera in a 3D sketch and defines a
88824           * box-shaped viewing frustum within which objects are seen. In this projection,
88825           * all objects with the same dimension appear the same size, regardless of
88826           * whether they are near or far from the camera. The parameters to this
88827           * function specify the viewing frustum where left and right are the minimum and
88828           * maximum x values, top and bottom are the minimum and maximum y values, and near
88829           * and far are the minimum and maximum z values. If no parameters are given, the
88830           * default is used: ortho(-width/2, width/2, -height/2, height/2).
88831           * @method  ortho
88832           * @for p5
88833           * @param  {Number} [left]   camera frustum left plane
88834           * @param  {Number} [right]  camera frustum right plane
88835           * @param  {Number} [bottom] camera frustum bottom plane
88836           * @param  {Number} [top]    camera frustum top plane
88837           * @param  {Number} [near]   camera frustum near plane
88838           * @param  {Number} [far]    camera frustum far plane
88839           * @chainable
88840           * @example
88841           * <div>
88842           * <code>
88843           * //drag the mouse to look around!
88844           * //there's no vanishing point
88845           * function setup() {
88846           *   createCanvas(100, 100, WEBGL);
88847           *   ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);
88848           * }
88849           * function draw() {
88850           *   background(200);
88851           *   orbitControl();
88852           *   normalMaterial();
88853           *
88854           *   rotateX(0.2);
88855           *   rotateY(-0.2);
88856           *   push();
88857           *   translate(-15, 0, sin(frameCount / 30) * 65);
88858           *   box(30);
88859           *   pop();
88860           *   push();
88861           *   translate(15, 0, sin(frameCount / 30 + PI) * 65);
88862           *   box(30);
88863           *   pop();
88864           * }
88865           * </code>
88866           * </div>
88867           *
88868           * @alt
88869           * two 3D boxes move back and forth along same plane, rotating as mouse is dragged.
88870           */
88871          _main.default.prototype.ortho = function() {
88872            var _this$_renderer$_curC3;
88873            this._assert3d('ortho');
88874            for (
88875              var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;
88876              _key3 < _len3;
88877              _key3++
88878            ) {
88879              args[_key3] = arguments[_key3];
88880            }
88881            _main.default._validateParameters('ortho', args);
88882            (_this$_renderer$_curC3 = this._renderer._curCamera).ortho.apply(
88883              _this$_renderer$_curC3,
88884              args
88885            );
88886            return this;
88887          };
88888
88889          /**
88890           * Sets a perspective matrix as defined by the parameters.
88891           *
88892           * A frustum is a geometric form: a pyramid with its top
88893           * cut off. With the viewer's eye at the imaginary top of
88894           * the pyramid, the six planes of the frustum act as clipping
88895           * planes when rendering a 3D view. Thus, any form inside the
88896           * clipping planes is visible; anything outside
88897           * those planes is not visible.
88898           *
88899           * Setting the frustum changes the perspective of the scene being rendered.
88900           * This can be achieved more simply in many cases by using
88901           * <a href="https://p5js.org/reference/#/p5/perspective">perspective()</a>.
88902           *
88903           * @method frustum
88904           * @for p5
88905           * @param  {Number} [left]   camera frustum left plane
88906           * @param  {Number} [right]  camera frustum right plane
88907           * @param  {Number} [bottom] camera frustum bottom plane
88908           * @param  {Number} [top]    camera frustum top plane
88909           * @param  {Number} [near]   camera frustum near plane
88910           * @param  {Number} [far]    camera frustum far plane
88911           * @chainable
88912           * @example
88913           * <div>
88914           * <code>
88915           * function setup() {
88916           *   createCanvas(100, 100, WEBGL);
88917           *   setAttributes('antialias', true);
88918           *   frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);
88919           * }
88920           * function draw() {
88921           *   background(200);
88922           *   orbitControl();
88923           *   strokeWeight(10);
88924           *   stroke(0, 0, 255);
88925           *   noFill();
88926           *
88927           *   rotateY(-0.2);
88928           *   rotateX(-0.3);
88929           *   push();
88930           *   translate(-15, 0, sin(frameCount / 30) * 25);
88931           *   box(30);
88932           *   pop();
88933           *   push();
88934           *   translate(15, 0, sin(frameCount / 30 + PI) * 25);
88935           *   box(30);
88936           *   pop();
88937           * }
88938           * </code>
88939           * </div>
88940           *
88941           * @alt
88942           * two 3D boxes move back and forth along same plane, rotating as mouse is dragged.
88943           */
88944          _main.default.prototype.frustum = function() {
88945            var _this$_renderer$_curC4;
88946            this._assert3d('frustum');
88947            for (
88948              var _len4 = arguments.length, args = new Array(_len4), _key4 = 0;
88949              _key4 < _len4;
88950              _key4++
88951            ) {
88952              args[_key4] = arguments[_key4];
88953            }
88954            _main.default._validateParameters('frustum', args);
88955            (_this$_renderer$_curC4 = this._renderer._curCamera).frustum.apply(
88956              _this$_renderer$_curC4,
88957              args
88958            );
88959            return this;
88960          };
88961
88962          ////////////////////////////////////////////////////////////////////////////////
88963          // p5.Camera
88964          ////////////////////////////////////////////////////////////////////////////////
88965
88966          /**
88967           * Creates a new <a href="#/p5.Camera">p5.Camera</a> object and tells the
88968           * renderer to use that camera.
88969           * Returns the p5.Camera object.
88970           * @method createCamera
88971           * @return {p5.Camera} The newly created camera object.
88972           * @for p5
88973           * @example
88974           * <div><code>
88975           * // Creates a camera object and animates it around a box.
88976           * let camera;
88977           * function setup() {
88978           *   createCanvas(100, 100, WEBGL);
88979           *   background(0);
88980           *   camera = createCamera();
88981           *   setCamera(camera);
88982           * }
88983           *
88984           * function draw() {
88985           *   camera.lookAt(0, 0, 0);
88986           *   camera.setPosition(sin(frameCount / 60) * 200, 0, 100);
88987           *   box(20);
88988           * }
88989           * </code></div>
88990           *
88991           * @alt
88992           * An example that creates a camera and moves it around the box.
88993           */
88994          _main.default.prototype.createCamera = function() {
88995            this._assert3d('createCamera');
88996            var _cam = new _main.default.Camera(this._renderer);
88997
88998            // compute default camera settings, then set a default camera
88999            _cam._computeCameraDefaultSettings();
89000            _cam._setDefaultCamera();
89001
89002            // set renderer current camera to the new camera
89003            this._renderer._curCamera = _cam;
89004
89005            return _cam;
89006          };
89007
89008          /**
89009           * This class describes a camera for use in p5's
89010           * <a href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">
89011           * WebGL mode</a>. It contains camera position, orientation, and projection
89012           * information necessary for rendering a 3D scene.
89013           *
89014           * New p5.Camera objects can be made through the
89015           * <a href="#/p5/createCamera">createCamera()</a> function and controlled through
89016           * the methods described below. A camera created in this way will use a default
89017           * position in the scene and a default perspective projection until these
89018           * properties are changed through the various methods available. It is possible
89019           * to create multiple cameras, in which case the current camera
89020           * can be set through the <a href="#/p5/setCamera">setCamera()</a> method.
89021           *
89022           * Note:
89023           * The methods below operate in two coordinate systems: the 'world' coordinate
89024           * system describe positions in terms of their relationship to the origin along
89025           * the X, Y and Z axes whereas the camera's 'local' coordinate system
89026           * describes positions from the camera's point of view: left-right, up-down,
89027           * and forward-backward. The <a href="#/p5.Camera/move">move()</a> method,
89028           * for instance, moves the camera along its own axes, whereas the
89029           * <a href="#/p5.Camera/setPosition">setPosition()</a>
89030           * method sets the camera's position in world-space.
89031           *
89032           * @class p5.Camera
89033           * @param {rendererGL} rendererGL instance of WebGL renderer
89034           * @example
89035           * <div>
89036           * <code>
89037           * let cam;
89038           * let delta = 0.01;
89039           *
89040           * function setup() {
89041           *   createCanvas(100, 100, WEBGL);
89042           *   normalMaterial();
89043           *   cam = createCamera();
89044           *   // set initial pan angle
89045           *   cam.pan(-0.8);
89046           * }
89047           *
89048           * function draw() {
89049           *   background(200);
89050           *
89051           *   // pan camera according to angle 'delta'
89052           *   cam.pan(delta);
89053           *
89054           *   // every 160 frames, switch direction
89055           *   if (frameCount % 160 === 0) {
89056           *     delta *= -1;
89057           *   }
89058           *
89059           *   rotateX(frameCount * 0.01);
89060           *   translate(-100, 0, 0);
89061           *   box(20);
89062           *   translate(35, 0, 0);
89063           *   box(20);
89064           *   translate(35, 0, 0);
89065           *   box(20);
89066           *   translate(35, 0, 0);
89067           *   box(20);
89068           *   translate(35, 0, 0);
89069           *   box(20);
89070           *   translate(35, 0, 0);
89071           *   box(20);
89072           *   translate(35, 0, 0);
89073           *   box(20);
89074           * }
89075           * </code>
89076           * </div>
89077           *
89078           * @alt
89079           * camera view pans left and right across a series of rotating 3D boxes.
89080           */
89081          _main.default.Camera = function(renderer) {
89082            this._renderer = renderer;
89083
89084            this.cameraType = 'default';
89085
89086            this.cameraMatrix = new _main.default.Matrix();
89087            this.projMatrix = new _main.default.Matrix();
89088          };
89089
89090          ////////////////////////////////////////////////////////////////////////////////
89091          // Camera Projection Methods
89092          ////////////////////////////////////////////////////////////////////////////////
89093
89094          /**
89095           * Sets a perspective projection for a p5.Camera object and sets parameters
89096           * for that projection according to <a href="#/p5/perspective">perspective()</a>
89097           * syntax.
89098           * @method perspective
89099           * @for p5.Camera
89100           */
89101          _main.default.Camera.prototype.perspective = function(fovy, aspect, near, far) {
89102            this.cameraType = arguments.length > 0 ? 'custom' : 'default';
89103            if (typeof fovy === 'undefined') {
89104              fovy = this.defaultCameraFOV;
89105              // this avoids issue where setting angleMode(DEGREES) before calling
89106              // perspective leads to a smaller than expected FOV (because
89107              // _computeCameraDefaultSettings computes in radians)
89108              this.cameraFOV = fovy;
89109            } else {
89110              this.cameraFOV = this._renderer._pInst._toRadians(fovy);
89111            }
89112            if (typeof aspect === 'undefined') {
89113              aspect = this.defaultAspectRatio;
89114            }
89115            if (typeof near === 'undefined') {
89116              near = this.defaultCameraNear;
89117            }
89118            if (typeof far === 'undefined') {
89119              far = this.defaultCameraFar;
89120            }
89121
89122            if (near <= 0.0001) {
89123              near = 0.01;
89124              console.log(
89125                'Avoid perspective near plane values close to or below 0. ' +
89126                  'Setting value to 0.01.'
89127              );
89128            }
89129
89130            if (far < near) {
89131              console.log(
89132                'Perspective far plane value is less than near plane value. ' +
89133                  'Nothing will be shown.'
89134              );
89135            }
89136
89137            this.aspectRatio = aspect;
89138            this.cameraNear = near;
89139            this.cameraFar = far;
89140
89141            this.projMatrix = _main.default.Matrix.identity();
89142
89143            var f = 1.0 / Math.tan(this.cameraFOV / 2);
89144            var nf = 1.0 / (this.cameraNear - this.cameraFar);
89145
89146            // prettier-ignore
89147            this.projMatrix.set(f / aspect, 0, 0, 0,
89148  0, -f, 0, 0,
89149  0, 0, (far + near) * nf, -1,
89150  0, 0, 2 * far * near * nf, 0);
89151
89152            if (this._isActive()) {
89153              this._renderer.uPMatrix.set(
89154                this.projMatrix.mat4[0],
89155                this.projMatrix.mat4[1],
89156                this.projMatrix.mat4[2],
89157                this.projMatrix.mat4[3],
89158                this.projMatrix.mat4[4],
89159                this.projMatrix.mat4[5],
89160                this.projMatrix.mat4[6],
89161                this.projMatrix.mat4[7],
89162                this.projMatrix.mat4[8],
89163                this.projMatrix.mat4[9],
89164                this.projMatrix.mat4[10],
89165                this.projMatrix.mat4[11],
89166                this.projMatrix.mat4[12],
89167                this.projMatrix.mat4[13],
89168                this.projMatrix.mat4[14],
89169                this.projMatrix.mat4[15]
89170              );
89171            }
89172          };
89173
89174          /**
89175           * Sets an orthographic projection for a p5.Camera object and sets parameters
89176           * for that projection according to <a href="#/p5/ortho">ortho()</a> syntax.
89177           * @method ortho
89178           * @for p5.Camera
89179           */
89180          _main.default.Camera.prototype.ortho = function(
89181            left,
89182            right,
89183            bottom,
89184            top,
89185            near,
89186            far
89187          ) {
89188            if (left === undefined) left = -this._renderer.width / 2;
89189            if (right === undefined) right = +this._renderer.width / 2;
89190            if (bottom === undefined) bottom = -this._renderer.height / 2;
89191            if (top === undefined) top = +this._renderer.height / 2;
89192            if (near === undefined) near = 0;
89193            if (far === undefined)
89194              far = Math.max(this._renderer.width, this._renderer.height);
89195
89196            var w = right - left;
89197            var h = top - bottom;
89198            var d = far - near;
89199
89200            var x = +2.0 / w;
89201            var y = +2.0 / h;
89202            var z = -2.0 / d;
89203
89204            var tx = -(right + left) / w;
89205            var ty = -(top + bottom) / h;
89206            var tz = -(far + near) / d;
89207
89208            this.projMatrix = _main.default.Matrix.identity();
89209
89210            // prettier-ignore
89211            this.projMatrix.set(x, 0, 0, 0,
89212  0, -y, 0, 0,
89213  0, 0, z, 0,
89214  tx, ty, tz, 1);
89215
89216            if (this._isActive()) {
89217              this._renderer.uPMatrix.set(
89218                this.projMatrix.mat4[0],
89219                this.projMatrix.mat4[1],
89220                this.projMatrix.mat4[2],
89221                this.projMatrix.mat4[3],
89222                this.projMatrix.mat4[4],
89223                this.projMatrix.mat4[5],
89224                this.projMatrix.mat4[6],
89225                this.projMatrix.mat4[7],
89226                this.projMatrix.mat4[8],
89227                this.projMatrix.mat4[9],
89228                this.projMatrix.mat4[10],
89229                this.projMatrix.mat4[11],
89230                this.projMatrix.mat4[12],
89231                this.projMatrix.mat4[13],
89232                this.projMatrix.mat4[14],
89233                this.projMatrix.mat4[15]
89234              );
89235            }
89236
89237            this.cameraType = 'custom';
89238          };
89239
89240          /**
89241           * @method frustum
89242           * @for p5.Camera
89243           */
89244          _main.default.Camera.prototype.frustum = function(
89245            left,
89246            right,
89247            bottom,
89248            top,
89249            near,
89250            far
89251          ) {
89252            if (left === undefined) left = -this._renderer.width / 2;
89253            if (right === undefined) right = +this._renderer.width / 2;
89254            if (bottom === undefined) bottom = -this._renderer.height / 2;
89255            if (top === undefined) top = +this._renderer.height / 2;
89256            if (near === undefined) near = 0;
89257            if (far === undefined)
89258              far = Math.max(this._renderer.width, this._renderer.height);
89259
89260            var w = right - left;
89261            var h = top - bottom;
89262            var d = far - near;
89263
89264            var x = +(2.0 * near) / w;
89265            var y = +(2.0 * near) / h;
89266            var z = -(2.0 * far * near) / d;
89267
89268            var tx = (right + left) / w;
89269            var ty = (top + bottom) / h;
89270            var tz = -(far + near) / d;
89271
89272            this.projMatrix = _main.default.Matrix.identity();
89273
89274            // prettier-ignore
89275            this.projMatrix.set(x, 0, 0, 0,
89276  0, y, 0, 0,
89277  tx, ty, tz, -1,
89278  0, 0, z, 0);
89279
89280            if (this._isActive()) {
89281              this._renderer.uPMatrix.set(
89282                this.projMatrix.mat4[0],
89283                this.projMatrix.mat4[1],
89284                this.projMatrix.mat4[2],
89285                this.projMatrix.mat4[3],
89286                this.projMatrix.mat4[4],
89287                this.projMatrix.mat4[5],
89288                this.projMatrix.mat4[6],
89289                this.projMatrix.mat4[7],
89290                this.projMatrix.mat4[8],
89291                this.projMatrix.mat4[9],
89292                this.projMatrix.mat4[10],
89293                this.projMatrix.mat4[11],
89294                this.projMatrix.mat4[12],
89295                this.projMatrix.mat4[13],
89296                this.projMatrix.mat4[14],
89297                this.projMatrix.mat4[15]
89298              );
89299            }
89300
89301            this.cameraType = 'custom';
89302          };
89303
89304          ////////////////////////////////////////////////////////////////////////////////
89305          // Camera Orientation Methods
89306          ////////////////////////////////////////////////////////////////////////////////
89307
89308          /**
89309           * Rotate camera view about arbitrary axis defined by x,y,z
89310           * based on http://learnwebgl.brown37.net/07_cameras/camera_rotating_motion.html
89311           * @method _rotateView
89312           * @private
89313           */
89314          _main.default.Camera.prototype._rotateView = function(a, x, y, z) {
89315            var centerX = this.centerX;
89316            var centerY = this.centerY;
89317            var centerZ = this.centerZ;
89318
89319            // move center by eye position such that rotation happens around eye position
89320            centerX -= this.eyeX;
89321            centerY -= this.eyeY;
89322            centerZ -= this.eyeZ;
89323
89324            var rotation = _main.default.Matrix.identity(this._renderer._pInst);
89325            rotation.rotate(this._renderer._pInst._toRadians(a), x, y, z);
89326
89327            // prettier-ignore
89328            var rotatedCenter = [
89329  centerX * rotation.mat4[0] + centerY * rotation.mat4[4] + centerZ * rotation.mat4[8],
89330  centerX * rotation.mat4[1] + centerY * rotation.mat4[5] + centerZ * rotation.mat4[9],
89331  centerX * rotation.mat4[2] + centerY * rotation.mat4[6] + centerZ * rotation.mat4[10]];
89332
89333            // add eye position back into center
89334            rotatedCenter[0] += this.eyeX;
89335            rotatedCenter[1] += this.eyeY;
89336            rotatedCenter[2] += this.eyeZ;
89337
89338            this.camera(
89339              this.eyeX,
89340              this.eyeY,
89341              this.eyeZ,
89342              rotatedCenter[0],
89343              rotatedCenter[1],
89344              rotatedCenter[2],
89345              this.upX,
89346              this.upY,
89347              this.upZ
89348            );
89349          };
89350
89351          /**
89352           * Panning rotates the camera view to the left and right.
89353           * @method pan
89354           * @param {Number} angle amount to rotate camera in current
89355           * <a href="#/p5/angleMode">angleMode</a> units.
89356           * Greater than 0 values rotate counterclockwise (to the left).
89357           * @example
89358           * <div>
89359           * <code>
89360           * let cam;
89361           * let delta = 0.01;
89362           *
89363           * function setup() {
89364           *   createCanvas(100, 100, WEBGL);
89365           *   normalMaterial();
89366           *   cam = createCamera();
89367           *   // set initial pan angle
89368           *   cam.pan(-0.8);
89369           * }
89370           *
89371           * function draw() {
89372           *   background(200);
89373           *
89374           *   // pan camera according to angle 'delta'
89375           *   cam.pan(delta);
89376           *
89377           *   // every 160 frames, switch direction
89378           *   if (frameCount % 160 === 0) {
89379           *     delta *= -1;
89380           *   }
89381           *
89382           *   rotateX(frameCount * 0.01);
89383           *   translate(-100, 0, 0);
89384           *   box(20);
89385           *   translate(35, 0, 0);
89386           *   box(20);
89387           *   translate(35, 0, 0);
89388           *   box(20);
89389           *   translate(35, 0, 0);
89390           *   box(20);
89391           *   translate(35, 0, 0);
89392           *   box(20);
89393           *   translate(35, 0, 0);
89394           *   box(20);
89395           *   translate(35, 0, 0);
89396           *   box(20);
89397           * }
89398           * </code>
89399           * </div>
89400           *
89401           * @alt
89402           * camera view pans left and right across a series of rotating 3D boxes.
89403           */
89404          _main.default.Camera.prototype.pan = function(amount) {
89405            var local = this._getLocalAxes();
89406            this._rotateView(amount, local.y[0], local.y[1], local.y[2]);
89407          };
89408
89409          /**
89410           * Tilting rotates the camera view up and down.
89411           * @method tilt
89412           * @param {Number} angle amount to rotate camera in current
89413           * <a href="#/p5/angleMode">angleMode</a> units.
89414           * Greater than 0 values rotate counterclockwise (to the left).
89415           * @example
89416           * <div>
89417           * <code>
89418           * let cam;
89419           * let delta = 0.01;
89420           *
89421           * function setup() {
89422           *   createCanvas(100, 100, WEBGL);
89423           *   normalMaterial();
89424           *   cam = createCamera();
89425           *   // set initial tilt
89426           *   cam.tilt(-0.8);
89427           * }
89428           *
89429           * function draw() {
89430           *   background(200);
89431           *
89432           *   // pan camera according to angle 'delta'
89433           *   cam.tilt(delta);
89434           *
89435           *   // every 160 frames, switch direction
89436           *   if (frameCount % 160 === 0) {
89437           *     delta *= -1;
89438           *   }
89439           *
89440           *   rotateY(frameCount * 0.01);
89441           *   translate(0, -100, 0);
89442           *   box(20);
89443           *   translate(0, 35, 0);
89444           *   box(20);
89445           *   translate(0, 35, 0);
89446           *   box(20);
89447           *   translate(0, 35, 0);
89448           *   box(20);
89449           *   translate(0, 35, 0);
89450           *   box(20);
89451           *   translate(0, 35, 0);
89452           *   box(20);
89453           *   translate(0, 35, 0);
89454           *   box(20);
89455           * }
89456           * </code>
89457           * </div>
89458           *
89459           * @alt
89460           * camera view tilts up and down across a series of rotating 3D boxes.
89461           */
89462          _main.default.Camera.prototype.tilt = function(amount) {
89463            var local = this._getLocalAxes();
89464            this._rotateView(amount, local.x[0], local.x[1], local.x[2]);
89465          };
89466
89467          /**
89468           * Reorients the camera to look at a position in world space.
89469           * @method lookAt
89470           * @for p5.Camera
89471           * @param {Number} x x position of a point in world space
89472           * @param {Number} y y position of a point in world space
89473           * @param {Number} z z position of a point in world space
89474           * @example
89475           * <div>
89476           * <code>
89477           * let cam;
89478           *
89479           * function setup() {
89480           *   createCanvas(100, 100, WEBGL);
89481           *   normalMaterial();
89482           *   cam = createCamera();
89483           * }
89484           *
89485           * function draw() {
89486           *   background(200);
89487           *
89488           *   // look at a new random point every 60 frames
89489           *   if (frameCount % 60 === 0) {
89490           *     cam.lookAt(random(-100, 100), random(-50, 50), 0);
89491           *   }
89492           *
89493           *   rotateX(frameCount * 0.01);
89494           *   translate(-100, 0, 0);
89495           *   box(20);
89496           *   translate(35, 0, 0);
89497           *   box(20);
89498           *   translate(35, 0, 0);
89499           *   box(20);
89500           *   translate(35, 0, 0);
89501           *   box(20);
89502           *   translate(35, 0, 0);
89503           *   box(20);
89504           *   translate(35, 0, 0);
89505           *   box(20);
89506           *   translate(35, 0, 0);
89507           *   box(20);
89508           * }
89509           * </code>
89510           * </div>
89511           *
89512           * @alt
89513           * camera view of rotating 3D cubes changes to look at a new random
89514           * point every second .
89515           */
89516          _main.default.Camera.prototype.lookAt = function(x, y, z) {
89517            this.camera(
89518              this.eyeX,
89519              this.eyeY,
89520              this.eyeZ,
89521              x,
89522              y,
89523              z,
89524              this.upX,
89525              this.upY,
89526              this.upZ
89527            );
89528          };
89529
89530          ////////////////////////////////////////////////////////////////////////////////
89531          // Camera Position Methods
89532          ////////////////////////////////////////////////////////////////////////////////
89533
89534          /**
89535           * Sets a camera's position and orientation.  This is equivalent to calling
89536           * <a href="#/p5/camera">camera()</a> on a p5.Camera object.
89537           * @method camera
89538           * @for p5.Camera
89539           */
89540          _main.default.Camera.prototype.camera = function(
89541            eyeX,
89542            eyeY,
89543            eyeZ,
89544            centerX,
89545            centerY,
89546            centerZ,
89547            upX,
89548            upY,
89549            upZ
89550          ) {
89551            if (typeof eyeX === 'undefined') {
89552              eyeX = this.defaultEyeX;
89553              eyeY = this.defaultEyeY;
89554              eyeZ = this.defaultEyeZ;
89555              centerX = eyeX;
89556              centerY = eyeY;
89557              centerZ = 0;
89558              upX = 0;
89559              upY = 1;
89560              upZ = 0;
89561            }
89562
89563            this.eyeX = eyeX;
89564            this.eyeY = eyeY;
89565            this.eyeZ = eyeZ;
89566
89567            if (typeof centerX !== 'undefined') {
89568              this.centerX = centerX;
89569              this.centerY = centerY;
89570              this.centerZ = centerZ;
89571            }
89572
89573            if (typeof upX !== 'undefined') {
89574              this.upX = upX;
89575              this.upY = upY;
89576              this.upZ = upZ;
89577            }
89578
89579            var local = this._getLocalAxes();
89580
89581            // the camera affects the model view matrix, insofar as it
89582            // inverse translates the world to the eye position of the camera
89583            // and rotates it.
89584            // prettier-ignore
89585            this.cameraMatrix.set(local.x[0], local.y[0], local.z[0], 0,
89586  local.x[1], local.y[1], local.z[1], 0,
89587  local.x[2], local.y[2], local.z[2], 0,
89588  0, 0, 0, 1);
89589
89590            var tx = -eyeX;
89591            var ty = -eyeY;
89592            var tz = -eyeZ;
89593
89594            this.cameraMatrix.translate([tx, ty, tz]);
89595
89596            if (this._isActive()) {
89597              this._renderer.uMVMatrix.set(
89598                this.cameraMatrix.mat4[0],
89599                this.cameraMatrix.mat4[1],
89600                this.cameraMatrix.mat4[2],
89601                this.cameraMatrix.mat4[3],
89602                this.cameraMatrix.mat4[4],
89603                this.cameraMatrix.mat4[5],
89604                this.cameraMatrix.mat4[6],
89605                this.cameraMatrix.mat4[7],
89606                this.cameraMatrix.mat4[8],
89607                this.cameraMatrix.mat4[9],
89608                this.cameraMatrix.mat4[10],
89609                this.cameraMatrix.mat4[11],
89610                this.cameraMatrix.mat4[12],
89611                this.cameraMatrix.mat4[13],
89612                this.cameraMatrix.mat4[14],
89613                this.cameraMatrix.mat4[15]
89614              );
89615            }
89616            return this;
89617          };
89618
89619          /**
89620           * Move camera along its local axes while maintaining current camera orientation.
89621           * @method move
89622           * @param {Number} x amount to move along camera's left-right axis
89623           * @param {Number} y amount to move along camera's up-down axis
89624           * @param {Number} z amount to move along camera's forward-backward axis
89625           * @example
89626           * <div>
89627           * <code>
89628           * // see the camera move along its own axes while maintaining its orientation
89629           * let cam;
89630           * let delta = 0.5;
89631           *
89632           * function setup() {
89633           *   createCanvas(100, 100, WEBGL);
89634           *   normalMaterial();
89635           *   cam = createCamera();
89636           * }
89637           *
89638           * function draw() {
89639           *   background(200);
89640           *
89641           *   // move the camera along its local axes
89642           *   cam.move(delta, delta, 0);
89643           *
89644           *   // every 100 frames, switch direction
89645           *   if (frameCount % 150 === 0) {
89646           *     delta *= -1;
89647           *   }
89648           *
89649           *   translate(-10, -10, 0);
89650           *   box(50, 8, 50);
89651           *   translate(15, 15, 0);
89652           *   box(50, 8, 50);
89653           *   translate(15, 15, 0);
89654           *   box(50, 8, 50);
89655           *   translate(15, 15, 0);
89656           *   box(50, 8, 50);
89657           *   translate(15, 15, 0);
89658           *   box(50, 8, 50);
89659           *   translate(15, 15, 0);
89660           *   box(50, 8, 50);
89661           * }
89662           * </code>
89663           * </div>
89664           *
89665           * @alt
89666           * camera view moves along a series of 3D boxes, maintaining the same
89667           * orientation throughout the move
89668           */
89669          _main.default.Camera.prototype.move = function(x, y, z) {
89670            var local = this._getLocalAxes();
89671
89672            // scale local axes by movement amounts
89673            // based on http://learnwebgl.brown37.net/07_cameras/camera_linear_motion.html
89674            var dx = [local.x[0] * x, local.x[1] * x, local.x[2] * x];
89675            var dy = [local.y[0] * y, local.y[1] * y, local.y[2] * y];
89676            var dz = [local.z[0] * z, local.z[1] * z, local.z[2] * z];
89677
89678            this.camera(
89679              this.eyeX + dx[0] + dy[0] + dz[0],
89680              this.eyeY + dx[1] + dy[1] + dz[1],
89681              this.eyeZ + dx[2] + dy[2] + dz[2],
89682              this.centerX + dx[0] + dy[0] + dz[0],
89683              this.centerY + dx[1] + dy[1] + dz[1],
89684              this.centerZ + dx[2] + dy[2] + dz[2],
89685              0,
89686              1,
89687              0
89688            );
89689          };
89690
89691          /**
89692           * Set camera position in world-space while maintaining current camera
89693           * orientation.
89694           * @method setPosition
89695           * @param {Number} x x position of a point in world space
89696           * @param {Number} y y position of a point in world space
89697           * @param {Number} z z position of a point in world space
89698           * @example
89699           * <div>
89700           * <code>
89701           * // press '1' '2' or '3' keys to set camera position
89702           *
89703           * let cam;
89704           *
89705           * function setup() {
89706           *   createCanvas(100, 100, WEBGL);
89707           *   normalMaterial();
89708           *   cam = createCamera();
89709           * }
89710           *
89711           * function draw() {
89712           *   background(200);
89713           *
89714           *   // '1' key
89715           *   if (keyIsDown(49)) {
89716           *     cam.setPosition(30, 0, 80);
89717           *   }
89718           *   // '2' key
89719           *   if (keyIsDown(50)) {
89720           *     cam.setPosition(0, 0, 80);
89721           *   }
89722           *   // '3' key
89723           *   if (keyIsDown(51)) {
89724           *     cam.setPosition(-30, 0, 80);
89725           *   }
89726           *
89727           *   box(20);
89728           * }
89729           * </code>
89730           * </div>
89731           *
89732           * @alt
89733           * camera position changes as the user presses keys, altering view of a 3D box
89734           */
89735          _main.default.Camera.prototype.setPosition = function(x, y, z) {
89736            var diffX = x - this.eyeX;
89737            var diffY = y - this.eyeY;
89738            var diffZ = z - this.eyeZ;
89739
89740            this.camera(
89741              x,
89742              y,
89743              z,
89744              this.centerX + diffX,
89745              this.centerY + diffY,
89746              this.centerZ + diffZ,
89747              0,
89748              1,
89749              0
89750            );
89751          };
89752
89753          ////////////////////////////////////////////////////////////////////////////////
89754          // Camera Helper Methods
89755          ////////////////////////////////////////////////////////////////////////////////
89756
89757          // @TODO: combine this function with _setDefaultCamera to compute these values
89758          // as-needed
89759          _main.default.Camera.prototype._computeCameraDefaultSettings = function() {
89760            this.defaultCameraFOV = 60 / 180 * Math.PI;
89761            this.defaultAspectRatio = this._renderer.width / this._renderer.height;
89762            this.defaultEyeX = 0;
89763            this.defaultEyeY = 0;
89764            this.defaultEyeZ =
89765              this._renderer.height / 2.0 / Math.tan(this.defaultCameraFOV / 2.0);
89766            this.defaultCenterX = 0;
89767            this.defaultCenterY = 0;
89768            this.defaultCenterZ = 0;
89769            this.defaultCameraNear = this.defaultEyeZ * 0.1;
89770            this.defaultCameraFar = this.defaultEyeZ * 10;
89771          };
89772
89773          //detect if user didn't set the camera
89774          //then call this function below
89775          _main.default.Camera.prototype._setDefaultCamera = function() {
89776            this.cameraFOV = this.defaultCameraFOV;
89777            this.aspectRatio = this.defaultAspectRatio;
89778            this.eyeX = this.defaultEyeX;
89779            this.eyeY = this.defaultEyeY;
89780            this.eyeZ = this.defaultEyeZ;
89781            this.centerX = this.defaultCenterX;
89782            this.centerY = this.defaultCenterY;
89783            this.centerZ = this.defaultCenterZ;
89784            this.upX = 0;
89785            this.upY = 1;
89786            this.upZ = 0;
89787            this.cameraNear = this.defaultCameraNear;
89788            this.cameraFar = this.defaultCameraFar;
89789
89790            this.perspective();
89791            this.camera();
89792
89793            this.cameraType = 'default';
89794          };
89795
89796          _main.default.Camera.prototype._resize = function() {
89797            // If we're using the default camera, update the aspect ratio
89798            if (this.cameraType === 'default') {
89799              this._computeCameraDefaultSettings();
89800              this._setDefaultCamera();
89801            } else {
89802              this.perspective(
89803                this.cameraFOV,
89804                this._renderer.width / this._renderer.height
89805              );
89806            }
89807          };
89808
89809          /**
89810           * Returns a copy of a camera.
89811           * @method copy
89812           * @private
89813           */
89814          _main.default.Camera.prototype.copy = function() {
89815            var _cam = new _main.default.Camera(this._renderer);
89816            _cam.cameraFOV = this.cameraFOV;
89817            _cam.aspectRatio = this.aspectRatio;
89818            _cam.eyeX = this.eyeX;
89819            _cam.eyeY = this.eyeY;
89820            _cam.eyeZ = this.eyeZ;
89821            _cam.centerX = this.centerX;
89822            _cam.centerY = this.centerY;
89823            _cam.centerZ = this.centerZ;
89824            _cam.cameraNear = this.cameraNear;
89825            _cam.cameraFar = this.cameraFar;
89826
89827            _cam.cameraType = this.cameraType;
89828
89829            _cam.cameraMatrix = this.cameraMatrix.copy();
89830            _cam.projMatrix = this.projMatrix.copy();
89831
89832            return _cam;
89833          };
89834
89835          /**
89836           * Returns a camera's local axes: left-right, up-down, and forward-backward,
89837           * as defined by vectors in world-space.
89838           * @method _getLocalAxes
89839           * @private
89840           */
89841          _main.default.Camera.prototype._getLocalAxes = function() {
89842            // calculate camera local Z vector
89843            var z0 = this.eyeX - this.centerX;
89844            var z1 = this.eyeY - this.centerY;
89845            var z2 = this.eyeZ - this.centerZ;
89846
89847            // normalize camera local Z vector
89848            var eyeDist = Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
89849            if (eyeDist !== 0) {
89850              z0 /= eyeDist;
89851              z1 /= eyeDist;
89852              z2 /= eyeDist;
89853            }
89854
89855            // calculate camera Y vector
89856            var y0 = this.upX;
89857            var y1 = this.upY;
89858            var y2 = this.upZ;
89859
89860            // compute camera local X vector as up vector (local Y) cross local Z
89861            var x0 = y1 * z2 - y2 * z1;
89862            var x1 = -y0 * z2 + y2 * z0;
89863            var x2 = y0 * z1 - y1 * z0;
89864
89865            // recompute y = z cross x
89866            y0 = z1 * x2 - z2 * x1;
89867            y1 = -z0 * x2 + z2 * x0;
89868            y2 = z0 * x1 - z1 * x0;
89869
89870            // cross product gives area of parallelogram, which is < 1.0 for
89871            // non-perpendicular unit-length vectors; so normalize x, y here:
89872            var xmag = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
89873            if (xmag !== 0) {
89874              x0 /= xmag;
89875              x1 /= xmag;
89876              x2 /= xmag;
89877            }
89878
89879            var ymag = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
89880            if (ymag !== 0) {
89881              y0 /= ymag;
89882              y1 /= ymag;
89883              y2 /= ymag;
89884            }
89885
89886            return {
89887              x: [x0, x1, x2],
89888              y: [y0, y1, y2],
89889              z: [z0, z1, z2]
89890            };
89891          };
89892
89893          /**
89894           * Orbits the camera about center point. For use with orbitControl().
89895           * @method _orbit
89896           * @private
89897           * @param {Number} dTheta change in spherical coordinate theta
89898           * @param {Number} dPhi change in spherical coordinate phi
89899           * @param {Number} dRadius change in radius
89900           */
89901          _main.default.Camera.prototype._orbit = function(dTheta, dPhi, dRadius) {
89902            var diffX = this.eyeX - this.centerX;
89903            var diffY = this.eyeY - this.centerY;
89904            var diffZ = this.eyeZ - this.centerZ;
89905
89906            // get spherical coorinates for current camera position about origin
89907            var camRadius = Math.sqrt(diffX * diffX + diffY * diffY + diffZ * diffZ);
89908            // from https://github.com/mrdoob/three.js/blob/dev/src/math/Spherical.js#L72-L73
89909            var camTheta = Math.atan2(diffX, diffZ); // equatorial angle
89910            var camPhi = Math.acos(Math.max(-1, Math.min(1, diffY / camRadius))); // polar angle
89911
89912            // add change
89913            camTheta += dTheta;
89914            camPhi += dPhi;
89915            camRadius += dRadius;
89916
89917            // prevent zooming through the center:
89918            if (camRadius < 0) {
89919              camRadius = 0.1;
89920            }
89921
89922            // prevent rotation over the zenith / under bottom
89923            if (camPhi > Math.PI) {
89924              camPhi = Math.PI;
89925            } else if (camPhi <= 0) {
89926              camPhi = 0.001;
89927            }
89928
89929            // from https://github.com/mrdoob/three.js/blob/dev/src/math/Vector3.js#L628-L632
89930            var _x = Math.sin(camPhi) * camRadius * Math.sin(camTheta);
89931            var _y = Math.cos(camPhi) * camRadius;
89932            var _z = Math.sin(camPhi) * camRadius * Math.cos(camTheta);
89933
89934            this.camera(
89935              _x + this.centerX,
89936              _y + this.centerY,
89937              _z + this.centerZ,
89938              this.centerX,
89939              this.centerY,
89940              this.centerZ,
89941              0,
89942              1,
89943              0
89944            );
89945          };
89946
89947          /**
89948           * Returns true if camera is currently attached to renderer.
89949           * @method _isActive
89950           * @private
89951           */
89952          _main.default.Camera.prototype._isActive = function() {
89953            return this === this._renderer._curCamera;
89954          };
89955
89956          /**
89957           * Sets rendererGL's current camera to a p5.Camera object.  Allows switching
89958           * between multiple cameras.
89959           * @method setCamera
89960           * @param  {p5.Camera} cam  p5.Camera object
89961           * @for p5
89962           * @example
89963           * <div>
89964           * <code>
89965           * let cam1, cam2;
89966           * let currentCamera;
89967           *
89968           * function setup() {
89969           *   createCanvas(100, 100, WEBGL);
89970           *   normalMaterial();
89971           *
89972           *   cam1 = createCamera();
89973           *   cam2 = createCamera();
89974           *   cam2.setPosition(30, 0, 50);
89975           *   cam2.lookAt(0, 0, 0);
89976           *   cam2.ortho();
89977           *
89978           *   // set variable for previously active camera:
89979           *   currentCamera = 1;
89980           * }
89981           *
89982           * function draw() {
89983           *   background(200);
89984           *
89985           *   // camera 1:
89986           *   cam1.lookAt(0, 0, 0);
89987           *   cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);
89988           *
89989           *   // every 100 frames, switch between the two cameras
89990           *   if (frameCount % 100 === 0) {
89991           *     if (currentCamera === 1) {
89992           *       setCamera(cam1);
89993           *       currentCamera = 0;
89994           *     } else {
89995           *       setCamera(cam2);
89996           *       currentCamera = 1;
89997           *     }
89998           *   }
89999           *
90000           *   drawBoxes();
90001           * }
90002           *
90003           * function drawBoxes() {
90004           *   rotateX(frameCount * 0.01);
90005           *   translate(-100, 0, 0);
90006           *   box(20);
90007           *   translate(35, 0, 0);
90008           *   box(20);
90009           *   translate(35, 0, 0);
90010           *   box(20);
90011           *   translate(35, 0, 0);
90012           *   box(20);
90013           *   translate(35, 0, 0);
90014           *   box(20);
90015           *   translate(35, 0, 0);
90016           *   box(20);
90017           *   translate(35, 0, 0);
90018           *   box(20);
90019           * }
90020           * </code>
90021           * </div>
90022           *
90023           * @alt
90024           * Canvas switches between two camera views, each showing a series of spinning
90025           * 3D boxes.
90026           */
90027          _main.default.prototype.setCamera = function(cam) {
90028            this._renderer._curCamera = cam;
90029
90030            // set the projection matrix (which is not normally updated each frame)
90031            this._renderer.uPMatrix.set(
90032              cam.projMatrix.mat4[0],
90033              cam.projMatrix.mat4[1],
90034              cam.projMatrix.mat4[2],
90035              cam.projMatrix.mat4[3],
90036              cam.projMatrix.mat4[4],
90037              cam.projMatrix.mat4[5],
90038              cam.projMatrix.mat4[6],
90039              cam.projMatrix.mat4[7],
90040              cam.projMatrix.mat4[8],
90041              cam.projMatrix.mat4[9],
90042              cam.projMatrix.mat4[10],
90043              cam.projMatrix.mat4[11],
90044              cam.projMatrix.mat4[12],
90045              cam.projMatrix.mat4[13],
90046              cam.projMatrix.mat4[14],
90047              cam.projMatrix.mat4[15]
90048            );
90049          };
90050          var _default = _main.default.Camera;
90051          exports.default = _default;
90052        },
90053        { '../core/main': 59 }
90054      ],
90055      108: [
90056        function(_dereq_, module, exports) {
90057          'use strict';
90058          Object.defineProperty(exports, '__esModule', { value: true });
90059          exports.default = void 0;
90060
90061          var _main = _interopRequireDefault(_dereq_('../core/main'));
90062          function _interopRequireDefault(obj) {
90063            return obj && obj.__esModule ? obj : { default: obj };
90064          } /** //some of the functions are adjusted from Three.js(http://threejs.org)
90065           * @module Lights, Camera
90066           * @submodule Material
90067           * @for p5
90068           * @requires core
90069           * @requires p5.Geometry
90070           */
90071          /**
90072           * p5 Geometry class
90073           * @class p5.Geometry
90074           * @constructor
90075           * @param  {Integer} [detailX] number of vertices on horizontal surface
90076           * @param  {Integer} [detailY] number of vertices on horizontal surface
90077           * @param {function} [callback] function to call upon object instantiation.
90078           */ _main.default.Geometry = function(detailX, detailY, callback) {
90079            //an array containing every vertex
90080            //@type [p5.Vector]
90081            this.vertices = []; //an array containing every vertex for stroke drawing
90082            this.lineVertices = []; //an array 1 normal per lineVertex with
90083            //final position representing which direction to
90084            //displace for strokeWeight
90085            //[[0,0,-1,1], [0,1,0,-1] ...];
90086            this.lineNormals = [];
90087
90088            //an array containing 1 normal per vertex
90089            //@type [p5.Vector]
90090            //[p5.Vector, p5.Vector, p5.Vector,p5.Vector, p5.Vector, p5.Vector,...]
90091            this.vertexNormals = [];
90092            //an array containing each three vertex indices that form a face
90093            //[[0, 1, 2], [2, 1, 3], ...]
90094            this.faces = [];
90095            //a 2D array containing uvs for every vertex
90096            //[[0.0,0.0],[1.0,0.0], ...]
90097            this.uvs = [];
90098            // a 2D array containing edge connectivity pattern for create line vertices
90099            //based on faces for most objects;
90100            this.edges = [];
90101            this.vertexColors = [];
90102            this.detailX = detailX !== undefined ? detailX : 1;
90103            this.detailY = detailY !== undefined ? detailY : 1;
90104            this.dirtyFlags = {};
90105
90106            if (callback instanceof Function) {
90107              callback.call(this);
90108            }
90109            return this; // TODO: is this a constructor?
90110          };
90111
90112          _main.default.Geometry.prototype.reset = function() {
90113            this.lineVertices.length = 0;
90114            this.lineNormals.length = 0;
90115
90116            this.vertices.length = 0;
90117            this.edges.length = 0;
90118            this.vertexColors.length = 0;
90119            this.vertexNormals.length = 0;
90120            this.uvs.length = 0;
90121
90122            this.dirtyFlags = {};
90123          };
90124
90125          /**
90126           * computes faces for geometry objects based on the vertices.
90127           * @method computeFaces
90128           * @chainable
90129           */
90130          _main.default.Geometry.prototype.computeFaces = function() {
90131            this.faces.length = 0;
90132            var sliceCount = this.detailX + 1;
90133            var a, b, c, d;
90134            for (var i = 0; i < this.detailY; i++) {
90135              for (var j = 0; j < this.detailX; j++) {
90136                a = i * sliceCount + j; // + offset;
90137                b = i * sliceCount + j + 1; // + offset;
90138                c = (i + 1) * sliceCount + j + 1; // + offset;
90139                d = (i + 1) * sliceCount + j; // + offset;
90140                this.faces.push([a, b, d]);
90141                this.faces.push([d, b, c]);
90142              }
90143            }
90144            return this;
90145          };
90146
90147          _main.default.Geometry.prototype._getFaceNormal = function(faceId) {
90148            //This assumes that vA->vB->vC is a counter-clockwise ordering
90149            var face = this.faces[faceId];
90150            var vA = this.vertices[face[0]];
90151            var vB = this.vertices[face[1]];
90152            var vC = this.vertices[face[2]];
90153            var ab = _main.default.Vector.sub(vB, vA);
90154            var ac = _main.default.Vector.sub(vC, vA);
90155            var n = _main.default.Vector.cross(ab, ac);
90156            var ln = _main.default.Vector.mag(n);
90157            var sinAlpha =
90158              ln / (_main.default.Vector.mag(ab) * _main.default.Vector.mag(ac));
90159            if (sinAlpha === 0 || isNaN(sinAlpha)) {
90160              console.warn(
90161                'p5.Geometry.prototype._getFaceNormal:',
90162                'face has colinear sides or a repeated vertex'
90163              );
90164
90165              return n;
90166            }
90167            if (sinAlpha > 1) sinAlpha = 1; // handle float rounding error
90168            return n.mult(Math.asin(sinAlpha) / ln);
90169          };
90170          /**
90171           * computes smooth normals per vertex as an average of each
90172           * face.
90173           * @method computeNormals
90174           * @chainable
90175           */
90176          _main.default.Geometry.prototype.computeNormals = function() {
90177            var vertexNormals = this.vertexNormals;
90178            var vertices = this.vertices;
90179            var faces = this.faces;
90180            var iv;
90181
90182            // initialize the vertexNormals array with empty vectors
90183            vertexNormals.length = 0;
90184            for (iv = 0; iv < vertices.length; ++iv) {
90185              vertexNormals.push(new _main.default.Vector());
90186            }
90187
90188            // loop through all the faces adding its normal to the normal
90189            // of each of its vertices
90190            for (var f = 0; f < faces.length; ++f) {
90191              var face = faces[f];
90192              var faceNormal = this._getFaceNormal(f);
90193
90194              // all three vertices get the normal added
90195              for (var fv = 0; fv < 3; ++fv) {
90196                var vertexIndex = face[fv];
90197                vertexNormals[vertexIndex].add(faceNormal);
90198              }
90199            }
90200
90201            // normalize the normals
90202            for (iv = 0; iv < vertices.length; ++iv) {
90203              vertexNormals[iv].normalize();
90204            }
90205
90206            return this;
90207          };
90208
90209          /**
90210           * Averages the vertex normals. Used in curved
90211           * surfaces
90212           * @method averageNormals
90213           * @chainable
90214           */
90215          _main.default.Geometry.prototype.averageNormals = function() {
90216            for (var i = 0; i <= this.detailY; i++) {
90217              var offset = this.detailX + 1;
90218              var temp = _main.default.Vector.add(
90219                this.vertexNormals[i * offset],
90220                this.vertexNormals[i * offset + this.detailX]
90221              );
90222
90223              temp = _main.default.Vector.div(temp, 2);
90224              this.vertexNormals[i * offset] = temp;
90225              this.vertexNormals[i * offset + this.detailX] = temp;
90226            }
90227            return this;
90228          };
90229
90230          /**
90231           * Averages pole normals.  Used in spherical primitives
90232           * @method averagePoleNormals
90233           * @chainable
90234           */
90235          _main.default.Geometry.prototype.averagePoleNormals = function() {
90236            //average the north pole
90237            var sum = new _main.default.Vector(0, 0, 0);
90238            for (var i = 0; i < this.detailX; i++) {
90239              sum.add(this.vertexNormals[i]);
90240            }
90241            sum = _main.default.Vector.div(sum, this.detailX);
90242
90243            for (var _i = 0; _i < this.detailX; _i++) {
90244              this.vertexNormals[_i] = sum;
90245            }
90246
90247            //average the south pole
90248            sum = new _main.default.Vector(0, 0, 0);
90249            for (
90250              var _i2 = this.vertices.length - 1;
90251              _i2 > this.vertices.length - 1 - this.detailX;
90252              _i2--
90253            ) {
90254              sum.add(this.vertexNormals[_i2]);
90255            }
90256            sum = _main.default.Vector.div(sum, this.detailX);
90257
90258            for (
90259              var _i3 = this.vertices.length - 1;
90260              _i3 > this.vertices.length - 1 - this.detailX;
90261              _i3--
90262            ) {
90263              this.vertexNormals[_i3] = sum;
90264            }
90265            return this;
90266          };
90267
90268          /**
90269           * Create a 2D array for establishing stroke connections
90270           * @private
90271           * @chainable
90272           */
90273          _main.default.Geometry.prototype._makeTriangleEdges = function() {
90274            this.edges.length = 0;
90275            if (Array.isArray(this.strokeIndices)) {
90276              for (var i = 0, max = this.strokeIndices.length; i < max; i++) {
90277                this.edges.push(this.strokeIndices[i]);
90278              }
90279            } else {
90280              for (var j = 0; j < this.faces.length; j++) {
90281                this.edges.push([this.faces[j][0], this.faces[j][1]]);
90282                this.edges.push([this.faces[j][1], this.faces[j][2]]);
90283                this.edges.push([this.faces[j][2], this.faces[j][0]]);
90284              }
90285            }
90286            return this;
90287          };
90288
90289          /**
90290           * Create 4 vertices for each stroke line, two at the beginning position
90291           * and two at the end position. These vertices are displaced relative to
90292           * that line's normal on the GPU
90293           * @private
90294           * @chainable
90295           */
90296          _main.default.Geometry.prototype._edgesToVertices = function() {
90297            this.lineVertices.length = 0;
90298            this.lineNormals.length = 0;
90299
90300            for (var i = 0; i < this.edges.length; i++) {
90301              var begin = this.vertices[this.edges[i][0]];
90302              var end = this.vertices[this.edges[i][1]];
90303              var dir = end
90304                .copy()
90305                .sub(begin)
90306                .normalize();
90307              var a = begin.array();
90308              var b = begin.array();
90309              var c = end.array();
90310              var d = end.array();
90311              var dirAdd = dir.array();
90312              var dirSub = dir.array();
90313              // below is used to displace the pair of vertices at beginning and end
90314              // in opposite directions
90315              dirAdd.push(1);
90316              dirSub.push(-1);
90317              this.lineNormals.push(dirAdd, dirSub, dirAdd, dirAdd, dirSub, dirSub);
90318              this.lineVertices.push(a, b, c, c, b, d);
90319            }
90320            return this;
90321          };
90322
90323          /**
90324           * Modifies all vertices to be centered within the range -100 to 100.
90325           * @method normalize
90326           * @chainable
90327           */
90328          _main.default.Geometry.prototype.normalize = function() {
90329            if (this.vertices.length > 0) {
90330              // Find the corners of our bounding box
90331              var maxPosition = this.vertices[0].copy();
90332              var minPosition = this.vertices[0].copy();
90333
90334              for (var i = 0; i < this.vertices.length; i++) {
90335                maxPosition.x = Math.max(maxPosition.x, this.vertices[i].x);
90336                minPosition.x = Math.min(minPosition.x, this.vertices[i].x);
90337                maxPosition.y = Math.max(maxPosition.y, this.vertices[i].y);
90338                minPosition.y = Math.min(minPosition.y, this.vertices[i].y);
90339                maxPosition.z = Math.max(maxPosition.z, this.vertices[i].z);
90340                minPosition.z = Math.min(minPosition.z, this.vertices[i].z);
90341              }
90342
90343              var center = _main.default.Vector.lerp(maxPosition, minPosition, 0.5);
90344              var dist = _main.default.Vector.sub(maxPosition, minPosition);
90345              var longestDist = Math.max(Math.max(dist.x, dist.y), dist.z);
90346              var scale = 200 / longestDist;
90347
90348              for (var _i4 = 0; _i4 < this.vertices.length; _i4++) {
90349                this.vertices[_i4].sub(center);
90350                this.vertices[_i4].mult(scale);
90351              }
90352            }
90353            return this;
90354          };
90355          var _default = _main.default.Geometry;
90356          exports.default = _default;
90357        },
90358        { '../core/main': 59 }
90359      ],
90360      109: [
90361        function(_dereq_, module, exports) {
90362          'use strict';
90363          Object.defineProperty(exports, '__esModule', { value: true });
90364          exports.default = void 0;
90365
90366          var _main = _interopRequireDefault(_dereq_('../core/main'));
90367          function _interopRequireDefault(obj) {
90368            return obj && obj.__esModule ? obj : { default: obj };
90369          }
90370          /**
90371           * @requires constants
90372           * @todo see methods below needing further implementation.
90373           * future consideration: implement SIMD optimizations
90374           * when browser compatibility becomes available
90375           * https://developer.mozilla.org/en-US/docs/Web/JavaScript/
90376           *   Reference/Global_Objects/SIMD
90377           */ var GLMAT_ARRAY_TYPE = Array;
90378          var isMatrixArray = function isMatrixArray(x) {
90379            return x instanceof Array;
90380          };
90381          if (typeof Float32Array !== 'undefined') {
90382            GLMAT_ARRAY_TYPE = Float32Array;
90383            isMatrixArray = function isMatrixArray(x) {
90384              return x instanceof Array || x instanceof Float32Array;
90385            };
90386          }
90387
90388          /**
90389           * A class to describe a 4x4 matrix
90390           * for model and view matrix manipulation in the p5js webgl renderer.
90391           * @class p5.Matrix
90392           * @private
90393           * @constructor
90394           * @param {Array} [mat4] array literal of our 4x4 matrix
90395           */
90396          _main.default.Matrix = function() {
90397            var args = new Array(arguments.length);
90398            for (var i = 0; i < args.length; ++i) {
90399              args[i] = arguments[i];
90400            }
90401
90402            // This is default behavior when object
90403            // instantiated using createMatrix()
90404            // @todo implement createMatrix() in core/math.js
90405            if (args.length && args[args.length - 1] instanceof _main.default) {
90406              this.p5 = args[args.length - 1];
90407            }
90408
90409            if (args[0] === 'mat3') {
90410              this.mat3 = Array.isArray(args[1])
90411                ? args[1]
90412                : new GLMAT_ARRAY_TYPE([1, 0, 0, 0, 1, 0, 0, 0, 1]);
90413            } else {
90414              this.mat4 = Array.isArray(args[0])
90415                ? args[0]
90416                : new GLMAT_ARRAY_TYPE([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
90417            }
90418            return this;
90419          };
90420
90421          /**
90422           * Sets the x, y, and z component of the vector using two or three separate
90423           * variables, the data from a p5.Matrix, or the values from a float array.
90424           *
90425           * @method set
90426           * @param {p5.Matrix|Float32Array|Number[]} [inMatrix] the input p5.Matrix or
90427           *                                     an Array of length 16
90428           * @chainable
90429           */
90430          /**
90431           * @method set
90432           * @param {Number[]} elements 16 numbers passed by value to avoid
90433           *                                     array copying.
90434           * @chainable
90435           */
90436          _main.default.Matrix.prototype.set = function(inMatrix) {
90437            if (inMatrix instanceof _main.default.Matrix) {
90438              this.mat4 = inMatrix.mat4;
90439              return this;
90440            } else if (isMatrixArray(inMatrix)) {
90441              this.mat4 = inMatrix;
90442              return this;
90443            } else if (arguments.length === 16) {
90444              this.mat4[0] = arguments[0];
90445              this.mat4[1] = arguments[1];
90446              this.mat4[2] = arguments[2];
90447              this.mat4[3] = arguments[3];
90448              this.mat4[4] = arguments[4];
90449              this.mat4[5] = arguments[5];
90450              this.mat4[6] = arguments[6];
90451              this.mat4[7] = arguments[7];
90452              this.mat4[8] = arguments[8];
90453              this.mat4[9] = arguments[9];
90454              this.mat4[10] = arguments[10];
90455              this.mat4[11] = arguments[11];
90456              this.mat4[12] = arguments[12];
90457              this.mat4[13] = arguments[13];
90458              this.mat4[14] = arguments[14];
90459              this.mat4[15] = arguments[15];
90460            }
90461            return this;
90462          };
90463
90464          /**
90465           * Gets a copy of the vector, returns a p5.Matrix object.
90466           *
90467           * @method get
90468           * @return {p5.Matrix} the copy of the p5.Matrix object
90469           */
90470          _main.default.Matrix.prototype.get = function() {
90471            return new _main.default.Matrix(this.mat4, this.p5);
90472          };
90473
90474          /**
90475           * return a copy of a matrix
90476           * @method copy
90477           * @return {p5.Matrix}   the result matrix
90478           */
90479          _main.default.Matrix.prototype.copy = function() {
90480            var copied = new _main.default.Matrix(this.p5);
90481            copied.mat4[0] = this.mat4[0];
90482            copied.mat4[1] = this.mat4[1];
90483            copied.mat4[2] = this.mat4[2];
90484            copied.mat4[3] = this.mat4[3];
90485            copied.mat4[4] = this.mat4[4];
90486            copied.mat4[5] = this.mat4[5];
90487            copied.mat4[6] = this.mat4[6];
90488            copied.mat4[7] = this.mat4[7];
90489            copied.mat4[8] = this.mat4[8];
90490            copied.mat4[9] = this.mat4[9];
90491            copied.mat4[10] = this.mat4[10];
90492            copied.mat4[11] = this.mat4[11];
90493            copied.mat4[12] = this.mat4[12];
90494            copied.mat4[13] = this.mat4[13];
90495            copied.mat4[14] = this.mat4[14];
90496            copied.mat4[15] = this.mat4[15];
90497            return copied;
90498          };
90499
90500          /**
90501           * return an identity matrix
90502           * @method identity
90503           * @return {p5.Matrix}   the result matrix
90504           */
90505          _main.default.Matrix.identity = function(pInst) {
90506            return new _main.default.Matrix(pInst);
90507          };
90508
90509          /**
90510           * transpose according to a given matrix
90511           * @method transpose
90512           * @param  {p5.Matrix|Float32Array|Number[]} a  the matrix to be
90513           *                                               based on to transpose
90514           * @chainable
90515           */
90516          _main.default.Matrix.prototype.transpose = function(a) {
90517            var a01, a02, a03, a12, a13, a23;
90518            if (a instanceof _main.default.Matrix) {
90519              a01 = a.mat4[1];
90520              a02 = a.mat4[2];
90521              a03 = a.mat4[3];
90522              a12 = a.mat4[6];
90523              a13 = a.mat4[7];
90524              a23 = a.mat4[11];
90525
90526              this.mat4[0] = a.mat4[0];
90527              this.mat4[1] = a.mat4[4];
90528              this.mat4[2] = a.mat4[8];
90529              this.mat4[3] = a.mat4[12];
90530              this.mat4[4] = a01;
90531              this.mat4[5] = a.mat4[5];
90532              this.mat4[6] = a.mat4[9];
90533              this.mat4[7] = a.mat4[13];
90534              this.mat4[8] = a02;
90535              this.mat4[9] = a12;
90536              this.mat4[10] = a.mat4[10];
90537              this.mat4[11] = a.mat4[14];
90538              this.mat4[12] = a03;
90539              this.mat4[13] = a13;
90540              this.mat4[14] = a23;
90541              this.mat4[15] = a.mat4[15];
90542            } else if (isMatrixArray(a)) {
90543              a01 = a[1];
90544              a02 = a[2];
90545              a03 = a[3];
90546              a12 = a[6];
90547              a13 = a[7];
90548              a23 = a[11];
90549
90550              this.mat4[0] = a[0];
90551              this.mat4[1] = a[4];
90552              this.mat4[2] = a[8];
90553              this.mat4[3] = a[12];
90554              this.mat4[4] = a01;
90555              this.mat4[5] = a[5];
90556              this.mat4[6] = a[9];
90557              this.mat4[7] = a[13];
90558              this.mat4[8] = a02;
90559              this.mat4[9] = a12;
90560              this.mat4[10] = a[10];
90561              this.mat4[11] = a[14];
90562              this.mat4[12] = a03;
90563              this.mat4[13] = a13;
90564              this.mat4[14] = a23;
90565              this.mat4[15] = a[15];
90566            }
90567            return this;
90568          };
90569
90570          /**
90571           * invert  matrix according to a give matrix
90572           * @method invert
90573           * @param  {p5.Matrix|Float32Array|Number[]} a   the matrix to be
90574           *                                                based on to invert
90575           * @chainable
90576           */
90577          _main.default.Matrix.prototype.invert = function(a) {
90578            var a00, a01, a02, a03, a10, a11, a12, a13;
90579            var a20, a21, a22, a23, a30, a31, a32, a33;
90580            if (a instanceof _main.default.Matrix) {
90581              a00 = a.mat4[0];
90582              a01 = a.mat4[1];
90583              a02 = a.mat4[2];
90584              a03 = a.mat4[3];
90585              a10 = a.mat4[4];
90586              a11 = a.mat4[5];
90587              a12 = a.mat4[6];
90588              a13 = a.mat4[7];
90589              a20 = a.mat4[8];
90590              a21 = a.mat4[9];
90591              a22 = a.mat4[10];
90592              a23 = a.mat4[11];
90593              a30 = a.mat4[12];
90594              a31 = a.mat4[13];
90595              a32 = a.mat4[14];
90596              a33 = a.mat4[15];
90597            } else if (isMatrixArray(a)) {
90598              a00 = a[0];
90599              a01 = a[1];
90600              a02 = a[2];
90601              a03 = a[3];
90602              a10 = a[4];
90603              a11 = a[5];
90604              a12 = a[6];
90605              a13 = a[7];
90606              a20 = a[8];
90607              a21 = a[9];
90608              a22 = a[10];
90609              a23 = a[11];
90610              a30 = a[12];
90611              a31 = a[13];
90612              a32 = a[14];
90613              a33 = a[15];
90614            }
90615            var b00 = a00 * a11 - a01 * a10;
90616            var b01 = a00 * a12 - a02 * a10;
90617            var b02 = a00 * a13 - a03 * a10;
90618            var b03 = a01 * a12 - a02 * a11;
90619            var b04 = a01 * a13 - a03 * a11;
90620            var b05 = a02 * a13 - a03 * a12;
90621            var b06 = a20 * a31 - a21 * a30;
90622            var b07 = a20 * a32 - a22 * a30;
90623            var b08 = a20 * a33 - a23 * a30;
90624            var b09 = a21 * a32 - a22 * a31;
90625            var b10 = a21 * a33 - a23 * a31;
90626            var b11 = a22 * a33 - a23 * a32;
90627
90628            // Calculate the determinant
90629            var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
90630
90631            if (!det) {
90632              return null;
90633            }
90634            det = 1.0 / det;
90635
90636            this.mat4[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
90637            this.mat4[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
90638            this.mat4[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
90639            this.mat4[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
90640            this.mat4[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
90641            this.mat4[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
90642            this.mat4[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
90643            this.mat4[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
90644            this.mat4[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
90645            this.mat4[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
90646            this.mat4[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
90647            this.mat4[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
90648            this.mat4[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
90649            this.mat4[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
90650            this.mat4[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
90651            this.mat4[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
90652
90653            return this;
90654          };
90655
90656          /**
90657           * Inverts a 3x3 matrix
90658           * @method invert3x3
90659           * @chainable
90660           */
90661          _main.default.Matrix.prototype.invert3x3 = function() {
90662            var a00 = this.mat3[0];
90663            var a01 = this.mat3[1];
90664            var a02 = this.mat3[2];
90665            var a10 = this.mat3[3];
90666            var a11 = this.mat3[4];
90667            var a12 = this.mat3[5];
90668            var a20 = this.mat3[6];
90669            var a21 = this.mat3[7];
90670            var a22 = this.mat3[8];
90671            var b01 = a22 * a11 - a12 * a21;
90672            var b11 = -a22 * a10 + a12 * a20;
90673            var b21 = a21 * a10 - a11 * a20;
90674
90675            // Calculate the determinant
90676            var det = a00 * b01 + a01 * b11 + a02 * b21;
90677            if (!det) {
90678              return null;
90679            }
90680            det = 1.0 / det;
90681            this.mat3[0] = b01 * det;
90682            this.mat3[1] = (-a22 * a01 + a02 * a21) * det;
90683            this.mat3[2] = (a12 * a01 - a02 * a11) * det;
90684            this.mat3[3] = b11 * det;
90685            this.mat3[4] = (a22 * a00 - a02 * a20) * det;
90686            this.mat3[5] = (-a12 * a00 + a02 * a10) * det;
90687            this.mat3[6] = b21 * det;
90688            this.mat3[7] = (-a21 * a00 + a01 * a20) * det;
90689            this.mat3[8] = (a11 * a00 - a01 * a10) * det;
90690            return this;
90691          };
90692
90693          /**
90694           * transposes a 3x3 p5.Matrix by a mat3
90695           * @method transpose3x3
90696           * @param  {Number[]} mat3 1-dimensional array
90697           * @chainable
90698           */
90699          _main.default.Matrix.prototype.transpose3x3 = function(mat3) {
90700            var a01 = mat3[1],
90701              a02 = mat3[2],
90702              a12 = mat3[5];
90703            this.mat3[1] = mat3[3];
90704            this.mat3[2] = mat3[6];
90705            this.mat3[3] = a01;
90706            this.mat3[5] = mat3[7];
90707            this.mat3[6] = a02;
90708            this.mat3[7] = a12;
90709            return this;
90710          };
90711
90712          /**
90713           * converts a 4x4 matrix to its 3x3 inverse transform
90714           * commonly used in MVMatrix to NMatrix conversions.
90715           * @method invertTranspose
90716           * @param  {p5.Matrix} mat4 the matrix to be based on to invert
90717           * @chainable
90718           * @todo  finish implementation
90719           */
90720          _main.default.Matrix.prototype.inverseTranspose = function(matrix) {
90721            if (this.mat3 === undefined) {
90722              console.error('sorry, this function only works with mat3');
90723            } else {
90724              //convert mat4 -> mat3
90725              this.mat3[0] = matrix.mat4[0];
90726              this.mat3[1] = matrix.mat4[1];
90727              this.mat3[2] = matrix.mat4[2];
90728              this.mat3[3] = matrix.mat4[4];
90729              this.mat3[4] = matrix.mat4[5];
90730              this.mat3[5] = matrix.mat4[6];
90731              this.mat3[6] = matrix.mat4[8];
90732              this.mat3[7] = matrix.mat4[9];
90733              this.mat3[8] = matrix.mat4[10];
90734            }
90735
90736            var inverse = this.invert3x3();
90737            // check inverse succeeded
90738            if (inverse) {
90739              inverse.transpose3x3(this.mat3);
90740            } else {
90741              // in case of singularity, just zero the matrix
90742              for (var i = 0; i < 9; i++) {
90743                this.mat3[i] = 0;
90744              }
90745            }
90746            return this;
90747          };
90748
90749          /**
90750           * inspired by Toji's mat4 determinant
90751           * @method determinant
90752           * @return {Number} Determinant of our 4x4 matrix
90753           */
90754          _main.default.Matrix.prototype.determinant = function() {
90755            var d00 = this.mat4[0] * this.mat4[5] - this.mat4[1] * this.mat4[4],
90756              d01 = this.mat4[0] * this.mat4[6] - this.mat4[2] * this.mat4[4],
90757              d02 = this.mat4[0] * this.mat4[7] - this.mat4[3] * this.mat4[4],
90758              d03 = this.mat4[1] * this.mat4[6] - this.mat4[2] * this.mat4[5],
90759              d04 = this.mat4[1] * this.mat4[7] - this.mat4[3] * this.mat4[5],
90760              d05 = this.mat4[2] * this.mat4[7] - this.mat4[3] * this.mat4[6],
90761              d06 = this.mat4[8] * this.mat4[13] - this.mat4[9] * this.mat4[12],
90762              d07 = this.mat4[8] * this.mat4[14] - this.mat4[10] * this.mat4[12],
90763              d08 = this.mat4[8] * this.mat4[15] - this.mat4[11] * this.mat4[12],
90764              d09 = this.mat4[9] * this.mat4[14] - this.mat4[10] * this.mat4[13],
90765              d10 = this.mat4[9] * this.mat4[15] - this.mat4[11] * this.mat4[13],
90766              d11 = this.mat4[10] * this.mat4[15] - this.mat4[11] * this.mat4[14];
90767
90768            // Calculate the determinant
90769            return d00 * d11 - d01 * d10 + d02 * d09 + d03 * d08 - d04 * d07 + d05 * d06;
90770          };
90771
90772          /**
90773           * multiply two mat4s
90774           * @method mult
90775           * @param {p5.Matrix|Float32Array|Number[]} multMatrix The matrix
90776           *                                                we want to multiply by
90777           * @chainable
90778           */
90779          _main.default.Matrix.prototype.mult = function(multMatrix) {
90780            var _src;
90781
90782            if (multMatrix === this || multMatrix === this.mat4) {
90783              _src = this.copy().mat4; // only need to allocate in this rare case
90784            } else if (multMatrix instanceof _main.default.Matrix) {
90785              _src = multMatrix.mat4;
90786            } else if (isMatrixArray(multMatrix)) {
90787              _src = multMatrix;
90788            } else if (arguments.length === 16) {
90789              _src = arguments;
90790            } else {
90791              return; // nothing to do.
90792            }
90793
90794            // each row is used for the multiplier
90795            var b0 = this.mat4[0],
90796              b1 = this.mat4[1],
90797              b2 = this.mat4[2],
90798              b3 = this.mat4[3];
90799            this.mat4[0] = b0 * _src[0] + b1 * _src[4] + b2 * _src[8] + b3 * _src[12];
90800            this.mat4[1] = b0 * _src[1] + b1 * _src[5] + b2 * _src[9] + b3 * _src[13];
90801            this.mat4[2] = b0 * _src[2] + b1 * _src[6] + b2 * _src[10] + b3 * _src[14];
90802            this.mat4[3] = b0 * _src[3] + b1 * _src[7] + b2 * _src[11] + b3 * _src[15];
90803
90804            b0 = this.mat4[4];
90805            b1 = this.mat4[5];
90806            b2 = this.mat4[6];
90807            b3 = this.mat4[7];
90808            this.mat4[4] = b0 * _src[0] + b1 * _src[4] + b2 * _src[8] + b3 * _src[12];
90809            this.mat4[5] = b0 * _src[1] + b1 * _src[5] + b2 * _src[9] + b3 * _src[13];
90810            this.mat4[6] = b0 * _src[2] + b1 * _src[6] + b2 * _src[10] + b3 * _src[14];
90811            this.mat4[7] = b0 * _src[3] + b1 * _src[7] + b2 * _src[11] + b3 * _src[15];
90812
90813            b0 = this.mat4[8];
90814            b1 = this.mat4[9];
90815            b2 = this.mat4[10];
90816            b3 = this.mat4[11];
90817            this.mat4[8] = b0 * _src[0] + b1 * _src[4] + b2 * _src[8] + b3 * _src[12];
90818            this.mat4[9] = b0 * _src[1] + b1 * _src[5] + b2 * _src[9] + b3 * _src[13];
90819            this.mat4[10] = b0 * _src[2] + b1 * _src[6] + b2 * _src[10] + b3 * _src[14];
90820            this.mat4[11] = b0 * _src[3] + b1 * _src[7] + b2 * _src[11] + b3 * _src[15];
90821
90822            b0 = this.mat4[12];
90823            b1 = this.mat4[13];
90824            b2 = this.mat4[14];
90825            b3 = this.mat4[15];
90826            this.mat4[12] = b0 * _src[0] + b1 * _src[4] + b2 * _src[8] + b3 * _src[12];
90827            this.mat4[13] = b0 * _src[1] + b1 * _src[5] + b2 * _src[9] + b3 * _src[13];
90828            this.mat4[14] = b0 * _src[2] + b1 * _src[6] + b2 * _src[10] + b3 * _src[14];
90829            this.mat4[15] = b0 * _src[3] + b1 * _src[7] + b2 * _src[11] + b3 * _src[15];
90830
90831            return this;
90832          };
90833
90834          _main.default.Matrix.prototype.apply = function(multMatrix) {
90835            var _src;
90836
90837            if (multMatrix === this || multMatrix === this.mat4) {
90838              _src = this.copy().mat4; // only need to allocate in this rare case
90839            } else if (multMatrix instanceof _main.default.Matrix) {
90840              _src = multMatrix.mat4;
90841            } else if (isMatrixArray(multMatrix)) {
90842              _src = multMatrix;
90843            } else if (arguments.length === 16) {
90844              _src = arguments;
90845            } else {
90846              return; // nothing to do.
90847            }
90848
90849            var mat4 = this.mat4;
90850
90851            // each row is used for the multiplier
90852            var m0 = mat4[0];
90853            var m4 = mat4[4];
90854            var m8 = mat4[8];
90855            var m12 = mat4[12];
90856            mat4[0] = _src[0] * m0 + _src[1] * m4 + _src[2] * m8 + _src[3] * m12;
90857            mat4[4] = _src[4] * m0 + _src[5] * m4 + _src[6] * m8 + _src[7] * m12;
90858            mat4[8] = _src[8] * m0 + _src[9] * m4 + _src[10] * m8 + _src[11] * m12;
90859            mat4[12] = _src[12] * m0 + _src[13] * m4 + _src[14] * m8 + _src[15] * m12;
90860
90861            var m1 = mat4[1];
90862            var m5 = mat4[5];
90863            var m9 = mat4[9];
90864            var m13 = mat4[13];
90865            mat4[1] = _src[0] * m1 + _src[1] * m5 + _src[2] * m9 + _src[3] * m13;
90866            mat4[5] = _src[4] * m1 + _src[5] * m5 + _src[6] * m9 + _src[7] * m13;
90867            mat4[9] = _src[8] * m1 + _src[9] * m5 + _src[10] * m9 + _src[11] * m13;
90868            mat4[13] = _src[12] * m1 + _src[13] * m5 + _src[14] * m9 + _src[15] * m13;
90869
90870            var m2 = mat4[2];
90871            var m6 = mat4[6];
90872            var m10 = mat4[10];
90873            var m14 = mat4[14];
90874            mat4[2] = _src[0] * m2 + _src[1] * m6 + _src[2] * m10 + _src[3] * m14;
90875            mat4[6] = _src[4] * m2 + _src[5] * m6 + _src[6] * m10 + _src[7] * m14;
90876            mat4[10] = _src[8] * m2 + _src[9] * m6 + _src[10] * m10 + _src[11] * m14;
90877            mat4[14] = _src[12] * m2 + _src[13] * m6 + _src[14] * m10 + _src[15] * m14;
90878
90879            var m3 = mat4[3];
90880            var m7 = mat4[7];
90881            var m11 = mat4[11];
90882            var m15 = mat4[15];
90883            mat4[3] = _src[0] * m3 + _src[1] * m7 + _src[2] * m11 + _src[3] * m15;
90884            mat4[7] = _src[4] * m3 + _src[5] * m7 + _src[6] * m11 + _src[7] * m15;
90885            mat4[11] = _src[8] * m3 + _src[9] * m7 + _src[10] * m11 + _src[11] * m15;
90886            mat4[15] = _src[12] * m3 + _src[13] * m7 + _src[14] * m11 + _src[15] * m15;
90887
90888            return this;
90889          };
90890
90891          /**
90892           * scales a p5.Matrix by scalars or a vector
90893           * @method scale
90894           * @param  {p5.Vector|Float32Array|Number[]} s vector to scale by
90895           * @chainable
90896           */
90897          _main.default.Matrix.prototype.scale = function(x, y, z) {
90898            if (x instanceof _main.default.Vector) {
90899              // x is a vector, extract the components from it.
90900              y = x.y;
90901              z = x.z;
90902              x = x.x; // must be last
90903            } else if (x instanceof Array) {
90904              // x is an array, extract the components from it.
90905              y = x[1];
90906              z = x[2];
90907              x = x[0]; // must be last
90908            }
90909
90910            this.mat4[0] *= x;
90911            this.mat4[1] *= x;
90912            this.mat4[2] *= x;
90913            this.mat4[3] *= x;
90914            this.mat4[4] *= y;
90915            this.mat4[5] *= y;
90916            this.mat4[6] *= y;
90917            this.mat4[7] *= y;
90918            this.mat4[8] *= z;
90919            this.mat4[9] *= z;
90920            this.mat4[10] *= z;
90921            this.mat4[11] *= z;
90922
90923            return this;
90924          };
90925
90926          /**
90927           * rotate our Matrix around an axis by the given angle.
90928           * @method rotate
90929           * @param  {Number} a The angle of rotation in radians
90930           * @param  {p5.Vector|Number[]} axis  the axis(es) to rotate around
90931           * @chainable
90932           * inspired by Toji's gl-matrix lib, mat4 rotation
90933           */
90934          _main.default.Matrix.prototype.rotate = function(a, x, y, z) {
90935            if (x instanceof _main.default.Vector) {
90936              // x is a vector, extract the components from it.
90937              y = x.y;
90938              z = x.z;
90939              x = x.x; //must be last
90940            } else if (x instanceof Array) {
90941              // x is an array, extract the components from it.
90942              y = x[1];
90943              z = x[2];
90944              x = x[0]; //must be last
90945            }
90946
90947            var len = Math.sqrt(x * x + y * y + z * z);
90948            x *= 1 / len;
90949            y *= 1 / len;
90950            z *= 1 / len;
90951
90952            var a00 = this.mat4[0];
90953            var a01 = this.mat4[1];
90954            var a02 = this.mat4[2];
90955            var a03 = this.mat4[3];
90956            var a10 = this.mat4[4];
90957            var a11 = this.mat4[5];
90958            var a12 = this.mat4[6];
90959            var a13 = this.mat4[7];
90960            var a20 = this.mat4[8];
90961            var a21 = this.mat4[9];
90962            var a22 = this.mat4[10];
90963            var a23 = this.mat4[11];
90964
90965            //sin,cos, and tan of respective angle
90966            var sA = Math.sin(a);
90967            var cA = Math.cos(a);
90968            var tA = 1 - cA;
90969            // Construct the elements of the rotation matrix
90970            var b00 = x * x * tA + cA;
90971            var b01 = y * x * tA + z * sA;
90972            var b02 = z * x * tA - y * sA;
90973            var b10 = x * y * tA - z * sA;
90974            var b11 = y * y * tA + cA;
90975            var b12 = z * y * tA + x * sA;
90976            var b20 = x * z * tA + y * sA;
90977            var b21 = y * z * tA - x * sA;
90978            var b22 = z * z * tA + cA;
90979
90980            // rotation-specific matrix multiplication
90981            this.mat4[0] = a00 * b00 + a10 * b01 + a20 * b02;
90982            this.mat4[1] = a01 * b00 + a11 * b01 + a21 * b02;
90983            this.mat4[2] = a02 * b00 + a12 * b01 + a22 * b02;
90984            this.mat4[3] = a03 * b00 + a13 * b01 + a23 * b02;
90985            this.mat4[4] = a00 * b10 + a10 * b11 + a20 * b12;
90986            this.mat4[5] = a01 * b10 + a11 * b11 + a21 * b12;
90987            this.mat4[6] = a02 * b10 + a12 * b11 + a22 * b12;
90988            this.mat4[7] = a03 * b10 + a13 * b11 + a23 * b12;
90989            this.mat4[8] = a00 * b20 + a10 * b21 + a20 * b22;
90990            this.mat4[9] = a01 * b20 + a11 * b21 + a21 * b22;
90991            this.mat4[10] = a02 * b20 + a12 * b21 + a22 * b22;
90992            this.mat4[11] = a03 * b20 + a13 * b21 + a23 * b22;
90993
90994            return this;
90995          };
90996
90997          /**
90998           * @todo  finish implementing this method!
90999           * translates
91000           * @method translate
91001           * @param  {Number[]} v vector to translate by
91002           * @chainable
91003           */
91004          _main.default.Matrix.prototype.translate = function(v) {
91005            var x = v[0],
91006              y = v[1],
91007              z = v[2] || 0;
91008            this.mat4[12] += this.mat4[0] * x + this.mat4[4] * y + this.mat4[8] * z;
91009            this.mat4[13] += this.mat4[1] * x + this.mat4[5] * y + this.mat4[9] * z;
91010            this.mat4[14] += this.mat4[2] * x + this.mat4[6] * y + this.mat4[10] * z;
91011            this.mat4[15] += this.mat4[3] * x + this.mat4[7] * y + this.mat4[11] * z;
91012          };
91013
91014          _main.default.Matrix.prototype.rotateX = function(a) {
91015            this.rotate(a, 1, 0, 0);
91016          };
91017          _main.default.Matrix.prototype.rotateY = function(a) {
91018            this.rotate(a, 0, 1, 0);
91019          };
91020          _main.default.Matrix.prototype.rotateZ = function(a) {
91021            this.rotate(a, 0, 0, 1);
91022          };
91023
91024          /**
91025           * sets the perspective matrix
91026           * @method perspective
91027           * @param  {Number} fovy   [description]
91028           * @param  {Number} aspect [description]
91029           * @param  {Number} near   near clipping plane
91030           * @param  {Number} far    far clipping plane
91031           * @chainable
91032           */
91033          _main.default.Matrix.prototype.perspective = function(fovy, aspect, near, far) {
91034            var f = 1.0 / Math.tan(fovy / 2),
91035              nf = 1 / (near - far);
91036
91037            this.mat4[0] = f / aspect;
91038            this.mat4[1] = 0;
91039            this.mat4[2] = 0;
91040            this.mat4[3] = 0;
91041            this.mat4[4] = 0;
91042            this.mat4[5] = f;
91043            this.mat4[6] = 0;
91044            this.mat4[7] = 0;
91045            this.mat4[8] = 0;
91046            this.mat4[9] = 0;
91047            this.mat4[10] = (far + near) * nf;
91048            this.mat4[11] = -1;
91049            this.mat4[12] = 0;
91050            this.mat4[13] = 0;
91051            this.mat4[14] = 2 * far * near * nf;
91052            this.mat4[15] = 0;
91053
91054            return this;
91055          };
91056
91057          /**
91058           * sets the ortho matrix
91059           * @method ortho
91060           * @param  {Number} left   [description]
91061           * @param  {Number} right  [description]
91062           * @param  {Number} bottom [description]
91063           * @param  {Number} top    [description]
91064           * @param  {Number} near   near clipping plane
91065           * @param  {Number} far    far clipping plane
91066           * @chainable
91067           */
91068          _main.default.Matrix.prototype.ortho = function(
91069            left,
91070            right,
91071            bottom,
91072            top,
91073            near,
91074            far
91075          ) {
91076            var lr = 1 / (left - right),
91077              bt = 1 / (bottom - top),
91078              nf = 1 / (near - far);
91079            this.mat4[0] = -2 * lr;
91080            this.mat4[1] = 0;
91081            this.mat4[2] = 0;
91082            this.mat4[3] = 0;
91083            this.mat4[4] = 0;
91084            this.mat4[5] = -2 * bt;
91085            this.mat4[6] = 0;
91086            this.mat4[7] = 0;
91087            this.mat4[8] = 0;
91088            this.mat4[9] = 0;
91089            this.mat4[10] = 2 * nf;
91090            this.mat4[11] = 0;
91091            this.mat4[12] = (left + right) * lr;
91092            this.mat4[13] = (top + bottom) * bt;
91093            this.mat4[14] = (far + near) * nf;
91094            this.mat4[15] = 1;
91095
91096            return this;
91097          };
91098
91099          /**
91100           * PRIVATE
91101           */
91102          // matrix methods adapted from:
91103          // https://developer.mozilla.org/en-US/docs/Web/WebGL/
91104          // gluPerspective
91105          //
91106          // function _makePerspective(fovy, aspect, znear, zfar){
91107          //    const ymax = znear * Math.tan(fovy * Math.PI / 360.0);
91108          //    const ymin = -ymax;
91109          //    const xmin = ymin * aspect;
91110          //    const xmax = ymax * aspect;
91111          //    return _makeFrustum(xmin, xmax, ymin, ymax, znear, zfar);
91112          //  }
91113
91114          ////
91115          //// glFrustum
91116          ////
91117          //function _makeFrustum(left, right, bottom, top, znear, zfar){
91118          //  const X = 2*znear/(right-left);
91119          //  const Y = 2*znear/(top-bottom);
91120          //  const A = (right+left)/(right-left);
91121          //  const B = (top+bottom)/(top-bottom);
91122          //  const C = -(zfar+znear)/(zfar-znear);
91123          //  const D = -2*zfar*znear/(zfar-znear);
91124          //  const frustrumMatrix =[
91125          //  X, 0, A, 0,
91126          //  0, Y, B, 0,
91127          //  0, 0, C, D,
91128          //  0, 0, -1, 0
91129          //];
91130          //return frustrumMatrix;
91131          // }
91132
91133          // function _setMVPMatrices(){
91134          ////an identity matrix
91135          ////@TODO use the p5.Matrix class to abstract away our MV matrices and
91136          ///other math
91137          //const _mvMatrix =
91138          //[
91139          //  1.0,0.0,0.0,0.0,
91140          //  0.0,1.0,0.0,0.0,
91141          //  0.0,0.0,1.0,0.0,
91142          //  0.0,0.0,0.0,1.0
91143          //];
91144          var _default = _main.default.Matrix;
91145          exports.default = _default;
91146        },
91147        { '../core/main': 59 }
91148      ],
91149      110: [
91150        function(_dereq_, module, exports) {
91151          'use strict';
91152          Object.defineProperty(exports, '__esModule', { value: true });
91153          exports.default = void 0;
91154          var _main = _interopRequireDefault(_dereq_('../core/main'));
91155          function _interopRequireDefault(obj) {
91156            return obj && obj.__esModule ? obj : { default: obj };
91157          }
91158
91159          _main.default.RenderBuffer = function(size, src, dst, attr, renderer, map) {
91160            this.size = size; // the number of FLOATs in each vertex
91161            this.src = src; // the name of the model's source array
91162            this.dst = dst; // the name of the geometry's buffer
91163            this.attr = attr; // the name of the vertex attribute
91164            this._renderer = renderer;
91165            this.map = map; // optional, a transformation function to apply to src
91166          };
91167
91168          /**
91169           * Enables and binds the buffers used by shader when the appropriate data exists in geometry.
91170           * Must always be done prior to drawing geometry in WebGL.
91171           * @param {p5.Geometry} geometry Geometry that is going to be drawn
91172           * @param {p5.Shader} shader Active shader
91173           * @private
91174           */
91175          _main.default.RenderBuffer.prototype._prepareBuffer = function(geometry, shader) {
91176            var attributes = shader.attributes;
91177            var gl = this._renderer.GL;
91178            var model;
91179            if (geometry.model) {
91180              model = geometry.model;
91181            } else {
91182              model = geometry;
91183            }
91184
91185            // loop through each of the buffer definitions
91186            var attr = attributes[this.attr];
91187            if (!attr) {
91188              return;
91189            }
91190
91191            // check if the model has the appropriate source array
91192            var buffer = geometry[this.dst];
91193            var src = model[this.src];
91194            if (src.length > 0) {
91195              // check if we need to create the GL buffer
91196              var createBuffer = !buffer;
91197              if (createBuffer) {
91198                // create and remember the buffer
91199                geometry[this.dst] = buffer = gl.createBuffer();
91200              }
91201              // bind the buffer
91202              gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
91203
91204              // check if we need to fill the buffer with data
91205              if (createBuffer || model.dirtyFlags[this.src] !== false) {
91206                var map = this.map;
91207                // get the values from the model, possibly transformed
91208                var values = map ? map(src) : src;
91209                // fill the buffer with the values
91210                this._renderer._bindBuffer(buffer, gl.ARRAY_BUFFER, values);
91211
91212                // mark the model's source array as clean
91213                model.dirtyFlags[this.src] = false;
91214              }
91215              // enable the attribute
91216              shader.enableAttrib(attr, this.size);
91217            }
91218          };
91219          var _default = _main.default.RenderBuffer;
91220          exports.default = _default;
91221        },
91222        { '../core/main': 59 }
91223      ],
91224      111: [
91225        function(_dereq_, module, exports) {
91226          'use strict';
91227          function _typeof(obj) {
91228            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
91229              _typeof = function _typeof(obj) {
91230                return typeof obj;
91231              };
91232            } else {
91233              _typeof = function _typeof(obj) {
91234                return obj &&
91235                  typeof Symbol === 'function' &&
91236                  obj.constructor === Symbol &&
91237                  obj !== Symbol.prototype
91238                  ? 'symbol'
91239                  : typeof obj;
91240              };
91241            }
91242            return _typeof(obj);
91243          }
91244          Object.defineProperty(exports, '__esModule', { value: true });
91245          exports.default = void 0;
91246
91247          var _main = _interopRequireDefault(_dereq_('../core/main'));
91248          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
91249          _dereq_('./p5.RenderBuffer');
91250          function _getRequireWildcardCache() {
91251            if (typeof WeakMap !== 'function') return null;
91252            var cache = new WeakMap();
91253            _getRequireWildcardCache = function _getRequireWildcardCache() {
91254              return cache;
91255            };
91256            return cache;
91257          }
91258          function _interopRequireWildcard(obj) {
91259            if (obj && obj.__esModule) {
91260              return obj;
91261            }
91262            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
91263              return { default: obj };
91264            }
91265            var cache = _getRequireWildcardCache();
91266            if (cache && cache.has(obj)) {
91267              return cache.get(obj);
91268            }
91269            var newObj = {};
91270            var hasPropertyDescriptor =
91271              Object.defineProperty && Object.getOwnPropertyDescriptor;
91272            for (var key in obj) {
91273              if (Object.prototype.hasOwnProperty.call(obj, key)) {
91274                var desc = hasPropertyDescriptor
91275                  ? Object.getOwnPropertyDescriptor(obj, key)
91276                  : null;
91277                if (desc && (desc.get || desc.set)) {
91278                  Object.defineProperty(newObj, key, desc);
91279                } else {
91280                  newObj[key] = obj[key];
91281                }
91282              }
91283            }
91284            newObj.default = obj;
91285            if (cache) {
91286              cache.set(obj, newObj);
91287            }
91288            return newObj;
91289          }
91290          function _interopRequireDefault(obj) {
91291            return obj && obj.__esModule ? obj : { default: obj };
91292          }
91293          /**
91294           * Welcome to RendererGL Immediate Mode.
91295           * Immediate mode is used for drawing custom shapes
91296           * from a set of vertices.  Immediate Mode is activated
91297           * when you call <a href="#/p5/beginShape">beginShape()</a> & de-activated when you call <a href="#/p5/endShape">endShape()</a>.
91298           * Immediate mode is a style of programming borrowed
91299           * from OpenGL's (now-deprecated) immediate mode.
91300           * It differs from p5.js' default, Retained Mode, which caches
91301           * geometries and buffers on the CPU to reduce the number of webgl
91302           * draw calls. Retained mode is more efficient & performative,
91303           * however, Immediate Mode is useful for sketching quick
91304           * geometric ideas.
91305           */ /**
91306           * Begin shape drawing.  This is a helpful way of generating
91307           * custom shapes quickly.  However in WEBGL mode, application
91308           * performance will likely drop as a result of too many calls to
91309           * <a href="#/p5/beginShape">beginShape()</a> / <a href="#/p5/endShape">endShape()</a>.  As a high performance alternative,
91310           * please use p5.js geometry primitives.
91311           * @private
91312           * @method beginShape
91313           * @param  {Number} mode webgl primitives mode.  beginShape supports the
91314           *                       following modes:
91315           *                       POINTS,LINES,LINE_STRIP,LINE_LOOP,TRIANGLES,
91316           *                       TRIANGLE_STRIP, TRIANGLE_FAN and TESS(WEBGL only)
91317           * @chainable
91318           */ _main.default.RendererGL.prototype.beginShape = function(mode) {
91319            this.immediateMode.shapeMode =
91320              mode !== undefined ? mode : constants.TRIANGLE_FAN;
91321            this.immediateMode.geometry.reset();
91322            return this;
91323          };
91324          /**
91325           * adds a vertex to be drawn in a custom Shape.
91326           * @private
91327           * @method vertex
91328           * @param  {Number} x x-coordinate of vertex
91329           * @param  {Number} y y-coordinate of vertex
91330           * @param  {Number} z z-coordinate of vertex
91331           * @chainable
91332           * @TODO implement handling of <a href="#/p5.Vector">p5.Vector</a> args
91333           */ _main.default.RendererGL.prototype.vertex = function(x, y) {
91334            var z, u, v;
91335
91336            // default to (x, y) mode: all other arugments assumed to be 0.
91337            z = u = v = 0;
91338
91339            if (arguments.length === 3) {
91340              // (x, y, z) mode: (u, v) assumed to be 0.
91341              z = arguments[2];
91342            } else if (arguments.length === 4) {
91343              // (x, y, u, v) mode: z assumed to be 0.
91344              u = arguments[2];
91345              v = arguments[3];
91346            } else if (arguments.length === 5) {
91347              // (x, y, z, u, v) mode
91348              z = arguments[2];
91349              u = arguments[3];
91350              v = arguments[4];
91351            }
91352            var vert = new _main.default.Vector(x, y, z);
91353            this.immediateMode.geometry.vertices.push(vert);
91354            var vertexColor = this.curFillColor || [0.5, 0.5, 0.5, 1.0];
91355            this.immediateMode.geometry.vertexColors.push(
91356              vertexColor[0],
91357              vertexColor[1],
91358              vertexColor[2],
91359              vertexColor[3]
91360            );
91361
91362            if (this.textureMode === constants.IMAGE) {
91363              if (this._tex !== null) {
91364                if (this._tex.width > 0 && this._tex.height > 0) {
91365                  u /= this._tex.width;
91366                  v /= this._tex.height;
91367                }
91368              } else if (this._tex === null && arguments.length >= 4) {
91369                // Only throw this warning if custom uv's have  been provided
91370                console.warn(
91371                  'You must first call texture() before using' +
91372                    ' vertex() with image based u and v coordinates'
91373                );
91374              }
91375            }
91376
91377            this.immediateMode.geometry.uvs.push(u, v);
91378
91379            this.immediateMode._bezierVertex[0] = x;
91380            this.immediateMode._bezierVertex[1] = y;
91381            this.immediateMode._bezierVertex[2] = z;
91382
91383            this.immediateMode._quadraticVertex[0] = x;
91384            this.immediateMode._quadraticVertex[1] = y;
91385            this.immediateMode._quadraticVertex[2] = z;
91386
91387            return this;
91388          };
91389
91390          /**
91391           * End shape drawing and render vertices to screen.
91392           * @chainable
91393           */
91394          _main.default.RendererGL.prototype.endShape = function(
91395            mode,
91396            isCurve,
91397            isBezier,
91398            isQuadratic,
91399            isContour,
91400            shapeKind
91401          ) {
91402            if (this.immediateMode.shapeMode === constants.POINTS) {
91403              this._drawPoints(
91404                this.immediateMode.geometry.vertices,
91405                this.immediateMode.buffers.point
91406              );
91407
91408              return this;
91409            }
91410            this._processVertices.apply(this, arguments);
91411            if (this._doFill) {
91412              if (this.immediateMode.geometry.vertices.length > 1) {
91413                this._drawImmediateFill();
91414              }
91415            }
91416            if (this._doStroke) {
91417              if (this.immediateMode.geometry.lineVertices.length > 1) {
91418                this._drawImmediateStroke();
91419              }
91420            }
91421
91422            this.isBezier = false;
91423            this.isQuadratic = false;
91424            this.isCurve = false;
91425            this.immediateMode._bezierVertex.length = 0;
91426            this.immediateMode._quadraticVertex.length = 0;
91427            this.immediateMode._curveVertex.length = 0;
91428            return this;
91429          };
91430
91431          /**
91432           * Called from endShape(). This function calculates the stroke vertices for custom shapes and
91433           * tesselates shapes when applicable.
91434           * @private
91435           * @param  {Number} mode webgl primitives mode.  beginShape supports the
91436           *                       following modes:
91437           *                       POINTS,LINES,LINE_STRIP,LINE_LOOP,TRIANGLES,
91438           *                       TRIANGLE_STRIP, TRIANGLE_FAN and TESS(WEBGL only)
91439           */
91440          _main.default.RendererGL.prototype._processVertices = function(mode) {
91441            if (this.immediateMode.geometry.vertices.length === 0) return;
91442
91443            var calculateStroke = this._doStroke && this.drawMode !== constants.TEXTURE;
91444            var shouldClose = mode === constants.CLOSE;
91445            if (calculateStroke) {
91446              this.immediateMode.geometry.edges = this._calculateEdges(
91447                this.immediateMode.shapeMode,
91448                this.immediateMode.geometry.vertices,
91449                shouldClose
91450              );
91451
91452              this.immediateMode.geometry._edgesToVertices();
91453            }
91454            // For hollow shapes, user must set mode to TESS
91455            var convexShape = this.immediateMode.shapeMode === constants.TESS;
91456            // We tesselate when drawing curves or convex shapes
91457            var shouldTess =
91458              (this.isBezier || this.isQuadratic || this.isCurve || convexShape) &&
91459              this.immediateMode.shapeMode !== constants.LINES;
91460
91461            if (shouldTess) {
91462              this._tesselateShape();
91463            }
91464          };
91465
91466          /**
91467           * Called from _processVertices(). This function calculates the stroke vertices for custom shapes and
91468           * tesselates shapes when applicable.
91469           * @private
91470           * @returns  {Array[Number]} indices for custom shape vertices indicating edges.
91471           */
91472          _main.default.RendererGL.prototype._calculateEdges = function(
91473            shapeMode,
91474            verts,
91475            shouldClose
91476          ) {
91477            var res = [];
91478            var i = 0;
91479            switch (shapeMode) {
91480              case constants.TRIANGLE_STRIP:
91481                for (i = 0; i < verts.length - 2; i++) {
91482                  res.push([i, i + 1]);
91483                  res.push([i, i + 2]);
91484                }
91485                res.push([i, i + 1]);
91486                break;
91487              case constants.TRIANGLES:
91488                for (i = 0; i < verts.length - 2; i = i + 3) {
91489                  res.push([i, i + 1]);
91490                  res.push([i + 1, i + 2]);
91491                  res.push([i + 2, i]);
91492                }
91493                break;
91494              case constants.LINES:
91495                for (i = 0; i < verts.length - 1; i = i + 2) {
91496                  res.push([i, i + 1]);
91497                }
91498                break;
91499              default:
91500                for (i = 0; i < verts.length - 1; i++) {
91501                  res.push([i, i + 1]);
91502                }
91503                break;
91504            }
91505
91506            if (shouldClose) {
91507              res.push([verts.length - 1, 0]);
91508            }
91509            return res;
91510          };
91511
91512          /**
91513           * Called from _processVertices() when applicable. This function tesselates immediateMode.geometry.
91514           * @private
91515           */
91516          _main.default.RendererGL.prototype._tesselateShape = function() {
91517            this.immediateMode.shapeMode = constants.TRIANGLES;
91518            var contours = [
91519              new Float32Array(this._vToNArray(this.immediateMode.geometry.vertices))
91520            ];
91521
91522            var polyTriangles = this._triangulate(contours);
91523            this.immediateMode.geometry.vertices = [];
91524            for (
91525              var j = 0, polyTriLength = polyTriangles.length;
91526              j < polyTriLength;
91527              j = j + 3
91528            ) {
91529              this.vertex(polyTriangles[j], polyTriangles[j + 1], polyTriangles[j + 2]);
91530            }
91531          };
91532
91533          /**
91534           * Called from endShape(). Responsible for calculating normals, setting shader uniforms,
91535           * enabling all appropriate buffers, applying color blend, and drawing the fill geometry.
91536           * @private
91537           */
91538          _main.default.RendererGL.prototype._drawImmediateFill = function() {
91539            var gl = this.GL;
91540            var shader = this._getImmediateFillShader();
91541
91542            this._calculateNormals(this.immediateMode.geometry);
91543            this._setFillUniforms(shader);
91544            var _iteratorNormalCompletion = true;
91545            var _didIteratorError = false;
91546            var _iteratorError = undefined;
91547            try {
91548              for (
91549                var _iterator = this.immediateMode.buffers.fill[Symbol.iterator](), _step;
91550                !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
91551                _iteratorNormalCompletion = true
91552              ) {
91553                var buff = _step.value;
91554                buff._prepareBuffer(this.immediateMode.geometry, shader);
91555              }
91556
91557              // LINE_STRIP and LINES are not used for rendering, instead
91558              // they only indicate a way to modify vertices during the _processVertices() step
91559            } catch (err) {
91560              _didIteratorError = true;
91561              _iteratorError = err;
91562            } finally {
91563              try {
91564                if (!_iteratorNormalCompletion && _iterator.return != null) {
91565                  _iterator.return();
91566                }
91567              } finally {
91568                if (_didIteratorError) {
91569                  throw _iteratorError;
91570                }
91571              }
91572            }
91573            if (
91574              this.immediateMode.shapeMode === constants.LINE_STRIP ||
91575              this.immediateMode.shapeMode === constants.LINES
91576            ) {
91577              this.immediateMode.shapeMode = constants.TRIANGLE_FAN;
91578            }
91579
91580            this._applyColorBlend(this.curFillColor);
91581            gl.drawArrays(
91582              this.immediateMode.shapeMode,
91583              0,
91584              this.immediateMode.geometry.vertices.length
91585            );
91586
91587            shader.unbindShader();
91588          };
91589
91590          /**
91591           * Called from endShape(). Responsible for calculating normals, setting shader uniforms,
91592           * enabling all appropriate buffers, applying color blend, and drawing the stroke geometry.
91593           * @private
91594           */
91595          _main.default.RendererGL.prototype._drawImmediateStroke = function() {
91596            var gl = this.GL;
91597            var shader = this._getImmediateStrokeShader();
91598            this._setStrokeUniforms(shader);
91599            var _iteratorNormalCompletion2 = true;
91600            var _didIteratorError2 = false;
91601            var _iteratorError2 = undefined;
91602            try {
91603              for (
91604                var _iterator2 = this.immediateMode.buffers.stroke[Symbol.iterator](),
91605                  _step2;
91606                !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done);
91607                _iteratorNormalCompletion2 = true
91608              ) {
91609                var buff = _step2.value;
91610                buff._prepareBuffer(this.immediateMode.geometry, shader);
91611              }
91612            } catch (err) {
91613              _didIteratorError2 = true;
91614              _iteratorError2 = err;
91615            } finally {
91616              try {
91617                if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
91618                  _iterator2.return();
91619                }
91620              } finally {
91621                if (_didIteratorError2) {
91622                  throw _iteratorError2;
91623                }
91624              }
91625            }
91626            this._applyColorBlend(this.curStrokeColor);
91627            gl.drawArrays(gl.TRIANGLES, 0, this.immediateMode.geometry.lineVertices.length);
91628
91629            shader.unbindShader();
91630          };
91631
91632          /**
91633           * Called from _drawImmediateFill(). Currently adds default normals which
91634           * only work for flat shapes.
91635           * @parem
91636           * @private
91637           */
91638          _main.default.RendererGL.prototype._calculateNormals = function(geometry) {
91639            geometry.vertices.forEach(function() {
91640              geometry.vertexNormals.push(new _main.default.Vector(0, 0, 1));
91641            });
91642          };
91643          var _default = _main.default.RendererGL;
91644          exports.default = _default;
91645        },
91646        { '../core/constants': 48, '../core/main': 59, './p5.RenderBuffer': 110 }
91647      ],
91648      112: [
91649        function(_dereq_, module, exports) {
91650          'use strict';
91651          Object.defineProperty(exports, '__esModule', { value: true });
91652          exports.default = void 0;
91653
91654          var _main = _interopRequireDefault(_dereq_('../core/main'));
91655          _dereq_('./p5.RendererGL');
91656          _dereq_('./p5.RenderBuffer');
91657          function _interopRequireDefault(obj) {
91658            return obj && obj.__esModule ? obj : { default: obj };
91659          } //Retained Mode. The default mode for rendering 3D primitives
91660          //in WEBGL.
91661          var hashCount = 0;
91662          /**
91663           * _initBufferDefaults
91664           * @private
91665           * @description initializes buffer defaults. runs each time a new geometry is
91666           * registered
91667           * @param  {String} gId  key of the geometry object
91668           * @returns {Object} a new buffer object
91669           */
91670          _main.default.RendererGL.prototype._initBufferDefaults = function(gId) {
91671            this._freeBuffers(gId);
91672
91673            //@TODO remove this limit on hashes in retainedMode.geometry
91674            hashCount++;
91675            if (hashCount > 1000) {
91676              var key = Object.keys(this.retainedMode.geometry)[0];
91677              delete this.retainedMode.geometry[key];
91678              hashCount--;
91679            }
91680
91681            //create a new entry in our retainedMode.geometry
91682            return (this.retainedMode.geometry[gId] = {});
91683          };
91684
91685          _main.default.RendererGL.prototype._freeBuffers = function(gId) {
91686            var buffers = this.retainedMode.geometry[gId];
91687            if (!buffers) {
91688              return;
91689            }
91690
91691            delete this.retainedMode.geometry[gId];
91692            hashCount--;
91693
91694            var gl = this.GL;
91695            if (buffers.indexBuffer) {
91696              gl.deleteBuffer(buffers.indexBuffer);
91697            }
91698
91699            function freeBuffers(defs) {
91700              var _iteratorNormalCompletion = true;
91701              var _didIteratorError = false;
91702              var _iteratorError = undefined;
91703              try {
91704                for (
91705                  var _iterator = defs[Symbol.iterator](), _step;
91706                  !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
91707                  _iteratorNormalCompletion = true
91708                ) {
91709                  var def = _step.value;
91710                  if (buffers[def.dst]) {
91711                    gl.deleteBuffer(buffers[def.dst]);
91712                    buffers[def.dst] = null;
91713                  }
91714                }
91715              } catch (err) {
91716                _didIteratorError = true;
91717                _iteratorError = err;
91718              } finally {
91719                try {
91720                  if (!_iteratorNormalCompletion && _iterator.return != null) {
91721                    _iterator.return();
91722                  }
91723                } finally {
91724                  if (_didIteratorError) {
91725                    throw _iteratorError;
91726                  }
91727                }
91728              }
91729            }
91730
91731            // free all the buffers
91732            freeBuffers(this.retainedMode.buffers.stroke);
91733            freeBuffers(this.retainedMode.buffers.fill);
91734          };
91735
91736          /**
91737           * creates a buffers object that holds the WebGL render buffers
91738           * for a geometry.
91739           * @private
91740           * @param  {String} gId    key of the geometry object
91741           * @param  {p5.Geometry}  model contains geometry data
91742           */
91743          _main.default.RendererGL.prototype.createBuffers = function(gId, model) {
91744            var gl = this.GL;
91745            //initialize the gl buffers for our geom groups
91746            var buffers = this._initBufferDefaults(gId);
91747            buffers.model = model;
91748
91749            var indexBuffer = buffers.indexBuffer;
91750
91751            if (model.faces.length) {
91752              // allocate space for faces
91753              if (!indexBuffer) indexBuffer = buffers.indexBuffer = gl.createBuffer();
91754              var vals = _main.default.RendererGL.prototype._flatten(model.faces);
91755              this._bindBuffer(indexBuffer, gl.ELEMENT_ARRAY_BUFFER, vals, Uint16Array);
91756
91757              // the vertex count is based on the number of faces
91758              buffers.vertexCount = model.faces.length * 3;
91759            } else {
91760              // the index buffer is unused, remove it
91761              if (indexBuffer) {
91762                gl.deleteBuffer(indexBuffer);
91763                buffers.indexBuffer = null;
91764              }
91765              // the vertex count comes directly from the model
91766              buffers.vertexCount = model.vertices ? model.vertices.length : 0;
91767            }
91768
91769            buffers.lineVertexCount = model.lineVertices ? model.lineVertices.length : 0;
91770
91771            return buffers;
91772          };
91773
91774          /**
91775           * Draws buffers given a geometry key ID
91776           * @private
91777           * @param  {String} gId     ID in our geom hash
91778           * @chainable
91779           */
91780          _main.default.RendererGL.prototype.drawBuffers = function(gId) {
91781            var gl = this.GL;
91782            var geometry = this.retainedMode.geometry[gId];
91783
91784            if (this._doStroke && geometry.lineVertexCount > 0) {
91785              var strokeShader = this._getRetainedStrokeShader();
91786              this._setStrokeUniforms(strokeShader);
91787              var _iteratorNormalCompletion2 = true;
91788              var _didIteratorError2 = false;
91789              var _iteratorError2 = undefined;
91790              try {
91791                for (
91792                  var _iterator2 = this.retainedMode.buffers.stroke[Symbol.iterator](),
91793                    _step2;
91794                  !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done);
91795                  _iteratorNormalCompletion2 = true
91796                ) {
91797                  var buff = _step2.value;
91798                  buff._prepareBuffer(geometry, strokeShader);
91799                }
91800              } catch (err) {
91801                _didIteratorError2 = true;
91802                _iteratorError2 = err;
91803              } finally {
91804                try {
91805                  if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
91806                    _iterator2.return();
91807                  }
91808                } finally {
91809                  if (_didIteratorError2) {
91810                    throw _iteratorError2;
91811                  }
91812                }
91813              }
91814              this._applyColorBlend(this.curStrokeColor);
91815              this._drawArrays(gl.TRIANGLES, gId);
91816              strokeShader.unbindShader();
91817            }
91818
91819            if (this._doFill) {
91820              var fillShader = this._getRetainedFillShader();
91821              this._setFillUniforms(fillShader);
91822              var _iteratorNormalCompletion3 = true;
91823              var _didIteratorError3 = false;
91824              var _iteratorError3 = undefined;
91825              try {
91826                for (
91827                  var _iterator3 = this.retainedMode.buffers.fill[Symbol.iterator](),
91828                    _step3;
91829                  !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done);
91830                  _iteratorNormalCompletion3 = true
91831                ) {
91832                  var _buff = _step3.value;
91833                  _buff._prepareBuffer(geometry, fillShader);
91834                }
91835              } catch (err) {
91836                _didIteratorError3 = true;
91837                _iteratorError3 = err;
91838              } finally {
91839                try {
91840                  if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
91841                    _iterator3.return();
91842                  }
91843                } finally {
91844                  if (_didIteratorError3) {
91845                    throw _iteratorError3;
91846                  }
91847                }
91848              }
91849              if (geometry.indexBuffer) {
91850                //vertex index buffer
91851                this._bindBuffer(geometry.indexBuffer, gl.ELEMENT_ARRAY_BUFFER);
91852              }
91853              this._applyColorBlend(this.curFillColor);
91854              this._drawElements(gl.TRIANGLES, gId);
91855              fillShader.unbindShader();
91856            }
91857            return this;
91858          };
91859
91860          /**
91861           * Calls drawBuffers() with a scaled model/view matrix.
91862           *
91863           * This is used by various 3d primitive methods (in primitives.js, eg. plane,
91864           * box, torus, etc...) to allow caching of un-scaled geometries. Those
91865           * geometries are generally created with unit-length dimensions, cached as
91866           * such, and then scaled appropriately in this method prior to rendering.
91867           *
91868           * @private
91869           * @method drawBuffersScaled
91870           * @param {String} gId     ID in our geom hash
91871           * @param {Number} scaleX  the amount to scale in the X direction
91872           * @param {Number} scaleY  the amount to scale in the Y direction
91873           * @param {Number} scaleZ  the amount to scale in the Z direction
91874           */
91875          _main.default.RendererGL.prototype.drawBuffersScaled = function(
91876            gId,
91877            scaleX,
91878            scaleY,
91879            scaleZ
91880          ) {
91881            var uMVMatrix = this.uMVMatrix.copy();
91882            try {
91883              this.uMVMatrix.scale(scaleX, scaleY, scaleZ);
91884              this.drawBuffers(gId);
91885            } finally {
91886              this.uMVMatrix = uMVMatrix;
91887            }
91888          };
91889
91890          _main.default.RendererGL.prototype._drawArrays = function(drawMode, gId) {
91891            this.GL.drawArrays(
91892              drawMode,
91893              0,
91894              this.retainedMode.geometry[gId].lineVertexCount
91895            );
91896
91897            return this;
91898          };
91899
91900          _main.default.RendererGL.prototype._drawElements = function(drawMode, gId) {
91901            var buffers = this.retainedMode.geometry[gId];
91902            var gl = this.GL;
91903            // render the fill
91904            if (buffers.indexBuffer) {
91905              // we're drawing faces
91906              gl.drawElements(gl.TRIANGLES, buffers.vertexCount, gl.UNSIGNED_SHORT, 0);
91907            } else {
91908              // drawing vertices
91909              gl.drawArrays(drawMode || gl.TRIANGLES, 0, buffers.vertexCount);
91910            }
91911          };
91912
91913          _main.default.RendererGL.prototype._drawPoints = function(
91914            vertices,
91915            vertexBuffer
91916          ) {
91917            var gl = this.GL;
91918            var pointShader = this._getImmediatePointShader();
91919            this._setPointUniforms(pointShader);
91920
91921            this._bindBuffer(
91922              vertexBuffer,
91923              gl.ARRAY_BUFFER,
91924              this._vToNArray(vertices),
91925              Float32Array,
91926              gl.STATIC_DRAW
91927            );
91928
91929            pointShader.enableAttrib(pointShader.attributes.aPosition, 3);
91930
91931            gl.drawArrays(gl.Points, 0, vertices.length);
91932
91933            pointShader.unbindShader();
91934          };
91935          var _default = _main.default.RendererGL;
91936          exports.default = _default;
91937        },
91938        { '../core/main': 59, './p5.RenderBuffer': 110, './p5.RendererGL': 113 }
91939      ],
91940      113: [
91941        function(_dereq_, module, exports) {
91942          'use strict';
91943          function _typeof(obj) {
91944            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
91945              _typeof = function _typeof(obj) {
91946                return typeof obj;
91947              };
91948            } else {
91949              _typeof = function _typeof(obj) {
91950                return obj &&
91951                  typeof Symbol === 'function' &&
91952                  obj.constructor === Symbol &&
91953                  obj !== Symbol.prototype
91954                  ? 'symbol'
91955                  : typeof obj;
91956              };
91957            }
91958            return _typeof(obj);
91959          }
91960          Object.defineProperty(exports, '__esModule', { value: true });
91961          exports.default = void 0;
91962          var _main = _interopRequireDefault(_dereq_('../core/main'));
91963          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
91964          var _libtess = _interopRequireDefault(_dereq_('libtess'));
91965          _dereq_('./p5.Shader');
91966          _dereq_('./p5.Camera');
91967          _dereq_('../core/p5.Renderer');
91968          _dereq_('./p5.Matrix');
91969
91970          var _path = _dereq_('path');
91971          function _getRequireWildcardCache() {
91972            if (typeof WeakMap !== 'function') return null;
91973            var cache = new WeakMap();
91974            _getRequireWildcardCache = function _getRequireWildcardCache() {
91975              return cache;
91976            };
91977            return cache;
91978          }
91979          function _interopRequireWildcard(obj) {
91980            if (obj && obj.__esModule) {
91981              return obj;
91982            }
91983            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
91984              return { default: obj };
91985            }
91986            var cache = _getRequireWildcardCache();
91987            if (cache && cache.has(obj)) {
91988              return cache.get(obj);
91989            }
91990            var newObj = {};
91991            var hasPropertyDescriptor =
91992              Object.defineProperty && Object.getOwnPropertyDescriptor;
91993            for (var key in obj) {
91994              if (Object.prototype.hasOwnProperty.call(obj, key)) {
91995                var desc = hasPropertyDescriptor
91996                  ? Object.getOwnPropertyDescriptor(obj, key)
91997                  : null;
91998                if (desc && (desc.get || desc.set)) {
91999                  Object.defineProperty(newObj, key, desc);
92000                } else {
92001                  newObj[key] = obj[key];
92002                }
92003              }
92004            }
92005            newObj.default = obj;
92006            if (cache) {
92007              cache.set(obj, newObj);
92008            }
92009            return newObj;
92010          }
92011          function _interopRequireDefault(obj) {
92012            return obj && obj.__esModule ? obj : { default: obj };
92013          }
92014          function _toConsumableArray(arr) {
92015            return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
92016          }
92017          function _nonIterableSpread() {
92018            throw new TypeError('Invalid attempt to spread non-iterable instance');
92019          }
92020          function _iterableToArray(iter) {
92021            if (
92022              Symbol.iterator in Object(iter) ||
92023              Object.prototype.toString.call(iter) === '[object Arguments]'
92024            )
92025              return Array.from(iter);
92026          }
92027          function _arrayWithoutHoles(arr) {
92028            if (Array.isArray(arr)) {
92029              for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
92030                arr2[i] = arr[i];
92031              }
92032              return arr2;
92033            }
92034          }
92035
92036          var lightingShader =
92037            'precision highp float;\nprecision highp int;\n\nuniform mat4 uViewMatrix;\n\nuniform bool uUseLighting;\n\nuniform int uAmbientLightCount;\nuniform vec3 uAmbientColor[5];\n\nuniform int uDirectionalLightCount;\nuniform vec3 uLightingDirection[5];\nuniform vec3 uDirectionalDiffuseColors[5];\nuniform vec3 uDirectionalSpecularColors[5];\n\nuniform int uPointLightCount;\nuniform vec3 uPointLightLocation[5];\nuniform vec3 uPointLightDiffuseColors[5];\t\nuniform vec3 uPointLightSpecularColors[5];\n\nuniform int uSpotLightCount;\nuniform float uSpotLightAngle[5];\nuniform float uSpotLightConc[5];\nuniform vec3 uSpotLightDiffuseColors[5];\nuniform vec3 uSpotLightSpecularColors[5];\nuniform vec3 uSpotLightLocation[5];\nuniform vec3 uSpotLightDirection[5];\n\nuniform bool uSpecular;\nuniform float uShininess;\n\nuniform float uConstantAttenuation;\nuniform float uLinearAttenuation;\nuniform float uQuadraticAttenuation;\n\nconst float specularFactor = 2.0;\nconst float diffuseFactor = 0.73;\n\nstruct LightResult {\n  float specular;\n  float diffuse;\n};\n\nfloat _phongSpecular(\n  vec3 lightDirection,\n  vec3 viewDirection,\n  vec3 surfaceNormal,\n  float shininess) {\
92037n\n  vec3 R = reflect(lightDirection, surfaceNormal);\n  return pow(max(0.0, dot(R, viewDirection)), shininess);\n}\n\nfloat _lambertDiffuse(vec3 lightDirection, vec3 surfaceNormal) {\n  return max(0.0, dot(-lightDirection, surfaceNormal));\n}\n\nLightResult _light(vec3 viewDirection, vec3 normal, vec3 lightVector) {\n\n  vec3 lightDir = normalize(lightVector);\n\n  //compute our diffuse & specular terms\n  LightResult lr;\n  if (uSpecular)\n    lr.specular = _phongSpecular(lightDir, viewDirection, normal, uShininess);\n  lr.diffuse = _lambertDiffuse(lightDir, normal);\n  return lr;\n}\n\nvoid totalLight(\n  vec3 modelPosition,\n  vec3 normal,\n  out vec3 totalDiffuse,\n  out vec3 totalSpecular\n) {\n\n  totalSpecular = vec3(0.0);\n\n  if (!uUseLighting) {\n    totalDiffuse = vec3(1.0);\n    return;\n  }\n\n  totalDiffuse = vec3(0.0);\n\n  vec3 viewDirection = normalize(-modelPosition);\n\n  for (int j = 0; j < 5; j++) {\n    if (j < uDirectionalLightCount) {\n      vec3 lightVector = (uViewMatrix * vec4(uLightingDirection[j], 0.0)).xyz;\n      vec3 lightColor = uDirectionalDiffuseColors[j];\n      vec3 specularColor = uDirectionalSpecularColors[j];\n      LightResult result = _light(viewDirection, normal, lightVector);\n      totalDiffuse += result.diffuse * lightColor;\n      totalSpecular += result.specular * lightColor * specularColor;\n    }\n\n    if (j < uPointLightCount) {\n      vec3 lightPosition = (uViewMatrix * vec4(uPointLightLocation[j], 1.0)).xyz;\n      vec3 lightVector = modelPosition - lightPosition;\n    \n      //calculate attenuation\n      float lightDistance = length(lightVector);\n      float lightFalloff = 1.0 / (uConstantAttenuation + lightDistance * uLinearAttenuation + (lightDistance * lightDistance) * uQuadraticAttenuation);\n      vec3 lightColor = lightFalloff * uPointLightDiffuseColors[j];\n      vec3 specularColor = lightFalloff * uPointLightSpecularColors[j];\n\n      LightResult result = _light(viewDirection, normal, lightVector);\n      totalDiffuse += result.diffuse * lightColor;\n      totalSpecular += result.specular * lightColor * specularColor;\n    }\n\n    if(j < uSpotLightCount) {\n      vec3 lightPosition = (uViewMatrix * vec4(uSpotLightLocation[j], 1.0)).xyz;\n      vec3 lightVector = modelPosition - lightPosition;\n    \n      float lightDistance = length(lightVector);\n      float lightFalloff = 1.0 / (uConstantAttenuation + lightDistance * uLinearAttenuation + (lightDistance * lightDistance) * uQuadraticAttenuation);\n\n      vec3 lightDirection = (uViewMatrix * vec4(uSpotLightDirection[j], 0.0)).xyz;\n      float spotDot = dot(normalize(lightVector), normalize(lightDirection));\n      float spotFalloff;\n      if(spotDot < uSpotLightAngle[j]) {\n        spotFalloff = 0.0;\n      }\n      else {\n        spotFalloff = pow(spotDot, uSpotLightConc[j]);\n      }\n      lightFalloff *= spotFalloff;\n\n      vec3 lightColor = uSpotLightDiffuseColors[j];\n      vec3 specularColor = uSpotLightSpecularColors[j];\n     \n      LightResult result = _light(viewDirection, normal, lightVector);\n      \n      totalDiffuse += result.diffuse * lightColor * lightFalloff;\n      totalSpecular += result.specular * lightColor * specularColor * lightFalloff;\n    }\n  }\n\n  totalDiffuse *= diffuseFactor;\n  totalSpecular *= specularFactor;\n}\n';
92038
92039          var defaultShaders = {
92040            immediateVert:
92041              'attribute vec3 aPosition;\nattribute vec4 aVertexColor;\n\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\nuniform float uResolution;\nuniform float uPointSize;\n\nvarying vec4 vColor;
92041\nvoid main(void) {\n  vec4 positionVec4 = vec4(aPosition, 1.0);\n  gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;\n  vColor = aVertexColor;\n  gl_PointSize = uPointSize;\n}\n',
92042
92043            vertexColorVert:
92044              'attribute vec3 aPosition;\nattribute vec4 aVertexColor;\n\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\n\nvarying vec4 vColor;\n\nvoid main(void) {\n  vec4 positionVec4 = vec4(aPosition, 1.0);\n  gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;\n  vColor = aVertexColor;\n}\n',
92045
92046            vertexColorFrag:
92047              'precision mediump float;\nvarying vec4 vColor;\nvoid main(void) {\n  gl_FragColor = vColor;\n}',
92048
92049            normalVert:
92050              'attribute vec3 aPosition;\nattribute vec3 aNormal;\nattribute vec2 aTexCoord;\n\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\nuniform mat3 uNormalMatrix;\n\nvarying vec3 vVertexNormal;\nvarying highp vec2 vVertTexCoord;\n\nvoid main(void) {\n  vec4 positionVec4 = vec4(aPosition, 1.0
92050);\n  gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;\n  vVertexNormal = normalize(vec3( uNormalMatrix * aNormal ));\n  vVertTexCoord = aTexCoord;\n}\n',
92051            normalFrag:
92052              'precision mediump float;\nvarying vec3 vVertexNormal;\nvoid main(void) {\n  gl_FragColor = vec4(vVertexNormal, 1.0);\n}',
92053            basicFrag:
92054              'precision mediump float;\nuniform vec4 uMaterialColor;\nvoid main(void) {\n  gl_FragColor = uMaterialColor;\n}',
92055            lightVert:
92056              lightingShader +
92057              '// include lighting.glgl\n\nattribute vec3 aPosition;\nattribute vec3 aNormal;\nattribute vec2 aTexCoord;\n\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\nuniform mat3 uNormalMatrix;\n\nvarying highp vec2 vVertTexCoord;\nvarying vec3 vDiffuseColor;\nvarying vec3 vSpecularColor;\n\nvoid main(void) {\n\n  vec4 viewModelPosition = uModelViewMatrix * vec4(aPosition, 1.0);\n  gl_Position = uProjectionMatrix * viewModelPosition;\n\n  vec3 vertexNormal = normalize(uNormalMatrix * aNormal);\n  vVertTexCoord = aTexCoord;\n\n  totalLight(viewModelPosition.xyz, vertexNormal, vDiffuseColor, vSpecularColor);\n\n  for (int i = 0; i < 8; i++) {\n    if (i < uAmbientLightCount) {\n      vDiffuseColor += uAmbientColor[i];\n    }\n  }\n}\n',
92058
92059            lightTextureFrag:
92060              'precision highp float;\n\nuniform vec4 uMaterialColor;\nuniform vec4 uTint;\nuniform sampler2D uSampler;\nuniform bool isTexture;\nuniform bool uEmissive;\n\nvarying highp vec2 vVertTexCoord;\nvarying vec3 vDiffuseColor;\nvarying vec3 vSpecularColor;\n\nvoid main(void) {\n  if(uEmissive && !isTexture) {\n    gl_FragColor = uMaterialColor;\n  }\n  else {\n    gl_FragColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;\n    gl_FragColor.rgb = gl_FragColor.rgb * vDiffuseColor + vSpecularColor;\n  }\n}',
92061
92062            phongVert:
92063              'precision highp float;\nprecision highp int;\n\nattribute vec3 aPosition;\nattribute vec3 aNormal;\nattribute vec2 aTexCoord;\n\nuniform vec3 uAmbientColor[5];\n\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\nuniform mat3 uNormalMatrix;\nuniform int uAmbientLightCount;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord;\nvarying vec3 vViewPosition;\nvarying vec3 vAmbientColor;\n\nvoid main(void) {\n\n  vec4 viewModelPosition = uModelViewMatrix * vec4(aPosition, 1.0
92063);\n\n  // Pass varyings to fragment shader\n  vViewPosition = viewModelPosition.xyz;\n  gl_Position = uProjectionMatrix * viewModelPosition;  \n\n  vNormal = uNormalMatrix * aNormal;\n  vTexCoord = aTexCoord;\n\n  // TODO: this should be a uniform\n  vAmbientColor = vec3(0.0);\n  for (int i = 0; i < 5; i++) {\n    if (i < uAmbientLightCount) {\n      vAmbientColor += uAmbientColor[i];\n    }\n  }\n}\n',
92064            phongFrag:
92065              lightingShader +
92066              '// include lighting.glsl\nprecision highp float;\nprecision highp int;\n\nuniform vec4 uMaterialColor;\nuniform vec4 uTint;\nuniform sampler2D uSampler;\nuniform bool isTexture;\nuniform bool uEmissive;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord;\nvarying vec3 vViewPosition;\nvarying vec3 vAmbientColor;\n\nvoid main(void) {\n\n  vec3 diffuse;\n  vec3 specular;\n  totalLight(vViewPosition, normalize(vNormal), diffuse, specular);\n\n  if(uEmissive && !isTexture) {\n    gl_FragColor = uMaterialColor;\n  }\n  else {\n    gl_FragColor = isTexture ? texture2D(uSampler, vTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;\n    gl_FragColor.rgb = gl_FragColor.rgb * (diffuse + vAmbientColor) + specular;\n  }\n}',
92067
92068            fontVert:
92069              "precision mediump float;\n\nattribute vec3 aPosition;\nattribute vec2 aTexCoord;\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\n\nuniform vec4 uGlyphRect;\nuniform float uGlyphOffset;\n\nvarying vec2 vTexCoord;\nvarying float w;
92069\n\nvoid main() {\n  vec4 positionVec4 = vec4(aPosition, 1.0);\n\n  // scale by the size of the glyph's rectangle\n  positionVec4.xy *= uGlyphRect.zw - uGlyphRect.xy;\n\n  // move to the corner of the glyph\n  positionVec4.xy += uGlyphRect.xy;\n\n  // move to the letter's line offset\n  positionVec4.x += uGlyphOffset;\n  \n  gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;\n  vTexCoord = aTexCoord;\n  w = gl_Position.w;\n}\n",
92070            fontFrag:
92071              "#extension GL_OES_standard_derivatives : enable\nprecision mediump float;\n\n#if 0\n  // simulate integer math using floats\n\t#define int float\n\t#define ivec2 vec2\n\t#define INT(x) float(x)\n\n\tint ifloor(float v) { return floor(v); }\n\tivec2 ifloor(vec2 v) { return floor(v); }\n\n#else\n  // use native integer math\n\tprecision highp int;\n\t#define INT(x) x\n\n\tint ifloor(float v) { return int(v); }\n\tint ifloor(int v) { return v; }\n\tivec2 ifloor(vec2 v) { return ivec2(v); }\n\n#endif\n\nuniform sampler2D uSamplerStrokes;\nuniform sampler2D uSamplerRowStrokes;\nuniform sampler2D uSamplerRows;\nuniform sampler2D uSamplerColStrokes;\nuniform sampler2D uSamplerCols;\n\nuniform ivec2 uStrokeImageSize;\nuniform ivec2 uCellsImageSize;\nuniform ivec2 uGridImageSize;\n\nuniform ivec2 uGridOffset;\nuniform ivec2 uGridSize;\nuniform vec4 uMaterialColor;\n\nvarying vec2 vTexCoord;\n\n// some helper functions\nint round(float v) { return ifloor(v + 0.5); }\nivec2 round(vec2 v) { return ifloor(v + 0.5); }\nfloat saturate(float v) { return clamp(v, 0.0, 1.0); }\nvec2 saturate(vec2 v) { return clamp(v, 0.0, 1.0); }\n\nint mul(float v1, int v2) {\n  return ifloor(v1 * float(v2));\n}\n\nivec2 mul(vec2 v1, ivec2 v2) {\n  return ifloor(v1 * vec2(v2) + 0.5);\n}\n\n// unpack a 16-bit integer from a float vec2\nint getInt16(vec2 v) {\n  ivec2 iv = round(v * 255.0);\n  return iv.x * INT(128) + iv.y;\n}\n\nvec2 pixelScale;\nvec2 coverage = vec2(0.0);\nvec2 weight = vec2(0.5);\nconst float minDistance = 1.0/8192.0;\nconst float hardness = 1.05; // amount of antialias\n\n// the maximum number of curves in a glyph\nconst int N = INT(250);\n\n// retrieves an indexed pixel from a sampler\nvec4 getTexel(sampler2D sampler, int pos, ivec2 size) {\n  int width = size.x;\n  int y = ifloor(pos / width);\n  int x = pos - y * width;  // pos % width\n\n  return texture2D(sampler, (vec2(x, y) + 0.5) / vec2(size));\n}\n\nvoid calulateCrossings(vec2 p0, vec2 p1, vec2 p2, out vec2 C1, out vec2 C2) {\n\n  // get the coefficients of the quadratic in t\n  vec2 a = p0 - p1 * 2.0 + p2;\n  vec2 b = p0 - p1;\n  vec2 c = p0 - vTexCoord;\n\n  // found out which values of 't' it crosses the axes\n  vec2 surd = sqrt(max(vec2(0.0), b * b - a * c));\n  vec2 t1 = ((b - surd) / a).yx;\n  vec2 t2 = ((b + surd) / a).yx;\n\n  // approximate straight lines to avoid rounding errors\n  if (abs(a.y) < 0.001)\n    t1.x = t2.x = c.y / (2.0 * b.y);\n\n  if (abs(a.x) < 0.001)\n    t1.y = t2.y = c.x / (2.0 * b.x);\n\n  // plug into quadratic formula to find the corrdinates of the crossings\n  C1 = ((a * t1 - b * 2.0) * t1 + c) * pixelScale;\n  C2 = ((a * t2 - b * 2.0) * t2 + c) * pixelScale;\n}\n\nvoid coverageX(vec2 p0, vec2 p1, vec2 p2) {\n\n  vec2 C1, C2;\n  calulateCrossings(p0, p1, p2, C1, C2);\n\n  // determine on which side of the x-axis the points lie\n  bool y0 = p0.y > vTexCoord.y;\n  bool y1 = p1.y > vTexCoord.y;\n  bool y2 = p2.y > vTexCoord.y;\n\n  // could web be under the curve (after t1)?\n  if (y1 ? !y2 : y0) {\n    // add the coverage for t1\n    coverage.x += saturate(C1.x + 0.5);\n    // calculate the anti-aliasing for t1\n    weight.x = min(weight.x, abs(C1.x));\n  }\n\n  // are we outside the curve (after t2)?\n  if (y1 ? !y0 : y2) {\n    // subtract the coverage for t2\n    coverage.x -= saturate(C2.x + 0.5);\n    // calculate the anti-aliasing for t2\n    weight.x = min(weight.x, abs(C2.x));\n  }\n}\n\n// this is essentially the same as coverageX, but with the axes swapped\nvoid coverageY(vec2 p0, vec2 p1, vec2 p2) {\n\n  vec2 C1, C2;\n  calulateCrossings(p0, p1, p2, C1, C2);\n\n  bool x0 = p0.x > vTexCoord.x;\n  bool x1 = p1.x > vTexCoord.x;\n  bool x2 = p2.x > vTexCoord.x;
92071\n\n  if (x1 ? !x2 : x0) {\n    coverage.y -= saturate(C1.y + 0.5);\n    weight.y = min(weight.y, abs(C1.y));\n  }\n\n  if (x1 ? !x0 : x2) {\n    coverage.y += saturate(C2.y + 0.5);\n    weight.y = min(weight.y, abs(C2.y));\n  }\n}\n\nvoid main() {\n\n  // calculate the pixel scale based on screen-coordinates\n  pixelScale = hardness / fwidth(vTexCoord);\n\n  // which grid cell is this pixel in?\n  ivec2 gridCoord = ifloor(vTexCoord * vec2(uGridSize));\n\n  // intersect curves in this row\n  {\n    // the index into the row info bitmap\n    int rowIndex = gridCoord.y + uGridOffset.y;\n    // fetch the info texel\n    vec4 rowInfo = getTexel(uSamplerRows, rowIndex, uGridImageSize);\n    // unpack the rowInfo\n    int rowStrokeIndex = getInt16(rowInfo.xy);\n    int rowStrokeCount = getInt16(rowInfo.zw);\n\n    for (int iRowStroke = INT(0); iRowStroke < N; iRowStroke++) {\n      if (iRowStroke >= rowStrokeCount)\n        break;\n\n      // each stroke is made up of 3 points: the start and control point\n      // and the start of the next curve.\n      // fetch the indices of this pair of strokes:\n      vec4 strokeIndices = getTexel(uSamplerRowStrokes, rowStrokeIndex++, uCellsImageSize);\n\n      // unpack the stroke index\n      int strokePos = getInt16(strokeIndices.xy);\n\n      // fetch the two strokes\n      vec4 stroke0 = getTexel(uSamplerStrokes, strokePos + INT(0), uStrokeImageSize);\n      vec4 stroke1 = getTexel(uSamplerStrokes, strokePos + INT(1), uStrokeImageSize);\n\n      // calculate the coverage\n      coverageX(stroke0.xy, stroke0.zw, stroke1.xy);\n    }\n  }\n\n  // intersect curves in this column\n  {\n    int colIndex = gridCoord.x + uGridOffset.x;\n    vec4 colInfo = getTexel(uSamplerCols, colIndex, uGridImageSize);\n    int colStrokeIndex = getInt16(colInfo.xy);\n    int colStrokeCount = getInt16(colInfo.zw);\n    \n    for (int iColStroke = INT(0); iColStroke < N; iColStroke++) {\n      if (iColStroke >= colStrokeCount)\n        break;\n\n      vec4 strokeIndices = getTexel(uSamplerColStrokes, colStrokeIndex++, uCellsImageSize);\n\n      int strokePos = getInt16(strokeIndices.xy);\n      vec4 stroke0 = getTexel(uSamplerStrokes, strokePos + INT(0), uStrokeImageSize);\n      vec4 stroke1 = getTexel(uSamplerStrokes, strokePos + INT(1), uStrokeImageSize);\n      coverageY(stroke0.xy, stroke0.zw, stroke1.xy);\n    }\n  }\n\n  weight = saturate(1.0 - weight * 2.0);\n  float distance = max(weight.x + weight.y, minDistance); // manhattan approx.\n  float antialias = abs(dot(coverage, weight) / distance);\n  float cover = min(abs(coverage.x), abs(coverage.y));\n  gl_FragColor = uMaterialColor;\n  gl_FragColor.a *= saturate(max(antialias, cover));\n}",
92072            lineVert:
92073              "/*\n  Part of the Processing project - http://processing.org\n  Copyright (c) 2012-15 The Processing Foundation\n  Copyright (c) 2004-12 Ben Fry and Casey Reas\n  Copyright (c) 2001-04 Massachusetts Institute of Technology\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation, version 2.1.\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n  You should have received a copy of the GNU Lesser General\n  Public License along with this library; if not, write to the\n  Free Software Foundation, Inc., 59 Temple Place, Suite 330,\n  Boston, MA  02111-1307  USA\n*/\n\n#define PROCESSING_LINE_SHADER\n\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\nuniform float uStrokeWeight;\n\nuniform vec4 uViewport;\nuniform int uPerspective;\n\nattribute vec4 aPosition;\nattribute vec4 aDirection;\n  \nvoid main() {\n  // using a scale <1 moves the lines towards the camera\n  // in order to prevent popping effects due to half of\n  // the line disappearing behind the geometry faces.\n  vec3 scale = vec3(0.9995);\n\n  vec4 posp = uModelViewMatrix * aPosition;\n  vec4 posq = uModelViewMatrix * (aPosition + vec4(aDirection.xyz, 0));\n\n  // Moving vertices slightly toward the camera\n  // to avoid depth-fighting with the fill triangles.\n  // Discussed here:\n  // http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=252848  \n  posp.xyz = posp.xyz * scale;\n  posq.xyz = posq.xyz * scale;\n\n  vec4 p = uProjectionMatrix * posp;\n  vec4 q = uProjectionMatrix * posq;\n\n  // formula to convert from clip space (range -1..1) to screen space (range 0..[width or height])\n  // screen_p = (p.xy/p.w + <1,1>) * 0.5 * uViewport.zw\n\n  // prevent division by W by transforming the tangent formula (div by 0 causes\n  // the line to disappear, see https://github.com/processing/processing/issues/5183)\n  // t = screen_q - screen_p\n  //\n  // tangent is normalized and we don't care which aDirection it points to (+-)\n  // t = +- normalize( screen_q - screen_p )\n  // t = +- normalize( (q.xy/q.w+<1,1>)*0.5*uViewport.zw - (p.xy/p.w+<1,1>)*0.5*uViewport.zw )\n  //\n  // extract common factor, <1,1> - <1,1> cancels out\n  // t = +- normalize( (q.xy/q.w - p.xy/p.w) * 0.5 * uViewport.zw )\n  //\n  // convert to common divisor\n  // t = +- normalize( ((q.xy*p.w - p.xy*q.w) / (p.w*q.w)) * 0.5 * uViewport.zw )\n  //\n  // remove the common scalar divisor/factor, not needed due to normalize and +-\n  // (keep uViewport - can't remove because it has different c
92073omponents for x and y\n  //  and corrects for aspect ratio, see https://github.com/processing/processing/issues/5181)\n  // t = +- normalize( (q.xy*p.w - p.xy*q.w) * uViewport.zw )\n\n  vec2 tangent = normalize((q.xy*p.w - p.xy*q.w) * uViewport.zw);\n\n  // flip tangent to normal (it's already normalized)\n  vec2 normal = vec2(-tangent.y, tangent.x);\n\n  float thickness = aDirection.w * uStrokeWeight;\n  vec2 offset = normal * thickness / 2.0;\n\n  vec2 curPerspScale;\n\n  if(uPerspective == 1) {\n    // Perspective ---\n    // convert from world to clip by multiplying with projection scaling factor\n    // to get the right thickness (see https://github.com/processing/processing/issues/5182)\n    // invert Y, projections in Processing invert Y\n    curPerspScale = (uProjectionMatrix * vec4(1, -1, 0, 0)).xy;\n  } else {\n    // No Perspective ---\n    // multiply by W (to cancel out division by W later in the pipeline) and\n    // convert from screen to clip (derived from clip to screen above)\n    curPerspScale = p.w / (0.5 * uViewport.zw);\n  }\n\n  gl_Position.xy = p.xy + offset.xy * curPerspScale;\n  gl_Position.zw = p.zw;\n}\n",
92074            lineFrag:
92075              'precision mediump float;\nprecision mediump int;\n\nuniform vec4 uMaterialColor;\n\nvoid main() {\n  gl_FragColor = uMaterialColor;\n}',
92076            pointVert:
92077              'attribute vec3 aPosition;\nuniform float uPointSize;\nvarying float vStrokeWeight;\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;
92077\nvoid main() {\n\tvec4 positionVec4 =  vec4(aPosition, 1.0);\n\tgl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;\n\tgl_PointSize = uPointSize;\n\tvStrokeWeight = uPointSize;\n}',
92078            pointFrag:
92079              'precision mediump float;\nprecision mediump int;\nuniform vec4 uMaterialColor;\nvarying float vStrokeWeight;\n\nvoid main(){\n\tfloat mask = 0.0;\n\n\t// make a circular mask using the gl_PointCoord (goes from 0 - 1 on a point)\n    // might be able to get a nicer edge on big strokeweights with smoothstep but slightly less performant\n\n\tmask = step(0.98, length(gl_PointCoord * 2.0 - 1.0));\n\n\t// if strokeWeight is 1 or less lets just draw a square\n\t// this prevents weird artifacting from carving circles when our points are really small\n\t// if strokeWeight is larger than 1, we just use it as is\n\n\tmask = mix(0.0, mask, clamp(floor(vStrokeWeight - 0.5),0.0,1.0));\n\n\t// throw away the borders of the mask\n    // otherwise we get weird alpha blending issues\n\n\tif(mask > 0.98){\n      discard;\n  \t}\n\n  \tgl_FragColor = vec4(uMaterialColor.rgb * (1.0 - mask), uMaterialColor.a) ;\n}'
92080          };
92081
92082          /**
92083           * 3D graphics class
92084           * @private
92085           * @class p5.RendererGL
92086           * @constructor
92087           * @extends p5.Renderer
92088           * @todo extend class to include public method for offscreen
92089           * rendering (FBO).
92090           */
92091          _main.default.RendererGL = function(elt, pInst, isMainCanvas, attr) {
92092            _main.default.Renderer.call(this, elt, pInst, isMainCanvas);
92093            this._setAttributeDefaults(pInst);
92094            this._initContext();
92095            this.isP3D = true; //lets us know we're in 3d mode
92096
92097            // This redundant property is useful in reminding you that you are
92098            // interacting with WebGLRenderingContext, still worth considering future removal
92099            this.GL = this.drawingContext;
92100            this._pInst._setProperty('drawingContext', this.drawingContext);
92101
92102            // erasing
92103            this._isErasing = false;
92104
92105            // lights
92106            this._enableLighting = false;
92107
92108            this.ambientLightColors = [];
92109            this.specularColors = [1, 1, 1];
92110
92111            this.directionalLightDirections = [];
92112            this.directionalLightDiffuseColors = [];
92113            this.directionalLightSpecularColors = [];
92114
92115            this.pointLightPositions = [];
92116            this.pointLightDiffuseColors = [];
92117            this.pointLightSpecularColors = [];
92118
92119            this.spotLightPositions = [];
92120            this.spotLightDirections = [];
92121            this.spotLightDiffuseColors = [];
92122            this.spotLightSpecularColors = [];
92123            this.spotLightAngle = [];
92124            this.spotLightConc = [];
92125
92126            this.drawMode = constants.FILL;
92127
92128            this.curFillColor = this._cachedFillStyle = [1, 1, 1, 1];
92129            this.curStrokeColor = this._cachedStrokeStyle = [0, 0, 0, 1];
92130
92131            this.curBlendMode = constants.BLEND;
92132            this._cachedBlendMode = undefined;
92133            this.blendExt = this.GL.getExtension('EXT_blend_minmax');
92134            this._isBlending = false;
92135
92136            this._useSpecularMaterial = false;
92137            this._useEmissiveMaterial = false;
92138            this._useNormalMaterial = false;
92139            this._useShininess = 1;
92140
92141            this._tint = [255, 255, 255, 255];
92142
92143            // lightFalloff variables
92144            this.constantAttenuation = 1;
92145            this.linearAttenuation = 0;
92146            this.quadraticAttenuation = 0;
92147
92148            /**
92149             * model view, projection, & normal
92150             * matrices
92151             */
92152            this.uMVMatrix = new _main.default.Matrix();
92153            this.uPMatrix = new _main.default.Matrix();
92154            this.uNMatrix = new _main.default.Matrix('mat3');
92155
92156            // Camera
92157            this._curCamera = new _main.default.Camera(this);
92158            this._curCamera._computeCameraDefaultSettings();
92159            this._curCamera._setDefaultCamera();
92160
92161            this._defaultLightShader = undefined;
92162            this._defaultImmediateModeShader = undefined;
92163            this._defaultNormalShader = undefined;
92164            this._defaultColorShader = undefined;
92165            this._defaultPointShader = undefined;
92166
92167            this.userFillShader = undefined;
92168            this.userStrokeShader = undefined;
92169            this.userPointShader = undefined;
92170
92171            // Default drawing is done in Retained Mode
92172            // Geometry and Material hashes stored here
92173            this.retainedMode = {
92174              geometry: {},
92175              buffers: {
92176                // prettier-ignore
92177                stroke: [
92178      new _main.default.RenderBuffer(3, 'lineVertices', 'lineVertexBuffer', 'aPosition', this, this._flatten),
92179      new _main.default.RenderBuffer(4, 'lineNormals', 'lineNormalBuffer', 'aDirection', this, this._flatten)],
92180
92181                // prettier-ignore
92182                fill: [
92183      new _main.default.RenderBuffer(3, 'vertices', 'vertexBuffer', 'aPosition', this, this._vToNArray),
92184      new _main.default.RenderBuffer(3, 'vertexNormals', 'normalBuffer', 'aNormal', this, this._vToNArray),
92185      new _main.default.RenderBuffer(4, 'vertexColors', 'colorBuffer', 'aMaterialColor', this),
92186      new _main.default.RenderBuffer(3, 'vertexAmbients', 'ambientBuffer', 'aAmbientColor', this),
92187      //new BufferDef(3, 'vertexSpeculars', 'specularBuffer', 'aSpecularColor'),
92188      new _main.default.RenderBuffer(2, 'uvs', 'uvBuffer', 'aTexCoord', this, this._flatten)],
92189
92190                // prettier-ignore
92191                text: [
92192      new _main.default.RenderBuffer(3, 'vertices', 'vertexBuffer', 'aPosition', this, this._vToNArray),
92193      new _main.default.RenderBuffer(2, 'uvs', 'uvBuffer', 'aTexCoord', this, this._flatten)]
92194              }
92195            };
92196
92197            // Immediate Mode
92198            // Geometry and Material hashes stored here
92199            this.immediateMode = {
92200              geometry: new _main.default.Geometry(),
92201              shapeMode: constants.TRIANGLE_FAN,
92202              _bezierVertex: [],
92203              _quadraticVertex: [],
92204              _curveVertex: [],
92205              buffers: {
92206                // prettier-ignore
92207                fill: [
92208      new _main.default.RenderBuffer(3, 'vertices', 'vertexBuffer', 'aPosition', this, this._vToNArray),
92209      new _main.default.RenderBuffer(3, 'vertexNormals', 'normalBuffer', 'aNormal', this, this._vToNArray),
92210      new _main.default.RenderBuffer(4, 'vertexColors', 'colorBuffer', 'aVertexColor', this),
92211      new _main.default.RenderBuffer(3, 'vertexAmbients', 'ambientBuffer', 'aAmbientColor', this),
92212      new _main.default.RenderBuffer(2, 'uvs', 'uvBuffer', 'aTexCoord', this, this._flatten)],
92213
92214                // prettier-ignore
92215                stroke: [
92216      new _main.default.RenderBuffer(3, 'lineVertices', 'lineVertexBuffer', 'aPosition', this, this._flatten),
92217      new _main.default.RenderBuffer(4, 'lineNormals', 'lineNormalBuffer', 'aDirection', this, this._flatten)],
92218
92219                point: this.GL.createBuffer()
92220              }
92221            };
92222
92223            this.pointSize = 5.0; //default point size
92224            this.curStrokeWeight = 1;
92225
92226            // array of textures created in this gl context via this.getTexture(src)
92227            this.textures = [];
92228
92229            this.textureMode = constants.IMAGE;
92230            // default wrap settings
92231            this.textureWrapX = constants.CLAMP;
92232            this.textureWrapY = constants.CLAMP;
92233            this._tex = null;
92234            this._curveTightness = 6;
92235
92236            // lookUpTable for coefficients needed to be calculated for bezierVertex, same are used for curveVertex
92237            this._lookUpTableBezier = [];
92238            // lookUpTable for coefficients needed to be calculated for quadraticVertex
92239            this._lookUpTableQuadratic = [];
92240
92241            // current curveDetail in the Bezier lookUpTable
92242            this._lutBezierDetail = 0;
92243            // current curveDetail in the Quadratic lookUpTable
92244            this._lutQuadraticDetail = 0;
92245
92246            this._tessy = this._initTessy();
92247
92248            this.fontInfos = {};
92249
92250            this._curShader = undefined;
92251
92252            return this;
92253          };
92254
92255          _main.default.RendererGL.prototype = Object.create(
92256            _main.default.Renderer.prototype
92257          );
92258
92259          //////////////////////////////////////////////
92260          // Setting
92261          //////////////////////////////////////////////
92262
92263          _main.default.RendererGL.prototype._setAttributeDefaults = function(pInst) {
92264            // See issue #3850, safer to enable AA in Safari
92265            var applyAA = navigator.userAgent.toLowerCase().includes('safari');
92266            var defaults = {
92267              alpha: true,
92268              depth: true,
92269              stencil: true,
92270              antialias: applyAA,
92271              premultipliedAlpha: false,
92272              preserveDrawingBuffer: true,
92273              perPixelLighting: true
92274            };
92275
92276            if (pInst._glAttributes === null) {
92277              pInst._glAttributes = defaults;
92278            } else {
92279              pInst._glAttributes = Object.assign(defaults, pInst._glAttributes);
92280            }
92281            return;
92282          };
92283
92284          _main.default.RendererGL.prototype._initContext = function() {
92285            try {
92286              this.drawingContext =
92287                this.canvas.getContext('webgl', this._pInst._glAttributes) ||
92288                this.canvas.getContext('experimental-webgl', this._pInst._glAttributes);
92289              if (this.drawingContext === null) {
92290                throw new Error('Error creating webgl context');
92291              } else {
92292                var gl = this.drawingContext;
92293                gl.enable(gl.DEPTH_TEST);
92294                gl.depthFunc(gl.LEQUAL);
92295                gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
92296                this._viewport = this.drawingContext.getParameter(
92297                  this.drawingContext.VIEWPORT
92298                );
92299              }
92300            } catch (er) {
92301              throw er;
92302            }
92303          };
92304
92305          //This is helper function to reset the context anytime the attributes
92306          //are changed with setAttributes()
92307
92308          _main.default.RendererGL.prototype._resetContext = function(options, callback) {
92309            var w = this.width;
92310            var h = this.height;
92311            var defaultId = this.canvas.id;
92312            var isPGraphics = this._pInst instanceof _main.default.Graphics;
92313
92314            if (isPGraphics) {
92315              var pg = this._pInst;
92316              pg.canvas.parentNode.removeChild(pg.canvas);
92317              pg.canvas = document.createElement('canvas');
92318              var node = pg._pInst._userNode || document.body;
92319              node.appendChild(pg.canvas);
92320              _main.default.Element.call(pg, pg.canvas, pg._pInst);
92321              pg.width = w;
92322              pg.height = h;
92323            } else {
92324              var c = this.canvas;
92325              if (c) {
92326                c.parentNode.removeChild(c);
92327              }
92328              c = document.createElement('canvas');
92329              c.id = defaultId;
92330              if (this._pInst._userNode) {
92331                this._pInst._userNode.appendChild(c);
92332              } else {
92333                document.body.appendChild(c);
92334              }
92335              this._pInst.canvas = c;
92336            }
92337
92338            var renderer = new _main.default.RendererGL(
92339              this._pInst.canvas,
92340              this._pInst,
92341              !isPGraphics
92342            );
92343
92344            this._pInst._setProperty('_renderer', renderer);
92345            renderer.resize(w, h);
92346            renderer._applyDefaults();
92347
92348            if (!isPGraphics) {
92349              this._pInst._elements.push(renderer);
92350            }
92351
92352            if (typeof callback === 'function') {
92353              //setTimeout with 0 forces the task to the back of the queue, this ensures that
92354              //we finish switching out the renderer
92355              setTimeout(function() {
92356                callback.apply(window._renderer, options);
92357              }, 0);
92358            }
92359          };
92360          /**
92361           * @module Rendering
92362           * @submodule Rendering
92363           * @for p5
92364           */
92365          /**
92366           * Set attributes for the WebGL Drawing context.
92367           * This is a way of adjusting how the WebGL
92368           * renderer works to fine-tune the display and performance.
92369           *
92370           * Note that this will reinitialize the drawing context
92371           * if called after the WebGL canvas is made.
92372           *
92373           * If an object is passed as the parameter, all attributes
92374           * not declared in the object will be set to defaults.
92375           *
92376           * The available attributes are:
92377           * <br>
92378           * alpha - indicates if the canvas contains an alpha buffer
92379           * default is true
92380           *
92381           * depth - indicates whether the drawing buffer has a depth buffer
92382           * of at least 16 bits - default is true
92383           *
92384           * stencil - indicates whether the drawing buffer has a stencil buffer
92385           * of at least 8 bits
92386           *
92387           * antialias - indicates whether or not to perform anti-ali
92387asing
92388           * default is false (true in Safari)
92389           *
92390           * premultipliedAlpha - indicates that the page compositor will assume
92391           * the drawing buffer contains colors with pre-multiplied alpha
92392           * default is false
92393           *
92394           * preserveDrawingBuffer - if true the buffers will not be cleared and
92395           * and will preserve their values until cleared or overwritten by author
92396           * (note that p5 clears automatically on draw loop)
92397           * default is true
92398           *
92399           * perPixelLighting - if true, per-pixel lighting will be used in the
92400           * lighting shader otherwise per-vertex lighting is used.
92401           * default is true.
92402           *
92403           * @method setAttributes
92404           * @for p5
92405           * @param  {String}  key Name of attribute
92406           * @param  {Boolean}        value New value of named attribute
92407           * @example
92408           * <div>
92409           * <code>
92410           * function setup() {
92411           *   createCanvas(100, 100, WEBGL);
92412           * }
92413           *
92414           * function draw() {
92415           *   background(255);
92416           *   push();
92417           *   rotateZ(frameCount * 0.02);
92418           *   rotateX(frameCount * 0.02);
92419           *   rotateY(frameCount * 0.02);
92420           *   fill(0, 0, 0);
92421           *   box(50);
92422           *   pop();
92423           * }
92424           * </code>
92425           * </div>
92426           * <br>
92427           * Now with the antialias attribute set to true.
92428           * <br>
92429           * <div>
92430           * <code>
92431           * function setup() {
92432           *   setAttributes('antialias', true);
92433           *   createCanvas(100, 100, WEBGL);
92434           * }
92435           *
92436           * function draw() {
92437           *   background(255);
92438           *   push();
92439           *   rotateZ(frameCount * 0.02);
92440           *   rotateX(frameCount * 0.02);
92441           *   rotateY(frameCount * 0.02);
92442           *   fill(0, 0, 0);
92443           *   box(50);
92444           *   pop();
92445           * }
92446           * </code>
92447           * </div>
92448           *
92449           * <div>
92450           * <code>
92451           * // press the mouse button to disable perPixelLighting
92452           * function setup() {
92453           *   createCanvas(100, 100, WEBGL);
92454           *   noStroke();
92455           *   fill(255);
92456           * }
92457           *
92458           * let lights = [
92459           *   { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },
92460           *   { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },
92461           *   { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },
92462           *   { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },
92463           *   { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },
92464           *   { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }
92465           * ];
92466           *
92467           * function draw() {
92468           *   let t = millis() / 1000 + 1000;
92469           *   background(0);
92470           *   directionalLight(color('#222'), 1, 1, 1);
92471           *
92472           *   for (let i = 0; i < lights.length; i++) {
92473           *     let light = lights[i];
92474           *     pointLight(
92475           *       color(light.c),
92476           *       p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)
92477           *     );
92478           *   }
92479           *
92480           *   specularMaterial(255);
92481           *   sphere(width * 0.1);
92482           *
92483           *   rotateX(t * 0.77);
92484           *   rotateY(t * 0.83);
92485           *   rotateZ(t * 0.91);
92486           *   torus(width * 0.3, width * 0.07, 24, 10);
92487           * }
92488           *
92489           * function mousePressed() {
92490           *   setAttributes('perPixelLighting', false);
92491           *   noStroke();
92492           *   fill(255);
92493           * }
92494           * function mouseReleased() {
92495           *   setAttributes('perPixelLighting', true);
92496           *   noStroke();
92497           *   fill(255);
92498           * }
92499           * </code>
92500           * </div>
92501           *
92502           * @alt a rotating cube with smoother edges
92503           */
92504          /**
92505           * @method setAttributes
92506           * @for p5
92507           * @param  {Object}  obj object with key-value pairs
92508           */
92509
92510          _main.default.prototype.setAttributes = function(key, value) {
92511            if (typeof this._glAttributes === 'undefined') {
92512              console.log(
92513                'You are trying to use setAttributes on a p5.Graphics object ' +
92514                  'that does not use a WEBGL renderer.'
92515              );
92516
92517              return;
92518            }
92519            var unchanged = true;
92520            if (typeof value !== 'undefined') {
92521              //first time modifying the attributes
92522              if (this._glAttributes === null) {
92523                this._glAttributes = {};
92524              }
92525              if (this._glAttributes[key] !== value) {
92526                //changing value of previously altered attribute
92527                this._glAttributes[key] = value;
92528                unchanged = false;
92529              }
92530              //setting all attributes with some change
92531            } else if (key instanceof Object) {
92532              if (this._glAttributes !== key) {
92533                this._glAttributes = key;
92534                unchanged = false;
92535              }
92536            }
92537            //@todo_FES
92538            if (!this._renderer.isP3D || unchanged) {
92539              return;
92540            }
92541
92542            if (!this._setupDone) {
92543              for (var x in this._renderer.retainedMode.geometry) {
92544                if (this._renderer.retainedMode.geometry.hasOwnProperty(x)) {
92545                  console.error(
92546                    'Sorry, Could not set the attributes, you need to call setAttributes() ' +
92547                      'before calling the other drawing methods in setup()'
92548                  );
92549
92550                  return;
92551                }
92552              }
92553            }
92554
92555            this.push();
92556            this._renderer._resetContext();
92557            this.pop();
92558
92559            if (this._renderer._curCamera) {
92560              this._renderer._curCamera._renderer = this._renderer;
92561            }
92562          };
92563
92564          /**
92565           * @class p5.RendererGL
92566           */
92567
92568          _main.default.RendererGL.prototype._update = function() {
92569            // reset model view and apply initial camera transform
92570            // (containing only look at info; no projection).
92571            this.uMVMatrix.set(
92572              this._curCamera.cameraMatrix.mat4[0],
92573              this._curCamera.cameraMatrix.mat4[1],
92574              this._curCamera.cameraMatrix.mat4[2],
92575              this._curCamera.cameraMatrix.mat4[3],
92576              this._curCamera.cameraMatrix.mat4[4],
92577              this._curCamera.cameraMatrix.mat4[5],
92578              this._curCamera.cameraMatrix.mat4[6],
92579              this._curCamera.cameraMatrix.mat4[7],
92580              this._curCamera.cameraMatrix.mat4[8],
92581              this._curCamera.cameraMatrix.mat4[9],
92582              this._curCamera.cameraMatrix.mat4[10],
92583              this._curCamera.cameraMatrix.mat4[11],
92584              this._curCamera.cameraMatrix.mat4[12],
92585              this._curCamera.cameraMatrix.mat4[13],
92586              this._curCamera.cameraMatrix.mat4[14],
92587              this._curCamera.cameraMatrix.mat4[15]
92588            );
92589
92590            // reset light data for new frame.
92591
92592            this.ambientLightColors.length = 0;
92593            this.specularColors = [1, 1, 1];
92594
92595            this.directionalLightDirections.length = 0;
92596            this.directionalLightDiffuseColors.length = 0;
92597            this.directionalLightSpecularColors.length = 0;
92598
92599            this.pointLightPositions.length = 0;
92600            this.pointLightDiffuseColors.length = 0;
92601            this.pointLightSpecularColors.length = 0;
92602
92603            this.spotLightPositions.length = 0;
92604            this.spotLightDirections.length = 0;
92605            this.spotLightDiffuseColors.length = 0;
92606            this.spotLightSpecularColors.length = 0;
92607            this.spotLightAngle.length = 0;
92608            this.spotLightConc.length = 0;
92609
92610            this._enableLighting = false;
92611
92612            //reset tint value for new frame
92613            this._tint = [255, 255, 255, 255];
92614
92615            //Clear depth every frame
92616            this.GL.clear(this.GL.DEPTH_BUFFER_BIT);
92617          };
92618
92619          /**
92620           * [background description]
92621           */
92622          _main.default.RendererGL.prototype.background = function() {
92623            var _this$_pInst;
92624            var _col = (_this$_pInst = this._pInst).color.apply(_this$_pInst, arguments);
92625            var _r = _col.levels[0] / 255;
92626            var _g = _col.levels[1] / 255;
92627            var _b = _col.levels[2] / 255;
92628            var _a = _col.levels[3] / 255;
92629            this.GL.clearColor(_r, _g, _b, _a);
92630
92631            this.GL.clear(this.GL.COLOR_BUFFER_BIT);
92632          };
92633
92634          //////////////////////////////////////////////
92635          // COLOR
92636          //////////////////////////////////////////////
92637          /**
92638           * Basic fill material for geometry with a given color
92639           * @method  fill
92640           * @class p5.RendererGL
92641           * @param  {Number|Number[]|String|p5.Color} v1  gray value,
92642           * red or hue value (depending on the current color mode),
92643           * or color Array, or CSS color string
92644           * @param  {Number}            [v2] green or saturation value
92645           * @param  {Number}            [v3] blue or brightness value
92646           * @param  {Number}            [a]  opacity
92647           * @chainable
92648           * @example
92649           * <div>
92650           * <code>
92651           * function setup() {
92652           *   createCanvas(200, 200, WEBGL);
92653           * }
92654           *
92655           * function draw() {
92656           *   background(0);
92657           *   noStroke();
92658           *   fill(100, 100, 240);
92659           *   rotateX(frameCount * 0.01);
92660           *   rotateY(frameCount * 0.01);
92661           *   box(75, 75, 75);
92662           * }
92663           * </code>
92664           * </div>
92665           *
92666           * @alt
92667           * black canvas with purple cube spinning
92668           */
92669          _main.default.RendererGL.prototype.fill = function(v1, v2, v3, a) {
92670            //see material.js for more info on color blending in webgl
92671            var color = _main.default.prototype.color.apply(this._pInst, arguments);
92672            this.curFillColor = color._array;
92673            this.drawMode = constants.FILL;
92674            this._useNormalMaterial = false;
92675            this._tex = null;
92676          };
92677
92678          /**
92679           * Basic stroke material for geometry with a given color
92680           * @method  stroke
92681           * @param  {Number|Number[]|String|p5.Color} v1  gray value,
92682           * red or hue value (depending on the current color mode),
92683           * or color Array, or CSS color string
92684           * @param  {Number}            [v2] green or saturation value
92685           * @param  {Number}            [v3] blue or brightness value
92686           * @param  {Number}            [a]  opacity
92687           * @example
92688           * <div>
92689           * <code>
92690           * function setup() {
92691           *   createCanvas(200, 200, WEBGL);
92692           * }
92693           *
92694           * function draw() {
92695           *   background(0);
92696           *   stroke(240, 150, 150);
92697           *   fill(100, 100, 240);
92698           *   rotateX(frameCount * 0.01);
92699           *   rotateY(frameCount * 0.01);
92700           *   box(75, 75, 75);
92701           * }
92702           * </code>
92703           * </div>
92704           *
92705           * @alt
92706           * black canvas with purple cube with pink outline spinning
92707           */
92708          _main.default.RendererGL.prototype.stroke = function(r, g, b, a) {
92709            //@todo allow transparency in stroking currently doesn't have
92710            //any impact and causes problems with specularMaterial
92711            arguments[3] = 255;
92712            var color = _main.default.prototype.color.apply(this._pInst, arguments);
92713            this.curStrokeColor = color._array;
92714          };
92715
92716          _main.default.RendererGL.prototype.strokeCap = function(cap) {
92717            // @TODO : to be implemented
92718            console.error('Sorry, strokeCap() is not yet implemented in WEBGL mode');
92719          };
92720
92721          _main.default.RendererGL.prototype.strokeJoin = function(join) {
92722            // @TODO : to be implemented
92723            // https://processing.org/reference/strokeJoin_.html
92724            console.error('Sorry, strokeJoin() is not yet implemented in WEBGL mode');
92725          };
92726
92727          _main.default.RendererGL.prototype.filter = function(filterType) {
92728            // filter can be achieved using custom shaders.
92729            // https://github.com/aferriss/p5jsShaderExamples
92730            // https://itp-xstory.github.io/p5js-shaders/#/
92731            console.error('filter() does not work in WEBGL mode');
92732          };
92733
92734          _main.default.RendererGL.prototype.blendMode = function(mode) {
92735            if (
92736              mode === constants.DARKEST ||
92737              mode === constants.LIGHTEST ||
92738              mode === constants.ADD ||
92739              mode === constants.BLEND ||
92740              mode === constants.SUBTRACT ||
92741              mode === constants.SCREEN ||
92742              mode === constants.EXCLUSION ||
92743              mode === constants.REPLACE ||
92744              mode === constants.MULTIPLY ||
92745              mode === constants.REMOVE
92746            )
92747              this.curBlendMode = mode;
92748            else if (
92749              mode === constants.BURN ||
92750              mode === constants.OVERLAY ||
92751              mode === constants.HARD_LIGHT ||
92752              mode === constants.SOFT_LIGHT ||
92753              mode === constants.DODGE
92754            ) {
92755              console.warn(
92756                'BURN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, and DODGE only work for blendMode in 2D mode.'
92757              );
92758            }
92759          };
92760
92761          _main.default.RendererGL.prototype.erase = function(opacityFill, opacityStroke) {
92762            if (!this._isErasing) {
92763              this._applyBlendMode(constants.REMOVE);
92764              this._isErasing = true;
92765
92766              this._cachedFillStyle = this.curFillColor.slice();
92767              this.curFillColor = [1, 1, 1, opacityFill / 255];
92768
92769              this._cachedStrokeStyle = this.curStrokeColor.slice();
92770              this.curStrokeColor = [1, 1, 1, opacityStroke / 255];
92771            }
92772          };
92773
92774          _main.default.RendererGL.prototype.noErase = function() {
92775            if (this._isErasing) {
92776              this._isErasing = false;
92777              this.curFillColor = this._cachedFillStyle.slice();
92778              this.curStrokeColor = this._cachedStrokeStyle.slice();
92779              this.blendMode(this._cachedBlendMode);
92780            }
92781          };
92782
92783          /**
92784           * Change weight of stroke
92785           * @method  strokeWeight
92786           * @param  {Number} stroke weight to be used for drawing
92787           * @example
92788           * <div>
92789           * <code>
92790           * function setup() {
92791           *   createCanvas(200, 400, WEBGL);
92792           *   setAttributes('antialias', true);
92793           * }
92794           *
92795           * function draw() {
92796           *   background(0);
92797           *   noStroke();
92798           *   translate(0, -100, 0);
92799           *   stroke(240, 150, 150);
92800           *   fill(100, 100, 240);
92801           *   push();
92802           *   strokeWeight(8);
92803           *   rotateX(frameCount * 0.01);
92804           *   rotateY(frameCount * 0.01);
92805           *   sphere(75);
92806           *   pop();
92807           *   push();
92808           *   translate(0, 200, 0);
92809           *   strokeWeight(1);
92810           *   rotateX(frameCount * 0.01);
92811           *   rotateY(frameCount * 0.01);
92812           *   sphere(75);
92813           *   pop();
92814           * }
92815           * </code>
92816           * </div>
92817           *
92818           * @alt
92819           * black canvas with two purple rotating spheres with pink
92820           * outlines the sphere on top has much heavier outlines,
92821           */
92822          _main.default.RendererGL.prototype.strokeWeight = function(w) {
92823            if (this.curStrokeWeight !== w) {
92824              this.pointSize = w;
92825              this.curStrokeWeight = w;
92826            }
92827          };
92828
92829          // x,y are canvas-relative (pre-scaled by _pixelDensity)
92830          _main.default.RendererGL.prototype._getPixel = function(x, y) {
92831            var imageData, index;
92832            imageData = new Uint8Array(4);
92833            // prettier-ignore
92834            this.drawingContext.readPixels(
92835  x, y, 1, 1,
92836  this.drawingContext.RGBA, this.drawingContext.UNSIGNED_BYTE,
92837  imageData);
92838
92839            index = 0;
92840            return [
92841              imageData[index + 0],
92842              imageData[index + 1],
92843              imageData[index + 2],
92844              imageData[index + 3]
92845            ];
92846          };
92847
92848          /**
92849           * Loads the pixels data for this canvas into the pixels[] attribute.
92850           * Note that updatePixels() and set() do not work.
92851           * Any pixel manipulation must be done directly to the pixels[] array.
92852           *
92853           * @private
92854           * @method loadPixels
92855           */
92856
92857          _main.default.RendererGL.prototype.loadPixels = function() {
92858            var pixelsState = this._pixelsState;
92859
92860            //@todo_FES
92861            if (this._pInst._glAttributes.preserveDrawingBuffer !== true) {
92862              console.log(
92863                'loadPixels only works in WebGL when preserveDrawingBuffer ' + 'is true.'
92864              );
92865
92866              return;
92867            }
92868
92869            //if there isn't a renderer-level temporary pixels buffer
92870            //make a new one
92871            var pixels = pixelsState.pixels;
92872            var len = this.GL.drawingBufferWidth * this.GL.drawingBufferHeight * 4;
92873            if (!(pixels instanceof Uint8Array) || pixels.length !== len) {
92874              pixels = new Uint8Array(len);
92875              this._pixelsState._setProperty('pixels', pixels);
92876            }
92877
92878            var pd = this._pInst._pixelDensity;
92879            // prettier-ignore
92880            this.GL.readPixels(
92881  0, 0, this.width * pd, this.height * pd,
92882  this.GL.RGBA, this.GL.UNSIGNED_BYTE,
92883  pixels);
92884          };
92885
92886          //////////////////////////////////////////////
92887          // HASH | for geometry
92888          //////////////////////////////////////////////
92889
92890          _main.default.RendererGL.prototype.geometryInHash = function(gId) {
92891            return this.retainedMode.geometry[gId] !== undefined;
92892          };
92893
92894          /**
92895           * [resize description]
92896           * @private
92897           * @param  {Number} w [description]
92898           * @param  {Number} h [description]
92899           */
92900          _main.default.RendererGL.prototype.resize = function(w, h) {
92901            _main.default.Renderer.prototype.resize.call(this, w, h);
92902            this.GL.viewport(0, 0, this.GL.drawingBufferWidth, this.GL.drawingBufferHeight);
92903
92904            this._viewport = this.GL.getParameter(this.GL.VIEWPORT);
92905
92906            this._curCamera._resize();
92907
92908            //resize pixels buffer
92909            var pixelsState = this._pixelsState;
92910            if (typeof pixelsState.pixels !== 'undefined') {
92911              pixelsState._setProperty(
92912                'pixels',
92913                new Uint8Array(this.GL.drawingBufferWidth * this.GL.drawingBufferHeight * 4)
92914              );
92915            }
92916          };
92917
92918          /**
92919           * clears color and depth buffers
92920           * with r,g,b,a
92921           * @private
92922           * @param {Number} r normalized red val.
92923           * @param {Number} g normalized green val.
92924           * @param {Number} b normalized blue val.
92925           * @param {Number} a normalized alpha val.
92926           */
92927          _main.default.RendererGL.prototype.clear = function() {
92928            var _r = (arguments.length <= 0 ? undefined : arguments[0]) || 0;
92929            var _g = (arguments.length <= 1 ? undefined : arguments[1]) || 0;
92930            var _b = (arguments.length <= 2 ? undefined : arguments[2]) || 0;
92931            var _a = (arguments.length <= 3 ? undefined : arguments[3]) || 0;
92932            this.GL.clearColor(_r, _g, _b, _a);
92933            this.GL.clear(this.GL.COLOR_BUFFER_BIT | this.GL.DEPTH_BUFFER_BIT);
92934          };
92935
92936          _main.default.RendererGL.prototype.applyMatrix = function(a, b, c, d, e, f) {
92937            if (arguments.length === 16) {
92938              _main.default.Matrix.prototype.apply.apply(this.uMVMatrix, arguments);
92939            } else {
92940              // prettier-ignore
92941              this.uMVMatrix.apply([
92942    a, b, 0, 0,
92943    c, d, 0, 0,
92944    0, 0, 1, 0,
92945    e, f, 0, 1]);
92946            }
92947          };
92948
92949          /**
92950           * [translate description]
92951           * @private
92952           * @param  {Number} x [description]
92953           * @param  {Number} y [description]
92954           * @param  {Number} z [description]
92955           * @chainable
92956           * @todo implement handle for components or vector as args
92957           */
92958          _main.default.RendererGL.prototype.translate = function(x, y, z) {
92959            if (x instanceof _main.default.Vector) {
92960              z = x.z;
92961              y = x.y;
92962              x = x.x;
92963            }
92964            this.uMVMatrix.translate([x, y, z]);
92965            return this;
92966          };
92967
92968          /**
92969           * Scales the Model View Matrix by a vector
92970           * @private
92971           * @param  {Number | p5.Vector | Array} x [description]
92972           * @param  {Number} [y] y-axis scalar
92973           * @param  {Number} [z] z-axis scalar
92974           * @chainable
92975           */
92976          _main.default.RendererGL.prototype.scale = function(x, y, z) {
92977            this.uMVMatrix.scale(x, y, z);
92978            return this;
92979          };
92980
92981          _main.default.RendererGL.prototype.rotate = function(rad, axis) {
92982            if (typeof axis === 'undefined') {
92983              return this.rotateZ(rad);
92984            }
92985            _main.default.Matrix.prototype.rotate.apply(this.uMVMatrix, arguments);
92986            return this;
92987          };
92988
92989          _main.default.RendererGL.prototype.rotateX = function(rad) {
92990            this.rotate(rad, 1, 0, 0);
92991            return this;
92992          };
92993
92994          _main.default.RendererGL.prototype.rotateY = function(rad) {
92995            this.rotate(rad, 0, 1, 0);
92996            return this;
92997          };
92998
92999          _main.default.RendererGL.prototype.rotateZ = function(rad) {
93000            this.rotate(rad, 0, 0, 1);
93001            return this;
93002          };
93003
93004          _main.default.RendererGL.prototype.push = function() {
93005            // get the base renderer style
93006            var style = _main.default.Renderer.prototype.push.apply(this);
93007
93008            // add webgl-specific style properties
93009            var properties = style.properties;
93010
93011            properties.uMVMatrix = this.uMVMatrix.copy();
93012            properties.uPMatrix = this.uPMatrix.copy();
93013            properties._curCamera = this._curCamera;
93014
93015            // make a copy of the current camera for the push state
93016            // this preserves any references stored using 'createCamera'
93017            this._curCamera = this._curCamera.copy();
93018
93019            properties.ambientLightColors = this.ambientLightColors.slice();
93020            properties.specularColors = this.specularColors.slice();
93021
93022            properties.directionalLightDirections = this.directionalLightDirections.slice();
93023            properties.directionalLightDiffuseColors = this.directionalLightDiffuseColors.slice();
93024            properties.directionalLightSpecularColors = this.directionalLightSpecularColors.slice();
93025
93026            properties.pointLightPositions = this.pointLightPositions.slice();
93027            properties.pointLightDiffuseColors = this.pointLightDiffuseColors.slice();
93028            properties.pointLightSpecularColors = this.pointLightSpecularColors.slice();
93029
93030            properties.spotLightPositions = this.spotLightPositions.slice();
93031            properties.spotLightDirections = this.spotLightDirections.slice();
93032            properties.spotLightDiffuseColors = this.spotLightDiffuseColors.slice();
93033            properties.spotLightSpecularColors = this.spotLightSpecularColors.slice();
93034            properties.spotLightAngle = this.spotLightAngle.slice();
93035            properties.spotLightConc = this.spotLightConc.slice();
93036
93037            properties.userFillShader = this.userFillShader;
93038            properties.userStrokeShader = this.userStrokeShader;
93039            properties.userPointShader = this.userPointShader;
93040
93041            properties.pointSize = this.pointSize;
93042            properties.curStrokeWeight = this.curStrokeWeight;
93043            properties.curStrokeColor = this.curStrokeColor;
93044            properties.curFillColor = this.curFillColor;
93045
93046            properties._useSpecularMaterial = this._useSpecularMaterial;
93047            properties._useEmissiveMaterial = this._useEmissiveMaterial;
93048            properties._useShininess = this._useShininess;
93049
93050            properties.constantAttenuation = this.constantAttenuation;
93051            properties.linearAttenuation = this.linearAttenuation;
93052            properties.quadraticAttenuation = this.quadraticAttenuation;
93053
93054            properties._enableLighting = this._enableLighting;
93055            properties._useNormalMaterial = this._useNormalMaterial;
93056            properties._tex = this._tex;
93057            properties.drawMode = this.drawMode;
93058
93059            return style;
93060          };
93061
93062          _main.default.RendererGL.prototype.resetMatrix = function() {
93063            this.uMVMatrix = _main.default.Matrix.identity(this._pInst);
93064            return this;
93065          };
93066
93067          //////////////////////////////////////////////
93068          // SHADER
93069          //////////////////////////////////////////////
93070
93071          /*
93072 * shaders are created and cached on a per-renderer basis,
93073 * on the grounds that each renderer will have its own gl context
93074 * and the shader must be valid in that context.
93075 */
93076
93077          _main.default.RendererGL.prototype._getImmediateStrokeShader = function() {
93078            // select the stroke shader to use
93079            var stroke = this.userStrokeShader;
93080            if (!stroke || !stroke.isStrokeShader()) {
93081              return this._getLineShader();
93082            }
93083            return stroke;
93084          };
93085
93086          _main.default.RendererGL.prototype._getRetainedStrokeShader =
93087            _main.default.RendererGL.prototype._getImmediateStrokeShader;
93088
93089          /*
93090                                                               * selects which fill shader should be used based on renderer state,
93091                                                               * for use with begin/endShape and immediate vertex mode.
93092                                                               */
93093          _main.default.RendererGL.prototype._getImmediateFillShader = function() {
93094            var fill = this.userFillShader;
93095            if (this._useNormalMaterial) {
93096              if (!fill || !fill.isNormalShader()) {
93097                return this._getNormalShader();
93098              }
93099            }
93100            if (this._enableLighting) {
93101              if (!fill || !fill.isLightShader()) {
93102                return this._getLightShader();
93103              }
93104            } else if (this._tex) {
93105              if (!fill || !fill.isTextureShader()) {
93106                return this._getLightShader();
93107              }
93108            } else if (!fill /*|| !fill.isColorShader()*/) {
93109              return this._getImmediateModeShader();
93110            }
93111            return fill;
93112          };
93113
93114          /*
93115    * selects which fill shader should be used based on renderer state
93116    * for retained mode.
93117    */
93118          _main.default.RendererGL.prototype._getRetainedFillShader = function() {
93119            if (this._useNormalMaterial) {
93120              return this._getNormalShader();
93121            }
93122
93123            var fill = this.userFillShader;
93124            if (this._enableLighting) {
93125              if (!fill || !fill.isLightShader()) {
93126                return this._getLightShader();
93127              }
93128            } else if (this._tex) {
93129              if (!fill || !fill.isTextureShader()) {
93130                return this._getLightShader();
93131              }
93132            } else if (!fill /* || !fill.isColorShader()*/) {
93133              return this._getColorShader();
93134            }
93135            return fill;
93136          };
93137
93138          _main.default.RendererGL.prototype._getImmediatePointShader = function() {
93139            // select the point shader to use
93140            var point = this.userPointShader;
93141            if (!point || !point.isPointShader()) {
93142              return this._getPointShader();
93143            }
93144            return point;
93145          };
93146
93147          _main.default.RendererGL.prototype._getRetainedLineShader =
93148            _main.default.RendererGL.prototype._getImmediateLineShader;
93149
93150          _main.default.RendererGL.prototype._getLightShader = function() {
93151            if (!this._defaultLightShader) {
93152              if (this._pInst._glAttributes.perPixelLighting) {
93153                this._defaultLightShader = new _main.default.Shader(
93154                  this,
93155                  defaultShaders.phongVert,
93156                  defaultShaders.phongFrag
93157                );
93158              } else {
93159                this._defaultLightShader = new _main.default.Shader(
93160                  this,
93161                  defaultShaders.lightVert,
93162                  defaultShaders.lightTextureFrag
93163                );
93164              }
93165            }
93166
93167            return this._defaultLightShader;
93168          };
93169
93170          _main.default.RendererGL.prototype._getImmediateModeShader = function() {
93171            if (!this._defaultImmediateModeShader) {
93172              this._defaultImmediateModeShader = new _main.default.Shader(
93173                this,
93174                defaultShaders.immediateVert,
93175                defaultShaders.vertexColorFrag
93176              );
93177            }
93178
93179            return this._defaultImmediateModeShader;
93180          };
93181
93182          _main.default.RendererGL.prototype._getNormalShader = function() {
93183            if (!this._defaultNormalShader) {
93184              this._defaultNormalShader = new _main.default.Shader(
93185                this,
93186                defaultShaders.normalVert,
93187                defaultShaders.normalFrag
93188              );
93189            }
93190
93191            return this._defaultNormalShader;
93192          };
93193
93194          _main.default.RendererGL.prototype._getColorShader = function() {
93195            if (!this._defaultColorShader) {
93196              this._defaultColorShader = new _main.default.Shader(
93197                this,
93198                defaultShaders.normalVert,
93199                defaultShaders.basicFrag
93200              );
93201            }
93202
93203            return this._defaultColorShader;
93204          };
93205
93206          _main.default.RendererGL.prototype._getPointShader = function() {
93207            if (!this._defaultPointShader) {
93208              this._defaultPointShader = new _main.default.Shader(
93209                this,
93210                defaultShaders.pointVert,
93211                defaultShaders.pointFrag
93212              );
93213            }
93214            return this._defaultPointShader;
93215          };
93216
93217          _main.default.RendererGL.prototype._getLineShader = function() {
93218            if (!this._defaultLineShader) {
93219              this._defaultLineShader = new _main.default.Shader(
93220                this,
93221                defaultShaders.lineVert,
93222                defaultShaders.lineFrag
93223              );
93224            }
93225
93226            return this._defaultLineShader;
93227          };
93228
93229          _main.default.RendererGL.prototype._getFontShader = function() {
93230            if (!this._defaultFontShader) {
93231              this.GL.getExtension('OES_standard_derivatives');
93232              this._defaultFontShader = new _main.default.Shader(
93233                this,
93234                defaultShaders.fontVert,
93235                defaultShaders.fontFrag
93236              );
93237            }
93238            return this._defaultFontShader;
93239          };
93240
93241          _main.default.RendererGL.prototype._getEmptyTexture = function() {
93242            if (!this._emptyTexture) {
93243              // a plain white texture RGBA, full alpha, single pixel.
93244              var im = new _main.default.Image(1, 1);
93245              im.set(0, 0, 255);
93246              this._emptyTexture = new _main.default.Texture(this, im);
93247            }
93248            return this._emptyTexture;
93249          };
93250
93251          _main.default.RendererGL.prototype.getTexture = function(img) {
93252            var textures = this.textures;
93253            var _iteratorNormalCompletion = true;
93254            var _didIteratorError = false;
93255            var _iteratorError = undefined;
93256            try {
93257              for (
93258                var _iterator = textures[Symbol.iterator](), _step;
93259                !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
93260                _iteratorNormalCompletion = true
93261              ) {
93262                var texture = _step.value;
93263                if (texture.src === img) return texture;
93264              }
93265            } catch (err) {
93266              _didIteratorError = true;
93267              _iteratorError = err;
93268            } finally {
93269              try {
93270                if (!_iteratorNormalCompletion && _iterator.return != null) {
93271                  _iterator.return();
93272                }
93273              } finally {
93274                if (_didIteratorError) {
93275                  throw _iteratorError;
93276                }
93277              }
93278            }
93279
93280            var tex = new _main.default.Texture(this, img);
93281            textures.push(tex);
93282            return tex;
93283          };
93284
93285          _main.default.RendererGL.prototype._setStrokeUniforms = function(strokeShader) {
93286            strokeShader.bindShader();
93287
93288            // set the uniform values
93289            strokeShader.setUniform('uMaterialColor', this.curStrokeColor);
93290            strokeShader.setUniform('uStrokeWeight', this.curStrokeWeight);
93291          };
93292
93293          _main.default.RendererGL.prototype._setFillUniforms = function(fillShader) {
93294            fillShader.bindShader();
93295
93296            // TODO: optimize
93297            fillShader.setUniform('uMaterialColor', this.curFillColor);
93298            fillShader.setUniform('isTexture', !!this._tex);
93299            if (this._tex) {
93300              fillShader.setUniform('uSampler', this._tex);
93301            }
93302            fillShader.setUniform('uTint', this._tint);
93303
93304            fillShader.setUniform('uSpecular', this._useSpecularMaterial);
93305            fillShader.setUniform('uEmissive', this._useEmissiveMaterial);
93306            fillShader.setUniform('uShininess', this._useShininess);
93307
93308            fillShader.setUniform('uUseLighting', this._enableLighting);
93309
93310            var pointLightCount = this.pointLightDiffuseColors.length / 3;
93311            fillShader.setUniform('uPointLightCount', pointLightCount);
93312            fillShader.setUniform('uPointLightLocation', this.pointLightPositions);
93313            fillShader.setUniform('uPointLightDiffuseColors', this.pointLightDiffuseColors);
93314
93315            fillShader.setUniform(
93316              'uPointLightSpecularColors',
93317              this.pointLightSpecularColors
93318            );
93319
93320            var directionalLightCount = this.directionalLightDiffuseColors.length / 3;
93321            fillShader.setUniform('uDirectionalLightCount', directionalLightCount);
93322            fillShader.setUniform('uLightingDirection', this.directionalLightDirections);
93323            fillShader.setUniform(
93324              'uDirectionalDiffuseColors',
93325              this.directionalLightDiffuseColors
93326            );
93327
93328            fillShader.setUniform(
93329              'uDirectionalSpecularColors',
93330              this.directionalLightSpecularColors
93331            );
93332
93333            // TODO: sum these here...
93334            var ambientLightCount = this.ambientLightColors.length / 3;
93335            fillShader.setUniform('uAmbientLightCount', ambientLightCount);
93336            fillShader.setUniform('uAmbientColor', this.ambientLightColors);
93337
93338            var spotLightCount = this.spotLightDiffuseColors.length / 3;
93339            fillShader.setUniform('uSpotLightCount', spotLightCount);
93340            fillShader.setUniform('uSpotLightAngle', this.spotLightAngle);
93341            fillShader.setUniform('uSpotLightConc', this.spotLightConc);
93342            fillShader.setUniform('uSpotLightDiffuseColors', this.spotLightDiffuseColors);
93343            fillShader.setUniform('uSpotLightSpecularColors', this.spotLightSpecularColors);
93344
93345            fillShader.setUniform('uSpotLightLocation', this.spotLightPositions);
93346            fillShader.setUniform('uSpotLightDirection', this.spotLightDirections);
93347
93348            fillShader.setUniform('uConstantAttenuation', this.constantAttenuation);
93349            fillShader.setUniform('uLinearAttenuation', this.linearAttenuation);
93350            fillShader.setUniform('uQuadraticAttenuation', this.quadraticAttenuation);
93351
93352            fillShader.bindTextures();
93353          };
93354
93355          _main.default.RendererGL.prototype._setPointUniforms = function(pointShader) {
93356            pointShader.bindShader();
93357
93358            // set the uniform values
93359            pointShader.setUniform('uMaterialColor', this.curStrokeColor);
93360            // @todo is there an instance where this isn't stroke weight?
93361            // should be they be same var?
93362            pointShader.setUniform(
93363              'uPointSize',
93364              this.pointSize * this._pInst._pixelDensity
93365            );
93366          };
93367
93368          /* Binds a buffer to the drawing context
93369    * when passed more than two arguments it also updates or initializes
93370    * the data associated with the buffer
93371    */
93372          _main.default.RendererGL.prototype._bindBuffer = function(
93373            buffer,
93374            target,
93375            values,
93376            type,
93377            usage
93378          ) {
93379            if (!target) target = this.GL.ARRAY_BUFFER;
93380            this.GL.bindBuffer(target, buffer);
93381            if (values !== undefined) {
93382              var data = new (type || Float32Array)(values);
93383              this.GL.bufferData(target, data, usage || this.GL.STATIC_DRAW);
93384            }
93385          };
93386
93387          ///////////////////////////////
93388          //// UTILITY FUNCTIONS
93389          //////////////////////////////
93390          _main.default.RendererGL.prototype._arraysEqual = function(a, b) {
93391            var aLength = a.length;
93392            if (aLength !== b.length) return false;
93393            for (var i = 0; i < aLength; i++) {
93394              if (a[i] !== b[i]) return false;
93395            }
93396            return true;
93397          };
93398
93399          _main.default.RendererGL.prototype._isTypedArray = function(arr) {
93400            var res = false;
93401            res = arr instanceof Float32Array;
93402            res = arr instanceof Float64Array;
93403            res = arr instanceof Int16Array;
93404            res = arr instanceof Uint16Array;
93405            res = arr instanceof Uint32Array;
93406            return res;
93407          };
93408          /**
93409           * turn a two dimensional array into one dimensional array
93410           * @private
93411           * @param  {Array} arr 2-dimensional array
93412           * @return {Array}     1-dimensional array
93413           * [[1, 2, 3],[4, 5, 6]] -> [1, 2, 3, 4, 5, 6]
93414           */
93415          _main.default.RendererGL.prototype._flatten = function(arr) {
93416            //when empty, return empty
93417            if (arr.length === 0) {
93418              return [];
93419            } else if (arr.length > 20000) {
93420              //big models , load slower to avoid stack overflow
93421              //faster non-recursive flatten via axelduch
93422              //stackoverflow.com/questions/27266550/how-to-flatten-nested-array-in-javascript
93423              var _toString = Object.prototype.toString;
93424              var arrayTypeStr = '[object Array]';
93425              var result = [];
93426              var nodes = arr.slice();
93427              var node;
93428              node = nodes.pop();
93429              do {
93430                if (_toString.call(node) === arrayTypeStr) {
93431                  nodes.push.apply(nodes, _toConsumableArray(node));
93432                } else {
93433                  result.push(node);
93434                }
93435              } while (nodes.length && (node = nodes.pop()) !== undefined);
93436              result.reverse(); // we reverse result to restore the original order
93437              return result;
93438            } else {
93439              var _ref;
93440              //otherwise if model within limits for browser
93441              //use faster recursive loading
93442              return (_ref = []).concat.apply(_ref, _toConsumableArray(arr));
93443            }
93444          };
93445
93446          /**
93447           * turn a p5.Vector Array into a one dimensional number array
93448           * @private
93449           * @param  {p5.Vector[]} arr  an array of p5.Vector
93450           * @return {Number[]}     a one dimensional array of numbers
93451           * [p5.Vector(1, 2, 3), p5.Vector(4, 5, 6)] ->
93452           * [1, 2, 3, 4, 5, 6]
93453           */
93454          _main.default.RendererGL.prototype._vToNArray = function(arr) {
93455            var ret = [];
93456            var _iteratorNormalCompletion2 = true;
93457            var _didIteratorError2 = false;
93458            var _iteratorError2 = undefined;
93459            try {
93460              for (
93461                var _iterator2 = arr[Symbol.iterator](), _step2;
93462                !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done);
93463                _iteratorNormalCompletion2 = true
93464              ) {
93465                var item = _step2.value;
93466                ret.push(item.x, item.y, item.z);
93467              }
93468            } catch (err) {
93469              _didIteratorError2 = true;
93470              _iteratorError2 = err;
93471            } finally {
93472              try {
93473                if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
93474                  _iterator2.return();
93475                }
93476              } finally {
93477                if (_didIteratorError2) {
93478                  throw _iteratorError2;
93479                }
93480              }
93481            }
93482
93483            return ret;
93484          };
93485
93486          /**
93487           * ensures that p5 is using a 3d renderer. throws an error if not.
93488           */
93489          _main.default.prototype._assert3d = function(name) {
93490            if (!this._renderer.isP3D)
93491              throw new Error(
93492                ''.concat(
93493                  name,
93494                  "() is only supported in WEBGL mode. If you'd like to use 3D graphics and WebGL, see  https://p5js.org/examples/form-3d-primitives.html for more information."
93495                )
93496              );
93497          };
93498
93499          // function to initialize GLU Tesselator
93500
93501          _main.default.RendererGL.prototype._initTessy = function initTesselator() {
93502            // function called for each vertex of tesselator output
93503            function vertexCallback(data, polyVertArray) {
93504              polyVertArray[polyVertArray.length] = data[0];
93505              polyVertArray[polyVertArray.length] = data[1];
93506              polyVertArray[polyVertArray.length] = data[2];
93507            }
93508
93509            function begincallback(type) {
93510              if (type !== _libtess.default.primitiveType.GL_TRIANGLES) {
93511                console.log('expected TRIANGLES but got type: '.concat(type));
93512              }
93513            }
93514
93515            function errorcallback(errno) {
93516              console.log('error callback');
93517              console.log('error number: '.concat(errno));
93518            }
93519            // callback for when segments intersect and must be split
93520            function combinecallback(coords, data, weight) {
93521              return [coords[0], coords[1], coords[2]];
93522            }
93523
93524            function edgeCallback(flag) {
93525              // don't really care about the flag, but need no-strip/no-fan behavior
93526            }
93527
93528            var tessy = new _libtess.default.GluTesselator();
93529            tessy.gluTessCallback(
93530              _libtess.default.gluEnum.GLU_TESS_VERTEX_DATA,
93531              vertexCallback
93532            );
93533            tessy.gluTessCallback(_libtess.default.gluEnum.GLU_TESS_BEGIN, begincallback);
93534            tessy.gluTessCallback(_libtess.default.gluEnum.GLU_TESS_ERROR, errorcallback);
93535            tessy.gluTessCallback(
93536              _libtess.default.gluEnum.GLU_TESS_COMBINE,
93537              combinecallback
93538            );
93539            tessy.gluTessCallback(
93540              _libtess.default.gluEnum.GLU_TESS_EDGE_FLAG,
93541              edgeCallback
93542            );
93543
93544            return tessy;
93545          };
93546
93547          _main.default.RendererGL.prototype._triangulate = function(contours) {
93548            // libtess will take 3d verts and flatten to a plane for tesselation
93549            // since only doing 2d tesselation here, provide z=1 normal to skip
93550            // iterating over verts only to get the same answer.
93551            // comment out to test normal-generation code
93552            this._tessy.gluTessNormal(0, 0, 1);
93553
93554            var triangleVerts = [];
93555            this._tessy.gluTessBeginPolygon(triangleVerts);
93556
93557            for (var i = 0; i < contours.length; i++) {
93558              this._tessy.gluTessBeginContour();
93559              var contour = contours[i];
93560              for (var j = 0; j < contour.length; j += 3) {
93561                var coords = [contour[j], contour[j + 1], contour[j + 2]];
93562                this._tessy.gluTessVertex(coords, coords);
93563              }
93564              this._tessy.gluTessEndContour();
93565            }
93566
93567            // finish polygon
93568            this._tessy.gluTessEndPolygon();
93569
93570            return triangleVerts;
93571          };
93572
93573          // function to calculate BezierVertex Coefficients
93574          _main.default.RendererGL.prototype._bezierCoefficients = function(t) {
93575            var t2 = t * t;
93576            var t3 = t2 * t;
93577            var mt = 1 - t;
93578            var mt2 = mt * mt;
93579            var mt3 = mt2 * mt;
93580            return [mt3, 3 * mt2 * t, 3 * mt * t2, t3];
93581          };
93582
93583          // function to calculate QuadraticVertex Coefficients
93584          _main.default.RendererGL.prototype._quadraticCoefficients = function(t) {
93585            var t2 = t * t;
93586            var mt = 1 - t;
93587            var mt2 = mt * mt;
93588            return [mt2, 2 * mt * t, t2];
93589          };
93590
93591          // function to convert Bezier coordinates to Catmull Rom Splines
93592          _main.default.RendererGL.prototype._bezierToCatmull = function(w) {
93593            var p1 = w[1];
93594            var p2 = w[1] + (w[2] - w[0]) / this._curveTightness;
93595            var p3 = w[2] - (w[3] - w[1]) / this._curveTightness;
93596            var p4 = w[2];
93597            var p = [p1, p2, p3, p4];
93598            return p;
93599          };
93600          var _default = _main.default.RendererGL;
93601          exports.default = _default;
93602        },
93603        {
93604          '../core/constants': 48,
93605          '../core/main': 59,
93606          '../core/p5.Renderer': 62,
93607          './p5.Camera': 107,
93608          './p5.Matrix': 109,
93609          './p5.Shader': 114,
93610          libtess: 32,
93611          path: 35
93612        }
93613      ],
93614      114: [
93615        function(_dereq_, module, exports) {
93616          'use strict';
93617          Object.defineProperty(exports, '__esModule', { value: true });
93618          exports.default = void 0;
93619
93620          var _main = _interopRequireDefault(_dereq_('../core/main'));
93621          function _interopRequireDefault(obj) {
93622            return obj && obj.__esModule ? obj : { default: obj };
93623          }
93624          /**
93625           * This module defines the p5.Shader class
93626           * @module Lights, Camera
93627           * @submodule Material
93628           * @for p5
93629           * @requires core
93630           */ /**
93631           * Shader class for WEBGL Mode
93632           * @class p5.Shader
93633           * @constructor
93634           * @param {p5.RendererGL} renderer an instance of p5.RendererGL that
93635           * will provide the GL context for this new p5.Shader
93636           * @param {String} vertSrc source code for the vertex shader (as a string)
93637           * @param {String} fragSrc source code for the fragment shader (as a string)
93638           */ _main.default.Shader = function(renderer, vertSrc, fragSrc) {
93639            // TODO: adapt this to not take ids, but rather,
93640            // to take the source for a vertex and fragment shader
93641            // to enable custom shaders at some later date
93642            this._renderer = renderer;
93643            this._vertSrc = vertSrc;
93644            this._fragSrc = fragSrc;
93645            this._vertShader = -1;
93646            this._fragShader = -1;
93647            this._glProgram = 0;
93648            this._loadedAttributes = false;
93649            this.attributes = {};
93650            this._loadedUniforms = false;
93651            this.uniforms = {};
93652            this._bound = false;
93653            this.samplers = [];
93654          };
93655
93656          /**
93657           * Creates, compiles, and links the shader based on its
93658           * sources for the vertex and fragment shaders (provided
93659           * to the constructor). Populates known attributes and
93660           * uniforms from the shader.
93661           * @method init
93662           * @chainable
93663           * @private
93664           */
93665          _main.default.Shader.prototype.init = function() {
93666            if (this._glProgram === 0 /* or context is stale? */) {
93667              var gl = this._renderer.GL;
93668
93669              // @todo: once custom shading is allowed,
93670              // friendly error messages should be used here to share
93671              // compiler and linker errors.
93672
93673              //set up the shader by
93674              // 1. creating and getting a gl id for the shader program,
93675              // 2. compliling its vertex & fragment sources,
93676              // 3. linking the vertex and fragment shaders
93677              this._vertShader = gl.createShader(gl.VERTEX_SHADER);
93678              //load in our default vertex shader
93679              gl.shaderSource(this._vertShader, this._vertSrc);
93680              gl.compileShader(this._vertShader);
93681              // if our vertex shader failed compilation?
93682              if (!gl.getShaderParameter(this._vertShader, gl.COMPILE_STATUS)) {
93683                console.error(
93684                  'Yikes! An error occurred compiling the vertex shader:'.concat(
93685                    gl.getShaderInfoLog(this._vertShader)
93686                  )
93687                );
93688
93689                return null;
93690              }
93691
93692              this._fragShader = gl.createShader(gl.FRAGMENT_SHADER);
93693              //load in our material frag shader
93694              gl.shaderSource(this._fragShader, this._fragSrc);
93695              gl.compileShader(this._fragShader);
93696              // if our frag shader failed compilation?
93697              if (!gl.getShaderParameter(this._fragShader, gl.COMPILE_STATUS)) {
93698                console.error(
93699                  'Darn! An error occurred compiling the fragment shader:'.concat(
93700                    gl.getShaderInfoLog(this._fragShader)
93701                  )
93702                );
93703
93704                return null;
93705              }
93706
93707              this._glProgram = gl.createProgram();
93708              gl.attachShader(this._glProgram, this._vertShader);
93709              gl.attachShader(this._glProgram, this._fragShader);
93710              gl.linkProgram(this._glProgram);
93711              if (!gl.getProgramParameter(this._glProgram, gl.LINK_STATUS)) {
93712                console.error(
93713                  'Snap! Error linking shader program: '.concat(
93714                    gl.getProgramInfoLog(this._glProgram)
93715                  )
93716                );
93717              }
93718
93719              this._loadAttributes();
93720              this._loadUniforms();
93721            }
93722            return this;
93723          };
93724
93725          /**
93726           * Queries the active attributes for this shader and loads
93727           * their names and locations into the attributes array.
93728           * @method _loadAttributes
93729           * @private
93730           */
93731          _main.default.Shader.prototype._loadAttributes = function() {
93732            if (this._loadedAttributes) {
93733              return;
93734            }
93735
93736            this.attributes = {};
93737
93738            var gl = this._renderer.GL;
93739
93740            var numAttributes = gl.getProgramParameter(
93741              this._glProgram,
93742              gl.ACTIVE_ATTRIBUTES
93743            );
93744
93745            for (var i = 0; i < numAttributes; ++i) {
93746              var attributeInfo = gl.getActiveAttrib(this._glProgram, i);
93747              var name = attributeInfo.name;
93748              var location = gl.getAttribLocation(this._glProgram, name);
93749              var attribute = {};
93750              attribute.name = name;
93751              attribute.location = location;
93752              attribute.index = i;
93753              attribute.type = attributeInfo.type;
93754              attribute.size = attributeInfo.size;
93755              this.attributes[name] = attribute;
93756            }
93757
93758            this._loadedAttributes = true;
93759          };
93760
93761          /**
93762           * Queries the active uniforms for this shader and loads
93763           * their names and locations into the uniforms array.
93764           * @method _loadUniforms
93765           * @private
93766           */
93767          _main.default.Shader.prototype._loadUniforms = function() {
93768            if (this._loadedUniforms) {
93769              return;
93770            }
93771
93772            var gl = this._renderer.GL;
93773
93774            // Inspect shader and cache uniform info
93775            var numUniforms = gl.getProgramParameter(this._glProgram, gl.ACTIVE_UNIFORMS);
93776
93777            var samplerIndex = 0;
93778            for (var i = 0; i < numUniforms; ++i) {
93779              var uniformInfo = gl.getActiveUniform(this._glProgram, i);
93780              var uniform = {};
93781              uniform.location = gl.getUniformLocation(this._glProgram, uniformInfo.name);
93782              uniform.size = uniformInfo.size;
93783              var uniformName = uniformInfo.name;
93784              //uniforms thats are arrays have their name returned as
93785              //someUniform[0] which is a bit silly so we trim it
93786              //off here. The size property tells us that its an array
93787              //so we dont lose any information by doing this
93788              if (uniformInfo.size > 1) {
93789                uniformName = uniformName.substring(0, uniformName.indexOf('[0]'));
93790              }
93791              uniform.name = uniformName;
93792              uniform.type = uniformInfo.type;
93793              uniform._cachedData = undefined;
93794              if (uniform.type === gl.SAMPLER_2D) {
93795                uniform.samplerIndex = samplerIndex;
93796                samplerIndex++;
93797                this.samplers.push(uniform);
93798              }
93799              uniform.isArray =
93800                uniform.type === gl.FLOAT_MAT3 ||
93801                uniform.type === gl.FLOAT_MAT4 ||
93802                uniform.type === gl.FLOAT_VEC2 ||
93803                uniform.type === gl.FLOAT_VEC3 ||
93804                uniform.type === gl.FLOAT_VEC4 ||
93805                uniform.type === gl.INT_VEC2 ||
93806                uniform.type === gl.INT_VEC3 ||
93807                uniform.type === gl.INT_VEC4;
93808
93809              this.uniforms[uniformName] = uniform;
93810            }
93811            this._loadedUniforms = true;
93812          };
93813
93814          _main.default.Shader.prototype.compile = function() {
93815            // TODO
93816          };
93817
93818          /**
93819           * initializes (if needed) and binds the shader program.
93820           * @method bindShader
93821           * @private
93822           */
93823          _main.default.Shader.prototype.bindShader = function() {
93824            this.init();
93825            if (!this._bound) {
93826              this.useProgram();
93827              this._bound = true;
93828
93829              this._setMatrixUniforms();
93830
93831              this.setUniform('uViewport', this._renderer._viewport);
93832            }
93833          };
93834
93835          /**
93836           * @method unbindShader
93837           * @chainable
93838           * @private
93839           */
93840          _main.default.Shader.prototype.unbindShader = function() {
93841            if (this._bound) {
93842              this.unbindTextures();
93843              //this._renderer.GL.useProgram(0); ??
93844              this._bound = false;
93845            }
93846            return this;
93847          };
93848
93849          _main.default.Shader.prototype.bindTextures = function() {
93850            var gl = this._renderer.GL;
93851            var _iteratorNormalCompletion = true;
93852            var _didIteratorError = false;
93853            var _iteratorError = undefined;
93854            try {
93855              for (
93856                var _iterator = this.samplers[Symbol.iterator](), _step;
93857                !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
93858                _iteratorNormalCompletion = true
93859              ) {
93860                var uniform = _step.value;
93861                var tex = uniform.texture;
93862                if (tex === undefined) {
93863                  // user hasn't yet supplied a texture for this slot.
93864                  // (or there may not be one--maybe just lighting),
93865                  // so we supply a default texture instead.
93866                  tex = this._renderer._getEmptyTexture();
93867                }
93868                gl.activeTexture(gl.TEXTURE0 + uniform.samplerIndex);
93869                tex.bindTexture();
93870                tex.update();
93871                gl.uniform1i(uniform.location, uniform.samplerIndex);
93872              }
93873            } catch (err) {
93874              _didIteratorError = true;
93875              _iteratorError = err;
93876            } finally {
93877              try {
93878                if (!_iteratorNormalCompletion && _iterator.return != null) {
93879                  _iterator.return();
93880                }
93881              } finally {
93882                if (_didIteratorError) {
93883                  throw _iteratorError;
93884                }
93885              }
93886            }
93887          };
93888
93889          _main.default.Shader.prototype.updateTextures = function() {
93890            var _iteratorNormalCompletion2 = true;
93891            var _didIteratorError2 = false;
93892            var _iteratorError2 = undefined;
93893            try {
93894              for (
93895                var _iterator2 = this.samplers[Symbol.iterator](), _step2;
93896                !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done);
93897                _iteratorNormalCompletion2 = true
93898              ) {
93899                var uniform = _step2.value;
93900                var tex = uniform.texture;
93901                if (tex) {
93902                  tex.update();
93903                }
93904              }
93905            } catch (err) {
93906              _didIteratorError2 = true;
93907              _iteratorError2 = err;
93908            } finally {
93909              try {
93910                if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
93911                  _iterator2.return();
93912                }
93913              } finally {
93914                if (_didIteratorError2) {
93915                  throw _iteratorError2;
93916                }
93917              }
93918            }
93919          };
93920
93921          _main.default.Shader.prototype.unbindTextures = function() {
93922            // TODO: migrate stuff from material.js here
93923            // - OR - have material.js define this function
93924          };
93925
93926          _main.default.Shader.prototype._setMatrixUniforms = function() {
93927            this.setUniform('uProjectionMatrix', this._renderer.uPMatrix.mat4);
93928            if (this.isStrokeShader()) {
93929              if (this._renderer._curCamera.cameraType === 'default') {
93930                // strokes scale up as they approach camera, default
93931                this.setUniform('uPerspective', 1);
93932              } else {
93933                // strokes have uniform scale regardless of distance from camera
93934                this.setUniform('uPerspective', 0);
93935              }
93936            }
93937            this.setUniform('uModelViewMatrix', this._renderer.uMVMatrix.mat4);
93938            this.setUniform('uViewMatrix', this._renderer._curCamera.cameraMatrix.mat4);
93939            if (this.uniforms.uNormalMatrix) {
93940              this._renderer.uNMatrix.inverseTranspose(this._renderer.uMVMatrix);
93941              this.setUniform('uNormalMatrix', this._renderer.uNMatrix.mat3);
93942            }
93943          };
93944
93945          /**
93946           * @method useProgram
93947           * @chainable
93948           * @private
93949           */
93950          _main.default.Shader.prototype.useProgram = function() {
93951            var gl = this._renderer.GL;
93952            if (this._renderer._curShader !== this) {
93953              gl.useProgram(this._glProgram);
93954              this._renderer._curShader = this;
93955            }
93956            return this;
93957          };
93958
93959          /**
93960           * Wrapper around gl.uniform functions.
93961           * As we store uniform info in the shader we can use that
93962           * to do type checking on the supplied data and call
93963           * the appropriate function.
93964           * @method setUniform
93965           * @chainable
93966           * @param {String} uniformName the name of the uniform in the
93967           * shader program
93968           * @param {Object|Number|Boolean|Number[]} data the data to be associated
93969           * with that uniform; type varies (could be a single numerical value, array,
93970           * matrix, or texture / sampler reference)
93971           *
93972           * @example
93973           * <div modernizr='webgl'>
93974           * <code>
93975           * // Click within the image to toggle the value of uniforms
93976           * // Note: for an alternative approach to the same example,
93977           * // involving toggling between shaders please refer to:
93978           * // https://p5js.org/reference/#/p5/shader
93979           *
93980           * let grad;
93981           * let showRedGreen = false;
93982           *
93983           * function preload() {
93984           *   // note that we are using two instances
93985           *   // of the same vertex and fragment shaders
93986           *   grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');
93987           * }
93988           *
93989           * function setup() {
93990           *   createCanvas(100, 100, WEBGL);
93991           *   shader(grad);
93992           *   noStroke();
93993           * }
93994           *
93995           * function draw() {
93996           *   // update the offset values for each scenario,
93997           *   // moving the "grad" shader in either vertical or
93998           *   // horizontal direction each with differing colors
93999           *
94000           *   if (showRedGreen === true) {
94001           *     grad.setUniform('colorCenter', [1, 0, 0]);
94002           *     grad.setUniform('colorBackground', [0, 1, 0]);
94003           *     grad.setUniform('offset', [sin(millis() / 2000), 1]);
94004           *   } else {
94005           *     grad.setUniform('colorCenter', [1, 0.5, 0]);
94006           *     grad.setUniform('colorBackground', [0.226, 0, 0.615]);
94007           *     grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);
94008           *   }
94009           *   quad(-1, -1, 1, -1, 1, 1, -1, 1);
94010           * }
94011           *
94012           * function mouseClicked() {
94013           *   showRedGreen = !showRedGreen;
94014           * }
94015           * </code>
94016           * </div>
94017           *
94018           * @alt
94019           * canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.
94020           */
94021          _main.default.Shader.prototype.setUniform = function(uniformName, data) {
94022            var uniform = this.uniforms[uniformName];
94023            if (!uniform) {
94024              return;
94025            }
94026            var gl = this._renderer.GL;
94027
94028            if (uniform.isArray) {
94029              if (
94030                uniform._cachedData &&
94031                this._renderer._arraysEqual(uniform._cachedData, data)
94032              ) {
94033                return;
94034              } else {
94035                uniform._cachedData = data.slice(0);
94036              }
94037            } else if (uniform._cachedData && uniform._cachedData === data) {
94038              return;
94039            } else {
94040              uniform._cachedData = data;
94041            }
94042
94043            var location = uniform.location;
94044
94045            this.useProgram();
94046
94047            switch (uniform.type) {
94048              case gl.BOOL:
94049                if (data === true) {
94050                  gl.uniform1i(location, 1);
94051                } else {
94052                  gl.uniform1i(location, 0);
94053                }
94054                break;
94055              case gl.INT:
94056                if (uniform.size > 1) {
94057                  data.length && gl.uniform1iv(location, data);
94058                } else {
94059                  gl.uniform1i(location, data);
94060                }
94061                break;
94062              case gl.FLOAT:
94063                if (uniform.size > 1) {
94064                  data.length && gl.uniform1fv(location, data);
94065                } else {
94066                  gl.uniform1f(location, data);
94067                }
94068                break;
94069              case gl.FLOAT_MAT3:
94070                gl.uniformMatrix3fv(location, false, data);
94071                break;
94072              case gl.FLOAT_MAT4:
94073                gl.uniformMatrix4fv(location, false, data);
94074                break;
94075              case gl.FLOAT_VEC2:
94076                if (uniform.size > 1) {
94077                  data.length && gl.uniform2fv(location, data);
94078                } else {
94079                  gl.uniform2f(location, data[0], data[1]);
94080                }
94081                break;
94082              case gl.FLOAT_VEC3:
94083                if (uniform.size > 1) {
94084                  data.length && gl.uniform3fv(location, data);
94085                } else {
94086                  gl.uniform3f(location, data[0], data[1], data[2]);
94087                }
94088                break;
94089              case gl.FLOAT_VEC4:
94090                if (uniform.size > 1) {
94091                  data.length && gl.uniform4fv(location, data);
94092                } else {
94093                  gl.uniform4f(location, data[0], data[1], data[2], data[3]);
94094                }
94095                break;
94096              case gl.INT_VEC2:
94097                if (uniform.size > 1) {
94098                  data.length && gl.uniform2iv(location, data);
94099                } else {
94100                  gl.uniform2i(location, data[0], data[1]);
94101                }
94102                break;
94103              case gl.INT_VEC3:
94104                if (uniform.size > 1) {
94105                  data.length && gl.uniform3iv(location, data);
94106                } else {
94107                  gl.uniform3i(location, data[0], data[1], data[2]);
94108                }
94109                break;
94110              case gl.INT_VEC4:
94111                if (uniform.size > 1) {
94112                  data.length && gl.uniform4iv(location, data);
94113                } else {
94114                  gl.uniform4i(location, data[0], data[1], data[2], data[3]);
94115                }
94116                break;
94117              case gl.SAMPLER_2D:
94118                gl.activeTexture(gl.TEXTURE0 + uniform.samplerIndex);
94119                uniform.texture = this._renderer.getTexture(data);
94120                gl.uniform1i(uniform.location, uniform.samplerIndex);
94121                break;
94122              //@todo complete all types
94123            }
94124            return this;
94125          };
94126
94127          /* NONE OF THIS IS FAST OR EFFICIENT BUT BEAR WITH ME
94128    *
94129    * these shader "type" query methods are used by various
94130    * facilities of the renderer to determine if changing
94131    * the shader type for the required action (for example,
94132    * do we need to load the default lighting shader if the
94133    * current shader cannot handle lighting?)
94134    *
94135    **/
94136
94137          _main.default.Shader.prototype.isLightShader = function() {
94138            return (
94139              this.attributes.aNormal !== undefined ||
94140              this.uniforms.uUseLighting !== undefined ||
94141              this.uniforms.uAmbientLightCount !== undefined ||
94142              this.uniforms.uDirectionalLightCount !== undefined ||
94143              this.uniforms.uPointLightCount !== undefined ||
94144              this.uniforms.uAmbientColor !== undefined ||
94145              this.uniforms.uDirectionalDiffuseColors !== undefined ||
94146              this.uniforms.uDirectionalSpecularColors !== undefined ||
94147              this.uniforms.uPointLightLocation !== undefined ||
94148              this.uniforms.uPointLightDiffuseColors !== undefined ||
94149              this.uniforms.uPointLightSpecularColors !== undefined ||
94150              this.uniforms.uLightingDirection !== undefined ||
94151              this.uniforms.uSpecular !== undefined
94152            );
94153          };
94154
94155          _main.default.Shader.prototype.isNormalShader = function() {
94156            return this.attributes.aNormal !== undefined;
94157          };
94158
94159          _main.default.Shader.prototype.isTextureShader = function() {
94160            return this.samplerIndex > 0;
94161          };
94162
94163          _main.default.Shader.prototype.isColorShader = function() {
94164            return (
94165              this.attributes.aVertexColor !== undefined ||
94166              this.uniforms.uMaterialColor !== undefined
94167            );
94168          };
94169
94170          _main.default.Shader.prototype.isTexLightShader = function() {
94171            return this.isLightShader() && this.isTextureShader();
94172          };
94173
94174          _main.default.Shader.prototype.isStrokeShader = function() {
94175            return this.uniforms.uStrokeWeight !== undefined;
94176          };
94177
94178          /**
94179           * @method enableAttrib
94180           * @chainable
94181           * @private
94182           */
94183          _main.default.Shader.prototype.enableAttrib = function(
94184            attr,
94185            size,
94186            type,
94187            normalized,
94188            stride,
94189            offset
94190          ) {
94191            if (attr) {
94192              if (
94193                typeof IS_MINIFIED === 'undefined' &&
94194                this.attributes[attr.name] !== attr
94195              ) {
94196                console.warn(
94197                  'The attribute "'.concat(
94198                    attr.name,
94199                    '"passed to enableAttrib does not belong to this shader.'
94200                  )
94201                );
94202              }
94203              var loc = attr.location;
94204              if (loc !== -1) {
94205                var gl = this._renderer.GL;
94206                if (!attr.enabled) {
94207                  gl.enableVertexAttribArray(loc);
94208                  attr.enabled = true;
94209                }
94210                this._renderer.GL.vertexAttribPointer(
94211                  loc,
94212                  size,
94213                  type || gl.FLOAT,
94214                  normalized || false,
94215                  stride || 0,
94216                  offset || 0
94217                );
94218              }
94219            }
94220            return this;
94221          };
94222          var _default = _main.default.Shader;
94223          exports.default = _default;
94224        },
94225        { '../core/main': 59 }
94226      ],
94227      115: [
94228        function(_dereq_, module, exports) {
94229          'use strict';
94230          function _typeof(obj) {
94231            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
94232              _typeof = function _typeof(obj) {
94233                return typeof obj;
94234              };
94235            } else {
94236              _typeof = function _typeof(obj) {
94237                return obj &&
94238                  typeof Symbol === 'function' &&
94239                  obj.constructor === Symbol &&
94240                  obj !== Symbol.prototype
94241                  ? 'symbol'
94242                  : typeof obj;
94243              };
94244            }
94245            return _typeof(obj);
94246          }
94247          Object.defineProperty(exports, '__esModule', { value: true });
94248          exports.default = void 0;
94249
94250          var _main = _interopRequireDefault(_dereq_('../core/main'));
94251          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
94252          function _getRequireWildcardCache() {
94253            if (typeof WeakMap !== 'function') return null;
94254            var cache = new WeakMap();
94255            _getRequireWildcardCache = function _getRequireWildcardCache() {
94256              return cache;
94257            };
94258            return cache;
94259          }
94260          function _interopRequireWildcard(obj) {
94261            if (obj && obj.__esModule) {
94262              return obj;
94263            }
94264            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
94265              return { default: obj };
94266            }
94267            var cache = _getRequireWildcardCache();
94268            if (cache && cache.has(obj)) {
94269              return cache.get(obj);
94270            }
94271            var newObj = {};
94272            var hasPropertyDescriptor =
94273              Object.defineProperty && Object.getOwnPropertyDescriptor;
94274            for (var key in obj) {
94275              if (Object.prototype.hasOwnProperty.call(obj, key)) {
94276                var desc = hasPropertyDescriptor
94277                  ? Object.getOwnPropertyDescriptor(obj, key)
94278                  : null;
94279                if (desc && (desc.get || desc.set)) {
94280                  Object.defineProperty(newObj, key, desc);
94281                } else {
94282                  newObj[key] = obj[key];
94283                }
94284              }
94285            }
94286            newObj.default = obj;
94287            if (cache) {
94288              cache.set(obj, newObj);
94289            }
94290            return newObj;
94291          }
94292          function _interopRequireDefault(obj) {
94293            return obj && obj.__esModule ? obj : { default: obj };
94294          }
94295          /**
94296           * This module defines the p5.Texture class
94297           * @module Lights, Camera
94298           * @submodule Material
94299           * @for p5
94300           * @requires core
94301           */ /**
94302           * Texture class for WEBGL Mode
94303           * @private
94304           * @class p5.Texture
94305           * @param {p5.RendererGL} renderer an instance of p5.RendererGL that
94306           * will provide the GL context for this new p5.Texture
94307           * @param {p5.Image|p5.Graphics|p5.Element|p5.MediaElement|ImageData} [obj] the
94308           * object containing the image data to store in the texture.
94309           */ _main.default.Texture = function(renderer, obj) {
94310            this._renderer = renderer;
94311            var gl = this._renderer.GL;
94312
94313            this.src = obj;
94314            this.glTex = undefined;
94315            this.glTarget = gl.TEXTURE_2D;
94316            this.glFormat = gl.RGBA;
94317            this.mipmaps = false;
94318            this.glMinFilter = gl.LINEAR;
94319            this.glMagFilter = gl.LINEAR;
94320            this.glWrapS = gl.CLAMP_TO_EDGE;
94321            this.glWrapT = gl.CLAMP_TO_EDGE;
94322
94323            // used to determine if this texture might need constant updating
94324            // because it is a video or gif.
94325            this.isSrcMediaElement =
94326              typeof _main.default.MediaElement !== 'undefined' &&
94327              obj instanceof _main.default.MediaElement;
94328            this._videoPrevUpdateTime = 0;
94329            this.isSrcHTMLElement =
94330              typeof _main.default.Element !== 'undefined' &&
94331              obj instanceof _main.default.Element &&
94332              !(obj instanceof _main.default.Graphics);
94333            this.isSrcP5Image = obj instanceof _main.default.Image;
94334            this.isSrcP5Graphics = obj instanceof _main.default.Graphics;
94335            this.isImageData = typeof ImageData !== 'undefined' && obj instanceof ImageData;
94336
94337            var textureData = this._getTextureDataFromSource();
94338            this.width = textureData.width;
94339            this.height = textureData.height;
94340
94341            this.init(textureData);
94342            return this;
94343          };
94344
94345          _main.default.Texture.prototype._getTextureDataFromSource = function() {
94346            var textureData;
94347            if (this.isSrcP5Image) {
94348              // param is a p5.Image
94349              textureData = this.src.canvas;
94350            } else if (
94351              this.isSrcMediaElement ||
94352              this.isSrcP5Graphics ||
94353              this.isSrcHTMLElement
94354            ) {
94355              // if param is a video HTML element
94356              textureData = this.src.elt;
94357            } else if (this.isImageData) {
94358              textureData = this.src;
94359            }
94360            return textureData;
94361          };
94362
94363          /**
94364           * Initializes common texture parameters, creates a gl texture,
94365           * tries to upload the texture for the first time if data is
94366           * already available.
94367           * @private
94368           * @method init
94369           */
94370          _main.default.Texture.prototype.init = function(data) {
94371            var gl = this._renderer.GL;
94372            this.glTex = gl.createTexture();
94373
94374            this.glWrapS = this._renderer.textureWrapX;
94375            this.glWrapT = this._renderer.textureWrapY;
94376
94377            this.setWrapMode(this.glWrapS, this.glWrapT);
94378            this.bindTexture();
94379
94380            //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
94381            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.glMagFilter);
94382            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.glMinFilter);
94383
94384            if (
94385              this.width === 0 ||
94386              this.height === 0 ||
94387              (this.isSrcMediaElement && !this.src.loadedmetadata)
94388            ) {
94389              // assign a 1x1 empty texture initially, because data is not yet ready,
94390              // so that no errors occur in gl console!
94391              var tmpdata = new Uint8Array([1, 1, 1, 1]);
94392              gl.texImage2D(
94393                this.glTarget,
94394                0,
94395                gl.RGBA,
94396                1,
94397                1,
94398                0,
94399                this.glFormat,
94400                gl.UNSIGNED_BYTE,
94401                tmpdata
94402              );
94403            } else {
94404              // data is ready: just push the texture!
94405              gl.texImage2D(
94406                this.glTarget,
94407                0,
94408                this.glFormat,
94409                this.glFormat,
94410                gl.UNSIGNED_BYTE,
94411                data
94412              );
94413            }
94414          };
94415
94416          /**
94417           * Checks if the source data for this texture has changed (if it's
94418           * easy to do so) and reuploads the texture if necessary. If it's not
94419           * possible or to expensive to do a calculation to determine wheter or
94420           * not the data has occurred, this method simply re-uploads the texture.
94421           * @method update
94422           */
94423          _main.default.Texture.prototype.update = function() {
94424            var data = this.src;
94425            if (data.width === 0 || data.height === 0) {
94426              return false; // nothing to do!
94427            }
94428
94429            var textureData = this._getTextureDataFromSource();
94430            var updated = false;
94431
94432            var gl = this._renderer.GL;
94433            // pull texture from data, make sure width & height are appropriate
94434            if (textureData.width !== this.width || textureData.height !== this.height) {
94435              updated = true;
94436
94437              // make sure that if the width and height of this.src have changed
94438              // for some reason, we update our metadata and upload the texture again
94439              this.width = textureData.width;
94440              this.height = textureData.height;
94441
94442              if (this.isSrcP5Image) {
94443                data.setModified(false);
94444              } else if (this.isSrcMediaElement || this.isSrcHTMLElement) {
94445                // on the first frame the metadata comes in, the size will be changed
94446                // from 0 to actual size, but pixels may not be available.
94447                // flag for update in a future frame.
94448                // if we don't do this, a paused video, for example, may not
94449                // send the first frame to texture memory.
94450                data.setModified(true);
94451              }
94452            } else if (this.isSrcP5Image) {
94453              // for an image, we only update if the modified field has been set,
94454              // for example, by a call to p5.Image.set
94455              if (data.isModified()) {
94456                updated = true;
94457                data.setModified(false);
94458              }
94459            } else if (this.isSrcMediaElement) {
94460              // for a media element (video), we'll check if the current time in
94461              // the video frame matches the last time. if it doesn't match, the
94462              // video has advanced or otherwise been taken to a new frame,
94463              // and we need to upload it.
94464              if (data.isModified()) {
94465                // p5.MediaElement may have also had set/updatePixels, etc. called
94466                // on it and should be updated, or may have been set for the first
94467                // time!
94468                updated = true;
94469                data.setModified(false);
94470              } else if (data.loadedmetadata) {
94471                // if the meta data has been loaded, we can ask the video
94472                // what it's current position (in time) is.
94473                if (this._videoPrevUpdateTime !== data.time()) {
94474                  // update the texture in gpu mem only if the current
94475                  // video timestamp does not match the timestamp of the last
94476                  // time we uploaded this texture (and update the time we
94477                  // last uploaded, too)
94478                  this._videoPrevUpdateTime = data.time();
94479                  updated = true;
94480                }
94481              }
94482            } else if (this.isImageData) {
94483              if (data._dirty) {
94484                data._dirty = false;
94485                updated = true;
94486              }
94487            } else {
94488              /* data instanceof p5.Graphics, probably */
94489              // there is not enough information to tell if the texture can be
94490              // conditionally updated; so to be safe, we just go ahead and upload it.
94491              updated = true;
94492            }
94493
94494            if (updated) {
94495              this.bindTexture();
94496              gl.texImage2D(
94497                this.glTarget,
94498                0,
94499                this.glFormat,
94500                this.glFormat,
94501                gl.UNSIGNED_BYTE,
94502                textureData
94503              );
94504            }
94505
94506            return updated;
94507          };
94508
94509          /**
94510           * Binds the texture to the appropriate GL target.
94511           * @method bindTexture
94512           */
94513          _main.default.Texture.prototype.bindTexture = function() {
94514            // bind texture using gl context + glTarget and
94515            // generated gl texture object
94516            var gl = this._renderer.GL;
94517            gl.bindTexture(this.glTarget, this.glTex);
94518
94519            return this;
94520          };
94521
94522          /**
94523           * Unbinds the texture from the appropriate GL target.
94524           * @method unbindTexture
94525           */
94526          _main.default.Texture.prototype.unbindTexture = function() {
94527            // unbind per above, disable texturing on glTarget
94528            var gl = this._renderer.GL;
94529            gl.bindTexture(this.glTarget, null);
94530          };
94531
94532          /**
94533           * Sets how a texture is be interpolated when upscaled or downscaled.
94534           * Nearest filtering uses nearest neighbor scaling when interpolating
94535           * Linear filtering uses WebGL's linear scaling when interpolating
94536           * @method setInterpolation
94537           * @param {String} downScale Specifies the texture filtering when
94538           *                           textures are shrunk. Options are LINEAR or NEAREST
94539           * @param {String} upScale Specifies the texture filtering when
94540           *                         textures are magnified. Options are LINEAR or NEAREST
94541           * @todo implement mipmapping filters
94542           */
94543          _main.default.Texture.prototype.setInterpolation = function(downScale, upScale) {
94544            var gl = this._renderer.GL;
94545
94546            if (downScale === constants.NEAREST) {
94547              this.glMinFilter = gl.NEAREST;
94548            } else {
94549              this.glMinFilter = gl.LINEAR;
94550            }
94551
94552            if (upScale === constants.NEAREST) {
94553              this.glMagFilter = gl.NEAREST;
94554            } else {
94555              this.glMagFilter = gl.LINEAR;
94556            }
94557
94558            this.bindTexture();
94559            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.glMinFilter);
94560            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.glMagFilter);
94561            this.unbindTexture();
94562          };
94563
94564          /**
94565           * Sets the texture wrapping mode. This controls how textures behave
94566           * when their uv's go outside of the 0 - 1 range. There are three options:
94567           * CLAMP, REPEAT, and MIRROR. REPEAT & MIRROR are only available if the texture
94568           * is a power of two size (128, 256, 512, 1024, etc.).
94569           * @method setWrapMode
94570           * @param {String} wrapX Controls the horizontal texture wrapping behavior
94571           * @param {String} wrapY Controls the vertical texture wrapping behavior
94572           */
94573          _main.default.Texture.prototype.setWrapMode = function(wrapX, wrapY) {
94574            var gl = this._renderer.GL;
94575
94576            // for webgl 1 we need to check if the texture is power of two
94577            // if it isn't we will set the wrap mode to CLAMP
94578            // webgl2 will support npot REPEAT and MIRROR but we don't check for it yet
94579            var isPowerOfTwo = function isPowerOfTwo(x) {
94580              return (x & (x - 1)) === 0;
94581            };
94582
94583            var widthPowerOfTwo = isPowerOfTwo(this.width);
94584            var heightPowerOfTwo = isPowerOfTwo(this.height);
94585
94586            if (wrapX === constants.REPEAT) {
94587              if (widthPowerOfTwo && heightPowerOfTwo) {
94588                this.glWrapS = gl.REPEAT;
94589              } else {
94590                console.warn(
94591                  'You tried to set the wrap mode to REPEAT but the texture size is not a power of two. Setting to CLAMP instead'
94592                );
94593
94594                this.glWrapS = gl.CLAMP_TO_EDGE;
94595              }
94596            } else if (wrapX === constants.MIRROR) {
94597              if (widthPowerOfTwo && heightPowerOfTwo) {
94598                this.glWrapS = gl.MIRRORED_REPEAT;
94599              } else {
94600                console.warn(
94601                  'You tried to set the wrap mode to MIRROR but the texture size is not a power of two. Setting to CLAMP instead'
94602                );
94603
94604                this.glWrapS = gl.CLAMP_TO_EDGE;
94605              }
94606            } else {
94607              // falling back to default if didn't get a proper mode
94608              this.glWrapS = gl.CLAMP_TO_EDGE;
94609            }
94610
94611            if (wrapY === constants.REPEAT) {
94612              if (widthPowerOfTwo && heightPowerOfTwo) {
94613                this.glWrapT = gl.REPEAT;
94614              } else {
94615                console.warn(
94616                  'You tried to set the wrap mode to REPEAT but the texture size is not a power of two. Setting to CLAMP instead'
94617                );
94618
94619                this.glWrapT = gl.CLAMP_TO_EDGE;
94620              }
94621            } else if (wrapY === constants.MIRROR) {
94622              if (widthPowerOfTwo && heightPowerOfTwo) {
94623                this.glWrapT = gl.MIRRORED_REPEAT;
94624              } else {
94625                console.warn(
94626                  'You tried to set the wrap mode to MIRROR but the texture size is not a power of two. Setting to CLAMP instead'
94627                );
94628
94629                this.glWrapT = gl.CLAMP_TO_EDGE;
94630              }
94631            } else {
94632              // falling back to default if didn't get a proper mode
94633              this.glWrapT = gl.CLAMP_TO_EDGE;
94634            }
94635
94636            this.bindTexture();
94637            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this.glWrapS);
94638            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this.glWrapT);
94639            this.unbindTexture();
94640          };
94641          var _default = _main.default.Texture;
94642          exports.default = _default;
94643        },
94644        { '../core/constants': 48, '../core/main': 59 }
94645      ],
94646      116: [
94647        function(_dereq_, module, exports) {
94648          'use strict';
94649          function _typeof(obj) {
94650            if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
94651              _typeof = function _typeof(obj) {
94652                return typeof obj;
94653              };
94654            } else {
94655              _typeof = function _typeof(obj) {
94656                return obj &&
94657                  typeof Symbol === 'function' &&
94658                  obj.constructor === Symbol &&
94659                  obj !== Symbol.prototype
94660                  ? 'symbol'
94661                  : typeof obj;
94662              };
94663            }
94664            return _typeof(obj);
94665          }
94666          var _main = _interopRequireDefault(_dereq_('../core/main'));
94667          var constants = _interopRequireWildcard(_dereq_('../core/constants'));
94668          _dereq_('./p5.Shader');
94669          _dereq_('./p5.RendererGL.Retained');
94670          function _getRequireWildcardCache() {
94671            if (typeof WeakMap !== 'function') return null;
94672            var cache = new WeakMap();
94673            _getRequireWildcardCache = function _getRequireWildcardCache() {
94674              return cache;
94675            };
94676            return cache;
94677          }
94678          function _interopRequireWildcard(obj) {
94679            if (obj && obj.__esModule) {
94680              return obj;
94681            }
94682            if (obj === null || (_typeof(obj) !== 'object' && typeof obj !== 'function')) {
94683              return { default: obj };
94684            }
94685            var cache = _getRequireWildcardCache();
94686            if (cache && cache.has(obj)) {
94687              return cache.get(obj);
94688            }
94689            var newObj = {};
94690            var hasPropertyDescriptor =
94691              Object.defineProperty && Object.getOwnPropertyDescriptor;
94692            for (var key in obj) {
94693              if (Object.prototype.hasOwnProperty.call(obj, key)) {
94694                var desc = hasPropertyDescriptor
94695                  ? Object.getOwnPropertyDescriptor(obj, key)
94696                  : null;
94697                if (desc && (desc.get || desc.set)) {
94698                  Object.defineProperty(newObj, key, desc);
94699                } else {
94700                  newObj[key] = obj[key];
94701                }
94702              }
94703            }
94704            newObj.default = obj;
94705            if (cache) {
94706              cache.set(obj, newObj);
94707            }
94708            return newObj;
94709          }
94710          function _interopRequireDefault(obj) {
94711            return obj && obj.__esModule ? obj : { default: obj };
94712          }
94713
94714          // Text/Typography
94715          // @TODO:
94716          _main.default.RendererGL.prototype._applyTextProperties = function() {
94717            //@TODO finish implementation
94718            //console.error('text commands not yet implemented in webgl');
94719          };
94720
94721          _main.default.RendererGL.prototype.textWidth = function(s) {
94722            if (this._isOpenType()) {
94723              return this._textFont._textWidth(s, this._textSize);
94724            }
94725
94726            return 0; // TODO: error
94727          };
94728
94729          // rendering constants
94730
94731          // the number of rows/columns dividing each glyph
94732          var charGridWidth = 9;
94733          var charGridHeight = charGridWidth;
94734
94735          // size of the image holding the bezier stroke info
94736          var strokeImageWidth = 64;
94737          var strokeImageHeight = 64;
94738
94739          // size of the image holding the stroke indices for each row/col
94740          var gridImageWidth = 64;
94741          var gridImageHeight = 64;
94742
94743          // size of the image holding the offset/length of each row/col stripe
94744          var cellImageWidth = 64;
94745          var cellImageHeight = 64;
94746
94747          /**
94748           * @private
94749           * @class ImageInfos
94750           * @param {Integer} width
94751           * @param {Integer} height
94752           *
94753           * the ImageInfos class holds a list of ImageDatas of a given size.
94754           */
94755          function ImageInfos(width, height) {
94756            this.width = width;
94757            this.height = height;
94758            this.infos = []; // the list of images
94759
94760            /**
94761             *
94762             * @method findImage
94763             * @param {Integer} space
94764             * @return {Object} contains the ImageData, and pixel index into that
94765             *                  ImageData where the free space was allocated.
94766             *
94767             * finds free space of a given size in the ImageData list
94768             */
94769            this.findImage = function(space) {
94770              var imageSize = this.width * this.height;
94771              if (space > imageSize) throw new Error('font is too complex to render in 3D');
94772
94773              // search through the list of images, looking for one with
94774              // anough unused space.
94775              var imageInfo, imageData;
94776              for (var ii = this.infos.length - 1; ii >= 0; --ii) {
94777                var imageInfoTest = this.infos[ii];
94778                if (imageInfoTest.index + space < imageSize) {
94779                  // found one
94780                  imageInfo = imageInfoTest;
94781                  imageData = imageInfoTest.imageData;
94782                  break;
94783                }
94784              }
94785
94786              if (!imageInfo) {
94787                try {
94788                  // create a new image
94789                  imageData = new ImageData(this.width, this.height);
94790                } catch (err) {
94791                  // for browsers that don't support ImageData constructors (ie IE11)
94792                  // create an ImageData using the old method
94793                  var canvas = document.getElementsByTagName('canvas')[0];
94794                  var created = !canvas;
94795                  if (!canvas) {
94796                    // create a temporary canvas
94797                    canvas = document.createElement('canvas');
94798                    canvas.style.display = 'none';
94799                    document.body.appendChild(canvas);
94800                  }
94801                  var ctx = canvas.getContext('2d');
94802                  if (ctx) {
94803                    imageData = ctx.createImageData(this.width, this.height);
94804                  }
94805                  if (created) {
94806                    // distroy the temporary canvas, if necessary
94807                    document.body.removeChild(canvas);
94808                  }
94809                }
94810                // construct & dd the new image info
94811                imageInfo = { index: 0, imageData: imageData };
94812                this.infos.push(imageInfo);
94813              }
94814
94815              var index = imageInfo.index;
94816              imageInfo.index += space; // move to the start of the next image
94817              imageData._dirty = true;
94818              return { imageData: imageData, index: index };
94819            };
94820          }
94821
94822          /**
94823           * @function setPixel
94824           * @param {Object} imageInfo
94825           * @param {Number} r
94826           * @param {Number} g
94827           * @param {Number} b
94828           * @param {Number} a
94829           *
94830           * writes the next pixel into an indexed ImageData
94831           */
94832          function setPixel(imageInfo, r, g, b, a) {
94833            var imageData = imageInfo.imageData;
94834            var pixels = imageData.data;
94835            var index = imageInfo.index++ * 4;
94836            pixels[index++] = r;
94837            pixels[index++] = g;
94838            pixels[index++] = b;
94839            pixels[index++] = a;
94840          }
94841
94842          var SQRT3 = Math.sqrt(3);
94843
94844          /**
94845           * @private
94846           * @class FontInfo
94847           * @param {Object} font an opentype.js font object
94848           *
94849           * contains cached images and glyph information for an opentype font
94850           */
94851          var FontInfo = function FontInfo(font) {
94852            this.font = font;
94853            // the bezier curve coordinates
94854            this.strokeImageInfos = new ImageInfos(strokeImageWidth, strokeImageHeight);
94855            // lists of curve indices for each row/column slice
94856            this.colDimImageInfos = new ImageInfos(gridImageWidth, gridImageHeight);
94857            this.rowDimImageInfos = new ImageInfos(gridImageWidth, gridImageHeight);
94858            // the offset & length of each row/col slice in the glyph
94859            this.colCellImageInfos = new ImageInfos(cellImageWidth, cellImageHeight);
94860            this.rowCellImageInfos = new ImageInfos(cellImageWidth, cellImageHeight);
94861
94862            // the cached information for each glyph
94863            this.glyphInfos = {};
94864
94865            /**
94866             * @method getGlyphInfo
94867             * @param {Glyph} glyph the x positions of points in the curve
94868             * @returns {Object} the glyphInfo for that glyph
94869             *
94870             * calculates rendering info for a glyph, including the curve information,
94871             * row & column stripes compiled into textures.
94872             */
94873
94874            this.getGlyphInfo = function(glyph) {
94875              // check the cache
94876              var gi = this.glyphInfos[glyph.index];
94877              if (gi) return gi;
94878
94879              // get the bounding box of the glyph from opentype.js
94880              var bb = glyph.getBoundingBox();
94881              var xMin = bb.x1;
94882              var yMin = bb.y1;
94883              var gWidth = bb.x2 - xMin;
94884              var gHeight = bb.y2 - yMin;
94885              var cmds = glyph.path.commands;
94886              // don't bother rendering invisible glyphs
94887              if (gWidth === 0 || gHeight === 0 || !cmds.length) {
94888                return (this.glyphInfos[glyph.index] = {});
94889              }
94890
94891              var i;
94892              var strokes = []; // the strokes in this glyph
94893              var rows = []; // the indices of strokes in each row
94894              var cols = []; // the indices of strokes in each column
94895              for (i = charGridWidth - 1; i >= 0; --i) {
94896                cols.push([]);
94897              }
94898              for (i = charGridHeight - 1; i >= 0; --i) {
94899                rows.push([]);
94900              }
94901
94902              /**
94903               * @function push
94904               * @param {Number[]} xs the x positions of points in the curve
94905               * @param {Number[]} ys the y positions of points in the curve
94906               * @param {Object} v    the curve information
94907               *
94908               * adds a curve to the rows & columns that it intersects with
94909               */
94910              function push(xs, ys, v) {
94911                var index = strokes.length; // the index of this stroke
94912                strokes.push(v);
94912 // add this stroke to the list
94913
94914                /**
94915                 * @function minMax
94916                 * @param {Number[]} rg the list of values to compare
94917                 * @param {Number} min the initial minimum value
94918                 * @param {Number} max the initial maximum value
94919                 *
94920                 * find the minimum & maximum value in a list of values
94921                 */
94922                function minMax(rg, min, max) {
94923                  for (var _i = rg.length; _i-- > 0; ) {
94924                    var _v = rg[_i];
94925                    if (min > _v) min = _v;
94926                    if (max < _v) max = _v;
94927                  }
94928                  return { min: min, max: max };
94929                }
94930
94931                // loop through the rows & columns that the curve intersects
94932                // adding the curve to those slices
94933                var mmX = minMax(xs, 1, 0);
94934                var ixMin = Math.max(Math.floor(mmX.min * charGridWidth), 0);
94935                var ixMax = Math.min(Math.ceil(mmX.max * charGridWidth), charGridWidth);
94936                for (var iCol = ixMin; iCol < ixMax; ++iCol) {
94937                  cols[iCol].push(index);
94938                }
94939
94940                var mmY = minMax(ys, 1, 0);
94941                var iyMin = Math.max(Math.floor(mmY.min * charGridHeight), 0);
94942                var iyMax = Math.min(Math.ceil(mmY.max * charGridHeight), charGridHeight);
94943
94944                for (var iRow = iyMin; iRow < iyMax; ++iRow) {
94945                  rows[iRow].push(index);
94946                }
94947              }
94948
94949              /**
94950               * @function clamp
94951               * @param {Number} v the value to clamp
94952               * @param {Number} min the minimum value
94953               * @param {Number} max the maxmimum value
94954               *
94955               * clamps a value between a minimum & maximum value
94956               */
94957              function clamp(v, min, max) {
94958                if (v < min) return min;
94959                if (v > max) return max;
94960                return v;
94961              }
94962
94963              /**
94964               * @function byte
94965               * @param {Number} v the value to scale
94966               *
94967               * converts a floating-point number in the range 0-1 to a byte 0-255
94968               */
94969              function byte(v) {
94970                return clamp(255 * v, 0, 255);
94971              }
94972
94973              /**
94974               * @private
94975               * @class Cubic
94976               * @param {Number} p0 the start point of the curve
94977               * @param {Number} c0 the first control point
94978               * @param {Number} c1 the second control point
94979               * @param {Number} p1 the end point
94980               *
94981               * a cubic curve
94982               */
94983              function Cubic(p0, c0, c1, p1) {
94984                this.p0 = p0;
94985                this.c0 = c0;
94986                this.c1 = c1;
94987                this.p1 = p1;
94988
94989                /**
94990                 * @method toQuadratic
94991                 * @return {Object} the quadratic approximation
94992                 *
94993                 * converts the cubic to a quadtratic approximation by
94994                 * picking an appropriate quadratic control point
94995                 */
94996                this.toQuadratic = function() {
94997                  return {
94998                    x: this.p0.x,
94999                    y: this.p0.y,
95000                    x1: this.p1.x,
95001                    y1: this.p1.y,
95002                    cx: ((this.c0.x + this.c1.x) * 3 - (this.p0.x + this.p1.x)) / 4,
95003                    cy: ((this.c0.y + this.c1.y) * 3 - (this.p0.y + this.p1.y)) / 4
95004                  };
95005                };
95006
95007                /**
95008                 * @method quadError
95009                 * @return {Number} the error
95010                 *
95011                 * calculates the magnitude of error of this curve's
95012                 * quadratic approximation.
95013                 */
95014                this.quadError = function() {
95015                  return (
95016                    _main.default.Vector.sub(
95017                      _main.default.Vector.sub(this.p1, this.p0),
95018                      _main.default.Vector.mult(
95019                        _main.default.Vector.sub(this.c1, this.c0),
95020                        3
95021                      )
95022                    ).mag() / 2
95023                  );
95024                };
95025
95026                /**
95027                 * @method split
95028                 * @param {Number} t the value (0-1) at which to split
95029                 * @return {Cubic} the second part of the curve
95030                 *
95031                 * splits the cubic into two parts at a point 't' along the curve.
95032                 * this cubic keeps its start point and its end point becomes the
95033                 * point at 't'. the 'end half is returned.
95034                 */
95035                this.split = function(t) {
95036                  var m1 = _main.default.Vector.lerp(this.p0, this.c0, t);
95037                  var m2 = _main.default.Vector.lerp(this.c0, this.c1, t);
95038                  var mm1 = _main.default.Vector.lerp(m1, m2, t);
95039
95040                  this.c1 = _main.default.Vector.lerp(this.c1, this.p1, t);
95041                  this.c0 = _main.default.Vector.lerp(m2, this.c1, t);
95042                  var pt = _main.default.Vector.lerp(mm1, this.c0, t);
95043                  var part1 = new Cubic(this.p0, m1, mm1, pt);
95044                  this.p0 = pt;
95045                  return part1;
95046                };
95047
95048                /**
95049                 * @method splitInflections
95050                 * @return {Cubic[]} the non-inflecting pieces of this cubic
95051                 *
95052                 * returns an array containing 0, 1 or 2 cubics split resulting
95053                 * from splitting this cubic at its inflection points.
95054                 * this cubic is (potentially) altered and returned in the list.
95055                 */
95056                this.splitInflections = function() {
95057                  var a = _main.default.Vector.sub(this.c0, this.p0);
95058                  var b = _main.default.Vector.sub(
95059                    _main.default.Vector.sub(this.c1, this.c0),
95060                    a
95061                  );
95062                  var c = _main.default.Vector.sub(
95063                    _main.default.Vector.sub(_main.default.Vector.sub(this.p1, this.c1), a),
95064                    _main.default.Vector.mult(b, 2)
95065                  );
95066
95067                  var cubics = [];
95068
95069                  // find the derivative coefficients
95070                  var A = b.x * c.y - b.y * c.x;
95071                  if (A !== 0) {
95072                    var B = a.x * c.y - a.y * c.x;
95073                    var C = a.x * b.y - a.y * b.x;
95074                    var disc = B * B - 4 * A * C;
95075                    if (disc >= 0) {
95076                      if (A < 0) {
95077                        A = -A;
95078                        B = -B;
95079                        C = -C;
95080                      }
95081
95082                      var Q = Math.sqrt(disc);
95083                      var t0 = (-B - Q) / (2 * A); // the first inflection point
95084                      var t1 = (-B + Q) / (2 * A); // the second inflection point
95085
95086                      // test if the first inflection point lies on the curve
95087                      if (t0 > 0 && t0 < 1) {
95088                        // split at the first inflection point
95089                        cubics.push(this.split(t0));
95090                        // scale t2 into the second part
95091                        t1 = 1 - (1 - t1) / (1 - t0);
95092                      }
95093
95094                      // test if the second inflection point lies on the curve
95095                      if (t1 > 0 && t1 < 1) {
95096                        // split at the second inflection point
95097                        cubics.push(this.split(t1));
95098                      }
95099                    }
95100                  }
95101
95102                  cubics.push(this);
95103                  return cubics;
95104                };
95105              }
95106
95107              /**
95108               * @function cubicToQuadratics
95109               * @param {Number} x0
95110               * @param {Number} y0
95111               * @param {Number} cx0
95112               * @param {Number} cy0
95113               * @param {Number} cx1
95114               * @param {Number} cy1
95115               * @param {Number} x1
95116               * @param {Number} y1
95117               * @returns {Cubic[]} an array of cubics whose quadratic approximations
95118               *                    closely match the civen cubic.
95119               *
95120               * converts a cubic curve to a list of quadratics.
95121               */
95122              function cubicToQuadratics(x0, y0, cx0, cy0, cx1, cy1, x1, y1) {
95123                // create the Cubic object and split it at its inflections
95124                var cubics = new Cubic(
95125                  new _main.default.Vector(x0, y0),
95126                  new _main.default.Vector(cx0, cy0),
95127                  new _main.default.Vector(cx1, cy1),
95128                  new _main.default.Vector(x1, y1)
95129                ).splitInflections();
95130
95131                var qs = []; // the final list of quadratics
95132                var precision = 30 / SQRT3;
95133
95134                // for each of the non-inflected pieces of the original cubic
95135                var _iteratorNormalCompletion = true;
95136                var _didIteratorError = false;
95137                var _iteratorError = undefined;
95138                try {
95139                  for (
95140                    var _iterator = cubics[Symbol.iterator](), _step;
95141                    !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
95142                    _iteratorNormalCompletion = true
95143                  ) {
95144                    var cubic = _step.value;
95145                    // the cubic is iteratively split in 3 pieces:
95146                    // the first piece is accumulated in 'qs', the result.
95147                    // the last piece is accumulated in 'tail', temporarily.
95148                    // the middle piece is repeatedly split again, while necessary.
95149                    var tail = [];
95150
95151                    var t3 = void 0;
95152                    for (;;) {
95153                      // calculate this cubic's precision
95154                      t3 = precision / cubic.quadError();
95155                      if (t3 >= 0.5 * 0.5 * 0.5) {
95156                        break; // not too bad, we're done
95157                      }
95158
95159                      // find a split point based on the error
95160                      var t = Math.pow(t3, 1.0 / 3.0);
95161                      // split the cubic in 3
95162                      var start = cubic.split(t);
95163                      var middle = cubic.split(1 - t / (1 - t));
95164
95165                      qs.push(start); // the first part
95166                      tail.push(cubic); // the last part
95167                      cubic = middle; // iterate on the middle piece
95168                    }
95169
95170                    if (t3 < 1) {
95171                      // a little excess error, split the middle in two
95172                      qs.push(cubic.split(0.5));
95173                    }
95174                    // add the middle piece to the result
95175                    qs.push(cubic);
95176
95177                    // finally add the tail, reversed, onto the result
95178                    Array.prototype.push.apply(qs, tail.reverse());
95179                  }
95180                } catch (err) {
95181                  _didIteratorError = true;
95182                  _iteratorError = err;
95183                } finally {
95184                  try {
95185                    if (!_iteratorNormalCompletion && _iterator.return != null) {
95186                      _iterator.return();
95187                    }
95188                  } finally {
95189                    if (_didIteratorError) {
95190                      throw _iteratorError;
95191                    }
95192                  }
95193                }
95194
95195                return qs;
95196              }
95197
95198              /**
95199               * @function pushLine
95200               * @param {Number} x0
95201               * @param {Number} y0
95202               * @param {Number} x1
95203               * @param {Number} y1
95204               *
95205               * add a straight line to the row/col grid of a glyph
95206               */
95207              function pushLine(x0, y0, x1, y1) {
95208                var mx = (x0 + x1) / 2;
95209                var my = (y0 + y1) / 2;
95210                push([x0, x1], [y0, y1], { x: x0, y: y0, cx: mx, cy: my });
95211              }
95212
95213              /**
95214               * @function samePoint
95215               * @param {Number} x0
95216               * @param {Number} y0
95217               * @param {Number} x1
95218               * @param {Number} y1
95219               * @return {Boolean} true if the two points are sufficiently close
95220               *
95221               * tests if two points are close enough to be considered the same
95222               */
95223              function samePoint(x0, y0, x1, y1) {
95224                return Math.abs(x1 - x0) < 0.00001 && Math.abs(y1 - y0) < 0.00001;
95225              }
95226
95227              var x0, y0, xs, ys;
95228              var _iteratorNormalCompletion2 = true;
95229              var _didIteratorError2 = false;
95230              var _iteratorError2 = undefined;
95231              try {
95232                for (
95233                  var _iterator2 = cmds[Symbol.iterator](), _step2;
95234                  !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done);
95235                  _iteratorNormalCompletion2 = true
95236                ) {
95237                  var cmd = _step2.value;
95238                  // scale the coordinates to the range 0-1
95239                  var x1 = (cmd.x - xMin) / gWidth;
95240                  var y1 = (cmd.y - yMin) / gHeight;
95241
95242                  // don't bother if this point is the same as the last
95243                  if (samePoint(x0, y0, x1, y1)) continue;
95244
95245                  switch (cmd.type) {
95246                    case 'M': {
95247                      // move
95248                      xs = x1;
95249                      ys = y1;
95250                      break;
95251                    }
95252                    case 'L': {
95253                      // line
95254                      pushLine(x0, y0, x1, y1);
95255                      break;
95256                    }
95257                    case 'Q': {
95258                      // quadratic
95259                      var cx = (cmd.x1 - xMin) / gWidth;
95260                      var cy = (cmd.y1 - yMin) / gHeight;
95261                      push([x0, x1, cx], [y0, y1, cy], { x: x0, y: y0, cx: cx, cy: cy });
95262                      break;
95263                    }
95264                    case 'Z': {
95265                      // end
95266                      if (!samePoint(x0, y0, xs, ys)) {
95267                        // add an extra line closing the loop, if necessary
95268                        pushLine(x0, y0, xs, ys);
95269                        strokes.push({ x: xs, y: ys });
95270                      } else {
95271                        strokes.push({ x: x0, y: y0 });
95272                      }
95273                      break;
95274                    }
95275                    case 'C': {
95276                      // cubic
95277                      var cx1 = (cmd.x1 - xMin) / gWidth;
95278                      var cy1 = (cmd.y1 - yMin) / gHeight;
95279                      var cx2 = (cmd.x2 - xMin) / gWidth;
95280                      var cy2 = (cmd.y2 - yMin) / gHeight;
95281                      var qs = cubicToQuadratics(x0, y0, cx1, cy1, cx2, cy2, x1, y1);
95282                      for (var iq = 0; iq < qs.length; iq++) {
95283                        var q = qs[iq].toQuadratic();
95284                        push([q.x, q.x1, q.cx], [q.y, q.y1, q.cy], q);
95285                      }
95286                      break;
95287                    }
95288                    default:
95289                      throw new Error('unknown command type: '.concat(cmd.type));
95290                  }
95291
95292                  x0 = x1;
95293                  y0 = y1;
95294                }
95295
95296                // allocate space for the strokes
95297              } catch (err) {
95298                _didIteratorError2 = true;
95299                _iteratorError2 = err;
95300              } finally {
95301                try {
95302                  if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
95303                    _iterator2.return();
95304                  }
95305                } finally {
95306                  if (_didIteratorError2) {
95307                    throw _iteratorError2;
95308                  }
95309                }
95310              }
95311              var strokeCount = strokes.length;
95312              var strokeImageInfo = this.strokeImageInfos.findImage(strokeCount);
95313              var strokeOffset = strokeImageInfo.index;
95314
95315              // fill the stroke image
95316              for (var il = 0; il < strokeCount; ++il) {
95317                var s = strokes[il];
95318                setPixel(strokeImageInfo, byte(s.x), byte(s.y), byte(s.cx), byte(s.cy));
95319              }
95320
95321              /**
95322               * @function layout
95323               * @param {Number[][]} dim
95324               * @param {ImageInfo[]} dimImageInfos
95325               * @param {ImageInfo[]} cellImageInfos
95326               * @return {Object}
95327               *
95328               * lays out the curves in a dimension (row or col) into two
95329               * images, one for the indices of the curves themselves, and
95330               * one containing the offset and length of those index spans.
95331               */
95332              function layout(dim, dimImageInfos, cellImageInfos) {
95333                var dimLength = dim.length; // the number of slices in this dimension
95334                var dimImageInfo = dimImageInfos.findImage(dimLength);
95335                var dimOffset = dimImageInfo.index;
95336                // calculate the total number of stroke indices in this dimension
95337                var totalStrokes = 0;
95338                for (var id = 0; id < dimLength; ++id) {
95339                  totalStrokes += dim[id].length;
95340                }
95341
95342                // allocate space for the stroke indices
95343                var cellImageInfo = cellImageInfos.findImage(totalStrokes);
95344
95345                // for each slice in the glyph
95346                for (var _i2 = 0; _i2 < dimLength; ++_i2) {
95347                  var strokeIndices = dim[_i2];
95348                  var _strokeCount = strokeIndices.length;
95349                  var cellLineIndex = cellImageInfo.index;
95350
95351                  // write the offset and count into the glyph slice image
95352                  setPixel(
95353                    dimImageInfo,
95354                    cellLineIndex >> 7,
95355                    cellLineIndex & 0x7f,
95356                    _strokeCount >> 7,
95357                    _strokeCount & 0x7f
95358                  );
95359
95360                  // for each stroke index in that slice
95361                  for (var iil = 0; iil < _strokeCount; ++iil) {
95362                    // write the stroke index into the slice's image
95363                    var strokeIndex = strokeIndices[iil] + strokeOffset;
95364                    setPixel(cellImageInfo, strokeIndex >> 7, strokeIndex & 0x7f, 0, 0);
95365                  }
95366                }
95367
95368                return {
95369                  cellImageInfo: cellImageInfo,
95370                  dimOffset: dimOffset,
95371                  dimImageInfo: dimImageInfo
95372                };
95373              }
95374
95375              // initialize the info for this glyph
95376              gi = this.glyphInfos[glyph.index] = {
95377                glyph: glyph,
95378                uGlyphRect: [bb.x1, -bb.y1, bb.x2, -bb.y2],
95379                strokeImageInfo: strokeImageInfo,
95380                strokes: strokes,
95381                colInfo: layout(cols, this.colDimImageInfos, this.colCellImageInfos),
95382                rowInfo: layout(rows, this.rowDimImageInfos, this.rowCellImageInfos)
95383              };
95384
95385              gi.uGridOffset = [gi.colInfo.dimOffset, gi.rowInfo.dimOffset];
95386              return gi;
95387            };
95388          };
95389
95390          _main.default.RendererGL.prototype._renderText = function(p, line, x, y, maxY) {
95391            if (!this._textFont || typeof this._textFont === 'string') {
95392              console.log(
95393                'WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` for more details.'
95394              );
95395
95396              return;
95397            }
95398            if (y >= maxY || !this._doFill) {
95399              return; // don't render lines beyond our maxY position
95400            }
95401
95402            if (!this._isOpenType()) {
95403              console.log(
95404                'WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts are supported'
95405              );
95406
95407              return p;
95408            }
95409
95410            p.push(); // fix to #803
95411
95412            // remember this state, so it can be restored later
95413            var doStroke = this._doStroke;
95414            var drawMode = this.drawMode;
95415
95416            this._doStroke = false;
95417            this.drawMode = constants.TEXTURE;
95418
95419            // get the cached FontInfo object
95420            var font = this._textFont.font;
95421            var fontInfo = this._textFont._fontInfo;
95422            if (!fontInfo) {
95423              fontInfo = this._textFont._fontInfo = new FontInfo(font);
95424            }
95425
95426            // calculate the alignment and move/scale the view accordingly
95427            var pos = this._textFont._handleAlignment(this, line, x, y);
95428            var fontSize = this._textSize;
95429            var scale = fontSize / font.unitsPerEm;
95430            this.translate(pos.x, pos.y, 0);
95431            this.scale(scale, scale, 1);
95432
95433            // initialize the font shader
95434            var gl = this.GL;
95435            var initializeShader = !this._defaultFontShader;
95436            var sh = this._getFontShader();
95437            sh.init();
95438            sh.bindShader(); // first time around, bind the shader fully
95439
95440            if (initializeShader) {
95441              // these are constants, really. just initialize them one-time.
95442              sh.setUniform('uGridImageSize', [gridImageWidth, gridImageHeight]);
95443              sh.setUniform('uCellsImageSize', [cellImageWidth, cellImageHeight]);
95444              sh.setUniform('uStrokeImageSize', [strokeImageWidth, strokeImageHeight]);
95445              sh.setUniform('uGridSize', [charGridWidth, charGridHeight]);
95446            }
95447            this._applyColorBlend(this.curFillColor);
95448
95449            var g = this.retainedMode.geometry['glyph'];
95450            if (!g) {
95451              // create the geometry for rendering a quad
95452              var geom = (this._textGeom = new _main.default.Geometry(1, 1, function() {
95453                for (var i = 0; i <= 1; i++) {
95454                  for (var j = 0; j <= 1; j++) {
95455                    this.vertices.push(new _main.default.Vector(j, i, 0));
95456                    this.uvs.push(j, i);
95457                  }
95458                }
95459              }));
95460              geom.computeFaces().computeNormals();
95461              g = this.createBuffers('glyph', geom);
95462            }
95463
95464            // bind the shader buffers
95465            var _iteratorNormalCompletion3 = true;
95466            var _didIteratorError3 = false;
95467            var _iteratorError3 = undefined;
95468            try {
95469              for (
95470                var _iterator3 = this.retainedMode.buffers.text[Symbol.iterator](), _step3;
95471                !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done);
95472                _iteratorNormalCompletion3 = true
95473              ) {
95474                var buff = _step3.value;
95475                buff._prepareBuffer(g, sh);
95476              }
95477            } catch (err) {
95478              _didIteratorError3 = true;
95479              _iteratorError3 = err;
95480            } finally {
95481              try {
95482                if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
95483                  _iterator3.return();
95484                }
95485              } finally {
95486                if (_didIteratorError3) {
95487                  throw _iteratorError3;
95488                }
95489              }
95490            }
95491            this._bindBuffer(g.indexBuffer, gl.ELEMENT_ARRAY_BUFFER);
95492
95493            // this will have to do for now...
95494            sh.setUniform('uMaterialColor', this.curFillColor);
95495
95496            try {
95497              var dx = 0; // the x position in the line
95498              var glyphPrev = null; // the previous glyph, used for kerning
95499              // fetch the glyphs in the line of text
95500              var glyphs = font.stringToGlyphs(line);
95501              var _iteratorNormalCompletion4 = true;
95502              var _didIteratorError4 = false;
95503              var _iteratorError4 = undefined;
95504              try {
95505                for (
95506                  var _iterator4 = glyphs[Symbol.iterator](), _step4;
95507                  !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done);
95508                  _iteratorNormalCompletion4 = true
95509                ) {
95510                  var glyph = _step4.value;
95511                  // kern
95512                  if (glyphPrev) dx += font.getKerningValue(glyphPrev, glyph);
95513
95514                  var gi = fontInfo.getGlyphInfo(glyph);
95515                  if (gi.uGlyphRect) {
95516                    var rowInfo = gi.rowInfo;
95517                    var colInfo = gi.colInfo;
95518                    sh.setUniform('uSamplerStrokes', gi.strokeImageInfo.imageData);
95519                    sh.setUniform('uSamplerRowStrokes', rowInfo.cellImageInfo.imageData);
95520                    sh.setUniform('uSamplerRows', rowInfo.dimImageInfo.imageData);
95521                    sh.setUniform('uSamplerColStrokes', colInfo.cellImageInfo.imageData);
95522                    sh.setUniform('uSamplerCols', colInfo.dimImageInfo.imageData);
95523                    sh.setUniform('uGridOffset', gi.uGridOffset);
95524                    sh.setUniform('uGlyphRect', gi.uGlyphRect);
95525                    sh.setUniform('uGlyphOffset', dx);
95526
95527                    sh.bindTextures(); // afterwards, only textures need updating
95528
95529                    // draw it
95530                    gl.drawElements(gl.TRIANGLES, 6, this.GL.UNSIGNED_SHORT, 0);
95531                  }
95532                  dx += glyph.advanceWidth;
95533                  glyphPrev = glyph;
95534                }
95535              } catch (err) {
95536                _didIteratorError4 = true;
95537                _iteratorError4 = err;
95538              } finally {
95539                try {
95540                  if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
95541                    _iterator4.return();
95542                  }
95543                } finally {
95544                  if (_didIteratorError4) {
95545                    throw _iteratorError4;
95546                  }
95547                }
95548              }
95549            } finally {
95550              // clean up
95551              sh.unbindShader();
95552
95553              this._doStroke = doStroke;
95554              this.drawMode = drawMode;
95555
95556              p.pop();
95557            }
95558
95559            return p;
95560          };
95561        },
95562        {
95563          '../core/constants': 48,
95564          '../core/main': 59,
95565          './p5.RendererGL.Retained': 112,
95566          './p5.Shader': 114
95567        }
95568      ],
95569      117: [
95570        function(_dereq_, module, exports) {
95571          module.exports = {
95572            fes: {
95573              autoplay:
95574                "The media that tried to play (with '{{src}}') wasn't allowed to by this browser, most likely due to the browser's autoplay policy. Check out {{link}} for more information about why.",
95575              checkUserDefinedFns:
95576                "It seems that you may have accidentally written {{name}} instead of {{actualName}}.\n\nPlease correct it if it's not intentional.",
95577              fileLoadError: {
95578                bytes:
95579                  'It looks like there was a problem loading your file. {{suggestion}}',
95580                font: 'It looks like there was a problem loading your font. {{suggestion}}',
95581                gif:
95582                  'There was some trouble loading your GIF. Make sure that your GIF is using 87a or 89a encoding.',
95583                image:
95584                  'It looks like there was a problem loading your image. {{suggestion}}',
95585                json:
95586                  'It looks like there was a problem loading your JSON file. {{suggestion}}',
95587                large:
95588                  "If your large file isn't fetched successfully, we recommend splitting the file into smaller segments and fetching those.",
95589                strings:
95590                  'It looks like there was a problem loading your text file. {{suggestion}}',
95591                suggestion:
95592                  'Try checking if the file path ({{filePath}}) is correct, hosting the file online, or running a local server. (More info at {{link}})',
95593                table:
95594                  'It looks like there was a problem loading your table file. {{suggestion}}',
95595                xml:
95596                  'It looks like there was a problem loading your XML file. {{suggestion}}'
95597              },
95598              friendlyParamError: {
95599                type_EMPTY_VAR:
95600                  '{{func}}() was expecting {{formatType}} for the {{position}} parameter, received an empty variable instead. {{location}}\n\nIf not intentional, this is often a problem with scope: {{link}}',
95601                type_TOO_FEW_ARGUMENTS:
95602                  '{{func}}() was expecting at least {{minParams}} arguments, but received only {{argCount}}. {{location}}',
95603                type_TOO_MANY_ARGUMENTS:
95604                  '{{func}}() was expecting no more than {{maxParams}} arguments, but received {{argCount}}. {{location}}',
95605                type_WRONG_TYPE:
95606                  '{{func}}() was expecting {{formatType}} for the {{position}} parameter, received {{argType}} instead. {{location}}'
95607              },
95608              globalErrors: {
95609                reference: {
95610                  notDefined:
95611                    'There\'s an error due to "{{symbol}}" not being defined in the current scope {{location}}.\n\nIf you have defined it in your code, you should check its scope, spelling, and letter-casing (JavaScript is case-sensitive). For more:\n{{url1}}\n{{url2}}'
95612                },
95613                stackSubseq:
95614                  '▶️ Called from line {{line}} in "{{func}}" in {{file}} ({{location}})\n\n',
95615                stackTop:
95616                  '▶️ Error at line {{line}} in "{{func}}" in {{file}} ({{location}})\n\n',
95617                syntax: {
95618                  invalidToken:
95619                    "There's a syntax error due to a symbol that JavaScript doesn't recognize or didn't expect at it's place.\nFor more: {{url}}",
95620                  unexpectedToken:
95621                    "There's a syntax error due to a symbol that wasn't expected at it's place.\nUsually this is due to a typo. Check the line number in the error below for anything missing/extra.\nFor more: {{url}}"
95622                },
95623                type: {
95624                  notfunc:
95625                    'There\'s an error as "{{symbol}}" could not be called as a function {{location}}.\nCheck the spelling, letter-casing (Javacript is case-sensitive) and its type.\nFor more: {{url}}',
95626                  notfuncObj:
95627                    'There\'s an error as "{{symbol}}" could not be called as a function {{location}}.\nVerify whether "{{obj}}" has "{{symbol}}" in it and check the spelling, letter-casing (Javacript is case-sensitive) and its type.\nFor more: {{url}}'
95628                }
95629              },
95630              libraryError:
95631                'An error with message "{{error}}" occured inside the p5js library when {{func}} was called {{location}}\n\nIf not stated otherwise, it might be an issue with the arguments passed to {{func}}.',
95632              location: '(on line {{line}} in {{file}} [{{location}}])',
95633              misspelling:
95634                'It seems that you may have accidentally written "{{name}}" instead of "{{actualName}}" {{location}}.\n\nPlease correct it to {{actualName}} if you wish to use the {{type}} from p5.js',
95635              misspelling_plural:
95636                'It seems that you may have accidentally written "{{name}}" {{location}}.\n\nYou may have meant one of the following:\n{{suggestions}}',
95637              misusedTopLevel:
95638                "Did you just try to use p5.js's {{symbolName}} {{symbolType}}? If so, you may want to move it into your sketch's setup() function.\n\nFor more details, see: {{link}}",
95639              positions: {
95640                p_1: 'first',
95641                p_10: 'tenth',
95642                p_11: 'eleventh',
95643                p_12: 'twelfth',
95644                p_2: 'second',
95645                p_3: 'third',
95646                p_4: 'fourth',
95647                p_5: 'fifth',
95648                p_6: 'sixth',
95649                p_7: 'seventh',
95650                p_8: 'eighth',
95651                p_9: 'ninth'
95652              },
95653              pre: '\n🌸 p5.js says: {{message}}',
95654              welcome:
95655                'Welcome! This is your friendly debugger. To turn me off, switch to using p5.min.js.',
95656              wrongPreload:
95657                'An error with message "{{error}}" occured inside the p5js library when "{{func}}" was called {{location}}.\n\nIf not stated otherwise, it might be due to "{{func}}" being called from preload. Nothing besides load calls (loadImage, loadJSON, loadFont, loadStrings, etc.) should be inside the preload function.'
95658            }
95659          };
95660        },
95661        {}
95662      ],
95663      118: [
95664        function(_dereq_, module, exports) {
95665          'use strict';
95666          Object.defineProperty(exports, '__esModule', { value: true });
95667          exports.languages = exports.default = void 0;
95668          var _translation = _interopRequireDefault(_dereq_('./en/translation'));
95669          function _interopRequireDefault(obj) {
95670            return obj && obj.__esModule ? obj : { default: obj };
95671          }
95672
95673          // Only one language is imported above. This is intentional as other languages
95674          // will be hosted online and then downloaded whenever needed
95675
95676          /**
95677           * Here, we define a default/fallback language which we can use without internet.
95678           * You won't have to change this when adding a new language.
95679           *
95680           * `translation` is the namespace we are using for our initial set of strings
95681           */ var _default = {
95682            en: {
95683              translation: _translation.default
95684            }
95685          };
95686
95687          /**
95688           * This is a list of languages that we have added so far.
95689           * If you have just added a new language (yay!), add its key to the list below
95690           * (`en` is english, `es` es español). Also add its export to
95691           * dev.js, which is another file in this folder.
95692           */ exports.default = _default;
95693          var languages = ['en', 'es'];
95694          exports.languages = languages;
95695        },
95696        { './en/translation': 117 }
95697      ]
95698    },
95699    {},
95700    [43]
95701  )(43);
95702});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.