
; (function(ns) {

    // If the widget loader is to be re-used across solutions, the JS/CSS assets registry must be made global
    // or directly attached to the <link> and <script> DOM elements that are inserted by the widget loader(s).

    ns.assets = ns.assets || { 'js': {}, 'css': {}};
    ns.widgets = ns.widgets || {};
    ns.config = ns.config || [];

    ns.assetIdSequence = ns.assetIdSequence || 1;
    ns.widgetIdSequence = ns.widgetIdSequence || 1;

    ns.configured = false;

    var _packages = {"vsmobile":{"js":["assets\/sbtechgi\/vsmobile\/js\/vsmobile.js?v=4268324154"],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile.css?v=2909533948"]},"vsmobile.vfl":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vfl.css?v=1807710352"]},"vsmobile.vflm":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vflm.css?v=3108623283"]},"vsmobile.vbl":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vbl.css?v=92909663"]},"vsmobile.vto":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vto.css?v=2650694996"]},"vsmobile.vfc":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vfc.css?v=1874308139"]},"vsmobile.vfnc":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vfnc.css?v=1904217873"]},"vsmobile.vfwc":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vfwc.css?v=3856002464"]},"vsmobile.vti":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vti.css?v=1328870235"]},"vsmobile.vdk":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vdk.css?v=34060391"]},"vsmobile.vhk":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vhk.css?v=3890548071"]},"vsmobile.vfas":{"js":[],"css":["assets\/sbtechgi\/vsmobile\/css\/vsmobile_vfas.css?v=2553831340"]}};
    var _components = [];
    var _solution = 'vsmobile';
    var _baseUrl = '' || inferBaseUrl();

    function getAssetsPackage(widget) {
        var parts = widget.toLowerCase().split('.');
        for (var i = parts.length; i > 0; --i) {
            var path = parts.slice(0, i).join('.');
            if (_packages.hasOwnProperty(path)) {
                return path;
            }
        }
        return null;
    }

    function getComponentPackages(widget) {
        var components = [];
        var parts = widget.toLowerCase().split('.');
        for (var i = 1; i < parts.length; ++i) {
            var path = parts.slice(0, i).join('.');
            if (_components.hasOwnProperty(path)) {
                components = components.concat(_components[path]);
            }
        }
        return components;
    }

    function getAssetUrls(package, assetType) {
        var assets = [];
        var parts = package.split('.');
        for (var i = 1; i <= parts.length; ++i) {
            var path = parts.slice(0, i).join('.');
            if (_packages.hasOwnProperty(path)) {
                assets = assets.concat(_packages[path][assetType]);
            }
        }
        return assets;
    }

    function getAssets(package, assetType) {
        var assets = [];
        var assetUrls = getAssetUrls(package, assetType);
        for (var i = 0; i < assetUrls.length; ++i) {
            var asset = ns.assets[assetType][assetUrls[i]];
            if (!asset) {
                continue;
            }
            assets.push(asset);
        }
        return assets;
    }

    function constructAssetId() {
        return 'sr-asset-' + 'vsmobile' + '-' + (ns.assetIdSequence++);
    }

    function constructWidgetId() {
        return 'sr-widget-' + 'vsmobile' + '-' + (ns.widgetIdSequence++);
    }

    function constructAsset(assetType, url) {
        return {
            id: constructAssetId(),
            url: url,
            type: assetType,
            loaded: false,
            callbacks: []
        };
    }

    function constructReferenceKey(package) {
        return _solution + '::' + package;
    }

    function addReference(asset, package) {
        var key = constructReferenceKey(package);
        if (!asset.references) {
            asset.references = {};
        }
        asset.references[key] = true;
    }

    function removeReference(asset, package) {
        var key = constructReferenceKey(package);
        if (asset.references) {
            delete asset.references[key];
        }
    }

    function removeAllReferences(asset) {
        var prefix = _solution + '::';
        var keys = Object.keys(asset.references || {});
        for (var i = 0; i < keys.length; ++i) {
            var key = keys[i];
            if (key.indexOf(prefix) == 0) {
                delete asset.references[key];
            }
        }
    }

    function getRefCount(asset) {
        return asset.references ? Object.keys(asset.references).length : 0;
    }

    function injectCSSAssets(package) {
        var styleSheetUrls = getAssetUrls(package, 'css');
        for (var i = 0; i < styleSheetUrls.length; ++i) {
            // check if the dependency is already loaded
            var url = _baseUrl + styleSheetUrls[i];
            var asset = ns.assets.css[url];

            if (!asset) {
                // prevent further loading of this asset by creating an entry for it
                asset = ns.assets.css[url] = constructAsset('css', url);

                // no onload event available, thus no callback
                var head = document.getElementsByTagName('head')[0];
                var l = document.createElement('link');

                l.id = asset.id;
                l.type = 'text/css';
                l.rel = 'stylesheet';
                l.href = url;

                head.appendChild(l);
                asset.loaded = true;
            }
            addReference(asset, package);
        }
    }

    function injectScript(package, url, callback) {
        var asset = ns.assets.js[url];
        if (asset) {
            // track the reference
            addReference(asset, package);
            // the dependency is either already loaded or is loading
            if (asset.loaded) {
                if (callback) callback();
            }
            else {
                asset.callbacks.push(callback);
            }
            return;
        }

        asset = ns.assets.js[url] = constructAsset('js', url);
        asset.callbacks.push(callback);
        addReference(asset, package);

        // Add JavaScript file to the DOM
        var head = document.getElementsByTagName('head')[0];
        var s = document.createElement('script');

        s.id = asset.id;
        s.type = 'text/javascript';
        s.charset = 'utf-8';
        s.src = _baseUrl + url;
        s.async = false;

        head.appendChild(s);

        var readyCallback = function() {
            var state = s.readyState;
            if (!asset.loaded && (!state || /loaded|complete/.test(state))) {
                asset.loaded = true;
                for (var i = 0; i < asset.callbacks.length; ++i) {
                    if (asset.callbacks[i]) asset.callbacks[i]();
                }
                asset.callbacks = [];
                s.onreadystatechange = s.onload = null;
            }
        };

        if (s.addEventListener) {
            s.addEventListener('load', readyCallback, false);
        } else if (s.readyState) {
            s.onreadystatechange = readyCallback;
        }
    }

    function injectJSAssets(package, callback) {
        var scriptUrls = getAssetUrls(package, 'js');
        var scriptCount = scriptUrls.length;

        // check if there are any JS assets to load
        if (scriptCount == 0) {
            if (callback) callback();
            return;
        }

        for (var i = 0; i < scriptUrls.length; ++i) {
            // inject each JS file and notify caller when all scripts are downloaded and run
            injectScript(package, scriptUrls[i], function() {
                if (--scriptCount == 0 && callback) {
                    callback();
                }
            });
        }
    }

    function initSRLive() {
        if (ns.configured || typeof SRLive === 'undefined' || !SRLive.configureClient) {
            return;
        }

        // Initialize SRLive.  Assets packages setup and dependencies must ensure that the package containing
        // SRLive is an explicit or implicit dependency of all other packages.  Therefore, SRLive will be
        // loaded with the first package that adds JavaScript to the page.
        var setup = {
            debugLevel: parseInt('3', 10),
            client: {
                timezone: 'Europe/Berlin',
                language: 'fr',
                name: 'sbtechgi',
                s4_client_id: '160',
                scoreradar_client_id: '-1'
            },
            widget: {
                url: _baseUrl,
                solution: _solution,
                setupOverridesOptions: false,
                delayComponentLoading: false,
                synchronousExecution: true            }
        };

        var keys = Object.keys(ns.config);
        for (var i = 0; i < keys.length; ++i) {
          setup[keys[i]] = ns.config[keys[i]];
        };

        SRLive.configureClient(setup);
        ns.configured = true;
    }

    function injectAssets(package, callback) {
        // Add CSS assets for package
        injectCSSAssets(package);
        // Add JavaScript assets for package
        injectJSAssets(package, function() {
            // Initialize SRLive and invoke caller's callback method
            initSRLive();
            if (callback) {
                callback();
            }
        });
    }

    function injectComponents(components, callback) {

        if (components.length <= 0) {
            callback();
            return;
        }

        // duplicate components array
        var loadedComponents = {};
        for (var i = 0; i < components.length; i++) {
            loadedComponents[components[i]] = false;
        }

        // load components from components parameter
        for (var i = 0; i < components.length; i++) {
            var widget = components[i];
            SRLive.w.add({
                name: widget,
                callback: function(component) {
                    var name = component.className;
                    delete loadedComponents[name];
                    if (Object.keys(loadedComponents).length <= 0) {
                        callback();
                    }
                },
                callbackScope: window
            });
            //SRLive.w.loadDelayedComponents();
        }
    }

    function removeObsoleteAssets(assets) {
        var assetsToRemove = [];
        for (var i = 0; i < assets.length; ++i) {
            var asset = assets[i];
            if (getRefCount(asset) <= 0) {
                assetsToRemove.push(asset);
                delete ns.assets[asset.type][asset.url];
            }
        }

        if (ns.configured && Object.keys(ns.assets.js).length == 0 && typeof SRLive !== 'undefined' && SRLive.destroy) {
            // Destroy SRLive. Assets packages setup and dependencies must ensure that the package containing
            // SRLive is an explicit or implicit dependency of all other packages.  Therefore, SRLive will be
            // removed only when the last JS assets are removed from the page.
            SRLive.destroy();
            ns.configured = false;
        }

        // Remove the elements from the DOM
        for (var i = 0; i < assetsToRemove.length; ++i) {
            var asset = assetsToRemove[i];
            var element = document.getElementById(asset.id);
            if (element && element.parentNode) {
                element.parentNode.removeChild(element);
            }
        }
    }

    function removeAssets(package) {
        var assets = getAssets(package, 'css').concat(getAssets(package, 'js'));
        for (var i = 0; i < assets.length; ++i) {
            removeReference(assets[i], package);
        }
        removeObsoleteAssets(assets);
    }

    function removeAllAssets() {
        var assets = [];
        var assetTypes = ['js', 'css'];

        for (var i = 0; i < assetTypes.length; ++i) {
            var assetCollection = ns.assets[assetTypes[i]];
            var urls = Object.keys(assetCollection);
            for (var j = 0; j < urls.length; ++j) {
                var asset = assetCollection[urls[j]];
                removeAllReferences(asset);
                assets.push(asset);
            }
        }

        removeObsoleteAssets(assets);

        /* remove widget specific styles */
        // var assetsToRemove = [];
        // var widgetStyles = document.getElementsByClassName('sr-widget-style');
        // for (var i = 0; i < widgetStyles.length; i++) {
        //     assetsToRemove.push(widgetStyles[i]);
        // }
        // for (var i = 0; i < assetsToRemove.length; i++) {
        //     var element = assetsToRemove[i];
        //     if (element && element.parentNode) {
        //         element.parentNode.removeChild(element);
        //     }
        // }

    }

    function inferBaseUrl() {

        var path;
        if (document.currentScript) {
            path = document.currentScript.src;
        }
        else {
            var scripts = document.getElementsByTagName('script');
            var testExp = /\/\?\/sbtechgi\/fr\/(.+\/)?page\/vsmobile/;
            for (var i = 0; i < scripts.length; ++i) {
                var src = scripts[i].src;
                if (!src) continue;
                var match = testExp.exec(src);
                if (match && match.index > 0 && src.indexOf('?') > 0) {
                    path = src;
                    break;
                }
            }   
        }

        var pos = path.indexOf('?');
        path = (pos > 0) ? path.substring(0, pos) : path;
        return path.replace(/\/+$/,'') + '/';
    }

    /**
     * Adds a new widget to the page and loads any necessary assets.
     *
     * @param {string} widget The widget type to load.
     * @param {Object} options Widget configuration/initialization options.
     * @param {function} callback Function to be invoked when the widget is loaded
     * @return {string} A unique handle to be used in calls to removeWidget().
     */
     ns.addWidget = function(widget, options, callback) {

        var id = constructWidgetId();
        ns.widgets[id] = null;

        injectAssets(getAssetsPackage(widget), function() {

            // inject component dependencies
            injectComponents(getComponentPackages(widget), function() {

                // check if we can, and still want to add the widget when the async callback is invoked
                if (typeof SRLive !== 'undefined' && SRLive.w && ns.widgets[id] === null) {
                    ns.widgets[id] = SRLive.w.add({
                        name: widget,
                        config: options,
                        callback: callback,
                        callbackScope: window
                    });
                    SRLive.w.loadDelayedComponents();
                }

            });
        });

        return id;
    }

    /**
     * Removes a widget from the page. Note that assets that may have been loaded into the page when the widget
     * was added will not be automatically deleted from the page.
     *
     * @param {string} widgetId The handle returned from addWidget.
     */
    ns.removeWidget = function(widgetId) {
        // signal that we don't want to load the widget if we are still loading assets in the background
        var handle = ns.widgets[widgetId];
        delete ns.widgets[widgetId];

        // remove the widget if we can, and if we ever got so far as to load it in the first place
        if (typeof SRLive !== 'undefined' && SRLive.w && typeof handle != 'undefined' && handle !== null) {
            SRLive.w.remove(handle);
        }
    }

    /**
     * Used for pre-loading assets. Only use if you know what you are doing.
     *
     * @param {string} package The assets package to load.
     * @param {function} callback An optional callback that will be invoked when assets are loaded.
     */
    ns.loadAssets = function(package, callback) {
        injectAssets(package, callback);
    };

    /**
     * Used for cleaning up specific assets. Only use if you *really* know what you are doing.
     *
     * @param {string} package The assets package to remove.
     */
    ns.unloadAssets = function(package) {
        removeAssets(package, callback);
    };

    /**
     * Used for total clean-up. All widgets will be removed and all assets will be unloaded.
     */
    ns.clean = function() {
        var keys = Object.keys(ns.widgets);
        var handles = [];
        for (var i = 0; i < keys.length; ++i) {
            var handle = ns.widgets[keys[i]];
            if (typeof handle != 'undefined' && handle !== null) {
                handles.push(handle);
            }
        }
        ns.widgets = {};

        for (var i = 0; i < handles.length; ++i) {
            if (typeof SRLive !== 'undefined' && SRLive.w) {
                SRLive.w.remove(handles[i]);
            }
        }

        removeAllAssets();
    };

    ns.setConfig = function(key, options) {
      if (!options) {
        ns.clearConfig(key);
        return;
      }

      ns.config[key] = options;
      if (ns.configured && typeof SRLive !== 'undefined' && SRLive.setup) {
        SRLive.setup[key] = options;
      }
    };

    ns.clearConfig = function(key) {
      if (ns.configured && typeof SRLive !== 'undefined' && SRLive.setup) {
        delete SRLive.setup[key];
      }
      delete ns.config[key];
    };

}(window.vsmobile = window.vsmobile || {}));

