{"code":"import * as tslib_1 from \"tslib\";\r\nimport sortBy from 'lodash-es/sortBy';\r\nimport omit from 'lodash-es/omit';\r\nimport throttle from 'lodash-es/throttle';\r\nimport includes from 'lodash-es/includes';\r\nimport queryString from 'query-string';\r\nimport parser from 'ua-parser-js';\r\n// import { ContentModelType } from '../../app/models/content.model';\r\nimport { Observable } from 'rxjs/Observable';\r\nimport { BehaviorSubject } from 'rxjs/BehaviorSubject';\r\nimport stringify from 'json-stable-stringify';\r\n// import { humanCase } from '../../app/functions/human-case.function';\r\nimport Cookies from 'js-cookie';\r\nimport url from 'url';\r\nimport 'whatwg-fetch';\r\nimport { EventCapturer } from './classes/event-capturer.class';\r\n// Annoying workaround for module loading\r\nvar stableStringify = stringify.default || stringify;\r\nvar anyParser = parser;\r\nexport var isBrowser = typeof window !== 'undefined';\r\nexport var isIframe = isBrowser && window.top !== window.self;\r\nvar fetch = (isBrowser && window.fetch) || require('node-fetch').default;\r\n// Workaround for oddly random module loading issues\r\nvar UaParser = typeof anyParser.default === 'function' ? anyParser.default : anyParser;\r\nvar immediate = setTimeout; // TODO: test this: typeof setImmediate === 'function' ? setImmediate : setTimeout;\r\nexport function BuilderComponent(info) {\r\n    if (info === void 0) { info = {}; }\r\n    return function (component) {\r\n        var spec = tslib_1.__assign({}, info, { class: component });\r\n        if (!spec.name) {\r\n            spec.name = component.name;\r\n        }\r\n        if (!Builder.components.find(function (item) { return item.name === spec.name; })) {\r\n            Builder.components.push(spec);\r\n            // TODO: serialize component name and inputs\r\n            if (isBrowser) {\r\n                window.top.postMessage({\r\n                    type: 'builder.registerComponent',\r\n                    data: omit(spec, 'class'),\r\n                }, '*');\r\n            }\r\n        }\r\n    };\r\n}\r\nvar Builder = /** @class */ (function () {\r\n    function Builder(apiKey) {\r\n        if (apiKey === void 0) { apiKey = null; }\r\n        var _this = this;\r\n        this.apiKey = apiKey;\r\n        this.eventsQueue = [];\r\n        this.throttledClearEventsQueue = throttle(function () {\r\n            _this.processEventsQueue();\r\n        }, 100);\r\n        this.isUsed = false;\r\n        this.editingMode$ = new BehaviorSubject(isIframe);\r\n        // TODO: decorator to do this stuff with the get/set (how do with typing too? compiler?)\r\n        this.editingModel$ = new BehaviorSubject(null);\r\n        this.userAgent = (typeof navigator === 'object' && navigator.userAgent) || '';\r\n        this.blockContentLoading = '';\r\n        this.observersByModelType = {};\r\n        this.getContentQueue = null;\r\n        this.priorContentQueue = null;\r\n        // TODO: how prune deprecated tests\r\n        this.testCookiePrefix = 'builder.tests';\r\n        // in the browser ensure this is a singleton\r\n        // FIXME: why are there attempts to load this twice?\r\n        if (isBrowser) {\r\n            // TODO: ensure certain events only bound one time as static property\r\n        }\r\n        if (isBrowser) {\r\n            this.bindMessageListeners();\r\n        }\r\n        if (isIframe) {\r\n            this.loadFullStory();\r\n        }\r\n    }\r\n    Builder.loadIncrementalDom = function () {\r\n        if (!this.isBrowser || this.incrementalDomLoaded) {\r\n            return;\r\n        }\r\n        console.info('Loading incremental DOM...');\r\n        var url = 'https://ajax.googleapis.com/ajax/libs/incrementaldom/0.5.1/incremental-dom-min.js';\r\n        var script = document.createElement('script');\r\n        script.src = url;\r\n        document.head.appendChild(script);\r\n        this.incrementalDomLoaded = true;\r\n    };\r\n    Builder.patchDom = function (selector, vtree) {\r\n        var _this = this;\r\n        if (!this.isBrowser) {\r\n            return;\r\n        }\r\n        var element = document.querySelector(selector);\r\n        if (!element) {\r\n            return;\r\n        }\r\n        if (!IncrementalDOM) {\r\n            console.warn('IncrementalDOM not loaded!');\r\n            return;\r\n        }\r\n        IncrementalDOM.patch(element, function () {\r\n            _this.vTreeToIncrementalDom(vtree);\r\n        });\r\n    };\r\n    Builder.patchHtml = function (selector, html) {\r\n        if (!this.isBrowser) {\r\n            return;\r\n        }\r\n        var element = document.querySelector(selector);\r\n        if (!element) {\r\n            return;\r\n        }\r\n        element.innerHTML = html;\r\n    };\r\n    Builder.vTreeToIncrementalDom = function (tree) {\r\n        var _this = this;\r\n        if (tree.type === 'VirtualNode') {\r\n            var node = tree;\r\n            // TODO: handle other properties/attributes\r\n            var properties = [];\r\n            for (var key in node.properties) {\r\n                var value = node.properties[key];\r\n                if (key === 'attributes') {\r\n                    for (var attrKey in value) {\r\n                        properties.push(attrKey);\r\n                        properties.push(value[attrKey]);\r\n                    }\r\n                }\r\n                else {\r\n                    properties.push(key);\r\n                    properties.push(value);\r\n                }\r\n            }\r\n            IncrementalDOM.elementOpen.apply(IncrementalDOM, [node.tagName, undefined, undefined].concat(properties));\r\n            node.children.forEach(function (node) { return _this.vTreeToIncrementalDom(tree); });\r\n            IncrementalDOM.elementClose(node.tagName);\r\n        }\r\n        else {\r\n            IncrementalDOM.text(tree.text);\r\n        }\r\n    };\r\n    Object.defineProperty(Builder, \"editingPage\", {\r\n        get: function () {\r\n            return this._editingPage;\r\n        },\r\n        set: function (editingPage) {\r\n            this._editingPage = editingPage;\r\n            if (isBrowser && isIframe) {\r\n                if (editingPage) {\r\n                    // this.loadIncrementalDom();\r\n                    document.body.classList.add('builder-editing-page');\r\n                }\r\n                else {\r\n                    document.body.classList.remove('builder-editing-page');\r\n                }\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true\r\n    });\r\n    // TODO: style guide, etc off this system as well?\r\n    Builder.component = function (info) {\r\n        var _this = this;\r\n        if (info === void 0) { info = {}; }\r\n        return function (component) {\r\n            var spec = tslib_1.__assign({}, info, { class: component });\r\n            if (!spec.name) {\r\n                spec.name = component.name;\r\n            }\r\n            if (!_this.components.find(function (item) { return item.name === spec.name; })) {\r\n                _this.components.push(spec);\r\n                // TODO: serialize component name and inputs\r\n                if (isBrowser) {\r\n                    window.top.postMessage({\r\n                        type: 'builder.registerComponent',\r\n                        data: omit(spec, 'class'),\r\n                    }, '*');\r\n                }\r\n            }\r\n        };\r\n    };\r\n    Object.defineProperty(Builder, \"Component\", {\r\n        get: function () {\r\n            return this.component;\r\n        },\r\n        enumerable: true,\r\n        configurable: true\r\n    });\r\n    Builder.prototype.processEventsQueue = function () {\r\n        if (!this.eventsQueue.length) {\r\n            return;\r\n        }\r\n        var events = this.eventsQueue;\r\n        this.eventsQueue = [];\r\n        // TODO: centralize this\r\n        var host = this.getLocation().host === 'localhost:4205' ? 'http://localhost:5000' : 'https://builder.io';\r\n        fetch(host + \"/api/v1/track\", {\r\n            method: 'POST',\r\n            body: JSON.stringify({ events: events }),\r\n            headers: {\r\n                'content-type': 'application/json',\r\n            },\r\n            mode: 'cors',\r\n        });\r\n    };\r\n    Object.defineProperty(Builder.prototype, \"editingMode\", {\r\n        get: function () {\r\n            return this.editingMode$.value;\r\n        },\r\n        set: function (value) {\r\n            if (value !== this.editingMode) {\r\n                this.editingMode$.next(value);\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true\r\n    });\r\n    Object.defineProperty(Builder.prototype, \"editingModel\", {\r\n        get: function () {\r\n            return this.editingModel$.value;\r\n        },\r\n        set: function (value) {\r\n            if (value !== this.editingModel) {\r\n                this.editingModel$.next(value);\r\n            }\r\n        },\r\n        enumerable: true,\r\n        configurable: true\r\n    });\r\n    Builder.prototype.setUserAgent = function (userAgent) {\r\n        this.userAgent = userAgent;\r\n    };\r\n    Builder.prototype.track = function (eventName, properties) {\r\n        if (properties === void 0) { properties = {}; }\r\n        if (isIframe || !isBrowser) {\r\n            return;\r\n        }\r\n        // batch events\r\n        this.eventsQueue.push({\r\n            type: 'impression',\r\n            data: tslib_1.__assign({}, properties),\r\n        });\r\n        this.throttledClearEventsQueue();\r\n    };\r\n    Builder.prototype.trackImpression = function (contentId, variationId) {\r\n        if (isIframe || !isBrowser) {\r\n            return;\r\n        }\r\n        // TODO: use this.track method\r\n        this.eventsQueue.push({\r\n            type: 'impression',\r\n            data: {\r\n                contentId: contentId,\r\n                variationId: variationId !== contentId ? variationId : undefined,\r\n                ownerId: this.apiKey,\r\n            },\r\n        });\r\n        this.throttledClearEventsQueue();\r\n    };\r\n    Builder.prototype.trackInteraction = function (contentId, variationId) {\r\n        if (isIframe || !isBrowser) {\r\n            return;\r\n        }\r\n        // TODO: use this.track method\r\n        this.eventsQueue.push({\r\n            type: 'click',\r\n            data: {\r\n                contentId: contentId,\r\n                variationId: variationId !== contentId ? variationId : undefined,\r\n                ownerId: this.apiKey,\r\n            },\r\n        });\r\n        this.throttledClearEventsQueue();\r\n    };\r\n    Builder.prototype.component = function (info) {\r\n        if (info === void 0) { info = {}; }\r\n        return Builder.component(info);\r\n    };\r\n    Builder.prototype.bindMessageListeners = function () {\r\n        var _this = this;\r\n        // TODO: handle race condition of content already loading\r\n        // TODO: move to another file\r\n        if (isBrowser) {\r\n            addEventListener('message', function (event) {\r\n                if (!_this.isUsed) {\r\n                    return;\r\n                }\r\n                var url = new URL(event.origin);\r\n                var allowedHosts = ['builder.io', 'localhost'];\r\n                if (!includes(allowedHosts, url.hostname)) {\r\n                    return;\r\n                }\r\n                var data = event.data;\r\n                if (data) {\r\n                    switch (data.type) {\r\n                        case 'builder.patchDom': {\r\n                            Builder.patchDom(data.data.selector, data.data.tree);\r\n                            break;\r\n                        }\r\n                        case 'builder.patchHtml': {\r\n                            Builder.patchHtml(data.data.selector, data.data.html);\r\n                            break;\r\n                        }\r\n                        case 'builder.contentUpdate':\r\n                            var model = data.data.modelName;\r\n                            var contentData = data.data.data; // hmmm...\r\n                            var observer = _this.observersByModelType[model];\r\n                            if (observer) {\r\n                                observer.next([contentData]);\r\n                            }\r\n                            break;\r\n                        case 'builder.getComponents':\r\n                            // TODO: serialize component name and inputs\r\n                            window.top.postMessage({\r\n                                type: 'builder.components',\r\n                                data: Builder.components.map(function (item) { return omit(item, 'class'); }),\r\n                            }, '*');\r\n                            break;\r\n                        case 'builder.editingModel':\r\n                            _this.editingModel = data.data.model;\r\n                            break;\r\n                        case 'builder.registerComponent':\r\n                            var componentData = data.data;\r\n                            Builder.components.push(componentData);\r\n                            break;\r\n                        case 'builder.blockContentLoading':\r\n                            if (typeof data.data.model === 'string') {\r\n                                _this.blockContentLoading = data.data.model;\r\n                            }\r\n                            break;\r\n                        case 'builder.editingMode':\r\n                            var editingMode = data.data;\r\n                            if (editingMode) {\r\n                                _this.editingMode = true;\r\n                                document.body.classList.add('builder-editing');\r\n                            }\r\n                            else {\r\n                                _this.editingMode = false;\r\n                                document.body.classList.remove('builder-editing');\r\n                            }\r\n                            break;\r\n                        case 'builder.editingPageMode':\r\n                            var editingPageMode = data.data;\r\n                            Builder.editingPage = editingPageMode;\r\n                            break;\r\n                        case 'builder.overrideUserAttributes':\r\n                            var userAttributes = data.data;\r\n                            Object.assign(Builder.overrideUserAttributes, data.data);\r\n                            _this.flushGetContentQueue(true);\r\n                            // TODO: refetch too\r\n                            break;\r\n                        case 'builder.overrideTestGroup':\r\n                            var _a = data.data, variationId = _a.variationId, contentId = _a.contentId;\r\n                            if (variationId && contentId) {\r\n                                _this.setTestCookie(contentId, variationId);\r\n                                _this.flushGetContentQueue(true);\r\n                            }\r\n                        case 'builder.evaluate': {\r\n                            var text = data.data.text;\r\n                            var args = data.data.arguments || [];\r\n                            var id = data.data.id;\r\n                            // tslint:disable-next-line:no-function-constructor-with-string-args\r\n                            var fn = new Function(text);\r\n                            var result = fn.apply(_this, args);\r\n                            window.top.postMessage({\r\n                                type: 'builder.evaluateResult',\r\n                                data: {\r\n                                    result: result,\r\n                                    id: id,\r\n                                    text: text,\r\n                                },\r\n                            }, '*');\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n        }\r\n    };\r\n    Builder.prototype.init = function (apiKey) {\r\n        this.apiKey = apiKey;\r\n        return this;\r\n    };\r\n    Builder.prototype.getLocation = function () {\r\n        return (typeof location === 'object' && url.parse(location.href)) || {};\r\n    };\r\n    Builder.prototype.getUserAttributes = function (userAgent) {\r\n        if (userAgent === void 0) { userAgent = this.userAgent; }\r\n        this.isUsed = true;\r\n        if (!userAgent) {\r\n            console.warn('No user agent set! For help on how to set this please contact steve@builder.io');\r\n        }\r\n        var ua = new UaParser(userAgent);\r\n        // FIXME\r\n        var url = this.getLocation();\r\n        var device = ua.getDevice();\r\n        // TODO: get these from exension as well\r\n        return tslib_1.__assign({ queryString: url.search, urlPath: url.pathname, \r\n            // Removinf for now because of cache keys\r\n            // referrer: document.referrer,\r\n            // language: navigator.language.split('-')[0],\r\n            device: device.type || 'desktop', operatingSystem: (ua.getOS().name || '').toLowerCase() || undefined, browser: (ua.getBrowser().name || '').toLowerCase() || undefined }, Builder.overrideUserAttributes);\r\n    };\r\n    Builder.prototype.setUserAttributes = function (options) {\r\n        Object.assign(Builder.overrideUserAttributes, options);\r\n    };\r\n    Builder.prototype.loadFullStory = function () {\r\n        // TODO: check that the iframe's parent is buidler.io\r\n        if (!Builder.isIframe) {\r\n            return;\r\n        }\r\n        // If fullstory already loaded return\r\n        if (window['_fs_org']) {\r\n            return;\r\n        }\r\n        var script = document.createElement('script');\r\n        script.innerHTML = \"\\n      window['_fs_run_in_iframe'] = true\\n      window['_fs_debug'] = false;\\n      window['_fs_host'] = 'fullstory.com';\\n      window['_fs_org'] = 'B9193';\\n      window['_fs_namespace'] = 'FS';\\n      (function(m,n,e,t,l,o,g,y){\\n          if (e in m) {if(m.console && m.console.log) { m.console.log('FullStory namespace conflict. Please set window[\\\"_fs_namespace\\\"].');} return;}\\n          g=m[e]=function(a,b){g.q?g.q.push([a,b]):g._api(a,b);};g.q=[];\\n          o=n.createElement(t);o.async=1;o.src='https://'+_fs_host+'/s/fs.js';\\n          y=n.getElementsByTagName(t)[0];y.parentNode.insertBefore(o,y);\\n          g.identify=function(i,v){g(l,{uid:i});if(v)g(l,v)};g.setUserVars=function(v){g(l,v)};\\n          y=\\\"rec\\\";g.shutdown=function(i,v){g(y,!1)};g.restart=function(i,v){g(y,!0)};\\n          y=\\\"consent\\\";g[y]=function(a){g(y,!arguments.length||a)};\\n          g.identifyAccount=function(i,v){o='account';v=v||{};v.acctId=i;g(o,v)};\\n          g.clearUserCookie=function(){};\\n      })(window,document,window['_fs_namespace'],'script','user');\\n    \";\r\n        document.head.appendChild(script);\r\n    };\r\n    // TODO: also take priority or group name/number so can\r\n    // group fast stuff to show right away and slow or lower priority after'\r\n    // how does graphql defer work?\r\n    // TODO: add defaultContent to regular getContent method\r\n    Builder.prototype.queueGetContent = function (modelName, options) {\r\n        var _this = this;\r\n        if (options === void 0) { options = {}; }\r\n        var initialContent = options.initialContent;\r\n        if (!initialContent) {\r\n            if (!this.getContentQueue) {\r\n                this.getContentQueue = [];\r\n                immediate(function () {\r\n                    _this.flushGetContentQueue();\r\n                });\r\n            }\r\n            this.getContentQueue.push(modelName);\r\n        }\r\n        return new Observable(function (observer) {\r\n            _this.observersByModelType[modelName] = observer;\r\n            if (initialContent) {\r\n                immediate(function () {\r\n                    observer.next(initialContent);\r\n                });\r\n            }\r\n        });\r\n    };\r\n    Builder.prototype.requestUrl = function (url) {\r\n        return fetch(url).then(function (res) { return res.json(); });\r\n    };\r\n    Builder.prototype.flushGetContentQueue = function (usePastQueue) {\r\n        var _this = this;\r\n        if (usePastQueue === void 0) { usePastQueue = false; }\r\n        if (!this.apiKey) {\r\n            throw new Error('Builder needs to be initialized with an API key!');\r\n        }\r\n        if (!usePastQueue && !this.getContentQueue) {\r\n            return;\r\n        }\r\n        var queryParams = {};\r\n        var pageQueryParams = typeof location !== 'undefined' ? queryString.parse(location.search) : undefined || {};\r\n        // TODO: merge in the attribute from query string ones\r\n        queryParams.userAttributes = stableStringify(this.getUserAttributes());\r\n        var queue = (usePastQueue ? this.priorContentQueue : this.getContentQueue) || [];\r\n        if (!usePastQueue) {\r\n            this.priorContentQueue = queue;\r\n            this.getContentQueue = null;\r\n        }\r\n        // TODO: cachebust if bd.noCache in request, also perhaps if in iframe\r\n        // if (options.cachebust) {\r\n        //   queryParams.t = Date.now().toString();\r\n        // }\r\n        var cachebust = isIframe || pageQueryParams.cachebust;\r\n        if (cachebust) {\r\n            queryParams.cachebuster = Date.now().toString();\r\n        }\r\n        var hasParams = Object.keys(queryParams).length > 0;\r\n        var host = this.getLocation().host === 'localhost:4205' ? 'http://localhost:5000' : 'https://builder.io';\r\n        var modelNames = queue.join(',');\r\n        // FIXME: have a \"core\" SDK that doesn't implement http,\r\n        // so SDKs like angular can use it's own http method\r\n        var promise = this.requestUrl(host + \"/api/v1/content/\" + this.apiKey + \"/\" + modelNames +\r\n            (queryParams && hasParams ? \"?\" + queryString.stringify(queryParams) : ''))\r\n            .then(function (result) {\r\n            for (var _i = 0, queue_1 = queue; _i < queue_1.length; _i++) {\r\n                var modelName = queue_1[_i];\r\n                if (modelName === _this.blockContentLoading) {\r\n                    continue;\r\n                }\r\n                var observer = _this.observersByModelType[modelName];\r\n                if (!observer) {\r\n                    return;\r\n                }\r\n                var data = result[modelName];\r\n                var sorted = sortBy(data, function (item) { return item.priority; });\r\n                var testModifiedResults = _this.processResultsForTests(sorted);\r\n                observer.next(testModifiedResults);\r\n                // observer.next(sorted);\r\n            }\r\n        })\r\n            .catch(function (err) {\r\n            for (var _i = 0, queue_2 = queue; _i < queue_2.length; _i++) {\r\n                var modelName = queue_2[_i];\r\n                var observer = _this.observersByModelType[modelName];\r\n                if (!observer) {\r\n                    return;\r\n                }\r\n                observer.error(err);\r\n            }\r\n        });\r\n    };\r\n    Builder.prototype.processResultsForTests = function (results) {\r\n        var _this = this;\r\n        var mappedResults = results.map(function (item) {\r\n            if (!item.variations) {\r\n                return item;\r\n            }\r\n            var cookieValue = _this.getTestCookie(item.id);\r\n            var cookieVariation = cookieValue === item.id ? item : item.variations[cookieValue];\r\n            if (cookieVariation) {\r\n                return tslib_1.__assign({}, item, { data: cookieVariation.data, variationId: cookieValue });\r\n            }\r\n            if (item.variations) {\r\n                var n = 0;\r\n                var random = Math.random();\r\n                for (var id in item.variations) {\r\n                    var variation = item.variations[id];\r\n                    var testRatio = variation.testRatio;\r\n                    n += testRatio;\r\n                    if (random < n) {\r\n                        _this.setTestCookie(item.id, variation.id);\r\n                        return tslib_1.__assign({}, item, { data: variation.data, variationId: variation.id });\r\n                    }\r\n                }\r\n            }\r\n            _this.setTestCookie(item.id, item.id);\r\n            return item;\r\n        });\r\n        if (isIframe) {\r\n            window.top.postMessage({ type: 'builder.contentResults', data: { results: mappedResults } }, '*');\r\n        }\r\n        return mappedResults;\r\n    };\r\n    Builder.prototype.getTestCookie = function (contentId) {\r\n        return this.getCookie(this.testCookiePrefix + \".\" + contentId);\r\n    };\r\n    Builder.prototype.setTestCookie = function (contentId, variationId) {\r\n        return this.setCookie(this.testCookiePrefix + \".\" + contentId, variationId, {\r\n            expires: 30,\r\n        });\r\n    };\r\n    Builder.prototype.getCookie = function (name) {\r\n        return Cookies.get(name);\r\n    };\r\n    Builder.prototype.setCookie = function (name, value, options) {\r\n        return Cookies.set(name, value, options);\r\n    };\r\n    // TODO:˝ param overrides\r\n    // TODO: gather user attributes\r\n    // Forward query to a server call so params like no cache or overrides can be extraced and applied\r\n    Builder.prototype.getContent = function (modelName, options) {\r\n        var _this = this;\r\n        if (options === void 0) { options = {}; }\r\n        if (!this.apiKey) {\r\n            throw new Error('Builder needs to be initialized with an API key!');\r\n        }\r\n        var queryParams = (typeof options.queryString === 'string'\r\n            ? queryString.parse(options.queryString)\r\n            : typeof location !== 'undefined' ? queryString.parse(location.search) : undefined) || {};\r\n        // TODO: merge in the attribute from query string ones\r\n        queryParams.userAttributes = stableStringify(this.getUserAttributes());\r\n        // TODO: cachebust if bd.noCache in request, also perhaps if in iframe\r\n        if (options.cachebust || isIframe) {\r\n            queryParams.cachebuster = Date.now().toString();\r\n        }\r\n        var hasParams = Object.keys(queryParams).length > 0;\r\n        // TODO: check for query params or global variable for overriding content (e.g. what to use for preview)\r\n        // TODO: query params and sorting\r\n        // TODO: with extension set up live connection to this query and send updates\r\n        // TODO: return observable with subscribe function that returns unsubscriber?\r\n        // TODO: (shorter than uuid) org namespace\r\n        // /api/v1/everlane-1/homepage-2\r\n        // \"space\" names? everlane-qa everlane-prod etc\r\n        // TODO: if in preview (maybe any iframe?) always no cache\r\n        // HACK: have a global option for setting dev\r\n        var host = options.dev || this.getLocation().host === 'localhost:4205'\r\n            ? 'http://localhost:5000'\r\n            : 'https://builder.io';\r\n        return new Observable(function (observer) {\r\n            // TODO: will there by use cases of multiple separate requests for same model type?\r\n            _this.observersByModelType[modelName] = observer;\r\n            // FIXME: have a \"core\" SDK that doesn't implement http,\r\n            // so SDKs like angular can use it's own http method\r\n            var promise = _this.requestUrl(host + \"/api/v1/content/\" + _this.apiKey + \"/\" + modelName +\r\n                (queryParams && hasParams ? \"?\" + queryString.stringify(queryParams) : ''))\r\n                .then(function (data) { return data[modelName]; })\r\n                .then(function (list) { return sortBy(list, function (item) { return item.priority; }); })\r\n                .then(function (result) {\r\n                if (modelName === _this.blockContentLoading) {\r\n                    return;\r\n                }\r\n                var testModifiedResults = _this.processResultsForTests(result);\r\n                observer.next(testModifiedResults);\r\n            })\r\n                .catch(function (err) {\r\n                observer.error(err);\r\n            });\r\n        });\r\n    };\r\n    Builder.eventCapturer = isIframe ? new EventCapturer().listen() : null;\r\n    Builder.components = [];\r\n    Builder.incrementalDomLoaded = false;\r\n    Builder._editingPage = false;\r\n    Builder.isIframe = isIframe;\r\n    Builder.isBrowser = isBrowser;\r\n    Builder.overrideUserAttributes = {};\r\n    return Builder;\r\n}());\r\nexport { Builder };\r\n","dts":{"name":"/Users/steve/Projects/bridge/builder/clients/js/dist/clients/js/src/builder.class.d.ts","text":"/// <reference types=\"virtual-dom\" />\r\n/// <reference types=\"node\" />\r\n/// <reference types=\"js-cookie\" />\r\nimport { Observable } from 'rxjs/Observable';\r\nimport { BehaviorSubject } from 'rxjs/BehaviorSubject';\r\nimport { Observer } from 'rxjs/Observer';\r\nimport Cookies from 'js-cookie';\r\nimport url from 'url';\r\nimport 'whatwg-fetch';\r\nimport { EventCapturer } from './classes/event-capturer.class';\r\nexport declare const isBrowser: boolean;\r\nexport declare const isIframe: boolean;\r\nexport interface ParamsMap {\r\n    [key: string]: undefined | string | string[];\r\n}\r\nexport interface UserAttributes {\r\n    urlPath?: string;\r\n    queryString?: string | ParamsMap;\r\n    device?: 'mobile' | 'tablet' | 'desktop';\r\n    location?: any;\r\n    os: string;\r\n    userAgent?: string;\r\n    referrer?: string;\r\n    entryMedium?: string;\r\n    language?: string;\r\n    browser?: string;\r\n    cookie?: string;\r\n    newVisitor?: boolean;\r\n    operatingSystem?: string;\r\n}\r\nexport interface GetContentOptions {\r\n    queryString?: string | ParamsMap;\r\n    userAttributes?: UserAttributes;\r\n    limit?: number;\r\n    cachebust?: boolean;\r\n    simulateDate?: Date | string;\r\n    publishedState?: 'published' | 'draft' | 'archived' | 'all';\r\n    filterDates?: boolean;\r\n    includeTests?: boolean;\r\n    dev?: boolean;\r\n    initialContent?: any;\r\n}\r\nexport declare type Class = {\r\n    name: string;\r\n    new (...args: any[]): any;\r\n};\r\nexport interface Input {\r\n    name: string;\r\n    description?: string;\r\n    defaultValue?: any;\r\n    type: string;\r\n    required?: boolean;\r\n    subFields?: Input[];\r\n    helperText?: string;\r\n}\r\nexport interface Component {\r\n    name: string;\r\n    description?: string;\r\n    image?: string;\r\n    inputs?: Input[];\r\n    class?: Class;\r\n}\r\nexport declare function BuilderComponent(info?: Partial<Component>): (component: Class) => void;\r\nexport declare class Builder {\r\n    protected apiKey: string | null;\r\n    static eventCapturer: EventCapturer | null;\r\n    static components: Component[];\r\n    private static incrementalDomLoaded;\r\n    static loadIncrementalDom(): void;\r\n    static patchDom(selector: string, vtree: VirtualDOM.VTree): void;\r\n    static patchHtml(selector: string, html: string): void;\r\n    static vTreeToIncrementalDom(tree: VirtualDOM.VTree): void;\r\n    private static _editingPage;\r\n    static isIframe: boolean;\r\n    static isBrowser: boolean;\r\n    static editingPage: boolean;\r\n    static component(info?: Partial<Component>): (component: Class) => void;\r\n    static readonly Component: typeof Builder.component;\r\n    private eventsQueue;\r\n    private throttledClearEventsQueue;\r\n    private processEventsQueue();\r\n    protected isUsed: boolean;\r\n    editingMode: boolean;\r\n    editingMode$: BehaviorSubject<boolean>;\r\n    editingModel: string | null;\r\n    editingModel$: BehaviorSubject<string | null>;\r\n    setUserAgent(userAgent: string): void;\r\n    userAgent: string;\r\n    track(eventName: string, properties?: any): void;\r\n    trackImpression(contentId: string, variationId?: string): void;\r\n    trackInteraction(contentId: string, variationId?: string): void;\r\n    static overrideUserAttributes: Partial<UserAttributes>;\r\n    component(info?: Partial<Component>): (component: Class) => void;\r\n    constructor(apiKey?: string | null);\r\n    private blockContentLoading;\r\n    private bindMessageListeners();\r\n    observersByModelType: {\r\n        [key: string]: Observer<any> | undefined;\r\n    };\r\n    init(apiKey: string): this;\r\n    getLocation(): url.Url;\r\n    getUserAttributes(userAgent?: string): UserAttributes;\r\n    setUserAttributes(options: object): void;\r\n    private getContentQueue;\r\n    private priorContentQueue;\r\n    private loadFullStory();\r\n    queueGetContent(modelName: string, options?: GetContentOptions): Observable<any[]>;\r\n    requestUrl(url: string): Promise<any>;\r\n    private flushGetContentQueue(usePastQueue?);\r\n    private testCookiePrefix;\r\n    private processResultsForTests(results);\r\n    private getTestCookie(contentId);\r\n    private setTestCookie(contentId, variationId);\r\n    protected getCookie(name: string): any;\r\n    protected setCookie(name: string, value: any, options?: Cookies.CookieAttributes): void;\r\n    getContent(modelName: string, options?: GetContentOptions): Observable<any[]>;\r\n}\r\n"}}
