Passed
Push — master ( fdcd11...4b42b4 )
by Ron
07:37
created

public/js/tinymce/themes/mobile/theme.js   F

Complexity

Total Complexity 2796
Complexity/F 1.22

Size

Lines of Code 12614
Function Count 2288

Duplication

Duplicated Lines 469
Ratio 3.72 %

Importance

Changes 0
Metric Value
eloc 9184
c 0
b 0
f 0
dl 469
loc 12614
rs 0.8
wmc 2796
mnd 508
bc 508
fnc 2288
bpm 0.222
cpm 1.222
noi 27

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like public/js/tinymce/themes/mobile/theme.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
(function () {
2
var mobile = (function () {
3
    'use strict';
4
5
    var noop = function () {
6
      var args = [];
7
      for (var _i = 0; _i < arguments.length; _i++) {
8
        args[_i] = arguments[_i];
9
      }
10
    };
11
    var compose = function (fa, fb) {
12
      return function () {
13
        var args = [];
14
        for (var _i = 0; _i < arguments.length; _i++) {
15
          args[_i] = arguments[_i];
16
        }
17
        return fa(fb.apply(null, args));
18
      };
19
    };
20
    var constant = function (value) {
21
      return function () {
22
        return value;
23
      };
24
    };
25
    var identity = function (x) {
26
      return x;
27
    };
28
    function curry(fn) {
29
      var initialArgs = [];
30
      for (var _i = 1; _i < arguments.length; _i++) {
31
        initialArgs[_i - 1] = arguments[_i];
32
      }
33
      return function () {
34
        var restArgs = [];
35
        for (var _i = 0; _i < arguments.length; _i++) {
36
          restArgs[_i] = arguments[_i];
37
        }
38
        var all = initialArgs.concat(restArgs);
39
        return fn.apply(null, all);
40
      };
41
    }
42
    var not = function (f) {
43
      return function () {
44
        var args = [];
45
        for (var _i = 0; _i < arguments.length; _i++) {
46
          args[_i] = arguments[_i];
47
        }
48
        return !f.apply(null, args);
49
      };
50
    };
51
    var die = function (msg) {
52
      return function () {
53
        throw new Error(msg);
54
      };
55
    };
56
    var apply = function (f) {
57
      return f();
58
    };
59
    var never = constant(false);
60
    var always = constant(true);
61
62
    var typeOf = function (x) {
63
      if (x === null)
64
        return 'null';
65
      var t = typeof x;
66
      if (t === 'object' && Array.prototype.isPrototypeOf(x))
67
        return 'array';
68
      if (t === 'object' && String.prototype.isPrototypeOf(x))
69
        return 'string';
70
      return t;
71
    };
72
    var isType = function (type) {
73
      return function (value) {
74
        return typeOf(value) === type;
75
      };
76
    };
77
    var isString = isType('string');
78
    var isObject = isType('object');
79
    var isArray = isType('array');
80
    var isBoolean = isType('boolean');
81
    var isFunction = isType('function');
82
    var isNumber = isType('number');
83
84
    var hasOwnProperty = Object.prototype.hasOwnProperty;
85
    var shallow = function (old, nu) {
86
      return nu;
87
    };
88
    var deep = function (old, nu) {
89
      var bothObjects = isObject(old) && isObject(nu);
90
      return bothObjects ? deepMerge(old, nu) : nu;
91
    };
92
    var baseMerge = function (merger) {
93
      return function () {
94
        var objects = new Array(arguments.length);
95
        for (var i = 0; i < objects.length; i++)
96
          objects[i] = arguments[i];
97
        if (objects.length === 0)
98
          throw new Error('Can\'t merge zero objects');
99
        var ret = {};
100
        for (var j = 0; j < objects.length; j++) {
101
          var curObject = objects[j];
102
          for (var key in curObject)
103
            if (hasOwnProperty.call(curObject, key)) {
104
              ret[key] = merger(ret[key], curObject[key]);
105
            }
106
        }
107
        return ret;
108
      };
109
    };
110
    var deepMerge = baseMerge(deep);
111
    var merge = baseMerge(shallow);
112
113
    var never$1 = never;
114
    var always$1 = always;
115
    var none = function () {
116
      return NONE;
117
    };
118
    var NONE = function () {
119
      var eq = function (o) {
120
        return o.isNone();
121
      };
122
      var call$$1 = function (thunk) {
123
        return thunk();
124
      };
125
      var id = function (n) {
126
        return n;
127
      };
128
      var noop$$1 = function () {
129
      };
130
      var nul = function () {
131
        return null;
132
      };
133
      var undef = function () {
134
        return undefined;
135
      };
136
      var me = {
137
        fold: function (n, s) {
138
          return n();
139
        },
140
        is: never$1,
141
        isSome: never$1,
142
        isNone: always$1,
143
        getOr: id,
144
        getOrThunk: call$$1,
145
        getOrDie: function (msg) {
146
          throw new Error(msg || 'error: getOrDie called on none.');
147
        },
148
        getOrNull: nul,
149
        getOrUndefined: undef,
150
        or: id,
151
        orThunk: call$$1,
152
        map: none,
153
        ap: none,
154
        each: noop$$1,
155
        bind: none,
156
        flatten: none,
157
        exists: never$1,
158
        forall: always$1,
159
        filter: none,
160
        equals: eq,
161
        equals_: eq,
162
        toArray: function () {
163
          return [];
164
        },
165
        toString: constant('none()')
166
      };
167
      if (Object.freeze)
168
        Object.freeze(me);
169
      return me;
170
    }();
171
    var some = function (a) {
172
      var constant_a = function () {
173
        return a;
174
      };
175
      var self = function () {
176
        return me;
177
      };
178
      var map = function (f) {
179
        return some(f(a));
180
      };
181
      var bind = function (f) {
182
        return f(a);
183
      };
184
      var me = {
185
        fold: function (n, s) {
186
          return s(a);
187
        },
188
        is: function (v) {
189
          return a === v;
190
        },
191
        isSome: always$1,
192
        isNone: never$1,
193
        getOr: constant_a,
194
        getOrThunk: constant_a,
195
        getOrDie: constant_a,
196
        getOrNull: constant_a,
197
        getOrUndefined: constant_a,
198
        or: self,
199
        orThunk: self,
200
        map: map,
201
        ap: function (optfab) {
202
          return optfab.fold(none, function (fab) {
203
            return some(fab(a));
204
          });
205
        },
206
        each: function (f) {
207
          f(a);
208
        },
209
        bind: bind,
210
        flatten: constant_a,
211
        exists: bind,
212
        forall: bind,
213
        filter: function (f) {
214
          return f(a) ? me : NONE;
215
        },
216
        equals: function (o) {
217
          return o.is(a);
218
        },
219
        equals_: function (o, elementEq) {
220
          return o.fold(never$1, function (b) {
221
            return elementEq(a, b);
222
          });
223
        },
224
        toArray: function () {
225
          return [a];
226
        },
227
        toString: function () {
228
          return 'some(' + a + ')';
229
        }
230
      };
231
      return me;
232
    };
233
    var from = function (value) {
234
      return value === null || value === undefined ? NONE : some(value);
235
    };
236
    var Option = {
237
      some: some,
238
      none: none,
239
      from: from
240
    };
241
242
    var keys = Object.keys;
243
    var each = function (obj, f) {
244
      var props = keys(obj);
245
      for (var k = 0, len = props.length; k < len; k++) {
246
        var i = props[k];
247
        var x = obj[i];
248
        f(x, i, obj);
249
      }
250
    };
251
    var map = function (obj, f) {
252
      return tupleMap(obj, function (x, i, obj) {
253
        return {
254
          k: i,
255
          v: f(x, i, obj)
256
        };
257
      });
258
    };
259
    var tupleMap = function (obj, f) {
260
      var r = {};
261
      each(obj, function (x, i) {
262
        var tuple = f(x, i, obj);
263
        r[tuple.k] = tuple.v;
264
      });
265
      return r;
266
    };
267
    var mapToArray = function (obj, f) {
268
      var r = [];
269
      each(obj, function (value, name) {
270
        r.push(f(value, name));
271
      });
272
      return r;
273
    };
274
275
    var touchstart = constant('touchstart');
276
    var touchmove = constant('touchmove');
277
    var touchend = constant('touchend');
278
    var mousedown = constant('mousedown');
279
    var mousemove = constant('mousemove');
280
    var mouseup = constant('mouseup');
281
    var mouseover = constant('mouseover');
282
    var keydown = constant('keydown');
283
    var input = constant('input');
284
    var change = constant('change');
285
    var click = constant('click');
286
    var transitionend = constant('transitionend');
287
    var selectstart = constant('selectstart');
288
289
    var cached = function (f) {
290
      var called = false;
291
      var r;
292
      return function () {
293
        var args = [];
294
        for (var _i = 0; _i < arguments.length; _i++) {
295
          args[_i] = arguments[_i];
296
        }
297
        if (!called) {
298
          called = true;
299
          r = f.apply(null, args);
300
        }
301
        return r;
302
      };
303
    };
304
305
    var firstMatch = function (regexes, s) {
306
      for (var i = 0; i < regexes.length; i++) {
307
        var x = regexes[i];
308
        if (x.test(s))
309
          return x;
310
      }
311
      return undefined;
312
    };
313
    var find$1 = function (regexes, agent) {
314
      var r = firstMatch(regexes, agent);
315
      if (!r)
316
        return {
317
          major: 0,
318
          minor: 0
319
        };
320
      var group = function (i) {
321
        return Number(agent.replace(r, '$' + i));
322
      };
323
      return nu(group(1), group(2));
324
    };
325
    var detect = function (versionRegexes, agent) {
326
      var cleanedAgent = String(agent).toLowerCase();
327
      if (versionRegexes.length === 0)
328
        return unknown();
329
      return find$1(versionRegexes, cleanedAgent);
330
    };
331
    var unknown = function () {
332
      return nu(0, 0);
333
    };
334
    var nu = function (major, minor) {
335
      return {
336
        major: major,
337
        minor: minor
338
      };
339
    };
340
    var Version = {
341
      nu: nu,
342
      detect: detect,
343
      unknown: unknown
344
    };
345
346
    var edge = 'Edge';
347
    var chrome = 'Chrome';
348
    var ie = 'IE';
349
    var opera = 'Opera';
350
    var firefox = 'Firefox';
351
    var safari = 'Safari';
352
    var isBrowser = function (name, current) {
353
      return function () {
354
        return current === name;
355
      };
356
    };
357
    var unknown$1 = function () {
358
      return nu$1({
359
        current: undefined,
360
        version: Version.unknown()
361
      });
362
    };
363
    var nu$1 = function (info) {
364
      var current = info.current;
365
      var version = info.version;
366
      return {
367
        current: current,
368
        version: version,
369
        isEdge: isBrowser(edge, current),
370
        isChrome: isBrowser(chrome, current),
371
        isIE: isBrowser(ie, current),
372
        isOpera: isBrowser(opera, current),
373
        isFirefox: isBrowser(firefox, current),
374
        isSafari: isBrowser(safari, current)
375
      };
376
    };
377
    var Browser = {
378
      unknown: unknown$1,
379
      nu: nu$1,
380
      edge: constant(edge),
381
      chrome: constant(chrome),
382
      ie: constant(ie),
383
      opera: constant(opera),
384
      firefox: constant(firefox),
385
      safari: constant(safari)
386
    };
387
388
    var windows = 'Windows';
389
    var ios = 'iOS';
390
    var android = 'Android';
391
    var linux = 'Linux';
392
    var osx = 'OSX';
393
    var solaris = 'Solaris';
394
    var freebsd = 'FreeBSD';
395
    var isOS = function (name, current) {
396
      return function () {
397
        return current === name;
398
      };
399
    };
400
    var unknown$2 = function () {
401
      return nu$2({
402
        current: undefined,
403
        version: Version.unknown()
404
      });
405
    };
406
    var nu$2 = function (info) {
407
      var current = info.current;
408
      var version = info.version;
409
      return {
410
        current: current,
411
        version: version,
412
        isWindows: isOS(windows, current),
413
        isiOS: isOS(ios, current),
414
        isAndroid: isOS(android, current),
415
        isOSX: isOS(osx, current),
416
        isLinux: isOS(linux, current),
417
        isSolaris: isOS(solaris, current),
418
        isFreeBSD: isOS(freebsd, current)
419
      };
420
    };
421
    var OperatingSystem = {
422
      unknown: unknown$2,
423
      nu: nu$2,
424
      windows: constant(windows),
425
      ios: constant(ios),
426
      android: constant(android),
427
      linux: constant(linux),
428
      osx: constant(osx),
429
      solaris: constant(solaris),
430
      freebsd: constant(freebsd)
431
    };
432
433
    var DeviceType = function (os, browser, userAgent) {
434
      var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
435
      var isiPhone = os.isiOS() && !isiPad;
436
      var isAndroid3 = os.isAndroid() && os.version.major === 3;
437
      var isAndroid4 = os.isAndroid() && os.version.major === 4;
438
      var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true;
439
      var isTouch = os.isiOS() || os.isAndroid();
440
      var isPhone = isTouch && !isTablet;
441
      var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
442
      return {
443
        isiPad: constant(isiPad),
444
        isiPhone: constant(isiPhone),
445
        isTablet: constant(isTablet),
446
        isPhone: constant(isPhone),
447
        isTouch: constant(isTouch),
448
        isAndroid: os.isAndroid,
449
        isiOS: os.isiOS,
450
        isWebView: constant(iOSwebview)
451
      };
452
    };
453
454
    var rawIndexOf = function () {
455
      var pIndexOf = Array.prototype.indexOf;
456
      var fastIndex = function (xs, x) {
457
        return pIndexOf.call(xs, x);
458
      };
459
      var slowIndex = function (xs, x) {
460
        return slowIndexOf(xs, x);
461
      };
462
      return pIndexOf === undefined ? slowIndex : fastIndex;
463
    }();
464
    var contains = function (xs, x) {
465
      return rawIndexOf(xs, x) > -1;
466
    };
467
    var exists = function (xs, pred) {
468
      return findIndex(xs, pred).isSome();
469
    };
470
    var map$1 = function (xs, f) {
471
      var len = xs.length;
472
      var r = new Array(len);
473
      for (var i = 0; i < len; i++) {
474
        var x = xs[i];
475
        r[i] = f(x, i, xs);
476
      }
477
      return r;
478
    };
479
    var each$1 = function (xs, f) {
480
      for (var i = 0, len = xs.length; i < len; i++) {
481
        var x = xs[i];
482
        f(x, i, xs);
483
      }
484
    };
485
    var eachr = function (xs, f) {
486
      for (var i = xs.length - 1; i >= 0; i--) {
487
        var x = xs[i];
488
        f(x, i, xs);
489
      }
490
    };
491
    var filter = function (xs, pred) {
492
      var r = [];
493
      for (var i = 0, len = xs.length; i < len; i++) {
494
        var x = xs[i];
495
        if (pred(x, i, xs)) {
496
          r.push(x);
497
        }
498
      }
499
      return r;
500
    };
501
    var foldr = function (xs, f, acc) {
502
      eachr(xs, function (x) {
503
        acc = f(acc, x);
504
      });
505
      return acc;
506
    };
507
    var foldl = function (xs, f, acc) {
508
      each$1(xs, function (x) {
509
        acc = f(acc, x);
510
      });
511
      return acc;
512
    };
513
    var find$2 = function (xs, pred) {
514
      for (var i = 0, len = xs.length; i < len; i++) {
515
        var x = xs[i];
516
        if (pred(x, i, xs)) {
517
          return Option.some(x);
518
        }
519
      }
520
      return Option.none();
521
    };
522
    var findIndex = function (xs, pred) {
523
      for (var i = 0, len = xs.length; i < len; i++) {
524
        var x = xs[i];
525
        if (pred(x, i, xs)) {
526
          return Option.some(i);
527
        }
528
      }
529
      return Option.none();
530
    };
531
    var slowIndexOf = function (xs, x) {
532
      for (var i = 0, len = xs.length; i < len; ++i) {
533
        if (xs[i] === x) {
534
          return i;
535
        }
536
      }
537
      return -1;
538
    };
539
    var push = Array.prototype.push;
540
    var flatten = function (xs) {
541
      var r = [];
542
      for (var i = 0, len = xs.length; i < len; ++i) {
543
        if (!Array.prototype.isPrototypeOf(xs[i]))
544
          throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
545
        push.apply(r, xs[i]);
546
      }
547
      return r;
548
    };
549
    var bind = function (xs, f) {
550
      var output = map$1(xs, f);
551
      return flatten(output);
552
    };
553
    var forall = function (xs, pred) {
554
      for (var i = 0, len = xs.length; i < len; ++i) {
555
        var x = xs[i];
556
        if (pred(x, i, xs) !== true) {
557
          return false;
558
        }
559
      }
560
      return true;
561
    };
562
    var slice = Array.prototype.slice;
563
    var reverse = function (xs) {
564
      var r = slice.call(xs, 0);
565
      r.reverse();
566
      return r;
567
    };
568
    var difference = function (a1, a2) {
569
      return filter(a1, function (x) {
570
        return !contains(a2, x);
571
      });
572
    };
573
    var pure = function (x) {
574
      return [x];
575
    };
576
    var from$1 = isFunction(Array.from) ? Array.from : function (x) {
577
      return slice.call(x);
578
    };
579
580
    var detect$1 = function (candidates, userAgent) {
581
      var agent = String(userAgent).toLowerCase();
582
      return find$2(candidates, function (candidate) {
583
        return candidate.search(agent);
584
      });
585
    };
586
    var detectBrowser = function (browsers, userAgent) {
587
      return detect$1(browsers, userAgent).map(function (browser) {
588
        var version = Version.detect(browser.versionRegexes, userAgent);
589
        return {
590
          current: browser.name,
591
          version: version
592
        };
593
      });
594
    };
595
    var detectOs = function (oses, userAgent) {
596
      return detect$1(oses, userAgent).map(function (os) {
597
        var version = Version.detect(os.versionRegexes, userAgent);
598
        return {
599
          current: os.name,
600
          version: version
601
        };
602
      });
603
    };
604
    var UaString = {
605
      detectBrowser: detectBrowser,
606
      detectOs: detectOs
607
    };
608
609
    var checkRange = function (str, substr, start) {
610
      if (substr === '')
611
        return true;
612
      if (str.length < substr.length)
613
        return false;
614
      var x = str.substr(start, start + substr.length);
615
      return x === substr;
616
    };
617
    var supplant = function (str, obj) {
618
      var isStringOrNumber = function (a) {
619
        var t = typeof a;
620
        return t === 'string' || t === 'number';
621
      };
622
      return str.replace(/\$\{([^{}]*)\}/g, function (fullMatch, key) {
623
        var value = obj[key];
624
        return isStringOrNumber(value) ? value.toString() : fullMatch;
625
      });
626
    };
627
    var contains$1 = function (str, substr) {
628
      return str.indexOf(substr) !== -1;
629
    };
630
    var endsWith = function (str, suffix) {
631
      return checkRange(str, suffix, str.length - suffix.length);
632
    };
633
    var trim = function (str) {
634
      return str.replace(/^\s+|\s+$/g, '');
635
    };
636
637
    var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
638
    var checkContains = function (target) {
639
      return function (uastring) {
640
        return contains$1(uastring, target);
641
      };
642
    };
643
    var browsers = [
644
      {
645
        name: 'Edge',
646
        versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
647
        search: function (uastring) {
648
          var monstrosity = contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit');
649
          return monstrosity;
650
        }
651
      },
652
      {
653
        name: 'Chrome',
654
        versionRegexes: [
655
          /.*?chrome\/([0-9]+)\.([0-9]+).*/,
656
          normalVersionRegex
657
        ],
658
        search: function (uastring) {
659
          return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe');
660
        }
661
      },
662
      {
663
        name: 'IE',
664
        versionRegexes: [
665
          /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
666
          /.*?rv:([0-9]+)\.([0-9]+).*/
667
        ],
668
        search: function (uastring) {
669
          return contains$1(uastring, 'msie') || contains$1(uastring, 'trident');
670
        }
671
      },
672
      {
673
        name: 'Opera',
674
        versionRegexes: [
675
          normalVersionRegex,
676
          /.*?opera\/([0-9]+)\.([0-9]+).*/
677
        ],
678
        search: checkContains('opera')
679
      },
680
      {
681
        name: 'Firefox',
682
        versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
683
        search: checkContains('firefox')
684
      },
685
      {
686
        name: 'Safari',
687
        versionRegexes: [
688
          normalVersionRegex,
689
          /.*?cpu os ([0-9]+)_([0-9]+).*/
690
        ],
691
        search: function (uastring) {
692
          return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit');
693
        }
694
      }
695
    ];
696
    var oses = [
697
      {
698
        name: 'Windows',
699
        search: checkContains('win'),
700
        versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
701
      },
702
      {
703
        name: 'iOS',
704
        search: function (uastring) {
705
          return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad');
706
        },
707
        versionRegexes: [
708
          /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
709
          /.*cpu os ([0-9]+)_([0-9]+).*/,
710
          /.*cpu iphone os ([0-9]+)_([0-9]+).*/
711
        ]
712
      },
713
      {
714
        name: 'Android',
715
        search: checkContains('android'),
716
        versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
717
      },
718
      {
719
        name: 'OSX',
720
        search: checkContains('os x'),
721
        versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/]
722
      },
723
      {
724
        name: 'Linux',
725
        search: checkContains('linux'),
726
        versionRegexes: []
727
      },
728
      {
729
        name: 'Solaris',
730
        search: checkContains('sunos'),
731
        versionRegexes: []
732
      },
733
      {
734
        name: 'FreeBSD',
735
        search: checkContains('freebsd'),
736
        versionRegexes: []
737
      }
738
    ];
739
    var PlatformInfo = {
740
      browsers: constant(browsers),
741
      oses: constant(oses)
742
    };
743
744
    var detect$2 = function (userAgent) {
745
      var browsers = PlatformInfo.browsers();
746
      var oses = PlatformInfo.oses();
747
      var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);
748
      var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
749
      var deviceType = DeviceType(os, browser, userAgent);
750
      return {
751
        browser: browser,
752
        os: os,
753
        deviceType: deviceType
754
      };
755
    };
756
    var PlatformDetection = { detect: detect$2 };
757
758
    var detect$3 = cached(function () {
759
      var userAgent = navigator.userAgent;
760
      return PlatformDetection.detect(userAgent);
761
    });
762
    var PlatformDetection$1 = { detect: detect$3 };
763
764
    var alloy = { tap: constant('alloy.tap') };
765
    var focus$1 = constant('alloy.focus');
766
    var postBlur = constant('alloy.blur.post');
767
    var receive = constant('alloy.receive');
768
    var execute = constant('alloy.execute');
769
    var focusItem = constant('alloy.focus.item');
770
    var tap = alloy.tap;
771
    var tapOrClick = PlatformDetection$1.detect().deviceType.isTouch() ? alloy.tap : click;
772
    var longpress = constant('alloy.longpress');
773
    var systemInit = constant('alloy.system.init');
774
    var windowScroll = constant('alloy.system.scroll');
775
    var attachedToDom = constant('alloy.system.attached');
776
    var detachedFromDom = constant('alloy.system.detached');
777
778
    var emit = function (component, event) {
779
      dispatchWith(component, component.element(), event, {});
780
    };
781
    var emitWith = function (component, event, properties) {
782
      dispatchWith(component, component.element(), event, properties);
783
    };
784
    var emitExecute = function (component) {
785
      emit(component, execute());
786
    };
787
    var dispatch = function (component, target, event) {
788
      dispatchWith(component, target, event, {});
789
    };
790
    var dispatchWith = function (component, target, event, properties) {
791
      var data = deepMerge({ target: target }, properties);
792
      component.getSystem().triggerEvent(event, target, map(data, constant));
793
    };
794
    var dispatchEvent = function (component, target, event, simulatedEvent) {
795
      component.getSystem().triggerEvent(event, target, simulatedEvent.event());
796
    };
797
    var dispatchFocus = function (component, target) {
798
      component.getSystem().triggerFocus(target, component.element());
799
    };
800
801
    var fromHtml = function (html, scope) {
802
      var doc = scope || document;
803
      var div = doc.createElement('div');
804
      div.innerHTML = html;
805
      if (!div.hasChildNodes() || div.childNodes.length > 1) {
806
        console.error('HTML does not have a single root node', html);
807
        throw 'HTML must have a single root node';
808
      }
809
      return fromDom(div.childNodes[0]);
810
    };
811
    var fromTag = function (tag, scope) {
812
      var doc = scope || document;
813
      var node = doc.createElement(tag);
814
      return fromDom(node);
815
    };
816
    var fromText = function (text, scope) {
817
      var doc = scope || document;
818
      var node = doc.createTextNode(text);
819
      return fromDom(node);
820
    };
821
    var fromDom = function (node) {
822
      if (node === null || node === undefined)
823
        throw new Error('Node cannot be null or undefined');
824
      return { dom: constant(node) };
825
    };
826
    var fromPoint = function (docElm, x, y) {
827
      var doc = docElm.dom();
828
      return Option.from(doc.elementFromPoint(x, y)).map(fromDom);
829
    };
830
    var Element$$1 = {
831
      fromHtml: fromHtml,
832
      fromTag: fromTag,
833
      fromText: fromText,
834
      fromDom: fromDom,
835
      fromPoint: fromPoint
836
    };
837
838
    var ATTRIBUTE = Node.ATTRIBUTE_NODE;
839
    var CDATA_SECTION = Node.CDATA_SECTION_NODE;
840
    var COMMENT = Node.COMMENT_NODE;
841
    var DOCUMENT = Node.DOCUMENT_NODE;
842
    var DOCUMENT_TYPE = Node.DOCUMENT_TYPE_NODE;
843
    var DOCUMENT_FRAGMENT = Node.DOCUMENT_FRAGMENT_NODE;
844
    var ELEMENT = Node.ELEMENT_NODE;
845
    var TEXT = Node.TEXT_NODE;
846
    var PROCESSING_INSTRUCTION = Node.PROCESSING_INSTRUCTION_NODE;
847
    var ENTITY_REFERENCE = Node.ENTITY_REFERENCE_NODE;
848
    var ENTITY = Node.ENTITY_NODE;
849
    var NOTATION = Node.NOTATION_NODE;
850
851
    var name = function (element) {
852
      var r = element.dom().nodeName;
853
      return r.toLowerCase();
854
    };
855
    var type = function (element) {
856
      return element.dom().nodeType;
857
    };
858
    var isType$1 = function (t) {
859
      return function (element) {
860
        return type(element) === t;
861
      };
862
    };
863
    var isElement = isType$1(ELEMENT);
864
    var isText = isType$1(TEXT);
865
866
    var inBody = function (element) {
867
      var dom = isText(element) ? element.dom().parentNode : element.dom();
868
      return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom);
869
    };
870
    var body = cached(function () {
871
      return getBody(Element$$1.fromDom(document));
872
    });
873
    var getBody = function (doc) {
874
      var body = doc.dom().body;
875
      if (body === null || body === undefined)
876
        throw 'Body is not available yet';
877
      return Element$$1.fromDom(body);
878
    };
879
880
    var Immutable = function () {
881
      var fields = [];
882
      for (var _i = 0; _i < arguments.length; _i++) {
883
        fields[_i] = arguments[_i];
884
      }
885
      return function () {
886
        var values = [];
887
        for (var _i = 0; _i < arguments.length; _i++) {
888
          values[_i] = arguments[_i];
889
        }
890
        if (fields.length !== values.length) {
891
          throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments');
892
        }
893
        var struct = {};
894
        each$1(fields, function (name, i) {
895
          struct[name] = constant(values[i]);
896
        });
897
        return struct;
898
      };
899
    };
900
901
    var sort$1 = function (arr) {
902
      return arr.slice(0).sort();
903
    };
904
    var reqMessage = function (required, keys) {
905
      throw new Error('All required keys (' + sort$1(required).join(', ') + ') were not specified. Specified keys were: ' + sort$1(keys).join(', ') + '.');
906
    };
907
    var unsuppMessage = function (unsupported) {
908
      throw new Error('Unsupported keys for object: ' + sort$1(unsupported).join(', '));
909
    };
910
    var validateStrArr = function (label, array) {
911
      if (!isArray(array))
912
        throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.');
913
      each$1(array, function (a) {
914
        if (!isString(a))
915
          throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.');
916
      });
917
    };
918
    var invalidTypeMessage = function (incorrect, type) {
919
      throw new Error('All values need to be of type: ' + type + '. Keys (' + sort$1(incorrect).join(', ') + ') were not.');
920
    };
921
    var checkDupes = function (everything) {
922
      var sorted = sort$1(everything);
923
      var dupe = find$2(sorted, function (s, i) {
924
        return i < sorted.length - 1 && s === sorted[i + 1];
925
      });
926
      dupe.each(function (d) {
927
        throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].');
928
      });
929
    };
930
931
    var MixedBag = function (required, optional) {
932
      var everything = required.concat(optional);
933
      if (everything.length === 0)
934
        throw new Error('You must specify at least one required or optional field.');
935
      validateStrArr('required', required);
936
      validateStrArr('optional', optional);
937
      checkDupes(everything);
938
      return function (obj) {
939
        var keys$$1 = keys(obj);
940
        var allReqd = forall(required, function (req) {
941
          return contains(keys$$1, req);
942
        });
943
        if (!allReqd)
944
          reqMessage(required, keys$$1);
945
        var unsupported = filter(keys$$1, function (key) {
946
          return !contains(everything, key);
947
        });
948
        if (unsupported.length > 0)
949
          unsuppMessage(unsupported);
950
        var r = {};
951
        each$1(required, function (req) {
952
          r[req] = constant(obj[req]);
953
        });
954
        each$1(optional, function (opt) {
955
          r[opt] = constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]) : Option.none());
956
        });
957
        return r;
958
      };
959
    };
960
961
    var Global = typeof window !== 'undefined' ? window : Function('return this;')();
962
963
    var path = function (parts, scope) {
964
      var o = scope !== undefined && scope !== null ? scope : Global;
965
      for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i)
966
        o = o[parts[i]];
967
      return o;
968
    };
969
    var resolve = function (p, scope) {
970
      var parts = p.split('.');
971
      return path(parts, scope);
972
    };
973
974
    var unsafe = function (name, scope) {
975
      return resolve(name, scope);
976
    };
977
    var getOrDie = function (name, scope) {
978
      var actual = unsafe(name, scope);
979
      if (actual === undefined || actual === null)
980
        throw name + ' not available on this browser';
981
      return actual;
982
    };
983
    var Global$1 = { getOrDie: getOrDie };
984
985
    var node = function () {
986
      var f = Global$1.getOrDie('Node');
987
      return f;
988
    };
989
    var compareDocumentPosition = function (a, b, match) {
990
      return (a.compareDocumentPosition(b) & match) !== 0;
991
    };
992
    var documentPositionPreceding = function (a, b) {
993
      return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING);
994
    };
995
    var documentPositionContainedBy = function (a, b) {
996
      return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY);
997
    };
998
    var Node$1 = {
999
      documentPositionPreceding: documentPositionPreceding,
1000
      documentPositionContainedBy: documentPositionContainedBy
1001
    };
1002
1003
    var ELEMENT$1 = ELEMENT;
1004
    var DOCUMENT$1 = DOCUMENT;
1005
    var is = function (element, selector) {
1006
      var elem = element.dom();
1007
      if (elem.nodeType !== ELEMENT$1)
1008
        return false;
1009
      else if (elem.matches !== undefined)
1010
        return elem.matches(selector);
1011
      else if (elem.msMatchesSelector !== undefined)
1012
        return elem.msMatchesSelector(selector);
1013
      else if (elem.webkitMatchesSelector !== undefined)
1014
        return elem.webkitMatchesSelector(selector);
1015
      else if (elem.mozMatchesSelector !== undefined)
1016
        return elem.mozMatchesSelector(selector);
1017
      else
1018
        throw new Error('Browser lacks native selectors');
1019
    };
1020
    var bypassSelector = function (dom) {
1021
      return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0;
1022
    };
1023
    var all = function (selector, scope) {
1024
      var base = scope === undefined ? document : scope.dom();
1025
      return bypassSelector(base) ? [] : map$1(base.querySelectorAll(selector), Element$$1.fromDom);
1026
    };
1027
    var one = function (selector, scope) {
1028
      var base = scope === undefined ? document : scope.dom();
1029
      return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element$$1.fromDom);
1030
    };
1031
1032
    var eq = function (e1, e2) {
1033
      return e1.dom() === e2.dom();
1034
    };
1035
    var regularContains = function (e1, e2) {
1036
      var d1 = e1.dom(), d2 = e2.dom();
1037
      return d1 === d2 ? false : d1.contains(d2);
1038
    };
1039
    var ieContains = function (e1, e2) {
1040
      return Node$1.documentPositionContainedBy(e1.dom(), e2.dom());
1041
    };
1042
    var browser = PlatformDetection$1.detect().browser;
1043
    var contains$2 = browser.isIE() ? ieContains : regularContains;
1044
1045
    var owner = function (element) {
1046
      return Element$$1.fromDom(element.dom().ownerDocument);
1047
    };
1048
    var defaultView = function (element) {
1049
      var el = element.dom();
1050
      var defaultView = el.ownerDocument.defaultView;
1051
      return Element$$1.fromDom(defaultView);
1052
    };
1053
    var parent = function (element) {
1054
      var dom = element.dom();
1055
      return Option.from(dom.parentNode).map(Element$$1.fromDom);
1056
    };
1057
    var parents = function (element, isRoot) {
1058
      var stop = isFunction(isRoot) ? isRoot : constant(false);
1059
      var dom = element.dom();
1060
      var ret = [];
1061
      while (dom.parentNode !== null && dom.parentNode !== undefined) {
1062
        var rawParent = dom.parentNode;
1063
        var parent = Element$$1.fromDom(rawParent);
1064
        ret.push(parent);
1065
        if (stop(parent) === true)
1066
          break;
1067
        else
1068
          dom = rawParent;
1069
      }
1070
      return ret;
1071
    };
1072
    var siblings = function (element) {
1073
      var filterSelf = function (elements) {
1074
        return filter(elements, function (x) {
1075
          return !eq(element, x);
1076
        });
1077
      };
1078
      return parent(element).map(children).map(filterSelf).getOr([]);
1079
    };
1080
    var nextSibling = function (element) {
1081
      var dom = element.dom();
1082
      return Option.from(dom.nextSibling).map(Element$$1.fromDom);
1083
    };
1084
    var children = function (element) {
1085
      var dom = element.dom();
1086
      return map$1(dom.childNodes, Element$$1.fromDom);
1087
    };
1088
    var child = function (element, index) {
1089
      var children = element.dom().childNodes;
1090
      return Option.from(children[index]).map(Element$$1.fromDom);
1091
    };
1092
    var firstChild = function (element) {
1093
      return child(element, 0);
1094
    };
1095
    var spot = Immutable('element', 'offset');
1096
1097
    var before = function (marker, element) {
1098
      var parent$$1 = parent(marker);
1099
      parent$$1.each(function (v) {
1100
        v.dom().insertBefore(element.dom(), marker.dom());
1101
      });
1102
    };
1103
    var after = function (marker, element) {
1104
      var sibling = nextSibling(marker);
1105
      sibling.fold(function () {
1106
        var parent$$1 = parent(marker);
1107
        parent$$1.each(function (v) {
1108
          append(v, element);
1109
        });
1110
      }, function (v) {
1111
        before(v, element);
1112
      });
1113
    };
1114
    var prepend = function (parent$$1, element) {
1115
      var firstChild$$1 = firstChild(parent$$1);
1116
      firstChild$$1.fold(function () {
1117
        append(parent$$1, element);
1118
      }, function (v) {
1119
        parent$$1.dom().insertBefore(element.dom(), v.dom());
1120
      });
1121
    };
1122
    var append = function (parent$$1, element) {
1123
      parent$$1.dom().appendChild(element.dom());
1124
    };
1125
1126
    var append$1 = function (parent, elements) {
1127
      each$1(elements, function (x) {
1128
        append(parent, x);
1129
      });
1130
    };
1131
1132
    var empty = function (element) {
1133
      element.dom().textContent = '';
1134
      each$1(children(element), function (rogue) {
1135
        remove(rogue);
1136
      });
1137
    };
1138
    var remove = function (element) {
1139
      var dom = element.dom();
1140
      if (dom.parentNode !== null)
1141
        dom.parentNode.removeChild(dom);
1142
    };
1143
1144
    var fireDetaching = function (component) {
1145
      emit(component, detachedFromDom());
1146
      var children$$1 = component.components();
1147
      each$1(children$$1, fireDetaching);
1148
    };
1149
    var fireAttaching = function (component) {
1150
      var children$$1 = component.components();
1151
      each$1(children$$1, fireAttaching);
1152
      emit(component, attachedToDom());
1153
    };
1154
    var attach = function (parent$$1, child$$1) {
1155
      attachWith(parent$$1, child$$1, append);
1156
    };
1157
    var attachWith = function (parent$$1, child$$1, insertion) {
1158
      parent$$1.getSystem().addToWorld(child$$1);
1159
      insertion(parent$$1.element(), child$$1.element());
1160
      if (inBody(parent$$1.element())) {
1161
        fireAttaching(child$$1);
1162
      }
1163
      parent$$1.syncComponents();
1164
    };
1165
    var doDetach = function (component) {
1166
      fireDetaching(component);
1167
      remove(component.element());
1168
      component.getSystem().removeFromWorld(component);
1169
    };
1170
    var detach = function (component) {
1171
      var parent$$1 = parent(component.element()).bind(function (p) {
1172
        return component.getSystem().getByDom(p).fold(Option.none, Option.some);
1173
      });
1174
      doDetach(component);
1175
      parent$$1.each(function (p) {
1176
        p.syncComponents();
1177
      });
1178
    };
1179
    var detachChildren = function (component) {
1180
      var subs = component.components();
1181
      each$1(subs, doDetach);
1182
      empty(component.element());
1183
      component.syncComponents();
1184
    };
1185
    var attachSystem = function (element, guiSystem) {
1186
      append(element, guiSystem.element());
1187
      var children$$1 = children(guiSystem.element());
1188
      each$1(children$$1, function (child$$1) {
1189
        guiSystem.getByDom(child$$1).each(fireAttaching);
1190
      });
1191
    };
1192
1193
    var value$1 = function (o) {
1194
      var is = function (v) {
1195
        return o === v;
1196
      };
1197
      var or = function (opt) {
1198
        return value$1(o);
1199
      };
1200
      var orThunk = function (f) {
1201
        return value$1(o);
1202
      };
1203
      var map = function (f) {
1204
        return value$1(f(o));
1205
      };
1206
      var each = function (f) {
1207
        f(o);
1208
      };
1209
      var bind = function (f) {
1210
        return f(o);
1211
      };
1212
      var fold = function (_, onValue) {
1213
        return onValue(o);
1214
      };
1215
      var exists = function (f) {
1216
        return f(o);
1217
      };
1218
      var forall = function (f) {
1219
        return f(o);
1220
      };
1221
      var toOption = function () {
1222
        return Option.some(o);
1223
      };
1224
      return {
1225
        is: is,
1226
        isValue: always,
1227
        isError: never,
1228
        getOr: constant(o),
1229
        getOrThunk: constant(o),
1230
        getOrDie: constant(o),
1231
        or: or,
1232
        orThunk: orThunk,
1233
        fold: fold,
1234
        map: map,
1235
        each: each,
1236
        bind: bind,
1237
        exists: exists,
1238
        forall: forall,
1239
        toOption: toOption
1240
      };
1241
    };
1242
    var error = function (message) {
1243
      var getOrThunk = function (f) {
1244
        return f();
1245
      };
1246
      var getOrDie = function () {
1247
        return die(String(message))();
1248
      };
1249
      var or = function (opt) {
1250
        return opt;
1251
      };
1252
      var orThunk = function (f) {
1253
        return f();
1254
      };
1255
      var map = function (f) {
1256
        return error(message);
1257
      };
1258
      var bind = function (f) {
1259
        return error(message);
1260
      };
1261
      var fold = function (onError, _) {
1262
        return onError(message);
1263
      };
1264
      return {
1265
        is: never,
1266
        isValue: never,
1267
        isError: always,
1268
        getOr: identity,
1269
        getOrThunk: getOrThunk,
1270
        getOrDie: getOrDie,
1271
        or: or,
1272
        orThunk: orThunk,
1273
        fold: fold,
1274
        map: map,
1275
        each: noop,
1276
        bind: bind,
1277
        exists: never,
1278
        forall: always,
1279
        toOption: Option.none
1280
      };
1281
    };
1282
    var Result = {
1283
      value: value$1,
1284
      error: error
1285
    };
1286
1287
    var generate = function (cases) {
1288
      if (!isArray(cases)) {
1289
        throw new Error('cases must be an array');
1290
      }
1291
      if (cases.length === 0) {
1292
        throw new Error('there must be at least one case');
1293
      }
1294
      var constructors = [];
1295
      var adt = {};
1296
      each$1(cases, function (acase, count) {
1297
        var keys$$1 = keys(acase);
1298
        if (keys$$1.length !== 1) {
1299
          throw new Error('one and only one name per case');
1300
        }
1301
        var key = keys$$1[0];
1302
        var value = acase[key];
1303
        if (adt[key] !== undefined) {
1304
          throw new Error('duplicate key detected:' + key);
1305
        } else if (key === 'cata') {
1306
          throw new Error('cannot have a case named cata (sorry)');
1307
        } else if (!isArray(value)) {
1308
          throw new Error('case arguments must be an array');
1309
        }
1310
        constructors.push(key);
1311
        adt[key] = function () {
1312
          var argLength = arguments.length;
1313
          if (argLength !== value.length) {
1314
            throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);
1315
          }
1316
          var args = new Array(argLength);
1317
          for (var i = 0; i < args.length; i++)
1318
            args[i] = arguments[i];
1319
          var match = function (branches) {
1320
            var branchKeys = keys(branches);
1321
            if (constructors.length !== branchKeys.length) {
1322
              throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(','));
1323
            }
1324
            var allReqd = forall(constructors, function (reqKey) {
1325
              return contains(branchKeys, reqKey);
1326
            });
1327
            if (!allReqd)
1328
              throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', '));
1329
            return branches[key].apply(null, args);
1330
          };
1331
          return {
1332
            fold: function () {
1333
              if (arguments.length !== cases.length) {
1334
                throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length);
1335
              }
1336
              var target = arguments[count];
1337
              return target.apply(null, args);
1338
            },
1339
            match: match,
1340
            log: function (label) {
1341
              console.log(label, {
1342
                constructors: constructors,
1343
                constructor: key,
1344
                params: args
1345
              });
1346
            }
1347
          };
1348
        };
1349
      });
1350
      return adt;
1351
    };
1352
    var Adt = { generate: generate };
1353
1354
    var adt = Adt.generate([
1355
      { strict: [] },
1356
      { defaultedThunk: ['fallbackThunk'] },
1357
      { asOption: [] },
1358
      { asDefaultedOptionThunk: ['fallbackThunk'] },
1359
      { mergeWithThunk: ['baseThunk'] }
1360
    ]);
1361
    var defaulted = function (fallback) {
1362
      return adt.defaultedThunk(constant(fallback));
1363
    };
1364
    var mergeWith = function (base) {
1365
      return adt.mergeWithThunk(constant(base));
1366
    };
1367
    var strict = adt.strict;
1368
    var asOption = adt.asOption;
1369
    var defaultedThunk = adt.defaultedThunk;
1370
    var mergeWithThunk = adt.mergeWithThunk;
1371
1372
    var comparison = Adt.generate([
1373
      {
1374
        bothErrors: [
1375
          'error1',
1376
          'error2'
1377
        ]
1378
      },
1379
      {
1380
        firstError: [
1381
          'error1',
1382
          'value2'
1383
        ]
1384
      },
1385
      {
1386
        secondError: [
1387
          'value1',
1388
          'error2'
1389
        ]
1390
      },
1391
      {
1392
        bothValues: [
1393
          'value1',
1394
          'value2'
1395
        ]
1396
      }
1397
    ]);
1398
    var partition$1 = function (results) {
1399
      var errors = [];
1400
      var values = [];
1401
      each$1(results, function (result) {
1402
        result.fold(function (err) {
1403
          errors.push(err);
1404
        }, function (value) {
1405
          values.push(value);
1406
        });
1407
      });
1408
      return {
1409
        errors: errors,
1410
        values: values
1411
      };
1412
    };
1413
1414
    var mergeValues = function (values, base) {
1415
      return Result.value(deepMerge.apply(undefined, [base].concat(values)));
1416
    };
1417
    var mergeErrors = function (errors) {
1418
      return compose(Result.error, flatten)(errors);
1419
    };
1420
    var consolidateObj = function (objects, base) {
1421
      var partitions = partition$1(objects);
1422
      return partitions.errors.length > 0 ? mergeErrors(partitions.errors) : mergeValues(partitions.values, base);
1423
    };
1424
    var consolidateArr = function (objects) {
1425
      var partitions = partition$1(objects);
1426
      return partitions.errors.length > 0 ? mergeErrors(partitions.errors) : Result.value(partitions.values);
1427
    };
1428
    var ResultCombine = {
1429
      consolidateObj: consolidateObj,
1430
      consolidateArr: consolidateArr
1431
    };
1432
1433
    var narrow = function (obj, fields) {
1434
      var r = {};
1435
      each$1(fields, function (field) {
1436
        if (obj[field] !== undefined && obj.hasOwnProperty(field)) {
1437
          r[field] = obj[field];
1438
        }
1439
      });
1440
      return r;
1441
    };
1442
    var exclude = function (obj, fields) {
1443
      var r = {};
1444
      each(obj, function (v, k) {
1445
        if (!contains(fields, k)) {
1446
          r[k] = v;
1447
        }
1448
      });
1449
      return r;
1450
    };
1451
1452
    var readOpt = function (key) {
1453
      return function (obj) {
1454
        return obj.hasOwnProperty(key) ? Option.from(obj[key]) : Option.none();
1455
      };
1456
    };
1457
    var readOr = function (key, fallback) {
1458
      return function (obj) {
1459
        return readOpt(key)(obj).getOr(fallback);
1460
      };
1461
    };
1462
    var readOptFrom = function (obj, key) {
1463
      return readOpt(key)(obj);
1464
    };
1465
    var hasKey = function (obj, key) {
1466
      return obj.hasOwnProperty(key) && obj[key] !== undefined && obj[key] !== null;
1467
    };
1468
1469
    var wrap$1 = function (key, value) {
1470
      var r = {};
1471
      r[key] = value;
1472
      return r;
1473
    };
1474
    var wrapAll = function (keyvalues) {
1475
      var r = {};
1476
      each$1(keyvalues, function (kv) {
1477
        r[kv.key] = kv.value;
1478
      });
1479
      return r;
1480
    };
1481
1482
    var narrow$1 = function (obj, fields) {
1483
      return narrow(obj, fields);
1484
    };
1485
    var exclude$1 = function (obj, fields) {
1486
      return exclude(obj, fields);
1487
    };
1488
    var readOpt$1 = function (key) {
1489
      return readOpt(key);
1490
    };
1491
    var readOr$1 = function (key, fallback) {
1492
      return readOr(key, fallback);
1493
    };
1494
    var readOptFrom$1 = function (obj, key) {
1495
      return readOptFrom(obj, key);
1496
    };
1497
    var wrap$2 = function (key, value) {
1498
      return wrap$1(key, value);
1499
    };
1500
    var wrapAll$1 = function (keyvalues) {
1501
      return wrapAll(keyvalues);
1502
    };
1503
    var consolidate = function (objs, base) {
1504
      return ResultCombine.consolidateObj(objs, base);
1505
    };
1506
    var hasKey$1 = function (obj, key) {
1507
      return hasKey(obj, key);
1508
    };
1509
1510
    var typeAdt = Adt.generate([
1511
      {
1512
        setOf: [
1513
          'validator',
1514
          'valueType'
1515
        ]
1516
      },
1517
      { arrOf: ['valueType'] },
1518
      { objOf: ['fields'] },
1519
      { itemOf: ['validator'] },
1520
      {
1521
        choiceOf: [
1522
          'key',
1523
          'branches'
1524
        ]
1525
      },
1526
      { thunk: ['description'] },
1527
      {
1528
        func: [
1529
          'args',
1530
          'outputSchema'
1531
        ]
1532
      }
1533
    ]);
1534
    var fieldAdt = Adt.generate([
1535
      {
1536
        field: [
1537
          'name',
1538
          'presence',
1539
          'type'
1540
        ]
1541
      },
1542
      { state: ['name'] }
1543
    ]);
1544
1545
    var json = function () {
1546
      return Global$1.getOrDie('JSON');
1547
    };
1548
    var parse = function (text) {
1549
      return json().parse(text);
1550
    };
1551
    var stringify = function (obj, replacer, space) {
1552
      return json().stringify(obj, replacer, space);
1553
    };
1554
    var Json = {
1555
      parse: parse,
1556
      stringify: stringify
1557
    };
1558
1559
    var formatObj = function (input) {
1560
      return isObject(input) && keys(input).length > 100 ? ' removed due to size' : Json.stringify(input, null, 2);
1561
    };
1562
    var formatErrors = function (errors) {
1563
      var es = errors.length > 10 ? errors.slice(0, 10).concat([{
1564
          path: [],
1565
          getErrorInfo: function () {
1566
            return '... (only showing first ten failures)';
1567
          }
1568
        }]) : errors;
1569
      return map$1(es, function (e) {
1570
        return 'Failed path: (' + e.path.join(' > ') + ')\n' + e.getErrorInfo();
1571
      });
1572
    };
1573
1574
    var nu$3 = function (path, getErrorInfo) {
1575
      return Result.error([{
1576
          path: path,
1577
          getErrorInfo: getErrorInfo
1578
        }]);
1579
    };
1580
    var missingStrict = function (path, key, obj) {
1581
      return nu$3(path, function () {
1582
        return 'Could not find valid *strict* value for "' + key + '" in ' + formatObj(obj);
1583
      });
1584
    };
1585
    var missingKey = function (path, key) {
1586
      return nu$3(path, function () {
1587
        return 'Choice schema did not contain choice key: "' + key + '"';
1588
      });
1589
    };
1590
    var missingBranch = function (path, branches, branch) {
1591
      return nu$3(path, function () {
1592
        return 'The chosen schema: "' + branch + '" did not exist in branches: ' + formatObj(branches);
1593
      });
1594
    };
1595
    var unsupportedFields = function (path, unsupported) {
1596
      return nu$3(path, function () {
1597
        return 'There are unsupported fields: [' + unsupported.join(', ') + '] specified';
1598
      });
1599
    };
1600
    var custom = function (path, err) {
1601
      return nu$3(path, function () {
1602
        return err;
1603
      });
1604
    };
1605
1606
    var adt$1 = Adt.generate([
1607
      {
1608
        field: [
1609
          'key',
1610
          'okey',
1611
          'presence',
1612
          'prop'
1613
        ]
1614
      },
1615
      {
1616
        state: [
1617
          'okey',
1618
          'instantiator'
1619
        ]
1620
      }
1621
    ]);
1622
    var strictAccess = function (path, obj, key) {
1623
      return readOptFrom(obj, key).fold(function () {
1624
        return missingStrict(path, key, obj);
1625
      }, Result.value);
1626
    };
1627
    var fallbackAccess = function (obj, key, fallbackThunk) {
1628
      var v = readOptFrom(obj, key).fold(function () {
1629
        return fallbackThunk(obj);
1630
      }, identity);
1631
      return Result.value(v);
1632
    };
1633
    var optionAccess = function (obj, key) {
1634
      return Result.value(readOptFrom(obj, key));
1635
    };
1636
    var optionDefaultedAccess = function (obj, key, fallback) {
1637
      var opt = readOptFrom(obj, key).map(function (val) {
1638
        return val === true ? fallback(obj) : val;
1639
      });
1640
      return Result.value(opt);
1641
    };
1642
    var cExtractOne = function (path, obj, field, strength) {
1643
      return field.fold(function (key, okey, presence, prop) {
1644
        var bundle = function (av) {
1645
          return prop.extract(path.concat([key]), strength, av).map(function (res) {
1646
            return wrap$1(okey, strength(res));
1647
          });
1648
        };
1649
        var bundleAsOption = function (optValue) {
1650
          return optValue.fold(function () {
1651
            var outcome = wrap$1(okey, strength(Option.none()));
1652
            return Result.value(outcome);
1653
          }, function (ov) {
1654
            return prop.extract(path.concat([key]), strength, ov).map(function (res) {
1655
              return wrap$1(okey, strength(Option.some(res)));
1656
            });
1657
          });
1658
        };
1659
        return function () {
1660
          return presence.fold(function () {
1661
            return strictAccess(path, obj, key).bind(bundle);
1662
          }, function (fallbackThunk) {
1663
            return fallbackAccess(obj, key, fallbackThunk).bind(bundle);
1664
          }, function () {
1665
            return optionAccess(obj, key).bind(bundleAsOption);
1666
          }, function (fallbackThunk) {
1667
            return optionDefaultedAccess(obj, key, fallbackThunk).bind(bundleAsOption);
1668
          }, function (baseThunk) {
1669
            var base = baseThunk(obj);
1670
            return fallbackAccess(obj, key, constant({})).map(function (v) {
1671
              return deepMerge(base, v);
1672
            }).bind(bundle);
1673
          });
1674
        }();
1675
      }, function (okey, instantiator) {
1676
        var state = instantiator(obj);
1677
        return Result.value(wrap$1(okey, strength(state)));
1678
      });
1679
    };
1680
    var cExtract = function (path, obj, fields, strength) {
1681
      var results = map$1(fields, function (field) {
1682
        return cExtractOne(path, obj, field, strength);
1683
      });
1684
      return ResultCombine.consolidateObj(results, {});
1685
    };
1686
    var value$2 = function (validator) {
1687
      var extract = function (path, strength, val) {
1688
        return validator(val, strength).fold(function (err) {
1689
          return custom(path, err);
1690
        }, Result.value);
1691
      };
1692
      var toString$$1 = function () {
1693
        return 'val';
1694
      };
1695
      var toDsl = function () {
1696
        return typeAdt.itemOf(validator);
1697
      };
1698
      return {
1699
        extract: extract,
1700
        toString: toString$$1,
1701
        toDsl: toDsl
1702
      };
1703
    };
1704
    var getSetKeys = function (obj) {
1705
      var keys$$1 = keys(obj);
1706
      return filter(keys$$1, function (k) {
1707
        return hasKey$1(obj, k);
1708
      });
1709
    };
1710
    var objOfOnly = function (fields) {
1711
      var delegate = objOf(fields);
1712
      var fieldNames = foldr(fields, function (acc, f) {
1713
        return f.fold(function (key) {
1714
          return deepMerge(acc, wrap$2(key, true));
1715
        }, constant(acc));
1716
      }, {});
1717
      var extract = function (path, strength, o) {
1718
        var keys$$1 = isBoolean(o) ? [] : getSetKeys(o);
1719
        var extra = filter(keys$$1, function (k) {
1720
          return !hasKey$1(fieldNames, k);
1721
        });
1722
        return extra.length === 0 ? delegate.extract(path, strength, o) : unsupportedFields(path, extra);
1723
      };
1724
      return {
1725
        extract: extract,
1726
        toString: delegate.toString,
1727
        toDsl: delegate.toDsl
1728
      };
1729
    };
1730
    var objOf = function (fields) {
1731
      var extract = function (path, strength, o) {
1732
        return cExtract(path, o, fields, strength);
1733
      };
1734
      var toString$$1 = function () {
1735
        var fieldStrings = map$1(fields, function (field) {
1736
          return field.fold(function (key, okey, presence, prop) {
1737
            return key + ' -> ' + prop.toString();
1738
          }, function (okey, instantiator) {
1739
            return 'state(' + okey + ')';
1740
          });
1741
        });
1742
        return 'obj{\n' + fieldStrings.join('\n') + '}';
1743
      };
1744
      var toDsl = function () {
1745
        return typeAdt.objOf(map$1(fields, function (f) {
1746
          return f.fold(function (key, okey, presence, prop) {
1747
            return fieldAdt.field(key, presence, prop);
1748
          }, function (okey, instantiator) {
1749
            return fieldAdt.state(okey);
1750
          });
1751
        }));
1752
      };
1753
      return {
1754
        extract: extract,
1755
        toString: toString$$1,
1756
        toDsl: toDsl
1757
      };
1758
    };
1759
    var arrOf = function (prop) {
1760
      var extract = function (path, strength, array) {
1761
        var results = map$1(array, function (a, i) {
1762
          return prop.extract(path.concat(['[' + i + ']']), strength, a);
1763
        });
1764
        return ResultCombine.consolidateArr(results);
1765
      };
1766
      var toString$$1 = function () {
1767
        return 'array(' + prop.toString() + ')';
1768
      };
1769
      var toDsl = function () {
1770
        return typeAdt.arrOf(prop);
1771
      };
1772
      return {
1773
        extract: extract,
1774
        toString: toString$$1,
1775
        toDsl: toDsl
1776
      };
1777
    };
1778
    var setOf = function (validator, prop) {
1779
      var validateKeys = function (path, keys$$1) {
1780
        return arrOf(value$2(validator)).extract(path, identity, keys$$1);
1781
      };
1782
      var extract = function (path, strength, o) {
1783
        var keys$$1 = keys(o);
1784
        return validateKeys(path, keys$$1).bind(function (validKeys) {
1785
          var schema = map$1(validKeys, function (vk) {
1786
            return adt$1.field(vk, vk, strict(), prop);
1787
          });
1788
          return objOf(schema).extract(path, strength, o);
1789
        });
1790
      };
1791
      var toString$$1 = function () {
1792
        return 'setOf(' + prop.toString() + ')';
1793
      };
1794
      var toDsl = function () {
1795
        return typeAdt.setOf(validator, prop);
1796
      };
1797
      return {
1798
        extract: extract,
1799
        toString: toString$$1,
1800
        toDsl: toDsl
1801
      };
1802
    };
1803
    var anyValue = constant(value$2(Result.value));
1804
    var state = adt$1.state;
1805
    var field = adt$1.field;
1806
1807
    var chooseFrom = function (path, strength, input, branches, ch) {
1808
      var fields = readOptFrom$1(branches, ch);
1809
      return fields.fold(function () {
1810
        return missingBranch(path, branches, ch);
1811
      }, function (fs) {
1812
        return objOf(fs).extract(path.concat(['branch: ' + ch]), strength, input);
1813
      });
1814
    };
1815
    var choose = function (key, branches) {
1816
      var extract = function (path, strength, input) {
1817
        var choice = readOptFrom$1(input, key);
1818
        return choice.fold(function () {
1819
          return missingKey(path, key);
1820
        }, function (chosen) {
1821
          return chooseFrom(path, strength, input, branches, chosen);
1822
        });
1823
      };
1824
      var toString$$1 = function () {
1825
        return 'chooseOn(' + key + '). Possible values: ' + keys(branches);
1826
      };
1827
      var toDsl = function () {
1828
        return typeAdt.choiceOf(key, branches);
1829
      };
1830
      return {
1831
        extract: extract,
1832
        toString: toString$$1,
1833
        toDsl: toDsl
1834
      };
1835
    };
1836
1837
    var _anyValue = value$2(Result.value);
1838
    var valueOf = function (validator) {
1839
      return value$2(function (v) {
1840
        return validator(v);
1841
      });
1842
    };
1843
    var extract = function (label, prop, strength, obj) {
1844
      return prop.extract([label], strength, obj).fold(function (errs) {
1845
        return Result.error({
1846
          input: obj,
1847
          errors: errs
1848
        });
1849
      }, Result.value);
1850
    };
1851
    var asStruct = function (label, prop, obj) {
1852
      return extract(label, prop, constant, obj);
1853
    };
1854
    var asRaw = function (label, prop, obj) {
1855
      return extract(label, prop, identity, obj);
1856
    };
1857
    var getOrDie$1 = function (extraction) {
1858
      return extraction.fold(function (errInfo) {
1859
        throw new Error(formatError(errInfo));
1860
      }, identity);
1861
    };
1862
    var asRawOrDie = function (label, prop, obj) {
1863
      return getOrDie$1(asRaw(label, prop, obj));
1864
    };
1865
    var asStructOrDie = function (label, prop, obj) {
1866
      return getOrDie$1(asStruct(label, prop, obj));
1867
    };
1868
    var formatError = function (errInfo) {
1869
      return 'Errors: \n' + formatErrors(errInfo.errors) + '\n\nInput object: ' + formatObj(errInfo.input);
1870
    };
1871
    var choose$1 = function (key, branches) {
1872
      return choose(key, branches);
1873
    };
1874
    var anyValue$1 = constant(_anyValue);
1875
    var typedValue = function (validator, expectedType) {
1876
      return value$2(function (a) {
1877
        var actualType = typeof a;
1878
        return validator(a) ? Result.value(a) : Result.error('Expected type: ' + expectedType + ' but got: ' + actualType);
1879
      });
1880
    };
1881
    var functionProcessor = typedValue(isFunction, 'function');
1882
1883
    var strict$1 = function (key) {
1884
      return field(key, key, strict(), anyValue());
1885
    };
1886
    var strictOf = function (key, schema) {
1887
      return field(key, key, strict(), schema);
1888
    };
1889
    var strictFunction = function (key) {
1890
      return strictOf(key, functionProcessor);
1891
    };
1892
    var forbid = function (key, message) {
1893
      return field(key, key, asOption(), value$2(function (v) {
1894
        return Result.error('The field: ' + key + ' is forbidden. ' + message);
1895
      }));
1896
    };
1897
    var strictObjOf = function (key, objSchema) {
1898
      return field(key, key, strict(), objOf(objSchema));
1899
    };
1900
    var option = function (key) {
1901
      return field(key, key, asOption(), anyValue());
1902
    };
1903
    var optionOf = function (key, schema) {
1904
      return field(key, key, asOption(), schema);
1905
    };
1906
    var optionObjOf = function (key, objSchema) {
1907
      return field(key, key, asOption(), objOf(objSchema));
1908
    };
1909
    var optionObjOfOnly = function (key, objSchema) {
1910
      return field(key, key, asOption(), objOfOnly(objSchema));
1911
    };
1912
    var defaulted$1 = function (key, fallback) {
1913
      return field(key, key, defaulted(fallback), anyValue());
1914
    };
1915
    var defaultedOf = function (key, fallback, schema) {
1916
      return field(key, key, defaulted(fallback), schema);
1917
    };
1918
    var defaultedObjOf = function (key, fallback, objSchema) {
1919
      return field(key, key, defaulted(fallback), objOf(objSchema));
1920
    };
1921
    var state$1 = function (okey, instantiator) {
1922
      return state(okey, instantiator);
1923
    };
1924
1925
    var isSource = function (component, simulatedEvent) {
1926
      return eq(component.element(), simulatedEvent.event().target());
1927
    };
1928
1929
    var nu$4 = function (parts) {
1930
      if (!hasKey$1(parts, 'can') && !hasKey$1(parts, 'abort') && !hasKey$1(parts, 'run')) {
1931
        throw new Error('EventHandler defined by: ' + Json.stringify(parts, null, 2) + ' does not have can, abort, or run!');
1932
      }
1933
      return asRawOrDie('Extracting event.handler', objOfOnly([
1934
        defaulted$1('can', constant(true)),
1935
        defaulted$1('abort', constant(false)),
1936
        defaulted$1('run', noop)
1937
      ]), parts);
1938
    };
1939
    var all$1 = function (handlers, f) {
1940
      return function () {
1941
        var args = [];
1942
        for (var _i = 0; _i < arguments.length; _i++) {
1943
          args[_i] = arguments[_i];
1944
        }
1945
        return foldl(handlers, function (acc, handler) {
1946
          return acc && f(handler).apply(undefined, args);
1947
        }, true);
1948
      };
1949
    };
1950
    var any = function (handlers, f) {
1951
      return function () {
1952
        var args = [];
1953
        for (var _i = 0; _i < arguments.length; _i++) {
1954
          args[_i] = arguments[_i];
1955
        }
1956
        return foldl(handlers, function (acc, handler) {
1957
          return acc || f(handler).apply(undefined, args);
1958
        }, false);
1959
      };
1960
    };
1961
    var read = function (handler) {
1962
      return isFunction(handler) ? {
1963
        can: constant(true),
1964
        abort: constant(false),
1965
        run: handler
1966
      } : handler;
1967
    };
1968
    var fuse = function (handlers) {
1969
      var can = all$1(handlers, function (handler) {
1970
        return handler.can;
1971
      });
1972
      var abort = any(handlers, function (handler) {
1973
        return handler.abort;
1974
      });
1975
      var run = function () {
1976
        var args = [];
1977
        for (var _i = 0; _i < arguments.length; _i++) {
1978
          args[_i] = arguments[_i];
1979
        }
1980
        each$1(handlers, function (handler) {
1981
          handler.run.apply(undefined, args);
1982
        });
1983
      };
1984
      return nu$4({
1985
        can: can,
1986
        abort: abort,
1987
        run: run
1988
      });
1989
    };
1990
1991
    var derive = function (configs) {
1992
      return wrapAll$1(configs);
1993
    };
1994
    var abort = function (name, predicate) {
1995
      return {
1996
        key: name,
1997
        value: nu$4({ abort: predicate })
1998
      };
1999
    };
2000
    var can = function (name, predicate) {
2001
      return {
2002
        key: name,
2003
        value: nu$4({ can: predicate })
2004
      };
2005
    };
2006
    var run = function (name, handler) {
2007
      return {
2008
        key: name,
2009
        value: nu$4({ run: handler })
2010
      };
2011
    };
2012
    var runActionExtra = function (name, action, extra) {
2013
      return {
2014
        key: name,
2015
        value: nu$4({
2016
          run: function (component) {
2017
            action.apply(undefined, [component].concat(extra));
2018
          }
2019
        })
2020
      };
2021
    };
2022
    var runOnName = function (name) {
2023
      return function (handler) {
2024
        return run(name, handler);
2025
      };
2026
    };
2027
    var runOnSourceName = function (name) {
2028
      return function (handler) {
2029
        return {
2030
          key: name,
2031
          value: nu$4({
2032
            run: function (component, simulatedEvent) {
2033
              if (isSource(component, simulatedEvent)) {
2034
                handler(component, simulatedEvent);
2035
              }
2036
            }
2037
          })
2038
        };
2039
      };
2040
    };
2041
    var redirectToUid = function (name, uid) {
2042
      return run(name, function (component, simulatedEvent) {
2043
        component.getSystem().getByUid(uid).each(function (redirectee) {
2044
          dispatchEvent(redirectee, redirectee.element(), name, simulatedEvent);
2045
        });
2046
      });
2047
    };
2048
    var redirectToPart = function (name, detail, partName) {
2049
      var uid = detail.partUids()[partName];
2050
      return redirectToUid(name, uid);
2051
    };
2052
    var runWithTarget = function (name, f) {
2053
      return run(name, function (component, simulatedEvent) {
2054
        var ev = simulatedEvent.event();
2055
        component.getSystem().getByDom(ev.target()).each(function (target) {
2056
          f(component, target, simulatedEvent);
2057
        });
2058
      });
2059
    };
2060
    var cutter = function (name) {
2061
      return run(name, function (component, simulatedEvent) {
2062
        simulatedEvent.cut();
2063
      });
2064
    };
2065
    var stopper = function (name) {
2066
      return run(name, function (component, simulatedEvent) {
2067
        simulatedEvent.stop();
2068
      });
2069
    };
2070
    var runOnAttached = runOnSourceName(attachedToDom());
2071
    var runOnDetached = runOnSourceName(detachedFromDom());
2072
    var runOnInit = runOnSourceName(systemInit());
2073
    var runOnExecute = runOnName(execute());
2074
2075
    var markAsBehaviourApi = function (f, apiName, apiFunction) {
2076
      var delegate = apiFunction.toString();
2077
      var endIndex = delegate.indexOf(')') + 1;
2078
      var openBracketIndex = delegate.indexOf('(');
2079
      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/);
2080
      f.toFunctionAnnotation = function () {
2081
        return {
2082
          name: apiName,
2083
          parameters: cleanParameters(parameters.slice(0, 1).concat(parameters.slice(3)))
2084
        };
2085
      };
2086
      return f;
2087
    };
2088
    var cleanParameters = function (parameters) {
2089
      return map$1(parameters, function (p) {
2090
        return endsWith(p, '/*') ? p.substring(0, p.length - '/*'.length) : p;
2091
      });
2092
    };
2093
    var markAsExtraApi = function (f, extraName) {
2094
      var delegate = f.toString();
2095
      var endIndex = delegate.indexOf(')') + 1;
2096
      var openBracketIndex = delegate.indexOf('(');
2097
      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/);
2098
      f.toFunctionAnnotation = function () {
2099
        return {
2100
          name: extraName,
2101
          parameters: cleanParameters(parameters)
2102
        };
2103
      };
2104
      return f;
2105
    };
2106
    var markAsSketchApi = function (f, apiFunction) {
2107
      var delegate = apiFunction.toString();
2108
      var endIndex = delegate.indexOf(')') + 1;
2109
      var openBracketIndex = delegate.indexOf('(');
2110
      var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/);
2111
      f.toFunctionAnnotation = function () {
2112
        return {
2113
          name: 'OVERRIDE',
2114
          parameters: cleanParameters(parameters.slice(1))
2115
        };
2116
      };
2117
      return f;
2118
    };
2119
2120
    var nu$5 = MixedBag(['tag'], [
2121
      'classes',
2122
      'attributes',
2123
      'styles',
2124
      'value',
2125
      'innerHtml',
2126
      'domChildren',
2127
      'defChildren'
2128
    ]);
2129
    var defToStr = function (defn) {
2130
      var raw = defToRaw(defn);
2131
      return Json.stringify(raw, null, 2);
2132
    };
2133
    var defToRaw = function (defn) {
2134
      return {
2135
        tag: defn.tag(),
2136
        classes: defn.classes().getOr([]),
2137
        attributes: defn.attributes().getOr({}),
2138
        styles: defn.styles().getOr({}),
2139
        value: defn.value().getOr('<none>'),
2140
        innerHtml: defn.innerHtml().getOr('<none>'),
2141
        defChildren: defn.defChildren().fold(function () {
2142
          return '<none>';
2143
        }, function (d) {
2144
          return Json.stringify(d, null, 2);
2145
        }),
2146
        domChildren: defn.domChildren().fold(function () {
2147
          return '<none>';
2148
        }, function (children) {
2149
          return children.length === 0 ? '0 children, but still specified' : String(children.length);
2150
        })
2151
      };
2152
    };
2153
2154
    var fields = [
2155
      'classes',
2156
      'attributes',
2157
      'styles',
2158
      'value',
2159
      'innerHtml',
2160
      'defChildren',
2161
      'domChildren'
2162
    ];
2163
    var nu$6 = MixedBag([], fields);
2164
    var clashingOptArrays = function (key, oArr1, oArr2) {
2165
      return oArr1.fold(function () {
2166
        return oArr2.fold(function () {
2167
          return {};
2168
        }, function (arr2) {
2169
          return wrap$2(key, arr2);
2170
        });
2171
      }, function (arr1) {
2172
        return oArr2.fold(function () {
2173
          return wrap$2(key, arr1);
2174
        }, function (arr2) {
2175
          return wrap$2(key, arr2);
2176
        });
2177
      });
2178
    };
2179
    var merge$1 = function (defnA, mod) {
2180
      var raw = deepMerge({
2181
        tag: defnA.tag(),
2182
        classes: mod.classes().getOr([]).concat(defnA.classes().getOr([])),
2183
        attributes: merge(defnA.attributes().getOr({}), mod.attributes().getOr({})),
2184
        styles: merge(defnA.styles().getOr({}), mod.styles().getOr({}))
2185
      }, mod.innerHtml().or(defnA.innerHtml()).map(function (innerHtml) {
2186
        return wrap$2('innerHtml', innerHtml);
2187
      }).getOr({}), clashingOptArrays('domChildren', mod.domChildren(), defnA.domChildren()), clashingOptArrays('defChildren', mod.defChildren(), defnA.defChildren()), mod.value().or(defnA.value()).map(function (value) {
2188
        return wrap$2('value', value);
2189
      }).getOr({}));
2190
      return nu$5(raw);
2191
    };
2192
2193
    var executeEvent = function (bConfig, bState, executor) {
2194
      return runOnExecute(function (component) {
2195
        executor(component, bConfig, bState);
2196
      });
2197
    };
2198
    var loadEvent = function (bConfig, bState, f) {
2199
      return runOnInit(function (component, simulatedEvent) {
2200
        f(component, bConfig, bState);
2201
      });
2202
    };
2203
    var create = function (schema, name, active, apis, extra, state) {
2204
      var configSchema = objOfOnly(schema);
2205
      var schemaSchema = optionObjOf(name, [optionObjOfOnly('config', schema)]);
2206
      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);
2207
    };
2208
    var createModes = function (modes, name, active, apis, extra, state) {
2209
      var configSchema = modes;
2210
      var schemaSchema = optionObjOf(name, [optionOf('config', modes)]);
2211
      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);
2212
    };
2213
    var wrapApi = function (bName, apiFunction, apiName) {
2214
      var f = function (component) {
2215
        var rest = [];
2216
        for (var _i = 1; _i < arguments.length; _i++) {
2217
          rest[_i - 1] = arguments[_i];
2218
        }
2219
        var args = [component].concat(rest);
2220
        return component.config({ name: constant(bName) }).fold(function () {
2221
          throw new Error('We could not find any behaviour configuration for: ' + bName + '. Using API: ' + apiName);
2222
        }, function (info) {
2223
          var rest = Array.prototype.slice.call(args, 1);
2224
          return apiFunction.apply(undefined, [
2225
            component,
2226
            info.config,
2227
            info.state
2228
          ].concat(rest));
2229
        });
2230
      };
2231
      return markAsBehaviourApi(f, apiName, apiFunction);
2232
    };
2233
    var revokeBehaviour = function (name) {
2234
      return {
2235
        key: name,
2236
        value: undefined
2237
      };
2238
    };
2239
    var doCreate = function (configSchema, schemaSchema, name, active, apis, extra, state) {
2240
      var getConfig = function (info) {
2241
        return hasKey$1(info, name) ? info[name]() : Option.none();
2242
      };
2243
      var wrappedApis = map(apis, function (apiF, apiName) {
2244
        return wrapApi(name, apiF, apiName);
2245
      });
2246
      var wrappedExtra = map(extra, function (extraF, extraName) {
2247
        return markAsExtraApi(extraF, extraName);
2248
      });
2249
      var me = deepMerge(wrappedExtra, wrappedApis, {
2250
        revoke: curry(revokeBehaviour, name),
2251
        config: function (spec) {
2252
          var prepared = asStructOrDie(name + '-config', configSchema, spec);
2253
          return {
2254
            key: name,
2255
            value: {
2256
              config: prepared,
2257
              me: me,
2258
              configAsRaw: cached(function () {
2259
                return asRawOrDie(name + '-config', configSchema, spec);
2260
              }),
2261
              initialConfig: spec,
2262
              state: state
2263
            }
2264
          };
2265
        },
2266
        schema: function () {
2267
          return schemaSchema;
2268
        },
2269
        exhibit: function (info, base) {
2270
          return getConfig(info).bind(function (behaviourInfo) {
2271
            return readOptFrom$1(active, 'exhibit').map(function (exhibitor) {
2272
              return exhibitor(base, behaviourInfo.config, behaviourInfo.state);
2273
            });
2274
          }).getOr(nu$6({}));
2275
        },
2276
        name: function () {
2277
          return name;
2278
        },
2279
        handlers: function (info) {
2280
          return getConfig(info).bind(function (behaviourInfo) {
2281
            return readOptFrom$1(active, 'events').map(function (events) {
2282
              return events(behaviourInfo.config, behaviourInfo.state);
2283
            });
2284
          }).getOr({});
2285
        }
2286
      });
2287
      return me;
2288
    };
2289
2290
    var base = function (handleUnsupported, required) {
2291
      return baseWith(handleUnsupported, required, {
2292
        validate: isFunction,
2293
        label: 'function'
2294
      });
2295
    };
2296
    var baseWith = function (handleUnsupported, required, pred) {
2297
      if (required.length === 0)
2298
        throw new Error('You must specify at least one required field.');
2299
      validateStrArr('required', required);
2300
      checkDupes(required);
2301
      return function (obj) {
2302
        var keys$$1 = keys(obj);
2303
        var allReqd = forall(required, function (req) {
2304
          return contains(keys$$1, req);
2305
        });
2306
        if (!allReqd)
2307
          reqMessage(required, keys$$1);
2308
        handleUnsupported(required, keys$$1);
2309
        var invalidKeys = filter(required, function (key) {
2310
          return !pred.validate(obj[key], key);
2311
        });
2312
        if (invalidKeys.length > 0)
2313
          invalidTypeMessage(invalidKeys, pred.label);
2314
        return obj;
2315
      };
2316
    };
2317
    var handleExact = function (required, keys$$1) {
2318
      var unsupported = filter(keys$$1, function (key) {
2319
        return !contains(required, key);
2320
      });
2321
      if (unsupported.length > 0)
2322
        unsuppMessage(unsupported);
2323
    };
2324
    var allowExtra = noop;
2325
    var exactly = function (required) {
2326
      return base(handleExact, required);
2327
    };
2328
    var ensure = function (required) {
2329
      return base(allowExtra, required);
2330
    };
2331
2332
    var NoState = {
2333
      init: function () {
2334
        return nu$7({
2335
          readState: function () {
2336
            return 'No State required';
2337
          }
2338
        });
2339
      }
2340
    };
2341
    var nu$7 = function (spec) {
2342
      ensure(['readState'])(spec);
2343
      return spec;
2344
    };
2345
2346
    var derive$2 = function (capabilities) {
2347
      return wrapAll$1(capabilities);
2348
    };
2349
    var simpleSchema = objOfOnly([
2350
      strict$1('fields'),
2351
      strict$1('name'),
2352
      defaulted$1('active', {}),
2353
      defaulted$1('apis', {}),
2354
      defaulted$1('state', NoState),
2355
      defaulted$1('extra', {})
2356
    ]);
2357
    var create$1 = function (data) {
2358
      var value = asRawOrDie('Creating behaviour: ' + data.name, simpleSchema, data);
2359
      return create(value.fields, value.name, value.active, value.apis, value.extra, value.state);
2360
    };
2361
    var modeSchema = objOfOnly([
2362
      strict$1('branchKey'),
2363
      strict$1('branches'),
2364
      strict$1('name'),
2365
      defaulted$1('active', {}),
2366
      defaulted$1('apis', {}),
2367
      defaulted$1('state', NoState),
2368
      defaulted$1('extra', {})
2369
    ]);
2370
    var createModes$1 = function (data) {
2371
      var value = asRawOrDie('Creating behaviour: ' + data.name, modeSchema, data);
2372
      return createModes(choose$1(value.branchKey, value.branches), value.name, value.active, value.apis, value.extra, value.state);
2373
    };
2374
    var revoke = constant(undefined);
2375
2376
    var rawSet = function (dom, key, value$$1) {
2377
      if (isString(value$$1) || isBoolean(value$$1) || isNumber(value$$1)) {
2378
        dom.setAttribute(key, value$$1 + '');
2379
      } else {
2380
        console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value$$1, ':: Element ', dom);
2381
        throw new Error('Attribute value was not simple');
2382
      }
2383
    };
2384
    var set = function (element, key, value$$1) {
2385
      rawSet(element.dom(), key, value$$1);
2386
    };
2387
    var setAll = function (element, attrs) {
2388
      var dom = element.dom();
2389
      each(attrs, function (v, k) {
2390
        rawSet(dom, k, v);
2391
      });
2392
    };
2393
    var get$1 = function (element, key) {
2394
      var v = element.dom().getAttribute(key);
2395
      return v === null ? undefined : v;
2396
    };
2397
    var has$1 = function (element, key) {
2398
      var dom = element.dom();
2399
      return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;
2400
    };
2401
    var remove$1 = function (element, key) {
2402
      element.dom().removeAttribute(key);
2403
    };
2404
2405
    var read$1 = function (element, attr) {
2406
      var value = get$1(element, attr);
2407
      return value === undefined || value === '' ? [] : value.split(' ');
2408
    };
2409
    var add = function (element, attr, id) {
2410
      var old = read$1(element, attr);
2411
      var nu = old.concat([id]);
2412
      set(element, attr, nu.join(' '));
2413
      return true;
2414
    };
2415
    var remove$2 = function (element, attr, id) {
2416
      var nu = filter(read$1(element, attr), function (v) {
2417
        return v !== id;
2418
      });
2419
      if (nu.length > 0)
2420
        set(element, attr, nu.join(' '));
2421
      else
2422
        remove$1(element, attr);
2423
      return false;
2424
    };
2425
2426
    var supports = function (element) {
2427
      return element.dom().classList !== undefined;
2428
    };
2429
    var get$2 = function (element) {
2430
      return read$1(element, 'class');
2431
    };
2432
    var add$1 = function (element, clazz) {
2433
      return add(element, 'class', clazz);
2434
    };
2435
    var remove$3 = function (element, clazz) {
2436
      return remove$2(element, 'class', clazz);
2437
    };
2438
    var toggle = function (element, clazz) {
2439
      if (contains(get$2(element), clazz)) {
2440
        return remove$3(element, clazz);
2441
      } else {
2442
        return add$1(element, clazz);
2443
      }
2444
    };
2445
2446
    var add$2 = function (element, clazz) {
2447
      if (supports(element))
2448
        element.dom().classList.add(clazz);
2449
      else
2450
        add$1(element, clazz);
2451
    };
2452
    var cleanClass = function (element) {
2453
      var classList = supports(element) ? element.dom().classList : get$2(element);
2454
      if (classList.length === 0) {
2455
        remove$1(element, 'class');
2456
      }
2457
    };
2458
    var remove$4 = function (element, clazz) {
2459
      if (supports(element)) {
2460
        var classList = element.dom().classList;
2461
        classList.remove(clazz);
2462
      } else
2463
        remove$3(element, clazz);
2464
      cleanClass(element);
2465
    };
2466
    var toggle$1 = function (element, clazz) {
2467
      return supports(element) ? element.dom().classList.toggle(clazz) : toggle(element, clazz);
2468
    };
2469
    var has$2 = function (element, clazz) {
2470
      return supports(element) && element.dom().classList.contains(clazz);
2471
    };
2472
2473
    var swap = function (element, addCls, removeCls) {
2474
      remove$4(element, removeCls);
2475
      add$2(element, addCls);
2476
    };
2477
    var toAlpha = function (component, swapConfig, swapState) {
2478
      swap(component.element(), swapConfig.alpha(), swapConfig.omega());
2479
    };
2480
    var toOmega = function (component, swapConfig, swapState) {
2481
      swap(component.element(), swapConfig.omega(), swapConfig.alpha());
2482
    };
2483
    var clear = function (component, swapConfig, swapState) {
2484
      remove$4(component.element(), swapConfig.alpha());
2485
      remove$4(component.element(), swapConfig.omega());
2486
    };
2487
    var isAlpha = function (component, swapConfig, swapState) {
2488
      return has$2(component.element(), swapConfig.alpha());
2489
    };
2490
    var isOmega = function (component, swapConfig, swapState) {
2491
      return has$2(component.element(), swapConfig.omega());
2492
    };
2493
2494
    var SwapApis = /*#__PURE__*/Object.freeze({
2495
        toAlpha: toAlpha,
2496
        toOmega: toOmega,
2497
        isAlpha: isAlpha,
2498
        isOmega: isOmega,
2499
        clear: clear
2500
    });
2501
2502
    var SwapSchema = [
2503
      strict$1('alpha'),
2504
      strict$1('omega')
2505
    ];
2506
2507
    var Swapping = create$1({
2508
      fields: SwapSchema,
2509
      name: 'swapping',
2510
      apis: SwapApis
2511
    });
2512
2513
    var Cell = function (initial) {
2514
      var value = initial;
2515
      var get = function () {
2516
        return value;
2517
      };
2518
      var set = function (v) {
2519
        value = v;
2520
      };
2521
      var clone = function () {
2522
        return Cell(get());
2523
      };
2524
      return {
2525
        get: get,
2526
        set: set,
2527
        clone: clone
2528
      };
2529
    };
2530
2531
    function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {
2532
      return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot);
2533
    }
2534
2535
    var ancestor = function (scope, predicate, isRoot) {
2536
      var element = scope.dom();
2537
      var stop = isFunction(isRoot) ? isRoot : constant(false);
2538
      while (element.parentNode) {
2539
        element = element.parentNode;
2540
        var el = Element$$1.fromDom(element);
2541
        if (predicate(el))
2542
          return Option.some(el);
2543
        else if (stop(el))
2544
          break;
2545
      }
2546
      return Option.none();
2547
    };
2548
    var closest = function (scope, predicate, isRoot) {
2549
      var is = function (scope) {
2550
        return predicate(scope);
2551
      };
2552
      return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);
2553
    };
2554
    var descendant = function (scope, predicate) {
2555
      var descend = function (node) {
2556
        for (var i = 0; i < node.childNodes.length; i++) {
2557
          if (predicate(Element$$1.fromDom(node.childNodes[i])))
2558
            return Option.some(Element$$1.fromDom(node.childNodes[i]));
2559
          var res = descend(node.childNodes[i]);
2560
          if (res.isSome())
2561
            return res;
2562
        }
2563
        return Option.none();
2564
      };
2565
      return descend(scope.dom());
2566
    };
2567
2568
    var focus$2 = function (element) {
2569
      element.dom().focus();
2570
    };
2571
    var blur$$1 = function (element) {
2572
      element.dom().blur();
2573
    };
2574
    var hasFocus = function (element) {
2575
      var doc = owner(element).dom();
2576
      return element.dom() === doc.activeElement;
2577
    };
2578
    var active = function (_doc) {
2579
      var doc = _doc !== undefined ? _doc.dom() : document;
2580
      return Option.from(doc.activeElement).map(Element$$1.fromDom);
2581
    };
2582
    var search = function (element) {
2583
      return active(owner(element)).filter(function (e) {
2584
        return element.dom().contains(e.dom());
2585
      });
2586
    };
2587
2588
    var global = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
2589
2590
    var global$1 = tinymce.util.Tools.resolve('tinymce.ThemeManager');
2591
2592
    var openLink = function (target) {
2593
      var link = document.createElement('a');
2594
      link.target = '_blank';
2595
      link.href = target.href;
2596
      link.rel = 'noreferrer noopener';
2597
      var nuEvt = document.createEvent('MouseEvents');
2598
      nuEvt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
2599
      document.body.appendChild(link);
2600
      link.dispatchEvent(nuEvt);
2601
      document.body.removeChild(link);
2602
    };
2603
    var TinyCodeDupe = { openLink: openLink };
2604
2605
    var isSkinDisabled = function (editor) {
2606
      return editor.settings.skin === false;
2607
    };
2608
    var readOnlyOnInit = function (editor) {
2609
      return false;
2610
    };
2611
2612
    var formatChanged = 'formatChanged';
2613
    var orientationChanged = 'orientationChanged';
2614
    var dropupDismissed = 'dropupDismissed';
2615
    var TinyChannels = {
2616
      formatChanged: constant(formatChanged),
2617
      orientationChanged: constant(orientationChanged),
2618
      dropupDismissed: constant(dropupDismissed)
2619
    };
2620
2621
    var fromHtml$1 = function (html, scope) {
2622
      var doc = scope || document;
2623
      var div = doc.createElement('div');
2624
      div.innerHTML = html;
2625
      return children(Element$$1.fromDom(div));
2626
    };
2627
2628
    var get$3 = function (element) {
2629
      return element.dom().innerHTML;
2630
    };
2631
    var set$1 = function (element, content) {
2632
      var owner$$1 = owner(element);
2633
      var docDom = owner$$1.dom();
2634
      var fragment = Element$$1.fromDom(docDom.createDocumentFragment());
2635
      var contentElements = fromHtml$1(content, docDom);
2636
      append$1(fragment, contentElements);
2637
      empty(element);
2638
      append(element, fragment);
2639
    };
2640
    var getOuter = function (element) {
2641
      var container = Element$$1.fromTag('div');
2642
      var clone = Element$$1.fromDom(element.dom().cloneNode(true));
2643
      append(container, clone);
2644
      return get$3(container);
2645
    };
2646
2647
    var clone$1 = function (original, deep) {
2648
      return Element$$1.fromDom(original.dom().cloneNode(deep));
2649
    };
2650
    var shallow$1 = function (original) {
2651
      return clone$1(original, false);
2652
    };
2653
2654
    var getHtml = function (element) {
2655
      var clone = shallow$1(element);
2656
      return getOuter(clone);
2657
    };
2658
2659
    var element = function (elem) {
2660
      return getHtml(elem);
2661
    };
2662
2663
    var chooseChannels = function (channels, message) {
2664
      return message.universal() ? channels : filter(channels, function (ch) {
2665
        return contains(message.channels(), ch);
2666
      });
2667
    };
2668
    var events = function (receiveConfig) {
2669
      return derive([run(receive(), function (component, message) {
2670
          var channelMap = receiveConfig.channels();
2671
          var channels = keys(channelMap);
2672
          var targetChannels = chooseChannels(channels, message);
2673
          each$1(targetChannels, function (ch) {
2674
            var channelInfo = channelMap[ch]();
2675
            var channelSchema = channelInfo.schema();
2676
            var data = asStructOrDie('channel[' + ch + '] data\nReceiver: ' + element(component.element()), channelSchema, message.data());
2677
            channelInfo.onReceive()(component, data);
2678
          });
2679
        })]);
2680
    };
2681
2682
    var ActiveReceiving = /*#__PURE__*/Object.freeze({
2683
        events: events
2684
    });
2685
2686
    var cat = function (arr) {
2687
      var r = [];
2688
      var push = function (x) {
2689
        r.push(x);
2690
      };
2691
      for (var i = 0; i < arr.length; i++) {
2692
        arr[i].each(push);
2693
      }
2694
      return r;
2695
    };
2696
    var findMap = function (arr, f) {
2697
      for (var i = 0; i < arr.length; i++) {
2698
        var r = f(arr[i], i);
2699
        if (r.isSome()) {
2700
          return r;
2701
        }
2702
      }
2703
      return Option.none();
2704
    };
2705
2706
    var unknown$3 = 'unknown';
2707
    var eventsMonitored = [];
2708
    var path$1 = [
2709
      'alloy/data/Fields',
2710
      'alloy/debugging/Debugging'
2711
    ];
2712
    var getTrace = function () {
2713
      var err = new Error();
2714
      if (err.stack !== undefined) {
2715
        var lines = err.stack.split('\n');
2716
        return find$2(lines, function (line) {
2717
          return line.indexOf('alloy') > 0 && !exists(path$1, function (p) {
2718
            return line.indexOf(p) > -1;
2719
          });
2720
        }).getOr(unknown$3);
2721
      } else {
2722
        return unknown$3;
2723
      }
2724
    };
2725
    var ignoreEvent = {
2726
      logEventCut: noop,
2727
      logEventStopped: noop,
2728
      logNoParent: noop,
2729
      logEventNoHandlers: noop,
2730
      logEventResponse: noop,
2731
      write: noop
2732
    };
2733
    var monitorEvent = function (eventName, initialTarget, f) {
2734
      var logger = eventsMonitored === '*' || contains(eventsMonitored, eventName) ? function () {
2735
        var sequence = [];
2736
        return {
2737
          logEventCut: function (name$$1, target, purpose) {
2738
            sequence.push({
2739
              outcome: 'cut',
2740
              target: target,
2741
              purpose: purpose
2742
            });
2743
          },
2744
          logEventStopped: function (name$$1, target, purpose) {
2745
            sequence.push({
2746
              outcome: 'stopped',
2747
              target: target,
2748
              purpose: purpose
2749
            });
2750
          },
2751
          logNoParent: function (name$$1, target, purpose) {
2752
            sequence.push({
2753
              outcome: 'no-parent',
2754
              target: target,
2755
              purpose: purpose
2756
            });
2757
          },
2758
          logEventNoHandlers: function (name$$1, target) {
2759
            sequence.push({
2760
              outcome: 'no-handlers-left',
2761
              target: target
2762
            });
2763
          },
2764
          logEventResponse: function (name$$1, target, purpose) {
2765
            sequence.push({
2766
              outcome: 'response',
2767
              purpose: purpose,
2768
              target: target
2769
            });
2770
          },
2771
          write: function () {
2772
            if (contains([
2773
                'mousemove',
2774
                'mouseover',
2775
                'mouseout',
2776
                systemInit()
2777
              ], eventName)) {
2778
              return;
2779
            }
2780
            console.log(eventName, {
2781
              event: eventName,
2782
              target: initialTarget.dom(),
2783
              sequence: map$1(sequence, function (s) {
2784
                if (!contains([
2785
                    'cut',
2786
                    'stopped',
2787
                    'response'
2788
                  ], s.outcome)) {
2789
                  return s.outcome;
2790
                } else {
2791
                  return '{' + s.purpose + '} ' + s.outcome + ' at (' + element(s.target) + ')';
2792
                }
2793
              })
2794
            });
2795
          }
2796
        };
2797
      }() : ignoreEvent;
2798
      var output = f(logger);
2799
      logger.write();
2800
      return output;
2801
    };
2802
2803
    var menuFields = constant([
2804
      strict$1('menu'),
2805
      strict$1('selectedMenu')
2806
    ]);
2807
    var itemFields = constant([
2808
      strict$1('item'),
2809
      strict$1('selectedItem')
2810
    ]);
2811
    var schema = constant(objOfOnly(itemFields().concat(menuFields())));
2812
    var itemSchema = constant(objOfOnly(itemFields()));
2813
2814
    var _initSize = strictObjOf('initSize', [
2815
      strict$1('numColumns'),
2816
      strict$1('numRows')
2817
    ]);
2818
    var itemMarkers = function () {
2819
      return strictOf('markers', itemSchema());
2820
    };
2821
    var tieredMenuMarkers = function () {
2822
      return strictObjOf('markers', [strict$1('backgroundMenu')].concat(menuFields()).concat(itemFields()));
2823
    };
2824
    var markers = function (required) {
2825
      return strictObjOf('markers', map$1(required, strict$1));
2826
    };
2827
    var onPresenceHandler = function (label, fieldName, presence) {
2828
      var trace = getTrace();
2829
      return field(fieldName, fieldName, presence, valueOf(function (f) {
2830
        return Result.value(function () {
2831
          var args = [];
2832
          for (var _i = 0; _i < arguments.length; _i++) {
2833
            args[_i] = arguments[_i];
2834
          }
2835
          return f.apply(undefined, args);
2836
        });
2837
      }));
2838
    };
2839
    var onHandler = function (fieldName) {
2840
      return onPresenceHandler('onHandler', fieldName, defaulted(noop));
2841
    };
2842
    var onKeyboardHandler = function (fieldName) {
2843
      return onPresenceHandler('onKeyboardHandler', fieldName, defaulted(Option.none));
2844
    };
2845
    var onStrictHandler = function (fieldName) {
2846
      return onPresenceHandler('onHandler', fieldName, strict());
2847
    };
2848
    var onStrictKeyboardHandler = function (fieldName) {
2849
      return onPresenceHandler('onKeyboardHandler', fieldName, strict());
2850
    };
2851
    var output$1 = function (name, value) {
2852
      return state$1(name, constant(value));
2853
    };
2854
    var snapshot$1 = function (name) {
2855
      return state$1(name, identity);
2856
    };
2857
    var initSize = constant(_initSize);
2858
2859
    var ReceivingSchema = [strictOf('channels', setOf(Result.value, objOfOnly([
2860
        onStrictHandler('onReceive'),
2861
        defaulted$1('schema', anyValue$1())
2862
      ])))];
2863
2864
    var Receiving = create$1({
2865
      fields: ReceivingSchema,
2866
      name: 'receiving',
2867
      active: ActiveReceiving
2868
    });
2869
2870
    var updateAriaState = function (component, toggleConfig) {
2871
      var pressed = isOn(component, toggleConfig);
2872
      var ariaInfo = toggleConfig.aria();
2873
      ariaInfo.update()(component, ariaInfo, pressed);
2874
    };
2875
    var toggle$2 = function (component, toggleConfig, toggleState) {
2876
      toggle$1(component.element(), toggleConfig.toggleClass());
2877
      updateAriaState(component, toggleConfig);
2878
    };
2879
    var on = function (component, toggleConfig, toggleState) {
2880
      add$2(component.element(), toggleConfig.toggleClass());
2881
      updateAriaState(component, toggleConfig);
2882
    };
2883
    var off = function (component, toggleConfig, toggleState) {
2884
      remove$4(component.element(), toggleConfig.toggleClass());
2885
      updateAriaState(component, toggleConfig);
2886
    };
2887
    var isOn = function (component, toggleConfig) {
2888
      return has$2(component.element(), toggleConfig.toggleClass());
2889
    };
2890
    var onLoad = function (component, toggleConfig, toggleState) {
2891
      var api = toggleConfig.selected() ? on : off;
2892
      api(component, toggleConfig, toggleState);
2893
    };
2894
2895
    var ToggleApis = /*#__PURE__*/Object.freeze({
2896
        onLoad: onLoad,
2897
        toggle: toggle$2,
2898
        isOn: isOn,
2899
        on: on,
2900
        off: off
2901
    });
2902
2903
    var exhibit = function (base, toggleConfig, toggleState) {
2904
      return nu$6({});
2905
    };
2906
    var events$1 = function (toggleConfig, toggleState) {
2907
      var execute = executeEvent(toggleConfig, toggleState, toggle$2);
2908
      var load = loadEvent(toggleConfig, toggleState, onLoad);
2909
      return derive(flatten([
2910
        toggleConfig.toggleOnExecute() ? [execute] : [],
2911
        [load]
2912
      ]));
2913
    };
2914
2915
    var ActiveToggle = /*#__PURE__*/Object.freeze({
2916
        exhibit: exhibit,
2917
        events: events$1
2918
    });
2919
2920
    var updatePressed = function (component, ariaInfo, status) {
2921
      set(component.element(), 'aria-pressed', status);
2922
      if (ariaInfo.syncWithExpanded()) {
2923
        updateExpanded(component, ariaInfo, status);
2924
      }
2925
    };
2926
    var updateSelected = function (component, ariaInfo, status) {
2927
      set(component.element(), 'aria-selected', status);
2928
    };
2929
    var updateChecked = function (component, ariaInfo, status) {
2930
      set(component.element(), 'aria-checked', status);
2931
    };
2932
    var updateExpanded = function (component, ariaInfo, status) {
2933
      set(component.element(), 'aria-expanded', status);
2934
    };
2935
2936
    var ToggleSchema = [
2937
      defaulted$1('selected', false),
2938
      strict$1('toggleClass'),
2939
      defaulted$1('toggleOnExecute', true),
2940
      defaultedOf('aria', { mode: 'none' }, choose$1('mode', {
2941
        pressed: [
2942
          defaulted$1('syncWithExpanded', false),
2943
          output$1('update', updatePressed)
2944
        ],
2945
        checked: [output$1('update', updateChecked)],
2946
        expanded: [output$1('update', updateExpanded)],
2947
        selected: [output$1('update', updateSelected)],
2948
        none: [output$1('update', noop)]
2949
      }))
2950
    ];
2951
2952
    var Toggling = create$1({
2953
      fields: ToggleSchema,
2954
      name: 'toggling',
2955
      active: ActiveToggle,
2956
      apis: ToggleApis
2957
    });
2958
2959
    var format = function (command, update) {
2960
      return Receiving.config({
2961
        channels: wrap$2(TinyChannels.formatChanged(), {
2962
          onReceive: function (button, data) {
2963
            if (data.command === command) {
2964
              update(button, data.state);
2965
            }
2966
          }
2967
        })
2968
      });
2969
    };
2970
    var orientation = function (onReceive) {
2971
      return Receiving.config({ channels: wrap$2(TinyChannels.orientationChanged(), { onReceive: onReceive }) });
2972
    };
2973
    var receive$1 = function (channel, onReceive) {
2974
      return {
2975
        key: channel,
2976
        value: { onReceive: onReceive }
2977
      };
2978
    };
2979
    var Receivers = {
2980
      format: format,
2981
      orientation: orientation,
2982
      receive: receive$1
2983
    };
2984
2985
    var prefix = 'tinymce-mobile';
2986
    var resolve$1 = function (p) {
2987
      return prefix + '-' + p;
2988
    };
2989
    var Styles = {
2990
      resolve: resolve$1,
2991
      prefix: constant(prefix)
2992
    };
2993
2994
    var events$2 = function (optAction) {
2995
      var executeHandler = function (action) {
2996
        return run(execute(), function (component, simulatedEvent) {
2997
          action(component);
2998
          simulatedEvent.stop();
2999
        });
3000
      };
3001
      var onClick = function (component, simulatedEvent) {
3002
        simulatedEvent.stop();
3003
        emitExecute(component);
3004
      };
3005
      var onMousedown = function (component, simulatedEvent) {
3006
        simulatedEvent.cut();
3007
      };
3008
      var pointerEvents = PlatformDetection$1.detect().deviceType.isTouch() ? [run(tap(), onClick)] : [
3009
        run(click(), onClick),
3010
        run(mousedown(), onMousedown)
3011
      ];
3012
      return derive(flatten([
3013
        optAction.map(executeHandler).toArray(),
3014
        pointerEvents
3015
      ]));
3016
    };
3017
3018
    var focus$3 = function (component, focusConfig) {
3019
      if (!focusConfig.ignore()) {
3020
        focus$2(component.element());
3021
        focusConfig.onFocus()(component);
3022
      }
3023
    };
3024
    var blur$1 = function (component, focusConfig) {
3025
      if (!focusConfig.ignore()) {
3026
        blur$$1(component.element());
3027
      }
3028
    };
3029
    var isFocused = function (component) {
3030
      return hasFocus(component.element());
3031
    };
3032
3033
    var FocusApis = /*#__PURE__*/Object.freeze({
3034
        focus: focus$3,
3035
        blur: blur$1,
3036
        isFocused: isFocused
3037
    });
3038
3039
    var exhibit$1 = function (base, focusConfig) {
3040
      if (focusConfig.ignore()) {
3041
        return nu$6({});
3042
      } else {
3043
        return nu$6({ attributes: { tabindex: '-1' } });
3044
      }
3045
    };
3046
    var events$3 = function (focusConfig) {
3047
      return derive([run(focus$1(), function (component, simulatedEvent) {
3048
          focus$3(component, focusConfig);
3049
          simulatedEvent.stop();
3050
        })]);
3051
    };
3052
3053
    var ActiveFocus = /*#__PURE__*/Object.freeze({
3054
        exhibit: exhibit$1,
3055
        events: events$3
3056
    });
3057
3058
    var FocusSchema = [
3059
      onHandler('onFocus'),
3060
      defaulted$1('ignore', false)
3061
    ];
3062
3063
    var Focusing = create$1({
3064
      fields: FocusSchema,
3065
      name: 'focusing',
3066
      active: ActiveFocus,
3067
      apis: FocusApis
3068
    });
3069
3070
    var isSupported = function (dom) {
3071
      return dom.style !== undefined;
3072
    };
3073
3074
    var internalSet = function (dom, property, value$$1) {
3075
      if (!isString(value$$1)) {
3076
        console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value$$1, ':: Element ', dom);
3077
        throw new Error('CSS value must be a string: ' + value$$1);
3078
      }
3079
      if (isSupported(dom))
3080
        dom.style.setProperty(property, value$$1);
3081
    };
3082
    var internalRemove = function (dom, property) {
3083
      if (isSupported(dom))
3084
        dom.style.removeProperty(property);
3085
    };
3086
    var set$2 = function (element, property, value$$1) {
3087
      var dom = element.dom();
3088
      internalSet(dom, property, value$$1);
3089
    };
3090
    var setAll$1 = function (element, css) {
3091
      var dom = element.dom();
3092
      each(css, function (v, k) {
3093
        internalSet(dom, k, v);
3094
      });
3095
    };
3096
    var get$4 = function (element, property) {
3097
      var dom = element.dom();
3098
      var styles = window.getComputedStyle(dom);
3099
      var r = styles.getPropertyValue(property);
3100
      var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
3101
      return v === null ? undefined : v;
3102
    };
3103
    var getUnsafeProperty = function (dom, property) {
3104
      return isSupported(dom) ? dom.style.getPropertyValue(property) : '';
3105
    };
3106
    var getRaw = function (element, property) {
3107
      var dom = element.dom();
3108
      var raw = getUnsafeProperty(dom, property);
3109
      return Option.from(raw).filter(function (r) {
3110
        return r.length > 0;
3111
      });
3112
    };
3113
    var remove$5 = function (element, property) {
3114
      var dom = element.dom();
3115
      internalRemove(dom, property);
3116
      if (has$1(element, 'style') && trim(get$1(element, 'style')) === '') {
3117
        remove$1(element, 'style');
3118
      }
3119
    };
3120
    var reflow = function (e) {
3121
      return e.dom().offsetWidth;
3122
    };
3123
3124
    function Dimension (name, getOffset) {
3125
      var set = function (element, h) {
3126
        if (!isNumber(h) && !h.match(/^[0-9]+$/))
3127
          throw name + '.set accepts only positive integer values. Value was ' + h;
3128
        var dom = element.dom();
3129
        if (isSupported(dom))
3130
          dom.style[name] = h + 'px';
3131
      };
3132
      var get = function (element) {
3133
        var r = getOffset(element);
3134
        if (r <= 0 || r === null) {
3135
          var css = get$4(element, name);
3136
          return parseFloat(css) || 0;
3137
        }
3138
        return r;
3139
      };
3140
      var getOuter = get;
3141
      var aggregate = function (element, properties) {
3142
        return foldl(properties, function (acc, property) {
3143
          var val = get$4(element, property);
3144
          var value = val === undefined ? 0 : parseInt(val, 10);
3145
          return isNaN(value) ? acc : acc + value;
3146
        }, 0);
3147
      };
3148
      var max = function (element, value, properties) {
3149
        var cumulativeInclusions = aggregate(element, properties);
3150
        var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;
3151
        return absoluteMax;
3152
      };
3153
      return {
3154
        set: set,
3155
        get: get,
3156
        getOuter: getOuter,
3157
        aggregate: aggregate,
3158
        max: max
3159
      };
3160
    }
3161
3162
    var api = Dimension('height', function (element) {
3163
      var dom = element.dom();
3164
      return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;
3165
    });
3166
    var get$5 = function (element) {
3167
      return api.get(element);
3168
    };
3169
3170
    var ancestors = function (scope, predicate, isRoot) {
3171
      return filter(parents(scope, isRoot), predicate);
3172
    };
3173
    var siblings$1 = function (scope, predicate) {
3174
      return filter(siblings(scope), predicate);
3175
    };
3176
3177
    var all$3 = function (selector) {
3178
      return all(selector);
3179
    };
3180
    var ancestors$1 = function (scope, selector, isRoot) {
3181
      return ancestors(scope, function (e) {
3182
        return is(e, selector);
3183
      }, isRoot);
3184
    };
3185
    var siblings$2 = function (scope, selector) {
3186
      return siblings$1(scope, function (e) {
3187
        return is(e, selector);
3188
      });
3189
    };
3190
    var descendants$1 = function (scope, selector) {
3191
      return all(selector, scope);
3192
    };
3193
3194
    var first$2 = function (selector) {
3195
      return one(selector);
3196
    };
3197
    var ancestor$2 = function (scope, selector, isRoot) {
3198
      return ancestor(scope, function (e) {
3199
        return is(e, selector);
3200
      }, isRoot);
3201
    };
3202
    var descendant$2 = function (scope, selector) {
3203
      return one(selector, scope);
3204
    };
3205
    var closest$2 = function (scope, selector, isRoot) {
3206
      return ClosestOrAncestor(is, ancestor$2, scope, selector, isRoot);
3207
    };
3208
3209
    var BACKSPACE = function () {
3210
      return [8];
3211
    };
3212
    var TAB = function () {
3213
      return [9];
3214
    };
3215
    var ENTER = function () {
3216
      return [13];
3217
    };
3218
    var ESCAPE = function () {
3219
      return [27];
3220
    };
3221
    var SPACE = function () {
3222
      return [32];
3223
    };
3224
    var LEFT = function () {
3225
      return [37];
3226
    };
3227
    var UP = function () {
3228
      return [38];
3229
    };
3230
    var RIGHT = function () {
3231
      return [39];
3232
    };
3233
    var DOWN = function () {
3234
      return [40];
3235
    };
3236
3237
    var cyclePrev = function (values, index, predicate) {
3238
      var before = reverse(values.slice(0, index));
3239
      var after = reverse(values.slice(index + 1));
3240
      return find$2(before.concat(after), predicate);
3241
    };
3242
    var tryPrev = function (values, index, predicate) {
3243
      var before = reverse(values.slice(0, index));
3244
      return find$2(before, predicate);
3245
    };
3246
    var cycleNext = function (values, index, predicate) {
3247
      var before = values.slice(0, index);
3248
      var after = values.slice(index + 1);
3249
      return find$2(after.concat(before), predicate);
3250
    };
3251
    var tryNext = function (values, index, predicate) {
3252
      var after = values.slice(index + 1);
3253
      return find$2(after, predicate);
3254
    };
3255
3256
    var inSet = function (keys) {
3257
      return function (event) {
3258
        var raw = event.raw();
3259
        return contains(keys, raw.which);
3260
      };
3261
    };
3262
    var and = function (preds) {
3263
      return function (event) {
3264
        return forall(preds, function (pred) {
3265
          return pred(event);
3266
        });
3267
      };
3268
    };
3269
    var isShift = function (event) {
3270
      var raw = event.raw();
3271
      return raw.shiftKey === true;
3272
    };
3273
    var isControl = function (event) {
3274
      var raw = event.raw();
3275
      return raw.ctrlKey === true;
3276
    };
3277
    var isNotShift = not(isShift);
3278
3279
    var rule = function (matches, action) {
3280
      return {
3281
        matches: matches,
3282
        classification: action
3283
      };
3284
    };
3285
    var choose$2 = function (transitions, event) {
3286
      var transition = find$2(transitions, function (t) {
3287
        return t.matches(event);
3288
      });
3289
      return transition.map(function (t) {
3290
        return t.classification;
3291
      });
3292
    };
3293
3294
    var cycleBy = function (value, delta, min, max) {
3295
      var r = value + delta;
3296
      if (r > max) {
3297
        return min;
3298
      } else {
3299
        return r < min ? max : r;
3300
      }
3301
    };
3302
    var cap = function (value, min, max) {
3303
      if (value <= min) {
3304
        return min;
3305
      } else {
3306
        return value >= max ? max : value;
3307
      }
3308
    };
3309
3310
    var dehighlightAll = function (component, hConfig, hState) {
3311
      var highlighted = descendants$1(component.element(), '.' + hConfig.highlightClass());
3312
      each$1(highlighted, function (h) {
3313
        remove$4(h, hConfig.highlightClass());
3314
        component.getSystem().getByDom(h).each(function (target) {
3315
          hConfig.onDehighlight()(component, target);
3316
        });
3317
      });
3318
    };
3319
    var dehighlight = function (component, hConfig, hState, target) {
3320
      var wasHighlighted = isHighlighted(component, hConfig, hState, target);
3321
      remove$4(target.element(), hConfig.highlightClass());
3322
      if (wasHighlighted) {
3323
        hConfig.onDehighlight()(component, target);
3324
      }
3325
    };
3326
    var highlight = function (component, hConfig, hState, target) {
3327
      var wasHighlighted = isHighlighted(component, hConfig, hState, target);
3328
      dehighlightAll(component, hConfig, hState);
3329
      add$2(target.element(), hConfig.highlightClass());
3330
      if (!wasHighlighted) {
3331
        hConfig.onHighlight()(component, target);
3332
      }
3333
    };
3334
    var highlightFirst = function (component, hConfig, hState) {
3335
      getFirst(component, hConfig, hState).each(function (firstComp) {
3336
        highlight(component, hConfig, hState, firstComp);
3337
      });
3338
    };
3339
    var highlightLast = function (component, hConfig, hState) {
3340
      getLast(component, hConfig, hState).each(function (lastComp) {
3341
        highlight(component, hConfig, hState, lastComp);
3342
      });
3343
    };
3344
    var highlightAt = function (component, hConfig, hState, index) {
3345
      getByIndex(component, hConfig, hState, index).fold(function (err) {
3346
        throw new Error(err);
3347
      }, function (firstComp) {
3348
        highlight(component, hConfig, hState, firstComp);
3349
      });
3350
    };
3351
    var highlightBy = function (component, hConfig, hState, predicate) {
3352
      var items = descendants$1(component.element(), '.' + hConfig.itemClass());
3353
      var itemComps = cat(map$1(items, function (i) {
3354
        return component.getSystem().getByDom(i).toOption();
3355
      }));
3356
      var targetComp = find$2(itemComps, predicate);
3357
      targetComp.each(function (c) {
3358
        highlight(component, hConfig, hState, c);
3359
      });
3360
    };
3361
    var isHighlighted = function (component, hConfig, hState, queryTarget) {
3362
      return has$2(queryTarget.element(), hConfig.highlightClass());
3363
    };
3364
    var getHighlighted = function (component, hConfig, hState) {
3365
      return descendant$2(component.element(), '.' + hConfig.highlightClass()).bind(function (e) {
3366
        return component.getSystem().getByDom(e).toOption();
3367
      });
3368
    };
3369
    var getByIndex = function (component, hConfig, hState, index) {
3370
      var items = descendants$1(component.element(), '.' + hConfig.itemClass());
3371
      return Option.from(items[index]).fold(function () {
3372
        return Result.error('No element found with index ' + index);
3373
      }, component.getSystem().getByDom);
3374
    };
3375
    var getFirst = function (component, hConfig, hState) {
3376
      return descendant$2(component.element(), '.' + hConfig.itemClass()).bind(function (e) {
3377
        return component.getSystem().getByDom(e).toOption();
3378
      });
3379
    };
3380
    var getLast = function (component, hConfig, hState) {
3381
      var items = descendants$1(component.element(), '.' + hConfig.itemClass());
3382
      var last$$1 = items.length > 0 ? Option.some(items[items.length - 1]) : Option.none();
3383
      return last$$1.bind(function (c) {
3384
        return component.getSystem().getByDom(c).toOption();
3385
      });
3386
    };
3387
    var getDelta = function (component, hConfig, hState, delta) {
3388
      var items = descendants$1(component.element(), '.' + hConfig.itemClass());
3389
      var current = findIndex(items, function (item) {
3390
        return has$2(item, hConfig.highlightClass());
3391
      });
3392
      return current.bind(function (selected) {
3393
        var dest = cycleBy(selected, delta, 0, items.length - 1);
3394
        return component.getSystem().getByDom(items[dest]).toOption();
3395
      });
3396
    };
3397
    var getPrevious = function (component, hConfig, hState) {
3398
      return getDelta(component, hConfig, hState, -1);
3399
    };
3400
    var getNext = function (component, hConfig, hState) {
3401
      return getDelta(component, hConfig, hState, +1);
3402
    };
3403
3404
    var HighlightApis = /*#__PURE__*/Object.freeze({
3405
        dehighlightAll: dehighlightAll,
3406
        dehighlight: dehighlight,
3407
        highlight: highlight,
3408
        highlightFirst: highlightFirst,
3409
        highlightLast: highlightLast,
3410
        highlightAt: highlightAt,
3411
        highlightBy: highlightBy,
3412
        isHighlighted: isHighlighted,
3413
        getHighlighted: getHighlighted,
3414
        getFirst: getFirst,
3415
        getLast: getLast,
3416
        getPrevious: getPrevious,
3417
        getNext: getNext
3418
    });
3419
3420
    var HighlightSchema = [
3421
      strict$1('highlightClass'),
3422
      strict$1('itemClass'),
3423
      onHandler('onHighlight'),
3424
      onHandler('onDehighlight')
3425
    ];
3426
3427
    var Highlighting = create$1({
3428
      fields: HighlightSchema,
3429
      name: 'highlighting',
3430
      apis: HighlightApis
3431
    });
3432
3433
    var dom = function () {
3434
      var get = function (component) {
3435
        return search(component.element());
3436
      };
3437
      var set = function (component, focusee) {
3438
        component.getSystem().triggerFocus(focusee, component.element());
3439
      };
3440
      return {
3441
        get: get,
3442
        set: set
3443
      };
3444
    };
3445
    var highlights = function () {
3446
      var get = function (component) {
3447
        return Highlighting.getHighlighted(component).map(function (item) {
3448
          return item.element();
3449
        });
3450
      };
3451
      var set = function (component, element) {
3452
        component.getSystem().getByDom(element).fold(noop, function (item) {
3453
          Highlighting.highlight(component, item);
3454
        });
3455
      };
3456
      return {
3457
        get: get,
3458
        set: set
3459
      };
3460
    };
3461
3462
    var typical = function (infoSchema, stateInit, getRules, getEvents, getApis, optFocusIn) {
3463
      var schema = function () {
3464
        return infoSchema.concat([
3465
          defaulted$1('focusManager', dom()),
3466
          output$1('handler', me),
3467
          output$1('state', stateInit)
3468
        ]);
3469
      };
3470
      var processKey = function (component, simulatedEvent, keyingConfig, keyingState) {
3471
        var rules = getRules(component, simulatedEvent, keyingConfig, keyingState);
3472
        return choose$2(rules, simulatedEvent.event()).bind(function (rule$$1) {
3473
          return rule$$1(component, simulatedEvent, keyingConfig, keyingState);
3474
        });
3475
      };
3476
      var toEvents = function (keyingConfig, keyingState) {
3477
        var otherEvents = getEvents(keyingConfig, keyingState);
3478
        var keyEvents = derive(optFocusIn.map(function (focusIn) {
3479
          return run(focus$1(), function (component, simulatedEvent) {
3480
            focusIn(component, keyingConfig, keyingState, simulatedEvent);
3481
            simulatedEvent.stop();
3482
          });
3483
        }).toArray().concat([run(keydown(), function (component, simulatedEvent) {
3484
            processKey(component, simulatedEvent, keyingConfig, keyingState).each(function (_) {
3485
              simulatedEvent.stop();
3486
            });
3487
          })]));
3488
        return deepMerge(otherEvents, keyEvents);
3489
      };
3490
      var me = {
3491
        schema: schema,
3492
        processKey: processKey,
3493
        toEvents: toEvents,
3494
        toApis: getApis
3495
      };
3496
      return me;
3497
    };
3498
3499
    var create$2 = function (cyclicField) {
3500
      var schema = [
3501
        option('onEscape'),
3502
        option('onEnter'),
3503
        defaulted$1('selector', '[data-alloy-tabstop="true"]'),
3504
        defaulted$1('firstTabstop', 0),
3505
        defaulted$1('useTabstopAt', constant(true)),
3506
        option('visibilitySelector')
3507
      ].concat([cyclicField]);
3508
      var isVisible = function (tabbingConfig, element) {
3509
        var target = tabbingConfig.visibilitySelector().bind(function (sel) {
3510
          return closest$2(element, sel);
3511
        }).getOr(element);
3512
        return get$5(target) > 0;
3513
      };
3514
      var findInitial = function (component, tabbingConfig) {
3515
        var tabstops = descendants$1(component.element(), tabbingConfig.selector());
3516
        var visibles = filter(tabstops, function (elem) {
3517
          return isVisible(tabbingConfig, elem);
3518
        });
3519
        return Option.from(visibles[tabbingConfig.firstTabstop()]);
3520
      };
3521
      var findCurrent = function (component, tabbingConfig) {
3522
        return tabbingConfig.focusManager().get(component).bind(function (elem) {
3523
          return closest$2(elem, tabbingConfig.selector());
3524
        });
3525
      };
3526
      var isTabstop = function (tabbingConfig, element) {
3527
        return isVisible(tabbingConfig, element) && tabbingConfig.useTabstopAt()(element);
3528
      };
3529
      var focusIn = function (component, tabbingConfig) {
3530
        findInitial(component, tabbingConfig).each(function (target) {
3531
          tabbingConfig.focusManager().set(component, target);
3532
        });
3533
      };
3534
      var goFromTabstop = function (component, tabstops, stopIndex, tabbingConfig, cycle) {
3535
        return cycle(tabstops, stopIndex, function (elem) {
3536
          return isTabstop(tabbingConfig, elem);
3537
        }).fold(function () {
3538
          return tabbingConfig.cyclic() ? Option.some(true) : Option.none();
3539
        }, function (target) {
3540
          tabbingConfig.focusManager().set(component, target);
3541
          return Option.some(true);
3542
        });
3543
      };
3544
      var go = function (component, simulatedEvent, tabbingConfig, cycle) {
3545
        var tabstops = descendants$1(component.element(), tabbingConfig.selector());
3546
        return findCurrent(component, tabbingConfig).bind(function (tabstop) {
3547
          var optStopIndex = findIndex(tabstops, curry(eq, tabstop));
3548
          return optStopIndex.bind(function (stopIndex) {
3549
            return goFromTabstop(component, tabstops, stopIndex, tabbingConfig, cycle);
3550
          });
3551
        });
3552
      };
3553
      var goBackwards = function (component, simulatedEvent, tabbingConfig, tabbingState) {
3554
        var navigate = tabbingConfig.cyclic() ? cyclePrev : tryPrev;
3555
        return go(component, simulatedEvent, tabbingConfig, navigate);
3556
      };
3557
      var goForwards = function (component, simulatedEvent, tabbingConfig, tabbingState) {
3558
        var navigate = tabbingConfig.cyclic() ? cycleNext : tryNext;
3559
        return go(component, simulatedEvent, tabbingConfig, navigate);
3560
      };
3561
      var execute = function (component, simulatedEvent, tabbingConfig, tabbingState) {
3562
        return tabbingConfig.onEnter().bind(function (f) {
3563
          return f(component, simulatedEvent);
3564
        });
3565
      };
3566
      var exit = function (component, simulatedEvent, tabbingConfig, tabbingState) {
3567
        return tabbingConfig.onEscape().bind(function (f) {
3568
          return f(component, simulatedEvent);
3569
        });
3570
      };
3571
      var getRules = constant([
3572
        rule(and([
3573
          isShift,
3574
          inSet(TAB())
3575
        ]), goBackwards),
3576
        rule(inSet(TAB()), goForwards),
3577
        rule(inSet(ESCAPE()), exit),
3578
        rule(and([
3579
          isNotShift,
3580
          inSet(ENTER())
3581
        ]), execute)
3582
      ]);
3583
      var getEvents = constant({});
3584
      var getApis = constant({});
3585
      return typical(schema, NoState.init, getRules, getEvents, getApis, Option.some(focusIn));
3586
    };
3587
3588
    var AcyclicType = create$2(state$1('cyclic', constant(false)));
3589
3590
    var CyclicType = create$2(state$1('cyclic', constant(true)));
3591
3592
    var inside = function (target) {
3593
      return name(target) === 'input' && get$1(target, 'type') !== 'radio' || name(target) === 'textarea';
3594
    };
3595
3596
    var doDefaultExecute = function (component, simulatedEvent, focused) {
3597
      dispatch(component, focused, execute());
3598
      return Option.some(true);
3599
    };
3600
    var defaultExecute = function (component, simulatedEvent, focused) {
3601
      return inside(focused) && inSet(SPACE())(simulatedEvent.event()) ? Option.none() : doDefaultExecute(component, simulatedEvent, focused);
3602
    };
3603
3604
    var schema$1 = [
3605
      defaulted$1('execute', defaultExecute),
3606
      defaulted$1('useSpace', false),
3607
      defaulted$1('useEnter', true),
3608
      defaulted$1('useControlEnter', false),
3609
      defaulted$1('useDown', false)
3610
    ];
3611
    var execute$1 = function (component, simulatedEvent, executeConfig) {
3612
      return executeConfig.execute()(component, simulatedEvent, component.element());
3613
    };
3614
    var getRules = function (component, simulatedEvent, executeConfig, executeState) {
3615
      var spaceExec = executeConfig.useSpace() && !inside(component.element()) ? SPACE() : [];
3616
      var enterExec = executeConfig.useEnter() ? ENTER() : [];
3617
      var downExec = executeConfig.useDown() ? DOWN() : [];
3618
      var execKeys = spaceExec.concat(enterExec).concat(downExec);
3619
      return [rule(inSet(execKeys), execute$1)].concat(executeConfig.useControlEnter() ? [rule(and([
3620
          isControl,
3621
          inSet(ENTER())
3622
        ]), execute$1)] : []);
3623
    };
3624
    var getEvents = constant({});
3625
    var getApis = constant({});
3626
    var ExecutionType = typical(schema$1, NoState.init, getRules, getEvents, getApis, Option.none());
3627
3628
    var flatgrid = function (spec) {
3629
      var dimensions = Cell(Option.none());
3630
      var setGridSize = function (numRows, numColumns) {
3631
        dimensions.set(Option.some({
3632
          numRows: constant(numRows),
3633
          numColumns: constant(numColumns)
3634
        }));
3635
      };
3636
      var getNumRows = function () {
3637
        return dimensions.get().map(function (d) {
3638
          return d.numRows();
3639
        });
3640
      };
3641
      var getNumColumns = function () {
3642
        return dimensions.get().map(function (d) {
3643
          return d.numColumns();
3644
        });
3645
      };
3646
      return nu$7({
3647
        readState: constant({}),
3648
        setGridSize: setGridSize,
3649
        getNumRows: getNumRows,
3650
        getNumColumns: getNumColumns
3651
      });
3652
    };
3653
    var init = function (spec) {
3654
      return spec.state()(spec);
3655
    };
3656
3657
    var KeyingState = /*#__PURE__*/Object.freeze({
3658
        flatgrid: flatgrid,
3659
        init: init
3660
    });
3661
3662
    var onDirection = function (isLtr, isRtl) {
3663
      return function (element) {
3664
        return getDirection(element) === 'rtl' ? isRtl : isLtr;
3665
      };
3666
    };
3667
    var getDirection = function (element) {
3668
      return get$4(element, 'direction') === 'rtl' ? 'rtl' : 'ltr';
3669
    };
3670
3671
    var useH = function (movement) {
3672
      return function (component, simulatedEvent, config, state) {
3673
        var move = movement(component.element());
3674
        return use(move, component, simulatedEvent, config, state);
3675
      };
3676
    };
3677
    var west = function (moveLeft, moveRight) {
3678
      var movement = onDirection(moveLeft, moveRight);
3679
      return useH(movement);
3680
    };
3681
    var east = function (moveLeft, moveRight) {
3682
      var movement = onDirection(moveRight, moveLeft);
3683
      return useH(movement);
3684
    };
3685
    var useV = function (move) {
3686
      return function (component, simulatedEvent, config, state) {
3687
        return use(move, component, simulatedEvent, config, state);
3688
      };
3689
    };
3690
    var use = function (move, component, simulatedEvent, config, state) {
3691
      var outcome = config.focusManager().get(component).bind(function (focused) {
3692
        return move(component.element(), focused, config, state);
3693
      });
3694
      return outcome.map(function (newFocus) {
3695
        config.focusManager().set(component, newFocus);
3696
        return true;
3697
      });
3698
    };
3699
    var north = useV;
3700
    var south = useV;
3701
    var move = useV;
3702
3703
    var isHidden = function (dom) {
3704
      return dom.offsetWidth <= 0 && dom.offsetHeight <= 0;
3705
    };
3706
    var isVisible = function (element) {
3707
      var dom = element.dom();
3708
      return !isHidden(dom);
3709
    };
3710
3711
    var indexInfo = MixedBag([
3712
      'index',
3713
      'candidates'
3714
    ], []);
3715
    var locate = function (candidates, predicate) {
3716
      return findIndex(candidates, predicate).map(function (index) {
3717
        return indexInfo({
3718
          index: index,
3719
          candidates: candidates
3720
        });
3721
      });
3722
    };
3723
3724
    var locateVisible = function (container, current, selector) {
3725
      var filter$$1 = isVisible;
3726
      return locateIn(container, current, selector, filter$$1);
3727
    };
3728
    var locateIn = function (container, current, selector, filter$$1) {
3729
      var predicate = curry(eq, current);
3730
      var candidates = descendants$1(container, selector);
3731
      var visible = filter(candidates, isVisible);
3732
      return locate(visible, predicate);
3733
    };
3734
    var findIndex$2 = function (elements, target) {
3735
      return findIndex(elements, function (elem) {
3736
        return eq(target, elem);
3737
      });
3738
    };
3739
3740
    var withGrid = function (values, index, numCols, f) {
3741
      var oldRow = Math.floor(index / numCols);
3742
      var oldColumn = index % numCols;
3743
      return f(oldRow, oldColumn).bind(function (address) {
3744
        var newIndex = address.row() * numCols + address.column();
3745
        return newIndex >= 0 && newIndex < values.length ? Option.some(values[newIndex]) : Option.none();
3746
      });
3747
    };
3748
    var cycleHorizontal = function (values, index, numRows, numCols, delta) {
3749
      return withGrid(values, index, numCols, function (oldRow, oldColumn) {
3750
        var onLastRow = oldRow === numRows - 1;
3751
        var colsInRow = onLastRow ? values.length - oldRow * numCols : numCols;
3752
        var newColumn = cycleBy(oldColumn, delta, 0, colsInRow - 1);
3753
        return Option.some({
3754
          row: constant(oldRow),
3755
          column: constant(newColumn)
3756
        });
3757
      });
3758
    };
3759
    var cycleVertical = function (values, index, numRows, numCols, delta) {
3760
      return withGrid(values, index, numCols, function (oldRow, oldColumn) {
3761
        var newRow = cycleBy(oldRow, delta, 0, numRows - 1);
3762
        var onLastRow = newRow === numRows - 1;
3763
        var colsInRow = onLastRow ? values.length - newRow * numCols : numCols;
3764
        var newCol = cap(oldColumn, 0, colsInRow - 1);
3765
        return Option.some({
3766
          row: constant(newRow),
3767
          column: constant(newCol)
3768
        });
3769
      });
3770
    };
3771
    var cycleRight = function (values, index, numRows, numCols) {
3772
      return cycleHorizontal(values, index, numRows, numCols, +1);
3773
    };
3774
    var cycleLeft = function (values, index, numRows, numCols) {
3775
      return cycleHorizontal(values, index, numRows, numCols, -1);
3776
    };
3777
    var cycleUp = function (values, index, numRows, numCols) {
3778
      return cycleVertical(values, index, numRows, numCols, -1);
3779
    };
3780
    var cycleDown = function (values, index, numRows, numCols) {
3781
      return cycleVertical(values, index, numRows, numCols, +1);
3782
    };
3783
3784
    var schema$2 = [
3785
      strict$1('selector'),
3786
      defaulted$1('execute', defaultExecute),
3787
      onKeyboardHandler('onEscape'),
3788
      defaulted$1('captureTab', false),
3789
      initSize()
3790
    ];
3791
    var focusIn = function (component, gridConfig, gridState) {
3792
      descendant$2(component.element(), gridConfig.selector()).each(function (first) {
3793
        gridConfig.focusManager().set(component, first);
3794
      });
3795
    };
3796
    var findCurrent = function (component, gridConfig) {
3797
      return gridConfig.focusManager().get(component).bind(function (elem) {
3798
        return closest$2(elem, gridConfig.selector());
3799
      });
3800
    };
3801
    var execute$2 = function (component, simulatedEvent, gridConfig, gridState) {
3802
      return findCurrent(component, gridConfig).bind(function (focused) {
3803
        return gridConfig.execute()(component, simulatedEvent, focused);
3804
      });
3805
    };
3806
    var doMove = function (cycle) {
3807
      return function (element, focused, gridConfig, gridState) {
3808
        return locateVisible(element, focused, gridConfig.selector()).bind(function (identified) {
3809
          return cycle(identified.candidates(), identified.index(), gridState.getNumRows().getOr(gridConfig.initSize().numRows()), gridState.getNumColumns().getOr(gridConfig.initSize().numColumns()));
3810
        });
3811
      };
3812
    };
3813
    var handleTab = function (component, simulatedEvent, gridConfig, gridState) {
3814
      return gridConfig.captureTab() ? Option.some(true) : Option.none();
3815
    };
3816
    var doEscape = function (component, simulatedEvent, gridConfig, gridState) {
3817
      return gridConfig.onEscape()(component, simulatedEvent);
3818
    };
3819
    var moveLeft = doMove(cycleLeft);
3820
    var moveRight = doMove(cycleRight);
3821
    var moveNorth = doMove(cycleUp);
3822
    var moveSouth = doMove(cycleDown);
3823
    var getRules$1 = constant([
3824
      rule(inSet(LEFT()), west(moveLeft, moveRight)),
3825
      rule(inSet(RIGHT()), east(moveLeft, moveRight)),
3826
      rule(inSet(UP()), north(moveNorth)),
3827
      rule(inSet(DOWN()), south(moveSouth)),
3828
      rule(and([
3829
        isShift,
3830
        inSet(TAB())
3831
      ]), handleTab),
3832
      rule(and([
3833
        isNotShift,
3834
        inSet(TAB())
3835
      ]), handleTab),
3836
      rule(inSet(ESCAPE()), doEscape),
3837
      rule(inSet(SPACE().concat(ENTER())), execute$2)
3838
    ]);
3839
    var getEvents$1 = constant({});
3840
    var getApis$1 = {};
3841
    var FlatgridType = typical(schema$2, flatgrid, getRules$1, getEvents$1, getApis$1, Option.some(focusIn));
3842
3843
    var horizontal = function (container, selector, current, delta) {
3844
      return locateVisible(container, current, selector).bind(function (identified) {
3845
        var index = identified.index();
3846
        var candidates = identified.candidates();
3847
        var newIndex = cycleBy(index, delta, 0, candidates.length - 1);
3848
        return Option.from(candidates[newIndex]);
3849
      });
3850
    };
3851
3852
    var schema$3 = [
3853
      strict$1('selector'),
3854
      defaulted$1('getInitial', Option.none),
3855
      defaulted$1('execute', defaultExecute),
3856
      defaulted$1('executeOnMove', false),
3857
      defaulted$1('allowVertical', true)
3858
    ];
3859
    var findCurrent$1 = function (component, flowConfig) {
3860
      return flowConfig.focusManager().get(component).bind(function (elem) {
3861
        return closest$2(elem, flowConfig.selector());
3862
      });
3863
    };
3864
    var execute$3 = function (component, simulatedEvent, flowConfig) {
3865
      return findCurrent$1(component, flowConfig).bind(function (focused) {
3866
        return flowConfig.execute()(component, simulatedEvent, focused);
3867
      });
3868
    };
3869
    var focusIn$1 = function (component, flowConfig) {
3870
      flowConfig.getInitial()(component).or(descendant$2(component.element(), flowConfig.selector())).each(function (first) {
3871
        flowConfig.focusManager().set(component, first);
3872
      });
3873
    };
3874
    var moveLeft$1 = function (element, focused, info) {
3875
      return horizontal(element, info.selector(), focused, -1);
3876
    };
3877
    var moveRight$1 = function (element, focused, info) {
3878
      return horizontal(element, info.selector(), focused, +1);
3879
    };
3880
    var doMove$1 = function (movement) {
3881
      return function (component, simulatedEvent, flowConfig) {
3882
        return movement(component, simulatedEvent, flowConfig).bind(function () {
3883
          return flowConfig.executeOnMove() ? execute$3(component, simulatedEvent, flowConfig) : Option.some(true);
3884
        });
3885
      };
3886
    };
3887
    var getRules$2 = function (_component, _se, flowConfig, _flowState) {
3888
      var westMovers = LEFT().concat(flowConfig.allowVertical() ? UP() : []);
3889
      var eastMovers = RIGHT().concat(flowConfig.allowVertical() ? DOWN() : []);
3890
      return [
3891
        rule(inSet(westMovers), doMove$1(west(moveLeft$1, moveRight$1))),
3892
        rule(inSet(eastMovers), doMove$1(east(moveLeft$1, moveRight$1))),
3893
        rule(inSet(ENTER()), execute$3),
3894
        rule(inSet(SPACE()), execute$3)
3895
      ];
3896
    };
3897
    var getEvents$2 = constant({});
3898
    var getApis$2 = constant({});
3899
    var FlowType = typical(schema$3, NoState.init, getRules$2, getEvents$2, getApis$2, Option.some(focusIn$1));
3900
3901
    var outcome = MixedBag([
3902
      'rowIndex',
3903
      'columnIndex',
3904
      'cell'
3905
    ], []);
3906
    var toCell = function (matrix, rowIndex, columnIndex) {
3907
      return Option.from(matrix[rowIndex]).bind(function (row) {
3908
        return Option.from(row[columnIndex]).map(function (cell) {
3909
          return outcome({
3910
            rowIndex: rowIndex,
3911
            columnIndex: columnIndex,
3912
            cell: cell
3913
          });
3914
        });
3915
      });
3916
    };
3917
    var cycleHorizontal$1 = function (matrix, rowIndex, startCol, deltaCol) {
3918
      var row = matrix[rowIndex];
3919
      var colsInRow = row.length;
3920
      var newColIndex = cycleBy(startCol, deltaCol, 0, colsInRow - 1);
3921
      return toCell(matrix, rowIndex, newColIndex);
3922
    };
3923
    var cycleVertical$1 = function (matrix, colIndex, startRow, deltaRow) {
3924
      var nextRowIndex = cycleBy(startRow, deltaRow, 0, matrix.length - 1);
3925
      var colsInNextRow = matrix[nextRowIndex].length;
3926
      var nextColIndex = cap(colIndex, 0, colsInNextRow - 1);
3927
      return toCell(matrix, nextRowIndex, nextColIndex);
3928
    };
3929
    var moveHorizontal = function (matrix, rowIndex, startCol, deltaCol) {
3930
      var row = matrix[rowIndex];
3931
      var colsInRow = row.length;
3932
      var newColIndex = cap(startCol + deltaCol, 0, colsInRow - 1);
3933
      return toCell(matrix, rowIndex, newColIndex);
3934
    };
3935
    var moveVertical = function (matrix, colIndex, startRow, deltaRow) {
3936
      var nextRowIndex = cap(startRow + deltaRow, 0, matrix.length - 1);
3937
      var colsInNextRow = matrix[nextRowIndex].length;
3938
      var nextColIndex = cap(colIndex, 0, colsInNextRow - 1);
3939
      return toCell(matrix, nextRowIndex, nextColIndex);
3940
    };
3941
    var cycleRight$1 = function (matrix, startRow, startCol) {
3942
      return cycleHorizontal$1(matrix, startRow, startCol, +1);
3943
    };
3944
    var cycleLeft$1 = function (matrix, startRow, startCol) {
3945
      return cycleHorizontal$1(matrix, startRow, startCol, -1);
3946
    };
3947
    var cycleUp$1 = function (matrix, startRow, startCol) {
3948
      return cycleVertical$1(matrix, startCol, startRow, -1);
3949
    };
3950
    var cycleDown$1 = function (matrix, startRow, startCol) {
3951
      return cycleVertical$1(matrix, startCol, startRow, +1);
3952
    };
3953
    var moveLeft$2 = function (matrix, startRow, startCol) {
3954
      return moveHorizontal(matrix, startRow, startCol, -1);
3955
    };
3956
    var moveRight$2 = function (matrix, startRow, startCol) {
3957
      return moveHorizontal(matrix, startRow, startCol, +1);
3958
    };
3959
    var moveUp = function (matrix, startRow, startCol) {
3960
      return moveVertical(matrix, startCol, startRow, -1);
3961
    };
3962
    var moveDown = function (matrix, startRow, startCol) {
3963
      return moveVertical(matrix, startCol, startRow, +1);
3964
    };
3965
3966
    var schema$4 = [
3967
      strictObjOf('selectors', [
3968
        strict$1('row'),
3969
        strict$1('cell')
3970
      ]),
3971
      defaulted$1('cycles', true),
3972
      defaulted$1('previousSelector', Option.none),
3973
      defaulted$1('execute', defaultExecute)
3974
    ];
3975
    var focusIn$2 = function (component, matrixConfig) {
3976
      var focused = matrixConfig.previousSelector()(component).orThunk(function () {
3977
        var selectors = matrixConfig.selectors();
3978
        return descendant$2(component.element(), selectors.cell());
3979
      });
3980
      focused.each(function (cell) {
3981
        matrixConfig.focusManager().set(component, cell);
3982
      });
3983
    };
3984
    var execute$4 = function (component, simulatedEvent, matrixConfig) {
3985
      return search(component.element()).bind(function (focused) {
3986
        return matrixConfig.execute()(component, simulatedEvent, focused);
3987
      });
3988
    };
3989
    var toMatrix = function (rows, matrixConfig) {
3990
      return map$1(rows, function (row) {
3991
        return descendants$1(row, matrixConfig.selectors().cell());
3992
      });
3993
    };
3994
    var doMove$2 = function (ifCycle, ifMove) {
3995
      return function (element, focused, matrixConfig) {
3996
        var move$$1 = matrixConfig.cycles() ? ifCycle : ifMove;
3997
        return closest$2(focused, matrixConfig.selectors().row()).bind(function (inRow) {
3998
          var cellsInRow = descendants$1(inRow, matrixConfig.selectors().cell());
3999
          return findIndex$2(cellsInRow, focused).bind(function (colIndex) {
4000
            var allRows = descendants$1(element, matrixConfig.selectors().row());
4001
            return findIndex$2(allRows, inRow).bind(function (rowIndex) {
4002
              var matrix = toMatrix(allRows, matrixConfig);
4003
              return move$$1(matrix, rowIndex, colIndex).map(function (next) {
4004
                return next.cell();
4005
              });
4006
            });
4007
          });
4008
        });
4009
      };
4010
    };
4011
    var moveLeft$3 = doMove$2(cycleLeft$1, moveLeft$2);
4012
    var moveRight$3 = doMove$2(cycleRight$1, moveRight$2);
4013
    var moveNorth$1 = doMove$2(cycleUp$1, moveUp);
4014
    var moveSouth$1 = doMove$2(cycleDown$1, moveDown);
4015
    var getRules$3 = constant([
4016
      rule(inSet(LEFT()), west(moveLeft$3, moveRight$3)),
4017
      rule(inSet(RIGHT()), east(moveLeft$3, moveRight$3)),
4018
      rule(inSet(UP()), north(moveNorth$1)),
4019
      rule(inSet(DOWN()), south(moveSouth$1)),
4020
      rule(inSet(SPACE().concat(ENTER())), execute$4)
4021
    ]);
4022
    var getEvents$3 = constant({});
4023
    var getApis$3 = constant({});
4024
    var MatrixType = typical(schema$4, NoState.init, getRules$3, getEvents$3, getApis$3, Option.some(focusIn$2));
4025
4026
    var schema$5 = [
4027
      strict$1('selector'),
4028
      defaulted$1('execute', defaultExecute),
4029
      defaulted$1('moveOnTab', false)
4030
    ];
4031
    var execute$5 = function (component, simulatedEvent, menuConfig) {
4032
      return menuConfig.focusManager().get(component).bind(function (focused) {
4033
        return menuConfig.execute()(component, simulatedEvent, focused);
4034
      });
4035
    };
4036
    var focusIn$3 = function (component, menuConfig) {
4037
      descendant$2(component.element(), menuConfig.selector()).each(function (first) {
4038
        menuConfig.focusManager().set(component, first);
4039
      });
4040
    };
4041
    var moveUp$1 = function (element, focused, info) {
4042
      return horizontal(element, info.selector(), focused, -1);
4043
    };
4044
    var moveDown$1 = function (element, focused, info) {
4045
      return horizontal(element, info.selector(), focused, +1);
4046
    };
4047
    var fireShiftTab = function (component, simulatedEvent, menuConfig) {
4048
      return menuConfig.moveOnTab() ? move(moveUp$1)(component, simulatedEvent, menuConfig) : Option.none();
4049
    };
4050
    var fireTab = function (component, simulatedEvent, menuConfig) {
4051
      return menuConfig.moveOnTab() ? move(moveDown$1)(component, simulatedEvent, menuConfig) : Option.none();
4052
    };
4053
    var getRules$4 = constant([
4054
      rule(inSet(UP()), move(moveUp$1)),
4055
      rule(inSet(DOWN()), move(moveDown$1)),
4056
      rule(and([
4057
        isShift,
4058
        inSet(TAB())
4059
      ]), fireShiftTab),
4060
      rule(and([
4061
        isNotShift,
4062
        inSet(TAB())
4063
      ]), fireTab),
4064
      rule(inSet(ENTER()), execute$5),
4065
      rule(inSet(SPACE()), execute$5)
4066
    ]);
4067
    var getEvents$4 = constant({});
4068
    var getApis$4 = constant({});
4069
    var MenuType = typical(schema$5, NoState.init, getRules$4, getEvents$4, getApis$4, Option.some(focusIn$3));
4070
4071
    var schema$6 = [
4072
      onKeyboardHandler('onSpace'),
4073
      onKeyboardHandler('onEnter'),
4074
      onKeyboardHandler('onShiftEnter'),
4075
      onKeyboardHandler('onLeft'),
4076
      onKeyboardHandler('onRight'),
4077
      onKeyboardHandler('onTab'),
4078
      onKeyboardHandler('onShiftTab'),
4079
      onKeyboardHandler('onUp'),
4080
      onKeyboardHandler('onDown'),
4081
      onKeyboardHandler('onEscape'),
4082
      option('focusIn')
4083
    ];
4084
    var getRules$5 = function (component, simulatedEvent, specialInfo) {
4085
      return [
4086
        rule(inSet(SPACE()), specialInfo.onSpace()),
4087
        rule(and([
4088
          isNotShift,
4089
          inSet(ENTER())
4090
        ]), specialInfo.onEnter()),
4091
        rule(and([
4092
          isShift,
4093
          inSet(ENTER())
4094
        ]), specialInfo.onShiftEnter()),
4095
        rule(and([
4096
          isShift,
4097
          inSet(TAB())
4098
        ]), specialInfo.onShiftTab()),
4099
        rule(and([
4100
          isNotShift,
4101
          inSet(TAB())
4102
        ]), specialInfo.onTab()),
4103
        rule(inSet(UP()), specialInfo.onUp()),
4104
        rule(inSet(DOWN()), specialInfo.onDown()),
4105
        rule(inSet(LEFT()), specialInfo.onLeft()),
4106
        rule(inSet(RIGHT()), specialInfo.onRight()),
4107
        rule(inSet(SPACE()), specialInfo.onSpace()),
4108
        rule(inSet(ESCAPE()), specialInfo.onEscape())
4109
      ];
4110
    };
4111
    var focusIn$4 = function (component, specialInfo) {
4112
      return specialInfo.focusIn().bind(function (f) {
4113
        return f(component, specialInfo);
4114
      });
4115
    };
4116
    var getEvents$5 = function () {
4117
      return {};
4118
    };
4119
    var getApis$5 = function () {
4120
      return {};
4121
    };
4122
    var SpecialType = typical(schema$6, NoState.init, getRules$5, getEvents$5, getApis$5, Option.some(focusIn$4));
4123
4124
    var acyclic = AcyclicType.schema();
4125
    var cyclic = CyclicType.schema();
4126
    var flow = FlowType.schema();
4127
    var flatgrid$1 = FlatgridType.schema();
4128
    var matrix = MatrixType.schema();
4129
    var execution = ExecutionType.schema();
4130
    var menu = MenuType.schema();
4131
    var special = SpecialType.schema();
4132
4133
    var KeyboardBranches = /*#__PURE__*/Object.freeze({
4134
        acyclic: acyclic,
4135
        cyclic: cyclic,
4136
        flow: flow,
4137
        flatgrid: flatgrid$1,
4138
        matrix: matrix,
4139
        execution: execution,
4140
        menu: menu,
4141
        special: special
4142
    });
4143
4144
    var Keying = createModes$1({
4145
      branchKey: 'mode',
4146
      branches: KeyboardBranches,
4147
      name: 'keying',
4148
      active: {
4149
        events: function (keyingConfig, keyingState) {
4150
          var handler = keyingConfig.handler();
4151
          return handler.toEvents(keyingConfig, keyingState);
4152
        }
4153
      },
4154
      apis: {
4155
        focusIn: function (component) {
4156
          component.getSystem().triggerFocus(component.element(), component.element());
4157
        },
4158
        setGridSize: function (component, keyConfig, keyState, numRows, numColumns) {
4159
          if (!hasKey$1(keyState, 'setGridSize')) {
4160
            console.error('Layout does not support setGridSize');
4161
          } else {
4162
            keyState.setGridSize(numRows, numColumns);
4163
          }
4164
        }
4165
      },
4166
      state: KeyingState
4167
    });
4168
4169
    var field$1 = function (name, forbidden) {
4170
      return defaultedObjOf(name, {}, map$1(forbidden, function (f) {
4171
        return forbid(f.name(), 'Cannot configure ' + f.name() + ' for ' + name);
4172
      }).concat([state$1('dump', identity)]));
4173
    };
4174
    var get$6 = function (data) {
4175
      return data.dump();
4176
    };
4177
4178
    var _placeholder = 'placeholder';
4179
    var adt$2 = Adt.generate([
4180
      {
4181
        single: [
4182
          'required',
4183
          'valueThunk'
4184
        ]
4185
      },
4186
      {
4187
        multiple: [
4188
          'required',
4189
          'valueThunks'
4190
        ]
4191
      }
4192
    ]);
4193
    var subPlaceholder = function (owner, detail, compSpec, placeholders) {
4194
      if (owner.exists(function (o) {
4195
          return o !== compSpec.owner;
4196
        })) {
4197
        return adt$2.single(true, constant(compSpec));
4198
      }
4199
      return readOptFrom$1(placeholders, compSpec.name).fold(function () {
4200
        throw new Error('Unknown placeholder component: ' + compSpec.name + '\nKnown: [' + keys(placeholders) + ']\nNamespace: ' + owner.getOr('none') + '\nSpec: ' + Json.stringify(compSpec, null, 2));
4201
      }, function (newSpec) {
4202
        return newSpec.replace();
4203
      });
4204
    };
4205
    var scan = function (owner, detail, compSpec, placeholders) {
4206
      if (compSpec.uiType === _placeholder) {
4207
        return subPlaceholder(owner, detail, compSpec, placeholders);
4208
      } else {
4209
        return adt$2.single(false, constant(compSpec));
4210
      }
4211
    };
4212
    var substitute = function (owner, detail, compSpec, placeholders) {
4213
      var base = scan(owner, detail, compSpec, placeholders);
4214
      return base.fold(function (req, valueThunk) {
4215
        var value = valueThunk(detail, compSpec.config, compSpec.validated);
4216
        var childSpecs = readOptFrom$1(value, 'components').getOr([]);
4217
        var substituted = bind(childSpecs, function (c) {
4218
          return substitute(owner, detail, c, placeholders);
4219
        });
4220
        return [deepMerge(value, { components: substituted })];
4221
      }, function (req, valuesThunk) {
4222
        var values$$1 = valuesThunk(detail, compSpec.config, compSpec.validated);
4223
        return values$$1;
4224
      });
4225
    };
4226
    var substituteAll = function (owner, detail, components, placeholders) {
4227
      return bind(components, function (c) {
4228
        return substitute(owner, detail, c, placeholders);
4229
      });
4230
    };
4231
    var oneReplace = function (label, replacements) {
4232
      var called = false;
4233
      var used = function () {
4234
        return called;
4235
      };
4236
      var replace = function () {
4237
        if (called === true) {
4238
          throw new Error('Trying to use the same placeholder more than once: ' + label);
4239
        }
4240
        called = true;
4241
        return replacements;
4242
      };
4243
      var required = function () {
4244
        return replacements.fold(function (req, _) {
4245
          return req;
4246
        }, function (req, _) {
4247
          return req;
4248
        });
4249
      };
4250
      return {
4251
        name: constant(label),
4252
        required: required,
4253
        used: used,
4254
        replace: replace
4255
      };
4256
    };
4257
    var substitutePlaces = function (owner, detail, components, placeholders) {
4258
      var ps = map(placeholders, function (ph, name) {
4259
        return oneReplace(name, ph);
4260
      });
4261
      var outcome = substituteAll(owner, detail, components, ps);
4262
      each(ps, function (p) {
4263
        if (p.used() === false && p.required()) {
4264
          throw new Error('Placeholder: ' + p.name() + ' was not found in components list\nNamespace: ' + owner.getOr('none') + '\nComponents: ' + Json.stringify(detail.components(), null, 2));
4265
        }
4266
      });
4267
      return outcome;
4268
    };
4269
    var single = adt$2.single;
4270
    var multiple = adt$2.multiple;
4271
    var placeholder = constant(_placeholder);
4272
4273
    var unique = 0;
4274
    var generate$1 = function (prefix) {
4275
      var date = new Date();
4276
      var time = date.getTime();
4277
      var random = Math.floor(Math.random() * 1000000000);
4278
      unique++;
4279
      return prefix + '_' + random + unique + String(time);
4280
    };
4281
4282
    var adt$3 = Adt.generate([
4283
      { required: ['data'] },
4284
      { external: ['data'] },
4285
      { optional: ['data'] },
4286
      { group: ['data'] }
4287
    ]);
4288
    var fFactory = defaulted$1('factory', { sketch: identity });
4289
    var fSchema = defaulted$1('schema', []);
4290
    var fName = strict$1('name');
4291
    var fPname = field('pname', 'pname', defaultedThunk(function (typeSpec) {
4292
      return '<alloy.' + generate$1(typeSpec.name) + '>';
4293
    }), anyValue$1());
4294
    var fDefaults = defaulted$1('defaults', constant({}));
4295
    var fOverrides = defaulted$1('overrides', constant({}));
4296
    var requiredSpec = objOf([
4297
      fFactory,
4298
      fSchema,
4299
      fName,
4300
      fPname,
4301
      fDefaults,
4302
      fOverrides
4303
    ]);
4304
    var optionalSpec = objOf([
4305
      fFactory,
4306
      fSchema,
4307
      fName,
4308
      fPname,
4309
      fDefaults,
4310
      fOverrides
4311
    ]);
4312
    var groupSpec = objOf([
4313
      fFactory,
4314
      fSchema,
4315
      fName,
4316
      strict$1('unit'),
4317
      fPname,
4318
      fDefaults,
4319
      fOverrides
4320
    ]);
4321
    var asNamedPart = function (part) {
4322
      return part.fold(Option.some, Option.none, Option.some, Option.some);
4323
    };
4324
    var name$1 = function (part) {
4325
      var get = function (data) {
4326
        return data.name();
4327
      };
4328
      return part.fold(get, get, get, get);
4329
    };
4330
    var convert = function (adtConstructor, partSchema) {
4331
      return function (spec) {
4332
        var data = asStructOrDie('Converting part type', partSchema, spec);
4333
        return adtConstructor(data);
4334
      };
4335
    };
4336
    var required = convert(adt$3.required, requiredSpec);
4337
    var optional = convert(adt$3.optional, optionalSpec);
4338
    var group = convert(adt$3.group, groupSpec);
4339
    var original = constant('entirety');
4340
4341
    var combine = function (detail, data, partSpec, partValidated) {
4342
      var spec = partSpec;
4343
      return deepMerge(data.defaults()(detail, partSpec, partValidated), partSpec, { uid: detail.partUids()[data.name()] }, data.overrides()(detail, partSpec, partValidated), { 'debug.sketcher': wrap$2('part-' + data.name(), spec) });
4344
    };
4345
    var subs = function (owner, detail, parts) {
4346
      var internals = {};
4347
      var externals = {};
4348
      each$1(parts, function (part) {
4349
        part.fold(function (data) {
4350
          internals[data.pname()] = single(true, function (detail, partSpec, partValidated) {
4351
            return data.factory().sketch(combine(detail, data, partSpec, partValidated));
4352
          });
4353
        }, function (data) {
4354
          var partSpec = detail.parts()[data.name()]();
4355
          externals[data.name()] = constant(combine(detail, data, partSpec[original()]()));
4356
        }, function (data) {
4357
          internals[data.pname()] = single(false, function (detail, partSpec, partValidated) {
4358
            return data.factory().sketch(combine(detail, data, partSpec, partValidated));
4359
          });
4360
        }, function (data) {
4361
          internals[data.pname()] = multiple(true, function (detail, _partSpec, _partValidated) {
4362
            var units = detail[data.name()]();
4363
            return map$1(units, function (u) {
4364
              return data.factory().sketch(deepMerge(data.defaults()(detail, u), u, data.overrides()(detail, u)));
4365
            });
4366
          });
4367
        });
4368
      });
4369
      return {
4370
        internals: constant(internals),
4371
        externals: constant(externals)
4372
      };
4373
    };
4374
4375
    var generate$2 = function (owner, parts) {
4376
      var r = {};
4377
      each$1(parts, function (part) {
4378
        asNamedPart(part).each(function (np) {
4379
          var g = doGenerateOne(owner, np.pname());
4380
          r[np.name()] = function (config) {
4381
            var validated = asRawOrDie('Part: ' + np.name() + ' in ' + owner, objOf(np.schema()), config);
4382
            return deepMerge(g, {
4383
              config: config,
4384
              validated: validated
4385
            });
4386
          };
4387
        });
4388
      });
4389
      return r;
4390
    };
4391
    var doGenerateOne = function (owner, pname) {
4392
      return {
4393
        uiType: placeholder(),
4394
        owner: owner,
4395
        name: pname
4396
      };
4397
    };
4398
    var generateOne = function (owner, pname, config) {
4399
      return {
4400
        uiType: placeholder(),
4401
        owner: owner,
4402
        name: pname,
4403
        config: config,
4404
        validated: {}
4405
      };
4406
    };
4407
    var schemas = function (parts) {
4408
      return bind(parts, function (part) {
4409
        return part.fold(Option.none, Option.some, Option.none, Option.none).map(function (data) {
4410
          return strictObjOf(data.name(), data.schema().concat([snapshot$1(original())]));
4411
        }).toArray();
4412
      });
4413
    };
4414
    var names = function (parts) {
4415
      return map$1(parts, name$1);
4416
    };
4417
    var substitutes = function (owner, detail, parts) {
4418
      return subs(owner, detail, parts);
4419
    };
4420
    var components = function (owner, detail, internals) {
4421
      return substitutePlaces(Option.some(owner), detail, detail.components(), internals);
4422
    };
4423
    var getPart = function (component, detail, partKey) {
4424
      var uid = detail.partUids()[partKey];
4425
      return component.getSystem().getByUid(uid).toOption();
4426
    };
4427
    var getPartOrDie = function (component, detail, partKey) {
4428
      return getPart(component, detail, partKey).getOrDie('Could not find part: ' + partKey);
4429
    };
4430
    var getAllParts = function (component, detail) {
4431
      var system = component.getSystem();
4432
      return map(detail.partUids(), function (pUid, k) {
4433
        return constant(system.getByUid(pUid));
4434
      });
4435
    };
4436
    var defaultUids = function (baseUid, partTypes) {
4437
      var partNames = names(partTypes);
4438
      return wrapAll$1(map$1(partNames, function (pn) {
4439
        return {
4440
          key: pn,
4441
          value: baseUid + '-' + pn
4442
        };
4443
      }));
4444
    };
4445
    var defaultUidsSchema = function (partTypes) {
4446
      return field('partUids', 'partUids', mergeWithThunk(function (spec) {
4447
        return defaultUids(spec.uid, partTypes);
4448
      }), anyValue$1());
4449
    };
4450
4451
    var premadeTag = generate$1('alloy-premade');
4452
    var _apiConfig = generate$1('api');
4453
    var premade = function (comp) {
4454
      return wrap$2(premadeTag, comp);
4455
    };
4456
    var getPremade = function (spec) {
4457
      return readOptFrom$1(spec, premadeTag);
4458
    };
4459
    var makeApi = function (f) {
4460
      return markAsSketchApi(function (component) {
4461
        var rest = [];
4462
        for (var _i = 1; _i < arguments.length; _i++) {
4463
          rest[_i - 1] = arguments[_i];
4464
        }
4465
        var spi = component.config(_apiConfig);
4466
        return f.apply(undefined, [spi].concat([component].concat(rest)));
4467
      }, f);
4468
    };
4469
    var apiConfig = constant(_apiConfig);
4470
4471
    var prefix$1 = constant('alloy-id-');
4472
    var idAttr = constant('data-alloy-id');
4473
4474
    var prefix$2 = prefix$1();
4475
    var idAttr$1 = idAttr();
4476
    var write = function (label, elem) {
4477
      var id = generate$1(prefix$2 + label);
4478
      set(elem, idAttr$1, id);
4479
      return id;
4480
    };
4481
    var writeOnly = function (elem, uid) {
4482
      set(elem, idAttr$1, uid);
4483
    };
4484
    var read$2 = function (elem) {
4485
      var id = isElement(elem) ? get$1(elem, idAttr$1) : null;
4486
      return Option.from(id);
4487
    };
4488
    var generate$3 = function (prefix) {
4489
      return generate$1(prefix);
4490
    };
4491
4492
    var base$1 = function (label, partSchemas, partUidsSchemas, spec) {
4493
      var ps = partSchemas.length > 0 ? [strictObjOf('parts', partSchemas)] : [];
4494
      return ps.concat([
4495
        strict$1('uid'),
4496
        defaulted$1('dom', {}),
4497
        defaulted$1('components', []),
4498
        snapshot$1('originalSpec'),
4499
        defaulted$1('debug.sketcher', {})
4500
      ]).concat(partUidsSchemas);
4501
    };
4502
    var asStructOrDie$1 = function (label, schema, spec, partSchemas, partUidsSchemas) {
4503
      var baseS = base$1(label, partSchemas, partUidsSchemas, spec);
4504
      return asStructOrDie(label + ' [SpecSchema]', objOfOnly(baseS.concat(schema)), spec);
4505
    };
4506
4507
    var single$1 = function (owner, schema, factory, spec) {
4508
      var specWithUid = supplyUid(spec);
4509
      var detail = asStructOrDie$1(owner, schema, specWithUid, [], []);
4510
      return deepMerge(factory(detail, specWithUid), { 'debug.sketcher': wrap$2(owner, spec) });
4511
    };
4512
    var composite = function (owner, schema, partTypes, factory, spec) {
4513
      var specWithUid = supplyUid(spec);
4514
      var partSchemas = schemas(partTypes);
4515
      var partUidsSchema = defaultUidsSchema(partTypes);
4516
      var detail = asStructOrDie$1(owner, schema, specWithUid, partSchemas, [partUidsSchema]);
4517
      var subs = substitutes(owner, detail, partTypes);
4518
      var components$$1 = components(owner, detail, subs.internals());
4519
      return deepMerge(factory(detail, components$$1, specWithUid, subs.externals()), { 'debug.sketcher': wrap$2(owner, spec) });
4520
    };
4521
    var supplyUid = function (spec) {
4522
      return deepMerge({ uid: generate$3('uid') }, spec);
4523
    };
4524
4525
    function isSketchSpec(spec) {
4526
      return spec.uid !== undefined;
4527
    }
4528
    var singleSchema = objOfOnly([
4529
      strict$1('name'),
4530
      strict$1('factory'),
4531
      strict$1('configFields'),
4532
      defaulted$1('apis', {}),
4533
      defaulted$1('extraApis', {})
4534
    ]);
4535
    var compositeSchema = objOfOnly([
4536
      strict$1('name'),
4537
      strict$1('factory'),
4538
      strict$1('configFields'),
4539
      strict$1('partFields'),
4540
      defaulted$1('apis', {}),
4541
      defaulted$1('extraApis', {})
4542
    ]);
4543
    var single$2 = function (rawConfig) {
4544
      var config = asRawOrDie('Sketcher for ' + rawConfig.name, singleSchema, rawConfig);
4545
      var sketch = function (spec) {
4546
        return single$1(config.name, config.configFields, config.factory, spec);
4547
      };
4548
      var apis = map(config.apis, makeApi);
4549
      var extraApis = map(config.extraApis, function (f, k) {
4550
        return markAsExtraApi(f, k);
4551
      });
4552
      return deepMerge({
4553
        name: constant(config.name),
4554
        partFields: constant([]),
4555
        configFields: constant(config.configFields),
4556
        sketch: sketch
4557
      }, apis, extraApis);
4558
    };
4559
    var composite$1 = function (rawConfig) {
4560
      var config = asRawOrDie('Sketcher for ' + rawConfig.name, compositeSchema, rawConfig);
4561
      var sketch = function (spec) {
4562
        return composite(config.name, config.configFields, config.partFields, config.factory, spec);
4563
      };
4564
      var parts = generate$2(config.name, config.partFields);
4565
      var apis = map(config.apis, makeApi);
4566
      var extraApis = map(config.extraApis, function (f, k) {
4567
        return markAsExtraApi(f, k);
4568
      });
4569
      return deepMerge({
4570
        name: constant(config.name),
4571
        partFields: constant(config.partFields),
4572
        configFields: constant(config.configFields),
4573
        sketch: sketch,
4574
        parts: constant(parts)
4575
      }, apis, extraApis);
4576
    };
4577
4578
    var factory = function (detail) {
4579
      var events = events$2(detail.action());
4580
      var optType = readOptFrom$1(detail.dom(), 'attributes').bind(readOpt$1('type'));
4581
      var optTag = readOptFrom$1(detail.dom(), 'tag');
4582
      return {
4583
        uid: detail.uid(),
4584
        dom: detail.dom(),
4585
        components: detail.components(),
4586
        events: events,
4587
        behaviours: deepMerge(derive$2([
4588
          Focusing.config({}),
4589
          Keying.config({
4590
            mode: 'execution',
4591
            useSpace: true,
4592
            useEnter: true
4593
          })
4594
        ]), get$6(detail.buttonBehaviours())),
4595
        domModification: {
4596
          attributes: deepMerge(optType.fold(function () {
4597
            return optTag.is('button') ? { type: 'button' } : {};
4598
          }, function (t) {
4599
            return {};
4600
          }), { role: detail.role().getOr('button') })
4601
        },
4602
        eventOrder: detail.eventOrder()
4603
      };
4604
    };
4605
    var Button = single$2({
4606
      name: 'Button',
4607
      factory: factory,
4608
      configFields: [
4609
        defaulted$1('uid', undefined),
4610
        strict$1('dom'),
4611
        defaulted$1('components', []),
4612
        field$1('buttonBehaviours', [
4613
          Focusing,
4614
          Keying
4615
        ]),
4616
        option('action'),
4617
        option('role'),
4618
        defaulted$1('eventOrder', {})
4619
      ]
4620
    });
4621
4622
    var exhibit$2 = function (base, unselectConfig) {
4623
      return nu$6({
4624
        styles: {
4625
          '-webkit-user-select': 'none',
4626
          'user-select': 'none',
4627
          '-ms-user-select': 'none',
4628
          '-moz-user-select': '-moz-none'
4629
        },
4630
        attributes: { unselectable: 'on' }
4631
      });
4632
    };
4633
    var events$4 = function (unselectConfig) {
4634
      return derive([abort(selectstart(), constant(true))]);
4635
    };
4636
4637
    var ActiveUnselecting = /*#__PURE__*/Object.freeze({
4638
        events: events$4,
4639
        exhibit: exhibit$2
4640
    });
4641
4642
    var Unselecting = create$1({
4643
      fields: [],
4644
      name: 'unselecting',
4645
      active: ActiveUnselecting
4646
    });
4647
4648
    var getAttrs = function (elem) {
4649
      var attributes = elem.dom().attributes !== undefined ? elem.dom().attributes : [];
4650
      return foldl(attributes, function (b, attr) {
4651
        if (attr.name === 'class') {
4652
          return b;
4653
        } else {
4654
          return deepMerge(b, wrap$2(attr.name, attr.value));
4655
        }
4656
      }, {});
4657
    };
4658
    var getClasses = function (elem) {
4659
      return Array.prototype.slice.call(elem.dom().classList, 0);
4660
    };
4661
    var fromHtml$2 = function (html) {
4662
      var elem = Element$$1.fromHtml(html);
4663
      var children$$1 = children(elem);
4664
      var attrs = getAttrs(elem);
4665
      var classes = getClasses(elem);
4666
      var contents = children$$1.length === 0 ? {} : { innerHtml: get$3(elem) };
4667
      return deepMerge({
4668
        tag: name(elem),
4669
        classes: classes,
4670
        attributes: attrs
4671
      }, contents);
4672
    };
4673
4674
    var dom$1 = function (rawHtml) {
4675
      var html = supplant(rawHtml, { prefix: Styles.prefix() });
4676
      return fromHtml$2(html);
4677
    };
4678
    var spec = function (rawHtml) {
4679
      var sDom = dom$1(rawHtml);
4680
      return { dom: sDom };
4681
    };
4682
4683
    var forToolbarCommand = function (editor, command) {
4684
      return forToolbar(command, function () {
4685
        editor.execCommand(command);
4686
      }, {});
4687
    };
4688
    var getToggleBehaviours = function (command) {
4689
      return derive$2([
4690
        Toggling.config({
4691
          toggleClass: Styles.resolve('toolbar-button-selected'),
4692
          toggleOnExecute: false,
4693
          aria: { mode: 'pressed' }
4694
        }),
4695
        Receivers.format(command, function (button, status) {
4696
          var toggle = status ? Toggling.on : Toggling.off;
4697
          toggle(button);
4698
        })
4699
      ]);
4700
    };
4701
    var forToolbarStateCommand = function (editor, command) {
4702
      var extraBehaviours = getToggleBehaviours(command);
4703
      return forToolbar(command, function () {
4704
        editor.execCommand(command);
4705
      }, extraBehaviours);
4706
    };
4707
    var forToolbarStateAction = function (editor, clazz, command, action) {
4708
      var extraBehaviours = getToggleBehaviours(command);
4709
      return forToolbar(clazz, action, extraBehaviours);
4710
    };
4711
    var forToolbar = function (clazz, action, extraBehaviours) {
4712
      return Button.sketch({
4713
        dom: dom$1('<span class="${prefix}-toolbar-button ${prefix}-icon-' + clazz + ' ${prefix}-icon"></span>'),
4714
        action: action,
4715
        buttonBehaviours: deepMerge(derive$2([Unselecting.config({})]), extraBehaviours)
4716
      });
4717
    };
4718
    var Buttons = {
4719
      forToolbar: forToolbar,
4720
      forToolbarCommand: forToolbarCommand,
4721
      forToolbarStateAction: forToolbarStateAction,
4722
      forToolbarStateCommand: forToolbarStateCommand
4723
    };
4724
4725
    var r = function (left, top) {
4726
      var translate = function (x, y) {
4727
        return r(left + x, top + y);
4728
      };
4729
      return {
4730
        left: constant(left),
4731
        top: constant(top),
4732
        translate: translate
4733
      };
4734
    };
4735
    var Position = r;
4736
4737
    var reduceBy = function (value, min, max, step) {
4738
      if (value < min) {
4739
        return value;
4740
      } else if (value > max) {
4741
        return max;
4742
      } else if (value === min) {
4743
        return min - 1;
4744
      } else {
4745
        return Math.max(min, value - step);
4746
      }
4747
    };
4748
    var increaseBy = function (value, min, max, step) {
4749
      if (value > max) {
4750
        return value;
4751
      } else if (value < min) {
4752
        return min;
4753
      } else if (value === max) {
4754
        return max + 1;
4755
      } else {
4756
        return Math.min(max, value + step);
4757
      }
4758
    };
4759
    var capValue = function (value, min, max) {
4760
      return Math.max(min, Math.min(max, value));
4761
    };
4762
    var snapValueOfX = function (bounds, value, min, max, step, snapStart) {
4763
      return snapStart.fold(function () {
4764
        var initValue = value - min;
4765
        var extraValue = Math.round(initValue / step) * step;
4766
        return capValue(min + extraValue, min - 1, max + 1);
4767
      }, function (start) {
4768
        var remainder = (value - start) % step;
4769
        var adjustment = Math.round(remainder / step);
4770
        var rawSteps = Math.floor((value - start) / step);
4771
        var maxSteps = Math.floor((max - start) / step);
4772
        var numSteps = Math.min(maxSteps, rawSteps + adjustment);
4773
        var r = start + numSteps * step;
4774
        return Math.max(start, r);
4775
      });
4776
    };
4777
    var findValueOfX = function (bounds, min, max, xValue, step, snapToGrid, snapStart) {
4778
      var range = max - min;
4779
      if (xValue < bounds.left) {
4780
        return min - 1;
4781
      } else if (xValue > bounds.right) {
4782
        return max + 1;
4783
      } else {
4784
        var xOffset = Math.min(bounds.right, Math.max(xValue, bounds.left)) - bounds.left;
4785
        var newValue = capValue(xOffset / bounds.width * range + min, min - 1, max + 1);
4786
        var roundedValue = Math.round(newValue);
4787
        return snapToGrid && newValue >= min && newValue <= max ? snapValueOfX(bounds, newValue, min, max, step, snapStart) : roundedValue;
4788
      }
4789
    };
4790
4791
    var _changeEvent = 'slider.change.value';
4792
    var isTouch = PlatformDetection$1.detect().deviceType.isTouch();
4793
    var getEventSource = function (simulatedEvent) {
4794
      var evt = simulatedEvent.event().raw();
4795
      if (isTouch) {
4796
        var touchEvent = evt;
4797
        return touchEvent.touches !== undefined && touchEvent.touches.length === 1 ? Option.some(touchEvent.touches[0]).map(function (t) {
4798
          return Position(t.clientX, t.clientY);
4799
        }) : Option.none();
4800
      } else {
4801
        var mouseEvent = evt;
4802
        return mouseEvent.clientX !== undefined ? Option.some(mouseEvent).map(function (me) {
4803
          return Position(me.clientX, me.clientY);
4804
        }) : Option.none();
4805
      }
4806
    };
4807
    var getEventX = function (simulatedEvent) {
4808
      var spot = getEventSource(simulatedEvent);
4809
      return spot.map(function (s) {
4810
        return s.left();
4811
      });
4812
    };
4813
    var fireChange = function (component, value) {
4814
      emitWith(component, _changeEvent, { value: value });
4815
    };
4816
    var setToRedge = function (redge, detail) {
4817
      fireChange(redge, detail.max() + 1);
4818
    };
4819
    var setToLedge = function (ledge, detail) {
4820
      fireChange(ledge, detail.min() - 1);
4821
    };
4822
    var setToX = function (spectrum, spectrumBounds, detail, xValue) {
4823
      var value = findValueOfX(spectrumBounds, detail.min(), detail.max(), xValue, detail.stepSize(), detail.snapToGrid(), detail.snapStart());
4824
      fireChange(spectrum, value);
4825
    };
4826
    var setXFromEvent = function (spectrum, detail, spectrumBounds, simulatedEvent) {
4827
      return getEventX(simulatedEvent).map(function (xValue) {
4828
        setToX(spectrum, spectrumBounds, detail, xValue);
4829
        return xValue;
4830
      });
4831
    };
4832
    var moveLeft$4 = function (spectrum, detail) {
4833
      var newValue = reduceBy(detail.value().get(), detail.min(), detail.max(), detail.stepSize());
4834
      fireChange(spectrum, newValue);
4835
    };
4836
    var moveRight$4 = function (spectrum, detail) {
4837
      var newValue = increaseBy(detail.value().get(), detail.min(), detail.max(), detail.stepSize());
4838
      fireChange(spectrum, newValue);
4839
    };
4840
    var changeEvent = function () {
4841
      return _changeEvent;
4842
    };
4843
4844
    var platform = PlatformDetection$1.detect();
4845
    var isTouch$1 = platform.deviceType.isTouch();
4846
    var edgePart = function (name, action) {
4847
      return optional({
4848
        name: '' + name + '-edge',
4849
        overrides: function (detail) {
4850
          var touchEvents = derive([runActionExtra(touchstart(), action, [detail])]);
4851
          var mouseEvents = derive([
4852
            runActionExtra(mousedown(), action, [detail]),
4853
            runActionExtra(mousemove(), function (l, det) {
4854
              if (det.mouseIsDown().get()) {
4855
                action(l, det);
4856
              }
4857
            }, [detail])
4858
          ]);
4859
          return { events: isTouch$1 ? touchEvents : mouseEvents };
4860
        }
4861
      });
4862
    };
4863
    var ledgePart = edgePart('left', setToLedge);
4864
    var redgePart = edgePart('right', setToRedge);
4865
    var thumbPart = required({
4866
      name: 'thumb',
4867
      defaults: constant({ dom: { styles: { position: 'absolute' } } }),
4868
      overrides: function (detail) {
4869
        return {
4870
          events: derive([
4871
            redirectToPart(touchstart(), detail, 'spectrum'),
4872
            redirectToPart(touchmove(), detail, 'spectrum'),
4873
            redirectToPart(touchend(), detail, 'spectrum')
4874
          ])
4875
        };
4876
      }
4877
    });
4878
    var spectrumPart = required({
4879
      schema: [state$1('mouseIsDown', function () {
4880
          return Cell(false);
4881
        })],
4882
      name: 'spectrum',
4883
      overrides: function (detail) {
4884
        var moveToX = function (spectrum, simulatedEvent) {
4885
          var domElem = spectrum.element().dom();
4886
          var spectrumBounds = domElem.getBoundingClientRect();
4887
          setXFromEvent(spectrum, detail, spectrumBounds, simulatedEvent);
4888
        };
4889
        var touchEvents = derive([
4890
          run(touchstart(), moveToX),
4891
          run(touchmove(), moveToX)
4892
        ]);
4893
        var mouseEvents = derive([
4894
          run(mousedown(), moveToX),
4895
          run(mousemove(), function (spectrum, se) {
4896
            if (detail.mouseIsDown().get()) {
4897
              moveToX(spectrum, se);
4898
            }
4899
          })
4900
        ]);
4901
        return {
4902
          behaviours: derive$2(isTouch$1 ? [] : [
4903
            Keying.config({
4904
              mode: 'special',
4905
              onLeft: function (spectrum) {
4906
                moveLeft$4(spectrum, detail);
4907
                return Option.some(true);
4908
              },
4909
              onRight: function (spectrum) {
4910
                moveRight$4(spectrum, detail);
4911
                return Option.some(true);
4912
              }
4913
            }),
4914
            Focusing.config({})
4915
          ]),
4916
          events: isTouch$1 ? touchEvents : mouseEvents
4917
        };
4918
      }
4919
    });
4920
    var SliderParts = [
4921
      ledgePart,
4922
      redgePart,
4923
      thumbPart,
4924
      spectrumPart
4925
    ];
4926
4927
    var onLoad$1 = function (component, repConfig, repState) {
4928
      repConfig.store().manager().onLoad(component, repConfig, repState);
4929
    };
4930
    var onUnload = function (component, repConfig, repState) {
4931
      repConfig.store().manager().onUnload(component, repConfig, repState);
4932
    };
4933
    var setValue = function (component, repConfig, repState, data) {
4934
      repConfig.store().manager().setValue(component, repConfig, repState, data);
4935
    };
4936
    var getValue = function (component, repConfig, repState) {
4937
      return repConfig.store().manager().getValue(component, repConfig, repState);
4938
    };
4939
4940
    var RepresentApis = /*#__PURE__*/Object.freeze({
4941
        onLoad: onLoad$1,
4942
        onUnload: onUnload,
4943
        setValue: setValue,
4944
        getValue: getValue
4945
    });
4946
4947
    var events$5 = function (repConfig, repState) {
4948
      var es = repConfig.resetOnDom() ? [
4949
        runOnAttached(function (comp, se) {
4950
          onLoad$1(comp, repConfig, repState);
4951
        }),
4952
        runOnDetached(function (comp, se) {
4953
          onUnload(comp, repConfig, repState);
4954
        })
4955
      ] : [loadEvent(repConfig, repState, onLoad$1)];
4956
      return derive(es);
4957
    };
4958
4959
    var ActiveRepresenting = /*#__PURE__*/Object.freeze({
4960
        events: events$5
4961
    });
4962
4963
    var memory = function () {
4964
      var data = Cell(null);
4965
      var readState = function () {
4966
        return {
4967
          mode: 'memory',
4968
          value: data.get()
4969
        };
4970
      };
4971
      var isNotSet = function () {
4972
        return data.get() === null;
4973
      };
4974
      var clear = function () {
4975
        data.set(null);
4976
      };
4977
      return nu$7({
4978
        set: data.set,
4979
        get: data.get,
4980
        isNotSet: isNotSet,
4981
        clear: clear,
4982
        readState: readState
4983
      });
4984
    };
4985
    var manual = function () {
4986
      var readState = function () {
4987
      };
4988
      return nu$7({ readState: readState });
4989
    };
4990
    var dataset = function () {
4991
      var data = Cell({});
4992
      var readState = function () {
4993
        return {
4994
          mode: 'dataset',
4995
          dataset: data.get()
4996
        };
4997
      };
4998
      return nu$7({
4999
        readState: readState,
5000
        set: data.set,
5001
        get: data.get
5002
      });
5003
    };
5004
    var init$1 = function (spec) {
5005
      return spec.store().manager().state(spec);
5006
    };
5007
5008
    var RepresentState = /*#__PURE__*/Object.freeze({
5009
        memory: memory,
5010
        dataset: dataset,
5011
        manual: manual,
5012
        init: init$1
5013
    });
5014
5015
    var setValue$1 = function (component, repConfig, repState, data) {
5016
      var dataKey = repConfig.store().getDataKey();
5017
      repState.set({});
5018
      repConfig.store().setData()(component, data);
5019
      repConfig.onSetValue()(component, data);
5020
    };
5021
    var getValue$1 = function (component, repConfig, repState) {
5022
      var key = repConfig.store().getDataKey()(component);
5023
      var dataset$$1 = repState.get();
5024
      return readOptFrom$1(dataset$$1, key).fold(function () {
5025
        return repConfig.store().getFallbackEntry()(key);
5026
      }, function (data) {
5027
        return data;
5028
      });
5029
    };
5030
    var onLoad$2 = function (component, repConfig, repState) {
5031
      repConfig.store().initialValue().each(function (data) {
5032
        setValue$1(component, repConfig, repState, data);
5033
      });
5034
    };
5035
    var onUnload$1 = function (component, repConfig, repState) {
5036
      repState.set({});
5037
    };
5038
    var DatasetStore = [
5039
      option('initialValue'),
5040
      strict$1('getFallbackEntry'),
5041
      strict$1('getDataKey'),
5042
      strict$1('setData'),
5043
      output$1('manager', {
5044
        setValue: setValue$1,
5045
        getValue: getValue$1,
5046
        onLoad: onLoad$2,
5047
        onUnload: onUnload$1,
5048
        state: dataset
5049
      })
5050
    ];
5051
5052
    var getValue$2 = function (component, repConfig, repState) {
5053
      return repConfig.store().getValue()(component);
5054
    };
5055
    var setValue$2 = function (component, repConfig, repState, data) {
5056
      repConfig.store().setValue()(component, data);
5057
      repConfig.onSetValue()(component, data);
5058
    };
5059
    var onLoad$3 = function (component, repConfig, repState) {
5060
      repConfig.store().initialValue().each(function (data) {
5061
        repConfig.store().setValue()(component, data);
5062
      });
5063
    };
5064
    var ManualStore = [
5065
      strict$1('getValue'),
5066
      defaulted$1('setValue', noop),
5067
      option('initialValue'),
5068
      output$1('manager', {
5069
        setValue: setValue$2,
5070
        getValue: getValue$2,
5071
        onLoad: onLoad$3,
5072
        onUnload: noop,
5073
        state: NoState.init
5074
      })
5075
    ];
5076
5077
    var setValue$3 = function (component, repConfig, repState, data) {
5078
      repState.set(data);
5079
      repConfig.onSetValue()(component, data);
5080
    };
5081
    var getValue$3 = function (component, repConfig, repState) {
5082
      return repState.get();
5083
    };
5084
    var onLoad$4 = function (component, repConfig, repState) {
5085
      repConfig.store().initialValue().each(function (initVal) {
5086
        if (repState.isNotSet()) {
5087
          repState.set(initVal);
5088
        }
5089
      });
5090
    };
5091
    var onUnload$2 = function (component, repConfig, repState) {
5092
      repState.clear();
5093
    };
5094
    var MemoryStore = [
5095
      option('initialValue'),
5096
      output$1('manager', {
5097
        setValue: setValue$3,
5098
        getValue: getValue$3,
5099
        onLoad: onLoad$4,
5100
        onUnload: onUnload$2,
5101
        state: memory
5102
      })
5103
    ];
5104
5105
    var RepresentSchema = [
5106
      defaultedOf('store', { mode: 'memory' }, choose$1('mode', {
5107
        memory: MemoryStore,
5108
        manual: ManualStore,
5109
        dataset: DatasetStore
5110
      })),
5111
      onHandler('onSetValue'),
5112
      defaulted$1('resetOnDom', false)
5113
    ];
5114
5115
    var Representing = create$1({
5116
      fields: RepresentSchema,
5117
      name: 'representing',
5118
      active: ActiveRepresenting,
5119
      apis: RepresentApis,
5120
      extra: {
5121
        setValueFrom: function (component, source) {
5122
          var value = Representing.getValue(source);
5123
          Representing.setValue(component, value);
5124
        }
5125
      },
5126
      state: RepresentState
5127
    });
5128
5129
    var isTouch$2 = PlatformDetection$1.detect().deviceType.isTouch();
5130
    var SliderSchema = [
5131
      strict$1('min'),
5132
      strict$1('max'),
5133
      defaulted$1('stepSize', 1),
5134
      defaulted$1('onChange', noop),
5135
      defaulted$1('onInit', noop),
5136
      defaulted$1('onDragStart', noop),
5137
      defaulted$1('onDragEnd', noop),
5138
      defaulted$1('snapToGrid', false),
5139
      option('snapStart'),
5140
      strict$1('getInitialValue'),
5141
      field$1('sliderBehaviours', [
5142
        Keying,
5143
        Representing
5144
      ]),
5145
      state$1('value', function (spec) {
5146
        return Cell(spec.min);
5147
      })
5148
    ].concat(!isTouch$2 ? [state$1('mouseIsDown', function () {
5149
        return Cell(false);
5150
      })] : []);
5151
5152
    var api$1 = Dimension('width', function (element) {
5153
      return element.dom().offsetWidth;
5154
    });
5155
    var set$4 = function (element, h) {
5156
      api$1.set(element, h);
5157
    };
5158
    var get$7 = function (element) {
5159
      return api$1.get(element);
5160
    };
5161
5162
    var isTouch$3 = PlatformDetection$1.detect().deviceType.isTouch();
5163
    var sketch$1 = function (detail, components$$1, spec, externals) {
5164
      var range$$1 = detail.max() - detail.min();
5165
      var getXCentre = function (component) {
5166
        var rect = component.element().dom().getBoundingClientRect();
5167
        return (rect.left + rect.right) / 2;
5168
      };
5169
      var getThumb = function (component) {
5170
        return getPartOrDie(component, detail, 'thumb');
5171
      };
5172
      var getXOffset = function (slider, spectrumBounds, detail) {
5173
        var v = detail.value().get();
5174
        if (v < detail.min()) {
5175
          return getPart(slider, detail, 'left-edge').fold(function () {
5176
            return 0;
5177
          }, function (ledge) {
5178
            return getXCentre(ledge) - spectrumBounds.left;
5179
          });
5180
        } else if (v > detail.max()) {
5181
          return getPart(slider, detail, 'right-edge').fold(function () {
5182
            return spectrumBounds.width;
5183
          }, function (redge) {
5184
            return getXCentre(redge) - spectrumBounds.left;
5185
          });
5186
        } else {
5187
          return (detail.value().get() - detail.min()) / range$$1 * spectrumBounds.width;
5188
        }
5189
      };
5190
      var getXPos = function (slider) {
5191
        var spectrum = getPartOrDie(slider, detail, 'spectrum');
5192
        var spectrumBounds = spectrum.element().dom().getBoundingClientRect();
5193
        var sliderBounds = slider.element().dom().getBoundingClientRect();
5194
        var xOffset = getXOffset(slider, spectrumBounds, detail);
5195
        return spectrumBounds.left - sliderBounds.left + xOffset;
5196
      };
5197
      var refresh = function (component) {
5198
        var pos = getXPos(component);
5199
        var thumb = getThumb(component);
5200
        var thumbRadius = get$7(thumb.element()) / 2;
5201
        set$2(thumb.element(), 'left', pos - thumbRadius + 'px');
5202
      };
5203
      var changeValue = function (component, newValue) {
5204
        var oldValue = detail.value().get();
5205
        var thumb = getThumb(component);
5206
        if (oldValue !== newValue || getRaw(thumb.element(), 'left').isNone()) {
5207
          detail.value().set(newValue);
5208
          refresh(component);
5209
          detail.onChange()(component, thumb, newValue);
5210
          return Option.some(true);
5211
        } else {
5212
          return Option.none();
5213
        }
5214
      };
5215
      var resetToMin = function (slider) {
5216
        changeValue(slider, detail.min());
5217
      };
5218
      var resetToMax = function (slider) {
5219
        changeValue(slider, detail.max());
5220
      };
5221
      var uiEventsArr = isTouch$3 ? [
5222
        run(touchstart(), function (slider, simulatedEvent) {
5223
          detail.onDragStart()(slider, getThumb(slider));
5224
        }),
5225
        run(touchend(), function (slider, simulatedEvent) {
5226
          detail.onDragEnd()(slider, getThumb(slider));
5227
        })
5228
      ] : [
5229
        run(mousedown(), function (slider, simulatedEvent) {
5230
          simulatedEvent.stop();
5231
          detail.onDragStart()(slider, getThumb(slider));
5232
          detail.mouseIsDown().set(true);
5233
        }),
5234
        run(mouseup(), function (slider, simulatedEvent) {
5235
          detail.onDragEnd()(slider, getThumb(slider));
5236
          detail.mouseIsDown().set(false);
5237
        })
5238
      ];
5239
      return {
5240
        uid: detail.uid(),
5241
        dom: detail.dom(),
5242
        components: components$$1,
5243
        behaviours: deepMerge(derive$2(flatten([
5244
          !isTouch$3 ? [Keying.config({
5245
              mode: 'special',
5246
              focusIn: function (slider) {
5247
                return getPart(slider, detail, 'spectrum').map(Keying.focusIn).map(constant(true));
5248
              }
5249
            })] : [],
5250
          [Representing.config({
5251
              store: {
5252
                mode: 'manual',
5253
                getValue: function (_) {
5254
                  return detail.value().get();
5255
                }
5256
              }
5257
            })]
5258
        ])), get$6(detail.sliderBehaviours())),
5259
        events: derive([
5260
          run(changeEvent(), function (slider, simulatedEvent) {
5261
            changeValue(slider, simulatedEvent.event().value());
5262
          }),
5263
          runOnAttached(function (slider, simulatedEvent) {
5264
            detail.value().set(detail.getInitialValue()());
5265
            var thumb = getThumb(slider);
5266
            refresh(slider);
5267
            detail.onInit()(slider, thumb, detail.value().get());
5268
          })
5269
        ].concat(uiEventsArr)),
5270
        apis: {
5271
          resetToMin: resetToMin,
5272
          resetToMax: resetToMax,
5273
          refresh: refresh
5274
        },
5275
        domModification: { styles: { position: 'relative' } }
5276
      };
5277
    };
5278
5279
    var Slider = composite$1({
5280
      name: 'Slider',
5281
      configFields: SliderSchema,
5282
      partFields: SliderParts,
5283
      factory: sketch$1,
5284
      apis: {
5285
        resetToMin: function (apis, slider) {
5286
          apis.resetToMin(slider);
5287
        },
5288
        resetToMax: function (apis, slider) {
5289
          apis.resetToMax(slider);
5290
        },
5291
        refresh: function (apis, slider) {
5292
          apis.refresh(slider);
5293
        }
5294
      }
5295
    });
5296
5297
    var button = function (realm, clazz, makeItems) {
5298
      return Buttons.forToolbar(clazz, function () {
5299
        var items = makeItems();
5300
        realm.setContextToolbar([{
5301
            label: clazz + ' group',
5302
            items: items
5303
          }]);
5304
      }, {});
5305
    };
5306
5307
    var BLACK = -1;
5308
    var makeSlider = function (spec$$1) {
5309
      var getColor = function (hue) {
5310
        if (hue < 0) {
5311
          return 'black';
5312
        } else if (hue > 360) {
5313
          return 'white';
5314
        } else {
5315
          return 'hsl(' + hue + ', 100%, 50%)';
5316
        }
5317
      };
5318
      var onInit = function (slider, thumb, value) {
5319
        var color = getColor(value);
5320
        set$2(thumb.element(), 'background-color', color);
5321
      };
5322
      var onChange = function (slider, thumb, value) {
5323
        var color = getColor(value);
5324
        set$2(thumb.element(), 'background-color', color);
5325
        spec$$1.onChange(slider, thumb, color);
5326
      };
5327
      return Slider.sketch({
5328
        dom: dom$1('<div class="${prefix}-slider ${prefix}-hue-slider-container"></div>'),
5329
        components: [
5330
          Slider.parts()['left-edge'](spec('<div class="${prefix}-hue-slider-black"></div>')),
5331
          Slider.parts().spectrum({
5332
            dom: dom$1('<div class="${prefix}-slider-gradient-container"></div>'),
5333
            components: [spec('<div class="${prefix}-slider-gradient"></div>')],
5334
            behaviours: derive$2([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })])
5335
          }),
5336
          Slider.parts()['right-edge'](spec('<div class="${prefix}-hue-slider-white"></div>')),
5337
          Slider.parts().thumb({
5338
            dom: dom$1('<div class="${prefix}-slider-thumb"></div>'),
5339
            behaviours: derive$2([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })])
5340
          })
5341
        ],
5342
        onChange: onChange,
5343
        onDragStart: function (slider, thumb) {
5344
          Toggling.on(thumb);
5345
        },
5346
        onDragEnd: function (slider, thumb) {
5347
          Toggling.off(thumb);
5348
        },
5349
        onInit: onInit,
5350
        stepSize: 10,
5351
        min: 0,
5352
        max: 360,
5353
        getInitialValue: spec$$1.getInitialValue,
5354
        sliderBehaviours: derive$2([Receivers.orientation(Slider.refresh)])
5355
      });
5356
    };
5357
    var makeItems = function (spec$$1) {
5358
      return [makeSlider(spec$$1)];
5359
    };
5360
    var sketch$2 = function (realm, editor) {
5361
      var spec$$1 = {
5362
        onChange: function (slider, thumb, color) {
5363
          editor.undoManager.transact(function () {
5364
            editor.formatter.apply('forecolor', { value: color });
5365
            editor.nodeChanged();
5366
          });
5367
        },
5368
        getInitialValue: function () {
5369
          return BLACK;
5370
        }
5371
      };
5372
      return button(realm, 'color', function () {
5373
        return makeItems(spec$$1);
5374
      });
5375
    };
5376
    var ColorSlider = {
5377
      makeItems: makeItems,
5378
      sketch: sketch$2
5379
    };
5380
5381
    var schema$7 = objOfOnly([
5382
      strict$1('getInitialValue'),
5383
      strict$1('onChange'),
5384
      strict$1('category'),
5385
      strict$1('sizes')
5386
    ]);
5387
    var sketch$3 = function (rawSpec) {
5388
      var spec$$1 = asRawOrDie('SizeSlider', schema$7, rawSpec);
5389
      var isValidValue = function (valueIndex) {
5390
        return valueIndex >= 0 && valueIndex < spec$$1.sizes.length;
5391
      };
5392
      var onChange = function (slider, thumb, valueIndex) {
5393
        if (isValidValue(valueIndex)) {
5394
          spec$$1.onChange(valueIndex);
5395
        }
5396
      };
5397
      return Slider.sketch({
5398
        dom: {
5399
          tag: 'div',
5400
          classes: [
5401
            Styles.resolve('slider-' + spec$$1.category + '-size-container'),
5402
            Styles.resolve('slider'),
5403
            Styles.resolve('slider-size-container')
5404
          ]
5405
        },
5406
        onChange: onChange,
5407
        onDragStart: function (slider, thumb) {
5408
          Toggling.on(thumb);
5409
        },
5410
        onDragEnd: function (slider, thumb) {
5411
          Toggling.off(thumb);
5412
        },
5413
        min: 0,
5414
        max: spec$$1.sizes.length - 1,
5415
        stepSize: 1,
5416
        getInitialValue: spec$$1.getInitialValue,
5417
        snapToGrid: true,
5418
        sliderBehaviours: derive$2([Receivers.orientation(Slider.refresh)]),
5419
        components: [
5420
          Slider.parts().spectrum({
5421
            dom: dom$1('<div class="${prefix}-slider-size-container"></div>'),
5422
            components: [spec('<div class="${prefix}-slider-size-line"></div>')]
5423
          }),
5424
          Slider.parts().thumb({
5425
            dom: dom$1('<div class="${prefix}-slider-thumb"></div>'),
5426
            behaviours: derive$2([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })])
5427
          })
5428
        ]
5429
      });
5430
    };
5431
    var SizeSlider = { sketch: sketch$3 };
5432
5433
    var candidates = [
5434
      '9px',
5435
      '10px',
5436
      '11px',
5437
      '12px',
5438
      '14px',
5439
      '16px',
5440
      '18px',
5441
      '20px',
5442
      '24px',
5443
      '32px',
5444
      '36px'
5445
    ];
5446
    var defaultSize = 'medium';
5447
    var defaultIndex = 2;
5448
    var indexToSize = function (index) {
5449
      return Option.from(candidates[index]);
5450
    };
5451
    var sizeToIndex = function (size) {
5452
      return findIndex(candidates, function (v) {
5453
        return v === size;
5454
      });
5455
    };
5456
    var getRawOrComputed = function (isRoot, rawStart) {
5457
      var optStart = isElement(rawStart) ? Option.some(rawStart) : parent(rawStart);
5458
      return optStart.map(function (start) {
5459
        var inline = closest(start, function (elem) {
5460
          return getRaw(elem, 'font-size').isSome();
5461
        }, isRoot).bind(function (elem) {
5462
          return getRaw(elem, 'font-size');
5463
        });
5464
        return inline.getOrThunk(function () {
5465
          return get$4(start, 'font-size');
5466
        });
5467
      }).getOr('');
5468
    };
5469
    var getSize = function (editor) {
5470
      var node = editor.selection.getStart();
5471
      var elem = Element$$1.fromDom(node);
5472
      var root = Element$$1.fromDom(editor.getBody());
5473
      var isRoot = function (e) {
5474
        return eq(root, e);
5475
      };
5476
      var elemSize = getRawOrComputed(isRoot, elem);
5477
      return find$2(candidates, function (size) {
5478
        return elemSize === size;
5479
      }).getOr(defaultSize);
5480
    };
5481
    var applySize = function (editor, value$$1) {
5482
      var currentValue = getSize(editor);
5483
      if (currentValue !== value$$1) {
5484
        editor.execCommand('fontSize', false, value$$1);
5485
      }
5486
    };
5487
    var get$8 = function (editor) {
5488
      var size = getSize(editor);
5489
      return sizeToIndex(size).getOr(defaultIndex);
5490
    };
5491
    var apply$1 = function (editor, index) {
5492
      indexToSize(index).each(function (size) {
5493
        applySize(editor, size);
5494
      });
5495
    };
5496
    var FontSizes = {
5497
      candidates: constant(candidates),
5498
      get: get$8,
5499
      apply: apply$1
5500
    };
5501
5502
    var sizes = FontSizes.candidates();
5503
    var makeSlider$1 = function (spec$$1) {
5504
      return SizeSlider.sketch({
5505
        onChange: spec$$1.onChange,
5506
        sizes: sizes,
5507
        category: 'font',
5508
        getInitialValue: spec$$1.getInitialValue
5509
      });
5510
    };
5511
    var makeItems$1 = function (spec$$1) {
5512
      return [
5513
        spec('<span class="${prefix}-toolbar-button ${prefix}-icon-small-font ${prefix}-icon"></span>'),
5514
        makeSlider$1(spec$$1),
5515
        spec('<span class="${prefix}-toolbar-button ${prefix}-icon-large-font ${prefix}-icon"></span>')
5516
      ];
5517
    };
5518
    var sketch$4 = function (realm, editor) {
5519
      var spec$$1 = {
5520
        onChange: function (value) {
5521
          FontSizes.apply(editor, value);
5522
        },
5523
        getInitialValue: function () {
5524
          return FontSizes.get(editor);
5525
        }
5526
      };
5527
      return button(realm, 'font-size', function () {
5528
        return makeItems$1(spec$$1);
5529
      });
5530
    };
5531
5532
    var record = function (spec) {
5533
      var uid = isSketchSpec(spec) && hasKey$1(spec, 'uid') ? spec.uid : generate$3('memento');
5534
      var get = function (anyInSystem) {
5535
        return anyInSystem.getSystem().getByUid(uid).getOrDie();
5536
      };
5537
      var getOpt = function (anyInSystem) {
5538
        return anyInSystem.getSystem().getByUid(uid).fold(Option.none, Option.some);
5539
      };
5540
      var asSpec = function () {
5541
        return deepMerge(spec, { uid: uid });
5542
      };
5543
      return {
5544
        get: get,
5545
        getOpt: getOpt,
5546
        asSpec: asSpec
5547
      };
5548
    };
5549
5550
    function create$3(width, height) {
5551
      return resize(document.createElement('canvas'), width, height);
5552
    }
5553
    function clone$2(canvas) {
5554
      var tCanvas, ctx;
5555
      tCanvas = create$3(canvas.width, canvas.height);
5556
      ctx = get2dContext(tCanvas);
5557
      ctx.drawImage(canvas, 0, 0);
5558
      return tCanvas;
5559
    }
5560
    function get2dContext(canvas) {
5561
      return canvas.getContext('2d');
5562
    }
5563
    function get3dContext(canvas) {
5564
      var gl = null;
5565
      try {
5566
        gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
5567
      } catch (e) {
5568
      }
5569
      if (!gl) {
5570
        gl = null;
5571
      }
5572
      return gl;
5573
    }
5574
    function resize(canvas, width, height) {
5575
      canvas.width = width;
5576
      canvas.height = height;
5577
      return canvas;
5578
    }
5579
    var Canvas = {
5580
      create: create$3,
5581
      clone: clone$2,
5582
      resize: resize,
5583
      get2dContext: get2dContext,
5584
      get3dContext: get3dContext
5585
    };
5586
5587
    function getWidth(image) {
5588
      return image.naturalWidth || image.width;
5589
    }
5590
    function getHeight(image) {
5591
      return image.naturalHeight || image.height;
5592
    }
5593
    var ImageSize = {
5594
      getWidth: getWidth,
5595
      getHeight: getHeight
5596
    };
5597
5598
    var promise = function () {
5599
      var Promise = function (fn) {
5600
        if (typeof this !== 'object')
5601
          throw new TypeError('Promises must be constructed via new');
5602
        if (typeof fn !== 'function')
5603
          throw new TypeError('not a function');
5604
        this._state = null;
5605
        this._value = null;
5606
        this._deferreds = [];
5607
        doResolve(fn, bind(resolve, this), bind(reject, this));
5608
      };
5609
      var asap = Promise.immediateFn || typeof window.setImmediate === 'function' && window.setImmediate || function (fn) {
5610
        setTimeout(fn, 1);
5611
      };
5612
      function bind(fn, thisArg) {
5613
        return function () {
5614
          fn.apply(thisArg, arguments);
5615
        };
5616
      }
5617
      var isArray = Array.isArray || function (value) {
5618
        return Object.prototype.toString.call(value) === '[object Array]';
5619
      };
5620
      function handle(deferred) {
5621
        var me = this;
5622
        if (this._state === null) {
5623
          this._deferreds.push(deferred);
5624
          return;
5625
        }
5626
        asap(function () {
5627
          var cb = me._state ? deferred.onFulfilled : deferred.onRejected;
5628
          if (cb === null) {
5629
            (me._state ? deferred.resolve : deferred.reject)(me._value);
5630
            return;
5631
          }
5632
          var ret;
5633
          try {
5634
            ret = cb(me._value);
5635
          } catch (e) {
5636
            deferred.reject(e);
5637
            return;
5638
          }
5639
          deferred.resolve(ret);
5640
        });
5641
      }
5642
      function resolve(newValue) {
5643
        try {
5644
          if (newValue === this)
5645
            throw new TypeError('A promise cannot be resolved with itself.');
5646
          if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
5647
            var then = newValue.then;
5648
            if (typeof then === 'function') {
5649
              doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this));
5650
              return;
5651
            }
5652
          }
5653
          this._state = true;
5654
          this._value = newValue;
5655
          finale.call(this);
5656
        } catch (e) {
5657
          reject.call(this, e);
5658
        }
5659
      }
5660
      function reject(newValue) {
5661
        this._state = false;
5662
        this._value = newValue;
5663
        finale.call(this);
5664
      }
5665
      function finale() {
5666
        for (var i = 0, len = this._deferreds.length; i < len; i++) {
5667
          handle.call(this, this._deferreds[i]);
5668
        }
5669
        this._deferreds = null;
5670
      }
5671
      function Handler(onFulfilled, onRejected, resolve, reject) {
5672
        this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
5673
        this.onRejected = typeof onRejected === 'function' ? onRejected : null;
5674
        this.resolve = resolve;
5675
        this.reject = reject;
5676
      }
5677
      function doResolve(fn, onFulfilled, onRejected) {
5678
        var done = false;
5679
        try {
5680
          fn(function (value) {
5681
            if (done)
5682
              return;
5683
            done = true;
5684
            onFulfilled(value);
5685
          }, function (reason) {
5686
            if (done)
5687
              return;
5688
            done = true;
5689
            onRejected(reason);
5690
          });
5691
        } catch (ex) {
5692
          if (done)
5693
            return;
5694
          done = true;
5695
          onRejected(ex);
5696
        }
5697
      }
5698
      Promise.prototype['catch'] = function (onRejected) {
5699
        return this.then(null, onRejected);
5700
      };
5701
      Promise.prototype.then = function (onFulfilled, onRejected) {
5702
        var me = this;
5703
        return new Promise(function (resolve, reject) {
5704
          handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject));
5705
        });
5706
      };
5707
      Promise.all = function () {
5708
        var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments);
5709
        return new Promise(function (resolve, reject) {
5710
          if (args.length === 0)
5711
            return resolve([]);
5712
          var remaining = args.length;
5713
          function res(i, val) {
5714
            try {
5715
              if (val && (typeof val === 'object' || typeof val === 'function')) {
5716
                var then = val.then;
5717
                if (typeof then === 'function') {
5718
                  then.call(val, function (val) {
5719
                    res(i, val);
5720
                  }, reject);
5721
                  return;
5722
                }
5723
              }
5724
              args[i] = val;
5725
              if (--remaining === 0) {
5726
                resolve(args);
5727
              }
5728
            } catch (ex) {
5729
              reject(ex);
5730
            }
5731
          }
5732
          for (var i = 0; i < args.length; i++) {
5733
            res(i, args[i]);
5734
          }
5735
        });
5736
      };
5737
      Promise.resolve = function (value) {
5738
        if (value && typeof value === 'object' && value.constructor === Promise) {
5739
          return value;
5740
        }
5741
        return new Promise(function (resolve) {
5742
          resolve(value);
5743
        });
5744
      };
5745
      Promise.reject = function (value) {
5746
        return new Promise(function (resolve, reject) {
5747
          reject(value);
5748
        });
5749
      };
5750
      Promise.race = function (values) {
5751
        return new Promise(function (resolve, reject) {
5752
          for (var i = 0, len = values.length; i < len; i++) {
5753
            values[i].then(resolve, reject);
5754
          }
5755
        });
5756
      };
5757
      return Promise;
5758
    };
5759
    var Promise = window.Promise ? window.Promise : promise();
5760
5761
    function Blob (parts, properties) {
5762
      var f = Global$1.getOrDie('Blob');
5763
      return new f(parts, properties);
5764
    }
5765
5766
    function FileReader () {
5767
      var f = Global$1.getOrDie('FileReader');
5768
      return new f();
5769
    }
5770
5771
    function Uint8Array (arr) {
5772
      var f = Global$1.getOrDie('Uint8Array');
5773
      return new f(arr);
5774
    }
5775
5776
    var requestAnimationFrame = function (callback) {
5777
      var f = Global$1.getOrDie('requestAnimationFrame');
5778
      f(callback);
5779
    };
5780
    var atob = function (base64) {
5781
      var f = Global$1.getOrDie('atob');
5782
      return f(base64);
5783
    };
5784
    var Window = {
5785
      atob: atob,
5786
      requestAnimationFrame: requestAnimationFrame
5787
    };
5788
5789
    function imageToBlob(image) {
5790
      var src = image.src;
5791
      if (src.indexOf('data:') === 0) {
5792
        return dataUriToBlob(src);
5793
      }
5794
      return anyUriToBlob(src);
5795
    }
5796
    function blobToImage(blob) {
5797
      return new Promise(function (resolve, reject) {
5798
        var blobUrl = URL.createObjectURL(blob);
5799
        var image = new Image();
5800
        var removeListeners = function () {
5801
          image.removeEventListener('load', loaded);
5802
          image.removeEventListener('error', error);
5803
        };
5804
        function loaded() {
5805
          removeListeners();
5806
          resolve(image);
5807
        }
5808
        function error() {
5809
          removeListeners();
5810
          reject('Unable to load data of type ' + blob.type + ': ' + blobUrl);
5811
        }
5812
        image.addEventListener('load', loaded);
5813
        image.addEventListener('error', error);
5814
        image.src = blobUrl;
5815
        if (image.complete) {
5816
          loaded();
5817
        }
5818
      });
5819
    }
5820
    function anyUriToBlob(url) {
5821
      return new Promise(function (resolve, reject) {
5822
        var xhr = new XMLHttpRequest();
5823
        xhr.open('GET', url, true);
5824
        xhr.responseType = 'blob';
5825
        xhr.onload = function () {
5826
          if (this.status == 200) {
5827
            resolve(this.response);
5828
          }
5829
        };
5830
        xhr.onerror = function () {
5831
          var _this = this;
5832
          var corsError = function () {
5833
            var obj = new Error('No access to download image');
5834
            obj.code = 18;
5835
            obj.name = 'SecurityError';
5836
            return obj;
5837
          };
5838
          var genericError = function () {
5839
            return new Error('Error ' + _this.status + ' downloading image');
5840
          };
5841
          reject(this.status === 0 ? corsError() : genericError());
5842
        };
5843
        xhr.send();
5844
      });
5845
    }
5846
    function dataUriToBlobSync(uri) {
5847
      var data = uri.split(',');
5848
      var matches = /data:([^;]+)/.exec(data[0]);
5849
      if (!matches)
5850
        return Option.none();
5851
      var mimetype = matches[1];
5852
      var base64 = data[1];
5853
      var sliceSize = 1024;
5854
      var byteCharacters = Window.atob(base64);
5855
      var bytesLength = byteCharacters.length;
5856
      var slicesCount = Math.ceil(bytesLength / sliceSize);
5857
      var byteArrays = new Array(slicesCount);
5858
      for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
5859
        var begin = sliceIndex * sliceSize;
5860
        var end = Math.min(begin + sliceSize, bytesLength);
5861
        var bytes = new Array(end - begin);
5862
        for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
5863
          bytes[i] = byteCharacters[offset].charCodeAt(0);
5864
        }
5865
        byteArrays[sliceIndex] = Uint8Array(bytes);
5866
      }
5867
      return Option.some(Blob(byteArrays, { type: mimetype }));
5868
    }
5869
    function dataUriToBlob(uri) {
5870
      return new Promise(function (resolve, reject) {
5871
        dataUriToBlobSync(uri).fold(function () {
5872
          reject('uri is not base64: ' + uri);
5873
        }, resolve);
5874
      });
5875
    }
5876
    function uriToBlob(url) {
5877
      if (url.indexOf('blob:') === 0) {
5878
        return anyUriToBlob(url);
5879
      }
5880
      if (url.indexOf('data:') === 0) {
5881
        return dataUriToBlob(url);
5882
      }
5883
      return null;
5884
    }
5885
    function canvasToBlob(canvas, type, quality) {
5886
      type = type || 'image/png';
5887
      if (HTMLCanvasElement.prototype.toBlob) {
5888
        return new Promise(function (resolve) {
5889
          canvas.toBlob(function (blob) {
5890
            resolve(blob);
5891
          }, type, quality);
5892
        });
5893
      } else {
5894
        return dataUriToBlob(canvas.toDataURL(type, quality));
5895
      }
5896
    }
5897
    function canvasToDataURL(getCanvas, type, quality) {
5898
      type = type || 'image/png';
5899
      return getCanvas.then(function (canvas) {
5900
        return canvas.toDataURL(type, quality);
5901
      });
5902
    }
5903
    function blobToCanvas(blob) {
5904
      return blobToImage(blob).then(function (image) {
5905
        revokeImageUrl(image);
5906
        var context, canvas;
5907
        canvas = Canvas.create(ImageSize.getWidth(image), ImageSize.getHeight(image));
5908
        context = Canvas.get2dContext(canvas);
5909
        context.drawImage(image, 0, 0);
5910
        return canvas;
5911
      });
5912
    }
5913
    function blobToDataUri(blob) {
5914
      return new Promise(function (resolve) {
5915
        var reader = FileReader();
5916
        reader.onloadend = function () {
5917
          resolve(reader.result);
5918
        };
5919
        reader.readAsDataURL(blob);
5920
      });
5921
    }
5922
    function blobToArrayBuffer(blob) {
5923
      return new Promise(function (resolve) {
5924
        var reader = FileReader();
5925
        reader.onloadend = function () {
5926
          resolve(reader.result);
5927
        };
5928
        reader.readAsArrayBuffer(blob);
5929
      });
5930
    }
5931
    function blobToBase64(blob) {
5932
      return blobToDataUri(blob).then(function (dataUri) {
5933
        return dataUri.split(',')[1];
5934
      });
5935
    }
5936
    function revokeImageUrl(image) {
5937
      URL.revokeObjectURL(image.src);
5938
    }
5939
    var Conversions = {
5940
      blobToImage: blobToImage,
5941
      imageToBlob: imageToBlob,
5942
      blobToArrayBuffer: blobToArrayBuffer,
5943
      blobToDataUri: blobToDataUri,
5944
      blobToBase64: blobToBase64,
5945
      dataUriToBlobSync: dataUriToBlobSync,
5946
      canvasToBlob: canvasToBlob,
5947
      canvasToDataURL: canvasToDataURL,
5948
      blobToCanvas: blobToCanvas,
5949
      uriToBlob: uriToBlob
5950
    };
5951
5952
    var blobToImage$1 = function (image) {
5953
      return Conversions.blobToImage(image);
5954
    };
5955
    var imageToBlob$1 = function (blob) {
5956
      return Conversions.imageToBlob(blob);
5957
    };
5958
    var blobToDataUri$1 = function (blob) {
5959
      return Conversions.blobToDataUri(blob);
5960
    };
5961
    var blobToBase64$1 = function (blob) {
5962
      return Conversions.blobToBase64(blob);
5963
    };
5964
    var dataUriToBlobSync$1 = function (uri) {
5965
      return Conversions.dataUriToBlobSync(uri);
5966
    };
5967
    var uriToBlob$1 = function (uri) {
5968
      return Option.from(Conversions.uriToBlob(uri));
5969
    };
5970
    var BlobConversions = {
5971
      blobToImage: blobToImage$1,
5972
      imageToBlob: imageToBlob$1,
5973
      blobToDataUri: blobToDataUri$1,
5974
      blobToBase64: blobToBase64$1,
5975
      dataUriToBlobSync: dataUriToBlobSync$1,
5976
      uriToBlob: uriToBlob$1
5977
    };
5978
5979
    var addImage = function (editor, blob) {
5980
      BlobConversions.blobToBase64(blob).then(function (base64) {
5981
        editor.undoManager.transact(function () {
5982
          var cache = editor.editorUpload.blobCache;
5983
          var info = cache.create(generate$1('mceu'), blob, base64);
5984
          cache.add(info);
5985
          var img = editor.dom.createHTML('img', { src: info.blobUri() });
5986
          editor.insertContent(img);
5987
        });
5988
      });
5989
    };
5990
    var extractBlob = function (simulatedEvent) {
5991
      var event = simulatedEvent.event();
5992
      var files = event.raw().target.files || event.raw().dataTransfer.files;
5993
      return Option.from(files[0]);
5994
    };
5995
    var sketch$5 = function (editor) {
5996
      var pickerDom = {
5997
        tag: 'input',
5998
        attributes: {
5999
          accept: 'image/*',
6000
          type: 'file',
6001
          title: ''
6002
        },
6003
        styles: {
6004
          visibility: 'hidden',
6005
          position: 'absolute'
6006
        }
6007
      };
6008
      var memPicker = record({
6009
        dom: pickerDom,
6010
        events: derive([
6011
          cutter(click()),
6012
          run(change(), function (picker, simulatedEvent) {
6013
            extractBlob(simulatedEvent).each(function (blob) {
6014
              addImage(editor, blob);
6015
            });
6016
          })
6017
        ])
6018
      });
6019
      return Button.sketch({
6020
        dom: dom$1('<span class="${prefix}-toolbar-button ${prefix}-icon-image ${prefix}-icon"></span>'),
6021
        components: [memPicker.asSpec()],
6022
        action: function (button) {
6023
          var picker = memPicker.get(button);
6024
          picker.element().dom().click();
6025
        }
6026
      });
6027
    };
6028
6029
    var get$9 = function (element) {
6030
      return element.dom().textContent;
6031
    };
6032
    var set$5 = function (element, value) {
6033
      element.dom().textContent = value;
6034
    };
6035
6036
    var isNotEmpty = function (val) {
6037
      return val.length > 0;
6038
    };
6039
    var defaultToEmpty = function (str) {
6040
      return str === undefined || str === null ? '' : str;
6041
    };
6042
    var noLink = function (editor) {
6043
      var text = editor.selection.getContent({ format: 'text' });
6044
      return {
6045
        url: '',
6046
        text: text,
6047
        title: '',
6048
        target: '',
6049
        link: Option.none()
6050
      };
6051
    };
6052
    var fromLink = function (link) {
6053
      var text = get$9(link);
6054
      var url = get$1(link, 'href');
6055
      var title = get$1(link, 'title');
6056
      var target = get$1(link, 'target');
6057
      return {
6058
        url: defaultToEmpty(url),
6059
        text: text !== url ? defaultToEmpty(text) : '',
6060
        title: defaultToEmpty(title),
6061
        target: defaultToEmpty(target),
6062
        link: Option.some(link)
6063
      };
6064
    };
6065
    var getInfo = function (editor) {
6066
      return query(editor).fold(function () {
6067
        return noLink(editor);
6068
      }, function (link) {
6069
        return fromLink(link);
6070
      });
6071
    };
6072
    var wasSimple = function (link) {
6073
      var prevHref = get$1(link, 'href');
6074
      var prevText = get$9(link);
6075
      return prevHref === prevText;
6076
    };
6077
    var getTextToApply = function (link, url, info) {
6078
      return info.text.filter(isNotEmpty).fold(function () {
6079
        return wasSimple(link) ? Option.some(url) : Option.none();
6080
      }, Option.some);
6081
    };
6082
    var unlinkIfRequired = function (editor, info) {
6083
      var activeLink = info.link.bind(identity);
6084
      activeLink.each(function (link) {
6085
        editor.execCommand('unlink');
6086
      });
6087
    };
6088
    var getAttrs$1 = function (url, info) {
6089
      var attrs = {};
6090
      attrs.href = url;
6091
      info.title.filter(isNotEmpty).each(function (title) {
6092
        attrs.title = title;
6093
      });
6094
      info.target.filter(isNotEmpty).each(function (target) {
6095
        attrs.target = target;
6096
      });
6097
      return attrs;
6098
    };
6099
    var applyInfo = function (editor, info) {
6100
      info.url.filter(isNotEmpty).fold(function () {
6101
        unlinkIfRequired(editor, info);
6102
      }, function (url) {
6103
        var attrs = getAttrs$1(url, info);
6104
        var activeLink = info.link.bind(identity);
6105
        activeLink.fold(function () {
6106
          var text = info.text.filter(isNotEmpty).getOr(url);
6107
          editor.insertContent(editor.dom.createHTML('a', attrs, editor.dom.encode(text)));
6108
        }, function (link) {
6109
          var text = getTextToApply(link, url, info);
6110
          setAll(link, attrs);
6111
          text.each(function (newText) {
6112
            set$5(link, newText);
6113
          });
6114
        });
6115
      });
6116
    };
6117
    var query = function (editor) {
6118
      var start = Element$$1.fromDom(editor.selection.getStart());
6119
      return closest$2(start, 'a');
6120
    };
6121
    var LinkBridge = {
6122
      getInfo: getInfo,
6123
      applyInfo: applyInfo,
6124
      query: query
6125
    };
6126
6127
    var platform$1 = PlatformDetection$1.detect();
6128
    var preserve$1 = function (f, editor) {
6129
      var rng = editor.selection.getRng();
6130
      f();
6131
      editor.selection.setRng(rng);
6132
    };
6133
    var forAndroid = function (editor, f) {
6134
      var wrapper = platform$1.os.isAndroid() ? preserve$1 : apply;
6135
      wrapper(f, editor);
6136
    };
6137
    var RangePreserver = { forAndroid: forAndroid };
6138
6139
    var events$6 = function (name, eventHandlers) {
6140
      var events = derive(eventHandlers);
6141
      return create$1({
6142
        fields: [strict$1('enabled')],
6143
        name: name,
6144
        active: { events: constant(events) }
6145
      });
6146
    };
6147
    var config = function (name, eventHandlers) {
6148
      var me = events$6(name, eventHandlers);
6149
      return {
6150
        key: name,
6151
        value: {
6152
          config: {},
6153
          me: me,
6154
          configAsRaw: constant({}),
6155
          initialConfig: {},
6156
          state: NoState
6157
        }
6158
      };
6159
    };
6160
6161
    var getCurrent = function (component, composeConfig, composeState) {
6162
      return composeConfig.find()(component);
6163
    };
6164
6165
    var ComposeApis = /*#__PURE__*/Object.freeze({
6166
        getCurrent: getCurrent
6167
    });
6168
6169
    var ComposeSchema = [strict$1('find')];
6170
6171
    var Composing = create$1({
6172
      fields: ComposeSchema,
6173
      name: 'composing',
6174
      apis: ComposeApis
6175
    });
6176
6177
    var factory$1 = function (detail) {
6178
      return {
6179
        uid: detail.uid(),
6180
        dom: deepMerge({
6181
          tag: 'div',
6182
          attributes: { role: 'presentation' }
6183
        }, detail.dom()),
6184
        components: detail.components(),
6185
        behaviours: get$6(detail.containerBehaviours()),
6186
        events: detail.events(),
6187
        domModification: detail.domModification(),
6188
        eventOrder: detail.eventOrder()
6189
      };
6190
    };
6191
    var Container = single$2({
6192
      name: 'Container',
6193
      factory: factory$1,
6194
      configFields: [
6195
        defaulted$1('components', []),
6196
        field$1('containerBehaviours', []),
6197
        defaulted$1('events', {}),
6198
        defaulted$1('domModification', {}),
6199
        defaulted$1('eventOrder', {})
6200
      ]
6201
    });
6202
6203
    var factory$2 = function (detail) {
6204
      return {
6205
        uid: detail.uid(),
6206
        dom: detail.dom(),
6207
        behaviours: deepMerge(derive$2([
6208
          Representing.config({
6209
            store: {
6210
              mode: 'memory',
6211
              initialValue: detail.getInitialValue()()
6212
            }
6213
          }),
6214
          Composing.config({ find: Option.some })
6215
        ]), get$6(detail.dataBehaviours())),
6216
        events: derive([runOnAttached(function (component, simulatedEvent) {
6217
            Representing.setValue(component, detail.getInitialValue()());
6218
          })])
6219
      };
6220
    };
6221
    var DataField = single$2({
6222
      name: 'DataField',
6223
      factory: factory$2,
6224
      configFields: [
6225
        strict$1('uid'),
6226
        strict$1('dom'),
6227
        strict$1('getInitialValue'),
6228
        field$1('dataBehaviours', [
6229
          Representing,
6230
          Composing
6231
        ])
6232
      ]
6233
    });
6234
6235
    var get$a = function (element) {
6236
      return element.dom().value;
6237
    };
6238
    var set$6 = function (element, value) {
6239
      if (value === undefined)
6240
        throw new Error('Value.set was undefined');
6241
      element.dom().value = value;
6242
    };
6243
6244
    var schema$8 = constant([
6245
      option('data'),
6246
      defaulted$1('inputAttributes', {}),
6247
      defaulted$1('inputStyles', {}),
6248
      defaulted$1('type', 'input'),
6249
      defaulted$1('tag', 'input'),
6250
      defaulted$1('inputClasses', []),
6251
      onHandler('onSetValue'),
6252
      defaulted$1('styles', {}),
6253
      option('placeholder'),
6254
      defaulted$1('eventOrder', {}),
6255
      field$1('inputBehaviours', [
6256
        Representing,
6257
        Focusing
6258
      ]),
6259
      defaulted$1('selectOnFocus', true)
6260
    ]);
6261
    var focusBehaviours = function (detail) {
6262
      return derive$2([Focusing.config({
6263
          onFocus: detail.selectOnFocus() === false ? noop : function (component) {
6264
            var input = component.element();
6265
            var value = get$a(input);
6266
            input.dom().setSelectionRange(0, value.length);
6267
          }
6268
        })]);
6269
    };
6270
    var behaviours = function (detail) {
6271
      return deepMerge(derive$2([Representing.config({
6272
          store: {
6273
            mode: 'manual',
6274
            initialValue: detail.data().getOr(undefined),
6275
            getValue: function (input) {
6276
              return get$a(input.element());
6277
            },
6278
            setValue: function (input, data) {
6279
              var current = get$a(input.element());
6280
              if (current !== data) {
6281
                set$6(input.element(), data);
6282
              }
6283
            }
6284
          },
6285
          onSetValue: detail.onSetValue()
6286
        })]), focusBehaviours(detail), get$6(detail.inputBehaviours()));
6287
    };
6288
    var dom$2 = function (detail) {
6289
      return {
6290
        tag: detail.tag(),
6291
        attributes: deepMerge(wrapAll$1([{
6292
            key: 'type',
6293
            value: detail.type()
6294
          }].concat(detail.placeholder().map(function (pc) {
6295
          return {
6296
            key: 'placeholder',
6297
            value: pc
6298
          };
6299
        }).toArray())), detail.inputAttributes()),
6300
        styles: detail.inputStyles(),
6301
        classes: detail.inputClasses()
6302
      };
6303
    };
6304
6305
    var factory$3 = function (detail, spec) {
6306
      return {
6307
        uid: detail.uid(),
6308
        dom: dom$2(detail),
6309
        components: [],
6310
        behaviours: behaviours(detail),
6311
        eventOrder: detail.eventOrder()
6312
      };
6313
    };
6314
    var Input = single$2({
6315
      name: 'Input',
6316
      configFields: schema$8(),
6317
      factory: factory$3
6318
    });
6319
6320
    var exhibit$3 = function (base, tabConfig) {
6321
      return nu$6({
6322
        attributes: wrapAll$1([{
6323
            key: tabConfig.tabAttr(),
6324
            value: 'true'
6325
          }])
6326
      });
6327
    };
6328
6329
    var ActiveTabstopping = /*#__PURE__*/Object.freeze({
6330
        exhibit: exhibit$3
6331
    });
6332
6333
    var TabstopSchema = [defaulted$1('tabAttr', 'data-alloy-tabstop')];
6334
6335
    var Tabstopping = create$1({
6336
      fields: TabstopSchema,
6337
      name: 'tabstopping',
6338
      active: ActiveTabstopping
6339
    });
6340
6341
    var clearInputBehaviour = 'input-clearing';
6342
    var field$2 = function (name, placeholder) {
6343
      var inputSpec = record(Input.sketch({
6344
        placeholder: placeholder,
6345
        onSetValue: function (input$$1, data) {
6346
          emit(input$$1, input());
6347
        },
6348
        inputBehaviours: derive$2([
6349
          Composing.config({ find: Option.some }),
6350
          Tabstopping.config({}),
6351
          Keying.config({ mode: 'execution' })
6352
        ]),
6353
        selectOnFocus: false
6354
      }));
6355
      var buttonSpec = record(Button.sketch({
6356
        dom: dom$1('<button class="${prefix}-input-container-x ${prefix}-icon-cancel-circle ${prefix}-icon"></button>'),
6357
        action: function (button) {
6358
          var input$$1 = inputSpec.get(button);
6359
          Representing.setValue(input$$1, '');
6360
        }
6361
      }));
6362
      return {
6363
        name: name,
6364
        spec: Container.sketch({
6365
          dom: dom$1('<div class="${prefix}-input-container"></div>'),
6366
          components: [
6367
            inputSpec.asSpec(),
6368
            buttonSpec.asSpec()
6369
          ],
6370
          containerBehaviours: derive$2([
6371
            Toggling.config({ toggleClass: Styles.resolve('input-container-empty') }),
6372
            Composing.config({
6373
              find: function (comp) {
6374
                return Option.some(inputSpec.get(comp));
6375
              }
6376
            }),
6377
            config(clearInputBehaviour, [run(input(), function (iContainer) {
6378
                var input$$1 = inputSpec.get(iContainer);
6379
                var val = Representing.getValue(input$$1);
6380
                var f = val.length > 0 ? Toggling.off : Toggling.on;
6381
                f(iContainer);
6382
              })])
6383
          ])
6384
        })
6385
      };
6386
    };
6387
    var hidden = function (name) {
6388
      return {
6389
        name: name,
6390
        spec: DataField.sketch({
6391
          dom: {
6392
            tag: 'span',
6393
            styles: { display: 'none' }
6394
          },
6395
          getInitialValue: function () {
6396
            return Option.none();
6397
          }
6398
        })
6399
      };
6400
    };
6401
6402
    var nativeDisabled = [
6403
      'input',
6404
      'button',
6405
      'textarea'
6406
    ];
6407
    var onLoad$5 = function (component, disableConfig, disableState) {
6408
      if (disableConfig.disabled()) {
6409
        disable(component, disableConfig, disableState);
6410
      }
6411
    };
6412
    var hasNative = function (component) {
6413
      return contains(nativeDisabled, name(component.element()));
6414
    };
6415
    var nativeIsDisabled = function (component) {
6416
      return has$1(component.element(), 'disabled');
6417
    };
6418
    var nativeDisable = function (component) {
6419
      set(component.element(), 'disabled', 'disabled');
6420
    };
6421
    var nativeEnable = function (component) {
6422
      remove$1(component.element(), 'disabled');
6423
    };
6424
    var ariaIsDisabled = function (component) {
6425
      return get$1(component.element(), 'aria-disabled') === 'true';
6426
    };
6427
    var ariaDisable = function (component) {
6428
      set(component.element(), 'aria-disabled', 'true');
6429
    };
6430
    var ariaEnable = function (component) {
6431
      set(component.element(), 'aria-disabled', 'false');
6432
    };
6433
    var disable = function (component, disableConfig, disableState) {
6434
      disableConfig.disableClass().each(function (disableClass) {
6435
        add$2(component.element(), disableClass);
6436
      });
6437
      var f = hasNative(component) ? nativeDisable : ariaDisable;
6438
      f(component);
6439
    };
6440
    var enable = function (component, disableConfig, disableState) {
6441
      disableConfig.disableClass().each(function (disableClass) {
6442
        remove$4(component.element(), disableClass);
6443
      });
6444
      var f = hasNative(component) ? nativeEnable : ariaEnable;
6445
      f(component);
6446
    };
6447
    var isDisabled = function (component) {
6448
      return hasNative(component) ? nativeIsDisabled(component) : ariaIsDisabled(component);
6449
    };
6450
6451
    var DisableApis = /*#__PURE__*/Object.freeze({
6452
        enable: enable,
6453
        disable: disable,
6454
        isDisabled: isDisabled,
6455
        onLoad: onLoad$5
6456
    });
6457
6458
    var exhibit$4 = function (base, disableConfig, disableState) {
6459
      return nu$6({ classes: disableConfig.disabled() ? disableConfig.disableClass().map(pure).getOr([]) : [] });
6460
    };
6461
    var events$7 = function (disableConfig, disableState) {
6462
      return derive([
6463
        abort(execute(), function (component, simulatedEvent) {
6464
          return isDisabled(component);
6465
        }),
6466
        loadEvent(disableConfig, disableState, onLoad$5)
6467
      ]);
6468
    };
6469
6470
    var ActiveDisable = /*#__PURE__*/Object.freeze({
6471
        exhibit: exhibit$4,
6472
        events: events$7
6473
    });
6474
6475
    var DisableSchema = [
6476
      defaulted$1('disabled', false),
6477
      option('disableClass')
6478
    ];
6479
6480
    var Disabling = create$1({
6481
      fields: DisableSchema,
6482
      name: 'disabling',
6483
      active: ActiveDisable,
6484
      apis: DisableApis
6485
    });
6486
6487
    var owner$1 = 'form';
6488
    var schema$9 = [field$1('formBehaviours', [Representing])];
6489
    var getPartName = function (name) {
6490
      return '<alloy.field.' + name + '>';
6491
    };
6492
    var sketch$6 = function (fSpec) {
6493
      var parts = function () {
6494
        var record = [];
6495
        var field = function (name, config) {
6496
          record.push(name);
6497
          return generateOne(owner$1, getPartName(name), config);
6498
        };
6499
        return {
6500
          field: field,
6501
          record: function () {
6502
            return record;
6503
          }
6504
        };
6505
      }();
6506
      var spec = fSpec(parts);
6507
      var partNames = parts.record();
6508
      var fieldParts = map$1(partNames, function (n) {
6509
        return required({
6510
          name: n,
6511
          pname: getPartName(n)
6512
        });
6513
      });
6514
      return composite(owner$1, schema$9, fieldParts, make, spec);
6515
    };
6516
    var make = function (detail, components$$1, spec) {
6517
      return deepMerge({
6518
        'debug.sketcher': { Form: spec },
6519
        'uid': detail.uid(),
6520
        'dom': detail.dom(),
6521
        'components': components$$1,
6522
        'behaviours': deepMerge(derive$2([Representing.config({
6523
            store: {
6524
              mode: 'manual',
6525
              getValue: function (form) {
6526
                var optPs = getAllParts(form, detail);
6527
                return map(optPs, function (optPThunk, pName) {
6528
                  return optPThunk().bind(Composing.getCurrent).map(Representing.getValue);
6529
                });
6530
              },
6531
              setValue: function (form, values$$1) {
6532
                each(values$$1, function (newValue, key) {
6533
                  getPart(form, detail, key).each(function (wrapper) {
6534
                    Composing.getCurrent(wrapper).each(function (field) {
6535
                      Representing.setValue(field, newValue);
6536
                    });
6537
                  });
6538
                });
6539
              }
6540
            }
6541
          })]), get$6(detail.formBehaviours())),
6542
        'apis': {
6543
          getField: function (form, key) {
6544
            return getPart(form, detail, key).bind(Composing.getCurrent);
6545
          }
6546
        }
6547
      });
6548
    };
6549
    var Form = {
6550
      getField: makeApi(function (apis, component, key) {
6551
        return apis.getField(component, key);
6552
      }),
6553
      sketch: sketch$6
6554
    };
6555
6556
    var api$2 = function () {
6557
      var subject = Cell(Option.none());
6558
      var revoke = function () {
6559
        subject.get().each(function (s) {
6560
          s.destroy();
6561
        });
6562
      };
6563
      var clear = function () {
6564
        revoke();
6565
        subject.set(Option.none());
6566
      };
6567
      var set = function (s) {
6568
        revoke();
6569
        subject.set(Option.some(s));
6570
      };
6571
      var run = function (f) {
6572
        subject.get().each(f);
6573
      };
6574
      var isSet = function () {
6575
        return subject.get().isSome();
6576
      };
6577
      return {
6578
        clear: clear,
6579
        isSet: isSet,
6580
        set: set,
6581
        run: run
6582
      };
6583
    };
6584
    var value$3 = function () {
6585
      var subject = Cell(Option.none());
6586
      var clear = function () {
6587
        subject.set(Option.none());
6588
      };
6589
      var set = function (s) {
6590
        subject.set(Option.some(s));
6591
      };
6592
      var on = function (f) {
6593
        subject.get().each(f);
6594
      };
6595
      var isSet = function () {
6596
        return subject.get().isSome();
6597
      };
6598
      return {
6599
        clear: clear,
6600
        set: set,
6601
        isSet: isSet,
6602
        on: on
6603
      };
6604
    };
6605
6606
    var SWIPING_LEFT = 1;
6607
    var SWIPING_RIGHT = -1;
6608
    var SWIPING_NONE = 0;
6609
    var init$2 = function (xValue) {
6610
      return {
6611
        xValue: xValue,
6612
        points: []
6613
      };
6614
    };
6615
    var move$1 = function (model, xValue) {
6616
      if (xValue === model.xValue) {
6617
        return model;
6618
      }
6619
      var currentDirection = xValue - model.xValue > 0 ? SWIPING_LEFT : SWIPING_RIGHT;
6620
      var newPoint = {
6621
        direction: currentDirection,
6622
        xValue: xValue
6623
      };
6624
      var priorPoints = function () {
6625
        if (model.points.length === 0) {
6626
          return [];
6627
        } else {
6628
          var prev = model.points[model.points.length - 1];
6629
          return prev.direction === currentDirection ? model.points.slice(0, model.points.length - 1) : model.points;
6630
        }
6631
      }();
6632
      return {
6633
        xValue: xValue,
6634
        points: priorPoints.concat([newPoint])
6635
      };
6636
    };
6637
    var complete = function (model) {
6638
      if (model.points.length === 0) {
6639
        return SWIPING_NONE;
6640
      } else {
6641
        var firstDirection = model.points[0].direction;
6642
        var lastDirection = model.points[model.points.length - 1].direction;
6643
        return firstDirection === SWIPING_RIGHT && lastDirection === SWIPING_RIGHT ? SWIPING_RIGHT : firstDirection === SWIPING_LEFT && lastDirection === SWIPING_LEFT ? SWIPING_LEFT : SWIPING_NONE;
6644
      }
6645
    };
6646
    var SwipingModel = {
6647
      init: init$2,
6648
      move: move$1,
6649
      complete: complete
6650
    };
6651
6652
    var sketch$7 = function (rawSpec) {
6653
      var navigateEvent = 'navigateEvent';
6654
      var wrapperAdhocEvents = 'serializer-wrapper-events';
6655
      var formAdhocEvents = 'form-events';
6656
      var schema = objOf([
6657
        strict$1('fields'),
6658
        defaulted$1('maxFieldIndex', rawSpec.fields.length - 1),
6659
        strict$1('onExecute'),
6660
        strict$1('getInitialValue'),
6661
        state$1('state', function () {
6662
          return {
6663
            dialogSwipeState: value$3(),
6664
            currentScreen: Cell(0)
6665
          };
6666
        })
6667
      ]);
6668
      var spec$$1 = asRawOrDie('SerialisedDialog', schema, rawSpec);
6669
      var navigationButton = function (direction, directionName, enabled) {
6670
        return Button.sketch({
6671
          dom: dom$1('<span class="${prefix}-icon-' + directionName + ' ${prefix}-icon"></span>'),
6672
          action: function (button) {
6673
            emitWith(button, navigateEvent, { direction: direction });
6674
          },
6675
          buttonBehaviours: derive$2([Disabling.config({
6676
              disableClass: Styles.resolve('toolbar-navigation-disabled'),
6677
              disabled: !enabled
6678
            })])
6679
        });
6680
      };
6681
      var reposition = function (dialog, message) {
6682
        descendant$2(dialog.element(), '.' + Styles.resolve('serialised-dialog-chain')).each(function (parent) {
6683
          set$2(parent, 'left', -spec$$1.state.currentScreen.get() * message.width + 'px');
6684
        });
6685
      };
6686
      var navigate = function (dialog, direction) {
6687
        var screens = descendants$1(dialog.element(), '.' + Styles.resolve('serialised-dialog-screen'));
6688
        descendant$2(dialog.element(), '.' + Styles.resolve('serialised-dialog-chain')).each(function (parent) {
6689
          if (spec$$1.state.currentScreen.get() + direction >= 0 && spec$$1.state.currentScreen.get() + direction < screens.length) {
6690
            getRaw(parent, 'left').each(function (left) {
6691
              var currentLeft = parseInt(left, 10);
6692
              var w = get$7(screens[0]);
6693
              set$2(parent, 'left', currentLeft - direction * w + 'px');
6694
            });
6695
            spec$$1.state.currentScreen.set(spec$$1.state.currentScreen.get() + direction);
6696
          }
6697
        });
6698
      };
6699
      var focusInput = function (dialog) {
6700
        var inputs = descendants$1(dialog.element(), 'input');
6701
        var optInput = Option.from(inputs[spec$$1.state.currentScreen.get()]);
6702
        optInput.each(function (input$$1) {
6703
          dialog.getSystem().getByDom(input$$1).each(function (inputComp) {
6704
            dispatchFocus(dialog, inputComp.element());
6705
          });
6706
        });
6707
        var dotitems = memDots.get(dialog);
6708
        Highlighting.highlightAt(dotitems, spec$$1.state.currentScreen.get());
6709
      };
6710
      var resetState = function () {
6711
        spec$$1.state.currentScreen.set(0);
6712
        spec$$1.state.dialogSwipeState.clear();
6713
      };
6714
      var memForm = record(Form.sketch(function (parts) {
6715
        return {
6716
          dom: dom$1('<div class="${prefix}-serialised-dialog"></div>'),
6717
          components: [Container.sketch({
6718
              dom: dom$1('<div class="${prefix}-serialised-dialog-chain" style="left: 0px; position: absolute;"></div>'),
6719
              components: map$1(spec$$1.fields, function (field$$1, i) {
6720
                return i <= spec$$1.maxFieldIndex ? Container.sketch({
6721
                  dom: dom$1('<div class="${prefix}-serialised-dialog-screen"></div>'),
6722
                  components: flatten([
6723
                    [navigationButton(-1, 'previous', i > 0)],
6724
                    [parts.field(field$$1.name, field$$1.spec)],
6725
                    [navigationButton(+1, 'next', i < spec$$1.maxFieldIndex)]
6726
                  ])
6727
                }) : parts.field(field$$1.name, field$$1.spec);
6728
              })
6729
            })],
6730
          formBehaviours: derive$2([
6731
            Receivers.orientation(function (dialog, message) {
6732
              reposition(dialog, message);
6733
            }),
6734
            Keying.config({
6735
              mode: 'special',
6736
              focusIn: function (dialog) {
6737
                focusInput(dialog);
6738
              },
6739
              onTab: function (dialog) {
6740
                navigate(dialog, +1);
6741
                return Option.some(true);
6742
              },
6743
              onShiftTab: function (dialog) {
6744
                navigate(dialog, -1);
6745
                return Option.some(true);
6746
              }
6747
            }),
6748
            config(formAdhocEvents, [
6749
              runOnAttached(function (dialog, simulatedEvent) {
6750
                resetState();
6751
                var dotitems = memDots.get(dialog);
6752
                Highlighting.highlightFirst(dotitems);
6753
                spec$$1.getInitialValue(dialog).each(function (v) {
6754
                  Representing.setValue(dialog, v);
6755
                });
6756
              }),
6757
              runOnExecute(spec$$1.onExecute),
6758
              run(transitionend(), function (dialog, simulatedEvent) {
6759
                var event = simulatedEvent.event();
6760
                if (event.raw().propertyName === 'left') {
6761
                  focusInput(dialog);
6762
                }
6763
              }),
6764
              run(navigateEvent, function (dialog, simulatedEvent) {
6765
                var event = simulatedEvent.event();
6766
                var direction = event.direction();
6767
                navigate(dialog, direction);
6768
              })
6769
            ])
6770
          ])
6771
        };
6772
      }));
6773
      var memDots = record({
6774
        dom: dom$1('<div class="${prefix}-dot-container"></div>'),
6775
        behaviours: derive$2([Highlighting.config({
6776
            highlightClass: Styles.resolve('dot-active'),
6777
            itemClass: Styles.resolve('dot-item')
6778
          })]),
6779
        components: bind(spec$$1.fields, function (_f, i) {
6780
          return i <= spec$$1.maxFieldIndex ? [spec('<div class="${prefix}-dot-item ${prefix}-icon-full-dot ${prefix}-icon"></div>')] : [];
6781
        })
6782
      });
6783
      return {
6784
        dom: dom$1('<div class="${prefix}-serializer-wrapper"></div>'),
6785
        components: [
6786
          memForm.asSpec(),
6787
          memDots.asSpec()
6788
        ],
6789
        behaviours: derive$2([
6790
          Keying.config({
6791
            mode: 'special',
6792
            focusIn: function (wrapper) {
6793
              var form = memForm.get(wrapper);
6794
              Keying.focusIn(form);
6795
            }
6796
          }),
6797
          config(wrapperAdhocEvents, [
6798
            run(touchstart(), function (wrapper, simulatedEvent) {
6799
              var event = simulatedEvent.event();
6800
              spec$$1.state.dialogSwipeState.set(SwipingModel.init(event.touches[0].clientX));
6801
            }),
6802
            run(touchmove(), function (wrapper, simulatedEvent) {
6803
              var event = simulatedEvent.event();
6804
              spec$$1.state.dialogSwipeState.on(function (state) {
6805
                simulatedEvent.event().prevent();
6806
                spec$$1.state.dialogSwipeState.set(SwipingModel.move(state, event.raw().touches[0].clientX));
6807
              });
6808
            }),
6809
            run(touchend(), function (wrapper) {
6810
              spec$$1.state.dialogSwipeState.on(function (state) {
6811
                var dialog = memForm.get(wrapper);
6812
                var direction = -1 * SwipingModel.complete(state);
6813
                navigate(dialog, direction);
6814
              });
6815
            })
6816
          ])
6817
        ])
6818
      };
6819
    };
6820
6821
    var getGroups = cached(function (realm, editor) {
6822
      return [{
6823
          label: 'the link group',
6824
          items: [sketch$7({
6825
              fields: [
6826
                field$2('url', 'Type or paste URL'),
6827
                field$2('text', 'Link text'),
6828
                field$2('title', 'Link title'),
6829
                field$2('target', 'Link target'),
6830
                hidden('link')
6831
              ],
6832
              maxFieldIndex: [
6833
                'url',
6834
                'text',
6835
                'title',
6836
                'target'
6837
              ].length - 1,
6838
              getInitialValue: function () {
6839
                return Option.some(LinkBridge.getInfo(editor));
6840
              },
6841
              onExecute: function (dialog) {
6842
                var info = Representing.getValue(dialog);
6843
                LinkBridge.applyInfo(editor, info);
6844
                realm.restoreToolbar();
6845
                editor.focus();
6846
              }
6847
            })]
6848
        }];
6849
    });
6850
    var sketch$8 = function (realm, editor) {
6851
      return Buttons.forToolbarStateAction(editor, 'link', 'link', function () {
6852
        var groups = getGroups(realm, editor);
6853
        realm.setContextToolbar(groups);
6854
        RangePreserver.forAndroid(editor, function () {
6855
          realm.focusToolbar();
6856
        });
6857
        LinkBridge.query(editor).each(function (link) {
6858
          editor.selection.select(link.dom());
6859
        });
6860
      });
6861
    };
6862
6863
    var DefaultStyleFormats = [
6864
      {
6865
        title: 'Headings',
6866
        items: [
6867
          {
6868
            title: 'Heading 1',
6869
            format: 'h1'
6870
          },
6871
          {
6872
            title: 'Heading 2',
6873
            format: 'h2'
6874
          },
6875
          {
6876
            title: 'Heading 3',
6877
            format: 'h3'
6878
          },
6879
          {
6880
            title: 'Heading 4',
6881
            format: 'h4'
6882
          },
6883
          {
6884
            title: 'Heading 5',
6885
            format: 'h5'
6886
          },
6887
          {
6888
            title: 'Heading 6',
6889
            format: 'h6'
6890
          }
6891
        ]
6892
      },
6893
      {
6894
        title: 'Inline',
6895
        items: [
6896
          {
6897
            title: 'Bold',
6898
            icon: 'bold',
6899
            format: 'bold'
6900
          },
6901
          {
6902
            title: 'Italic',
6903
            icon: 'italic',
6904
            format: 'italic'
6905
          },
6906
          {
6907
            title: 'Underline',
6908
            icon: 'underline',
6909
            format: 'underline'
6910
          },
6911
          {
6912
            title: 'Strikethrough',
6913
            icon: 'strikethrough',
6914
            format: 'strikethrough'
6915
          },
6916
          {
6917
            title: 'Superscript',
6918
            icon: 'superscript',
6919
            format: 'superscript'
6920
          },
6921
          {
6922
            title: 'Subscript',
6923
            icon: 'subscript',
6924
            format: 'subscript'
6925
          },
6926
          {
6927
            title: 'Code',
6928
            icon: 'code',
6929
            format: 'code'
6930
          }
6931
        ]
6932
      },
6933
      {
6934
        title: 'Blocks',
6935
        items: [
6936
          {
6937
            title: 'Paragraph',
6938
            format: 'p'
6939
          },
6940
          {
6941
            title: 'Blockquote',
6942
            format: 'blockquote'
6943
          },
6944
          {
6945
            title: 'Div',
6946
            format: 'div'
6947
          },
6948
          {
6949
            title: 'Pre',
6950
            format: 'pre'
6951
          }
6952
        ]
6953
      },
6954
      {
6955
        title: 'Alignment',
6956
        items: [
6957
          {
6958
            title: 'Left',
6959
            icon: 'alignleft',
6960
            format: 'alignleft'
6961
          },
6962
          {
6963
            title: 'Center',
6964
            icon: 'aligncenter',
6965
            format: 'aligncenter'
6966
          },
6967
          {
6968
            title: 'Right',
6969
            icon: 'alignright',
6970
            format: 'alignright'
6971
          },
6972
          {
6973
            title: 'Justify',
6974
            icon: 'alignjustify',
6975
            format: 'alignjustify'
6976
          }
6977
        ]
6978
      }
6979
    ];
6980
6981
    var isRecursive = function (component, originator, target) {
6982
      return eq(originator, component.element()) && !eq(originator, target);
6983
    };
6984
    var events$8 = derive([can(focus$1(), function (component, simulatedEvent) {
6985
        var originator = simulatedEvent.event().originator();
6986
        var target = simulatedEvent.event().target();
6987
        if (isRecursive(component, originator, target)) {
6988
          console.warn(focus$1() + ' did not get interpreted by the desired target. ' + '\nOriginator: ' + element(originator) + '\nTarget: ' + element(target) + '\nCheck the ' + focus$1() + ' event handlers');
6989
          return false;
6990
        } else {
6991
          return true;
6992
        }
6993
      })]);
6994
6995
    var DefaultEvents = /*#__PURE__*/Object.freeze({
6996
        events: events$8
6997
    });
6998
6999
    var make$1 = identity;
7000
7001
    var SystemApi = exactly([
7002
      'debugInfo',
7003
      'triggerFocus',
7004
      'triggerEvent',
7005
      'triggerEscape',
7006
      'addToWorld',
7007
      'removeFromWorld',
7008
      'addToGui',
7009
      'removeFromGui',
7010
      'build',
7011
      'getByUid',
7012
      'getByDom',
7013
      'broadcast',
7014
      'broadcastOn',
7015
      'isConnected'
7016
    ]);
7017
7018
    var NoContextApi = function (getComp) {
7019
      var fail = function (event) {
7020
        return function () {
7021
          throw new Error('The component must be in a context to send: ' + event + '\n' + element(getComp().element()) + ' is not in context.');
7022
        };
7023
      };
7024
      return SystemApi({
7025
        debugInfo: constant('fake'),
7026
        triggerEvent: fail('triggerEvent'),
7027
        triggerFocus: fail('triggerFocus'),
7028
        triggerEscape: fail('triggerEscape'),
7029
        build: fail('build'),
7030
        addToWorld: fail('addToWorld'),
7031
        removeFromWorld: fail('removeFromWorld'),
7032
        addToGui: fail('addToGui'),
7033
        removeFromGui: fail('removeFromGui'),
7034
        getByUid: fail('getByUid'),
7035
        getByDom: fail('getByDom'),
7036
        broadcast: fail('broadcast'),
7037
        broadcastOn: fail('broadcastOn'),
7038
        isConnected: constant(false)
7039
      });
7040
    };
7041
7042
    var generateFrom = function (spec, all) {
7043
      var schema = map$1(all, function (a) {
7044
        return optionObjOf(a.name(), [
7045
          strict$1('config'),
7046
          defaulted$1('state', NoState)
7047
        ]);
7048
      });
7049
      var validated = asStruct('component.behaviours', objOf(schema), spec.behaviours).fold(function (errInfo) {
7050
        throw new Error(formatError(errInfo) + '\nComplete spec:\n' + Json.stringify(spec, null, 2));
7051
      }, function (v) {
7052
        return v;
7053
      });
7054
      return {
7055
        list: all,
7056
        data: map(validated, function (optBlobThunk) {
7057
          var optBlob = optBlobThunk();
7058
          var output = optBlob.map(function (blob) {
7059
            return {
7060
              config: blob.config(),
7061
              state: blob.state().init(blob.config())
7062
            };
7063
          });
7064
          return function () {
7065
            return output;
7066
          };
7067
        })
7068
      };
7069
    };
7070
    var getBehaviours = function (bData) {
7071
      return bData.list;
7072
    };
7073
    var getData = function (bData) {
7074
      return bData.data;
7075
    };
7076
7077
    var byInnerKey = function (data, tuple) {
7078
      var r = {};
7079
      each(data, function (detail, key) {
7080
        each(detail, function (value, indexKey) {
7081
          var chain = readOr$1(indexKey, [])(r);
7082
          r[indexKey] = chain.concat([tuple(key, value)]);
7083
        });
7084
      });
7085
      return r;
7086
    };
7087
7088
    var concat = function (chain, aspect) {
7089
      var values$$1 = bind(chain, function (c) {
7090
        return c.modification().getOr([]);
7091
      });
7092
      return Result.value(wrap$2(aspect, values$$1));
7093
    };
7094
    var onlyOne = function (chain, aspect) {
7095
      if (chain.length > 1) {
7096
        return Result.error('Multiple behaviours have tried to change DOM "' + aspect + '". The guilty behaviours are: ' + Json.stringify(map$1(chain, function (b) {
7097
          return b.name();
7098
        })) + '. At this stage, this ' + 'is not supported. Future releases might provide strategies for resolving this.');
7099
      } else if (chain.length === 0) {
7100
        return Result.value({});
7101
      } else {
7102
        return Result.value(chain[0].modification().fold(function () {
7103
          return {};
7104
        }, function (m) {
7105
          return wrap$2(aspect, m);
7106
        }));
7107
      }
7108
    };
7109
    var duplicate = function (aspect, k, obj, behaviours) {
7110
      return Result.error('Mulitple behaviours have tried to change the _' + k + '_ "' + aspect + '"' + '. The guilty behaviours are: ' + Json.stringify(bind(behaviours, function (b) {
7111
        return b.modification().getOr({})[k] !== undefined ? [b.name()] : [];
7112
      }), null, 2) + '. This is not currently supported.');
7113
    };
7114
    var objSafeMerge = function (chain, aspect) {
7115
      var y = foldl(chain, function (acc, c) {
7116
        var obj = c.modification().getOr({});
7117
        return acc.bind(function (accRest) {
7118
          var parts = mapToArray(obj, function (v, k) {
7119
            return accRest[k] !== undefined ? duplicate(aspect, k, obj, chain) : Result.value(wrap$2(k, v));
7120
          });
7121
          return consolidate(parts, accRest);
7122
        });
7123
      }, Result.value({}));
7124
      return y.map(function (yValue) {
7125
        return wrap$2(aspect, yValue);
7126
      });
7127
    };
7128
    var mergeTypes = {
7129
      classes: concat,
7130
      attributes: objSafeMerge,
7131
      styles: objSafeMerge,
7132
      domChildren: onlyOne,
7133
      defChildren: onlyOne,
7134
      innerHtml: onlyOne,
7135
      value: onlyOne
7136
    };
7137
    var combine$1 = function (info, baseMod, behaviours, base) {
7138
      var modsByBehaviour = deepMerge({}, baseMod);
7139
      each$1(behaviours, function (behaviour) {
7140
        modsByBehaviour[behaviour.name()] = behaviour.exhibit(info, base);
7141
      });
7142
      var nameAndMod = function (name, modification) {
7143
        return {
7144
          name: function () {
7145
            return name;
7146
          },
7147
          modification: modification
7148
        };
7149
      };
7150
      var byAspect = byInnerKey(modsByBehaviour, nameAndMod);
7151
      var usedAspect = map(byAspect, function (values$$1, aspect) {
7152
        return bind(values$$1, function (value) {
7153
          return value.modification().fold(function () {
7154
            return [];
7155
          }, function (v) {
7156
            return [value];
7157
          });
7158
        });
7159
      });
7160
      var modifications = mapToArray(usedAspect, function (values$$1, aspect) {
7161
        return readOptFrom$1(mergeTypes, aspect).fold(function () {
7162
          return Result.error('Unknown field type: ' + aspect);
7163
        }, function (merger) {
7164
          return merger(values$$1, aspect);
7165
        });
7166
      });
7167
      var consolidated = consolidate(modifications, {});
7168
      return consolidated.map(nu$6);
7169
    };
7170
7171
    var sortKeys = function (label, keyName, array, order) {
7172
      var sliced = array.slice(0);
7173
      try {
7174
        var sorted = sliced.sort(function (a, b) {
7175
          var aKey = a[keyName]();
7176
          var bKey = b[keyName]();
7177
          var aIndex = order.indexOf(aKey);
7178
          var bIndex = order.indexOf(bKey);
7179
          if (aIndex === -1) {
7180
            throw new Error('The ordering for ' + label + ' does not have an entry for ' + aKey + '.\nOrder specified: ' + Json.stringify(order, null, 2));
7181
          }
7182
          if (bIndex === -1) {
7183
            throw new Error('The ordering for ' + label + ' does not have an entry for ' + bKey + '.\nOrder specified: ' + Json.stringify(order, null, 2));
7184
          }
7185
          if (aIndex < bIndex) {
7186
            return -1;
7187
          } else if (bIndex < aIndex) {
7188
            return 1;
7189
          } else {
7190
            return 0;
7191
          }
7192
        });
7193
        return Result.value(sorted);
7194
      } catch (err) {
7195
        return Result.error([err]);
7196
      }
7197
    };
7198
7199
    var uncurried = function (handler, purpose) {
7200
      return {
7201
        handler: handler,
7202
        purpose: constant(purpose)
7203
      };
7204
    };
7205
    var curried = function (handler, purpose) {
7206
      return {
7207
        cHandler: handler,
7208
        purpose: constant(purpose)
7209
      };
7210
    };
7211
    var curryArgs = function (descHandler, extraArgs) {
7212
      return curried(curry.apply(undefined, [descHandler.handler].concat(extraArgs)), descHandler.purpose());
7213
    };
7214
    var getCurried = function (descHandler) {
7215
      return descHandler.cHandler;
7216
    };
7217
7218
    var behaviourTuple = function (name, handler) {
7219
      return {
7220
        name: constant(name),
7221
        handler: constant(handler)
7222
      };
7223
    };
7224
    var nameToHandlers = function (behaviours, info) {
7225
      var r = {};
7226
      each$1(behaviours, function (behaviour) {
7227
        r[behaviour.name()] = behaviour.handlers(info);
7228
      });
7229
      return r;
7230
    };
7231
    var groupByEvents = function (info, behaviours, base) {
7232
      var behaviourEvents = deepMerge(base, nameToHandlers(behaviours, info));
7233
      return byInnerKey(behaviourEvents, behaviourTuple);
7234
    };
7235
    var combine$2 = function (info, eventOrder, behaviours, base) {
7236
      var byEventName = groupByEvents(info, behaviours, base);
7237
      return combineGroups(byEventName, eventOrder);
7238
    };
7239
    var assemble = function (rawHandler) {
7240
      var handler = read(rawHandler);
7241
      return function (component, simulatedEvent) {
7242
        var rest = [];
7243
        for (var _i = 2; _i < arguments.length; _i++) {
7244
          rest[_i - 2] = arguments[_i];
7245
        }
7246
        var args = [
7247
          component,
7248
          simulatedEvent
7249
        ].concat(rest);
7250
        if (handler.abort.apply(undefined, args)) {
7251
          simulatedEvent.stop();
7252
        } else if (handler.can.apply(undefined, args)) {
7253
          handler.run.apply(undefined, args);
7254
        }
7255
      };
7256
    };
7257
    var missingOrderError = function (eventName, tuples) {
7258
      return Result.error(['The event (' + eventName + ') has more than one behaviour that listens to it.\nWhen this occurs, you must ' + 'specify an event ordering for the behaviours in your spec (e.g. [ "listing", "toggling" ]).\nThe behaviours that ' + 'can trigger it are: ' + Json.stringify(map$1(tuples, function (c) {
7259
          return c.name();
7260
        }), null, 2)]);
7261
    };
7262
    var fuse$1 = function (tuples, eventOrder, eventName) {
7263
      var order = eventOrder[eventName];
7264
      if (!order) {
7265
        return missingOrderError(eventName, tuples);
7266
      } else {
7267
        return sortKeys('Event: ' + eventName, 'name', tuples, order).map(function (sortedTuples) {
7268
          var handlers = map$1(sortedTuples, function (tuple) {
7269
            return tuple.handler();
7270
          });
7271
          return fuse(handlers);
7272
        });
7273
      }
7274
    };
7275
    var combineGroups = function (byEventName, eventOrder) {
7276
      var r = mapToArray(byEventName, function (tuples, eventName) {
7277
        var combined = tuples.length === 1 ? Result.value(tuples[0].handler()) : fuse$1(tuples, eventOrder, eventName);
7278
        return combined.map(function (handler) {
7279
          var assembled = assemble(handler);
7280
          var purpose = tuples.length > 1 ? filter(eventOrder, function (o) {
7281
            return contains(tuples, function (t) {
7282
              return t.name() === o;
7283
            });
7284
          }).join(' > ') : tuples[0].name();
7285
          return wrap$2(eventName, uncurried(assembled, purpose));
7286
        });
7287
      });
7288
      return consolidate(r, {});
7289
    };
7290
7291
    var toInfo = function (spec) {
7292
      return asStruct('custom.definition', objOfOnly([
7293
        field('dom', 'dom', strict(), objOfOnly([
7294
          strict$1('tag'),
7295
          defaulted$1('styles', {}),
7296
          defaulted$1('classes', []),
7297
          defaulted$1('attributes', {}),
7298
          option('value'),
7299
          option('innerHtml')
7300
        ])),
7301
        strict$1('components'),
7302
        strict$1('uid'),
7303
        defaulted$1('events', {}),
7304
        defaulted$1('apis', constant({})),
7305
        field('eventOrder', 'eventOrder', mergeWith({
7306
          'alloy.execute': [
7307
            'disabling',
7308
            'alloy.base.behaviour',
7309
            'toggling'
7310
          ],
7311
          'alloy.focus': [
7312
            'alloy.base.behaviour',
7313
            'focusing',
7314
            'keying'
7315
          ],
7316
          'alloy.system.init': [
7317
            'alloy.base.behaviour',
7318
            'disabling',
7319
            'toggling',
7320
            'representing'
7321
          ],
7322
          'input': [
7323
            'alloy.base.behaviour',
7324
            'representing',
7325
            'streaming',
7326
            'invalidating'
7327
          ],
7328
          'alloy.system.detached': [
7329
            'alloy.base.behaviour',
7330
            'representing'
7331
          ]
7332
        }), anyValue$1()),
7333
        option('domModification'),
7334
        snapshot$1('originalSpec'),
7335
        defaulted$1('debug.sketcher', 'unknown')
7336
      ]), spec);
7337
    };
7338
    var getUid = function (detail) {
7339
      return wrap$2(idAttr(), detail.uid());
7340
    };
7341
    var toDefinition = function (detail) {
7342
      var base = {
7343
        tag: detail.dom().tag(),
7344
        classes: detail.dom().classes(),
7345
        attributes: deepMerge(getUid(detail), detail.dom().attributes()),
7346
        styles: detail.dom().styles(),
7347
        domChildren: map$1(detail.components(), function (comp) {
7348
          return comp.element();
7349
        })
7350
      };
7351
      return nu$5(deepMerge(base, detail.dom().innerHtml().map(function (h) {
7352
        return wrap$2('innerHtml', h);
7353
      }).getOr({}), detail.dom().value().map(function (h) {
7354
        return wrap$2('value', h);
7355
      }).getOr({})));
7356
    };
7357
    var toModification = function (detail) {
7358
      return detail.domModification().fold(function () {
7359
        return nu$6({});
7360
      }, nu$6);
7361
    };
7362
    var toEvents = function (info) {
7363
      return info.events();
7364
    };
7365
7366
    var add$3 = function (element, classes) {
7367
      each$1(classes, function (x) {
7368
        add$2(element, x);
7369
      });
7370
    };
7371
    var remove$6 = function (element, classes) {
7372
      each$1(classes, function (x) {
7373
        remove$4(element, x);
7374
      });
7375
    };
7376
7377
    var getChildren = function (definition) {
7378
      if (definition.domChildren().isSome() && definition.defChildren().isSome()) {
7379
        throw new Error('Cannot specify children and child specs! Must be one or the other.\nDef: ' + defToStr(definition));
7380
      } else {
7381
        return definition.domChildren().fold(function () {
7382
          var defChildren = definition.defChildren().getOr([]);
7383
          return map$1(defChildren, renderDef);
7384
        }, function (domChildren) {
7385
          return domChildren;
7386
        });
7387
      }
7388
    };
7389
    var renderToDom = function (definition) {
7390
      var subject = Element$$1.fromTag(definition.tag());
7391
      setAll(subject, definition.attributes().getOr({}));
7392
      add$3(subject, definition.classes().getOr([]));
7393
      setAll$1(subject, definition.styles().getOr({}));
7394
      set$1(subject, definition.innerHtml().getOr(''));
7395
      var children = getChildren(definition);
7396
      append$1(subject, children);
7397
      definition.value().each(function (value) {
7398
        set$6(subject, value);
7399
      });
7400
      return subject;
7401
    };
7402
    var renderDef = function (spec) {
7403
      var definition = nu$5(spec);
7404
      return renderToDom(definition);
7405
    };
7406
7407
    var getBehaviours$1 = function (spec) {
7408
      var behaviours = readOptFrom$1(spec, 'behaviours').getOr({});
7409
      var keys$$1 = filter(keys(behaviours), function (k) {
7410
        return behaviours[k] !== undefined;
7411
      });
7412
      return map$1(keys$$1, function (k) {
7413
        return behaviours[k].me;
7414
      });
7415
    };
7416
    var generateFrom$1 = function (spec, all) {
7417
      return generateFrom(spec, all);
7418
    };
7419
    var generate$4 = function (spec) {
7420
      var all = getBehaviours$1(spec);
7421
      return generateFrom$1(spec, all);
7422
    };
7423
7424
    var ComponentApi = exactly([
7425
      'getSystem',
7426
      'config',
7427
      'hasConfigured',
7428
      'spec',
7429
      'connect',
7430
      'disconnect',
7431
      'element',
7432
      'syncComponents',
7433
      'readState',
7434
      'components',
7435
      'events'
7436
    ]);
7437
7438
    var getDomDefinition = function (info, bList, bData) {
7439
      var definition = toDefinition(info);
7440
      var baseModification = { 'alloy.base.modification': toModification(info) };
7441
      var modification = combine$1(bData, baseModification, bList, definition).getOrDie();
7442
      return merge$1(definition, modification);
7443
    };
7444
    var getEvents$6 = function (info, bList, bData) {
7445
      var baseEvents = { 'alloy.base.behaviour': toEvents(info) };
7446
      return combine$2(bData, info.eventOrder(), bList, baseEvents).getOrDie();
7447
    };
7448
    var build = function (spec) {
7449
      var getMe = function () {
7450
        return me;
7451
      };
7452
      var systemApi = Cell(NoContextApi(getMe));
7453
      var info = getOrDie$1(toInfo(deepMerge(spec, { behaviours: undefined })));
7454
      var bBlob = generate$4(spec);
7455
      var bList = getBehaviours(bBlob);
7456
      var bData = getData(bBlob);
7457
      var modDefinition = getDomDefinition(info, bList, bData);
7458
      var item = renderToDom(modDefinition);
7459
      var events = getEvents$6(info, bList, bData);
7460
      var subcomponents = Cell(info.components());
7461
      var connect = function (newApi) {
7462
        systemApi.set(newApi);
7463
      };
7464
      var disconnect = function () {
7465
        systemApi.set(NoContextApi(getMe));
7466
      };
7467
      var syncComponents = function () {
7468
        var children$$1 = children(item);
7469
        var subs = bind(children$$1, function (child$$1) {
7470
          return systemApi.get().getByDom(child$$1).fold(function () {
7471
            return [];
7472
          }, function (c) {
7473
            return [c];
7474
          });
7475
        });
7476
        subcomponents.set(subs);
7477
      };
7478
      var config = function (behaviour) {
7479
        if (behaviour === apiConfig()) {
7480
          return info.apis();
7481
        } else if (isString(behaviour)) {
7482
          throw new Error('Invalid input: only API constant is allowed');
7483
        }
7484
        var b = bData;
7485
        var f = isFunction(b[behaviour.name()]) ? b[behaviour.name()] : function () {
7486
          throw new Error('Could not find ' + behaviour.name() + ' in ' + Json.stringify(spec, null, 2));
7487
        };
7488
        return f();
7489
      };
7490
      var hasConfigured = function (behaviour) {
7491
        return isFunction(bData[behaviour.name()]);
7492
      };
7493
      var readState = function (behaviourName) {
7494
        return bData[behaviourName]().map(function (b) {
7495
          return b.state.readState();
7496
        }).getOr('not enabled');
7497
      };
7498
      var me = ComponentApi({
7499
        getSystem: systemApi.get,
7500
        config: config,
7501
        hasConfigured: hasConfigured,
7502
        spec: constant(spec),
7503
        readState: readState,
7504
        connect: connect,
7505
        disconnect: disconnect,
7506
        element: constant(item),
7507
        syncComponents: syncComponents,
7508
        components: subcomponents.get,
7509
        events: constant(events)
7510
      });
7511
      return me;
7512
    };
7513
7514
    var buildSubcomponents = function (spec) {
7515
      var components = readOr$1('components', [])(spec);
7516
      return map$1(components, build$1);
7517
    };
7518
    var buildFromSpec = function (userSpec) {
7519
      var spec = make$1(userSpec);
7520
      var components = buildSubcomponents(spec);
7521
      var completeSpec = deepMerge(DefaultEvents, spec, wrap$2('components', components));
7522
      return Result.value(build(completeSpec));
7523
    };
7524
    var text = function (textContent) {
7525
      var element = Element$$1.fromText(textContent);
7526
      return external$1({ element: element });
7527
    };
7528
    var external$1 = function (spec) {
7529
      var extSpec = asStructOrDie('external.component', objOfOnly([
7530
        strict$1('element'),
7531
        option('uid')
7532
      ]), spec);
7533
      var systemApi = Cell(NoContextApi());
7534
      var connect = function (newApi) {
7535
        systemApi.set(newApi);
7536
      };
7537
      var disconnect = function () {
7538
        systemApi.set(NoContextApi(function () {
7539
          return me;
7540
        }));
7541
      };
7542
      extSpec.uid().each(function (uid) {
7543
        writeOnly(extSpec.element(), uid);
7544
      });
7545
      var me = ComponentApi({
7546
        getSystem: systemApi.get,
7547
        config: Option.none,
7548
        hasConfigured: constant(false),
7549
        connect: connect,
7550
        disconnect: disconnect,
7551
        element: constant(extSpec.element()),
7552
        spec: constant(spec),
7553
        readState: constant('No state'),
7554
        syncComponents: noop,
7555
        components: constant([]),
7556
        events: constant({})
7557
      });
7558
      return premade(me);
7559
    };
7560
    var build$1 = function (spec) {
7561
      return getPremade(spec).fold(function () {
7562
        var userSpecWithUid = deepMerge({ uid: generate$3('') }, spec);
7563
        return buildFromSpec(userSpecWithUid).getOrDie();
7564
      }, function (prebuilt) {
7565
        return prebuilt;
7566
      });
7567
    };
7568
    var premade$1 = premade;
7569
7570
    var hoverEvent = 'alloy.item-hover';
7571
    var focusEvent = 'alloy.item-focus';
7572
    var onHover = function (item) {
7573
      if (search(item.element()).isNone() || Focusing.isFocused(item)) {
7574
        if (!Focusing.isFocused(item)) {
7575
          Focusing.focus(item);
7576
        }
7577
        emitWith(item, hoverEvent, { item: item });
7578
      }
7579
    };
7580
    var onFocus = function (item) {
7581
      emitWith(item, focusEvent, { item: item });
7582
    };
7583
    var hover = constant(hoverEvent);
7584
    var focus$4 = constant(focusEvent);
7585
7586
    var builder = function (detail) {
7587
      return {
7588
        dom: deepMerge(detail.dom(), { attributes: { role: detail.toggling().isSome() ? 'menuitemcheckbox' : 'menuitem' } }),
7589
        behaviours: deepMerge(derive$2([
7590
          detail.toggling().fold(Toggling.revoke, function (tConfig) {
7591
            return Toggling.config(deepMerge({ aria: { mode: 'checked' } }, tConfig));
7592
          }),
7593
          Focusing.config({
7594
            ignore: detail.ignoreFocus(),
7595
            onFocus: function (component) {
7596
              onFocus(component);
7597
            }
7598
          }),
7599
          Keying.config({ mode: 'execution' }),
7600
          Representing.config({
7601
            store: {
7602
              mode: 'memory',
7603
              initialValue: detail.data()
7604
            }
7605
          })
7606
        ]), detail.itemBehaviours()),
7607
        events: derive([
7608
          runWithTarget(tapOrClick(), emitExecute),
7609
          cutter(mousedown()),
7610
          run(mouseover(), onHover),
7611
          run(focusItem(), Focusing.focus)
7612
        ]),
7613
        components: detail.components(),
7614
        domModification: detail.domModification(),
7615
        eventOrder: detail.eventOrder()
7616
      };
7617
    };
7618
    var schema$a = [
7619
      strict$1('data'),
7620
      strict$1('components'),
7621
      strict$1('dom'),
7622
      option('toggling'),
7623
      defaulted$1('itemBehaviours', {}),
7624
      defaulted$1('ignoreFocus', false),
7625
      defaulted$1('domModification', {}),
7626
      output$1('builder', builder),
7627
      defaulted$1('eventOrder', {})
7628
    ];
7629
7630
    var builder$1 = function (detail) {
7631
      return {
7632
        dom: detail.dom(),
7633
        components: detail.components(),
7634
        events: derive([stopper(focusItem())])
7635
      };
7636
    };
7637
    var schema$b = [
7638
      strict$1('dom'),
7639
      strict$1('components'),
7640
      output$1('builder', builder$1)
7641
    ];
7642
7643
    var owner$2 = function () {
7644
      return 'item-widget';
7645
    };
7646
    var parts = constant([required({
7647
        name: 'widget',
7648
        overrides: function (detail) {
7649
          return {
7650
            behaviours: derive$2([Representing.config({
7651
                store: {
7652
                  mode: 'manual',
7653
                  getValue: function (component) {
7654
                    return detail.data();
7655
                  },
7656
                  setValue: function () {
7657
                  }
7658
                }
7659
              })])
7660
          };
7661
        }
7662
      })]);
7663
7664
    var builder$2 = function (detail) {
7665
      var subs = substitutes(owner$2(), detail, parts());
7666
      var components$$1 = components(owner$2(), detail, subs.internals());
7667
      var focusWidget = function (component) {
7668
        return getPart(component, detail, 'widget').map(function (widget) {
7669
          Keying.focusIn(widget);
7670
          return widget;
7671
        });
7672
      };
7673
      var onHorizontalArrow = function (component, simulatedEvent) {
7674
        return inside(simulatedEvent.event().target()) ? Option.none() : function () {
7675
          if (detail.autofocus()) {
7676
            simulatedEvent.setSource(component.element());
7677
            return Option.none();
7678
          } else {
7679
            return Option.none();
7680
          }
7681
        }();
7682
      };
7683
      return deepMerge({
7684
        dom: detail.dom(),
7685
        components: components$$1,
7686
        domModification: detail.domModification(),
7687
        events: derive([
7688
          runOnExecute(function (component, simulatedEvent) {
7689
            focusWidget(component).each(function (widget) {
7690
              simulatedEvent.stop();
7691
            });
7692
          }),
7693
          run(mouseover(), onHover),
7694
          run(focusItem(), function (component, simulatedEvent) {
7695
            if (detail.autofocus()) {
7696
              focusWidget(component);
7697
            } else {
7698
              Focusing.focus(component);
7699
            }
7700
          })
7701
        ]),
7702
        behaviours: derive$2([
7703
          Representing.config({
7704
            store: {
7705
              mode: 'memory',
7706
              initialValue: detail.data()
7707
            }
7708
          }),
7709
          Focusing.config({
7710
            onFocus: function (component) {
7711
              onFocus(component);
7712
            }
7713
          }),
7714
          Keying.config({
7715
            mode: 'special',
7716
            focusIn: detail.autofocus() ? function (component) {
7717
              focusWidget(component);
7718
            } : revoke(),
7719
            onLeft: onHorizontalArrow,
7720
            onRight: onHorizontalArrow,
7721
            onEscape: function (component, simulatedEvent) {
7722
              if (!Focusing.isFocused(component) && !detail.autofocus()) {
7723
                Focusing.focus(component);
7724
                return Option.some(true);
7725
              } else if (detail.autofocus()) {
7726
                simulatedEvent.setSource(component.element());
7727
                return Option.none();
7728
              } else {
7729
                return Option.none();
7730
              }
7731
            }
7732
          })
7733
        ])
7734
      });
7735
    };
7736
    var schema$c = [
7737
      strict$1('uid'),
7738
      strict$1('data'),
7739
      strict$1('components'),
7740
      strict$1('dom'),
7741
      defaulted$1('autofocus', false),
7742
      defaulted$1('domModification', {}),
7743
      defaultUidsSchema(parts()),
7744
      output$1('builder', builder$2)
7745
    ];
7746
7747
    var itemSchema$1 = choose$1('type', {
7748
      widget: schema$c,
7749
      item: schema$a,
7750
      separator: schema$b
7751
    });
7752
    var configureGrid = function (detail, movementInfo) {
7753
      return {
7754
        mode: 'flatgrid',
7755
        selector: '.' + detail.markers().item(),
7756
        initSize: {
7757
          numColumns: movementInfo.initSize().numColumns(),
7758
          numRows: movementInfo.initSize().numRows()
7759
        },
7760
        focusManager: detail.focusManager()
7761
      };
7762
    };
7763
    var configureMenu = function (detail, movementInfo) {
7764
      return {
7765
        mode: 'menu',
7766
        selector: '.' + detail.markers().item(),
7767
        moveOnTab: movementInfo.moveOnTab(),
7768
        focusManager: detail.focusManager()
7769
      };
7770
    };
7771
    var parts$1 = constant([group({
7772
        factory: {
7773
          sketch: function (spec) {
7774
            var itemInfo = asStructOrDie('menu.spec item', itemSchema$1, spec);
7775
            return itemInfo.builder()(itemInfo);
7776
          }
7777
        },
7778
        name: 'items',
7779
        unit: 'item',
7780
        defaults: function (detail, u) {
7781
          var fallbackUid = generate$3('');
7782
          return deepMerge({ uid: fallbackUid }, u);
7783
        },
7784
        overrides: function (detail, u) {
7785
          return {
7786
            type: u.type,
7787
            ignoreFocus: detail.fakeFocus(),
7788
            domModification: { classes: [detail.markers().item()] }
7789
          };
7790
        }
7791
      })]);
7792
    var schema$d = constant([
7793
      strict$1('value'),
7794
      strict$1('items'),
7795
      strict$1('dom'),
7796
      strict$1('components'),
7797
      defaulted$1('eventOrder', {}),
7798
      field$1('menuBehaviours', [
7799
        Highlighting,
7800
        Representing,
7801
        Composing,
7802
        Keying
7803
      ]),
7804
      defaultedOf('movement', {
7805
        mode: 'menu',
7806
        moveOnTab: true
7807
      }, choose$1('mode', {
7808
        grid: [
7809
          initSize(),
7810
          output$1('config', configureGrid)
7811
        ],
7812
        menu: [
7813
          defaulted$1('moveOnTab', true),
7814
          output$1('config', configureMenu)
7815
        ]
7816
      })),
7817
      itemMarkers(),
7818
      defaulted$1('fakeFocus', false),
7819
      defaulted$1('focusManager', dom()),
7820
      onHandler('onHighlight')
7821
    ]);
7822
7823
    var focus$5 = constant('alloy.menu-focus');
7824
7825
    var make$2 = function (detail, components, spec, externals) {
7826
      return deepMerge({
7827
        dom: deepMerge(detail.dom(), { attributes: { role: 'menu' } }),
7828
        uid: detail.uid(),
7829
        behaviours: deepMerge(derive$2([
7830
          Highlighting.config({
7831
            highlightClass: detail.markers().selectedItem(),
7832
            itemClass: detail.markers().item(),
7833
            onHighlight: detail.onHighlight()
7834
          }),
7835
          Representing.config({
7836
            store: {
7837
              mode: 'memory',
7838
              initialValue: detail.value()
7839
            }
7840
          }),
7841
          Composing.config({ find: Option.some }),
7842
          Keying.config(detail.movement().config()(detail, detail.movement()))
7843
        ]), get$6(detail.menuBehaviours())),
7844
        events: derive([
7845
          run(focus$4(), function (menu, simulatedEvent) {
7846
            var event = simulatedEvent.event();
7847
            menu.getSystem().getByDom(event.target()).each(function (item) {
7848
              Highlighting.highlight(menu, item);
7849
              simulatedEvent.stop();
7850
              emitWith(menu, focus$5(), {
7851
                menu: menu,
7852
                item: item
7853
              });
7854
            });
7855
          }),
7856
          run(hover(), function (menu, simulatedEvent) {
7857
            var item = simulatedEvent.event().item();
7858
            Highlighting.highlight(menu, item);
7859
          })
7860
        ]),
7861
        components: components,
7862
        eventOrder: detail.eventOrder()
7863
      });
7864
    };
7865
7866
    var Menu = composite$1({
7867
      name: 'Menu',
7868
      configFields: schema$d(),
7869
      partFields: parts$1(),
7870
      factory: make$2
7871
    });
7872
7873
    var preserve$2 = function (f, container) {
7874
      var ownerDoc = owner(container);
7875
      var refocus = active(ownerDoc).bind(function (focused) {
7876
        var hasFocus$$1 = function (elem) {
7877
          return eq(focused, elem);
7878
        };
7879
        return hasFocus$$1(container) ? Option.some(container) : descendant(container, hasFocus$$1);
7880
      });
7881
      var result = f(container);
7882
      refocus.each(function (oldFocus) {
7883
        active(ownerDoc).filter(function (newFocus) {
7884
          return eq(newFocus, oldFocus);
7885
        }).fold(function () {
7886
          focus$2(oldFocus);
7887
        }, noop);
7888
      });
7889
      return result;
7890
    };
7891
7892
    var set$7 = function (component, replaceConfig, replaceState, data) {
7893
      detachChildren(component);
7894
      preserve$2(function () {
7895
        var children = map$1(data, component.getSystem().build);
7896
        each$1(children, function (l) {
7897
          attach(component, l);
7898
        });
7899
      }, component.element());
7900
    };
7901
    var insert = function (component, replaceConfig, insertion, childSpec) {
7902
      var child = component.getSystem().build(childSpec);
7903
      attachWith(component, child, insertion);
7904
    };
7905
    var append$2 = function (component, replaceConfig, replaceState, appendee) {
7906
      insert(component, replaceConfig, append, appendee);
7907
    };
7908
    var prepend$2 = function (component, replaceConfig, replaceState, prependee) {
7909
      insert(component, replaceConfig, prepend, prependee);
7910
    };
7911
    var remove$7 = function (component, replaceConfig, replaceState, removee) {
7912
      var children = contents(component, replaceConfig);
7913
      var foundChild = find$2(children, function (child) {
7914
        return eq(removee.element(), child.element());
7915
      });
7916
      foundChild.each(detach);
7917
    };
7918
    var contents = function (component, replaceConfig) {
7919
      return component.components();
7920
    };
7921
7922
    var ReplaceApis = /*#__PURE__*/Object.freeze({
7923
        append: append$2,
7924
        prepend: prepend$2,
7925
        remove: remove$7,
7926
        set: set$7,
7927
        contents: contents
7928
    });
7929
7930
    var Replacing = create$1({
7931
      fields: [],
7932
      name: 'replacing',
7933
      apis: ReplaceApis
7934
    });
7935
7936
    var transpose = function (obj) {
7937
      return tupleMap(obj, function (v, k) {
7938
        return {
7939
          k: v,
7940
          v: k
7941
        };
7942
      });
7943
    };
7944
    var trace = function (items, byItem, byMenu, finish) {
7945
      return readOptFrom$1(byMenu, finish).bind(function (triggerItem) {
7946
        return readOptFrom$1(items, triggerItem).bind(function (triggerMenu) {
7947
          var rest = trace(items, byItem, byMenu, triggerMenu);
7948
          return Option.some([triggerMenu].concat(rest));
7949
        });
7950
      }).getOr([]);
7951
    };
7952
    var generate$5 = function (menus, expansions) {
7953
      var items = {};
7954
      each(menus, function (menuItems, menu) {
7955
        each$1(menuItems, function (item) {
7956
          items[item] = menu;
7957
        });
7958
      });
7959
      var byItem = expansions;
7960
      var byMenu = transpose(expansions);
7961
      var menuPaths = map(byMenu, function (_triggerItem, submenu) {
7962
        return [submenu].concat(trace(items, byItem, byMenu, submenu));
7963
      });
7964
      return map(items, function (menu) {
7965
        return readOptFrom$1(menuPaths, menu).getOr([menu]);
7966
      });
7967
    };
7968
7969
    var init$3 = function () {
7970
      var expansions = Cell({});
7971
      var menus = Cell({});
7972
      var paths = Cell({});
7973
      var primary = Cell(Option.none());
7974
      var directory = Cell({});
7975
      var clear = function () {
7976
        expansions.set({});
7977
        menus.set({});
7978
        paths.set({});
7979
        primary.set(Option.none());
7980
      };
7981
      var isClear = function () {
7982
        return primary.get().isNone();
7983
      };
7984
      var setContents = function (sPrimary, sMenus, sExpansions, dir) {
7985
        primary.set(Option.some(sPrimary));
7986
        expansions.set(sExpansions);
7987
        menus.set(sMenus);
7988
        directory.set(dir);
7989
        var sPaths = generate$5(dir, sExpansions);
7990
        paths.set(sPaths);
7991
      };
7992
      var expand = function (itemValue) {
7993
        return readOptFrom$1(expansions.get(), itemValue).map(function (menu) {
7994
          var current = readOptFrom$1(paths.get(), itemValue).getOr([]);
7995
          return [menu].concat(current);
7996
        });
7997
      };
7998
      var collapse = function (itemValue) {
7999
        return readOptFrom$1(paths.get(), itemValue).bind(function (path) {
8000
          return path.length > 1 ? Option.some(path.slice(1)) : Option.none();
8001
        });
8002
      };
8003
      var refresh = function (itemValue) {
8004
        return readOptFrom$1(paths.get(), itemValue);
8005
      };
8006
      var lookupMenu = function (menuValue) {
8007
        return readOptFrom$1(menus.get(), menuValue);
8008
      };
8009
      var otherMenus = function (path) {
8010
        var menuValues = directory.get();
8011
        return difference(keys(menuValues), path);
8012
      };
8013
      var getPrimary = function () {
8014
        return primary.get().bind(lookupMenu);
8015
      };
8016
      var getMenus = function () {
8017
        return menus.get();
8018
      };
8019
      return {
8020
        setContents: setContents,
8021
        expand: expand,
8022
        refresh: refresh,
8023
        collapse: collapse,
8024
        lookupMenu: lookupMenu,
8025
        otherMenus: otherMenus,
8026
        getPrimary: getPrimary,
8027
        getMenus: getMenus,
8028
        clear: clear,
8029
        isClear: isClear
8030
      };
8031
    };
8032
    var LayeredState = { init: init$3 };
8033
8034
    var make$3 = function (detail, rawUiSpec) {
8035
      var buildMenus = function (container, menus) {
8036
        return map(menus, function (spec, name) {
8037
          var data = Menu.sketch(deepMerge(spec, {
8038
            value: name,
8039
            items: spec.items,
8040
            markers: narrow$1(rawUiSpec.markers, [
8041
              'item',
8042
              'selectedItem'
8043
            ]),
8044
            fakeFocus: detail.fakeFocus(),
8045
            onHighlight: detail.onHighlight(),
8046
            focusManager: detail.fakeFocus() ? highlights() : dom()
8047
          }));
8048
          return container.getSystem().build(data);
8049
        });
8050
      };
8051
      var layeredState = LayeredState.init();
8052
      var setup = function (container) {
8053
        var componentMap = buildMenus(container, detail.data().menus());
8054
        var directory = toDirectory(container);
8055
        layeredState.setContents(detail.data().primary(), componentMap, detail.data().expansions(), directory);
8056
        return layeredState.getPrimary();
8057
      };
8058
      var getItemValue = function (item) {
8059
        return Representing.getValue(item).value;
8060
      };
8061
      var toDirectory = function (container) {
8062
        return map(detail.data().menus(), function (data, menuName) {
8063
          return bind(data.items, function (item) {
8064
            return item.type === 'separator' ? [] : [item.data.value];
8065
          });
8066
        });
8067
      };
8068
      var setActiveMenu = function (container, menu) {
8069
        Highlighting.highlight(container, menu);
8070
        Highlighting.getHighlighted(menu).orThunk(function () {
8071
          return Highlighting.getFirst(menu);
8072
        }).each(function (item) {
8073
          dispatch(container, item.element(), focusItem());
8074
        });
8075
      };
8076
      var getMenus = function (state, menuValues) {
8077
        return cat(map$1(menuValues, state.lookupMenu));
8078
      };
8079
      var updateMenuPath = function (container, state, path) {
8080
        return Option.from(path[0]).bind(state.lookupMenu).map(function (activeMenu) {
8081
          var rest = getMenus(state, path.slice(1));
8082
          each$1(rest, function (r) {
8083
            add$2(r.element(), detail.markers().backgroundMenu());
8084
          });
8085
          if (!inBody(activeMenu.element())) {
8086
            Replacing.append(container, premade$1(activeMenu));
8087
          }
8088
          remove$6(activeMenu.element(), [detail.markers().backgroundMenu()]);
8089
          setActiveMenu(container, activeMenu);
8090
          var others = getMenus(state, state.otherMenus(path));
8091
          each$1(others, function (o) {
8092
            remove$6(o.element(), [detail.markers().backgroundMenu()]);
8093
            if (!detail.stayInDom()) {
8094
              Replacing.remove(container, o);
8095
            }
8096
          });
8097
          return activeMenu;
8098
        });
8099
      };
8100
      var expandRight = function (container, item) {
8101
        var value = getItemValue(item);
8102
        return layeredState.expand(value).bind(function (path) {
8103
          Option.from(path[0]).bind(layeredState.lookupMenu).each(function (activeMenu) {
8104
            if (!inBody(activeMenu.element())) {
8105
              Replacing.append(container, premade$1(activeMenu));
8106
            }
8107
            detail.onOpenSubmenu()(container, item, activeMenu);
8108
            Highlighting.highlightFirst(activeMenu);
8109
          });
8110
          return updateMenuPath(container, layeredState, path);
8111
        });
8112
      };
8113
      var collapseLeft = function (container, item) {
8114
        var value = getItemValue(item);
8115
        return layeredState.collapse(value).bind(function (path) {
8116
          return updateMenuPath(container, layeredState, path).map(function (activeMenu) {
8117
            detail.onCollapseMenu()(container, item, activeMenu);
8118
            return activeMenu;
8119
          });
8120
        });
8121
      };
8122
      var updateView = function (container, item) {
8123
        var value = getItemValue(item);
8124
        return layeredState.refresh(value).bind(function (path) {
8125
          return updateMenuPath(container, layeredState, path);
8126
        });
8127
      };
8128
      var onRight = function (container, item) {
8129
        return inside(item.element()) ? Option.none() : expandRight(container, item);
8130
      };
8131
      var onLeft = function (container, item) {
8132
        return inside(item.element()) ? Option.none() : collapseLeft(container, item);
8133
      };
8134
      var onEscape = function (container, item) {
8135
        return collapseLeft(container, item).orThunk(function () {
8136
          return detail.onEscape()(container, item).map(function () {
8137
            return container;
8138
          });
8139
        });
8140
      };
8141
      var keyOnItem = function (f) {
8142
        return function (container, simulatedEvent) {
8143
          return closest$2(simulatedEvent.getSource(), '.' + detail.markers().item()).bind(function (target) {
8144
            return container.getSystem().getByDom(target).toOption().bind(function (item) {
8145
              return f(container, item).map(function () {
8146
                return true;
8147
              });
8148
            });
8149
          });
8150
        };
8151
      };
8152
      var events = derive([
8153
        run(focus$5(), function (sandbox, simulatedEvent) {
8154
          var menu = simulatedEvent.event().menu();
8155
          Highlighting.highlight(sandbox, menu);
8156
        }),
8157
        runOnExecute(function (component, simulatedEvent) {
8158
          var target = simulatedEvent.event().target();
8159
          component.getSystem().getByDom(target).each(function (item) {
8160
            var itemValue = getItemValue(item);
8161
            if (itemValue.indexOf('collapse-item') === 0) {
8162
              collapseLeft(component, item);
8163
            }
8164
            expandRight(component, item).fold(function () {
8165
              detail.onExecute()(component, item);
8166
            }, function () {
8167
            });
8168
          });
8169
        }),
8170
        runOnAttached(function (container, simulatedEvent) {
8171
          setup(container).each(function (primary) {
8172
            Replacing.append(container, premade$1(primary));
8173
            if (detail.openImmediately()) {
8174
              setActiveMenu(container, primary);
8175
              detail.onOpenMenu()(container, primary);
8176
            }
8177
          });
8178
        })
8179
      ].concat(detail.navigateOnHover() ? [run(hover(), function (sandbox, simulatedEvent) {
8180
          var item = simulatedEvent.event().item();
8181
          updateView(sandbox, item);
8182
          expandRight(sandbox, item);
8183
          detail.onHover()(sandbox, item);
8184
        })] : []));
8185
      var collapseMenuApi = function (container) {
8186
        Highlighting.getHighlighted(container).each(function (currentMenu) {
8187
          Highlighting.getHighlighted(currentMenu).each(function (currentItem) {
8188
            collapseLeft(container, currentItem);
8189
          });
8190
        });
8191
      };
8192
      return {
8193
        uid: detail.uid(),
8194
        dom: detail.dom(),
8195
        behaviours: deepMerge(derive$2([
8196
          Keying.config({
8197
            mode: 'special',
8198
            onRight: keyOnItem(onRight),
8199
            onLeft: keyOnItem(onLeft),
8200
            onEscape: keyOnItem(onEscape),
8201
            focusIn: function (container, keyInfo) {
8202
              layeredState.getPrimary().each(function (primary) {
8203
                dispatch(container, primary.element(), focusItem());
8204
              });
8205
            }
8206
          }),
8207
          Highlighting.config({
8208
            highlightClass: detail.markers().selectedMenu(),
8209
            itemClass: detail.markers().menu()
8210
          }),
8211
          Composing.config({
8212
            find: function (container) {
8213
              return Highlighting.getHighlighted(container);
8214
            }
8215
          }),
8216
          Replacing.config({})
8217
        ]), get$6(detail.tmenuBehaviours())),
8218
        eventOrder: detail.eventOrder(),
8219
        apis: { collapseMenu: collapseMenuApi },
8220
        events: events
8221
      };
8222
    };
8223
    var collapseItem = constant('collapse-item');
8224
8225
    var tieredData = function (primary, menus, expansions) {
8226
      return {
8227
        primary: primary,
8228
        menus: menus,
8229
        expansions: expansions
8230
      };
8231
    };
8232
    var singleData = function (name, menu) {
8233
      return {
8234
        primary: name,
8235
        menus: wrap$2(name, menu),
8236
        expansions: {}
8237
      };
8238
    };
8239
    var collapseItem$1 = function (text) {
8240
      return {
8241
        value: generate$1(collapseItem()),
8242
        text: text
8243
      };
8244
    };
8245
    var tieredMenu = single$2({
8246
      name: 'TieredMenu',
8247
      configFields: [
8248
        onStrictKeyboardHandler('onExecute'),
8249
        onStrictKeyboardHandler('onEscape'),
8250
        onStrictHandler('onOpenMenu'),
8251
        onStrictHandler('onOpenSubmenu'),
8252
        onHandler('onCollapseMenu'),
8253
        defaulted$1('openImmediately', true),
8254
        strictObjOf('data', [
8255
          strict$1('primary'),
8256
          strict$1('menus'),
8257
          strict$1('expansions')
8258
        ]),
8259
        defaulted$1('fakeFocus', false),
8260
        onHandler('onHighlight'),
8261
        onHandler('onHover'),
8262
        tieredMenuMarkers(),
8263
        strict$1('dom'),
8264
        defaulted$1('navigateOnHover', true),
8265
        defaulted$1('stayInDom', false),
8266
        field$1('tmenuBehaviours', [
8267
          Keying,
8268
          Highlighting,
8269
          Composing,
8270
          Replacing
8271
        ]),
8272
        defaulted$1('eventOrder', {})
8273
      ],
8274
      apis: {
8275
        collapseMenu: function (apis, tmenu) {
8276
          apis.collapseMenu(tmenu);
8277
        }
8278
      },
8279
      factory: make$3,
8280
      extraApis: {
8281
        tieredData: tieredData,
8282
        singleData: singleData,
8283
        collapseItem: collapseItem$1
8284
      }
8285
    });
8286
8287
    var findRoute = function (component, transConfig, transState, route) {
8288
      return readOptFrom$1(transConfig.routes(), route.start()).map(apply).bind(function (sConfig) {
8289
        return readOptFrom$1(sConfig, route.destination()).map(apply);
8290
      });
8291
    };
8292
    var getTransition = function (comp, transConfig, transState) {
8293
      var route = getCurrentRoute(comp, transConfig, transState);
8294
      return route.bind(function (r) {
8295
        return getTransitionOf(comp, transConfig, transState, r);
8296
      });
8297
    };
8298
    var getTransitionOf = function (comp, transConfig, transState, route) {
8299
      return findRoute(comp, transConfig, transState, route).bind(function (r) {
8300
        return r.transition().map(function (t) {
8301
          return {
8302
            transition: constant(t),
8303
            route: constant(r)
8304
          };
8305
        });
8306
      });
8307
    };
8308
    var disableTransition = function (comp, transConfig, transState) {
8309
      getTransition(comp, transConfig, transState).each(function (routeTransition) {
8310
        var t = routeTransition.transition();
8311
        remove$4(comp.element(), t.transitionClass());
8312
        remove$1(comp.element(), transConfig.destinationAttr());
8313
      });
8314
    };
8315
    var getNewRoute = function (comp, transConfig, transState, destination) {
8316
      return {
8317
        start: constant(get$1(comp.element(), transConfig.stateAttr())),
8318
        destination: constant(destination)
8319
      };
8320
    };
8321
    var getCurrentRoute = function (comp, transConfig, transState) {
8322
      var el = comp.element();
8323
      return has$1(el, transConfig.destinationAttr()) ? Option.some({
8324
        start: constant(get$1(comp.element(), transConfig.stateAttr())),
8325
        destination: constant(get$1(comp.element(), transConfig.destinationAttr()))
8326
      }) : Option.none();
8327
    };
8328
    var jumpTo = function (comp, transConfig, transState, destination) {
8329
      disableTransition(comp, transConfig, transState);
8330
      if (has$1(comp.element(), transConfig.stateAttr()) && get$1(comp.element(), transConfig.stateAttr()) !== destination) {
8331
        transConfig.onFinish()(comp, destination);
8332
      }
8333
      set(comp.element(), transConfig.stateAttr(), destination);
8334
    };
8335
    var fasttrack = function (comp, transConfig, transState, destination) {
8336
      if (has$1(comp.element(), transConfig.destinationAttr())) {
8337
        set(comp.element(), transConfig.stateAttr(), get$1(comp.element(), transConfig.destinationAttr()));
8338
        remove$1(comp.element(), transConfig.destinationAttr());
8339
      }
8340
    };
8341
    var progressTo = function (comp, transConfig, transState, destination) {
8342
      fasttrack(comp, transConfig, transState, destination);
8343
      var route = getNewRoute(comp, transConfig, transState, destination);
8344
      getTransitionOf(comp, transConfig, transState, route).fold(function () {
8345
        jumpTo(comp, transConfig, transState, destination);
8346
      }, function (routeTransition) {
8347
        disableTransition(comp, transConfig, transState);
8348
        var t = routeTransition.transition();
8349
        add$2(comp.element(), t.transitionClass());
8350
        set(comp.element(), transConfig.destinationAttr(), destination);
8351
      });
8352
    };
8353
    var getState = function (comp, transConfig, transState) {
8354
      var e = comp.element();
8355
      return has$1(e, transConfig.stateAttr()) ? Option.some(get$1(e, transConfig.stateAttr())) : Option.none();
8356
    };
8357
8358
    var TransitionApis = /*#__PURE__*/Object.freeze({
8359
        findRoute: findRoute,
8360
        disableTransition: disableTransition,
8361
        getCurrentRoute: getCurrentRoute,
8362
        jumpTo: jumpTo,
8363
        progressTo: progressTo,
8364
        getState: getState
8365
    });
8366
8367
    var events$9 = function (transConfig, transState) {
8368
      return derive([
8369
        run(transitionend(), function (component, simulatedEvent) {
8370
          var raw = simulatedEvent.event().raw();
8371
          getCurrentRoute(component, transConfig, transState).each(function (route) {
8372
            findRoute(component, transConfig, transState, route).each(function (rInfo) {
8373
              rInfo.transition().each(function (rTransition) {
8374
                if (raw.propertyName === rTransition.property()) {
8375
                  jumpTo(component, transConfig, transState, route.destination());
8376
                  transConfig.onTransition()(component, route);
8377
                }
8378
              });
8379
            });
8380
          });
8381
        }),
8382
        runOnAttached(function (comp, se) {
8383
          jumpTo(comp, transConfig, transState, transConfig.initialState());
8384
        })
8385
      ]);
8386
    };
8387
8388
    var ActiveTransitioning = /*#__PURE__*/Object.freeze({
8389
        events: events$9
8390
    });
8391
8392
    var TransitionSchema = [
8393
      defaulted$1('destinationAttr', 'data-transitioning-destination'),
8394
      defaulted$1('stateAttr', 'data-transitioning-state'),
8395
      strict$1('initialState'),
8396
      onHandler('onTransition'),
8397
      onHandler('onFinish'),
8398
      strictOf('routes', setOf(Result.value, setOf(Result.value, objOfOnly([optionObjOfOnly('transition', [
8399
          strict$1('property'),
8400
          strict$1('transitionClass')
8401
        ])]))))
8402
    ];
8403
8404
    var createRoutes = function (routes) {
8405
      var r = {};
8406
      each(routes, function (v, k) {
8407
        var waypoints = k.split('<->');
8408
        r[waypoints[0]] = wrap$2(waypoints[1], v);
8409
        r[waypoints[1]] = wrap$2(waypoints[0], v);
8410
      });
8411
      return r;
8412
    };
8413
    var createBistate = function (first, second, transitions) {
8414
      return wrapAll$1([
8415
        {
8416
          key: first,
8417
          value: wrap$2(second, transitions)
8418
        },
8419
        {
8420
          key: second,
8421
          value: wrap$2(first, transitions)
8422
        }
8423
      ]);
8424
    };
8425
    var createTristate = function (first, second, third, transitions) {
8426
      return wrapAll$1([
8427
        {
8428
          key: first,
8429
          value: wrapAll$1([
8430
            {
8431
              key: second,
8432
              value: transitions
8433
            },
8434
            {
8435
              key: third,
8436
              value: transitions
8437
            }
8438
          ])
8439
        },
8440
        {
8441
          key: second,
8442
          value: wrapAll$1([
8443
            {
8444
              key: first,
8445
              value: transitions
8446
            },
8447
            {
8448
              key: third,
8449
              value: transitions
8450
            }
8451
          ])
8452
        },
8453
        {
8454
          key: third,
8455
          value: wrapAll$1([
8456
            {
8457
              key: first,
8458
              value: transitions
8459
            },
8460
            {
8461
              key: second,
8462
              value: transitions
8463
            }
8464
          ])
8465
        }
8466
      ]);
8467
    };
8468
    var Transitioning = create$1({
8469
      fields: TransitionSchema,
8470
      name: 'transitioning',
8471
      active: ActiveTransitioning,
8472
      apis: TransitionApis,
8473
      extra: {
8474
        createRoutes: createRoutes,
8475
        createBistate: createBistate,
8476
        createTristate: createTristate
8477
      }
8478
    });
8479
8480
    var scrollable = Styles.resolve('scrollable');
8481
    var register = function (element) {
8482
      add$2(element, scrollable);
8483
    };
8484
    var deregister = function (element) {
8485
      remove$4(element, scrollable);
8486
    };
8487
    var Scrollable = {
8488
      register: register,
8489
      deregister: deregister,
8490
      scrollable: constant(scrollable)
8491
    };
8492
8493
    var getValue$4 = function (item) {
8494
      return readOptFrom$1(item, 'format').getOr(item.title);
8495
    };
8496
    var convert$1 = function (formats, memMenuThunk) {
8497
      var mainMenu = makeMenu('Styles', [].concat(map$1(formats.items, function (k) {
8498
        return makeItem(getValue$4(k), k.title, k.isSelected(), k.getPreview(), hasKey$1(formats.expansions, getValue$4(k)));
8499
      })), memMenuThunk, false);
8500
      var submenus = map(formats.menus, function (menuItems, menuName) {
8501
        var items = map$1(menuItems, function (item) {
8502
          return makeItem(getValue$4(item), item.title, item.isSelected !== undefined ? item.isSelected() : false, item.getPreview !== undefined ? item.getPreview() : '', hasKey$1(formats.expansions, getValue$4(item)));
8503
        });
8504
        return makeMenu(menuName, items, memMenuThunk, true);
8505
      });
8506
      var menus = deepMerge(submenus, wrap$2('styles', mainMenu));
8507
      var tmenu = tieredMenu.tieredData('styles', menus, formats.expansions);
8508
      return { tmenu: tmenu };
8509
    };
8510
    var makeItem = function (value, text$$1, selected, preview, isMenu) {
8511
      return {
8512
        data: {
8513
          value: value,
8514
          text: text$$1
8515
        },
8516
        type: 'item',
8517
        dom: {
8518
          tag: 'div',
8519
          classes: isMenu ? [Styles.resolve('styles-item-is-menu')] : []
8520
        },
8521
        toggling: {
8522
          toggleOnExecute: false,
8523
          toggleClass: Styles.resolve('format-matches'),
8524
          selected: selected
8525
        },
8526
        itemBehaviours: derive$2(isMenu ? [] : [Receivers.format(value, function (comp, status) {
8527
            var toggle = status ? Toggling.on : Toggling.off;
8528
            toggle(comp);
8529
          })]),
8530
        components: [{
8531
            dom: {
8532
              tag: 'div',
8533
              attributes: { style: preview },
8534
              innerHtml: text$$1
8535
            }
8536
          }]
8537
      };
8538
    };
8539
    var makeMenu = function (value, items, memMenuThunk, collapsable) {
8540
      return {
8541
        value: value,
8542
        dom: { tag: 'div' },
8543
        components: [
8544
          Button.sketch({
8545
            dom: {
8546
              tag: 'div',
8547
              classes: [Styles.resolve('styles-collapser')]
8548
            },
8549
            components: collapsable ? [
8550
              {
8551
                dom: {
8552
                  tag: 'span',
8553
                  classes: [Styles.resolve('styles-collapse-icon')]
8554
                }
8555
              },
8556
              text(value)
8557
            ] : [text(value)],
8558
            action: function (item) {
8559
              if (collapsable) {
8560
                var comp = memMenuThunk().get(item);
8561
                tieredMenu.collapseMenu(comp);
8562
              }
8563
            }
8564
          }),
8565
          {
8566
            dom: {
8567
              tag: 'div',
8568
              classes: [Styles.resolve('styles-menu-items-container')]
8569
            },
8570
            components: [Menu.parts().items({})],
8571
            behaviours: derive$2([config('adhoc-scrollable-menu', [
8572
                runOnAttached(function (component, simulatedEvent) {
8573
                  set$2(component.element(), 'overflow-y', 'auto');
8574
                  set$2(component.element(), '-webkit-overflow-scrolling', 'touch');
8575
                  Scrollable.register(component.element());
8576
                }),
8577
                runOnDetached(function (component) {
8578
                  remove$5(component.element(), 'overflow-y');
8579
                  remove$5(component.element(), '-webkit-overflow-scrolling');
8580
                  Scrollable.deregister(component.element());
8581
                })
8582
              ])])
8583
          }
8584
        ],
8585
        items: items,
8586
        menuBehaviours: derive$2([Transitioning.config({
8587
            initialState: 'after',
8588
            routes: Transitioning.createTristate('before', 'current', 'after', {
8589
              transition: {
8590
                property: 'transform',
8591
                transitionClass: 'transitioning'
8592
              }
8593
            })
8594
          })])
8595
      };
8596
    };
8597
    var sketch$9 = function (settings) {
8598
      var dataset = convert$1(settings.formats, function () {
8599
        return memMenu;
8600
      });
8601
      var memMenu = record(tieredMenu.sketch({
8602
        dom: {
8603
          tag: 'div',
8604
          classes: [Styles.resolve('styles-menu')]
8605
        },
8606
        components: [],
8607
        fakeFocus: true,
8608
        stayInDom: true,
8609
        onExecute: function (tmenu, item) {
8610
          var v = Representing.getValue(item);
8611
          settings.handle(item, v.value);
8612
          return Option.none();
8613
        },
8614
        onEscape: function () {
8615
          return Option.none();
8616
        },
8617
        onOpenMenu: function (container, menu) {
8618
          var w = get$7(container.element());
8619
          set$4(menu.element(), w);
8620
          Transitioning.jumpTo(menu, 'current');
8621
        },
8622
        onOpenSubmenu: function (container, item, submenu) {
8623
          var w = get$7(container.element());
8624
          var menu = ancestor$2(item.element(), '[role="menu"]').getOrDie('hacky');
8625
          var menuComp = container.getSystem().getByDom(menu).getOrDie();
8626
          set$4(submenu.element(), w);
8627
          Transitioning.progressTo(menuComp, 'before');
8628
          Transitioning.jumpTo(submenu, 'after');
8629
          Transitioning.progressTo(submenu, 'current');
8630
        },
8631
        onCollapseMenu: function (container, item, menu) {
8632
          var submenu = ancestor$2(item.element(), '[role="menu"]').getOrDie('hacky');
8633
          var submenuComp = container.getSystem().getByDom(submenu).getOrDie();
8634
          Transitioning.progressTo(submenuComp, 'after');
8635
          Transitioning.progressTo(menu, 'current');
8636
        },
8637
        navigateOnHover: false,
8638
        openImmediately: true,
8639
        data: dataset.tmenu,
8640
        markers: {
8641
          backgroundMenu: Styles.resolve('styles-background-menu'),
8642
          menu: Styles.resolve('styles-menu'),
8643
          selectedMenu: Styles.resolve('styles-selected-menu'),
8644
          item: Styles.resolve('styles-item'),
8645
          selectedItem: Styles.resolve('styles-selected-item')
8646
        }
8647
      }));
8648
      return memMenu.asSpec();
8649
    };
8650
    var StylesMenu = { sketch: sketch$9 };
8651
8652
    var getFromExpandingItem = function (item) {
8653
      var newItem = deepMerge(exclude$1(item, ['items']), { menu: true });
8654
      var rest = expand(item.items);
8655
      var newMenus = deepMerge(rest.menus, wrap$2(item.title, rest.items));
8656
      var newExpansions = deepMerge(rest.expansions, wrap$2(item.title, item.title));
8657
      return {
8658
        item: newItem,
8659
        menus: newMenus,
8660
        expansions: newExpansions
8661
      };
8662
    };
8663
    var getFromItem = function (item) {
8664
      return hasKey$1(item, 'items') ? getFromExpandingItem(item) : {
8665
        item: item,
8666
        menus: {},
8667
        expansions: {}
8668
      };
8669
    };
8670
    var expand = function (items) {
8671
      return foldr(items, function (acc, item) {
8672
        var newData = getFromItem(item);
8673
        return {
8674
          menus: deepMerge(acc.menus, newData.menus),
8675
          items: [newData.item].concat(acc.items),
8676
          expansions: deepMerge(acc.expansions, newData.expansions)
8677
        };
8678
      }, {
8679
        menus: {},
8680
        expansions: {},
8681
        items: []
8682
      });
8683
    };
8684
    var StyleConversions = { expand: expand };
8685
8686
    var register$1 = function (editor, settings) {
8687
      var isSelectedFor = function (format) {
8688
        return function () {
8689
          return editor.formatter.match(format);
8690
        };
8691
      };
8692
      var getPreview = function (format) {
8693
        return function () {
8694
          var styles = editor.formatter.getCssText(format);
8695
          return styles;
8696
        };
8697
      };
8698
      var enrichSupported = function (item) {
8699
        return deepMerge(item, {
8700
          isSelected: isSelectedFor(item.format),
8701
          getPreview: getPreview(item.format)
8702
        });
8703
      };
8704
      var enrichMenu = function (item) {
8705
        return deepMerge(item, {
8706
          isSelected: constant(false),
8707
          getPreview: constant('')
8708
        });
8709
      };
8710
      var enrichCustom = function (item) {
8711
        var formatName = generate$1(item.title);
8712
        var newItem = deepMerge(item, {
8713
          format: formatName,
8714
          isSelected: isSelectedFor(formatName),
8715
          getPreview: getPreview(formatName)
8716
        });
8717
        editor.formatter.register(formatName, newItem);
8718
        return newItem;
8719
      };
8720
      var formats = readOptFrom$1(settings, 'style_formats').getOr(DefaultStyleFormats);
8721
      var doEnrich = function (items) {
8722
        return map$1(items, function (item) {
8723
          if (hasKey$1(item, 'items')) {
8724
            var newItems = doEnrich(item.items);
8725
            return deepMerge(enrichMenu(item), { items: newItems });
8726
          } else if (hasKey$1(item, 'format')) {
8727
            return enrichSupported(item);
8728
          } else {
8729
            return enrichCustom(item);
8730
          }
8731
        });
8732
      };
8733
      return doEnrich(formats);
8734
    };
8735
    var prune = function (editor, formats) {
8736
      var doPrune = function (items) {
8737
        return bind(items, function (item) {
8738
          if (item.items !== undefined) {
8739
            var newItems = doPrune(item.items);
8740
            return newItems.length > 0 ? [item] : [];
8741
          } else {
8742
            var keep = hasKey$1(item, 'format') ? editor.formatter.canApply(item.format) : true;
8743
            return keep ? [item] : [];
8744
          }
8745
        });
8746
      };
8747
      var prunedItems = doPrune(formats);
8748
      return StyleConversions.expand(prunedItems);
8749
    };
8750
    var ui = function (editor, formats, onDone) {
8751
      var pruned = prune(editor, formats);
8752
      return StylesMenu.sketch({
8753
        formats: pruned,
8754
        handle: function (item, value) {
8755
          editor.undoManager.transact(function () {
8756
            if (Toggling.isOn(item)) {
8757
              editor.formatter.remove(value);
8758
            } else {
8759
              editor.formatter.apply(value);
8760
            }
8761
          });
8762
          onDone();
8763
        }
8764
      });
8765
    };
8766
    var StyleFormats = {
8767
      register: register$1,
8768
      ui: ui
8769
    };
8770
8771
    var defaults = [
8772
      'undo',
8773
      'bold',
8774
      'italic',
8775
      'link',
8776
      'image',
8777
      'bullist',
8778
      'styleselect'
8779
    ];
8780
    var extract$1 = function (rawToolbar) {
8781
      var toolbar = rawToolbar.replace(/\|/g, ' ').trim();
8782
      return toolbar.length > 0 ? toolbar.split(/\s+/) : [];
8783
    };
8784
    var identifyFromArray = function (toolbar) {
8785
      return bind(toolbar, function (item) {
8786
        return isArray(item) ? identifyFromArray(item) : extract$1(item);
8787
      });
8788
    };
8789
    var identify = function (settings) {
8790
      var toolbar = settings.toolbar !== undefined ? settings.toolbar : defaults;
8791
      return isArray(toolbar) ? identifyFromArray(toolbar) : extract$1(toolbar);
8792
    };
8793
    var setup = function (realm, editor) {
8794
      var commandSketch = function (name) {
8795
        return function () {
8796
          return Buttons.forToolbarCommand(editor, name);
8797
        };
8798
      };
8799
      var stateCommandSketch = function (name) {
8800
        return function () {
8801
          return Buttons.forToolbarStateCommand(editor, name);
8802
        };
8803
      };
8804
      var actionSketch = function (name, query, action) {
8805
        return function () {
8806
          return Buttons.forToolbarStateAction(editor, name, query, action);
8807
        };
8808
      };
8809
      var undo = commandSketch('undo');
8810
      var redo = commandSketch('redo');
8811
      var bold = stateCommandSketch('bold');
8812
      var italic = stateCommandSketch('italic');
8813
      var underline = stateCommandSketch('underline');
8814
      var removeformat = commandSketch('removeformat');
8815
      var link = function () {
8816
        return sketch$8(realm, editor);
8817
      };
8818
      var unlink = actionSketch('unlink', 'link', function () {
8819
        editor.execCommand('unlink', null, false);
8820
      });
8821
      var image = function () {
8822
        return sketch$5(editor);
8823
      };
8824
      var bullist = actionSketch('unordered-list', 'ul', function () {
8825
        editor.execCommand('InsertUnorderedList', null, false);
8826
      });
8827
      var numlist = actionSketch('ordered-list', 'ol', function () {
8828
        editor.execCommand('InsertOrderedList', null, false);
8829
      });
8830
      var fontsizeselect = function () {
8831
        return sketch$4(realm, editor);
8832
      };
8833
      var forecolor = function () {
8834
        return ColorSlider.sketch(realm, editor);
8835
      };
8836
      var styleFormats = StyleFormats.register(editor, editor.settings);
8837
      var styleFormatsMenu = function () {
8838
        return StyleFormats.ui(editor, styleFormats, function () {
8839
          editor.fire('scrollIntoView');
8840
        });
8841
      };
8842
      var styleselect = function () {
8843
        return Buttons.forToolbar('style-formats', function (button) {
8844
          editor.fire('toReading');
8845
          realm.dropup().appear(styleFormatsMenu, Toggling.on, button);
8846
        }, derive$2([
8847
          Toggling.config({
8848
            toggleClass: Styles.resolve('toolbar-button-selected'),
8849
            toggleOnExecute: false,
8850
            aria: { mode: 'pressed' }
8851
          }),
8852
          Receiving.config({
8853
            channels: wrapAll$1([
8854
              Receivers.receive(TinyChannels.orientationChanged(), Toggling.off),
8855
              Receivers.receive(TinyChannels.dropupDismissed(), Toggling.off)
8856
            ])
8857
          })
8858
        ]));
8859
      };
8860
      var feature = function (prereq, sketch) {
8861
        return {
8862
          isSupported: function () {
8863
            return prereq.forall(function (p) {
8864
              return hasKey$1(editor.buttons, p);
8865
            });
8866
          },
8867
          sketch: sketch
8868
        };
8869
      };
8870
      return {
8871
        undo: feature(Option.none(), undo),
8872
        redo: feature(Option.none(), redo),
8873
        bold: feature(Option.none(), bold),
8874
        italic: feature(Option.none(), italic),
8875
        underline: feature(Option.none(), underline),
8876
        removeformat: feature(Option.none(), removeformat),
8877
        link: feature(Option.none(), link),
8878
        unlink: feature(Option.none(), unlink),
8879
        image: feature(Option.none(), image),
8880
        bullist: feature(Option.some('bullist'), bullist),
8881
        numlist: feature(Option.some('numlist'), numlist),
8882
        fontsizeselect: feature(Option.none(), fontsizeselect),
8883
        forecolor: feature(Option.none(), forecolor),
8884
        styleselect: feature(Option.none(), styleselect)
8885
      };
8886
    };
8887
    var detect$4 = function (settings, features) {
8888
      var itemNames = identify(settings);
8889
      var present = {};
8890
      return bind(itemNames, function (iName) {
8891
        var r = !hasKey$1(present, iName) && hasKey$1(features, iName) && features[iName].isSupported() ? [features[iName].sketch()] : [];
8892
        present[iName] = true;
8893
        return r;
8894
      });
8895
    };
8896
    var Features = {
8897
      identify: identify,
8898
      setup: setup,
8899
      detect: detect$4
8900
    };
8901
8902
    var mkEvent = function (target, x, y, stop, prevent, kill, raw) {
8903
      return {
8904
        'target': constant(target),
8905
        'x': constant(x),
8906
        'y': constant(y),
8907
        'stop': stop,
8908
        'prevent': prevent,
8909
        'kill': kill,
8910
        'raw': constant(raw)
8911
      };
8912
    };
8913
    var handle = function (filter, handler) {
8914
      return function (rawEvent) {
8915
        if (!filter(rawEvent))
8916
          return;
8917
        var target = Element$$1.fromDom(rawEvent.target);
8918
        var stop = function () {
8919
          rawEvent.stopPropagation();
8920
        };
8921
        var prevent = function () {
8922
          rawEvent.preventDefault();
8923
        };
8924
        var kill = compose(prevent, stop);
8925
        var evt = mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent);
8926
        handler(evt);
8927
      };
8928
    };
8929
    var binder = function (element, event, filter, handler, useCapture) {
8930
      var wrapped = handle(filter, handler);
8931
      element.dom().addEventListener(event, wrapped, useCapture);
8932
      return { unbind: curry(unbind, element, event, wrapped, useCapture) };
8933
    };
8934
    var bind$1 = function (element, event, filter, handler) {
8935
      return binder(element, event, filter, handler, false);
8936
    };
8937
    var capture = function (element, event, filter, handler) {
8938
      return binder(element, event, filter, handler, true);
8939
    };
8940
    var unbind = function (element, event, handler, useCapture) {
8941
      element.dom().removeEventListener(event, handler, useCapture);
8942
    };
8943
8944
    var filter$1 = constant(true);
8945
    var bind$2 = function (element, event, handler) {
8946
      return bind$1(element, event, filter$1, handler);
8947
    };
8948
    var capture$1 = function (element, event, handler) {
8949
      return capture(element, event, filter$1, handler);
8950
    };
8951
8952
    var INTERVAL = 50;
8953
    var INSURANCE = 1000 / INTERVAL;
8954
    var get$c = function (outerWindow) {
8955
      var isPortrait = outerWindow.matchMedia('(orientation: portrait)').matches;
8956
      return { isPortrait: constant(isPortrait) };
8957
    };
8958
    var getActualWidth = function (outerWindow) {
8959
      var isIos = PlatformDetection$1.detect().os.isiOS();
8960
      var isPortrait = get$c(outerWindow).isPortrait();
8961
      return isIos && !isPortrait ? outerWindow.screen.height : outerWindow.screen.width;
8962
    };
8963
    var onChange = function (outerWindow, listeners) {
8964
      var win = Element$$1.fromDom(outerWindow);
8965
      var poller = null;
8966
      var change = function () {
8967
        clearInterval(poller);
8968
        var orientation = get$c(outerWindow);
8969
        listeners.onChange(orientation);
8970
        onAdjustment(function () {
8971
          listeners.onReady(orientation);
8972
        });
8973
      };
8974
      var orientationHandle = bind$2(win, 'orientationchange', change);
8975
      var onAdjustment = function (f) {
8976
        clearInterval(poller);
8977
        var flag = outerWindow.innerHeight;
8978
        var insurance = 0;
8979
        poller = setInterval(function () {
8980
          if (flag !== outerWindow.innerHeight) {
8981
            clearInterval(poller);
8982
            f(Option.some(outerWindow.innerHeight));
8983
          } else if (insurance > INSURANCE) {
8984
            clearInterval(poller);
8985
            f(Option.none());
8986
          }
8987
          insurance++;
8988
        }, INTERVAL);
8989
      };
8990
      var destroy = function () {
8991
        orientationHandle.unbind();
8992
      };
8993
      return {
8994
        onAdjustment: onAdjustment,
8995
        destroy: destroy
8996
      };
8997
    };
8998
    var Orientation = {
8999
      get: get$c,
9000
      onChange: onChange,
9001
      getActualWidth: getActualWidth
9002
    };
9003
9004
    function DelayedFunction (fun, delay) {
9005
      var ref = null;
9006
      var schedule = function () {
9007
        var args = [];
9008
        for (var _i = 0; _i < arguments.length; _i++) {
9009
          args[_i] = arguments[_i];
9010
        }
9011
        ref = setTimeout(function () {
9012
          fun.apply(null, args);
9013
          ref = null;
9014
        }, delay);
9015
      };
9016
      var cancel = function () {
9017
        if (ref !== null) {
9018
          clearTimeout(ref);
9019
          ref = null;
9020
        }
9021
      };
9022
      return {
9023
        cancel: cancel,
9024
        schedule: schedule
9025
      };
9026
    }
9027
9028
    var SIGNIFICANT_MOVE = 5;
9029
    var LONGPRESS_DELAY = 400;
9030
    var getTouch = function (event) {
9031
      var raw = event.raw();
9032
      if (raw.touches === undefined || raw.touches.length !== 1) {
9033
        return Option.none();
9034
      }
9035
      return Option.some(raw.touches[0]);
9036
    };
9037
    var isFarEnough = function (touch, data) {
9038
      var distX = Math.abs(touch.clientX - data.x());
9039
      var distY = Math.abs(touch.clientY - data.y());
9040
      return distX > SIGNIFICANT_MOVE || distY > SIGNIFICANT_MOVE;
9041
    };
9042
    var monitor = function (settings) {
9043
      var startData = Cell(Option.none());
9044
      var longpress$$1 = DelayedFunction(function (event) {
9045
        startData.set(Option.none());
9046
        settings.triggerEvent(longpress(), event);
9047
      }, LONGPRESS_DELAY);
9048
      var handleTouchstart = function (event) {
9049
        getTouch(event).each(function (touch) {
9050
          longpress$$1.cancel();
9051
          var data = {
9052
            x: constant(touch.clientX),
9053
            y: constant(touch.clientY),
9054
            target: event.target
9055
          };
9056
          longpress$$1.schedule(event);
9057
          startData.set(Option.some(data));
9058
        });
9059
        return Option.none();
9060
      };
9061
      var handleTouchmove = function (event) {
9062
        longpress$$1.cancel();
9063
        getTouch(event).each(function (touch) {
9064
          startData.get().each(function (data) {
9065
            if (isFarEnough(touch, data)) {
9066
              startData.set(Option.none());
9067
            }
9068
          });
9069
        });
9070
        return Option.none();
9071
      };
9072
      var handleTouchend = function (event) {
9073
        longpress$$1.cancel();
9074
        var isSame = function (data) {
9075
          return eq(data.target(), event.target());
9076
        };
9077
        return startData.get().filter(isSame).map(function (data) {
9078
          return settings.triggerEvent(tap(), event);
9079
        });
9080
      };
9081
      var handlers = wrapAll$1([
9082
        {
9083
          key: touchstart(),
9084
          value: handleTouchstart
9085
        },
9086
        {
9087
          key: touchmove(),
9088
          value: handleTouchmove
9089
        },
9090
        {
9091
          key: touchend(),
9092
          value: handleTouchend
9093
        }
9094
      ]);
9095
      var fireIfReady = function (event, type) {
9096
        return readOptFrom$1(handlers, type).bind(function (handler) {
9097
          return handler(event);
9098
        });
9099
      };
9100
      return { fireIfReady: fireIfReady };
9101
    };
9102
9103
    var monitor$1 = function (editorApi) {
9104
      var tapEvent = monitor({
9105
        triggerEvent: function (type, evt) {
9106
          editorApi.onTapContent(evt);
9107
        }
9108
      });
9109
      var onTouchend = function () {
9110
        return bind$2(editorApi.body(), 'touchend', function (evt) {
9111
          tapEvent.fireIfReady(evt, 'touchend');
9112
        });
9113
      };
9114
      var onTouchmove = function () {
9115
        return bind$2(editorApi.body(), 'touchmove', function (evt) {
9116
          tapEvent.fireIfReady(evt, 'touchmove');
9117
        });
9118
      };
9119
      var fireTouchstart = function (evt) {
9120
        tapEvent.fireIfReady(evt, 'touchstart');
9121
      };
9122
      return {
9123
        fireTouchstart: fireTouchstart,
9124
        onTouchend: onTouchend,
9125
        onTouchmove: onTouchmove
9126
      };
9127
    };
9128
    var TappingEvent = { monitor: monitor$1 };
9129
9130
    var isAndroid6 = PlatformDetection$1.detect().os.version.major >= 6;
9131
    var initEvents = function (editorApi, toolstrip, alloy) {
9132
      var tapping = TappingEvent.monitor(editorApi);
9133
      var outerDoc = owner(toolstrip);
9134
      var isRanged = function (sel) {
9135
        return !eq(sel.start(), sel.finish()) || sel.soffset() !== sel.foffset();
9136
      };
9137
      var hasRangeInUi = function () {
9138
        return active(outerDoc).filter(function (input) {
9139
          return name(input) === 'input';
9140
        }).exists(function (input) {
9141
          return input.dom().selectionStart !== input.dom().selectionEnd;
9142
        });
9143
      };
9144
      var updateMargin = function () {
9145
        var rangeInContent = editorApi.doc().dom().hasFocus() && editorApi.getSelection().exists(isRanged);
9146
        alloy.getByDom(toolstrip).each((rangeInContent || hasRangeInUi()) === true ? Toggling.on : Toggling.off);
9147
      };
9148
      var listeners = [
9149
        bind$2(editorApi.body(), 'touchstart', function (evt) {
9150
          editorApi.onTouchContent();
9151
          tapping.fireTouchstart(evt);
9152
        }),
9153
        tapping.onTouchmove(),
9154
        tapping.onTouchend(),
9155
        bind$2(toolstrip, 'touchstart', function (evt) {
9156
          editorApi.onTouchToolstrip();
9157
        }),
9158
        editorApi.onToReading(function () {
9159
          blur$$1(editorApi.body());
9160
        }),
9161
        editorApi.onToEditing(noop),
9162
        editorApi.onScrollToCursor(function (tinyEvent) {
9163
          tinyEvent.preventDefault();
9164
          editorApi.getCursorBox().each(function (bounds) {
9165
            var cWin = editorApi.win();
9166
            var isOutside = bounds.top() > cWin.innerHeight || bounds.bottom() > cWin.innerHeight;
9167
            var cScrollBy = isOutside ? bounds.bottom() - cWin.innerHeight + 50 : 0;
9168
            if (cScrollBy !== 0) {
9169
              cWin.scrollTo(cWin.pageXOffset, cWin.pageYOffset + cScrollBy);
9170
            }
9171
          });
9172
        })
9173
      ].concat(isAndroid6 === true ? [] : [
9174
        bind$2(Element$$1.fromDom(editorApi.win()), 'blur', function () {
9175
          alloy.getByDom(toolstrip).each(Toggling.off);
9176
        }),
9177
        bind$2(outerDoc, 'select', updateMargin),
9178
        bind$2(editorApi.doc(), 'selectionchange', updateMargin)
9179
      ]);
9180
      var destroy = function () {
9181
        each$1(listeners, function (l) {
9182
          l.unbind();
9183
        });
9184
      };
9185
      return { destroy: destroy };
9186
    };
9187
    var AndroidEvents = { initEvents: initEvents };
9188
9189
    var safeParse = function (element, attribute) {
9190
      var parsed = parseInt(get$1(element, attribute), 10);
9191
      return isNaN(parsed) ? 0 : parsed;
9192
    };
9193
    var DataAttributes = { safeParse: safeParse };
9194
9195
    function NodeValue (is, name) {
9196
      var get = function (element) {
9197
        if (!is(element))
9198
          throw new Error('Can only get ' + name + ' value of a ' + name + ' node');
9199
        return getOption(element).getOr('');
9200
      };
9201
      var getOptionIE10 = function (element) {
9202
        try {
9203
          return getOptionSafe(element);
9204
        } catch (e) {
9205
          return Option.none();
9206
        }
9207
      };
9208
      var getOptionSafe = function (element) {
9209
        return is(element) ? Option.from(element.dom().nodeValue) : Option.none();
9210
      };
9211
      var browser = PlatformDetection$1.detect().browser;
9212
      var getOption = browser.isIE() && browser.version.major === 10 ? getOptionIE10 : getOptionSafe;
9213
      var set = function (element, value) {
9214
        if (!is(element))
9215
          throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');
9216
        element.dom().nodeValue = value;
9217
      };
9218
      return {
9219
        get: get,
9220
        getOption: getOption,
9221
        set: set
9222
      };
9223
    }
9224
9225
    var api$3 = NodeValue(isText, 'text');
9226
    var get$d = function (element) {
9227
      return api$3.get(element);
9228
    };
9229
    var getOption = function (element) {
9230
      return api$3.getOption(element);
9231
    };
9232
9233
    var getEnd = function (element) {
9234
      return name(element) === 'img' ? 1 : getOption(element).fold(function () {
9235
        return children(element).length;
9236
      }, function (v) {
9237
        return v.length;
9238
      });
9239
    };
9240
    var NBSP = '\xA0';
9241
    var isTextNodeWithCursorPosition = function (el) {
9242
      return getOption(el).filter(function (text) {
9243
        return text.trim().length !== 0 || text.indexOf(NBSP) > -1;
9244
      }).isSome();
9245
    };
9246
    var elementsWithCursorPosition = [
9247
      'img',
9248
      'br'
9249
    ];
9250
    var isCursorPosition = function (elem) {
9251
      var hasCursorPosition = isTextNodeWithCursorPosition(elem);
9252
      return hasCursorPosition || contains(elementsWithCursorPosition, name(elem));
9253
    };
9254
9255
    var adt$4 = Adt.generate([
9256
      { 'before': ['element'] },
9257
      {
9258
        'on': [
9259
          'element',
9260
          'offset'
9261
        ]
9262
      },
9263
      { after: ['element'] }
9264
    ]);
9265
    var cata = function (subject, onBefore, onOn, onAfter) {
9266
      return subject.fold(onBefore, onOn, onAfter);
9267
    };
9268
    var getStart = function (situ) {
9269
      return situ.fold(identity, identity, identity);
9270
    };
9271
    var before$2 = adt$4.before;
9272
    var on$1 = adt$4.on;
9273
    var after$2 = adt$4.after;
9274
    var Situ = {
9275
      before: before$2,
9276
      on: on$1,
9277
      after: after$2,
9278
      cata: cata,
9279
      getStart: getStart
9280
    };
9281
9282
    var type$1 = Adt.generate([
9283
      { domRange: ['rng'] },
9284
      {
9285
        relative: [
9286
          'startSitu',
9287
          'finishSitu'
9288
        ]
9289
      },
9290
      {
9291
        exact: [
9292
          'start',
9293
          'soffset',
9294
          'finish',
9295
          'foffset'
9296
        ]
9297
      }
9298
    ]);
9299
    var range$1 = Immutable('start', 'soffset', 'finish', 'foffset');
9300
    var relative = type$1.relative;
9301
    var exact = type$1.exact;
9302
9303
    var makeRange = function (start, soffset, finish, foffset) {
9304
      var doc = owner(start);
9305
      var rng = doc.dom().createRange();
9306
      rng.setStart(start.dom(), soffset);
9307
      rng.setEnd(finish.dom(), foffset);
9308
      return rng;
9309
    };
9310
    var after$3 = function (start, soffset, finish, foffset) {
9311
      var r = makeRange(start, soffset, finish, foffset);
9312
      var same = eq(start, finish) && soffset === foffset;
9313
      return r.collapsed && !same;
9314
    };
9315
9316
    var setStart = function (rng, situ) {
9317
      situ.fold(function (e) {
9318
        rng.setStartBefore(e.dom());
9319
      }, function (e, o) {
9320
        rng.setStart(e.dom(), o);
9321
      }, function (e) {
9322
        rng.setStartAfter(e.dom());
9323
      });
9324
    };
9325
    var setFinish = function (rng, situ) {
9326
      situ.fold(function (e) {
9327
        rng.setEndBefore(e.dom());
9328
      }, function (e, o) {
9329
        rng.setEnd(e.dom(), o);
9330
      }, function (e) {
9331
        rng.setEndAfter(e.dom());
9332
      });
9333
    };
9334
    var relativeToNative = function (win, startSitu, finishSitu) {
9335
      var range = win.document.createRange();
9336
      setStart(range, startSitu);
9337
      setFinish(range, finishSitu);
9338
      return range;
9339
    };
9340
    var exactToNative = function (win, start, soffset, finish, foffset) {
9341
      var rng = win.document.createRange();
9342
      rng.setStart(start.dom(), soffset);
9343
      rng.setEnd(finish.dom(), foffset);
9344
      return rng;
9345
    };
9346
    var toRect = function (rect) {
9347
      return {
9348
        left: constant(rect.left),
9349
        top: constant(rect.top),
9350
        right: constant(rect.right),
9351
        bottom: constant(rect.bottom),
9352
        width: constant(rect.width),
9353
        height: constant(rect.height)
9354
      };
9355
    };
9356
    var getFirstRect = function (rng) {
9357
      var rects = rng.getClientRects();
9358
      var rect = rects.length > 0 ? rects[0] : rng.getBoundingClientRect();
9359
      return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect) : Option.none();
9360
    };
9361
9362
    var adt$5 = Adt.generate([
9363
      {
9364
        ltr: [
9365
          'start',
9366
          'soffset',
9367
          'finish',
9368
          'foffset'
9369
        ]
9370
      },
9371
      {
9372
        rtl: [
9373
          'start',
9374
          'soffset',
9375
          'finish',
9376
          'foffset'
9377
        ]
9378
      }
9379
    ]);
9380
    var fromRange = function (win, type, range) {
9381
      return type(Element$$1.fromDom(range.startContainer), range.startOffset, Element$$1.fromDom(range.endContainer), range.endOffset);
9382
    };
9383
    var getRanges = function (win, selection) {
9384
      return selection.match({
9385
        domRange: function (rng) {
9386
          return {
9387
            ltr: constant(rng),
9388
            rtl: Option.none
9389
          };
9390
        },
9391
        relative: function (startSitu, finishSitu) {
9392
          return {
9393
            ltr: cached(function () {
9394
              return relativeToNative(win, startSitu, finishSitu);
9395
            }),
9396
            rtl: cached(function () {
9397
              return Option.some(relativeToNative(win, finishSitu, startSitu));
9398
            })
9399
          };
9400
        },
9401
        exact: function (start, soffset, finish, foffset) {
9402
          return {
9403
            ltr: cached(function () {
9404
              return exactToNative(win, start, soffset, finish, foffset);
9405
            }),
9406
            rtl: cached(function () {
9407
              return Option.some(exactToNative(win, finish, foffset, start, soffset));
9408
            })
9409
          };
9410
        }
9411
      });
9412
    };
9413
    var doDiagnose = function (win, ranges) {
9414
      var rng = ranges.ltr();
9415
      if (rng.collapsed) {
9416
        var reversed = ranges.rtl().filter(function (rev) {
9417
          return rev.collapsed === false;
9418
        });
9419
        return reversed.map(function (rev) {
9420
          return adt$5.rtl(Element$$1.fromDom(rev.endContainer), rev.endOffset, Element$$1.fromDom(rev.startContainer), rev.startOffset);
9421
        }).getOrThunk(function () {
9422
          return fromRange(win, adt$5.ltr, rng);
9423
        });
9424
      } else {
9425
        return fromRange(win, adt$5.ltr, rng);
9426
      }
9427
    };
9428
    var diagnose = function (win, selection) {
9429
      var ranges = getRanges(win, selection);
9430
      return doDiagnose(win, ranges);
9431
    };
9432
    var asLtrRange = function (win, selection) {
9433
      var diagnosis = diagnose(win, selection);
9434
      return diagnosis.match({
9435
        ltr: function (start, soffset, finish, foffset) {
9436
          var rng = win.document.createRange();
9437
          rng.setStart(start.dom(), soffset);
9438
          rng.setEnd(finish.dom(), foffset);
9439
          return rng;
9440
        },
9441
        rtl: function (start, soffset, finish, foffset) {
9442
          var rng = win.document.createRange();
9443
          rng.setStart(finish.dom(), foffset);
9444
          rng.setEnd(start.dom(), soffset);
9445
          return rng;
9446
        }
9447
      });
9448
    };
9449
9450
    var searchForPoint = function (rectForOffset, x, y, maxX, length) {
9451
      if (length === 0)
9452
        return 0;
9453
      else if (x === maxX)
9454
        return length - 1;
9455
      var xDelta = maxX;
9456
      for (var i = 1; i < length; i++) {
9457
        var rect = rectForOffset(i);
9458
        var curDeltaX = Math.abs(x - rect.left);
9459
        if (y <= rect.bottom) {
9460
          if (y < rect.top || curDeltaX > xDelta) {
9461
            return i - 1;
9462
          } else {
9463
            xDelta = curDeltaX;
9464
          }
9465
        }
9466
      }
9467
      return 0;
9468
    };
9469
    var inRect = function (rect, x, y) {
9470
      return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
9471
    };
9472
9473
    var locateOffset = function (doc, textnode, x, y, rect) {
9474
      var rangeForOffset = function (offset) {
9475
        var r = doc.dom().createRange();
9476
        r.setStart(textnode.dom(), offset);
9477
        r.collapse(true);
9478
        return r;
9479
      };
9480
      var rectForOffset = function (offset) {
9481
        var r = rangeForOffset(offset);
9482
        return r.getBoundingClientRect();
9483
      };
9484
      var length = get$d(textnode).length;
9485
      var offset = searchForPoint(rectForOffset, x, y, rect.right, length);
9486
      return rangeForOffset(offset);
9487
    };
9488
    var locate$1 = function (doc, node, x, y) {
9489
      var r = doc.dom().createRange();
9490
      r.selectNode(node.dom());
9491
      var rects = r.getClientRects();
9492
      var foundRect = findMap(rects, function (rect) {
9493
        return inRect(rect, x, y) ? Option.some(rect) : Option.none();
9494
      });
9495
      return foundRect.map(function (rect) {
9496
        return locateOffset(doc, node, x, y, rect);
9497
      });
9498
    };
9499
9500
    var searchInChildren = function (doc, node, x, y) {
9501
      var r = doc.dom().createRange();
9502
      var nodes = children(node);
9503
      return findMap(nodes, function (n) {
9504
        r.selectNode(n.dom());
9505
        return inRect(r.getBoundingClientRect(), x, y) ? locateNode(doc, n, x, y) : Option.none();
9506
      });
9507
    };
9508
    var locateNode = function (doc, node, x, y) {
9509
      var locator = isText(node) ? locate$1 : searchInChildren;
9510
      return locator(doc, node, x, y);
9511
    };
9512
    var locate$2 = function (doc, node, x, y) {
9513
      var r = doc.dom().createRange();
9514
      r.selectNode(node.dom());
9515
      var rect = r.getBoundingClientRect();
9516
      var boundedX = Math.max(rect.left, Math.min(rect.right, x));
9517
      var boundedY = Math.max(rect.top, Math.min(rect.bottom, y));
9518
      return locateNode(doc, node, boundedX, boundedY);
9519
    };
9520
9521
    var first$3 = function (element) {
9522
      return descendant(element, isCursorPosition);
9523
    };
9524
    var last$2 = function (element) {
9525
      return descendantRtl(element, isCursorPosition);
9526
    };
9527
    var descendantRtl = function (scope, predicate) {
9528
      var descend = function (element) {
9529
        var children$$1 = children(element);
9530
        for (var i = children$$1.length - 1; i >= 0; i--) {
9531
          var child$$1 = children$$1[i];
9532
          if (predicate(child$$1))
9533
            return Option.some(child$$1);
9534
          var res = descend(child$$1);
9535
          if (res.isSome())
9536
            return res;
9537
        }
9538
        return Option.none();
9539
      };
9540
      return descend(scope);
9541
    };
9542
9543
    var COLLAPSE_TO_LEFT = true;
9544
    var COLLAPSE_TO_RIGHT = false;
9545
    var getCollapseDirection = function (rect, x) {
9546
      return x - rect.left < rect.right - x ? COLLAPSE_TO_LEFT : COLLAPSE_TO_RIGHT;
9547
    };
9548
    var createCollapsedNode = function (doc, target, collapseDirection) {
9549
      var r = doc.dom().createRange();
9550
      r.selectNode(target.dom());
9551
      r.collapse(collapseDirection);
9552
      return r;
9553
    };
9554
    var locateInElement = function (doc, node, x) {
9555
      var cursorRange = doc.dom().createRange();
9556
      cursorRange.selectNode(node.dom());
9557
      var rect = cursorRange.getBoundingClientRect();
9558
      var collapseDirection = getCollapseDirection(rect, x);
9559
      var f = collapseDirection === COLLAPSE_TO_LEFT ? first$3 : last$2;
9560
      return f(node).map(function (target) {
9561
        return createCollapsedNode(doc, target, collapseDirection);
9562
      });
9563
    };
9564
    var locateInEmpty = function (doc, node, x) {
9565
      var rect = node.dom().getBoundingClientRect();
9566
      var collapseDirection = getCollapseDirection(rect, x);
9567
      return Option.some(createCollapsedNode(doc, node, collapseDirection));
9568
    };
9569
    var search$1 = function (doc, node, x) {
9570
      var f = children(node).length === 0 ? locateInEmpty : locateInElement;
9571
      return f(doc, node, x);
9572
    };
9573
9574
    var caretPositionFromPoint = function (doc, x, y) {
9575
      return Option.from(doc.dom().caretPositionFromPoint(x, y)).bind(function (pos) {
9576
        if (pos.offsetNode === null)
9577
          return Option.none();
9578
        var r = doc.dom().createRange();
9579
        r.setStart(pos.offsetNode, pos.offset);
9580
        r.collapse();
9581
        return Option.some(r);
9582
      });
9583
    };
9584
    var caretRangeFromPoint = function (doc, x, y) {
9585
      return Option.from(doc.dom().caretRangeFromPoint(x, y));
9586
    };
9587
    var searchTextNodes = function (doc, node, x, y) {
9588
      var r = doc.dom().createRange();
9589
      r.selectNode(node.dom());
9590
      var rect = r.getBoundingClientRect();
9591
      var boundedX = Math.max(rect.left, Math.min(rect.right, x));
9592
      var boundedY = Math.max(rect.top, Math.min(rect.bottom, y));
9593
      return locate$2(doc, node, boundedX, boundedY);
9594
    };
9595
    var searchFromPoint = function (doc, x, y) {
9596
      return Element$$1.fromPoint(doc, x, y).bind(function (elem) {
9597
        var fallback = function () {
9598
          return search$1(doc, elem, x);
9599
        };
9600
        return children(elem).length === 0 ? fallback() : searchTextNodes(doc, elem, x, y).orThunk(fallback);
9601
      });
9602
    };
9603
    var availableSearch = document.caretPositionFromPoint ? caretPositionFromPoint : document.caretRangeFromPoint ? caretRangeFromPoint : searchFromPoint;
9604
9605
    var beforeSpecial = function (element, offset) {
9606
      var name$$1 = name(element);
9607
      if ('input' === name$$1)
9608
        return Situ.after(element);
9609
      else if (!contains([
9610
          'br',
9611
          'img'
9612
        ], name$$1))
9613
        return Situ.on(element, offset);
9614
      else
9615
        return offset === 0 ? Situ.before(element) : Situ.after(element);
9616
    };
9617
    var preprocessExact = function (start, soffset, finish, foffset) {
9618
      var startSitu = beforeSpecial(start, soffset);
9619
      var finishSitu = beforeSpecial(finish, foffset);
9620
      return relative(startSitu, finishSitu);
9621
    };
9622
9623
    var doSetNativeRange = function (win, rng) {
9624
      Option.from(win.getSelection()).each(function (selection) {
9625
        selection.removeAllRanges();
9626
        selection.addRange(rng);
9627
      });
9628
    };
9629
    var doSetRange = function (win, start, soffset, finish, foffset) {
9630
      var rng = exactToNative(win, start, soffset, finish, foffset);
9631
      doSetNativeRange(win, rng);
9632
    };
9633
    var setLegacyRtlRange = function (win, selection, start, soffset, finish, foffset) {
9634
      selection.collapse(start.dom(), soffset);
9635
      selection.extend(finish.dom(), foffset);
9636
    };
9637
    var setRangeFromRelative = function (win, relative$$1) {
9638
      return diagnose(win, relative$$1).match({
9639
        ltr: function (start, soffset, finish, foffset) {
9640
          doSetRange(win, start, soffset, finish, foffset);
9641
        },
9642
        rtl: function (start, soffset, finish, foffset) {
9643
          var selection = win.getSelection();
9644
          if (selection.setBaseAndExtent) {
9645
            selection.setBaseAndExtent(start.dom(), soffset, finish.dom(), foffset);
9646
          } else if (selection.extend) {
9647
            try {
9648
              setLegacyRtlRange(win, selection, start, soffset, finish, foffset);
9649
            } catch (e) {
9650
              doSetRange(win, finish, foffset, start, soffset);
9651
            }
9652
          } else {
9653
            doSetRange(win, finish, foffset, start, soffset);
9654
          }
9655
        }
9656
      });
9657
    };
9658
    var setExact = function (win, start, soffset, finish, foffset) {
9659
      var relative$$1 = preprocessExact(start, soffset, finish, foffset);
9660
      setRangeFromRelative(win, relative$$1);
9661
    };
9662
    var readRange = function (selection) {
9663
      if (selection.rangeCount > 0) {
9664
        var firstRng = selection.getRangeAt(0);
9665
        var lastRng = selection.getRangeAt(selection.rangeCount - 1);
9666
        return Option.some(range$1(Element$$1.fromDom(firstRng.startContainer), firstRng.startOffset, Element$$1.fromDom(lastRng.endContainer), lastRng.endOffset));
9667
      } else {
9668
        return Option.none();
9669
      }
9670
    };
9671
    var doGetExact = function (selection) {
9672
      var anchorNode = Element$$1.fromDom(selection.anchorNode);
9673
      var focusNode = Element$$1.fromDom(selection.focusNode);
9674
      return after$3(anchorNode, selection.anchorOffset, focusNode, selection.focusOffset) ? Option.some(range$1(Element$$1.fromDom(selection.anchorNode), selection.anchorOffset, Element$$1.fromDom(selection.focusNode), selection.focusOffset)) : readRange(selection);
9675
    };
9676
    var getExact = function (win) {
9677
      return Option.from(win.getSelection()).filter(function (sel) {
9678
        return sel.rangeCount > 0;
9679
      }).bind(doGetExact);
9680
    };
9681
    var get$e = function (win) {
9682
      return getExact(win).map(function (range) {
9683
        return exact(range.start(), range.soffset(), range.finish(), range.foffset());
9684
      });
9685
    };
9686
    var getFirstRect$1 = function (win, selection) {
9687
      var rng = asLtrRange(win, selection);
9688
      return getFirstRect(rng);
9689
    };
9690
    var clear$1 = function (win) {
9691
      var selection = win.getSelection();
9692
      selection.removeAllRanges();
9693
    };
9694
9695
    var COLLAPSED_WIDTH = 2;
9696
    var collapsedRect = function (rect) {
9697
      return {
9698
        left: rect.left,
9699
        top: rect.top,
9700
        right: rect.right,
9701
        bottom: rect.bottom,
9702
        width: constant(COLLAPSED_WIDTH),
9703
        height: rect.height
9704
      };
9705
    };
9706
    var toRect$1 = function (rawRect) {
9707
      return {
9708
        left: constant(rawRect.left),
9709
        top: constant(rawRect.top),
9710
        right: constant(rawRect.right),
9711
        bottom: constant(rawRect.bottom),
9712
        width: constant(rawRect.width),
9713
        height: constant(rawRect.height)
9714
      };
9715
    };
9716
    var getRectsFromRange = function (range$$1) {
9717
      if (!range$$1.collapsed) {
9718
        return map$1(range$$1.getClientRects(), toRect$1);
9719
      } else {
9720
        var start_1 = Element$$1.fromDom(range$$1.startContainer);
9721
        return parent(start_1).bind(function (parent$$1) {
9722
          var selection = exact(start_1, range$$1.startOffset, parent$$1, getEnd(parent$$1));
9723
          var optRect = getFirstRect$1(range$$1.startContainer.ownerDocument.defaultView, selection);
9724
          return optRect.map(collapsedRect).map(pure);
9725
        }).getOr([]);
9726
      }
9727
    };
9728
    var getRectangles = function (cWin) {
9729
      var sel = cWin.getSelection();
9730
      return sel !== undefined && sel.rangeCount > 0 ? getRectsFromRange(sel.getRangeAt(0)) : [];
9731
    };
9732
    var Rectangles = { getRectangles: getRectangles };
9733
9734
    var autocompleteHack = function () {
9735
      return function (f) {
9736
        setTimeout(function () {
9737
          f();
9738
        }, 0);
9739
      };
9740
    };
9741
    var resume = function (cWin) {
9742
      cWin.focus();
9743
      var iBody = Element$$1.fromDom(cWin.document.body);
9744
      var inInput = active().exists(function (elem) {
9745
        return contains([
9746
          'input',
9747
          'textarea'
9748
        ], name(elem));
9749
      });
9750
      var transaction = inInput ? autocompleteHack() : apply;
9751
      transaction(function () {
9752
        active().each(blur$$1);
9753
        focus$2(iBody);
9754
      });
9755
    };
9756
    var ResumeEditing = { resume: resume };
9757
9758
    var EXTRA_SPACING = 50;
9759
    var data = 'data-' + Styles.resolve('last-outer-height');
9760
    var setLastHeight = function (cBody, value) {
9761
      set(cBody, data, value);
9762
    };
9763
    var getLastHeight = function (cBody) {
9764
      return DataAttributes.safeParse(cBody, data);
9765
    };
9766
    var getBoundsFrom = function (rect) {
9767
      return {
9768
        top: constant(rect.top()),
9769
        bottom: constant(rect.top() + rect.height())
9770
      };
9771
    };
9772
    var getBounds$2 = function (cWin) {
9773
      var rects = Rectangles.getRectangles(cWin);
9774
      return rects.length > 0 ? Option.some(rects[0]).map(getBoundsFrom) : Option.none();
9775
    };
9776
    var findDelta = function (outerWindow, cBody) {
9777
      var last = getLastHeight(cBody);
9778
      var current = outerWindow.innerHeight;
9779
      return last > current ? Option.some(last - current) : Option.none();
9780
    };
9781
    var calculate = function (cWin, bounds, delta) {
9782
      var isOutside = bounds.top() > cWin.innerHeight || bounds.bottom() > cWin.innerHeight;
9783
      return isOutside ? Math.min(delta, bounds.bottom() - cWin.innerHeight + EXTRA_SPACING) : 0;
9784
    };
9785
    var setup$1 = function (outerWindow, cWin) {
9786
      var cBody = Element$$1.fromDom(cWin.document.body);
9787
      var toEditing = function () {
9788
        ResumeEditing.resume(cWin);
9789
      };
9790
      var onResize = bind$2(Element$$1.fromDom(outerWindow), 'resize', function () {
9791
        findDelta(outerWindow, cBody).each(function (delta) {
9792
          getBounds$2(cWin).each(function (bounds) {
9793
            var cScrollBy = calculate(cWin, bounds, delta);
9794
            if (cScrollBy !== 0) {
9795
              cWin.scrollTo(cWin.pageXOffset, cWin.pageYOffset + cScrollBy);
9796
            }
9797
          });
9798
        });
9799
        setLastHeight(cBody, outerWindow.innerHeight);
9800
      });
9801
      setLastHeight(cBody, outerWindow.innerHeight);
9802
      var destroy = function () {
9803
        onResize.unbind();
9804
      };
9805
      return {
9806
        toEditing: toEditing,
9807
        destroy: destroy
9808
      };
9809
    };
9810
    var AndroidSetup = { setup: setup$1 };
9811
9812
    var getBodyFromFrame = function (frame) {
9813
      return Option.some(Element$$1.fromDom(frame.dom().contentWindow.document.body));
9814
    };
9815
    var getDocFromFrame = function (frame) {
9816
      return Option.some(Element$$1.fromDom(frame.dom().contentWindow.document));
9817
    };
9818
    var getWinFromFrame = function (frame) {
9819
      return Option.from(frame.dom().contentWindow);
9820
    };
9821
    var getSelectionFromFrame = function (frame) {
9822
      var optWin = getWinFromFrame(frame);
9823
      return optWin.bind(getExact);
9824
    };
9825
    var getFrame = function (editor) {
9826
      return editor.getFrame();
9827
    };
9828
    var getOrDerive = function (name, f) {
9829
      return function (editor) {
9830
        var g = editor[name].getOrThunk(function () {
9831
          var frame = getFrame(editor);
9832
          return function () {
9833
            return f(frame);
9834
          };
9835
        });
9836
        return g();
9837
      };
9838
    };
9839
    var getOrListen = function (editor, doc, name, type) {
9840
      return editor[name].getOrThunk(function () {
9841
        return function (handler) {
9842
          return bind$2(doc, type, handler);
9843
        };
9844
      });
9845
    };
9846
    var toRect$2 = function (rect) {
9847
      return {
9848
        left: constant(rect.left),
9849
        top: constant(rect.top),
9850
        right: constant(rect.right),
9851
        bottom: constant(rect.bottom),
9852
        width: constant(rect.width),
9853
        height: constant(rect.height)
9854
      };
9855
    };
9856
    var getActiveApi = function (editor) {
9857
      var frame = getFrame(editor);
9858
      var tryFallbackBox = function (win) {
9859
        var isCollapsed$$1 = function (sel) {
9860
          return eq(sel.start(), sel.finish()) && sel.soffset() === sel.foffset();
9861
        };
9862
        var toStartRect = function (sel) {
9863
          var rect = sel.start().dom().getBoundingClientRect();
9864
          return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect$2) : Option.none();
9865
        };
9866
        return getExact(win).filter(isCollapsed$$1).bind(toStartRect);
9867
      };
9868
      return getBodyFromFrame(frame).bind(function (body) {
9869
        return getDocFromFrame(frame).bind(function (doc) {
9870
          return getWinFromFrame(frame).map(function (win) {
9871
            var html = Element$$1.fromDom(doc.dom().documentElement);
9872
            var getCursorBox = editor.getCursorBox.getOrThunk(function () {
9873
              return function () {
9874
                return get$e(win).bind(function (sel) {
9875
                  return getFirstRect$1(win, sel).orThunk(function () {
9876
                    return tryFallbackBox(win);
9877
                  });
9878
                });
9879
              };
9880
            });
9881
            var setSelection = editor.setSelection.getOrThunk(function () {
9882
              return function (start, soffset, finish, foffset) {
9883
                setExact(win, start, soffset, finish, foffset);
9884
              };
9885
            });
9886
            var clearSelection = editor.clearSelection.getOrThunk(function () {
9887
              return function () {
9888
                clear$1(win);
9889
              };
9890
            });
9891
            return {
9892
              body: constant(body),
9893
              doc: constant(doc),
9894
              win: constant(win),
9895
              html: constant(html),
9896
              getSelection: curry(getSelectionFromFrame, frame),
9897
              setSelection: setSelection,
9898
              clearSelection: clearSelection,
9899
              frame: constant(frame),
9900
              onKeyup: getOrListen(editor, doc, 'onKeyup', 'keyup'),
9901
              onNodeChanged: getOrListen(editor, doc, 'onNodeChanged', 'selectionchange'),
9902
              onDomChanged: editor.onDomChanged,
9903
              onScrollToCursor: editor.onScrollToCursor,
9904
              onScrollToElement: editor.onScrollToElement,
9905
              onToReading: editor.onToReading,
9906
              onToEditing: editor.onToEditing,
9907
              onToolbarScrollStart: editor.onToolbarScrollStart,
9908
              onTouchContent: editor.onTouchContent,
9909
              onTapContent: editor.onTapContent,
9910
              onTouchToolstrip: editor.onTouchToolstrip,
9911
              getCursorBox: getCursorBox
9912
            };
9913
          });
9914
        });
9915
      });
9916
    };
9917
    var PlatformEditor = {
9918
      getBody: getOrDerive('getBody', getBodyFromFrame),
9919
      getDoc: getOrDerive('getDoc', getDocFromFrame),
9920
      getWin: getOrDerive('getWin', getWinFromFrame),
9921
      getSelection: getOrDerive('getSelection', getSelectionFromFrame),
9922
      getFrame: getFrame,
9923
      getActiveApi: getActiveApi
9924
    };
9925
9926
    var attr = 'data-ephox-mobile-fullscreen-style';
9927
    var siblingStyles = 'display:none!important;';
9928
    var ancestorPosition = 'position:absolute!important;';
9929
    var ancestorStyles = 'top:0!important;left:0!important;margin:0' + '!important;padding:0!important;width:100%!important;';
9930
    var bgFallback = 'background-color:rgb(255,255,255)!important;';
9931
    var isAndroid = PlatformDetection$1.detect().os.isAndroid();
9932
    var matchColor = function (editorBody) {
9933
      var color = get$4(editorBody, 'background-color');
9934
      return color !== undefined && color !== '' ? 'background-color:' + color + '!important' : bgFallback;
9935
    };
9936
    var clobberStyles = function (container, editorBody) {
9937
      var gatherSibilings = function (element) {
9938
        var siblings = siblings$2(element, '*');
9939
        return siblings;
9940
      };
9941
      var clobber = function (clobberStyle) {
9942
        return function (element) {
9943
          var styles = get$1(element, 'style');
9944
          var backup = styles === undefined ? 'no-styles' : styles.trim();
9945
          if (backup === clobberStyle) {
9946
            return;
9947
          } else {
9948
            set(element, attr, backup);
9949
            set(element, 'style', clobberStyle);
9950
          }
9951
        };
9952
      };
9953
      var ancestors = ancestors$1(container, '*');
9954
      var siblings = bind(ancestors, gatherSibilings);
9955
      var bgColor = matchColor(editorBody);
9956
      each$1(siblings, clobber(siblingStyles));
9957
      each$1(ancestors, clobber(ancestorPosition + ancestorStyles + bgColor));
9958
      var containerStyles = isAndroid === true ? '' : ancestorPosition;
9959
      clobber(containerStyles + ancestorStyles + bgColor)(container);
9960
    };
9961
    var restoreStyles = function () {
9962
      var clobberedEls = all$3('[' + attr + ']');
9963
      each$1(clobberedEls, function (element) {
9964
        var restore = get$1(element, attr);
9965
        if (restore !== 'no-styles') {
9966
          set(element, 'style', restore);
9967
        } else {
9968
          remove$1(element, 'style');
9969
        }
9970
        remove$1(element, attr);
9971
      });
9972
    };
9973
    var Thor = {
9974
      clobberStyles: clobberStyles,
9975
      restoreStyles: restoreStyles
9976
    };
9977
9978
    var tag = function () {
9979
      var head = first$2('head').getOrDie();
9980
      var nu = function () {
9981
        var meta = Element$$1.fromTag('meta');
9982
        set(meta, 'name', 'viewport');
9983
        append(head, meta);
9984
        return meta;
9985
      };
9986
      var element = first$2('meta[name="viewport"]').getOrThunk(nu);
9987
      var backup = get$1(element, 'content');
9988
      var maximize = function () {
9989
        set(element, 'content', 'width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0');
9990
      };
9991
      var restore = function () {
9992
        if (backup !== undefined && backup !== null && backup.length > 0) {
9993
          set(element, 'content', backup);
9994
        } else {
9995
          set(element, 'content', 'user-scalable=yes');
9996
        }
9997
      };
9998
      return {
9999
        maximize: maximize,
10000
        restore: restore
10001
      };
10002
    };
10003
    var MetaViewport = { tag: tag };
10004
10005
    var create$5 = function (platform, mask) {
10006
      var meta = MetaViewport.tag();
10007
      var androidApi = api$2();
10008
      var androidEvents = api$2();
10009
      var enter = function () {
10010
        mask.hide();
10011
        add$2(platform.container, Styles.resolve('fullscreen-maximized'));
10012
        add$2(platform.container, Styles.resolve('android-maximized'));
10013
        meta.maximize();
10014
        add$2(platform.body, Styles.resolve('android-scroll-reload'));
10015
        androidApi.set(AndroidSetup.setup(platform.win, PlatformEditor.getWin(platform.editor).getOrDie('no')));
10016
        PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) {
10017
          Thor.clobberStyles(platform.container, editorApi.body());
10018
          androidEvents.set(AndroidEvents.initEvents(editorApi, platform.toolstrip, platform.alloy));
10019
        });
10020
      };
10021
      var exit = function () {
10022
        meta.restore();
10023
        mask.show();
10024
        remove$4(platform.container, Styles.resolve('fullscreen-maximized'));
10025
        remove$4(platform.container, Styles.resolve('android-maximized'));
10026
        Thor.restoreStyles();
10027
        remove$4(platform.body, Styles.resolve('android-scroll-reload'));
10028
        androidEvents.clear();
10029
        androidApi.clear();
10030
      };
10031
      return {
10032
        enter: enter,
10033
        exit: exit
10034
      };
10035
    };
10036
    var AndroidMode = { create: create$5 };
10037
10038
    var first$4 = function (fn, rate) {
10039
      var timer = null;
10040
      var cancel = function () {
10041
        if (timer !== null) {
10042
          clearTimeout(timer);
10043
          timer = null;
10044
        }
10045
      };
10046
      var throttle = function () {
10047
        var args = [];
10048
        for (var _i = 0; _i < arguments.length; _i++) {
10049
          args[_i] = arguments[_i];
10050
        }
10051
        if (timer === null) {
10052
          timer = setTimeout(function () {
10053
            fn.apply(null, args);
10054
            timer = null;
10055
          }, rate);
10056
        }
10057
      };
10058
      return {
10059
        cancel: cancel,
10060
        throttle: throttle
10061
      };
10062
    };
10063
    var last$3 = function (fn, rate) {
10064
      var timer = null;
10065
      var cancel = function () {
10066
        if (timer !== null) {
10067
          clearTimeout(timer);
10068
          timer = null;
10069
        }
10070
      };
10071
      var throttle = function () {
10072
        var args = [];
10073
        for (var _i = 0; _i < arguments.length; _i++) {
10074
          args[_i] = arguments[_i];
10075
        }
10076
        if (timer !== null)
10077
          clearTimeout(timer);
10078
        timer = setTimeout(function () {
10079
          fn.apply(null, args);
10080
          timer = null;
10081
        }, rate);
10082
      };
10083
      return {
10084
        cancel: cancel,
10085
        throttle: throttle
10086
      };
10087
    };
10088
10089
    var sketch$a = function (onView, translate) {
10090
      var memIcon = record(Container.sketch({
10091
        dom: dom$1('<div aria-hidden="true" class="${prefix}-mask-tap-icon"></div>'),
10092
        containerBehaviours: derive$2([Toggling.config({
10093
            toggleClass: Styles.resolve('mask-tap-icon-selected'),
10094
            toggleOnExecute: false
10095
          })])
10096
      }));
10097
      var onViewThrottle = first$4(onView, 200);
10098
      return Container.sketch({
10099
        dom: dom$1('<div class="${prefix}-disabled-mask"></div>'),
10100
        components: [Container.sketch({
10101
            dom: dom$1('<div class="${prefix}-content-container"></div>'),
10102
            components: [Button.sketch({
10103
                dom: dom$1('<div class="${prefix}-content-tap-section"></div>'),
10104
                components: [memIcon.asSpec()],
10105
                action: function (button) {
10106
                  onViewThrottle.throttle();
10107
                },
10108
                buttonBehaviours: derive$2([Toggling.config({ toggleClass: Styles.resolve('mask-tap-icon-selected') })])
10109
              })]
10110
          })]
10111
      });
10112
    };
10113
    var TapToEditMask = { sketch: sketch$a };
10114
10115
    var MobileSchema = objOf([
10116
      strictObjOf('editor', [
10117
        strict$1('getFrame'),
10118
        option('getBody'),
10119
        option('getDoc'),
10120
        option('getWin'),
10121
        option('getSelection'),
10122
        option('setSelection'),
10123
        option('clearSelection'),
10124
        option('cursorSaver'),
10125
        option('onKeyup'),
10126
        option('onNodeChanged'),
10127
        option('getCursorBox'),
10128
        strict$1('onDomChanged'),
10129
        defaulted$1('onTouchContent', noop),
10130
        defaulted$1('onTapContent', noop),
10131
        defaulted$1('onTouchToolstrip', noop),
10132
        defaulted$1('onScrollToCursor', constant({ unbind: noop })),
10133
        defaulted$1('onScrollToElement', constant({ unbind: noop })),
10134
        defaulted$1('onToEditing', constant({ unbind: noop })),
10135
        defaulted$1('onToReading', constant({ unbind: noop })),
10136
        defaulted$1('onToolbarScrollStart', identity)
10137
      ]),
10138
      strict$1('socket'),
10139
      strict$1('toolstrip'),
10140
      strict$1('dropup'),
10141
      strict$1('toolbar'),
10142
      strict$1('container'),
10143
      strict$1('alloy'),
10144
      state$1('win', function (spec) {
10145
        return owner(spec.socket).dom().defaultView;
10146
      }),
10147
      state$1('body', function (spec) {
10148
        return Element$$1.fromDom(spec.socket.dom().ownerDocument.body);
10149
      }),
10150
      defaulted$1('translate', identity),
10151
      defaulted$1('setReadOnly', noop),
10152
      defaulted$1('readOnlyOnInit', constant(true))
10153
    ]);
10154
10155
    var produce = function (raw) {
10156
      var mobile = asRawOrDie('Getting AndroidWebapp schema', MobileSchema, raw);
10157
      set$2(mobile.toolstrip, 'width', '100%');
10158
      var onTap = function () {
10159
        mobile.setReadOnly(mobile.readOnlyOnInit());
10160
        mode.enter();
10161
      };
10162
      var mask = build$1(TapToEditMask.sketch(onTap, mobile.translate));
10163
      mobile.alloy.add(mask);
10164
      var maskApi = {
10165
        show: function () {
10166
          mobile.alloy.add(mask);
10167
        },
10168
        hide: function () {
10169
          mobile.alloy.remove(mask);
10170
        }
10171
      };
10172
      append(mobile.container, mask.element());
10173
      var mode = AndroidMode.create(mobile, maskApi);
10174
      return {
10175
        setReadOnly: mobile.setReadOnly,
10176
        refreshStructure: noop,
10177
        enter: mode.enter,
10178
        exit: mode.exit,
10179
        destroy: noop
10180
      };
10181
    };
10182
    var AndroidWebapp = { produce: produce };
10183
10184
    var schema$e = constant([
10185
      defaulted$1('shell', true),
10186
      field$1('toolbarBehaviours', [Replacing])
10187
    ]);
10188
    var enhanceGroups = function (detail) {
10189
      return { behaviours: derive$2([Replacing.config({})]) };
10190
    };
10191
    var parts$2 = constant([optional({
10192
        name: 'groups',
10193
        overrides: enhanceGroups
10194
      })]);
10195
10196
    var factory$4 = function (detail, components$$1, spec, _externals) {
10197
      var setGroups = function (toolbar$$1, groups) {
10198
        getGroupContainer(toolbar$$1).fold(function () {
10199
          console.error('Toolbar was defined to not be a shell, but no groups container was specified in components');
10200
          throw new Error('Toolbar was defined to not be a shell, but no groups container was specified in components');
10201
        }, function (container) {
10202
          Replacing.set(container, groups);
10203
        });
10204
      };
10205
      var getGroupContainer = function (component) {
10206
        return detail.shell() ? Option.some(component) : getPart(component, detail, 'groups');
10207
      };
10208
      var extra = detail.shell() ? {
10209
        behaviours: [Replacing.config({})],
10210
        components: []
10211
      } : {
10212
        behaviours: [],
10213
        components: components$$1
10214
      };
10215
      return {
10216
        uid: detail.uid(),
10217
        dom: detail.dom(),
10218
        components: extra.components,
10219
        behaviours: deepMerge(derive$2(extra.behaviours), get$6(detail.toolbarBehaviours())),
10220
        apis: { setGroups: setGroups },
10221
        domModification: { attributes: { role: 'group' } }
10222
      };
10223
    };
10224
    var Toolbar = composite$1({
10225
      name: 'Toolbar',
10226
      configFields: schema$e(),
10227
      partFields: parts$2(),
10228
      factory: factory$4,
10229
      apis: {
10230
        setGroups: function (apis, toolbar$$1, groups) {
10231
          apis.setGroups(toolbar$$1, groups);
10232
        }
10233
      }
10234
    });
10235
10236
    var schema$f = constant([
10237
      strict$1('items'),
10238
      markers(['itemClass']),
10239
      field$1('tgroupBehaviours', [Keying])
10240
    ]);
10241
    var parts$3 = constant([group({
10242
        name: 'items',
10243
        unit: 'item',
10244
        overrides: function (detail) {
10245
          return { domModification: { classes: [detail.markers().itemClass()] } };
10246
        }
10247
      })]);
10248
10249
    var factory$5 = function (detail, components, spec, _externals) {
10250
      return deepMerge({ dom: { attributes: { role: 'toolbar' } } }, {
10251
        'uid': detail.uid(),
10252
        'dom': detail.dom(),
10253
        'components': components,
10254
        'behaviours': deepMerge(derive$2([Keying.config({
10255
            mode: 'flow',
10256
            selector: '.' + detail.markers().itemClass()
10257
          })]), get$6(detail.tgroupBehaviours())),
10258
        'debug.sketcher': spec['debug.sketcher']
10259
      });
10260
    };
10261
    var ToolbarGroup = composite$1({
10262
      name: 'ToolbarGroup',
10263
      configFields: schema$f(),
10264
      partFields: parts$3(),
10265
      factory: factory$5
10266
    });
10267
10268
    var dataHorizontal = 'data-' + Styles.resolve('horizontal-scroll');
10269
    var canScrollVertically = function (container) {
10270
      container.dom().scrollTop = 1;
10271
      var result = container.dom().scrollTop !== 0;
10272
      container.dom().scrollTop = 0;
10273
      return result;
10274
    };
10275
    var canScrollHorizontally = function (container) {
10276
      container.dom().scrollLeft = 1;
10277
      var result = container.dom().scrollLeft !== 0;
10278
      container.dom().scrollLeft = 0;
10279
      return result;
10280
    };
10281
    var hasVerticalScroll = function (container) {
10282
      return container.dom().scrollTop > 0 || canScrollVertically(container);
10283
    };
10284
    var hasHorizontalScroll = function (container) {
10285
      return container.dom().scrollLeft > 0 || canScrollHorizontally(container);
10286
    };
10287
    var markAsHorizontal = function (container) {
10288
      set(container, dataHorizontal, 'true');
10289
    };
10290
    var hasScroll = function (container) {
10291
      return get$1(container, dataHorizontal) === 'true' ? hasHorizontalScroll(container) : hasVerticalScroll(container);
10292
    };
10293
    var exclusive = function (scope, selector) {
10294
      return bind$2(scope, 'touchmove', function (event) {
10295
        closest$2(event.target(), selector).filter(hasScroll).fold(function () {
10296
          event.raw().preventDefault();
10297
        }, noop);
10298
      });
10299
    };
10300
    var Scrollables = {
10301
      exclusive: exclusive,
10302
      markAsHorizontal: markAsHorizontal
10303
    };
10304
10305
    function ScrollingToolbar () {
10306
      var makeGroup = function (gSpec) {
10307
        var scrollClass = gSpec.scrollable === true ? '${prefix}-toolbar-scrollable-group' : '';
10308
        return {
10309
          dom: dom$1('<div aria-label="' + gSpec.label + '" class="${prefix}-toolbar-group ' + scrollClass + '"></div>'),
10310
          tgroupBehaviours: derive$2([config('adhoc-scrollable-toolbar', gSpec.scrollable === true ? [runOnInit(function (component, simulatedEvent) {
10311
                set$2(component.element(), 'overflow-x', 'auto');
10312
                Scrollables.markAsHorizontal(component.element());
10313
                Scrollable.register(component.element());
10314
              })] : [])]),
10315
          components: [Container.sketch({ components: [ToolbarGroup.parts().items({})] })],
10316
          markers: { itemClass: Styles.resolve('toolbar-group-item') },
10317
          items: gSpec.items
10318
        };
10319
      };
10320
      var toolbar = build$1(Toolbar.sketch({
10321
        dom: dom$1('<div class="${prefix}-toolbar"></div>'),
10322
        components: [Toolbar.parts().groups({})],
10323
        toolbarBehaviours: derive$2([
10324
          Toggling.config({
10325
            toggleClass: Styles.resolve('context-toolbar'),
10326
            toggleOnExecute: false,
10327
            aria: { mode: 'none' }
10328
          }),
10329
          Keying.config({ mode: 'cyclic' })
10330
        ]),
10331
        shell: true
10332
      }));
10333
      var wrapper = build$1(Container.sketch({
10334
        dom: { classes: [Styles.resolve('toolstrip')] },
10335
        components: [premade$1(toolbar)],
10336
        containerBehaviours: derive$2([Toggling.config({
10337
            toggleClass: Styles.resolve('android-selection-context-toolbar'),
10338
            toggleOnExecute: false
10339
          })])
10340
      }));
10341
      var resetGroups = function () {
10342
        Toolbar.setGroups(toolbar, initGroups.get());
10343
        Toggling.off(toolbar);
10344
      };
10345
      var initGroups = Cell([]);
10346
      var setGroups = function (gs) {
10347
        initGroups.set(gs);
10348
        resetGroups();
10349
      };
10350
      var createGroups = function (gs) {
10351
        return map$1(gs, compose(ToolbarGroup.sketch, makeGroup));
10352
      };
10353
      var refresh = function () {
10354
      };
10355
      var setContextToolbar = function (gs) {
10356
        Toggling.on(toolbar);
10357
        Toolbar.setGroups(toolbar, gs);
10358
      };
10359
      var restoreToolbar = function () {
10360
        if (Toggling.isOn(toolbar)) {
10361
          resetGroups();
10362
        }
10363
      };
10364
      var focus = function () {
10365
        Keying.focusIn(toolbar);
10366
      };
10367
      return {
10368
        wrapper: constant(wrapper),
10369
        toolbar: constant(toolbar),
10370
        createGroups: createGroups,
10371
        setGroups: setGroups,
10372
        setContextToolbar: setContextToolbar,
10373
        restoreToolbar: restoreToolbar,
10374
        refresh: refresh,
10375
        focus: focus
10376
      };
10377
    }
10378
10379
    var makeEditSwitch = function (webapp) {
10380
      return build$1(Button.sketch({
10381
        dom: dom$1('<div class="${prefix}-mask-edit-icon ${prefix}-icon"></div>'),
10382
        action: function () {
10383
          webapp.run(function (w) {
10384
            w.setReadOnly(false);
10385
          });
10386
        }
10387
      }));
10388
    };
10389
    var makeSocket = function () {
10390
      return build$1(Container.sketch({
10391
        dom: dom$1('<div class="${prefix}-editor-socket"></div>'),
10392
        components: [],
10393
        containerBehaviours: derive$2([Replacing.config({})])
10394
      }));
10395
    };
10396
    var showEdit = function (socket, switchToEdit) {
10397
      Replacing.append(socket, premade$1(switchToEdit));
10398
    };
10399
    var hideEdit = function (socket, switchToEdit) {
10400
      Replacing.remove(socket, switchToEdit);
10401
    };
10402
    var updateMode = function (socket, switchToEdit, readOnly, root) {
10403
      var swap = readOnly === true ? Swapping.toAlpha : Swapping.toOmega;
10404
      swap(root);
10405
      var f = readOnly ? showEdit : hideEdit;
10406
      f(socket, switchToEdit);
10407
    };
10408
    var CommonRealm = {
10409
      makeEditSwitch: makeEditSwitch,
10410
      makeSocket: makeSocket,
10411
      updateMode: updateMode
10412
    };
10413
10414
    var getAnimationRoot = function (component, slideConfig) {
10415
      return slideConfig.getAnimationRoot().fold(function () {
10416
        return component.element();
10417
      }, function (get) {
10418
        return get(component);
10419
      });
10420
    };
10421
    var getDimensionProperty = function (slideConfig) {
10422
      return slideConfig.dimension().property();
10423
    };
10424
    var getDimension = function (slideConfig, elem) {
10425
      return slideConfig.dimension().getDimension()(elem);
10426
    };
10427
    var disableTransitions = function (component, slideConfig) {
10428
      var root = getAnimationRoot(component, slideConfig);
10429
      remove$6(root, [
10430
        slideConfig.shrinkingClass(),
10431
        slideConfig.growingClass()
10432
      ]);
10433
    };
10434
    var setShrunk = function (component, slideConfig) {
10435
      remove$4(component.element(), slideConfig.openClass());
10436
      add$2(component.element(), slideConfig.closedClass());
10437
      set$2(component.element(), getDimensionProperty(slideConfig), '0px');
10438
      reflow(component.element());
10439
    };
10440
    var measureTargetSize = function (component, slideConfig) {
10441
      setGrown(component, slideConfig);
10442
      var expanded = getDimension(slideConfig, component.element());
10443
      setShrunk(component, slideConfig);
10444
      return expanded;
10445
    };
10446
    var setGrown = function (component, slideConfig) {
10447
      remove$4(component.element(), slideConfig.closedClass());
10448
      add$2(component.element(), slideConfig.openClass());
10449
      remove$5(component.element(), getDimensionProperty(slideConfig));
10450
    };
10451
    var doImmediateShrink = function (component, slideConfig, slideState) {
10452
      slideState.setCollapsed();
10453
      set$2(component.element(), getDimensionProperty(slideConfig), getDimension(slideConfig, component.element()));
10454
      reflow(component.element());
10455
      disableTransitions(component, slideConfig);
10456
      setShrunk(component, slideConfig);
10457
      slideConfig.onStartShrink()(component);
10458
      slideConfig.onShrunk()(component);
10459
    };
10460
    var doStartShrink = function (component, slideConfig, slideState) {
10461
      slideState.setCollapsed();
10462
      set$2(component.element(), getDimensionProperty(slideConfig), getDimension(slideConfig, component.element()));
10463
      reflow(component.element());
10464
      var root = getAnimationRoot(component, slideConfig);
10465
      add$2(root, slideConfig.shrinkingClass());
10466
      setShrunk(component, slideConfig);
10467
      slideConfig.onStartShrink()(component);
10468
    };
10469
    var doStartGrow = function (component, slideConfig, slideState) {
10470
      var fullSize = measureTargetSize(component, slideConfig);
10471
      var root = getAnimationRoot(component, slideConfig);
10472
      add$2(root, slideConfig.growingClass());
10473
      setGrown(component, slideConfig);
10474
      set$2(component.element(), getDimensionProperty(slideConfig), fullSize);
10475
      slideState.setExpanded();
10476
      slideConfig.onStartGrow()(component);
10477
    };
10478
    var grow = function (component, slideConfig, slideState) {
10479
      if (!slideState.isExpanded()) {
10480
        doStartGrow(component, slideConfig, slideState);
10481
      }
10482
    };
10483
    var shrink = function (component, slideConfig, slideState) {
10484
      if (slideState.isExpanded()) {
10485
        doStartShrink(component, slideConfig, slideState);
10486
      }
10487
    };
10488
    var immediateShrink = function (component, slideConfig, slideState) {
10489
      if (slideState.isExpanded()) {
10490
        doImmediateShrink(component, slideConfig, slideState);
10491
      }
10492
    };
10493
    var hasGrown = function (component, slideConfig, slideState) {
10494
      return slideState.isExpanded();
10495
    };
10496
    var hasShrunk = function (component, slideConfig, slideState) {
10497
      return slideState.isCollapsed();
10498
    };
10499
    var isGrowing = function (component, slideConfig, slideState) {
10500
      var root = getAnimationRoot(component, slideConfig);
10501
      return has$2(root, slideConfig.growingClass()) === true;
10502
    };
10503
    var isShrinking = function (component, slideConfig, slideState) {
10504
      var root = getAnimationRoot(component, slideConfig);
10505
      return has$2(root, slideConfig.shrinkingClass()) === true;
10506
    };
10507
    var isTransitioning = function (component, slideConfig, slideState) {
10508
      return isGrowing(component, slideConfig, slideState) === true || isShrinking(component, slideConfig, slideState) === true;
10509
    };
10510
    var toggleGrow = function (component, slideConfig, slideState) {
10511
      var f = slideState.isExpanded() ? doStartShrink : doStartGrow;
10512
      f(component, slideConfig, slideState);
10513
    };
10514
10515
    var SlidingApis = /*#__PURE__*/Object.freeze({
10516
        grow: grow,
10517
        shrink: shrink,
10518
        immediateShrink: immediateShrink,
10519
        hasGrown: hasGrown,
10520
        hasShrunk: hasShrunk,
10521
        isGrowing: isGrowing,
10522
        isShrinking: isShrinking,
10523
        isTransitioning: isTransitioning,
10524
        toggleGrow: toggleGrow,
10525
        disableTransitions: disableTransitions
10526
    });
10527
10528
    var exhibit$5 = function (base, slideConfig) {
10529
      var expanded = slideConfig.expanded();
10530
      return expanded ? nu$6({
10531
        classes: [slideConfig.openClass()],
10532
        styles: {}
10533
      }) : nu$6({
10534
        classes: [slideConfig.closedClass()],
10535
        styles: wrap$2(slideConfig.dimension().property(), '0px')
10536
      });
10537
    };
10538
    var events$a = function (slideConfig, slideState) {
10539
      return derive([run(transitionend(), function (component, simulatedEvent) {
10540
          var raw = simulatedEvent.event().raw();
10541
          if (raw.propertyName === slideConfig.dimension().property()) {
10542
            disableTransitions(component, slideConfig);
10543
            if (slideState.isExpanded()) {
10544
              remove$5(component.element(), slideConfig.dimension().property());
10545
            }
10546
            var notify = slideState.isExpanded() ? slideConfig.onGrown() : slideConfig.onShrunk();
10547
            notify(component);
10548
          }
10549
        })]);
10550
    };
10551
10552
    var ActiveSliding = /*#__PURE__*/Object.freeze({
10553
        exhibit: exhibit$5,
10554
        events: events$a
10555
    });
10556
10557
    var SlidingSchema = [
10558
      strict$1('closedClass'),
10559
      strict$1('openClass'),
10560
      strict$1('shrinkingClass'),
10561
      strict$1('growingClass'),
10562
      option('getAnimationRoot'),
10563
      onHandler('onShrunk'),
10564
      onHandler('onStartShrink'),
10565
      onHandler('onGrown'),
10566
      onHandler('onStartGrow'),
10567
      defaulted$1('expanded', false),
10568
      strictOf('dimension', choose$1('property', {
10569
        width: [
10570
          output$1('property', 'width'),
10571
          output$1('getDimension', function (elem) {
10572
            return get$7(elem) + 'px';
10573
          })
10574
        ],
10575
        height: [
10576
          output$1('property', 'height'),
10577
          output$1('getDimension', function (elem) {
10578
            return get$5(elem) + 'px';
10579
          })
10580
        ]
10581
      }))
10582
    ];
10583
10584
    var init$4 = function (spec) {
10585
      var state = Cell(spec.expanded());
10586
      var readState = function () {
10587
        return 'expanded: ' + state.get();
10588
      };
10589
      return nu$7({
10590
        isExpanded: function () {
10591
          return state.get() === true;
10592
        },
10593
        isCollapsed: function () {
10594
          return state.get() === false;
10595
        },
10596
        setCollapsed: curry(state.set, false),
10597
        setExpanded: curry(state.set, true),
10598
        readState: readState
10599
      });
10600
    };
10601
10602
    var SlidingState = /*#__PURE__*/Object.freeze({
10603
        init: init$4
10604
    });
10605
10606
    var Sliding = create$1({
10607
      fields: SlidingSchema,
10608
      name: 'sliding',
10609
      active: ActiveSliding,
10610
      apis: SlidingApis,
10611
      state: SlidingState
10612
    });
10613
10614
    var build$2 = function (refresh, scrollIntoView) {
10615
      var dropup = build$1(Container.sketch({
10616
        dom: {
10617
          tag: 'div',
10618
          classes: [Styles.resolve('dropup')]
10619
        },
10620
        components: [],
10621
        containerBehaviours: derive$2([
10622
          Replacing.config({}),
10623
          Sliding.config({
10624
            closedClass: Styles.resolve('dropup-closed'),
10625
            openClass: Styles.resolve('dropup-open'),
10626
            shrinkingClass: Styles.resolve('dropup-shrinking'),
10627
            growingClass: Styles.resolve('dropup-growing'),
10628
            dimension: { property: 'height' },
10629
            onShrunk: function (component) {
10630
              refresh();
10631
              scrollIntoView();
10632
              Replacing.set(component, []);
10633
            },
10634
            onGrown: function (component) {
10635
              refresh();
10636
              scrollIntoView();
10637
            }
10638
          }),
10639
          Receivers.orientation(function (component, data) {
10640
            disappear(noop);
10641
          })
10642
        ])
10643
      }));
10644
      var appear = function (menu, update, component) {
10645
        if (Sliding.hasShrunk(dropup) === true && Sliding.isTransitioning(dropup) === false) {
10646
          window.requestAnimationFrame(function () {
10647
            update(component);
10648
            Replacing.set(dropup, [menu()]);
10649
            Sliding.grow(dropup);
10650
          });
10651
        }
10652
      };
10653
      var disappear = function (onReadyToShrink) {
10654
        window.requestAnimationFrame(function () {
10655
          onReadyToShrink();
10656
          Sliding.shrink(dropup);
10657
        });
10658
      };
10659
      return {
10660
        appear: appear,
10661
        disappear: disappear,
10662
        component: constant(dropup),
10663
        element: dropup.element
10664
      };
10665
    };
10666
10667
    var isDangerous = function (event$$1) {
10668
      var keyEv = event$$1.raw();
10669
      return keyEv.which === BACKSPACE()[0] && !contains([
10670
        'input',
10671
        'textarea'
10672
      ], name(event$$1.target()));
10673
    };
10674
    var isFirefox = PlatformDetection$1.detect().browser.isFirefox();
10675
    var settingsSchema = objOfOnly([
10676
      strictFunction('triggerEvent'),
10677
      strictFunction('broadcastEvent'),
10678
      defaulted$1('stopBackspace', true)
10679
    ]);
10680
    var bindFocus = function (container, handler) {
10681
      if (isFirefox) {
10682
        return capture$1(container, 'focus', handler);
10683
      } else {
10684
        return bind$2(container, 'focusin', handler);
10685
      }
10686
    };
10687
    var bindBlur = function (container, handler) {
10688
      if (isFirefox) {
10689
        return capture$1(container, 'blur', handler);
10690
      } else {
10691
        return bind$2(container, 'focusout', handler);
10692
      }
10693
    };
10694
    var setup$2 = function (container, rawSettings) {
10695
      var settings = asRawOrDie('Getting GUI events settings', settingsSchema, rawSettings);
10696
      var pointerEvents = PlatformDetection$1.detect().deviceType.isTouch() ? [
10697
        'touchstart',
10698
        'touchmove',
10699
        'touchend',
10700
        'gesturestart'
10701
      ] : [
10702
        'mousedown',
10703
        'mouseup',
10704
        'mouseover',
10705
        'mousemove',
10706
        'mouseout',
10707
        'click'
10708
      ];
10709
      var tapEvent = monitor(settings);
10710
      var simpleEvents = map$1(pointerEvents.concat([
10711
        'selectstart',
10712
        'input',
10713
        'contextmenu',
10714
        'change',
10715
        'transitionend',
10716
        'drag',
10717
        'dragstart',
10718
        'dragend',
10719
        'dragenter',
10720
        'dragleave',
10721
        'dragover',
10722
        'drop'
10723
      ]), function (type$$1) {
10724
        return bind$2(container, type$$1, function (event$$1) {
10725
          tapEvent.fireIfReady(event$$1, type$$1).each(function (tapStopped) {
10726
            if (tapStopped) {
10727
              event$$1.kill();
10728
            }
10729
          });
10730
          var stopped = settings.triggerEvent(type$$1, event$$1);
10731
          if (stopped) {
10732
            event$$1.kill();
10733
          }
10734
        });
10735
      });
10736
      var onKeydown = bind$2(container, 'keydown', function (event$$1) {
10737
        var stopped = settings.triggerEvent('keydown', event$$1);
10738
        if (stopped) {
10739
          event$$1.kill();
10740
        } else if (settings.stopBackspace === true && isDangerous(event$$1)) {
10741
          event$$1.prevent();
10742
        }
10743
      });
10744
      var onFocusIn = bindFocus(container, function (event$$1) {
10745
        var stopped = settings.triggerEvent('focusin', event$$1);
10746
        if (stopped) {
10747
          event$$1.kill();
10748
        }
10749
      });
10750
      var onFocusOut = bindBlur(container, function (event$$1) {
10751
        var stopped = settings.triggerEvent('focusout', event$$1);
10752
        if (stopped) {
10753
          event$$1.kill();
10754
        }
10755
        setTimeout(function () {
10756
          settings.triggerEvent(postBlur(), event$$1);
10757
        }, 0);
10758
      });
10759
      var defaultView$$1 = defaultView(container);
10760
      var onWindowScroll = bind$2(defaultView$$1, 'scroll', function (event$$1) {
10761
        var stopped = settings.broadcastEvent(windowScroll(), event$$1);
10762
        if (stopped) {
10763
          event$$1.kill();
10764
        }
10765
      });
10766
      var unbind = function () {
10767
        each$1(simpleEvents, function (e) {
10768
          e.unbind();
10769
        });
10770
        onKeydown.unbind();
10771
        onFocusIn.unbind();
10772
        onFocusOut.unbind();
10773
        onWindowScroll.unbind();
10774
      };
10775
      return { unbind: unbind };
10776
    };
10777
10778
    var derive$3 = function (rawEvent, rawTarget) {
10779
      var source = readOptFrom$1(rawEvent, 'target').map(function (getTarget) {
10780
        return getTarget();
10781
      }).getOr(rawTarget);
10782
      return Cell(source);
10783
    };
10784
10785
    var fromSource = function (event, source) {
10786
      var stopper = Cell(false);
10787
      var cutter = Cell(false);
10788
      var stop = function () {
10789
        stopper.set(true);
10790
      };
10791
      var cut = function () {
10792
        cutter.set(true);
10793
      };
10794
      return {
10795
        stop: stop,
10796
        cut: cut,
10797
        isStopped: stopper.get,
10798
        isCut: cutter.get,
10799
        event: constant(event),
10800
        setSource: source.set,
10801
        getSource: source.get
10802
      };
10803
    };
10804
    var fromExternal = function (event) {
10805
      var stopper = Cell(false);
10806
      var stop = function () {
10807
        stopper.set(true);
10808
      };
10809
      return {
10810
        stop: stop,
10811
        cut: noop,
10812
        isStopped: stopper.get,
10813
        isCut: constant(false),
10814
        event: constant(event),
10815
        setSource: die('Cannot set source of a broadcasted event'),
10816
        getSource: die('Cannot get source of a broadcasted event')
10817
      };
10818
    };
10819
10820
    var adt$6 = Adt.generate([
10821
      { stopped: [] },
10822
      { resume: ['element'] },
10823
      { complete: [] }
10824
    ]);
10825
    var doTriggerHandler = function (lookup, eventType, rawEvent, target, source, logger) {
10826
      var handler = lookup(eventType, target);
10827
      var simulatedEvent = fromSource(rawEvent, source);
10828
      return handler.fold(function () {
10829
        logger.logEventNoHandlers(eventType, target);
10830
        return adt$6.complete();
10831
      }, function (handlerInfo) {
10832
        var descHandler = handlerInfo.descHandler();
10833
        var eventHandler = getCurried(descHandler);
10834
        eventHandler(simulatedEvent);
10835
        if (simulatedEvent.isStopped()) {
10836
          logger.logEventStopped(eventType, handlerInfo.element(), descHandler.purpose());
10837
          return adt$6.stopped();
10838
        } else if (simulatedEvent.isCut()) {
10839
          logger.logEventCut(eventType, handlerInfo.element(), descHandler.purpose());
10840
          return adt$6.complete();
10841
        } else {
10842
          return parent(handlerInfo.element()).fold(function () {
10843
            logger.logNoParent(eventType, handlerInfo.element(), descHandler.purpose());
10844
            return adt$6.complete();
10845
          }, function (parent$$1) {
10846
            logger.logEventResponse(eventType, handlerInfo.element(), descHandler.purpose());
10847
            return adt$6.resume(parent$$1);
10848
          });
10849
        }
10850
      });
10851
    };
10852
    var doTriggerOnUntilStopped = function (lookup, eventType, rawEvent, rawTarget, source, logger) {
10853
      return doTriggerHandler(lookup, eventType, rawEvent, rawTarget, source, logger).fold(function () {
10854
        return true;
10855
      }, function (parent$$1) {
10856
        return doTriggerOnUntilStopped(lookup, eventType, rawEvent, parent$$1, source, logger);
10857
      }, function () {
10858
        return false;
10859
      });
10860
    };
10861
    var triggerHandler = function (lookup, eventType, rawEvent, target, logger) {
10862
      var source = derive$3(rawEvent, target);
10863
      return doTriggerHandler(lookup, eventType, rawEvent, target, source, logger);
10864
    };
10865
    var broadcast = function (listeners, rawEvent, logger) {
10866
      var simulatedEvent = fromExternal(rawEvent);
10867
      each$1(listeners, function (listener) {
10868
        var descHandler = listener.descHandler();
10869
        var handler = getCurried(descHandler);
10870
        handler(simulatedEvent);
10871
      });
10872
      return simulatedEvent.isStopped();
10873
    };
10874
    var triggerUntilStopped = function (lookup, eventType, rawEvent, logger) {
10875
      var rawTarget = rawEvent.target();
10876
      return triggerOnUntilStopped(lookup, eventType, rawEvent, rawTarget, logger);
10877
    };
10878
    var triggerOnUntilStopped = function (lookup, eventType, rawEvent, rawTarget, logger) {
10879
      var source = derive$3(rawEvent, rawTarget);
10880
      return doTriggerOnUntilStopped(lookup, eventType, rawEvent, rawTarget, source, logger);
10881
    };
10882
10883
    var closest$3 = function (target, transform, isRoot) {
10884
      var delegate = closest(target, function (elem) {
10885
        return transform(elem).isSome();
10886
      }, isRoot);
10887
      return delegate.bind(transform);
10888
    };
10889
10890
    var eventHandler = Immutable('element', 'descHandler');
10891
    var broadcastHandler = function (id, handler) {
10892
      return {
10893
        id: constant(id),
10894
        descHandler: constant(handler)
10895
      };
10896
    };
10897
    function EventRegistry () {
10898
      var registry = {};
10899
      var registerId = function (extraArgs, id, events) {
10900
        each(events, function (v, k) {
10901
          var handlers = registry[k] !== undefined ? registry[k] : {};
10902
          handlers[id] = curryArgs(v, extraArgs);
10903
          registry[k] = handlers;
10904
        });
10905
      };
10906
      var findHandler = function (handlers, elem) {
10907
        return read$2(elem).fold(function () {
10908
          return Option.none();
10909
        }, function (id) {
10910
          var reader = readOpt$1(id);
10911
          return handlers.bind(reader).map(function (descHandler) {
10912
            return eventHandler(elem, descHandler);
10913
          });
10914
        });
10915
      };
10916
      var filterByType = function (type) {
10917
        return readOptFrom$1(registry, type).map(function (handlers) {
10918
          return mapToArray(handlers, function (f, id) {
10919
            return broadcastHandler(id, f);
10920
          });
10921
        }).getOr([]);
10922
      };
10923
      var find$$1 = function (isAboveRoot, type, target) {
10924
        var readType = readOpt$1(type);
10925
        var handlers = readType(registry);
10926
        return closest$3(target, function (elem) {
10927
          return findHandler(handlers, elem);
10928
        }, isAboveRoot);
10929
      };
10930
      var unregisterId = function (id) {
10931
        each(registry, function (handlersById, eventName) {
10932
          if (handlersById.hasOwnProperty(id)) {
10933
            delete handlersById[id];
10934
          }
10935
        });
10936
      };
10937
      return {
10938
        registerId: registerId,
10939
        unregisterId: unregisterId,
10940
        filterByType: filterByType,
10941
        find: find$$1
10942
      };
10943
    }
10944
10945
    function Registry () {
10946
      var events = EventRegistry();
10947
      var components = {};
10948
      var readOrTag = function (component) {
10949
        var elem = component.element();
10950
        return read$2(elem).fold(function () {
10951
          return write('uid-', component.element());
10952
        }, function (uid) {
10953
          return uid;
10954
        });
10955
      };
10956
      var failOnDuplicate = function (component, tagId) {
10957
        var conflict = components[tagId];
10958
        if (conflict === component) {
10959
          unregister(component);
10960
        } else {
10961
          throw new Error('The tagId "' + tagId + '" is already used by: ' + element(conflict.element()) + '\nCannot use it for: ' + element(component.element()) + '\n' + 'The conflicting element is' + (inBody(conflict.element()) ? ' ' : ' not ') + 'already in the DOM');
10962
        }
10963
      };
10964
      var register = function (component) {
10965
        var tagId = readOrTag(component);
10966
        if (hasKey$1(components, tagId)) {
10967
          failOnDuplicate(component, tagId);
10968
        }
10969
        var extraArgs = [component];
10970
        events.registerId(extraArgs, tagId, component.events());
10971
        components[tagId] = component;
10972
      };
10973
      var unregister = function (component) {
10974
        read$2(component.element()).each(function (tagId) {
10975
          components[tagId] = undefined;
10976
          events.unregisterId(tagId);
10977
        });
10978
      };
10979
      var filter = function (type) {
10980
        return events.filterByType(type);
10981
      };
10982
      var find = function (isAboveRoot, type, target) {
10983
        return events.find(isAboveRoot, type, target);
10984
      };
10985
      var getById = function (id) {
10986
        return readOpt$1(id)(components);
10987
      };
10988
      return {
10989
        find: find,
10990
        filter: filter,
10991
        register: register,
10992
        unregister: unregister,
10993
        getById: getById
10994
      };
10995
    }
10996
10997
    var takeover = function (root) {
10998
      var isAboveRoot = function (el) {
10999
        return parent(root.element()).fold(function () {
11000
          return true;
11001
        }, function (parent$$1) {
11002
          return eq(el, parent$$1);
11003
        });
11004
      };
11005
      var registry = Registry();
11006
      var lookup = function (eventName, target) {
11007
        return registry.find(isAboveRoot, eventName, target);
11008
      };
11009
      var domEvents = setup$2(root.element(), {
11010
        triggerEvent: function (eventName, event) {
11011
          return monitorEvent(eventName, event.target(), function (logger) {
11012
            return triggerUntilStopped(lookup, eventName, event, logger);
11013
          });
11014
        },
11015
        broadcastEvent: function (eventName, event) {
11016
          var listeners = registry.filter(eventName);
11017
          return broadcast(listeners, event);
11018
        }
11019
      });
11020
      var systemApi = SystemApi({
11021
        debugInfo: constant('real'),
11022
        triggerEvent: function (eventName, target, data) {
11023
          monitorEvent(eventName, target, function (logger) {
11024
            triggerOnUntilStopped(lookup, eventName, data, target, logger);
11025
          });
11026
        },
11027
        triggerFocus: function (target, originator) {
11028
          read$2(target).fold(function () {
11029
            focus$2(target);
11030
          }, function (_alloyId) {
11031
            monitorEvent(focus$1(), target, function (logger) {
11032
              triggerHandler(lookup, focus$1(), {
11033
                originator: constant(originator),
11034
                kill: noop,
11035
                prevent: noop,
11036
                target: constant(target)
11037
              }, target, logger);
11038
            });
11039
          });
11040
        },
11041
        triggerEscape: function (comp, simulatedEvent) {
11042
          systemApi.triggerEvent('keydown', comp.element(), simulatedEvent.event());
11043
        },
11044
        getByUid: function (uid) {
11045
          return getByUid(uid);
11046
        },
11047
        getByDom: function (elem) {
11048
          return getByDom(elem);
11049
        },
11050
        build: build$1,
11051
        addToGui: function (c) {
11052
          add(c);
11053
        },
11054
        removeFromGui: function (c) {
11055
          remove$$1(c);
11056
        },
11057
        addToWorld: function (c) {
11058
          addToWorld(c);
11059
        },
11060
        removeFromWorld: function (c) {
11061
          removeFromWorld(c);
11062
        },
11063
        broadcast: function (message) {
11064
          broadcast$$1(message);
11065
        },
11066
        broadcastOn: function (channels, message) {
11067
          broadcastOn(channels, message);
11068
        },
11069
        isConnected: constant(true)
11070
      });
11071
      var addToWorld = function (component) {
11072
        component.connect(systemApi);
11073
        if (!isText(component.element())) {
11074
          registry.register(component);
11075
          each$1(component.components(), addToWorld);
11076
          systemApi.triggerEvent(systemInit(), component.element(), { target: constant(component.element()) });
11077
        }
11078
      };
11079
      var removeFromWorld = function (component) {
11080
        if (!isText(component.element())) {
11081
          each$1(component.components(), removeFromWorld);
11082
          registry.unregister(component);
11083
        }
11084
        component.disconnect();
11085
      };
11086
      var add = function (component) {
11087
        attach(root, component);
11088
      };
11089
      var remove$$1 = function (component) {
11090
        detach(component);
11091
      };
11092
      var destroy = function () {
11093
        domEvents.unbind();
11094
        remove(root.element());
11095
      };
11096
      var broadcastData = function (data) {
11097
        var receivers = registry.filter(receive());
11098
        each$1(receivers, function (receiver) {
11099
          var descHandler = receiver.descHandler();
11100
          var handler = getCurried(descHandler);
11101
          handler(data);
11102
        });
11103
      };
11104
      var broadcast$$1 = function (message) {
11105
        broadcastData({
11106
          universal: constant(true),
11107
          data: constant(message)
11108
        });
11109
      };
11110
      var broadcastOn = function (channels, message) {
11111
        broadcastData({
11112
          universal: constant(false),
11113
          channels: constant(channels),
11114
          data: constant(message)
11115
        });
11116
      };
11117
      var getByUid = function (uid) {
11118
        return registry.getById(uid).fold(function () {
11119
          return Result.error(new Error('Could not find component with uid: "' + uid + '" in system.'));
11120
        }, Result.value);
11121
      };
11122
      var getByDom = function (elem) {
11123
        var uid = read$2(elem).getOr('not found');
11124
        return getByUid(uid);
11125
      };
11126
      addToWorld(root);
11127
      return {
11128
        root: constant(root),
11129
        element: root.element,
11130
        destroy: destroy,
11131
        add: add,
11132
        remove: remove$$1,
11133
        getByUid: getByUid,
11134
        getByDom: getByDom,
11135
        addToWorld: addToWorld,
11136
        removeFromWorld: removeFromWorld,
11137
        broadcast: broadcast$$1,
11138
        broadcastOn: broadcastOn
11139
      };
11140
    };
11141
11142
    var READ_ONLY_MODE_CLASS = constant(Styles.resolve('readonly-mode'));
11143
    var EDIT_MODE_CLASS = constant(Styles.resolve('edit-mode'));
11144
    function OuterContainer (spec) {
11145
      var root = build$1(Container.sketch({
11146
        dom: { classes: [Styles.resolve('outer-container')].concat(spec.classes) },
11147
        containerBehaviours: derive$2([Swapping.config({
11148
            alpha: READ_ONLY_MODE_CLASS(),
11149
            omega: EDIT_MODE_CLASS()
11150
          })])
11151
      }));
11152
      return takeover(root);
11153
    }
11154
11155
    function AndroidRealm (scrollIntoView) {
11156
      var alloy = OuterContainer({ classes: [Styles.resolve('android-container')] });
11157
      var toolbar = ScrollingToolbar();
11158
      var webapp = api$2();
11159
      var switchToEdit = CommonRealm.makeEditSwitch(webapp);
11160
      var socket = CommonRealm.makeSocket();
11161
      var dropup = build$2(noop, scrollIntoView);
11162
      alloy.add(toolbar.wrapper());
11163
      alloy.add(socket);
11164
      alloy.add(dropup.component());
11165
      var setToolbarGroups = function (rawGroups) {
11166
        var groups = toolbar.createGroups(rawGroups);
11167
        toolbar.setGroups(groups);
11168
      };
11169
      var setContextToolbar = function (rawGroups) {
11170
        var groups = toolbar.createGroups(rawGroups);
11171
        toolbar.setContextToolbar(groups);
11172
      };
11173
      var focusToolbar = function () {
11174
        toolbar.focus();
11175
      };
11176
      var restoreToolbar = function () {
11177
        toolbar.restoreToolbar();
11178
      };
11179
      var init = function (spec) {
11180
        webapp.set(AndroidWebapp.produce(spec));
11181
      };
11182
      var exit = function () {
11183
        webapp.run(function (w) {
11184
          w.exit();
11185
          Replacing.remove(socket, switchToEdit);
11186
        });
11187
      };
11188
      var updateMode = function (readOnly) {
11189
        CommonRealm.updateMode(socket, switchToEdit, readOnly, alloy.root());
11190
      };
11191
      return {
11192
        system: constant(alloy),
11193
        element: alloy.element,
11194
        init: init,
11195
        exit: exit,
11196
        setToolbarGroups: setToolbarGroups,
11197
        setContextToolbar: setContextToolbar,
11198
        focusToolbar: focusToolbar,
11199
        restoreToolbar: restoreToolbar,
11200
        updateMode: updateMode,
11201
        socket: constant(socket),
11202
        dropup: constant(dropup)
11203
      };
11204
    }
11205
11206
    var input$1 = function (parent, operation) {
11207
      var input = Element$$1.fromTag('input');
11208
      setAll$1(input, {
11209
        opacity: '0',
11210
        position: 'absolute',
11211
        top: '-1000px',
11212
        left: '-1000px'
11213
      });
11214
      append(parent, input);
11215
      focus$2(input);
11216
      operation(input);
11217
      remove(input);
11218
    };
11219
    var CaptureBin = { input: input$1 };
11220
11221
    var refreshInput = function (input) {
11222
      var start = input.dom().selectionStart;
11223
      var end = input.dom().selectionEnd;
11224
      var dir = input.dom().selectionDirection;
11225
      setTimeout(function () {
11226
        input.dom().setSelectionRange(start, end, dir);
11227
        focus$2(input);
11228
      }, 50);
11229
    };
11230
    var refresh = function (winScope) {
11231
      var sel = winScope.getSelection();
11232
      if (sel.rangeCount > 0) {
11233
        var br = sel.getRangeAt(0);
11234
        var r = winScope.document.createRange();
11235
        r.setStart(br.startContainer, br.startOffset);
11236
        r.setEnd(br.endContainer, br.endOffset);
11237
        sel.removeAllRanges();
11238
        sel.addRange(r);
11239
      }
11240
    };
11241
    var CursorRefresh = {
11242
      refreshInput: refreshInput,
11243
      refresh: refresh
11244
    };
11245
11246
    var resume$1 = function (cWin, frame) {
11247
      active().each(function (active$$1) {
11248
        if (!eq(active$$1, frame)) {
11249
          blur$$1(active$$1);
11250
        }
11251
      });
11252
      cWin.focus();
11253
      focus$2(Element$$1.fromDom(cWin.document.body));
11254
      CursorRefresh.refresh(cWin);
11255
    };
11256
    var ResumeEditing$1 = { resume: resume$1 };
11257
11258
    var stubborn = function (outerBody, cWin, page, frame) {
11259
      var toEditing = function () {
11260
        ResumeEditing$1.resume(cWin, frame);
11261
      };
11262
      var toReading = function () {
11263
        CaptureBin.input(outerBody, blur$$1);
11264
      };
11265
      var captureInput = bind$2(page, 'keydown', function (evt) {
11266
        if (!contains([
11267
            'input',
11268
            'textarea'
11269
          ], name(evt.target()))) {
11270
          toEditing();
11271
        }
11272
      });
11273
      var onToolbarTouch = function () {
11274
      };
11275
      var destroy = function () {
11276
        captureInput.unbind();
11277
      };
11278
      return {
11279
        toReading: toReading,
11280
        toEditing: toEditing,
11281
        onToolbarTouch: onToolbarTouch,
11282
        destroy: destroy
11283
      };
11284
    };
11285
    var timid = function (outerBody, cWin, page, frame) {
11286
      var dismissKeyboard = function () {
11287
        blur$$1(frame);
11288
      };
11289
      var onToolbarTouch = function () {
11290
        dismissKeyboard();
11291
      };
11292
      var toReading = function () {
11293
        dismissKeyboard();
11294
      };
11295
      var toEditing = function () {
11296
        ResumeEditing$1.resume(cWin, frame);
11297
      };
11298
      return {
11299
        toReading: toReading,
11300
        toEditing: toEditing,
11301
        onToolbarTouch: onToolbarTouch,
11302
        destroy: noop
11303
      };
11304
    };
11305
    var IosKeyboard = {
11306
      stubborn: stubborn,
11307
      timid: timid
11308
    };
11309
11310
    var initEvents$1 = function (editorApi, iosApi, toolstrip, socket, dropup) {
11311
      var saveSelectionFirst = function () {
11312
        iosApi.run(function (api) {
11313
          api.highlightSelection();
11314
        });
11315
      };
11316
      var refreshIosSelection = function () {
11317
        iosApi.run(function (api) {
11318
          api.refreshSelection();
11319
        });
11320
      };
11321
      var scrollToY = function (yTop, height) {
11322
        var y = yTop - socket.dom().scrollTop;
11323
        iosApi.run(function (api) {
11324
          api.scrollIntoView(y, y + height);
11325
        });
11326
      };
11327
      var scrollToElement = function (target) {
11328
        scrollToY(iosApi, socket);
11329
      };
11330
      var scrollToCursor = function () {
11331
        editorApi.getCursorBox().each(function (box) {
11332
          scrollToY(box.top(), box.height());
11333
        });
11334
      };
11335
      var clearSelection = function () {
11336
        iosApi.run(function (api) {
11337
          api.clearSelection();
11338
        });
11339
      };
11340
      var clearAndRefresh = function () {
11341
        clearSelection();
11342
        refreshThrottle.throttle();
11343
      };
11344
      var refreshView = function () {
11345
        scrollToCursor();
11346
        iosApi.run(function (api) {
11347
          api.syncHeight();
11348
        });
11349
      };
11350
      var reposition = function () {
11351
        var toolbarHeight = get$5(toolstrip);
11352
        iosApi.run(function (api) {
11353
          api.setViewportOffset(toolbarHeight);
11354
        });
11355
        refreshIosSelection();
11356
        refreshView();
11357
      };
11358
      var toEditing = function () {
11359
        iosApi.run(function (api) {
11360
          api.toEditing();
11361
        });
11362
      };
11363
      var toReading = function () {
11364
        iosApi.run(function (api) {
11365
          api.toReading();
11366
        });
11367
      };
11368
      var onToolbarTouch = function (event) {
11369
        iosApi.run(function (api) {
11370
          api.onToolbarTouch(event);
11371
        });
11372
      };
11373
      var tapping = TappingEvent.monitor(editorApi);
11374
      var refreshThrottle = last$3(refreshView, 300);
11375
      var listeners = [
11376
        editorApi.onKeyup(clearAndRefresh),
11377
        editorApi.onNodeChanged(refreshIosSelection),
11378
        editorApi.onDomChanged(refreshThrottle.throttle),
11379
        editorApi.onDomChanged(refreshIosSelection),
11380
        editorApi.onScrollToCursor(function (tinyEvent) {
11381
          tinyEvent.preventDefault();
11382
          refreshThrottle.throttle();
11383
        }),
11384
        editorApi.onScrollToElement(function (event) {
11385
          scrollToElement(event.element());
11386
        }),
11387
        editorApi.onToEditing(toEditing),
11388
        editorApi.onToReading(toReading),
11389
        bind$2(editorApi.doc(), 'touchend', function (touchEvent) {
11390
          if (eq(editorApi.html(), touchEvent.target()) || eq(editorApi.body(), touchEvent.target())) ;
11391
        }),
11392
        bind$2(toolstrip, 'transitionend', function (transitionEvent) {
11393
          if (transitionEvent.raw().propertyName === 'height') {
11394
            reposition();
11395
          }
11396
        }),
11397
        capture$1(toolstrip, 'touchstart', function (touchEvent) {
11398
          saveSelectionFirst();
11399
          onToolbarTouch(touchEvent);
11400
          editorApi.onTouchToolstrip();
11401
        }),
11402
        bind$2(editorApi.body(), 'touchstart', function (evt) {
11403
          clearSelection();
11404
          editorApi.onTouchContent();
11405
          tapping.fireTouchstart(evt);
11406
        }),
11407
        tapping.onTouchmove(),
11408
        tapping.onTouchend(),
11409
        bind$2(editorApi.body(), 'click', function (event) {
11410
          event.kill();
11411
        }),
11412
        bind$2(toolstrip, 'touchmove', function () {
11413
          editorApi.onToolbarScrollStart();
11414
        })
11415
      ];
11416
      var destroy = function () {
11417
        each$1(listeners, function (l) {
11418
          l.unbind();
11419
        });
11420
      };
11421
      return { destroy: destroy };
11422
    };
11423
    var IosEvents = { initEvents: initEvents$1 };
11424
11425
    function FakeSelection (win, frame) {
11426
      var doc = win.document;
11427
      var container = Element$$1.fromTag('div');
11428
      add$2(container, Styles.resolve('unfocused-selections'));
11429
      append(Element$$1.fromDom(doc.documentElement), container);
11430
      var onTouch = bind$2(container, 'touchstart', function (event) {
11431
        event.prevent();
11432
        ResumeEditing$1.resume(win, frame);
11433
        clear();
11434
      });
11435
      var make = function (rectangle) {
11436
        var span = Element$$1.fromTag('span');
11437
        add$3(span, [
11438
          Styles.resolve('layer-editor'),
11439
          Styles.resolve('unfocused-selection')
11440
        ]);
11441
        setAll$1(span, {
11442
          left: rectangle.left() + 'px',
11443
          top: rectangle.top() + 'px',
11444
          width: rectangle.width() + 'px',
11445
          height: rectangle.height() + 'px'
11446
        });
11447
        return span;
11448
      };
11449
      var update = function () {
11450
        clear();
11451
        var rectangles = Rectangles.getRectangles(win);
11452
        var spans = map$1(rectangles, make);
11453
        append$1(container, spans);
11454
      };
11455
      var clear = function () {
11456
        empty(container);
11457
      };
11458
      var destroy = function () {
11459
        onTouch.unbind();
11460
        remove(container);
11461
      };
11462
      var isActive = function () {
11463
        return children(container).length > 0;
11464
      };
11465
      return {
11466
        update: update,
11467
        isActive: isActive,
11468
        destroy: destroy,
11469
        clear: clear
11470
      };
11471
    }
11472
11473
    var nu$8 = function (baseFn) {
11474
      var data = Option.none();
11475
      var callbacks = [];
11476
      var map = function (f) {
11477
        return nu$8(function (nCallback) {
11478
          get(function (data) {
11479
            nCallback(f(data));
11480
          });
11481
        });
11482
      };
11483
      var get = function (nCallback) {
11484
        if (isReady())
11485
          call(nCallback);
11486
        else
11487
          callbacks.push(nCallback);
11488
      };
11489
      var set = function (x) {
11490
        data = Option.some(x);
11491
        run(callbacks);
11492
        callbacks = [];
11493
      };
11494
      var isReady = function () {
11495
        return data.isSome();
11496
      };
11497
      var run = function (cbs) {
11498
        each$1(cbs, call);
11499
      };
11500
      var call = function (cb) {
11501
        data.each(function (x) {
11502
          setTimeout(function () {
11503
            cb(x);
11504
          }, 0);
11505
        });
11506
      };
11507
      baseFn(set);
11508
      return {
11509
        get: get,
11510
        map: map,
11511
        isReady: isReady
11512
      };
11513
    };
11514
    var pure$1 = function (a) {
11515
      return nu$8(function (callback) {
11516
        callback(a);
11517
      });
11518
    };
11519
    var LazyValue = {
11520
      nu: nu$8,
11521
      pure: pure$1
11522
    };
11523
11524
    var bounce = function (f) {
11525
      return function () {
11526
        var args = [];
11527
        for (var _i = 0; _i < arguments.length; _i++) {
11528
          args[_i] = arguments[_i];
11529
        }
11530
        var me = this;
11531
        setTimeout(function () {
11532
          f.apply(me, args);
11533
        }, 0);
11534
      };
11535
    };
11536
11537
    var nu$9 = function (baseFn) {
11538
      var get = function (callback) {
11539
        baseFn(bounce(callback));
11540
      };
11541
      var map = function (fab) {
11542
        return nu$9(function (callback) {
11543
          get(function (a) {
11544
            var value = fab(a);
11545
            callback(value);
11546
          });
11547
        });
11548
      };
11549
      var bind = function (aFutureB) {
11550
        return nu$9(function (callback) {
11551
          get(function (a) {
11552
            aFutureB(a).get(callback);
11553
          });
11554
        });
11555
      };
11556
      var anonBind = function (futureB) {
11557
        return nu$9(function (callback) {
11558
          get(function (a) {
11559
            futureB.get(callback);
11560
          });
11561
        });
11562
      };
11563
      var toLazy = function () {
11564
        return LazyValue.nu(get);
11565
      };
11566
      var toCached = function () {
11567
        var cache = null;
11568
        return nu$9(function (callback) {
11569
          if (cache === null) {
11570
            cache = toLazy();
11571
          }
11572
          cache.get(callback);
11573
        });
11574
      };
11575
      return {
11576
        map: map,
11577
        bind: bind,
11578
        anonBind: anonBind,
11579
        toLazy: toLazy,
11580
        toCached: toCached,
11581
        get: get
11582
      };
11583
    };
11584
    var pure$2 = function (a) {
11585
      return nu$9(function (callback) {
11586
        callback(a);
11587
      });
11588
    };
11589
    var Future = {
11590
      nu: nu$9,
11591
      pure: pure$2
11592
    };
11593
11594
    var adjust = function (value, destination, amount) {
11595
      if (Math.abs(value - destination) <= amount) {
11596
        return Option.none();
11597
      } else if (value < destination) {
11598
        return Option.some(value + amount);
11599
      } else {
11600
        return Option.some(value - amount);
11601
      }
11602
    };
11603
    var create$7 = function () {
11604
      var interval = null;
11605
      var animate = function (getCurrent, destination, amount, increment, doFinish, rate) {
11606
        var finished = false;
11607
        var finish = function (v) {
11608
          finished = true;
11609
          doFinish(v);
11610
        };
11611
        clearInterval(interval);
11612
        var abort = function (v) {
11613
          clearInterval(interval);
11614
          finish(v);
11615
        };
11616
        interval = setInterval(function () {
11617
          var value = getCurrent();
11618
          adjust(value, destination, amount).fold(function () {
11619
            clearInterval(interval);
11620
            finish(destination);
11621
          }, function (s) {
11622
            increment(s, abort);
11623
            if (!finished) {
11624
              var newValue = getCurrent();
11625
              if (newValue !== s || Math.abs(newValue - destination) > Math.abs(value - destination)) {
11626
                clearInterval(interval);
11627
                finish(destination);
11628
              }
11629
            }
11630
          });
11631
        }, rate);
11632
      };
11633
      return { animate: animate };
11634
    };
11635
    var SmoothAnimation = {
11636
      create: create$7,
11637
      adjust: adjust
11638
    };
11639
11640
    var findDevice = function (deviceWidth, deviceHeight) {
11641
      var devices = [
11642
        {
11643
          width: 320,
11644
          height: 480,
11645
          keyboard: {
11646
            portrait: 300,
11647
            landscape: 240
11648
          }
11649
        },
11650
        {
11651
          width: 320,
11652
          height: 568,
11653
          keyboard: {
11654
            portrait: 300,
11655
            landscape: 240
11656
          }
11657
        },
11658
        {
11659
          width: 375,
11660
          height: 667,
11661
          keyboard: {
11662
            portrait: 305,
11663
            landscape: 240
11664
          }
11665
        },
11666
        {
11667
          width: 414,
11668
          height: 736,
11669
          keyboard: {
11670
            portrait: 320,
11671
            landscape: 240
11672
          }
11673
        },
11674
        {
11675
          width: 768,
11676
          height: 1024,
11677
          keyboard: {
11678
            portrait: 320,
11679
            landscape: 400
11680
          }
11681
        },
11682
        {
11683
          width: 1024,
11684
          height: 1366,
11685
          keyboard: {
11686
            portrait: 380,
11687
            landscape: 460
11688
          }
11689
        }
11690
      ];
11691
      return findMap(devices, function (device) {
11692
        return deviceWidth <= device.width && deviceHeight <= device.height ? Option.some(device.keyboard) : Option.none();
11693
      }).getOr({
11694
        portrait: deviceHeight / 5,
11695
        landscape: deviceWidth / 4
11696
      });
11697
    };
11698
    var Devices = { findDevice: findDevice };
11699
11700
    var softKeyboardLimits = function (outerWindow) {
11701
      return Devices.findDevice(outerWindow.screen.width, outerWindow.screen.height);
11702
    };
11703
    var accountableKeyboardHeight = function (outerWindow) {
11704
      var portrait = Orientation.get(outerWindow).isPortrait();
11705
      var limits = softKeyboardLimits(outerWindow);
11706
      var keyboard = portrait ? limits.portrait : limits.landscape;
11707
      var visualScreenHeight = portrait ? outerWindow.screen.height : outerWindow.screen.width;
11708
      return visualScreenHeight - outerWindow.innerHeight > keyboard ? 0 : keyboard;
11709
    };
11710
    var getGreenzone = function (socket, dropup) {
11711
      var outerWindow = owner(socket).dom().defaultView;
11712
      var viewportHeight = get$5(socket) + get$5(dropup);
11713
      var acc = accountableKeyboardHeight(outerWindow);
11714
      return viewportHeight - acc;
11715
    };
11716
    var updatePadding = function (contentBody, socket, dropup) {
11717
      var greenzoneHeight = getGreenzone(socket, dropup);
11718
      var deltaHeight = get$5(socket) + get$5(dropup) - greenzoneHeight;
11719
      set$2(contentBody, 'padding-bottom', deltaHeight + 'px');
11720
    };
11721
    var DeviceZones = {
11722
      getGreenzone: getGreenzone,
11723
      updatePadding: updatePadding
11724
    };
11725
11726
    var fixture = Adt.generate([
11727
      {
11728
        fixed: [
11729
          'element',
11730
          'property',
11731
          'offsetY'
11732
        ]
11733
      },
11734
      {
11735
        scroller: [
11736
          'element',
11737
          'offsetY'
11738
        ]
11739
      }
11740
    ]);
11741
    var yFixedData = 'data-' + Styles.resolve('position-y-fixed');
11742
    var yFixedProperty = 'data-' + Styles.resolve('y-property');
11743
    var yScrollingData = 'data-' + Styles.resolve('scrolling');
11744
    var windowSizeData = 'data-' + Styles.resolve('last-window-height');
11745
    var getYFixedData = function (element) {
11746
      return DataAttributes.safeParse(element, yFixedData);
11747
    };
11748
    var getYFixedProperty = function (element) {
11749
      return get$1(element, yFixedProperty);
11750
    };
11751
    var getLastWindowSize = function (element) {
11752
      return DataAttributes.safeParse(element, windowSizeData);
11753
    };
11754
    var classifyFixed = function (element, offsetY) {
11755
      var prop = getYFixedProperty(element);
11756
      return fixture.fixed(element, prop, offsetY);
11757
    };
11758
    var classifyScrolling = function (element, offsetY) {
11759
      return fixture.scroller(element, offsetY);
11760
    };
11761
    var classify = function (element) {
11762
      var offsetY = getYFixedData(element);
11763
      var classifier = get$1(element, yScrollingData) === 'true' ? classifyScrolling : classifyFixed;
11764
      return classifier(element, offsetY);
11765
    };
11766
    var findFixtures = function (container) {
11767
      var candidates = descendants$1(container, '[' + yFixedData + ']');
11768
      return map$1(candidates, classify);
11769
    };
11770
    var takeoverToolbar = function (toolbar) {
11771
      var oldToolbarStyle = get$1(toolbar, 'style');
11772
      setAll$1(toolbar, {
11773
        position: 'absolute',
11774
        top: '0px'
11775
      });
11776
      set(toolbar, yFixedData, '0px');
11777
      set(toolbar, yFixedProperty, 'top');
11778
      var restore = function () {
11779
        set(toolbar, 'style', oldToolbarStyle || '');
11780
        remove$1(toolbar, yFixedData);
11781
        remove$1(toolbar, yFixedProperty);
11782
      };
11783
      return { restore: restore };
11784
    };
11785
    var takeoverViewport = function (toolbarHeight, height, viewport) {
11786
      var oldViewportStyle = get$1(viewport, 'style');
11787
      Scrollable.register(viewport);
11788
      setAll$1(viewport, {
11789
        position: 'absolute',
11790
        height: height + 'px',
11791
        width: '100%',
11792
        top: toolbarHeight + 'px'
11793
      });
11794
      set(viewport, yFixedData, toolbarHeight + 'px');
11795
      set(viewport, yScrollingData, 'true');
11796
      set(viewport, yFixedProperty, 'top');
11797
      var restore = function () {
11798
        Scrollable.deregister(viewport);
11799
        set(viewport, 'style', oldViewportStyle || '');
11800
        remove$1(viewport, yFixedData);
11801
        remove$1(viewport, yScrollingData);
11802
        remove$1(viewport, yFixedProperty);
11803
      };
11804
      return { restore: restore };
11805
    };
11806
    var takeoverDropup = function (dropup, toolbarHeight, viewportHeight) {
11807
      var oldDropupStyle = get$1(dropup, 'style');
11808
      setAll$1(dropup, {
11809
        position: 'absolute',
11810
        bottom: '0px'
11811
      });
11812
      set(dropup, yFixedData, '0px');
11813
      set(dropup, yFixedProperty, 'bottom');
11814
      var restore = function () {
11815
        set(dropup, 'style', oldDropupStyle || '');
11816
        remove$1(dropup, yFixedData);
11817
        remove$1(dropup, yFixedProperty);
11818
      };
11819
      return { restore: restore };
11820
    };
11821
    var deriveViewportHeight = function (viewport, toolbarHeight, dropupHeight) {
11822
      var outerWindow = owner(viewport).dom().defaultView;
11823
      var winH = outerWindow.innerHeight;
11824
      set(viewport, windowSizeData, winH + 'px');
11825
      return winH - toolbarHeight - dropupHeight;
11826
    };
11827
    var takeover$1 = function (viewport, contentBody, toolbar, dropup) {
11828
      var outerWindow = owner(viewport).dom().defaultView;
11829
      var toolbarSetup = takeoverToolbar(toolbar);
11830
      var toolbarHeight = get$5(toolbar);
11831
      var dropupHeight = get$5(dropup);
11832
      var viewportHeight = deriveViewportHeight(viewport, toolbarHeight, dropupHeight);
11833
      var viewportSetup = takeoverViewport(toolbarHeight, viewportHeight, viewport);
11834
      var dropupSetup = takeoverDropup(dropup, toolbarHeight, viewportHeight);
11835
      var isActive = true;
11836
      var restore = function () {
11837
        isActive = false;
11838
        toolbarSetup.restore();
11839
        viewportSetup.restore();
11840
        dropupSetup.restore();
11841
      };
11842
      var isExpanding = function () {
11843
        var currentWinHeight = outerWindow.innerHeight;
11844
        var lastWinHeight = getLastWindowSize(viewport);
11845
        return currentWinHeight > lastWinHeight;
11846
      };
11847
      var refresh = function () {
11848
        if (isActive) {
11849
          var newToolbarHeight = get$5(toolbar);
11850
          var dropupHeight_1 = get$5(dropup);
11851
          var newHeight = deriveViewportHeight(viewport, newToolbarHeight, dropupHeight_1);
11852
          set(viewport, yFixedData, newToolbarHeight + 'px');
11853
          set$2(viewport, 'height', newHeight + 'px');
11854
          set$2(dropup, 'bottom', -(newToolbarHeight + newHeight + dropupHeight_1) + 'px');
11855
          DeviceZones.updatePadding(contentBody, viewport, dropup);
11856
        }
11857
      };
11858
      var setViewportOffset = function (newYOffset) {
11859
        var offsetPx = newYOffset + 'px';
11860
        set(viewport, yFixedData, offsetPx);
11861
        refresh();
11862
      };
11863
      DeviceZones.updatePadding(contentBody, viewport, dropup);
11864
      return {
11865
        setViewportOffset: setViewportOffset,
11866
        isExpanding: isExpanding,
11867
        isShrinking: not(isExpanding),
11868
        refresh: refresh,
11869
        restore: restore
11870
      };
11871
    };
11872
    var IosViewport = {
11873
      findFixtures: findFixtures,
11874
      takeover: takeover$1,
11875
      getYFixedData: getYFixedData
11876
    };
11877
11878
    var animator = SmoothAnimation.create();
11879
    var ANIMATION_STEP = 15;
11880
    var NUM_TOP_ANIMATION_FRAMES = 10;
11881
    var ANIMATION_RATE = 10;
11882
    var lastScroll = 'data-' + Styles.resolve('last-scroll-top');
11883
    var getTop = function (element) {
11884
      var raw = getRaw(element, 'top').getOr('0');
11885
      return parseInt(raw, 10);
11886
    };
11887
    var getScrollTop = function (element) {
11888
      return parseInt(element.dom().scrollTop, 10);
11889
    };
11890
    var moveScrollAndTop = function (element, destination, finalTop) {
11891
      return Future.nu(function (callback) {
11892
        var getCurrent = curry(getScrollTop, element);
11893
        var update = function (newScroll) {
11894
          element.dom().scrollTop = newScroll;
11895
          set$2(element, 'top', getTop(element) + ANIMATION_STEP + 'px');
11896
        };
11897
        var finish = function () {
11898
          element.dom().scrollTop = destination;
11899
          set$2(element, 'top', finalTop + 'px');
11900
          callback(destination);
11901
        };
11902
        animator.animate(getCurrent, destination, ANIMATION_STEP, update, finish, ANIMATION_RATE);
11903
      });
11904
    };
11905
    var moveOnlyScroll = function (element, destination) {
11906
      return Future.nu(function (callback) {
11907
        var getCurrent = curry(getScrollTop, element);
11908
        set(element, lastScroll, getCurrent());
11909
        var update = function (newScroll, abort) {
11910
          var previous = DataAttributes.safeParse(element, lastScroll);
11911
          if (previous !== element.dom().scrollTop) {
11912
            abort(element.dom().scrollTop);
11913
          } else {
11914
            element.dom().scrollTop = newScroll;
11915
            set(element, lastScroll, newScroll);
11916
          }
11917
        };
11918
        var finish = function () {
11919
          element.dom().scrollTop = destination;
11920
          set(element, lastScroll, destination);
11921
          callback(destination);
11922
        };
11923
        var distance = Math.abs(destination - getCurrent());
11924
        var step = Math.ceil(distance / NUM_TOP_ANIMATION_FRAMES);
11925
        animator.animate(getCurrent, destination, step, update, finish, ANIMATION_RATE);
11926
      });
11927
    };
11928
    var moveOnlyTop = function (element, destination) {
11929
      return Future.nu(function (callback) {
11930
        var getCurrent = curry(getTop, element);
11931
        var update = function (newTop) {
11932
          set$2(element, 'top', newTop + 'px');
11933
        };
11934
        var finish = function () {
11935
          update(destination);
11936
          callback(destination);
11937
        };
11938
        var distance = Math.abs(destination - getCurrent());
11939
        var step = Math.ceil(distance / NUM_TOP_ANIMATION_FRAMES);
11940
        animator.animate(getCurrent, destination, step, update, finish, ANIMATION_RATE);
11941
      });
11942
    };
11943
    var updateTop = function (element, amount) {
11944
      var newTop = amount + IosViewport.getYFixedData(element) + 'px';
11945
      set$2(element, 'top', newTop);
11946
    };
11947
    var moveWindowScroll = function (toolbar, viewport, destY) {
11948
      var outerWindow = owner(toolbar).dom().defaultView;
11949
      return Future.nu(function (callback) {
11950
        updateTop(toolbar, destY);
11951
        updateTop(viewport, destY);
11952
        outerWindow.scrollTo(0, destY);
11953
        callback(destY);
11954
      });
11955
    };
11956
    var IosScrolling = {
11957
      moveScrollAndTop: moveScrollAndTop,
11958
      moveOnlyScroll: moveOnlyScroll,
11959
      moveOnlyTop: moveOnlyTop,
11960
      moveWindowScroll: moveWindowScroll
11961
    };
11962
11963
    function BackgroundActivity (doAction) {
11964
      var action = Cell(LazyValue.pure({}));
11965
      var start = function (value) {
11966
        var future = LazyValue.nu(function (callback) {
11967
          return doAction(value).get(callback);
11968
        });
11969
        action.set(future);
11970
      };
11971
      var idle = function (g) {
11972
        action.get().get(function () {
11973
          g();
11974
        });
11975
      };
11976
      return {
11977
        start: start,
11978
        idle: idle
11979
      };
11980
    }
11981
11982
    var scrollIntoView = function (cWin, socket, dropup, top, bottom) {
11983
      var greenzone = DeviceZones.getGreenzone(socket, dropup);
11984
      var refreshCursor = curry(CursorRefresh.refresh, cWin);
11985
      if (top > greenzone || bottom > greenzone) {
11986
        IosScrolling.moveOnlyScroll(socket, socket.dom().scrollTop - greenzone + bottom).get(refreshCursor);
11987
      } else if (top < 0) {
11988
        IosScrolling.moveOnlyScroll(socket, socket.dom().scrollTop + top).get(refreshCursor);
11989
      }
11990
    };
11991
    var Greenzone = { scrollIntoView: scrollIntoView };
11992
11993
    var par = function (asyncValues, nu) {
11994
      return nu(function (callback) {
11995
        var r = [];
11996
        var count = 0;
11997
        var cb = function (i) {
11998
          return function (value) {
11999
            r[i] = value;
12000
            count++;
12001
            if (count >= asyncValues.length) {
12002
              callback(r);
12003
            }
12004
          };
12005
        };
12006
        if (asyncValues.length === 0) {
12007
          callback([]);
12008
        } else {
12009
          each$1(asyncValues, function (asyncValue, i) {
12010
            asyncValue.get(cb(i));
12011
          });
12012
        }
12013
      });
12014
    };
12015
12016
    var par$1 = function (futures) {
12017
      return par(futures, Future.nu);
12018
    };
12019
12020
    var updateFixed = function (element, property, winY, offsetY) {
12021
      var destination = winY + offsetY;
12022
      set$2(element, property, destination + 'px');
12023
      return Future.pure(offsetY);
12024
    };
12025
    var updateScrollingFixed = function (element, winY, offsetY) {
12026
      var destTop = winY + offsetY;
12027
      var oldProp = getRaw(element, 'top').getOr(offsetY);
12028
      var delta = destTop - parseInt(oldProp, 10);
12029
      var destScroll = element.dom().scrollTop + delta;
12030
      return IosScrolling.moveScrollAndTop(element, destScroll, destTop);
12031
    };
12032
    var updateFixture = function (fixture, winY) {
12033
      return fixture.fold(function (element, property, offsetY) {
12034
        return updateFixed(element, property, winY, offsetY);
12035
      }, function (element, offsetY) {
12036
        return updateScrollingFixed(element, winY, offsetY);
12037
      });
12038
    };
12039
    var updatePositions = function (container, winY) {
12040
      var fixtures = IosViewport.findFixtures(container);
12041
      var updates = map$1(fixtures, function (fixture) {
12042
        return updateFixture(fixture, winY);
12043
      });
12044
      return par$1(updates);
12045
    };
12046
    var IosUpdates = { updatePositions: updatePositions };
12047
12048
    var VIEW_MARGIN = 5;
12049
    var register$2 = function (toolstrip, socket, container, outerWindow, structure, cWin) {
12050
      var scroller = BackgroundActivity(function (y) {
12051
        return IosScrolling.moveWindowScroll(toolstrip, socket, y);
12052
      });
12053
      var scrollBounds = function () {
12054
        var rects = Rectangles.getRectangles(cWin);
12055
        return Option.from(rects[0]).bind(function (rect) {
12056
          var viewTop = rect.top() - socket.dom().scrollTop;
12057
          var outside = viewTop > outerWindow.innerHeight + VIEW_MARGIN || viewTop < -VIEW_MARGIN;
12058
          return outside ? Option.some({
12059
            top: constant(viewTop),
12060
            bottom: constant(viewTop + rect.height())
12061
          }) : Option.none();
12062
        });
12063
      };
12064
      var scrollThrottle = last$3(function () {
12065
        scroller.idle(function () {
12066
          IosUpdates.updatePositions(container, outerWindow.pageYOffset).get(function () {
12067
            var extraScroll = scrollBounds();
12068
            extraScroll.each(function (extra) {
12069
              socket.dom().scrollTop = socket.dom().scrollTop + extra.top();
12070
            });
12071
            scroller.start(0);
12072
            structure.refresh();
12073
          });
12074
        });
12075
      }, 1000);
12076
      var onScroll = bind$2(Element$$1.fromDom(outerWindow), 'scroll', function () {
12077
        if (outerWindow.pageYOffset < 0) {
12078
          return;
12079
        }
12080
        scrollThrottle.throttle();
12081
      });
12082
      IosUpdates.updatePositions(container, outerWindow.pageYOffset).get(identity);
12083
      return { unbind: onScroll.unbind };
12084
    };
12085
    var setup$3 = function (bag) {
12086
      var cWin = bag.cWin();
12087
      var ceBody = bag.ceBody();
12088
      var socket = bag.socket();
12089
      var toolstrip = bag.toolstrip();
12090
      var toolbar = bag.toolbar();
12091
      var contentElement = bag.contentElement();
12092
      var keyboardType = bag.keyboardType();
12093
      var outerWindow = bag.outerWindow();
12094
      var dropup = bag.dropup();
12095
      var structure = IosViewport.takeover(socket, ceBody, toolstrip, dropup);
12096
      var keyboardModel = keyboardType(bag.outerBody(), cWin, body(), contentElement, toolstrip, toolbar);
12097
      var toEditing = function () {
12098
        keyboardModel.toEditing();
12099
        clearSelection();
12100
      };
12101
      var toReading = function () {
12102
        keyboardModel.toReading();
12103
      };
12104
      var onToolbarTouch = function (event) {
12105
        keyboardModel.onToolbarTouch(event);
12106
      };
12107
      var onOrientation = Orientation.onChange(outerWindow, {
12108
        onChange: noop,
12109
        onReady: structure.refresh
12110
      });
12111
      onOrientation.onAdjustment(function () {
12112
        structure.refresh();
12113
      });
12114
      var onResize = bind$2(Element$$1.fromDom(outerWindow), 'resize', function () {
12115
        if (structure.isExpanding()) {
12116
          structure.refresh();
12117
        }
12118
      });
12119
      var onScroll = register$2(toolstrip, socket, bag.outerBody(), outerWindow, structure, cWin);
12120
      var unfocusedSelection = FakeSelection(cWin, contentElement);
12121
      var refreshSelection = function () {
12122
        if (unfocusedSelection.isActive()) {
12123
          unfocusedSelection.update();
12124
        }
12125
      };
12126
      var highlightSelection = function () {
12127
        unfocusedSelection.update();
12128
      };
12129
      var clearSelection = function () {
12130
        unfocusedSelection.clear();
12131
      };
12132
      var scrollIntoView = function (top, bottom) {
12133
        Greenzone.scrollIntoView(cWin, socket, dropup, top, bottom);
12134
      };
12135
      var syncHeight = function () {
12136
        set$2(contentElement, 'height', contentElement.dom().contentWindow.document.body.scrollHeight + 'px');
12137
      };
12138
      var setViewportOffset = function (newYOffset) {
12139
        structure.setViewportOffset(newYOffset);
12140
        IosScrolling.moveOnlyTop(socket, newYOffset).get(identity);
12141
      };
12142
      var destroy = function () {
12143
        structure.restore();
12144
        onOrientation.destroy();
12145
        onScroll.unbind();
12146
        onResize.unbind();
12147
        keyboardModel.destroy();
12148
        unfocusedSelection.destroy();
12149
        CaptureBin.input(body(), blur$$1);
12150
      };
12151
      return {
12152
        toEditing: toEditing,
12153
        toReading: toReading,
12154
        onToolbarTouch: onToolbarTouch,
12155
        refreshSelection: refreshSelection,
12156
        clearSelection: clearSelection,
12157
        highlightSelection: highlightSelection,
12158
        scrollIntoView: scrollIntoView,
12159
        updateToolbarPadding: noop,
12160
        setViewportOffset: setViewportOffset,
12161
        syncHeight: syncHeight,
12162
        refreshStructure: structure.refresh,
12163
        destroy: destroy
12164
      };
12165
    };
12166
    var IosSetup = { setup: setup$3 };
12167
12168
    var create$8 = function (platform, mask) {
12169
      var meta = MetaViewport.tag();
12170
      var priorState = value$3();
12171
      var scrollEvents = value$3();
12172
      var iosApi = api$2();
12173
      var iosEvents = api$2();
12174
      var enter = function () {
12175
        mask.hide();
12176
        var doc = Element$$1.fromDom(document);
12177
        PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) {
12178
          priorState.set({
12179
            socketHeight: getRaw(platform.socket, 'height'),
12180
            iframeHeight: getRaw(editorApi.frame(), 'height'),
12181
            outerScroll: document.body.scrollTop
12182
          });
12183
          scrollEvents.set({ exclusives: Scrollables.exclusive(doc, '.' + Scrollable.scrollable()) });
12184
          add$2(platform.container, Styles.resolve('fullscreen-maximized'));
12185
          Thor.clobberStyles(platform.container, editorApi.body());
12186
          meta.maximize();
12187
          set$2(platform.socket, 'overflow', 'scroll');
12188
          set$2(platform.socket, '-webkit-overflow-scrolling', 'touch');
12189
          focus$2(editorApi.body());
12190
          var setupBag = MixedBag([
12191
            'cWin',
12192
            'ceBody',
12193
            'socket',
12194
            'toolstrip',
12195
            'toolbar',
12196
            'dropup',
12197
            'contentElement',
12198
            'cursor',
12199
            'keyboardType',
12200
            'isScrolling',
12201
            'outerWindow',
12202
            'outerBody'
12203
          ], []);
12204
          iosApi.set(IosSetup.setup(setupBag({
12205
            cWin: editorApi.win(),
12206
            ceBody: editorApi.body(),
12207
            socket: platform.socket,
12208
            toolstrip: platform.toolstrip,
12209
            toolbar: platform.toolbar,
12210
            dropup: platform.dropup.element(),
12211
            contentElement: editorApi.frame(),
12212
            cursor: noop,
12213
            outerBody: platform.body,
12214
            outerWindow: platform.win,
12215
            keyboardType: IosKeyboard.stubborn,
12216
            isScrolling: function () {
12217
              var scrollValue = scrollEvents;
12218
              return scrollValue.get().exists(function (s) {
12219
                return s.socket.isScrolling();
12220
              });
12221
            }
12222
          })));
12223
          iosApi.run(function (api) {
12224
            api.syncHeight();
12225
          });
12226
          iosEvents.set(IosEvents.initEvents(editorApi, iosApi, platform.toolstrip, platform.socket, platform.dropup));
12227
        });
12228
      };
12229
      var exit = function () {
12230
        meta.restore();
12231
        iosEvents.clear();
12232
        iosApi.clear();
12233
        mask.show();
12234
        priorState.on(function (s) {
12235
          s.socketHeight.each(function (h) {
12236
            set$2(platform.socket, 'height', h);
12237
          });
12238
          s.iframeHeight.each(function (h) {
12239
            set$2(platform.editor.getFrame(), 'height', h);
12240
          });
12241
          document.body.scrollTop = s.scrollTop;
12242
        });
12243
        priorState.clear();
12244
        scrollEvents.on(function (s) {
12245
          s.exclusives.unbind();
12246
        });
12247
        scrollEvents.clear();
12248
        remove$4(platform.container, Styles.resolve('fullscreen-maximized'));
12249
        Thor.restoreStyles();
12250
        Scrollable.deregister(platform.toolbar);
12251
        remove$5(platform.socket, 'overflow');
12252
        remove$5(platform.socket, '-webkit-overflow-scrolling');
12253
        blur$$1(platform.editor.getFrame());
12254
        PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) {
12255
          editorApi.clearSelection();
12256
        });
12257
      };
12258
      var refreshStructure = function () {
12259
        iosApi.run(function (api) {
12260
          api.refreshStructure();
12261
        });
12262
      };
12263
      return {
12264
        enter: enter,
12265
        refreshStructure: refreshStructure,
12266
        exit: exit
12267
      };
12268
    };
12269
    var IosMode = { create: create$8 };
12270
12271
    var produce$1 = function (raw) {
12272
      var mobile = asRawOrDie('Getting IosWebapp schema', MobileSchema, raw);
12273
      set$2(mobile.toolstrip, 'width', '100%');
12274
      set$2(mobile.container, 'position', 'relative');
12275
      var onView = function () {
12276
        mobile.setReadOnly(mobile.readOnlyOnInit());
12277
        mode.enter();
12278
      };
12279
      var mask = build$1(TapToEditMask.sketch(onView, mobile.translate));
12280
      mobile.alloy.add(mask);
12281
      var maskApi = {
12282
        show: function () {
12283
          mobile.alloy.add(mask);
12284
        },
12285
        hide: function () {
12286
          mobile.alloy.remove(mask);
12287
        }
12288
      };
12289
      var mode = IosMode.create(mobile, maskApi);
12290
      return {
12291
        setReadOnly: mobile.setReadOnly,
12292
        refreshStructure: mode.refreshStructure,
12293
        enter: mode.enter,
12294
        exit: mode.exit,
12295
        destroy: noop
12296
      };
12297
    };
12298
    var IosWebapp = { produce: produce$1 };
12299
12300
    function IosRealm (scrollIntoView) {
12301
      var alloy = OuterContainer({ classes: [Styles.resolve('ios-container')] });
12302
      var toolbar = ScrollingToolbar();
12303
      var webapp = api$2();
12304
      var switchToEdit = CommonRealm.makeEditSwitch(webapp);
12305
      var socket = CommonRealm.makeSocket();
12306
      var dropup = build$2(function () {
12307
        webapp.run(function (w) {
12308
          w.refreshStructure();
12309
        });
12310
      }, scrollIntoView);
12311
      alloy.add(toolbar.wrapper());
12312
      alloy.add(socket);
12313
      alloy.add(dropup.component());
12314
      var setToolbarGroups = function (rawGroups) {
12315
        var groups = toolbar.createGroups(rawGroups);
12316
        toolbar.setGroups(groups);
12317
      };
12318
      var setContextToolbar = function (rawGroups) {
12319
        var groups = toolbar.createGroups(rawGroups);
12320
        toolbar.setContextToolbar(groups);
12321
      };
12322
      var focusToolbar = function () {
12323
        toolbar.focus();
12324
      };
12325
      var restoreToolbar = function () {
12326
        toolbar.restoreToolbar();
12327
      };
12328
      var init = function (spec) {
12329
        webapp.set(IosWebapp.produce(spec));
12330
      };
12331
      var exit = function () {
12332
        webapp.run(function (w) {
12333
          Replacing.remove(socket, switchToEdit);
12334
          w.exit();
12335
        });
12336
      };
12337
      var updateMode = function (readOnly) {
12338
        CommonRealm.updateMode(socket, switchToEdit, readOnly, alloy.root());
12339
      };
12340
      return {
12341
        system: constant(alloy),
12342
        element: alloy.element,
12343
        init: init,
12344
        exit: exit,
12345
        setToolbarGroups: setToolbarGroups,
12346
        setContextToolbar: setContextToolbar,
12347
        focusToolbar: focusToolbar,
12348
        restoreToolbar: restoreToolbar,
12349
        updateMode: updateMode,
12350
        socket: constant(socket),
12351
        dropup: constant(dropup)
12352
      };
12353
    }
12354
12355
    var global$2 = tinymce.util.Tools.resolve('tinymce.EditorManager');
12356
12357
    var derive$4 = function (editor) {
12358
      var base = readOptFrom$1(editor.settings, 'skin_url').fold(function () {
12359
        return global$2.baseURL + '/skins/' + 'lightgray';
12360
      }, function (url) {
12361
        return url;
12362
      });
12363
      return {
12364
        content: base + '/content.mobile.min.css',
12365
        ui: base + '/skin.mobile.min.css'
12366
      };
12367
    };
12368
    var CssUrls = { derive: derive$4 };
12369
12370
    var fontSizes = [
12371
      'x-small',
12372
      'small',
12373
      'medium',
12374
      'large',
12375
      'x-large'
12376
    ];
12377
    var fireChange$1 = function (realm, command, state) {
12378
      realm.system().broadcastOn([TinyChannels.formatChanged()], {
12379
        command: command,
12380
        state: state
12381
      });
12382
    };
12383
    var init$5 = function (realm, editor) {
12384
      var allFormats = keys(editor.formatter.get());
12385
      each$1(allFormats, function (command) {
12386
        editor.formatter.formatChanged(command, function (state) {
12387
          fireChange$1(realm, command, state);
12388
        });
12389
      });
12390
      each$1([
12391
        'ul',
12392
        'ol'
12393
      ], function (command) {
12394
        editor.selection.selectorChanged(command, function (state, data) {
12395
          fireChange$1(realm, command, state);
12396
        });
12397
      });
12398
    };
12399
    var FormatChangers = {
12400
      init: init$5,
12401
      fontSizes: constant(fontSizes)
12402
    };
12403
12404
    var fireSkinLoaded = function (editor) {
12405
      var done = function () {
12406
        editor._skinLoaded = true;
12407
        editor.fire('SkinLoaded');
12408
      };
12409
      return function () {
12410
        if (editor.initialized) {
12411
          done();
12412
        } else {
12413
          editor.on('init', done);
12414
        }
12415
      };
12416
    };
12417
    var SkinLoaded = { fireSkinLoaded: fireSkinLoaded };
12418
12419
    var READING = constant('toReading');
12420
    var EDITING = constant('toEditing');
12421
    global$1.add('mobile', function (editor) {
12422
      var renderUI = function (args) {
12423
        var cssUrls = CssUrls.derive(editor);
12424
        if (isSkinDisabled(editor) === false) {
12425
          editor.contentCSS.push(cssUrls.content);
12426
          global.DOM.styleSheetLoader.load(cssUrls.ui, SkinLoaded.fireSkinLoaded(editor));
12427
        } else {
12428
          SkinLoaded.fireSkinLoaded(editor)();
12429
        }
12430
        var doScrollIntoView = function () {
12431
          editor.fire('scrollIntoView');
12432
        };
12433
        var wrapper = Element$$1.fromTag('div');
12434
        var realm = PlatformDetection$1.detect().os.isAndroid() ? AndroidRealm(doScrollIntoView) : IosRealm(doScrollIntoView);
12435
        var original = Element$$1.fromDom(args.targetNode);
12436
        after(original, wrapper);
12437
        attachSystem(wrapper, realm.system());
12438
        var findFocusIn = function (elem) {
12439
          return search(elem).bind(function (focused) {
12440
            return realm.system().getByDom(focused).toOption();
12441
          });
12442
        };
12443
        var outerWindow = args.targetNode.ownerDocument.defaultView;
12444
        var orientation = Orientation.onChange(outerWindow, {
12445
          onChange: function () {
12446
            var alloy = realm.system();
12447
            alloy.broadcastOn([TinyChannels.orientationChanged()], { width: Orientation.getActualWidth(outerWindow) });
12448
          },
12449
          onReady: noop
12450
        });
12451
        var setReadOnly = function (dynamicGroup, readOnlyGroups, mainGroups, ro) {
12452
          if (ro === false) {
12453
            editor.selection.collapse();
12454
          }
12455
          var toolbars = configureToolbar(dynamicGroup, readOnlyGroups, mainGroups);
12456
          realm.setToolbarGroups(ro === true ? toolbars.readOnly : toolbars.main);
12457
          editor.setMode(ro === true ? 'readonly' : 'design');
12458
          editor.fire(ro === true ? READING() : EDITING());
12459
          realm.updateMode(ro);
12460
        };
12461
        var configureToolbar = function (dynamicGroup, readOnlyGroups, mainGroups) {
12462
          var dynamic = dynamicGroup.get();
12463
          var toolbars = {
12464
            readOnly: dynamic.backToMask.concat(readOnlyGroups.get()),
12465
            main: dynamic.backToMask.concat(mainGroups.get())
12466
          };
12467
          return toolbars;
12468
        };
12469
        var bindHandler = function (label, handler) {
12470
          editor.on(label, handler);
12471
          return {
12472
            unbind: function () {
12473
              editor.off(label);
12474
            }
12475
          };
12476
        };
12477
        editor.on('init', function () {
12478
          realm.init({
12479
            editor: {
12480
              getFrame: function () {
12481
                return Element$$1.fromDom(editor.contentAreaContainer.querySelector('iframe'));
12482
              },
12483
              onDomChanged: function () {
12484
                return { unbind: noop };
12485
              },
12486
              onToReading: function (handler) {
12487
                return bindHandler(READING(), handler);
12488
              },
12489
              onToEditing: function (handler) {
12490
                return bindHandler(EDITING(), handler);
12491
              },
12492
              onScrollToCursor: function (handler) {
12493
                editor.on('scrollIntoView', function (tinyEvent) {
12494
                  handler(tinyEvent);
12495
                });
12496
                var unbind = function () {
12497
                  editor.off('scrollIntoView');
12498
                  orientation.destroy();
12499
                };
12500
                return { unbind: unbind };
12501
              },
12502
              onTouchToolstrip: function () {
12503
                hideDropup();
12504
              },
12505
              onTouchContent: function () {
12506
                var toolbar = Element$$1.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolbar')));
12507
                findFocusIn(toolbar).each(emitExecute);
12508
                realm.restoreToolbar();
12509
                hideDropup();
12510
              },
12511
              onTapContent: function (evt) {
12512
                var target = evt.target();
12513
                if (name(target) === 'img') {
12514
                  editor.selection.select(target.dom());
12515
                  evt.kill();
12516
                } else if (name(target) === 'a') {
12517
                  var component = realm.system().getByDom(Element$$1.fromDom(editor.editorContainer));
12518
                  component.each(function (container) {
12519
                    if (Swapping.isAlpha(container)) {
12520
                      TinyCodeDupe.openLink(target.dom());
12521
                    }
12522
                  });
12523
                }
12524
              }
12525
            },
12526
            container: Element$$1.fromDom(editor.editorContainer),
12527
            socket: Element$$1.fromDom(editor.contentAreaContainer),
12528
            toolstrip: Element$$1.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolstrip'))),
12529
            toolbar: Element$$1.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolbar'))),
12530
            dropup: realm.dropup(),
12531
            alloy: realm.system(),
12532
            translate: noop,
12533
            setReadOnly: function (ro) {
12534
              setReadOnly(dynamicGroup, readOnlyGroups, mainGroups, ro);
12535
            },
12536
            readOnlyOnInit: function () {
12537
              return readOnlyOnInit(editor);
12538
            }
12539
          });
12540
          var hideDropup = function () {
12541
            realm.dropup().disappear(function () {
12542
              realm.system().broadcastOn([TinyChannels.dropupDismissed()], {});
12543
            });
12544
          };
12545
          var backToMaskGroup = {
12546
            label: 'The first group',
12547
            scrollable: false,
12548
            items: [Buttons.forToolbar('back', function () {
12549
                editor.selection.collapse();
12550
                realm.exit();
12551
              }, {})]
12552
          };
12553
          var backToReadOnlyGroup = {
12554
            label: 'Back to read only',
12555
            scrollable: false,
12556
            items: [Buttons.forToolbar('readonly-back', function () {
12557
                setReadOnly(dynamicGroup, readOnlyGroups, mainGroups, true);
12558
              }, {})]
12559
          };
12560
          var readOnlyGroup = {
12561
            label: 'The read only mode group',
12562
            scrollable: true,
12563
            items: []
12564
          };
12565
          var features = Features.setup(realm, editor);
12566
          var items = Features.detect(editor.settings, features);
12567
          var actionGroup = {
12568
            label: 'the action group',
12569
            scrollable: true,
12570
            items: items
12571
          };
12572
          var extraGroup = {
12573
            label: 'The extra group',
12574
            scrollable: false,
12575
            items: []
12576
          };
12577
          var mainGroups = Cell([
12578
            actionGroup,
12579
            extraGroup
12580
          ]);
12581
          var readOnlyGroups = Cell([
12582
            readOnlyGroup,
12583
            extraGroup
12584
          ]);
12585
          var dynamicGroup = Cell({
12586
            backToMask: [backToMaskGroup],
12587
            backToReadOnly: [backToReadOnlyGroup]
12588
          });
12589
          FormatChangers.init(realm, editor);
12590
        });
12591
        return {
12592
          iframeContainer: realm.socket().element().dom(),
12593
          editorContainer: realm.element().dom()
12594
        };
12595
      };
12596
      return {
12597
        getNotificationManagerImpl: function () {
12598
          return {
12599
            open: identity,
12600
            close: noop,
12601
            reposition: noop,
12602
            getArgs: identity
12603
          };
12604
        },
12605
        renderUI: renderUI
12606
      };
12607
    });
12608
    function Theme () {
12609
    }
12610
12611
    return Theme;
12612
12613
}());
12614
})();
12615