var $aa = $aa || { 'ready': [] }, mustache = null, render = null; function Controllers() { } function coreController(userID, brand) { setMustache(); initializeReady(); function setMustache() { mustache = new itsMustache(); render = mustache.render; } function initializeReady() { if ($aa && $aa.ready && $aa.ready instanceof Array && $aa.ready.length > 0) readyCall($aa.ready); function readyCall(a) { for (var i = 0, l = a.length; i < l; i++) { if (isFunction(a[i])) a[i](userID, brand); } } } } var TagContainer = function (target, obj, returnCB) { var events = new EventManager, template = '', element = getElementFromString(template), data = obj.data, label = obj.label || 'Enter label name', filterFn = typeof obj.filter === 'function' ? obj.filter : null, keywordsObj = {}, tagsObj = {}, tagsCount = 0, limit = !isDefined(obj.limit) ? -1 : obj.limit, addContainer = undefined, initialized = false; function initialize() { if (data.length > 0) processData(data); initializeAddContainer(); initialized = true; target.appendChild(element); } function processData(d) { var fragment = getFragment(); for (var i = 0, l = d.length; i < l; i++) { var t = processTag(d[i]); if (!!t && t instanceof Node) fragment.appendChild(t); } element.appendChild(fragment); } function processTag(name) { if (!keywordsObj[name]) { var obj = { 'name': name }, tag = new Tag(obj, update); tagsObj[name] = obj; keywordsObj[name] = true; if (initialized) returnCB(getKeywords()); return tag; } return null; } function initializeAddContainer() { addContainer = new AddTagContainer(addTag); element.appendChild(addContainer.container); if (!isUnderLimit()) addContainer.hide(); } function addTag(e) { loop(e, p); function p(k, v) { if (!isUnderLimit()) { addContainer.hide(); return true; } else if (isValidTag(v)) { run(v); } return false; } function run(v) { var tag = processTag(v); if (tag !== null) insertTag(tag); } } function isUnderLimit() { return limit === -1 || tagsCount < limit; } function isValidTag(e) { return typeof e == 'string' && e.length > 0 && (!filterFn || filterFn(e)); } function insertTag(tag) { element.insertBefore(tag, addContainer.container); } function update(e) { if (e.status == false) closeTag(e); } function closeTag(e) { delete tagsObj[e.name]; if (isUnderLimit()) addContainer.show(); } function getKeywords() { var a = []; for (var k in keywordsObj) { a.push(k); } return a; } var AddTagContainer = function (cb) { var container = undefined, input = undefined, button = undefined; initialize(); this.show = show; this.hide = hide; this.container = container; function initialize() { button = createButton(); input = createInput(); container = createContainer(button, input); } function createButton() { var t = document.createElement('div'); t.className = 'add'; bindButton(t); return t; } function createInput() { var t = document.createElement('input'); t.type = 'text'; t.placeholder = label; bindInput(t); return t; } function createContainer(b, i) { var c = document.createElement('div'); c.className = 'addContainer'; c.appendChild(i); c.appendChild(b); return c; } function bindButton(t) { events.add(t, 'click', updateAction); } function bindInput(t) { events.add(t, 'focus', bindWindow); events.add(t, 'blur', unbindWindow); } function bindWindow() { events.add(window, 'keydown', enterCheck); } function unbindWindow() { events.removeAll(window); } function enterCheck(e) { if (e.keyCode == '13') updateAction(); } function updateAction(e) { preventDefault(e); var a = input.value.split(/[\s]{0,}[,][\s]{0,}/g); input.value = ''; cb(a); } function show() { container.classList.remove('noDisplay'); } function hide() { container.classList.add('noDisplay'); } }; var Tag = function (obj, cb) { var name = undefined, tag = undefined, close = undefined, className = ''; if (obj) initialize(); return tag; function initialize() { name = obj.name; close = createClose(); tag = createTag(close); obj.tag = tag; } function createTag(c) { var t = document.createElement('tag'), p = document.createElement('p'); p.textContent = name; if (obj.className) className += ' ' + obj.className; t.className = className; t.appendChild(p); t.appendChild(c); tagsCount++; return t; } function createClose() { var t = document.createElement('div'); t.className = 'close'; bindClose(t); return t; } function bindClose(t) { events.add(t, 'click', closeTag); } function unbindClose() { events.removeAll(close); } function closeTag() { obj.status = false; unbindClose(); tag.parentNode.removeChild(tag); handleKeywords(); tagsCount--; cb(obj); } function handleKeywords() { delete keywordsObj[name]; if (initialized) returnCB(getKeywords()); } }; initialize(); }; var ColumnSquares = function (target, dataObj) { var main = new MainObj, sizeReference = { 'one': { 'width': 1, 'height': 1 }, 'two': { 'width': 2, 'height': 1 }, 'three': { 'width': 2, 'height': 2 }, }; function initialize(m, o) { setSquares(m, o.squares); setColumns(m); refreshPlacement(m); } function MainObj() { this.widthMetric = 180; this.heightMetric = 180; this.margin = [0, 8, 8, 0]; this.squares = []; this.columns = []; this.targetRects = target.getClientRects()[0]; this.maxColumns = getSizeUnits(!!this.targetRects ? this.targetRects.width : 0); this.template = getTemplate(); } function Square(o, m, i) { var drag = null, element = null; this.squareIndex = i; this.column = o.column; this.columnIndex = null; this.rects = getColumnSquareRects(o.size); this.templateData = getTemplateData(o); this.element = element = getElementFromString(render(m.template, this.templateData)); this.setOffsets = setOffsets; this.setPositioning = setPositioning; if (o.element) element.querySelector('content').appendChild(o.element); //var dC = function(t){ return function(e){ dragEnd(t, e); } }(this); //setTimeout(setDrag, 1); function dragStart(e) { } function dragEnd(t, e) { updateSquarePositioning(e, t.squareIndex); } function setDrag() { drag = new DragController(element, dragStart, dC); } function setOffsets() { return false; /* Disabling this function for now drag.setOffsets(); */ } function setPositioning(l, t) { setTimeout(setOffsets, 300); element.style.position = 'absolute'; element.style.left = l; element.style.top = t; } } function updateSquarePositioning(e, i) { var t = e.target, m = main, square = m.squares[i], columns = m.columns, oldColumn = square ? columns[square.column] : null, matchColumnIndex = getColumnByOffset(t.offsetLeft, t.offsetWidth).i, matchColumn = columns[matchColumnIndex], position = matchColumn ? getColumnPosition(t.offsetTop, t.offsetHeight, matchColumn) : null; switchColumns(square, oldColumn, matchColumn, position); square.column = matchColumnIndex; refreshSquaresArray(m); refreshColumnsArray(m); refreshPlacement(m); } function switchColumns(square, o, n, p) { n.splice(p, 0, o.splice(square.columnIndex, 1)[0]); updateColumnIndexes(o); updateColumnIndexes(n); } function updateColumnIndexes(a) { for (var i = 0, l = a.length; i < l; i++) { if (a[i] != 0 && a[i] != undefined) a[i].columnIndex = i; } } function getColumnByOffset(oL, oW) { var wEnd = oL + oW, m = main, width = m.widthMetric, margin = m.margin, uMargin = margin[1] + margin[3], v = 0, match = false; for (var i = 0, c = m.columns, l = c.length; i < l; i++) { var cStart = v, cEnd = ((i + 1) * width) + uMargin; if (cStart < wEnd && cEnd > oL) match = getColumnMatch(match, i, cStart - oL); v = cEnd; } return match; } function getColumnPosition(oT, oH, c) { var hEnd = oT + oH, m = main, height = m.heightMetric, margin = m.margin, uMargin = margin[0] + margin[2], v = 0, match = false; for (var i = 0, l = c.length; i < l; i++) { var pStart = v, pEnd = ((i + 1) * height) + uMargin; if (c[i] !== 0 && pStart < hEnd && pEnd > oT) match = getColumnMatch(match, i, pStart - oT); v = pEnd; } return match == false ? c.length : match.i; } function getColumnMatch(match, i, d) { if (d < 0) d = d * -1; if (match == false || match.delta > d) return { 'i': i, 'delta': d }; else return match; } function refreshSquaresArray(m) { var columns = m.columns, a = [], row = 0, maxRow = 1; for (var i = 0; i < maxRow; i++) { processRow(); } m.squares = a; function processRow() { for (var i = 0, l = columns.length; i < l; i++) { if (row == 0) { setMaxRow(columns[i].length); } var t = columns[i][row]; if (t !== 0 && t !== undefined) pushSquare(a, t); } if (row == 0) maxRow++; row++; } function setMaxRow(l) { if (l > maxRow) maxRow = l; } function pushSquare(a, t) { var aL = a.length; t.squareIndex = aL; a[aL] = t; } } function refreshColumnsArray(m) { m.columns = []; setColumns(m); } function refreshPlacement(m) { var c = m.columns, w = 0, margin = main.margin, leftMargin = margin[3], rightMargin = margin[1]; for (var i = 0, l = c.length; i < l; i++) { w += leftMargin; var t = c[i], lP = null if (i === 0) lP = w; else lP = getSquareLeftPositioning(w, i); refreshColumn(t, i, lP); w = lP + rightMargin; } refreshTarget(); } function refreshColumn(c, cI, lP) { var h = 0, margin = main.margin, topMargin = margin[0], bottomMargin = margin[2]; for (var i = 0, l = c.length; i < l; i++) { var t = c[i], tP = null; h += topMargin; if (i === 0) tP = h; else tP = getSquareTopPositioning(h, i); if (t !== 0 && t != undefined) t.setPositioning(lP + 'px', tP + 'px'); h = tP + bottomMargin; } } function refreshTarget() { var v = 0; for (var i = 0, c = main.columns, l = c.length; i < l; i++) { var t = getSizePixels(c[i].length); if (t > v) v = t; } target.style.height = v + 20 + 'px'; } function getSquareLeftPositioning(v, i) { return (v + main.widthMetric); } function getSquareTopPositioning(v, i) { return (v + main.heightMetric); } function getTemplate() { var h = '

{{ title }}

', c = ''; classString = 'size="{{ size }}" class="{{^ status }}off{{/ status }}"'; return '' + h + c + ''; } function setSquares(m, s) { var f = document.createDocumentFragment(); for (var i = 0, l = s.length; i < l; i++) { var sq = new Square(s[i], m, i); m.squares[i] = sq; f.appendChild(sq.element) } target.appendChild(f); } function setColumns(m) { var max = m.maxColumns, s = m.squares, c = m.columns; populateEmptyColumns(c, max); processSquares(s, c); function populateEmptyColumns(c, max) { for (var i = 0; i < max; i++) { c[i] = []; } } function processSquares(s, c) { for (var i = 0, l = s.length; i < l; i++) { addToColumn(c, s[i], s[i].column); } } function addToColumn(c, o, i) { var p = findPlace(c, o, i); if (p != false) { c[i].push(o); stretchOut(c, i, o.rects); } } function findPlace(c, o, i) { var w = i + o.rects.width - 1, s = c[i] != undefined, e = c[w] != undefined; if (s && e) { var sV = c[i].length; var eV = c[w].length; var d = sV - eV; if (d < 0) fillZeros(c[i], d * -1); else if (d > 0) fillZeros(c[w], d); return true; } else return false; } function fillZeros(t, c) { for (var i = 0; i < c; i++) { t.push(0); } } function isValidPlace(c, i) { return c[i] != undefined; } } function stretchOut(c, cI, r) { var tCol = c[cI], tI = tCol.length - 1, h = r.height, w = r.width; for (var i = tI, l = tI + h; i < l; i++) { if (i != tI) tCol[i] = 0; if (w > 1) stretchRight(c, cI + 1, i, w - 1); } tCol[tI].columnIndex = tI; } function stretchRight(c, cI, i, w) { for (var l = cI + w; cI < l; cI++) { c[cI][i] = 0; } } function getTemplateData(o) { return { 'title': o.title, 'status': o.status === undefined ? true : o.status, 'size': o.size }; } function getSizeUnits(px) { return Math.floor(px / 180); } function getSizePixels(units) { return Math.floor(units * 180); } function getColumnSquareRects(s) { return sizeReference[s]; } initialize(main, dataObj); }; var DragController = function (t, dragStart, dragEnd, dragMove, config) { var events = new EventManager, startX = null, startY = null, cX = null, cY = null, oL = null, oT = null, scrollTop = null, scrollEvent = undefined, scrollTimer = null, xOnly = config && config.xOnly ? true : false, yOnly = config && config.yOnly ? true : false, inBounds = config && config.inBounds ? true : false, autoSet = config && config.autoSet ? true : false, parentNode = t.parentNode, parentRects = null, targetRects = null, originalTransition = getOriginalTransition(); this.setOffsets = setOffsets; this.exit = exit; setOffsets(); bindTarget(); function mouseDownAction(e) { stopDefaultAction(e); startDrag(e); } function mouseUpAction(e) { stopDefaultAction(e); endDrag(e); } function stopDefaultAction(e) { if (e && e.preventDefault) e.preventDefault(); } function startDrag(e) { setScrollTop(); setStartPoint(e); setTargetStyle(); bindWindow(); bindScroll(); dragStart(e); } function endDrag(e) { unbindWindow(); removeTargetStyle(); unbindScroll(); dragEnd(e); if (autoSet) setOffsets(); } function scrollAction(e) { setDifference(getFauxEvent()); } function setScrollTimer() { if (scrollTimer) clearTimeout(scrollTimer); scrollTimer = setTimeout(scrollAction, 100); } function setOffsets() { oL = t.offsetLeft; oT = t.offsetTop; } function setStartPoint(e) { var oT = (e.target == t) ? t : e.target.parentNode; setStartPointX(e, oT); setStartPointY(e, oT); } function setStartPointX(e, oT) { startX = e.clientX; } function setStartPointY(e, oT) { startY = e.clientY; } function setScrollTop() { scrollTop = window.scrollY; } function setTargetStyle() { t.style.zIndex = '10000'; t.setAttribute('cssTransition', 'none'); } function setDifference(e) { setRects(); setPosition(e, getLeftValue(e), getTopValue(e)); } function setPosition(e, left, top) { t.style.position = 'absolute'; left = getLeftPosition(left + oL); top = getTopPosition(top + oT); if (!dragMove || (dragMove && dragMove(e, left, top) !== false)) { setLeftPosition(left); setTopPosition(top); } } function setLeftPosition(left) { if (left !== null) t.style.left = left + 'px'; } function setTopPosition(top) { if (top !== null) t.style.top = top + 'px'; } function getLeftPosition(left) { if ((!inBounds && !yOnly) || (left >= 0 && left + targetRects.width <= parentRects.width)) return left; else if (yOnly) return null; else if (left < 0) return 0; else if (left > parentRects.width) return parentRects.width - targetRects.width; } function getTopPosition(top) { if ((!inBounds && !xOnly) || (top >= 0 && top + targetRects.height <= parentRects.height)) return top; else if (xOnly) return null; else if (top < 0) return 0; else if (top > parentRects.height) return parentRects.height - targetRects.height; } function getLeftValue(e) { cX = e.clientX; return cX - startX; } function getTopValue(e) { cY = e.clientY; return cY - startY - (scrollTop - window.scrollY); } function getFauxEvent() { return { 'clientX': cX, 'clientY': cY }; } function getOriginalTransition() { return t.getAttribute('cssTransition') || ''; } function setRects() { setParentRects(); setTargetRects(); } function setParentRects() { if (!parentRects) parentRects = { 'width': parentNode.offsetWidth, 'height': parentNode.offsetHeight }; } function setTargetRects() { if (!targetRects) targetRects = { 'width': t.offsetWidth, 'height': t.offsetHeight }; } function bindTarget() { events.add(t, 'mousedown', mouseDownAction); } function bindWindow() { wal('mousemove', setDifference); wal('mouseup', mouseUpAction); } function unbindWindow() { wrl(); } function bindScroll() { scrollEvent = new MouseScrollEvent(setScrollTimer); } function unbindScroll() { scrollEvent.unbind(); } function wal(eT, fn) { events.add(window, eT, fn, 'window'); } function wrl() { events.removeByTag('window'); } function removeTargetStyle() { t.style.zIndex = ''; t.setAttribute('cssTransition', originalTransition); } function exit() { if (events) events.reset(); housekeeping(); } function housekeeping() { t = dragStart = dragEnd = dragMove = config = events = startX = startY = null; cX = cY = oL = oT = scrollTop = scrollEvent = srollTimer = xOnly = yOnly = null; inBounds = autoSet = parentNode = parentRects = targetRects = originalTransition = null; } }; var MouseScrollEvent = function (cb) { var events = new EventManager; mozillaBind(); defaultBind(); this.unbind = unbind; function mozillaBind() { events.add(window, 'DOMMouseScroll', cb); } function mozillaCB(e, cb) { e.delta = e.detail * -40; cb(e); } function defaultBind() { events.add(document, 'mousewheel', cb); } function unbind() { events.reset(); } }; var CheckboxListContainer = function (target, data, returnCB) { window['__listCount'] = 0; var template = '
', element = getElementFromString(template), lists = [], navigation = [], toggle = null; refresh(); insertElement(); this.setAll = setAll; this.unsetAll = unsetAll; this.reset = unsetAll; this.getLists = getLists; this.exit = exit; function refresh() { forEach(data, processList); } function insertElement() { toggle = new ToggleNavigation(element.querySelector('header'), { 'data': lists, 'className': 'toggle' }, updateToggle); target.appendChild(element); } function getLists() { var a = []; forEach(lists, p); return a; function p(t, lists, i) { a[i] = t; } } function processList(t) { lists.push(new List(t)); } function updateToggle(e) { forEach(lists, process); function process(t) { if (t.title == e.title) t.show(); else t.hide(); } } function setAll() { forEach(lists, p); function p(t) { t.setAll(); } } function unsetAll() { forEach(lists, p); function p(t) { t.unsetAll(); } } function exitAll() { forEach(lists, p); function p(t) { if (t.exit) t.exit(); } } function List(o) { var lO = { 'title': o.title, 'data': o.data, 'api': o.api, 'apiData': o.apiData, 'apiFn': o.apiFn, 'config': o.config }, list = new CheckboxList(element, lO, update), e = list.getElement(); this.data = o.data; this.title = o.title; this.value = o.title; this.list = list; this.show = show; this.hide = hide; this.exit = exit; this.setAll = list.setAll; this.unsetAll = list.unsetAll; function update(e) { if (returnCB) returnCB({ 'key': o.key, 'value': e }); } function hide() { e.classList.add('noDisplay'); } function show() { e.classList.remove('noDisplay'); } function exit() { if (list && list.exit) list.exit(); list = null; } } function exit() { if (lists) exitAll(); if (toggle) toggle.exit(); housekeeping(); } function housekeeping() { target = data = returnCB = template = element = lists = navigation = toggle = null; } }; function BenchTimer() { var s = new Date; this.check = function () { return new Date - s; }; } var CheckboxList = function (target, obj, returnCB) { var search = null, template = '

{{ title }}:

{{# data }}

{{ . }}{{#data}}{{name}}{{/data}}

{{/ data }}
', element = getElementFromString(render(template, obj)), listElement = element.querySelector('list'), listItems = listElement.querySelectorAll('item'), pagination = null, pageSize = obj.pageSize || 10, currentMatches = null, currentPage = 0, currentPageCount = 0, list = [], dynamicObj = {} dynamicList = []; this.getElement = getElement; this.setAll = setAll; this.unsetAll = unsetAll; this.getList = getList; this.reset = unsetAll; this.exit = exit; if (isDefined(obj.data)) initStaticData(); else if (isDefined(obj.api)) initDynamicData(); target.appendChild(element); function initStaticData() { forEach(obj.data, processCheckbox); initializePagination(); initializeSearch(processMatches) } function initDynamicData() { initializeSearch(processDynamic); } function initializeSearch(fn) { if (obj.searchable !== false) { search = new SearchContainer(element.querySelector('header'), obj, fn); } } function initializePagination() { var d = obj.data, dL = d.length; if (obj.pagination !== false && dL > pageSize) pagination = new Pagination(element, Math.ceil(dL / pageSize), 5, paginationUpdate); } function getItemElement(title) { var template = '

{{ . }}

'; return getElementFromString(render(template, title)); } function setAll() { forEach(list, p); function p(t) { t.set(); }; } function unsetAll() { forEach(list, p); function p(t) { t.unset(); }; } function processMatches(e) { currentMatches = e; refresh(getSimpleJSONCopy(e), 1); } function paginationUpdate(e, t) { var d = currentMatches ? getSimpleJSONCopy(currentMatches) : null; refresh(d, e); } function paginationReduce(a, e) { var s = pageSize * (e - 1), e = s + pageSize - 1; forEach(a, reduce, true); function reduce(t, d, i) { if (i < s || i > e) a.splice(i, 1); } } function getPlaceholderArray(c) { var a = []; for (var i = 0; i < c; i++) { a.push({ 'index': i }); } return a; } function refresh(a, page) { var arr = isDefined(a) ? a : getPlaceholderArray(list.length), nLength = arr.length, cPage = isDefined(page) ? page : 1; if (currentPage !== cPage) currentPage = cPage; if (!!pagination) { if (nLength !== currentPageCount) { currentPageCount = nLength; pagination.updatePageCount(nLength, pageSize); } paginationReduce(arr, cPage); } insertItems(arr); } function insertItems(a) { removeItems(); var f = getFragment(); forEach(a, insert); listElement.appendChild(f); function insert(t) { f.appendChild(list[t.index].getElement()) } } function removeItems() { forEach(list, remove); function remove(t) { removeChild(listElement, t.getElement()); } } function processDynamic(e) { var a = []; forEach(e, p); refresh(a, 1); function p(t, d, i) { if(!t) return; if (!dynamicObj[t.title]) { dynamicObj[t.title] = new Item(t.title, t.value || t.id, list.length, true); list.push(dynamicObj[t.title]); if (isDynamicMatch(t.title, t.value)) dynamicObj[t.title].set(); } a.push({ 'index': dynamicObj[t.title].getIndex() }); } } function isDynamicMatch(title, value) { var isMatch = false; forEach(obj.apiData, p); return isMatch; function p(t) { if (t === title || t === value) isMatch = true; return true; } } function isMatch(val) { var m = false; loop(obj.apiData, p); return m; function p(k, v) { if (v === val) { m = true; return true; } } } function processCheckbox(t, d, i) { if (typeof t === 'string') return list.push(new Item(t, t, i)); if (!!t.title && !!t.value) return list.push(new Item(t.title, t.value, i)); if (!!t.data) return list.push(new Item(!!t.data.name ? t.name : t.value, t.value, i)); } function Item(t, v, i, create) { var element = create !== true ? listItems[i] : getItemElement(t), checkbox = new Checkbox(element, checkCB, true), state = false; if (isMatch(t)) { checkbox.set(); state = true; } this.getTitle = getTitle; this.getValue = getValue; this.getName = getName; this.getState = getState; this.getElement = getElement; this.getIndex = getIndex; this.unset = function () { state = false; checkbox.unset(); }; this.set = function () { state = true; checkbox.set(); }; this.exit = exit; function getIndex() { return i; } function getName() { console.error('Warning, getName has been depreciated. Please update the calling function to use getTitle or getValue instead!'); return getTitle(); } function getTitle() { return t; } function getValue() { return v; } function getState() { return state; } function getElement() { return element; } function checkCB(e) { state = e; notify(); } function exit() { if (checkbox) checkbox.exit(); checkbox = null; } }; function getList() { var a = []; forEach(list, p); return a; function p(t) { a.push(t); } } function getElement() { return element; } function getSelectedItems() { var a = []; forEach(list, processItem); return a; function processItem(t, d, i) { if (t.getState() === true) a.push({ 'title': t.getTitle(), 'value': t.getValue() }); } } function notify() { if (returnCB) returnCB(getSelectedItems()); } function exit() { if (list) exitAll(); if (pagination) pagination.exit(); if (search) search.exit(); housekeeping(); } function exitAll() { forEach(list, p); function p(t) { if (t.exit) t.exit(); }; } function housekeeping() { target = obj = returnCB = search = template = element = listElement = listItems = pageSize = currentMatches = list = null; } }; var Checkbox = function (target, cb, prepend) { var state = false, events = new EventManager, element = document.createElement('m-checkbox'); bindElement(element); if (prepend !== true) target.appendChild(element); else prependChild(target, element); this.unset = unset; this.set = set; this.exit = exit; function toggle() { if (state) unset(); else set(); if (cb) cb(state); } function set() { state = true; element.classList.add('active'); } function unset() { state = false; element.classList.remove('active'); } function bindElement(t) { events.add(t, 'click', toggle); } function exit() { if (events) events.reset(); target = cb = prepend = state = events = element = null; } }; var Notification = function (t, html, obj, closeCallback) { var events = new EventManager, data = obj.data, notification = null, closeButton = null; if (t && html && obj) initNotification(); this.getElement = getElement; this.exit = exit; function initNotification() { notification = document.createElement('notification'); closeButton = getCloseButton(); if (obj.id) notification.id = obj.id; if (obj.className) notification.className = obj.className; if (obj.cssTransition) notification.setAttribute('cssTransition', obj.cssTransition); insertToTarget() } function getElement() { return notification; } function getCloseButton() { var c = document.createElement('icon'); c.className = 'close'; events.add(c, 'click', closeCallback); return c; } function insertToTarget() { notification.innerHTML = render(html, data); notification.appendChild(closeButton); t.appendChild(notification); } function exit() { if (notification !== null) { removeChild(t, notification); cleanUp(); } } function cleanUp() { if (events) events.reset(); events = data = notification = closeButton = null; } }; var Alert = function (t, html, obj) { var events = new EventManager, data = obj.data, alert = null, closeButton = null; if (t && html && obj) initAlert(); this.getElement = getElement; this.exit = closeAlert; function initAlert() { alert = document.createElement('alert'); closeButton = getCloseButton(); if (obj.id) alert.id = obj.id; if (obj.className) alert.className = obj.className; if (obj.cssTransition) alert.setAttribute('cssTransition', obj.cssTransition); insertToTarget() } function getElement() { return alert; } function getCloseButton() { var c = document.createElement('icon'); c.className = 'close'; events.add(c, 'click', closeAlert); return c; } function insertToTarget() { alert.innerHTML = render(html, data); alert.appendChild(closeButton); t.appendChild(alert); } function closeAlert() { if (alert !== null) removeChild(t, alert); cleanUp(); } function cleanUp() { if (events) events.reset(); alert = null; closeButton = null; } }; var LoggedInAsNotification = function (id, isAdmin, returnCB) { var tgt = document.getElementById('loggedInAs'), p = null, a = null, events = new EventManager, tmpl = new Template, __id = id; this.show = show; this.hide = hide; this.update = update; this.exit = exit; refreshMessage(__id); show(); function Template() { this.p = '

Controlling user id: {{ id }}.

'; this.a = '' + (isAdmin ? 'Return to main account' : 'Return to advertisers list') + ''; } function show() { tgt.classList.remove("noDisplay"); } function hide() { tgt.classList.add("noDisplay"); } function update(v) { __id = v; refreshMessage(v); show(); } function refreshMessage(v) { var f = document.createDocumentFragment(); p = getElementFromString(render(tmpl.p, __id)) a = getElementFromString(tmpl.a); f.appendChild(p); f.appendChild(a); events.reset(); tgt.innerHTML = ""; tgt.appendChild(f); events.add(a, 'click', returnCB); } function exit() { if (!!events) { events.reset(); } hide(); housekeeping(); } function housekeeping() { events = tmpl = tgt = null; } }; var Autocomplete = function (target, data, config) { var events = new EventManager(), matchesTemplate = '{{# . }}{{ . }}{{/ . }}', input = null, matchesContainer = null, mc = null, state = false, selected = -1; initialize(); this.reset = resetInput(); this.exit = exit; function initialize() { config = config || {}; initInput(); initMatchesContainer(); insertChildren(); } function initInput() { input = document.createElement('input'); input.type = 'text'; setInputConfig(); } function initMatchesContainer() { matchesContainer = mc = document.createElement('ac-matches'); } function setInputConfig() { var c = config; if (c.placeholder) input.placeholder = c.placeholder; if (c.className) input.className = c.className; } function insertChildren() { var t = target, i = input; t.appendChild(i); t.appendChild(mc); events.add(i, 'keyup', keyUpAction); } function windowClickAction(e) { if (!isTargetChild(e.target, target)) resetInput(); else if (e.target.tagName == 'AC-MATCH') setInput(e.target.textContent); } function keyUpAction(e) { var kc = e.keyCode; switch (kc) { case 13: enterCheck(e); break; case 27: resetInput(); break; case 38: decrementSelected(); break; case 40: incrementSelected(); break; default: searchValidation(e); break; } } function enterCheck(e) { if (selected > -1) { e.preventDefault(); setInput(matchesContainer.childNodes[selected].textContent); } } function resetInput() { mc.innerHTML = ''; input.value = ''; unbindCancelItems(); } function setInput(v) { mc.innerHTML = ''; input.value = v; unbindCancelItems(); } function decrementSelected() { if (selected > -1) { unsetSelected(); selected--; setSelected(); } } function incrementSelected() { if (selected < matchesContainer.childNodes.length - 1) { unsetSelected(); selected++; setSelected(); } } function searchValidation(e) { var v = e.target.value; if (v !== '') searchAction(v); else resetInput(); } function searchAction(v) { processMatches(getMatches(v.toLowerCase())); } function setSelected() { var c = mc.childNodes; if (isValidSelection(c)) c[selected].classList.add('selected'); } function unsetSelected() { var c = mc.childNodes; if (isValidSelection(c)) c[selected].classList.remove('selected'); } function getMatches(s) { var a = []; for (var i = 0, d = data, l = d.length; i < l; i++) { processMatch(d[i], s, a); } if (a.length > 0 && state == false) bindCancelItems(); else if (a.length === 0) a = null; return a; } function getMatchValue(t, s) { return t.toLowerCase().indexOf(s) } function getHighlightedString(m, iO, l) { return m.substring(0, iO) + '' + m.substring(iO, iO + l) + '' + m.substring(iO + l); } function pushMatchToArray(a, t, iO, l) { if (iO > -1) a.push(getHighlightedString(t, iO, l)); } function processMatches(m) { if (m != null) mc.innerHTML = render(matchesTemplate, m); else mc.innerHTML = ''; } function processMatch(t, s, a) { pushMatchToArray(a, t, getMatchValue(t, s), s.length) } function bindCancelItems() { state = true; events.add(window, 'click', windowClickAction); } function unbindCancelItems() { state = false; events.removeAll(window); } function isTargetChild(c, t) { var p = c.parentNode; if (p == t) return true; else if (p != document.body) return isTargetChild(p, t); else return false; } function isValidSelection(c) { return selected < c.length && selected > -1; } function exit() { if (events) events.reset(); target = data = config = events = matchesTemplate = input = matchesContainer = mc = state = selected = null; } }; var SearchContainer = function (target, obj, returnCB) { var events = new EventManager, template = '', data = isDefined(obj.data) ? obj.data : [], config = obj.config || {}, element = getElementFromString(render(template, config)), input = element.querySelector('input'), search = new Search(data), apiTimer = null; if (returnCB) { if (data.length > 0) events.add(element, 'keyup', check); else if (obj.api) events.add(element, 'keyup', apiCheck); target.appendChild(element); } this.exit = exit; function check(e) { returnCB(search.getMatches(e.target.value)); } function apiCheck(e) { clearRequest(); setRequest(e.target.value); } function clearRequest() { clearTimeout(apiTimer); } function setRequest(v) { apiTimer = setTimeout(request, 600); } function request() { new HttpRequest('GET', obj.api + '/' + input.value, null, null, 'json', apiCheckCB); } function apiCheckCB(e) { var v = isDefined(obj.apiFn) ? obj.apiFn(e) : e; returnCB(v); } function removeElement() { if (element.parentNode === target) target.removeChild(element); } function exit() { removeElement(); if (events) events.reset(); template = data = config = element = search = events = null; } }; var Search = function (d) { var data = getData(d); this.getMatches = getMatches; this.update = update; function Item(title, value, i) { this.title = title || ""; this.lc = title.toLowerCase(); this.value = value || null; this.index = i || 0; } function update(d) { if (isArray(d)) data = getData(d); } function getData(d) { var a = []; forEach(d, processItem); return a; function processItem(t, d, i) { if (isString(t)) { a.push(new Item(t, t, i)); } else if (isObject(t)) { a.push(new Item(t.title, t.value, i)); } else { console.error("unsupported type", t) return; } } } function getMatches(s) { var lc = s.toLowerCase(); function checkItem(t) { return t.lc.indexOf(lc) > -1; } return data.filter(checkItem); } }; /* Pagination Variable declarations -------------------------------- target Element reference - Pagination will be inserted to this reference pages Number setLength Number */ var Pagination = function (target, pageCount, setLength, returnCB) { var events = new EventManager, template = new TemplateObj().index, currentPage = 1, currentSet = 1, pages = Math.ceil(pageCount), totalSets = null, obj = null, paginationElement = null, beforeCurrentSections = [], currentSections = [], afterCurrentSections = [], previousButton = null, nextButton = null; setLength = getSetLength(); totalSets = getTotalSets(); setTimeout(init, 1); this.updatePageCount = updatePageCount; this.exit = exit; function init() { if (target && pages) refresh(); } function updatePageCount(c, s) { currentPage = 1; currentSet = 1; updatePages(Math.ceil(c / s)); returnCB(1); } function updatePages(p) { if (pages !== p) { pages = p; totalSets = getTotalSets(); refresh(true); } } function PaginationObj() { this.pages = getPagesArray([]); this.beforeSections = currentSet != 1 ? getBeforeSections([]) : null; this.beforeActive = this.beforeSections != null && this.beforeSections.length > 0 ? true : false; this.afterSections = isThereOverflow() ? getAfterSections([]) : null; this.afterActive = this.afterSections != null && this.afterSections.length > 0 ? true : false; } function PageObj(i, v) { this.value = i + 1; this.active = (i + 1) != v + currentPage ? false : true; } function TemplateObj() { this.previousButton = ''; this.nextButton = ''; this.expandSection = '

{{ . }}

'; this.pagesSection = '

{{ value }}

'; this.pages = '{{# pages }}' + this.pagesSection + '{{/ pages }}'; this.beforeSections = '{{# beforeSections }}' + this.expandSection + '{{/ beforeSections }}'; this.afterSections = '{{# afterSections }}' + this.expandSection + '{{/ afterSections }}'; this.beforeCheck = '{{# beforeActive }}' + this.beforeSections + '{{/ beforeActive }}'; this.afterCheck = '{{# afterActive }}' + this.afterSections + '{{/ afterActive }}'; this.index = '' + this.previousButton + this.beforeCheck + '' + this.pages + '' + this.afterCheck + this.nextButton + ''; } function refresh(ignore) { obj = new PaginationObj; var n = getElementFromString(render(template, obj)); if (paginationElement) refreshPagination(n); else target.appendChild(n); paginationElement = n; setBindings(n); if (returnCB && ignore !== true) returnCB(getCurrentPageValue()); } function incrementPage() { var r = Math.ceil(pageCount - ((currentSet - 1) * setLength)), sL = r >= setLength ? setLength : r; if (currentPage < sL) updateCurrentPage(currentPage); else if (!isOnLastSet()) incrementSet(); } function incrementSet() { if (currentSet < totalSets) { currentSet++; currentPage = 1; refresh(); } } function decrementPage() { if (currentPage > 1) updateCurrentPage(currentPage - 2); else if (currentSet > 1) decrementSet(); } function decrementSet() { if (currentSet > 1) { currentSet--; currentPage = setLength; refresh(); } } function refreshPagination(n) { unsetBindings(); replacePagination(n); } function unsetBindings() { unbindSections(); unbindBeforeSections(); unbindAfterSections(); unbindButtons(); } function setBindings(n) { var b = getBeforeElement(n); a = getAfterElement(n); bindSections(getPageSectionElements(n)); if (b) bindBeforeSections(b.querySelectorAll('section')); if (a) bindAfterSections(a.querySelectorAll('section')); bindNextButton(); bindPreviousButton(); } function replacePagination(n) { target.insertBefore(n, paginationElement); target.removeChild(paginationElement); } function updateCurrentPage(i) { var s = getListSections(); s[currentPage - 1].classList.remove('active'); s[i].classList.add('active'); currentPage = i + 1; if (!!returnCB) returnCB(getCurrentPageValue()); } function beforeSectionClick(e, i) { currentPage = 1; currentSet = i + 1; refresh(); } function afterSectionClick(e, i) { currentPage = 1; currentSet = currentSet + i + 1; refresh(); } function getPagesArray(a) { var v = getSetStartingValue(); for (var i = v, l = v + getSetLength(); i < l; i++) { a.push(new PageObj(i, v)); } return a; } function getSetStartingValue() { return (currentSet - 1) * setLength; } function getCurrentPageValue() { return getSetStartingValue() + currentPage; } function getSetLength() { if (isThereOverflow()) return setLength; else return pages - (setLength * (currentSet - 1)); } function getBeforeSections(a) { var v = (setLength * (currentSet - 1)) + 1; for (var i = 1; i < v; i = i + setLength) { if (i < v) a.push(getOverflowSet(i, v)); } return a; } function getAfterSections(a) { var i = (setLength * (currentSet)) + 1; for (var l = pages; i < l + 1; i = i + setLength) { a.push(getOverflowSet(i, l)); } return a; } function getOverflowSet(i, l) { var v = i + setLength - 1; if (v > l) v = l; return i + ' - ' + v; } function getSectionEventClosure(i) { return function (i) { return function () { updateCurrentPage(i); } }(i); } function getBeforeSectionClosure(i) { return function (i) { return function (e) { beforeSectionClick(e, i); } }(i); } function getAfterSectionClosure(i) { return function (i) { return function (e) { afterSectionClick(e, i); } }(i); } function getListSections() { return paginationElement.querySelector('pagination-list').querySelectorAll('section'); } function getBeforeElement(n) { return n.querySelector('pagination-overflow.before'); } function getAfterElement(n) { return n.querySelector('pagination-overflow.after'); } function getPageSectionElements(n) { return n.querySelector('pagination-list').querySelectorAll('section'); } function getTotalSets() { return Math.ceil(pages / setLength); } function isThereOverflow() { return isDefined(setLength) && (setLength * currentSet) <= pages; } function isOnLastSet() { return currentSet == totalSets; } function bindSections(t) { for (var i = 0, l = t.length; i < l; i++) { bindSection(t[i], i); } } function bindSection(t, i) { var o = { 't': t, 'c': getSectionEventClosure(i), 'value': getSetStartingValue() + i + 1 }; events.add(t, 'click', o.c); currentSections.push(o); } function bindBeforeSections(t) { for (var i = 0, l = t.length; i < l; i++) { bindBeforeSection(t[i], i); } } function bindBeforeSection(t, i) { var o = { 't': t, 'c': getBeforeSectionClosure(i), 'value': obj.beforeSections[i] }; events.add(t, 'click', o.c); beforeCurrentSections.push(o); } function bindAfterSections(t) { for (var i = 0, l = t.length; i < l; i++) { bindAfterSection(t[i], i); } } function bindAfterSection(t, i) { var o = { 't': t, 'c': getAfterSectionClosure(i), 'value': obj.afterSections[i] }; events.add(t, 'click', o.c); afterCurrentSections.push(o); } function bindNextButton() { var t = paginationElement.querySelector('.nextButton'); if (t) events.add(t, 'click', incrementPage); nextButton = t; } function bindPreviousButton() { var t = paginationElement.querySelector('.prevButton'); if (t) events.add(t, 'click', decrementPage); previousButton = t; } function unbindSections() { for (var i = 0, t = afterCurrentSections, l = t.length; i < l; i++) { unbindSection(t[i]); } currentSections = []; } function unbindSection(o) { events.removeAll(o.t); } function unbindBeforeSections() { for (var i = 0, t = beforeCurrentSections, l = t.length; i < l; i++) { unbindBeforeSection(t[i]); } beforeCurrentSections = []; } function unbindBeforeSection(o) { events.removeAll(o.t); } function unbindAfterSections() { for (var i = 0, t = afterCurrentSections, l = t.length; i < l; i++) { unbindAfterSection(t[i]); } afterCurrentSections = []; } function unbindAfterSection(o) { events.removeAll(o.t); } function unbindButtons() { if (nextButton) events.removeAll(nextButton); if (previousButton) events.removeAll(previousButton); nextButton = null; previousButton = null; } function exit() { if (events) events.reset(); housekeeping(); } function housekeeping() { target = pages = setLength = returnCB = events = template = currentPage = currentSet = totalSets = obj = null; paginationElement = beforeCurrentSections = currentSections = afterCurrentSections = previousButton = nextButton = null; } }; var ToggleInput = function (target, returnCB, obj) { var events = new EventManager, state = false, config = new Configuration(obj || {}), template = getTemplate(), element = getElementFromString(render(template, config)); startingState(); bindElement(); target.appendChild(element); this.toggle = toggle; this.set = on; this.reset = on; this.unset = off; this.getState = getState; this.exit = exit; function Configuration(o) { this.trueLabel = o.trueLabel || 'On'; this.falseLabel = o.falseLabel || 'Off'; this.toggleTheme = o.toggleTheme || 'royal'; this.labelTheme = o.labelTheme || 'fresh'; this.switchTheme = o.switchTheme || 'fresh'; this.transition = o.transition || ''; this.initialValue = o.initialValue || true; } function startingState() { var v = obj ? obj.initialValue : null, fn = on; if (v === false || isString(v) && v.toLowerCase() == 'off') { fn = off; } fn(); } function toggle() { if (!state) on(); else off(); } function on() { state = true; setElementOn(); if (returnCB) returnCB(true); } function off() { state = false; setElementOff(); if (returnCB) returnCB(false); } function setElementOn() { var e = element; if (e) e.classList.remove('off'); } function setElementOff() { var e = element; if (e) e.classList.add('off'); } function getState() { return state; } function getTemplate() { var trueLabel = '

{{ trueLabel }}

', s = '', falseLabel = '

{{ falseLabel }}

', transition = '{{# transition }}cssTransition="{{ . }}"{{/ transition }}'; return '' + trueLabel + s + falseLabel + ''; } function bindElement() { events.add(element, 'click', toggle); } function exit() { if (events) events.reset(); removeElement(); state = null; config = null; template = null; element = null; target = null; returnCB = null; obj = null; events = null; } function removeElement() { if (element.parentNode === target) target.removeChild(element); } }; var ToggleNavigation = function (target, obj, returnCB) { fixObj(obj); var events = new EventManager, template = new NavigationTemplate().index, navigation = getElementFromString(render(template, obj)), tabs = navigation.querySelectorAll('tab'), tabList = [], hidden = {}, activeTab = null; this.getTabs = getTabs; this.reset = reset; this.set = set; this.setByValue = setByValue; this.showTab = showTab; this.hideTab = hideTab; this.exit = exit; function initialize() { bindTabs(tabs); target.appendChild(navigation); if (isDefined(obj.initialValue)) setByValue(obj.initialValue); } function NavigationTemplate(className) { this.index = '{{# data }}

{{ title }}

{{/ data }}
'; } function Tab(tab, i, active) { var data = obj.data[i]; events.add(tab, 'click', updateActive); if (active) updateActive(); this.set = updateActive; this.show = show; this.hide = hide; function updateActive() { if (activeTab) activeTab.unset(); activeTab = { 'unset': unset, 'index': i }; set(); if (returnCB) returnCB(data, i); } function show() { tab.classList.remove('noDisplay'); delete hidden[i]; } function hide() { if (activeTab.index === i) setNext(); tab.classList.add('noDisplay'); hidden[i] = true; } function set() { tab.classList.add('active'); } function unset() { tab.classList.remove('active'); } function setNext() { for (var v = 0, l = tabList.length; v < l; v++) { if (v !== i && hidden[v] !== true) { tabList[v].set(); return } } } } function bindTabs(t) { for (var i = 0, l = t.length; i < l; i++) { tabList.push(new Tab(t[i], i, i == 0 ? true : false)); } } function getTabs() { var a = []; forEach(tabList, p); return a; function p(t, d, i) { a[i] = t; } } function set(v) { if (v > -1 && v < tabList.length) tabList[v].set(); } function setByValue(v) { var len = tabList.length - 1, c = len; while (c > -1) { var i = len - c--; if (obj.data[i].value === v) { set(i); return true; } } return false; } function showTab(i) { var t = tabList[i]; if (isDefined(t)) t.show(); } function hideTab(i) { var t = tabList[i]; if (isDefined(t)) t.hide(); } function reset() { tabList[0].set(); } function exit() { if (events) events.reset(); target = obj = returnCB = events = template = navigation = tabs = tabList = activeTab = null; } function fixObj(o) { var t = o.data.length, c = t; while (c) { var d = o.data[t - c--]; if (!d.title) d.title = d.value; } } if (target && obj.data) initialize(); }; var TabbedContainer = function (target, obj, returnCB) { var active = null, data = obj.data, config = obj.config || {}, navigationData = getNavigationData(data), containerData = getContainerData(data), template = '
', element = getElementFromString(template), header = element.querySelector('header'), container = element.querySelector('container'), navigation = new ToggleNavigation(header, navigationData, refresh); if (config.prepend !== true) target.appendChild(element); else prependChild(target, element); this.reset = navigation.reset; this.showTab = navigation.showTab; this.hideTab = navigation.hideTab; this.update = update; this.exit = exit; function update(d) { data = d; navigationData = getNavigationData(data); containerData = getContainerData(data); } function refresh(e, i) { var c = containerData[i], d = data[i]; if (isDefined(d.initFn)) initPanel(d); if (active !== null) container.removeChild(active); active = c; container.appendChild(active); if (isDefined(returnCB)) returnCB(i); } function getClassName() { var c = config.className; if (isDefined(c)) { return c; } return 'tabbed'; } function getNavigationData(d) { var a = { 'data': [], 'className': getClassName() }; d.forEach(function (item) { a.data.push({ "value": item.title }); }); return a; } function getContainerData(d) { var a = []; d.forEach(function (item) { a.push(item.element); }) return a; } function initPanel(c) { setTimeout(function (fn) { return function () { fn(); } }(c.initFn), 1); c.initFn = null; } function exit() { if (navigation) navigation.exit(); housekeeping(); } function housekeeping() { target = obj = active = data = config = navigationData = containerData = template = element = header = container = navigation = null; } }; var FileDataManager = function () { var b = void 0, c = void 0, a = void 0, b = new FileReader, c = document.querySelector("body"), a = document.createElement("input"); b.onload = function (a) { window.prompt("Image Data", a.target.result) }; a.type = "file"; c.innerHTML = ""; c.appendChild(a); this.load = function () { b.readAsDataURL(a.files[0]) } }; var __emc = 0; var EventManager = function (debug) { var bindings = getEmptyObj(), referenceTable = getEmptyObj(); this.add = add; this.remove = removeRequest; this.removeAll = removeAll; this.removeByTag = removeByTag; this.reset = reset; function Binding(t, type, fn, tag, keyID, id) { this.t = t; this.type = type; this.fn = fn; this.tag = tag; this.keyID = keyID; this.is = id; } function add(t, type, fn, tag) { if (isValidTag(tag)) { t.addEventListener(type, fn); return insertReference(t, type, fn, tag); } else addError(); return null; } function addError() { console.error('Well, we\'ve encountered an issue. It appears that a protected prefix was used in the tag for this add request. Please refer to the API documentation'); } function removeRequest(t, id) { if (isDefined(t) && isDefined(id)) remove(bindings[t][id]); else removeRequestError(); } function removeRequestError() { console.error("Well shucks, it looks like I'm missing some information. Please include both target and id attributes to remove a single event."); } function remove(b) { if (b) { b.t.removeEventListener(b.type, b.fn); removeReference(b); } } function removeReference(b) { var kID = b.keyID; delete bindings[kID][b.id]; if (bindings[kID].length == 0) delete referenceTable[kID]; } function removeAll(id) { var o = bindings[id]; for (var k in o) { if (k != 'length') remove(o[k]); } } function removeByTag(tag) { var o = bindings; for (var k in o) { if (k !== 'length') processKey(o[k], tag); } function processKey(o, tag) { for (var k in o) { if (isValidRemoval(o[k], tag) && (k != 'length')) remove(o[k]); } } } function reset() { for (var k in bindings) { removeAll(k); } } function insertReference(t, type, fn, tag) { var keyID = setKey(t), o = bindings[keyID], l = o.length; o[l] = new Binding(t, type, fn, tag, keyID, l); return o.length++; } function setTagKey(tag) { if (bindings[tag] === undefined) bindings[tag] = { 'length': 0 }; } function setKey(t) { var k = getKey(t); if (k === null) k = addKey(t, referenceTable, bindings); return k; } function addKey(t, r, b) { if (b[r.length] === undefined) b[r.length] = getEmptyObj(); r[r.length] = t; return r.length++; } function getKey(t) { var o = referenceTable; for (var k in o) { if (k !== 'length' && o[k] == t) return k; } return null; } function getEmptyObj() { return { 'length': 0 }; } function isValidRemoval(t, tag) { return tag === undefined || tag == t.tag; } function isValidTag(tag) { return tag === undefined || tag.indexOf('__') !== 0; } function invalidTagError() { console.error('Sorry, a restricted prefix was used as a tag. Please refer to the documentation for acceptable tag names.'); } }; var Calendar = function (target, options, returnCB) { var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], events = new EventManager(), cal = new CalendarAssistant, template = new Template(), currentDate, element = getElementFromString(''), data = null; this.setToPresent = setToPresent; this.set = set; this.get = function () { return currentDate; }; this.exit = exit; if (!!options && !!options.value) { set(options.value); } else { setToPresent(); } target.appendChild(element); function set(v) { if (isNumber(v)) { // We are expecting the int to be seconds rather than milliseconds return refresh(getDataFromDateObj(new Date(v * 1000))); } if (isDefined(v) && typeof v.toUTCString === 'function') { return refresh(getDataFromDateObj(v)); } if (isDefined(v) && isDefined(v.month) && isDefined(v.monthValue) && isDefined(v.date) && isDefined(v.year)) { return refresh(v); } console.error("Oh noes!", v); } function getDataFromDateObj(v) { return { month: months[v.getUTCMonth()], monthValue: v.getUTCMonth() + 1, date: v.getUTCDate(), year: v.getUTCFullYear(), }; } function setToPresent() { refresh(cal.getCurrentDay()); } function Data(focusDay) { var focusMonth = cal.getMonth(focusDay.month, focusDay.year); this.monthName = focusDay.month this.yearValue = focusDay.year this.days = processDays(getDays(focusMonth[0]), focusDay); this.daysOfWeek = cal.getDaysOfWeek(this.days[0]); this.focusDay = getFocusDay(this.days); } function Day(o, t) { o.element = t; events.add(t, 'click', clickAction, 'tmp'); function clickAction() { updateDay(o); } } function refresh(day, ignore) { events.removeByTag('tmp'); data = new Data(day); repaint(element); bindAll(element); currentDate = getReturnData(data.focusDay); if (ignore !== true && returnCB) returnCB(currentDate); } function getReturnData(d) { var v = !isDefined(d) ? cal.getCurrentDay() : d, o = {}; o.date = v.date; o.display = v.date + ' ' + v.month + ', ' + v.year; o.month = v.month; o.year = v.year; o.monthValue = v.monthValue; o.toDate = function () { return new Date(Date.UTC(o.year, o.monthValue - 1, o.date, 0, 0, 0, 0)); }; o.toUnix = function () { return Date.UTC(o.year, o.monthValue - 1, o.date, 0, 0, 0, 0) / 1000; } return o; } function repaint(e) { var f = getFragment(), gefs = getElementFromString; f.appendChild(gefs(render(template.header, data))); f.appendChild(gefs(render(template.month, data))); element.innerHTML = ''; element.appendChild(f); } function bindAll(e) { bindButtons(e.querySelector('header')); bindDays(e.querySelector('days').querySelectorAll('day')); } function bindPrev(h) { events.add(h.querySelector('prev-button'), 'click', prev); } function bindNext(h) { events.add(h.querySelector('next-button'), 'click', next); } function bindButtons(h) { bindPrev(h); bindNext(h); } function bindDays(m) { forEach(m, bindDay); } function bindDay(t, d, i) { new Day(data.days[i], t); } function getDays(d) { var b = cal.getDaysBefore(d.name), n = cal.getNumberOfDays(d.month, d.year), size = Math.ceil((b + n) / 7) * 7, s = getStartDay(d, b); return cal.getDays(s, size); } function getStartDay(d, b) { if (b === 0) return d; else return getPreviousMonthDay(d, b); } function getPreviousMonthDay(d, b) { var m = cal.getPreviousMonth(d.month, d.year), n = cal.getNumberOfDays(m.name, m.year), s = n - b + 1, day = cal.getDay(m.name, s, m.year); return day; } function getDayClassName(t, f) { if (!isSameMonth(t, f)) return 'grey'; else if (isSameDate(t, f)) return 'focus'; } function getFocusDay(days) { var m = null; forEach(days, check); return m; function check(t) { if (t.className === 'focus') { m = t; return false; } } } function Template() { var calHeaderPrev = '', calHeaderP = '

{{ monthName }}, {{ yearValue }}

', calHeaderNext = '', calHeader = '
' + calHeaderPrev + calHeaderP + calHeaderNext + '
', month = '
{{# daysOfWeek }}{{ abbreviation }}{{/ daysOfWeek }}
{{# days }}{{ date }}{{/ days }}
'; this.header = calHeader; this.month = month; } function isSameDate(t, f) { return t.date === f.date; } function isSameMonth(t, f) { return t.month === f.month; } function prev() { var f = data.focusDay; goTo(cal.getPreviousMonth(f.month, f.year)); } function next() { var f = data.focusDay; goTo(cal.getNextMonth(f.month, f.year)); } function goTo(m) { refresh(cal.getDay(m.name, 1, m.year)); } function processDays(days, focus) { forEach(days, processDay); return days; function processDay(t) { t.className = getDayClassName(t, focus); } } function updateDay(day) { var f = data.focusDay; if (isDefined(f) && day.month == f.month) sameMonthUpdate(day, f); else refresh(day); } function sameMonthUpdate(d, f) { f.element.classList.remove('focus'); d.element.classList.add('focus'); data.focusDay = d; if (returnCB) returnCB(getReturnData(data.focusDay)); } function exit() { if (events) events.reset(); housekeeping(); } function housekeeping() { target = options = returnCB = events = cal = template = element = data = null; } }; var CalendarInput = function (target, options, returnCB) { var events = new EventManager, template = '', element = getElementFromString(template), input = element.querySelector('input'), currentValue = null, cal = new Calendar(element, options, calendarUpdate), calendar = element.querySelector('calendar'), state = false; this.reset = reset; this.exit = exit; this.set = cal.set; this.get = cal.get; hideCalendar(); events.add(element.querySelector('input'), 'click', toggleCalendar); target.appendChild(element); function reset() { cal.setToPresent(); } function set(v) { cal.set(v); } function toggleCalendar() { if (!state) showCalendar(); else hideCalendar(); } function hideCalendar() { events.removeAll(window); calendar.classList.add('noDisplay'); state = false; } function showCalendar() { element.classList[target.getBoundingClientRect().top < 400 ? 'add' : 'remove']('bottom'); events.add(window, 'mousedown', windowClick); calendar.classList.remove('noDisplay'); state = true; } function calendarUpdate(v) { input.value = v.display; if (currentValue != null && v.month == currentValue.month) { hideCalendar(); } currentValue = v; if (returnCB) returnCB(v); } function windowClick(e) { if (!isParentOfTarget(element, e.target)) hideCalendar(); } function exit() { if (events) events.reset(); if (cal) cal.exit(); housekeeping(); } function housekeeping() { target = options = returnCB = events = template = element = input = currentValue = cal = calendar = state = null; } }; var SlideInput = function (target, obj, returnCB) { var data = new Data(obj), template = '{{# separators }}{{/ separators }}{{# nubs }}{{/ nubs }}', element = getElementFromString(render(template, data)), fill = element.querySelector('fill'), dragList = []; target.appendChild(element); init(); this.getValues = getValues; this.setValues = setValues; this.exit = exit; function setValues(a) { if (a.length == data.nubs.length) forEach(data.nubs, p); function p(t, d, i) { t.setPosition(parseFloat(a[i])); } } function init() { bindNubs(); if (returnCB) returnCB(getValues()); } function Data(o) { this.separatorCount = o.separatorCount || 4; this.separators = getSeparators(this.separatorCount); this.nubs = getNubs(o); this.valueRange = o.valueRange; this.prependValue = o.prependValue || null; this.appendValue = o.appendValue || null; this.startValues = o.startValues ? getStartValues(o.valueRange, o.startValues) : null; this.decimalPlaces = isDefined(o.decimalPlaces) ? o.decimalPlaces : 2; } function getStartValues(r, s) { var a = []; if (isDefined(s[0])) a[0] = getValueInRange(r, s[0]); if (isDefined(s[1])) a[1] = getValueInRange(r, s[1]); return a; } function getValueInRange(r, v) { if (v <= r[1]) { // If the value is less than or equal to the max range if (v >= r[0]) return v; // If the value is greater than or equal to the min range, return value else return r[0]; // Else if the value is less than the min range, return min range } else return r[1]; //Else if the value is greater than max, return max } function Nub(key) { var nub = null, nubRects = null, label = { 'element': null, 'value': null, 'content': null }, left = 0, drag = null; this.key = key; this.drag = null; this.dragStart = dragStart; this.dragEnd = dragEnd; this.dragMove = dragMove; this.setElement = setElement; this.setPosition = setPosition; this.getLocation = getLocation; this.getRects = getRects; this.getData = getData; this.setDrag = setDrag; function getRects() { return nubRects; } function getLocation() { return left; } function getPrependage() { if (isDefined(data.prependValue)) return data.prependValue; else return '' } function getAppendage() { if (isDefined(data.appendValue)) return data.appendValue; else return '' } function getLabelValue() { return left !== 0 ? (left / (element.offsetWidth - nubRects.width)) : 0 } function getLabelResult(v) { return parseFloat((v * (data.valueRange[1] - data.valueRange[0])).toFixed(data.decimalPlaces)) } function getLeftValue(v) { return (element.offsetWidth - nubRects.width) * (v / data.valueRange[1] - data.valueRange[0]); } function getData() { return label; } function setDrag(d) { drag = d; dragList.push(d); } function setPosition(v) { setRects(); setLeftPosition(v); setNubPosition(); dragMove(null, left, null, true); drag.setOffsets(); } function setLeftPosition(v) { if (isDefined(v)) left = getLeftValue(v); } function setNubPosition() { nub.style.position = 'absolute'; nub.style.left = left + 'px'; } function setElement(e) { nub = e; label.element = nub.querySelector('label'); } function setRects() { if (!nubRects) nubRects = nub.getClientRects()[0]; } function setLabel() { var l = label; l.value = getLabelResult(getLabelValue()); l.element.textContent = l.content = getPrependage() + l.value + getAppendage(); } function isValid(v) { if (key == 'start' && isStartValid(v)) return true; else if (key == 'end' && isEndValid(v)) return true; else return false; } function isStartValid(v) { if (isDefined(data.nubs[1])) return (data.nubs[1].getLocation() - nubRects.width > v); else return true; } function isEndValid(v) { if (isDefined(data.nubs[1])) return (data.nubs[0].getLocation() + nubRects.width < v); else return true; } function dragStart(e) { nub.classList.add('active'); } function dragMove(e, l, t, force) { setRects(); if (dragCheck(l, force)) dragMoveAction(l); else return false; } function dragEnd(e) { nub.classList.remove('active'); if (returnCB) returnCB(getValues()); } function dragCheck(l, f) { return ((isDefined(l) && isValid(l)) || f); } function dragMoveAction(l) { left = l; setLabel(); setFill(); } } function getValues() { var a = []; forEach(data.nubs, process); return a; function process(t, d, i) { a.push(t.getData()); } } function Separator(v) { this.left = v + '%'; } function setFill() { var nubs = data.nubs; multi = nubs.length > 1, s = multi ? nubs[0] : 0, e = multi ? nubs[1] : nubs[0], sP = multi ? s.getLocation() : 0, eP = e.getLocation(); fill.style.left = (multi ? s.getRects().width / 2 : 0) + sP + 'px'; fill.style.width = (multi ? eP - sP : eP + (e.getRects().width / 2)) + 'px'; } function getSeparators(c) { var v = 100 / (c + 1), a = []; for (var i = 0; i < c; i++) { a.push(new Separator(v * (i + 1))); } return a; } function getNubs(o) { var a = []; if (o.startNub !== false) a.push(new Nub('start')); if (o.endNub !== false) a.push(new Nub('end')); return a; } function bindNubs() { var e = element.querySelectorAll('nub'); forEach(e, process); setFill(); function process(t, d, i) { t = data.nubs[i]; t.element = t.setElement(e[i]); t.setDrag(new DragController(e[i], t.dragStart, t.dragEnd, t.dragMove, { 'xOnly': true, 'inBounds': true, 'autoSet': true })); t.setPosition(data.startValues[i]); } } function exit() { exitDragList(); housekeeping(); } function exitDragList() { forEach(dragList, p, true); function p(t, d, i) { if (t.exit) t.exit(); d.splice(i, 1); } } function housekeeping() { target = obj = returnCB = data = template = element = fill = null; } }; var ConfirmationButton = function (target, obj, returnCB) { var events = new EventManager(true), options = new Options(obj, getDefaultOptions()), template = getTemplate(), element = getElementFromString(render(template, options)), state = 0, timer = null; this.exit = exit; this.resetState = resetState; events.add(element, 'click', clickAction); target.appendChild(element); function clickAction(e) { prevent(e); if (state == 0) confirmState(); else if (state == 1) confirmationSuccess(); } function confirmState() { var e = element, o = options; state = 1; if (!!o.color) e.classList.remove(o.color); if (!!o.confirmColor) e.classList.add(o.confirmColor); e.textContent = o.confirmText; setTimer(); } function confirmationSuccess() { resetState(); if (returnCB) returnCB(true); } function resetState() { var e = element, o = options; state = 0; if (!!o.confirmColor) e.classList.remove(o.confirmColor); if (!!o.color) e.classList.add(o.color); e.textContent = o.text; clearTimer(); } function prevent(e) { if (e && e.preventDefault) e.preventDefault(); } function Options(o, dO) { this.text = getOptionValue('text', o, dO); this.confirmText = getOptionValue('confirmText', o, dO); if (o.noClass !== true) { this.className = getOptionValue('className', o, dO); this.color = getOptionValue('color', o, dO); this.confirmColor = getOptionValue('confirmColor', o, dO); } else { this.noClass = true; this.className = ""; this.color = ""; this.confirmColor = ""; } } function getOptionValue(k, o, dO) { if (!isDefined(o[k])) return dO[k]; else return o[k]; } function getDefaultOptions() { return { 'className': '', 'color': 'cool', 'confirmColor': 'hot', 'text': 'Click', 'confirmText': 'Confirm' }; } function getTemplate() { return '{{ text }}'; } function setTimer() { clearTimer(); timer = setTimeout(resetState, 3000); } function clearTimer() { if (timer) clearTimeout(timer); timer = null; } function exit() { events.reset(); target = obj = returnCB = events = options = template = element = state = timer = null; } }; // Multi Select // - The only required field is target // - Return callback will return the selected values // - Options are used to set classes, that's currently the only functionality var MultiSelect = function (target, returnCB, options) { var itemArray = undefined, select = undefined, selectData = undefined, selectReplacement = undefined, items = undefined, multiSelect = undefined, MultiSelectState = true, initialLoad = true, self = this; initialize(); MultiSelectState = true; this.disable = disable; this.enable = enable; this.update = update; this.value = getValue; this.getSelected = getSelected; this.setSelectedByValue = setSelectedByValue; this.ele = target; function initialize() { select = target.querySelector('select'); selectData = getSelectData(select); selectReplacement = createSelectReplacement(target, select); multiSelect = createMultiSelect(target, createMenuItems(selectData), select); insertMultiSelect(target, multiSelect); if (options && isArray(options.selected)) { setSelectedByValue(options.selected); } initialLoad = false; } function bindMenuItem(element, item) { var closure = function (item) { return function (e) { updateMultiSelect(e, item); } }(item); element.addEventListener('click', closure); } function disable() { closeDropDown(); dropDownState = false; } function enable() { dropDownState = true; } function update(i) { updateMultiSelect(null, itemArray[i]); } function updateMultiSelect(e, item) { if (e && e.preventDefault) e.preventDefault(); update(); function update() { if (!item.active) setItemActive(item); else setItemDisabled(item); updateSelectReplacement(item); if (returnCB && !initialLoad) returnCB(item, self); } } function setItemActive(t) { t.active = true; t.element.classList.add('active'); } function setItemDisabled(t) { t.active = false; t.element.classList.remove('active'); } function updateSelectReplacement() { var string = '', count = 0; for (var i = 0, t = itemArray, l = t.length; i < l; i++) { var item = t[i]; if (item.active) { string += (count > 0 ? ', ' : '') + item.text; count++; } } selectReplacement.value = string; } function getValue() { return itemArray[activeItem].value; } function getSelected() { var o = []; for (var i = 0; i < itemArray.length; i++) { var it = itemArray[i]; if (it.active) o.push({ title: it.text, value: it.value, index: it.index }); } return o; } function setSelectedByValue(values) { for (var i = 0; i < itemArray.length; i++) { var it = itemArray[i]; if (values.indexOf(it.value) !== -1) { setItemActive(it) } } } function createSelectReplacement(target, select) { var hidden = document.createElement('input'), name = select.getAttribute('name'); hidden.name = name; hidden.type = 'hidden'; return hidden; } function createMultiSelect(target, items, select) { var t = document.createElement('div'); t.className = getTargetClassName('multiSelect', 'multiSelectMenu') + ' ' + select.className; t.appendChild(items); return t; } function createMenuItems(selectData) { var fragment = document.createDocumentFragment(); itemArray = []; for (var i = 0, d = selectData, l = d.length; i < l; i++) { var item = d[i], element = document.createElement('div'), p = document.createElement('p'); item.element = element; item.index = i; p.textContent = item.text; element.appendChild(p); element.className = getTargetClassName('menuItem', 'menuItem quickTransition'); bindMenuItem(element, item); itemArray.push(item); fragment.appendChild(element); } return fragment; } function getTargetClassName(k, s) { var o = options; if (o && o[k] && o[k].className) s += ' ' + o[k].className; return s; } function insertMultiSelect(target, dropDown) { target.innerHTML = ''; target.appendChild(dropDown); target.appendChild(selectReplacement); return dropDown; } }; var AdGroupAdCountUpdate = function (adGroupID, delta, userID, returnCB) { var data = null, adCount = 0; if (isValid()) new ApiManager({ 'adsList': null }, userID, init); function init(e, d) { data = d; if (isDefined(d.adsList)) updateGroup(d.adsList); else returnCB(null); } function isValid() { return (adGroupID && isDefined(delta) && isNumber(delta) && userID && returnCB) } function updateGroup(d) { forEach(d, p); apiRequest('GET', 'adGroups', adGroupID, null, update); function p(t) { if (t.data.group == adGroupID) adCount++; } } function update(e) { e.adCount = adCount; apiRequest('PUT', 'adGroups', adGroupID, e, requestCB); } function requestCB() { returnCB(data.adGroups); } }; var ApiUpdate = function (o, userID, returnCB) { var d = {}, l = getObjectLength(o), c = 0; for (var k in o) { new Item(o[k], o, k); } function Item(t, o, k) { var c = {}; c[k] = null; new ApiManager(c, userID, setNew); function setNew(error, d) { update(getVal(getData(error, d, k), t)); } function getData(e, d, k) { if (!e) d = d[k]; else if (isEmpty(e)) d = []; return d; } function getVal(d, t) { d[getArrayLocation(d, t)] = t; return d; } function getArrayLocation(d, t) { if (isDefined(t.displayOrder)) { if (t.displayOrder !== '') { var v = getUpdateID(d, t.displayOrder); if (v !== null) return v; } t.displayOrder = getNextID(d); } return d.length; } function getNextID(d) { return d.length > 0 ? d[d.length - 1].displayOrder + 1 : 1; } function getUpdateID(d, v) { var m = null; forEach(d, p); return m; function p(t, d, i) { if (t.displayOrder === v) { m = i; return false; } } } function isEmpty(e) { return e[0].error == getAPIErrorMessage('noMatch'); } function update(d) { apiRequest('PUT', k, userID, d, check); } } function check() { c++; if (c == l && returnCB) returnCB(true); } } var ApiManager = function (o, userID, returnCB) { var c = getObjectLength(o), l = 0, error = null, state = true; if (o) process(o); this.abort = abort; function process(o) { for (var k in o) { new Api(k, o); } } function readyCheck() { l++; if (isReady() && returnCB && state === true) returnCB(error, o); } function isReady() { return c === l; } function pushError(m) { if (error == null) error = []; error.push(m); } function Api(k, o) { var v = o[k] || {}; if (v.type != 'jsonP') { if (!!v.source) apiRequest('GET', v.source, v.noID ? null : userID, null, apiCB, v.args); else apiRequest('GET', k, v.noID ? null : userID, null, apiCB, v.args); } else jsonpRequest(v.source, jsonPCB, 'callback', 15000); function apiCB(d, status) { if (status === 200) o[k] = d; else { o[k] = null; pushError({ 'error': isDefined(d) && isDefined(d.error) ? d.error : "Error", 'status': status }); } readyCheck(); } function jsonPCB(d) { o[k] = d; readyCheck(); } } function abort() { state = false; } }; var ApiImageDelete = function (core, data, selectedRows, returnCB) { var count = 0, total = selectedRows.length; check(); function check() { if (count < total) new Request(selectedRows[count++]); else returnCB(true); } function Request(row) { var c = 0, t = 0, d = row.getData(); if (!!d.imageKey) { c++; new HttpRequest('DELETE', '/api/v1/images/' + d.imageKey, null, null, 'json', rCheck); } if (!!d.logoKey) { c++; new HttpRequest('DELETE', '/api/v1/images/' + d.logoKey, null, null, 'json', rCheck); } if (!!d.backupBannerKey) { c++; new HttpRequest('DELETE', '/api/v1/images/' + d.backupBannerKey, null, null, 'json', rCheck); } if (c === 0) check(); function rCheck() { if (++t === c) check(); } } }; var ApiMarketingDelete = function (core, data, labelKeys, selectedRows, apiName, returnCB) { var requestCount = 0, completeCount = 0, responseArray = []; forEach(selectedRows, initRequest); function initRequest(row, rows, i) { requestCount++; new Request(row, rows, i); } function Request(row, rows, i) { var rdata = !!row.getData ? row.getData() : row; new HttpRequest('DELETE', '/api/v1/' + apiName + '/' + rdata.id, null, null, 'json', cb); function cb(e, statusCode) { if (statusCode == 200) setSuccess(); else setError(e); } function setError(e) { responseArray[i] = { "success": false }; if (e.error) responseArray[i] = { error: true, message: e.message }; requestComplete(); } function setSuccess() { responseArray[i] = { "success": true }; requestComplete(); } } function getDBUpdateObj(d, lk) { var o = {}; for (var k in lk) { var v = d[lk[k]]; if (isDefined(v)) o[k] = v; else o[k] = 0; } return o; } function requestComplete() { if (++completeCount == requestCount) returnCB(responseArray); } }; var ApiReqGroup = function (items, returnCB) { var reqCnt = items.length, finCnt = 0, errCnt = 0; loop(items, req); function req(k, v) { new HttpRequest(v.method, v.url, v.data, 'json', 'json', cb); } function cb(e, sC) { if (sC !== 200) errCnt++; if (++finCnt == reqCnt) returnCB(errCnt > 0); } }; function ApiReqItem(method, url, data) { this.method = method; this.url = url; this.data = data; } var ApiDelete = function (data, selectedRows, apiName, userID, returnCB) { var c = getSimpleJSONCopy(data.table.rows), errors = [], responses = [], count = 0, total = selectedRows.length; forEach(selectedRows, p); function p(t, sR, i) { delRow(t, i); } function delRow(t, i) { var e = t.getElement(), name = e.querySelector('.nameColumn'), span = name.querySelector('span'), data = t.getData(); t.unset(); span.className = 'deleting'; apiRequest('DELETE', apiName, data.id, data, cb) } function cb(e, d) { populateArrays(e, d); completeCheck(); } function populateArrays(e, d) { errors[count] = e; responses[count] = d; } function isComplete() { return ++count == total; } function completeCheck() { if (isComplete()) returnCB(errors, responses); } }; var ApiAdGroupDelete = function (data, selectedRows, userID, returnCB) { var adsList = null, count = 0, total = selectedRows.length, results = {}; apiRequest('GET', 'adsList', userID, null, init) function init(d) { adsList = d; forEach(selectedRows, checkGroup); } function checkGroup(group) { var match = false; forEach(adsList, check) if (match === false) new Delete(group); else deletionError(group); function check(ad, adsList, i) { if (group.getData().id == ad.data.group) { match = true; return true; } } } var Delete = function (group) { var id = group.getData().id apiRequest('DELETE', 'adGroups', id, null, cb); function cb(e, d) { results[id] = { 'success': d == 200 }; if (isDefined(e.error)) results[id].error = e.error; requestCheck(); } } function deletionError(group) { results[group.getData().id] = { 'success': false, 'error': 'One or more ads still exist which are using this Ad Group' }; requestCheck(); } function requestCheck() { if (++count == total) returnCB(results); } }; var ApiDuplicate = function (data, selectedRows, apiName, userID, returnCB) { var d = selectedRows, count = 0, total = d.length; check(); function check() { if (count < total) duplicateRow(d[count], count++); else returnCB(); } function duplicateRow(t, i) { var e = t.getElement(), name = e.querySelector('.nameColumn'), span = name.querySelector('span'); t.unset(); span.className = 'duplicating'; apiRequest('POST', apiName, userID, t.getData(), check); } }; var ApiChangeAdGroup = function (data, selectedRows, targetAdGroup, apiName, userID, returnCB) { var d = selectedRows, count = 0, total = d.length; check(); function check() { if (count < total) changeRow(d[count], count++); else returnCB(); } function changeRow(t, i) { var e = t.getElement(), name = e.querySelector('.nameColumn'), span = name.querySelector('span'); t.unset(); span.className = 'saving'; var rD = t.getData(); rD.group = targetAdGroup; apiRequest('PUT', apiName, rD.id, rD, check); } }; var ApiAdPause = function (data, selectedRows, getIdFn, state, userID, returnCB) { var d = selectedRows, count = 0, total = d.length; check(); function check() { if (count < total) changeRow(d[count], count++); else returnCB(); } function changeRow(t, i) { var e = t.getElement(), name = e.querySelector('.nameColumn'), span = name.querySelector('span'); t.unset(); span.className = 'saving'; var rD = t.getData(); rD.active = state; rD.group = getIdFn(rD.group) apiRequest('PUT', 'ads', rD.id, rD, check); } }; var ApiPause = function (data, selectedRows, apiName, state, userID, returnCB) { var d = selectedRows, count = 0, total = d.length; check(); function check() { if (count < total) changeRow(d[count], count++); else returnCB(); } function changeRow(t, i) { var e = t.getElement(), name = e.querySelector('.nameColumn'), span = name.querySelector('span'); t.unset(); span.className = 'saving'; var rD = t.getData(); rD.active = state; apiRequest('PUT', apiName, rD.id, rD, check); } }; var MailSend = function (core, template, data, subject, toEmail, toName, returnCB) { if (isValid()) request(); function Data(template, data, subject, toEmail, toName) { this.template = template; this.data = data; this.subject = subject; this.toEmail = toEmail; this.toName = toName; } function request() { new HttpRequest('POST', '/sendMail', new Data(template, data, subject, toEmail, toName), 'json', null, returnCB); } function isValid() { var iD = isDefined; return iD(core) && iD(data) && iD(toEmail) && iD(toName); } } var MailPixelInstructions = function (core, toEmail, returnCB) { new MailSend(core, 'index', { 'id': core.userID }, core.brand.name + ' - Pixel placement instructions', toEmail, 'Webmaster', returnCB); }; var AdSet = function (obj, hiddenInput, resultElement, optional) { var ads = [], resultImage = resultElement.querySelector('img'), current = new Ad; optional = optional || {}; this.getAds = getAds; this.resetAds = resetAds; this.push = push; this.setValue = setValue; this.getValue = getValue; this.setCurrentImage = setCurrentImage; this.isValid = isValid; this.getAdCount = getAdCount; function push(ad) { for (var k in obj) { ad[k] = obj[k]; } ads.push(current); } function setCurrentImage(d, i) { current.image = getImage(d, i); push(current); current = new Ad; } function setValue(k, v) { if (obj[k] !== undefined) { obj[k] = v; setAds(k, v); return true; } return false; } function getValue(k) { return obj[k]; } function setAds(k, v) { forEach(ads, process); function process(t) { t[k] = v; } } function getAds() { var a = []; forEach(ads, process); return a; function process(t, d, i) { a[i] = t; } } function getAdCount() { return ads.length } function resetAds() { ads = []; } function isValid() { for (var k in obj) { var t = obj[k]; if (!optional[k] && (t == null || t.length === 0)) return false; } return true; } function Ad(o) { var valid = false, i = null; this.image = null; this.isValid = isValid; this.setIndex = setIndex; for (var k in o) { if (this[k] == undefined) this[k] = o[k]; } function setIndex(v) { i = v; } function validate() { if (this.image !== null && hasObjKeys(o)) valid = true; else valid = false; } function hasObjKeys(o) { for (var k in o) { if (!isDefined(this[k])) return false; } return true; } function isValid() { return valid; } } function Image(data, rects, name, fileSize) { this.data = data; this.width = rects.width; this.height = rects.height; this.name = name; this.fileSize = fileSize; } function getImage(d, i) { var f = hiddenInput.files[i]; return new Image(d.result, getImageRects(resultImage), f.name, getKilobytesFromBytes(f.size) + 'K'); } function getImageRects(t) { var o = t.getClientRects()[0]; return { 'width': o.width, 'height': o.height }; } }; var AdImage = function (data, name, width, height) { this.data = data; this.width = width; this.height = height; this.name = name; this.fileSize = getKilobytesFromBytes(getStringByteValue(data)) + 'K'; }; var AdBatchData = function (imageData, name, width, height, adGroup, landingURL, data) { this.image = new AdImage(imageData, name, width, height); this.adGroup = adGroup; this.data = data; this.landingURL = landingURL; }; var AdSave = function (core, ads, adType, userID, returnCB) { var iK = null, adBatchData = null; if (ads && adType) uploadImageBatch(setImageBatch(ads)); else console.error('Well it appears as though I have undefined ads and/or adType, would you mind fixing that? Thanks!'); function setImageBatch(ads) { var a = []; forEach(ads, p); return a; function p(t) { a.push(t.image); } } function setAdBatch(keys) { var a = []; forEach(ads, p); adBatchData = a; uploadAdBatch(a); function p(t, d, i) { a.push(new AdBatchItem(t, keys[i])); } } function AdBatchItem(t, imageResponse) { var w = Math.round(t.image.width), h = Math.round(t.image.height); this.imageKey = imageResponse.id; this.imageLocation = imageResponse.location; this.active = true; this.name = t.image.name; this.size = w + 'x' + h; this.width = w; this.height = h; this.group = t.adGroup; this.imps = 0; this.clicks = 0; this.conv = 0; this.adType = adType; this.titleText = t.titleText || null; this.captionText = t.captionText || null; this.bodyText = t.bodyText || null; this.data = t.data || null; this.landingURL = t.landingURL; this.clickTrack = t.clickTrack; this.impTrack = t.impTrack; } function uploadImageBatch(iB) { var count = 0, max = iB.length, errors = 0, a = []; request(); function check(v) { if (v) { if (v.error && !!v.message) { uploadComplete(v.message); return; } a.push(v); } if (count < max) { request(); } else { setAdBatch(a); } } function request() { apiRequest('POST', 'images', core.userID, iB[count++], check); } } function uploadAdBatch(aB) { var count = 0, max = aB.length, a = []; request(); function check(v) { if (v) a.push(v.id); if (count < max) request(); else new AdGroupProcess(); } function request() { apiRequest('POST', 'ads', core.userID, aB[count++], check); } } function isEmpty(error, d) { return d.ads === null || (error != null && error[0].error == getAPIErrorMessage('noMatch')); } function AdGroupProcess() { var adGroupHash = {}, updateCount = 0, completeCount = 0; if (adBatchData.length > 0) forEach(adBatchData, setChanges); processAdGroupHash(); function setChanges(t) { if (adGroupHash[t.group] === undefined) { updateCount++; adGroupHash[t.group] = 1; } else adGroupHash[t.group]++; } function processAdGroupHash() { for (var k in adGroupHash) { new AdGroupAdCountUpdate(k, adGroupHash[k], core.userID, adGroupUpdateCB); } } function adGroupUpdateCB() { completeCount++; if (updateCount == completeCount) uploadComplete(); } } function uploadComplete(e) { if (returnCB) returnCB(e); } }; var DynamicSave = function (core, ad, userID, returnCB) { var iK = null, adBatchData = null; if (!!ad) uploadImageBatch([ad.logo, ad.backupBanner]); else console.error('Well it appears as though I have an undefined ad, would you mind fixing that? Thanks!'); function AdBatchItem(t, imageResponses) { var w = 300, h = 250; this.active = true; this.name = 'Dynamic Ad - ' + w + 'x' + h; this.size = w + 'x' + h; this.width = w; this.height = h; this.group = t.adGroup; this.adType = 'dynamic'; this.logoKey = imageResponses[0].id; this.logoLocation = imageResponses[0].location; this.buttonText = t.buttonText; this.landingURL = t.backupLandingUrl; this.backupBannerKey = imageResponses[1].id; this.backupBannerLocation = imageResponses[1].location; this.adTemplate = t.adTemplate; this.preImageContent = t.preImageContent; this.postImageContent = t.postImageContent; this.footerContent = t.footerContent; this.clickTrack = t.clickTrack; this.impTrack = t.impTrack; } function uploadImageBatch(iB) { var count = 0, max = iB.length, a = []; request(); function check(v, sC) { if (sC !== 200) { returnCB("Error saving image.") } else { if (v) a.push(v); if (count < max) request(); else apiRequest('POST', 'ads', core.userID, new AdBatchItem(ad, a), adGroupProcess); } } function request() { apiRequest('POST', 'images', core.userID, iB[count++], check); } } function adGroupProcess() { new AdGroupAdCountUpdate(ad.adGroup, 1, core.userID, uploadComplete); } function uploadComplete(e) { if (returnCB) returnCB(e); } }; var EnterInput = function (input, returnCB) { var events = new EventManager; if (input && returnCB) events.add(input, 'keyup', kuAction); this.exit = exit; function kuAction(e) { if (e.keyCode === 13) returnCB(); } function exit() { events.reset(); events = input = returnCB = null; } }; function AlertModal(obj, returnCB, preInit) { if (!obj.actionOneClass) obj.actionOneClass = 'grey'; if (!obj.actionTwoClass) obj.actionTwoClass = 'cool'; var events = new EventManager(), template = new Template, modal = new Modal({ 'title': obj.title, 'contents': render(template.index, obj) }, falseCB, preInit), element = modal.element, footer = element.querySelector('footer'), anchors = footer.querySelectorAll('a'); if (obj.NoFooter) footer.classList.add('noDisplay'); setTimeout(init, 1); this.close = close; function init() { events.add(anchors[0], 'click', falseCB); events.add(anchors[1], 'click', trueCB); } function trueCB(e) { preventDefault(e); if (returnCB) returnCB(true, element); close(); } function falseCB(e) { preventDefault(e); if (returnCB) returnCB(false); close(); } function close() { if (modal) modal.close(); if (events) events.reset(); housekeeping(); } function housekeeping() { events = template = element = footer = anchors = modal = null; } function Template() { var div = '
{{ message }}
', footer = ''; this.index = div + footer; } } function BillingUpdate(uid, fns, returnCB) { var events = new EventManager, template = new Template, fragment = getFragment(), modal = new Modal({ 'title': 'Please add your billing info to continue:', 'className': 'editBilling doubleColumnForm' }), element = modal.element, billing = new BillingModule(uid, fns, fragment, {}, init, billingCB), footer = getElementFromString(template.footer), anchors = footer.querySelectorAll('a'); this.close = close; function init() { fragment.appendChild(footer); modal.element.querySelector('.inner').appendChild(fragment); events.add(anchors[0], 'click', falseCB); events.add(anchors[1], 'click', trueCB); } function trueCB() { billing.save(); } function falseCB() { if (returnCB) returnCB(false); close(); } function billingCB(e) { close(); returnCB(e); } function close() { if (modal) modal.close(); if (events) events.reset(); housekeeping(); } function housekeeping() { events = template = element = footer = anchors = modal = null; } function Template() { var footer = ''; this.footer = footer; } } var BillingModule = function (uid, fns, target, data, readyCB, returnCB) { var events = new EventManager, template = new BillingTemplate, invalidHash = getInvalidHash(), data = null, renderObj = null, element = null, elements = null, inboundData = null; new ApiManager({ 'billing': null, 'billingHistory': null }, uid, init); this.exit = exit; this.save = saveAction; this.element = element; function Data(d) { this.advanced = new Advanced; this.basic = new Basic(d); function Advanced() { this.firstName = null; this.lastName = null; this.cardholderName = null; this.cardNumber = null; this.month = null; this.year = null; this.cvv = null; } function Basic(d) { this.addressOne = d.addressOne; this.addressTwo = d.addressTwo; this.city = d.city; this.state = d.state; this.zip = d.zip; this.lastFour = d.lastFour; this.insertionOrder = d.insertionOrder; } } function init(error, d) { var billing = isDefined(d.billing) ? d.billing : {}; inboundData = billing; data = new Data(billing); element = getElementFromString(render(template.card, { 'billing': data })), elements = new Elements(element, { 'firstName': { 'selector': '.firstName' }, 'lastName': { 'selector': '.lastName' }, 'cardNumber': { 'selector': '.cardNumber' }, 'month': { 'selector': '.month' }, 'year': { 'selector': '.year' }, 'cvv': { 'selector': '.cvv' }, 'addressOne': { 'selector': '.addressOne' }, 'addressTwo': { 'selector': '.addressTwo' }, 'city': { 'selector': '.city' }, 'state': { 'selector': '.state' }, 'zip': { 'selector': '.zip' } }); var e = elements; events.add(e.firstName, 'change', updateFirstName); events.add(e.lastName, 'change', updateLastName); events.add(e.cardNumber, 'change', updateCardNumber); events.add(e.month, 'change', updateMonth); events.add(e.year, 'change', updateYear); events.add(e.cvv, 'change', updateCVV); events.add(e.addressOne, 'change', updateAddressOne); events.add(e.addressTwo, 'change', updateAddressTwo); events.add(e.city, 'change', updateCity); events.add(e.state, 'change', updateState); events.add(e.zip, 'change', updateZip); insertElement(); if (readyCB) readyCB(); } function insertElement() { target.appendChild(element); } function updateFirstName(e) { updateData('firstName', e.target.value, true); } function updateLastName(e) { updateData('lastName', e.target.value, true); } function updateCardNumber(e) { updateData('cardNumber', e.target.value, true); } function updateMonth(e) { updateData('month', e.target.value, true); } function updateYear(e) { updateData('year', e.target.value, true); } function updateCVV(e) { updateData('cvv', e.target.value, true); } function updateAddressOne(e) { updateData('addressOne', e.target.value); } function updateAddressTwo(e) { updateData('addressTwo', e.target.value); } function updateCity(e) { updateData('city', e.target.value); } function updateState(e) { updateData('state', e.target.value); } function updateZip(e) { updateData('zip', e.target.value); } function updateData(k, v, adv) { data[adv !== true ? 'basic' : 'advanced'][k] = v; } function saveAction(e) { var basicUpdate = true, advUpdate = false, completeCount = 0; if (e && e.preventDefault) e.preventDefault(); var adv = data.advanced, basic = data.basic; if (!isDefined(basic.lastFour)) advUpdate = true; var invalid = getInvalidItems(advUpdate ? adv : null, basicUpdate ? basic : null); if (invalid === null) { if (advUpdate) { basic.lastFour = getLastFour(adv.cardNumber); basicUpdate = true; } save(); } else setMissing(invalid); function save() { if (basicUpdate) saveBasic(); if (advUpdate) saveAdvanced(); } function saveBasic() { apiRequest('PUT', 'billing', uid, data.basic, completeCheck); } function saveAdvanced() { apiRequest('PUT', 'billingAdvanced', uid, data.advanced, completeCheck); } function completeCheck(e) { var c = 0; completeCount++; if (basicUpdate == true) c++; if (advUpdate == true) c++; if (c == completeCount) saveComplete(true); } function saveComplete(e) { if (returnCB) returnCB(e); } function isSetEmpty(d) { var c = 0; for (var k in d) { if (isDefined(d[k])) c++; } return c === 0; } } function setMissing(a) { if (!!fns && !!fns.setMissingFields) fns.setMissingFields(a); } function getLastFour(s) { return s.slice(s.length - 4); } function getInvalidHash() { return { 'firstName': 'First name', 'lastName': 'Last name', 'cardNumber': 'Card number', 'month': 'Month', 'year': 'Year', 'cvv': 'CVV', 'addressOne': 'Address One', 'city': 'City', 'state': 'State', 'zip': 'Zip', }; } function getInvalidItems(adv, basic) { var a = []; check(basic); if (isDefined(adv)) checkAdvanced(adv); return a.length > 0 ? a : null; function checkAdvanced() { var cI = checkItem; check(adv); if (!cI(adv.cardNumber)) checkCardNumber(adv); if (!cI(adv.month)) checkMonth(adv); if (!cI(adv.year)) checkYear(adv); } function checkCardNumber(d) { var s = d.cardNumber.replace(/[ ]/g, ''); d.cardNumber = s; if (isValidCardLength(s.length)) a.push('Invalid card number length'); if (s.indexOf(/[0-9]/g) > -1) a.push('Invalid card number characters'); } function checkMonth(d) { if (d.month.length !== 2 || d.month.indexOf(/[a-zA-Z]/g) > -1) a.push('Please set month the two-digit numeric representation'); else if (!isValidMonth(d.month)) a.push('Please set valid month'); } function checkYear(d) { if (d.year.length !== 2 || d.year.indexOf(/[a-zA-Z]/g) > -1) a.push('Please set year the two-digit numeric representation'); } function isValidCardLength(l) { return l < 15 || l > 19; } function isValidMonth(s) { var v = parseFloat(s); if (!isNaN(v) && v > -1 && v < 13) return true; return false; } function check(d) { for (var k in d) { var s = invalidHash[k]; if (checkItem(d[k]) && isDefined(s)) { a.push('Missing ' + s); } } } function checkItem(t) { return (!isDefined(t) || t.length === 0); } } function exit() { if (element) removeChild(target, element); if (events) events.reset(); if (elements) elements.exit(); housekeeping(); } function housekeeping() { target = data = returnCB = events = data = template = element = elements = inboundData = null; } }; var Modal = function (obj, returnCB, preInit) { 'use strict'; var events = new EventManager(), template = new Template(), element = getElementFromString(template.index, obj); setTimeout(init, 1); this.close = close; this.element = element; function init() { events.add(element.querySelector('.modalClose'), 'click', eventClose); events.add(element, 'click', childCheck); if (typeof preInit === 'function') preInit(element, events); document.body.appendChild(element); } function eventClose() { if (returnCB) returnCB(); close(); } function close() { if (element) removeChild(document.body, element); if (events) events.reset(); housekeeping(); } function housekeeping() { events = element = null; } function childCheck(e) { if (e.target === element) eventClose(); } function Template() { var header = '

{{ title }}

', inner = '
' + header + '{{ contents }}
'; this.index = '
' + inner + '
'; } }; function jsonpRequest(src, cb, cbKey, timeoutDuration) { var tD = isDefined(timeoutDuration) ? timeoutDuration : 3000; if (src && cb) request(src, cb, cbKey); else errorResponse(); function request(src, cb, cbKey) { if (!cbKey) cbKey = 'callback'; cycle(src, cb, cbKey); } function cycle(src, cb, cbKey) { var target = initScript(src, cb, cbKey); addScript(target); } function errorResponse() { console.error('Well shoot, it looks like I\'m missing some essential arguments. Please try again!'); } function addScript(target) { var head = getDocumentHead(); head.appendChild(target); } function setLoadTimer(cb) { setTimeout(function () { if (window[cb]) window[cb](); }, tD); } function removeScript(target) { var head = getDocumentHead(); head.removeChild(target); target = null; } function initScript(src, cb, cbKey) { var target = document.createElement('script'), jsoncb = getCallback(cb, cbKey, target); target.type = 'text/javascript'; target.src = src + jsoncb; return target; } function getDocumentHead() { return document.head || document.getElementsByTagName('head')[0]; } function getCallback(cb, cbKey, target) { var cbName = 'jsonPCallback' + (new Date().getTime()) + getRandomInt(10000, 99999), closure = getClosure(cb, cbName, target); window[cbName] = closure; setLoadTimer(cbName); return getQueryChar(src) + cbKey + '=' + cbName; } function getQueryChar(s) { return s.indexOf('?') > -1 ? '&' : '?'; } function getClosure(cb, cbName, target) { var closure = function (cb, cbName, target) { return function (e) { if (isDefined(window[cbName])) { cb(e); window[cbName] = undefined; removeScript(target); } } }(cb, cbName, target); return closure; } }; function HttpRequest(method, url, data, requestType, responseType, returnCB) { var request = null; if (url && returnCB) cycle(); else cycleError(); function cycle() { if (!isDefined(requestType)) requestType = 'text'; method = method.toUpperCase(); request = new XMLHttpRequest(); openRequest(); setResponseType(); setMethod(); setRequest(); sendRequest(); } function cycleError() { console.error("Uh oh! I need both URL and Callback to perform an HTTP Request."); } function openRequest() { request.open(method, url + (url.indexOf('?') > -1 ? '&' : '?') + "ts=" + new Date().getTime(), true); } function getRequestData() { if (!isDefined(data)) return null; else return rdProcess(); } function rdProcess() { switch (requestType) { case 'text': return rdProcessText(); case 'json': return rdProcessJSON(); } console.error('unknown request type', requestType); } function rdProcessText() { setRequestHeaders(request, 'text/plain'); return data; } function rdProcessJSON() { setRequestHeaders(request, 'application/json'); return JSON.stringify(data); } function setRequestHeaders(r, contentType) { r.setRequestHeader('Content-type', contentType); } function setRequest() { request.responseType = responseType; request.onload = response; } function setResponseType() { if (!isDefined(responseType)) responseType = 'text'; } function setMethod() { if (!isDefined(method)) method = 'GET'; } function sendRequest() { var d = getRequestData(); request.send(d); } function response() { if (returnCB) returnCB(getData(), request.status); request = null; } function getData() { if (responseType == 'text') return request.responseText; else return request.response; } } function prependChild(t, c, limit) { t.insertBefore(c, t.firstChild); if (typeof limit === 'number' && t.children.length > limit) t.removeChild(t.lastChild); } function popAnchor(e) { if (e && e.preventDefault) e.preventDefault(); pop('Pop!', 'Dashboard', e.target.getAttribute('href')); } function pop(str, title, url) { window.history.pushState({ 'foo': 'bar' }, title, url); if (isFunction(window.ic) && window.intercomSetting) { // intercom.io ic('reattach_activator'); ic('update', intercomSettings); } } (function (h) { var pushState = h.pushState; h.pushState = function (s) { if (typeof h.onpushstate == "function") h.onpushstate({ 'state': s }); return pushState.apply(h, arguments); } })(window.history); function FileToImageData(i, cb) { var fr = new FileReader, f = i.files, c = 0, l = f.length, a = [], i = 0; fr.onload = check; read(); function check(e) { var r = e.target.result; if (r) a.push({ 'e': e, 'result': r }); if (c++ + 1 == l) cb(a); else read(); } function read() { if (fr.readAsDataURL.result !== null) fr.readAsDataURL(f[i++]); } } /* Calendar Manager - Compiled */ function CalendarAssistant() { function p(a, d) { function b(a, b) { var d = []; c(a, b, function (a, b) { var c = b + a.date, e = h(a.month, c, a.year); e.number = c; d.push(e) }); return d } function e() { var c = q(a.month, a.year); return b(a, f).concat(p(h(c.name, 1, c.year), d - f)) } function c(a, b, d) { for (var c = 0; c < b; c++) d(a, c) } var f = getNumberOfDays(a.month, a.year) - a.date + 1; return f >= d ? b(a, d) : e() } function h(a, d, b) { var e = parseFloat(b.toString().substr(2, 2)), c = { January: 3, February: 6, March: 6, April: 2, May: 4, June: 0, July: 2, August: 5, September: 1, October: 3, November: 6, December: 1 }[a], f = e / 4; 0 != f % 1 ? f = Math.floor(f) : "January" != a && "February" != a || (0 != e || 0 != e % 400) && 0 == e || (c -= 1); e = "Saturday Sunday Monday Tuesday Wednesday Thursday Friday".split(" ")[(4 + e + f + c + parseFloat(d)) % 7]; var vv = new s(a, d, b, e, e.substr(0, 3)) return vv; } function s(a, d, b, e, c) { this.month = a; this.monthValue = g[a]; this.name = e; this.element = null; this.abbreviation = c || null; this.number = this.className = null; this.__defineGetter__("date", function () { return d }); this.__defineSetter__("date", function () { return !1 }); this.__defineGetter__("year", function () { return b }); this.__defineSetter__("year", function () { return !1 }) } function q(a, d) { var b = null, b = g[a]; void 0 == d && (d = n().year); "December" !== a ? b = k[b] : (b = k[0], d++); return { name: b, year: d } } function n() { var a = new Date; return h(r(a.getMonth()), a.getDate(), a.getFullYear()) } function r(a) { return t[a] } var k = "January February March April May June July August September October November December".split(" "), m = [{ name: "Sunday", abbreviation: "Sn" }, { name: "Monday", abbreviation: "Mo" }, { name: "Tuesday", abbreviation: "Tu" }, { name: "Wednesday", abbreviation: "We" }, { name: "Thursday", abbreviation: "Th" }, { name: "Friday", abbreviation: "Fr" }, { name: "Saturday", abbreviation: "Sa" }], u = { Sunday: 0, Monday: 1, Tuesday: 2, Wednesday: 3, Thursday: 4, Friday: 5, Saturday: 6 }, g = { January: 1, February: 2, March: 3, April: 4, May: 5, June: 6, July: 7, August: 8, September: 9, October: 10, November: 11, December: 12 }, t = "January February March April May June July August September October November December".split(" "), l = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; this.numberofdays = l; this.getDaysOfWeek = function (a) { a = a.name; for (var d = [], b = [], e = null, c = 0, f = m.length; c < f; c++) m[c].name == a && (e = c), null === e ? d.push(m[c]) : b.push(m[c]); return b.concat(d) }; this.getNextMonth = q; this.getPreviousMonth = function (a, d) { var b = null, b = g[a] - 1; void 0 == d && (d = n().year); "January" !== a ? b = k[b - 1] : (b = k[k.length - 1], d--); return { name: b, year: d } }; this.getDaysBefore = function (a) { return u[a] }; this.getMonth = function (a, d) { for (var b = l[g[a] - 1], e = [], c = 1; c <= b; c++) { var f = h(a, c, d); f.number = c; e.push(f) } return e }; this.getCurrentDay = n; this.getDays = p; this.getDay = h; this.getMonthValue = function (a) { return g[a] }; this.getMonthName = r; this.getNumberOfDays = getNumberOfDays; function getNumberOfDays(month, year) { var v = l[g[month] - 1]; if (month === "February" && isLeapYear(year)) { v++; } return v; } function isLeapYear(year) { if (year % 4 !== 0) { return false; } if (year % 100 === 0 && year % 400 !== 0) { return false } return true; } }; /* End Calendar Manager - Compiled */ var AdCreationTool = function (core, target, data, returnCB, title, adFields, adData, adTemplate, adWidth, adHeight, useLogo, addAnother) { var events = new EventManager, template = new Template, adReference = adTemplate[adWidth + 'x' + adHeight], data = null, renderData = null, element = null, elements = null, inboundData = null; this.exit = exit; new ApiManager({ 'adGroupsList': null }, core.userID, init); function Data(d) { this.ads = []; this.logo = null; this.adGroup = null; } function RenderData(d) { this.ads = adData; this.adGroups = d.adGroupsList; this.title = title; this.adFields = adFields; this.useLogo = useLogo; this.addAnother = addAnother; } function Ad(e, i, d) { var d = new AdData(d), cO = getCanvasObj(d, e), config = cO.config, rows = e.querySelector('rows'), c = getCanvas(e, cO), controls = getControls(e), close = getClose(e), index = i, updateObj = {}; this.element = e; this.data = d; this.canvas = c; this.set = set; this.setIndex = setIndex; this.remove = remove; bindLandingURL(); setUpdateObj(); initRows(); function initRows() { var f = getFragment(); for (var k in updateObj) { new RowKey(k, updateObj[k], f); } rows.insertBefore(f, rows.childNodes[1]); } function bindLandingURL() { var t = e.querySelector('.landingURL'); if (t) events.add(t, 'change', setLandingURL); } function RowKey(k, d, f) { forEach(d, p); function p(t) { if (t.type == 'input') f.appendChild(new Row(t, k)); } } function Row(t, k) { var row = getElementFromString(getRowString(t.title, d[t.key])); events.add(row.querySelector('input'), 'change', check); return row; function getRowString(t, v) { return '

' + t + '

'; } function check(e) { var v = e.target.value; set(t.key, v); setObj(t.updateKey, t, v); } function setObj(key, t, v) { var o = getRefreshObj([key]), m = !isDefined(t.fn) ? v : t.fn(v); if (isString(t.set)) single(t.set) else forEach(t.set, p); c.updateData(o); function p(setItem) { o[key][setItem] = m[setItem]; } function single(setItem) { o[key][setItem] = m; } } } function checkUpdates(k, v) { var t = updateObj[k], o = {}; if (isDefined(updateObj[k])) forEach(updateObj[k], p); c.updateData(o); function p(t) { if (t.type !== 'input') setItem(o, t, t.updateKey, v); } function setItem(o, t, r, v) { var m = getValue(t, v); o[r] = getRefreshObjItem(r); if (isString(t.set)) single(t.set) else forEach(t.set, p); function p(setItem) { o[r][setItem] = m[setItem]; } function single(setItem) { o[r][setItem] = m; } } function getValue(t, v) { return !isDefined(t.fn) ? v : t.fn(v); } } function getRefreshObj(a) { var o = {}; forEach(a, p); return o; function p(t) { o[t] = getRefreshObjItem(t); } } function getRefreshObjItem(i) { return cO.template[i]; } function getControls() { return new ToggleNavigation(e.querySelector('.controls'), getControlsObj(), setView); } function getControlsObj() { var a = []; forEach(config.views, p); return { 'data': a, 'className': 'toggle' }; function p(item) { a.push({ 'value': item.title }); } } function getClose(e) { return new ConfirmationButton(e.querySelector('.close'), { 'color': 'hot', 'text': 'Close', 'className': 'tidySmall', 'confirmColor': 'mist', 'confirmText': 'Confirm?' }, remove) } function set(k, v) { if (d) { if (isString(v)) single(v) else forEach(v, p); checkUpdates(k, v); } function p(setItem) { d[k] = v[setItem]; } function single() { d[k] = v; } } function setIndex(v) { index = v; } function setLogo(e) { var o = getRefreshObj([2]); o[2].src = e; c.updateData(o); } function setLandingURL(e) { set('landingURL', e.target.value); } function setUpdateObj() { processItems(config.updateItems); function processItems(item) { for (var k in item) { processItem(item[k], k); } } function processItem(t, k) { t.updateKey = parseFloat(k); push(t.key, t); } function setTargetItem(k, t) { t.reference = parseFloat(k); push(t.target, t); } function push(k, v) { if (!isDefined(updateObj[k])) updateObj[k] = []; updateObj[k].push(v); } } function setView(e) { var v = e.value; if (v == 'Main') c.setView(0); else if (v == 'Re-position background') c.setView(1); } function remove() { data.ads.splice(index, 1); updateAdIndexes(); exit(); } function exit() { if (c && c.exit) c.exit(); if (controls) controls.exit(); if (close) close.exit(); if (e) removeChild(elements.adsContainer, e); housekeeping(); } function housekeeping() { e = name = price = imageURL = landingURL = d = cO = c = main = position = controls = null; } } function AdData(d) { for (var k in d) { this[k] = d[k]; } this.logo = get300x40LogoImage(); this.adGroup = null; this.landingURL = ''; } function Template() { var header = '

{{ title }} Ads - Create

{{# useLogo }}Set logo{{/ useLogo }}
', controls = '', close = '', url = '

Landing Page URL

', ad = '' + controls + url + close + '', ads = '{{# ads }}' + ad + '{{/ ads }}{{# addAnother }}
Create another
{{/ addAnother }}
', footer = ''; this.ad = ad; this.index = '
' + header + ads + footer + '
'; this.hidden = ''; } function init(error, d) { inboundData = d; setData(d); setElements(); initAdGroups(); if (useLogo) initLogoInput(); initAds(); initSave(); initCreateAnother(); if (returnCB) returnCB(); insertElement(); } function initAdGroups() { var e = elements; e.adGroups = new Dropdown(e.header.querySelector('row'), { 'data': getAdGroups(renderData.adGroups), 'options': getAdGroupOptions() }, updateAdGroups); } function initLogoInput() { events.add(elements.logoInput, 'click', openFileInput); events.add(elements.hidden, 'change', checkFileInput); } function initAds() { forEach(elements.ads = getAdElements(elements.adsContainer), processAd); } function initCreateAnother() { var c = elements.createAnother; if (isDefined(c)) events.add(c.querySelector('a'), 'click', insertAd); } function insertAd() { var ad = getElementFromString(render(template.ad, {})); elements.adsContainer.insertBefore(ad, elements.createAnother); renderData.ads.push(getEmptyObj()); processAd(ad, null, renderData.ads.length - 1); } function processAd(e, ads, i) { data.ads.push(getAd(e, renderData.ads[i], i)); } function getEmptyObj() { var o = {}; forEach(adFields, p); return o; function p(item) { o[item.key] = ''; } } function getAd(e, d, i) { return new Ad(e, i, getAdObj(d)); } function initSave() { events.add(elements.save, 'click', saveAction); } function insertElement() { target.appendChild(element); } function getAdElements(t) { return t.querySelectorAll('ad'); } function getAdGroups(d) { var a = [{ "title": "Change Ad Group", "value": "", "placeholder": true }]; forEach(d, p); return a; function p(t) { a.push({ 'title': t.data.name, 'value': t.data.name }); } } function getAdGroupOptions() { return { "dropdownClass": "cool", "menuItemClass": "cool", "carrotClass": "cool" }; } function getAdObj(d) { var o = {}; forEach(adFields, process); return o; function process(field, fields, i) { o[field.key] = d[field.reference]; } } function getProductName(name) { if (isDefined(name) && name.length >= 24) return name.substr(0, 21) + '...'; else return name; } function getCanvasObj(d, e) { return adReference(d); } function getCanvas(e, t) { if (isDefined(t)) { var c = new CanvasRenderingTool(t.config, e.querySelector('canvas')); c.run(t.template); return c; } else return null; } function getInvalidItems() { var a = []; if (!isDefined(data.adGroup)) a.push('Please set an ad group'); //if(!isDefined(data.landingURL) || data.landingURL.length == 0) a.push('Please set a landing url'); forEach(data.ads, p); return a.length > 0 ? a : null; function p(ad, ads, i) { var d = ad.data; forEach(adFields, adFieldProcess); function adFieldProcess(adField, adFields, aI) { if (!getDataMatch(adField, d)) a.push(!isDefined(adField.errorMessage) ? getMessage(i) : adField.errorMessage + ' for ad #' + (i + 1)); } function getDataMatch(adField, d) { for (var k in d) { if (k == adField.key && isDefined(d[k]) && d[k].length > 0 && (!isDefined(adField.fn) || (isDefined(adField.fn) && adField.fn(d[k])))) return true; } return false; } } function getMessage(i) { return 'Please check the fields for ad #' + (i + 1); } function isInvalid(d) { return !isDefined(d) || d.length === 0; } } function getItemIDFromName(key, name) { var match = null, keyList = inboundData[key]; forEach(keyList, check); return match; function check(t, o, i) { if (t.data.name == name) { match = t.id; return true; } } } function setData(d) { renderData = new RenderData(d); data = new Data; } function setElements() { element = getElementFromString(render(template.index, renderData)); elements = new Elements(element, { 'header': { 'selector': 'header' }, 'hidden': { 'target': getElementFromString(template.hidden) }, 'logoInput': { 'selector': '.logoInput' }, 'adGroups': {}, 'adsContainer': { 'selector': 'ads' }, 'ads': {}, 'save': { 'selector': '.saveButton' }, 'createAnother': { 'selector': '.createAnother' }, 'missing': {} }); } function updateLogo(d) { elements.logoInput.classList.add('set'); updateData('logo', d.result); updateAds('logo', d.result) } function updateAdGroups(e) { var v = getItemIDFromName('adGroupsList', e); updateData('adGroup', v); updateAds('adGroup', v) } function updateData(k, v, ignore) { data[k] = v; if (ignore !== true) refresh(); } function updateAds(key, value) { forEach(data.ads, process); function process(ad, ads) { ad.set(key, value); } } function updateAdIndexes() { forEach(data.ads, p); function p(t, d, i) { t.setIndex(i); } } function setMissing(a) { elements.missing = core.notifications.setMissingFields(a); } function closeMissing() { if (elements.missing && elements.missing.close) elements.missing.close(); } function openFileInput(e) { if (e && e.preventDefault) e.preventDefault(); elements.hidden.click(); } function checkFileInput() { new FileToImageData(elements.hidden, returnFileInputData); } function returnFileInputData(a) { if (a.length > 0) { updateLogo(a[0]); } } function refresh() { } function saveAction(e) { if (e && e.preventDefault) e.preventDefault(); var invalid = getInvalidItems(); if (invalid !== null) setMissing(invalid); else save(getAdBatch()); function save(b) { removeChild(element, elements.footer); core.notifications.setLoading(); new AdSave(core, b, title, core.userID, complete) } function complete() { core.notifications.setSuccess('w00t! Redirecting you to Ads.'); setTimeout(redirect, 1500); } function redirect() { pop('Pop!', 'Dashboard - Ads', '/dashboard/ads'); } } function getAdBatch() { var a = []; forEach(data.ads, p); return a; function p(ad, ads, i) { var c = ad.canvas, d = ad.data; c.setView(0); var n = title + ' ads - ' + (d.name || d.title || d.adTitle); a.push(new AdBatchData(c.getImage(), n, adWidth, adHeight, d.adGroup, d.landingURL, null)); } } function clearAds() { forEach(data.ads, p, true); data.ads = null; function p(ad, ads, i) { ad.remove(); } } function exit() { if (data.ads) clearAds(); if (element) target.removeChild(element); if (elements) elements.exit(); if (events) events.reset(); houseKeeping(); } function houseKeeping() { template = events = data = renderData = element = elements = null; } } function forEach(d, fn, reverse) { if (isDefined(d)) { if (!isDefined(reverse)) go(); else goBackward(); return true; } return false; function go() { for (var i = 0, l = d.length; i < l; i++) { if (fn(d[i], d, i) === false) break; } } function goBackward() { for (var i = d.length - 1; i > -1; i--) { if (fn(d[i], d, i) === false) break; } } } function removeChild(p, c) { if (isDefined(c) && c.parentNode === p) p.removeChild(c); } function preventDefault(e) { if (isDefined(e) && isDefined(e.preventDefault)) e.preventDefault(); } function shiftArrayPosition(a, o, n) { a.splice(n, 0, a.splice(o, 1)[0]); } var isEventSupported = (function () { var r = { 'select': 'input', 'change': 'input', 'submit': 'form', 'reset': 'form', 'error': 'img', 'load': 'img', 'abort': 'img', 'DOMMouseScroll': 'window' }, d = { 'window': window, 'document': document }; return isEventSupported; function isEventSupported(name) { var dT = d[r[name]], t = !dT ? createTarget(name) : dT, eN = 'on' + name, s = (eN in t); if (!s) s = eventCheck(t, eN); t = null; return s; } function eventCheck(t, eN) { t.setAttribute(eN, 'return;'); return typeof t[eN] == 'function'; } function createTarget(n) { return document.createElement(r[n]) || document.createElement('div'); } })(); function isObject(t) { return t instanceof Object && typeof t != 'function' && !(t instanceof Array); } function isArray(t) { return Array.isArray(t); } function isNumber(t) { return typeof t === 'number'; } function isString(t) { return typeof t === 'string'; } function isFunction(t) { return t instanceof Function; } function isElement(t) { return t instanceof Element; } function isEmptyObject(t) { for (var k in t) { return false; } return true; } function isParentOfTarget(parent, target) { return c(target); function c(t) { var p = t ? t.parentNode : null; if (p == parent) return true; else if (p != document.body && p != null) return c(p); else return false; } } function isDefined(t) { return t !== null && t !== undefined; } function isChildOfTarget(c, t) { var p = c ? c.parentNode : null; if (p == t) return true; else if (p != document.body && p != null) return isChildOfTarget(p, t); else return false; } /** * Gets date (new Date()) based on value of difference (integer) from current date. (Yesterday = -1, Tomorrow = 1) * * Use: * var tomorrow = getDateByDifference(1), * yesterday = getDateByDifference(-1); * * Day in MS value calculated from (1000 * 60 * 60 * 24) * Creates currentDate and gets time in MS. * Arrival date string is Time in MS with (value * dayInMS) added to it. * New date is created with updated MS string, new date is returned. */ function getDateByDifference(value) { var dayInMS = 86400000, currentDate = new Date(), arrivalDateString = currentDate.getTime() + (dayInMS * value), arrivalDate = new Date(arrivalDateString); return arrivalDate; } /** * Returns name of day based on it's numerical value. * * Use: * var date = new Date(), * day = date.getDay(), * dayOfWeek = getDayByValue(day); */ function getDayByValue(dayValue) { var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; return days[dayValue]; } /** * Returns month name by value. * * Use: * var date = new Date(), * month = date.getMonth(), * monthName = geTMonthByValue(month); */ function getMonthByValue(monthValue) { var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November']; return months[monthValue]; } /** * Returns length of object */ function getObjectLength(obj) { var counter = 0; for (key in obj) { counter++; } return counter; } /** * Gets element's offset from document. * Can specify 'Left' or 'Top' for direction */ function getDocumentOffset(target, direction) { if (direction != 'Top' && direction != 'Left') direction = 'Top'; var offset = 0, directionString = 'offset' + direction; return run(target, directionString, offset); function run(target, directionString, offset) { var offsetAmount = target[directionString], offsetParent = target.offsetParent; if (!isNaN(offsetAmount)) offset += offsetAmount; if (offsetParent) return run(offsetParent, directionString, offset); else return offset; } } function getSelectData(select) { var options = select.querySelectorAll('option'), selectData = []; for (var i = 0, t = options, l = t.length; i < l; i++) { var option = t[i], value = option.value, text = option.textContent, optionObj = { 'value': value, 'text': text }; if (select.value == value) activeItem = i; selectData.push(optionObj); } return selectData; } function getStringByteValue(s) { return encodeURI(s).split(/%..|./).length - 1; } function getSimpleJSONCopy(o) { return JSON.parse(JSON.stringify(o)); } function getElementFromString(s, tmplArgs) { var d = document.createElement('div'); d.innerHTML = !!tmplArgs ? render(s, tmplArgs) : s; return d.childNodes[0]; } function getFragment() { return document.createDocumentFragment(); } function getDollarValue(v) { var $ = v.indexOf('$') == 0, s = $ ? parseFloat(v.substr(1)) : null; return !isNaN(s) ? s : null; } function getInputFilename(input) { var s = input.value, iO = s.lastIndexOf('\\'); if (iO < 0) iO = s.lastIndexOf('/'); return s.substr(iO + 1); } function getKilobytesFromBytes(bytes) { return Math.ceil(bytes / 1000); } function getRandomNumber(min, max) { if (!isDefined(min)) min = 0; if (!isDefined(max)) max = 1000; return Math.round(Math.random() * (max - min) + min); } function getRequiredPixel(brand, id) { return ''; } function getConversionPixel() { return ''; }; function getAdvancedProductsPixel() { return ''; } function getAdvancedShoppingCartPixel() { return ''; } function getCurrentHost() { var loc = document.location, o = loc.origin, l = (loc.protocol + '//').length, s = o.substr(l), port = s.indexOf(':'); if (port > -1) s = s.substr(0, port); return s; } function getRoundedValue(value, places) { var d = Math.pow(10, places); return Math.round(value * d) / d; } function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min)) + min; } function getBillingHistoryObj(d) { var currentDate = null, currentEntry = null; var a = []; forEach(d, setData); if (currentEntry !== null) a.push(currentEntry); return a; function Entry(date) { this.date = date; this.charges = []; } function Charge(t, i) { var tD = t.transactionData || {}; this.campaignName = tD.campaignName; this.success = t.success; this.id = i + 1; this.amount = '$' + t.amount; } function setData(t, d, i) { if (!isDefined(t.errors)) { var date = getDate(t); if (currentDate !== date) { if (currentEntry !== null && currentDate !== date) a.push(currentEntry); currentEntry = new Entry(date); currentDate = date; } currentEntry.charges.push(new Charge(t, i)); } } function getDate(t) { if (!isDefined(t.createdAt) || t.createdAt.length === 0) return 'Unavailable'; return getFormattedDate(t.createdAt.slice(0, 10).split('-')) } function getFormattedDate(d) { return d[1] + '/' + d[2] + '/' + d[0]; } } function getSeriesOfNumbers(start, end) { var c = end - start + 1, n = start, a = []; while (c--) { a.push(n++); } return a.join(', '); } function getSeriesOfNumbersArray(start, end) { var c = end - start + 1, n = start, a = []; while (c--) { a.push(n++); } return a; } function apiUpdate(o, uid, cb) { return new ApiUpdate(o, uid, cb); } function apiRequest(method, url, id, data, returnCB, extra) { var loc = getApiRequestLocation(url, id); if (!!extra) loc += '/' + extra; new HttpRequest(method, loc, data, isDefined(data) ? 'json' : null, 'json', returnCB); } function getApiRequestLocation(url, id) { return isDefined(id) ? '/api/v1/' + url + '/' + id : '/api/v1/' + url; } function isFunction(fn) { return !!(fn && fn.constructor && fn.call && fn.apply); } function isValidURL(url) { return isDefined(url) && (url.indexOf('http://') === 0 || url.indexOf('https://') === 0 || url.indexOf('//') === 0 || url.indexOf('tel:') === 0); } var getAPIErrorMessage = (function () { var o = { 'noMatch': 'MDB_NOTFOUND: No matching key/data pair found', 'notLoggedIn': 'AuthHandler: session cookie not set' }; return get; function get(k) { return o[k] || null; } })(); var getFormattedDay = (function () { var o = { '1': '1st', '2': '2nd', '3': '3rd', '4': '4th', '5': '5th', '6': '6th', '7': '7th', '8': '8th', '9': '9th', '01': '1st', '02': '2nd', '03': '3rd', '04': '4th', '05': '5th', '06': '6th', '07': '7th', '08': '8th', '09': '9th', '10': '10th', '11': '11th', '12': '12th', '13': '13th', '14': '14th', '15': '15th', '16': '16th', '17': '17th', '18': '18th', '19': '19th', '20': '20th', '21': '21st', '22': '22nd', '23': '23rd', '24': '24th', '25': '25th', '26': '26th', '27': '27th', '28': '28th', '29': '29th', '30': '30th', '31': '31st' }; return get; function get(k) { return o[k] || null; } })(); var getMonthName = (function () { var months = { "01": "Jan", "02": "Feb", "03": "Mar", "04": "Apr", "05": "May", "06": "Jun", "07": "Jul", "08": "Aug", "09": "Sep", "10": "Oct", "11": "Nov", "12": "Dec", } return get; function get(m) { return months[m]; } })(); var getSortedReportingDates = (function () { var months = { 'Jan': 0, 'Feb': 1, 'Mar': 2, 'Apr': 3, 'May': 4, 'Jun': 5, 'Jul': 6, 'Aug': 7, 'Sep': 8, 'Oct': 9, 'Nov': 10, 'Dec': 11 } return get; function get(dates, data) { var sL = getSortedList(dates, data), dA = [], lA = []; for (var i = 0, l = sL.length; i < l; i++) { dA[i] = sL[i].value; lA[i] = sL[i].key; } return { 'data': dA, 'labels': lA }; } function getSortedList(dates, data) { var a = []; for (var i = 0, l = data.length; i < l; i++) { a[i] = new SortItem(dates[i], data[i]) } a.sort(compare) return a; } function SortItem(date, value) { this.date = date; this.value = value; this.key = date.month + ' ' + getFormattedDay(date.day) + ' ' + date.year } function compare(a, b) { var aYear = parseFloat(a.date.year), bYear = parseFloat(b.date.year); if (aYear == bYear) { var aMonth = months[a.date.month], bMonth = months[b.date.month]; if (aMonth < bMonth || (!isDefined(aMonth) && isDefined(bMonth))) { return -1; } else if (aMonth > bMonth || (isDefined(aMonth) && !isDefined(bMonth))) { return 1; } else { var aDay = parseFloat(a.date.day), bDay = parseFloat(b.date.day); if (aDay < bDay) { return -1; } else if (aDay > bDay) { return 1; } else { return 0; } } } else if (aYear < bYear) { return -1; } else { return 1; } } })(); function fmtNum(n, p) { if (n == null || isNaN(n)) n = 0; if (p == null) p = 2; if (n < 9999) { return n.toFixed(p).replace(/\.0*$/, ''); } if (n < 999999) { return (n / 1000.0).toFixed(p).replace(/\.0*$/, '') + 'K'; } return (n / 1000000.0).toFixed(p).replace(/\.0*$/, '') + 'M'; } function cleanRTBObject(uid, o) { for (var k in o) { var v = o[k] || {}; if (k.indexOf('rtb') == 0) { var nk = k.replace(/^(?:rtb|rtb-totals)\//, ''); o[nk] = v[uid]; if (o[nk] == null) { o[nk] = {}; } delete o[k]; } } return o; } /* function compare(a, b) { if (a is less than b by some ordering criterion) { return -1; } if (a is greater than b by the ordering criterion) { return 1; } // a must be equal to b return 0; } */ function setQueryParameter(url, key, value) { return url + getSeparator() + key + '=' + value; function getSeparator() { return url.indexOf('?') > -1 ? '&' : '?'; } } /* Cookie Manager */ var CookieManager = function (l) { function g(a) { if (a) { for (var b in e) a[b] || (a[b] = e[b]); d = a } else d = e } function h(a, b, c) { if (a) { var f = new Date; c = c || d.defaultDuration; c = (new Date).getTime() + 864E5 * c; f.setTime(c); !0 == d.escapeValue && (b = escape(b)); "string" != typeof b && "number" != typeof b && (b = JSON.stringify(b)); a = a + "=" + b; f = ";expires=" + f.toGMTString(); document.cookie = a + f + (";path=" + d.path) + (";domain=" + d.domain) + (!0 != d.secure ? "" : ";secure=true;") } } function k() { for (var a = document.cookie.split(/[;]{1}[ ]?/), b = [], c = 0, f = a.length; c < f; c++) { var d = new m(a[c]); b.push(d) } return b } var d = void 0, e = { escapeValues: !1, defaultDuration: 1, path: "/", domain: document.location.host, secure: !1 }; g(l); this.set = h; this.get = function (a) { for (var b = k(), c = 0, d = b.length; c < d; c++) { var e = b[c]; if (e.key == a) return e } return !1 }; this.remove = function (a) { h(a, "", -1) }; this.list = k; this.setConfig = g; var m = function (a) { a = a.split("="); this.key = a[0]; this.value = a[1] } }; /* End Cookie Manager */ function padNumber(n) { if (n < 10) return '0' + n; return n; } function formatISODate(d, dateOnly) { let out = d.getUTCFullYear() + '-' + padNumber(d.getUTCMonth() + 1) + '-' + padNumber(d.getUTCDate()); if(dateOnly) return out; return out + ' ' + padNumber(d.getUTCHours()) + ':' + padNumber(d.getUTCMinutes()) + ':' + padNumber(d.getUTCSeconds()); } var HiddenFileInput = function (returnCB) { var events = new EventManager, i = document.createElement('input'); i.type = 'file'; events.add(i, 'change', check); this.open = open; this.exit = exit; function open(e) { if (e && e.preventDefault) e.preventDefault(); i.click(); } function check() { new FileToImageData(i, returnCB); } function exit() { if (!!events) events.reset(); events = i = null; } }; var getAdDimensionName = (function () { var o = { 300: { 250: 'mediumRectangle', 600: 'halfPage', 1050: 'portrait', 50: 'mobileRectangle', 100: 'highMobileRectangle' }, 160: { 600: 'wideSkyscraper' }, 720: { 90: 'leaderboard-pearl' }, 728: { 90: 'leaderBoard' }, 180: { 150: 'rectangle' }, 970: { 90: 'superLeaderboard', 250: 'billboard' }, 320: { 50: 'wideMobileRectangle', 480: 'wideRectangle' }, 468: { 60: 'mobileBanner' } }; return get; function get(w, h) { if (!isDefined(o[w]) || !isDefined(o[w][h])) return ''; else return o[w][h]; } })(); function forEachQSA(q, cb, ele) { return Array.prototype.forEach.call((!!ele ? ele : document).querySelectorAll(q), cb); } function toggleNoDisplay(e) { if (e.classList.has('noDisplay')) { return e.classList.remove('noDisplay'); } e.classList.add('noDisplay'); } function getInputSetter(dataSet, fieldName, checkCallback) { if (typeof dataSet !== 'object') return console.error('dataSet is not an object.'); return function (e) { var value = null; if (!!e.target) { value = e.target.value; } else if (!!e.value) { value = e.value; } else { value = e; } if (typeof checkCallback === 'function') { value = checkCallback(value); if (value == null) return; } if (typeof dataSet.set === 'function') return dataSet.set(fieldName, value); if (typeof dataSet.setValue === 'function') return dataSet.setValue(fieldName, value); dataSet[fieldName] = value; } } function mergeOpts(opts, defaults) { defaults = defaults || {}; if (typeof opts !== 'object' || isArray(opts)) return defaults; for (var k in defaults) { if (typeof opts[k] === 'undefined') opts[k] = defaults[k]; } return opts; } function capitalizeN(n, s) { if (s == null || !s.length) return s; return (n !== 0 ? s.substring(0, n) : '') + s.substring(n, n + 1).toUpperCase() + s.substring(n + 1); } /* parseURL accepts a url and splits it into all it's relevant components parseURL('http://meteora:8080/dashboard/campaigns/create?q=a&q=b&z=a#this-is-a-hash-value') returns: { "host": "meteora", "port": "8080", "path": "/dashboard/campaigns/create", "query": { "q": ["a", "b"], "z": "a" }, "hash": "this-is-a-hash-value" } */ var parseURL = (function () { // re is a fancy regexp to break down URLs, // queryRe breaks down query strings. var re = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/, queryRe = /[?&;](.+?)=([^&;]+)/g; function parseQuery(q) { if (!q || !q.length) return {}; var params = {}, m; while (m = queryRe.exec(q)) { if (!!params[m[1]]) { if (!Array.isArray(params[m[1]])) params[m[1]] = [params[m[1]]]; params[m[1]].push(decodeURIComponent(m[2])) } else { params[m[1]] = decodeURIComponent(m[2]); } } return params; } function parseURL(url) { var m = re.exec(url), parts = { host: m[11] || '', port: m[12] || '', path: m[13] || '', query: parseQuery(m[16]), hash: (m[17] || '').replace(/^#/, '') }; if (!parts.host.length && url.length) parts = parseURL('http://' + url); return parts; } return parseURL; })(); var DelayedCallbacks = (function () { function DelayedCallbacks() { this.cbs = []; } DelayedCallbacks.prototype = { add: function add(cb) { this.cbs.push(cb); }, exec: function exec() { this.cbs.forEach(function (cb) { if (typeof cb === 'function') cb(); }); this.cbs = []; } } return DelayedCallbacks; })(); var isValidDomain = (function () { var re = /^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/i; return function (domain) { return re.test(domain); }; })(); function getHiddenInput(multi) { var t = document.createElement('input'); t.type = 'file'; if (multi === true) t.setAttribute('multiple', true); return t; } function getQueryVariables() { var d = document.location.search.split(/[?&]/g), t = d.length, c = t, o = {}; while (c) { var tgt = d[t - c--].split("="); if (tgt.length !== 2 || tgt[0] === "" || tgt[1] === "") { continue; } o[tgt[0]] = tgt[1]; } return o; } function DropdownObj(d, iv, ddc, mic, cc, sm) { this.data = d; this.initialValue = !!iv ? iv : null; this.options = { "dropdownClass": !!ddc ? ddc : "cool", "menuItemClass": !!mic ? mic : "cool", "carrotClass": !!cc ? cc : "cool", "staticMenu": sm === true }; } function CheckboxHelper(d, list) { this.processSelected = processSelected; this.getIdsList = getIdsList; this.getNamesList = getNamesList; function processSelected(e) { loop(e, p); function p(k, v) { if (isActive(d, v.getTitle())) v.set(); } } function isActive(d, name) { var m = false; if (!!d) loop(getNamesList(d, list), p); return m; function p(k, v) { if (v === name) { m = true; return true; } } } function getNamesList(d, list) { var a = []; loop(d, p); return a; function p(k, v) { var id = v; loop(list, m); function m(k, v) { if (v.id === id) { a.push(v.data.name); return true; } } } } function getIdsList(e) { var a = []; loop(e, p); return a; function p(k, name) { loop(list, check); function check(k, v) { if (v.data.name === name) { a.push(v.id); return true; } } } } } var measureText = (function () { var c = document.createElement('canvas'); return measure; function measure(txt, font) { var ctx = c.getContext('2d'); ctx.font = font; return ctx.measureText(txt).width; } })(); var defer = (function () { var stack = [], len = 0; return function (fn) { if (!isFunction(fn)) return; if (len === 0) { setTimeout(clear, 0); } stack[len++] = fn; } function clear() { var r = stack.slice(0, len).reverse(); len = 0; loop(r, function (k, v) { v(); }); } })(); function sleep(ms) { var start = new Date().getTime(), delta = 0; while (delta < ms) { delta = new Date().getTime() - start; } } var supportedTimezones = [ { 'title': 'Universal (UTC)', 'value': 'UTC' }, { 'title': 'Pacific (PT)', 'value': 'PST8PDT' }, { 'title': 'Mountain (MT)', 'value': 'MST' }, { 'title': 'Central (CT)', 'value': 'CST6CDT' }, { 'title': 'Eastern (ET)', 'value': 'EST' } ]; function getTimezone(tz) { var ret; loop(supportedTimezones, function (_, v) { if (v.value === tz) { ret = v.title; return false; } }); return ret; } function defaultRadiusValues() { var fpm = 5280, // Feet per mile radArr = [ { 'title': '100 ft', 'value': 100 / fpm }, { 'title': '250 ft', 'value': 200 / fpm }, { 'title': '500 ft', 'value': 500 / fpm }, { 'title': '750 ft', 'value': 750 / fpm }, { 'title': '1000 ft', 'value': 1000 / fpm }, { 'title': '1500 ft', 'value': 1500 / fpm }, { 'title': '2000 ft', 'value': 2000 / fpm }, { 'title': '2500 ft', 'value': 2500 / fpm }, { 'title': '1 mile', 'value': 1 }, { 'title': '2 miles', 'value': 2 }, { 'title': '3 miles', 'value': 3 }, { 'title': '5 miles', 'value': 5 }, { 'title': '10 miles', 'value': 10 } ]; return radArr; }; function Brand(obj) { this.name = obj.name || "Meteora"; this.id = obj.id || "2"; this.domain = obj.domain || "meteora.us"; this.privacyPolicyURL = obj.privacyPolicyURL || "https://meteora.co/terms-conditions"; this.termsOfServiceURL = obj.termsOfServiceURL || "https://meteora.co/privacy-policy"; this.logo64x64 = obj.logo64x64 || "//cdn.meteora.us/images/assets/64x64.png"; this.logo80x24 = obj.logo80x20 || "//cdn.meteora.us/images/assets/80x20.png"; this.logo144x24 = obj.logo144x24 || "//cdn.meteora.us/images/assets/144x24.png"; this.logo144x24Light = obj.logo144x24Light || "//meteora.co/whitelabel/180x34Light.png"; this.colorScheme = obj.colorScheme || "edge"; this.customerSupportEmail = obj.customerSupportEmail || "engage@meteora.co"; this.pixelURL = obj.pixelURL || '//pixel.meteora.us/serve/'; } function getATCMultiplier() { return 10000000; } function amountToCredits(amt) { return Math.round(amt * getATCMultiplier()); } function creditsToAmount(crdts) { return crdts / getATCMultiplier(); } /* o.toUnix = function(){ var d = new Date(o.year, o.monthValue - 1, o.date, 0, 0, 0, 0); return Math.round(d.getTime() / 1000); } */ function toUnix(d) { return Math.round(d.getTime() / 1000); } function fromUnix(ts) { return new Date(ts * 1000) } var FileUploader = (function () { 'use strict' return newUploader; function newUploader(element, callback) { return new Uploader(element, callback); } function Uploader(element, callback) { if (!element.files) { return } var fr = new FileReader(), file = element.files[0]; fr.onload = ready; fr.readAsDataURL(file); function ready(e) { if (!e.target || !e.target.result) { return } callback(e.target.result); } } })(); var getErrorMsg = function (resp, def) { if (!resp) return Array.isArray(def) ? def : [def]; if (!!resp.error) return [resp.error]; // support old-school error responses, they exist somewhere. if (Array.isArray(resp.errors)) { let messages = []; for (let err of resp.errors) { if (typeof err === 'string') { // workaround billing errors, they return as json strings for whatever reason. err = JSON.parse(err); } if (err.message) messages.push(err.message); } return messages; } return Array.isArray(def) ? def : [def]; }; const replaceElement = (e, ne) => e.parentNode.replaceChild(e, ne); /* _,add8ba, ,d888888888b, d8888888888888b _,ad8ba,_ d888888888888888) ,d888888888b, I8888888888888888 _________ ,8888888888888b __________`Y88888888888888P"""""""""""baaa,__ ,888888888888888, ,adP"""""""""""9888888888P""^ ^""Y8888888888888888I ,a8"^ ,d888P"888P^ ^"Y8888888888P' ,a8^ ,d8888' ^Y8888888P' a88' ,d8888P' I88P"^ ,d88' d88888P' "b, ,d88' d888888' `b, ,d88' d888888I `b, d88I ,8888888' ___ `b, ,888' d8888888 ,d88888b, ____ `b, d888 ,8888888I d88888888b, ,d8888b, `b ,8888 I8888888I d8888888888I ,88888888b 8, I8888 88888888b d88888888888' 8888888888b 8I d8886 888888888 Y888888888P' Y8888888888, ,8b 88888b I88888888b `Y8888888^ `Y888888888I d88, Y88888b `888888888b, `""""^ `Y8888888P' d888I `888888b 88888888888b, `Y8888P^ d88888 Y888888b ,8888888888888ba,_ _______ `""^ ,d888888 I8888888b, ,888888888888888888ba,_ d88888888b ,ad8888888I `888888888b, I8888888888888888888888b, ^"Y888P"^ ____.,ad88888888888I 88888888888b,`888888888888888888888888b, "" ad888888888888888888888' 8888888888888698888888888888888888888888b_,ad88ba,_,d88888888888888888888888 88888888888888888888888888888888888888888b,`"""^ d8888888888888888888888888I 8888888888888888888888888888888888888888888baaad888888888888888888888888888' Y8888888888888888888888888888888888888888888888888888888888888888888888888P I888888888888888888888888888888888888888888888P^ ^Y8888888888888888888888' `Y88888888888888888P88888888888888888888888888' ^88888888888888888888I `Y8888888888888888 `8888888888888888888888888 8888888888888888888P' `Y888888888888888 `888888888888888888888888, ,888888888888888888P' `Y88888888888888b `88888888888888888888888I I888888888888888888' "Y8888888888888b `8888888888888888888888I I88888888888888888' "Y88888888888P `888888888888888888888b d8888888888888888' ^""""""""^ `Y88888888888888888888, 888888888888888P' "8888888888888888888b, Y888888888888P^ `Y888888888888888888b `Y8888888P"^ "Y8888888888888888P `""""^ `"YY88888888888P' ^""""""""' */