Browse code

Readded jbox files in public folder

Benjamin Roth authored on22/02/2023 21:56:38
Showing34 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,1251 @@
1
+.jBox-wrapper {
2
+  text-align: left;
3
+  box-sizing: border-box;
4
+}
5
+
6
+.jBox-title,
7
+.jBox-content,
8
+.jBox-container {
9
+  position: relative;
10
+  word-break: break-word;
11
+  box-sizing: border-box;
12
+}
13
+
14
+.jBox-container {
15
+  background: #fff;
16
+}
17
+
18
+.jBox-content {
19
+  padding: 8px 12px;
20
+  overflow-x: hidden;
21
+  overflow-y: auto;
22
+  transition: opacity .2s;
23
+}
24
+
25
+.jBox-footer {
26
+  box-sizing: border-box;
27
+}
28
+
29
+.jBox-Tooltip .jBox-container,
30
+.jBox-Mouse .jBox-container {
31
+  border-radius: 4px;
32
+  box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
33
+}
34
+
35
+.jBox-Tooltip .jBox-title,
36
+.jBox-Mouse .jBox-title {
37
+  padding: 8px 10px 0;
38
+  font-weight: bold;
39
+}
40
+
41
+.jBox-Tooltip.jBox-hasTitle .jBox-content,
42
+.jBox-Mouse.jBox-hasTitle .jBox-content {
43
+  padding-top: 5px;
44
+}
45
+
46
+.jBox-Mouse {
47
+  pointer-events: none;
48
+}
49
+
50
+.jBox-pointer {
51
+  position: absolute;
52
+  overflow: hidden;
53
+  box-sizing: border-box;
54
+}
55
+
56
+.jBox-pointer:after {
57
+  content: '';
58
+  width: 20px;
59
+  height: 20px;
60
+  position: absolute;
61
+  background: #fff;
62
+  transform: rotate(45deg);
63
+  box-sizing: border-box;
64
+}
65
+
66
+.jBox-pointer-top {
67
+  top: 0;
68
+}
69
+
70
+.jBox-pointer-top:after {
71
+  left: 5px;
72
+  top: 6px;
73
+  box-shadow: -1px -1px 2px rgba(0, 0, 0, 0.15);
74
+}
75
+
76
+.jBox-pointer-right {
77
+  right: 0;
78
+}
79
+
80
+.jBox-pointer-right:after {
81
+  top: 5px;
82
+  right: 6px;
83
+  box-shadow: 1px -1px 2px rgba(0, 0, 0, 0.15);
84
+}
85
+
86
+.jBox-pointer-left {
87
+  left: 0;
88
+}
89
+
90
+.jBox-pointer-left:after {
91
+  top: 5px;
92
+  left: 6px;
93
+  box-shadow: -1px 1px 2px rgba(0, 0, 0, 0.15);
94
+}
95
+
96
+.jBox-pointer-bottom {
97
+  bottom: 0;
98
+}
99
+
100
+.jBox-pointer-bottom:after {
101
+  left: 5px;
102
+  bottom: 6px;
103
+  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15);
104
+}
105
+
106
+.jBox-pointer-top, .jBox-pointer-bottom {
107
+  width: 30px;
108
+  height: 12px;
109
+}
110
+
111
+.jBox-pointer-left, .jBox-pointer-right {
112
+  width: 12px;
113
+  height: 30px;
114
+}
115
+
116
+.jBox-Modal .jBox-container {
117
+  border-radius: 4px;
118
+}
119
+
120
+.jBox-Modal .jBox-container, .jBox-Modal.jBox-closeButton-box:before {
121
+  box-shadow: 0 3px 15px rgba(0, 0, 0, 0.4), 0 0 5px rgba(0, 0, 0, 0.4);
122
+}
123
+
124
+.jBox-Modal .jBox-content {
125
+  padding: 15px 20px;
126
+}
127
+
128
+.jBox-Modal .jBox-title {
129
+  border-radius: 4px 4px 0 0;
130
+  padding: 15px 20px;
131
+  background: #fafafa;
132
+  border-bottom: 1px solid #eee;
133
+}
134
+
135
+.jBox-Modal.jBox-closeButton-title .jBox-title {
136
+  padding-right: 65px;
137
+}
138
+
139
+.jBox-Modal .jBox-footer {
140
+  border-radius: 0 0 4px 4px;
141
+}
142
+
143
+.jBox-closeButton {
144
+  z-index: 1;
145
+  cursor: pointer;
146
+  position: absolute;
147
+  box-sizing: border-box;
148
+}
149
+
150
+.jBox-closeButton svg {
151
+  position: absolute;
152
+  top: 50%;
153
+  right: 50%;
154
+}
155
+
156
+.jBox-closeButton path {
157
+  fill: #aaa;
158
+  transition: fill .2s;
159
+}
160
+
161
+.jBox-closeButton:hover path {
162
+  fill: #888;
163
+}
164
+
165
+.jBox-overlay .jBox-closeButton {
166
+  top: 0;
167
+  right: 0;
168
+  width: 40px;
169
+  height: 40px;
170
+}
171
+
172
+.jBox-overlay .jBox-closeButton svg {
173
+  width: 20px;
174
+  height: 20px;
175
+  margin-top: -10px;
176
+  margin-right: -10px;
177
+}
178
+
179
+.jBox-overlay .jBox-closeButton path {
180
+  fill: #ddd;
181
+}
182
+
183
+.jBox-overlay .jBox-closeButton:hover path {
184
+  fill: #fff;
185
+}
186
+
187
+.jBox-closeButton-title .jBox-closeButton {
188
+  top: 0;
189
+  right: 0;
190
+  bottom: 0;
191
+  width: 50px;
192
+}
193
+
194
+.jBox-closeButton-title svg {
195
+  width: 12px;
196
+  height: 12px;
197
+  margin-top: -6px;
198
+  margin-right: -6px;
199
+}
200
+
201
+.jBox-closeButton-box {
202
+  box-sizing: border-box;
203
+}
204
+
205
+.jBox-closeButton-box .jBox-closeButton {
206
+  top: -8px;
207
+  right: -10px;
208
+  width: 24px;
209
+  height: 24px;
210
+  background: #fff;
211
+  border-radius: 50%;
212
+}
213
+
214
+.jBox-closeButton-box .jBox-closeButton svg {
215
+  width: 10px;
216
+  height: 10px;
217
+  margin-top: -5px;
218
+  margin-right: -5px;
219
+}
220
+
221
+.jBox-closeButton-box:before {
222
+  content: '';
223
+  position: absolute;
224
+  top: -8px;
225
+  right: -10px;
226
+  width: 24px;
227
+  height: 24px;
228
+  border-radius: 50%;
229
+  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
230
+}
231
+
232
+.jBox-closeButton-box.jBox-pointerPosition-top:before {
233
+  top: 5px;
234
+}
235
+
236
+.jBox-closeButton-box.jBox-pointerPosition-right:before {
237
+  right: 2px;
238
+}
239
+
240
+.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton {
241
+  background: #fafafa;
242
+}
243
+
244
+.jBox-overlay {
245
+  position: fixed;
246
+  top: 0;
247
+  left: 0;
248
+  width: 100%;
249
+  height: 100%;
250
+  background-color: rgba(0, 0, 0, 0.82);
251
+}
252
+
253
+.jBox-footer {
254
+  background: #fafafa;
255
+  border-top: 1px solid #eee;
256
+  padding: 8px 10px;
257
+  border-radius: 0 0 3px 3px;
258
+}
259
+
260
+body[class^="jBox-blockScroll-"],
261
+body[class*=" jBox-blockScroll-"] {
262
+  overflow: hidden;
263
+}
264
+
265
+.jBox-draggable {
266
+  cursor: move;
267
+}
268
+
269
+@keyframes jBoxLoading {
270
+  to {
271
+    transform: rotate(360deg);
272
+  }
273
+}
274
+
275
+.jBox-loading .jBox-content {
276
+  opacity: .2;
277
+}
278
+
279
+.jBox-loading-spinner .jBox-content {
280
+  min-height: 38px !important;
281
+  min-width: 38px !important;
282
+  opacity: 0;
283
+}
284
+
285
+.jBox-spinner {
286
+  box-sizing: border-box;
287
+  position: absolute;
288
+  top: 50%;
289
+  left: 50%;
290
+  width: 24px;
291
+  height: 24px;
292
+  margin-top: -12px;
293
+  margin-left: -12px;
294
+}
295
+
296
+.jBox-spinner:before {
297
+  display: block;
298
+  box-sizing: border-box;
299
+  content: '';
300
+  width: 24px;
301
+  height: 24px;
302
+  border-radius: 50%;
303
+  border: 2px solid rgba(0, 0, 0, 0.2);
304
+  border-top-color: rgba(0, 0, 0, 0.8);
305
+  animation: jBoxLoading .6s linear infinite;
306
+}
307
+
308
+.jBox-countdown {
309
+  border-radius: 4px 4px 0 0;
310
+  z-index: 0;
311
+  background: #000;
312
+  opacity: .2;
313
+  position: absolute;
314
+  top: 0;
315
+  left: 0;
316
+  right: 0;
317
+  height: 3px;
318
+  overflow: hidden;
319
+}
320
+
321
+.jBox-countdown-inner {
322
+  top: 0;
323
+  right: 0;
324
+  width: 100%;
325
+  height: 3px;
326
+  position: absolute;
327
+  background: #fff;
328
+}
329
+
330
+[class^="jBox-animated-"],
331
+[class*=" jBox-animated-"] {
332
+  animation-fill-mode: both;
333
+}
334
+
335
+@keyframes jBox-tada {
336
+  0% {
337
+    transform: scale(1);
338
+  }
339
+  10%,
340
+  20% {
341
+    transform: scale(0.8) rotate(-4deg);
342
+  }
343
+  30%,
344
+  50%,
345
+  70%,
346
+  90% {
347
+    transform: scale(1.2) rotate(4deg);
348
+  }
349
+  40%,
350
+  60%,
351
+  80% {
352
+    transform: scale(1.2) rotate(-4deg);
353
+  }
354
+  100% {
355
+    transform: scale(1) rotate(0);
356
+  }
357
+}
358
+
359
+.jBox-animated-tada {
360
+  animation: jBox-tada 1s;
361
+}
362
+
363
+@keyframes jBox-tadaSmall {
364
+  0% {
365
+    transform: scale(1);
366
+  }
367
+  10%,
368
+  20% {
369
+    transform: scale(0.9) rotate(-2deg);
370
+  }
371
+  30%,
372
+  50%,
373
+  70%,
374
+  90% {
375
+    transform: scale(1.1) rotate(2deg);
376
+  }
377
+  40%,
378
+  60%,
379
+  80% {
380
+    transform: scale(1.1) rotate(-2deg);
381
+  }
382
+  100% {
383
+    transform: scale(1) rotate(0);
384
+  }
385
+}
386
+
387
+.jBox-animated-tadaSmall {
388
+  animation: jBox-tadaSmall 1s;
389
+}
390
+
391
+@keyframes jBox-flash {
392
+  0%,
393
+  50%,
394
+  100% {
395
+    opacity: 1;
396
+  }
397
+  25%,
398
+  75% {
399
+    opacity: 0;
400
+  }
401
+}
402
+
403
+.jBox-animated-flash {
404
+  animation: jBox-flash .5s;
405
+}
406
+
407
+@keyframes jBox-shake {
408
+  0%,
409
+  100% {
410
+    transform: translateX(0);
411
+  }
412
+  20%,
413
+  60% {
414
+    transform: translateX(-6px);
415
+  }
416
+  40%,
417
+  80% {
418
+    transform: translateX(6px);
419
+  }
420
+}
421
+
422
+.jBox-animated-shake {
423
+  animation: jBox-shake .4s;
424
+}
425
+
426
+@keyframes jBox-pulseUp {
427
+  0% {
428
+    transform: scale(1);
429
+  }
430
+  50% {
431
+    transform: scale(1.15);
432
+  }
433
+  100% {
434
+    transform: scale(1);
435
+  }
436
+}
437
+
438
+.jBox-animated-pulseUp {
439
+  animation: jBox-pulseUp .25s;
440
+}
441
+
442
+@keyframes jBox-pulseDown {
443
+  0% {
444
+    transform: scale(1);
445
+  }
446
+  50% {
447
+    transform: scale(0.85);
448
+  }
449
+  100% {
450
+    transform: scale(1);
451
+  }
452
+}
453
+
454
+.jBox-animated-pulseDown {
455
+  animation: jBox-pulseDown .25s;
456
+}
457
+
458
+@keyframes jBox-popIn {
459
+  0% {
460
+    transform: scale(0);
461
+  }
462
+  50% {
463
+    transform: scale(1.1);
464
+  }
465
+  100% {
466
+    transform: scale(1);
467
+  }
468
+}
469
+
470
+.jBox-animated-popIn {
471
+  animation: jBox-popIn .25s;
472
+}
473
+
474
+@keyframes jBox-popOut {
475
+  0% {
476
+    transform: scale(1);
477
+  }
478
+  50% {
479
+    transform: scale(1.1);
480
+  }
481
+  100% {
482
+    transform: scale(0);
483
+  }
484
+}
485
+
486
+.jBox-animated-popOut {
487
+  animation: jBox-popOut .25s;
488
+}
489
+
490
+@keyframes jBox-fadeIn {
491
+  0% {
492
+    opacity: 0;
493
+  }
494
+  100% {
495
+    opacity: 1;
496
+  }
497
+}
498
+
499
+.jBox-animated-fadeIn {
500
+  animation: jBox-fadeIn .2s;
501
+}
502
+
503
+@keyframes jBox-fadeOut {
504
+  0% {
505
+    opacity: 1;
506
+  }
507
+  100% {
508
+    opacity: 0;
509
+  }
510
+}
511
+
512
+.jBox-animated-fadeOut {
513
+  animation: jBox-fadeOut .2s;
514
+}
515
+
516
+@keyframes jBox-slideUp {
517
+  0% {
518
+    transform: translateY(0);
519
+  }
520
+  100% {
521
+    transform: translateY(-300px);
522
+    opacity: 0;
523
+  }
524
+}
525
+
526
+.jBox-animated-slideUp {
527
+  animation: jBox-slideUp .4s;
528
+}
529
+
530
+@keyframes jBox-slideRight {
531
+  0% {
532
+    transform: translateX(0);
533
+  }
534
+  100% {
535
+    transform: translateX(300px);
536
+    opacity: 0;
537
+  }
538
+}
539
+
540
+.jBox-animated-slideRight {
541
+  animation: jBox-slideRight .4s;
542
+}
543
+
544
+@keyframes jBox-slideDown {
545
+  0% {
546
+    transform: translateY(0);
547
+  }
548
+  100% {
549
+    transform: translateY(300px);
550
+    opacity: 0;
551
+  }
552
+}
553
+
554
+.jBox-animated-slideDown {
555
+  animation: jBox-slideDown .4s;
556
+}
557
+
558
+@keyframes jBox-slideLeft {
559
+  0% {
560
+    transform: translateX(0);
561
+  }
562
+  100% {
563
+    transform: translateX(-300px);
564
+    opacity: 0;
565
+  }
566
+}
567
+
568
+.jBox-animated-slideLeft {
569
+  animation: jBox-slideLeft .4s;
570
+}
571
+
572
+.jBox-Confirm .jBox-content {
573
+  text-align: center;
574
+  padding: 46px 35px;
575
+}
576
+
577
+@media (max-width: 500px) {
578
+  .jBox-Confirm .jBox-content {
579
+    padding: 32px 20px;
580
+  }
581
+}
582
+
583
+.jBox-Confirm-footer {
584
+  height: 46px;
585
+}
586
+
587
+.jBox-Confirm-button {
588
+  display: block;
589
+  float: left;
590
+  cursor: pointer;
591
+  text-align: center;
592
+  width: 50%;
593
+  line-height: 46px;
594
+  height: 46px;
595
+  overflow: hidden;
596
+  padding: 0 10px;
597
+  transition: color .2s, background-color .2s;
598
+  box-sizing: border-box;
599
+}
600
+
601
+.jBox-Confirm-button-cancel {
602
+  border-bottom-left-radius: 4px;
603
+  background: #ddd;
604
+  color: #666;
605
+}
606
+
607
+.jBox-Confirm-button-cancel:hover, .jBox-Confirm-button-cancel:active {
608
+  background: #ccc;
609
+}
610
+
611
+.jBox-Confirm-button-cancel:active {
612
+  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
613
+}
614
+
615
+.jBox-Confirm-button-submit {
616
+  border-bottom-right-radius: 4px;
617
+  background: #7d0;
618
+  color: #fff;
619
+}
620
+
621
+.jBox-Confirm-button-submit:hover, .jBox-Confirm-button-submit:active {
622
+  background: #6c0;
623
+}
624
+
625
+.jBox-Confirm-button-submit:active {
626
+  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
627
+}
628
+
629
+.jBox-Image .jBox-container {
630
+  background-color: transparent;
631
+}
632
+
633
+.jBox-Image .jBox-content {
634
+  padding: 0;
635
+  width: 100%;
636
+  height: 100%;
637
+}
638
+
639
+.jBox-image-container {
640
+  background: center center no-repeat;
641
+  position: absolute;
642
+  width: 100%;
643
+  height: 100%;
644
+  opacity: 0;
645
+}
646
+
647
+.jBox-image-label-wrapper {
648
+  position: absolute;
649
+  top: 100%;
650
+  left: 0;
651
+  right: 0;
652
+  height: 40px;
653
+  z-index: 100;
654
+  display: flex;
655
+}
656
+
657
+.jBox-image-label-container {
658
+  position: relative;
659
+  flex: 1;
660
+}
661
+
662
+.jBox-image-label {
663
+  box-sizing: border-box;
664
+  position: absolute;
665
+  left: 0;
666
+  bottom: 0;
667
+  width: 100%;
668
+  text-align: center;
669
+  color: #fff;
670
+  padding: 8px 12px;
671
+  font-size: 15px;
672
+  line-height: 24px;
673
+  transition: opacity .36s;
674
+  opacity: 0;
675
+  z-index: 0;
676
+  pointer-events: none;
677
+}
678
+
679
+.jBox-image-label.expanded {
680
+  background: #000;
681
+}
682
+
683
+.jBox-image-label:not(.expanded) {
684
+  text-overflow: ellipsis;
685
+  white-space: nowrap;
686
+  overflow: hidden;
687
+}
688
+
689
+.jBox-image-label.active {
690
+  opacity: 1;
691
+  pointer-events: all;
692
+}
693
+
694
+@media (max-width: 600px) {
695
+  .jBox-image-label {
696
+    font-size: 13px;
697
+  }
698
+}
699
+
700
+.jBox-image-pointer-next,
701
+.jBox-image-pointer-prev {
702
+  flex-shrink: 0;
703
+  width: 40px;
704
+  height: 40px;
705
+  cursor: pointer;
706
+  opacity: .8;
707
+  transition: opacity .2s;
708
+  background: no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);
709
+  background-size: 11px auto;
710
+  user-select: none;
711
+  z-index: 1;
712
+}
713
+
714
+.jBox-image-pointer-next:hover,
715
+.jBox-image-pointer-prev:hover {
716
+  opacity: 1;
717
+}
718
+
719
+.jBox-image-pointer-next {
720
+  transform: scaleX(-1);
721
+}
722
+
723
+.jBox-image-counter-container {
724
+  flex-shrink: 0;
725
+  white-space: nowrap;
726
+  height: 40px;
727
+  line-height: 40px;
728
+  font-size: 13px;
729
+  color: #fff;
730
+  text-align: right;
731
+  display: none;
732
+}
733
+
734
+.jBox-image-has-counter .jBox-image-counter-container {
735
+  display: block;
736
+}
737
+
738
+.jBox-overlay.jBox-overlay-Image {
739
+  background: #000;
740
+}
741
+
742
+.jBox-image-not-found {
743
+  background: #000;
744
+}
745
+
746
+.jBox-image-not-found:before {
747
+  content: '';
748
+  box-sizing: border-box;
749
+  display: block;
750
+  width: 80px;
751
+  height: 80px;
752
+  margin-top: -40px;
753
+  margin-left: -40px;
754
+  position: absolute;
755
+  top: 50%;
756
+  left: 50%;
757
+  border: 5px solid #222;
758
+  border-radius: 50%;
759
+}
760
+
761
+.jBox-image-not-found:after {
762
+  content: '';
763
+  display: block;
764
+  box-sizing: content-box;
765
+  z-index: auto;
766
+  width: 6px;
767
+  height: 74px;
768
+  margin-top: -37px;
769
+  margin-left: -3px;
770
+  position: absolute;
771
+  top: 50%;
772
+  left: 50%;
773
+  background: #222;
774
+  transform: rotateZ(45deg);
775
+  transform-origin: 50% 50% 0;
776
+}
777
+
778
+.jBox-image-download-button-wrapper {
779
+  position: absolute;
780
+  top: -40px;
781
+  right: 35px;
782
+  height: 40px;
783
+  display: flex;
784
+  cursor: pointer;
785
+  opacity: .8;
786
+  transition: opacity .2s;
787
+}
788
+
789
+.jBox-image-download-button-wrapper:hover {
790
+  opacity: 1;
791
+}
792
+
793
+.jBox-image-download-button-icon {
794
+  width: 40px;
795
+  height: 40px;
796
+  background: center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);
797
+  background-size: 60%;
798
+}
799
+
800
+.jBox-image-download-button-text {
801
+  white-space: nowrap;
802
+  line-height: 40px;
803
+  padding: 0 10px 0 0;
804
+  color: #fff;
805
+  font-size: 14px;
806
+}
807
+
808
+@keyframes jBoxImageLoading {
809
+  to {
810
+    transform: rotate(360deg);
811
+  }
812
+}
813
+
814
+.jBox-image-loading:before {
815
+  content: '';
816
+  position: absolute;
817
+  top: 50%;
818
+  left: 50%;
819
+  width: 32px;
820
+  height: 32px;
821
+  margin-top: -16px;
822
+  margin-left: -16px;
823
+  border: 4px solid #333;
824
+  border-bottom-color: #666;
825
+  animation: jBoxImageLoading 1.2s linear infinite;
826
+  border-radius: 50%;
827
+}
828
+
829
+.jBox-Notice {
830
+  transition: margin .2s;
831
+}
832
+
833
+.jBox-Notice .jBox-container {
834
+  border-radius: 4px;
835
+  box-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.25), inset -1px -1px 0 0 rgba(0, 0, 0, 0.1);
836
+}
837
+
838
+.jBox-Notice .jBox-content {
839
+  border-radius: 4px;
840
+  padding: 12px 20px;
841
+}
842
+
843
+@media (max-width: 768px) {
844
+  .jBox-Notice .jBox-content {
845
+    padding: 10px 15px;
846
+  }
847
+}
848
+
849
+@media (max-width: 500px) {
850
+  .jBox-Notice .jBox-content {
851
+    padding: 8px 10px;
852
+  }
853
+}
854
+
855
+.jBox-Notice.jBox-hasTitle .jBox-content {
856
+  padding-top: 5px;
857
+}
858
+
859
+@media (max-width: 500px) {
860
+  .jBox-Notice.jBox-hasTitle .jBox-content {
861
+    padding-top: 0;
862
+  }
863
+}
864
+
865
+.jBox-Notice.jBox-hasTitle .jBox-title {
866
+  padding: 12px 20px 0;
867
+  font-weight: bold;
868
+}
869
+
870
+@media (max-width: 768px) {
871
+  .jBox-Notice.jBox-hasTitle .jBox-title {
872
+    padding: 10px 15px 0;
873
+  }
874
+}
875
+
876
+@media (max-width: 500px) {
877
+  .jBox-Notice.jBox-hasTitle .jBox-title {
878
+    padding: 8px 10px 0;
879
+  }
880
+}
881
+
882
+.jBox-Notice.jBox-closeButton-title .jBox-title {
883
+  padding-right: 55px;
884
+}
885
+
886
+.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
887
+  width: 40px;
888
+}
889
+
890
+.jBox-Notice.jBox-Notice-black .jBox-container {
891
+  color: #fff;
892
+  background: #000;
893
+}
894
+
895
+.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
896
+.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
897
+  fill: #fff;
898
+}
899
+
900
+.jBox-Notice.jBox-Notice-gray .jBox-container {
901
+  color: #222;
902
+  background: #f6f6f6;
903
+}
904
+
905
+.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
906
+.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
907
+  fill: #222;
908
+}
909
+
910
+.jBox-Notice.jBox-Notice-red .jBox-container {
911
+  color: #fff;
912
+  background: #d00;
913
+}
914
+
915
+.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
916
+.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
917
+  fill: #fff;
918
+}
919
+
920
+.jBox-Notice.jBox-Notice-green .jBox-container {
921
+  color: #fff;
922
+  background: #5d0;
923
+}
924
+
925
+.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
926
+.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
927
+  fill: #fff;
928
+}
929
+
930
+.jBox-Notice.jBox-Notice-blue .jBox-container {
931
+  color: #fff;
932
+  background: #49d;
933
+}
934
+
935
+.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
936
+.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
937
+  fill: #fff;
938
+}
939
+
940
+.jBox-Notice.jBox-Notice-yellow .jBox-container {
941
+  color: #000;
942
+  background: #fd0;
943
+}
944
+
945
+.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
946
+.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
947
+  fill: #fff;
948
+}
949
+
950
+.jBox-NoticeFancy .jBox-content,
951
+.jBox-NoticeFancy .jBox-title {
952
+  padding-left: 25px;
953
+}
954
+
955
+.jBox-NoticeFancy.jBox-Notice-color .jBox-container {
956
+  color: #fff;
957
+  background: #000;
958
+}
959
+
960
+.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after {
961
+  content: '';
962
+  position: absolute;
963
+  top: 0;
964
+  left: 0;
965
+  bottom: 0;
966
+  width: 8px;
967
+  border-radius: 4px 0 0 4px;
968
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);
969
+  background-size: 14px 14px;
970
+}
971
+
972
+.jBox-NoticeFancy.jBox-Notice-black .jBox-container:after,
973
+.jBox-NoticeFancy.jBox-Notice-gray .jBox-container:after {
974
+  background-color: #888;
975
+}
976
+
977
+.jBox-NoticeFancy.jBox-Notice-red .jBox-container:after {
978
+  background-color: #e00;
979
+}
980
+
981
+.jBox-NoticeFancy.jBox-Notice-green .jBox-container:after {
982
+  background-color: #6c0;
983
+}
984
+
985
+.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after {
986
+  background-color: #49d;
987
+}
988
+
989
+.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after {
990
+  background-color: #fb0;
991
+}
992
+
993
+.jBox-NoticeFancy .jBox-countdown {
994
+  left: 8px;
995
+  border-radius: 0 4px 0 0;
996
+}
997
+
998
+.jBox-TooltipBorder .jBox-container,
999
+.jBox-TooltipBorder .jBox-pointer:after {
1000
+  border: 2px solid #49d;
1001
+}
1002
+
1003
+.jBox-TooltipBorder .jBox-pointer:after {
1004
+  width: 22px;
1005
+  height: 22px;
1006
+}
1007
+
1008
+.jBox-TooltipBorder .jBox-pointer-top,
1009
+.jBox-TooltipBorder .jBox-pointer-bottom {
1010
+  width: 34px;
1011
+  height: 13px;
1012
+}
1013
+
1014
+.jBox-TooltipBorder .jBox-pointer-top:after,
1015
+.jBox-TooltipBorder .jBox-pointer-bottom:after {
1016
+  left: 6px;
1017
+}
1018
+
1019
+.jBox-TooltipBorder .jBox-pointer-left,
1020
+.jBox-TooltipBorder .jBox-pointer-right {
1021
+  width: 13px;
1022
+  height: 34px;
1023
+}
1024
+
1025
+.jBox-TooltipBorder .jBox-pointer-left:after,
1026
+.jBox-TooltipBorder .jBox-pointer-right:after {
1027
+  top: 6px;
1028
+}
1029
+
1030
+.jBox-TooltipBorder.jBox-closeButton-box:before {
1031
+  width: 28px;
1032
+  height: 28px;
1033
+  background: #49d;
1034
+}
1035
+
1036
+.jBox-TooltipBorderThick .jBox-container {
1037
+  box-shadow: none;
1038
+  border-radius: 8px;
1039
+  border: 4px solid #ccc;
1040
+}
1041
+
1042
+.jBox-TooltipBorderThick .jBox-pointer:after {
1043
+  box-shadow: none;
1044
+  border: 4px solid #ccc;
1045
+  width: 24px;
1046
+  height: 24px;
1047
+}
1048
+
1049
+.jBox-TooltipBorderThick .jBox-pointer-top,
1050
+.jBox-TooltipBorderThick .jBox-pointer-bottom {
1051
+  width: 38px;
1052
+  height: 13px;
1053
+}
1054
+
1055
+.jBox-TooltipBorderThick .jBox-pointer-left,
1056
+.jBox-TooltipBorderThick .jBox-pointer-right {
1057
+  width: 13px;
1058
+  height: 38px;
1059
+}
1060
+
1061
+.jBox-TooltipBorderThick.jBox-closeButton-box:before {
1062
+  width: 32px;
1063
+  height: 32px;
1064
+  background: #ccc;
1065
+}
1066
+
1067
+.jBox-TooltipDark .jBox-container {
1068
+  border-radius: 4px;
1069
+  background: #000;
1070
+  color: #fff;
1071
+  box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
1072
+}
1073
+
1074
+.jBox-TooltipDark .jBox-pointer:after {
1075
+  background: #000;
1076
+}
1077
+
1078
+.jBox-TooltipDark .jBox-closeButton {
1079
+  background: #000;
1080
+}
1081
+
1082
+.jBox-TooltipDark.jBox-closeButton-box:before {
1083
+  box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
1084
+}
1085
+
1086
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path {
1087
+  fill: #ddd;
1088
+}
1089
+
1090
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path {
1091
+  fill: #fff;
1092
+}
1093
+
1094
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path {
1095
+  fill: #bbb;
1096
+}
1097
+
1098
+.jBox-TooltipError {
1099
+  pointer-events: none;
1100
+}
1101
+
1102
+.jBox-TooltipError .jBox-container {
1103
+  border-radius: 2px;
1104
+  background: #d00;
1105
+  color: #fff;
1106
+  font-weight: bold;
1107
+  font-size: 13px;
1108
+}
1109
+
1110
+.jBox-TooltipError .jBox-content {
1111
+  padding: 0 10px;
1112
+  line-height: 28px;
1113
+}
1114
+
1115
+.jBox-TooltipError .jBox-pointer:after {
1116
+  background: #d00;
1117
+  width: 20px;
1118
+  height: 20px;
1119
+}
1120
+
1121
+.jBox-TooltipError .jBox-pointer-top, .jBox-TooltipError .jBox-pointer-bottom {
1122
+  width: 22px;
1123
+  height: 8px;
1124
+}
1125
+
1126
+.jBox-TooltipError .jBox-pointer-right, .jBox-TooltipError .jBox-pointer-left {
1127
+  width: 8px;
1128
+  height: 22px;
1129
+}
1130
+
1131
+.jBox-TooltipError .jBox-pointer-top:after {
1132
+  left: 1px;
1133
+  top: 6px;
1134
+}
1135
+
1136
+.jBox-TooltipError .jBox-pointer-right:after {
1137
+  top: 1px;
1138
+  right: 6px;
1139
+}
1140
+
1141
+.jBox-TooltipError .jBox-pointer-bottom:after {
1142
+  left: 1px;
1143
+  bottom: 6px;
1144
+}
1145
+
1146
+.jBox-TooltipError .jBox-pointer-left:after {
1147
+  top: 1px;
1148
+  left: 6px;
1149
+}
1150
+
1151
+.jBox-TooltipSmall {
1152
+  pointer-events: none;
1153
+}
1154
+
1155
+.jBox-TooltipSmall .jBox-container {
1156
+  border-radius: 2px;
1157
+}
1158
+
1159
+.jBox-TooltipSmall .jBox-content {
1160
+  padding: 0 10px;
1161
+  line-height: 28px;
1162
+}
1163
+
1164
+.jBox-TooltipSmall .jBox-pointer:after {
1165
+  width: 20px;
1166
+  height: 20px;
1167
+}
1168
+
1169
+.jBox-TooltipSmall .jBox-pointer-top, .jBox-TooltipSmall .jBox-pointer-bottom {
1170
+  width: 22px;
1171
+  height: 8px;
1172
+}
1173
+
1174
+.jBox-TooltipSmall .jBox-pointer-right, .jBox-TooltipSmall .jBox-pointer-left {
1175
+  width: 8px;
1176
+  height: 22px;
1177
+}
1178
+
1179
+.jBox-TooltipSmall .jBox-pointer-top:after {
1180
+  left: 1px;
1181
+  top: 6px;
1182
+}
1183
+
1184
+.jBox-TooltipSmall .jBox-pointer-right:after {
1185
+  top: 1px;
1186
+  right: 6px;
1187
+}
1188
+
1189
+.jBox-TooltipSmall .jBox-pointer-bottom:after {
1190
+  left: 1px;
1191
+  bottom: 6px;
1192
+}
1193
+
1194
+.jBox-TooltipSmall .jBox-pointer-left:after {
1195
+  top: 1px;
1196
+  left: 6px;
1197
+}
1198
+
1199
+.jBox-TooltipSmallGray {
1200
+  pointer-events: none;
1201
+}
1202
+
1203
+.jBox-TooltipSmallGray .jBox-container {
1204
+  font-size: 13px;
1205
+  line-height: 24px;
1206
+  border-radius: 12px;
1207
+  background-image: linear-gradient(to bottom, #fafafa, #f2f2f2);
1208
+}
1209
+
1210
+.jBox-TooltipSmallGray .jBox-content {
1211
+  padding: 0 10px;
1212
+}
1213
+
1214
+.jBox-TooltipSmallGray .jBox-pointer:after {
1215
+  width: 20px;
1216
+  height: 20px;
1217
+}
1218
+
1219
+.jBox-TooltipSmallGray .jBox-pointer-top, .jBox-TooltipSmallGray .jBox-pointer-bottom {
1220
+  width: 22px;
1221
+  height: 8px;
1222
+}
1223
+
1224
+.jBox-TooltipSmallGray .jBox-pointer-left, .jBox-TooltipSmallGray .jBox-pointer-right {
1225
+  width: 8px;
1226
+  height: 22px;
1227
+}
1228
+
1229
+.jBox-TooltipSmallGray .jBox-pointer-top:after {
1230
+  background: #fafafa;
1231
+  left: 1px;
1232
+  top: 6px;
1233
+}
1234
+
1235
+.jBox-TooltipSmallGray .jBox-pointer-right:after {
1236
+  top: 1px;
1237
+  right: 6px;
1238
+}
1239
+
1240
+.jBox-TooltipSmallGray .jBox-pointer-bottom:after {
1241
+  background: #f2f2f2;
1242
+  left: 1px;
1243
+  bottom: 6px;
1244
+}
1245
+
1246
+.jBox-TooltipSmallGray .jBox-pointer-left:after {
1247
+  top: 1px;
1248
+  left: 6px;
1249
+}
1250
+
1251
+/*# sourceMappingURL=jBox.all.css.map */
0 1252
new file mode 100644
... ...
@@ -0,0 +1,2953 @@
1
+/**
2
+ * jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.
3
+ *
4
+ * Author: Stephan Wagner <stephanwagner.me@gmail.com> (https://stephanwagner.me)
5
+ *
6
+ * License: MIT (https://opensource.org/licenses/MIT)
7
+ *
8
+ * Requires: jQuery 3.5.0 (https://code.jquery.com/jquery-3.5.0.min.js)
9
+ *
10
+ * Documentation: https://stephanwagner.me/jBox/documentation
11
+ *
12
+ * Demos: https://stephanwagner.me/jBox/demos
13
+ */
14
+
15
+function jBoxWrapper(jQuery) {
16
+
17
+
18
+  var jBox = function jBox(type, options) {
19
+
20
+
21
+    // Options (https://stephanwagner.me/jBox/options)
22
+
23
+    this.options = {
24
+
25
+      // jBox ID
26
+      id: null,                    // Choose a unique id, otherwise jBox will set one for you (jBox1, jBox2, ...)
27
+
28
+      // Dimensions
29
+      width: 'auto',               // The width of the content area, e.g. 'auto', 200, '80%'
30
+      height: 'auto',              // The height of the content area
31
+      minWidth: null,              // Minimal width
32
+      minHeight: null,             // Minimal height
33
+      maxWidth: null,              // Maximal width
34
+      maxHeight: null,             // Maximal height
35
+
36
+      // Responsive dimensions
37
+      responsiveWidth: true,       // Adjusts the width to fit the viewport
38
+      responsiveHeight: true,      // Adjusts the height to fit the viewport
39
+      responsiveMinWidth: 100,     // Don't adjust width below this value (in pixel)
40
+      responsiveMinHeight: 100,    // Don't adjust height below this value (in pixel)
41
+
42
+      // Attach
43
+      attach: null,                // A jQuery selector to elements that will open and close your jBox, e.g. '.tooltip'
44
+      trigger: 'click',            // The event to open or close your jBox, use 'click', 'touchclick' or 'mouseenter'
45
+      preventDefault: false,       // Prevent the default event when opening jBox, e.g. don't follow the href in a link
46
+
47
+      // Content
48
+      content: null,               // You can use HTML or a jQuery element, e.g. jQuery('#jBox-content'). The elements will be appended to the content element and then made visible, so hide them with style="display: none" beforehand
49
+      getContent: null,            // Get the content from an attribute when jBox opens, e.g. getContent: 'data-content'. Use 'html' to get the attached elements HTML as content
50
+      title: null,                 // Adds a title to your jBox
51
+      getTitle: null,              // Get the title from an attribute when jBox opens, e.g. getTitle: 'data-title'
52
+      footer: null,                // Adds a footer to your jBox
53
+      isolateScroll: true,         // Isolates scrolling to the content container
54
+
55
+      // AJAX
56
+      ajax: {                      // Setting an URL will make an AJAX request when jBox opens. Optional you can add any jQuery AJAX option (http://api.jquery.com/jquery.ajax/)
57
+        url: null,                 // The URL to send the AJAX request to
58
+        data: '',                  // Data to send with your AJAX request, e.g. {id: 82, limit: 10}
59
+        reload: false,             // Resend the AJAX request when jBox opens. Use true to send the AJAX request only once for every attached element or 'strict' to resend every time jBox opens
60
+        getURL: 'data-url',        // The attribute in the source element where the AJAX request will look for the URL, e.g. data-url="https://reqres.in/api/users"
61
+        getData: 'data-ajax',      // The attribute in the source element where the AJAX request will look for the data, e.g. data-ajax="id=82&limit=10"
62
+        setContent: true,          // Automatically set the response as new content when the AJAX request is finished
63
+        loadingClass: true,        // Add a class to the wrapper when jBox is loading, set to class name or true to use the default class name 'jBox-loading'
64
+        spinner: true,             // Hides the current content and adds a spinner while loading. You can pass HTML content to add your own spinner, e.g. spinner: '<div class="mySpinner"></div>'
65
+        spinnerDelay: 300,         // Milliseconds to wait until spinner appears
66
+        spinnerReposition: true    // Repositions jBox when the spinner is added or removed
67
+      },
68
+      cancelAjaxOnClose: true,     // Cancels the ajax call when jBox closes and it hasn't finished loading yet
69
+
70
+      // Position
71
+      target: null,                // The jQuery selector to the target element where jBox will be opened. If no element is found, jBox will use the attached element as target
72
+      position: {
73
+        x: 'center',               // Horizontal position, use a number, 'left', 'right' or 'center'
74
+        y: 'center'                // Vertical position, use a number, 'top', 'bottom' or 'center'
75
+      },
76
+      outside: null,               // Use 'x', 'y', or 'xy' to move your jBox outside of the target element
77
+      offset: 0,                   // Offset to final position, you can set different values for x and y with an object, e.g. {x: 20, y: 10}
78
+      attributes: {                // Note that attributes can only be 'left' or 'right' when using numbers for position, e.g. {x: 300, y: 20}
79
+        x: 'left',                 // Horizontal position, use 'left' or 'right'
80
+        y: 'top'                   // Vertical position, use 'top' or 'bottom'
81
+      },
82
+      fixed: false,                // Your jBox will stay on position when scrolling
83
+      adjustPosition: true,        // Adjusts your jBoxes position if there is not enough space, use 'flip', 'move' or true for both. This option overrides the reposition options
84
+      adjustTracker: false,        // By default jBox adjusts its position when it opens or when the window size changes, set to true to also adjust when scrolling
85
+      adjustDistance: 5,           // The minimal distance to the viewport edge while adjusting. Use an object to set different values, e.g. {top: 50, right: 5, bottom: 20, left: 5}
86
+      reposition: true,            // Calculates new position when the window-size changes
87
+      repositionOnOpen: true,      // Calculates new position each time jBox opens (rather than only when it opens the first time)
88
+      repositionOnContent: true,   // Calculates new position when the content changes with .setContent() or .setTitle()
89
+      holdPosition: true,          // Keeps current position if space permits. Applies only to 'Modal' type.
90
+
91
+      // Pointer
92
+      pointer: false,              // Your pointer will always point towards the target element, so the option outside needs to be 'x' or 'y'. By default the pointer is centered, set a position to move it to any side. You can also add an offset, e.g. 'left:30' or 'center:-20'
93
+      pointTo: 'target',           // Setting something else than 'target' will add a pointer even if there is no target element set or found. Use 'top', 'right', 'bottom' or 'left'
94
+
95
+      // Animations
96
+      fade: 180,                   // Fade duration in ms, set to 0 or false to disable
97
+      animation: null,             // Animation when opening or closing, use 'pulse', 'zoomIn', 'zoomOut', 'move', 'slide', 'flip', 'tada' (CSS inspired from Daniel Edens Animate.css: http://daneden.me/animate)
98
+
99
+      // Appearance
100
+      theme: 'Default',            // Set a jBox theme class
101
+      addClass: null,              // Adds classes to the wrapper
102
+      overlay: false,              // Adds an overlay to hide page content when jBox opens (adjust color and opacity with CSS)
103
+      overlayClass: null,          // Add a class name to the overlay
104
+      zIndex: 10000,               // Use a high z-index, or set to 'auto' to bring to front on open
105
+
106
+      // Delays
107
+      delayOpen: 0,                // Delay opening in ms. Note that the delay will be ignored if your jBox didn't finish closing
108
+      delayClose: 0,               // Delay closing in ms. Nnote that there is always a closing delay of at least 10ms to ensure jBox won't be closed when opening right away
109
+
110
+      // Closing
111
+      closeOnEsc: false,           // Close jBox when pressing [esc] key
112
+      closeOnClick: false,         // Close jBox with mouseclick. Use true (click anywhere), 'box' (click on jBox itself), 'overlay' (click on the overlay), 'body' (click anywhere but jBox)
113
+      closeOnMouseleave: false,    // Close jBox when the mouse leaves the jBox area or the area of the attached element
114
+      closeButton: false,          // Adds a close button to your jBox. Use 'title', 'box', 'overlay' or true (true will add the button to the overlay, title or the jBox itself, in that order if any of those elements can be found)
115
+
116
+      // Other options
117
+      appendTo: jQuery('body'),    // The element your jBox will be appended to. Any other element than jQuery('body') is only useful for fixed positions or when position values are numbers
118
+      createOnInit: false,         // Creates jBox and makes it available in DOM when it's being initialized, otherwise it will be created when it opens for the first time
119
+      blockScroll: false,          // Blocks scrolling when jBox is open
120
+      blockScrollAdjust: true,     // Adjust page elements to avoid content jumps when scrolling is blocked. See more here: https://github.com/StephanWagner/unscroll
121
+      draggable: false,            // Make your jBox draggable (use 'true', 'title' or provide an element as handle) (inspired from Chris Coyiers CSS-Tricks http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/)
122
+      dragOver: true,              // When you have multiple draggable jBoxes, the one you select will always move over the other ones
123
+      autoClose: false,            // Time in ms when jBox will close automatically after it was opened
124
+      delayOnHover: false,         // Delay auto-closing while mouse is hovered
125
+      showCountdown: false,        // Display a nice progress-indicator when autoClose is enabled
126
+
127
+      // Audio                     // You can use the integrated audio function whenever you'd like to play an audio file, e.g. onInit: function () { this.audio('url_to_audio_file_without_file_extension', 75); }
128
+      preloadAudio: true,          // Preloads the audio files set in option audio. You can also preload other audio files, e.g. ['src_to_file.mp3', 'src_to_file.ogg']
129
+      audio: null,                 // The URL to an audio file to play when jBox opens. Set the URL without file extension, jBox will look for an .mp3 and .ogg file. To play audio when jBox closes, use an object, e.g. {open: 'src_to_audio1', close: 'src_to_audio2'}
130
+      volume: 100,                 // The volume in percent. To have different volumes for opening and closeing, use an object, e.g. {open: 75, close: 100}
131
+
132
+      // Events                    // Note that you can use 'this' in all event functions, it refers to your jBox object (e.g. onInit: function () { this.open(); })
133
+      onInit: null,                // Fired when jBox is initialized
134
+      onAttach: null,              // Fired when jBox attached itself to elements, the attached element will be passed as a parameter, e.g. onAttach: function (element) { element.css({color: 'red'}); }
135
+      onPosition: null,            // Fired when jBox is positioned
136
+      onCreated: null,             // Fired when jBox is created and availible in DOM
137
+      onOpen: null,                // Fired when jBox opens
138
+      onOpenComplete: null,        // Fired when jBox is completely open (when fading is finished)
139
+      onClose: null,               // Fired when jBox closes
140
+      onCloseComplete: null,       // Fired when jBox is completely closed (when fading is finished)
141
+      onDragStart: null,           // Fired when dragging starts
142
+      onDragEnd: null              // Fired when dragging finished
143
+    };
144
+
145
+
146
+    // Default plugin options
147
+
148
+    this._pluginOptions = {
149
+
150
+      // Default options for tooltips
151
+      'Tooltip': {
152
+        getContent: 'title',
153
+        trigger: 'mouseenter',
154
+        position: {
155
+          x: 'center',
156
+          y: 'top'
157
+        },
158
+        outside: 'y',
159
+        pointer: true
160
+      },
161
+
162
+      // Default options for mouse tooltips
163
+      'Mouse': {
164
+        responsiveWidth: false,
165
+        responsiveHeight: false,
166
+        adjustPosition: 'flip',
167
+        target: 'mouse',
168
+        trigger: 'mouseenter',
169
+        position: {
170
+          x: 'right',
171
+          y: 'bottom'
172
+        },
173
+        outside: 'xy',
174
+        offset: 5
175
+      },
176
+
177
+      // Default options for modal windows
178
+      'Modal': {
179
+        target: jQuery(window),
180
+        fixed: true,
181
+        blockScroll: true,
182
+        closeOnEsc: true,
183
+        closeOnClick: 'overlay',
184
+        closeButton: true,
185
+        overlay: true,
186
+        animation: 'zoomIn'
187
+      },
188
+    };
189
+
190
+
191
+    // Merge options
192
+
193
+    this.options = jQuery.extend(true, this.options, this._pluginOptions[type] ? this._pluginOptions[type] : jBox._pluginOptions[type], options);
194
+
195
+
196
+    // Set the jBox type
197
+
198
+    jQuery.type(type) == 'string' && (this.type = type);
199
+
200
+
201
+    // Checks if the user is on a touch device, borrowed from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
202
+
203
+    this.isTouchDevice = (function () {
204
+      var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
205
+      var mq = function (query) {
206
+        return window.matchMedia(query).matches;
207
+      }
208
+
209
+      if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
210
+        return true;
211
+      }
212
+
213
+      var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
214
+      return mq(query);
215
+    })();
216
+
217
+
218
+    // Add close event for body click when we are on touch device and jBox triggers on mouseenter
219
+
220
+    if (this.isTouchDevice && this.options.trigger === 'mouseenter' && this.options.closeOnClick === false) {
221
+      this.options.closeOnClick = 'body';
222
+    }
223
+
224
+
225
+    // Local function to fire events
226
+
227
+    this._fireEvent = function (event, pass)
228
+    {
229
+      this.options['_' + event] && (this.options['_' + event].bind(this))(pass);
230
+      this.options[event] && (this.options[event].bind(this))(pass);
231
+    };
232
+
233
+
234
+    // Get a unique jBox ID
235
+
236
+    this.options.id === null && (this.options.id = 'jBox' + jBox._getUniqueID());
237
+    this.id = this.options.id;
238
+
239
+
240
+    // Correct impossible options
241
+
242
+    ((this.options.position.x == 'center' && this.options.outside == 'x') || (this.options.position.y == 'center' && this.options.outside == 'y')) && (this.options.outside = null);
243
+    this.options.pointTo == 'target' && (!this.options.outside || this.options.outside == 'xy') && (this.options.pointer = false);
244
+
245
+
246
+    // Correct multiple choice options
247
+
248
+    jQuery.type(this.options.offset) != 'object' ? (this.options.offset = {x: this.options.offset, y: this.options.offset}) : (this.options.offset = jQuery.extend({x: 0, y: 0}, this.options.offset));
249
+    jQuery.type(this.options.adjustDistance) != 'object' ? (this.options.adjustDistance = {top: this.options.adjustDistance, right: this.options.adjustDistance, bottom: this.options.adjustDistance, left: this.options.adjustDistance}) : (this.options.adjustDistance = jQuery.extend({top: 5, left: 5, right: 5, bottom: 5}, this.options.adjustDistance));
250
+
251
+
252
+    // Save default outside position
253
+
254
+    this.outside = this.options.outside && this.options.outside != 'xy' ? this.options.position[this.options.outside] : false;
255
+
256
+
257
+    // Save where the jBox is aligned to
258
+
259
+    this.align = this.outside ? this.outside : (this.options.position.y != 'center' && jQuery.type(this.options.position.y) != 'number' ? this.options.position.x : (this.options.position.x != 'center' && jQuery.type(this.options.position.x) != 'number' ? this.options.position.y : this.options.attributes.x));
260
+
261
+
262
+    // Adjust option zIndex
263
+
264
+    jBox.zIndexMax = Math.max(jBox.zIndexMax || 0, this.options.zIndex === 'auto' ? 10000 : this.options.zIndex);
265
+    if (this.options.zIndex === 'auto') {
266
+      this.adjustZIndexOnOpen = true;
267
+      jBox.zIndexMax += 2;
268
+      this.options.zIndex = jBox.zIndexMax;
269
+      this.trueModal = this.options.overlay;
270
+    }
271
+
272
+    // Internal positioning functions
273
+
274
+    this._getOpp = function (opp) { return {left: 'right', right: 'left', top: 'bottom', bottom: 'top', x: 'y', y: 'x'}[opp]; };
275
+    this._getXY = function (xy) { return {left: 'x', right: 'x', top: 'y', bottom: 'y', center: 'x'}[xy]; };
276
+    this._getTL = function (tl) { return {left: 'left', right: 'left', top: 'top', bottom: 'top', center: 'left', x: 'left', y: 'top'}[tl]; };
277
+
278
+
279
+    // Get a dimension value in integer pixel dependent on appended element
280
+
281
+    this._getInt = function (value, dimension) {
282
+      if (value == 'auto') return 'auto';
283
+      if (value && jQuery.type(value) == 'string' && value.slice(-1) == '%') {
284
+        return jQuery(window)[dimension == 'height' ? 'innerHeight' : 'innerWidth']() * parseInt(value.replace('%', '')) / 100;
285
+      }
286
+      return value;
287
+    };
288
+
289
+
290
+    // Create an svg element
291
+
292
+    this._createSVG = function (type, options)
293
+    {
294
+      var svg = document.createElementNS('http://www.w3.org/2000/svg', type);
295
+      jQuery.each(options, function (index, item) {
296
+        svg.setAttribute(item[0], (item[1] || ''));
297
+      });
298
+      return svg;
299
+    };
300
+
301
+
302
+    // Isolate scrolling in a container
303
+
304
+    this._isolateScroll = function (el)
305
+    {
306
+      // Abort if element not found
307
+      if (!el || !el.length) return;
308
+
309
+      el.on('DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll', function (ev) {
310
+        var delta = ev.wheelDelta || (ev.originalEvent && ev.originalEvent.wheelDelta) || -ev.detail;
311
+        var overflowBottom = this.scrollTop + el.outerHeight() - this.scrollHeight >= 0;
312
+        var overflowTop = this.scrollTop <= 0;
313
+        ((delta < 0 && overflowBottom) || (delta > 0 && overflowTop)) && ev.preventDefault();
314
+      });
315
+    };
316
+
317
+
318
+    // Set the title width to content width
319
+
320
+    this._setTitleWidth = function ()
321
+    {
322
+      // Abort if there is no title or width of content is auto
323
+      if (!this.titleContainer || (this.content[0].style.width == 'auto' && !this.content[0].style.maxWidth)) return null;
324
+
325
+      // Expose wrapper to get actual width
326
+      if (this.wrapper.css('display') == 'none') {
327
+        this.wrapper.css('display', 'block');
328
+        var contentWidth = this.content.outerWidth();
329
+        this.wrapper.css('display', 'none');
330
+      } else {
331
+        var contentWidth = this.content.outerWidth();
332
+      }
333
+
334
+      // Set max-width only
335
+      this.titleContainer.css({maxWidth: (Math.max(contentWidth, parseInt(this.content[0].style.maxWidth)) || null)});
336
+    }
337
+
338
+
339
+    // Make jBox draggable
340
+
341
+    this._draggable = function ()
342
+    {
343
+      // Abort if jBox is not draggable
344
+      if (!this.options.draggable) return false;
345
+
346
+      // Get the handle where jBox will be dragged with
347
+      var handle = this.options.draggable == 'title' ? this.titleContainer : (this.options.draggable instanceof jQuery ? this.options.draggable : (jQuery.type(this.options.draggable) == 'string' ? jQuery(this.options.draggable) : this.wrapper));
348
+
349
+      // Abort if no handle or if draggable was set already
350
+      if (!handle || !(handle instanceof jQuery) || !handle.length || handle.data('jBox-draggable')) {
351
+        return false;
352
+      }
353
+
354
+      // Add mouse events
355
+      handle.addClass('jBox-draggable').data('jBox-draggable', true).on('touchstart mousedown', function (ev)
356
+      {
357
+        if (ev.button == 2 || jQuery(ev.target).hasClass('jBox-noDrag') || jQuery(ev.target).parents('.jBox-noDrag').length) {
358
+          // Hacky fix for jBox not closing on mobile devices when using draggable
359
+          if (ev.type == 'touchstart' && (jQuery(ev.target).hasClass('jBox-closeButton') || jQuery(ev.target).parents('.jBox-closeButton').length)) {
360
+            this.close({ignoreDelay: true});
361
+          }
362
+          return;
363
+        }
364
+
365
+        var pageX;
366
+        var pageY;
367
+
368
+        if (ev.type == 'touchstart' && ev.touches && ev.touches[0]) {
369
+          pageX = ev.touches[0].pageX;
370
+          pageY = ev.touches[0].pageY;
371
+        } else {
372
+          pageX = ev.pageX;
373
+          pageY = ev.pageY;
374
+        }
375
+
376
+        // Store current mouse position
377
+        this.draggingStartX = pageX;
378
+        this.draggingStartY = pageY;
379
+
380
+        // Adjust z-index when dragging jBox over another draggable jBox
381
+        if (this.options.dragOver && !this.trueModal && parseInt(this.wrapper.css('zIndex'), 10) <= jBox.zIndexMaxDragover) {
382
+          jBox.zIndexMaxDragover += 1;
383
+          this.wrapper.css('zIndex', jBox.zIndexMaxDragover);
384
+        }
385
+
386
+        var drg_h = this.wrapper.outerHeight();
387
+        var drg_w = this.wrapper.outerWidth();
388
+        var pos_y = this.wrapper.offset().top + drg_h - pageY;
389
+        var pos_x = this.wrapper.offset().left + drg_w - pageX;
390
+
391
+        jQuery(document).on('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id, function (ev) {
392
+
393
+          var movingPageX;
394
+          var movingPageY;
395
+
396
+          if (ev.type == 'touchmove' && ev.touches && ev.touches[0]) {
397
+            movingPageX = ev.touches[0].pageX;
398
+            movingPageY = ev.touches[0].pageY;
399
+          } else {
400
+            movingPageX = ev.pageX;
401
+            movingPageY = ev.pageY;
402
+          }
403
+
404
+          // Fire onDragStart event when jBox moves
405
+          if (!this.dragging && this.draggingStartX != movingPageX && this.draggingStartY != movingPageY) {
406
+            this._fireEvent('onDragStart');
407
+            this.dragging = true;
408
+          }
409
+
410
+          // Adjust position
411
+          this.wrapper.offset({
412
+            top: movingPageY + pos_y - drg_h,
413
+            left: movingPageX + pos_x - drg_w
414
+          });
415
+        }.bind(this));
416
+        ev.preventDefault();
417
+
418
+      }.bind(this)).on('touchend mouseup', function () {
419
+        // Remove drag event
420
+        jQuery(document).off('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id);
421
+
422
+        // Fire onDragEnd event
423
+        this.dragging && this._fireEvent('onDragEnd');
424
+
425
+        // Reset dragging reference
426
+        this.dragging = false;
427
+
428
+        if ((this.type == 'Modal' || this.type == 'Confirm') && this.options.holdPosition) {
429
+          // Drag end captures new position
430
+          var jBoxOffset = jQuery('#' + this.id).offset(),
431
+            pos = {
432
+              x: jBoxOffset.left - jQuery(document).scrollLeft(),
433
+              y: jBoxOffset.top - jQuery(document).scrollTop()
434
+            };
435
+          this.position({position: pos, offset: {x: 0, y: 0}});
436
+        }
437
+      }.bind(this));
438
+
439
+      // Get highest z-index
440
+      if (!this.trueModal) {
441
+        jBox.zIndexMaxDragover = !jBox.zIndexMaxDragover ? this.options.zIndex : Math.max(jBox.zIndexMaxDragover, this.options.zIndex);
442
+      }
443
+
444
+      return this;
445
+    };
446
+
447
+    // Create jBox
448
+
449
+    this._create = function ()
450
+    {
451
+      // Abort if jBox was created already
452
+      if (this.wrapper) return;
453
+
454
+      // Create wrapper
455
+      this.wrapper = jQuery('<div/>', {
456
+        id: this.id,
457
+        'class': 'jBox-wrapper' + (this.type ? ' jBox-' + this.type : '') + (this.options.theme ? ' jBox-' + this.options.theme : '') + (this.options.addClass ? ' ' + this.options.addClass : '')
458
+      }).css({
459
+        position: (this.options.fixed ? 'fixed' : 'absolute'),
460
+        display: 'none',
461
+        opacity: 0,
462
+        zIndex: this.options.zIndex
463
+
464
+        // Save the jBox instance in the wrapper, so you can get access to your jBox when you only have the element
465
+      }).data('jBox', this);
466
+
467
+      // Add mouseleave event, only close jBox when the new target is not the source element
468
+      this.options.closeOnMouseleave && this.wrapper.on('mouseleave', function (ev) {
469
+        !this.source || !(ev.relatedTarget == this.source[0] || jQuery.inArray(this.source[0], jQuery(ev.relatedTarget).parents('*')) !== -1) && this.close();
470
+      }.bind(this));
471
+
472
+      // Add closeOnClick: 'box' events
473
+      (this.options.closeOnClick == 'box') && this.wrapper.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
474
+
475
+      // Create container
476
+      this.container = jQuery('<div class="jBox-container"/>').appendTo(this.wrapper);
477
+
478
+      // Create content
479
+      this.content = jQuery('<div class="jBox-content"/>').appendTo(this.container);
480
+
481
+      // Create footer
482
+      this.options.footer && (this.footer = jQuery('<div class="jBox-footer"/>').append(this.options.footer).appendTo(this.container));
483
+
484
+      // Isolate scrolling
485
+      this.options.isolateScroll && this._isolateScroll(this.content);
486
+
487
+      // Create close button
488
+      if (this.options.closeButton) {
489
+        var closeButtonSVG = this._createSVG('svg', [['viewBox', '0 0 24 24']]);
490
+        closeButtonSVG.appendChild(this._createSVG('path', [['d', 'M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z']]));
491
+        this.closeButton = jQuery('<div class="jBox-closeButton jBox-noDrag"/>').on('click tap', function (ev) { this.close({ignoreDelay: true}); }.bind(this)).append(closeButtonSVG);
492
+
493
+        // Add close button to jBox container
494
+        if (this.options.closeButton == 'box' || (this.options.closeButton === true && !this.options.overlay && !this.options.title && !this.options.getTitle)) {
495
+          this.wrapper.addClass('jBox-closeButton-box');
496
+          this.closeButton.appendTo(this.container);
497
+        }
498
+      }
499
+
500
+      // Append jBox to DOM
501
+      this.wrapper.appendTo(this.options.appendTo);
502
+
503
+      // Fix adjustDistance if there is a close button in the box
504
+      this.wrapper.find('.jBox-closeButton').length &&  jQuery.each(['top', 'right', 'bottom', 'left'], function (index, pos) {
505
+        this.wrapper.find('.jBox-closeButton').css(pos) && this.wrapper.find('.jBox-closeButton').css(pos) != 'auto' && (this.options.adjustDistance[pos] = Math.max(this.options.adjustDistance[pos], this.options.adjustDistance[pos] + (((parseInt(this.wrapper.find('.jBox-closeButton').css(pos)) || 0) + (parseInt(this.container.css('border-' + pos + '-width')) || 0)) * -1)));
506
+      }.bind(this));
507
+
508
+      // Create pointer
509
+      if (this.options.pointer) {
510
+
511
+        // Get pointer vars and save globally
512
+        this.pointer = {
513
+          position: (this.options.pointTo != 'target') ? this.options.pointTo : this._getOpp(this.outside),
514
+          xy: (this.options.pointTo != 'target') ? this._getXY(this.options.pointTo) : this._getXY(this.outside),
515
+          align: 'center',
516
+          offset: 0
517
+        };
518
+
519
+        this.pointer.element = jQuery('<div class="jBox-pointer jBox-pointer-' + this.pointer.position + '"/>').appendTo(this.wrapper);
520
+        this.pointer.dimensions = {
521
+          x: this.pointer.element.outerWidth(),
522
+          y: this.pointer.element.outerHeight()
523
+        };
524
+
525
+        if (jQuery.type(this.options.pointer) == 'string') {
526
+          var split = this.options.pointer.split(':');
527
+          split[0] && (this.pointer.align = split[0]);
528
+          split[1] && (this.pointer.offset = parseInt(split[1]));
529
+        }
530
+        this.pointer.alignAttribute = (this.pointer.xy == 'x' ? (this.pointer.align == 'bottom' ? 'bottom' : 'top') : (this.pointer.align == 'right' ? 'right' : 'left'));
531
+
532
+        // Set wrapper CSS
533
+        this.wrapper.css('padding-' + this.pointer.position, this.pointer.dimensions[this.pointer.xy]);
534
+
535
+        // Set pointer CSS
536
+        this.pointer.element.css(this.pointer.alignAttribute, (this.pointer.align == 'center' ? '50%' : 0)).css('margin-' + this.pointer.alignAttribute, this.pointer.offset);
537
+        this.pointer.margin = {};
538
+        this.pointer.margin['margin-' + this.pointer.alignAttribute] = this.pointer.offset;
539
+
540
+        // Add a transform to fix centered position
541
+        (this.pointer.align == 'center') && this.pointer.element.css('transform', 'translate(' + (this.pointer.xy == 'y' ? (this.pointer.dimensions.x * -0.5 + 'px') : 0) + ', ' + (this.pointer.xy == 'x' ? (this.pointer.dimensions.y * -0.5 + 'px') : 0) + ')');
542
+
543
+        this.pointer.element.css((this.pointer.xy == 'x' ? 'width' : 'height'), parseInt(this.pointer.dimensions[this.pointer.xy]) + parseInt(this.container.css('border-' + this.pointer.alignAttribute + '-width')));
544
+
545
+        // Add class to wrapper for CSS access
546
+        this.wrapper.addClass('jBox-pointerPosition-' + this.pointer.position);
547
+      }
548
+
549
+      // Set title and content
550
+      this.setContent(this.options.content, true);
551
+      this.setTitle(this.options.title, true);
552
+
553
+      this.options.draggable && this._draggable();
554
+
555
+      // Fire onCreated event
556
+      this._fireEvent('onCreated');
557
+    };
558
+
559
+
560
+    // Create jBox onInit
561
+
562
+    this.options.createOnInit && this._create();
563
+
564
+
565
+    // Attach jBox
566
+
567
+    this.options.attach && this.attach();
568
+
569
+
570
+    // Attach document and window events
571
+
572
+    this._attachEvents = function ()
573
+    {
574
+      // Cancel countdown on mouseenter if delayOnHover
575
+      this.options.delayOnHover && jQuery('#' + this.id).on('mouseenter', function (ev) { this.isHovered = true; }.bind(this));
576
+
577
+      // Resume countdown on mouseleave if delayOnHover
578
+      this.options.delayOnHover && jQuery('#' + this.id).on('mouseleave', function (ev) { this.isHovered = false; }.bind(this));
579
+
580
+      // Positioning events
581
+      if ((this.options.adjustPosition || this.options.reposition) && !this.fixed && this.outside) {
582
+
583
+        // Trigger position events when scrolling
584
+        this.options.adjustTracker && jQuery(window).on('scroll.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
585
+
586
+        // Trigger position events when resizing
587
+        (this.options.adjustPosition || this.options.reposition) && jQuery(window).on('resize.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
588
+      }
589
+
590
+      // Mousemove events
591
+      this.options.target == 'mouse' && jQuery('body').on('mousemove.jBox-' + this.id, function (ev) { this.position({mouseTarget: {top: ev.pageY, left: ev.pageX}}); }.bind(this));
592
+    };
593
+
594
+
595
+    // Detach document and window events
596
+
597
+    this._detachEvents = function ()
598
+    {
599
+      // Closing event: closeOnEsc
600
+      this.options.closeOnEsc && jQuery(document).off('keyup.jBox-' + this.id);
601
+
602
+      // Closing event: closeOnClick
603
+      (this.options.closeOnClick === true || this.options.closeOnClick == 'body') && jQuery(document).off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
604
+
605
+      // Positioning events
606
+      this.options.adjustTracker && jQuery(window).off('scroll.jBox-' + this.id);
607
+      (this.options.adjustPosition || this.options.reposition) && jQuery(window).off('resize.jBox-' + this.id);
608
+
609
+      // Mousemove events
610
+      this.options.target == 'mouse' && jQuery('body').off('mousemove.jBox-' + this.id);
611
+    };
612
+
613
+
614
+    // Show overlay
615
+
616
+    this._showOverlay = function ()
617
+    {
618
+      // Create the overlay if wasn't created already
619
+      if (!this.overlay) {
620
+
621
+        // Create element and append to the element where jBox is appended to
622
+        this.overlay = jQuery('<div id="' + this.id + '-overlay"/>').addClass('jBox-overlay' + (this.type ? ' jBox-overlay-' + this.type : '')).css({
623
+          display: 'none',
624
+          opacity: 0,
625
+          zIndex: this.options.zIndex - 1
626
+        }).appendTo(this.options.appendTo);
627
+
628
+        // Add a class name to the overlay
629
+        this.options.overlayClass && this.overlay.addClass(this.options.overlayClass);
630
+
631
+        // Add close button to overlay
632
+        (this.options.closeButton == 'overlay' || this.options.closeButton === true) && this.overlay.append(this.closeButton);
633
+
634
+        // Add closeOnClick: 'overlay' events
635
+        this.options.closeOnClick == 'overlay' && this.overlay.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
636
+
637
+        // Adjust option adjustDistance if there is a close button in the overlay
638
+        jQuery('#' + this.id + '-overlay .jBox-closeButton').length && (this.options.adjustDistance.top = Math.max(jQuery('#' + this.id + '-overlay .jBox-closeButton').outerHeight(), this.options.adjustDistance.top));
639
+      }
640
+
641
+      // Adjust zIndex
642
+      if (this.adjustZIndexOnOpen === true) {
643
+        this.overlay.css('zIndex', parseInt(this.wrapper.css('zIndex'), 10) - 1);
644
+      }
645
+
646
+      // Abort if overlay is already visible
647
+      if (this.overlay.css('display') == 'block') return;
648
+
649
+      // Show overlay
650
+      this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 1}, {
651
+        queue: false,
652
+        duration: this.options.fade,
653
+        start: function () { this.overlay.css({display: 'block'}); }.bind(this)
654
+      })) : this.overlay.css({display: 'block', opacity: 1});
655
+    };
656
+
657
+
658
+    // Hide overlay
659
+
660
+    this._hideOverlay = function ()
661
+    {
662
+      // Abort if the overlay wasn't created yet
663
+      if (!this.overlay) return;
664
+
665
+      // Hide overlay if no other jBox needs it
666
+      this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 0}, {
667
+        queue: false,
668
+        duration: this.options.fade,
669
+        complete: function () { this.overlay.css({display: 'none'}); }.bind(this)
670
+      })) : this.overlay.css({display: 'none', opacity: 0});
671
+    };
672
+
673
+
674
+    // Get the correct jBox dimensions by moving jBox out of viewport
675
+
676
+    this._exposeDimensions = function ()
677
+    {
678
+      // Move wrapper out of viewport
679
+      this.wrapper.css({
680
+        top: -10000,
681
+        left: -10000,
682
+        right: 'auto',
683
+        bottom: 'auto'
684
+      });
685
+
686
+      // Get jBox dimensions
687
+      var jBoxDimensions = {
688
+        x: this.wrapper.outerWidth(),
689
+        y: this.wrapper.outerHeight()
690
+      };
691
+
692
+      // Reset position to viewport
693
+      this.wrapper.css({
694
+        top: 'auto',
695
+        left: 'auto'
696
+      });
697
+
698
+      return jBoxDimensions;
699
+    };
700
+
701
+
702
+    // Generate CSS for animations and append to header
703
+
704
+    this._generateAnimationCSS = function ()
705
+    {
706
+      // Get open and close animations if none provided
707
+      (jQuery.type(this.options.animation) != 'object') && (this.options.animation = {
708
+        pulse: {open: 'pulse', close: 'zoomOut'},
709
+        zoomIn: {open: 'zoomIn', close: 'zoomIn'},
710
+        zoomOut: {open: 'zoomOut', close: 'zoomOut'},
711
+        move: {open: 'move', close: 'move'},
712
+        slide: {open: 'slide', close: 'slide'},
713
+        flip: {open: 'flip', close: 'flip'},
714
+        tada: {open: 'tada', close: 'zoomOut'}
715
+      }[this.options.animation]);
716
+
717
+      // Abort if animation not found
718
+      if (!this.options.animation) return null;
719
+
720
+      // Get direction var
721
+      this.options.animation.open && (this.options.animation.open = this.options.animation.open.split(':'));
722
+      this.options.animation.close && (this.options.animation.close = this.options.animation.close.split(':'));
723
+      this.options.animation.openDirection = this.options.animation.open[1] ? this.options.animation.open[1] : null;
724
+      this.options.animation.closeDirection = this.options.animation.close[1] ? this.options.animation.close[1] : null;
725
+      this.options.animation.open && (this.options.animation.open = this.options.animation.open[0]);
726
+      this.options.animation.close && (this.options.animation.close = this.options.animation.close[0]);
727
+
728
+      // Add 'Open' and 'Close' to animation names
729
+      this.options.animation.open && (this.options.animation.open += 'Open');
730
+      this.options.animation.close && (this.options.animation.close += 'Close');
731
+
732
+      // All animations
733
+      var animations = {
734
+        pulse: {
735
+          duration: 350,
736
+          css: [['0%', 'scale(1)'], ['50%', 'scale(1.1)'], ['100%', 'scale(1)']]
737
+        },
738
+        zoomInOpen: {
739
+          duration: (this.options.fade || 180),
740
+          css: [['0%', 'scale(0.9)'], ['100%', 'scale(1)']]
741
+        },
742
+        zoomInClose: {
743
+          duration: (this.options.fade || 180),
744
+          css: [['0%', 'scale(1)'], ['100%', 'scale(0.9)']]
745
+        },
746
+        zoomOutOpen: {
747
+          duration: (this.options.fade || 180),
748
+          css: [['0%', 'scale(1.1)'], ['100%', 'scale(1)']]
749
+        },
750
+        zoomOutClose: {
751
+          duration: (this.options.fade || 180),
752
+          css: [['0%', 'scale(1)'], ['100%', 'scale(1.1)']]
753
+        },
754
+        moveOpen: {
755
+          duration: (this.options.fade || 180),
756
+          positions: {top: {'0%': -12}, right: {'0%': 12}, bottom: {'0%': 12}, left: {'0%': -12}},
757
+          css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
758
+        },
759
+        moveClose: {
760
+          duration: (this.options.fade || 180),
761
+          timing: 'ease-in',
762
+          positions: {top: {'100%': -12}, right: {'100%': 12}, bottom: {'100%': 12}, left: {'100%': -12}},
763
+          css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
764
+        },
765
+        slideOpen: {
766
+          duration: 400,
767
+          positions: {top: {'0%': -400}, right: {'0%': 400}, bottom: {'0%': 400}, left: {'0%': -400}},
768
+          css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
769
+        },
770
+        slideClose: {
771
+          duration: 400,
772
+          timing: 'ease-in',
773
+          positions: {top: {'100%': -400}, right: {'100%': 400}, bottom: {'100%': 400}, left: {'100%': -400}},
774
+          css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
775
+        },
776
+        flipOpen: {
777
+          duration: 600,
778
+          css: [['0%', 'perspective(400px) rotateX(90deg)'], ['40%', 'perspective(400px) rotateX(-15deg)'], ['70%', 'perspective(400px) rotateX(15deg)'], ['100%', 'perspective(400px) rotateX(0deg)']]
779
+        },
780
+        flipClose: {
781
+          duration: (this.options.fade || 300),
782
+          css: [['0%', 'perspective(400px) rotateX(0deg)'], ['100%', 'perspective(400px) rotateX(90deg)']]
783
+        },
784
+        tada: {
785
+          duration: 800,
786
+          css: [['0%', 'scale(1)'], ['10%, 20%', 'scale(0.9) rotate(-3deg)'], ['30%, 50%, 70%, 90%', 'scale(1.1) rotate(3deg)'], ['40%, 60%, 80%', 'scale(1.1) rotate(-3deg)'], ['100%', 'scale(1) rotate(0)']]
787
+        }
788
+      };
789
+
790
+      // Set Open and Close names for standalone animations
791
+      jQuery.each(['pulse', 'tada'], function (index, item) { animations[item + 'Open'] = animations[item + 'Close'] = animations[item]; });
792
+
793
+      // Function to generate the CSS for the keyframes
794
+      var generateKeyframeCSS = function (ev, position)
795
+      {
796
+        // Generate keyframes CSS
797
+        var keyframe_css = '@keyframes jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
798
+        jQuery.each(animations[this.options.animation[ev]].css, function (index, item) {
799
+          var translate = position ? item[1].replace('%XY', this._getXY(position).toUpperCase()) : item[1];
800
+          animations[this.options.animation[ev]].positions && (translate = translate.replace('%V', animations[this.options.animation[ev]].positions[position][item[0]]));
801
+          keyframe_css += item[0] + ' {transform:' + translate + ';}';
802
+
803
+        }.bind(this));
804
+        keyframe_css += '}';
805
+
806
+        // Generate class CSS
807
+        keyframe_css += '.jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
808
+        keyframe_css += 'animation-duration: ' + animations[this.options.animation[ev]].duration + 'ms;';
809
+        keyframe_css += 'animation-name: jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ';';
810
+        keyframe_css += animations[this.options.animation[ev]].timing ? ('animation-timing-function: ' + animations[this.options.animation[ev]].timing + ';') : '';
811
+        keyframe_css += '}';
812
+
813
+        return keyframe_css;
814
+      }.bind(this);
815
+
816
+      // Generate css for each event and positions
817
+      this._animationCSS = '';
818
+      jQuery.each(['open', 'close'], function (index, ev)
819
+      {
820
+        // No CSS needed for closing with no fade
821
+        if (!this.options.animation[ev] || !animations[this.options.animation[ev]] || (ev == 'close' && !this.options.fade)) return '';
822
+
823
+        // Generate CSS
824
+        animations[this.options.animation[ev]].positions ?
825
+          jQuery.each(['top', 'right', 'bottom', 'left'], function (index2, position) { this._animationCSS += generateKeyframeCSS(ev, position); }.bind(this)) :
826
+          this._animationCSS += generateKeyframeCSS(ev);
827
+      }.bind(this));
828
+
829
+    };
830
+
831
+
832
+    // Add css for animations
833
+
834
+    this.options.animation && this._generateAnimationCSS();
835
+
836
+
837
+    // Block body clicks for 10ms to prevent extra event triggering
838
+
839
+    this._blockBodyClick = function ()
840
+    {
841
+      this.blockBodyClick = true;
842
+      setTimeout(function () { this.blockBodyClick = false; }.bind(this), 10);
843
+    };
844
+
845
+
846
+    // Animations
847
+
848
+    this._animate = function (ev)
849
+    {
850
+      // The event which triggers the animation
851
+      !ev && (ev = this.isOpen ? 'open' : 'close');
852
+
853
+      // Don't animate when closing with no fade duration
854
+      if (!this.options.fade && ev == 'close') return null;
855
+
856
+      // Get the current position, use opposite if jBox is flipped
857
+      var animationDirection = (this.options.animation[ev + 'Direction'] || ((this.align != 'center') ? this.align : this.options.attributes.x));
858
+      this.flipped && this._getXY(animationDirection) == (this._getXY(this.align)) && (animationDirection = this._getOpp(animationDirection));
859
+
860
+      // Add event and position classes
861
+      var classnames = 'jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + ' jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + '-' + animationDirection;
862
+      this.wrapper.addClass(classnames);
863
+
864
+      // Get duration of animation
865
+      var animationDuration = parseFloat(this.wrapper.css('animation-duration')) * 1000;
866
+      ev == 'close' && (animationDuration = Math.min(animationDuration, this.options.fade));
867
+
868
+      // Remove animation classes when animation is finished
869
+      setTimeout(function () {
870
+        this.wrapper && this.wrapper.removeClass(classnames);
871
+      }.bind(this), animationDuration);
872
+    };
873
+
874
+
875
+    // Abort an animation
876
+
877
+    this._abortAnimation = function ()
878
+    {
879
+      // Remove all animation classes
880
+      var classes = this.wrapper.attr('class').split(' ').filter(function (c) {
881
+        return c.lastIndexOf('jBox-' + this.id + '-animation', 0) !== 0;
882
+      }.bind(this));
883
+      this.wrapper.attr('class', classes.join(' '));
884
+    };
885
+
886
+
887
+    // Adjust dimensions when browser is resized
888
+
889
+    if (this.options.responsiveWidth || this.options.responsiveHeight)
890
+    {
891
+      // Responsive positioning overrides options adjustPosition and reposition
892
+      // TODO: Only add this resize event when the other one from adjustPosition and reposition was not set
893
+      jQuery(window).on('resize.responsivejBox-' + this.id, function (ev) { if (this.isOpen) { this.position(); } }.bind(this));
894
+    }
895
+
896
+
897
+    // Fix audio options
898
+
899
+    jQuery.type(this.options.preloadAudio) === 'string' && (this.options.preloadAudio = [this.options.preloadAudio]);
900
+    jQuery.type(this.options.audio) === 'string' && (this.options.audio = {open: this.options.audio});
901
+    jQuery.type(this.options.volume) === 'number' && (this.options.volume = {open: this.options.volume, close: this.options.volume});
902
+
903
+    if (this.options.preloadAudio === true && this.options.audio) {
904
+      this.options.preloadAudio = [];
905
+      jQuery.each(this.options.audio, function (index, url) {
906
+        this.options.preloadAudio.push(url + '.mp3');
907
+        this.options.preloadAudio.push(url + '.ogg');
908
+      }.bind(this));
909
+    }
910
+
911
+
912
+    // Preload audio files
913
+
914
+    this.options.preloadAudio.length && jQuery.each(this.options.preloadAudio, function (index, url) {
915
+      var audio = new Audio();
916
+      audio.src = url;
917
+      audio.preload = 'auto';
918
+    });
919
+
920
+
921
+    // Fire onInit event
922
+
923
+    this._fireEvent('onInit');
924
+
925
+
926
+    return this;
927
+  };
928
+
929
+
930
+  // Attach jBox to elements
931
+
932
+  jBox.prototype.attach = function (elements, trigger)
933
+  {
934
+    // Get elements from options if none passed
935
+    !elements && (elements = this.options.attach);
936
+
937
+    // Convert selectors to jQuery objects
938
+    jQuery.type(elements) == 'string' && (elements = jQuery(elements));
939
+
940
+    // Get trigger event from options if not passed
941
+    !trigger && (trigger = this.options.trigger);
942
+
943
+    // Loop through elements and attach jBox
944
+    elements && elements.length && jQuery.each(elements, function (index, el) {
945
+      el = jQuery(el);
946
+
947
+      // Only attach if the element wasn't attached to this jBox already
948
+      if (!el.data('jBox-attached-' + this.id)) {
949
+
950
+        // Remove title attribute and store content on element
951
+        (this.options.getContent == 'title' && el.attr('title') != undefined) && el.data('jBox-getContent', el.attr('title')).removeAttr('title');
952
+
953
+        // Add Element to collection
954
+        this.attachedElements || (this.attachedElements = []);
955
+        this.attachedElements.push(el[0]);
956
+
957
+        // Add click or mouseenter event, click events can prevent default as well
958
+        el.on(trigger + '.jBox-attach-' + this.id, function (ev)
959
+        {
960
+          // Clear timer
961
+          this.timer && clearTimeout(this.timer);
962
+
963
+          // Block opening when jbox is open and the source element is triggering
964
+          if (trigger == 'mouseenter' && this.isOpen && this.source[0] == el[0]) return;
965
+
966
+          // Only close jBox if you click the current target element, otherwise open at new target
967
+          if (this.isOpen && this.source && this.source[0] != el[0]) var forceOpen = true;
968
+
969
+          // Set new source element
970
+          this.source = el;
971
+
972
+          // Set new target
973
+          !this.options.target && (this.target = el);
974
+
975
+          // Prevent default action on click
976
+          trigger == 'click' && this.options.preventDefault && ev.preventDefault();
977
+
978
+          // Toggle or open jBox
979
+          this[trigger == 'click' && !forceOpen ? 'toggle' : 'open']();
980
+
981
+        }.bind(this));
982
+
983
+        // Add close event for trigger event mouseenter
984
+        (this.options.trigger == 'mouseenter') && el.on('mouseleave', function (ev)
985
+        {
986
+          // Abort if jBox wasn't created yet
987
+          if (!this.wrapper) return null;
988
+
989
+          // If we have set closeOnMouseleave, do not close jBox when leaving attached element and mouse is over jBox
990
+          if (!this.options.closeOnMouseleave || !(ev.relatedTarget == this.wrapper[0] || jQuery(ev.relatedTarget).parents('#' + this.id).length)) this.close();
991
+        }.bind(this));
992
+
993
+        // Store
994
+        el.data('jBox-attached-' + this.id, trigger);
995
+
996
+        // Fire onAttach event
997
+        this._fireEvent('onAttach', el);
998
+      }
999
+
1000
+    }.bind(this));
1001
+
1002
+    return this;
1003
+  };
1004
+
1005
+
1006
+  // Detach jBox from elements
1007
+
1008
+  jBox.prototype.detach = function (elements)
1009
+  {
1010
+    // Get elements from stores elements if none passed
1011
+    !elements && (elements = this.attachedElements || []);
1012
+
1013
+    elements && elements.length && jQuery.each(elements, function (index, el) {
1014
+      el = jQuery(el);
1015
+
1016
+      // Remove events
1017
+      if (el.data('jBox-attached-' + this.id)) {
1018
+        el.off(el.data('jBox-attached-' + this.id) + '.jBox-attach-' + this.id);
1019
+        el.data('jBox-attached-' + this.id, null);
1020
+      }
1021
+      // Remove element from collection
1022
+      this.attachedElements = jQuery.grep(this.attachedElements, function (value) {
1023
+        return value != el[0];
1024
+      });
1025
+    }.bind(this));
1026
+
1027
+    return this;
1028
+  };
1029
+
1030
+
1031
+  // Set title
1032
+
1033
+  jBox.prototype.setTitle = function (title, ignore_positioning)
1034
+  {
1035
+    // Abort if title to set
1036
+    if (title == null || title == undefined) return this;
1037
+
1038
+    // Create jBox if it wasn't created already
1039
+    !this.wrapper && this._create();
1040
+
1041
+    // Get the width and height of wrapper, only if they change we need to reposition
1042
+    var wrapperHeight = this.wrapper.outerHeight();
1043
+    var wrapperWidth = this.wrapper.outerWidth();
1044
+
1045
+    // Create title elements if they weren't created already
1046
+    if (!this.title) {
1047
+      this.titleContainer = jQuery('<div class="jBox-title"/>');
1048
+      this.title = jQuery('<div/>').appendTo(this.titleContainer);
1049
+      if (this.options.closeButton == 'title' || (this.options.closeButton === true && !this.options.overlay)) {
1050
+        this.wrapper.addClass('jBox-closeButton-title');
1051
+        this.closeButton.appendTo(this.titleContainer);
1052
+      }
1053
+      this.titleContainer.insertBefore(this.content);
1054
+      this._setTitleWidth();
1055
+    }
1056
+
1057
+    // Add or remove wrapper class
1058
+    this.wrapper[title ? 'addClass' : 'removeClass']('jBox-hasTitle');
1059
+
1060
+    // Set title html
1061
+    this.title.html(title);
1062
+
1063
+    // Adjust width of title
1064
+    wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
1065
+
1066
+    // Make jBox draggable
1067
+    this.options.draggable && this._draggable();
1068
+
1069
+    // Reposition if dimensions changed
1070
+    !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
1071
+
1072
+    return this;
1073
+  };
1074
+
1075
+
1076
+  // Set content
1077
+
1078
+  jBox.prototype.setContent = function (content, ignore_positioning)
1079
+  {
1080
+    // Abort if no content to set
1081
+    if (content == null || content == undefined) return this;
1082
+
1083
+    // Create jBox if it wasn't created already
1084
+    !this.wrapper && this._create();
1085
+
1086
+    // Get the width and height of wrapper, only if they change we need to reposition
1087
+    var wrapperHeight = this.wrapper.outerHeight();
1088
+    var wrapperWidth = this.wrapper.outerWidth();
1089
+
1090
+    // Move all appended containers to body
1091
+    this.content.children('[data-jbox-content-appended]').appendTo('body').css({display: 'none'});
1092
+
1093
+    // Set the new content
1094
+    switch (jQuery.type(content)) {
1095
+      case 'string':
1096
+        this.content.html(content);
1097
+        break;
1098
+      case 'object':
1099
+        if (content && (content instanceof jQuery || content.constructor.prototype.jquery)) {
1100
+          this.content.html('');
1101
+          content.attr('data-jbox-content-appended', 1).appendTo(this.content).css({display: 'block'});
1102
+        } else {
1103
+          this.content.html(JSON.stringify(content));
1104
+        }
1105
+        break;
1106
+     }
1107
+
1108
+    // Adjust title width
1109
+    wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
1110
+
1111
+    // Make jBox draggable
1112
+    this.options.draggable && this._draggable();
1113
+
1114
+    // Reposition if dimensions changed
1115
+    !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
1116
+
1117
+    return this;
1118
+  };
1119
+
1120
+
1121
+  // Set jBox dimensions
1122
+
1123
+  jBox.prototype.setDimensions = function (type, value, pos)
1124
+  {
1125
+    // Create jBox if it wasn't created already
1126
+    !this.wrapper && this._create();
1127
+
1128
+    // Default value is 'auto'
1129
+    value == undefined && (value = 'auto');
1130
+
1131
+    // Set CSS of content and title
1132
+    this.content.css(type, this._getInt(value));
1133
+
1134
+    // Adjust title width
1135
+    type == 'width' && this._setTitleWidth();
1136
+
1137
+    // Update options
1138
+    this.options[type] = value;
1139
+
1140
+    // Reposition by default
1141
+    (pos == undefined || pos) && this.position();
1142
+  };
1143
+
1144
+
1145
+  // Set jBox width or height
1146
+
1147
+  jBox.prototype.setWidth = function (value, pos) { this.setDimensions('width', value, pos); };
1148
+  jBox.prototype.setHeight = function (value, pos) { this.setDimensions('height', value, pos); };
1149
+
1150
+
1151
+  // Position jBox
1152
+
1153
+  jBox.prototype.position = function (options)
1154
+  {
1155
+    // Options are required
1156
+    !options && (options = {});
1157
+
1158
+    // Combine passed options with jBox options
1159
+    options = jQuery.extend(true, this.options, options);
1160
+
1161
+    // Get the target
1162
+    this.target = options.target || this.target || jQuery(window);
1163
+
1164
+    // Make sure target is a jQuery element
1165
+    !(this.target instanceof jQuery || this.target == 'mouse') && (this.target = jQuery(this.target));
1166
+
1167
+    // Abort if target is missing
1168
+    if (!this.target.length) return this;
1169
+
1170
+    // Reset content css to get original dimensions
1171
+    this.content.css({
1172
+      width: this._getInt(options.width, 'width'),
1173
+      height: this._getInt(options.height, 'height'),
1174
+      minWidth: this._getInt(options.minWidth, 'width'),
1175
+      minHeight: this._getInt(options.minHeight, 'height'),
1176
+      maxWidth: this._getInt(options.maxWidth, 'width'),
1177
+      maxHeight: this._getInt(options.maxHeight, 'height'),
1178
+    });
1179
+
1180
+    // Reset width of title
1181
+    this._setTitleWidth();
1182
+
1183
+    // Get jBox dimensions
1184
+    var jBoxDimensions = this._exposeDimensions();
1185
+
1186
+    // Check if target has fixed position, store in elements data
1187
+    this.target != 'mouse' && !this.target.data('jBox-' + this.id + '-fixed') && this.target.data('jBox-' + this.id + '-fixed', (this.target[0] != jQuery(window)[0] && (this.target.css('position') == 'fixed' || this.target.parents().filter(function () { return jQuery(this).css('position') == 'fixed'; }).length > 0)) ? 'fixed' : 'static');
1188
+
1189
+    // Get the window dimensions
1190
+    var windowDimensions = {
1191
+      x: jQuery(window).outerWidth(),
1192
+      y: jQuery(window).outerHeight(),
1193
+      top: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollTop()),
1194
+      left: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollLeft())
1195
+    };
1196
+    windowDimensions.bottom = windowDimensions.top + windowDimensions.y;
1197
+    windowDimensions.right = windowDimensions.left + windowDimensions.x;
1198
+
1199
+    // Get target offset
1200
+    try { var targetOffset = this.target.offset(); } catch (e) { var targetOffset = {top: 0, left: 0}; };
1201
+
1202
+    // When the target is fixed and jBox is fixed, remove scroll offset
1203
+    if (this.target != 'mouse' && this.target.data('jBox-' + this.id + '-fixed') == 'fixed' && options.fixed) {
1204
+      targetOffset.top = targetOffset.top - jQuery(window).scrollTop();
1205
+      targetOffset.left = targetOffset.left - jQuery(window).scrollLeft();
1206
+    }
1207
+
1208
+    // Get target dimensions
1209
+    var targetDimensions = {
1210
+      x: this.target == 'mouse' ? 12 : this.target.outerWidth(),
1211
+      y: this.target == 'mouse' ? 20 : this.target.outerHeight(),
1212
+      top: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.top : (targetOffset ? targetOffset.top : 0),
1213
+      left: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.left : (targetOffset ? targetOffset.left : 0)
1214
+    };
1215
+
1216
+    // Check if jBox is outside
1217
+    var outside = options.outside && !(options.position.x == 'center' && options.position.y == 'center');
1218
+
1219
+    // Get the available space on all sides
1220
+    var availableSpace = {
1221
+      x: windowDimensions.x - options.adjustDistance.left - options.adjustDistance.right, // TODO: substract position.x when they are numbers
1222
+      y: windowDimensions.y - options.adjustDistance.top - options.adjustDistance.bottom, // TODO: substract position.x when they are numbers
1223
+      left: !outside ? 0 : (targetDimensions.left - jQuery(window).scrollLeft() - options.adjustDistance.left),
1224
+      right: !outside ? 0 : (windowDimensions.x - targetDimensions.left + jQuery(window).scrollLeft() - targetDimensions.x - options.adjustDistance.right),
1225
+      top: !outside ? 0 : (targetDimensions.top - jQuery(window).scrollTop() - this.options.adjustDistance.top),
1226
+      bottom: !outside ? 0 : (windowDimensions.y - targetDimensions.top + jQuery(window).scrollTop() - targetDimensions.y - options.adjustDistance.bottom),
1227
+    };
1228
+
1229
+    // Get the default outside position, check if box will be flipped
1230
+    var jBoxOutsidePosition = {
1231
+      x: (options.outside == 'x' || options.outside == 'xy') && jQuery.type(options.position.x) != 'number' ? options.position.x : null,
1232
+      y: (options.outside == 'y' || options.outside == 'xy') && jQuery.type(options.position.y) != 'number' ? options.position.y : null
1233
+    };
1234
+    var flip = {x: false, y: false};
1235
+    (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
1236
+    (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
1237
+
1238
+    // Adjust responsive dimensions
1239
+    if (options.responsiveWidth || options.responsiveHeight) {
1240
+
1241
+      // Adjust width and height according to default outside position
1242
+      var adjustResponsiveWidth = function ()
1243
+      {
1244
+        if (options.responsiveWidth && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x || 'x']) {
1245
+          var contentWidth = availableSpace[jBoxOutsidePosition.x || 'x'] - (this.pointer && outside && options.outside == 'x' ? this.pointer.dimensions.x : 0) - parseInt(this.container.css('border-left-width')) - parseInt(this.container.css('border-right-width'));
1246
+          this.content.css({
1247
+            width: contentWidth > this.options.responsiveMinWidth ? contentWidth : null,
1248
+            minWidth: contentWidth < parseInt(this.content.css('minWidth')) ? 0 : null
1249
+          });
1250
+          this._setTitleWidth();
1251
+        }
1252
+        jBoxDimensions = this._exposeDimensions();
1253
+
1254
+      }.bind(this);
1255
+      options.responsiveWidth && adjustResponsiveWidth();
1256
+
1257
+      // After adjusting width, check if jBox will be flipped for y
1258
+      options.responsiveWidth && !flip.y && (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
1259
+
1260
+      // Adjust width and height according to default outside position
1261
+      var adjustResponsiveHeight = function ()
1262
+      {
1263
+        if (options.responsiveHeight && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y || 'y']) {
1264
+
1265
+          // Expose wrapper to get correct title height
1266
+          var exposeTitleFooterHeight = function () {
1267
+            if (!this.titleContainer && !this.footer) return 0;
1268
+            if (this.wrapper.css('display') == 'none') {
1269
+              this.wrapper.css('display', 'block');
1270
+              var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
1271
+              this.wrapper.css('display', 'none');
1272
+            } else {
1273
+              var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
1274
+            }
1275
+            return height || 0;
1276
+          }.bind(this);
1277
+
1278
+          var contentHeight = availableSpace[jBoxOutsidePosition.y || 'y'] - (this.pointer && outside && options.outside == 'y' ? this.pointer.dimensions.y : 0) - exposeTitleFooterHeight() - parseInt(this.container.css('border-top-width')) - parseInt(this.container.css('border-bottom-width'));
1279
+          this.content.css({height: contentHeight > this.options.responsiveMinHeight ? contentHeight : null});
1280
+          this._setTitleWidth();
1281
+        }
1282
+        jBoxDimensions = this._exposeDimensions();
1283
+
1284
+      }.bind(this);
1285
+      options.responsiveHeight && adjustResponsiveHeight();
1286
+
1287
+      // After adjusting height, check if jBox will be flipped for x
1288
+      options.responsiveHeight && !flip.x && (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
1289
+
1290
+      // Adjust width and height if jBox will be flipped
1291
+      if (options.adjustPosition && options.adjustPosition != 'move') {
1292
+        flip.x && adjustResponsiveWidth();
1293
+        flip.y && adjustResponsiveHeight();
1294
+      }
1295
+    }
1296
+
1297
+    // Store new positioning vars in local var
1298
+    var pos = {};
1299
+
1300
+    // Calculate positions
1301
+    var setPosition = function (p)
1302
+    {
1303
+      // Set number positions
1304
+      if (jQuery.type(options.position[p]) == 'number') {
1305
+        pos[options.attributes[p]] = options.position[p];
1306
+        return;
1307
+      }
1308
+
1309
+      // We have a target, so use 'left' or 'top' as attributes
1310
+      var a = options.attributes[p] = (p == 'x' ? 'left' : 'top');
1311
+
1312
+      // Start at target position
1313
+      pos[a] = targetDimensions[a];
1314
+
1315
+      // Set centered position
1316
+      if (options.position[p] == 'center') {
1317
+        pos[a] += Math.ceil((targetDimensions[p] - jBoxDimensions[p]) / 2);
1318
+
1319
+        // If the target is the window, adjust centered position depending on adjustDistance
1320
+        (this.target != 'mouse' && this.target[0] && this.target[0] == jQuery(window)[0]) && (pos[a] += (options.adjustDistance[a] - options.adjustDistance[this._getOpp(a)]) * 0.5);
1321
+        return;
1322
+      }
1323
+
1324
+      // Move inside
1325
+      (a != options.position[p]) && (pos[a] += targetDimensions[p] - jBoxDimensions[p]);
1326
+
1327
+      // Move outside
1328
+      (options.outside == p || options.outside == 'xy') && (pos[a] += jBoxDimensions[p] * (a != options.position[p] ? 1 : -1));
1329
+
1330
+    }.bind(this);
1331
+
1332
+    // Set position including offset
1333
+    setPosition('x');
1334
+    setPosition('y');
1335
+
1336
+    // Adjust position depending on pointer align
1337
+    if (this.pointer && options.pointTo == 'target' && jQuery.type(options.position.x) != 'number' && jQuery.type(options.position.y) != 'number') {
1338
+
1339
+      var adjustWrapper = 0;
1340
+
1341
+      // Where is the pointer aligned? Add or substract accordingly
1342
+      switch (this.pointer.align) {
1343
+        case 'center':
1344
+        if (options.position[this._getOpp(options.outside)] != 'center') {
1345
+          adjustWrapper += (jBoxDimensions[this._getOpp(options.outside)] / 2);
1346
+        }
1347
+        break;
1348
+        default:
1349
+        switch (options.position[this._getOpp(options.outside)]) {
1350
+          case 'center':
1351
+            adjustWrapper += ((jBoxDimensions[this._getOpp(options.outside)] / 2) - (this.pointer.dimensions[this._getOpp(options.outside)] / 2)) * (this.pointer.align == this._getTL(this.pointer.align) ? 1 : -1);
1352
+          break;
1353
+          default:
1354
+            adjustWrapper += (this.pointer.align != options.position[this._getOpp(options.outside)]) ?
1355
+
1356
+            // If pointer align is different to position align
1357
+            (jBoxDimensions[this._getOpp(options.outside)] * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1)) + ((this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? -1 : 1)) :
1358
+
1359
+            // If pointer align is same as position align
1360
+            (this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1);
1361
+          break;
1362
+        }
1363
+        break;
1364
+      }
1365
+
1366
+      adjustWrapper *= (options.position[this._getOpp(options.outside)] == this.pointer.alignAttribute ? -1 : 1);
1367
+      adjustWrapper += this.pointer.offset * (this.pointer.align == this._getOpp(this._getTL(this.pointer.align)) ? 1 : -1);
1368
+
1369
+      pos[this._getTL(this._getOpp(this.pointer.xy))] += adjustWrapper;
1370
+    }
1371
+
1372
+    // Add final offset
1373
+    pos[options.attributes.x] += options.offset.x;
1374
+    pos[options.attributes.y] += options.offset.y;
1375
+
1376
+    // Set CSS
1377
+    this.wrapper.css(pos);
1378
+
1379
+    // Adjust position
1380
+    if (options.adjustPosition) {
1381
+
1382
+      // Reset cached pointer position
1383
+      if (this.positionAdjusted) {
1384
+        this.pointer && this.wrapper.css('padding', 0).css('padding-' + this._getOpp(this.outside), this.pointer.dimensions[this._getXY(this.outside)]).removeClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).addClass('jBox-pointerPosition-' + this.pointer.position);
1385
+        this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + this._getOpp(this.outside)).css(this.pointer.margin);
1386
+        this.positionAdjusted = false;
1387
+        this.flipped = false;
1388
+      }
1389
+
1390
+      // Find out where the jBox is out of view area
1391
+      var outYT = (windowDimensions.top > pos.top - (options.adjustDistance.top || 0)),
1392
+        outXR = (windowDimensions.right < pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0)),
1393
+        outYB = (windowDimensions.bottom < pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0)),
1394
+        outXL = (windowDimensions.left > pos.left - (options.adjustDistance.left || 0)),
1395
+        outX = outXL ? 'left' : (outXR ? 'right' : null),
1396
+        outY = outYT ? 'top' : (outYB ? 'bottom' : null),
1397
+        out = outX || outY;
1398
+
1399
+      // Only continue if jBox is out of view area
1400
+      if (out) {
1401
+
1402
+        if ((this.type == 'Modal' || this.type == 'Confirm')
1403
+          && jQuery.type(this.options.position.x) == 'number'
1404
+          && jQuery.type(this.options.position.y) == 'number'
1405
+        ) {
1406
+          var diffX = 0, diffY = 0;
1407
+          if (this.options.holdPosition) {
1408
+
1409
+            // Adjust left or right
1410
+            if (outXL) {
1411
+              diffX = windowDimensions.left - (pos.left - (options.adjustDistance.left || 0));
1412
+            } else if (outXR) {
1413
+              diffX = windowDimensions.right - (pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0));
1414
+            }
1415
+
1416
+            // Adjust top or bottom
1417
+            if (outYT) {
1418
+              diffY = windowDimensions.top - (pos.top - (options.adjustDistance.top || 0));
1419
+            } else if (outYB) {
1420
+              diffY = windowDimensions.bottom - (pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0));
1421
+            }
1422
+
1423
+            this.options.position.x = Math.max(windowDimensions.top, this.options.position.x + diffX);
1424
+            this.options.position.y = Math.max(windowDimensions.left, this.options.position.y + diffY);
1425
+
1426
+            setPosition('x');
1427
+            setPosition('y');
1428
+            this.wrapper.css(pos);
1429
+          }
1430
+          // Fire onPosition event
1431
+          this._fireEvent('onPosition');
1432
+
1433
+          return this;
1434
+        }
1435
+
1436
+        // Function to flip position
1437
+        if (options.adjustPosition === true || options.adjustPosition === 'flip') {
1438
+          var flipJBox = function (xy) {
1439
+            this.wrapper.css(this._getTL(xy), pos[this._getTL(xy)] + ((jBoxDimensions[this._getXY(xy)] + (options.offset[this._getXY(xy)] * (xy == 'top' || xy == 'left' ? -2 : 2)) + targetDimensions[this._getXY(xy)]) * (xy == 'top' || xy == 'left' ? 1 : -1)));
1440
+            this.pointer && this.wrapper.removeClass('jBox-pointerPosition-' + this.pointer.position).addClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).css('padding', 0).css('padding-' + xy, this.pointer.dimensions[this._getXY(xy)]);
1441
+            this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + xy);
1442
+            this.positionAdjusted = true;
1443
+            this.flipped = true;
1444
+          }.bind(this);
1445
+
1446
+          // Flip jBox
1447
+          flip.x && flipJBox(this.options.position.x);
1448
+          flip.y && flipJBox(this.options.position.y);
1449
+        }
1450
+
1451
+        // Move jBox (only possible with pointer)
1452
+        var outMove = (this._getXY(this.outside) == 'x') ? outY : outX;
1453
+
1454
+        if (this.pointer && options.pointTo == 'target' && options.adjustPosition != 'flip' && this._getXY(outMove) == this._getOpp(this._getXY(this.outside))) {
1455
+
1456
+          // Get the maximum space we have availible to adjust
1457
+          if (this.pointer.align == 'center') {
1458
+            var spaceAvail = (jBoxDimensions[this._getXY(outMove)] / 2) - (this.pointer.dimensions[this._getOpp(this.pointer.xy)] / 2) - (parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) * (outMove != this._getTL(outMove) ? -1 : 1));
1459
+          } else {
1460
+            var spaceAvail = (outMove == this.pointer.alignAttribute) ?
1461
+              parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) :
1462
+              jBoxDimensions[this._getXY(outMove)] - parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - this.pointer.dimensions[this._getXY(outMove)];
1463
+          }
1464
+
1465
+          // Get the overlapping space
1466
+          var spaceDiff = (outMove == this._getTL(outMove)) ?
1467
+            windowDimensions[this._getTL(outMove)] - pos[this._getTL(outMove)] + options.adjustDistance[outMove] :
1468
+            (windowDimensions[this._getOpp(this._getTL(outMove))] - pos[this._getTL(outMove)] - options.adjustDistance[outMove] - jBoxDimensions[this._getXY(outMove)]) * -1;
1469
+
1470
+          // Add overlapping space on left or top window edge
1471
+          if (outMove == this._getOpp(this._getTL(outMove)) && pos[this._getTL(outMove)] - spaceDiff < windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)]) {
1472
+            spaceDiff -= windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)] - (pos[this._getTL(outMove)] - spaceDiff);
1473
+          }
1474
+
1475
+          // Only adjust the maximum availible
1476
+          spaceDiff = Math.min(spaceDiff, spaceAvail);
1477
+
1478
+          // Move jBox
1479
+          if (spaceDiff <= spaceAvail && spaceDiff > 0) {
1480
+            this.pointer.element.css('margin-' + this.pointer.alignAttribute, parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - (spaceDiff * (outMove != this.pointer.alignAttribute ? -1 : 1)));
1481
+            this.wrapper.css(this._getTL(outMove), pos[this._getTL(outMove)] + (spaceDiff * (outMove != this._getTL(outMove) ? -1 : 1)));
1482
+            this.positionAdjusted = true;
1483
+          }
1484
+        }
1485
+      }
1486
+    }
1487
+
1488
+    // Fire onPosition event
1489
+    this._fireEvent('onPosition');
1490
+
1491
+    return this;
1492
+  };
1493
+
1494
+
1495
+  // Block scrolling
1496
+  // Borrowed from https://github.com/StephanWagner/unscroll
1497
+
1498
+  jBox.prototype.unscroll = function (elements) {
1499
+
1500
+    // Store reusable vars
1501
+    this.set = function (id, value) {
1502
+      if (!window.unscrollStore) {
1503
+        window.unscrollStore = {};
1504
+      }
1505
+      window.unscrollStore[id] = value;
1506
+    };
1507
+
1508
+    // Get reusable vars
1509
+    this.get = function (id) {
1510
+      return window.unscrollStore ? window.unscrollStore[id] : null;
1511
+    };
1512
+
1513
+    // Get the width of the scroll bar in pixel
1514
+    this.getScrollbarWidth = function () {
1515
+      if (this.get('scrollbarWidth')) {
1516
+        return this.get('scrollbarWidth') + 'px';
1517
+      }
1518
+      var scrollElement = document.createElement('div');
1519
+      scrollElement.style.width = '100px';
1520
+      scrollElement.style.height = '100px';
1521
+      scrollElement.style.overflow = 'scroll';
1522
+      scrollElement.style.position = 'absolute';
1523
+      scrollElement.style.top = '-10000';
1524
+
1525
+      document.body.appendChild(scrollElement);
1526
+      var scrollbarWidth = scrollElement.offsetWidth - scrollElement.clientWidth;
1527
+      document.body.removeChild(scrollElement);
1528
+
1529
+      this.set('scrollbarWidth', scrollbarWidth);
1530
+      return scrollbarWidth + 'px';
1531
+    }
1532
+
1533
+    // Add unscroll class to head
1534
+    function addUnscrollClassName() {
1535
+      if (document.getElementById('unscroll-class-name')) {
1536
+        return;
1537
+      }
1538
+      var css = '.unscrollable { overflow: hidden !important; }',
1539
+        head = document.head || document.getElementsByTagName('head')[0],
1540
+        style = document.createElement('style');
1541
+      style.type = 'text/css';
1542
+      style.setAttribute('id', 'unscroll-class-name');
1543
+      style.appendChild(document.createTextNode(css));
1544
+      head.appendChild(style);
1545
+    }
1546
+
1547
+    // Get the elements to adjust, force body element
1548
+    this.getElementsToAdjust = function (elements) {
1549
+      !elements && (elements = []);
1550
+
1551
+      if (typeof elements === 'string') {
1552
+        elements = [
1553
+          [elements, 'padding-right']
1554
+        ];
1555
+      }
1556
+
1557
+      elements.forEach(function (element, index) {
1558
+        if (typeof element === 'string') {
1559
+          elements[index] = [element, 'padding-right'];
1560
+        }
1561
+      });
1562
+
1563
+      var bodyFound = false;
1564
+      for (var i = 0; i < elements.length; i++) {
1565
+        if (elements[i][0].indexOf('body') !== -1) {
1566
+          bodyFound = true;
1567
+        }
1568
+      };
1569
+
1570
+      if (bodyFound === false) {
1571
+        elements.push(['body', 'padding-right']);
1572
+      }
1573
+
1574
+      return elements;
1575
+    }
1576
+
1577
+    this.pageHasScrollbar = function () {
1578
+      return this.getScrollbarWidth() && document.body.offsetHeight > window.innerHeight;
1579
+    }
1580
+
1581
+    // Clean up elements
1582
+    if (this.pageHasScrollbar()) {
1583
+      elements = this.getElementsToAdjust(elements);
1584
+
1585
+      // Loop through elements and adjust accordingly
1586
+      for (var i = 0; i < elements.length; i++) {
1587
+        var elementsDOM = document.querySelectorAll(elements[i][0]);
1588
+        for (var j = 0; j < elementsDOM.length; j++) {
1589
+          if (elementsDOM[j].getAttribute('data-unscroll')) {
1590
+            return;
1591
+          }
1592
+          var attribute = elements[i][1];
1593
+          var computedStyles = window.getComputedStyle(elementsDOM[j]);
1594
+          var computedStyle = computedStyles.getPropertyValue(attribute);
1595
+          elementsDOM[j].setAttribute('data-unscroll', attribute);
1596
+          if (!computedStyle) {
1597
+            computedStyle = '0px';
1598
+          }
1599
+          var operator = attribute == 'padding-right' || attribute == 'right' ? '+' : '-';
1600
+          elementsDOM[j].style[attribute] = 'calc(' + computedStyle + ' ' + operator + ' ' + this.getScrollbarWidth() + ')';
1601
+        }
1602
+      }
1603
+    }
1604
+
1605
+    // Make the page unscrollable
1606
+    addUnscrollClassName();
1607
+    document.body.classList.add('unscrollable');
1608
+  }
1609
+
1610
+  jBox.prototype.unscroll.reset = function () {
1611
+    var elements = document.querySelectorAll('[data-unscroll]');
1612
+
1613
+    for (var i = 0; i < elements.length; i++) {
1614
+      var attribute = elements[i].getAttribute('data-unscroll');
1615
+      elements[i].style[attribute] = null;
1616
+      elements[i].removeAttribute('data-unscroll');
1617
+    }
1618
+    document.body.classList.remove('unscrollable');
1619
+  }
1620
+
1621
+
1622
+  // Open jBox
1623
+
1624
+  jBox.prototype.open = function (options)
1625
+  {
1626
+    // Create blank options if none passed
1627
+    !options && (options = {});
1628
+
1629
+    // Abort if jBox was destroyed
1630
+    if (this.isDestroyed) return this;
1631
+
1632
+    // Construct jBox if not already constructed
1633
+    !this.wrapper && this._create();
1634
+
1635
+    // Add css to header if not added already
1636
+    !this._styles && (this._styles = jQuery('<style/>').append(this._animationCSS).appendTo(jQuery('head')));
1637
+
1638
+    // Abort any opening or closing timer
1639
+    this.timer && clearTimeout(this.timer);
1640
+
1641
+    // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body'
1642
+    this._blockBodyClick();
1643
+
1644
+    // Block opening
1645
+    if (this.isDisabled) return this;
1646
+
1647
+    // Closing event: closeOnEsc
1648
+    this.options.closeOnEsc && jQuery(document).on('keyup.jBox-' + this.id, function (ev) { if (ev.keyCode == 27) { this.close({ignoreDelay: true}); }}.bind(this));
1649
+
1650
+    // Closing event: closeOnClick
1651
+    if (this.options.closeOnClick === true || this.options.closeOnClick === 'body') {
1652
+      jQuery('body').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function (ev) {
1653
+        if (this.blockBodyClick || (this.options.closeOnClick == 'body' && (ev.target == this.wrapper[0] || this.wrapper.has(ev.target).length))) return;
1654
+        this.close({ignoreDelay: true});
1655
+      }.bind(this));
1656
+
1657
+      // Fix for iOS event bubbling issue
1658
+      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
1659
+      this.isTouchDevice && jQuery('body > *').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function () {
1660
+        return true;
1661
+      });
1662
+    }
1663
+
1664
+    // Opening function
1665
+    var open = function () {
1666
+
1667
+      // Adjust zIndex
1668
+      if (this.adjustZIndexOnOpen === true) {
1669
+        jBox.zIndexMax = Math.max(
1670
+          parseInt(this.wrapper.css('zIndex'), 10),
1671
+          this.options.zIndex,
1672
+          jBox.zIndexMax || 0,
1673
+          jBox.zIndexMaxDragover || 0
1674
+        ) + 2;
1675
+        this.wrapper.css('zIndex', jBox.zIndexMax);
1676
+        this.options.zIndex = jBox.zIndexMax;
1677
+      }
1678
+
1679
+      // Set title from source element
1680
+      this.source && this.options.getTitle && (this.source.attr(this.options.getTitle) && this.setTitle(this.source.attr(this.options.getTitle), true));
1681
+
1682
+      // Set content from source element
1683
+      this.source && this.options.getContent && (this.source.data('jBox-getContent') ? this.setContent(this.source.data('jBox-getContent'), true) : (this.source.attr(this.options.getContent) ? this.setContent(this.source.attr(this.options.getContent), true) : (this.options.getContent == 'html' ? this.setContent(this.source.html(), true) : null)));
1684
+
1685
+      // Fire onOpen event
1686
+      this._fireEvent('onOpen');
1687
+
1688
+      // Get content from ajax
1689
+      if ((this.options.ajax && (this.options.ajax.url || (this.source && this.source.attr(this.options.ajax.getURL))) && (!this.ajaxLoaded || this.options.ajax.reload)) || (options.ajax && (options.ajax.url || options.ajax.data))) {
1690
+        // Send the content from stored data if there is any, otherwise load new data
1691
+        (this.options.ajax.reload != 'strict' && this.source && this.source.data('jBox-ajax-data') && !(options.ajax && (options.ajax.url || options.ajax.data))) ? this.setContent(this.source.data('jBox-ajax-data')) : this.ajax((options.ajax || null), true);
1692
+      }
1693
+
1694
+      // Set position
1695
+      (!this.positionedOnOpen || this.options.repositionOnOpen) && this.position(options) && (this.positionedOnOpen = true);
1696
+
1697
+      // Abort closing
1698
+      this.isClosing && this._abortAnimation();
1699
+
1700
+      // Open functions to call when jBox is closed
1701
+      if (!this.isOpen) {
1702
+
1703
+        // jBox is open now
1704
+        this.isOpen = true;
1705
+
1706
+        // Automatically close jBox after some time
1707
+        this.options.autoClose && (this.options.delayClose = this.options.autoClose) && this.close();
1708
+
1709
+        // Attach events
1710
+        this._attachEvents();
1711
+
1712
+        // Block scrolling
1713
+        if (this.options.blockScroll) {
1714
+          if (this.options.blockScrollAdjust) {
1715
+            if (jBox.blockScrollScopes) {
1716
+              jBox.blockScrollScopes++;
1717
+            } else {
1718
+              jBox.blockScrollScopes = 1;
1719
+              this.unscroll(Array.isArray(this.options.blockScrollAdjust) || typeof this.options.blockScrollAdjust === 'string' ? this.options.blockScrollAdjust : null);
1720
+            }
1721
+          } else {
1722
+            jQuery('body').addClass('jBox-blockScroll-' + this.id);
1723
+          }
1724
+        }
1725
+
1726
+        // Show overlay
1727
+        if (this.options.overlay) {
1728
+          this._showOverlay();
1729
+
1730
+          // TODO Optimize: We have to position here again, because if the overlay has a close button, the upper adjustDistance will be wrong
1731
+          this.position();
1732
+        }
1733
+
1734
+        // Only animate if jBox is completely closed
1735
+        this.options.animation && !this.isClosing && this._animate('open');
1736
+
1737
+        // Play audio file
1738
+        this.options.audio && this.options.audio.open && this.audio(this.options.audio.open, this.options.volume.open);
1739
+
1740
+        // Fading animation or show immediately
1741
+        if (this.options.fade) {
1742
+          this.wrapper.stop().animate({opacity: 1}, {
1743
+            queue: false,
1744
+            duration: this.options.fade,
1745
+            start: function () {
1746
+              this.isOpening = true;
1747
+              this.wrapper.css({display: 'block'});
1748
+            }.bind(this),
1749
+            complete: function () {
1750
+              this._fireEvent('onOpenComplete');
1751
+            }.bind(this),
1752
+            always: function () {
1753
+              this.isOpening = false;
1754
+
1755
+              // Delay positioning for ajax to prevent positioning during animation
1756
+              setTimeout(function () { this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false); }.bind(this), 10);
1757
+            }.bind(this)
1758
+          });
1759
+        } else {
1760
+          this.wrapper.css({display: 'block', opacity: 1});
1761
+          this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false);
1762
+          this._fireEvent('onOpenComplete');
1763
+        }
1764
+      }
1765
+    }.bind(this);
1766
+
1767
+    // Open jBox
1768
+    this.options.delayOpen && !this.isOpen && !this.isClosing && !options.ignoreDelay ? (this.timer = setTimeout(open, this.options.delayOpen)) : open();
1769
+
1770
+    return this;
1771
+  };
1772
+
1773
+
1774
+  // Close jBox
1775
+
1776
+  jBox.prototype.close = function (options)
1777
+  {
1778
+    // Create blank options if none passed
1779
+    options || (options = {});
1780
+
1781
+    // Remove close events
1782
+    jQuery('body').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
1783
+    this.isTouchDevice && jQuery('body > *').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
1784
+
1785
+    // Abort if jBox was destroyed or is currently closing
1786
+    if (this.isDestroyed || this.isClosing) return this;
1787
+
1788
+    // Abort opening
1789
+    this.timer && clearTimeout(this.timer);
1790
+
1791
+    // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body' is true
1792
+    this._blockBodyClick();
1793
+
1794
+    // Block closing
1795
+    if (this.isDisabled) return this;
1796
+
1797
+    // Close function
1798
+    var close = function () {
1799
+
1800
+      // Fire onClose event
1801
+      this._fireEvent('onClose');
1802
+
1803
+      // Cancel the ajax call
1804
+      if (this.options.cancelAjaxOnClose) {
1805
+        this.cancelAjax();
1806
+      }
1807
+
1808
+      // Only close if jBox is open
1809
+      if (this.isOpen) {
1810
+
1811
+        // jBox is not open anymore
1812
+        this.isOpen = false;
1813
+
1814
+        // Detach events
1815
+        this._detachEvents();
1816
+
1817
+        // Unblock scrolling
1818
+        if (this.options.blockScroll) {
1819
+          if (this.options.blockScrollAdjust) {
1820
+            jBox.blockScrollScopes = jBox.blockScrollScopes ? --jBox.blockScrollScopes : 0;
1821
+            !jBox.blockScrollScopes && this.unscroll.reset();
1822
+          } else {
1823
+            jQuery('body').removeClass('jBox-blockScroll-' + this.id);
1824
+          }
1825
+        }
1826
+
1827
+        // Hide overlay
1828
+        this.options.overlay && this._hideOverlay();
1829
+
1830
+        // Only animate if jBox is compleately closed
1831
+        this.options.animation && !this.isOpening && this._animate('close');
1832
+
1833
+        // Play audio file
1834
+        this.options.audio && this.options.audio.close && this.audio(this.options.audio.close, this.options.volume.close);
1835
+
1836
+        // Get fade duration
1837
+        var fadeDuration = this.isTouchDevice && this.options.target == 'mouse' ? 0 : this.options.fade;
1838
+
1839
+        // Fading animation or show immediately
1840
+        if (fadeDuration) {
1841
+          this.wrapper.stop().animate({opacity: 0}, {
1842
+            queue: false,
1843
+            duration: fadeDuration,
1844
+            start: function () {
1845
+              this.isClosing = true;
1846
+            }.bind(this),
1847
+            complete: function () {
1848
+              this.wrapper.css({display: 'none'});
1849
+              this._fireEvent('onCloseComplete');
1850
+            }.bind(this),
1851
+            always: function () {
1852
+              this.isClosing = false;
1853
+            }.bind(this)
1854
+          });
1855
+        } else {
1856
+          this.wrapper.css({display: 'none', opacity: 0});
1857
+          this._fireEvent('onCloseComplete');
1858
+        }
1859
+      }
1860
+    }.bind(this);
1861
+
1862
+    // Close jBox
1863
+    if (options.ignoreDelay || (this.isTouchDevice && this.options.target == 'mouse')) {
1864
+      close();
1865
+    } else if ((this.options.delayOnHover || this.options.showCountdown) && this.options.delayClose > 10) {
1866
+      var self = this;
1867
+      var remaining = this.options.delayClose;
1868
+      var prevFrame = Date.now();
1869
+      if (this.options.showCountdown && !this.inner) {
1870
+        var outer = jQuery('<div class="jBox-countdown" />');
1871
+        this.inner = jQuery('<div class="jBox-countdown-inner" />');
1872
+        outer.prepend(this.inner);
1873
+        jQuery('#' + this.id).append(outer);
1874
+      }
1875
+      this.countdown = function(){
1876
+        var dateNow = Date.now();
1877
+        if (!self.isHovered) {
1878
+          remaining -= dateNow - prevFrame;
1879
+        }
1880
+        prevFrame = dateNow;
1881
+        if (remaining > 0) {
1882
+          if (self.options.showCountdown) {
1883
+            self.inner.css('width', (remaining * 100 / self.options.delayClose) + '%');
1884
+          }
1885
+          window.requestAnimationFrame(self.countdown);
1886
+        } else {
1887
+          close();
1888
+        }
1889
+      };
1890
+      window.requestAnimationFrame(this.countdown);
1891
+    } else {
1892
+      this.timer = setTimeout(close, Math.max(this.options.delayClose, 10));
1893
+    }
1894
+
1895
+    return this;
1896
+  };
1897
+
1898
+
1899
+  // Open or close jBox
1900
+
1901
+  jBox.prototype.toggle = function (options)
1902
+  {
1903
+    this[this.isOpen ? 'close' : 'open'](options);
1904
+    return this;
1905
+  };
1906
+
1907
+
1908
+  // Block opening and closing
1909
+
1910
+  jBox.prototype.disable = function ()
1911
+  {
1912
+    this.isDisabled = true;
1913
+    return this;
1914
+  };
1915
+
1916
+
1917
+  // Unblock opening and closing
1918
+
1919
+  jBox.prototype.enable = function ()
1920
+  {
1921
+    this.isDisabled = false;
1922
+    return this;
1923
+  };
1924
+
1925
+
1926
+  // Hide jBox
1927
+
1928
+  jBox.prototype.hide = function ()
1929
+  {
1930
+    this.disable();
1931
+    if (this.wrapper) {
1932
+      this.cacheWrapperDisplay = this.wrapper.css('display');
1933
+      this.wrapper.css({display: 'none'});
1934
+    }
1935
+    if (this.overlay) {
1936
+      this.cacheOverlayDisplay = this.overlay.css('display');
1937
+      this.overlay.css({display: 'none'});
1938
+    }
1939
+    return this;
1940
+  };
1941
+
1942
+
1943
+  // Show jBox
1944
+
1945
+  jBox.prototype.show = function ()
1946
+  {
1947
+    this.enable();
1948
+    if (this.wrapper && this.cacheWrapperDisplay) {
1949
+      this.wrapper.css({display: this.cacheWrapperDisplay});
1950
+      this.cacheWrapperDisplay = null;
1951
+    }
1952
+    if (this.overlay && this.cacheOverlayDisplay) {
1953
+      this.overlay.css({display: this.cacheOverlayDisplay});
1954
+      this.cacheOverlayDisplay = null;
1955
+    }
1956
+    return this;
1957
+  };
1958
+
1959
+
1960
+  // Get content from ajax
1961
+
1962
+  jBox.prototype.ajax = function (options, opening)
1963
+  {
1964
+    options || (options = {});
1965
+
1966
+    // Add data or url from source element if none set in options
1967
+    jQuery.each([['getData', 'data'], ['getURL', 'url']], function (index, item) {
1968
+      (this.options.ajax[item[0]] && !options[item[1]] && this.source && this.source.attr(this.options.ajax[item[0]]) != undefined) && (options[item[1]] = this.source.attr(this.options.ajax[item[0]]) || '');
1969
+    }.bind(this));
1970
+
1971
+    // Clone the system options
1972
+    var sysOptions = jQuery.extend(true, {}, this.options.ajax);
1973
+
1974
+    // Abort running ajax call
1975
+    this.cancelAjax();
1976
+
1977
+    // Extract events
1978
+    var beforeSend = options.beforeSend || sysOptions.beforeSend || function () {};
1979
+    var complete = options.complete || sysOptions.complete || function () {};
1980
+    var success = options.success || sysOptions.success || function () {};
1981
+    var error = options.error || sysOptions.error || function () {};
1982
+
1983
+    // Merge options
1984
+    var userOptions = jQuery.extend(true, sysOptions, options);
1985
+
1986
+    // Set new beforeSend event
1987
+    userOptions.beforeSend = function (xhr)
1988
+    {
1989
+      // jBox is loading
1990
+      userOptions.loadingClass && this.wrapper.addClass(userOptions.loadingClass === true ? 'jBox-loading' : userOptions.loadingClass);
1991
+
1992
+      // Add loading spinner
1993
+      userOptions.spinner && (this.spinnerDelay = setTimeout(function ()
1994
+      {
1995
+        // Add class for loading spinner
1996
+        this.wrapper.addClass('jBox-loading-spinner');
1997
+
1998
+        // Reposition jBox
1999
+        // TODO: Only reposition if dimensions change
2000
+        userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
2001
+
2002
+        // Add spinner to container
2003
+        this.spinner = jQuery(userOptions.spinner !== true ? userOptions.spinner : '<div class="jBox-spinner"></div>').appendTo(this.container);
2004
+
2005
+        // Fix spinners position if there is a title
2006
+        this.titleContainer && this.spinner.css('position') == 'absolute' && this.spinner.css({transform: 'translateY(' + (this.titleContainer.outerHeight() * 0.5) + 'px)'});
2007
+
2008
+      }.bind(this), (this.content.html() == '' ? 0 : (userOptions.spinnerDelay || 0))));
2009
+
2010
+      // Fire users beforeSend event
2011
+      (beforeSend.bind(this))(xhr);
2012
+
2013
+    }.bind(this);
2014
+
2015
+    // Set up new complete event
2016
+    userOptions.complete = function (response)
2017
+    {
2018
+      // Abort spinner timeout
2019
+      this.spinnerDelay && clearTimeout(this.spinnerDelay);
2020
+
2021
+      // jBox finished loading
2022
+      this.wrapper.removeClass('jBox-loading jBox-loading-spinner jBox-loading-spinner-delay');
2023
+
2024
+      // Remove spinner
2025
+      this.spinner && this.spinner.length && this.spinner.remove() && userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
2026
+
2027
+      // Store that ajax loading finished
2028
+      this.ajaxLoaded = true;
2029
+
2030
+      // Fire users complete event
2031
+      (complete.bind(this))(response);
2032
+
2033
+    }.bind(this);
2034
+
2035
+    // Set up new success event
2036
+    userOptions.success = function (response)
2037
+    {
2038
+      // Set content
2039
+      userOptions.setContent && this.setContent(response, true) && (opening ? (this.positionOnFadeComplete = true) : this.position());
2040
+
2041
+      // Store content in source element
2042
+      userOptions.setContent && this.source && this.source.data('jBox-ajax-data', response);
2043
+
2044
+      // Fire users success event
2045
+      (success.bind(this))(response);
2046
+
2047
+    }.bind(this);
2048
+
2049
+    // Add error event
2050
+    userOptions.error = function (response) { (error.bind(this))(response); }.bind(this);
2051
+
2052
+    // Send new ajax request
2053
+    this.ajaxRequest = jQuery.ajax(userOptions);
2054
+
2055
+    return this;
2056
+  };
2057
+
2058
+
2059
+  // Abort an ajax call
2060
+
2061
+  jBox.prototype.cancelAjax = function () {
2062
+    if (this.ajaxRequest) {
2063
+      this.ajaxRequest.abort();
2064
+      this.ajaxLoaded = false;
2065
+    }
2066
+  };
2067
+
2068
+
2069
+  // Play an audio file
2070
+
2071
+  jBox.prototype.audio = function (url, volume)
2072
+  {
2073
+    // URL is required
2074
+    if (!url) return this;
2075
+
2076
+    // Create intern audio object if it wasn't created already
2077
+    !jBox._audio && (jBox._audio = {});
2078
+
2079
+    // Create an audio element specific to this audio file if it doesn't exist already
2080
+    if (!jBox._audio[url]) {
2081
+      var audio = jQuery('<audio/>');
2082
+      jQuery('<source/>', {src: url + '.mp3'}).appendTo(audio);
2083
+      jQuery('<source/>', {src: url + '.ogg'}).appendTo(audio);
2084
+      jBox._audio[url] = audio[0];
2085
+    }
2086
+
2087
+    // Set volume
2088
+    jBox._audio[url].volume = Math.min(((volume != undefined ? volume : 100) / 100), 1);
2089
+
2090
+    // Try to pause current audio
2091
+    try {
2092
+      jBox._audio[url].pause();
2093
+      jBox._audio[url].currentTime = 0;
2094
+    } catch (e) {}
2095
+
2096
+    // Play audio
2097
+    jBox._audio[url].play();
2098
+
2099
+    return this;
2100
+  };
2101
+
2102
+  // Apply custom animations to jBox (being used in playground demos)
2103
+
2104
+  jBox._animationSpeeds = {
2105
+    'tada': 1000,
2106
+    'tadaSmall': 1000,
2107
+    'flash': 500,
2108
+    'shake': 400,
2109
+    'pulseUp': 250,
2110
+    'pulseDown': 250,
2111
+    'popIn': 250,
2112
+    'popOut': 250,
2113
+    'fadeIn': 200,
2114
+    'fadeOut': 200,
2115
+    'slideUp': 400,
2116
+    'slideRight': 400,
2117
+    'slideLeft': 400,
2118
+    'slideDown': 400
2119
+  };
2120
+
2121
+  jBox.prototype.animate = function (animation, options)
2122
+  {
2123
+    // Options are required
2124
+    !options && (options = {});
2125
+
2126
+    // Timout needs to be an object
2127
+    !this.animationTimeout && (this.animationTimeout = {});
2128
+
2129
+    // Use jBox wrapper by default
2130
+    !options.element && (options.element = this.wrapper);
2131
+
2132
+    // Give the element an unique id
2133
+    !options.element.data('jBox-animating-id') && options.element.data('jBox-animating-id', jBox._getUniqueElementID());
2134
+
2135
+    // Abort if element is animating
2136
+    if (options.element.data('jBox-animating')) {
2137
+      options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null);
2138
+      this.animationTimeout[options.element.data('jBox-animating-id')] && clearTimeout(this.animationTimeout[options.element.data('jBox-animating-id')]);
2139
+    }
2140
+
2141
+    // Animate the element
2142
+    options.element.addClass('jBox-animated-' + animation).data('jBox-animating', 'jBox-animated-' + animation);
2143
+    this.animationTimeout[options.element.data('jBox-animating-id')] = setTimeout((function() { options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null); options.complete && options.complete(); }), jBox._animationSpeeds[animation]);
2144
+  };
2145
+
2146
+  // https://gist.github.com/AlexEmashev/ee8302b5036b01362f63dab35948401f
2147
+  jBox.prototype.swipeDetector = function (swipeTarget, options) {
2148
+    // States: 0 - no swipe, 1 - swipe started, 2 - swipe released
2149
+    var swipeState = 0;
2150
+    // Coordinates when swipe started
2151
+    var startX = 0;
2152
+    var startY = 0;
2153
+    // Distance of swipe
2154
+    var pixelOffsetX = 0;
2155
+    var pixelOffsetY = 0;
2156
+
2157
+    var defaultSettings = {
2158
+      // Amount of pixels, when swipe don't count.
2159
+      swipeThreshold: 70,
2160
+      // Flag that indicates that plugin should react only on touch events.
2161
+      // Not on mouse events too.
2162
+      useOnlyTouch: false
2163
+    };
2164
+
2165
+    // Initializer
2166
+    (function init() {
2167
+      options = jQuery.extend(defaultSettings, options);
2168
+      // Support touch and mouse as well.
2169
+      swipeTarget.on("mousedown touchstart", swipeStart);
2170
+      jQuery("html").on("mouseup touchend", swipeEnd);
2171
+      jQuery("html").on("mousemove touchmove", swiping);
2172
+    })();
2173
+
2174
+    function swipeStart(event) {
2175
+      if (options.useOnlyTouch && !event.originalEvent.touches) {
2176
+        return;
2177
+      }
2178
+
2179
+      if (event.originalEvent.touches) {
2180
+        event = event.originalEvent.touches[0];
2181
+      }
2182
+
2183
+      if (swipeState === 0) {
2184
+        swipeState = 1;
2185
+        startX = event.clientX;
2186
+        startY = event.clientY;
2187
+      }
2188
+    }
2189
+
2190
+    function swipeEnd(event) {
2191
+      if (swipeState === 2) {
2192
+        swipeState = 0;
2193
+
2194
+        if (
2195
+          Math.abs(pixelOffsetX) > Math.abs(pixelOffsetY) &&
2196
+          Math.abs(pixelOffsetX) > options.swipeThreshold
2197
+        ) {
2198
+          // Horizontal Swipe
2199
+          if (pixelOffsetX < 0) {
2200
+            swipeTarget.trigger(jQuery.Event("swipeLeft.sd"));
2201
+          } else {
2202
+            swipeTarget.trigger(jQuery.Event("swipeRight.sd"));
2203
+          }
2204
+        } else if (Math.abs(pixelOffsetY) > options.swipeThreshold) {
2205
+          // Vertical swipe
2206
+          if (pixelOffsetY < 0) {
2207
+            swipeTarget.trigger(jQuery.Event("swipeUp.sd"));
2208
+          } else {
2209
+            swipeTarget.trigger(jQuery.Event("swipeDown.sd"));
2210
+          }
2211
+        }
2212
+      }
2213
+    }
2214
+
2215
+    function swiping(event) {
2216
+      // If swipe don't occuring, do nothing.
2217
+      if (swipeState !== 1) return;
2218
+
2219
+      if (event.originalEvent.touches) {
2220
+        event = event.originalEvent.touches[0];
2221
+      }
2222
+
2223
+      var swipeOffsetX = event.clientX - startX;
2224
+      var swipeOffsetY = event.clientY - startY;
2225
+
2226
+      if (
2227
+        Math.abs(swipeOffsetX) > options.swipeThreshold ||
2228
+        Math.abs(swipeOffsetY) > options.swipeThreshold
2229
+      ) {
2230
+        swipeState = 2;
2231
+        pixelOffsetX = swipeOffsetX;
2232
+        pixelOffsetY = swipeOffsetY;
2233
+      }
2234
+    }
2235
+
2236
+    return swipeTarget; // Return element available for chaining.
2237
+  }
2238
+
2239
+
2240
+  // Destroy jBox and remove it from DOM
2241
+
2242
+  jBox.prototype.destroy = function ()
2243
+  {
2244
+    // Detach from attached elements
2245
+    this.detach();
2246
+
2247
+    // If jBox is open, close without delay
2248
+    this.isOpen && this.close({ignoreDelay: true});
2249
+
2250
+    // Remove wrapper
2251
+    this.wrapper && this.wrapper.remove();
2252
+
2253
+    // Remove overlay
2254
+    this.overlay && this.overlay.remove();
2255
+
2256
+    // Remove styles
2257
+    this._styles && this._styles.remove();
2258
+
2259
+    // Tell the jBox instance it is destroyed
2260
+    this.isDestroyed = true;
2261
+
2262
+    return this;
2263
+  };
2264
+
2265
+
2266
+  // Get a unique ID for jBoxes
2267
+
2268
+  jBox._getUniqueID = (function ()
2269
+  {
2270
+    var i = 1;
2271
+    return function () { return i++; };
2272
+  }());
2273
+
2274
+
2275
+  // Get a unique ID for animating elements
2276
+
2277
+  jBox._getUniqueElementID = (function ()
2278
+  {
2279
+    var i = 1;
2280
+    return function () { return i++; };
2281
+  }());
2282
+
2283
+
2284
+  // Function to create jBox plugins
2285
+
2286
+  jBox._pluginOptions = {};
2287
+  jBox.plugin = function (type, options)
2288
+  {
2289
+    jBox._pluginOptions[type] = options;
2290
+  };
2291
+
2292
+
2293
+  // Make jBox usable with jQuery selectors
2294
+
2295
+  jQuery.fn.jBox = function (type, options) {
2296
+    // Variables type and object are required
2297
+    !type && (type = {});
2298
+    !options && (options = {});
2299
+
2300
+    // Return a new instance of jBox with the selector as attached element
2301
+    return new jBox(type, jQuery.extend(options, {
2302
+      attach: this
2303
+    }));
2304
+  };
2305
+
2306
+  return jBox;
2307
+
2308
+};
2309
+
2310
+/**
2311
+ * jBox Confirm plugin: Add a confirm dialog to links, buttons, etc.
2312
+ *
2313
+ * Author: Stephan Wagner <stephanwagner.me@gmail.com> (https://stephanwagner.me)
2314
+ *
2315
+ * License: MIT (https://opensource.org/licenses/MIT)
2316
+ *
2317
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
2318
+ */
2319
+
2320
+function jBoxConfirmWrapper(jBox, jQuery) {
2321
+
2322
+  new jBox.plugin('Confirm', {
2323
+
2324
+
2325
+    // Options (https://stephanwagner.me/jBox/options#options-confirm)
2326
+
2327
+    confirmButton: 'Submit',  // Text for the submit button
2328
+    cancelButton: 'Cancel',   // Text for the cancel button
2329
+    confirm: null,            // Function to execute when clicking the submit button. By default jBox will use the onclick or href attribute in that order if found
2330
+    cancel: null,             // Function to execute when clicking the cancel button
2331
+    closeOnConfirm: true,     // Close jBox when the user clicks the confirm button
2332
+    target: window,
2333
+    fixed: true,
2334
+    attach: '[data-confirm]',
2335
+    getContent: 'data-confirm',
2336
+    content: 'Do you really want to do this?',
2337
+    minWidth: 360,
2338
+    maxWidth: 500,
2339
+    blockScroll: true,
2340
+    closeOnEsc: true,
2341
+    closeOnClick: false,
2342
+    closeButton: false,
2343
+    overlay: true,
2344
+    animation: 'zoomIn',
2345
+    preventDefault: true,
2346
+
2347
+
2348
+    // Triggered when jBox is attached to the element
2349
+
2350
+    _onAttach: function (el)
2351
+    {
2352
+      // Extract the href or the onclick event if no submit event is passed
2353
+      if (!this.options.confirm) {
2354
+        var submit = el.attr('onclick') ? el.attr('onclick') : (
2355
+          el.attr('href') ? (
2356
+            el.attr('target') ? 'window.open("' + el.attr('href') + '", "' + el.attr('target') + '");'  : 'window.location.href = "' + el.attr('href') + '";'
2357
+          ) : '');
2358
+        el.prop('onclick', null).data('jBox-Confirm-submit', submit);
2359
+      }
2360
+    },
2361
+
2362
+
2363
+    // Triggered when jBox was created
2364
+
2365
+    _onCreated: function ()
2366
+    {
2367
+      // Add modal class to mimic jBox modal
2368
+      this.wrapper.addClass('jBox-Modal');
2369
+
2370
+      // Add a footer to the jBox container
2371
+      this.footer = jQuery('<div class="jBox-Confirm-footer"/>');
2372
+
2373
+      jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-cancel"/>')
2374
+        .html(this.options.cancelButton)
2375
+        .on('click tap', function () {
2376
+          this.options.cancel && this.options.cancel(this.source);
2377
+          this.close();
2378
+        }.bind(this))
2379
+        .appendTo(this.footer);
2380
+
2381
+      this.submitButton = jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-submit"/>')
2382
+        .html(this.options.confirmButton)
2383
+        .appendTo(this.footer);
2384
+
2385
+      this.footer.appendTo(this.container);
2386
+    },
2387
+
2388
+
2389
+    // Triggered when jBox is opened
2390
+
2391
+    _onOpen: function ()
2392
+    {
2393
+      // Set the new action for the submit button
2394
+      this.submitButton
2395
+        .off('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id)
2396
+        .on('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id, function () {
2397
+          this.options.confirm ? this.options.confirm(this.source) : eval(this.source.data('jBox-Confirm-submit'));
2398
+          this.options.closeOnConfirm && this.close();
2399
+        }.bind(this));
2400
+    }
2401
+
2402
+  });
2403
+
2404
+};
2405
+
2406
+/**
2407
+ * jBox Image plugin: Adds a lightbox to your images
2408
+ *
2409
+ * Author: Stephan Wagner <stephanwagner.me@gmail.com> (https://stephanwagner.me)
2410
+ *
2411
+ * License: MIT (https://opensource.org/licenses/MIT)
2412
+ *
2413
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
2414
+ */
2415
+
2416
+function jBoxImageWrapper(jBox, jQuery) {
2417
+
2418
+  new jBox.plugin('Image', {
2419
+
2420
+
2421
+    // Options (https://stephanwagner.me/jBox/options#options-image)
2422
+
2423
+    src: 'href',                 // The attribute where jBox gets the image source from, e.g. href="/path_to_image/image.jpg"
2424
+    gallery: 'data-jbox-image',  // The attribute to set the galleries, e.g. data-jbox-image="gallery1"
2425
+    imageLabel: 'title',         // The attribute where jBox gets the image label from, e.g. title="My label"
2426
+    imageFade: 360,              // The fade duration for images in ms
2427
+    imageSize: 'contain',        // How to display the images. Use CSS background-position values, e.g. 'cover', 'contain', 'auto', 'initial', '50% 50%'
2428
+    imageCounter: false,         // Set to true to add an image counter, e.g. 4/20
2429
+    imageCounterSeparator: '/',  // HTML to separate the current image number from all image numbers, e.g. '/' or ' of '
2430
+    downloadButton: false,       // Adds a download button
2431
+    downloadButtonText: null,    // Text for the download button
2432
+    downloadButtonUrl: null,     // The attribute at the source element where to find the image to download, e.g. data-download="/path_to_image/image.jpg". If none provided, the currently active image will be downloaded
2433
+    mobileImageAttr: null,       // The attribute to look for an mobile version of the image
2434
+    mobileImageBreakpoint: null, // The upper breakpoint to load the mobile image
2435
+    preloadFirstImage: false,    // Preload the first image when page is loaded
2436
+    target: window,
2437
+    attach: '[data-jbox-image]',
2438
+    fixed: true,
2439
+    blockScroll: true,
2440
+    closeOnEsc: true,
2441
+    closeOnClick: 'button',
2442
+    closeButton: true,
2443
+    overlay: true,
2444
+    animation: 'zoomIn',
2445
+    preventDefault: true,
2446
+    width: '100%',
2447
+    height: '100%',
2448
+    adjustDistance: {
2449
+      top: 40,
2450
+      right: 0,
2451
+      bottom: 40,
2452
+      left: 0
2453
+    },
2454
+
2455
+
2456
+    // Triggered when jBox is initialized
2457
+
2458
+    _onInit: function ()
2459
+    {
2460
+      // Initial images and z-index
2461
+      this.images = this.currentImage = {};
2462
+      this.imageZIndex = 1;
2463
+
2464
+      this.initImage = function (item) {
2465
+        item = jQuery(item);
2466
+
2467
+        // Abort if the item was added to a gallery already
2468
+        if (item.data('jBox-image-gallery')) {
2469
+          return;
2470
+        }
2471
+
2472
+        // Get the image src
2473
+        var src = item.attr(this.options.src);
2474
+
2475
+        // Update responsive image src
2476
+        if (this.options.mobileImageAttr && this.options.mobileImageBreakpoint && item.attr(this.options.mobileImageAttr)) {
2477
+          if (jQuery(window).width() <= this.options.mobileImageBreakpoint) {
2478
+            src = item.attr(this.options.mobileImageAttr);
2479
+          }
2480
+        }
2481
+
2482
+        // Add item to a gallery
2483
+        var gallery = item.attr(this.options.gallery) || 'default';
2484
+        !this.images[gallery] && (this.images[gallery] = []);
2485
+        this.images[gallery].push({
2486
+          src: src,
2487
+          label: (item.attr(this.options.imageLabel) || ''),
2488
+          downloadUrl: this.options.downloadButtonUrl && item.attr(this.options.downloadButtonUrl) ? item.attr(this.options.downloadButtonUrl) : null
2489
+        });
2490
+
2491
+        // Remove the title attribute so it won't show the browsers tooltip
2492
+        this.options.imageLabel == 'title' && item.removeAttr('title');
2493
+
2494
+        // Store data in source element for easy access
2495
+        item.data('jBox-image-gallery', gallery);
2496
+        item.data('jBox-image-id', (this.images[gallery].length - 1));
2497
+      }.bind(this);
2498
+
2499
+      // Loop through images, sort and save in global variable
2500
+      this.attachedElements && this.attachedElements.length && jQuery.each(this.attachedElements, function (index, item) {
2501
+        this.initImage(item);
2502
+      }.bind(this));
2503
+
2504
+      // Helper to inject the image into content area
2505
+      var appendImage = function (gallery, id, show, instant) {
2506
+        // Abort if image was appended already
2507
+        if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
2508
+          return;
2509
+        }
2510
+
2511
+        // Create image container
2512
+        var image = jQuery('<div/>', {
2513
+          id: 'jBox-image-' + gallery + '-' + id,
2514
+          'class': 'jBox-image-container' + (show ? ' jBox-image-' + gallery + '-current' : '')
2515
+        }).css({
2516
+          backgroundSize: this.options.imageSize,
2517
+          opacity: (instant ? 1 : 0),
2518
+          zIndex: (show ? this.imageZIndex++ : 0)
2519
+        }).appendTo(this.content);
2520
+
2521
+        // Add swipe events
2522
+        this.swipeDetector(image)
2523
+          .on("swipeLeft.sd swipeRight.sd", function (event) {
2524
+            if (event.type === "swipeLeft") {
2525
+              this.showImage('next');
2526
+            } else if (event.type === "swipeRight") {
2527
+              this.showImage('prev');
2528
+            }
2529
+          }.bind(this));
2530
+
2531
+        // Create labels
2532
+        jQuery('<div/>', {
2533
+          id: 'jBox-image-label-' + gallery + '-' + id,
2534
+          'class': 'jBox-image-label' + (show ? ' active' : '')
2535
+        })
2536
+        .html(this.images[gallery][id].label)
2537
+        .on('click tap', function () {
2538
+          jQuery(this).toggleClass('expanded');
2539
+        })
2540
+        .appendTo(this.imageLabelContainer);
2541
+
2542
+        // Show image
2543
+        show && image.animate({opacity: 1}, instant ? 0 : this.options.imageFade);
2544
+
2545
+        return image;
2546
+      }.bind(this);
2547
+
2548
+      // Function to download an image
2549
+      this.downloadImage = function (imageUrl) {
2550
+        var link = document.createElement('a');
2551
+        link.href = imageUrl;
2552
+        link.setAttribute('download', imageUrl.substring(imageUrl.lastIndexOf('/')+1));
2553
+        document.body.appendChild(link);
2554
+        link.click();
2555
+      };
2556
+
2557
+      // Helper to show new image label
2558
+      var showLabel = function (gallery, id) {
2559
+        jQuery('.jBox-image-label.active').removeClass('active expanded');
2560
+        jQuery('#jBox-image-label-' + gallery + '-' + id).addClass('active');
2561
+      };
2562
+
2563
+      // Helper to load image
2564
+      var loadImage = function (gallery, id, show, instant) {
2565
+        var imageContainer = appendImage(gallery, id, show, instant);
2566
+        imageContainer.addClass('jBox-image-loading');
2567
+
2568
+        jQuery('<img src="' + this.images[gallery][id].src + '" />').each(function () {
2569
+          var tmpImg = new Image();
2570
+          tmpImg.onload = function () {
2571
+            imageContainer.removeClass('jBox-image-loading');
2572
+            imageContainer.css({backgroundImage: 'url("' + this.images[gallery][id].src + '")'});
2573
+          }.bind(this);
2574
+
2575
+          tmpImg.onerror = function () {
2576
+            imageContainer.removeClass('jBox-image-loading');
2577
+            imageContainer.addClass('jBox-image-not-found');
2578
+          }.bind(this);
2579
+
2580
+          tmpImg.src = this.images[gallery][id].src;
2581
+        }.bind(this));
2582
+      }.bind(this);
2583
+
2584
+      // Show images when they are loaded or load them if not
2585
+      this.showImage = function (img) {
2586
+        // Get the gallery and the image id from the next or the previous image
2587
+        var gallery;
2588
+        var id;
2589
+
2590
+        if (img != 'open') {
2591
+          gallery = this.currentImage.gallery;
2592
+          id = this.currentImage.id + (1 * (img == 'prev') ? -1 : 1);
2593
+          id = id > (this.images[gallery].length - 1) ? 0 : (id < 0 ? (this.images[gallery].length - 1) : id);
2594
+
2595
+        // Or get image data from source element
2596
+        } else {
2597
+          // Get gallery and image id from source element
2598
+          if (this.source) {
2599
+            gallery = this.source.data('jBox-image-gallery');
2600
+            id = this.source.data('jBox-image-id');
2601
+
2602
+          // Get gallery and image id attached elements
2603
+          } else if (this.attachedElements && this.attachedElements.length) {
2604
+            gallery = jQuery(this.attachedElements[0]).data('jBox-image-gallery');
2605
+            id = jQuery(this.attachedElements[0]).data('jBox-image-id');
2606
+          } else {
2607
+            return;
2608
+          }
2609
+
2610
+          // Remove or show the next and prev buttons
2611
+          if (this.images && this.images[gallery]) {
2612
+            jQuery('.jBox-image-pointer-prev, .jBox-image-pointer-next').css({display: (this.images[gallery].length > 1 ? 'block' : 'none')});
2613
+          }
2614
+        }
2615
+
2616
+        // If there is a current image already shown, hide it
2617
+        if (jQuery('.jBox-image-' + gallery + '-current').length) {
2618
+          jQuery('.jBox-image-' + gallery + '-current').removeClass('jBox-image-' + gallery + '-current').animate({opacity: 0}, (img == 'open') ? 0 : this.options.imageFade);
2619
+        }
2620
+
2621
+        // Set new current image
2622
+        this.currentImage = {gallery: gallery, id: id};
2623
+
2624
+        // Show image if it already exists
2625
+        if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
2626
+          jQuery('#jBox-image-' + gallery + '-' + id).addClass('jBox-image-' + gallery + '-current').css({zIndex: this.imageZIndex++, opacity: 0}).animate({opacity: 1}, (img == 'open') ? 0 : this.options.imageFade);
2627
+
2628
+        // Load image
2629
+        } else {
2630
+          loadImage(gallery, id, true, (img === 'open'));
2631
+        }
2632
+
2633
+        // Show label
2634
+        showLabel(gallery, id);
2635
+
2636
+        // Update the image counter numbers
2637
+        if (this.imageCounter) {
2638
+          if (this.images[gallery] && this.images[gallery].length > 1) {
2639
+            this.wrapper.addClass('jBox-image-has-counter');
2640
+            this.imageCounter.find('.jBox-image-counter-all').html(this.images[gallery].length);
2641
+            this.imageCounter.find('.jBox-image-counter-current').html(id + 1);
2642
+          } else {
2643
+            this.wrapper.removeClass('jBox-image-has-counter');
2644
+          }
2645
+        }
2646
+
2647
+        // Preload next image
2648
+        if (this.images[gallery] && this.images[gallery].length - 1) {
2649
+	        var next_id = id + 1;
2650
+	        next_id = next_id > (this.images[gallery].length - 1) ? 0 : (next_id < 0 ? (this.images[gallery].length - 1) : next_id);
2651
+
2652
+	        if (!jQuery('#jBox-image-' + gallery + '-' + next_id).length) {
2653
+            loadImage(gallery, next_id, false, false);
2654
+          }
2655
+	      }
2656
+      };
2657
+
2658
+      // Preload image
2659
+      if (this.options.preloadFirstImage) {
2660
+        jQuery(window).on('load', function() {
2661
+          this.showImage('open');
2662
+        }.bind(this));
2663
+      }
2664
+    },
2665
+
2666
+
2667
+    // Triggered when jBox attaches a new element
2668
+
2669
+    _onAttach: function (item) {
2670
+      this.initImage && this.initImage(item);
2671
+    },
2672
+
2673
+
2674
+    // Triggered when jBox was created
2675
+
2676
+    _onCreated: function ()
2677
+    {
2678
+      // Create image label and navigation buttons
2679
+      this.imageLabelWrapper = jQuery('<div class="jBox-image-label-wrapper"/>').appendTo(this.wrapper);
2680
+
2681
+      this.imagePrevButton = jQuery('<div class="jBox-image-pointer-prev"/>')
2682
+        .on('click tap', function () {
2683
+          this.showImage('prev');
2684
+        }.bind(this));
2685
+
2686
+      this.imageNextButton = jQuery('<div class="jBox-image-pointer-next"/>')
2687
+        .on('click tap', function () {
2688
+          this.showImage('next');
2689
+        }.bind(this));
2690
+
2691
+      this.imageLabelContainer = jQuery('<div class="jBox-image-label-container"/>');
2692
+
2693
+      this.imageLabelWrapper
2694
+        .append(this.imagePrevButton)
2695
+        .append(this.imageLabelContainer)
2696
+        .append(this.imageNextButton);
2697
+
2698
+      // Append the download button
2699
+      if (this.options.downloadButton) {
2700
+        this.downloadButton = jQuery('<div/>', {'class': 'jBox-image-download-button-wrapper'})
2701
+          .appendTo(this.wrapper)
2702
+          .append(
2703
+            this.options.downloadButtonText ? jQuery('<div/>', {'class': 'jBox-image-download-button-text'}).html(this.options.downloadButtonText) : null
2704
+          )
2705
+          .append(
2706
+            jQuery('<div/>', {'class': 'jBox-image-download-button-icon'})
2707
+          ).on('click tap', function () {
2708
+            if (this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl) {
2709
+              var currentImageUrl = this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl;
2710
+            } else {
2711
+              var currentImage = this.wrapper.find('.jBox-image-' + this.currentImage.gallery + '-current');
2712
+              var currentImageStyle = currentImage[0].style.backgroundImage;
2713
+              var currentImageUrl = currentImageStyle.slice(4, -1).replace(/["']/g, '');
2714
+            }
2715
+            this.downloadImage(currentImageUrl);
2716
+          }.bind(this));
2717
+      }
2718
+
2719
+      // Creating the image counter containers
2720
+      if (this.options.imageCounter) {
2721
+        this.imageCounter = jQuery('<div/>', {'class': 'jBox-image-counter-container'}).insertAfter(this.imageLabelContainer);
2722
+        this.imageCounter.append(jQuery('<span/>', {'class': 'jBox-image-counter-current'})).append(jQuery('<span/>').html(this.options.imageCounterSeparator)).append(jQuery('<span/>', {'class': 'jBox-image-counter-all'}));
2723
+      }
2724
+    },
2725
+
2726
+
2727
+    // Triggered when jBox opens
2728
+
2729
+    _onOpen: function ()
2730
+    {
2731
+      // Add key events
2732
+      jQuery(document).on('keyup.jBox-Image-' + this.id, function (ev) {
2733
+        (ev.keyCode == 37) && this.showImage('prev');
2734
+        (ev.keyCode == 39) && this.showImage('next');
2735
+      }.bind(this));
2736
+
2737
+      // Load the image from the attached element
2738
+      this.showImage('open');
2739
+    },
2740
+
2741
+
2742
+    // Triggered when jBox closes
2743
+
2744
+    _onClose: function ()
2745
+    {
2746
+      // Remove key events
2747
+      jQuery(document).off('keyup.jBox-Image-' + this.id);
2748
+    },
2749
+
2750
+
2751
+    // Triggered when jBox finished closing
2752
+
2753
+    _onCloseComplete: function ()
2754
+    {
2755
+      // Hide all image containers
2756
+      this.wrapper.find('.jBox-image-container').css('opacity', 0);
2757
+    }
2758
+
2759
+  });
2760
+
2761
+};
2762
+
2763
+/**
2764
+ * jBox Notice plugin: Opens a popup notice
2765
+ *
2766
+ * Author: Stephan Wagner <stephanwagner.me@gmail.com> (https://stephanwagner.me)
2767
+ *
2768
+ * License: MIT (https://opensource.org/licenses/MIT)
2769
+ *
2770
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
2771
+ */
2772
+
2773
+function jBoxNoticeWrapper(jBox, jQuery) {
2774
+
2775
+  new jBox.plugin('Notice', {
2776
+
2777
+
2778
+    // Options (https://stephanwagner.me/jBox/options#options-notice)
2779
+
2780
+    color: null,      // Add a color to your notices, use 'gray' (default), 'black', 'red', 'green', 'blue' or 'yellow'
2781
+    stack: true,      // Set to false to disable notice-stacking
2782
+    stackSpacing: 10, // Spacing between notices when they stack
2783
+    autoClose: 6000,  // Time in ms after which the notice will disappear
2784
+    attributes: {     // Defines where the notice will pop up
2785
+      x: 'right',     // 'left' or 'right'
2786
+      y: 'top'        // 'top' or 'bottom'
2787
+    },
2788
+    position: {       // Defines the distance to the viewport boundary
2789
+      x: 15,
2790
+      y: 15
2791
+    },
2792
+    responsivePositions: {  // Responsive positions
2793
+      500: {                // The key defines the maximum width of the viewport, the values will replace the default position options
2794
+        x: 5,               // Start with the lowest viewport
2795
+        y: 5
2796
+      },
2797
+      768: {
2798
+        x: 10,
2799
+        y: 10
2800
+      }
2801
+    },
2802
+    target: window,
2803
+    fixed: true,
2804
+    animation: 'zoomIn',
2805
+    closeOnClick: 'box',
2806
+    zIndex: 12000,
2807
+
2808
+
2809
+    // Triggered when notice is initialized
2810
+
2811
+    _onInit: function ()
2812
+    {
2813
+      // Cache position values
2814
+      this.defaultNoticePosition = jQuery.extend({}, this.options.position);
2815
+
2816
+      // Type Notice has its own adjust position function
2817
+      this._adjustNoticePositon = function () {
2818
+        var win = jQuery(window);
2819
+        var windowDimensions = {
2820
+          x: win.width(),
2821
+          y: win.height()
2822
+        };
2823
+
2824
+        // Reset default position
2825
+        this.options.position = jQuery.extend({}, this.defaultNoticePosition);
2826
+
2827
+        // Adjust depending on viewport
2828
+        jQuery.each(this.options.responsivePositions, function (viewport, position) {
2829
+          if (windowDimensions.x <= viewport) {
2830
+            this.options.position = position;
2831
+            return false;
2832
+          }
2833
+        }.bind(this));
2834
+
2835
+        // Set new padding options
2836
+        this.options.adjustDistance = {
2837
+          top: this.options.position.y,
2838
+          right: this.options.position.x,
2839
+          bottom: this.options.position.y,
2840
+          left: this.options.position.x
2841
+        };
2842
+      };
2843
+
2844
+      // If jBox grabs an element as content, crab a clone instead
2845
+      this.options.content instanceof jQuery && (this.options.content = this.options.content.clone().attr('id', ''));
2846
+
2847
+      // Adjust paddings when window resizes
2848
+      jQuery(window).on('resize.responsivejBoxNotice-' + this.id, function (ev) { if (this.isOpen) { this._adjustNoticePositon(); } }.bind(this));
2849
+
2850
+      this.open();
2851
+    },
2852
+
2853
+
2854
+    // Triggered when notice was created
2855
+
2856
+    _onCreated: function ()
2857
+    {
2858
+      // Add color class
2859
+      this.wrapper.addClass('jBox-Notice-color jBox-Notice-' + (this.options.color || 'gray'));
2860
+
2861
+      // Store position in jBox wrapper
2862
+      this.wrapper.data('jBox-Notice-position', this.options.attributes.x + '-' + this.options.attributes.y);
2863
+    },
2864
+
2865
+
2866
+    // Triggered when notice opens
2867
+
2868
+    _onOpen: function ()
2869
+    {
2870
+      // Bail if we're stacking
2871
+      if (this.options.stack) {
2872
+          return;
2873
+      }
2874
+
2875
+      // Adjust position when opening
2876
+      this._adjustNoticePositon();
2877
+
2878
+      // Loop through notices at same window corner destroy them
2879
+      jQuery.each(jQuery('.jBox-Notice'), function (index, el)
2880
+      {
2881
+        el = jQuery(el);
2882
+
2883
+        // Abort if the element is this notice or when it's not at the same position
2884
+        if (el.attr('id') == this.id || el.data('jBox-Notice-position') != this.options.attributes.x + '-' + this.options.attributes.y) {
2885
+          return;
2886
+        }
2887
+
2888
+        // Remove notice when we don't wont to stack them
2889
+        if (!this.options.stack) {
2890
+          el.data('jBox').close({ignoreDelay: true});
2891
+          return;
2892
+        }
2893
+      }.bind(this));
2894
+    },
2895
+
2896
+    // Triggered when resizing window etc.
2897
+
2898
+    _onPosition: function ()
2899
+    {
2900
+        var stacks = {};
2901
+        jQuery.each(jQuery('.jBox-Notice'), function (index, el)
2902
+        {
2903
+          el = jQuery(el);
2904
+          var pos = el.data('jBox-Notice-position');
2905
+          if (!stacks[pos]) {
2906
+              stacks[pos] = [];
2907
+          }
2908
+          stacks[pos].push(el);
2909
+        });
2910
+        for (var pos in stacks) {
2911
+            var position = pos.split('-');
2912
+            var direction = position[1];
2913
+            stacks[pos].reverse();
2914
+            var margin = 0;
2915
+            for (var i in stacks[pos]) {
2916
+                var el = jQuery(stacks[pos][i]);
2917
+                el.css('margin-' + direction, margin);
2918
+                margin += el.outerHeight() + this.options.stackSpacing;
2919
+            }
2920
+        }
2921
+    },
2922
+
2923
+    // Remove notice from DOM and reposition other notices when closing finishes
2924
+
2925
+    _onCloseComplete: function ()
2926
+    {
2927
+        this.destroy();
2928
+        this.options._onPosition.bind(this).call();
2929
+    }
2930
+
2931
+  });
2932
+
2933
+};
2934
+
2935
+(function (root, factory) {
2936
+  if (typeof define === 'function' && define.amd) {
2937
+    define(['jquery'], function (jQuery) {
2938
+      return (root.jBox = factory(jQuery));
2939
+    });
2940
+  } else if (typeof module === 'object' && module.exports) {
2941
+    module.exports = (root.jBox = factory(require('jquery')));
2942
+  } else {
2943
+    root.jBox = factory(root.jQuery);
2944
+  }
2945
+}(this, function (jQuery) {
2946
+  var jBox = jBoxWrapper(jQuery);
2947
+  try { typeof jBoxConfirmWrapper !== 'undefined' && jBoxConfirmWrapper && jBoxConfirmWrapper(jBox, jQuery); } catch(e) { console.error(e); }
2948
+  try { typeof jBoxImageWrapper !== 'undefined' && jBoxImageWrapper && jBoxImageWrapper(jBox, jQuery); } catch(e) { console.error(e); }
2949
+  try { typeof jBoxNoticeWrapper !== 'undefined' && jBoxNoticeWrapper && jBoxNoticeWrapper(jBox, jQuery); } catch(e) { console.error(e); }
2950
+  return jBox;
2951
+}));
2952
+
2953
+//# sourceMappingURL=jBox.all.js.map
0 2954
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-wrapper{text-align:left;box-sizing:border-box}.jBox-container,.jBox-content,.jBox-title{position:relative;word-break:break-word;box-sizing:border-box}.jBox-container{background:#fff}.jBox-content{padding:8px 12px;overflow-x:hidden;overflow-y:auto;transition:opacity .2s}.jBox-footer{box-sizing:border-box}.jBox-Mouse .jBox-container,.jBox-Tooltip .jBox-container{border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.25)}.jBox-Mouse .jBox-title,.jBox-Tooltip .jBox-title{padding:8px 10px 0;font-weight:700}.jBox-Mouse.jBox-hasTitle .jBox-content,.jBox-Tooltip.jBox-hasTitle .jBox-content{padding-top:5px}.jBox-Mouse{pointer-events:none}.jBox-pointer{position:absolute;overflow:hidden;box-sizing:border-box}.jBox-pointer:after{content:'';width:20px;height:20px;position:absolute;background:#fff;transform:rotate(45deg);box-sizing:border-box}.jBox-pointer-top{top:0}.jBox-pointer-top:after{left:5px;top:6px;box-shadow:-1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-right{right:0}.jBox-pointer-right:after{top:5px;right:6px;box-shadow:1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-left{left:0}.jBox-pointer-left:after{top:5px;left:6px;box-shadow:-1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom{bottom:0}.jBox-pointer-bottom:after{left:5px;bottom:6px;box-shadow:1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom,.jBox-pointer-top{width:30px;height:12px}.jBox-pointer-left,.jBox-pointer-right{width:12px;height:30px}.jBox-Modal .jBox-container{border-radius:4px}.jBox-Modal .jBox-container,.jBox-Modal.jBox-closeButton-box:before{box-shadow:0 3px 15px rgba(0,0,0,.4),0 0 5px rgba(0,0,0,.4)}.jBox-Modal .jBox-content{padding:15px 20px}.jBox-Modal .jBox-title{border-radius:4px 4px 0 0;padding:15px 20px;background:#fafafa;border-bottom:1px solid #eee}.jBox-Modal.jBox-closeButton-title .jBox-title{padding-right:65px}.jBox-Modal .jBox-footer{border-radius:0 0 4px 4px}.jBox-closeButton{z-index:1;cursor:pointer;position:absolute;box-sizing:border-box}.jBox-closeButton svg{position:absolute;top:50%;right:50%}.jBox-closeButton path{fill:#aaa;transition:fill .2s}.jBox-closeButton:hover path{fill:#888}.jBox-overlay .jBox-closeButton{top:0;right:0;width:40px;height:40px}.jBox-overlay .jBox-closeButton svg{width:20px;height:20px;margin-top:-10px;margin-right:-10px}.jBox-overlay .jBox-closeButton path{fill:#ddd}.jBox-overlay .jBox-closeButton:hover path{fill:#fff}.jBox-closeButton-title .jBox-closeButton{top:0;right:0;bottom:0;width:50px}.jBox-closeButton-title svg{width:12px;height:12px;margin-top:-6px;margin-right:-6px}.jBox-closeButton-box{box-sizing:border-box}.jBox-closeButton-box .jBox-closeButton{top:-8px;right:-10px;width:24px;height:24px;background:#fff;border-radius:50%}.jBox-closeButton-box .jBox-closeButton svg{width:10px;height:10px;margin-top:-5px;margin-right:-5px}.jBox-closeButton-box:before{content:'';position:absolute;top:-8px;right:-10px;width:24px;height:24px;border-radius:50%;box-shadow:0 0 5px rgba(0,0,0,.3)}.jBox-closeButton-box.jBox-pointerPosition-top:before{top:5px}.jBox-closeButton-box.jBox-pointerPosition-right:before{right:2px}.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton{background:#fafafa}.jBox-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.82)}.jBox-footer{background:#fafafa;border-top:1px solid #eee;padding:8px 10px;border-radius:0 0 3px 3px}body[class*=" jBox-blockScroll-"],body[class^=jBox-blockScroll-]{overflow:hidden}.jBox-draggable{cursor:move}@keyframes jBoxLoading{to{transform:rotate(360deg)}}.jBox-loading .jBox-content{opacity:.2}.jBox-loading-spinner .jBox-content{min-height:38px!important;min-width:38px!important;opacity:0}.jBox-spinner{box-sizing:border-box;position:absolute;top:50%;left:50%;width:24px;height:24px;margin-top:-12px;margin-left:-12px}.jBox-spinner:before{display:block;box-sizing:border-box;content:'';width:24px;height:24px;border-radius:50%;border:2px solid rgba(0,0,0,.2);border-top-color:rgba(0,0,0,.8);animation:jBoxLoading .6s linear infinite}.jBox-countdown{border-radius:4px 4px 0 0;z-index:0;background:#000;opacity:.2;position:absolute;top:0;left:0;right:0;height:3px;overflow:hidden}.jBox-countdown-inner{top:0;right:0;width:100%;height:3px;position:absolute;background:#fff}[class*=" jBox-animated-"],[class^=jBox-animated-]{animation-fill-mode:both}@keyframes jBox-tada{0%{transform:scale(1)}10%,20%{transform:scale(.8) rotate(-4deg)}30%,50%,70%,90%{transform:scale(1.2) rotate(4deg)}40%,60%,80%{transform:scale(1.2) rotate(-4deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tada{animation:jBox-tada 1s}@keyframes jBox-tadaSmall{0%{transform:scale(1)}10%,20%{transform:scale(.9) rotate(-2deg)}30%,50%,70%,90%{transform:scale(1.1) rotate(2deg)}40%,60%,80%{transform:scale(1.1) rotate(-2deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tadaSmall{animation:jBox-tadaSmall 1s}@keyframes jBox-flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.jBox-animated-flash{animation:jBox-flash .5s}@keyframes jBox-shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-6px)}40%,80%{transform:translateX(6px)}}.jBox-animated-shake{animation:jBox-shake .4s}@keyframes jBox-pulseUp{0%{transform:scale(1)}50%{transform:scale(1.15)}100%{transform:scale(1)}}.jBox-animated-pulseUp{animation:jBox-pulseUp .25s}@keyframes jBox-pulseDown{0%{transform:scale(1)}50%{transform:scale(.85)}100%{transform:scale(1)}}.jBox-animated-pulseDown{animation:jBox-pulseDown .25s}@keyframes jBox-popIn{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.jBox-animated-popIn{animation:jBox-popIn .25s}@keyframes jBox-popOut{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(0)}}.jBox-animated-popOut{animation:jBox-popOut .25s}@keyframes jBox-fadeIn{0%{opacity:0}100%{opacity:1}}.jBox-animated-fadeIn{animation:jBox-fadeIn .2s}@keyframes jBox-fadeOut{0%{opacity:1}100%{opacity:0}}.jBox-animated-fadeOut{animation:jBox-fadeOut .2s}@keyframes jBox-slideUp{0%{transform:translateY(0)}100%{transform:translateY(-300px);opacity:0}}.jBox-animated-slideUp{animation:jBox-slideUp .4s}@keyframes jBox-slideRight{0%{transform:translateX(0)}100%{transform:translateX(300px);opacity:0}}.jBox-animated-slideRight{animation:jBox-slideRight .4s}@keyframes jBox-slideDown{0%{transform:translateY(0)}100%{transform:translateY(300px);opacity:0}}.jBox-animated-slideDown{animation:jBox-slideDown .4s}@keyframes jBox-slideLeft{0%{transform:translateX(0)}100%{transform:translateX(-300px);opacity:0}}.jBox-animated-slideLeft{animation:jBox-slideLeft .4s}.jBox-Confirm .jBox-content{text-align:center;padding:46px 35px}@media (max-width:500px){.jBox-Confirm .jBox-content{padding:32px 20px}}.jBox-Confirm-footer{height:46px}.jBox-Confirm-button{display:block;float:left;cursor:pointer;text-align:center;width:50%;line-height:46px;height:46px;overflow:hidden;padding:0 10px;transition:color .2s,background-color .2s;box-sizing:border-box}.jBox-Confirm-button-cancel{border-bottom-left-radius:4px;background:#ddd;color:#666}.jBox-Confirm-button-cancel:active,.jBox-Confirm-button-cancel:hover{background:#ccc}.jBox-Confirm-button-cancel:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}.jBox-Confirm-button-submit{border-bottom-right-radius:4px;background:#7d0;color:#fff}.jBox-Confirm-button-submit:active,.jBox-Confirm-button-submit:hover{background:#6c0}.jBox-Confirm-button-submit:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}.jBox-Image .jBox-container{background-color:transparent}.jBox-Image .jBox-content{padding:0;width:100%;height:100%}.jBox-image-container{background:center center no-repeat;position:absolute;width:100%;height:100%;opacity:0}.jBox-image-label-wrapper{position:absolute;top:100%;left:0;right:0;height:40px;z-index:100;display:flex}.jBox-image-label-container{position:relative;flex:1}.jBox-image-label{box-sizing:border-box;position:absolute;left:0;bottom:0;width:100%;text-align:center;color:#fff;padding:8px 12px;font-size:15px;line-height:24px;transition:opacity .36s;opacity:0;z-index:0;pointer-events:none}.jBox-image-label.expanded{background:#000}.jBox-image-label:not(.expanded){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.jBox-image-label.active{opacity:1;pointer-events:all}@media (max-width:600px){.jBox-image-label{font-size:13px}}.jBox-image-pointer-next,.jBox-image-pointer-prev{flex-shrink:0;width:40px;height:40px;cursor:pointer;opacity:.8;transition:opacity .2s;background:no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);background-size:11px auto;user-select:none;z-index:1}.jBox-image-pointer-next:hover,.jBox-image-pointer-prev:hover{opacity:1}.jBox-image-pointer-next{transform:scaleX(-1)}.jBox-image-counter-container{flex-shrink:0;white-space:nowrap;height:40px;line-height:40px;font-size:13px;color:#fff;text-align:right;display:none}.jBox-image-has-counter .jBox-image-counter-container{display:block}.jBox-overlay.jBox-overlay-Image{background:#000}.jBox-image-not-found{background:#000}.jBox-image-not-found:before{content:'';box-sizing:border-box;display:block;width:80px;height:80px;margin-top:-40px;margin-left:-40px;position:absolute;top:50%;left:50%;border:5px solid #222;border-radius:50%}.jBox-image-not-found:after{content:'';display:block;box-sizing:content-box;z-index:auto;width:6px;height:74px;margin-top:-37px;margin-left:-3px;position:absolute;top:50%;left:50%;background:#222;transform:rotateZ(45deg);transform-origin:50% 50% 0}.jBox-image-download-button-wrapper{position:absolute;top:-40px;right:35px;height:40px;display:flex;cursor:pointer;opacity:.8;transition:opacity .2s}.jBox-image-download-button-wrapper:hover{opacity:1}.jBox-image-download-button-icon{width:40px;height:40px;background:center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);background-size:60%}.jBox-image-download-button-text{white-space:nowrap;line-height:40px;padding:0 10px 0 0;color:#fff;font-size:14px}@keyframes jBoxImageLoading{to{transform:rotate(360deg)}}.jBox-image-loading:before{content:'';position:absolute;top:50%;left:50%;width:32px;height:32px;margin-top:-16px;margin-left:-16px;border:4px solid #333;border-bottom-color:#666;animation:jBoxImageLoading 1.2s linear infinite;border-radius:50%}.jBox-Notice{transition:margin .2s}.jBox-Notice .jBox-container{border-radius:4px;box-shadow:inset 1px 1px 0 0 rgba(255,255,255,.25),inset -1px -1px 0 0 rgba(0,0,0,.1)}.jBox-Notice .jBox-content{border-radius:4px;padding:12px 20px}@media (max-width:768px){.jBox-Notice .jBox-content{padding:10px 15px}}@media (max-width:500px){.jBox-Notice .jBox-content{padding:8px 10px}}.jBox-Notice.jBox-hasTitle .jBox-content{padding-top:5px}@media (max-width:500px){.jBox-Notice.jBox-hasTitle .jBox-content{padding-top:0}}.jBox-Notice.jBox-hasTitle .jBox-title{padding:12px 20px 0;font-weight:700}@media (max-width:768px){.jBox-Notice.jBox-hasTitle .jBox-title{padding:10px 15px 0}}@media (max-width:500px){.jBox-Notice.jBox-hasTitle .jBox-title{padding:8px 10px 0}}.jBox-Notice.jBox-closeButton-title .jBox-title{padding-right:55px}.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton{width:40px}.jBox-Notice.jBox-Notice-black .jBox-container{color:#fff;background:#000}.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-gray .jBox-container{color:#222;background:#f6f6f6}.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#222}.jBox-Notice.jBox-Notice-red .jBox-container{color:#fff;background:#d00}.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-green .jBox-container{color:#fff;background:#5d0}.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-blue .jBox-container{color:#fff;background:#49d}.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-yellow .jBox-container{color:#000;background:#fd0}.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-NoticeFancy .jBox-content,.jBox-NoticeFancy .jBox-title{padding-left:25px}.jBox-NoticeFancy.jBox-Notice-color .jBox-container{color:#fff;background:#000}.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after{content:'';position:absolute;top:0;left:0;bottom:0;width:8px;border-radius:4px 0 0 4px;background-image:linear-gradient(45deg,rgba(255,255,255,.4) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.4) 75%,transparent 75%,transparent);background-size:14px 14px}.jBox-NoticeFancy.jBox-Notice-black .jBox-container:after,.jBox-NoticeFancy.jBox-Notice-gray .jBox-container:after{background-color:#888}.jBox-NoticeFancy.jBox-Notice-red .jBox-container:after{background-color:#e00}.jBox-NoticeFancy.jBox-Notice-green .jBox-container:after{background-color:#6c0}.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after{background-color:#49d}.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after{background-color:#fb0}.jBox-NoticeFancy .jBox-countdown{left:8px;border-radius:0 4px 0 0}.jBox-TooltipBorder .jBox-container,.jBox-TooltipBorder .jBox-pointer:after{border:2px solid #49d}.jBox-TooltipBorder .jBox-pointer:after{width:22px;height:22px}.jBox-TooltipBorder .jBox-pointer-bottom,.jBox-TooltipBorder .jBox-pointer-top{width:34px;height:13px}.jBox-TooltipBorder .jBox-pointer-bottom:after,.jBox-TooltipBorder .jBox-pointer-top:after{left:6px}.jBox-TooltipBorder .jBox-pointer-left,.jBox-TooltipBorder .jBox-pointer-right{width:13px;height:34px}.jBox-TooltipBorder .jBox-pointer-left:after,.jBox-TooltipBorder .jBox-pointer-right:after{top:6px}.jBox-TooltipBorder.jBox-closeButton-box:before{width:28px;height:28px;background:#49d}.jBox-TooltipBorderThick .jBox-container{box-shadow:none;border-radius:8px;border:4px solid #ccc}.jBox-TooltipBorderThick .jBox-pointer:after{box-shadow:none;border:4px solid #ccc;width:24px;height:24px}.jBox-TooltipBorderThick .jBox-pointer-bottom,.jBox-TooltipBorderThick .jBox-pointer-top{width:38px;height:13px}.jBox-TooltipBorderThick .jBox-pointer-left,.jBox-TooltipBorderThick .jBox-pointer-right{width:13px;height:38px}.jBox-TooltipBorderThick.jBox-closeButton-box:before{width:32px;height:32px;background:#ccc}.jBox-TooltipDark .jBox-container{border-radius:4px;background:#000;color:#fff;box-shadow:0 0 6px rgba(0,0,0,.4)}.jBox-TooltipDark .jBox-pointer:after{background:#000}.jBox-TooltipDark .jBox-closeButton{background:#000}.jBox-TooltipDark.jBox-closeButton-box:before{box-shadow:0 0 6px rgba(0,0,0,.4)}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path{fill:#ddd}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path{fill:#fff}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path{fill:#bbb}.jBox-TooltipError{pointer-events:none}.jBox-TooltipError .jBox-container{border-radius:2px;background:#d00;color:#fff;font-weight:700;font-size:13px}.jBox-TooltipError .jBox-content{padding:0 10px;line-height:28px}.jBox-TooltipError .jBox-pointer:after{background:#d00;width:20px;height:20px}.jBox-TooltipError .jBox-pointer-bottom,.jBox-TooltipError .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipError .jBox-pointer-left,.jBox-TooltipError .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipError .jBox-pointer-top:after{left:1px;top:6px}.jBox-TooltipError .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipError .jBox-pointer-bottom:after{left:1px;bottom:6px}.jBox-TooltipError .jBox-pointer-left:after{top:1px;left:6px}.jBox-TooltipSmall{pointer-events:none}.jBox-TooltipSmall .jBox-container{border-radius:2px}.jBox-TooltipSmall .jBox-content{padding:0 10px;line-height:28px}.jBox-TooltipSmall .jBox-pointer:after{width:20px;height:20px}.jBox-TooltipSmall .jBox-pointer-bottom,.jBox-TooltipSmall .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipSmall .jBox-pointer-left,.jBox-TooltipSmall .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipSmall .jBox-pointer-top:after{left:1px;top:6px}.jBox-TooltipSmall .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipSmall .jBox-pointer-bottom:after{left:1px;bottom:6px}.jBox-TooltipSmall .jBox-pointer-left:after{top:1px;left:6px}.jBox-TooltipSmallGray{pointer-events:none}.jBox-TooltipSmallGray .jBox-container{font-size:13px;line-height:24px;border-radius:12px;background-image:linear-gradient(to bottom,#fafafa,#f2f2f2)}.jBox-TooltipSmallGray .jBox-content{padding:0 10px}.jBox-TooltipSmallGray .jBox-pointer:after{width:20px;height:20px}.jBox-TooltipSmallGray .jBox-pointer-bottom,.jBox-TooltipSmallGray .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipSmallGray .jBox-pointer-left,.jBox-TooltipSmallGray .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipSmallGray .jBox-pointer-top:after{background:#fafafa;left:1px;top:6px}.jBox-TooltipSmallGray .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipSmallGray .jBox-pointer-bottom:after{background:#f2f2f2;left:1px;bottom:6px}.jBox-TooltipSmallGray .jBox-pointer-left:after{top:1px;left:6px}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+function jBoxWrapper(j){function h(t,i){return this.options={id:null,width:"auto",height:"auto",minWidth:null,minHeight:null,maxWidth:null,maxHeight:null,responsiveWidth:!0,responsiveHeight:!0,responsiveMinWidth:100,responsiveMinHeight:100,attach:null,trigger:"click",preventDefault:!1,content:null,getContent:null,title:null,getTitle:null,footer:null,isolateScroll:!0,ajax:{url:null,data:"",reload:!1,getURL:"data-url",getData:"data-ajax",setContent:!0,loadingClass:!0,spinner:!0,spinnerDelay:300,spinnerReposition:!0},cancelAjaxOnClose:!0,target:null,position:{x:"center",y:"center"},outside:null,offset:0,attributes:{x:"left",y:"top"},fixed:!1,adjustPosition:!0,adjustTracker:!1,adjustDistance:5,reposition:!0,repositionOnOpen:!0,repositionOnContent:!0,holdPosition:!0,pointer:!1,pointTo:"target",fade:180,animation:null,theme:"Default",addClass:null,overlay:!1,overlayClass:null,zIndex:1e4,delayOpen:0,delayClose:0,closeOnEsc:!1,closeOnClick:!1,closeOnMouseleave:!1,closeButton:!1,appendTo:j("body"),createOnInit:!1,blockScroll:!1,blockScrollAdjust:!0,draggable:!1,dragOver:!0,autoClose:!1,delayOnHover:!1,showCountdown:!1,preloadAudio:!0,audio:null,volume:100,onInit:null,onAttach:null,onPosition:null,onCreated:null,onOpen:null,onOpenComplete:null,onClose:null,onCloseComplete:null,onDragStart:null,onDragEnd:null},this._pluginOptions={Tooltip:{getContent:"title",trigger:"mouseenter",position:{x:"center",y:"top"},outside:"y",pointer:!0},Mouse:{responsiveWidth:!1,responsiveHeight:!1,adjustPosition:"flip",target:"mouse",trigger:"mouseenter",position:{x:"right",y:"bottom"},outside:"xy",offset:5},Modal:{target:j(window),fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"overlay",closeButton:!0,overlay:!0,animation:"zoomIn"}},this.options=j.extend(!0,this.options,this._pluginOptions[t]||h._pluginOptions[t],i),"string"==j.type(t)&&(this.type=t),this.isTouchDevice=function(){var t=" -webkit- -moz- -o- -ms- ".split(" ");if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)return!0;var i,t=["(",t.join("touch-enabled),("),"heartz",")"].join("");return i=t,window.matchMedia(i).matches}(),this.isTouchDevice&&"mouseenter"===this.options.trigger&&!1===this.options.closeOnClick&&(this.options.closeOnClick="body"),this._fireEvent=function(t,i){this.options["_"+t]&&this.options["_"+t].bind(this)(i),this.options[t]&&this.options[t].bind(this)(i)},null===this.options.id&&(this.options.id="jBox"+h._getUniqueID()),this.id=this.options.id,("center"==this.options.position.x&&"x"==this.options.outside||"center"==this.options.position.y&&"y"==this.options.outside)&&(this.options.outside=null),"target"!=this.options.pointTo||this.options.outside&&"xy"!=this.options.outside||(this.options.pointer=!1),"object"!=j.type(this.options.offset)?this.options.offset={x:this.options.offset,y:this.options.offset}:this.options.offset=j.extend({x:0,y:0},this.options.offset),"object"!=j.type(this.options.adjustDistance)?this.options.adjustDistance={top:this.options.adjustDistance,right:this.options.adjustDistance,bottom:this.options.adjustDistance,left:this.options.adjustDistance}:this.options.adjustDistance=j.extend({top:5,left:5,right:5,bottom:5},this.options.adjustDistance),this.outside=!(!this.options.outside||"xy"==this.options.outside)&&this.options.position[this.options.outside],this.align=this.outside||("center"!=this.options.position.y&&"number"!=j.type(this.options.position.y)?this.options.position.x:"center"!=this.options.position.x&&"number"!=j.type(this.options.position.x)?this.options.position.y:this.options.attributes.x),h.zIndexMax=Math.max(h.zIndexMax||0,"auto"===this.options.zIndex?1e4:this.options.zIndex),"auto"===this.options.zIndex&&(this.adjustZIndexOnOpen=!0,this.options.zIndex=h.zIndexMax+=2,this.trueModal=this.options.overlay),this._getOpp=function(t){return{left:"right",right:"left",top:"bottom",bottom:"top",x:"y",y:"x"}[t]},this._getXY=function(t){return{left:"x",right:"x",top:"y",bottom:"y",center:"x"}[t]},this._getTL=function(t){return{left:"left",right:"left",top:"top",bottom:"top",center:"left",x:"left",y:"top"}[t]},this._getInt=function(t,i){return"auto"==t?"auto":t&&"string"==j.type(t)&&"%"==t.slice(-1)?j(window)["height"==i?"innerHeight":"innerWidth"]()*parseInt(t.replace("%",""))/100:t},this._createSVG=function(t,i){var o=document.createElementNS("http://www.w3.org/2000/svg",t);return j.each(i,function(t,i){o.setAttribute(i[0],i[1]||"")}),o},this._isolateScroll=function(e){e&&e.length&&e.on("DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll",function(t){var i=t.wheelDelta||t.originalEvent&&t.originalEvent.wheelDelta||-t.detail,o=0<=this.scrollTop+e.outerHeight()-this.scrollHeight,s=this.scrollTop<=0;(i<0&&o||0<i&&s)&&t.preventDefault()})},this._setTitleWidth=function(){if(!this.titleContainer||"auto"==this.content[0].style.width&&!this.content[0].style.maxWidth)return null;var t;"none"==this.wrapper.css("display")?(this.wrapper.css("display","block"),t=this.content.outerWidth(),this.wrapper.css("display","none")):t=this.content.outerWidth(),this.titleContainer.css({maxWidth:Math.max(t,parseInt(this.content[0].style.maxWidth))||null})},this._draggable=function(){if(!this.options.draggable)return!1;var t="title"==this.options.draggable?this.titleContainer:this.options.draggable instanceof j?this.options.draggable:"string"==j.type(this.options.draggable)?j(this.options.draggable):this.wrapper;return!(!(t&&t instanceof j&&t.length)||t.data("jBox-draggable"))&&(t.addClass("jBox-draggable").data("jBox-draggable",!0).on("touchstart mousedown",function(t){var i,o,s,e,n,a;2==t.button||j(t.target).hasClass("jBox-noDrag")||j(t.target).parents(".jBox-noDrag").length?"touchstart"==t.type&&(j(t.target).hasClass("jBox-closeButton")||j(t.target).parents(".jBox-closeButton").length)&&this.close({ignoreDelay:!0}):(o="touchstart"==t.type&&t.touches&&t.touches[0]?(i=t.touches[0].pageX,t.touches[0].pageY):(i=t.pageX,t.pageY),this.draggingStartX=i,this.draggingStartY=o,this.options.dragOver&&!this.trueModal&&parseInt(this.wrapper.css("zIndex"),10)<=h.zIndexMaxDragover&&(h.zIndexMaxDragover+=1,this.wrapper.css("zIndex",h.zIndexMaxDragover)),s=this.wrapper.outerHeight(),e=this.wrapper.outerWidth(),n=this.wrapper.offset().top+s-o,a=this.wrapper.offset().left+e-i,j(document).on("touchmove.jBox-draggable-"+this.id+" mousemove.jBox-draggable-"+this.id,function(t){var i,t="touchmove"==t.type&&t.touches&&t.touches[0]?(i=t.touches[0].pageX,t.touches[0].pageY):(i=t.pageX,t.pageY);this.dragging||this.draggingStartX==i||this.draggingStartY==t||(this._fireEvent("onDragStart"),this.dragging=!0),this.wrapper.offset({top:t+n-s,left:i+a-e})}.bind(this)),t.preventDefault())}.bind(this)).on("touchend mouseup",function(){var t;j(document).off("touchmove.jBox-draggable-"+this.id+" mousemove.jBox-draggable-"+this.id),this.dragging&&this._fireEvent("onDragEnd"),this.dragging=!1,"Modal"!=this.type&&"Confirm"!=this.type||!this.options.holdPosition||(t={x:(t=j("#"+this.id).offset()).left-j(document).scrollLeft(),y:t.top-j(document).scrollTop()},this.position({position:t,offset:{x:0,y:0}}))}.bind(this)),this.trueModal||(h.zIndexMaxDragover=h.zIndexMaxDragover?Math.max(h.zIndexMaxDragover,this.options.zIndex):this.options.zIndex),this)},this._create=function(){var t;this.wrapper||(this.wrapper=j("<div/>",{id:this.id,class:"jBox-wrapper"+(this.type?" jBox-"+this.type:"")+(this.options.theme?" jBox-"+this.options.theme:"")+(this.options.addClass?" "+this.options.addClass:"")}).css({position:this.options.fixed?"fixed":"absolute",display:"none",opacity:0,zIndex:this.options.zIndex}).data("jBox",this),this.options.closeOnMouseleave&&this.wrapper.on("mouseleave",function(t){!this.source||t.relatedTarget!=this.source[0]&&-1===j.inArray(this.source[0],j(t.relatedTarget).parents("*"))&&this.close()}.bind(this)),"box"==this.options.closeOnClick&&this.wrapper.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),this.container=j('<div class="jBox-container"/>').appendTo(this.wrapper),this.content=j('<div class="jBox-content"/>').appendTo(this.container),this.options.footer&&(this.footer=j('<div class="jBox-footer"/>').append(this.options.footer).appendTo(this.container)),this.options.isolateScroll&&this._isolateScroll(this.content),this.options.closeButton&&((t=this._createSVG("svg",[["viewBox","0 0 24 24"]])).appendChild(this._createSVG("path",[["d","M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z"]])),this.closeButton=j('<div class="jBox-closeButton jBox-noDrag"/>').on("click tap",function(t){this.close({ignoreDelay:!0})}.bind(this)).append(t),"box"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay||this.options.title||this.options.getTitle)||(this.wrapper.addClass("jBox-closeButton-box"),this.closeButton.appendTo(this.container))),this.wrapper.appendTo(this.options.appendTo),this.wrapper.find(".jBox-closeButton").length&&j.each(["top","right","bottom","left"],function(t,i){this.wrapper.find(".jBox-closeButton").css(i)&&"auto"!=this.wrapper.find(".jBox-closeButton").css(i)&&(this.options.adjustDistance[i]=Math.max(this.options.adjustDistance[i],this.options.adjustDistance[i]+-1*((parseInt(this.wrapper.find(".jBox-closeButton").css(i))||0)+(parseInt(this.container.css("border-"+i+"-width"))||0))))}.bind(this)),this.options.pointer&&(this.pointer={position:"target"!=this.options.pointTo?this.options.pointTo:this._getOpp(this.outside),xy:"target"!=this.options.pointTo?this._getXY(this.options.pointTo):this._getXY(this.outside),align:"center",offset:0},this.pointer.element=j('<div class="jBox-pointer jBox-pointer-'+this.pointer.position+'"/>').appendTo(this.wrapper),this.pointer.dimensions={x:this.pointer.element.outerWidth(),y:this.pointer.element.outerHeight()},"string"==j.type(this.options.pointer)&&((t=this.options.pointer.split(":"))[0]&&(this.pointer.align=t[0]),t[1]&&(this.pointer.offset=parseInt(t[1]))),this.pointer.alignAttribute="x"==this.pointer.xy?"bottom"==this.pointer.align?"bottom":"top":"right"==this.pointer.align?"right":"left",this.wrapper.css("padding-"+this.pointer.position,this.pointer.dimensions[this.pointer.xy]),this.pointer.element.css(this.pointer.alignAttribute,"center"==this.pointer.align?"50%":0).css("margin-"+this.pointer.alignAttribute,this.pointer.offset),this.pointer.margin={},this.pointer.margin["margin-"+this.pointer.alignAttribute]=this.pointer.offset,"center"==this.pointer.align&&this.pointer.element.css("transform","translate("+("y"==this.pointer.xy?-.5*this.pointer.dimensions.x+"px":0)+", "+("x"==this.pointer.xy?-.5*this.pointer.dimensions.y+"px":0)+")"),this.pointer.element.css("x"==this.pointer.xy?"width":"height",parseInt(this.pointer.dimensions[this.pointer.xy])+parseInt(this.container.css("border-"+this.pointer.alignAttribute+"-width"))),this.wrapper.addClass("jBox-pointerPosition-"+this.pointer.position)),this.setContent(this.options.content,!0),this.setTitle(this.options.title,!0),this.options.draggable&&this._draggable(),this._fireEvent("onCreated"))},this.options.createOnInit&&this._create(),this.options.attach&&this.attach(),this._attachEvents=function(){this.options.delayOnHover&&j("#"+this.id).on("mouseenter",function(t){this.isHovered=!0}.bind(this)),this.options.delayOnHover&&j("#"+this.id).on("mouseleave",function(t){this.isHovered=!1}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&!this.fixed&&this.outside&&(this.options.adjustTracker&&j(window).on("scroll.jBox-"+this.id,function(t){this.position()}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&j(window).on("resize.jBox-"+this.id,function(t){this.position()}.bind(this))),"mouse"==this.options.target&&j("body").on("mousemove.jBox-"+this.id,function(t){this.position({mouseTarget:{top:t.pageY,left:t.pageX}})}.bind(this))},this._detachEvents=function(){this.options.closeOnEsc&&j(document).off("keyup.jBox-"+this.id),!0!==this.options.closeOnClick&&"body"!=this.options.closeOnClick||j(document).off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.options.adjustTracker&&j(window).off("scroll.jBox-"+this.id),(this.options.adjustPosition||this.options.reposition)&&j(window).off("resize.jBox-"+this.id),"mouse"==this.options.target&&j("body").off("mousemove.jBox-"+this.id)},this._showOverlay=function(){this.overlay||(this.overlay=j('<div id="'+this.id+'-overlay"/>').addClass("jBox-overlay"+(this.type?" jBox-overlay-"+this.type:"")).css({display:"none",opacity:0,zIndex:this.options.zIndex-1}).appendTo(this.options.appendTo),this.options.overlayClass&&this.overlay.addClass(this.options.overlayClass),"overlay"!=this.options.closeButton&&!0!==this.options.closeButton||this.overlay.append(this.closeButton),"overlay"==this.options.closeOnClick&&this.overlay.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),j("#"+this.id+"-overlay .jBox-closeButton").length&&(this.options.adjustDistance.top=Math.max(j("#"+this.id+"-overlay .jBox-closeButton").outerHeight(),this.options.adjustDistance.top))),!0===this.adjustZIndexOnOpen&&this.overlay.css("zIndex",parseInt(this.wrapper.css("zIndex"),10)-1),"block"!=this.overlay.css("display")&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.overlay.css({display:"block"})}.bind(this)}):this.overlay.css({display:"block",opacity:1}))},this._hideOverlay=function(){this.overlay&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:0},{queue:!1,duration:this.options.fade,complete:function(){this.overlay.css({display:"none"})}.bind(this)}):this.overlay.css({display:"none",opacity:0}))},this._exposeDimensions=function(){this.wrapper.css({top:-1e4,left:-1e4,right:"auto",bottom:"auto"});var t={x:this.wrapper.outerWidth(),y:this.wrapper.outerHeight()};return this.wrapper.css({top:"auto",left:"auto"}),t},this._generateAnimationCSS=function(){if("object"!=j.type(this.options.animation)&&(this.options.animation={pulse:{open:"pulse",close:"zoomOut"},zoomIn:{open:"zoomIn",close:"zoomIn"},zoomOut:{open:"zoomOut",close:"zoomOut"},move:{open:"move",close:"move"},slide:{open:"slide",close:"slide"},flip:{open:"flip",close:"flip"},tada:{open:"tada",close:"zoomOut"}}[this.options.animation]),!this.options.animation)return null;this.options.animation.open&&(this.options.animation.open=this.options.animation.open.split(":")),this.options.animation.close&&(this.options.animation.close=this.options.animation.close.split(":")),this.options.animation.openDirection=this.options.animation.open[1]||null,this.options.animation.closeDirection=this.options.animation.close[1]||null,this.options.animation.open&&(this.options.animation.open=this.options.animation.open[0]),this.options.animation.close&&(this.options.animation.close=this.options.animation.close[0]),this.options.animation.open&&(this.options.animation.open+="Open"),this.options.animation.close&&(this.options.animation.close+="Close");var a={pulse:{duration:350,css:[["0%","scale(1)"],["50%","scale(1.1)"],["100%","scale(1)"]]},zoomInOpen:{duration:this.options.fade||180,css:[["0%","scale(0.9)"],["100%","scale(1)"]]},zoomInClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(0.9)"]]},zoomOutOpen:{duration:this.options.fade||180,css:[["0%","scale(1.1)"],["100%","scale(1)"]]},zoomOutClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(1.1)"]]},moveOpen:{duration:this.options.fade||180,positions:{top:{"0%":-12},right:{"0%":12},bottom:{"0%":12},left:{"0%":-12}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},moveClose:{duration:this.options.fade||180,timing:"ease-in",positions:{top:{"100%":-12},right:{"100%":12},bottom:{"100%":12},left:{"100%":-12}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},slideOpen:{duration:400,positions:{top:{"0%":-400},right:{"0%":400},bottom:{"0%":400},left:{"0%":-400}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},slideClose:{duration:400,timing:"ease-in",positions:{top:{"100%":-400},right:{"100%":400},bottom:{"100%":400},left:{"100%":-400}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},flipOpen:{duration:600,css:[["0%","perspective(400px) rotateX(90deg)"],["40%","perspective(400px) rotateX(-15deg)"],["70%","perspective(400px) rotateX(15deg)"],["100%","perspective(400px) rotateX(0deg)"]]},flipClose:{duration:this.options.fade||300,css:[["0%","perspective(400px) rotateX(0deg)"],["100%","perspective(400px) rotateX(90deg)"]]},tada:{duration:800,css:[["0%","scale(1)"],["10%, 20%","scale(0.9) rotate(-3deg)"],["30%, 50%, 70%, 90%","scale(1.1) rotate(3deg)"],["40%, 60%, 80%","scale(1.1) rotate(-3deg)"],["100%","scale(1) rotate(0)"]]}};j.each(["pulse","tada"],function(t,i){a[i+"Open"]=a[i+"Close"]=a[i]});var s=function(s,e){var n="@keyframes jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {";return j.each(a[this.options.animation[s]].css,function(t,i){var o=e?i[1].replace("%XY",this._getXY(e).toUpperCase()):i[1];a[this.options.animation[s]].positions&&(o=o.replace("%V",a[this.options.animation[s]].positions[e][i[0]])),n+=i[0]+" {transform:"+o+";}"}.bind(this)),n+="}",n+=".jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {",n+="animation-duration: "+a[this.options.animation[s]].duration+"ms;",n+="animation-name: jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+";",n+=a[this.options.animation[s]].timing?"animation-timing-function: "+a[this.options.animation[s]].timing+";":"",n+="}"}.bind(this);this._animationCSS="",j.each(["open","close"],function(t,o){if(!this.options.animation[o]||!a[this.options.animation[o]]||"close"==o&&!this.options.fade)return"";a[this.options.animation[o]].positions?j.each(["top","right","bottom","left"],function(t,i){this._animationCSS+=s(o,i)}.bind(this)):this._animationCSS+=s(o)}.bind(this))},this.options.animation&&this._generateAnimationCSS(),this._blockBodyClick=function(){this.blockBodyClick=!0,setTimeout(function(){this.blockBodyClick=!1}.bind(this),10)},this._animate=function(t){if(t=t||(this.isOpen?"open":"close"),!this.options.fade&&"close"==t)return null;var i=this.options.animation[t+"Direction"]||("center"!=this.align?this.align:this.options.attributes.x);this.flipped&&this._getXY(i)==this._getXY(this.align)&&(i=this._getOpp(i));var o="jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+" jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+"-"+i;this.wrapper.addClass(o);i=1e3*parseFloat(this.wrapper.css("animation-duration"));"close"==t&&(i=Math.min(i,this.options.fade)),setTimeout(function(){this.wrapper&&this.wrapper.removeClass(o)}.bind(this),i)},this._abortAnimation=function(){var t=this.wrapper.attr("class").split(" ").filter(function(t){return 0!==t.lastIndexOf("jBox-"+this.id+"-animation",0)}.bind(this));this.wrapper.attr("class",t.join(" "))},(this.options.responsiveWidth||this.options.responsiveHeight)&&j(window).on("resize.responsivejBox-"+this.id,function(t){this.isOpen&&this.position()}.bind(this)),"string"===j.type(this.options.preloadAudio)&&(this.options.preloadAudio=[this.options.preloadAudio]),"string"===j.type(this.options.audio)&&(this.options.audio={open:this.options.audio}),"number"===j.type(this.options.volume)&&(this.options.volume={open:this.options.volume,close:this.options.volume}),!0===this.options.preloadAudio&&this.options.audio&&(this.options.preloadAudio=[],j.each(this.options.audio,function(t,i){this.options.preloadAudio.push(i+".mp3"),this.options.preloadAudio.push(i+".ogg")}.bind(this))),this.options.preloadAudio.length&&j.each(this.options.preloadAudio,function(t,i){var o=new Audio;o.src=i,o.preload="auto"}),this._fireEvent("onInit"),this}var t,i;return h.prototype.attach=function(t,s){return t=t||this.options.attach,"string"==j.type(t)&&(t=j(t)),s=s||this.options.trigger,t&&t.length&&j.each(t,function(t,o){(o=j(o)).data("jBox-attached-"+this.id)||("title"==this.options.getContent&&null!=o.attr("title")&&o.data("jBox-getContent",o.attr("title")).removeAttr("title"),this.attachedElements||(this.attachedElements=[]),this.attachedElements.push(o[0]),o.on(s+".jBox-attach-"+this.id,function(t){var i;this.timer&&clearTimeout(this.timer),"mouseenter"==s&&this.isOpen&&this.source[0]==o[0]||(this.isOpen&&this.source&&this.source[0]!=o[0]&&(i=!0),this.source=o,this.options.target||(this.target=o),"click"==s&&this.options.preventDefault&&t.preventDefault(),this["click"!=s||i?"open":"toggle"]())}.bind(this)),"mouseenter"==this.options.trigger&&o.on("mouseleave",function(t){if(!this.wrapper)return null;this.options.closeOnMouseleave&&(t.relatedTarget==this.wrapper[0]||j(t.relatedTarget).parents("#"+this.id).length)||this.close()}.bind(this)),o.data("jBox-attached-"+this.id,s),this._fireEvent("onAttach",o))}.bind(this)),this},h.prototype.detach=function(t){return(t=t||(this.attachedElements||[]))&&t.length&&j.each(t,function(t,i){(i=j(i)).data("jBox-attached-"+this.id)&&(i.off(i.data("jBox-attached-"+this.id)+".jBox-attach-"+this.id),i.data("jBox-attached-"+this.id,null)),this.attachedElements=j.grep(this.attachedElements,function(t){return t!=i[0]})}.bind(this)),this},h.prototype.setTitle=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();return this.title||(this.titleContainer=j('<div class="jBox-title"/>'),this.title=j("<div/>").appendTo(this.titleContainer),"title"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay)||(this.wrapper.addClass("jBox-closeButton-title"),this.closeButton.appendTo(this.titleContainer)),this.titleContainer.insertBefore(this.content),this._setTitleWidth()),this.wrapper[t?"addClass":"removeClass"]("jBox-hasTitle"),this.title.html(t),s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setContent=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();switch(this.content.children("[data-jbox-content-appended]").appendTo("body").css({display:"none"}),j.type(t)){case"string":this.content.html(t);break;case"object":t&&(t instanceof j||t.constructor.prototype.jquery)?(this.content.html(""),t.attr("data-jbox-content-appended",1).appendTo(this.content).css({display:"block"})):this.content.html(JSON.stringify(t))}return s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setDimensions=function(t,i,o){this.wrapper||this._create(),this.content.css(t,this._getInt(i=null==i?"auto":i)),"width"==t&&this._setTitleWidth(),this.options[t]=i,null!=o&&!o||this.position()},h.prototype.setWidth=function(t,i){this.setDimensions("width",t,i)},h.prototype.setHeight=function(t,i){this.setDimensions("height",t,i)},h.prototype.position=function(o){if(o=j.extend(!0,this.options,o=o||{}),this.target=o.target||this.target||j(window),this.target instanceof j||"mouse"==this.target||(this.target=j(this.target)),!this.target.length)return this;this.content.css({width:this._getInt(o.width,"width"),height:this._getInt(o.height,"height"),minWidth:this._getInt(o.minWidth,"width"),minHeight:this._getInt(o.minHeight,"height"),maxWidth:this._getInt(o.maxWidth,"width"),maxHeight:this._getInt(o.maxHeight,"height")}),this._setTitleWidth();var s=this._exposeDimensions();"mouse"==this.target||this.target.data("jBox-"+this.id+"-fixed")||this.target.data("jBox-"+this.id+"-fixed",this.target[0]!=j(window)[0]&&("fixed"==this.target.css("position")||0<this.target.parents().filter(function(){return"fixed"==j(this).css("position")}).length)?"fixed":"static");var t={x:j(window).outerWidth(),y:j(window).outerHeight(),top:o.fixed&&this.target.data("jBox-"+this.id+"-fixed")?0:j(window).scrollTop(),left:o.fixed&&this.target.data("jBox-"+this.id+"-fixed")?0:j(window).scrollLeft()};t.bottom=t.top+t.y,t.right=t.left+t.x;try{var i=this.target.offset()}catch(t){i={top:0,left:0}}"mouse"!=this.target&&"fixed"==this.target.data("jBox-"+this.id+"-fixed")&&o.fixed&&(i.top=i.top-j(window).scrollTop(),i.left=i.left-j(window).scrollLeft());var e={x:"mouse"==this.target?12:this.target.outerWidth(),y:"mouse"==this.target?20:this.target.outerHeight(),top:"mouse"==this.target&&o.mouseTarget?o.mouseTarget.top:i?i.top:0,left:"mouse"==this.target&&o.mouseTarget?o.mouseTarget.left:i?i.left:0},n=o.outside&&!("center"==o.position.x&&"center"==o.position.y),a={x:t.x-o.adjustDistance.left-o.adjustDistance.right,y:t.y-o.adjustDistance.top-o.adjustDistance.bottom,left:n?e.left-j(window).scrollLeft()-o.adjustDistance.left:0,right:n?t.x-e.left+j(window).scrollLeft()-e.x-o.adjustDistance.right:0,top:n?e.top-j(window).scrollTop()-this.options.adjustDistance.top:0,bottom:n?t.y-e.top+j(window).scrollTop()-e.y-o.adjustDistance.bottom:0},h={x:"x"!=o.outside&&"xy"!=o.outside||"number"==j.type(o.position.x)?null:o.position.x,y:"y"!=o.outside&&"xy"!=o.outside||"number"==j.type(o.position.y)?null:o.position.y},r={x:!1,y:!1};h.x&&s.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),h.y&&s.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),(o.responsiveWidth||o.responsiveHeight)&&(m=function(){var t;o.responsiveWidth&&s.x>a[h.x||"x"]&&(t=a[h.x||"x"]-(this.pointer&&n&&"x"==o.outside?this.pointer.dimensions.x:0)-parseInt(this.container.css("border-left-width"))-parseInt(this.container.css("border-right-width")),this.content.css({width:t>this.options.responsiveMinWidth?t:null,minWidth:t<parseInt(this.content.css("minWidth"))?0:null}),this._setTitleWidth()),s=this._exposeDimensions()}.bind(this),o.responsiveWidth&&m(),o.responsiveWidth&&!r.y&&h.y&&s.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),f=function(){var t;o.responsiveHeight&&s.y>a[h.y||"y"]&&(t=function(){return this.titleContainer||this.footer?("none"==this.wrapper.css("display")?(this.wrapper.css("display","block"),t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),this.wrapper.css("display","none")):t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),t||0):0;var t}.bind(this),t=a[h.y||"y"]-(this.pointer&&n&&"y"==o.outside?this.pointer.dimensions.y:0)-t()-parseInt(this.container.css("border-top-width"))-parseInt(this.container.css("border-bottom-width")),this.content.css({height:t>this.options.responsiveMinHeight?t:null}),this._setTitleWidth()),s=this._exposeDimensions()}.bind(this),o.responsiveHeight&&f(),o.responsiveHeight&&!r.x&&h.x&&s.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),o.adjustPosition&&"move"!=o.adjustPosition&&(r.x&&m(),r.y&&f()));var p={},l=function(t){if("number"!=j.type(o.position[t])){var i=o.attributes[t]="x"==t?"left":"top";if(p[i]=e[i],"center"==o.position[t])return p[i]+=Math.ceil((e[t]-s[t])/2),void("mouse"!=this.target&&this.target[0]&&this.target[0]==j(window)[0]&&(p[i]+=.5*(o.adjustDistance[i]-o.adjustDistance[this._getOpp(i)])));i!=o.position[t]&&(p[i]+=e[t]-s[t]),o.outside!=t&&"xy"!=o.outside||(p[i]+=s[t]*(i!=o.position[t]?1:-1))}else p[o.attributes[t]]=o.position[t]}.bind(this);if(l("x"),l("y"),this.pointer&&"target"==o.pointTo&&"number"!=j.type(o.position.x)&&"number"!=j.type(o.position.y)&&(x=0,"center"===this.pointer.align?"center"!=o.position[this._getOpp(o.outside)]&&(x+=s[this._getOpp(o.outside)]/2):"center"===o.position[this._getOpp(o.outside)]?x+=(s[this._getOpp(o.outside)]/2-this.pointer.dimensions[this._getOpp(o.outside)]/2)*(this.pointer.align==this._getTL(this.pointer.align)?1:-1):x+=this.pointer.align!=o.position[this._getOpp(o.outside)]?s[this._getOpp(o.outside)]*(-1!==j.inArray(this.pointer.align,["top","left"])?1:-1)+this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==j.inArray(this.pointer.align,["top","left"])?-1:1):this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==j.inArray(this.pointer.align,["top","left"])?1:-1),x*=o.position[this._getOpp(o.outside)]==this.pointer.alignAttribute?-1:1,x+=this.pointer.offset*(this.pointer.align==this._getOpp(this._getTL(this.pointer.align))?1:-1),p[this._getTL(this._getOpp(this.pointer.xy))]+=x),p[o.attributes.x]+=o.offset.x,p[o.attributes.y]+=o.offset.y,this.wrapper.css(p),o.adjustPosition){this.positionAdjusted&&(this.pointer&&this.wrapper.css("padding",0).css("padding-"+this._getOpp(this.outside),this.pointer.dimensions[this._getXY(this.outside)]).removeClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).addClass("jBox-pointerPosition-"+this.pointer.position),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+this._getOpp(this.outside)).css(this.pointer.margin),this.positionAdjusted=!1,this.flipped=!1);var d=t.top>p.top-(o.adjustDistance.top||0),c=t.right<p.left+s.x+(o.adjustDistance.right||0),u=t.bottom<p.top+s.y+(o.adjustDistance.bottom||0),g=t.left>p.left-(o.adjustDistance.left||0),i=g?"left":c?"right":null,m=d?"top":u?"bottom":null;if(i||m){if(("Modal"==this.type||"Confirm"==this.type)&&"number"==j.type(this.options.position.x)&&"number"==j.type(this.options.position.y)){var f=0,x=0;return this.options.holdPosition&&(g?f=t.left-(p.left-(o.adjustDistance.left||0)):c&&(f=t.right-(p.left+s.x+(o.adjustDistance.right||0))),d?x=t.top-(p.top-(o.adjustDistance.top||0)):u&&(x=t.bottom-(p.top+s.y+(o.adjustDistance.bottom||0))),this.options.position.x=Math.max(t.top,this.options.position.x+f),this.options.position.y=Math.max(t.left,this.options.position.y+x),l("x"),l("y"),this.wrapper.css(p)),this._fireEvent("onPosition"),this}!0!==o.adjustPosition&&"flip"!==o.adjustPosition||(y=function(t){this.wrapper.css(this._getTL(t),p[this._getTL(t)]+(s[this._getXY(t)]+o.offset[this._getXY(t)]*("top"==t||"left"==t?-2:2)+e[this._getXY(t)])*("top"==t||"left"==t?1:-1)),this.pointer&&this.wrapper.removeClass("jBox-pointerPosition-"+this.pointer.position).addClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).css("padding",0).css("padding-"+t,this.pointer.dimensions[this._getXY(t)]),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+t),this.positionAdjusted=!0,this.flipped=!0}.bind(this),r.x&&y(this.options.position.x),r.y&&y(this.options.position.y));var y="x"==this._getXY(this.outside)?m:i;this.pointer&&"target"==o.pointTo&&"flip"!=o.adjustPosition&&this._getXY(y)==this._getOpp(this._getXY(this.outside))&&(m="center"==this.pointer.align?s[this._getXY(y)]/2-this.pointer.dimensions[this._getOpp(this.pointer.xy)]/2-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))*(y!=this._getTL(y)?-1:1):y==this.pointer.alignAttribute?parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute)):s[this._getXY(y)]-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-this.pointer.dimensions[this._getXY(y)],i=y==this._getTL(y)?t[this._getTL(y)]-p[this._getTL(y)]+o.adjustDistance[y]:-1*(t[this._getOpp(this._getTL(y))]-p[this._getTL(y)]-o.adjustDistance[y]-s[this._getXY(y)]),y==this._getOpp(this._getTL(y))&&p[this._getTL(y)]-i<t[this._getTL(y)]+o.adjustDistance[this._getTL(y)]&&(i-=t[this._getTL(y)]+o.adjustDistance[this._getTL(y)]-(p[this._getTL(y)]-i)),(i=Math.min(i,m))<=m&&0<i&&(this.pointer.element.css("margin-"+this.pointer.alignAttribute,parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-i*(y!=this.pointer.alignAttribute?-1:1)),this.wrapper.css(this._getTL(y),p[this._getTL(y)]+i*(y!=this._getTL(y)?-1:1)),this.positionAdjusted=!0))}}return this._fireEvent("onPosition"),this},(h.prototype.unscroll=function(t){if(this.set=function(t,i){window.unscrollStore||(window.unscrollStore={}),window.unscrollStore[t]=i},this.get=function(t){return window.unscrollStore?window.unscrollStore[t]:null},this.getScrollbarWidth=function(){if(this.get("scrollbarWidth"))return this.get("scrollbarWidth")+"px";var t=document.createElement("div");t.style.width="100px",t.style.height="100px",t.style.overflow="scroll",t.style.position="absolute",t.style.top="-10000",document.body.appendChild(t);var i=t.offsetWidth-t.clientWidth;return document.body.removeChild(t),this.set("scrollbarWidth",i),i+"px"},this.getElementsToAdjust=function(o){(o="string"==typeof(o=o||[])?[[o,"padding-right"]]:o).forEach(function(t,i){"string"==typeof t&&(o[i]=[t,"padding-right"])});for(var t=!1,i=0;i<o.length;i++)-1!==o[i][0].indexOf("body")&&(t=!0);return!1===t&&o.push(["body","padding-right"]),o},this.pageHasScrollbar=function(){return this.getScrollbarWidth()&&document.body.offsetHeight>window.innerHeight},this.pageHasScrollbar()){t=this.getElementsToAdjust(t);for(var i=0;i<t.length;i++)for(var o=document.querySelectorAll(t[i][0]),s=0;s<o.length;s++){if(o[s].getAttribute("data-unscroll"))return;var e=t[i][1],n=window.getComputedStyle(o[s]).getPropertyValue(e);o[s].setAttribute("data-unscroll",e),o[s].style[e]="calc("+(n=n||"0px")+" "+("padding-right"==e||"right"==e?"+":"-")+" "+this.getScrollbarWidth()+")"}}var a,h;document.getElementById("unscroll-class-name")||(a=document.head||document.getElementsByTagName("head")[0],(h=document.createElement("style")).type="text/css",h.setAttribute("id","unscroll-class-name"),h.appendChild(document.createTextNode(".unscrollable { overflow: hidden !important; }")),a.appendChild(h)),document.body.classList.add("unscrollable")}).reset=function(){for(var t=document.querySelectorAll("[data-unscroll]"),i=0;i<t.length;i++){var o=t[i].getAttribute("data-unscroll");t[i].style[o]=null,t[i].removeAttribute("data-unscroll")}document.body.classList.remove("unscrollable")},h.prototype.open=function(t){if(t=t||{},this.isDestroyed)return this;if(this.wrapper||this._create(),this._styles||(this._styles=j("<style/>").append(this._animationCSS).appendTo(j("head"))),this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;this.options.closeOnEsc&&j(document).on("keyup.jBox-"+this.id,function(t){27==t.keyCode&&this.close({ignoreDelay:!0})}.bind(this)),!0!==this.options.closeOnClick&&"body"!==this.options.closeOnClick||(j("body").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(t){this.blockBodyClick||"body"==this.options.closeOnClick&&(t.target==this.wrapper[0]||this.wrapper.has(t.target).length)||this.close({ignoreDelay:!0})}.bind(this)),this.isTouchDevice&&j("body > *").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(){return!0}));var i=function(){!0===this.adjustZIndexOnOpen&&(h.zIndexMax=Math.max(parseInt(this.wrapper.css("zIndex"),10),this.options.zIndex,h.zIndexMax||0,h.zIndexMaxDragover||0)+2,this.wrapper.css("zIndex",h.zIndexMax),this.options.zIndex=h.zIndexMax),this.source&&this.options.getTitle&&this.source.attr(this.options.getTitle)&&this.setTitle(this.source.attr(this.options.getTitle),!0),this.source&&this.options.getContent&&(this.source.data("jBox-getContent")?this.setContent(this.source.data("jBox-getContent"),!0):this.source.attr(this.options.getContent)?this.setContent(this.source.attr(this.options.getContent),!0):"html"==this.options.getContent&&this.setContent(this.source.html(),!0)),this._fireEvent("onOpen"),(this.options.ajax&&(this.options.ajax.url||this.source&&this.source.attr(this.options.ajax.getURL))&&(!this.ajaxLoaded||this.options.ajax.reload)||t.ajax&&(t.ajax.url||t.ajax.data))&&("strict"==this.options.ajax.reload||!this.source||!this.source.data("jBox-ajax-data")||t.ajax&&(t.ajax.url||t.ajax.data)?this.ajax(t.ajax||null,!0):this.setContent(this.source.data("jBox-ajax-data"))),this.positionedOnOpen&&!this.options.repositionOnOpen||!this.position(t)||(this.positionedOnOpen=!0),this.isClosing&&this._abortAnimation(),this.isOpen||(this.isOpen=!0,this.options.autoClose&&(this.options.delayClose=this.options.autoClose)&&this.close(),this._attachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?h.blockScrollScopes?h.blockScrollScopes++:(h.blockScrollScopes=1,this.unscroll(Array.isArray(this.options.blockScrollAdjust)||"string"==typeof this.options.blockScrollAdjust?this.options.blockScrollAdjust:null)):j("body").addClass("jBox-blockScroll-"+this.id)),this.options.overlay&&(this._showOverlay(),this.position()),this.options.animation&&!this.isClosing&&this._animate("open"),this.options.audio&&this.options.audio.open&&this.audio(this.options.audio.open,this.options.volume.open),this.options.fade?this.wrapper.stop().animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.isOpening=!0,this.wrapper.css({display:"block"})}.bind(this),complete:function(){this._fireEvent("onOpenComplete")}.bind(this),always:function(){this.isOpening=!1,setTimeout(function(){this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1)}.bind(this),10)}.bind(this)}):(this.wrapper.css({display:"block",opacity:1}),this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1),this._fireEvent("onOpenComplete")))}.bind(this);return!this.options.delayOpen||this.isOpen||this.isClosing||t.ignoreDelay?i():this.timer=setTimeout(i,this.options.delayOpen),this},h.prototype.close=function(t){if(t=t||{},j("body").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isTouchDevice&&j("body > *").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isDestroyed||this.isClosing)return this;if(this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;var i,o,s,e=function(){var t;this._fireEvent("onClose"),this.options.cancelAjaxOnClose&&this.cancelAjax(),this.isOpen&&(this.isOpen=!1,this._detachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?(h.blockScrollScopes=h.blockScrollScopes?--h.blockScrollScopes:0)||this.unscroll.reset():j("body").removeClass("jBox-blockScroll-"+this.id)),this.options.overlay&&this._hideOverlay(),this.options.animation&&!this.isOpening&&this._animate("close"),this.options.audio&&this.options.audio.close&&this.audio(this.options.audio.close,this.options.volume.close),(t=this.isTouchDevice&&"mouse"==this.options.target?0:this.options.fade)?this.wrapper.stop().animate({opacity:0},{queue:!1,duration:t,start:function(){this.isClosing=!0}.bind(this),complete:function(){this.wrapper.css({display:"none"}),this._fireEvent("onCloseComplete")}.bind(this),always:function(){this.isClosing=!1}.bind(this)}):(this.wrapper.css({display:"none",opacity:0}),this._fireEvent("onCloseComplete")))}.bind(this);return t.ignoreDelay||this.isTouchDevice&&"mouse"==this.options.target?e():(this.options.delayOnHover||this.options.showCountdown)&&10<this.options.delayClose?(o=(i=this).options.delayClose,s=Date.now(),this.options.showCountdown&&!this.inner&&(t=j('<div class="jBox-countdown" />'),this.inner=j('<div class="jBox-countdown-inner" />'),t.prepend(this.inner),j("#"+this.id).append(t)),this.countdown=function(){var t=Date.now();i.isHovered||(o-=t-s),s=t,0<o?(i.options.showCountdown&&i.inner.css("width",100*o/i.options.delayClose+"%"),window.requestAnimationFrame(i.countdown)):e()},window.requestAnimationFrame(this.countdown)):this.timer=setTimeout(e,Math.max(this.options.delayClose,10)),this},h.prototype.toggle=function(t){return this[this.isOpen?"close":"open"](t),this},h.prototype.disable=function(){return this.isDisabled=!0,this},h.prototype.enable=function(){return this.isDisabled=!1,this},h.prototype.hide=function(){return this.disable(),this.wrapper&&(this.cacheWrapperDisplay=this.wrapper.css("display"),this.wrapper.css({display:"none"})),this.overlay&&(this.cacheOverlayDisplay=this.overlay.css("display"),this.overlay.css({display:"none"})),this},h.prototype.show=function(){return this.enable(),this.wrapper&&this.cacheWrapperDisplay&&(this.wrapper.css({display:this.cacheWrapperDisplay}),this.cacheWrapperDisplay=null),this.overlay&&this.cacheOverlayDisplay&&(this.overlay.css({display:this.cacheOverlayDisplay}),this.cacheOverlayDisplay=null),this},h.prototype.ajax=function(o,i){o=o||{},j.each([["getData","data"],["getURL","url"]],function(t,i){this.options.ajax[i[0]]&&!o[i[1]]&&this.source&&null!=this.source.attr(this.options.ajax[i[0]])&&(o[i[1]]=this.source.attr(this.options.ajax[i[0]])||"")}.bind(this));var t=j.extend(!0,{},this.options.ajax);this.cancelAjax();var s=o.beforeSend||t.beforeSend||function(){},e=o.complete||t.complete||function(){},n=o.success||t.success||function(){},a=o.error||t.error||function(){},h=j.extend(!0,t,o);return h.beforeSend=function(t){h.loadingClass&&this.wrapper.addClass(!0===h.loadingClass?"jBox-loading":h.loadingClass),h.spinner&&(this.spinnerDelay=setTimeout(function(){this.wrapper.addClass("jBox-loading-spinner"),h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.spinner=j(!0!==h.spinner?h.spinner:'<div class="jBox-spinner"></div>').appendTo(this.container),this.titleContainer&&"absolute"==this.spinner.css("position")&&this.spinner.css({transform:"translateY("+.5*this.titleContainer.outerHeight()+"px)"})}.bind(this),""!=this.content.html()&&h.spinnerDelay||0)),s.bind(this)(t)}.bind(this),h.complete=function(t){this.spinnerDelay&&clearTimeout(this.spinnerDelay),this.wrapper.removeClass("jBox-loading jBox-loading-spinner jBox-loading-spinner-delay"),this.spinner&&this.spinner.length&&this.spinner.remove()&&h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.ajaxLoaded=!0,e.bind(this)(t)}.bind(this),h.success=function(t){h.setContent&&this.setContent(t,!0)&&(i?this.positionOnFadeComplete=!0:this.position()),h.setContent&&this.source&&this.source.data("jBox-ajax-data",t),n.bind(this)(t)}.bind(this),h.error=function(t){a.bind(this)(t)}.bind(this),this.ajaxRequest=j.ajax(h),this},h.prototype.cancelAjax=function(){this.ajaxRequest&&(this.ajaxRequest.abort(),this.ajaxLoaded=!1)},h.prototype.audio=function(t,i){if(!t)return this;var o;(h._audio=!h._audio?{}:h._audio)[t]||(o=j("<audio/>"),j("<source/>",{src:t+".mp3"}).appendTo(o),j("<source/>",{src:t+".ogg"}).appendTo(o),h._audio[t]=o[0]),h._audio[t].volume=Math.min((null!=i?i:100)/100,1);try{h._audio[t].pause(),h._audio[t].currentTime=0}catch(t){}return h._audio[t].play(),this},h._animationSpeeds={tada:1e3,tadaSmall:1e3,flash:500,shake:400,pulseUp:250,pulseDown:250,popIn:250,popOut:250,fadeIn:200,fadeOut:200,slideUp:400,slideRight:400,slideLeft:400,slideDown:400},h.prototype.animate=function(t,i){i=i||{},this.animationTimeout||(this.animationTimeout={}),i.element||(i.element=this.wrapper),i.element.data("jBox-animating-id")||i.element.data("jBox-animating-id",h._getUniqueElementID()),i.element.data("jBox-animating")&&(i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),this.animationTimeout[i.element.data("jBox-animating-id")]&&clearTimeout(this.animationTimeout[i.element.data("jBox-animating-id")])),i.element.addClass("jBox-animated-"+t).data("jBox-animating","jBox-animated-"+t),this.animationTimeout[i.element.data("jBox-animating-id")]=setTimeout(function(){i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),i.complete&&i.complete()},h._animationSpeeds[t])},h.prototype.swipeDetector=function(i,o){var s=0,e=0,n=0,a=0,h=0;function t(t){o.useOnlyTouch&&!t.originalEvent.touches||(t.originalEvent.touches&&(t=t.originalEvent.touches[0]),0===s&&(s=1,e=t.clientX,n=t.clientY))}function r(t){2===s&&(s=0,Math.abs(a)>Math.abs(h)&&Math.abs(a)>o.swipeThreshold?a<0?i.trigger(j.Event("swipeLeft.sd")):i.trigger(j.Event("swipeRight.sd")):Math.abs(h)>o.swipeThreshold&&(h<0?i.trigger(j.Event("swipeUp.sd")):i.trigger(j.Event("swipeDown.sd"))))}function p(t){var i;1===s&&(i=(t=t.originalEvent.touches?t.originalEvent.touches[0]:t).clientX-e,t=t.clientY-n,(Math.abs(i)>o.swipeThreshold||Math.abs(t)>o.swipeThreshold)&&(s=2,a=i,h=t))}return o=j.extend({swipeThreshold:70,useOnlyTouch:!1},o),i.on("mousedown touchstart",t),j("html").on("mouseup touchend",r),j("html").on("mousemove touchmove",p),i},h.prototype.destroy=function(){return this.detach(),this.isOpen&&this.close({ignoreDelay:!0}),this.wrapper&&this.wrapper.remove(),this.overlay&&this.overlay.remove(),this._styles&&this._styles.remove(),this.isDestroyed=!0,this},h._getUniqueID=(t=1,function(){return t++}),h._getUniqueElementID=(i=1,function(){return i++}),h._pluginOptions={},h.plugin=function(t,i){h._pluginOptions[t]=i},j.fn.jBox=function(t,i){return new h(t=t||{},j.extend(i=i||{},{attach:this}))},h}function jBoxConfirmWrapper(jBox,jQuery){new jBox.plugin("Confirm",{confirmButton:"Submit",cancelButton:"Cancel",confirm:null,cancel:null,closeOnConfirm:!0,target:window,fixed:!0,attach:"[data-confirm]",getContent:"data-confirm",content:"Do you really want to do this?",minWidth:360,maxWidth:500,blockScroll:!0,closeOnEsc:!0,closeOnClick:!1,closeButton:!1,overlay:!0,animation:"zoomIn",preventDefault:!0,_onAttach:function(t){var i;this.options.confirm||(i=t.attr("onclick")?t.attr("onclick"):t.attr("href")?t.attr("target")?'window.open("'+t.attr("href")+'", "'+t.attr("target")+'");':'window.location.href = "'+t.attr("href")+'";':"",t.prop("onclick",null).data("jBox-Confirm-submit",i))},_onCreated:function(){this.wrapper.addClass("jBox-Modal"),this.footer=jQuery('<div class="jBox-Confirm-footer"/>'),jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-cancel"/>').html(this.options.cancelButton).on("click tap",function(){this.options.cancel&&this.options.cancel(this.source),this.close()}.bind(this)).appendTo(this.footer),this.submitButton=jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-submit"/>').html(this.options.confirmButton).appendTo(this.footer),this.footer.appendTo(this.container)},_onOpen:function(){this.submitButton.off("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id).on("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id,function(){this.options.confirm?this.options.confirm(this.source):eval(this.source.data("jBox-Confirm-submit")),this.options.closeOnConfirm&&this.close()}.bind(this))}})}function jBoxImageWrapper(t,a){new t.plugin("Image",{src:"href",gallery:"data-jbox-image",imageLabel:"title",imageFade:360,imageSize:"contain",imageCounter:!1,imageCounterSeparator:"/",downloadButton:!1,downloadButtonText:null,downloadButtonUrl:null,mobileImageAttr:null,mobileImageBreakpoint:null,preloadFirstImage:!1,target:window,attach:"[data-jbox-image]",fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"button",closeButton:!0,overlay:!0,animation:"zoomIn",preventDefault:!0,width:"100%",height:"100%",adjustDistance:{top:40,right:0,bottom:40,left:0},_onInit:function(){this.images=this.currentImage={},this.imageZIndex=1,this.initImage=function(t){var i,o;(t=a(t)).data("jBox-image-gallery")||(i=t.attr(this.options.src),this.options.mobileImageAttr&&this.options.mobileImageBreakpoint&&t.attr(this.options.mobileImageAttr)&&a(window).width()<=this.options.mobileImageBreakpoint&&(i=t.attr(this.options.mobileImageAttr)),o=t.attr(this.options.gallery)||"default",this.images[o]||(this.images[o]=[]),this.images[o].push({src:i,label:t.attr(this.options.imageLabel)||"",downloadUrl:this.options.downloadButtonUrl&&t.attr(this.options.downloadButtonUrl)?t.attr(this.options.downloadButtonUrl):null}),"title"==this.options.imageLabel&&t.removeAttr("title"),t.data("jBox-image-gallery",o),t.data("jBox-image-id",this.images[o].length-1))}.bind(this),this.attachedElements&&this.attachedElements.length&&a.each(this.attachedElements,function(t,i){this.initImage(i)}.bind(this));var n=function(t,i,o,s){if(!a("#jBox-image-"+t+"-"+i).length){var e=a("<div/>",{id:"jBox-image-"+t+"-"+i,class:"jBox-image-container"+(o?" jBox-image-"+t+"-current":"")}).css({backgroundSize:this.options.imageSize,opacity:s?1:0,zIndex:o?this.imageZIndex++:0}).appendTo(this.content);return this.swipeDetector(e).on("swipeLeft.sd swipeRight.sd",function(t){"swipeLeft"===t.type?this.showImage("next"):"swipeRight"===t.type&&this.showImage("prev")}.bind(this)),a("<div/>",{id:"jBox-image-label-"+t+"-"+i,class:"jBox-image-label"+(o?" active":"")}).html(this.images[t][i].label).on("click tap",function(){a(this).toggleClass("expanded")}).appendTo(this.imageLabelContainer),o&&e.animate({opacity:1},s?0:this.options.imageFade),e}}.bind(this);this.downloadImage=function(t){var i=document.createElement("a");i.href=t,i.setAttribute("download",t.substring(t.lastIndexOf("/")+1)),document.body.appendChild(i),i.click()};var e=function(i,o,t,s){var e=n(i,o,t,s);e.addClass("jBox-image-loading"),a('<img src="'+this.images[i][o].src+'" />').each(function(){var t=new Image;t.onload=function(){e.removeClass("jBox-image-loading"),e.css({backgroundImage:'url("'+this.images[i][o].src+'")'})}.bind(this),t.onerror=function(){e.removeClass("jBox-image-loading"),e.addClass("jBox-image-not-found")}.bind(this),t.src=this.images[i][o].src}.bind(this))}.bind(this);this.showImage=function(t){var i,o,s;if("open"!=t)i=this.currentImage.gallery,s=(s=this.currentImage.id+(+("prev"==t)?-1:1))>this.images[i].length-1?0:s<0?this.images[i].length-1:s;else{if(this.source)i=this.source.data("jBox-image-gallery"),s=this.source.data("jBox-image-id");else{if(!this.attachedElements||!this.attachedElements.length)return;i=a(this.attachedElements[0]).data("jBox-image-gallery"),s=a(this.attachedElements[0]).data("jBox-image-id")}this.images&&this.images[i]&&a(".jBox-image-pointer-prev, .jBox-image-pointer-next").css({display:1<this.images[i].length?"block":"none"})}a(".jBox-image-"+i+"-current").length&&a(".jBox-image-"+i+"-current").removeClass("jBox-image-"+i+"-current").animate({opacity:0},"open"==t?0:this.options.imageFade),this.currentImage={gallery:i,id:s},a("#jBox-image-"+i+"-"+s).length?a("#jBox-image-"+i+"-"+s).addClass("jBox-image-"+i+"-current").css({zIndex:this.imageZIndex++,opacity:0}).animate({opacity:1},"open"==t?0:this.options.imageFade):e(i,s,!0,"open"===t),o=i,t=s,a(".jBox-image-label.active").removeClass("active expanded"),a("#jBox-image-label-"+o+"-"+t).addClass("active"),this.imageCounter&&(this.images[i]&&1<this.images[i].length?(this.wrapper.addClass("jBox-image-has-counter"),this.imageCounter.find(".jBox-image-counter-all").html(this.images[i].length),this.imageCounter.find(".jBox-image-counter-current").html(s+1)):this.wrapper.removeClass("jBox-image-has-counter")),this.images[i]&&this.images[i].length-1&&(s=(s=s+1)>this.images[i].length-1?0:s<0?this.images[i].length-1:s,a("#jBox-image-"+i+"-"+s).length||e(i,s,!1,!1))},this.options.preloadFirstImage&&a(window).on("load",function(){this.showImage("open")}.bind(this))},_onAttach:function(t){this.initImage&&this.initImage(t)},_onCreated:function(){this.imageLabelWrapper=a('<div class="jBox-image-label-wrapper"/>').appendTo(this.wrapper),this.imagePrevButton=a('<div class="jBox-image-pointer-prev"/>').on("click tap",function(){this.showImage("prev")}.bind(this)),this.imageNextButton=a('<div class="jBox-image-pointer-next"/>').on("click tap",function(){this.showImage("next")}.bind(this)),this.imageLabelContainer=a('<div class="jBox-image-label-container"/>'),this.imageLabelWrapper.append(this.imagePrevButton).append(this.imageLabelContainer).append(this.imageNextButton),this.options.downloadButton&&(this.downloadButton=a("<div/>",{class:"jBox-image-download-button-wrapper"}).appendTo(this.wrapper).append(this.options.downloadButtonText?a("<div/>",{class:"jBox-image-download-button-text"}).html(this.options.downloadButtonText):null).append(a("<div/>",{class:"jBox-image-download-button-icon"})).on("click tap",function(){var t;t=this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl||this.wrapper.find(".jBox-image-"+this.currentImage.gallery+"-current")[0].style.backgroundImage.slice(4,-1).replace(/["']/g,""),this.downloadImage(t)}.bind(this))),this.options.imageCounter&&(this.imageCounter=a("<div/>",{class:"jBox-image-counter-container"}).insertAfter(this.imageLabelContainer),this.imageCounter.append(a("<span/>",{class:"jBox-image-counter-current"})).append(a("<span/>").html(this.options.imageCounterSeparator)).append(a("<span/>",{class:"jBox-image-counter-all"})))},_onOpen:function(){a(document).on("keyup.jBox-Image-"+this.id,function(t){37==t.keyCode&&this.showImage("prev"),39==t.keyCode&&this.showImage("next")}.bind(this)),this.showImage("open")},_onClose:function(){a(document).off("keyup.jBox-Image-"+this.id)},_onCloseComplete:function(){this.wrapper.find(".jBox-image-container").css("opacity",0)}})}function jBoxNoticeWrapper(t,a){new t.plugin("Notice",{color:null,stack:!0,stackSpacing:10,autoClose:6e3,attributes:{x:"right",y:"top"},position:{x:15,y:15},responsivePositions:{500:{x:5,y:5},768:{x:10,y:10}},target:window,fixed:!0,animation:"zoomIn",closeOnClick:"box",zIndex:12e3,_onInit:function(){this.defaultNoticePosition=a.extend({},this.options.position),this._adjustNoticePositon=function(){var t=a(window),o=t.width();t.height();this.options.position=a.extend({},this.defaultNoticePosition),a.each(this.options.responsivePositions,function(t,i){if(o<=t)return this.options.position=i,!1}.bind(this)),this.options.adjustDistance={top:this.options.position.y,right:this.options.position.x,bottom:this.options.position.y,left:this.options.position.x}},this.options.content instanceof a&&(this.options.content=this.options.content.clone().attr("id","")),a(window).on("resize.responsivejBoxNotice-"+this.id,function(t){this.isOpen&&this._adjustNoticePositon()}.bind(this)),this.open()},_onCreated:function(){this.wrapper.addClass("jBox-Notice-color jBox-Notice-"+(this.options.color||"gray")),this.wrapper.data("jBox-Notice-position",this.options.attributes.x+"-"+this.options.attributes.y)},_onOpen:function(){this.options.stack||(this._adjustNoticePositon(),a.each(a(".jBox-Notice"),function(t,i){(i=a(i)).attr("id")!=this.id&&i.data("jBox-Notice-position")==this.options.attributes.x+"-"+this.options.attributes.y&&(this.options.stack||i.data("jBox").close({ignoreDelay:!0}))}.bind(this)))},_onPosition:function(){var t,s={};for(t in a.each(a(".jBox-Notice"),function(t,i){var o=(i=a(i)).data("jBox-Notice-position");s[o]||(s[o]=[]),s[o].push(i)}),s){var i=t.split("-")[1];s[t].reverse();var o,e=0;for(o in s[t]){var n=a(s[t][o]);n.css("margin-"+i,e),e+=n.outerHeight()+this.options.stackSpacing}}},_onCloseComplete:function(){this.destroy(),this.options._onPosition.bind(this).call()}})}!function(i,o){"function"==typeof define&&define.amd?define(["jquery"],function(t){return i.jBox=o(t)}):"object"==typeof module&&module.exports?module.exports=i.jBox=o(require("jquery")):i.jBox=o(i.jQuery)}(this,function(t){var i=jBoxWrapper(t);try{void 0!==jBoxConfirmWrapper&&jBoxConfirmWrapper&&jBoxConfirmWrapper(i,t)}catch(t){console.error(t)}try{void 0!==jBoxImageWrapper&&jBoxImageWrapper&&jBoxImageWrapper(i,t)}catch(t){console.error(t)}try{void 0!==jBoxNoticeWrapper&&jBoxNoticeWrapper&&jBoxNoticeWrapper(i,t)}catch(t){console.error(t)}return i});
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,572 @@
1
+.jBox-wrapper {
2
+  text-align: left;
3
+  box-sizing: border-box;
4
+}
5
+
6
+.jBox-title,
7
+.jBox-content,
8
+.jBox-container {
9
+  position: relative;
10
+  word-break: break-word;
11
+  box-sizing: border-box;
12
+}
13
+
14
+.jBox-container {
15
+  background: #fff;
16
+}
17
+
18
+.jBox-content {
19
+  padding: 8px 12px;
20
+  overflow-x: hidden;
21
+  overflow-y: auto;
22
+  transition: opacity .2s;
23
+}
24
+
25
+.jBox-footer {
26
+  box-sizing: border-box;
27
+}
28
+
29
+.jBox-Tooltip .jBox-container,
30
+.jBox-Mouse .jBox-container {
31
+  border-radius: 4px;
32
+  box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
33
+}
34
+
35
+.jBox-Tooltip .jBox-title,
36
+.jBox-Mouse .jBox-title {
37
+  padding: 8px 10px 0;
38
+  font-weight: bold;
39
+}
40
+
41
+.jBox-Tooltip.jBox-hasTitle .jBox-content,
42
+.jBox-Mouse.jBox-hasTitle .jBox-content {
43
+  padding-top: 5px;
44
+}
45
+
46
+.jBox-Mouse {
47
+  pointer-events: none;
48
+}
49
+
50
+.jBox-pointer {
51
+  position: absolute;
52
+  overflow: hidden;
53
+  box-sizing: border-box;
54
+}
55
+
56
+.jBox-pointer:after {
57
+  content: '';
58
+  width: 20px;
59
+  height: 20px;
60
+  position: absolute;
61
+  background: #fff;
62
+  transform: rotate(45deg);
63
+  box-sizing: border-box;
64
+}
65
+
66
+.jBox-pointer-top {
67
+  top: 0;
68
+}
69
+
70
+.jBox-pointer-top:after {
71
+  left: 5px;
72
+  top: 6px;
73
+  box-shadow: -1px -1px 2px rgba(0, 0, 0, 0.15);
74
+}
75
+
76
+.jBox-pointer-right {
77
+  right: 0;
78
+}
79
+
80
+.jBox-pointer-right:after {
81
+  top: 5px;
82
+  right: 6px;
83
+  box-shadow: 1px -1px 2px rgba(0, 0, 0, 0.15);
84
+}
85
+
86
+.jBox-pointer-left {
87
+  left: 0;
88
+}
89
+
90
+.jBox-pointer-left:after {
91
+  top: 5px;
92
+  left: 6px;
93
+  box-shadow: -1px 1px 2px rgba(0, 0, 0, 0.15);
94
+}
95
+
96
+.jBox-pointer-bottom {
97
+  bottom: 0;
98
+}
99
+
100
+.jBox-pointer-bottom:after {
101
+  left: 5px;
102
+  bottom: 6px;
103
+  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15);
104
+}
105
+
106
+.jBox-pointer-top, .jBox-pointer-bottom {
107
+  width: 30px;
108
+  height: 12px;
109
+}
110
+
111
+.jBox-pointer-left, .jBox-pointer-right {
112
+  width: 12px;
113
+  height: 30px;
114
+}
115
+
116
+.jBox-Modal .jBox-container {
117
+  border-radius: 4px;
118
+}
119
+
120
+.jBox-Modal .jBox-container, .jBox-Modal.jBox-closeButton-box:before {
121
+  box-shadow: 0 3px 15px rgba(0, 0, 0, 0.4), 0 0 5px rgba(0, 0, 0, 0.4);
122
+}
123
+
124
+.jBox-Modal .jBox-content {
125
+  padding: 15px 20px;
126
+}
127
+
128
+.jBox-Modal .jBox-title {
129
+  border-radius: 4px 4px 0 0;
130
+  padding: 15px 20px;
131
+  background: #fafafa;
132
+  border-bottom: 1px solid #eee;
133
+}
134
+
135
+.jBox-Modal.jBox-closeButton-title .jBox-title {
136
+  padding-right: 65px;
137
+}
138
+
139
+.jBox-Modal .jBox-footer {
140
+  border-radius: 0 0 4px 4px;
141
+}
142
+
143
+.jBox-closeButton {
144
+  z-index: 1;
145
+  cursor: pointer;
146
+  position: absolute;
147
+  box-sizing: border-box;
148
+}
149
+
150
+.jBox-closeButton svg {
151
+  position: absolute;
152
+  top: 50%;
153
+  right: 50%;
154
+}
155
+
156
+.jBox-closeButton path {
157
+  fill: #aaa;
158
+  transition: fill .2s;
159
+}
160
+
161
+.jBox-closeButton:hover path {
162
+  fill: #888;
163
+}
164
+
165
+.jBox-overlay .jBox-closeButton {
166
+  top: 0;
167
+  right: 0;
168
+  width: 40px;
169
+  height: 40px;
170
+}
171
+
172
+.jBox-overlay .jBox-closeButton svg {
173
+  width: 20px;
174
+  height: 20px;
175
+  margin-top: -10px;
176
+  margin-right: -10px;
177
+}
178
+
179
+.jBox-overlay .jBox-closeButton path {
180
+  fill: #ddd;
181
+}
182
+
183
+.jBox-overlay .jBox-closeButton:hover path {
184
+  fill: #fff;
185
+}
186
+
187
+.jBox-closeButton-title .jBox-closeButton {
188
+  top: 0;
189
+  right: 0;
190
+  bottom: 0;
191
+  width: 50px;
192
+}
193
+
194
+.jBox-closeButton-title svg {
195
+  width: 12px;
196
+  height: 12px;
197
+  margin-top: -6px;
198
+  margin-right: -6px;
199
+}
200
+
201
+.jBox-closeButton-box {
202
+  box-sizing: border-box;
203
+}
204
+
205
+.jBox-closeButton-box .jBox-closeButton {
206
+  top: -8px;
207
+  right: -10px;
208
+  width: 24px;
209
+  height: 24px;
210
+  background: #fff;
211
+  border-radius: 50%;
212
+}
213
+
214
+.jBox-closeButton-box .jBox-closeButton svg {
215
+  width: 10px;
216
+  height: 10px;
217
+  margin-top: -5px;
218
+  margin-right: -5px;
219
+}
220
+
221
+.jBox-closeButton-box:before {
222
+  content: '';
223
+  position: absolute;
224
+  top: -8px;
225
+  right: -10px;
226
+  width: 24px;
227
+  height: 24px;
228
+  border-radius: 50%;
229
+  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
230
+}
231
+
232
+.jBox-closeButton-box.jBox-pointerPosition-top:before {
233
+  top: 5px;
234
+}
235
+
236
+.jBox-closeButton-box.jBox-pointerPosition-right:before {
237
+  right: 2px;
238
+}
239
+
240
+.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton {
241
+  background: #fafafa;
242
+}
243
+
244
+.jBox-overlay {
245
+  position: fixed;
246
+  top: 0;
247
+  left: 0;
248
+  width: 100%;
249
+  height: 100%;
250
+  background-color: rgba(0, 0, 0, 0.82);
251
+}
252
+
253
+.jBox-footer {
254
+  background: #fafafa;
255
+  border-top: 1px solid #eee;
256
+  padding: 8px 10px;
257
+  border-radius: 0 0 3px 3px;
258
+}
259
+
260
+body[class^="jBox-blockScroll-"],
261
+body[class*=" jBox-blockScroll-"] {
262
+  overflow: hidden;
263
+}
264
+
265
+.jBox-draggable {
266
+  cursor: move;
267
+}
268
+
269
+@keyframes jBoxLoading {
270
+  to {
271
+    transform: rotate(360deg);
272
+  }
273
+}
274
+
275
+.jBox-loading .jBox-content {
276
+  opacity: .2;
277
+}
278
+
279
+.jBox-loading-spinner .jBox-content {
280
+  min-height: 38px !important;
281
+  min-width: 38px !important;
282
+  opacity: 0;
283
+}
284
+
285
+.jBox-spinner {
286
+  box-sizing: border-box;
287
+  position: absolute;
288
+  top: 50%;
289
+  left: 50%;
290
+  width: 24px;
291
+  height: 24px;
292
+  margin-top: -12px;
293
+  margin-left: -12px;
294
+}
295
+
296
+.jBox-spinner:before {
297
+  display: block;
298
+  box-sizing: border-box;
299
+  content: '';
300
+  width: 24px;
301
+  height: 24px;
302
+  border-radius: 50%;
303
+  border: 2px solid rgba(0, 0, 0, 0.2);
304
+  border-top-color: rgba(0, 0, 0, 0.8);
305
+  animation: jBoxLoading .6s linear infinite;
306
+}
307
+
308
+.jBox-countdown {
309
+  border-radius: 4px 4px 0 0;
310
+  z-index: 0;
311
+  background: #000;
312
+  opacity: .2;
313
+  position: absolute;
314
+  top: 0;
315
+  left: 0;
316
+  right: 0;
317
+  height: 3px;
318
+  overflow: hidden;
319
+}
320
+
321
+.jBox-countdown-inner {
322
+  top: 0;
323
+  right: 0;
324
+  width: 100%;
325
+  height: 3px;
326
+  position: absolute;
327
+  background: #fff;
328
+}
329
+
330
+[class^="jBox-animated-"],
331
+[class*=" jBox-animated-"] {
332
+  animation-fill-mode: both;
333
+}
334
+
335
+@keyframes jBox-tada {
336
+  0% {
337
+    transform: scale(1);
338
+  }
339
+  10%,
340
+  20% {
341
+    transform: scale(0.8) rotate(-4deg);
342
+  }
343
+  30%,
344
+  50%,
345
+  70%,
346
+  90% {
347
+    transform: scale(1.2) rotate(4deg);
348
+  }
349
+  40%,
350
+  60%,
351
+  80% {
352
+    transform: scale(1.2) rotate(-4deg);
353
+  }
354
+  100% {
355
+    transform: scale(1) rotate(0);
356
+  }
357
+}
358
+
359
+.jBox-animated-tada {
360
+  animation: jBox-tada 1s;
361
+}
362
+
363
+@keyframes jBox-tadaSmall {
364
+  0% {
365
+    transform: scale(1);
366
+  }
367
+  10%,
368
+  20% {
369
+    transform: scale(0.9) rotate(-2deg);
370
+  }
371
+  30%,
372
+  50%,
373
+  70%,
374
+  90% {
375
+    transform: scale(1.1) rotate(2deg);
376
+  }
377
+  40%,
378
+  60%,
379
+  80% {
380
+    transform: scale(1.1) rotate(-2deg);
381
+  }
382
+  100% {
383
+    transform: scale(1) rotate(0);
384
+  }
385
+}
386
+
387
+.jBox-animated-tadaSmall {
388
+  animation: jBox-tadaSmall 1s;
389
+}
390
+
391
+@keyframes jBox-flash {
392
+  0%,
393
+  50%,
394
+  100% {
395
+    opacity: 1;
396
+  }
397
+  25%,
398
+  75% {
399
+    opacity: 0;
400
+  }
401
+}
402
+
403
+.jBox-animated-flash {
404
+  animation: jBox-flash .5s;
405
+}
406
+
407
+@keyframes jBox-shake {
408
+  0%,
409
+  100% {
410
+    transform: translateX(0);
411
+  }
412
+  20%,
413
+  60% {
414
+    transform: translateX(-6px);
415
+  }
416
+  40%,
417
+  80% {
418
+    transform: translateX(6px);
419
+  }
420
+}
421
+
422
+.jBox-animated-shake {
423
+  animation: jBox-shake .4s;
424
+}
425
+
426
+@keyframes jBox-pulseUp {
427
+  0% {
428
+    transform: scale(1);
429
+  }
430
+  50% {
431
+    transform: scale(1.15);
432
+  }
433
+  100% {
434
+    transform: scale(1);
435
+  }
436
+}
437
+
438
+.jBox-animated-pulseUp {
439
+  animation: jBox-pulseUp .25s;
440
+}
441
+
442
+@keyframes jBox-pulseDown {
443
+  0% {
444
+    transform: scale(1);
445
+  }
446
+  50% {
447
+    transform: scale(0.85);
448
+  }
449
+  100% {
450
+    transform: scale(1);
451
+  }
452
+}
453
+
454
+.jBox-animated-pulseDown {
455
+  animation: jBox-pulseDown .25s;
456
+}
457
+
458
+@keyframes jBox-popIn {
459
+  0% {
460
+    transform: scale(0);
461
+  }
462
+  50% {
463
+    transform: scale(1.1);
464
+  }
465
+  100% {
466
+    transform: scale(1);
467
+  }
468
+}
469
+
470
+.jBox-animated-popIn {
471
+  animation: jBox-popIn .25s;
472
+}
473
+
474
+@keyframes jBox-popOut {
475
+  0% {
476
+    transform: scale(1);
477
+  }
478
+  50% {
479
+    transform: scale(1.1);
480
+  }
481
+  100% {
482
+    transform: scale(0);
483
+  }
484
+}
485
+
486
+.jBox-animated-popOut {
487
+  animation: jBox-popOut .25s;
488
+}
489
+
490
+@keyframes jBox-fadeIn {
491
+  0% {
492
+    opacity: 0;
493
+  }
494
+  100% {
495
+    opacity: 1;
496
+  }
497
+}
498
+
499
+.jBox-animated-fadeIn {
500
+  animation: jBox-fadeIn .2s;
501
+}
502
+
503
+@keyframes jBox-fadeOut {
504
+  0% {
505
+    opacity: 1;
506
+  }
507
+  100% {
508
+    opacity: 0;
509
+  }
510
+}
511
+
512
+.jBox-animated-fadeOut {
513
+  animation: jBox-fadeOut .2s;
514
+}
515
+
516
+@keyframes jBox-slideUp {
517
+  0% {
518
+    transform: translateY(0);
519
+  }
520
+  100% {
521
+    transform: translateY(-300px);
522
+    opacity: 0;
523
+  }
524
+}
525
+
526
+.jBox-animated-slideUp {
527
+  animation: jBox-slideUp .4s;
528
+}
529
+
530
+@keyframes jBox-slideRight {
531
+  0% {
532
+    transform: translateX(0);
533
+  }
534
+  100% {
535
+    transform: translateX(300px);
536
+    opacity: 0;
537
+  }
538
+}
539
+
540
+.jBox-animated-slideRight {
541
+  animation: jBox-slideRight .4s;
542
+}
543
+
544
+@keyframes jBox-slideDown {
545
+  0% {
546
+    transform: translateY(0);
547
+  }
548
+  100% {
549
+    transform: translateY(300px);
550
+    opacity: 0;
551
+  }
552
+}
553
+
554
+.jBox-animated-slideDown {
555
+  animation: jBox-slideDown .4s;
556
+}
557
+
558
+@keyframes jBox-slideLeft {
559
+  0% {
560
+    transform: translateX(0);
561
+  }
562
+  100% {
563
+    transform: translateX(-300px);
564
+    opacity: 0;
565
+  }
566
+}
567
+
568
+.jBox-animated-slideLeft {
569
+  animation: jBox-slideLeft .4s;
570
+}
571
+
572
+/*# sourceMappingURL=jBox.css.map */
0 573
new file mode 100644
... ...
@@ -0,0 +1,2328 @@
1
+/**
2
+ * jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.
3
+ *
4
+ * Author: Stephan Wagner <stephanwagner.me@gmail.com> (https://stephanwagner.me)
5
+ *
6
+ * License: MIT (https://opensource.org/licenses/MIT)
7
+ *
8
+ * Requires: jQuery 3.5.0 (https://code.jquery.com/jquery-3.5.0.min.js)
9
+ *
10
+ * Documentation: https://stephanwagner.me/jBox/documentation
11
+ *
12
+ * Demos: https://stephanwagner.me/jBox/demos
13
+ */
14
+
15
+function jBoxWrapper(jQuery) {
16
+
17
+
18
+  var jBox = function jBox(type, options) {
19
+
20
+
21
+    // Options (https://stephanwagner.me/jBox/options)
22
+
23
+    this.options = {
24
+
25
+      // jBox ID
26
+      id: null,                    // Choose a unique id, otherwise jBox will set one for you (jBox1, jBox2, ...)
27
+
28
+      // Dimensions
29
+      width: 'auto',               // The width of the content area, e.g. 'auto', 200, '80%'
30
+      height: 'auto',              // The height of the content area
31
+      minWidth: null,              // Minimal width
32
+      minHeight: null,             // Minimal height
33
+      maxWidth: null,              // Maximal width
34
+      maxHeight: null,             // Maximal height
35
+
36
+      // Responsive dimensions
37
+      responsiveWidth: true,       // Adjusts the width to fit the viewport
38
+      responsiveHeight: true,      // Adjusts the height to fit the viewport
39
+      responsiveMinWidth: 100,     // Don't adjust width below this value (in pixel)
40
+      responsiveMinHeight: 100,    // Don't adjust height below this value (in pixel)
41
+
42
+      // Attach
43
+      attach: null,                // A jQuery selector to elements that will open and close your jBox, e.g. '.tooltip'
44
+      trigger: 'click',            // The event to open or close your jBox, use 'click', 'touchclick' or 'mouseenter'
45
+      preventDefault: false,       // Prevent the default event when opening jBox, e.g. don't follow the href in a link
46
+
47
+      // Content
48
+      content: null,               // You can use HTML or a jQuery element, e.g. jQuery('#jBox-content'). The elements will be appended to the content element and then made visible, so hide them with style="display: none" beforehand
49
+      getContent: null,            // Get the content from an attribute when jBox opens, e.g. getContent: 'data-content'. Use 'html' to get the attached elements HTML as content
50
+      title: null,                 // Adds a title to your jBox
51
+      getTitle: null,              // Get the title from an attribute when jBox opens, e.g. getTitle: 'data-title'
52
+      footer: null,                // Adds a footer to your jBox
53
+      isolateScroll: true,         // Isolates scrolling to the content container
54
+
55
+      // AJAX
56
+      ajax: {                      // Setting an URL will make an AJAX request when jBox opens. Optional you can add any jQuery AJAX option (http://api.jquery.com/jquery.ajax/)
57
+        url: null,                 // The URL to send the AJAX request to
58
+        data: '',                  // Data to send with your AJAX request, e.g. {id: 82, limit: 10}
59
+        reload: false,             // Resend the AJAX request when jBox opens. Use true to send the AJAX request only once for every attached element or 'strict' to resend every time jBox opens
60
+        getURL: 'data-url',        // The attribute in the source element where the AJAX request will look for the URL, e.g. data-url="https://reqres.in/api/users"
61
+        getData: 'data-ajax',      // The attribute in the source element where the AJAX request will look for the data, e.g. data-ajax="id=82&limit=10"
62
+        setContent: true,          // Automatically set the response as new content when the AJAX request is finished
63
+        loadingClass: true,        // Add a class to the wrapper when jBox is loading, set to class name or true to use the default class name 'jBox-loading'
64
+        spinner: true,             // Hides the current content and adds a spinner while loading. You can pass HTML content to add your own spinner, e.g. spinner: '<div class="mySpinner"></div>'
65
+        spinnerDelay: 300,         // Milliseconds to wait until spinner appears
66
+        spinnerReposition: true    // Repositions jBox when the spinner is added or removed
67
+      },
68
+      cancelAjaxOnClose: true,     // Cancels the ajax call when jBox closes and it hasn't finished loading yet
69
+
70
+      // Position
71
+      target: null,                // The jQuery selector to the target element where jBox will be opened. If no element is found, jBox will use the attached element as target
72
+      position: {
73
+        x: 'center',               // Horizontal position, use a number, 'left', 'right' or 'center'
74
+        y: 'center'                // Vertical position, use a number, 'top', 'bottom' or 'center'
75
+      },
76
+      outside: null,               // Use 'x', 'y', or 'xy' to move your jBox outside of the target element
77
+      offset: 0,                   // Offset to final position, you can set different values for x and y with an object, e.g. {x: 20, y: 10}
78
+      attributes: {                // Note that attributes can only be 'left' or 'right' when using numbers for position, e.g. {x: 300, y: 20}
79
+        x: 'left',                 // Horizontal position, use 'left' or 'right'
80
+        y: 'top'                   // Vertical position, use 'top' or 'bottom'
81
+      },
82
+      fixed: false,                // Your jBox will stay on position when scrolling
83
+      adjustPosition: true,        // Adjusts your jBoxes position if there is not enough space, use 'flip', 'move' or true for both. This option overrides the reposition options
84
+      adjustTracker: false,        // By default jBox adjusts its position when it opens or when the window size changes, set to true to also adjust when scrolling
85
+      adjustDistance: 5,           // The minimal distance to the viewport edge while adjusting. Use an object to set different values, e.g. {top: 50, right: 5, bottom: 20, left: 5}
86
+      reposition: true,            // Calculates new position when the window-size changes
87
+      repositionOnOpen: true,      // Calculates new position each time jBox opens (rather than only when it opens the first time)
88
+      repositionOnContent: true,   // Calculates new position when the content changes with .setContent() or .setTitle()
89
+      holdPosition: true,          // Keeps current position if space permits. Applies only to 'Modal' type.
90
+
91
+      // Pointer
92
+      pointer: false,              // Your pointer will always point towards the target element, so the option outside needs to be 'x' or 'y'. By default the pointer is centered, set a position to move it to any side. You can also add an offset, e.g. 'left:30' or 'center:-20'
93
+      pointTo: 'target',           // Setting something else than 'target' will add a pointer even if there is no target element set or found. Use 'top', 'right', 'bottom' or 'left'
94
+
95
+      // Animations
96
+      fade: 180,                   // Fade duration in ms, set to 0 or false to disable
97
+      animation: null,             // Animation when opening or closing, use 'pulse', 'zoomIn', 'zoomOut', 'move', 'slide', 'flip', 'tada' (CSS inspired from Daniel Edens Animate.css: http://daneden.me/animate)
98
+
99
+      // Appearance
100
+      theme: 'Default',            // Set a jBox theme class
101
+      addClass: null,              // Adds classes to the wrapper
102
+      overlay: false,              // Adds an overlay to hide page content when jBox opens (adjust color and opacity with CSS)
103
+      overlayClass: null,          // Add a class name to the overlay
104
+      zIndex: 10000,               // Use a high z-index, or set to 'auto' to bring to front on open
105
+
106
+      // Delays
107
+      delayOpen: 0,                // Delay opening in ms. Note that the delay will be ignored if your jBox didn't finish closing
108
+      delayClose: 0,               // Delay closing in ms. Nnote that there is always a closing delay of at least 10ms to ensure jBox won't be closed when opening right away
109
+
110
+      // Closing
111
+      closeOnEsc: false,           // Close jBox when pressing [esc] key
112
+      closeOnClick: false,         // Close jBox with mouseclick. Use true (click anywhere), 'box' (click on jBox itself), 'overlay' (click on the overlay), 'body' (click anywhere but jBox)
113
+      closeOnMouseleave: false,    // Close jBox when the mouse leaves the jBox area or the area of the attached element
114
+      closeButton: false,          // Adds a close button to your jBox. Use 'title', 'box', 'overlay' or true (true will add the button to the overlay, title or the jBox itself, in that order if any of those elements can be found)
115
+
116
+      // Other options
117
+      appendTo: jQuery('body'),    // The element your jBox will be appended to. Any other element than jQuery('body') is only useful for fixed positions or when position values are numbers
118
+      createOnInit: false,         // Creates jBox and makes it available in DOM when it's being initialized, otherwise it will be created when it opens for the first time
119
+      blockScroll: false,          // Blocks scrolling when jBox is open
120
+      blockScrollAdjust: true,     // Adjust page elements to avoid content jumps when scrolling is blocked. See more here: https://github.com/StephanWagner/unscroll
121
+      draggable: false,            // Make your jBox draggable (use 'true', 'title' or provide an element as handle) (inspired from Chris Coyiers CSS-Tricks http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/)
122
+      dragOver: true,              // When you have multiple draggable jBoxes, the one you select will always move over the other ones
123
+      autoClose: false,            // Time in ms when jBox will close automatically after it was opened
124
+      delayOnHover: false,         // Delay auto-closing while mouse is hovered
125
+      showCountdown: false,        // Display a nice progress-indicator when autoClose is enabled
126
+
127
+      // Audio                     // You can use the integrated audio function whenever you'd like to play an audio file, e.g. onInit: function () { this.audio('url_to_audio_file_without_file_extension', 75); }
128
+      preloadAudio: true,          // Preloads the audio files set in option audio. You can also preload other audio files, e.g. ['src_to_file.mp3', 'src_to_file.ogg']
129
+      audio: null,                 // The URL to an audio file to play when jBox opens. Set the URL without file extension, jBox will look for an .mp3 and .ogg file. To play audio when jBox closes, use an object, e.g. {open: 'src_to_audio1', close: 'src_to_audio2'}
130
+      volume: 100,                 // The volume in percent. To have different volumes for opening and closeing, use an object, e.g. {open: 75, close: 100}
131
+
132
+      // Events                    // Note that you can use 'this' in all event functions, it refers to your jBox object (e.g. onInit: function () { this.open(); })
133
+      onInit: null,                // Fired when jBox is initialized
134
+      onAttach: null,              // Fired when jBox attached itself to elements, the attached element will be passed as a parameter, e.g. onAttach: function (element) { element.css({color: 'red'}); }
135
+      onPosition: null,            // Fired when jBox is positioned
136
+      onCreated: null,             // Fired when jBox is created and availible in DOM
137
+      onOpen: null,                // Fired when jBox opens
138
+      onOpenComplete: null,        // Fired when jBox is completely open (when fading is finished)
139
+      onClose: null,               // Fired when jBox closes
140
+      onCloseComplete: null,       // Fired when jBox is completely closed (when fading is finished)
141
+      onDragStart: null,           // Fired when dragging starts
142
+      onDragEnd: null              // Fired when dragging finished
143
+    };
144
+
145
+
146
+    // Default plugin options
147
+
148
+    this._pluginOptions = {
149
+
150
+      // Default options for tooltips
151
+      'Tooltip': {
152
+        getContent: 'title',
153
+        trigger: 'mouseenter',
154
+        position: {
155
+          x: 'center',
156
+          y: 'top'
157
+        },
158
+        outside: 'y',
159
+        pointer: true
160
+      },
161
+
162
+      // Default options for mouse tooltips
163
+      'Mouse': {
164
+        responsiveWidth: false,
165
+        responsiveHeight: false,
166
+        adjustPosition: 'flip',
167
+        target: 'mouse',
168
+        trigger: 'mouseenter',
169
+        position: {
170
+          x: 'right',
171
+          y: 'bottom'
172
+        },
173
+        outside: 'xy',
174
+        offset: 5
175
+      },
176
+
177
+      // Default options for modal windows
178
+      'Modal': {
179
+        target: jQuery(window),
180
+        fixed: true,
181
+        blockScroll: true,
182
+        closeOnEsc: true,
183
+        closeOnClick: 'overlay',
184
+        closeButton: true,
185
+        overlay: true,
186
+        animation: 'zoomIn'
187
+      },
188
+    };
189
+
190
+
191
+    // Merge options
192
+
193
+    this.options = jQuery.extend(true, this.options, this._pluginOptions[type] ? this._pluginOptions[type] : jBox._pluginOptions[type], options);
194
+
195
+
196
+    // Set the jBox type
197
+
198
+    jQuery.type(type) == 'string' && (this.type = type);
199
+
200
+
201
+    // Checks if the user is on a touch device, borrowed from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
202
+
203
+    this.isTouchDevice = (function () {
204
+      var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
205
+      var mq = function (query) {
206
+        return window.matchMedia(query).matches;
207
+      }
208
+
209
+      if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
210
+        return true;
211
+      }
212
+
213
+      var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
214
+      return mq(query);
215
+    })();
216
+
217
+
218
+    // Add close event for body click when we are on touch device and jBox triggers on mouseenter
219
+
220
+    if (this.isTouchDevice && this.options.trigger === 'mouseenter' && this.options.closeOnClick === false) {
221
+      this.options.closeOnClick = 'body';
222
+    }
223
+
224
+
225
+    // Local function to fire events
226
+
227
+    this._fireEvent = function (event, pass)
228
+    {
229
+      this.options['_' + event] && (this.options['_' + event].bind(this))(pass);
230
+      this.options[event] && (this.options[event].bind(this))(pass);
231
+    };
232
+
233
+
234
+    // Get a unique jBox ID
235
+
236
+    this.options.id === null && (this.options.id = 'jBox' + jBox._getUniqueID());
237
+    this.id = this.options.id;
238
+
239
+
240
+    // Correct impossible options
241
+
242
+    ((this.options.position.x == 'center' && this.options.outside == 'x') || (this.options.position.y == 'center' && this.options.outside == 'y')) && (this.options.outside = null);
243
+    this.options.pointTo == 'target' && (!this.options.outside || this.options.outside == 'xy') && (this.options.pointer = false);
244
+
245
+
246
+    // Correct multiple choice options
247
+
248
+    jQuery.type(this.options.offset) != 'object' ? (this.options.offset = {x: this.options.offset, y: this.options.offset}) : (this.options.offset = jQuery.extend({x: 0, y: 0}, this.options.offset));
249
+    jQuery.type(this.options.adjustDistance) != 'object' ? (this.options.adjustDistance = {top: this.options.adjustDistance, right: this.options.adjustDistance, bottom: this.options.adjustDistance, left: this.options.adjustDistance}) : (this.options.adjustDistance = jQuery.extend({top: 5, left: 5, right: 5, bottom: 5}, this.options.adjustDistance));
250
+
251
+
252
+    // Save default outside position
253
+
254
+    this.outside = this.options.outside && this.options.outside != 'xy' ? this.options.position[this.options.outside] : false;
255
+
256
+
257
+    // Save where the jBox is aligned to
258
+
259
+    this.align = this.outside ? this.outside : (this.options.position.y != 'center' && jQuery.type(this.options.position.y) != 'number' ? this.options.position.x : (this.options.position.x != 'center' && jQuery.type(this.options.position.x) != 'number' ? this.options.position.y : this.options.attributes.x));
260
+
261
+
262
+    // Adjust option zIndex
263
+
264
+    jBox.zIndexMax = Math.max(jBox.zIndexMax || 0, this.options.zIndex === 'auto' ? 10000 : this.options.zIndex);
265
+    if (this.options.zIndex === 'auto') {
266
+      this.adjustZIndexOnOpen = true;
267
+      jBox.zIndexMax += 2;
268
+      this.options.zIndex = jBox.zIndexMax;
269
+      this.trueModal = this.options.overlay;
270
+    }
271
+
272
+    // Internal positioning functions
273
+
274
+    this._getOpp = function (opp) { return {left: 'right', right: 'left', top: 'bottom', bottom: 'top', x: 'y', y: 'x'}[opp]; };
275
+    this._getXY = function (xy) { return {left: 'x', right: 'x', top: 'y', bottom: 'y', center: 'x'}[xy]; };
276
+    this._getTL = function (tl) { return {left: 'left', right: 'left', top: 'top', bottom: 'top', center: 'left', x: 'left', y: 'top'}[tl]; };
277
+
278
+
279
+    // Get a dimension value in integer pixel dependent on appended element
280
+
281
+    this._getInt = function (value, dimension) {
282
+      if (value == 'auto') return 'auto';
283
+      if (value && jQuery.type(value) == 'string' && value.slice(-1) == '%') {
284
+        return jQuery(window)[dimension == 'height' ? 'innerHeight' : 'innerWidth']() * parseInt(value.replace('%', '')) / 100;
285
+      }
286
+      return value;
287
+    };
288
+
289
+
290
+    // Create an svg element
291
+
292
+    this._createSVG = function (type, options)
293
+    {
294
+      var svg = document.createElementNS('http://www.w3.org/2000/svg', type);
295
+      jQuery.each(options, function (index, item) {
296
+        svg.setAttribute(item[0], (item[1] || ''));
297
+      });
298
+      return svg;
299
+    };
300
+
301
+
302
+    // Isolate scrolling in a container
303
+
304
+    this._isolateScroll = function (el)
305
+    {
306
+      // Abort if element not found
307
+      if (!el || !el.length) return;
308
+
309
+      el.on('DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll', function (ev) {
310
+        var delta = ev.wheelDelta || (ev.originalEvent && ev.originalEvent.wheelDelta) || -ev.detail;
311
+        var overflowBottom = this.scrollTop + el.outerHeight() - this.scrollHeight >= 0;
312
+        var overflowTop = this.scrollTop <= 0;
313
+        ((delta < 0 && overflowBottom) || (delta > 0 && overflowTop)) && ev.preventDefault();
314
+      });
315
+    };
316
+
317
+
318
+    // Set the title width to content width
319
+
320
+    this._setTitleWidth = function ()
321
+    {
322
+      // Abort if there is no title or width of content is auto
323
+      if (!this.titleContainer || (this.content[0].style.width == 'auto' && !this.content[0].style.maxWidth)) return null;
324
+
325
+      // Expose wrapper to get actual width
326
+      if (this.wrapper.css('display') == 'none') {
327
+        this.wrapper.css('display', 'block');
328
+        var contentWidth = this.content.outerWidth();
329
+        this.wrapper.css('display', 'none');
330
+      } else {
331
+        var contentWidth = this.content.outerWidth();
332
+      }
333
+
334
+      // Set max-width only
335
+      this.titleContainer.css({maxWidth: (Math.max(contentWidth, parseInt(this.content[0].style.maxWidth)) || null)});
336
+    }
337
+
338
+
339
+    // Make jBox draggable
340
+
341
+    this._draggable = function ()
342
+    {
343
+      // Abort if jBox is not draggable
344
+      if (!this.options.draggable) return false;
345
+
346
+      // Get the handle where jBox will be dragged with
347
+      var handle = this.options.draggable == 'title' ? this.titleContainer : (this.options.draggable instanceof jQuery ? this.options.draggable : (jQuery.type(this.options.draggable) == 'string' ? jQuery(this.options.draggable) : this.wrapper));
348
+
349
+      // Abort if no handle or if draggable was set already
350
+      if (!handle || !(handle instanceof jQuery) || !handle.length || handle.data('jBox-draggable')) {
351
+        return false;
352
+      }
353
+
354
+      // Add mouse events
355
+      handle.addClass('jBox-draggable').data('jBox-draggable', true).on('touchstart mousedown', function (ev)
356
+      {
357
+        if (ev.button == 2 || jQuery(ev.target).hasClass('jBox-noDrag') || jQuery(ev.target).parents('.jBox-noDrag').length) {
358
+          // Hacky fix for jBox not closing on mobile devices when using draggable
359
+          if (ev.type == 'touchstart' && (jQuery(ev.target).hasClass('jBox-closeButton') || jQuery(ev.target).parents('.jBox-closeButton').length)) {
360
+            this.close({ignoreDelay: true});
361
+          }
362
+          return;
363
+        }
364
+
365
+        var pageX;
366
+        var pageY;
367
+
368
+        if (ev.type == 'touchstart' && ev.touches && ev.touches[0]) {
369
+          pageX = ev.touches[0].pageX;
370
+          pageY = ev.touches[0].pageY;
371
+        } else {
372
+          pageX = ev.pageX;
373
+          pageY = ev.pageY;
374
+        }
375
+
376
+        // Store current mouse position
377
+        this.draggingStartX = pageX;
378
+        this.draggingStartY = pageY;
379
+
380
+        // Adjust z-index when dragging jBox over another draggable jBox
381
+        if (this.options.dragOver && !this.trueModal && parseInt(this.wrapper.css('zIndex'), 10) <= jBox.zIndexMaxDragover) {
382
+          jBox.zIndexMaxDragover += 1;
383
+          this.wrapper.css('zIndex', jBox.zIndexMaxDragover);
384
+        }
385
+
386
+        var drg_h = this.wrapper.outerHeight();
387
+        var drg_w = this.wrapper.outerWidth();
388
+        var pos_y = this.wrapper.offset().top + drg_h - pageY;
389
+        var pos_x = this.wrapper.offset().left + drg_w - pageX;
390
+
391
+        jQuery(document).on('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id, function (ev) {
392
+
393
+          var movingPageX;
394
+          var movingPageY;
395
+
396
+          if (ev.type == 'touchmove' && ev.touches && ev.touches[0]) {
397
+            movingPageX = ev.touches[0].pageX;
398
+            movingPageY = ev.touches[0].pageY;
399
+          } else {
400
+            movingPageX = ev.pageX;
401
+            movingPageY = ev.pageY;
402
+          }
403
+
404
+          // Fire onDragStart event when jBox moves
405
+          if (!this.dragging && this.draggingStartX != movingPageX && this.draggingStartY != movingPageY) {
406
+            this._fireEvent('onDragStart');
407
+            this.dragging = true;
408
+          }
409
+
410
+          // Adjust position
411
+          this.wrapper.offset({
412
+            top: movingPageY + pos_y - drg_h,
413
+            left: movingPageX + pos_x - drg_w
414
+          });
415
+        }.bind(this));
416
+        ev.preventDefault();
417
+
418
+      }.bind(this)).on('touchend mouseup', function () {
419
+        // Remove drag event
420
+        jQuery(document).off('touchmove.jBox-draggable-' + this.id + ' mousemove.jBox-draggable-' + this.id);
421
+
422
+        // Fire onDragEnd event
423
+        this.dragging && this._fireEvent('onDragEnd');
424
+
425
+        // Reset dragging reference
426
+        this.dragging = false;
427
+
428
+        if ((this.type == 'Modal' || this.type == 'Confirm') && this.options.holdPosition) {
429
+          // Drag end captures new position
430
+          var jBoxOffset = jQuery('#' + this.id).offset(),
431
+            pos = {
432
+              x: jBoxOffset.left - jQuery(document).scrollLeft(),
433
+              y: jBoxOffset.top - jQuery(document).scrollTop()
434
+            };
435
+          this.position({position: pos, offset: {x: 0, y: 0}});
436
+        }
437
+      }.bind(this));
438
+
439
+      // Get highest z-index
440
+      if (!this.trueModal) {
441
+        jBox.zIndexMaxDragover = !jBox.zIndexMaxDragover ? this.options.zIndex : Math.max(jBox.zIndexMaxDragover, this.options.zIndex);
442
+      }
443
+
444
+      return this;
445
+    };
446
+
447
+    // Create jBox
448
+
449
+    this._create = function ()
450
+    {
451
+      // Abort if jBox was created already
452
+      if (this.wrapper) return;
453
+
454
+      // Create wrapper
455
+      this.wrapper = jQuery('<div/>', {
456
+        id: this.id,
457
+        'class': 'jBox-wrapper' + (this.type ? ' jBox-' + this.type : '') + (this.options.theme ? ' jBox-' + this.options.theme : '') + (this.options.addClass ? ' ' + this.options.addClass : '')
458
+      }).css({
459
+        position: (this.options.fixed ? 'fixed' : 'absolute'),
460
+        display: 'none',
461
+        opacity: 0,
462
+        zIndex: this.options.zIndex
463
+
464
+        // Save the jBox instance in the wrapper, so you can get access to your jBox when you only have the element
465
+      }).data('jBox', this);
466
+
467
+      // Add mouseleave event, only close jBox when the new target is not the source element
468
+      this.options.closeOnMouseleave && this.wrapper.on('mouseleave', function (ev) {
469
+        !this.source || !(ev.relatedTarget == this.source[0] || jQuery.inArray(this.source[0], jQuery(ev.relatedTarget).parents('*')) !== -1) && this.close();
470
+      }.bind(this));
471
+
472
+      // Add closeOnClick: 'box' events
473
+      (this.options.closeOnClick == 'box') && this.wrapper.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
474
+
475
+      // Create container
476
+      this.container = jQuery('<div class="jBox-container"/>').appendTo(this.wrapper);
477
+
478
+      // Create content
479
+      this.content = jQuery('<div class="jBox-content"/>').appendTo(this.container);
480
+
481
+      // Create footer
482
+      this.options.footer && (this.footer = jQuery('<div class="jBox-footer"/>').append(this.options.footer).appendTo(this.container));
483
+
484
+      // Isolate scrolling
485
+      this.options.isolateScroll && this._isolateScroll(this.content);
486
+
487
+      // Create close button
488
+      if (this.options.closeButton) {
489
+        var closeButtonSVG = this._createSVG('svg', [['viewBox', '0 0 24 24']]);
490
+        closeButtonSVG.appendChild(this._createSVG('path', [['d', 'M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z']]));
491
+        this.closeButton = jQuery('<div class="jBox-closeButton jBox-noDrag"/>').on('click tap', function (ev) { this.close({ignoreDelay: true}); }.bind(this)).append(closeButtonSVG);
492
+
493
+        // Add close button to jBox container
494
+        if (this.options.closeButton == 'box' || (this.options.closeButton === true && !this.options.overlay && !this.options.title && !this.options.getTitle)) {
495
+          this.wrapper.addClass('jBox-closeButton-box');
496
+          this.closeButton.appendTo(this.container);
497
+        }
498
+      }
499
+
500
+      // Append jBox to DOM
501
+      this.wrapper.appendTo(this.options.appendTo);
502
+
503
+      // Fix adjustDistance if there is a close button in the box
504
+      this.wrapper.find('.jBox-closeButton').length &&  jQuery.each(['top', 'right', 'bottom', 'left'], function (index, pos) {
505
+        this.wrapper.find('.jBox-closeButton').css(pos) && this.wrapper.find('.jBox-closeButton').css(pos) != 'auto' && (this.options.adjustDistance[pos] = Math.max(this.options.adjustDistance[pos], this.options.adjustDistance[pos] + (((parseInt(this.wrapper.find('.jBox-closeButton').css(pos)) || 0) + (parseInt(this.container.css('border-' + pos + '-width')) || 0)) * -1)));
506
+      }.bind(this));
507
+
508
+      // Create pointer
509
+      if (this.options.pointer) {
510
+
511
+        // Get pointer vars and save globally
512
+        this.pointer = {
513
+          position: (this.options.pointTo != 'target') ? this.options.pointTo : this._getOpp(this.outside),
514
+          xy: (this.options.pointTo != 'target') ? this._getXY(this.options.pointTo) : this._getXY(this.outside),
515
+          align: 'center',
516
+          offset: 0
517
+        };
518
+
519
+        this.pointer.element = jQuery('<div class="jBox-pointer jBox-pointer-' + this.pointer.position + '"/>').appendTo(this.wrapper);
520
+        this.pointer.dimensions = {
521
+          x: this.pointer.element.outerWidth(),
522
+          y: this.pointer.element.outerHeight()
523
+        };
524
+
525
+        if (jQuery.type(this.options.pointer) == 'string') {
526
+          var split = this.options.pointer.split(':');
527
+          split[0] && (this.pointer.align = split[0]);
528
+          split[1] && (this.pointer.offset = parseInt(split[1]));
529
+        }
530
+        this.pointer.alignAttribute = (this.pointer.xy == 'x' ? (this.pointer.align == 'bottom' ? 'bottom' : 'top') : (this.pointer.align == 'right' ? 'right' : 'left'));
531
+
532
+        // Set wrapper CSS
533
+        this.wrapper.css('padding-' + this.pointer.position, this.pointer.dimensions[this.pointer.xy]);
534
+
535
+        // Set pointer CSS
536
+        this.pointer.element.css(this.pointer.alignAttribute, (this.pointer.align == 'center' ? '50%' : 0)).css('margin-' + this.pointer.alignAttribute, this.pointer.offset);
537
+        this.pointer.margin = {};
538
+        this.pointer.margin['margin-' + this.pointer.alignAttribute] = this.pointer.offset;
539
+
540
+        // Add a transform to fix centered position
541
+        (this.pointer.align == 'center') && this.pointer.element.css('transform', 'translate(' + (this.pointer.xy == 'y' ? (this.pointer.dimensions.x * -0.5 + 'px') : 0) + ', ' + (this.pointer.xy == 'x' ? (this.pointer.dimensions.y * -0.5 + 'px') : 0) + ')');
542
+
543
+        this.pointer.element.css((this.pointer.xy == 'x' ? 'width' : 'height'), parseInt(this.pointer.dimensions[this.pointer.xy]) + parseInt(this.container.css('border-' + this.pointer.alignAttribute + '-width')));
544
+
545
+        // Add class to wrapper for CSS access
546
+        this.wrapper.addClass('jBox-pointerPosition-' + this.pointer.position);
547
+      }
548
+
549
+      // Set title and content
550
+      this.setContent(this.options.content, true);
551
+      this.setTitle(this.options.title, true);
552
+
553
+      this.options.draggable && this._draggable();
554
+
555
+      // Fire onCreated event
556
+      this._fireEvent('onCreated');
557
+    };
558
+
559
+
560
+    // Create jBox onInit
561
+
562
+    this.options.createOnInit && this._create();
563
+
564
+
565
+    // Attach jBox
566
+
567
+    this.options.attach && this.attach();
568
+
569
+
570
+    // Attach document and window events
571
+
572
+    this._attachEvents = function ()
573
+    {
574
+      // Cancel countdown on mouseenter if delayOnHover
575
+      this.options.delayOnHover && jQuery('#' + this.id).on('mouseenter', function (ev) { this.isHovered = true; }.bind(this));
576
+
577
+      // Resume countdown on mouseleave if delayOnHover
578
+      this.options.delayOnHover && jQuery('#' + this.id).on('mouseleave', function (ev) { this.isHovered = false; }.bind(this));
579
+
580
+      // Positioning events
581
+      if ((this.options.adjustPosition || this.options.reposition) && !this.fixed && this.outside) {
582
+
583
+        // Trigger position events when scrolling
584
+        this.options.adjustTracker && jQuery(window).on('scroll.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
585
+
586
+        // Trigger position events when resizing
587
+        (this.options.adjustPosition || this.options.reposition) && jQuery(window).on('resize.jBox-' + this.id, function (ev) { this.position(); }.bind(this));
588
+      }
589
+
590
+      // Mousemove events
591
+      this.options.target == 'mouse' && jQuery('body').on('mousemove.jBox-' + this.id, function (ev) { this.position({mouseTarget: {top: ev.pageY, left: ev.pageX}}); }.bind(this));
592
+    };
593
+
594
+
595
+    // Detach document and window events
596
+
597
+    this._detachEvents = function ()
598
+    {
599
+      // Closing event: closeOnEsc
600
+      this.options.closeOnEsc && jQuery(document).off('keyup.jBox-' + this.id);
601
+
602
+      // Closing event: closeOnClick
603
+      (this.options.closeOnClick === true || this.options.closeOnClick == 'body') && jQuery(document).off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
604
+
605
+      // Positioning events
606
+      this.options.adjustTracker && jQuery(window).off('scroll.jBox-' + this.id);
607
+      (this.options.adjustPosition || this.options.reposition) && jQuery(window).off('resize.jBox-' + this.id);
608
+
609
+      // Mousemove events
610
+      this.options.target == 'mouse' && jQuery('body').off('mousemove.jBox-' + this.id);
611
+    };
612
+
613
+
614
+    // Show overlay
615
+
616
+    this._showOverlay = function ()
617
+    {
618
+      // Create the overlay if wasn't created already
619
+      if (!this.overlay) {
620
+
621
+        // Create element and append to the element where jBox is appended to
622
+        this.overlay = jQuery('<div id="' + this.id + '-overlay"/>').addClass('jBox-overlay' + (this.type ? ' jBox-overlay-' + this.type : '')).css({
623
+          display: 'none',
624
+          opacity: 0,
625
+          zIndex: this.options.zIndex - 1
626
+        }).appendTo(this.options.appendTo);
627
+
628
+        // Add a class name to the overlay
629
+        this.options.overlayClass && this.overlay.addClass(this.options.overlayClass);
630
+
631
+        // Add close button to overlay
632
+        (this.options.closeButton == 'overlay' || this.options.closeButton === true) && this.overlay.append(this.closeButton);
633
+
634
+        // Add closeOnClick: 'overlay' events
635
+        this.options.closeOnClick == 'overlay' && this.overlay.on('click tap', function () { this.close({ignoreDelay: true}); }.bind(this));
636
+
637
+        // Adjust option adjustDistance if there is a close button in the overlay
638
+        jQuery('#' + this.id + '-overlay .jBox-closeButton').length && (this.options.adjustDistance.top = Math.max(jQuery('#' + this.id + '-overlay .jBox-closeButton').outerHeight(), this.options.adjustDistance.top));
639
+      }
640
+
641
+      // Adjust zIndex
642
+      if (this.adjustZIndexOnOpen === true) {
643
+        this.overlay.css('zIndex', parseInt(this.wrapper.css('zIndex'), 10) - 1);
644
+      }
645
+
646
+      // Abort if overlay is already visible
647
+      if (this.overlay.css('display') == 'block') return;
648
+
649
+      // Show overlay
650
+      this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 1}, {
651
+        queue: false,
652
+        duration: this.options.fade,
653
+        start: function () { this.overlay.css({display: 'block'}); }.bind(this)
654
+      })) : this.overlay.css({display: 'block', opacity: 1});
655
+    };
656
+
657
+
658
+    // Hide overlay
659
+
660
+    this._hideOverlay = function ()
661
+    {
662
+      // Abort if the overlay wasn't created yet
663
+      if (!this.overlay) return;
664
+
665
+      // Hide overlay if no other jBox needs it
666
+      this.options.fade ? (this.overlay.stop() && this.overlay.animate({opacity: 0}, {
667
+        queue: false,
668
+        duration: this.options.fade,
669
+        complete: function () { this.overlay.css({display: 'none'}); }.bind(this)
670
+      })) : this.overlay.css({display: 'none', opacity: 0});
671
+    };
672
+
673
+
674
+    // Get the correct jBox dimensions by moving jBox out of viewport
675
+
676
+    this._exposeDimensions = function ()
677
+    {
678
+      // Move wrapper out of viewport
679
+      this.wrapper.css({
680
+        top: -10000,
681
+        left: -10000,
682
+        right: 'auto',
683
+        bottom: 'auto'
684
+      });
685
+
686
+      // Get jBox dimensions
687
+      var jBoxDimensions = {
688
+        x: this.wrapper.outerWidth(),
689
+        y: this.wrapper.outerHeight()
690
+      };
691
+
692
+      // Reset position to viewport
693
+      this.wrapper.css({
694
+        top: 'auto',
695
+        left: 'auto'
696
+      });
697
+
698
+      return jBoxDimensions;
699
+    };
700
+
701
+
702
+    // Generate CSS for animations and append to header
703
+
704
+    this._generateAnimationCSS = function ()
705
+    {
706
+      // Get open and close animations if none provided
707
+      (jQuery.type(this.options.animation) != 'object') && (this.options.animation = {
708
+        pulse: {open: 'pulse', close: 'zoomOut'},
709
+        zoomIn: {open: 'zoomIn', close: 'zoomIn'},
710
+        zoomOut: {open: 'zoomOut', close: 'zoomOut'},
711
+        move: {open: 'move', close: 'move'},
712
+        slide: {open: 'slide', close: 'slide'},
713
+        flip: {open: 'flip', close: 'flip'},
714
+        tada: {open: 'tada', close: 'zoomOut'}
715
+      }[this.options.animation]);
716
+
717
+      // Abort if animation not found
718
+      if (!this.options.animation) return null;
719
+
720
+      // Get direction var
721
+      this.options.animation.open && (this.options.animation.open = this.options.animation.open.split(':'));
722
+      this.options.animation.close && (this.options.animation.close = this.options.animation.close.split(':'));
723
+      this.options.animation.openDirection = this.options.animation.open[1] ? this.options.animation.open[1] : null;
724
+      this.options.animation.closeDirection = this.options.animation.close[1] ? this.options.animation.close[1] : null;
725
+      this.options.animation.open && (this.options.animation.open = this.options.animation.open[0]);
726
+      this.options.animation.close && (this.options.animation.close = this.options.animation.close[0]);
727
+
728
+      // Add 'Open' and 'Close' to animation names
729
+      this.options.animation.open && (this.options.animation.open += 'Open');
730
+      this.options.animation.close && (this.options.animation.close += 'Close');
731
+
732
+      // All animations
733
+      var animations = {
734
+        pulse: {
735
+          duration: 350,
736
+          css: [['0%', 'scale(1)'], ['50%', 'scale(1.1)'], ['100%', 'scale(1)']]
737
+        },
738
+        zoomInOpen: {
739
+          duration: (this.options.fade || 180),
740
+          css: [['0%', 'scale(0.9)'], ['100%', 'scale(1)']]
741
+        },
742
+        zoomInClose: {
743
+          duration: (this.options.fade || 180),
744
+          css: [['0%', 'scale(1)'], ['100%', 'scale(0.9)']]
745
+        },
746
+        zoomOutOpen: {
747
+          duration: (this.options.fade || 180),
748
+          css: [['0%', 'scale(1.1)'], ['100%', 'scale(1)']]
749
+        },
750
+        zoomOutClose: {
751
+          duration: (this.options.fade || 180),
752
+          css: [['0%', 'scale(1)'], ['100%', 'scale(1.1)']]
753
+        },
754
+        moveOpen: {
755
+          duration: (this.options.fade || 180),
756
+          positions: {top: {'0%': -12}, right: {'0%': 12}, bottom: {'0%': 12}, left: {'0%': -12}},
757
+          css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
758
+        },
759
+        moveClose: {
760
+          duration: (this.options.fade || 180),
761
+          timing: 'ease-in',
762
+          positions: {top: {'100%': -12}, right: {'100%': 12}, bottom: {'100%': 12}, left: {'100%': -12}},
763
+          css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
764
+        },
765
+        slideOpen: {
766
+          duration: 400,
767
+          positions: {top: {'0%': -400}, right: {'0%': 400}, bottom: {'0%': 400}, left: {'0%': -400}},
768
+          css: [['0%', 'translate%XY(%Vpx)'], ['100%', 'translate%XY(0px)']]
769
+        },
770
+        slideClose: {
771
+          duration: 400,
772
+          timing: 'ease-in',
773
+          positions: {top: {'100%': -400}, right: {'100%': 400}, bottom: {'100%': 400}, left: {'100%': -400}},
774
+          css: [['0%', 'translate%XY(0px)'], ['100%', 'translate%XY(%Vpx)']]
775
+        },
776
+        flipOpen: {
777
+          duration: 600,
778
+          css: [['0%', 'perspective(400px) rotateX(90deg)'], ['40%', 'perspective(400px) rotateX(-15deg)'], ['70%', 'perspective(400px) rotateX(15deg)'], ['100%', 'perspective(400px) rotateX(0deg)']]
779
+        },
780
+        flipClose: {
781
+          duration: (this.options.fade || 300),
782
+          css: [['0%', 'perspective(400px) rotateX(0deg)'], ['100%', 'perspective(400px) rotateX(90deg)']]
783
+        },
784
+        tada: {
785
+          duration: 800,
786
+          css: [['0%', 'scale(1)'], ['10%, 20%', 'scale(0.9) rotate(-3deg)'], ['30%, 50%, 70%, 90%', 'scale(1.1) rotate(3deg)'], ['40%, 60%, 80%', 'scale(1.1) rotate(-3deg)'], ['100%', 'scale(1) rotate(0)']]
787
+        }
788
+      };
789
+
790
+      // Set Open and Close names for standalone animations
791
+      jQuery.each(['pulse', 'tada'], function (index, item) { animations[item + 'Open'] = animations[item + 'Close'] = animations[item]; });
792
+
793
+      // Function to generate the CSS for the keyframes
794
+      var generateKeyframeCSS = function (ev, position)
795
+      {
796
+        // Generate keyframes CSS
797
+        var keyframe_css = '@keyframes jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
798
+        jQuery.each(animations[this.options.animation[ev]].css, function (index, item) {
799
+          var translate = position ? item[1].replace('%XY', this._getXY(position).toUpperCase()) : item[1];
800
+          animations[this.options.animation[ev]].positions && (translate = translate.replace('%V', animations[this.options.animation[ev]].positions[position][item[0]]));
801
+          keyframe_css += item[0] + ' {transform:' + translate + ';}';
802
+
803
+        }.bind(this));
804
+        keyframe_css += '}';
805
+
806
+        // Generate class CSS
807
+        keyframe_css += '.jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ' {';
808
+        keyframe_css += 'animation-duration: ' + animations[this.options.animation[ev]].duration + 'ms;';
809
+        keyframe_css += 'animation-name: jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + (position ? '-' + position : '') + ';';
810
+        keyframe_css += animations[this.options.animation[ev]].timing ? ('animation-timing-function: ' + animations[this.options.animation[ev]].timing + ';') : '';
811
+        keyframe_css += '}';
812
+
813
+        return keyframe_css;
814
+      }.bind(this);
815
+
816
+      // Generate css for each event and positions
817
+      this._animationCSS = '';
818
+      jQuery.each(['open', 'close'], function (index, ev)
819
+      {
820
+        // No CSS needed for closing with no fade
821
+        if (!this.options.animation[ev] || !animations[this.options.animation[ev]] || (ev == 'close' && !this.options.fade)) return '';
822
+
823
+        // Generate CSS
824
+        animations[this.options.animation[ev]].positions ?
825
+          jQuery.each(['top', 'right', 'bottom', 'left'], function (index2, position) { this._animationCSS += generateKeyframeCSS(ev, position); }.bind(this)) :
826
+          this._animationCSS += generateKeyframeCSS(ev);
827
+      }.bind(this));
828
+
829
+    };
830
+
831
+
832
+    // Add css for animations
833
+
834
+    this.options.animation && this._generateAnimationCSS();
835
+
836
+
837
+    // Block body clicks for 10ms to prevent extra event triggering
838
+
839
+    this._blockBodyClick = function ()
840
+    {
841
+      this.blockBodyClick = true;
842
+      setTimeout(function () { this.blockBodyClick = false; }.bind(this), 10);
843
+    };
844
+
845
+
846
+    // Animations
847
+
848
+    this._animate = function (ev)
849
+    {
850
+      // The event which triggers the animation
851
+      !ev && (ev = this.isOpen ? 'open' : 'close');
852
+
853
+      // Don't animate when closing with no fade duration
854
+      if (!this.options.fade && ev == 'close') return null;
855
+
856
+      // Get the current position, use opposite if jBox is flipped
857
+      var animationDirection = (this.options.animation[ev + 'Direction'] || ((this.align != 'center') ? this.align : this.options.attributes.x));
858
+      this.flipped && this._getXY(animationDirection) == (this._getXY(this.align)) && (animationDirection = this._getOpp(animationDirection));
859
+
860
+      // Add event and position classes
861
+      var classnames = 'jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + ' jBox-' + this.id + '-animation-' + this.options.animation[ev] + '-' + ev + '-' + animationDirection;
862
+      this.wrapper.addClass(classnames);
863
+
864
+      // Get duration of animation
865
+      var animationDuration = parseFloat(this.wrapper.css('animation-duration')) * 1000;
866
+      ev == 'close' && (animationDuration = Math.min(animationDuration, this.options.fade));
867
+
868
+      // Remove animation classes when animation is finished
869
+      setTimeout(function () {
870
+        this.wrapper && this.wrapper.removeClass(classnames);
871
+      }.bind(this), animationDuration);
872
+    };
873
+
874
+
875
+    // Abort an animation
876
+
877
+    this._abortAnimation = function ()
878
+    {
879
+      // Remove all animation classes
880
+      var classes = this.wrapper.attr('class').split(' ').filter(function (c) {
881
+        return c.lastIndexOf('jBox-' + this.id + '-animation', 0) !== 0;
882
+      }.bind(this));
883
+      this.wrapper.attr('class', classes.join(' '));
884
+    };
885
+
886
+
887
+    // Adjust dimensions when browser is resized
888
+
889
+    if (this.options.responsiveWidth || this.options.responsiveHeight)
890
+    {
891
+      // Responsive positioning overrides options adjustPosition and reposition
892
+      // TODO: Only add this resize event when the other one from adjustPosition and reposition was not set
893
+      jQuery(window).on('resize.responsivejBox-' + this.id, function (ev) { if (this.isOpen) { this.position(); } }.bind(this));
894
+    }
895
+
896
+
897
+    // Fix audio options
898
+
899
+    jQuery.type(this.options.preloadAudio) === 'string' && (this.options.preloadAudio = [this.options.preloadAudio]);
900
+    jQuery.type(this.options.audio) === 'string' && (this.options.audio = {open: this.options.audio});
901
+    jQuery.type(this.options.volume) === 'number' && (this.options.volume = {open: this.options.volume, close: this.options.volume});
902
+
903
+    if (this.options.preloadAudio === true && this.options.audio) {
904
+      this.options.preloadAudio = [];
905
+      jQuery.each(this.options.audio, function (index, url) {
906
+        this.options.preloadAudio.push(url + '.mp3');
907
+        this.options.preloadAudio.push(url + '.ogg');
908
+      }.bind(this));
909
+    }
910
+
911
+
912
+    // Preload audio files
913
+
914
+    this.options.preloadAudio.length && jQuery.each(this.options.preloadAudio, function (index, url) {
915
+      var audio = new Audio();
916
+      audio.src = url;
917
+      audio.preload = 'auto';
918
+    });
919
+
920
+
921
+    // Fire onInit event
922
+
923
+    this._fireEvent('onInit');
924
+
925
+
926
+    return this;
927
+  };
928
+
929
+
930
+  // Attach jBox to elements
931
+
932
+  jBox.prototype.attach = function (elements, trigger)
933
+  {
934
+    // Get elements from options if none passed
935
+    !elements && (elements = this.options.attach);
936
+
937
+    // Convert selectors to jQuery objects
938
+    jQuery.type(elements) == 'string' && (elements = jQuery(elements));
939
+
940
+    // Get trigger event from options if not passed
941
+    !trigger && (trigger = this.options.trigger);
942
+
943
+    // Loop through elements and attach jBox
944
+    elements && elements.length && jQuery.each(elements, function (index, el) {
945
+      el = jQuery(el);
946
+
947
+      // Only attach if the element wasn't attached to this jBox already
948
+      if (!el.data('jBox-attached-' + this.id)) {
949
+
950
+        // Remove title attribute and store content on element
951
+        (this.options.getContent == 'title' && el.attr('title') != undefined) && el.data('jBox-getContent', el.attr('title')).removeAttr('title');
952
+
953
+        // Add Element to collection
954
+        this.attachedElements || (this.attachedElements = []);
955
+        this.attachedElements.push(el[0]);
956
+
957
+        // Add click or mouseenter event, click events can prevent default as well
958
+        el.on(trigger + '.jBox-attach-' + this.id, function (ev)
959
+        {
960
+          // Clear timer
961
+          this.timer && clearTimeout(this.timer);
962
+
963
+          // Block opening when jbox is open and the source element is triggering
964
+          if (trigger == 'mouseenter' && this.isOpen && this.source[0] == el[0]) return;
965
+
966
+          // Only close jBox if you click the current target element, otherwise open at new target
967
+          if (this.isOpen && this.source && this.source[0] != el[0]) var forceOpen = true;
968
+
969
+          // Set new source element
970
+          this.source = el;
971
+
972
+          // Set new target
973
+          !this.options.target && (this.target = el);
974
+
975
+          // Prevent default action on click
976
+          trigger == 'click' && this.options.preventDefault && ev.preventDefault();
977
+
978
+          // Toggle or open jBox
979
+          this[trigger == 'click' && !forceOpen ? 'toggle' : 'open']();
980
+
981
+        }.bind(this));
982
+
983
+        // Add close event for trigger event mouseenter
984
+        (this.options.trigger == 'mouseenter') && el.on('mouseleave', function (ev)
985
+        {
986
+          // Abort if jBox wasn't created yet
987
+          if (!this.wrapper) return null;
988
+
989
+          // If we have set closeOnMouseleave, do not close jBox when leaving attached element and mouse is over jBox
990
+          if (!this.options.closeOnMouseleave || !(ev.relatedTarget == this.wrapper[0] || jQuery(ev.relatedTarget).parents('#' + this.id).length)) this.close();
991
+        }.bind(this));
992
+
993
+        // Store
994
+        el.data('jBox-attached-' + this.id, trigger);
995
+
996
+        // Fire onAttach event
997
+        this._fireEvent('onAttach', el);
998
+      }
999
+
1000
+    }.bind(this));
1001
+
1002
+    return this;
1003
+  };
1004
+
1005
+
1006
+  // Detach jBox from elements
1007
+
1008
+  jBox.prototype.detach = function (elements)
1009
+  {
1010
+    // Get elements from stores elements if none passed
1011
+    !elements && (elements = this.attachedElements || []);
1012
+
1013
+    elements && elements.length && jQuery.each(elements, function (index, el) {
1014
+      el = jQuery(el);
1015
+
1016
+      // Remove events
1017
+      if (el.data('jBox-attached-' + this.id)) {
1018
+        el.off(el.data('jBox-attached-' + this.id) + '.jBox-attach-' + this.id);
1019
+        el.data('jBox-attached-' + this.id, null);
1020
+      }
1021
+      // Remove element from collection
1022
+      this.attachedElements = jQuery.grep(this.attachedElements, function (value) {
1023
+        return value != el[0];
1024
+      });
1025
+    }.bind(this));
1026
+
1027
+    return this;
1028
+  };
1029
+
1030
+
1031
+  // Set title
1032
+
1033
+  jBox.prototype.setTitle = function (title, ignore_positioning)
1034
+  {
1035
+    // Abort if title to set
1036
+    if (title == null || title == undefined) return this;
1037
+
1038
+    // Create jBox if it wasn't created already
1039
+    !this.wrapper && this._create();
1040
+
1041
+    // Get the width and height of wrapper, only if they change we need to reposition
1042
+    var wrapperHeight = this.wrapper.outerHeight();
1043
+    var wrapperWidth = this.wrapper.outerWidth();
1044
+
1045
+    // Create title elements if they weren't created already
1046
+    if (!this.title) {
1047
+      this.titleContainer = jQuery('<div class="jBox-title"/>');
1048
+      this.title = jQuery('<div/>').appendTo(this.titleContainer);
1049
+      if (this.options.closeButton == 'title' || (this.options.closeButton === true && !this.options.overlay)) {
1050
+        this.wrapper.addClass('jBox-closeButton-title');
1051
+        this.closeButton.appendTo(this.titleContainer);
1052
+      }
1053
+      this.titleContainer.insertBefore(this.content);
1054
+      this._setTitleWidth();
1055
+    }
1056
+
1057
+    // Add or remove wrapper class
1058
+    this.wrapper[title ? 'addClass' : 'removeClass']('jBox-hasTitle');
1059
+
1060
+    // Set title html
1061
+    this.title.html(title);
1062
+
1063
+    // Adjust width of title
1064
+    wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
1065
+
1066
+    // Make jBox draggable
1067
+    this.options.draggable && this._draggable();
1068
+
1069
+    // Reposition if dimensions changed
1070
+    !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
1071
+
1072
+    return this;
1073
+  };
1074
+
1075
+
1076
+  // Set content
1077
+
1078
+  jBox.prototype.setContent = function (content, ignore_positioning)
1079
+  {
1080
+    // Abort if no content to set
1081
+    if (content == null || content == undefined) return this;
1082
+
1083
+    // Create jBox if it wasn't created already
1084
+    !this.wrapper && this._create();
1085
+
1086
+    // Get the width and height of wrapper, only if they change we need to reposition
1087
+    var wrapperHeight = this.wrapper.outerHeight();
1088
+    var wrapperWidth = this.wrapper.outerWidth();
1089
+
1090
+    // Move all appended containers to body
1091
+    this.content.children('[data-jbox-content-appended]').appendTo('body').css({display: 'none'});
1092
+
1093
+    // Set the new content
1094
+    switch (jQuery.type(content)) {
1095
+      case 'string':
1096
+        this.content.html(content);
1097
+        break;
1098
+      case 'object':
1099
+        if (content && (content instanceof jQuery || content.constructor.prototype.jquery)) {
1100
+          this.content.html('');
1101
+          content.attr('data-jbox-content-appended', 1).appendTo(this.content).css({display: 'block'});
1102
+        } else {
1103
+          this.content.html(JSON.stringify(content));
1104
+        }
1105
+        break;
1106
+     }
1107
+
1108
+    // Adjust title width
1109
+    wrapperWidth != this.wrapper.outerWidth() && this._setTitleWidth();
1110
+
1111
+    // Make jBox draggable
1112
+    this.options.draggable && this._draggable();
1113
+
1114
+    // Reposition if dimensions changed
1115
+    !ignore_positioning && this.options.repositionOnContent && (wrapperHeight != this.wrapper.outerHeight() || wrapperWidth != this.wrapper.outerWidth()) && this.position();
1116
+
1117
+    return this;
1118
+  };
1119
+
1120
+
1121
+  // Set jBox dimensions
1122
+
1123
+  jBox.prototype.setDimensions = function (type, value, pos)
1124
+  {
1125
+    // Create jBox if it wasn't created already
1126
+    !this.wrapper && this._create();
1127
+
1128
+    // Default value is 'auto'
1129
+    value == undefined && (value = 'auto');
1130
+
1131
+    // Set CSS of content and title
1132
+    this.content.css(type, this._getInt(value));
1133
+
1134
+    // Adjust title width
1135
+    type == 'width' && this._setTitleWidth();
1136
+
1137
+    // Update options
1138
+    this.options[type] = value;
1139
+
1140
+    // Reposition by default
1141
+    (pos == undefined || pos) && this.position();
1142
+  };
1143
+
1144
+
1145
+  // Set jBox width or height
1146
+
1147
+  jBox.prototype.setWidth = function (value, pos) { this.setDimensions('width', value, pos); };
1148
+  jBox.prototype.setHeight = function (value, pos) { this.setDimensions('height', value, pos); };
1149
+
1150
+
1151
+  // Position jBox
1152
+
1153
+  jBox.prototype.position = function (options)
1154
+  {
1155
+    // Options are required
1156
+    !options && (options = {});
1157
+
1158
+    // Combine passed options with jBox options
1159
+    options = jQuery.extend(true, this.options, options);
1160
+
1161
+    // Get the target
1162
+    this.target = options.target || this.target || jQuery(window);
1163
+
1164
+    // Make sure target is a jQuery element
1165
+    !(this.target instanceof jQuery || this.target == 'mouse') && (this.target = jQuery(this.target));
1166
+
1167
+    // Abort if target is missing
1168
+    if (!this.target.length) return this;
1169
+
1170
+    // Reset content css to get original dimensions
1171
+    this.content.css({
1172
+      width: this._getInt(options.width, 'width'),
1173
+      height: this._getInt(options.height, 'height'),
1174
+      minWidth: this._getInt(options.minWidth, 'width'),
1175
+      minHeight: this._getInt(options.minHeight, 'height'),
1176
+      maxWidth: this._getInt(options.maxWidth, 'width'),
1177
+      maxHeight: this._getInt(options.maxHeight, 'height'),
1178
+    });
1179
+
1180
+    // Reset width of title
1181
+    this._setTitleWidth();
1182
+
1183
+    // Get jBox dimensions
1184
+    var jBoxDimensions = this._exposeDimensions();
1185
+
1186
+    // Check if target has fixed position, store in elements data
1187
+    this.target != 'mouse' && !this.target.data('jBox-' + this.id + '-fixed') && this.target.data('jBox-' + this.id + '-fixed', (this.target[0] != jQuery(window)[0] && (this.target.css('position') == 'fixed' || this.target.parents().filter(function () { return jQuery(this).css('position') == 'fixed'; }).length > 0)) ? 'fixed' : 'static');
1188
+
1189
+    // Get the window dimensions
1190
+    var windowDimensions = {
1191
+      x: jQuery(window).outerWidth(),
1192
+      y: jQuery(window).outerHeight(),
1193
+      top: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollTop()),
1194
+      left: (options.fixed && this.target.data('jBox-' + this.id + '-fixed') ? 0 : jQuery(window).scrollLeft())
1195
+    };
1196
+    windowDimensions.bottom = windowDimensions.top + windowDimensions.y;
1197
+    windowDimensions.right = windowDimensions.left + windowDimensions.x;
1198
+
1199
+    // Get target offset
1200
+    try { var targetOffset = this.target.offset(); } catch (e) { var targetOffset = {top: 0, left: 0}; };
1201
+
1202
+    // When the target is fixed and jBox is fixed, remove scroll offset
1203
+    if (this.target != 'mouse' && this.target.data('jBox-' + this.id + '-fixed') == 'fixed' && options.fixed) {
1204
+      targetOffset.top = targetOffset.top - jQuery(window).scrollTop();
1205
+      targetOffset.left = targetOffset.left - jQuery(window).scrollLeft();
1206
+    }
1207
+
1208
+    // Get target dimensions
1209
+    var targetDimensions = {
1210
+      x: this.target == 'mouse' ? 12 : this.target.outerWidth(),
1211
+      y: this.target == 'mouse' ? 20 : this.target.outerHeight(),
1212
+      top: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.top : (targetOffset ? targetOffset.top : 0),
1213
+      left: this.target == 'mouse' && options.mouseTarget ? options.mouseTarget.left : (targetOffset ? targetOffset.left : 0)
1214
+    };
1215
+
1216
+    // Check if jBox is outside
1217
+    var outside = options.outside && !(options.position.x == 'center' && options.position.y == 'center');
1218
+
1219
+    // Get the available space on all sides
1220
+    var availableSpace = {
1221
+      x: windowDimensions.x - options.adjustDistance.left - options.adjustDistance.right, // TODO: substract position.x when they are numbers
1222
+      y: windowDimensions.y - options.adjustDistance.top - options.adjustDistance.bottom, // TODO: substract position.x when they are numbers
1223
+      left: !outside ? 0 : (targetDimensions.left - jQuery(window).scrollLeft() - options.adjustDistance.left),
1224
+      right: !outside ? 0 : (windowDimensions.x - targetDimensions.left + jQuery(window).scrollLeft() - targetDimensions.x - options.adjustDistance.right),
1225
+      top: !outside ? 0 : (targetDimensions.top - jQuery(window).scrollTop() - this.options.adjustDistance.top),
1226
+      bottom: !outside ? 0 : (windowDimensions.y - targetDimensions.top + jQuery(window).scrollTop() - targetDimensions.y - options.adjustDistance.bottom),
1227
+    };
1228
+
1229
+    // Get the default outside position, check if box will be flipped
1230
+    var jBoxOutsidePosition = {
1231
+      x: (options.outside == 'x' || options.outside == 'xy') && jQuery.type(options.position.x) != 'number' ? options.position.x : null,
1232
+      y: (options.outside == 'y' || options.outside == 'xy') && jQuery.type(options.position.y) != 'number' ? options.position.y : null
1233
+    };
1234
+    var flip = {x: false, y: false};
1235
+    (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
1236
+    (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
1237
+
1238
+    // Adjust responsive dimensions
1239
+    if (options.responsiveWidth || options.responsiveHeight) {
1240
+
1241
+      // Adjust width and height according to default outside position
1242
+      var adjustResponsiveWidth = function ()
1243
+      {
1244
+        if (options.responsiveWidth && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x || 'x']) {
1245
+          var contentWidth = availableSpace[jBoxOutsidePosition.x || 'x'] - (this.pointer && outside && options.outside == 'x' ? this.pointer.dimensions.x : 0) - parseInt(this.container.css('border-left-width')) - parseInt(this.container.css('border-right-width'));
1246
+          this.content.css({
1247
+            width: contentWidth > this.options.responsiveMinWidth ? contentWidth : null,
1248
+            minWidth: contentWidth < parseInt(this.content.css('minWidth')) ? 0 : null
1249
+          });
1250
+          this._setTitleWidth();
1251
+        }
1252
+        jBoxDimensions = this._exposeDimensions();
1253
+
1254
+      }.bind(this);
1255
+      options.responsiveWidth && adjustResponsiveWidth();
1256
+
1257
+      // After adjusting width, check if jBox will be flipped for y
1258
+      options.responsiveWidth && !flip.y && (jBoxOutsidePosition.y && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y] && availableSpace[this._getOpp(jBoxOutsidePosition.y)] > availableSpace[jBoxOutsidePosition.y]) && (jBoxOutsidePosition.y = this._getOpp(jBoxOutsidePosition.y)) && (flip.y = true);
1259
+
1260
+      // Adjust width and height according to default outside position
1261
+      var adjustResponsiveHeight = function ()
1262
+      {
1263
+        if (options.responsiveHeight && jBoxDimensions.y > availableSpace[jBoxOutsidePosition.y || 'y']) {
1264
+
1265
+          // Expose wrapper to get correct title height
1266
+          var exposeTitleFooterHeight = function () {
1267
+            if (!this.titleContainer && !this.footer) return 0;
1268
+            if (this.wrapper.css('display') == 'none') {
1269
+              this.wrapper.css('display', 'block');
1270
+              var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
1271
+              this.wrapper.css('display', 'none');
1272
+            } else {
1273
+              var height = (this.titleContainer ? this.titleContainer.outerHeight() : 0) + (this.footer ? this.footer.outerHeight() : 0);
1274
+            }
1275
+            return height || 0;
1276
+          }.bind(this);
1277
+
1278
+          var contentHeight = availableSpace[jBoxOutsidePosition.y || 'y'] - (this.pointer && outside && options.outside == 'y' ? this.pointer.dimensions.y : 0) - exposeTitleFooterHeight() - parseInt(this.container.css('border-top-width')) - parseInt(this.container.css('border-bottom-width'));
1279
+          this.content.css({height: contentHeight > this.options.responsiveMinHeight ? contentHeight : null});
1280
+          this._setTitleWidth();
1281
+        }
1282
+        jBoxDimensions = this._exposeDimensions();
1283
+
1284
+      }.bind(this);
1285
+      options.responsiveHeight && adjustResponsiveHeight();
1286
+
1287
+      // After adjusting height, check if jBox will be flipped for x
1288
+      options.responsiveHeight && !flip.x && (jBoxOutsidePosition.x && jBoxDimensions.x > availableSpace[jBoxOutsidePosition.x] && availableSpace[this._getOpp(jBoxOutsidePosition.x)] > availableSpace[jBoxOutsidePosition.x]) && (jBoxOutsidePosition.x = this._getOpp(jBoxOutsidePosition.x)) && (flip.x = true);
1289
+
1290
+      // Adjust width and height if jBox will be flipped
1291
+      if (options.adjustPosition && options.adjustPosition != 'move') {
1292
+        flip.x && adjustResponsiveWidth();
1293
+        flip.y && adjustResponsiveHeight();
1294
+      }
1295
+    }
1296
+
1297
+    // Store new positioning vars in local var
1298
+    var pos = {};
1299
+
1300
+    // Calculate positions
1301
+    var setPosition = function (p)
1302
+    {
1303
+      // Set number positions
1304
+      if (jQuery.type(options.position[p]) == 'number') {
1305
+        pos[options.attributes[p]] = options.position[p];
1306
+        return;
1307
+      }
1308
+
1309
+      // We have a target, so use 'left' or 'top' as attributes
1310
+      var a = options.attributes[p] = (p == 'x' ? 'left' : 'top');
1311
+
1312
+      // Start at target position
1313
+      pos[a] = targetDimensions[a];
1314
+
1315
+      // Set centered position
1316
+      if (options.position[p] == 'center') {
1317
+        pos[a] += Math.ceil((targetDimensions[p] - jBoxDimensions[p]) / 2);
1318
+
1319
+        // If the target is the window, adjust centered position depending on adjustDistance
1320
+        (this.target != 'mouse' && this.target[0] && this.target[0] == jQuery(window)[0]) && (pos[a] += (options.adjustDistance[a] - options.adjustDistance[this._getOpp(a)]) * 0.5);
1321
+        return;
1322
+      }
1323
+
1324
+      // Move inside
1325
+      (a != options.position[p]) && (pos[a] += targetDimensions[p] - jBoxDimensions[p]);
1326
+
1327
+      // Move outside
1328
+      (options.outside == p || options.outside == 'xy') && (pos[a] += jBoxDimensions[p] * (a != options.position[p] ? 1 : -1));
1329
+
1330
+    }.bind(this);
1331
+
1332
+    // Set position including offset
1333
+    setPosition('x');
1334
+    setPosition('y');
1335
+
1336
+    // Adjust position depending on pointer align
1337
+    if (this.pointer && options.pointTo == 'target' && jQuery.type(options.position.x) != 'number' && jQuery.type(options.position.y) != 'number') {
1338
+
1339
+      var adjustWrapper = 0;
1340
+
1341
+      // Where is the pointer aligned? Add or substract accordingly
1342
+      switch (this.pointer.align) {
1343
+        case 'center':
1344
+        if (options.position[this._getOpp(options.outside)] != 'center') {
1345
+          adjustWrapper += (jBoxDimensions[this._getOpp(options.outside)] / 2);
1346
+        }
1347
+        break;
1348
+        default:
1349
+        switch (options.position[this._getOpp(options.outside)]) {
1350
+          case 'center':
1351
+            adjustWrapper += ((jBoxDimensions[this._getOpp(options.outside)] / 2) - (this.pointer.dimensions[this._getOpp(options.outside)] / 2)) * (this.pointer.align == this._getTL(this.pointer.align) ? 1 : -1);
1352
+          break;
1353
+          default:
1354
+            adjustWrapper += (this.pointer.align != options.position[this._getOpp(options.outside)]) ?
1355
+
1356
+            // If pointer align is different to position align
1357
+            (jBoxDimensions[this._getOpp(options.outside)] * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1)) + ((this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? -1 : 1)) :
1358
+
1359
+            // If pointer align is same as position align
1360
+            (this.pointer.dimensions[this._getOpp(options.outside)] / 2) * (jQuery.inArray(this.pointer.align, ['top', 'left']) !== -1 ? 1 : -1);
1361
+          break;
1362
+        }
1363
+        break;
1364
+      }
1365
+
1366
+      adjustWrapper *= (options.position[this._getOpp(options.outside)] == this.pointer.alignAttribute ? -1 : 1);
1367
+      adjustWrapper += this.pointer.offset * (this.pointer.align == this._getOpp(this._getTL(this.pointer.align)) ? 1 : -1);
1368
+
1369
+      pos[this._getTL(this._getOpp(this.pointer.xy))] += adjustWrapper;
1370
+    }
1371
+
1372
+    // Add final offset
1373
+    pos[options.attributes.x] += options.offset.x;
1374
+    pos[options.attributes.y] += options.offset.y;
1375
+
1376
+    // Set CSS
1377
+    this.wrapper.css(pos);
1378
+
1379
+    // Adjust position
1380
+    if (options.adjustPosition) {
1381
+
1382
+      // Reset cached pointer position
1383
+      if (this.positionAdjusted) {
1384
+        this.pointer && this.wrapper.css('padding', 0).css('padding-' + this._getOpp(this.outside), this.pointer.dimensions[this._getXY(this.outside)]).removeClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).addClass('jBox-pointerPosition-' + this.pointer.position);
1385
+        this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + this._getOpp(this.outside)).css(this.pointer.margin);
1386
+        this.positionAdjusted = false;
1387
+        this.flipped = false;
1388
+      }
1389
+
1390
+      // Find out where the jBox is out of view area
1391
+      var outYT = (windowDimensions.top > pos.top - (options.adjustDistance.top || 0)),
1392
+        outXR = (windowDimensions.right < pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0)),
1393
+        outYB = (windowDimensions.bottom < pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0)),
1394
+        outXL = (windowDimensions.left > pos.left - (options.adjustDistance.left || 0)),
1395
+        outX = outXL ? 'left' : (outXR ? 'right' : null),
1396
+        outY = outYT ? 'top' : (outYB ? 'bottom' : null),
1397
+        out = outX || outY;
1398
+
1399
+      // Only continue if jBox is out of view area
1400
+      if (out) {
1401
+
1402
+        if ((this.type == 'Modal' || this.type == 'Confirm')
1403
+          && jQuery.type(this.options.position.x) == 'number'
1404
+          && jQuery.type(this.options.position.y) == 'number'
1405
+        ) {
1406
+          var diffX = 0, diffY = 0;
1407
+          if (this.options.holdPosition) {
1408
+
1409
+            // Adjust left or right
1410
+            if (outXL) {
1411
+              diffX = windowDimensions.left - (pos.left - (options.adjustDistance.left || 0));
1412
+            } else if (outXR) {
1413
+              diffX = windowDimensions.right - (pos.left + jBoxDimensions.x + (options.adjustDistance.right || 0));
1414
+            }
1415
+
1416
+            // Adjust top or bottom
1417
+            if (outYT) {
1418
+              diffY = windowDimensions.top - (pos.top - (options.adjustDistance.top || 0));
1419
+            } else if (outYB) {
1420
+              diffY = windowDimensions.bottom - (pos.top + jBoxDimensions.y + (options.adjustDistance.bottom || 0));
1421
+            }
1422
+
1423
+            this.options.position.x = Math.max(windowDimensions.top, this.options.position.x + diffX);
1424
+            this.options.position.y = Math.max(windowDimensions.left, this.options.position.y + diffY);
1425
+
1426
+            setPosition('x');
1427
+            setPosition('y');
1428
+            this.wrapper.css(pos);
1429
+          }
1430
+          // Fire onPosition event
1431
+          this._fireEvent('onPosition');
1432
+
1433
+          return this;
1434
+        }
1435
+
1436
+        // Function to flip position
1437
+        if (options.adjustPosition === true || options.adjustPosition === 'flip') {
1438
+          var flipJBox = function (xy) {
1439
+            this.wrapper.css(this._getTL(xy), pos[this._getTL(xy)] + ((jBoxDimensions[this._getXY(xy)] + (options.offset[this._getXY(xy)] * (xy == 'top' || xy == 'left' ? -2 : 2)) + targetDimensions[this._getXY(xy)]) * (xy == 'top' || xy == 'left' ? 1 : -1)));
1440
+            this.pointer && this.wrapper.removeClass('jBox-pointerPosition-' + this.pointer.position).addClass('jBox-pointerPosition-' + this._getOpp(this.pointer.position)).css('padding', 0).css('padding-' + xy, this.pointer.dimensions[this._getXY(xy)]);
1441
+            this.pointer && this.pointer.element.attr('class', 'jBox-pointer jBox-pointer-' + xy);
1442
+            this.positionAdjusted = true;
1443
+            this.flipped = true;
1444
+          }.bind(this);
1445
+
1446
+          // Flip jBox
1447
+          flip.x && flipJBox(this.options.position.x);
1448
+          flip.y && flipJBox(this.options.position.y);
1449
+        }
1450
+
1451
+        // Move jBox (only possible with pointer)
1452
+        var outMove = (this._getXY(this.outside) == 'x') ? outY : outX;
1453
+
1454
+        if (this.pointer && options.pointTo == 'target' && options.adjustPosition != 'flip' && this._getXY(outMove) == this._getOpp(this._getXY(this.outside))) {
1455
+
1456
+          // Get the maximum space we have availible to adjust
1457
+          if (this.pointer.align == 'center') {
1458
+            var spaceAvail = (jBoxDimensions[this._getXY(outMove)] / 2) - (this.pointer.dimensions[this._getOpp(this.pointer.xy)] / 2) - (parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) * (outMove != this._getTL(outMove) ? -1 : 1));
1459
+          } else {
1460
+            var spaceAvail = (outMove == this.pointer.alignAttribute) ?
1461
+              parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) :
1462
+              jBoxDimensions[this._getXY(outMove)] - parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - this.pointer.dimensions[this._getXY(outMove)];
1463
+          }
1464
+
1465
+          // Get the overlapping space
1466
+          var spaceDiff = (outMove == this._getTL(outMove)) ?
1467
+            windowDimensions[this._getTL(outMove)] - pos[this._getTL(outMove)] + options.adjustDistance[outMove] :
1468
+            (windowDimensions[this._getOpp(this._getTL(outMove))] - pos[this._getTL(outMove)] - options.adjustDistance[outMove] - jBoxDimensions[this._getXY(outMove)]) * -1;
1469
+
1470
+          // Add overlapping space on left or top window edge
1471
+          if (outMove == this._getOpp(this._getTL(outMove)) && pos[this._getTL(outMove)] - spaceDiff < windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)]) {
1472
+            spaceDiff -= windowDimensions[this._getTL(outMove)] + options.adjustDistance[this._getTL(outMove)] - (pos[this._getTL(outMove)] - spaceDiff);
1473
+          }
1474
+
1475
+          // Only adjust the maximum availible
1476
+          spaceDiff = Math.min(spaceDiff, spaceAvail);
1477
+
1478
+          // Move jBox
1479
+          if (spaceDiff <= spaceAvail && spaceDiff > 0) {
1480
+            this.pointer.element.css('margin-' + this.pointer.alignAttribute, parseInt(this.pointer.element.css('margin-' + this.pointer.alignAttribute)) - (spaceDiff * (outMove != this.pointer.alignAttribute ? -1 : 1)));
1481
+            this.wrapper.css(this._getTL(outMove), pos[this._getTL(outMove)] + (spaceDiff * (outMove != this._getTL(outMove) ? -1 : 1)));
1482
+            this.positionAdjusted = true;
1483
+          }
1484
+        }
1485
+      }
1486
+    }
1487
+
1488
+    // Fire onPosition event
1489
+    this._fireEvent('onPosition');
1490
+
1491
+    return this;
1492
+  };
1493
+
1494
+
1495
+  // Block scrolling
1496
+  // Borrowed from https://github.com/StephanWagner/unscroll
1497
+
1498
+  jBox.prototype.unscroll = function (elements) {
1499
+
1500
+    // Store reusable vars
1501
+    this.set = function (id, value) {
1502
+      if (!window.unscrollStore) {
1503
+        window.unscrollStore = {};
1504
+      }
1505
+      window.unscrollStore[id] = value;
1506
+    };
1507
+
1508
+    // Get reusable vars
1509
+    this.get = function (id) {
1510
+      return window.unscrollStore ? window.unscrollStore[id] : null;
1511
+    };
1512
+
1513
+    // Get the width of the scroll bar in pixel
1514
+    this.getScrollbarWidth = function () {
1515
+      if (this.get('scrollbarWidth')) {
1516
+        return this.get('scrollbarWidth') + 'px';
1517
+      }
1518
+      var scrollElement = document.createElement('div');
1519
+      scrollElement.style.width = '100px';
1520
+      scrollElement.style.height = '100px';
1521
+      scrollElement.style.overflow = 'scroll';
1522
+      scrollElement.style.position = 'absolute';
1523
+      scrollElement.style.top = '-10000';
1524
+
1525
+      document.body.appendChild(scrollElement);
1526
+      var scrollbarWidth = scrollElement.offsetWidth - scrollElement.clientWidth;
1527
+      document.body.removeChild(scrollElement);
1528
+
1529
+      this.set('scrollbarWidth', scrollbarWidth);
1530
+      return scrollbarWidth + 'px';
1531
+    }
1532
+
1533
+    // Add unscroll class to head
1534
+    function addUnscrollClassName() {
1535
+      if (document.getElementById('unscroll-class-name')) {
1536
+        return;
1537
+      }
1538
+      var css = '.unscrollable { overflow: hidden !important; }',
1539
+        head = document.head || document.getElementsByTagName('head')[0],
1540
+        style = document.createElement('style');
1541
+      style.type = 'text/css';
1542
+      style.setAttribute('id', 'unscroll-class-name');
1543
+      style.appendChild(document.createTextNode(css));
1544
+      head.appendChild(style);
1545
+    }
1546
+
1547
+    // Get the elements to adjust, force body element
1548
+    this.getElementsToAdjust = function (elements) {
1549
+      !elements && (elements = []);
1550
+
1551
+      if (typeof elements === 'string') {
1552
+        elements = [
1553
+          [elements, 'padding-right']
1554
+        ];
1555
+      }
1556
+
1557
+      elements.forEach(function (element, index) {
1558
+        if (typeof element === 'string') {
1559
+          elements[index] = [element, 'padding-right'];
1560
+        }
1561
+      });
1562
+
1563
+      var bodyFound = false;
1564
+      for (var i = 0; i < elements.length; i++) {
1565
+        if (elements[i][0].indexOf('body') !== -1) {
1566
+          bodyFound = true;
1567
+        }
1568
+      };
1569
+
1570
+      if (bodyFound === false) {
1571
+        elements.push(['body', 'padding-right']);
1572
+      }
1573
+
1574
+      return elements;
1575
+    }
1576
+
1577
+    this.pageHasScrollbar = function () {
1578
+      return this.getScrollbarWidth() && document.body.offsetHeight > window.innerHeight;
1579
+    }
1580
+
1581
+    // Clean up elements
1582
+    if (this.pageHasScrollbar()) {
1583
+      elements = this.getElementsToAdjust(elements);
1584
+
1585
+      // Loop through elements and adjust accordingly
1586
+      for (var i = 0; i < elements.length; i++) {
1587
+        var elementsDOM = document.querySelectorAll(elements[i][0]);
1588
+        for (var j = 0; j < elementsDOM.length; j++) {
1589
+          if (elementsDOM[j].getAttribute('data-unscroll')) {
1590
+            return;
1591
+          }
1592
+          var attribute = elements[i][1];
1593
+          var computedStyles = window.getComputedStyle(elementsDOM[j]);
1594
+          var computedStyle = computedStyles.getPropertyValue(attribute);
1595
+          elementsDOM[j].setAttribute('data-unscroll', attribute);
1596
+          if (!computedStyle) {
1597
+            computedStyle = '0px';
1598
+          }
1599
+          var operator = attribute == 'padding-right' || attribute == 'right' ? '+' : '-';
1600
+          elementsDOM[j].style[attribute] = 'calc(' + computedStyle + ' ' + operator + ' ' + this.getScrollbarWidth() + ')';
1601
+        }
1602
+      }
1603
+    }
1604
+
1605
+    // Make the page unscrollable
1606
+    addUnscrollClassName();
1607
+    document.body.classList.add('unscrollable');
1608
+  }
1609
+
1610
+  jBox.prototype.unscroll.reset = function () {
1611
+    var elements = document.querySelectorAll('[data-unscroll]');
1612
+
1613
+    for (var i = 0; i < elements.length; i++) {
1614
+      var attribute = elements[i].getAttribute('data-unscroll');
1615
+      elements[i].style[attribute] = null;
1616
+      elements[i].removeAttribute('data-unscroll');
1617
+    }
1618
+    document.body.classList.remove('unscrollable');
1619
+  }
1620
+
1621
+
1622
+  // Open jBox
1623
+
1624
+  jBox.prototype.open = function (options)
1625
+  {
1626
+    // Create blank options if none passed
1627
+    !options && (options = {});
1628
+
1629
+    // Abort if jBox was destroyed
1630
+    if (this.isDestroyed) return this;
1631
+
1632
+    // Construct jBox if not already constructed
1633
+    !this.wrapper && this._create();
1634
+
1635
+    // Add css to header if not added already
1636
+    !this._styles && (this._styles = jQuery('<style/>').append(this._animationCSS).appendTo(jQuery('head')));
1637
+
1638
+    // Abort any opening or closing timer
1639
+    this.timer && clearTimeout(this.timer);
1640
+
1641
+    // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body'
1642
+    this._blockBodyClick();
1643
+
1644
+    // Block opening
1645
+    if (this.isDisabled) return this;
1646
+
1647
+    // Closing event: closeOnEsc
1648
+    this.options.closeOnEsc && jQuery(document).on('keyup.jBox-' + this.id, function (ev) { if (ev.keyCode == 27) { this.close({ignoreDelay: true}); }}.bind(this));
1649
+
1650
+    // Closing event: closeOnClick
1651
+    if (this.options.closeOnClick === true || this.options.closeOnClick === 'body') {
1652
+      jQuery('body').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function (ev) {
1653
+        if (this.blockBodyClick || (this.options.closeOnClick == 'body' && (ev.target == this.wrapper[0] || this.wrapper.has(ev.target).length))) return;
1654
+        this.close({ignoreDelay: true});
1655
+      }.bind(this));
1656
+
1657
+      // Fix for iOS event bubbling issue
1658
+      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
1659
+      this.isTouchDevice && jQuery('body > *').on('click.jBox-' + this.id + ' tap.jBox-' + this.id, function () {
1660
+        return true;
1661
+      });
1662
+    }
1663
+
1664
+    // Opening function
1665
+    var open = function () {
1666
+
1667
+      // Adjust zIndex
1668
+      if (this.adjustZIndexOnOpen === true) {
1669
+        jBox.zIndexMax = Math.max(
1670
+          parseInt(this.wrapper.css('zIndex'), 10),
1671
+          this.options.zIndex,
1672
+          jBox.zIndexMax || 0,
1673
+          jBox.zIndexMaxDragover || 0
1674
+        ) + 2;
1675
+        this.wrapper.css('zIndex', jBox.zIndexMax);
1676
+        this.options.zIndex = jBox.zIndexMax;
1677
+      }
1678
+
1679
+      // Set title from source element
1680
+      this.source && this.options.getTitle && (this.source.attr(this.options.getTitle) && this.setTitle(this.source.attr(this.options.getTitle), true));
1681
+
1682
+      // Set content from source element
1683
+      this.source && this.options.getContent && (this.source.data('jBox-getContent') ? this.setContent(this.source.data('jBox-getContent'), true) : (this.source.attr(this.options.getContent) ? this.setContent(this.source.attr(this.options.getContent), true) : (this.options.getContent == 'html' ? this.setContent(this.source.html(), true) : null)));
1684
+
1685
+      // Fire onOpen event
1686
+      this._fireEvent('onOpen');
1687
+
1688
+      // Get content from ajax
1689
+      if ((this.options.ajax && (this.options.ajax.url || (this.source && this.source.attr(this.options.ajax.getURL))) && (!this.ajaxLoaded || this.options.ajax.reload)) || (options.ajax && (options.ajax.url || options.ajax.data))) {
1690
+        // Send the content from stored data if there is any, otherwise load new data
1691
+        (this.options.ajax.reload != 'strict' && this.source && this.source.data('jBox-ajax-data') && !(options.ajax && (options.ajax.url || options.ajax.data))) ? this.setContent(this.source.data('jBox-ajax-data')) : this.ajax((options.ajax || null), true);
1692
+      }
1693
+
1694
+      // Set position
1695
+      (!this.positionedOnOpen || this.options.repositionOnOpen) && this.position(options) && (this.positionedOnOpen = true);
1696
+
1697
+      // Abort closing
1698
+      this.isClosing && this._abortAnimation();
1699
+
1700
+      // Open functions to call when jBox is closed
1701
+      if (!this.isOpen) {
1702
+
1703
+        // jBox is open now
1704
+        this.isOpen = true;
1705
+
1706
+        // Automatically close jBox after some time
1707
+        this.options.autoClose && (this.options.delayClose = this.options.autoClose) && this.close();
1708
+
1709
+        // Attach events
1710
+        this._attachEvents();
1711
+
1712
+        // Block scrolling
1713
+        if (this.options.blockScroll) {
1714
+          if (this.options.blockScrollAdjust) {
1715
+            if (jBox.blockScrollScopes) {
1716
+              jBox.blockScrollScopes++;
1717
+            } else {
1718
+              jBox.blockScrollScopes = 1;
1719
+              this.unscroll(Array.isArray(this.options.blockScrollAdjust) || typeof this.options.blockScrollAdjust === 'string' ? this.options.blockScrollAdjust : null);
1720
+            }
1721
+          } else {
1722
+            jQuery('body').addClass('jBox-blockScroll-' + this.id);
1723
+          }
1724
+        }
1725
+
1726
+        // Show overlay
1727
+        if (this.options.overlay) {
1728
+          this._showOverlay();
1729
+
1730
+          // TODO Optimize: We have to position here again, because if the overlay has a close button, the upper adjustDistance will be wrong
1731
+          this.position();
1732
+        }
1733
+
1734
+        // Only animate if jBox is completely closed
1735
+        this.options.animation && !this.isClosing && this._animate('open');
1736
+
1737
+        // Play audio file
1738
+        this.options.audio && this.options.audio.open && this.audio(this.options.audio.open, this.options.volume.open);
1739
+
1740
+        // Fading animation or show immediately
1741
+        if (this.options.fade) {
1742
+          this.wrapper.stop().animate({opacity: 1}, {
1743
+            queue: false,
1744
+            duration: this.options.fade,
1745
+            start: function () {
1746
+              this.isOpening = true;
1747
+              this.wrapper.css({display: 'block'});
1748
+            }.bind(this),
1749
+            complete: function () {
1750
+              this._fireEvent('onOpenComplete');
1751
+            }.bind(this),
1752
+            always: function () {
1753
+              this.isOpening = false;
1754
+
1755
+              // Delay positioning for ajax to prevent positioning during animation
1756
+              setTimeout(function () { this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false); }.bind(this), 10);
1757
+            }.bind(this)
1758
+          });
1759
+        } else {
1760
+          this.wrapper.css({display: 'block', opacity: 1});
1761
+          this.positionOnFadeComplete && this.position() && (this.positionOnFadeComplete = false);
1762
+          this._fireEvent('onOpenComplete');
1763
+        }
1764
+      }
1765
+    }.bind(this);
1766
+
1767
+    // Open jBox
1768
+    this.options.delayOpen && !this.isOpen && !this.isClosing && !options.ignoreDelay ? (this.timer = setTimeout(open, this.options.delayOpen)) : open();
1769
+
1770
+    return this;
1771
+  };
1772
+
1773
+
1774
+  // Close jBox
1775
+
1776
+  jBox.prototype.close = function (options)
1777
+  {
1778
+    // Create blank options if none passed
1779
+    options || (options = {});
1780
+
1781
+    // Remove close events
1782
+    jQuery('body').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
1783
+    this.isTouchDevice && jQuery('body > *').off('click.jBox-' + this.id + ' tap.jBox-' + this.id);
1784
+
1785
+    // Abort if jBox was destroyed or is currently closing
1786
+    if (this.isDestroyed || this.isClosing) return this;
1787
+
1788
+    // Abort opening
1789
+    this.timer && clearTimeout(this.timer);
1790
+
1791
+    // Block body click for 10ms, so jBox can open on attached elements while closeOnClick = 'body' is true
1792
+    this._blockBodyClick();
1793
+
1794
+    // Block closing
1795
+    if (this.isDisabled) return this;
1796
+
1797
+    // Close function
1798
+    var close = function () {
1799
+
1800
+      // Fire onClose event
1801
+      this._fireEvent('onClose');
1802
+
1803
+      // Cancel the ajax call
1804
+      if (this.options.cancelAjaxOnClose) {
1805
+        this.cancelAjax();
1806
+      }
1807
+
1808
+      // Only close if jBox is open
1809
+      if (this.isOpen) {
1810
+
1811
+        // jBox is not open anymore
1812
+        this.isOpen = false;
1813
+
1814
+        // Detach events
1815
+        this._detachEvents();
1816
+
1817
+        // Unblock scrolling
1818
+        if (this.options.blockScroll) {
1819
+          if (this.options.blockScrollAdjust) {
1820
+            jBox.blockScrollScopes = jBox.blockScrollScopes ? --jBox.blockScrollScopes : 0;
1821
+            !jBox.blockScrollScopes && this.unscroll.reset();
1822
+          } else {
1823
+            jQuery('body').removeClass('jBox-blockScroll-' + this.id);
1824
+          }
1825
+        }
1826
+
1827
+        // Hide overlay
1828
+        this.options.overlay && this._hideOverlay();
1829
+
1830
+        // Only animate if jBox is compleately closed
1831
+        this.options.animation && !this.isOpening && this._animate('close');
1832
+
1833
+        // Play audio file
1834
+        this.options.audio && this.options.audio.close && this.audio(this.options.audio.close, this.options.volume.close);
1835
+
1836
+        // Get fade duration
1837
+        var fadeDuration = this.isTouchDevice && this.options.target == 'mouse' ? 0 : this.options.fade;
1838
+
1839
+        // Fading animation or show immediately
1840
+        if (fadeDuration) {
1841
+          this.wrapper.stop().animate({opacity: 0}, {
1842
+            queue: false,
1843
+            duration: fadeDuration,
1844
+            start: function () {
1845
+              this.isClosing = true;
1846
+            }.bind(this),
1847
+            complete: function () {
1848
+              this.wrapper.css({display: 'none'});
1849
+              this._fireEvent('onCloseComplete');
1850
+            }.bind(this),
1851
+            always: function () {
1852
+              this.isClosing = false;
1853
+            }.bind(this)
1854
+          });
1855
+        } else {
1856
+          this.wrapper.css({display: 'none', opacity: 0});
1857
+          this._fireEvent('onCloseComplete');
1858
+        }
1859
+      }
1860
+    }.bind(this);
1861
+
1862
+    // Close jBox
1863
+    if (options.ignoreDelay || (this.isTouchDevice && this.options.target == 'mouse')) {
1864
+      close();
1865
+    } else if ((this.options.delayOnHover || this.options.showCountdown) && this.options.delayClose > 10) {
1866
+      var self = this;
1867
+      var remaining = this.options.delayClose;
1868
+      var prevFrame = Date.now();
1869
+      if (this.options.showCountdown && !this.inner) {
1870
+        var outer = jQuery('<div class="jBox-countdown" />');
1871
+        this.inner = jQuery('<div class="jBox-countdown-inner" />');
1872
+        outer.prepend(this.inner);
1873
+        jQuery('#' + this.id).append(outer);
1874
+      }
1875
+      this.countdown = function(){
1876
+        var dateNow = Date.now();
1877
+        if (!self.isHovered) {
1878
+          remaining -= dateNow - prevFrame;
1879
+        }
1880
+        prevFrame = dateNow;
1881
+        if (remaining > 0) {
1882
+          if (self.options.showCountdown) {
1883
+            self.inner.css('width', (remaining * 100 / self.options.delayClose) + '%');
1884
+          }
1885
+          window.requestAnimationFrame(self.countdown);
1886
+        } else {
1887
+          close();
1888
+        }
1889
+      };
1890
+      window.requestAnimationFrame(this.countdown);
1891
+    } else {
1892
+      this.timer = setTimeout(close, Math.max(this.options.delayClose, 10));
1893
+    }
1894
+
1895
+    return this;
1896
+  };
1897
+
1898
+
1899
+  // Open or close jBox
1900
+
1901
+  jBox.prototype.toggle = function (options)
1902
+  {
1903
+    this[this.isOpen ? 'close' : 'open'](options);
1904
+    return this;
1905
+  };
1906
+
1907
+
1908
+  // Block opening and closing
1909
+
1910
+  jBox.prototype.disable = function ()
1911
+  {
1912
+    this.isDisabled = true;
1913
+    return this;
1914
+  };
1915
+
1916
+
1917
+  // Unblock opening and closing
1918
+
1919
+  jBox.prototype.enable = function ()
1920
+  {
1921
+    this.isDisabled = false;
1922
+    return this;
1923
+  };
1924
+
1925
+
1926
+  // Hide jBox
1927
+
1928
+  jBox.prototype.hide = function ()
1929
+  {
1930
+    this.disable();
1931
+    if (this.wrapper) {
1932
+      this.cacheWrapperDisplay = this.wrapper.css('display');
1933
+      this.wrapper.css({display: 'none'});
1934
+    }
1935
+    if (this.overlay) {
1936
+      this.cacheOverlayDisplay = this.overlay.css('display');
1937
+      this.overlay.css({display: 'none'});
1938
+    }
1939
+    return this;
1940
+  };
1941
+
1942
+
1943
+  // Show jBox
1944
+
1945
+  jBox.prototype.show = function ()
1946
+  {
1947
+    this.enable();
1948
+    if (this.wrapper && this.cacheWrapperDisplay) {
1949
+      this.wrapper.css({display: this.cacheWrapperDisplay});
1950
+      this.cacheWrapperDisplay = null;
1951
+    }
1952
+    if (this.overlay && this.cacheOverlayDisplay) {
1953
+      this.overlay.css({display: this.cacheOverlayDisplay});
1954
+      this.cacheOverlayDisplay = null;
1955
+    }
1956
+    return this;
1957
+  };
1958
+
1959
+
1960
+  // Get content from ajax
1961
+
1962
+  jBox.prototype.ajax = function (options, opening)
1963
+  {
1964
+    options || (options = {});
1965
+
1966
+    // Add data or url from source element if none set in options
1967
+    jQuery.each([['getData', 'data'], ['getURL', 'url']], function (index, item) {
1968
+      (this.options.ajax[item[0]] && !options[item[1]] && this.source && this.source.attr(this.options.ajax[item[0]]) != undefined) && (options[item[1]] = this.source.attr(this.options.ajax[item[0]]) || '');
1969
+    }.bind(this));
1970
+
1971
+    // Clone the system options
1972
+    var sysOptions = jQuery.extend(true, {}, this.options.ajax);
1973
+
1974
+    // Abort running ajax call
1975
+    this.cancelAjax();
1976
+
1977
+    // Extract events
1978
+    var beforeSend = options.beforeSend || sysOptions.beforeSend || function () {};
1979
+    var complete = options.complete || sysOptions.complete || function () {};
1980
+    var success = options.success || sysOptions.success || function () {};
1981
+    var error = options.error || sysOptions.error || function () {};
1982
+
1983
+    // Merge options
1984
+    var userOptions = jQuery.extend(true, sysOptions, options);
1985
+
1986
+    // Set new beforeSend event
1987
+    userOptions.beforeSend = function (xhr)
1988
+    {
1989
+      // jBox is loading
1990
+      userOptions.loadingClass && this.wrapper.addClass(userOptions.loadingClass === true ? 'jBox-loading' : userOptions.loadingClass);
1991
+
1992
+      // Add loading spinner
1993
+      userOptions.spinner && (this.spinnerDelay = setTimeout(function ()
1994
+      {
1995
+        // Add class for loading spinner
1996
+        this.wrapper.addClass('jBox-loading-spinner');
1997
+
1998
+        // Reposition jBox
1999
+        // TODO: Only reposition if dimensions change
2000
+        userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
2001
+
2002
+        // Add spinner to container
2003
+        this.spinner = jQuery(userOptions.spinner !== true ? userOptions.spinner : '<div class="jBox-spinner"></div>').appendTo(this.container);
2004
+
2005
+        // Fix spinners position if there is a title
2006
+        this.titleContainer && this.spinner.css('position') == 'absolute' && this.spinner.css({transform: 'translateY(' + (this.titleContainer.outerHeight() * 0.5) + 'px)'});
2007
+
2008
+      }.bind(this), (this.content.html() == '' ? 0 : (userOptions.spinnerDelay || 0))));
2009
+
2010
+      // Fire users beforeSend event
2011
+      (beforeSend.bind(this))(xhr);
2012
+
2013
+    }.bind(this);
2014
+
2015
+    // Set up new complete event
2016
+    userOptions.complete = function (response)
2017
+    {
2018
+      // Abort spinner timeout
2019
+      this.spinnerDelay && clearTimeout(this.spinnerDelay);
2020
+
2021
+      // jBox finished loading
2022
+      this.wrapper.removeClass('jBox-loading jBox-loading-spinner jBox-loading-spinner-delay');
2023
+
2024
+      // Remove spinner
2025
+      this.spinner && this.spinner.length && this.spinner.remove() && userOptions.spinnerReposition && (opening ? (this.positionOnFadeComplete = true) : this.position());
2026
+
2027
+      // Store that ajax loading finished
2028
+      this.ajaxLoaded = true;
2029
+
2030
+      // Fire users complete event
2031
+      (complete.bind(this))(response);
2032
+
2033
+    }.bind(this);
2034
+
2035
+    // Set up new success event
2036
+    userOptions.success = function (response)
2037
+    {
2038
+      // Set content
2039
+      userOptions.setContent && this.setContent(response, true) && (opening ? (this.positionOnFadeComplete = true) : this.position());
2040
+
2041
+      // Store content in source element
2042
+      userOptions.setContent && this.source && this.source.data('jBox-ajax-data', response);
2043
+
2044
+      // Fire users success event
2045
+      (success.bind(this))(response);
2046
+
2047
+    }.bind(this);
2048
+
2049
+    // Add error event
2050
+    userOptions.error = function (response) { (error.bind(this))(response); }.bind(this);
2051
+
2052
+    // Send new ajax request
2053
+    this.ajaxRequest = jQuery.ajax(userOptions);
2054
+
2055
+    return this;
2056
+  };
2057
+
2058
+
2059
+  // Abort an ajax call
2060
+
2061
+  jBox.prototype.cancelAjax = function () {
2062
+    if (this.ajaxRequest) {
2063
+      this.ajaxRequest.abort();
2064
+      this.ajaxLoaded = false;
2065
+    }
2066
+  };
2067
+
2068
+
2069
+  // Play an audio file
2070
+
2071
+  jBox.prototype.audio = function (url, volume)
2072
+  {
2073
+    // URL is required
2074
+    if (!url) return this;
2075
+
2076
+    // Create intern audio object if it wasn't created already
2077
+    !jBox._audio && (jBox._audio = {});
2078
+
2079
+    // Create an audio element specific to this audio file if it doesn't exist already
2080
+    if (!jBox._audio[url]) {
2081
+      var audio = jQuery('<audio/>');
2082
+      jQuery('<source/>', {src: url + '.mp3'}).appendTo(audio);
2083
+      jQuery('<source/>', {src: url + '.ogg'}).appendTo(audio);
2084
+      jBox._audio[url] = audio[0];
2085
+    }
2086
+
2087
+    // Set volume
2088
+    jBox._audio[url].volume = Math.min(((volume != undefined ? volume : 100) / 100), 1);
2089
+
2090
+    // Try to pause current audio
2091
+    try {
2092
+      jBox._audio[url].pause();
2093
+      jBox._audio[url].currentTime = 0;
2094
+    } catch (e) {}
2095
+
2096
+    // Play audio
2097
+    jBox._audio[url].play();
2098
+
2099
+    return this;
2100
+  };
2101
+
2102
+  // Apply custom animations to jBox (being used in playground demos)
2103
+
2104
+  jBox._animationSpeeds = {
2105
+    'tada': 1000,
2106
+    'tadaSmall': 1000,
2107
+    'flash': 500,
2108
+    'shake': 400,
2109
+    'pulseUp': 250,
2110
+    'pulseDown': 250,
2111
+    'popIn': 250,
2112
+    'popOut': 250,
2113
+    'fadeIn': 200,
2114
+    'fadeOut': 200,
2115
+    'slideUp': 400,
2116
+    'slideRight': 400,
2117
+    'slideLeft': 400,
2118
+    'slideDown': 400
2119
+  };
2120
+
2121
+  jBox.prototype.animate = function (animation, options)
2122
+  {
2123
+    // Options are required
2124
+    !options && (options = {});
2125
+
2126
+    // Timout needs to be an object
2127
+    !this.animationTimeout && (this.animationTimeout = {});
2128
+
2129
+    // Use jBox wrapper by default
2130
+    !options.element && (options.element = this.wrapper);
2131
+
2132
+    // Give the element an unique id
2133
+    !options.element.data('jBox-animating-id') && options.element.data('jBox-animating-id', jBox._getUniqueElementID());
2134
+
2135
+    // Abort if element is animating
2136
+    if (options.element.data('jBox-animating')) {
2137
+      options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null);
2138
+      this.animationTimeout[options.element.data('jBox-animating-id')] && clearTimeout(this.animationTimeout[options.element.data('jBox-animating-id')]);
2139
+    }
2140
+
2141
+    // Animate the element
2142
+    options.element.addClass('jBox-animated-' + animation).data('jBox-animating', 'jBox-animated-' + animation);
2143
+    this.animationTimeout[options.element.data('jBox-animating-id')] = setTimeout((function() { options.element.removeClass(options.element.data('jBox-animating')).data('jBox-animating', null); options.complete && options.complete(); }), jBox._animationSpeeds[animation]);
2144
+  };
2145
+
2146
+  // https://gist.github.com/AlexEmashev/ee8302b5036b01362f63dab35948401f
2147
+  jBox.prototype.swipeDetector = function (swipeTarget, options) {
2148
+    // States: 0 - no swipe, 1 - swipe started, 2 - swipe released
2149
+    var swipeState = 0;
2150
+    // Coordinates when swipe started
2151
+    var startX = 0;
2152
+    var startY = 0;
2153
+    // Distance of swipe
2154
+    var pixelOffsetX = 0;
2155
+    var pixelOffsetY = 0;
2156
+
2157
+    var defaultSettings = {
2158
+      // Amount of pixels, when swipe don't count.
2159
+      swipeThreshold: 70,
2160
+      // Flag that indicates that plugin should react only on touch events.
2161
+      // Not on mouse events too.
2162
+      useOnlyTouch: false
2163
+    };
2164
+
2165
+    // Initializer
2166
+    (function init() {
2167
+      options = jQuery.extend(defaultSettings, options);
2168
+      // Support touch and mouse as well.
2169
+      swipeTarget.on("mousedown touchstart", swipeStart);
2170
+      jQuery("html").on("mouseup touchend", swipeEnd);
2171
+      jQuery("html").on("mousemove touchmove", swiping);
2172
+    })();
2173
+
2174
+    function swipeStart(event) {
2175
+      if (options.useOnlyTouch && !event.originalEvent.touches) {
2176
+        return;
2177
+      }
2178
+
2179
+      if (event.originalEvent.touches) {
2180
+        event = event.originalEvent.touches[0];
2181
+      }
2182
+
2183
+      if (swipeState === 0) {
2184
+        swipeState = 1;
2185
+        startX = event.clientX;
2186
+        startY = event.clientY;
2187
+      }
2188
+    }
2189
+
2190
+    function swipeEnd(event) {
2191
+      if (swipeState === 2) {
2192
+        swipeState = 0;
2193
+
2194
+        if (
2195
+          Math.abs(pixelOffsetX) > Math.abs(pixelOffsetY) &&
2196
+          Math.abs(pixelOffsetX) > options.swipeThreshold
2197
+        ) {
2198
+          // Horizontal Swipe
2199
+          if (pixelOffsetX < 0) {
2200
+            swipeTarget.trigger(jQuery.Event("swipeLeft.sd"));
2201
+          } else {
2202
+            swipeTarget.trigger(jQuery.Event("swipeRight.sd"));
2203
+          }
2204
+        } else if (Math.abs(pixelOffsetY) > options.swipeThreshold) {
2205
+          // Vertical swipe
2206
+          if (pixelOffsetY < 0) {
2207
+            swipeTarget.trigger(jQuery.Event("swipeUp.sd"));
2208
+          } else {
2209
+            swipeTarget.trigger(jQuery.Event("swipeDown.sd"));
2210
+          }
2211
+        }
2212
+      }
2213
+    }
2214
+
2215
+    function swiping(event) {
2216
+      // If swipe don't occuring, do nothing.
2217
+      if (swipeState !== 1) return;
2218
+
2219
+      if (event.originalEvent.touches) {
2220
+        event = event.originalEvent.touches[0];
2221
+      }
2222
+
2223
+      var swipeOffsetX = event.clientX - startX;
2224
+      var swipeOffsetY = event.clientY - startY;
2225
+
2226
+      if (
2227
+        Math.abs(swipeOffsetX) > options.swipeThreshold ||
2228
+        Math.abs(swipeOffsetY) > options.swipeThreshold
2229
+      ) {
2230
+        swipeState = 2;
2231
+        pixelOffsetX = swipeOffsetX;
2232
+        pixelOffsetY = swipeOffsetY;
2233
+      }
2234
+    }
2235
+
2236
+    return swipeTarget; // Return element available for chaining.
2237
+  }
2238
+
2239
+
2240
+  // Destroy jBox and remove it from DOM
2241
+
2242
+  jBox.prototype.destroy = function ()
2243
+  {
2244
+    // Detach from attached elements
2245
+    this.detach();
2246
+
2247
+    // If jBox is open, close without delay
2248
+    this.isOpen && this.close({ignoreDelay: true});
2249
+
2250
+    // Remove wrapper
2251
+    this.wrapper && this.wrapper.remove();
2252
+
2253
+    // Remove overlay
2254
+    this.overlay && this.overlay.remove();
2255
+
2256
+    // Remove styles
2257
+    this._styles && this._styles.remove();
2258
+
2259
+    // Tell the jBox instance it is destroyed
2260
+    this.isDestroyed = true;
2261
+
2262
+    return this;
2263
+  };
2264
+
2265
+
2266
+  // Get a unique ID for jBoxes
2267
+
2268
+  jBox._getUniqueID = (function ()
2269
+  {
2270
+    var i = 1;
2271
+    return function () { return i++; };
2272
+  }());
2273
+
2274
+
2275
+  // Get a unique ID for animating elements
2276
+
2277
+  jBox._getUniqueElementID = (function ()
2278
+  {
2279
+    var i = 1;
2280
+    return function () { return i++; };
2281
+  }());
2282
+
2283
+
2284
+  // Function to create jBox plugins
2285
+
2286
+  jBox._pluginOptions = {};
2287
+  jBox.plugin = function (type, options)
2288
+  {
2289
+    jBox._pluginOptions[type] = options;
2290
+  };
2291
+
2292
+
2293
+  // Make jBox usable with jQuery selectors
2294
+
2295
+  jQuery.fn.jBox = function (type, options) {
2296
+    // Variables type and object are required
2297
+    !type && (type = {});
2298
+    !options && (options = {});
2299
+
2300
+    // Return a new instance of jBox with the selector as attached element
2301
+    return new jBox(type, jQuery.extend(options, {
2302
+      attach: this
2303
+    }));
2304
+  };
2305
+
2306
+  return jBox;
2307
+
2308
+};
2309
+
2310
+(function (root, factory) {
2311
+  if (typeof define === 'function' && define.amd) {
2312
+    define(['jquery'], function (jQuery) {
2313
+      return (root.jBox = factory(jQuery));
2314
+    });
2315
+  } else if (typeof module === 'object' && module.exports) {
2316
+    module.exports = (root.jBox = factory(require('jquery')));
2317
+  } else {
2318
+    root.jBox = factory(root.jQuery);
2319
+  }
2320
+}(this, function (jQuery) {
2321
+  var jBox = jBoxWrapper(jQuery);
2322
+  try { typeof jBoxConfirmWrapper !== 'undefined' && jBoxConfirmWrapper && jBoxConfirmWrapper(jBox, jQuery); } catch(e) { console.error(e); }
2323
+  try { typeof jBoxImageWrapper !== 'undefined' && jBoxImageWrapper && jBoxImageWrapper(jBox, jQuery); } catch(e) { console.error(e); }
2324
+  try { typeof jBoxNoticeWrapper !== 'undefined' && jBoxNoticeWrapper && jBoxNoticeWrapper(jBox, jQuery); } catch(e) { console.error(e); }
2325
+  return jBox;
2326
+}));
2327
+
2328
+//# sourceMappingURL=jBox.js.map
0 2329
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-wrapper{text-align:left;box-sizing:border-box}.jBox-container,.jBox-content,.jBox-title{position:relative;word-break:break-word;box-sizing:border-box}.jBox-container{background:#fff}.jBox-content{padding:8px 12px;overflow-x:hidden;overflow-y:auto;transition:opacity .2s}.jBox-footer{box-sizing:border-box}.jBox-Mouse .jBox-container,.jBox-Tooltip .jBox-container{border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.25)}.jBox-Mouse .jBox-title,.jBox-Tooltip .jBox-title{padding:8px 10px 0;font-weight:700}.jBox-Mouse.jBox-hasTitle .jBox-content,.jBox-Tooltip.jBox-hasTitle .jBox-content{padding-top:5px}.jBox-Mouse{pointer-events:none}.jBox-pointer{position:absolute;overflow:hidden;box-sizing:border-box}.jBox-pointer:after{content:'';width:20px;height:20px;position:absolute;background:#fff;transform:rotate(45deg);box-sizing:border-box}.jBox-pointer-top{top:0}.jBox-pointer-top:after{left:5px;top:6px;box-shadow:-1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-right{right:0}.jBox-pointer-right:after{top:5px;right:6px;box-shadow:1px -1px 2px rgba(0,0,0,.15)}.jBox-pointer-left{left:0}.jBox-pointer-left:after{top:5px;left:6px;box-shadow:-1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom{bottom:0}.jBox-pointer-bottom:after{left:5px;bottom:6px;box-shadow:1px 1px 2px rgba(0,0,0,.15)}.jBox-pointer-bottom,.jBox-pointer-top{width:30px;height:12px}.jBox-pointer-left,.jBox-pointer-right{width:12px;height:30px}.jBox-Modal .jBox-container{border-radius:4px}.jBox-Modal .jBox-container,.jBox-Modal.jBox-closeButton-box:before{box-shadow:0 3px 15px rgba(0,0,0,.4),0 0 5px rgba(0,0,0,.4)}.jBox-Modal .jBox-content{padding:15px 20px}.jBox-Modal .jBox-title{border-radius:4px 4px 0 0;padding:15px 20px;background:#fafafa;border-bottom:1px solid #eee}.jBox-Modal.jBox-closeButton-title .jBox-title{padding-right:65px}.jBox-Modal .jBox-footer{border-radius:0 0 4px 4px}.jBox-closeButton{z-index:1;cursor:pointer;position:absolute;box-sizing:border-box}.jBox-closeButton svg{position:absolute;top:50%;right:50%}.jBox-closeButton path{fill:#aaa;transition:fill .2s}.jBox-closeButton:hover path{fill:#888}.jBox-overlay .jBox-closeButton{top:0;right:0;width:40px;height:40px}.jBox-overlay .jBox-closeButton svg{width:20px;height:20px;margin-top:-10px;margin-right:-10px}.jBox-overlay .jBox-closeButton path{fill:#ddd}.jBox-overlay .jBox-closeButton:hover path{fill:#fff}.jBox-closeButton-title .jBox-closeButton{top:0;right:0;bottom:0;width:50px}.jBox-closeButton-title svg{width:12px;height:12px;margin-top:-6px;margin-right:-6px}.jBox-closeButton-box{box-sizing:border-box}.jBox-closeButton-box .jBox-closeButton{top:-8px;right:-10px;width:24px;height:24px;background:#fff;border-radius:50%}.jBox-closeButton-box .jBox-closeButton svg{width:10px;height:10px;margin-top:-5px;margin-right:-5px}.jBox-closeButton-box:before{content:'';position:absolute;top:-8px;right:-10px;width:24px;height:24px;border-radius:50%;box-shadow:0 0 5px rgba(0,0,0,.3)}.jBox-closeButton-box.jBox-pointerPosition-top:before{top:5px}.jBox-closeButton-box.jBox-pointerPosition-right:before{right:2px}.jBox-Modal.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton{background:#fafafa}.jBox-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.82)}.jBox-footer{background:#fafafa;border-top:1px solid #eee;padding:8px 10px;border-radius:0 0 3px 3px}body[class*=" jBox-blockScroll-"],body[class^=jBox-blockScroll-]{overflow:hidden}.jBox-draggable{cursor:move}@keyframes jBoxLoading{to{transform:rotate(360deg)}}.jBox-loading .jBox-content{opacity:.2}.jBox-loading-spinner .jBox-content{min-height:38px!important;min-width:38px!important;opacity:0}.jBox-spinner{box-sizing:border-box;position:absolute;top:50%;left:50%;width:24px;height:24px;margin-top:-12px;margin-left:-12px}.jBox-spinner:before{display:block;box-sizing:border-box;content:'';width:24px;height:24px;border-radius:50%;border:2px solid rgba(0,0,0,.2);border-top-color:rgba(0,0,0,.8);animation:jBoxLoading .6s linear infinite}.jBox-countdown{border-radius:4px 4px 0 0;z-index:0;background:#000;opacity:.2;position:absolute;top:0;left:0;right:0;height:3px;overflow:hidden}.jBox-countdown-inner{top:0;right:0;width:100%;height:3px;position:absolute;background:#fff}[class*=" jBox-animated-"],[class^=jBox-animated-]{animation-fill-mode:both}@keyframes jBox-tada{0%{transform:scale(1)}10%,20%{transform:scale(.8) rotate(-4deg)}30%,50%,70%,90%{transform:scale(1.2) rotate(4deg)}40%,60%,80%{transform:scale(1.2) rotate(-4deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tada{animation:jBox-tada 1s}@keyframes jBox-tadaSmall{0%{transform:scale(1)}10%,20%{transform:scale(.9) rotate(-2deg)}30%,50%,70%,90%{transform:scale(1.1) rotate(2deg)}40%,60%,80%{transform:scale(1.1) rotate(-2deg)}100%{transform:scale(1) rotate(0)}}.jBox-animated-tadaSmall{animation:jBox-tadaSmall 1s}@keyframes jBox-flash{0%,100%,50%{opacity:1}25%,75%{opacity:0}}.jBox-animated-flash{animation:jBox-flash .5s}@keyframes jBox-shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-6px)}40%,80%{transform:translateX(6px)}}.jBox-animated-shake{animation:jBox-shake .4s}@keyframes jBox-pulseUp{0%{transform:scale(1)}50%{transform:scale(1.15)}100%{transform:scale(1)}}.jBox-animated-pulseUp{animation:jBox-pulseUp .25s}@keyframes jBox-pulseDown{0%{transform:scale(1)}50%{transform:scale(.85)}100%{transform:scale(1)}}.jBox-animated-pulseDown{animation:jBox-pulseDown .25s}@keyframes jBox-popIn{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.jBox-animated-popIn{animation:jBox-popIn .25s}@keyframes jBox-popOut{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(0)}}.jBox-animated-popOut{animation:jBox-popOut .25s}@keyframes jBox-fadeIn{0%{opacity:0}100%{opacity:1}}.jBox-animated-fadeIn{animation:jBox-fadeIn .2s}@keyframes jBox-fadeOut{0%{opacity:1}100%{opacity:0}}.jBox-animated-fadeOut{animation:jBox-fadeOut .2s}@keyframes jBox-slideUp{0%{transform:translateY(0)}100%{transform:translateY(-300px);opacity:0}}.jBox-animated-slideUp{animation:jBox-slideUp .4s}@keyframes jBox-slideRight{0%{transform:translateX(0)}100%{transform:translateX(300px);opacity:0}}.jBox-animated-slideRight{animation:jBox-slideRight .4s}@keyframes jBox-slideDown{0%{transform:translateY(0)}100%{transform:translateY(300px);opacity:0}}.jBox-animated-slideDown{animation:jBox-slideDown .4s}@keyframes jBox-slideLeft{0%{transform:translateX(0)}100%{transform:translateX(-300px);opacity:0}}.jBox-animated-slideLeft{animation:jBox-slideLeft .4s}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+function jBoxWrapper(v){function h(t,i){return this.options={id:null,width:"auto",height:"auto",minWidth:null,minHeight:null,maxWidth:null,maxHeight:null,responsiveWidth:!0,responsiveHeight:!0,responsiveMinWidth:100,responsiveMinHeight:100,attach:null,trigger:"click",preventDefault:!1,content:null,getContent:null,title:null,getTitle:null,footer:null,isolateScroll:!0,ajax:{url:null,data:"",reload:!1,getURL:"data-url",getData:"data-ajax",setContent:!0,loadingClass:!0,spinner:!0,spinnerDelay:300,spinnerReposition:!0},cancelAjaxOnClose:!0,target:null,position:{x:"center",y:"center"},outside:null,offset:0,attributes:{x:"left",y:"top"},fixed:!1,adjustPosition:!0,adjustTracker:!1,adjustDistance:5,reposition:!0,repositionOnOpen:!0,repositionOnContent:!0,holdPosition:!0,pointer:!1,pointTo:"target",fade:180,animation:null,theme:"Default",addClass:null,overlay:!1,overlayClass:null,zIndex:1e4,delayOpen:0,delayClose:0,closeOnEsc:!1,closeOnClick:!1,closeOnMouseleave:!1,closeButton:!1,appendTo:v("body"),createOnInit:!1,blockScroll:!1,blockScrollAdjust:!0,draggable:!1,dragOver:!0,autoClose:!1,delayOnHover:!1,showCountdown:!1,preloadAudio:!0,audio:null,volume:100,onInit:null,onAttach:null,onPosition:null,onCreated:null,onOpen:null,onOpenComplete:null,onClose:null,onCloseComplete:null,onDragStart:null,onDragEnd:null},this._pluginOptions={Tooltip:{getContent:"title",trigger:"mouseenter",position:{x:"center",y:"top"},outside:"y",pointer:!0},Mouse:{responsiveWidth:!1,responsiveHeight:!1,adjustPosition:"flip",target:"mouse",trigger:"mouseenter",position:{x:"right",y:"bottom"},outside:"xy",offset:5},Modal:{target:v(window),fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"overlay",closeButton:!0,overlay:!0,animation:"zoomIn"}},this.options=v.extend(!0,this.options,this._pluginOptions[t]||h._pluginOptions[t],i),"string"==v.type(t)&&(this.type=t),this.isTouchDevice=function(){var t=" -webkit- -moz- -o- -ms- ".split(" ");if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)return!0;var i,t=["(",t.join("touch-enabled),("),"heartz",")"].join("");return i=t,window.matchMedia(i).matches}(),this.isTouchDevice&&"mouseenter"===this.options.trigger&&!1===this.options.closeOnClick&&(this.options.closeOnClick="body"),this._fireEvent=function(t,i){this.options["_"+t]&&this.options["_"+t].bind(this)(i),this.options[t]&&this.options[t].bind(this)(i)},null===this.options.id&&(this.options.id="jBox"+h._getUniqueID()),this.id=this.options.id,("center"==this.options.position.x&&"x"==this.options.outside||"center"==this.options.position.y&&"y"==this.options.outside)&&(this.options.outside=null),"target"!=this.options.pointTo||this.options.outside&&"xy"!=this.options.outside||(this.options.pointer=!1),"object"!=v.type(this.options.offset)?this.options.offset={x:this.options.offset,y:this.options.offset}:this.options.offset=v.extend({x:0,y:0},this.options.offset),"object"!=v.type(this.options.adjustDistance)?this.options.adjustDistance={top:this.options.adjustDistance,right:this.options.adjustDistance,bottom:this.options.adjustDistance,left:this.options.adjustDistance}:this.options.adjustDistance=v.extend({top:5,left:5,right:5,bottom:5},this.options.adjustDistance),this.outside=!(!this.options.outside||"xy"==this.options.outside)&&this.options.position[this.options.outside],this.align=this.outside||("center"!=this.options.position.y&&"number"!=v.type(this.options.position.y)?this.options.position.x:"center"!=this.options.position.x&&"number"!=v.type(this.options.position.x)?this.options.position.y:this.options.attributes.x),h.zIndexMax=Math.max(h.zIndexMax||0,"auto"===this.options.zIndex?1e4:this.options.zIndex),"auto"===this.options.zIndex&&(this.adjustZIndexOnOpen=!0,this.options.zIndex=h.zIndexMax+=2,this.trueModal=this.options.overlay),this._getOpp=function(t){return{left:"right",right:"left",top:"bottom",bottom:"top",x:"y",y:"x"}[t]},this._getXY=function(t){return{left:"x",right:"x",top:"y",bottom:"y",center:"x"}[t]},this._getTL=function(t){return{left:"left",right:"left",top:"top",bottom:"top",center:"left",x:"left",y:"top"}[t]},this._getInt=function(t,i){return"auto"==t?"auto":t&&"string"==v.type(t)&&"%"==t.slice(-1)?v(window)["height"==i?"innerHeight":"innerWidth"]()*parseInt(t.replace("%",""))/100:t},this._createSVG=function(t,i){var o=document.createElementNS("http://www.w3.org/2000/svg",t);return v.each(i,function(t,i){o.setAttribute(i[0],i[1]||"")}),o},this._isolateScroll=function(e){e&&e.length&&e.on("DOMMouseScroll.jBoxIsolateScroll mousewheel.jBoxIsolateScroll",function(t){var i=t.wheelDelta||t.originalEvent&&t.originalEvent.wheelDelta||-t.detail,o=0<=this.scrollTop+e.outerHeight()-this.scrollHeight,s=this.scrollTop<=0;(i<0&&o||0<i&&s)&&t.preventDefault()})},this._setTitleWidth=function(){if(!this.titleContainer||"auto"==this.content[0].style.width&&!this.content[0].style.maxWidth)return null;var t;"none"==this.wrapper.css("display")?(this.wrapper.css("display","block"),t=this.content.outerWidth(),this.wrapper.css("display","none")):t=this.content.outerWidth(),this.titleContainer.css({maxWidth:Math.max(t,parseInt(this.content[0].style.maxWidth))||null})},this._draggable=function(){if(!this.options.draggable)return!1;var t="title"==this.options.draggable?this.titleContainer:this.options.draggable instanceof v?this.options.draggable:"string"==v.type(this.options.draggable)?v(this.options.draggable):this.wrapper;return!(!(t&&t instanceof v&&t.length)||t.data("jBox-draggable"))&&(t.addClass("jBox-draggable").data("jBox-draggable",!0).on("touchstart mousedown",function(t){var i,o,s,e,n,a;2==t.button||v(t.target).hasClass("jBox-noDrag")||v(t.target).parents(".jBox-noDrag").length?"touchstart"==t.type&&(v(t.target).hasClass("jBox-closeButton")||v(t.target).parents(".jBox-closeButton").length)&&this.close({ignoreDelay:!0}):(o="touchstart"==t.type&&t.touches&&t.touches[0]?(i=t.touches[0].pageX,t.touches[0].pageY):(i=t.pageX,t.pageY),this.draggingStartX=i,this.draggingStartY=o,this.options.dragOver&&!this.trueModal&&parseInt(this.wrapper.css("zIndex"),10)<=h.zIndexMaxDragover&&(h.zIndexMaxDragover+=1,this.wrapper.css("zIndex",h.zIndexMaxDragover)),s=this.wrapper.outerHeight(),e=this.wrapper.outerWidth(),n=this.wrapper.offset().top+s-o,a=this.wrapper.offset().left+e-i,v(document).on("touchmove.jBox-draggable-"+this.id+" mousemove.jBox-draggable-"+this.id,function(t){var i,t="touchmove"==t.type&&t.touches&&t.touches[0]?(i=t.touches[0].pageX,t.touches[0].pageY):(i=t.pageX,t.pageY);this.dragging||this.draggingStartX==i||this.draggingStartY==t||(this._fireEvent("onDragStart"),this.dragging=!0),this.wrapper.offset({top:t+n-s,left:i+a-e})}.bind(this)),t.preventDefault())}.bind(this)).on("touchend mouseup",function(){var t;v(document).off("touchmove.jBox-draggable-"+this.id+" mousemove.jBox-draggable-"+this.id),this.dragging&&this._fireEvent("onDragEnd"),this.dragging=!1,"Modal"!=this.type&&"Confirm"!=this.type||!this.options.holdPosition||(t={x:(t=v("#"+this.id).offset()).left-v(document).scrollLeft(),y:t.top-v(document).scrollTop()},this.position({position:t,offset:{x:0,y:0}}))}.bind(this)),this.trueModal||(h.zIndexMaxDragover=h.zIndexMaxDragover?Math.max(h.zIndexMaxDragover,this.options.zIndex):this.options.zIndex),this)},this._create=function(){var t;this.wrapper||(this.wrapper=v("<div/>",{id:this.id,class:"jBox-wrapper"+(this.type?" jBox-"+this.type:"")+(this.options.theme?" jBox-"+this.options.theme:"")+(this.options.addClass?" "+this.options.addClass:"")}).css({position:this.options.fixed?"fixed":"absolute",display:"none",opacity:0,zIndex:this.options.zIndex}).data("jBox",this),this.options.closeOnMouseleave&&this.wrapper.on("mouseleave",function(t){!this.source||t.relatedTarget!=this.source[0]&&-1===v.inArray(this.source[0],v(t.relatedTarget).parents("*"))&&this.close()}.bind(this)),"box"==this.options.closeOnClick&&this.wrapper.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),this.container=v('<div class="jBox-container"/>').appendTo(this.wrapper),this.content=v('<div class="jBox-content"/>').appendTo(this.container),this.options.footer&&(this.footer=v('<div class="jBox-footer"/>').append(this.options.footer).appendTo(this.container)),this.options.isolateScroll&&this._isolateScroll(this.content),this.options.closeButton&&((t=this._createSVG("svg",[["viewBox","0 0 24 24"]])).appendChild(this._createSVG("path",[["d","M22.2,4c0,0,0.5,0.6,0,1.1l-6.8,6.8l6.9,6.9c0.5,0.5,0,1.1,0,1.1L20,22.3c0,0-0.6,0.5-1.1,0L12,15.4l-6.9,6.9c-0.5,0.5-1.1,0-1.1,0L1.7,20c0,0-0.5-0.6,0-1.1L8.6,12L1.7,5.1C1.2,4.6,1.7,4,1.7,4L4,1.7c0,0,0.6-0.5,1.1,0L12,8.5l6.8-6.8c0.5-0.5,1.1,0,1.1,0L22.2,4z"]])),this.closeButton=v('<div class="jBox-closeButton jBox-noDrag"/>').on("click tap",function(t){this.close({ignoreDelay:!0})}.bind(this)).append(t),"box"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay||this.options.title||this.options.getTitle)||(this.wrapper.addClass("jBox-closeButton-box"),this.closeButton.appendTo(this.container))),this.wrapper.appendTo(this.options.appendTo),this.wrapper.find(".jBox-closeButton").length&&v.each(["top","right","bottom","left"],function(t,i){this.wrapper.find(".jBox-closeButton").css(i)&&"auto"!=this.wrapper.find(".jBox-closeButton").css(i)&&(this.options.adjustDistance[i]=Math.max(this.options.adjustDistance[i],this.options.adjustDistance[i]+-1*((parseInt(this.wrapper.find(".jBox-closeButton").css(i))||0)+(parseInt(this.container.css("border-"+i+"-width"))||0))))}.bind(this)),this.options.pointer&&(this.pointer={position:"target"!=this.options.pointTo?this.options.pointTo:this._getOpp(this.outside),xy:"target"!=this.options.pointTo?this._getXY(this.options.pointTo):this._getXY(this.outside),align:"center",offset:0},this.pointer.element=v('<div class="jBox-pointer jBox-pointer-'+this.pointer.position+'"/>').appendTo(this.wrapper),this.pointer.dimensions={x:this.pointer.element.outerWidth(),y:this.pointer.element.outerHeight()},"string"==v.type(this.options.pointer)&&((t=this.options.pointer.split(":"))[0]&&(this.pointer.align=t[0]),t[1]&&(this.pointer.offset=parseInt(t[1]))),this.pointer.alignAttribute="x"==this.pointer.xy?"bottom"==this.pointer.align?"bottom":"top":"right"==this.pointer.align?"right":"left",this.wrapper.css("padding-"+this.pointer.position,this.pointer.dimensions[this.pointer.xy]),this.pointer.element.css(this.pointer.alignAttribute,"center"==this.pointer.align?"50%":0).css("margin-"+this.pointer.alignAttribute,this.pointer.offset),this.pointer.margin={},this.pointer.margin["margin-"+this.pointer.alignAttribute]=this.pointer.offset,"center"==this.pointer.align&&this.pointer.element.css("transform","translate("+("y"==this.pointer.xy?-.5*this.pointer.dimensions.x+"px":0)+", "+("x"==this.pointer.xy?-.5*this.pointer.dimensions.y+"px":0)+")"),this.pointer.element.css("x"==this.pointer.xy?"width":"height",parseInt(this.pointer.dimensions[this.pointer.xy])+parseInt(this.container.css("border-"+this.pointer.alignAttribute+"-width"))),this.wrapper.addClass("jBox-pointerPosition-"+this.pointer.position)),this.setContent(this.options.content,!0),this.setTitle(this.options.title,!0),this.options.draggable&&this._draggable(),this._fireEvent("onCreated"))},this.options.createOnInit&&this._create(),this.options.attach&&this.attach(),this._attachEvents=function(){this.options.delayOnHover&&v("#"+this.id).on("mouseenter",function(t){this.isHovered=!0}.bind(this)),this.options.delayOnHover&&v("#"+this.id).on("mouseleave",function(t){this.isHovered=!1}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&!this.fixed&&this.outside&&(this.options.adjustTracker&&v(window).on("scroll.jBox-"+this.id,function(t){this.position()}.bind(this)),(this.options.adjustPosition||this.options.reposition)&&v(window).on("resize.jBox-"+this.id,function(t){this.position()}.bind(this))),"mouse"==this.options.target&&v("body").on("mousemove.jBox-"+this.id,function(t){this.position({mouseTarget:{top:t.pageY,left:t.pageX}})}.bind(this))},this._detachEvents=function(){this.options.closeOnEsc&&v(document).off("keyup.jBox-"+this.id),!0!==this.options.closeOnClick&&"body"!=this.options.closeOnClick||v(document).off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.options.adjustTracker&&v(window).off("scroll.jBox-"+this.id),(this.options.adjustPosition||this.options.reposition)&&v(window).off("resize.jBox-"+this.id),"mouse"==this.options.target&&v("body").off("mousemove.jBox-"+this.id)},this._showOverlay=function(){this.overlay||(this.overlay=v('<div id="'+this.id+'-overlay"/>').addClass("jBox-overlay"+(this.type?" jBox-overlay-"+this.type:"")).css({display:"none",opacity:0,zIndex:this.options.zIndex-1}).appendTo(this.options.appendTo),this.options.overlayClass&&this.overlay.addClass(this.options.overlayClass),"overlay"!=this.options.closeButton&&!0!==this.options.closeButton||this.overlay.append(this.closeButton),"overlay"==this.options.closeOnClick&&this.overlay.on("click tap",function(){this.close({ignoreDelay:!0})}.bind(this)),v("#"+this.id+"-overlay .jBox-closeButton").length&&(this.options.adjustDistance.top=Math.max(v("#"+this.id+"-overlay .jBox-closeButton").outerHeight(),this.options.adjustDistance.top))),!0===this.adjustZIndexOnOpen&&this.overlay.css("zIndex",parseInt(this.wrapper.css("zIndex"),10)-1),"block"!=this.overlay.css("display")&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.overlay.css({display:"block"})}.bind(this)}):this.overlay.css({display:"block",opacity:1}))},this._hideOverlay=function(){this.overlay&&(this.options.fade?this.overlay.stop()&&this.overlay.animate({opacity:0},{queue:!1,duration:this.options.fade,complete:function(){this.overlay.css({display:"none"})}.bind(this)}):this.overlay.css({display:"none",opacity:0}))},this._exposeDimensions=function(){this.wrapper.css({top:-1e4,left:-1e4,right:"auto",bottom:"auto"});var t={x:this.wrapper.outerWidth(),y:this.wrapper.outerHeight()};return this.wrapper.css({top:"auto",left:"auto"}),t},this._generateAnimationCSS=function(){if("object"!=v.type(this.options.animation)&&(this.options.animation={pulse:{open:"pulse",close:"zoomOut"},zoomIn:{open:"zoomIn",close:"zoomIn"},zoomOut:{open:"zoomOut",close:"zoomOut"},move:{open:"move",close:"move"},slide:{open:"slide",close:"slide"},flip:{open:"flip",close:"flip"},tada:{open:"tada",close:"zoomOut"}}[this.options.animation]),!this.options.animation)return null;this.options.animation.open&&(this.options.animation.open=this.options.animation.open.split(":")),this.options.animation.close&&(this.options.animation.close=this.options.animation.close.split(":")),this.options.animation.openDirection=this.options.animation.open[1]||null,this.options.animation.closeDirection=this.options.animation.close[1]||null,this.options.animation.open&&(this.options.animation.open=this.options.animation.open[0]),this.options.animation.close&&(this.options.animation.close=this.options.animation.close[0]),this.options.animation.open&&(this.options.animation.open+="Open"),this.options.animation.close&&(this.options.animation.close+="Close");var a={pulse:{duration:350,css:[["0%","scale(1)"],["50%","scale(1.1)"],["100%","scale(1)"]]},zoomInOpen:{duration:this.options.fade||180,css:[["0%","scale(0.9)"],["100%","scale(1)"]]},zoomInClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(0.9)"]]},zoomOutOpen:{duration:this.options.fade||180,css:[["0%","scale(1.1)"],["100%","scale(1)"]]},zoomOutClose:{duration:this.options.fade||180,css:[["0%","scale(1)"],["100%","scale(1.1)"]]},moveOpen:{duration:this.options.fade||180,positions:{top:{"0%":-12},right:{"0%":12},bottom:{"0%":12},left:{"0%":-12}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},moveClose:{duration:this.options.fade||180,timing:"ease-in",positions:{top:{"100%":-12},right:{"100%":12},bottom:{"100%":12},left:{"100%":-12}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},slideOpen:{duration:400,positions:{top:{"0%":-400},right:{"0%":400},bottom:{"0%":400},left:{"0%":-400}},css:[["0%","translate%XY(%Vpx)"],["100%","translate%XY(0px)"]]},slideClose:{duration:400,timing:"ease-in",positions:{top:{"100%":-400},right:{"100%":400},bottom:{"100%":400},left:{"100%":-400}},css:[["0%","translate%XY(0px)"],["100%","translate%XY(%Vpx)"]]},flipOpen:{duration:600,css:[["0%","perspective(400px) rotateX(90deg)"],["40%","perspective(400px) rotateX(-15deg)"],["70%","perspective(400px) rotateX(15deg)"],["100%","perspective(400px) rotateX(0deg)"]]},flipClose:{duration:this.options.fade||300,css:[["0%","perspective(400px) rotateX(0deg)"],["100%","perspective(400px) rotateX(90deg)"]]},tada:{duration:800,css:[["0%","scale(1)"],["10%, 20%","scale(0.9) rotate(-3deg)"],["30%, 50%, 70%, 90%","scale(1.1) rotate(3deg)"],["40%, 60%, 80%","scale(1.1) rotate(-3deg)"],["100%","scale(1) rotate(0)"]]}};v.each(["pulse","tada"],function(t,i){a[i+"Open"]=a[i+"Close"]=a[i]});var s=function(s,e){var n="@keyframes jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {";return v.each(a[this.options.animation[s]].css,function(t,i){var o=e?i[1].replace("%XY",this._getXY(e).toUpperCase()):i[1];a[this.options.animation[s]].positions&&(o=o.replace("%V",a[this.options.animation[s]].positions[e][i[0]])),n+=i[0]+" {transform:"+o+";}"}.bind(this)),n+="}",n+=".jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+" {",n+="animation-duration: "+a[this.options.animation[s]].duration+"ms;",n+="animation-name: jBox-"+this.id+"-animation-"+this.options.animation[s]+"-"+s+(e?"-"+e:"")+";",n+=a[this.options.animation[s]].timing?"animation-timing-function: "+a[this.options.animation[s]].timing+";":"",n+="}"}.bind(this);this._animationCSS="",v.each(["open","close"],function(t,o){if(!this.options.animation[o]||!a[this.options.animation[o]]||"close"==o&&!this.options.fade)return"";a[this.options.animation[o]].positions?v.each(["top","right","bottom","left"],function(t,i){this._animationCSS+=s(o,i)}.bind(this)):this._animationCSS+=s(o)}.bind(this))},this.options.animation&&this._generateAnimationCSS(),this._blockBodyClick=function(){this.blockBodyClick=!0,setTimeout(function(){this.blockBodyClick=!1}.bind(this),10)},this._animate=function(t){if(t=t||(this.isOpen?"open":"close"),!this.options.fade&&"close"==t)return null;var i=this.options.animation[t+"Direction"]||("center"!=this.align?this.align:this.options.attributes.x);this.flipped&&this._getXY(i)==this._getXY(this.align)&&(i=this._getOpp(i));var o="jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+" jBox-"+this.id+"-animation-"+this.options.animation[t]+"-"+t+"-"+i;this.wrapper.addClass(o);i=1e3*parseFloat(this.wrapper.css("animation-duration"));"close"==t&&(i=Math.min(i,this.options.fade)),setTimeout(function(){this.wrapper&&this.wrapper.removeClass(o)}.bind(this),i)},this._abortAnimation=function(){var t=this.wrapper.attr("class").split(" ").filter(function(t){return 0!==t.lastIndexOf("jBox-"+this.id+"-animation",0)}.bind(this));this.wrapper.attr("class",t.join(" "))},(this.options.responsiveWidth||this.options.responsiveHeight)&&v(window).on("resize.responsivejBox-"+this.id,function(t){this.isOpen&&this.position()}.bind(this)),"string"===v.type(this.options.preloadAudio)&&(this.options.preloadAudio=[this.options.preloadAudio]),"string"===v.type(this.options.audio)&&(this.options.audio={open:this.options.audio}),"number"===v.type(this.options.volume)&&(this.options.volume={open:this.options.volume,close:this.options.volume}),!0===this.options.preloadAudio&&this.options.audio&&(this.options.preloadAudio=[],v.each(this.options.audio,function(t,i){this.options.preloadAudio.push(i+".mp3"),this.options.preloadAudio.push(i+".ogg")}.bind(this))),this.options.preloadAudio.length&&v.each(this.options.preloadAudio,function(t,i){var o=new Audio;o.src=i,o.preload="auto"}),this._fireEvent("onInit"),this}var t,i;return h.prototype.attach=function(t,s){return t=t||this.options.attach,"string"==v.type(t)&&(t=v(t)),s=s||this.options.trigger,t&&t.length&&v.each(t,function(t,o){(o=v(o)).data("jBox-attached-"+this.id)||("title"==this.options.getContent&&null!=o.attr("title")&&o.data("jBox-getContent",o.attr("title")).removeAttr("title"),this.attachedElements||(this.attachedElements=[]),this.attachedElements.push(o[0]),o.on(s+".jBox-attach-"+this.id,function(t){var i;this.timer&&clearTimeout(this.timer),"mouseenter"==s&&this.isOpen&&this.source[0]==o[0]||(this.isOpen&&this.source&&this.source[0]!=o[0]&&(i=!0),this.source=o,this.options.target||(this.target=o),"click"==s&&this.options.preventDefault&&t.preventDefault(),this["click"!=s||i?"open":"toggle"]())}.bind(this)),"mouseenter"==this.options.trigger&&o.on("mouseleave",function(t){if(!this.wrapper)return null;this.options.closeOnMouseleave&&(t.relatedTarget==this.wrapper[0]||v(t.relatedTarget).parents("#"+this.id).length)||this.close()}.bind(this)),o.data("jBox-attached-"+this.id,s),this._fireEvent("onAttach",o))}.bind(this)),this},h.prototype.detach=function(t){return(t=t||(this.attachedElements||[]))&&t.length&&v.each(t,function(t,i){(i=v(i)).data("jBox-attached-"+this.id)&&(i.off(i.data("jBox-attached-"+this.id)+".jBox-attach-"+this.id),i.data("jBox-attached-"+this.id,null)),this.attachedElements=v.grep(this.attachedElements,function(t){return t!=i[0]})}.bind(this)),this},h.prototype.setTitle=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();return this.title||(this.titleContainer=v('<div class="jBox-title"/>'),this.title=v("<div/>").appendTo(this.titleContainer),"title"!=this.options.closeButton&&(!0!==this.options.closeButton||this.options.overlay)||(this.wrapper.addClass("jBox-closeButton-title"),this.closeButton.appendTo(this.titleContainer)),this.titleContainer.insertBefore(this.content),this._setTitleWidth()),this.wrapper[t?"addClass":"removeClass"]("jBox-hasTitle"),this.title.html(t),s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setContent=function(t,i){if(null==t||null==t)return this;this.wrapper||this._create();var o=this.wrapper.outerHeight(),s=this.wrapper.outerWidth();switch(this.content.children("[data-jbox-content-appended]").appendTo("body").css({display:"none"}),v.type(t)){case"string":this.content.html(t);break;case"object":t&&(t instanceof v||t.constructor.prototype.jquery)?(this.content.html(""),t.attr("data-jbox-content-appended",1).appendTo(this.content).css({display:"block"})):this.content.html(JSON.stringify(t))}return s!=this.wrapper.outerWidth()&&this._setTitleWidth(),this.options.draggable&&this._draggable(),i||!this.options.repositionOnContent||o==this.wrapper.outerHeight()&&s==this.wrapper.outerWidth()||this.position(),this},h.prototype.setDimensions=function(t,i,o){this.wrapper||this._create(),this.content.css(t,this._getInt(i=null==i?"auto":i)),"width"==t&&this._setTitleWidth(),this.options[t]=i,null!=o&&!o||this.position()},h.prototype.setWidth=function(t,i){this.setDimensions("width",t,i)},h.prototype.setHeight=function(t,i){this.setDimensions("height",t,i)},h.prototype.position=function(o){if(o=v.extend(!0,this.options,o=o||{}),this.target=o.target||this.target||v(window),this.target instanceof v||"mouse"==this.target||(this.target=v(this.target)),!this.target.length)return this;this.content.css({width:this._getInt(o.width,"width"),height:this._getInt(o.height,"height"),minWidth:this._getInt(o.minWidth,"width"),minHeight:this._getInt(o.minHeight,"height"),maxWidth:this._getInt(o.maxWidth,"width"),maxHeight:this._getInt(o.maxHeight,"height")}),this._setTitleWidth();var s=this._exposeDimensions();"mouse"==this.target||this.target.data("jBox-"+this.id+"-fixed")||this.target.data("jBox-"+this.id+"-fixed",this.target[0]!=v(window)[0]&&("fixed"==this.target.css("position")||0<this.target.parents().filter(function(){return"fixed"==v(this).css("position")}).length)?"fixed":"static");var t={x:v(window).outerWidth(),y:v(window).outerHeight(),top:o.fixed&&this.target.data("jBox-"+this.id+"-fixed")?0:v(window).scrollTop(),left:o.fixed&&this.target.data("jBox-"+this.id+"-fixed")?0:v(window).scrollLeft()};t.bottom=t.top+t.y,t.right=t.left+t.x;try{var i=this.target.offset()}catch(t){i={top:0,left:0}}"mouse"!=this.target&&"fixed"==this.target.data("jBox-"+this.id+"-fixed")&&o.fixed&&(i.top=i.top-v(window).scrollTop(),i.left=i.left-v(window).scrollLeft());var e={x:"mouse"==this.target?12:this.target.outerWidth(),y:"mouse"==this.target?20:this.target.outerHeight(),top:"mouse"==this.target&&o.mouseTarget?o.mouseTarget.top:i?i.top:0,left:"mouse"==this.target&&o.mouseTarget?o.mouseTarget.left:i?i.left:0},n=o.outside&&!("center"==o.position.x&&"center"==o.position.y),a={x:t.x-o.adjustDistance.left-o.adjustDistance.right,y:t.y-o.adjustDistance.top-o.adjustDistance.bottom,left:n?e.left-v(window).scrollLeft()-o.adjustDistance.left:0,right:n?t.x-e.left+v(window).scrollLeft()-e.x-o.adjustDistance.right:0,top:n?e.top-v(window).scrollTop()-this.options.adjustDistance.top:0,bottom:n?t.y-e.top+v(window).scrollTop()-e.y-o.adjustDistance.bottom:0},h={x:"x"!=o.outside&&"xy"!=o.outside||"number"==v.type(o.position.x)?null:o.position.x,y:"y"!=o.outside&&"xy"!=o.outside||"number"==v.type(o.position.y)?null:o.position.y},r={x:!1,y:!1};h.x&&s.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),h.y&&s.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),(o.responsiveWidth||o.responsiveHeight)&&(m=function(){var t;o.responsiveWidth&&s.x>a[h.x||"x"]&&(t=a[h.x||"x"]-(this.pointer&&n&&"x"==o.outside?this.pointer.dimensions.x:0)-parseInt(this.container.css("border-left-width"))-parseInt(this.container.css("border-right-width")),this.content.css({width:t>this.options.responsiveMinWidth?t:null,minWidth:t<parseInt(this.content.css("minWidth"))?0:null}),this._setTitleWidth()),s=this._exposeDimensions()}.bind(this),o.responsiveWidth&&m(),o.responsiveWidth&&!r.y&&h.y&&s.y>a[h.y]&&a[this._getOpp(h.y)]>a[h.y]&&(h.y=this._getOpp(h.y))&&(r.y=!0),f=function(){var t;o.responsiveHeight&&s.y>a[h.y||"y"]&&(t=function(){return this.titleContainer||this.footer?("none"==this.wrapper.css("display")?(this.wrapper.css("display","block"),t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),this.wrapper.css("display","none")):t=(this.titleContainer?this.titleContainer.outerHeight():0)+(this.footer?this.footer.outerHeight():0),t||0):0;var t}.bind(this),t=a[h.y||"y"]-(this.pointer&&n&&"y"==o.outside?this.pointer.dimensions.y:0)-t()-parseInt(this.container.css("border-top-width"))-parseInt(this.container.css("border-bottom-width")),this.content.css({height:t>this.options.responsiveMinHeight?t:null}),this._setTitleWidth()),s=this._exposeDimensions()}.bind(this),o.responsiveHeight&&f(),o.responsiveHeight&&!r.x&&h.x&&s.x>a[h.x]&&a[this._getOpp(h.x)]>a[h.x]&&(h.x=this._getOpp(h.x))&&(r.x=!0),o.adjustPosition&&"move"!=o.adjustPosition&&(r.x&&m(),r.y&&f()));var p={},l=function(t){if("number"!=v.type(o.position[t])){var i=o.attributes[t]="x"==t?"left":"top";if(p[i]=e[i],"center"==o.position[t])return p[i]+=Math.ceil((e[t]-s[t])/2),void("mouse"!=this.target&&this.target[0]&&this.target[0]==v(window)[0]&&(p[i]+=.5*(o.adjustDistance[i]-o.adjustDistance[this._getOpp(i)])));i!=o.position[t]&&(p[i]+=e[t]-s[t]),o.outside!=t&&"xy"!=o.outside||(p[i]+=s[t]*(i!=o.position[t]?1:-1))}else p[o.attributes[t]]=o.position[t]}.bind(this);if(l("x"),l("y"),this.pointer&&"target"==o.pointTo&&"number"!=v.type(o.position.x)&&"number"!=v.type(o.position.y)&&(x=0,"center"===this.pointer.align?"center"!=o.position[this._getOpp(o.outside)]&&(x+=s[this._getOpp(o.outside)]/2):"center"===o.position[this._getOpp(o.outside)]?x+=(s[this._getOpp(o.outside)]/2-this.pointer.dimensions[this._getOpp(o.outside)]/2)*(this.pointer.align==this._getTL(this.pointer.align)?1:-1):x+=this.pointer.align!=o.position[this._getOpp(o.outside)]?s[this._getOpp(o.outside)]*(-1!==v.inArray(this.pointer.align,["top","left"])?1:-1)+this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==v.inArray(this.pointer.align,["top","left"])?-1:1):this.pointer.dimensions[this._getOpp(o.outside)]/2*(-1!==v.inArray(this.pointer.align,["top","left"])?1:-1),x*=o.position[this._getOpp(o.outside)]==this.pointer.alignAttribute?-1:1,x+=this.pointer.offset*(this.pointer.align==this._getOpp(this._getTL(this.pointer.align))?1:-1),p[this._getTL(this._getOpp(this.pointer.xy))]+=x),p[o.attributes.x]+=o.offset.x,p[o.attributes.y]+=o.offset.y,this.wrapper.css(p),o.adjustPosition){this.positionAdjusted&&(this.pointer&&this.wrapper.css("padding",0).css("padding-"+this._getOpp(this.outside),this.pointer.dimensions[this._getXY(this.outside)]).removeClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).addClass("jBox-pointerPosition-"+this.pointer.position),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+this._getOpp(this.outside)).css(this.pointer.margin),this.positionAdjusted=!1,this.flipped=!1);var d=t.top>p.top-(o.adjustDistance.top||0),c=t.right<p.left+s.x+(o.adjustDistance.right||0),u=t.bottom<p.top+s.y+(o.adjustDistance.bottom||0),g=t.left>p.left-(o.adjustDistance.left||0),i=g?"left":c?"right":null,m=d?"top":u?"bottom":null;if(i||m){if(("Modal"==this.type||"Confirm"==this.type)&&"number"==v.type(this.options.position.x)&&"number"==v.type(this.options.position.y)){var f=0,x=0;return this.options.holdPosition&&(g?f=t.left-(p.left-(o.adjustDistance.left||0)):c&&(f=t.right-(p.left+s.x+(o.adjustDistance.right||0))),d?x=t.top-(p.top-(o.adjustDistance.top||0)):u&&(x=t.bottom-(p.top+s.y+(o.adjustDistance.bottom||0))),this.options.position.x=Math.max(t.top,this.options.position.x+f),this.options.position.y=Math.max(t.left,this.options.position.y+x),l("x"),l("y"),this.wrapper.css(p)),this._fireEvent("onPosition"),this}!0!==o.adjustPosition&&"flip"!==o.adjustPosition||(y=function(t){this.wrapper.css(this._getTL(t),p[this._getTL(t)]+(s[this._getXY(t)]+o.offset[this._getXY(t)]*("top"==t||"left"==t?-2:2)+e[this._getXY(t)])*("top"==t||"left"==t?1:-1)),this.pointer&&this.wrapper.removeClass("jBox-pointerPosition-"+this.pointer.position).addClass("jBox-pointerPosition-"+this._getOpp(this.pointer.position)).css("padding",0).css("padding-"+t,this.pointer.dimensions[this._getXY(t)]),this.pointer&&this.pointer.element.attr("class","jBox-pointer jBox-pointer-"+t),this.positionAdjusted=!0,this.flipped=!0}.bind(this),r.x&&y(this.options.position.x),r.y&&y(this.options.position.y));var y="x"==this._getXY(this.outside)?m:i;this.pointer&&"target"==o.pointTo&&"flip"!=o.adjustPosition&&this._getXY(y)==this._getOpp(this._getXY(this.outside))&&(m="center"==this.pointer.align?s[this._getXY(y)]/2-this.pointer.dimensions[this._getOpp(this.pointer.xy)]/2-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))*(y!=this._getTL(y)?-1:1):y==this.pointer.alignAttribute?parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute)):s[this._getXY(y)]-parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-this.pointer.dimensions[this._getXY(y)],i=y==this._getTL(y)?t[this._getTL(y)]-p[this._getTL(y)]+o.adjustDistance[y]:-1*(t[this._getOpp(this._getTL(y))]-p[this._getTL(y)]-o.adjustDistance[y]-s[this._getXY(y)]),y==this._getOpp(this._getTL(y))&&p[this._getTL(y)]-i<t[this._getTL(y)]+o.adjustDistance[this._getTL(y)]&&(i-=t[this._getTL(y)]+o.adjustDistance[this._getTL(y)]-(p[this._getTL(y)]-i)),(i=Math.min(i,m))<=m&&0<i&&(this.pointer.element.css("margin-"+this.pointer.alignAttribute,parseInt(this.pointer.element.css("margin-"+this.pointer.alignAttribute))-i*(y!=this.pointer.alignAttribute?-1:1)),this.wrapper.css(this._getTL(y),p[this._getTL(y)]+i*(y!=this._getTL(y)?-1:1)),this.positionAdjusted=!0))}}return this._fireEvent("onPosition"),this},(h.prototype.unscroll=function(t){if(this.set=function(t,i){window.unscrollStore||(window.unscrollStore={}),window.unscrollStore[t]=i},this.get=function(t){return window.unscrollStore?window.unscrollStore[t]:null},this.getScrollbarWidth=function(){if(this.get("scrollbarWidth"))return this.get("scrollbarWidth")+"px";var t=document.createElement("div");t.style.width="100px",t.style.height="100px",t.style.overflow="scroll",t.style.position="absolute",t.style.top="-10000",document.body.appendChild(t);var i=t.offsetWidth-t.clientWidth;return document.body.removeChild(t),this.set("scrollbarWidth",i),i+"px"},this.getElementsToAdjust=function(o){(o="string"==typeof(o=o||[])?[[o,"padding-right"]]:o).forEach(function(t,i){"string"==typeof t&&(o[i]=[t,"padding-right"])});for(var t=!1,i=0;i<o.length;i++)-1!==o[i][0].indexOf("body")&&(t=!0);return!1===t&&o.push(["body","padding-right"]),o},this.pageHasScrollbar=function(){return this.getScrollbarWidth()&&document.body.offsetHeight>window.innerHeight},this.pageHasScrollbar()){t=this.getElementsToAdjust(t);for(var i=0;i<t.length;i++)for(var o=document.querySelectorAll(t[i][0]),s=0;s<o.length;s++){if(o[s].getAttribute("data-unscroll"))return;var e=t[i][1],n=window.getComputedStyle(o[s]).getPropertyValue(e);o[s].setAttribute("data-unscroll",e),o[s].style[e]="calc("+(n=n||"0px")+" "+("padding-right"==e||"right"==e?"+":"-")+" "+this.getScrollbarWidth()+")"}}var a,h;document.getElementById("unscroll-class-name")||(a=document.head||document.getElementsByTagName("head")[0],(h=document.createElement("style")).type="text/css",h.setAttribute("id","unscroll-class-name"),h.appendChild(document.createTextNode(".unscrollable { overflow: hidden !important; }")),a.appendChild(h)),document.body.classList.add("unscrollable")}).reset=function(){for(var t=document.querySelectorAll("[data-unscroll]"),i=0;i<t.length;i++){var o=t[i].getAttribute("data-unscroll");t[i].style[o]=null,t[i].removeAttribute("data-unscroll")}document.body.classList.remove("unscrollable")},h.prototype.open=function(t){if(t=t||{},this.isDestroyed)return this;if(this.wrapper||this._create(),this._styles||(this._styles=v("<style/>").append(this._animationCSS).appendTo(v("head"))),this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;this.options.closeOnEsc&&v(document).on("keyup.jBox-"+this.id,function(t){27==t.keyCode&&this.close({ignoreDelay:!0})}.bind(this)),!0!==this.options.closeOnClick&&"body"!==this.options.closeOnClick||(v("body").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(t){this.blockBodyClick||"body"==this.options.closeOnClick&&(t.target==this.wrapper[0]||this.wrapper.has(t.target).length)||this.close({ignoreDelay:!0})}.bind(this)),this.isTouchDevice&&v("body > *").on("click.jBox-"+this.id+" tap.jBox-"+this.id,function(){return!0}));var i=function(){!0===this.adjustZIndexOnOpen&&(h.zIndexMax=Math.max(parseInt(this.wrapper.css("zIndex"),10),this.options.zIndex,h.zIndexMax||0,h.zIndexMaxDragover||0)+2,this.wrapper.css("zIndex",h.zIndexMax),this.options.zIndex=h.zIndexMax),this.source&&this.options.getTitle&&this.source.attr(this.options.getTitle)&&this.setTitle(this.source.attr(this.options.getTitle),!0),this.source&&this.options.getContent&&(this.source.data("jBox-getContent")?this.setContent(this.source.data("jBox-getContent"),!0):this.source.attr(this.options.getContent)?this.setContent(this.source.attr(this.options.getContent),!0):"html"==this.options.getContent&&this.setContent(this.source.html(),!0)),this._fireEvent("onOpen"),(this.options.ajax&&(this.options.ajax.url||this.source&&this.source.attr(this.options.ajax.getURL))&&(!this.ajaxLoaded||this.options.ajax.reload)||t.ajax&&(t.ajax.url||t.ajax.data))&&("strict"==this.options.ajax.reload||!this.source||!this.source.data("jBox-ajax-data")||t.ajax&&(t.ajax.url||t.ajax.data)?this.ajax(t.ajax||null,!0):this.setContent(this.source.data("jBox-ajax-data"))),this.positionedOnOpen&&!this.options.repositionOnOpen||!this.position(t)||(this.positionedOnOpen=!0),this.isClosing&&this._abortAnimation(),this.isOpen||(this.isOpen=!0,this.options.autoClose&&(this.options.delayClose=this.options.autoClose)&&this.close(),this._attachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?h.blockScrollScopes?h.blockScrollScopes++:(h.blockScrollScopes=1,this.unscroll(Array.isArray(this.options.blockScrollAdjust)||"string"==typeof this.options.blockScrollAdjust?this.options.blockScrollAdjust:null)):v("body").addClass("jBox-blockScroll-"+this.id)),this.options.overlay&&(this._showOverlay(),this.position()),this.options.animation&&!this.isClosing&&this._animate("open"),this.options.audio&&this.options.audio.open&&this.audio(this.options.audio.open,this.options.volume.open),this.options.fade?this.wrapper.stop().animate({opacity:1},{queue:!1,duration:this.options.fade,start:function(){this.isOpening=!0,this.wrapper.css({display:"block"})}.bind(this),complete:function(){this._fireEvent("onOpenComplete")}.bind(this),always:function(){this.isOpening=!1,setTimeout(function(){this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1)}.bind(this),10)}.bind(this)}):(this.wrapper.css({display:"block",opacity:1}),this.positionOnFadeComplete&&this.position()&&(this.positionOnFadeComplete=!1),this._fireEvent("onOpenComplete")))}.bind(this);return!this.options.delayOpen||this.isOpen||this.isClosing||t.ignoreDelay?i():this.timer=setTimeout(i,this.options.delayOpen),this},h.prototype.close=function(t){if(t=t||{},v("body").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isTouchDevice&&v("body > *").off("click.jBox-"+this.id+" tap.jBox-"+this.id),this.isDestroyed||this.isClosing)return this;if(this.timer&&clearTimeout(this.timer),this._blockBodyClick(),this.isDisabled)return this;var i,o,s,e=function(){var t;this._fireEvent("onClose"),this.options.cancelAjaxOnClose&&this.cancelAjax(),this.isOpen&&(this.isOpen=!1,this._detachEvents(),this.options.blockScroll&&(this.options.blockScrollAdjust?(h.blockScrollScopes=h.blockScrollScopes?--h.blockScrollScopes:0)||this.unscroll.reset():v("body").removeClass("jBox-blockScroll-"+this.id)),this.options.overlay&&this._hideOverlay(),this.options.animation&&!this.isOpening&&this._animate("close"),this.options.audio&&this.options.audio.close&&this.audio(this.options.audio.close,this.options.volume.close),(t=this.isTouchDevice&&"mouse"==this.options.target?0:this.options.fade)?this.wrapper.stop().animate({opacity:0},{queue:!1,duration:t,start:function(){this.isClosing=!0}.bind(this),complete:function(){this.wrapper.css({display:"none"}),this._fireEvent("onCloseComplete")}.bind(this),always:function(){this.isClosing=!1}.bind(this)}):(this.wrapper.css({display:"none",opacity:0}),this._fireEvent("onCloseComplete")))}.bind(this);return t.ignoreDelay||this.isTouchDevice&&"mouse"==this.options.target?e():(this.options.delayOnHover||this.options.showCountdown)&&10<this.options.delayClose?(o=(i=this).options.delayClose,s=Date.now(),this.options.showCountdown&&!this.inner&&(t=v('<div class="jBox-countdown" />'),this.inner=v('<div class="jBox-countdown-inner" />'),t.prepend(this.inner),v("#"+this.id).append(t)),this.countdown=function(){var t=Date.now();i.isHovered||(o-=t-s),s=t,0<o?(i.options.showCountdown&&i.inner.css("width",100*o/i.options.delayClose+"%"),window.requestAnimationFrame(i.countdown)):e()},window.requestAnimationFrame(this.countdown)):this.timer=setTimeout(e,Math.max(this.options.delayClose,10)),this},h.prototype.toggle=function(t){return this[this.isOpen?"close":"open"](t),this},h.prototype.disable=function(){return this.isDisabled=!0,this},h.prototype.enable=function(){return this.isDisabled=!1,this},h.prototype.hide=function(){return this.disable(),this.wrapper&&(this.cacheWrapperDisplay=this.wrapper.css("display"),this.wrapper.css({display:"none"})),this.overlay&&(this.cacheOverlayDisplay=this.overlay.css("display"),this.overlay.css({display:"none"})),this},h.prototype.show=function(){return this.enable(),this.wrapper&&this.cacheWrapperDisplay&&(this.wrapper.css({display:this.cacheWrapperDisplay}),this.cacheWrapperDisplay=null),this.overlay&&this.cacheOverlayDisplay&&(this.overlay.css({display:this.cacheOverlayDisplay}),this.cacheOverlayDisplay=null),this},h.prototype.ajax=function(o,i){o=o||{},v.each([["getData","data"],["getURL","url"]],function(t,i){this.options.ajax[i[0]]&&!o[i[1]]&&this.source&&null!=this.source.attr(this.options.ajax[i[0]])&&(o[i[1]]=this.source.attr(this.options.ajax[i[0]])||"")}.bind(this));var t=v.extend(!0,{},this.options.ajax);this.cancelAjax();var s=o.beforeSend||t.beforeSend||function(){},e=o.complete||t.complete||function(){},n=o.success||t.success||function(){},a=o.error||t.error||function(){},h=v.extend(!0,t,o);return h.beforeSend=function(t){h.loadingClass&&this.wrapper.addClass(!0===h.loadingClass?"jBox-loading":h.loadingClass),h.spinner&&(this.spinnerDelay=setTimeout(function(){this.wrapper.addClass("jBox-loading-spinner"),h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.spinner=v(!0!==h.spinner?h.spinner:'<div class="jBox-spinner"></div>').appendTo(this.container),this.titleContainer&&"absolute"==this.spinner.css("position")&&this.spinner.css({transform:"translateY("+.5*this.titleContainer.outerHeight()+"px)"})}.bind(this),""!=this.content.html()&&h.spinnerDelay||0)),s.bind(this)(t)}.bind(this),h.complete=function(t){this.spinnerDelay&&clearTimeout(this.spinnerDelay),this.wrapper.removeClass("jBox-loading jBox-loading-spinner jBox-loading-spinner-delay"),this.spinner&&this.spinner.length&&this.spinner.remove()&&h.spinnerReposition&&(i?this.positionOnFadeComplete=!0:this.position()),this.ajaxLoaded=!0,e.bind(this)(t)}.bind(this),h.success=function(t){h.setContent&&this.setContent(t,!0)&&(i?this.positionOnFadeComplete=!0:this.position()),h.setContent&&this.source&&this.source.data("jBox-ajax-data",t),n.bind(this)(t)}.bind(this),h.error=function(t){a.bind(this)(t)}.bind(this),this.ajaxRequest=v.ajax(h),this},h.prototype.cancelAjax=function(){this.ajaxRequest&&(this.ajaxRequest.abort(),this.ajaxLoaded=!1)},h.prototype.audio=function(t,i){if(!t)return this;var o;(h._audio=!h._audio?{}:h._audio)[t]||(o=v("<audio/>"),v("<source/>",{src:t+".mp3"}).appendTo(o),v("<source/>",{src:t+".ogg"}).appendTo(o),h._audio[t]=o[0]),h._audio[t].volume=Math.min((null!=i?i:100)/100,1);try{h._audio[t].pause(),h._audio[t].currentTime=0}catch(t){}return h._audio[t].play(),this},h._animationSpeeds={tada:1e3,tadaSmall:1e3,flash:500,shake:400,pulseUp:250,pulseDown:250,popIn:250,popOut:250,fadeIn:200,fadeOut:200,slideUp:400,slideRight:400,slideLeft:400,slideDown:400},h.prototype.animate=function(t,i){i=i||{},this.animationTimeout||(this.animationTimeout={}),i.element||(i.element=this.wrapper),i.element.data("jBox-animating-id")||i.element.data("jBox-animating-id",h._getUniqueElementID()),i.element.data("jBox-animating")&&(i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),this.animationTimeout[i.element.data("jBox-animating-id")]&&clearTimeout(this.animationTimeout[i.element.data("jBox-animating-id")])),i.element.addClass("jBox-animated-"+t).data("jBox-animating","jBox-animated-"+t),this.animationTimeout[i.element.data("jBox-animating-id")]=setTimeout(function(){i.element.removeClass(i.element.data("jBox-animating")).data("jBox-animating",null),i.complete&&i.complete()},h._animationSpeeds[t])},h.prototype.swipeDetector=function(i,o){var s=0,e=0,n=0,a=0,h=0;function t(t){o.useOnlyTouch&&!t.originalEvent.touches||(t.originalEvent.touches&&(t=t.originalEvent.touches[0]),0===s&&(s=1,e=t.clientX,n=t.clientY))}function r(t){2===s&&(s=0,Math.abs(a)>Math.abs(h)&&Math.abs(a)>o.swipeThreshold?a<0?i.trigger(v.Event("swipeLeft.sd")):i.trigger(v.Event("swipeRight.sd")):Math.abs(h)>o.swipeThreshold&&(h<0?i.trigger(v.Event("swipeUp.sd")):i.trigger(v.Event("swipeDown.sd"))))}function p(t){var i;1===s&&(i=(t=t.originalEvent.touches?t.originalEvent.touches[0]:t).clientX-e,t=t.clientY-n,(Math.abs(i)>o.swipeThreshold||Math.abs(t)>o.swipeThreshold)&&(s=2,a=i,h=t))}return o=v.extend({swipeThreshold:70,useOnlyTouch:!1},o),i.on("mousedown touchstart",t),v("html").on("mouseup touchend",r),v("html").on("mousemove touchmove",p),i},h.prototype.destroy=function(){return this.detach(),this.isOpen&&this.close({ignoreDelay:!0}),this.wrapper&&this.wrapper.remove(),this.overlay&&this.overlay.remove(),this._styles&&this._styles.remove(),this.isDestroyed=!0,this},h._getUniqueID=(t=1,function(){return t++}),h._getUniqueElementID=(i=1,function(){return i++}),h._pluginOptions={},h.plugin=function(t,i){h._pluginOptions[t]=i},v.fn.jBox=function(t,i){return new h(t=t||{},v.extend(i=i||{},{attach:this}))},h}!function(i,o){"function"==typeof define&&define.amd?define(["jquery"],function(t){return i.jBox=o(t)}):"object"==typeof module&&module.exports?module.exports=i.jBox=o(require("jquery")):i.jBox=o(i.jQuery)}(this,function(t){var i=jBoxWrapper(t);try{"undefined"!=typeof jBoxConfirmWrapper&&jBoxConfirmWrapper&&jBoxConfirmWrapper(i,t)}catch(t){console.error(t)}try{"undefined"!=typeof jBoxImageWrapper&&jBoxImageWrapper&&jBoxImageWrapper(i,t)}catch(t){console.error(t)}try{"undefined"!=typeof jBoxNoticeWrapper&&jBoxNoticeWrapper&&jBoxNoticeWrapper(i,t)}catch(t){console.error(t)}return i});
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,58 @@
1
+.jBox-Confirm .jBox-content {
2
+  text-align: center;
3
+  padding: 46px 35px;
4
+}
5
+
6
+@media (max-width: 500px) {
7
+  .jBox-Confirm .jBox-content {
8
+    padding: 32px 20px;
9
+  }
10
+}
11
+
12
+.jBox-Confirm-footer {
13
+  height: 46px;
14
+}
15
+
16
+.jBox-Confirm-button {
17
+  display: block;
18
+  float: left;
19
+  cursor: pointer;
20
+  text-align: center;
21
+  width: 50%;
22
+  line-height: 46px;
23
+  height: 46px;
24
+  overflow: hidden;
25
+  padding: 0 10px;
26
+  transition: color .2s, background-color .2s;
27
+  box-sizing: border-box;
28
+}
29
+
30
+.jBox-Confirm-button-cancel {
31
+  border-bottom-left-radius: 4px;
32
+  background: #ddd;
33
+  color: #666;
34
+}
35
+
36
+.jBox-Confirm-button-cancel:hover, .jBox-Confirm-button-cancel:active {
37
+  background: #ccc;
38
+}
39
+
40
+.jBox-Confirm-button-cancel:active {
41
+  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
42
+}
43
+
44
+.jBox-Confirm-button-submit {
45
+  border-bottom-right-radius: 4px;
46
+  background: #7d0;
47
+  color: #fff;
48
+}
49
+
50
+.jBox-Confirm-button-submit:hover, .jBox-Confirm-button-submit:active {
51
+  background: #6c0;
52
+}
53
+
54
+.jBox-Confirm-button-submit:active {
55
+  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
56
+}
57
+
58
+/*# sourceMappingURL=jBox.Confirm.css.map */
0 59
new file mode 100644
... ...
@@ -0,0 +1,97 @@
1
+/**
2
+ * jBox Confirm plugin: Add a confirm dialog to links, buttons, etc.
3
+ *
4
+ * Author: Stephan Wagner <stephanwagner.me@gmail.com> (https://stephanwagner.me)
5
+ *
6
+ * License: MIT (https://opensource.org/licenses/MIT)
7
+ *
8
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
9
+ */
10
+
11
+function jBoxConfirmWrapper(jBox, jQuery) {
12
+
13
+  new jBox.plugin('Confirm', {
14
+
15
+
16
+    // Options (https://stephanwagner.me/jBox/options#options-confirm)
17
+
18
+    confirmButton: 'Submit',  // Text for the submit button
19
+    cancelButton: 'Cancel',   // Text for the cancel button
20
+    confirm: null,            // Function to execute when clicking the submit button. By default jBox will use the onclick or href attribute in that order if found
21
+    cancel: null,             // Function to execute when clicking the cancel button
22
+    closeOnConfirm: true,     // Close jBox when the user clicks the confirm button
23
+    target: window,
24
+    fixed: true,
25
+    attach: '[data-confirm]',
26
+    getContent: 'data-confirm',
27
+    content: 'Do you really want to do this?',
28
+    minWidth: 360,
29
+    maxWidth: 500,
30
+    blockScroll: true,
31
+    closeOnEsc: true,
32
+    closeOnClick: false,
33
+    closeButton: false,
34
+    overlay: true,
35
+    animation: 'zoomIn',
36
+    preventDefault: true,
37
+
38
+
39
+    // Triggered when jBox is attached to the element
40
+
41
+    _onAttach: function (el)
42
+    {
43
+      // Extract the href or the onclick event if no submit event is passed
44
+      if (!this.options.confirm) {
45
+        var submit = el.attr('onclick') ? el.attr('onclick') : (
46
+          el.attr('href') ? (
47
+            el.attr('target') ? 'window.open("' + el.attr('href') + '", "' + el.attr('target') + '");'  : 'window.location.href = "' + el.attr('href') + '";'
48
+          ) : '');
49
+        el.prop('onclick', null).data('jBox-Confirm-submit', submit);
50
+      }
51
+    },
52
+
53
+
54
+    // Triggered when jBox was created
55
+
56
+    _onCreated: function ()
57
+    {
58
+      // Add modal class to mimic jBox modal
59
+      this.wrapper.addClass('jBox-Modal');
60
+
61
+      // Add a footer to the jBox container
62
+      this.footer = jQuery('<div class="jBox-Confirm-footer"/>');
63
+
64
+      jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-cancel"/>')
65
+        .html(this.options.cancelButton)
66
+        .on('click tap', function () {
67
+          this.options.cancel && this.options.cancel(this.source);
68
+          this.close();
69
+        }.bind(this))
70
+        .appendTo(this.footer);
71
+
72
+      this.submitButton = jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-submit"/>')
73
+        .html(this.options.confirmButton)
74
+        .appendTo(this.footer);
75
+
76
+      this.footer.appendTo(this.container);
77
+    },
78
+
79
+
80
+    // Triggered when jBox is opened
81
+
82
+    _onOpen: function ()
83
+    {
84
+      // Set the new action for the submit button
85
+      this.submitButton
86
+        .off('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id)
87
+        .on('click.jBox-Confirm' + this.id + ' tap.jBox-Confirm' + this.id, function () {
88
+          this.options.confirm ? this.options.confirm(this.source) : eval(this.source.data('jBox-Confirm-submit'));
89
+          this.options.closeOnConfirm && this.close();
90
+        }.bind(this));
91
+    }
92
+
93
+  });
94
+
95
+};
96
+
97
+//# sourceMappingURL=jBox.Confirm.js.map
0 98
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-Confirm .jBox-content{text-align:center;padding:46px 35px}@media (max-width:500px){.jBox-Confirm .jBox-content{padding:32px 20px}}.jBox-Confirm-footer{height:46px}.jBox-Confirm-button{display:block;float:left;cursor:pointer;text-align:center;width:50%;line-height:46px;height:46px;overflow:hidden;padding:0 10px;transition:color .2s,background-color .2s;box-sizing:border-box}.jBox-Confirm-button-cancel{border-bottom-left-radius:4px;background:#ddd;color:#666}.jBox-Confirm-button-cancel:active,.jBox-Confirm-button-cancel:hover{background:#ccc}.jBox-Confirm-button-cancel:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}.jBox-Confirm-button-submit{border-bottom-right-radius:4px;background:#7d0;color:#fff}.jBox-Confirm-button-submit:active,.jBox-Confirm-button-submit:hover{background:#6c0}.jBox-Confirm-button-submit:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.2)}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+function jBoxConfirmWrapper(jBox,jQuery){new jBox.plugin("Confirm",{confirmButton:"Submit",cancelButton:"Cancel",confirm:null,cancel:null,closeOnConfirm:!0,target:window,fixed:!0,attach:"[data-confirm]",getContent:"data-confirm",content:"Do you really want to do this?",minWidth:360,maxWidth:500,blockScroll:!0,closeOnEsc:!0,closeOnClick:!1,closeButton:!1,overlay:!0,animation:"zoomIn",preventDefault:!0,_onAttach:function(o){var t;this.options.confirm||(t=o.attr("onclick")?o.attr("onclick"):o.attr("href")?o.attr("target")?'window.open("'+o.attr("href")+'", "'+o.attr("target")+'");':'window.location.href = "'+o.attr("href")+'";':"",o.prop("onclick",null).data("jBox-Confirm-submit",t))},_onCreated:function(){this.wrapper.addClass("jBox-Modal"),this.footer=jQuery('<div class="jBox-Confirm-footer"/>'),jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-cancel"/>').html(this.options.cancelButton).on("click tap",function(){this.options.cancel&&this.options.cancel(this.source),this.close()}.bind(this)).appendTo(this.footer),this.submitButton=jQuery('<div class="jBox-Confirm-button jBox-Confirm-button-submit"/>').html(this.options.confirmButton).appendTo(this.footer),this.footer.appendTo(this.container)},_onOpen:function(){this.submitButton.off("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id).on("click.jBox-Confirm"+this.id+" tap.jBox-Confirm"+this.id,function(){this.options.confirm?this.options.confirm(this.source):eval(this.source.data("jBox-Confirm-submit")),this.options.closeOnConfirm&&this.close()}.bind(this))}})}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,201 @@
1
+.jBox-Image .jBox-container {
2
+  background-color: transparent;
3
+}
4
+
5
+.jBox-Image .jBox-content {
6
+  padding: 0;
7
+  width: 100%;
8
+  height: 100%;
9
+}
10
+
11
+.jBox-image-container {
12
+  background: center center no-repeat;
13
+  position: absolute;
14
+  width: 100%;
15
+  height: 100%;
16
+  opacity: 0;
17
+}
18
+
19
+.jBox-image-label-wrapper {
20
+  position: absolute;
21
+  top: 100%;
22
+  left: 0;
23
+  right: 0;
24
+  height: 40px;
25
+  z-index: 100;
26
+  display: flex;
27
+}
28
+
29
+.jBox-image-label-container {
30
+  position: relative;
31
+  flex: 1;
32
+}
33
+
34
+.jBox-image-label {
35
+  box-sizing: border-box;
36
+  position: absolute;
37
+  left: 0;
38
+  bottom: 0;
39
+  width: 100%;
40
+  text-align: center;
41
+  color: #fff;
42
+  padding: 8px 12px;
43
+  font-size: 15px;
44
+  line-height: 24px;
45
+  transition: opacity .36s;
46
+  opacity: 0;
47
+  z-index: 0;
48
+  pointer-events: none;
49
+}
50
+
51
+.jBox-image-label.expanded {
52
+  background: #000;
53
+}
54
+
55
+.jBox-image-label:not(.expanded) {
56
+  text-overflow: ellipsis;
57
+  white-space: nowrap;
58
+  overflow: hidden;
59
+}
60
+
61
+.jBox-image-label.active {
62
+  opacity: 1;
63
+  pointer-events: all;
64
+}
65
+
66
+@media (max-width: 600px) {
67
+  .jBox-image-label {
68
+    font-size: 13px;
69
+  }
70
+}
71
+
72
+.jBox-image-pointer-next,
73
+.jBox-image-pointer-prev {
74
+  flex-shrink: 0;
75
+  width: 40px;
76
+  height: 40px;
77
+  cursor: pointer;
78
+  opacity: .8;
79
+  transition: opacity .2s;
80
+  background: no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);
81
+  background-size: 11px auto;
82
+  user-select: none;
83
+  z-index: 1;
84
+}
85
+
86
+.jBox-image-pointer-next:hover,
87
+.jBox-image-pointer-prev:hover {
88
+  opacity: 1;
89
+}
90
+
91
+.jBox-image-pointer-next {
92
+  transform: scaleX(-1);
93
+}
94
+
95
+.jBox-image-counter-container {
96
+  flex-shrink: 0;
97
+  white-space: nowrap;
98
+  height: 40px;
99
+  line-height: 40px;
100
+  font-size: 13px;
101
+  color: #fff;
102
+  text-align: right;
103
+  display: none;
104
+}
105
+
106
+.jBox-image-has-counter .jBox-image-counter-container {
107
+  display: block;
108
+}
109
+
110
+.jBox-overlay.jBox-overlay-Image {
111
+  background: #000;
112
+}
113
+
114
+.jBox-image-not-found {
115
+  background: #000;
116
+}
117
+
118
+.jBox-image-not-found:before {
119
+  content: '';
120
+  box-sizing: border-box;
121
+  display: block;
122
+  width: 80px;
123
+  height: 80px;
124
+  margin-top: -40px;
125
+  margin-left: -40px;
126
+  position: absolute;
127
+  top: 50%;
128
+  left: 50%;
129
+  border: 5px solid #222;
130
+  border-radius: 50%;
131
+}
132
+
133
+.jBox-image-not-found:after {
134
+  content: '';
135
+  display: block;
136
+  box-sizing: content-box;
137
+  z-index: auto;
138
+  width: 6px;
139
+  height: 74px;
140
+  margin-top: -37px;
141
+  margin-left: -3px;
142
+  position: absolute;
143
+  top: 50%;
144
+  left: 50%;
145
+  background: #222;
146
+  transform: rotateZ(45deg);
147
+  transform-origin: 50% 50% 0;
148
+}
149
+
150
+.jBox-image-download-button-wrapper {
151
+  position: absolute;
152
+  top: -40px;
153
+  right: 35px;
154
+  height: 40px;
155
+  display: flex;
156
+  cursor: pointer;
157
+  opacity: .8;
158
+  transition: opacity .2s;
159
+}
160
+
161
+.jBox-image-download-button-wrapper:hover {
162
+  opacity: 1;
163
+}
164
+
165
+.jBox-image-download-button-icon {
166
+  width: 40px;
167
+  height: 40px;
168
+  background: center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);
169
+  background-size: 60%;
170
+}
171
+
172
+.jBox-image-download-button-text {
173
+  white-space: nowrap;
174
+  line-height: 40px;
175
+  padding: 0 10px 0 0;
176
+  color: #fff;
177
+  font-size: 14px;
178
+}
179
+
180
+@keyframes jBoxImageLoading {
181
+  to {
182
+    transform: rotate(360deg);
183
+  }
184
+}
185
+
186
+.jBox-image-loading:before {
187
+  content: '';
188
+  position: absolute;
189
+  top: 50%;
190
+  left: 50%;
191
+  width: 32px;
192
+  height: 32px;
193
+  margin-top: -16px;
194
+  margin-left: -16px;
195
+  border: 4px solid #333;
196
+  border-bottom-color: #666;
197
+  animation: jBoxImageLoading 1.2s linear infinite;
198
+  border-radius: 50%;
199
+}
200
+
201
+/*# sourceMappingURL=jBox.Image.css.map */
0 202
new file mode 100644
... ...
@@ -0,0 +1,358 @@
1
+/**
2
+ * jBox Image plugin: Adds a lightbox to your images
3
+ *
4
+ * Author: Stephan Wagner <stephanwagner.me@gmail.com> (https://stephanwagner.me)
5
+ *
6
+ * License: MIT (https://opensource.org/licenses/MIT)
7
+ *
8
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
9
+ */
10
+
11
+function jBoxImageWrapper(jBox, jQuery) {
12
+
13
+  new jBox.plugin('Image', {
14
+
15
+
16
+    // Options (https://stephanwagner.me/jBox/options#options-image)
17
+
18
+    src: 'href',                 // The attribute where jBox gets the image source from, e.g. href="/path_to_image/image.jpg"
19
+    gallery: 'data-jbox-image',  // The attribute to set the galleries, e.g. data-jbox-image="gallery1"
20
+    imageLabel: 'title',         // The attribute where jBox gets the image label from, e.g. title="My label"
21
+    imageFade: 360,              // The fade duration for images in ms
22
+    imageSize: 'contain',        // How to display the images. Use CSS background-position values, e.g. 'cover', 'contain', 'auto', 'initial', '50% 50%'
23
+    imageCounter: false,         // Set to true to add an image counter, e.g. 4/20
24
+    imageCounterSeparator: '/',  // HTML to separate the current image number from all image numbers, e.g. '/' or ' of '
25
+    downloadButton: false,       // Adds a download button
26
+    downloadButtonText: null,    // Text for the download button
27
+    downloadButtonUrl: null,     // The attribute at the source element where to find the image to download, e.g. data-download="/path_to_image/image.jpg". If none provided, the currently active image will be downloaded
28
+    mobileImageAttr: null,       // The attribute to look for an mobile version of the image
29
+    mobileImageBreakpoint: null, // The upper breakpoint to load the mobile image
30
+    preloadFirstImage: false,    // Preload the first image when page is loaded
31
+    target: window,
32
+    attach: '[data-jbox-image]',
33
+    fixed: true,
34
+    blockScroll: true,
35
+    closeOnEsc: true,
36
+    closeOnClick: 'button',
37
+    closeButton: true,
38
+    overlay: true,
39
+    animation: 'zoomIn',
40
+    preventDefault: true,
41
+    width: '100%',
42
+    height: '100%',
43
+    adjustDistance: {
44
+      top: 40,
45
+      right: 0,
46
+      bottom: 40,
47
+      left: 0
48
+    },
49
+
50
+
51
+    // Triggered when jBox is initialized
52
+
53
+    _onInit: function ()
54
+    {
55
+      // Initial images and z-index
56
+      this.images = this.currentImage = {};
57
+      this.imageZIndex = 1;
58
+
59
+      this.initImage = function (item) {
60
+        item = jQuery(item);
61
+
62
+        // Abort if the item was added to a gallery already
63
+        if (item.data('jBox-image-gallery')) {
64
+          return;
65
+        }
66
+
67
+        // Get the image src
68
+        var src = item.attr(this.options.src);
69
+
70
+        // Update responsive image src
71
+        if (this.options.mobileImageAttr && this.options.mobileImageBreakpoint && item.attr(this.options.mobileImageAttr)) {
72
+          if (jQuery(window).width() <= this.options.mobileImageBreakpoint) {
73
+            src = item.attr(this.options.mobileImageAttr);
74
+          }
75
+        }
76
+
77
+        // Add item to a gallery
78
+        var gallery = item.attr(this.options.gallery) || 'default';
79
+        !this.images[gallery] && (this.images[gallery] = []);
80
+        this.images[gallery].push({
81
+          src: src,
82
+          label: (item.attr(this.options.imageLabel) || ''),
83
+          downloadUrl: this.options.downloadButtonUrl && item.attr(this.options.downloadButtonUrl) ? item.attr(this.options.downloadButtonUrl) : null
84
+        });
85
+
86
+        // Remove the title attribute so it won't show the browsers tooltip
87
+        this.options.imageLabel == 'title' && item.removeAttr('title');
88
+
89
+        // Store data in source element for easy access
90
+        item.data('jBox-image-gallery', gallery);
91
+        item.data('jBox-image-id', (this.images[gallery].length - 1));
92
+      }.bind(this);
93
+
94
+      // Loop through images, sort and save in global variable
95
+      this.attachedElements && this.attachedElements.length && jQuery.each(this.attachedElements, function (index, item) {
96
+        this.initImage(item);
97
+      }.bind(this));
98
+
99
+      // Helper to inject the image into content area
100
+      var appendImage = function (gallery, id, show, instant) {
101
+        // Abort if image was appended already
102
+        if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
103
+          return;
104
+        }
105
+
106
+        // Create image container
107
+        var image = jQuery('<div/>', {
108
+          id: 'jBox-image-' + gallery + '-' + id,
109
+          'class': 'jBox-image-container' + (show ? ' jBox-image-' + gallery + '-current' : '')
110
+        }).css({
111
+          backgroundSize: this.options.imageSize,
112
+          opacity: (instant ? 1 : 0),
113
+          zIndex: (show ? this.imageZIndex++ : 0)
114
+        }).appendTo(this.content);
115
+
116
+        // Add swipe events
117
+        this.swipeDetector(image)
118
+          .on("swipeLeft.sd swipeRight.sd", function (event) {
119
+            if (event.type === "swipeLeft") {
120
+              this.showImage('next');
121
+            } else if (event.type === "swipeRight") {
122
+              this.showImage('prev');
123
+            }
124
+          }.bind(this));
125
+
126
+        // Create labels
127
+        jQuery('<div/>', {
128
+          id: 'jBox-image-label-' + gallery + '-' + id,
129
+          'class': 'jBox-image-label' + (show ? ' active' : '')
130
+        })
131
+        .html(this.images[gallery][id].label)
132
+        .on('click tap', function () {
133
+          jQuery(this).toggleClass('expanded');
134
+        })
135
+        .appendTo(this.imageLabelContainer);
136
+
137
+        // Show image
138
+        show && image.animate({opacity: 1}, instant ? 0 : this.options.imageFade);
139
+
140
+        return image;
141
+      }.bind(this);
142
+
143
+      // Function to download an image
144
+      this.downloadImage = function (imageUrl) {
145
+        var link = document.createElement('a');
146
+        link.href = imageUrl;
147
+        link.setAttribute('download', imageUrl.substring(imageUrl.lastIndexOf('/')+1));
148
+        document.body.appendChild(link);
149
+        link.click();
150
+      };
151
+
152
+      // Helper to show new image label
153
+      var showLabel = function (gallery, id) {
154
+        jQuery('.jBox-image-label.active').removeClass('active expanded');
155
+        jQuery('#jBox-image-label-' + gallery + '-' + id).addClass('active');
156
+      };
157
+
158
+      // Helper to load image
159
+      var loadImage = function (gallery, id, show, instant) {
160
+        var imageContainer = appendImage(gallery, id, show, instant);
161
+        imageContainer.addClass('jBox-image-loading');
162
+
163
+        jQuery('<img src="' + this.images[gallery][id].src + '" />').each(function () {
164
+          var tmpImg = new Image();
165
+          tmpImg.onload = function () {
166
+            imageContainer.removeClass('jBox-image-loading');
167
+            imageContainer.css({backgroundImage: 'url("' + this.images[gallery][id].src + '")'});
168
+          }.bind(this);
169
+
170
+          tmpImg.onerror = function () {
171
+            imageContainer.removeClass('jBox-image-loading');
172
+            imageContainer.addClass('jBox-image-not-found');
173
+          }.bind(this);
174
+
175
+          tmpImg.src = this.images[gallery][id].src;
176
+        }.bind(this));
177
+      }.bind(this);
178
+
179
+      // Show images when they are loaded or load them if not
180
+      this.showImage = function (img) {
181
+        // Get the gallery and the image id from the next or the previous image
182
+        var gallery;
183
+        var id;
184
+
185
+        if (img != 'open') {
186
+          gallery = this.currentImage.gallery;
187
+          id = this.currentImage.id + (1 * (img == 'prev') ? -1 : 1);
188
+          id = id > (this.images[gallery].length - 1) ? 0 : (id < 0 ? (this.images[gallery].length - 1) : id);
189
+
190
+        // Or get image data from source element
191
+        } else {
192
+          // Get gallery and image id from source element
193
+          if (this.source) {
194
+            gallery = this.source.data('jBox-image-gallery');
195
+            id = this.source.data('jBox-image-id');
196
+
197
+          // Get gallery and image id attached elements
198
+          } else if (this.attachedElements && this.attachedElements.length) {
199
+            gallery = jQuery(this.attachedElements[0]).data('jBox-image-gallery');
200
+            id = jQuery(this.attachedElements[0]).data('jBox-image-id');
201
+          } else {
202
+            return;
203
+          }
204
+
205
+          // Remove or show the next and prev buttons
206
+          if (this.images && this.images[gallery]) {
207
+            jQuery('.jBox-image-pointer-prev, .jBox-image-pointer-next').css({display: (this.images[gallery].length > 1 ? 'block' : 'none')});
208
+          }
209
+        }
210
+
211
+        // If there is a current image already shown, hide it
212
+        if (jQuery('.jBox-image-' + gallery + '-current').length) {
213
+          jQuery('.jBox-image-' + gallery + '-current').removeClass('jBox-image-' + gallery + '-current').animate({opacity: 0}, (img == 'open') ? 0 : this.options.imageFade);
214
+        }
215
+
216
+        // Set new current image
217
+        this.currentImage = {gallery: gallery, id: id};
218
+
219
+        // Show image if it already exists
220
+        if (jQuery('#jBox-image-' + gallery + '-' + id).length) {
221
+          jQuery('#jBox-image-' + gallery + '-' + id).addClass('jBox-image-' + gallery + '-current').css({zIndex: this.imageZIndex++, opacity: 0}).animate({opacity: 1}, (img == 'open') ? 0 : this.options.imageFade);
222
+
223
+        // Load image
224
+        } else {
225
+          loadImage(gallery, id, true, (img === 'open'));
226
+        }
227
+
228
+        // Show label
229
+        showLabel(gallery, id);
230
+
231
+        // Update the image counter numbers
232
+        if (this.imageCounter) {
233
+          if (this.images[gallery] && this.images[gallery].length > 1) {
234
+            this.wrapper.addClass('jBox-image-has-counter');
235
+            this.imageCounter.find('.jBox-image-counter-all').html(this.images[gallery].length);
236
+            this.imageCounter.find('.jBox-image-counter-current').html(id + 1);
237
+          } else {
238
+            this.wrapper.removeClass('jBox-image-has-counter');
239
+          }
240
+        }
241
+
242
+        // Preload next image
243
+        if (this.images[gallery] && this.images[gallery].length - 1) {
244
+	        var next_id = id + 1;
245
+	        next_id = next_id > (this.images[gallery].length - 1) ? 0 : (next_id < 0 ? (this.images[gallery].length - 1) : next_id);
246
+
247
+	        if (!jQuery('#jBox-image-' + gallery + '-' + next_id).length) {
248
+            loadImage(gallery, next_id, false, false);
249
+          }
250
+	      }
251
+      };
252
+
253
+      // Preload image
254
+      if (this.options.preloadFirstImage) {
255
+        jQuery(window).on('load', function() {
256
+          this.showImage('open');
257
+        }.bind(this));
258
+      }
259
+    },
260
+
261
+
262
+    // Triggered when jBox attaches a new element
263
+
264
+    _onAttach: function (item) {
265
+      this.initImage && this.initImage(item);
266
+    },
267
+
268
+
269
+    // Triggered when jBox was created
270
+
271
+    _onCreated: function ()
272
+    {
273
+      // Create image label and navigation buttons
274
+      this.imageLabelWrapper = jQuery('<div class="jBox-image-label-wrapper"/>').appendTo(this.wrapper);
275
+
276
+      this.imagePrevButton = jQuery('<div class="jBox-image-pointer-prev"/>')
277
+        .on('click tap', function () {
278
+          this.showImage('prev');
279
+        }.bind(this));
280
+
281
+      this.imageNextButton = jQuery('<div class="jBox-image-pointer-next"/>')
282
+        .on('click tap', function () {
283
+          this.showImage('next');
284
+        }.bind(this));
285
+
286
+      this.imageLabelContainer = jQuery('<div class="jBox-image-label-container"/>');
287
+
288
+      this.imageLabelWrapper
289
+        .append(this.imagePrevButton)
290
+        .append(this.imageLabelContainer)
291
+        .append(this.imageNextButton);
292
+
293
+      // Append the download button
294
+      if (this.options.downloadButton) {
295
+        this.downloadButton = jQuery('<div/>', {'class': 'jBox-image-download-button-wrapper'})
296
+          .appendTo(this.wrapper)
297
+          .append(
298
+            this.options.downloadButtonText ? jQuery('<div/>', {'class': 'jBox-image-download-button-text'}).html(this.options.downloadButtonText) : null
299
+          )
300
+          .append(
301
+            jQuery('<div/>', {'class': 'jBox-image-download-button-icon'})
302
+          ).on('click tap', function () {
303
+            if (this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl) {
304
+              var currentImageUrl = this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl;
305
+            } else {
306
+              var currentImage = this.wrapper.find('.jBox-image-' + this.currentImage.gallery + '-current');
307
+              var currentImageStyle = currentImage[0].style.backgroundImage;
308
+              var currentImageUrl = currentImageStyle.slice(4, -1).replace(/["']/g, '');
309
+            }
310
+            this.downloadImage(currentImageUrl);
311
+          }.bind(this));
312
+      }
313
+
314
+      // Creating the image counter containers
315
+      if (this.options.imageCounter) {
316
+        this.imageCounter = jQuery('<div/>', {'class': 'jBox-image-counter-container'}).insertAfter(this.imageLabelContainer);
317
+        this.imageCounter.append(jQuery('<span/>', {'class': 'jBox-image-counter-current'})).append(jQuery('<span/>').html(this.options.imageCounterSeparator)).append(jQuery('<span/>', {'class': 'jBox-image-counter-all'}));
318
+      }
319
+    },
320
+
321
+
322
+    // Triggered when jBox opens
323
+
324
+    _onOpen: function ()
325
+    {
326
+      // Add key events
327
+      jQuery(document).on('keyup.jBox-Image-' + this.id, function (ev) {
328
+        (ev.keyCode == 37) && this.showImage('prev');
329
+        (ev.keyCode == 39) && this.showImage('next');
330
+      }.bind(this));
331
+
332
+      // Load the image from the attached element
333
+      this.showImage('open');
334
+    },
335
+
336
+
337
+    // Triggered when jBox closes
338
+
339
+    _onClose: function ()
340
+    {
341
+      // Remove key events
342
+      jQuery(document).off('keyup.jBox-Image-' + this.id);
343
+    },
344
+
345
+
346
+    // Triggered when jBox finished closing
347
+
348
+    _onCloseComplete: function ()
349
+    {
350
+      // Hide all image containers
351
+      this.wrapper.find('.jBox-image-container').css('opacity', 0);
352
+    }
353
+
354
+  });
355
+
356
+};
357
+
358
+//# sourceMappingURL=jBox.Image.js.map
0 359
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-Image .jBox-container{background-color:transparent}.jBox-Image .jBox-content{padding:0;width:100%;height:100%}.jBox-image-container{background:center center no-repeat;position:absolute;width:100%;height:100%;opacity:0}.jBox-image-label-wrapper{position:absolute;top:100%;left:0;right:0;height:40px;z-index:100;display:flex}.jBox-image-label-container{position:relative;flex:1}.jBox-image-label{box-sizing:border-box;position:absolute;left:0;bottom:0;width:100%;text-align:center;color:#fff;padding:8px 12px;font-size:15px;line-height:24px;transition:opacity .36s;opacity:0;z-index:0;pointer-events:none}.jBox-image-label.expanded{background:#000}.jBox-image-label:not(.expanded){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.jBox-image-label.active{opacity:1;pointer-events:all}@media (max-width:600px){.jBox-image-label{font-size:13px}}.jBox-image-pointer-next,.jBox-image-pointer-prev{flex-shrink:0;width:40px;height:40px;cursor:pointer;opacity:.8;transition:opacity .2s;background:no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);background-size:11px auto;user-select:none;z-index:1}.jBox-image-pointer-next:hover,.jBox-image-pointer-prev:hover{opacity:1}.jBox-image-pointer-next{transform:scaleX(-1)}.jBox-image-counter-container{flex-shrink:0;white-space:nowrap;height:40px;line-height:40px;font-size:13px;color:#fff;text-align:right;display:none}.jBox-image-has-counter .jBox-image-counter-container{display:block}.jBox-overlay.jBox-overlay-Image{background:#000}.jBox-image-not-found{background:#000}.jBox-image-not-found:before{content:'';box-sizing:border-box;display:block;width:80px;height:80px;margin-top:-40px;margin-left:-40px;position:absolute;top:50%;left:50%;border:5px solid #222;border-radius:50%}.jBox-image-not-found:after{content:'';display:block;box-sizing:content-box;z-index:auto;width:6px;height:74px;margin-top:-37px;margin-left:-3px;position:absolute;top:50%;left:50%;background:#222;transform:rotateZ(45deg);transform-origin:50% 50% 0}.jBox-image-download-button-wrapper{position:absolute;top:-40px;right:35px;height:40px;display:flex;cursor:pointer;opacity:.8;transition:opacity .2s}.jBox-image-download-button-wrapper:hover{opacity:1}.jBox-image-download-button-icon{width:40px;height:40px;background:center center no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNDE2IDI1NnYtMTkyaC0xOTJ2MTkyaC0xNjBsMjU2IDI1NiAyNTYtMjU2aC0xNjB6TTAgNTc2aDY0MHY2NGgtNjQwdi02NHoiPjwvcGF0aD48L3N2Zz4=);background-size:60%}.jBox-image-download-button-text{white-space:nowrap;line-height:40px;padding:0 10px 0 0;color:#fff;font-size:14px}@keyframes jBoxImageLoading{to{transform:rotate(360deg)}}.jBox-image-loading:before{content:'';position:absolute;top:50%;left:50%;width:32px;height:32px;margin-top:-16px;margin-left:-16px;border:4px solid #333;border-bottom-color:#666;animation:jBoxImageLoading 1.2s linear infinite;border-radius:50%}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+function jBoxImageWrapper(t,s){new t.plugin("Image",{src:"href",gallery:"data-jbox-image",imageLabel:"title",imageFade:360,imageSize:"contain",imageCounter:!1,imageCounterSeparator:"/",downloadButton:!1,downloadButtonText:null,downloadButtonUrl:null,mobileImageAttr:null,mobileImageBreakpoint:null,preloadFirstImage:!1,target:window,attach:"[data-jbox-image]",fixed:!0,blockScroll:!0,closeOnEsc:!0,closeOnClick:"button",closeButton:!0,overlay:!0,animation:"zoomIn",preventDefault:!0,width:"100%",height:"100%",adjustDistance:{top:40,right:0,bottom:40,left:0},_onInit:function(){this.images=this.currentImage={},this.imageZIndex=1,this.initImage=function(t){var e,i;(t=s(t)).data("jBox-image-gallery")||(e=t.attr(this.options.src),this.options.mobileImageAttr&&this.options.mobileImageBreakpoint&&t.attr(this.options.mobileImageAttr)&&s(window).width()<=this.options.mobileImageBreakpoint&&(e=t.attr(this.options.mobileImageAttr)),i=t.attr(this.options.gallery)||"default",this.images[i]||(this.images[i]=[]),this.images[i].push({src:e,label:t.attr(this.options.imageLabel)||"",downloadUrl:this.options.downloadButtonUrl&&t.attr(this.options.downloadButtonUrl)?t.attr(this.options.downloadButtonUrl):null}),"title"==this.options.imageLabel&&t.removeAttr("title"),t.data("jBox-image-gallery",i),t.data("jBox-image-id",this.images[i].length-1))}.bind(this),this.attachedElements&&this.attachedElements.length&&s.each(this.attachedElements,function(t,e){this.initImage(e)}.bind(this));var n=function(t,e,i,a){if(!s("#jBox-image-"+t+"-"+e).length){var o=s("<div/>",{id:"jBox-image-"+t+"-"+e,class:"jBox-image-container"+(i?" jBox-image-"+t+"-current":"")}).css({backgroundSize:this.options.imageSize,opacity:a?1:0,zIndex:i?this.imageZIndex++:0}).appendTo(this.content);return this.swipeDetector(o).on("swipeLeft.sd swipeRight.sd",function(t){"swipeLeft"===t.type?this.showImage("next"):"swipeRight"===t.type&&this.showImage("prev")}.bind(this)),s("<div/>",{id:"jBox-image-label-"+t+"-"+e,class:"jBox-image-label"+(i?" active":"")}).html(this.images[t][e].label).on("click tap",function(){s(this).toggleClass("expanded")}).appendTo(this.imageLabelContainer),i&&o.animate({opacity:1},a?0:this.options.imageFade),o}}.bind(this);this.downloadImage=function(t){var e=document.createElement("a");e.href=t,e.setAttribute("download",t.substring(t.lastIndexOf("/")+1)),document.body.appendChild(e),e.click()};var o=function(e,i,t,a){var o=n(e,i,t,a);o.addClass("jBox-image-loading"),s('<img src="'+this.images[e][i].src+'" />').each(function(){var t=new Image;t.onload=function(){o.removeClass("jBox-image-loading"),o.css({backgroundImage:'url("'+this.images[e][i].src+'")'})}.bind(this),t.onerror=function(){o.removeClass("jBox-image-loading"),o.addClass("jBox-image-not-found")}.bind(this),t.src=this.images[e][i].src}.bind(this))}.bind(this);this.showImage=function(t){var e,i,a;if("open"!=t)e=this.currentImage.gallery,a=(a=this.currentImage.id+(+("prev"==t)?-1:1))>this.images[e].length-1?0:a<0?this.images[e].length-1:a;else{if(this.source)e=this.source.data("jBox-image-gallery"),a=this.source.data("jBox-image-id");else{if(!this.attachedElements||!this.attachedElements.length)return;e=s(this.attachedElements[0]).data("jBox-image-gallery"),a=s(this.attachedElements[0]).data("jBox-image-id")}this.images&&this.images[e]&&s(".jBox-image-pointer-prev, .jBox-image-pointer-next").css({display:1<this.images[e].length?"block":"none"})}s(".jBox-image-"+e+"-current").length&&s(".jBox-image-"+e+"-current").removeClass("jBox-image-"+e+"-current").animate({opacity:0},"open"==t?0:this.options.imageFade),this.currentImage={gallery:e,id:a},s("#jBox-image-"+e+"-"+a).length?s("#jBox-image-"+e+"-"+a).addClass("jBox-image-"+e+"-current").css({zIndex:this.imageZIndex++,opacity:0}).animate({opacity:1},"open"==t?0:this.options.imageFade):o(e,a,!0,"open"===t),i=e,t=a,s(".jBox-image-label.active").removeClass("active expanded"),s("#jBox-image-label-"+i+"-"+t).addClass("active"),this.imageCounter&&(this.images[e]&&1<this.images[e].length?(this.wrapper.addClass("jBox-image-has-counter"),this.imageCounter.find(".jBox-image-counter-all").html(this.images[e].length),this.imageCounter.find(".jBox-image-counter-current").html(a+1)):this.wrapper.removeClass("jBox-image-has-counter")),this.images[e]&&this.images[e].length-1&&(a=(a=a+1)>this.images[e].length-1?0:a<0?this.images[e].length-1:a,s("#jBox-image-"+e+"-"+a).length||o(e,a,!1,!1))},this.options.preloadFirstImage&&s(window).on("load",function(){this.showImage("open")}.bind(this))},_onAttach:function(t){this.initImage&&this.initImage(t)},_onCreated:function(){this.imageLabelWrapper=s('<div class="jBox-image-label-wrapper"/>').appendTo(this.wrapper),this.imagePrevButton=s('<div class="jBox-image-pointer-prev"/>').on("click tap",function(){this.showImage("prev")}.bind(this)),this.imageNextButton=s('<div class="jBox-image-pointer-next"/>').on("click tap",function(){this.showImage("next")}.bind(this)),this.imageLabelContainer=s('<div class="jBox-image-label-container"/>'),this.imageLabelWrapper.append(this.imagePrevButton).append(this.imageLabelContainer).append(this.imageNextButton),this.options.downloadButton&&(this.downloadButton=s("<div/>",{class:"jBox-image-download-button-wrapper"}).appendTo(this.wrapper).append(this.options.downloadButtonText?s("<div/>",{class:"jBox-image-download-button-text"}).html(this.options.downloadButtonText):null).append(s("<div/>",{class:"jBox-image-download-button-icon"})).on("click tap",function(){var t;t=this.images[this.currentImage.gallery][this.currentImage.id].downloadUrl||this.wrapper.find(".jBox-image-"+this.currentImage.gallery+"-current")[0].style.backgroundImage.slice(4,-1).replace(/["']/g,""),this.downloadImage(t)}.bind(this))),this.options.imageCounter&&(this.imageCounter=s("<div/>",{class:"jBox-image-counter-container"}).insertAfter(this.imageLabelContainer),this.imageCounter.append(s("<span/>",{class:"jBox-image-counter-current"})).append(s("<span/>").html(this.options.imageCounterSeparator)).append(s("<span/>",{class:"jBox-image-counter-all"})))},_onOpen:function(){s(document).on("keyup.jBox-Image-"+this.id,function(t){37==t.keyCode&&this.showImage("prev"),39==t.keyCode&&this.showImage("next")}.bind(this)),this.showImage("open")},_onClose:function(){s(document).off("keyup.jBox-Image-"+this.id)},_onCloseComplete:function(){this.wrapper.find(".jBox-image-container").css("opacity",0)}})}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,122 @@
1
+.jBox-Notice {
2
+  transition: margin .2s;
3
+}
4
+
5
+.jBox-Notice .jBox-container {
6
+  border-radius: 4px;
7
+  box-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.25), inset -1px -1px 0 0 rgba(0, 0, 0, 0.1);
8
+}
9
+
10
+.jBox-Notice .jBox-content {
11
+  border-radius: 4px;
12
+  padding: 12px 20px;
13
+}
14
+
15
+@media (max-width: 768px) {
16
+  .jBox-Notice .jBox-content {
17
+    padding: 10px 15px;
18
+  }
19
+}
20
+
21
+@media (max-width: 500px) {
22
+  .jBox-Notice .jBox-content {
23
+    padding: 8px 10px;
24
+  }
25
+}
26
+
27
+.jBox-Notice.jBox-hasTitle .jBox-content {
28
+  padding-top: 5px;
29
+}
30
+
31
+@media (max-width: 500px) {
32
+  .jBox-Notice.jBox-hasTitle .jBox-content {
33
+    padding-top: 0;
34
+  }
35
+}
36
+
37
+.jBox-Notice.jBox-hasTitle .jBox-title {
38
+  padding: 12px 20px 0;
39
+  font-weight: bold;
40
+}
41
+
42
+@media (max-width: 768px) {
43
+  .jBox-Notice.jBox-hasTitle .jBox-title {
44
+    padding: 10px 15px 0;
45
+  }
46
+}
47
+
48
+@media (max-width: 500px) {
49
+  .jBox-Notice.jBox-hasTitle .jBox-title {
50
+    padding: 8px 10px 0;
51
+  }
52
+}
53
+
54
+.jBox-Notice.jBox-closeButton-title .jBox-title {
55
+  padding-right: 55px;
56
+}
57
+
58
+.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton {
59
+  width: 40px;
60
+}
61
+
62
+.jBox-Notice.jBox-Notice-black .jBox-container {
63
+  color: #fff;
64
+  background: #000;
65
+}
66
+
67
+.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
68
+.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
69
+  fill: #fff;
70
+}
71
+
72
+.jBox-Notice.jBox-Notice-gray .jBox-container {
73
+  color: #222;
74
+  background: #f6f6f6;
75
+}
76
+
77
+.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
78
+.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
79
+  fill: #222;
80
+}
81
+
82
+.jBox-Notice.jBox-Notice-red .jBox-container {
83
+  color: #fff;
84
+  background: #d00;
85
+}
86
+
87
+.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
88
+.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
89
+  fill: #fff;
90
+}
91
+
92
+.jBox-Notice.jBox-Notice-green .jBox-container {
93
+  color: #fff;
94
+  background: #5d0;
95
+}
96
+
97
+.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
98
+.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
99
+  fill: #fff;
100
+}
101
+
102
+.jBox-Notice.jBox-Notice-blue .jBox-container {
103
+  color: #fff;
104
+  background: #49d;
105
+}
106
+
107
+.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
108
+.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
109
+  fill: #fff;
110
+}
111
+
112
+.jBox-Notice.jBox-Notice-yellow .jBox-container {
113
+  color: #000;
114
+  background: #fd0;
115
+}
116
+
117
+.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,
118
+.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path {
119
+  fill: #fff;
120
+}
121
+
122
+/*# sourceMappingURL=jBox.Notice.css.map */
0 123
new file mode 100644
... ...
@@ -0,0 +1,173 @@
1
+/**
2
+ * jBox Notice plugin: Opens a popup notice
3
+ *
4
+ * Author: Stephan Wagner <stephanwagner.me@gmail.com> (https://stephanwagner.me)
5
+ *
6
+ * License: MIT (https://opensource.org/licenses/MIT)
7
+ *
8
+ * Requires: jBox (https://cdn.jsdelivr.net/gh/StephanWagner/jBox@latest/dist/jBox.min.js)
9
+ */
10
+
11
+function jBoxNoticeWrapper(jBox, jQuery) {
12
+
13
+  new jBox.plugin('Notice', {
14
+
15
+
16
+    // Options (https://stephanwagner.me/jBox/options#options-notice)
17
+
18
+    color: null,      // Add a color to your notices, use 'gray' (default), 'black', 'red', 'green', 'blue' or 'yellow'
19
+    stack: true,      // Set to false to disable notice-stacking
20
+    stackSpacing: 10, // Spacing between notices when they stack
21
+    autoClose: 6000,  // Time in ms after which the notice will disappear
22
+    attributes: {     // Defines where the notice will pop up
23
+      x: 'right',     // 'left' or 'right'
24
+      y: 'top'        // 'top' or 'bottom'
25
+    },
26
+    position: {       // Defines the distance to the viewport boundary
27
+      x: 15,
28
+      y: 15
29
+    },
30
+    responsivePositions: {  // Responsive positions
31
+      500: {                // The key defines the maximum width of the viewport, the values will replace the default position options
32
+        x: 5,               // Start with the lowest viewport
33
+        y: 5
34
+      },
35
+      768: {
36
+        x: 10,
37
+        y: 10
38
+      }
39
+    },
40
+    target: window,
41
+    fixed: true,
42
+    animation: 'zoomIn',
43
+    closeOnClick: 'box',
44
+    zIndex: 12000,
45
+
46
+
47
+    // Triggered when notice is initialized
48
+
49
+    _onInit: function ()
50
+    {
51
+      // Cache position values
52
+      this.defaultNoticePosition = jQuery.extend({}, this.options.position);
53
+
54
+      // Type Notice has its own adjust position function
55
+      this._adjustNoticePositon = function () {
56
+        var win = jQuery(window);
57
+        var windowDimensions = {
58
+          x: win.width(),
59
+          y: win.height()
60
+        };
61
+
62
+        // Reset default position
63
+        this.options.position = jQuery.extend({}, this.defaultNoticePosition);
64
+
65
+        // Adjust depending on viewport
66
+        jQuery.each(this.options.responsivePositions, function (viewport, position) {
67
+          if (windowDimensions.x <= viewport) {
68
+            this.options.position = position;
69
+            return false;
70
+          }
71
+        }.bind(this));
72
+
73
+        // Set new padding options
74
+        this.options.adjustDistance = {
75
+          top: this.options.position.y,
76
+          right: this.options.position.x,
77
+          bottom: this.options.position.y,
78
+          left: this.options.position.x
79
+        };
80
+      };
81
+
82
+      // If jBox grabs an element as content, crab a clone instead
83
+      this.options.content instanceof jQuery && (this.options.content = this.options.content.clone().attr('id', ''));
84
+
85
+      // Adjust paddings when window resizes
86
+      jQuery(window).on('resize.responsivejBoxNotice-' + this.id, function (ev) { if (this.isOpen) { this._adjustNoticePositon(); } }.bind(this));
87
+
88
+      this.open();
89
+    },
90
+
91
+
92
+    // Triggered when notice was created
93
+
94
+    _onCreated: function ()
95
+    {
96
+      // Add color class
97
+      this.wrapper.addClass('jBox-Notice-color jBox-Notice-' + (this.options.color || 'gray'));
98
+
99
+      // Store position in jBox wrapper
100
+      this.wrapper.data('jBox-Notice-position', this.options.attributes.x + '-' + this.options.attributes.y);
101
+    },
102
+
103
+
104
+    // Triggered when notice opens
105
+
106
+    _onOpen: function ()
107
+    {
108
+      // Bail if we're stacking
109
+      if (this.options.stack) {
110
+          return;
111
+      }
112
+
113
+      // Adjust position when opening
114
+      this._adjustNoticePositon();
115
+
116
+      // Loop through notices at same window corner destroy them
117
+      jQuery.each(jQuery('.jBox-Notice'), function (index, el)
118
+      {
119
+        el = jQuery(el);
120
+
121
+        // Abort if the element is this notice or when it's not at the same position
122
+        if (el.attr('id') == this.id || el.data('jBox-Notice-position') != this.options.attributes.x + '-' + this.options.attributes.y) {
123
+          return;
124
+        }
125
+
126
+        // Remove notice when we don't wont to stack them
127
+        if (!this.options.stack) {
128
+          el.data('jBox').close({ignoreDelay: true});
129
+          return;
130
+        }
131
+      }.bind(this));
132
+    },
133
+
134
+    // Triggered when resizing window etc.
135
+
136
+    _onPosition: function ()
137
+    {
138
+        var stacks = {};
139
+        jQuery.each(jQuery('.jBox-Notice'), function (index, el)
140
+        {
141
+          el = jQuery(el);
142
+          var pos = el.data('jBox-Notice-position');
143
+          if (!stacks[pos]) {
144
+              stacks[pos] = [];
145
+          }
146
+          stacks[pos].push(el);
147
+        });
148
+        for (var pos in stacks) {
149
+            var position = pos.split('-');
150
+            var direction = position[1];
151
+            stacks[pos].reverse();
152
+            var margin = 0;
153
+            for (var i in stacks[pos]) {
154
+                var el = jQuery(stacks[pos][i]);
155
+                el.css('margin-' + direction, margin);
156
+                margin += el.outerHeight() + this.options.stackSpacing;
157
+            }
158
+        }
159
+    },
160
+
161
+    // Remove notice from DOM and reposition other notices when closing finishes
162
+
163
+    _onCloseComplete: function ()
164
+    {
165
+        this.destroy();
166
+        this.options._onPosition.bind(this).call();
167
+    }
168
+
169
+  });
170
+
171
+};
172
+
173
+//# sourceMappingURL=jBox.Notice.js.map
0 174
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-Notice{transition:margin .2s}.jBox-Notice .jBox-container{border-radius:4px;box-shadow:inset 1px 1px 0 0 rgba(255,255,255,.25),inset -1px -1px 0 0 rgba(0,0,0,.1)}.jBox-Notice .jBox-content{border-radius:4px;padding:12px 20px}@media (max-width:768px){.jBox-Notice .jBox-content{padding:10px 15px}}@media (max-width:500px){.jBox-Notice .jBox-content{padding:8px 10px}}.jBox-Notice.jBox-hasTitle .jBox-content{padding-top:5px}@media (max-width:500px){.jBox-Notice.jBox-hasTitle .jBox-content{padding-top:0}}.jBox-Notice.jBox-hasTitle .jBox-title{padding:12px 20px 0;font-weight:700}@media (max-width:768px){.jBox-Notice.jBox-hasTitle .jBox-title{padding:10px 15px 0}}@media (max-width:500px){.jBox-Notice.jBox-hasTitle .jBox-title{padding:8px 10px 0}}.jBox-Notice.jBox-closeButton-title .jBox-title{padding-right:55px}.jBox-Notice.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton{width:40px}.jBox-Notice.jBox-Notice-black .jBox-container{color:#fff;background:#000}.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-black.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-gray .jBox-container{color:#222;background:#f6f6f6}.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-gray.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#222}.jBox-Notice.jBox-Notice-red .jBox-container{color:#fff;background:#d00}.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-red.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-green .jBox-container{color:#fff;background:#5d0}.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-green.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-blue .jBox-container{color:#fff;background:#49d}.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-blue.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}.jBox-Notice.jBox-Notice-yellow .jBox-container{color:#000;background:#fd0}.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton path,.jBox-Notice.jBox-Notice-yellow.jBox-closeButton-title.jBox-hasTitle .jBox-closeButton:hover path{fill:#fff}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+function jBoxNoticeWrapper(t,a){new t.plugin("Notice",{color:null,stack:!0,stackSpacing:10,autoClose:6e3,attributes:{x:"right",y:"top"},position:{x:15,y:15},responsivePositions:{500:{x:5,y:5},768:{x:10,y:10}},target:window,fixed:!0,animation:"zoomIn",closeOnClick:"box",zIndex:12e3,_onInit:function(){this.defaultNoticePosition=a.extend({},this.options.position),this._adjustNoticePositon=function(){var t=a(window),o=t.width();t.height();this.options.position=a.extend({},this.defaultNoticePosition),a.each(this.options.responsivePositions,function(t,i){if(o<=t)return this.options.position=i,!1}.bind(this)),this.options.adjustDistance={top:this.options.position.y,right:this.options.position.x,bottom:this.options.position.y,left:this.options.position.x}},this.options.content instanceof a&&(this.options.content=this.options.content.clone().attr("id","")),a(window).on("resize.responsivejBoxNotice-"+this.id,function(t){this.isOpen&&this._adjustNoticePositon()}.bind(this)),this.open()},_onCreated:function(){this.wrapper.addClass("jBox-Notice-color jBox-Notice-"+(this.options.color||"gray")),this.wrapper.data("jBox-Notice-position",this.options.attributes.x+"-"+this.options.attributes.y)},_onOpen:function(){this.options.stack||(this._adjustNoticePositon(),a.each(a(".jBox-Notice"),function(t,i){(i=a(i)).attr("id")!=this.id&&i.data("jBox-Notice-position")==this.options.attributes.x+"-"+this.options.attributes.y&&(this.options.stack||i.data("jBox").close({ignoreDelay:!0}))}.bind(this)))},_onPosition:function(){var t,s={};for(t in a.each(a(".jBox-Notice"),function(t,i){var o=(i=a(i)).data("jBox-Notice-position");s[o]||(s[o]=[]),s[o].push(i)}),s){var i=t.split("-")[1];s[t].reverse();var o,n=0;for(o in s[t]){var e=a(s[t][o]);e.css("margin-"+i,n),n+=e.outerHeight()+this.options.stackSpacing}}},_onCloseComplete:function(){this.destroy(),this.options._onPosition.bind(this).call()}})}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,49 @@
1
+.jBox-NoticeFancy .jBox-content,
2
+.jBox-NoticeFancy .jBox-title {
3
+  padding-left: 25px;
4
+}
5
+
6
+.jBox-NoticeFancy.jBox-Notice-color .jBox-container {
7
+  color: #fff;
8
+  background: #000;
9
+}
10
+
11
+.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after {
12
+  content: '';
13
+  position: absolute;
14
+  top: 0;
15
+  left: 0;
16
+  bottom: 0;
17
+  width: 8px;
18
+  border-radius: 4px 0 0 4px;
19
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);
20
+  background-size: 14px 14px;
21
+}
22
+
23
+.jBox-NoticeFancy.jBox-Notice-black .jBox-container:after,
24
+.jBox-NoticeFancy.jBox-Notice-gray .jBox-container:after {
25
+  background-color: #888;
26
+}
27
+
28
+.jBox-NoticeFancy.jBox-Notice-red .jBox-container:after {
29
+  background-color: #e00;
30
+}
31
+
32
+.jBox-NoticeFancy.jBox-Notice-green .jBox-container:after {
33
+  background-color: #6c0;
34
+}
35
+
36
+.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after {
37
+  background-color: #49d;
38
+}
39
+
40
+.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after {
41
+  background-color: #fb0;
42
+}
43
+
44
+.jBox-NoticeFancy .jBox-countdown {
45
+  left: 8px;
46
+  border-radius: 0 4px 0 0;
47
+}
48
+
49
+/*# sourceMappingURL=jBox.NoticeFancy.css.map */
0 50
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-NoticeFancy .jBox-content,.jBox-NoticeFancy .jBox-title{padding-left:25px}.jBox-NoticeFancy.jBox-Notice-color .jBox-container{color:#fff;background:#000}.jBox-NoticeFancy.jBox-Notice-color .jBox-container:after{content:'';position:absolute;top:0;left:0;bottom:0;width:8px;border-radius:4px 0 0 4px;background-image:linear-gradient(45deg,rgba(255,255,255,.4) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.4) 75%,transparent 75%,transparent);background-size:14px 14px}.jBox-NoticeFancy.jBox-Notice-black .jBox-container:after,.jBox-NoticeFancy.jBox-Notice-gray .jBox-container:after{background-color:#888}.jBox-NoticeFancy.jBox-Notice-red .jBox-container:after{background-color:#e00}.jBox-NoticeFancy.jBox-Notice-green .jBox-container:after{background-color:#6c0}.jBox-NoticeFancy.jBox-Notice-blue .jBox-container:after{background-color:#49d}.jBox-NoticeFancy.jBox-Notice-yellow .jBox-container:after{background-color:#fb0}.jBox-NoticeFancy .jBox-countdown{left:8px;border-radius:0 4px 0 0}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,39 @@
1
+.jBox-TooltipBorder .jBox-container,
2
+.jBox-TooltipBorder .jBox-pointer:after {
3
+  border: 2px solid #49d;
4
+}
5
+
6
+.jBox-TooltipBorder .jBox-pointer:after {
7
+  width: 22px;
8
+  height: 22px;
9
+}
10
+
11
+.jBox-TooltipBorder .jBox-pointer-top,
12
+.jBox-TooltipBorder .jBox-pointer-bottom {
13
+  width: 34px;
14
+  height: 13px;
15
+}
16
+
17
+.jBox-TooltipBorder .jBox-pointer-top:after,
18
+.jBox-TooltipBorder .jBox-pointer-bottom:after {
19
+  left: 6px;
20
+}
21
+
22
+.jBox-TooltipBorder .jBox-pointer-left,
23
+.jBox-TooltipBorder .jBox-pointer-right {
24
+  width: 13px;
25
+  height: 34px;
26
+}
27
+
28
+.jBox-TooltipBorder .jBox-pointer-left:after,
29
+.jBox-TooltipBorder .jBox-pointer-right:after {
30
+  top: 6px;
31
+}
32
+
33
+.jBox-TooltipBorder.jBox-closeButton-box:before {
34
+  width: 28px;
35
+  height: 28px;
36
+  background: #49d;
37
+}
38
+
39
+/*# sourceMappingURL=jBox.TooltipBorder.css.map */
0 40
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-TooltipBorder .jBox-container,.jBox-TooltipBorder .jBox-pointer:after{border:2px solid #49d}.jBox-TooltipBorder .jBox-pointer:after{width:22px;height:22px}.jBox-TooltipBorder .jBox-pointer-bottom,.jBox-TooltipBorder .jBox-pointer-top{width:34px;height:13px}.jBox-TooltipBorder .jBox-pointer-bottom:after,.jBox-TooltipBorder .jBox-pointer-top:after{left:6px}.jBox-TooltipBorder .jBox-pointer-left,.jBox-TooltipBorder .jBox-pointer-right{width:13px;height:34px}.jBox-TooltipBorder .jBox-pointer-left:after,.jBox-TooltipBorder .jBox-pointer-right:after{top:6px}.jBox-TooltipBorder.jBox-closeButton-box:before{width:28px;height:28px;background:#49d}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,32 @@
1
+.jBox-TooltipBorderThick .jBox-container {
2
+  box-shadow: none;
3
+  border-radius: 8px;
4
+  border: 4px solid #ccc;
5
+}
6
+
7
+.jBox-TooltipBorderThick .jBox-pointer:after {
8
+  box-shadow: none;
9
+  border: 4px solid #ccc;
10
+  width: 24px;
11
+  height: 24px;
12
+}
13
+
14
+.jBox-TooltipBorderThick .jBox-pointer-top,
15
+.jBox-TooltipBorderThick .jBox-pointer-bottom {
16
+  width: 38px;
17
+  height: 13px;
18
+}
19
+
20
+.jBox-TooltipBorderThick .jBox-pointer-left,
21
+.jBox-TooltipBorderThick .jBox-pointer-right {
22
+  width: 13px;
23
+  height: 38px;
24
+}
25
+
26
+.jBox-TooltipBorderThick.jBox-closeButton-box:before {
27
+  width: 32px;
28
+  height: 32px;
29
+  background: #ccc;
30
+}
31
+
32
+/*# sourceMappingURL=jBox.TooltipBorderThick.css.map */
0 33
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-TooltipBorderThick .jBox-container{box-shadow:none;border-radius:8px;border:4px solid #ccc}.jBox-TooltipBorderThick .jBox-pointer:after{box-shadow:none;border:4px solid #ccc;width:24px;height:24px}.jBox-TooltipBorderThick .jBox-pointer-bottom,.jBox-TooltipBorderThick .jBox-pointer-top{width:38px;height:13px}.jBox-TooltipBorderThick .jBox-pointer-left,.jBox-TooltipBorderThick .jBox-pointer-right{width:13px;height:38px}.jBox-TooltipBorderThick.jBox-closeButton-box:before{width:32px;height:32px;background:#ccc}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,32 @@
1
+.jBox-TooltipDark .jBox-container {
2
+  border-radius: 4px;
3
+  background: #000;
4
+  color: #fff;
5
+  box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
6
+}
7
+
8
+.jBox-TooltipDark .jBox-pointer:after {
9
+  background: #000;
10
+}
11
+
12
+.jBox-TooltipDark .jBox-closeButton {
13
+  background: #000;
14
+}
15
+
16
+.jBox-TooltipDark.jBox-closeButton-box:before {
17
+  box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
18
+}
19
+
20
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path {
21
+  fill: #ddd;
22
+}
23
+
24
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path {
25
+  fill: #fff;
26
+}
27
+
28
+.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path {
29
+  fill: #bbb;
30
+}
31
+
32
+/*# sourceMappingURL=jBox.TooltipDark.css.map */
0 33
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-TooltipDark .jBox-container{border-radius:4px;background:#000;color:#fff;box-shadow:0 0 6px rgba(0,0,0,.4)}.jBox-TooltipDark .jBox-pointer:after{background:#000}.jBox-TooltipDark .jBox-closeButton{background:#000}.jBox-TooltipDark.jBox-closeButton-box:before{box-shadow:0 0 6px rgba(0,0,0,.4)}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path{fill:#ddd}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path{fill:#fff}.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path{fill:#bbb}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,54 @@
1
+.jBox-TooltipError {
2
+  pointer-events: none;
3
+}
4
+
5
+.jBox-TooltipError .jBox-container {
6
+  border-radius: 2px;
7
+  background: #d00;
8
+  color: #fff;
9
+  font-weight: bold;
10
+  font-size: 13px;
11
+}
12
+
13
+.jBox-TooltipError .jBox-content {
14
+  padding: 0 10px;
15
+  line-height: 28px;
16
+}
17
+
18
+.jBox-TooltipError .jBox-pointer:after {
19
+  background: #d00;
20
+  width: 20px;
21
+  height: 20px;
22
+}
23
+
24
+.jBox-TooltipError .jBox-pointer-top, .jBox-TooltipError .jBox-pointer-bottom {
25
+  width: 22px;
26
+  height: 8px;
27
+}
28
+
29
+.jBox-TooltipError .jBox-pointer-right, .jBox-TooltipError .jBox-pointer-left {
30
+  width: 8px;
31
+  height: 22px;
32
+}
33
+
34
+.jBox-TooltipError .jBox-pointer-top:after {
35
+  left: 1px;
36
+  top: 6px;
37
+}
38
+
39
+.jBox-TooltipError .jBox-pointer-right:after {
40
+  top: 1px;
41
+  right: 6px;
42
+}
43
+
44
+.jBox-TooltipError .jBox-pointer-bottom:after {
45
+  left: 1px;
46
+  bottom: 6px;
47
+}
48
+
49
+.jBox-TooltipError .jBox-pointer-left:after {
50
+  top: 1px;
51
+  left: 6px;
52
+}
53
+
54
+/*# sourceMappingURL=jBox.TooltipError.css.map */
0 55
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-TooltipError{pointer-events:none}.jBox-TooltipError .jBox-container{border-radius:2px;background:#d00;color:#fff;font-weight:700;font-size:13px}.jBox-TooltipError .jBox-content{padding:0 10px;line-height:28px}.jBox-TooltipError .jBox-pointer:after{background:#d00;width:20px;height:20px}.jBox-TooltipError .jBox-pointer-bottom,.jBox-TooltipError .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipError .jBox-pointer-left,.jBox-TooltipError .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipError .jBox-pointer-top:after{left:1px;top:6px}.jBox-TooltipError .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipError .jBox-pointer-bottom:after{left:1px;bottom:6px}.jBox-TooltipError .jBox-pointer-left:after{top:1px;left:6px}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,49 @@
1
+.jBox-TooltipSmall {
2
+  pointer-events: none;
3
+}
4
+
5
+.jBox-TooltipSmall .jBox-container {
6
+  border-radius: 2px;
7
+}
8
+
9
+.jBox-TooltipSmall .jBox-content {
10
+  padding: 0 10px;
11
+  line-height: 28px;
12
+}
13
+
14
+.jBox-TooltipSmall .jBox-pointer:after {
15
+  width: 20px;
16
+  height: 20px;
17
+}
18
+
19
+.jBox-TooltipSmall .jBox-pointer-top, .jBox-TooltipSmall .jBox-pointer-bottom {
20
+  width: 22px;
21
+  height: 8px;
22
+}
23
+
24
+.jBox-TooltipSmall .jBox-pointer-right, .jBox-TooltipSmall .jBox-pointer-left {
25
+  width: 8px;
26
+  height: 22px;
27
+}
28
+
29
+.jBox-TooltipSmall .jBox-pointer-top:after {
30
+  left: 1px;
31
+  top: 6px;
32
+}
33
+
34
+.jBox-TooltipSmall .jBox-pointer-right:after {
35
+  top: 1px;
36
+  right: 6px;
37
+}
38
+
39
+.jBox-TooltipSmall .jBox-pointer-bottom:after {
40
+  left: 1px;
41
+  bottom: 6px;
42
+}
43
+
44
+.jBox-TooltipSmall .jBox-pointer-left:after {
45
+  top: 1px;
46
+  left: 6px;
47
+}
48
+
49
+/*# sourceMappingURL=jBox.TooltipSmall.css.map */
0 50
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-TooltipSmall{pointer-events:none}.jBox-TooltipSmall .jBox-container{border-radius:2px}.jBox-TooltipSmall .jBox-content{padding:0 10px;line-height:28px}.jBox-TooltipSmall .jBox-pointer:after{width:20px;height:20px}.jBox-TooltipSmall .jBox-pointer-bottom,.jBox-TooltipSmall .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipSmall .jBox-pointer-left,.jBox-TooltipSmall .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipSmall .jBox-pointer-top:after{left:1px;top:6px}.jBox-TooltipSmall .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipSmall .jBox-pointer-bottom:after{left:1px;bottom:6px}.jBox-TooltipSmall .jBox-pointer-left:after{top:1px;left:6px}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,53 @@
1
+.jBox-TooltipSmallGray {
2
+  pointer-events: none;
3
+}
4
+
5
+.jBox-TooltipSmallGray .jBox-container {
6
+  font-size: 13px;
7
+  line-height: 24px;
8
+  border-radius: 12px;
9
+  background-image: linear-gradient(to bottom, #fafafa, #f2f2f2);
10
+}
11
+
12
+.jBox-TooltipSmallGray .jBox-content {
13
+  padding: 0 10px;
14
+}
15
+
16
+.jBox-TooltipSmallGray .jBox-pointer:after {
17
+  width: 20px;
18
+  height: 20px;
19
+}
20
+
21
+.jBox-TooltipSmallGray .jBox-pointer-top, .jBox-TooltipSmallGray .jBox-pointer-bottom {
22
+  width: 22px;
23
+  height: 8px;
24
+}
25
+
26
+.jBox-TooltipSmallGray .jBox-pointer-left, .jBox-TooltipSmallGray .jBox-pointer-right {
27
+  width: 8px;
28
+  height: 22px;
29
+}
30
+
31
+.jBox-TooltipSmallGray .jBox-pointer-top:after {
32
+  background: #fafafa;
33
+  left: 1px;
34
+  top: 6px;
35
+}
36
+
37
+.jBox-TooltipSmallGray .jBox-pointer-right:after {
38
+  top: 1px;
39
+  right: 6px;
40
+}
41
+
42
+.jBox-TooltipSmallGray .jBox-pointer-bottom:after {
43
+  background: #f2f2f2;
44
+  left: 1px;
45
+  bottom: 6px;
46
+}
47
+
48
+.jBox-TooltipSmallGray .jBox-pointer-left:after {
49
+  top: 1px;
50
+  left: 6px;
51
+}
52
+
53
+/*# sourceMappingURL=jBox.TooltipSmallGray.css.map */
0 54
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+.jBox-TooltipSmallGray{pointer-events:none}.jBox-TooltipSmallGray .jBox-container{font-size:13px;line-height:24px;border-radius:12px;background-image:linear-gradient(to bottom,#fafafa,#f2f2f2)}.jBox-TooltipSmallGray .jBox-content{padding:0 10px}.jBox-TooltipSmallGray .jBox-pointer:after{width:20px;height:20px}.jBox-TooltipSmallGray .jBox-pointer-bottom,.jBox-TooltipSmallGray .jBox-pointer-top{width:22px;height:8px}.jBox-TooltipSmallGray .jBox-pointer-left,.jBox-TooltipSmallGray .jBox-pointer-right{width:8px;height:22px}.jBox-TooltipSmallGray .jBox-pointer-top:after{background:#fafafa;left:1px;top:6px}.jBox-TooltipSmallGray .jBox-pointer-right:after{top:1px;right:6px}.jBox-TooltipSmallGray .jBox-pointer-bottom:after{background:#f2f2f2;left:1px;bottom:6px}.jBox-TooltipSmallGray .jBox-pointer-left:after{top:1px;left:6px}
0 2
\ No newline at end of file