UNPKG

53.4 kBJavaScriptView Raw
1// Platform: Capacitor
2/*
3 Licensed to the Apache Software Foundation (ASF) under one
4 or more contributor license agreements. See the NOTICE file
5 distributed with this work for additional information
6 regarding copyright ownership. The ASF licenses this file
7 to you under the Apache License, Version 2.0 (the
8 "License"); you may not use this file except in compliance
9 with the License. You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing,
14 software distributed under the License is distributed on an
15 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 KIND, either express or implied. See the License for the
17 specific language governing permissions and limitations
18 under the License.
19*/
20(function () {
21 var PLATFORM_VERSION_BUILD_LABEL = '1.0.0';
22 // file: src/scripts/require.js
23
24 /* jshint -W079 */
25 /* jshint -W020 */
26
27 var require;
28 var define;
29
30 (function () {
31 var modules = {};
32 // Stack of moduleIds currently being built.
33 var requireStack = [];
34 // Map of module ID -> index into requireStack of modules currently being built.
35 var inProgressModules = {};
36 var SEPARATOR = '.';
37
38 function build(module) {
39 var factory = module.factory;
40 var localRequire = function (id) {
41 var resultantId = id;
42 // Its a relative path, so lop off the last portion and add the id (minus "./")
43 if (id.charAt(0) === '.') {
44 resultantId =
45 module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) +
46 SEPARATOR +
47 id.slice(2);
48 }
49 return require(resultantId);
50 };
51 module.exports = {};
52 delete module.factory;
53 factory(localRequire, module.exports, module);
54 return module.exports;
55 }
56
57 require = function (id) {
58 if (!modules[id]) {
59 throw 'module ' + id + ' not found';
60 } else if (id in inProgressModules) {
61 var cycle =
62 requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
63 throw 'Cycle in require graph: ' + cycle;
64 }
65 if (modules[id].factory) {
66 try {
67 inProgressModules[id] = requireStack.length;
68 requireStack.push(id);
69 return build(modules[id]);
70 } finally {
71 delete inProgressModules[id];
72 requireStack.pop();
73 }
74 }
75 return modules[id].exports;
76 };
77
78 define = function (id, factory) {
79 if (modules[id]) {
80 throw 'module ' + id + ' already defined';
81 }
82
83 modules[id] = {
84 id: id,
85 factory: factory,
86 };
87 };
88
89 define.remove = function (id) {
90 delete modules[id];
91 };
92
93 define.moduleMap = modules;
94 })();
95
96 // Export for use in node
97 if (typeof module === 'object' && typeof require === 'function') {
98 module.exports.require = require;
99 module.exports.define = define;
100 }
101
102 // file: src/cordova.js
103 define('cordova', function (require, exports, module) {
104 var channel = require('cordova/channel');
105 var platform = require('cordova/platform');
106
107 /**
108 * Intercept calls to addEventListener + removeEventListener and handle deviceready,
109 * resume, and pause events.
110 */
111 var m_document_addEventListener = document.addEventListener;
112 var m_document_removeEventListener = document.removeEventListener;
113 var m_window_addEventListener = window.addEventListener;
114 var m_window_removeEventListener = window.removeEventListener;
115
116 /**
117 * Houses custom event handlers to intercept on document + window event listeners.
118 */
119 var documentEventHandlers = {};
120 var windowEventHandlers = {};
121
122 document.addEventListener = function (evt, handler, capture) {
123 var e = evt.toLowerCase();
124 if (typeof documentEventHandlers[e] !== 'undefined') {
125 documentEventHandlers[e].subscribe(handler);
126 } else {
127 m_document_addEventListener.call(document, evt, handler, capture);
128 }
129 };
130
131 window.addEventListener = function (evt, handler, capture) {
132 var e = evt.toLowerCase();
133 if (typeof windowEventHandlers[e] !== 'undefined') {
134 windowEventHandlers[e].subscribe(handler);
135 } else {
136 m_window_addEventListener.call(window, evt, handler, capture);
137 }
138 };
139
140 document.removeEventListener = function (evt, handler, capture) {
141 var e = evt.toLowerCase();
142 // If unsubscribing from an event that is handled by a plugin
143 if (typeof documentEventHandlers[e] !== 'undefined') {
144 documentEventHandlers[e].unsubscribe(handler);
145 } else {
146 m_document_removeEventListener.call(document, evt, handler, capture);
147 }
148 };
149
150 window.removeEventListener = function (evt, handler, capture) {
151 var e = evt.toLowerCase();
152 // If unsubscribing from an event that is handled by a plugin
153 if (typeof windowEventHandlers[e] !== 'undefined') {
154 windowEventHandlers[e].unsubscribe(handler);
155 } else {
156 m_window_removeEventListener.call(window, evt, handler, capture);
157 }
158 };
159
160 /* eslint-disable no-undef */
161 var cordova = {
162 define: define,
163 require: require,
164 version: PLATFORM_VERSION_BUILD_LABEL,
165 platformVersion: PLATFORM_VERSION_BUILD_LABEL,
166 platformId: platform.id,
167
168 /* eslint-enable no-undef */
169
170 /**
171 * Methods to add/remove your own addEventListener hijacking on document + window.
172 */
173 addWindowEventHandler: function (event) {
174 return (windowEventHandlers[event] = channel.create(event));
175 },
176 addStickyDocumentEventHandler: function (event) {
177 return (documentEventHandlers[event] = channel.createSticky(event));
178 },
179 addDocumentEventHandler: function (event) {
180 return (documentEventHandlers[event] = channel.create(event));
181 },
182 removeWindowEventHandler: function (event) {
183 delete windowEventHandlers[event];
184 },
185 removeDocumentEventHandler: function (event) {
186 delete documentEventHandlers[event];
187 },
188 /**
189 * Retrieve original event handlers that were replaced by Cordova
190 *
191 * @return object
192 */
193 getOriginalHandlers: function () {
194 return {
195 document: {
196 addEventListener: m_document_addEventListener,
197 removeEventListener: m_document_removeEventListener,
198 },
199 window: {
200 addEventListener: m_window_addEventListener,
201 removeEventListener: m_window_removeEventListener,
202 },
203 };
204 },
205 /**
206 * Method to fire event from native code
207 * bNoDetach is required for events which cause an exception which needs to be caught in native code
208 */
209 fireDocumentEvent: function (type, data, bNoDetach) {
210 var evt = Capacitor.createEvent(type, data);
211 if (typeof documentEventHandlers[type] !== 'undefined') {
212 if (bNoDetach) {
213 documentEventHandlers[type].fire(evt);
214 } else {
215 setTimeout(function () {
216 // Fire deviceready on listeners that were registered before cordova.js was loaded.
217 if (type === 'deviceready') {
218 document.dispatchEvent(evt);
219 }
220 documentEventHandlers[type].fire(evt);
221 }, 0);
222 }
223 } else {
224 document.dispatchEvent(evt);
225 }
226 },
227 fireWindowEvent: function (type, data) {
228 var evt = Capacitor.createEvent(type, data);
229 if (typeof windowEventHandlers[type] !== 'undefined') {
230 setTimeout(function () {
231 windowEventHandlers[type].fire(evt);
232 }, 0);
233 } else {
234 window.dispatchEvent(evt);
235 }
236 },
237
238 /**
239 * Plugin callback mechanism.
240 */
241 // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
242 // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
243 callbackId: Math.floor(Math.random() * 2000000000),
244 callbacks: {},
245 callbackStatus: {
246 NO_RESULT: 0,
247 OK: 1,
248 CLASS_NOT_FOUND_EXCEPTION: 2,
249 ILLEGAL_ACCESS_EXCEPTION: 3,
250 INSTANTIATION_EXCEPTION: 4,
251 MALFORMED_URL_EXCEPTION: 5,
252 IO_EXCEPTION: 6,
253 INVALID_ACTION: 7,
254 JSON_EXCEPTION: 8,
255 ERROR: 9,
256 },
257
258 /**
259 * Called by native code when returning successful result from an action.
260 */
261 callbackSuccess: function (callbackId, args) {
262 cordova.callbackFromNative(
263 callbackId,
264 true,
265 args.status,
266 [args.message],
267 args.keepCallback,
268 );
269 },
270
271 /**
272 * Called by native code when returning error result from an action.
273 */
274 callbackError: function (callbackId, args) {
275 // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
276 // Derive success from status.
277 cordova.callbackFromNative(
278 callbackId,
279 false,
280 args.status,
281 [args.message],
282 args.keepCallback,
283 );
284 },
285
286 /**
287 * Called by native code when returning the result from an action.
288 */
289 callbackFromNative: function (
290 callbackId,
291 isSuccess,
292 status,
293 args,
294 keepCallback,
295 ) {
296 try {
297 var callback = cordova.callbacks[callbackId];
298 if (callback) {
299 if (isSuccess && status === cordova.callbackStatus.OK) {
300 callback.success && callback.success.apply(null, args);
301 } else if (!isSuccess) {
302 callback.fail && callback.fail.apply(null, args);
303 }
304 /*
305 else
306 Note, this case is intentionally not caught.
307 this can happen if isSuccess is true, but callbackStatus is NO_RESULT
308 which is used to remove a callback from the list without calling the callbacks
309 typically keepCallback is false in this case
310 */
311 // Clear callback if not expecting any more results
312 if (!keepCallback) {
313 delete cordova.callbacks[callbackId];
314 }
315 }
316 } catch (err) {
317 var msg =
318 'Error in ' +
319 (isSuccess ? 'Success' : 'Error') +
320 ' callbackId: ' +
321 callbackId +
322 ' : ' +
323 err;
324 console && console.log && console.log(msg);
325 cordova.fireWindowEvent('cordovacallbackerror', { message: msg });
326 throw err;
327 }
328 },
329 addConstructor: function (func) {
330 channel.onCordovaReady.subscribe(function () {
331 try {
332 func();
333 } catch (e) {
334 console.log('Failed to run constructor: ' + e);
335 }
336 });
337 },
338 };
339
340 module.exports = cordova;
341 });
342
343 // file: src/common/argscheck.js
344 define('cordova/argscheck', function (require, exports, module) {
345 var utils = require('cordova/utils');
346
347 var moduleExports = module.exports;
348
349 var typeMap = {
350 A: 'Array',
351 D: 'Date',
352 N: 'Number',
353 S: 'String',
354 F: 'Function',
355 O: 'Object',
356 };
357
358 function extractParamName(callee, argIndex) {
359 return /.*?\((.*?)\)/.exec(callee)[1].split(', ')[argIndex];
360 }
361
362 function checkArgs(spec, functionName, args, opt_callee) {
363 if (!moduleExports.enableChecks) {
364 return;
365 }
366 var errMsg = null;
367 var typeName;
368 for (var i = 0; i < spec.length; ++i) {
369 var c = spec.charAt(i);
370 var cUpper = c.toUpperCase();
371 var arg = args[i];
372 // Asterix means allow anything.
373 if (c === '*') {
374 continue;
375 }
376 typeName = utils.typeName(arg);
377 if ((arg === null || arg === undefined) && c === cUpper) {
378 continue;
379 }
380 if (typeName !== typeMap[cUpper]) {
381 errMsg = 'Expected ' + typeMap[cUpper];
382 break;
383 }
384 }
385 if (errMsg) {
386 errMsg += ', but got ' + typeName + '.';
387 errMsg =
388 'Wrong type for parameter "' +
389 extractParamName(opt_callee || args.callee, i) +
390 '" of ' +
391 functionName +
392 ': ' +
393 errMsg;
394 // Don't log when running unit tests.
395 if (typeof jasmine === 'undefined') {
396 console.error(errMsg);
397 }
398 throw TypeError(errMsg);
399 }
400 }
401
402 function getValue(value, defaultValue) {
403 return value === undefined ? defaultValue : value;
404 }
405
406 moduleExports.checkArgs = checkArgs;
407 moduleExports.getValue = getValue;
408 moduleExports.enableChecks = true;
409 });
410
411 // file: src/common/base64.js
412 define('cordova/base64', function (require, exports, module) {
413 var base64 = exports;
414
415 base64.fromArrayBuffer = function (arrayBuffer) {
416 var array = new Uint8Array(arrayBuffer);
417 return uint8ToBase64(array);
418 };
419
420 base64.toArrayBuffer = function (str) {
421 var decodedStr =
422 typeof atob !== 'undefined'
423 ? atob(str)
424 : Buffer.from(str, 'base64').toString('binary'); // eslint-disable-line no-undef
425 var arrayBuffer = new ArrayBuffer(decodedStr.length);
426 var array = new Uint8Array(arrayBuffer);
427 for (var i = 0, len = decodedStr.length; i < len; i++) {
428 array[i] = decodedStr.charCodeAt(i);
429 }
430 return arrayBuffer;
431 };
432
433 // ------------------------------------------------------------------------------
434
435 /* This code is based on the performance tests at http://jsperf.com/b64tests
436 * This 12-bit-at-a-time algorithm was the best performing version on all
437 * platforms tested.
438 */
439
440 var b64_6bit =
441 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
442 var b64_12bit;
443
444 var b64_12bitTable = function () {
445 b64_12bit = [];
446 for (var i = 0; i < 64; i++) {
447 for (var j = 0; j < 64; j++) {
448 b64_12bit[i * 64 + j] = b64_6bit[i] + b64_6bit[j];
449 }
450 }
451 b64_12bitTable = function () {
452 return b64_12bit;
453 };
454 return b64_12bit;
455 };
456
457 function uint8ToBase64(rawData) {
458 var numBytes = rawData.byteLength;
459 var output = '';
460 var segment;
461 var table = b64_12bitTable();
462 for (var i = 0; i < numBytes - 2; i += 3) {
463 segment = (rawData[i] << 16) + (rawData[i + 1] << 8) + rawData[i + 2];
464 output += table[segment >> 12];
465 output += table[segment & 0xfff];
466 }
467 if (numBytes - i === 2) {
468 segment = (rawData[i] << 16) + (rawData[i + 1] << 8);
469 output += table[segment >> 12];
470 output += b64_6bit[(segment & 0xfff) >> 6];
471 output += '=';
472 } else if (numBytes - i === 1) {
473 segment = rawData[i] << 16;
474 output += table[segment >> 12];
475 output += '==';
476 }
477 return output;
478 }
479 });
480
481 // file: src/common/builder.js
482 define('cordova/builder', function (require, exports, module) {
483 var utils = require('cordova/utils');
484
485 function each(objects, func, context) {
486 for (var prop in objects) {
487 if (objects.hasOwnProperty(prop)) {
488 func.apply(context, [objects[prop], prop]);
489 }
490 }
491 }
492
493 function clobber(obj, key, value) {
494 exports.replaceHookForTesting(obj, key);
495 var needsProperty = false;
496 try {
497 obj[key] = value;
498 } catch (e) {
499 needsProperty = true;
500 }
501 // Getters can only be overridden by getters.
502 if (needsProperty || obj[key] !== value) {
503 utils.defineGetter(obj, key, function () {
504 return value;
505 });
506 }
507 }
508
509 function assignOrWrapInDeprecateGetter(obj, key, value, message) {
510 if (message) {
511 utils.defineGetter(obj, key, function () {
512 console.log(message);
513 delete obj[key];
514 clobber(obj, key, value);
515 return value;
516 });
517 } else {
518 clobber(obj, key, value);
519 }
520 }
521
522 function include(parent, objects, clobber, merge) {
523 each(objects, function (obj, key) {
524 try {
525 var result = obj.path ? require(obj.path) : {};
526
527 if (clobber) {
528 // Clobber if it doesn't exist.
529 if (typeof parent[key] === 'undefined') {
530 assignOrWrapInDeprecateGetter(
531 parent,
532 key,
533 result,
534 obj.deprecated,
535 );
536 } else if (typeof obj.path !== 'undefined') {
537 // If merging, merge properties onto parent, otherwise, clobber.
538 if (merge) {
539 recursiveMerge(parent[key], result);
540 } else {
541 assignOrWrapInDeprecateGetter(
542 parent,
543 key,
544 result,
545 obj.deprecated,
546 );
547 }
548 }
549 result = parent[key];
550 } else {
551 // Overwrite if not currently defined.
552 if (typeof parent[key] === 'undefined') {
553 assignOrWrapInDeprecateGetter(
554 parent,
555 key,
556 result,
557 obj.deprecated,
558 );
559 } else {
560 // Set result to what already exists, so we can build children into it if they exist.
561 result = parent[key];
562 }
563 }
564
565 if (obj.children) {
566 include(result, obj.children, clobber, merge);
567 }
568 } catch (e) {
569 utils.alert(
570 'Exception building Cordova JS globals: ' +
571 e +
572 ' for key "' +
573 key +
574 '"',
575 );
576 }
577 });
578 }
579
580 /**
581 * Merge properties from one object onto another recursively. Properties from
582 * the src object will overwrite existing target property.
583 *
584 * @param target Object to merge properties into.
585 * @param src Object to merge properties from.
586 */
587 function recursiveMerge(target, src) {
588 for (var prop in src) {
589 if (src.hasOwnProperty(prop)) {
590 if (target.prototype && target.prototype.constructor === target) {
591 // If the target object is a constructor override off prototype.
592 clobber(target.prototype, prop, src[prop]);
593 } else {
594 if (
595 typeof src[prop] === 'object' &&
596 typeof target[prop] === 'object'
597 ) {
598 recursiveMerge(target[prop], src[prop]);
599 } else {
600 clobber(target, prop, src[prop]);
601 }
602 }
603 }
604 }
605 }
606
607 exports.buildIntoButDoNotClobber = function (objects, target) {
608 include(target, objects, false, false);
609 };
610 exports.buildIntoAndClobber = function (objects, target) {
611 include(target, objects, true, false);
612 };
613 exports.buildIntoAndMerge = function (objects, target) {
614 include(target, objects, true, true);
615 };
616 exports.recursiveMerge = recursiveMerge;
617 exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
618 exports.replaceHookForTesting = function () {};
619 });
620
621 // file: src/common/channel.js
622 define('cordova/channel', function (require, exports, module) {
623 var utils = require('cordova/utils');
624 var nextGuid = 1;
625
626 /**
627 * Custom pub-sub "channel" that can have functions subscribed to it
628 * This object is used to define and control firing of events for
629 * cordova initialization, as well as for custom events thereafter.
630 *
631 * The order of events during page load and Cordova startup is as follows:
632 *
633 * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed.
634 * onNativeReady* Internal event that indicates the Cordova native side is ready.
635 * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created.
636 * onDeviceReady* User event fired to indicate that Cordova is ready
637 * onResume User event fired to indicate a start/resume lifecycle event
638 * onPause User event fired to indicate a pause lifecycle event
639 *
640 * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
641 * All listeners that subscribe after the event is fired will be executed right away.
642 *
643 * The only Cordova events that user code should register for are:
644 * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
645 * pause App has moved to background
646 * resume App has returned to foreground
647 *
648 * Listeners can be registered as:
649 * document.addEventListener("deviceready", myDeviceReadyListener, false);
650 * document.addEventListener("resume", myResumeListener, false);
651 * document.addEventListener("pause", myPauseListener, false);
652 *
653 * The DOM lifecycle events should be used for saving and restoring state
654 * window.onload
655 * window.onunload
656 *
657 */
658
659 /**
660 * Channel
661 * @constructor
662 * @param type String the channel name
663 */
664 var Channel = function (type, sticky) {
665 this.type = type;
666 // Map of guid -> function.
667 this.handlers = {};
668 // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
669 this.state = sticky ? 1 : 0;
670 // Used in sticky mode to remember args passed to fire().
671 this.fireArgs = null;
672 // Used by onHasSubscribersChange to know if there are any listeners.
673 this.numHandlers = 0;
674 // Function that is called when the first listener is subscribed, or when
675 // the last listener is unsubscribed.
676 this.onHasSubscribersChange = null;
677 };
678 var channel = {
679 /**
680 * Calls the provided function only after all of the channels specified
681 * have been fired. All channels must be sticky channels.
682 */
683 join: function (h, c) {
684 var len = c.length;
685 var i = len;
686 var f = function () {
687 if (!--i) h();
688 };
689 for (var j = 0; j < len; j++) {
690 if (c[j].state === 0) {
691 throw Error('Can only use join with sticky channels.');
692 }
693 c[j].subscribe(f);
694 }
695 if (!len) h();
696 },
697 /* eslint-disable no-return-assign */
698 create: function (type) {
699 return (channel[type] = new Channel(type, false));
700 },
701 createSticky: function (type) {
702 return (channel[type] = new Channel(type, true));
703 },
704 /* eslint-enable no-return-assign */
705 /**
706 * cordova Channels that must fire before "deviceready" is fired.
707 */
708 deviceReadyChannelsArray: [],
709 deviceReadyChannelsMap: {},
710
711 /**
712 * Indicate that a feature needs to be initialized before it is ready to be used.
713 * This holds up Cordova's "deviceready" event until the feature has been initialized
714 * and Cordova.initComplete(feature) is called.
715 *
716 * @param feature {String} The unique feature name
717 */
718 waitForInitialization: function (feature) {
719 if (feature) {
720 var c = channel[feature] || this.createSticky(feature);
721 this.deviceReadyChannelsMap[feature] = c;
722 this.deviceReadyChannelsArray.push(c);
723 }
724 },
725
726 /**
727 * Indicate that initialization code has completed and the feature is ready to be used.
728 *
729 * @param feature {String} The unique feature name
730 */
731 initializationComplete: function (feature) {
732 var c = this.deviceReadyChannelsMap[feature];
733 if (c) {
734 c.fire();
735 }
736 },
737 };
738
739 function checkSubscriptionArgument(argument) {
740 if (
741 typeof argument !== 'function' &&
742 typeof argument.handleEvent !== 'function'
743 ) {
744 throw new Error(
745 'Must provide a function or an EventListener object ' +
746 'implementing the handleEvent interface.',
747 );
748 }
749 }
750
751 /**
752 * Subscribes the given function to the channel. Any time that
753 * Channel.fire is called so too will the function.
754 * Optionally specify an execution context for the function
755 * and a guid that can be used to stop subscribing to the channel.
756 * Returns the guid.
757 */
758 Channel.prototype.subscribe = function (
759 eventListenerOrFunction,
760 eventListener,
761 ) {
762 checkSubscriptionArgument(eventListenerOrFunction);
763 var handleEvent, guid;
764
765 if (
766 eventListenerOrFunction &&
767 typeof eventListenerOrFunction === 'object'
768 ) {
769 // Received an EventListener object implementing the handleEvent interface
770 handleEvent = eventListenerOrFunction.handleEvent;
771 eventListener = eventListenerOrFunction;
772 } else {
773 // Received a function to handle event
774 handleEvent = eventListenerOrFunction;
775 }
776
777 if (this.state === 2) {
778 handleEvent.apply(eventListener || this, this.fireArgs);
779 return;
780 }
781
782 guid = eventListenerOrFunction.observer_guid;
783 if (typeof eventListener === 'object') {
784 handleEvent = utils.close(eventListener, handleEvent);
785 }
786
787 if (!guid) {
788 // First time any channel has seen this subscriber
789 guid = '' + nextGuid++;
790 }
791 handleEvent.observer_guid = guid;
792 eventListenerOrFunction.observer_guid = guid;
793
794 // Don't add the same handler more than once.
795 if (!this.handlers[guid]) {
796 this.handlers[guid] = handleEvent;
797 this.numHandlers++;
798 if (this.numHandlers === 1) {
799 this.onHasSubscribersChange && this.onHasSubscribersChange();
800 }
801 }
802 };
803
804 /**
805 * Unsubscribes the function with the given guid from the channel.
806 */
807 Channel.prototype.unsubscribe = function (eventListenerOrFunction) {
808 checkSubscriptionArgument(eventListenerOrFunction);
809 var handleEvent, guid, handler;
810
811 if (
812 eventListenerOrFunction &&
813 typeof eventListenerOrFunction === 'object'
814 ) {
815 // Received an EventListener object implementing the handleEvent interface
816 handleEvent = eventListenerOrFunction.handleEvent;
817 } else {
818 // Received a function to handle event
819 handleEvent = eventListenerOrFunction;
820 }
821
822 guid = handleEvent.observer_guid;
823 handler = this.handlers[guid];
824 if (handler) {
825 delete this.handlers[guid];
826 this.numHandlers--;
827 if (this.numHandlers === 0) {
828 this.onHasSubscribersChange && this.onHasSubscribersChange();
829 }
830 }
831 };
832
833 /**
834 * Calls all functions subscribed to this channel.
835 */
836 Channel.prototype.fire = function (e) {
837 var fail = false; // eslint-disable-line no-unused-vars
838 var fireArgs = Array.prototype.slice.call(arguments);
839 // Apply stickiness.
840 if (this.state === 1) {
841 this.state = 2;
842 this.fireArgs = fireArgs;
843 }
844 if (this.numHandlers) {
845 // Copy the values first so that it is safe to modify it from within
846 // callbacks.
847 var toCall = [];
848 for (var item in this.handlers) {
849 toCall.push(this.handlers[item]);
850 }
851 for (var i = 0; i < toCall.length; ++i) {
852 toCall[i].apply(this, fireArgs);
853 }
854 if (this.state === 2 && this.numHandlers) {
855 this.numHandlers = 0;
856 this.handlers = {};
857 this.onHasSubscribersChange && this.onHasSubscribersChange();
858 }
859 }
860 };
861
862 // defining them here so they are ready super fast!
863 // DOM event that is received when the web page is loaded and parsed.
864 channel.createSticky('onDOMContentLoaded');
865
866 // Event to indicate the Cordova native side is ready.
867 channel.createSticky('onNativeReady');
868
869 // Event to indicate that all Cordova JavaScript objects have been created
870 // and it's time to run plugin constructors.
871 channel.createSticky('onCordovaReady');
872
873 // Event to indicate that all automatically loaded JS plugins are loaded and ready.
874 // FIXME remove this
875 channel.createSticky('onPluginsReady');
876
877 // Event to indicate that Cordova is ready
878 channel.createSticky('onDeviceReady');
879
880 // Event to indicate a resume lifecycle event
881 channel.create('onResume');
882
883 // Event to indicate a pause lifecycle event
884 channel.create('onPause');
885
886 // Channels that must fire before "deviceready" is fired.
887 channel.waitForInitialization('onCordovaReady');
888 channel.waitForInitialization('onDOMContentLoaded');
889
890 module.exports = channel;
891 });
892
893 define('cordova/exec', function (require, exports, module) {
894 /*global require, module, atob, document */
895
896 /**
897 * Creates a gap bridge iframe used to notify the native code about queued
898 * commands.
899 */
900 var cordova = require('cordova'),
901 utils = require('cordova/utils'),
902 base64 = require('cordova/base64'),
903 execIframe,
904 commandQueue = [], // Contains pending JS->Native messages.
905 isInContextOfEvalJs = 0,
906 failSafeTimerId = 0;
907
908 function massageArgsJsToNative(args) {
909 if (window.androidBridge) {
910 for (var i = 0; i < args.length; i++) {
911 if (utils.typeName(args[i]) == 'ArrayBuffer') {
912 args[i] = base64.fromArrayBuffer(args[i]);
913 }
914 }
915 return args;
916 } else {
917 if (!args || utils.typeName(args) !== 'Array') {
918 return args;
919 }
920 var ret = [];
921 args.forEach(function (arg, i) {
922 if (utils.typeName(arg) === 'ArrayBuffer') {
923 ret.push({
924 CDVType: 'ArrayBuffer',
925 data: base64.fromArrayBuffer(arg),
926 });
927 } else {
928 ret.push(arg);
929 }
930 });
931 return ret;
932 }
933 }
934
935 function massageMessageNativeToJs(message) {
936 if (message.CDVType === 'ArrayBuffer') {
937 var stringToArrayBuffer = function (str) {
938 var ret = new Uint8Array(str.length);
939 for (var i = 0; i < str.length; i++) {
940 ret[i] = str.charCodeAt(i);
941 }
942 return ret.buffer;
943 };
944 var base64ToArrayBuffer = function (b64) {
945 return stringToArrayBuffer(atob(b64)); // eslint-disable-line no-undef
946 };
947 message = base64ToArrayBuffer(message.data);
948 }
949 return message;
950 }
951
952 function convertMessageToArgsNativeToJs(message) {
953 var args = [];
954 if (!message || !message.hasOwnProperty('CDVType')) {
955 args.push(message);
956 } else if (message.CDVType === 'MultiPart') {
957 message.messages.forEach(function (e) {
958 args.push(massageMessageNativeToJs(e));
959 });
960 } else {
961 args.push(massageMessageNativeToJs(message));
962 }
963 return args;
964 }
965
966 var capacitorExec = function () {
967 // detect change in bridge, if there is a change, we forward to new bridge
968
969 var successCallback, failCallback, service, action, actionArgs;
970 var callbackId = null;
971 if (typeof arguments[0] !== 'string') {
972 // FORMAT ONE
973 successCallback = arguments[0];
974 failCallback = arguments[1];
975 service = arguments[2];
976 action = arguments[3];
977 actionArgs = arguments[4];
978
979 // Since we need to maintain backwards compatibility, we have to pass
980 // an invalid callbackId even if no callback was provided since plugins
981 // will be expecting it. The Cordova.exec() implementation allocates
982 // an invalid callbackId and passes it even if no callbacks were given.
983 callbackId = 'INVALID';
984 } else {
985 throw new Error(
986 'The old format of this exec call has been removed (deprecated since 2.1). Change to: ' + // eslint-disable-line
987 "cordova.exec(null, null, 'Service', 'action', [ arg1, arg2 ]);",
988 );
989 }
990
991 // If actionArgs is not provided, default to an empty array
992 actionArgs = actionArgs || [];
993
994 // Register the callbacks and add the callbackId to the positional
995 // arguments if given.
996 if (successCallback || failCallback) {
997 callbackId = service + cordova.callbackId++;
998 cordova.callbacks[callbackId] = {
999 success: successCallback,
1000 fail: failCallback,
1001 };
1002 }
1003
1004 // Properly encode ArrayBuffer action arguments
1005 actionArgs = massageArgsJsToNative(actionArgs);
1006 actionArgs = JSON.parse(JSON.stringify(actionArgs));
1007 var command = {
1008 type: 'cordova',
1009 callbackId: callbackId,
1010 service: service,
1011 action: action,
1012 actionArgs: actionArgs,
1013 };
1014 if (window.androidBridge) {
1015 window.androidBridge.postMessage(JSON.stringify(command));
1016 } else if (
1017 window.webkit &&
1018 window.webkit.messageHandlers &&
1019 window.webkit.messageHandlers.bridge
1020 ) {
1021 window.webkit.messageHandlers.bridge.postMessage(command);
1022 }
1023 };
1024
1025 // CB-10530
1026 function proxyChanged() {
1027 var cexec = cordovaExec();
1028
1029 return (
1030 execProxy !== cexec && capacitorExec !== cexec // proxy objects are different // proxy object is not the current capacitorExec
1031 );
1032 }
1033
1034 // CB-10106
1035 function handleBridgeChange() {
1036 if (proxyChanged()) {
1037 var commandString = commandQueue.shift();
1038 while (commandString) {
1039 var command = JSON.parse(commandString);
1040 var callbackId = command[0];
1041 var service = command[1];
1042 var action = command[2];
1043 var actionArgs = command[3];
1044 var callbacks = cordova.callbacks[callbackId] || {};
1045
1046 execProxy(
1047 callbacks.success,
1048 callbacks.fail,
1049 service,
1050 action,
1051 actionArgs,
1052 );
1053
1054 commandString = commandQueue.shift();
1055 }
1056 return true;
1057 }
1058
1059 return false;
1060 }
1061
1062 function pokeNative() {
1063 // CB-5488 - Don't attempt to create iframe before document.body is available.
1064 if (!document.body) {
1065 setTimeout(pokeNative);
1066 return;
1067 }
1068
1069 // Check if they've removed it from the DOM, and put it back if so.
1070 if (execIframe && execIframe.contentWindow) {
1071 execIframe.contentWindow.location = 'gap://ready';
1072 } else {
1073 execIframe = document.createElement('iframe');
1074 execIframe.style.display = 'none';
1075 execIframe.src = 'gap://ready';
1076 document.body.appendChild(execIframe);
1077 }
1078 // Use a timer to protect against iframe being unloaded during the poke (CB-7735).
1079 // This makes the bridge ~ 7% slower, but works around the poke getting lost
1080 // when the iframe is removed from the DOM.
1081 // An onunload listener could be used in the case where the iframe has just been
1082 // created, but since unload events fire only once, it doesn't work in the normal
1083 // case of iframe reuse (where unload will have already fired due to the attempted
1084 // navigation of the page).
1085 failSafeTimerId = setTimeout(function () {
1086 if (commandQueue.length) {
1087 // CB-10106 - flush the queue on bridge change
1088 if (!handleBridgeChange()) {
1089 pokeNative();
1090 }
1091 }
1092 }, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn't fire).
1093 }
1094
1095 capacitorExec.nativeFetchMessages = function () {
1096 // Stop listing for window detatch once native side confirms poke.
1097 if (failSafeTimerId) {
1098 clearTimeout(failSafeTimerId);
1099 failSafeTimerId = 0;
1100 }
1101 // Each entry in commandQueue is a JSON string already.
1102 if (!commandQueue.length) {
1103 return '';
1104 }
1105 var json = '[' + commandQueue.join(',') + ']';
1106 commandQueue.length = 0;
1107 return json;
1108 };
1109
1110 capacitorExec.nativeCallback = function (
1111 callbackId,
1112 status,
1113 message,
1114 keepCallback,
1115 debug,
1116 ) {
1117 var success = status === 0 || status === 1;
1118 var args = convertMessageToArgsNativeToJs(message);
1119 Promise.resolve().then(function () {
1120 cordova.callbackFromNative(
1121 callbackId,
1122 success,
1123 status,
1124 args,
1125 keepCallback,
1126 ); // eslint-disable-line
1127 });
1128 };
1129
1130 // for backwards compatibility
1131 capacitorExec.nativeEvalAndFetch = function (func) {
1132 try {
1133 func();
1134 } catch (e) {
1135 console.log(e);
1136 }
1137 };
1138
1139 // Proxy the exec for bridge changes. See CB-10106
1140 function cordovaExec() {
1141 var cexec = require('cordova/exec');
1142 var cexec_valid =
1143 typeof cexec.nativeFetchMessages === 'function' &&
1144 typeof cexec.nativeEvalAndFetch === 'function' &&
1145 typeof cexec.nativeCallback === 'function';
1146 return cexec_valid && execProxy !== cexec ? cexec : capacitorExec;
1147 }
1148 function execProxy() {
1149 cordovaExec().apply(null, arguments);
1150 }
1151
1152 execProxy.nativeFetchMessages = function () {
1153 return cordovaExec().nativeFetchMessages.apply(null, arguments);
1154 };
1155
1156 execProxy.nativeEvalAndFetch = function () {
1157 return cordovaExec().nativeEvalAndFetch.apply(null, arguments);
1158 };
1159
1160 execProxy.nativeCallback = function () {
1161 return cordovaExec().nativeCallback.apply(null, arguments);
1162 };
1163
1164 module.exports = execProxy;
1165 });
1166
1167 // file: src/common/exec/proxy.js
1168 define('cordova/exec/proxy', function (require, exports, module) {
1169 // internal map of proxy function
1170 var CommandProxyMap = {};
1171
1172 module.exports = {
1173 // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
1174 add: function (id, proxyObj) {
1175 console.log('adding proxy for ' + id);
1176 CommandProxyMap[id] = proxyObj;
1177 return proxyObj;
1178 },
1179
1180 // cordova.commandProxy.remove("Accelerometer");
1181 remove: function (id) {
1182 var proxy = CommandProxyMap[id];
1183 delete CommandProxyMap[id];
1184 CommandProxyMap[id] = null;
1185 return proxy;
1186 },
1187
1188 get: function (service, action) {
1189 return CommandProxyMap[service]
1190 ? CommandProxyMap[service][action]
1191 : null;
1192 },
1193 };
1194 });
1195
1196 // file: src/common/init.js
1197 define('cordova/init', function (require, exports, module) {
1198 var channel = require('cordova/channel');
1199 var cordova = require('cordova');
1200 var modulemapper = require('cordova/modulemapper');
1201 var platform = require('cordova/platform');
1202 var pluginloader = require('cordova/pluginloader');
1203 var utils = require('cordova/utils');
1204
1205 var platformInitChannelsArray = [
1206 channel.onNativeReady,
1207 channel.onPluginsReady,
1208 ];
1209
1210 function logUnfiredChannels(arr) {
1211 for (var i = 0; i < arr.length; ++i) {
1212 if (arr[i].state !== 2) {
1213 console.log('Channel not fired: ' + arr[i].type);
1214 }
1215 }
1216 }
1217
1218 window.setTimeout(function () {
1219 if (channel.onDeviceReady.state !== 2) {
1220 console.log('deviceready has not fired after 5 seconds.');
1221 logUnfiredChannels(platformInitChannelsArray);
1222 logUnfiredChannels(channel.deviceReadyChannelsArray);
1223 }
1224 }, 5000);
1225
1226 // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
1227 // We replace it so that properties that can't be clobbered can instead be overridden.
1228 function replaceNavigator(origNavigator) {
1229 var CordovaNavigator = function () {};
1230 CordovaNavigator.prototype = origNavigator;
1231 var newNavigator = new CordovaNavigator();
1232 // This work-around really only applies to new APIs that are newer than Function.bind.
1233 // Without it, APIs such as getGamepads() break.
1234 if (CordovaNavigator.bind) {
1235 for (var key in origNavigator) {
1236 if (typeof origNavigator[key] === 'function') {
1237 newNavigator[key] = origNavigator[key].bind(origNavigator);
1238 } else {
1239 (function (k) {
1240 utils.defineGetterSetter(newNavigator, key, function () {
1241 return origNavigator[k];
1242 });
1243 })(key);
1244 }
1245 }
1246 }
1247 return newNavigator;
1248 }
1249
1250 if (window.navigator) {
1251 window.navigator = replaceNavigator(window.navigator);
1252 }
1253
1254 // Register pause, resume and deviceready channels as events on document.
1255 channel.onPause = cordova.addDocumentEventHandler('pause');
1256 channel.onResume = cordova.addDocumentEventHandler('resume');
1257 channel.onActivated = cordova.addDocumentEventHandler('activated');
1258 channel.onDeviceReady =
1259 cordova.addStickyDocumentEventHandler('deviceready');
1260
1261 // Listen for DOMContentLoaded and notify our channel subscribers.
1262 if (
1263 document.readyState === 'complete' ||
1264 document.readyState === 'interactive'
1265 ) {
1266 channel.onDOMContentLoaded.fire();
1267 } else {
1268 document.addEventListener(
1269 'DOMContentLoaded',
1270 function () {
1271 channel.onDOMContentLoaded.fire();
1272 },
1273 false,
1274 );
1275 }
1276
1277 // _nativeReady is global variable that the native side can set
1278 // to signify that the native code is ready. It is a global since
1279 // it may be called before any cordova JS is ready.
1280 if (window._nativeReady) {
1281 channel.onNativeReady.fire();
1282 }
1283
1284 modulemapper.clobbers('cordova', 'cordova');
1285 modulemapper.clobbers('cordova/exec', 'cordova.exec');
1286 modulemapper.clobbers('cordova/exec', 'Cordova.exec');
1287
1288 // Call the platform-specific initialization.
1289 platform.bootstrap && platform.bootstrap();
1290
1291 // Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
1292 // The delay allows the attached modules to be defined before the plugin loader looks for them.
1293 setTimeout(function () {
1294 pluginloader.load(function () {
1295 channel.onPluginsReady.fire();
1296 });
1297 }, 0);
1298
1299 /**
1300 * Create all cordova objects once native side is ready.
1301 */
1302 channel.join(function () {
1303 modulemapper.mapModules(window);
1304
1305 platform.initialize && platform.initialize();
1306
1307 // Fire event to notify that all objects are created
1308 channel.onCordovaReady.fire();
1309
1310 // Fire onDeviceReady event once page has fully loaded, all
1311 // constructors have run and cordova info has been received from native
1312 // side.
1313 channel.join(function () {
1314 require('cordova').fireDocumentEvent('deviceready');
1315 }, channel.deviceReadyChannelsArray);
1316 }, platformInitChannelsArray);
1317 });
1318
1319 // file: src/common/modulemapper.js
1320 define('cordova/modulemapper', function (require, exports, module) {
1321 var builder = require('cordova/builder');
1322 var moduleMap = define.moduleMap; // eslint-disable-line no-undef
1323 var symbolList;
1324 var deprecationMap;
1325
1326 exports.reset = function () {
1327 symbolList = [];
1328 deprecationMap = {};
1329 };
1330
1331 function addEntry(
1332 strategy,
1333 moduleName,
1334 symbolPath,
1335 opt_deprecationMessage,
1336 ) {
1337 if (!(moduleName in moduleMap)) {
1338 throw new Error('Module ' + moduleName + ' does not exist.');
1339 }
1340 symbolList.push(strategy, moduleName, symbolPath);
1341 if (opt_deprecationMessage) {
1342 deprecationMap[symbolPath] = opt_deprecationMessage;
1343 }
1344 }
1345
1346 // Note: Android 2.3 does have Function.bind().
1347 exports.clobbers = function (
1348 moduleName,
1349 symbolPath,
1350 opt_deprecationMessage,
1351 ) {
1352 addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
1353 };
1354
1355 exports.merges = function (moduleName, symbolPath, opt_deprecationMessage) {
1356 addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
1357 };
1358
1359 exports.defaults = function (
1360 moduleName,
1361 symbolPath,
1362 opt_deprecationMessage,
1363 ) {
1364 addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
1365 };
1366
1367 exports.runs = function (moduleName) {
1368 addEntry('r', moduleName, null);
1369 };
1370
1371 function prepareNamespace(symbolPath, context) {
1372 if (!symbolPath) {
1373 return context;
1374 }
1375 var parts = symbolPath.split('.');
1376 var cur = context;
1377 for (var i = 0, part; (part = parts[i]); ++i) {
1378 // eslint-disable-line no-cond-assign
1379 cur = cur[part] = cur[part] || {};
1380 }
1381 return cur;
1382 }
1383
1384 exports.mapModules = function (context) {
1385 var origSymbols = {};
1386 context.CDV_origSymbols = origSymbols;
1387 for (var i = 0, len = symbolList.length; i < len; i += 3) {
1388 var strategy = symbolList[i];
1389 var moduleName = symbolList[i + 1];
1390 var module = require(moduleName);
1391 // <runs/>
1392 if (strategy === 'r') {
1393 continue;
1394 }
1395 var symbolPath = symbolList[i + 2];
1396 var lastDot = symbolPath.lastIndexOf('.');
1397 var namespace = symbolPath.substr(0, lastDot);
1398 var lastName = symbolPath.substr(lastDot + 1);
1399
1400 var deprecationMsg =
1401 symbolPath in deprecationMap
1402 ? 'Access made to deprecated symbol: ' +
1403 symbolPath +
1404 '. ' +
1405 deprecationMsg
1406 : null;
1407 var parentObj = prepareNamespace(namespace, context);
1408 var target = parentObj[lastName];
1409
1410 if (strategy === 'm' && target) {
1411 builder.recursiveMerge(target, module);
1412 } else if ((strategy === 'd' && !target) || strategy !== 'd') {
1413 if (!(symbolPath in origSymbols)) {
1414 origSymbols[symbolPath] = target;
1415 }
1416 builder.assignOrWrapInDeprecateGetter(
1417 parentObj,
1418 lastName,
1419 module,
1420 deprecationMsg,
1421 );
1422 }
1423 }
1424 };
1425
1426 exports.getOriginalSymbol = function (context, symbolPath) {
1427 var origSymbols = context.CDV_origSymbols;
1428 if (origSymbols && symbolPath in origSymbols) {
1429 return origSymbols[symbolPath];
1430 }
1431 var parts = symbolPath.split('.');
1432 var obj = context;
1433 for (var i = 0; i < parts.length; ++i) {
1434 obj = obj && obj[parts[i]];
1435 }
1436 return obj;
1437 };
1438
1439 exports.reset();
1440 });
1441
1442 define('cordova/platform', function (require, exports, module) {
1443 module.exports = {
1444 id: Capacitor.platform,
1445 bootstrap: function () {
1446 require('cordova/channel').onNativeReady.fire();
1447 },
1448 };
1449 });
1450
1451 // file: src/common/pluginloader.js
1452 define('cordova/pluginloader', function (require, exports, module) {
1453 var modulemapper = require('cordova/modulemapper');
1454
1455 function onScriptLoadingComplete(moduleList, finishPluginLoading) {
1456 console.log('onscript loading complete');
1457 // Loop through all the plugins and then through their clobbers and merges.
1458 for (var i = 0, module; (module = moduleList[i]); i++) {
1459 // eslint-disable-line no-cond-assign
1460 if (module.clobbers && module.clobbers.length) {
1461 for (var j = 0; j < module.clobbers.length; j++) {
1462 modulemapper.clobbers(module.id, module.clobbers[j]);
1463 }
1464 }
1465
1466 if (module.merges && module.merges.length) {
1467 for (var k = 0; k < module.merges.length; k++) {
1468 modulemapper.merges(module.id, module.merges[k]);
1469 }
1470 }
1471
1472 // Finally, if runs is truthy we want to simply require() the module.
1473 if (module.runs) {
1474 modulemapper.runs(module.id);
1475 }
1476 }
1477
1478 finishPluginLoading();
1479 }
1480
1481 // Tries to load all plugins' js-modules.
1482 // This is an async process, but onDeviceReady is blocked on onPluginsReady.
1483 // onPluginsReady is fired when there are no plugins to load, or they are all done.
1484 exports.load = function (callback) {
1485 var moduleList = require('cordova/plugin_list');
1486 onScriptLoadingComplete(moduleList, callback);
1487 };
1488 });
1489
1490 // file: src/common/urlutil.js
1491 define('cordova/urlutil', function (require, exports, module) {
1492 /**
1493 * For already absolute URLs, returns what is passed in.
1494 * For relative URLs, converts them to absolute ones.
1495 */
1496 exports.makeAbsolute = function makeAbsolute(url) {
1497 var anchorEl = document.createElement('a');
1498 anchorEl.href = url;
1499 return anchorEl.href;
1500 };
1501 });
1502
1503 // file: src/common/utils.js
1504 define('cordova/utils', function (require, exports, module) {
1505 var utils = exports;
1506
1507 /**
1508 * Defines a property getter / setter for obj[key].
1509 */
1510 utils.defineGetterSetter = function (obj, key, getFunc, opt_setFunc) {
1511 if (Object.defineProperty) {
1512 var desc = {
1513 get: getFunc,
1514 configurable: true,
1515 };
1516 if (opt_setFunc) {
1517 desc.set = opt_setFunc;
1518 }
1519 Object.defineProperty(obj, key, desc);
1520 } else {
1521 obj.__defineGetter__(key, getFunc);
1522 if (opt_setFunc) {
1523 obj.__defineSetter__(key, opt_setFunc);
1524 }
1525 }
1526 };
1527
1528 /**
1529 * Defines a property getter for obj[key].
1530 */
1531 utils.defineGetter = utils.defineGetterSetter;
1532
1533 utils.arrayIndexOf = function (a, item) {
1534 if (a.indexOf) {
1535 return a.indexOf(item);
1536 }
1537 var len = a.length;
1538 for (var i = 0; i < len; ++i) {
1539 if (a[i] === item) {
1540 return i;
1541 }
1542 }
1543 return -1;
1544 };
1545
1546 /**
1547 * Returns whether the item was found in the array.
1548 */
1549 utils.arrayRemove = function (a, item) {
1550 var index = utils.arrayIndexOf(a, item);
1551 if (index !== -1) {
1552 a.splice(index, 1);
1553 }
1554 return index !== -1;
1555 };
1556
1557 utils.typeName = function (val) {
1558 return Object.prototype.toString.call(val).slice(8, -1);
1559 };
1560
1561 /**
1562 * Returns an indication of whether the argument is an array or not
1563 */
1564 utils.isArray =
1565 Array.isArray ||
1566 function (a) {
1567 return utils.typeName(a) === 'Array';
1568 };
1569
1570 /**
1571 * Returns an indication of whether the argument is a Date or not
1572 */
1573 utils.isDate = function (d) {
1574 return d instanceof Date;
1575 };
1576
1577 /**
1578 * Does a deep clone of the object.
1579 */
1580 utils.clone = function (obj) {
1581 if (
1582 !obj ||
1583 typeof obj === 'function' ||
1584 utils.isDate(obj) ||
1585 typeof obj !== 'object'
1586 ) {
1587 return obj;
1588 }
1589
1590 var retVal, i;
1591
1592 if (utils.isArray(obj)) {
1593 retVal = [];
1594 for (i = 0; i < obj.length; ++i) {
1595 retVal.push(utils.clone(obj[i]));
1596 }
1597 return retVal;
1598 }
1599
1600 retVal = {};
1601 for (i in obj) {
1602 // https://issues.apache.org/jira/browse/CB-11522 'unknown' type may be returned in
1603 // custom protocol activation case on Windows Phone 8.1 causing "No such interface supported" exception
1604 // on cloning.
1605 if (
1606 (!(i in retVal) || retVal[i] !== obj[i]) &&
1607 typeof obj[i] !== 'undefined' &&
1608 typeof obj[i] !== 'unknown'
1609 ) {
1610 // eslint-disable-line valid-typeof
1611 retVal[i] = utils.clone(obj[i]);
1612 }
1613 }
1614 return retVal;
1615 };
1616
1617 /**
1618 * Returns a wrapped version of the function
1619 */
1620 utils.close = function (context, func, params) {
1621 return function () {
1622 var args = params || arguments;
1623 return func.apply(context, args);
1624 };
1625 };
1626
1627 // ------------------------------------------------------------------------------
1628 function UUIDcreatePart(length) {
1629 var uuidpart = '';
1630 for (var i = 0; i < length; i++) {
1631 var uuidchar = parseInt(Math.random() * 256, 10).toString(16);
1632 if (uuidchar.length === 1) {
1633 uuidchar = '0' + uuidchar;
1634 }
1635 uuidpart += uuidchar;
1636 }
1637 return uuidpart;
1638 }
1639
1640 /**
1641 * Create a UUID
1642 */
1643 utils.createUUID = function () {
1644 return (
1645 UUIDcreatePart(4) +
1646 '-' +
1647 UUIDcreatePart(2) +
1648 '-' +
1649 UUIDcreatePart(2) +
1650 '-' +
1651 UUIDcreatePart(2) +
1652 '-' +
1653 UUIDcreatePart(6)
1654 );
1655 };
1656
1657 /**
1658 * Extends a child object from a parent object using classical inheritance
1659 * pattern.
1660 */
1661 utils.extend = (function () {
1662 // proxy used to establish prototype chain
1663 var F = function () {};
1664 // extend Child from Parent
1665 return function (Child, Parent) {
1666 F.prototype = Parent.prototype;
1667 Child.prototype = new F();
1668 Child.__super__ = Parent.prototype;
1669 Child.prototype.constructor = Child;
1670 };
1671 })();
1672
1673 /**
1674 * Alerts a message in any available way: alert or console.log.
1675 */
1676 utils.alert = function (msg) {
1677 if (window.alert) {
1678 window.alert(msg);
1679 } else if (console && console.log) {
1680 console.log(msg);
1681 }
1682 };
1683 });
1684
1685 window.cordova = require('cordova');
1686 // file: src/scripts/bootstrap.js
1687
1688 require('cordova/init');
1689})();