; (function(ns) {

    /** global definitions **/
    ns.instance = ns.instance || null;

    ns.init = function(container, options) {
        if (ns.instance) {
            console.log('Virtual Sports widget already initialized.');
            return null;
        }

        ns.instance = new Instance(container, options);
        return ns.instance;
    };

    if (typeof Object.assign != 'function') {
        Object.assign = function(target) {
            'use strict';
            if (target == null) {
                throw new TypeError('Cannot convert undefined or null to object');
            }
            target = Object(target);
            for (var index = 1; index < arguments.length; index++) {
                var source = arguments[index];
                if (source != null) {
                    for (var key in source) {
                        if (Object.prototype.hasOwnProperty.call(source, key)) {
                            target[key] = source[key];
                        }
                    }
                }
            }
            return target;
        };
    }

    function Instance(container, options) {
        var Status = {
            INITIALIZING: 'INITIALIZING',
            INITIALIZED: 'INITIALIZED',
            DESTROYED: 'DESTROYED'
        };

        /*
         * Public properties
         */
        this.options = options || {};
        this.container = container;
        this.loaded = false;
        this.shown = true;
        this.betmanager = null;
        this.rgsAdapter = null;
        this.subscriptions = [];
        this.bets = {};

        /*
         * Private methods and properties
         */
        function mergeProperty(property, source, target) {
            if (source.hasOwnProperty(property)) {
                target[property] = source[property];
            }
        }

        function generateBetSignature(key) {
            var parts = key.split('::');
            if (parts.length != 4) {
                return null;
            }

            return {
                sport: parts[0],
                matchId: parts[1],
                betId: parts[2],
                betOutcomeId: parts[3]
            };
        }

        function removeBet(selectionKey, context) {
            if (!this.loaded || !this.betmanager || !SRUtil.isString(selectionKey)) {
                return;
            }
            var signature = generateBetSignature(selectionKey);
            if (signature) {
                this.betmanager.removeBet(signature, true, context);
            }
        }

        function betsChangedHandler(eventData) {

            var newBets = {};

            var bets = eventData.bets;
            var betsAdded = [];
            var betsRemoved = [];

            bets.forEach(function(bet) {
                if (!this.bets[bet.bet.selectionKey]) {
                    betsAdded.push(Object.assign({}, bet.bet));
                }
                newBets[bet.bet.selectionKey] = Object.assign({}, bet);
            }, this);

            Object.keys(this.bets).forEach(function(key) {
                if (!newBets[key]) {
                    betsRemoved.push(Object.assign({}, this.bets[key].bet));
                }
            }, this);

            this.bets = newBets;

            var currentBets = [];
            bets.forEach(function(bet) {
                currentBets.push(Object.assign({}, bet.bet));
            });

            if (SRUtil.isFunction(this.options.betsChanged)) {
                this.options.betsChanged.call(window, this, currentBets, betsAdded, betsRemoved, eventData.context);
            }
        }

        function showSlipHandler(eventData) {
            if (this.loaded && SRUtil.isFunction(this.options.showSlip)) {
                this.options.showSlip.call(window, this, this.getAllSelectedBets());
            }
        }

        function notifyLoginRequired(eventData) {
            if (this.loaded && SRUtil.isFunction(this.options.loginRequired)) {
                this.options.loginRequired.call(window, this);
            }
        }

        function oddsOverrideHandler(roundInfo, oddsSuggestions, callback) {
            if (this.loaded && SRUtil.isFunction(this.options.roundOddsOverride)) {
                // customer-supplied override handler must invoke the odds override callback
                this.options.roundOddsOverride.call(window, this, roundInfo, oddsSuggestions, callback);
            }
            else {
                callback(oddsSuggestions);
            }
        }

        function palAvvOverrideHandler(doc) {
            if (this.loaded && SRUtil.isFunction(this.options.palAvvOverride)) {
                this.options.palAvvOverride.call(window, doc.matches, doc.callback);
            }
            else {
                doc.callback(doc.matches);
            }
        }

        function setEventsHandler(data) {
            if (this.loaded && SRUtil.isFunction(this.options.setEvents)) {
                this.options.setEvents.call(window, this, data);
            }
        }

        function maintenanceCallbackHandler(data) {
            if (this.loaded && SRUtil.isFunction(this.options.maintenanceCallback)) {
                this.options.maintenanceCallback.call(window, this, data);
            }
        }

        function widgetLoaded() {
            this.loaded = true;

            // load default skinning
            SRLive.w.add({
                name: 'vswidgets.core.skinner',
                config: {
                    sport: null
                },
                callback: function(component) {
                    this.skinner = component;
                    //this.skinner.addBaseMobileStyleSheet();
                }.bind(this)
            });

            this.betmanager = SRLive.w.get('vsmobile.core.betmanager');
            this.rgsAdapter = SRLive.w.get('vsmobile.core.rgsbetslipadapter');
            this.rgsValidator = SRLive.w.get('vsmobile.core.rgsbetvalidator');

            this.subscriptions.push(SRLive.event.subscribe('betslip:betsChanged', betsChangedHandler.bind(this)));
            this.subscriptions.push(SRLive.event.subscribe('betslip:betslipButtonClick', showSlipHandler.bind(this)));
            this.subscriptions.push(SRLive.event.subscribe('vsmobile:loginRequired', notifyLoginRequired.bind(this)));
            this.subscriptions.push(SRLive.event.subscribe('vsmobile:setEvents', setEventsHandler.bind(this)));
            this.subscriptions.push(SRLive.event.subscribe('vsmobile:maintenanceCallback', maintenanceCallbackHandler.bind(this)));
            this.subscriptions.push(SRLive.event.subscribe('vsmobile:noModeActive', maintenanceCallbackHandler.bind(this)));

            if (this.options.referrer) {
                if (this.rgsAdapter) {
                    this.rgsAdapter.setReferrer(this.options.referrer);
                } else if (this.rgsValidator) {
                    this.rgsValidator.setReferrer(this.options.referrer);
                }
            }

            if (this.options.roundOddsOverride) {
                var markets = SRLive.w.get('vswidgets.core.data.markets');
                if (markets && SRUtil.isFunction(markets.setOddsOverrideHandler)) {
                    markets.setOddsOverrideHandler(oddsOverrideHandler.bind(this));
                }
            }

            if (SRUtil.isFunction(this.options.onLoad)) {
                this.options.onLoad.call(window, this);
            }

            this.subscriptions.push(SRLive.event.subscribe('vsmobile:passPalAvvOverrides', palAvvOverrideHandler.bind(this)));
        }

        /**
         * Initialization - executed in constructor
         */

        var userOptions = {};
        mergeProperty('topHeaderHeight', this.options, userOptions);
        mergeProperty('bottomFooterHeight', this.options, userOptions);
        mergeProperty('betSelectionMode', this.options, userOptions);
        mergeProperty('outrightSelectionMode', this.options, userOptions);
        mergeProperty('showBetButton', this.options, userOptions);
        mergeProperty('displayMode', this.options, userOptions);
        mergeProperty('showUnsupportedDeviceWarning', this.options, userOptions);
        mergeProperty('useBrowserHistoryAPI', this.options, userOptions);
        mergeProperty('enableMenuShortcuts', this.options, userOptions);
        mergeProperty('persistSelections', this.options, userOptions);

        var config = {};
        if (typeof this.options.widgetOptions === 'object') {
            config = this.options.widgetOptions;
        }

        config.container = this.container;
        config.userOptions = userOptions;

        // These options are passed through to the widget
        var passthru_params = [
            "currentMatchdayTitleContainer",
            "nextMatchdayTitleContainer",
            "headerContainer"
        ];
        for( var i = 0; i < passthru_params.length; i++ ) {
            var key = passthru_params[i];
            if( typeof this.options[key] !== undefined ) {
                config[key] = this.options[key];
            }
        }

        var widget = "vsmobile." + (this.options.sport ? this.options.sport.trim().toLowerCase() : "index");
        ns.addWidget(widget, config, widgetLoaded.bind(this));

        /*
         * Public API
         */
        this.destroy = function() {
            this.loaded = false;

            var subscriptions = this.subscriptions.splice(0, Number.MAX_VALUE);
            for (var i = 0; i < subscriptions.length; ++i) {
                SRLive.event.unsubscribe(subscriptions[i]);
            }

            if (SRLive.poller) {
                SRLive.poller.stop();
            }

            ns.clean();
            ns.instance = null;
        };

        this.getOptions = function() {
            return this.options;
        };

        this.getLanguage = function() {
            return "fr";
        };

        this.getSelector = function() {
            return this.container;
        };

        this.show = function() {
            if (this.shown) {
                return;
            }
            if (this.loaded && this.container) {
                SRjQuery(this.container).css('display', '');
            }
            this.shown = true;
        };

        this.hide = function() {
            if (!this.shown) {
                return;
            }
            if (this.loaded && this.container) {
                SRjQuery(this.container).css('display', 'none');
            }
            this.shown = false;
        };

        this.isShown = function() {
            return this.shown;
        };

        this.isHidden = function() {
            return !this.shown;
        };

        this.getAllSelectedBets = function() {
            if (!this.loaded || !this.betmanager) {
                return [];
            }
            var selectedBets = [];
            var bets = this.betmanager.getBets().bets;
            for(var i=0; i < bets.length; i++) {
                selectedBets.push(bets[i].bet);
            }
            return selectedBets;
        };

        this.confirmBet = function(selectionKey) {
            return removeBet.call(this, selectionKey, 'selectionsConfirmedViaAPI');
        };

        this.deselectBet = function(selectionKey) {
            return removeBet.call(this, selectionKey, 'selectionsDismissedViaAPI');
        };

        this.clearAllSelectedBets = function() {
            var bets = this.getAllSelectedBets();
            if (bets) {
                for (var i = 0; i < bets.length; ++i) {
                    this.deselectBet(bets[i].selectionKey);
                }
            }
        };

        this.selectBets = function(bets) {
            if (bets && this.betmanager) {
                this.betmanager.restoreBets(bets);
            }
        };

        this.setUserToken = function(userToken) {
            if (SRLive) {
                SRLive.event.trigger('vsmobile:setUserToken', {
                    userToken: userToken
                });
            }
        };

        this.setCurrency = function(currencyCode, currencyLabel, decimalPlaces, defaultStake) {
            if (SRLive) {
                SRLive.event.trigger('vsmobile:setCurrency', {
                    currencyCode: currencyCode,
                    currencyLabel: currencyLabel,
                    decimalPlaces: decimalPlaces,
                    defaultStake: defaultStake
                });
            }
        };

        this.getStatus = function() {
            if (ns.instance !== this) {
                return Status.DESTROYED;
            }
            else if (!this.loaded) {
                return Status.INITIALIZING;
            }
            else {
                return Status.INITIALIZED;
            }
        };

        this.playVideo = function() {
            if (SRLive) {
                SRLive.event.trigger('vsm:video-play');
            }
        };

        this.stopVideo = function() {
            if (SRLive) {
                SRLive.event.trigger('vsm:video-stop');
            }
        };

        this.authenticate = function(callback) {
            if (this.rgsAdapter) {
                this.rgsAdapter.authenticate(callback);
            }
        };

        this.getUserAccountInfo = function(callback) {
            if (this.rgsAdapter) {
                this.rgsAdapter.getUserAccountInfo(callback);
            }
        };

        this.getLimits = function(callback) {
            if (this.rgsAdapter) {
                this.rgsAdapter.getLimits(callback);
            }
        };

        this.getSystems = function(callback) {
            if (this.rgsAdapter) {
                this.rgsAdapter.getSystems(callback);
            }
        };

        this.validateTickets = function(tickets, callback) {
            if (this.rgsAdapter) {
                this.rgsAdapter.validateTickets(tickets, callback);
            }
        };

        this.placeTickets = function(tickets, callback) {
            if (this.rgsAdapter) {
                this.rgsAdapter.placeTickets(tickets, callback);
            }
        };

        this.addVsmWidget = function(widgetName, container, options) {
            var widget = "vsmobile." + widgetName;
            var config = {
                container: container
            };
            $.extend(config, options);
            return SRLive.w.add(widget, config);
        };

        this.removeVsmWidget = function(widgetHandle) {
            SRLive.w.remove(widgetHandle);
        };
    }
} (window.vsmobile = window.vsmobile || {}));
