<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">/*
  Version 1.6
  6/8/2015
*/

/*global define,document,location,require */
/*jslint sloppy:true,nomen:true,plusplus:true */
/*
 | Copyright 2014 Esri
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
define([
    "dojo/_base/array",
    "dojo/_base/declare",
    "dojo/_base/kernel",
    "dojo/_base/lang",

    "dojo/Evented",
    "dojo/Deferred",
    "dojo/string",

    "dojo/dom-class",

    "dojo/promise/all",

    "esri/config",
    "esri/IdentityManager",
    "esri/lang",
    "esri/request",
    "esri/urlUtils",

    "esri/arcgis/Portal",
    "esri/arcgis/OAuthInfo",
    "esri/arcgis/utils",

    "esri/tasks/GeometryService",

    "config/defaults"
], function (
    array, declare, kernel, lang,
    Evented, Deferred, string,
    domClass,
    all,
    esriConfig, IdentityManager, esriLang, esriRequest, urlUtils,
    esriPortal, ArcGISOAuthInfo, arcgisUtils,
    GeometryService,
    defaults
) {
    return declare([Evented], {
        config: {},
        orgConfig: {},
        appConfig: {},
        urlConfig: {},
        i18nConfig: {},
        groupItemConfig: {},
        groupInfoConfig: {},
        itemConfig: {},
        customUrlConfig: {},
        sharedThemeConfig: {},
        commonUrlItems: ["webmap", "appid", "group", "oauthappid"],
        constructor: function (templateConfig) {
            // template settings
            var defaultTemplateConfig = {
                queryForWebmap: true
            };
            this.templateConfig = lang.mixin(defaultTemplateConfig, templateConfig);
            // config will contain application and user defined info for the application such as i18n strings the web map id and application id, any url parameters and any application specific configuration information.
            this.config = defaults;
            this.config.isIE = this._detectIESupport();
            // Gets parameters from the URL, convert them to an object and remove HTML tags.
            this.urlObject = this._createUrlParamsObject();
        },
        startup: function () {
            var promise = this._init();
            promise.then(lang.hitch(this, function (config) {
                // optional ready event to listen to
                this.emit("ready", config);
            }), lang.hitch(this, function (error) {
                // optional error event to listen to
                this.emit("error", error);
            }));
            return promise;
        },
        // Get URL parameters and set application defaults needed to query arcgis.com for
        // an application and to see if the app is running in Portal or an Org
        _init: function () {
            var deferred;
            deferred = new Deferred();
            // Set the web map, group and appid if they exist but ignore other url params.
            // Additional url parameters may be defined by the application but they need to be mixed in
            // to the config object after we retrieve the application configuration info. As an example,
            // we'll mix in some commonly used url parameters after
            // the application configuration has been applied so that the url parameters overwrite any
            // configured settings. It's up to the application developer to update the application to take
            // advantage of these parameters.
            this.urlConfig = this._getUrlParamValues(this.commonUrlItems);
            // This demonstrates how to handle additional custom url parameters. For example
            // if you want users to be able to specify lat/lon coordinates that define the map's center or
            // specify an alternate basemap via a url parameter.
            // If these options are also configurable these updates need to be added after any
            // application default and configuration info has been applied. Currently these values
            // (center, basemap, theme) are only here as examples and can be removed if you don't plan on
            // supporting additional url parameters in your application.
            this.customUrlConfig = this._getUrlParamValues(this.templateConfig.urlItems);
            // config defaults &lt;- standard url params
            // we need the webmap, appid, group and oauthappid to query for the data
            this._mixinAll();
            // Define the sharing url and other default values like the proxy.
            // The sharing url defines where to search for the web map and application content. The
            // default value is arcgis.com.
            this._initializeApplication();
            if (this.urlObject &amp;&amp; this.urlObject.query &amp;&amp; this.urlObject.query.previewImage &amp;&amp; this.urlObject.query.previewImage === "true" &amp;&amp; this.urlObject.query.webmap) {
                // Get preview image and show until map is loaded then hide
                var preview = document.getElementById("previewImage");
                domClass.remove(preview, "hidden");
                domClass.add(preview, "fade");
                var imagesrc = this.config.sharinghost + "/sharing/rest/content/items/" + this.urlObject.query.webmap + "/resources/preview-image.png";
                preview.style.backgroundImage = "url(" + imagesrc + ")";

                preview.onerror = function () {
                    domClass.add(preview, "hidden");
                };
            }

            // check if signed in. Once we know if we're signed in, we can get appConfig, orgConfig and create a portal if needed.
            this._checkSignIn().always(lang.hitch(this, function (response) {
                // execute these tasks async
                all({
                    // get localization
                    i18n: this._queryLocalization(),
                    // get application data
                    app: this.queryApplication(),
                    // creates a portal for the app if necessary (groups use them)
                    portal: this._createPortal(),
                    // get org data
                    org: this.queryOrganization()
                }).then(lang.hitch(this, function () {
                    // mixin all new settings from org and app
                    this._mixinAll();
                    // then execute these async
                    all({
                        // webmap item
                        item: this.queryItem(),
                        // group information
                        groupInfo: this.queryGroupInfo(),
                        // group items
                        groupItems: this.queryGroupItems(),
                        // shared themes
                        sharedTheme: this.querySharedTheme()
                    }).then(lang.hitch(this, function () {
                        // mixin all new settings from item, group info and group items.
                        this._mixinAll();
                        if (response &amp;&amp; response.message &amp;&amp; response.message === "User is not signed in.") {
                            // Not signed in check for short org url 
                            var withinFrame = window.location !== window.parent.location;

                            if (this.config.appResponse &amp;&amp; this.config.appResponse.item &amp;&amp; this.config.appResponse.item.contentOrigin &amp;&amp; this.config.appResponse.item.contentOrigin === "other" &amp;&amp; !withinFrame) {
                                var appUrl = this._getAppUrl();
                                deferred.reject({
                                    error: "application:origin-other",
                                    appUrl: appUrl
                                });
                            }
                        }

                        if ((this.config.appResponse &amp;&amp; this.config.appResponse.item.access !== "public")) { // check app access
                            if (response &amp;&amp; response.code &amp;&amp; response.code === "IdentityManagerBase.1") {
                                var licenseMessage = "&lt;h1&gt;" + this.i18nConfig.i18n.map.licenseError.title + "&lt;/h1&gt;&lt;p&gt;" + this.i18nConfig.i18n.map.licenseError.message + "&lt;/p&gt;";
                                deferred.reject(new Error(licenseMessage));
                            }
                        }
                        // We have all we need, let's set up a few things
                        this._completeApplication();
                        deferred.resolve(this.config);
                    }), deferred.reject);
                }), deferred.reject);
            }));
            // return promise
            return deferred.promise;
        },
        _completeApplication: function () {
            // ArcGIS.com allows you to set an application extent on the application item. Overwrite the
            // existing web map extent with the application item extent when set.
            if (this.config.appid &amp;&amp; this.config.application_extent &amp;&amp; this.config.application_extent.length &gt; 0 &amp;&amp; this.config.itemInfo &amp;&amp; this.config.itemInfo.item &amp;&amp; this.config.itemInfo.item.extent) {
                this.config.itemInfo.item.extent = [
                    [
                        parseFloat(this.config.application_extent[0][0]), parseFloat(this.config.application_extent[0][1])
                    ],
                    [
                        parseFloat(this.config.application_extent[1][0]), parseFloat(this.config.application_extent[1][1])
                    ]
                ];
            }
            // Set the geometry helper service to be the app default.
            if (this.config.helperServices &amp;&amp; this.config.helperServices.geometry &amp;&amp; this.config.helperServices.geometry.url) {
                esriConfig.defaults.geometryService = new GeometryService(this.config.helperServices.geometry.url);
            }
        },
        _mixinAll: function () {
            /*
            mix in all the settings we got!
            {} &lt;- i18n &lt;- organization &lt;- application &lt;- group info &lt;- group items &lt;- webmap &lt;- custom url params &lt;- standard url params.
            */
            lang.mixin(this.config, this.i18nConfig, this.orgConfig, this.appConfig, this.groupInfoConfig, this.groupItemConfig, this.itemConfig, this.customUrlConfig, this.urlConfig);
        },
        _createPortal: function () {
            var deferred = new Deferred();
            if (this.templateConfig.queryForGroupInfo || this.templateConfig.queryForGroupItems) {
                this.portal = new esriPortal.Portal(this.config.sharinghost);
                this.portal.on("load", function () {
                    deferred.resolve();
                });
            } else {
                deferred.resolve();
            }
            return deferred.promise;
        },
        _getUrlParamValues: function (items) {
            // retrieves only the items specified from the URL object.
            var urlObject = this.urlObject;
            var obj = {};
            if (urlObject &amp;&amp; urlObject.query &amp;&amp; items &amp;&amp; items.length) {
                for (var i = 0; i &lt; items.length; i++) {
                    var item = urlObject.query[items[i]];
                    if (item) {
                        if (typeof item === "string") {
                            switch (item.toLowerCase()) {
                                case "true":
                                    obj[items[i]] = true;
                                    break;
                                case "false":
                                    obj[items[i]] = false;
                                    break;
                                default:
                                    obj[items[i]] = item;
                            }
                        } else {
                            obj[items[i]] = item;
                        }
                    }
                }
            }
            return obj;
        },
        _createUrlParamsObject: function () {
            var urlObject,
                url;
            // retrieve url parameters. Templates all use url parameters to determine which arcgis.com
            // resource to work with.
            // Map templates use the webmap param to define the webmap to display
            // Group templates use the group param to provide the id of the group to display.
            // appid is the id of the application based on the template. We use this
            // id to retrieve application specific configuration information. The configuration
            // information will contain the values the  user selected on the template configuration
            // panel.
            url = document.location.href;
            urlObject = urlUtils.urlToObject(url);
            urlObject.query = urlObject.query || {};
            // remove any HTML tags from query item
            urlObject.query = esriLang.stripTags(urlObject.query);
            return urlObject;
        },
        _initializeApplication: function () {
            // If this app is hosted on an Esri environment.
            if (this.templateConfig.esriEnvironment) {
                var appLocation, instance;
                // Check to see if the app is hosted or a portal. If the app is hosted or a portal set the
                // sharing url and the proxy. Otherwise use the sharing url set it to arcgis.com.
                // We know app is hosted (or portal) if it has /apps/ or /home/ in the url.
                appLocation = location.pathname.indexOf("/apps/");
                if (appLocation === -1) {
                    appLocation = location.pathname.indexOf("/home/");
                }
                // app is hosted and no sharing url is defined so let's figure it out.
                if (appLocation !== -1) {
                    // hosted or portal
                    instance = location.pathname.substr(0, appLocation); //get the portal instance name
                    this.config.sharinghost = "https://" + location.host + instance;
                    this.config.proxyurl = "https://" + location.host + instance + "/sharing/proxy";
                }
            }
            arcgisUtils.arcgisUrl = this.config.sharinghost + "/sharing/rest/content/items";
            // Define the proxy url for the app
            if (this.config.proxyurl) {
                esriConfig.defaults.io.proxyUrl = this.config.proxyurl;
                esriConfig.defaults.io.alwaysUseProxy = false;
            }
        },
        _getAppUrl: function () {
            var location = window.location;
            var hostname = location.hostname;
            var newOrigin = "//www.arcgis.com";
            if (hostname.indexOf("devext.arcgis.com") !== -1) {
                newOrigin = "//devext.arcgis.com";
            } else if (hostname.indexOf("qaext.arcgis.com") !== -1) {
                newOrigin = "//qaext.arcgis.com";
            }
            var appurl = location.protocol + newOrigin + location.pathname;
            if (location &amp;&amp; location.search) {
                appurl = appurl + location.search;
            }
            return appurl;
        },
        _checkSignIn: function () {
            var deferred, signedIn, oAuthInfo;
            deferred = new Deferred();
            //If there's an oauth appid specified register it
            if (this.config.oauthappid) {
                oAuthInfo = new ArcGISOAuthInfo({
                    appId: this.config.oauthappid,
                    portalUrl: this.config.sharinghost,
                    popup: true
                });
                IdentityManager.registerOAuthInfos([oAuthInfo]);
            }
            // check app access or signed-in status
            if (this.config.oauthappid &amp;&amp; this.templateConfig.esriEnvironment) {
                signedIn = IdentityManager.checkAppAccess(this.config.sharinghost + "/sharing", this.config.oauthappid);
                signedIn.always(function (response) {
                    deferred.resolve(response);
                });
            } else {
                signedIn = IdentityManager.checkSignInStatus(this.config.sharinghost + "/sharing");
                // resolve regardless of signed in or not.
                signedIn.promise.always(function (response) {
                    deferred.resolve(response);
                });
            }
            return deferred.promise;
        },
        _queryLocalization: function () {
            var deferred, dirNode, classes, rtlClasses;
            deferred = new Deferred();
            if (this.templateConfig.queryForLocale) {
                require(["dojo/i18n!application/nls/resources"], lang.hitch(this, function (appBundle) {
                    var cfg = {};
                    // Get the localization strings for the template and store in an i18n variable. Also determine if the
                    // application is in a right-to-left language like Arabic or Hebrew.
                    cfg.i18n = appBundle || {};
                    // Bi-directional language support added to support right-to-left languages like Arabic and Hebrew
                    // Note: The map must stay ltr
                    cfg.i18n.direction = "ltr";
                    array.some(["ar", "he"], lang.hitch(this, function (l) {
                        if (kernel.locale.indexOf(l) !== -1) {
                            cfg.i18n.direction = "rtl";
                            return true;
                        }
                        return false;
                    }));
                    // add a dir attribute to the html tag. Then you can add special css classes for rtl languages
                    dirNode = document.getElementsByTagName("html")[0];
                    classes = dirNode.className + " ";
                    if (cfg.i18n.direction === "rtl") {
                        // need to add support for dj_rtl.
                        // if the dir node is set when the app loads dojo will handle.
                        dirNode.setAttribute("dir", "rtl");
                        rtlClasses = " esriRTL dj_rtl dijitRtl " + classes.replace(/ /g, "-rtl ");
                        dirNode.className = lang.trim(classes + rtlClasses);
                    } else {
                        dirNode.setAttribute("dir", "ltr");
                        domClass.add(dirNode, "esriLTR");
                    }
                    this.i18nConfig = cfg;
                    deferred.resolve(cfg);
                }));
            } else {
                deferred.resolve();
            }
            return deferred.promise;
        },
        queryGroupItems: function (options) {
            var deferred = new Deferred(),
                error, defaultParams, params;
            // If we want to get the group info
            if (this.templateConfig.queryForGroupItems) {
                if (this.config.group) {
                    // group params
                    defaultParams = {
                        q: "group:\"${groupid}\" AND -type:\"Code Attachment\"",
                        sortField: "modified",
                        sortOrder: "desc",
                        num: 9,
                        start: 0,
                        f: "json"
                    };
                    // mixin params
                    params = lang.mixin(defaultParams, this.templateConfig.groupParams, options);
                    // place group ID
                    if (params.q) {
                        params.q = string.substitute(params.q, {
                            groupid: this.config.group
                        });
                    }
                    // get items from the group
                    this.portal.queryItems(params).then(lang.hitch(this, function (response) {
                        var cfg = {};
                        cfg.groupItems = response;
                        this.groupItemConfig = cfg;
                        deferred.resolve(cfg);
                    }), function (error) {
                        deferred.reject(error);
                    });
                } else {
                    error = new Error("Group undefined.");
                    deferred.reject(error);
                }
            } else {
                // just resolve
                deferred.resolve();
            }
            return deferred.promise;
        },
        queryGroupInfo: function () {
            var deferred = new Deferred(),
                error, params;
            // If we want to get the group info
            if (this.templateConfig.queryForGroupInfo) {
                if (this.config.group) {
                    // group params
                    params = {
                        q: "id:\"" + this.config.group + "\"",
                        f: "json"
                    };
                    this.portal.queryGroups(params).then(lang.hitch(this, function (response) {
                        var cfg = {};
                        cfg.groupInfo = response;
                        this.groupInfoConfig = cfg;
                        deferred.resolve(cfg);
                    }), function (error) {
                        deferred.reject(error);
                    });
                } else {
                    error = new Error("Group undefined.");
                    deferred.reject(error);
                }
            } else {
                // just resolve
                deferred.resolve();
            }
            return deferred.promise;
        },
        queryItem: function () {
            var deferred, cfg = {};
            // Get details about the specified web map. If the web map is not shared publicly users will
            // be prompted to log-in by the Identity Manager.
            deferred = new Deferred();
            // If we want to get the webmap
            if (this.templateConfig.queryForWebmap) {
                // Use local webmap instead of portal webmap
                if (this.templateConfig.useLocalWebmap) {
                    // get webmap js file
                    require([this.templateConfig.localWebmapFile], lang.hitch(this, function (webmap) {
                        // return webmap json
                        cfg.itemInfo = webmap;
                        this.itemConfig = cfg;
                        deferred.resolve(cfg);
                    }));
                }
                // no webmap is set and we have organization's info
                else if (!this.config.webmap &amp;&amp; this.config.orgInfo) {
                    var defaultWebmap = {
                        "item": {
                            "title": "Default Webmap",
                            "type": "Web Map",
                            "description": "A webmap with the default basemap and extent.",
                            "snippet": "A webmap with the default basemap and extent.",
                            "extent": this.config.orgInfo.defaultExtent
                        },
                        "itemData": {
                            "operationalLayers": [],
                            "baseMap": this.config.orgInfo.defaultBasemap
                        }
                    };
                    cfg.itemInfo = defaultWebmap;
                    this.itemConfig = cfg;
                    deferred.resolve(cfg);
                }
                // use webmap from id
                else {
                    arcgisUtils.getItem(this.config.webmap).then(lang.hitch(this, function (itemInfo) {
                        // Set the itemInfo config option. This can be used when calling createMap instead of the webmap id
                        cfg.itemInfo = itemInfo;
                        this.itemConfig = cfg;
                        deferred.resolve(cfg);
                    }), function (error) {
                        if (!error) {
                            error = new Error("Error retrieving display item.");
                        }
                        deferred.reject(error);
                    });
                }
            } else {
                // we're done. we dont need to get the webmap
                deferred.resolve();
            }
            return deferred.promise;
        },
        queryApplication: function () {
            // Get the application configuration details using the application id. When the response contains
            // itemData.values then we know the app contains configuration information. We'll use these values
            // to overwrite the application defaults.
            var deferred = new Deferred();
            if (this.config.appid) {
                arcgisUtils.getItem(this.config.appid).then(lang.hitch(this, function (response) {
                    var cfg = {};
                    if (response.item &amp;&amp; response.itemData &amp;&amp; response.itemData.values) {
                        // get app config values - we'll merge them with config later.
                        cfg = response.itemData.values;
                        // save response
                        cfg.appResponse = response;
                    }
                    // get the extent for the application item. This can be used to override the default web map extent
                    if (response.item &amp;&amp; response.item.extent) {
                        cfg.application_extent = response.item.extent;
                    }
                    // get any app proxies defined on the application item
                    if (response.item &amp;&amp; response.item.appProxies) {
                        var layerMixins = array.map(response.item.appProxies, function (p) {
                            return {
                                "url": p.sourceUrl,
                                "mixin": {
                                    "url": p.proxyUrl
                                }
                            };
                        });
                        cfg.layerMixins = layerMixins;
                    }
                    this.appConfig = cfg;
                    deferred.resolve(cfg);
                }), function (error) {
                    if (!error) {
                        error = new Error("Error retrieving application configuration.");
                    }
                    deferred.reject(error);
                });
            } else {
                deferred.resolve();
            }
            return deferred.promise;
        },
        queryOrganization: function () {
            var deferred = new Deferred();
            if (this.templateConfig.queryForOrg) {
                // Query the ArcGIS.com organization. This is defined by the sharinghost that is specified. For example if you
                // are a member of an org you'll want to set the sharinghost to be http://&lt;your org name&gt;.arcgis.com. We query
                // the organization by making a self request to the org url which returns details specific to that organization.
                // Examples of the type of information returned are custom roles, units settings, helper services and more.
                // If this fails, the application will continue to function
                esriRequest({
                    url: this.config.sharinghost + "/sharing/rest/portals/self",
                    content: {
                        "f": "json"
                    },
                    callbackParamName: "callback"
                }).then(lang.hitch(this, function (response) {
                    if (this.templateConfig.webTierSecurity) {
                        var trustedHost;
                        if (response.authorizedCrossOriginDomains &amp;&amp; response.authorizedCrossOriginDomains.length &gt; 0) {
                            for (var i = 0; i &lt; response.authorizedCrossOriginDomains.length; i++) {
                                trustedHost = response.authorizedCrossOriginDomains[i];
                                // add if trusted host is not null, undefined, or empty string
                                if (esriLang.isDefined(trustedHost) &amp;&amp; trustedHost.length &gt; 0) {
                                    esriConfig.defaults.io.corsEnabledServers.push({
                                        host: trustedHost,
                                        withCredentials: true
                                    });
                                }
                            }
                        }
                    }
                    var cfg = {};
                    // save organization information
                    cfg.orgInfo = response;
                    // get units defined by the org or the org user
                    cfg.units = "metric";
                    if (response.user &amp;&amp; response.user.units) { //user defined units
                        cfg.units = response.user.units;
                    } else if (response.units) { //org level units
                        cfg.units = response.units;
                    } else if ((response.user &amp;&amp; response.user.region &amp;&amp; response.user.region === "US") || (response.user &amp;&amp; !response.user.region &amp;&amp; response.region === "US") || (response.user &amp;&amp; !response.user.region &amp;&amp; !response.region) || (!response.user &amp;&amp; response.ipCntryCode === "US") || (!response.user &amp;&amp; !response.ipCntryCode &amp;&amp; kernel.locale === "en-us")) {
                        // use feet/miles only for the US and if nothing is set for a user
                        cfg.units = "english";
                    }
                    // If it has the useVectorBasemaps property and its true then use the
                    // vectorBasemapGalleryGroupQuery otherwise use the default
                    var basemapGalleryGroupQuery = response.basemapGalleryGroupQuery;
                    if (response.hasOwnProperty("useVectorBasemaps") &amp;&amp; response.useVectorBasemaps === true &amp;&amp; response.vectorBasemapGalleryGroupQuery) {
                        basemapGalleryGroupQuery = response.vectorBasemapGalleryGroupQuery;
                    }

                    var q = this._parseQuery(basemapGalleryGroupQuery);
                    cfg.basemapgroup = {
                        id: null,
                        title: null,
                        owner: null
                    };
                    if (q.id) {
                        cfg.basemapgroup.id = q.id;
                    } else if (q.title &amp;&amp; q.owner) {
                        cfg.basemapgroup.title = q.title;
                        cfg.basemapgroup.owner = q.owner;
                    }
                    // Get the helper services (routing, print, locator etc)
                    cfg.helperServices = response.helperServices;
                    // are any custom roles defined in the organization?
                    if (response.user &amp;&amp; esriLang.isDefined(response.user.roleId)) {
                        if (response.user.privileges) {
                            cfg.userPrivileges = response.user.privileges;
                        }
                    }
                    this.orgConfig = cfg;
                    deferred.resolve(cfg);
                }), function (error) {
                    if (!error) {
                        error = new Error("Error retrieving organization information.");
                    }
                    deferred.reject(error);
                });
            } else {
                deferred.resolve();
            }
            return deferred.promise;
        },
        _parseQuery: function (queryString) {

            var regex = /(AND|OR)?\W*([a-z]+):/ig,
                fields = {},
                fieldName,
                fieldIndex,
                result = regex.exec(queryString);
            while (result) {
                fieldName = result &amp;&amp; result[2];
                fieldIndex = result ? (result.index + result[0].length) : -1;

                result = regex.exec(queryString);

                fields[fieldName] = queryString.substring(fieldIndex, result ? result.index : queryString.length).replace(/^\s+|\s+$/g, "").replace(/\"/g, ""); //remove extra quotes in title
            }
            return fields;
        },
        querySharedTheme: function () {
            var deferred = new Deferred();
            if (this.config &amp;&amp; this.config.sharedTheme) {
                esriConfig.defaults.io.corsEnabledServers.push("opendata.arcgis.com");
                var sharedThemeStatus = this._getSharedThemeStatus(this.config.sharedTheme);
                this._getSharedThemeObject(sharedThemeStatus).then(function (response) {
                    deferred.resolve(response);
                }, function () {
                    var error = new Error("Unable to get theme");
                    deferred.reject(error);
                });

            } else if (this.config &amp;&amp; this.config.sharedThemeItem) {
                arcgisUtils.getItem(this.config.sharedThemeItem).then(lang.hitch(this, function (response) {
                    if (response &amp;&amp; response.itemData &amp;&amp; response.itemData.data) {
                        this.config.sharedThemeConfig = response.itemData.data;
                    }
                    deferred.resolve();
                }), function (error) {
                    deferred.reject(error);
                });


            } else {
                deferred.resolve();
            }
            return deferred.promise;
        },
        _getSharedThemeStatus: function (input) {
            // we have a theme url param get  theming
            var result = {};
            if (/\d+/.test(input)) { // numeric theme value
                result.status = "siteId";
                result.output = input;
            } else if (input === "current") {
                result.status = "domain";
                result.output = window.location.href;
            } // leaving out appid for now
            return result;
        },
        _getSharedThemeObject: function (sharedThemeStatus) {
            var deferred = new Deferred();
            var requestUrl = this._generateRequestUrl(sharedThemeStatus);
            // if the status is site id or domain lookup make an external API call to opendatadev.arcgis.com
            if (sharedThemeStatus.status === "siteId" || sharedThemeStatus.status === "domain") {
                var themeRequest = esriRequest({
                    url: requestUrl,
                    handleAs: "json"
                });
                themeRequest.then(lang.hitch(this, function (response) {
                    // return for a domain call is an array so adjust the call slightly
                    if (sharedThemeStatus.status === "domain" &amp;&amp; response &amp;&amp; response.data &amp;&amp; response.data.length &amp;&amp; response.data.length &gt; 0) {
                        this.config.sharedThemeConfig = response.data[0];
                    } else if (response &amp;&amp; response.data) {
                        this.config.sharedThemeConfig = response.data;
                    }
                    deferred.resolve();
                }), function (error) {
                    deferred.reject(error);
                });
            } else {
                deferred.resolve();
            }
            return deferred.promise;
        },
        _detectIESupport: function () {
            var isIE = false;
            if (navigator &amp;&amp; navigator.userAgent) {
                var match = /\b(MSIE |Trident.*?rv:|Edge\/)(\d+)/.exec(navigator.userAgent);
                if (match &amp;&amp; match.length &amp;&amp; match.length === 3) {
                    var version = parseInt(match[2]);
                    if (version &lt;= 19) {
                        isIE = true;
                    }
                }
            }
            return isIE;
        },
        _generateRequestUrl: function (status) {
            var requestUrl;
            switch (status.status) {
                // "https://opendata.arcgis.com/api/v2/sites/" + status.output;
                case "siteId":
                    requestUrl = "https://opendata.arcgis.com/api/v2/sites/" + status.output;
                    break;
                case "domain":
                    //"https://opendatadev.arcgis.com/api/v2/sites?filter%5Burl%5D=" + status.output;
                    requestUrl = status.output;
                    requestUrl = "https://opendata.arcgis.com/api/v2/sites?filter%5Burl%5D=" + status.output;
                    break;
                case "appId":
                    break;
                default:
            }
            return requestUrl;
        }

    });
});
</pre></body></html>