<commit_before>function createElement(type, props, ...children) {
  return {
    type,
    props: {
      ...props,
      children: children.map(child =>
        typeof child === "object"
          ? child
          : createTextElement(child)
      ),
    },
  }
}

function createTextElement(text) {
  return {
    type: "TEXT_ELEMENT",
    props: {
      nodeValue: text,
      children: [],
    },
  }
}

function createDom(fiber) {
  const dom =
    fiber.type == "TEXT_ELEMENT"
      ? document.createTextNode("")
      : document.createElement(fiber.type)

  updateDom(dom, {}, fiber.props)

  return dom
}

const isEvent = key => key.startsWith("on")
const isProperty = key =>
  key !== "children" && !isEvent(key)
const isNew = (prev, next) => key =>
  prev[key] !== next[key]
const isGone = (prev, next) => key => !(key in next)
function updateDom(dom, prevProps, nextProps) {
  //Remove old or changed event listeners
  Object.keys(prevProps)
    .filter(isEvent)
    .filter(
      key =>
        !(key in nextProps) ||
        isNew(prevProps, nextProps)(key)
    )
    .forEach(name => {
      const eventType = name
        .toLowerCase()
        .substring(2)
      dom.removeEventListener(
        eventType,
        prevProps[name]
      )
    })

  // Remove old properties
  Object.keys(prevProps)
    .filter(isProperty)
    .filter(isGone(prevProps, nextProps))
    .forEach(name => {
      dom[name] = ""
    })

  // Set new or changed properties
  Object.keys(nextProps)
    .filter(isProperty)
    .filter(isNew(prevProps, nextProps))
    .forEach(name => {
      dom[name] = nextProps[name]
    })

  // Add event listeners
  Object.keys(nextProps)
    .filter(isEvent)
    .filter(isNew(prevProps, nextProps))
    .forEach(name => {
      const eventType = name
        .toLowerCase()
        .substring(2)
      dom.addEventListener(
        eventType,
        nextProps[name]
      )
    })
}

function commitRoot() {
  deletions.forEach(commitWork)
  commitWork(wipRoot.child)
  currentRoot = wipRoot
  wipRoot = null
}

function commitWork(fiber) {
  if (!fiber) {
    return
  }

  let domParentFiber = fiber.parent
  while (!domParentFiber.dom) {
    domParentFiber = domParentFiber.parent
  }
  const domParent = domParentFiber.dom

  if (
    fiber.effectTag === "PLACEMENT" &&
    fiber.dom != null
  ) {
    domParent.appendChild(fiber.dom)
  } else if (
    fiber.effectTag === "UPDATE" &&
    fiber.dom != null
  ) {
    updateDom(
      fiber.dom,
      fiber.alternate.props,
      fiber.props
    )
  } else if (fiber.effectTag === "DELETION") {
    commitDeletion(fiber, domParent)
  }

  commitWork(fiber.child)
  commitWork(fiber.sibling)
}

function commitDeletion(fiber, domParent) {
  if (fiber.dom) {
    domParent.removeChild(fiber.dom)
  } else {
    commitDeletion(fiber.child, domParent)
  }
}

function render(element, container) {
  wipRoot = {
    dom: container,
    props: {
      children: [element],
    },
    alternate: currentRoot,
  }
  deletions = []
  nextUnitOfWork = wipRoot
}

let nextUnitOfWork = null
let currentRoot = null
let wipRoot = null
let deletions = null

function workLoop(deadline) {
  let shouldYield = false
  while (nextUnitOfWork && !shouldYield) {
    nextUnitOfWork = performUnitOfWork(
      nextUnitOfWork
    )
    shouldYield = deadline.timeRemaining() < 1
  }

  if (!nextUnitOfWork && wipRoot) {
    commitRoot()
  }

  requestIdleCallback(workLoop)
}

requestIdleCallback(workLoop)

function performUnitOfWork(fiber) {
  const isFunctionComponent =
    fiber.type instanceof Function
  if (isFunctionComponent) {
    updateFunctionComponent(fiber)
  } else {
    updateHostComponent(fiber)
  }
  if (fiber.child) {
    return fiber.child
  }
  let nextFiber = fiber
  while (nextFiber) {
    if (nextFiber.sibling) {
      return nextFiber.sibling
    }
    nextFiber = nextFiber.parent
  }
}

let wipFiber = null
let hookIndex = null

function updateFunctionComponent(fiber) {
  wipFiber = fiber
  hookIndex = 0
  wipFiber.hooks = []
  const children = [fiber.type(fiber.props)]
  reconcileChildren(fiber, children)
}

function useState(initial) {
  const oldHook =
    wipFiber.alternate &&
    wipFiber.alternate.hooks &&
    wipFiber.alternate.hooks[hookIndex]
  const hook = {
    state: oldHook ? oldHook.state : initial,
    queue: [],
  }

  const setState = action => {
    hook.queue.push(action)
    wipRoot = {
      dom: currentRoot.dom,
      props: currentRoot.props,
      alternate: currentRoot,
    }
    nextUnitOfWork = wipRoot
    deletions = []
  }

  wipFiber.hooks.push(hook)
  hookIndex++
  return [hook.state, setState]
}

function updateHostComponent(fiber) {
  if (!fiber.dom) {
    fiber.dom = createDom(fiber)
  }
  reconcileChildren(fiber, fiber.props.children)
}

function reconcileChildren(wipFiber, elements) {
  let index = 0
  let oldFiber =
    wipFiber.alternate && wipFiber.alternate.child
  let prevSibling = null

  while (
    index < elements.length ||
    oldFiber != null
  ) {
    const element = elements[index]
    let newFiber = null

    const sameType =
      oldFiber &&
      element &&
      element.type == oldFiber.type

    if (sameType) {
      newFiber = {
        type: oldFiber.type,
        props: element.props,
        dom: oldFiber.dom,
        parent: wipFiber,
        alternate: oldFiber,
        effectTag: "UPDATE",
      }
    }
    if (element && !sameType) {
      newFiber = {
        type: element.type,
        props: element.props,
        dom: null,
        parent: wipFiber,
        alternate: null,
        effectTag: "PLACEMENT",
      }
    }
    if (oldFiber && !sameType) {
      oldFiber.effectTag = "DELETION"
      deletions.push(oldFiber)
    }

    if (oldFiber) {
      oldFiber = oldFiber.sibling
    }

    if (index === 0) {
      wipFiber.child = newFiber
    } else if (element) {
      prevSibling.sibling = newFiber
    }

    prevSibling = newFiber
    index++
  }
}

const Didact = {
  createElement,
  render,
  useState,
}

/** @jsx Didact.createElement */
function Counter() {
  const [state, setState] = Didact.useState(1)
  return (

 setState(c => c + 1)}>
      Count: {state}

  )
}
const element = <Counter />
const container = document.getElementById("root")
Didact.render(element, container)
<commit_msg>Run state updates<commit_after>function createElement(type, props, ...children) {
  return {
    type,
    props: {
      ...props,
      children: children.map(child =>
        typeof child === "object"
          ? child
          : createTextElement(child)
      ),
    },
  }
}

function createTextElement(text) {
  return {
    type: "TEXT_ELEMENT",
    props: {
      nodeValue: text,
      children: [],
    },
  }
}

function createDom(fiber) {
  const dom =
    fiber.type == "TEXT_ELEMENT"
      ? document.createTextNode("")
      : document.createElement(fiber.type)

  updateDom(dom, {}, fiber.props)

  return dom
}

const isEvent = key => key.startsWith("on")
const isProperty = key =>
  key !== "children" && !isEvent(key)
const isNew = (prev, next) => key =>
  prev[key] !== next[key]
const isGone = (prev, next) => key => !(key in next)
function updateDom(dom, prevProps, nextProps) {
  //Remove old or changed event listeners
  Object.keys(prevProps)
    .filter(isEvent)
    .filter(
      key =>
        !(key in nextProps) ||
        isNew(prevProps, nextProps)(key)
    )
    .forEach(name => {
      const eventType = name
        .toLowerCase()
        .substring(2)
      dom.removeEventListener(
        eventType,
        prevProps[name]
      )
    })

  // Remove old properties
  Object.keys(prevProps)
    .filter(isProperty)
    .filter(isGone(prevProps, nextProps))
    .forEach(name => {
      dom[name] = ""
    })

  // Set new or changed properties
  Object.keys(nextProps)
    .filter(isProperty)
    .filter(isNew(prevProps, nextProps))
    .forEach(name => {
      dom[name] = nextProps[name]
    })

  // Add event listeners
  Object.keys(nextProps)
    .filter(isEvent)
    .filter(isNew(prevProps, nextProps))
    .forEach(name => {
      const eventType = name
        .toLowerCase()
        .substring(2)
      dom.addEventListener(
        eventType,
        nextProps[name]
      )
    })
}

function commitRoot() {
  deletions.forEach(commitWork)
  commitWork(wipRoot.child)
  currentRoot = wipRoot
  wipRoot = null
}

function commitWork(fiber) {
  if (!fiber) {
    return
  }

  let domParentFiber = fiber.parent
  while (!domParentFiber.dom) {
    domParentFiber = domParentFiber.parent
  }
  const domParent = domParentFiber.dom

  if (
    fiber.effectTag === "PLACEMENT" &&
    fiber.dom != null
  ) {
    domParent.appendChild(fiber.dom)
  } else if (
    fiber.effectTag === "UPDATE" &&
    fiber.dom != null
  ) {
    updateDom(
      fiber.dom,
      fiber.alternate.props,
      fiber.props
    )
  } else if (fiber.effectTag === "DELETION") {
    commitDeletion(fiber, domParent)
  }

  commitWork(fiber.child)
  commitWork(fiber.sibling)
}

function commitDeletion(fiber, domParent) {
  if (fiber.dom) {
    domParent.removeChild(fiber.dom)
  } else {
    commitDeletion(fiber.child, domParent)
  }
}

function render(element, container) {
  wipRoot = {
    dom: container,
    props: {
      children: [element],
    },
    alternate: currentRoot,
  }
  deletions = []
  nextUnitOfWork = wipRoot
}

let nextUnitOfWork = null
let currentRoot = null
let wipRoot = null
let deletions = null

function workLoop(deadline) {
  let shouldYield = false
  while (nextUnitOfWork && !shouldYield) {
    nextUnitOfWork = performUnitOfWork(
      nextUnitOfWork
    )
    shouldYield = deadline.timeRemaining() < 1
  }

  if (!nextUnitOfWork && wipRoot) {
    commitRoot()
  }

  requestIdleCallback(workLoop)
}

requestIdleCallback(workLoop)

function performUnitOfWork(fiber) {
  const isFunctionComponent =
    fiber.type instanceof Function
  if (isFunctionComponent) {
    updateFunctionComponent(fiber)
  } else {
    updateHostComponent(fiber)
  }
  if (fiber.child) {
    return fiber.child
  }
  let nextFiber = fiber
  while (nextFiber) {
    if (nextFiber.sibling) {
      return nextFiber.sibling
    }
    nextFiber = nextFiber.parent
  }
}

let wipFiber = null
let hookIndex = null

function updateFunctionComponent(fiber) {
  wipFiber = fiber
  hookIndex = 0
  wipFiber.hooks = []
  const children = [fiber.type(fiber.props)]
  reconcileChildren(fiber, children)
}

function useState(initial) {
  const oldHook =
    wipFiber.alternate &&
    wipFiber.alternate.hooks &&
    wipFiber.alternate.hooks[hookIndex]
  const hook = {
    state: oldHook ? oldHook.state : initial,
    queue: [],
  }

  const actions = oldHook ? oldHook.queue : []
  actions.forEach(action => {
    hook.state = action(hook.state)
  })

  const setState = action => {
    hook.queue.push(action)
    wipRoot = {
      dom: currentRoot.dom,
      props: currentRoot.props,
      alternate: currentRoot,
    }
    nextUnitOfWork = wipRoot
    deletions = []
  }

  wipFiber.hooks.push(hook)
  hookIndex++
  return [hook.state, setState]
}

function updateHostComponent(fiber) {
  if (!fiber.dom) {
    fiber.dom = createDom(fiber)
  }
  reconcileChildren(fiber, fiber.props.children)
}

function reconcileChildren(wipFiber, elements) {
  let index = 0
  let oldFiber =
    wipFiber.alternate && wipFiber.alternate.child
  let prevSibling = null

  while (
    index < elements.length ||
    oldFiber != null
  ) {
    const element = elements[index]
    let newFiber = null

    const sameType =
      oldFiber &&
      element &&
      element.type == oldFiber.type

    if (sameType) {
      newFiber = {
        type: oldFiber.type,
        props: element.props,
        dom: oldFiber.dom,
        parent: wipFiber,
        alternate: oldFiber,
        effectTag: "UPDATE",
      }
    }
    if (element && !sameType) {
      newFiber = {
        type: element.type,
        props: element.props,
        dom: null,
        parent: wipFiber,
        alternate: null,
        effectTag: "PLACEMENT",
      }
    }
    if (oldFiber && !sameType) {
      oldFiber.effectTag = "DELETION"
      deletions.push(oldFiber)
    }

    if (oldFiber) {
      oldFiber = oldFiber.sibling
    }

    if (index === 0) {
      wipFiber.child = newFiber
    } else if (element) {
      prevSibling.sibling = newFiber
    }

    prevSibling = newFiber
    index++
  }
}

const Didact = {
  createElement,
  render,
  useState,
}

/** @jsx Didact.createElement */
function Counter() {
  const [state, setState] = Didact.useState(1)
  return (

 setState(c => c + 1)}>
      Count: {state}

  )
}
const element = <Counter />
const container = document.getElementById("root")
Didact.render(element, container)
<|endoftext|>


<commit_before><commit_msg>Save level to file added<commit_after><|endoftext|>


<commit_before>var util = require('util');
var exec = require('child_process').exec,
    child;

var result = {};
child = exec('azure config mode asm', {maxBuffer: 1000*1024}, function (error, stdout, stderr) {
  console.log(stdout);
  child = exec('azure help --json', {maxBuffer: 1000*1024}, function (error, stdout, stderr) {
    var data = JSON.parse(stdout);
    parse(data);
    if (error) {
      console.log('exec error: ' + error);
    }
    child = exec('azure config mode arm', {maxBuffer: 1000*1024}, function (error, stdout, stderr) {
      console.log(stdout);
      child = exec('azure help --json', {maxBuffer: 1000*1024}, function (error, stdout, stderr) {
        var data = JSON.parse(stdout);
        parse(data);
        if (error) {
          console.log('exec error: ' + error);
        }
        var cmds = Object.keys(result);
        console.log(util.inspect(cmds, {depth: null}));
        console.log("The total number of commands for xplat-cli in asm and arm mode is: " + cmds.length);
      });
    });
  });
});

function parse(cmdObj) {
  if (cmdObj) {
    Object.keys(cmdObj).forEach(function(key) {
      if (key === 'commands') {
        cmdObj[key].forEach(function(element) {
          result[element.name] = element.name;
        });
      }
      else {
        parse(cmdObj[key]);
      }
    });
  }
}<commit_msg>fix havesting script bugs and do not require azure to be installed<commit_after>var util = require('util');

var result = {};
var metedataArm = require('../lib/plugins.arm.json');
parse(metedataArm, '');
var cmdsArm = Object.keys(result);
console.log(util.inspect(cmdsArm));

console.log('********************************');
console.log('Done with ARM');
console.log('********************************');

result = {};
var metedataAsm = require('../lib/plugins.asm.json');
parse(metedataAsm, '');
var cmdsAsm = Object.keys(result);
console.log(util.inspect(cmdsAsm));

console.log('********************************');
console.log('The total number of commands for xplat-cli in ARM mode is: ' + cmdsArm.length);
console.log('The total number of commands for xplat-cli in ASM mode is: ' + cmdsAsm.length);
console.log('********************************');

function parse(cmdObj, category) {
  if (cmdObj !== null && typeof cmdObj === 'object') {
    Object.keys(cmdObj).forEach(function (key) {
      if (key === 'commands') {
        cmdObj[key].forEach(function (element) {
          var fullname = element.filePath + ': ' + category + ' ' + element.name;
          result[fullname] = fullname;
        });
      } else if (key === 'categories') {
        Object.keys(cmdObj[key]).forEach(function (subCategory) {
          parse(cmdObj[key][subCategory], category + ' ' + subCategory);
        });
      }
    });
  }
}<|endoftext|>


<commit_before>module.exports = require('./PropertyView').extend({

  templateInput() {
    const pfx = this.pfx;
    const ppfx = this.ppfx;
    return `

    `;
  },

  onRender() {
    const pfx = this.pfx;
    const ppfx = this.ppfx;
    const itemCls = `${ppfx}radio-item-label`;
    const model = this.model;
    const prop = model.get('property');
    const options = model.get('list') || model.get('options') || [];

    if (!this.input) {
      if(options && options.length) {
        let inputStr = '';

        options.forEach(el => {
          let cl = el.className ?  `${el.className} ${pfx}icon ${itemCls}` : '';
          let id = `${prop}-${el.value}`;
          let labelTxt = el.name || el.value;
          let titleAttr = el.title ? `title="${el.title}"` : '';
          inputStr += `

              <input type="radio" class="${pfx}radio" id="${id}" name="${prop}" value="${el.value}"/>
              ${cl ? '' : labelTxt}

          `;
        });

        const inputHld = this.el.querySelector(`#${pfx}input-holder`);
        inputHld.innerHTML = `<div>${inputStr}</div>`;
        this.input = inputHld.firstChild;
      }
    }
  },
  /*
  getInputValue() {
    return this.$input ? this.$el.find('input:checked').val() : '';
  },
*/
  getInputValue() {
    const input = this.getInputEl();
    const inputIn = input ? input.querySelector('input:checked') : '';
    return inputIn ? inputIn.value : '';
  },

  setValue(value) {
    const model = this.model;
    let val = value || model.get('value') || model.getDefaultValue();
    const input = this.getInputEl();
    const inputIn = input ? input.querySelector(`[value="${val}"]`) : '';
    inputIn && (inputIn.checked = true);
  },

});
<commit_msg>Update radio property view setValue method<commit_after>module.exports = require('./PropertyView').extend({

  templateInput() {
    const pfx = this.pfx;
    const ppfx = this.ppfx;
    return `

    `;
  },

  onRender() {
    const pfx = this.pfx;
    const ppfx = this.ppfx;
    const itemCls = `${ppfx}radio-item-label`;
    const model = this.model;
    const prop = model.get('property');
    const options = model.get('list') || model.get('options') || [];

    if (!this.input) {
      if(options && options.length) {
        let inputStr = '';

        options.forEach(el => {
          let cl = el.className ?  `${el.className} ${pfx}icon ${itemCls}` : '';
          let id = `${prop}-${el.value}`;
          let labelTxt = el.name || el.value;
          let titleAttr = el.title ? `title="${el.title}"` : '';
          inputStr += `

              <input type="radio" class="${pfx}radio" id="${id}" name="${prop}" value="${el.value}"/>
              ${cl ? '' : labelTxt}

          `;
        });

        const inputHld = this.el.querySelector(`#${pfx}input-holder`);
        inputHld.innerHTML = `<div>${inputStr}</div>`;
        this.input = inputHld.firstChild;
      }
    }
  },

  getInputValue() {
    const inputChk = this.getCheckedEl();
    return inputChk ? inputChk.value : '';
  },

  getCheckedEl() {
    const input = this.getInputEl();
    return input ? input.querySelector('input:checked') : '';
  },

  setValue(value) {
    const model = this.model;
    let val = value || model.get('value') || model.getDefaultValue();
    const input = this.getInputEl();
    const inputIn = input ? input.querySelector(`[value="${val}"]`) : '';

    if (inputIn) {
      inputIn.checked = true
    } else {
      const inputChk = this.getCheckedEl();
      inputChk && (inputChk.checked = false);
    }
  },

});
<|endoftext|>


<commit_before>Z.wrap('github/jillix/layout/v0.0.1/layout.js', function (require, module, exports) {

module.exports = init;

/*
    type: constructor
*/
function init (config, ready) {
    var self = this;
    var pageName = '_page_' + self._name;

    config = $.extend(config, {
        locale: null,
        title: ""
    });

    // locale stuff
    self.locale = {};
    function verifyDeps() {

        if (typeof $ === "undefined") {
            throw new Error("jQuery is required for layout module");
        }

        if (config.locale && typeof $.cookie === "undefined") {
            throw new Error("jQuery cookie library is required when using locale");
        }
    }

    verifyDeps();

    // set locale
    self.locale.set = function (ev, data) {
        var locale = data.locale;
        var cookie = data.cookie || config.locale.cookie;
        $.cookie(cookie, locale);
        self.emit("localeSet", null, {
            locale: locale,
            cookie: cookie
        });
    };

    // get locale
    self.locale.get = function (ev, data) {
        return $.cookie(cookie || config.locale.cookie);
    };

    if (config.locale) {

        if (typeof config.locale === "string") {
            config.locale = {
                value: config.locale,
                cookie: "_loc"
            };
        }

        if (typeof config.locale.value !== "string") {
            throw new Error("config.locale.value shoud be a string.");
        }

        if (typeof config.locale.cookie !== "string") {
            throw new Error("config.locale.cookie shoud be a string.");
        }

        self.locale.set(config.locale);
    }

    // set document title
    if (config.title) {
        self.title = config.title;
        document.title = config.title;
    }

    // attach state handler to instance
    self.page = page;
    self.transition = transition;
    self.render = render;
    self.$jq = $jq;

    // state handler to handle css in pages
    self.pageSelector = '.' + pageName;

    // render other views
    for (var view in self.view) {
        self.view[view].render([{page: pageName}]);
    }

    // get pages dom refs
    self.pages = $(self.pageSelector);

    // hide all pages in init state
    self.pages.hide();

    // handle not found
    if ((self.notFound = $(config.notFound))) {
        self.on('route', notFoundHandler);
    }

    ready();
}

/*
    type: actor
*/
function page (state, data) {
    var self = this;
    var target = data.show;
    var options = data.options;

    // return when no target page is given
    if (!target) {
        return;
    }

    // state found
    self._state = true;

    options = options || {};

    // hide not found
    if (self.notFound) {
        self.notFound.hide();
    }

    // set document title
    if (self.title) {
        document.title = self.title;
    }

    self.pages.hide();

    var targetPage = $(target);

    // animate page transition
    if (options.animate) {
        animate.call(self, targetPage, options.animate);

    // show requested page
    } else {
        targetPage.show();
    }
}

/*
    type: actor
    TODO: implement animations
*/
function transition (state, data) {

    if (!data) {
        return;
    }

    data.hide && $(data.hide).hide();
    data.show && $(data.show).show();
}

/*
    type: private
*/
function animate (elm, config) {
    var self = this;

    if (!elm || !config) {
        return;
    }

    for (var i = 0; i < config.length; ++i) {

        // get element
        elm = config[i].elm ? $(config[i].elm, elm) : elm;

        // handle show/hide
        if (config[i].fx === 'show' || config[i].fx === 'hide') {
            elm[config[i].fx]();

        // handle animateion
        } else {

            // set timing
            if (config[i].dd) {
                elm.css("-webkit-animation-duration", config[i].dd[0]);
                elm.css("-webkit-animation-delay", config[i].dd[1]);
            }

            var animate_class = 'animated ' + config[i].fx;

            // animation end handler
            elm.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', animation_end_handler(elm, animate_class));

            // start animation
            elm.addClass(animate_class);
            elm.show();
        }
    }
}

/*
    type: actor
*/
function render (event, data) {
    var self = this;
    var view = data.view;

    if (!self.view || !self.view[view] || !data) {
        return;
    }

    // TODO Handle pages on manual rendering
    // data.item && (data.item.page = '_page_' + self._name);

    // render data
    self.view[view].render([data.item]);
}

/*
    type: actor
    desc: mainpulate dom with jquery
*/
function $jq (event, data) {
    var self = this;
    var selector = data.selector;
    var method = data.method;
    var args = data.args;

    // call jquery function
    if ($.fn[method]) {

        // get selector from url
        if (typeof selector !== 'string') {

            // return when regexp is not found
            var re = new RegExp(selector[0]);
            if (!re.test(window.location)) {
                return;
            }

            selector = window.location.href.replace(re, selector[1]);

        } else {

            // get selector
            switch (selector) {
                case 'cur':
                    selector = event.currentTarget;
                    break;
                case 'src':
                    selector = event.srcElement;
                    break;
                case 'all':
                    selector = event.elms;
                    break;
            }
        }

        // call method
        selector = $(selector);
        selector[method].apply(selector, args);
    }
}

/*
    type: private
*/
function animation_end_handler (elm, animate_class) {
    return function () {
        elm.removeClass(animate_class);
    };
}

/*
    type: private
    TODO: needs to be tested
*/
function notFoundHandler (state) {
    var self = this;

    if (self._url === state.url) {
        return;
    }

    if (!self._state) {
        self.pages.hide();
        self.notFound.show();
    }

    self._state = false;
}

return module;

});
<commit_msg>Providing callback via data<commit_after>Z.wrap('github/jillix/layout/v0.0.1/layout.js', function (require, module, exports) {

module.exports = init;

/*
    type: constructor
*/
function init (config, ready) {
    var self = this;
    var pageName = '_page_' + self._name;

    config = $.extend(config, {
        locale: null,
        title: ""
    });

    // locale stuff
    self.locale = {};
    function verifyDeps() {

        if (typeof $ === "undefined") {
            throw new Error("jQuery is required for layout module");
        }

        if (config.locale && typeof $.cookie === "undefined") {
            throw new Error("jQuery cookie library is required when using locale");
        }
    }

    verifyDeps();

    // set locale
    self.locale.set = function (ev, data) {
        var locale = data.locale;
        var cookie = data.cookie || config.locale.cookie;
        $.cookie(cookie, locale);
        self.emit("localeSet", null, {
            locale: locale,
            cookie: cookie
        });
    };

    // get locale
    self.locale.get = function (ev, data) {
        data && data.callback(null, $.cookie(cookie || config.locale.cookie));
    };

    if (config.locale) {

        if (typeof config.locale === "string") {
            config.locale = {
                value: config.locale,
                cookie: "_loc"
            };
        }

        if (typeof config.locale.value !== "string") {
            throw new Error("config.locale.value shoud be a string.");
        }

        if (typeof config.locale.cookie !== "string") {
            throw new Error("config.locale.cookie shoud be a string.");
        }

        self.locale.set(config.locale);
    }

    // set document title
    if (config.title) {
        self.title = config.title;
        document.title = config.title;
    }

    // attach state handler to instance
    self.page = page;
    self.transition = transition;
    self.render = render;
    self.$jq = $jq;

    // state handler to handle css in pages
    self.pageSelector = '.' + pageName;

    // render other views
    for (var view in self.view) {
        self.view[view].render([{page: pageName}]);
    }

    // get pages dom refs
    self.pages = $(self.pageSelector);

    // hide all pages in init state
    self.pages.hide();

    // handle not found
    if ((self.notFound = $(config.notFound))) {
        self.on('route', notFoundHandler);
    }

    ready();
}

/*
    type: actor
*/
function page (state, data) {
    var self = this;
    var target = data.show;
    var options = data.options;

    // return when no target page is given
    if (!target) {
        return;
    }

    // state found
    self._state = true;

    options = options || {};

    // hide not found
    if (self.notFound) {
        self.notFound.hide();
    }

    // set document title
    if (self.title) {
        document.title = self.title;
    }

    self.pages.hide();

    var targetPage = $(target);

    // animate page transition
    if (options.animate) {
        animate.call(self, targetPage, options.animate);

    // show requested page
    } else {
        targetPage.show();
    }
}

/*
    type: actor
    TODO: implement animations
*/
function transition (state, data) {

    if (!data) {
        return;
    }

    data.hide && $(data.hide).hide();
    data.show && $(data.show).show();
}

/*
    type: private
*/
function animate (elm, config) {
    var self = this;

    if (!elm || !config) {
        return;
    }

    for (var i = 0; i < config.length; ++i) {

        // get element
        elm = config[i].elm ? $(config[i].elm, elm) : elm;

        // handle show/hide
        if (config[i].fx === 'show' || config[i].fx === 'hide') {
            elm[config[i].fx]();

        // handle animateion
        } else {

            // set timing
            if (config[i].dd) {
                elm.css("-webkit-animation-duration", config[i].dd[0]);
                elm.css("-webkit-animation-delay", config[i].dd[1]);
            }

            var animate_class = 'animated ' + config[i].fx;

            // animation end handler
            elm.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', animation_end_handler(elm, animate_class));

            // start animation
            elm.addClass(animate_class);
            elm.show();
        }
    }
}

/*
    type: actor
*/
function render (event, data) {
    var self = this;
    var view = data.view;

    if (!self.view || !self.view[view] || !data) {
        return;
    }

    // TODO Handle pages on manual rendering
    // data.item && (data.item.page = '_page_' + self._name);

    // render data
    self.view[view].render([data.item]);
}

/*
    type: actor
    desc: mainpulate dom with jquery
*/
function $jq (event, data) {
    var self = this;
    var selector = data.selector;
    var method = data.method;
    var args = data.args;

    // call jquery function
    if ($.fn[method]) {

        // get selector from url
        if (typeof selector !== 'string') {

            // return when regexp is not found
            var re = new RegExp(selector[0]);
            if (!re.test(window.location)) {
                return;
            }

            selector = window.location.href.replace(re, selector[1]);

        } else {

            // get selector
            switch (selector) {
                case 'cur':
                    selector = event.currentTarget;
                    break;
                case 'src':
                    selector = event.srcElement;
                    break;
                case 'all':
                    selector = event.elms;
                    break;
            }
        }

        // call method
        selector = $(selector);
        selector[method].apply(selector, args);
    }
}

/*
    type: private
*/
function animation_end_handler (elm, animate_class) {
    return function () {
        elm.removeClass(animate_class);
    };
}

/*
    type: private
    TODO: needs to be tested
*/
function notFoundHandler (state) {
    var self = this;

    if (self._url === state.url) {
        return;
    }

    if (!self._state) {
        self.pages.hide();
        self.notFound.show();
    }

    self._state = false;
}

return module;

});
<|endoftext|>


<commit_before>var BODY_POLL_MS = 30;
var DIMMER_DIV_ID = '_crackbook_dimmer_';
var DIMMER_TEXT1 = "Enough junk for today, don't you think?";
var DIMMER_TEXT2 = "Wait %d seconds for the content to appear.";
var DIMMER_TEXT3 = "The timer restarts if you switch away from this tab.";

var timeoutFn = function() {
  var dimmer = document.getElementById(DIMMER_DIV_ID);
  dimmer.style.display = "none";
  // Disable the dimmer, and do not dim this page again.
}

function clearTimer(dimmer) {
  // Clear old timer.
  var timerIdInput = document.getElementById(DIMMER_DIV_ID + "timerId");
  if (timerIdInput) {
    timerId = parseInt(timerIdInput.value);
    clearTimeout(timerId);
    dimmer.removeChild(timerIdInput);
  }
}

function setTimer(dimmer, delay) {
  // Clear old timer.
  var timerIdInput = document.getElementById(DIMMER_DIV_ID + "timerId");
  if (timerIdInput) {
    timerId = parseInt(timerIdInput.value);
    clearTimeout(timerId);
  }

  // Set timer.
  var timerId = setTimeout(timeoutFn, Math.round(delay * 1000));

  // Store timer ID.
  if (!timerIdInput) {
    var timerIdInput = document.createElement("input");
    timerIdInput.id = DIMMER_DIV_ID + "timerId";
    timerIdInput.type = "hidden";
    dimmer.appendChild(timerIdInput);
  }
  timerIdInput.value = timerId;
}

function addDimmer(delay, appearance) {
  var dimmer = document.createElement('div');
  dimmer.id = DIMMER_DIV_ID;

  // TODO: add a picture

  // Message
  dimmer.style.color = "#ffffff";
  dimmer.style.paddingTop = window.innerHeight / 2 - 30 + "px";
  dimmer.style.fontSize = '36px';
  dimmer.style.fontFamily = 'Georgia';
  dimmer.style.fontVariant = 'normal';

  var text1 = document.createElement("div");
  text1.innerHTML = DIMMER_TEXT1;
  text1.style.textAlign = "center";
  dimmer.appendChild(text1);

  var text2 = document.createElement("div");
  text2.innerHTML = DIMMER_TEXT2.replace('%d', Math.round(delay));
  text2.style.textAlign = "center";
  text2.style.paddingTop = "50px";
  text2.style.fontSize = "20px";
  dimmer.appendChild(text2);

  var text3 = document.createElement("div");
  text3.innerHTML = DIMMER_TEXT3;
  text3.id = DIMMER_DIV_ID + 'stayput';
  text3.style.display = "none";
  text3.style.textAlign = "center";
  text3.style.paddingTop = "10px";
  text3.style.fontSize = "14px";
  text3.style.color = "#aaaaaa";
  dimmer.appendChild(text3);

  // Positioning.
  dimmer.style.position = "fixed";
  dimmer.style.top = "0px";
  dimmer.style.left = "0px";
  dimmer.style.width = "100%";
  dimmer.style.height = "100%";

  // Background.
  dimmer.style.background = "#001000";
  if (appearance && appearance.transparent) {
    dimmer.style.opacity = "0.95";
  }
  dimmer.style.zIndex = "99999";

  document.body.insertBefore(dimmer, document.body.firstChild);

  return dimmer;
}

// Actions

function create(dimmer_el, delay, appearance) {
  if (!dimmer_el) {
    var dimmer = addDimmer(delay, appearance);
    setTimer(dimmer, delay);
  }
}

function create_suspended(dimmer_el, delay, appearance) {
  if (!dimmer_el) {
    var dimmer = addDimmer(delay, appearance);
  }
}

function suspend(dimmer_el, delay) {
  if (dimmer_el) {
    clearTimer(dimmer_el);
  }
}

function resume(dimmer_el, delay) {
  if (dimmer_el && dimmer_el.style.display != "none") {
    setTimer(dimmer_el, delay);

    var text3 = document.getElementById(DIMMER_DIV_ID + 'stayput');
    text3.style.display = "block";
  }
}

/* Dims the current page for a given time in seconds

   'action' is one of the following:
     - "create": a dimmer is created on the page if it is not already there and a timer is started
     - "create_suspended": a dimmer is created on the page if it is not already there, no timer is started
     - "suspend": the countdown is suspended if there is a dimmer on the page, no-op otherwise
     - "resume": the countdown is resumed if there is a dimmer on the page, no-op otherwise

   'delay' is delay time in seconds.
 */
function dim(action, delay, appearance) {
  // Dispatch by action name.
  var action_fns = {
    create: create,
    suspend: suspend,
    resume: resume,
    create_suspended: create_suspended
  };

  var action_fn = action_fns[action];

  var dimmer_el = document.getElementById(DIMMER_DIV_ID);
  action_fn(dimmer_el, delay, appearance);
}

/* Forwarder function for calls using executeScript() */
function invoke_dimmer(args) {
  dim(args.dimmerAction, args.delay, args.appearance);
}

// On initial load, check with the extension whether action needs to be taken.
chrome.extension.sendRequest({}, function(response) {
  if (response.redirectUrl) {
    window.location.href = response.redirectUrl;
  } else if (response.dimmerAction) {
    function delayedDimmerFn() {
      if (document.body != null) {
        // The body of the document has started loading, the dimmer can be shown.
        invoke_dimmer(response);
      } else {
        // The body is not yet available.
        setTimeout(delayedDimmerFn, BODY_POLL_MS);
      }
    }
    // Start polling.
    delayedDimmerFn();
  }
});
<commit_msg>Removed slightly obnoxious message on the center.<commit_after>var BODY_POLL_MS = 30;
var DIMMER_DIV_ID = '_crackbook_dimmer_';
var DIMMER_TEXT = "Wait %d seconds for the content to appear.";
var DIMMER_SWITCH_TEXT = "The timer restarts if you switch away from this tab.";

var timeoutFn = function() {
  var dimmer = document.getElementById(DIMMER_DIV_ID);
  dimmer.style.display = "none";
  // Disable the dimmer, and do not dim this page again.
}

function clearTimer(dimmer) {
  // Clear old timer.
  var timerIdInput = document.getElementById(DIMMER_DIV_ID + "timerId");
  if (timerIdInput) {
    timerId = parseInt(timerIdInput.value);
    clearTimeout(timerId);
    dimmer.removeChild(timerIdInput);
  }
}

function setTimer(dimmer, delay) {
  // Clear old timer.
  var timerIdInput = document.getElementById(DIMMER_DIV_ID + "timerId");
  if (timerIdInput) {
    timerId = parseInt(timerIdInput.value);
    clearTimeout(timerId);
  }

  // Set timer.
  var timerId = setTimeout(timeoutFn, Math.round(delay * 1000));

  // Store timer ID.
  if (!timerIdInput) {
    var timerIdInput = document.createElement("input");
    timerIdInput.id = DIMMER_DIV_ID + "timerId";
    timerIdInput.type = "hidden";
    dimmer.appendChild(timerIdInput);
  }
  timerIdInput.value = timerId;
}

function addDimmer(delay, appearance) {
  var dimmer = document.createElement('div');
  dimmer.id = DIMMER_DIV_ID;

  // TODO: add a picture

  // Message
  dimmer.style.color = "#ffffff";
  dimmer.style.paddingTop = window.innerHeight / 2 - 30 + "px";
  dimmer.style.fontSize = '36px';
  dimmer.style.fontFamily = 'Georgia';
  dimmer.style.fontVariant = 'normal';

  var text = document.createElement("div");
  text.innerHTML = DIMMER_TEXT.replace('%d', Math.round(delay));
  text.style.textAlign = "center";
  text.style.paddingTop = "50px";
  text.style.fontSize = "20px";
  dimmer.appendChild(text);

  var switch_text = document.createElement("div");
  switch_text.innerHTML = DIMMER_SWITCH_TEXT;
  switch_text.id = DIMMER_DIV_ID + 'stayput';
  switch_text.style.display = "none";
  switch_text.style.textAlign = "center";
  switch_text.style.paddingTop = "10px";
  switch_text.style.fontSize = "14px";
  switch_text.style.color = "#aaaaaa";
  dimmer.appendChild(switch_text);

  // Positioning.
  dimmer.style.position = "fixed";
  dimmer.style.top = "0px";
  dimmer.style.left = "0px";
  dimmer.style.width = "100%";
  dimmer.style.height = "100%";

  // Background.
  dimmer.style.background = "#001000";
  if (appearance && appearance.transparent) {
    dimmer.style.opacity = "0.95";
  }
  dimmer.style.zIndex = "99999";

  document.body.insertBefore(dimmer, document.body.firstChild);

  return dimmer;
}

// Actions

function create(dimmer_el, delay, appearance) {
  if (!dimmer_el) {
    var dimmer = addDimmer(delay, appearance);
    setTimer(dimmer, delay);
  }
}

function create_suspended(dimmer_el, delay, appearance) {
  if (!dimmer_el) {
    var dimmer = addDimmer(delay, appearance);
  }
}

function suspend(dimmer_el, delay) {
  if (dimmer_el) {
    clearTimer(dimmer_el);
  }
}

function resume(dimmer_el, delay) {
  if (dimmer_el && dimmer_el.style.display != "none") {
    setTimer(dimmer_el, delay);

    var switch_text = document.getElementById(DIMMER_DIV_ID + 'stayput');
    switch_text.style.display = "block";
  }
}

/* Dims the current page for a given time in seconds

   'action' is one of the following:
     - "create": a dimmer is created on the page if it is not already there and a timer is started
     - "create_suspended": a dimmer is created on the page if it is not already there, no timer is started
     - "suspend": the countdown is suspended if there is a dimmer on the page, no-op otherwise
     - "resume": the countdown is resumed if there is a dimmer on the page, no-op otherwise

   'delay' is delay time in seconds.
 */
function dim(action, delay, appearance) {
  // Dispatch by action name.
  var action_fns = {
    create: create,
    suspend: suspend,
    resume: resume,
    create_suspended: create_suspended
  };

  var action_fn = action_fns[action];

  var dimmer_el = document.getElementById(DIMMER_DIV_ID);
  action_fn(dimmer_el, delay, appearance);
}

/* Forwarder function for calls using executeScript() */
function invoke_dimmer(args) {
  dim(args.dimmerAction, args.delay, args.appearance);
}

// On initial load, check with the extension whether action needs to be taken.
chrome.extension.sendRequest({}, function(response) {
  if (response.redirectUrl) {
    window.location.href = response.redirectUrl;
  } else if (response.dimmerAction) {
    function delayedDimmerFn() {
      if (document.body != null) {
        // The body of the document has started loading, the dimmer can be shown.
        invoke_dimmer(response);
      } else {
        // The body is not yet available.
        setTimeout(delayedDimmerFn, BODY_POLL_MS);
      }
    }
    // Start polling.
    delayedDimmerFn();
  }
});
<|endoftext|>


<commit_before>define([
        'underscore',
        'jquery',
        'JBrowse/Browser',
        'JBrowse/Model/SimpleFeature',
        '../tests/data/RefSeq_1',
        '../tests/data/RefSeq_2',
        '../tests/data/transcripts/transcript_data',
        '../tests/data/tracks',
        ], function (
            _,
            $,
            Browser,
            SimpleFeature,
            refSeq,
            refSeq_2,
            transcript_data,
            track
            ) {

describe( "Edit Track", function() {

    var baseURL = '/data/jbrowse/Solenopsis_invicta/Si_gnF';
    var jbrowse = new Browser({
        containerID: 'genome',
        baseUrl: baseURL,
        include: [baseURL + '/trackList.json', '/data/jbrowse/edit-track.json'],
        refSeqs: baseURL + '/seq/refSeqs.json'
    });

    var editTrack;
    var sortAnnotations = function(annots) {

        if (!_.isArray(annots)) return;

        return annots.sort(function(annot1, annot2) {
            var start1 = annot1.get("start");
            var end1 = annot1.get("end");
            var start2 = annot2.get("start");
            var end2 = annot2.get("end");
            var type1 = annot1.get("type");
            var type2 = annot2.get("type");

            if (start1 != start2)  { return start1 - start2; }
            else if (end1 != end2) { return end1 - end2; }
            else                   { if (type1 === type2) {
                                       return 0;
                                   }
                                   else {
                                       if(type1 < type2) {
                                           return -1;
                                       }
                                       else {
                                           return 1;
                                       }
                                   }
                               }
        });
    };

    /**
     * Returns `true` if the given SimpleFeature objects are "equal" and false
     * if they aren't.
     * Two SimpleFeature A and B are to be considered equal if
     * 1. If the type, start, end, strand and seq_id of A is same that of B.
     * 2. If any of A or B contains subfeatures then the set of subfeatures of
     *    A should be "equal" to the set of subfeatures of B.
     **/
    var compareFeatures = function(feature_a, feature_b) {
        var a = feature_a.data;
        var b = feature_b.data;

        if (a.type === b.type
                && a.seq_id === b.seq_id
                && a.start === b.start
                && a.end === b.end
                && a.strand === b.strand) {
            if (a.subfeatures !== undefined || b.subfeatures !== undefined) {
                return _.every(_.zip(sortAnnotations(a.subfeatures),
                            sortAnnotations(b.subfeatures)), function (sub_pair) {
                                return compareFeatures(sub_pair[0], sub_pair[1]);
                            });
            }
            return true;
        }
        return false;
    };

    beforeEach(function(done) {
        setTimeout(function () {
            editTrack = jbrowse.getEditTrack();
            done();
        }, 1000);
    });

    it( 'constructs', function() {
        expect(editTrack).toBeTruthy();
        expect(compareFeatures).toBeDefined();
        expect(refSeq).toBeDefined();
        expect(refSeq_2).toBeDefined();
        expect(transcript_data).toBeDefined();
        expect(track).toBeDefined();
    });

    it( 'tests comparison function', function() {
        expect(compareFeatures(transcript_data["input"][0], transcript_data["input"][0])).toBe(true);
    });

    it('tests getWholeCDSCoordinates', function() {
        expect(editTrack.getWholeCDSCoordinates(transcript_data.input[0])).toEqual([undefined, undefined]);
        expect(editTrack.getWholeCDSCoordinates(transcript_data.input[1])).toEqual([19977, 18796]);
    });

    it('tests flipStrand', function() {
        expect(editTrack.flipStrand(transcript_data.input[0]).get('strand')).toEqual(-1);
    });

    it('tests setLongestORF', function() {
        expect(compareFeatures(transcript_data.orf[2], editTrack.setLongestORF(refSeq, transcript_data.input[1]))).toEqual(true);
    });

    it('tests markNonCanonicalSpliceSites', function() {
        expect(editTrack.markNonCanonicalSpliceSites(transcript_data.input[0],
            refSeq).get('subfeatures')[2].get('type')).toEqual('non_canonical_splice_site');
    });

    it('tests markNonCanonicalTranslationStartSite', function() {
        expect(editTrack.markNonCanonicalTranslationStartSite(transcript_data.non_canonical[1],
            refSeq).get('subfeatures')[2].get('type')).toEqual('non_canonical_translation_start_site');
    });

    it('tests markNonCanonicalTranslationStopSite', function() {
        expect(editTrack.markNonCanonicalTranslationStopSite(transcript_data.non_canonical[0],
            refSeq).get('subfeatures')[0].get('type')).toEqual('non_canonical_translation_stop_site');
    });

    it('tests transcriptToCDNA', function() {
        expect(editTrack.transcriptToCDNA(transcript_data.input[3], 4)).toEqual(0);
    });

    it('tests CDNAToTranscript', function() {
        expect(editTrack.CDNAToTranscript(transcript_data.input[3], 0)).toEqual(4);
    });

    it('tests getCDNA', function() {
        expect(editTrack.getCDNA(refSeq_2, transcript_data.input[2])).toEqual(refSeq_2.slice(1));
    });

    it('tests getCDS', function() {
        expect(editTrack.getCDS(refSeq_2, transcript_data.input[2])).toEqual(refSeq_2.slice(1));
    });

    it ('test setORF', function() {
        expect(compareFeatures(
                editTrack.setORF(refSeq_2, transcript_data.input[2]),
                transcript_data.orf[0])).toBe(true);

        expect(compareFeatures(
                editTrack.setORF(refSeq_2, transcript_data.input[3]),
                transcript_data.orf[1])).toBe(true);
    });

    it ('tests setCDS', function() {
        expect(compareFeatures(
                editTrack.setCDS(transcript_data.input[4], 0, 24),
                transcript_data.cds[0])).toBe(true);
    });

    it( 'tests resizeExon', function() {
        exon = editTrack.filterExons(transcript_data["input"][0])[0];
        var right = 17120;
        var left = exon.get('start');
        outTranscript = editTrack.resizeExon(refSeq, transcript_data["input"][0], exon, left, right);
        expect(compareFeatures(transcript_data["resize"][0], outTranscript)).toBe(true);

        exon = editTrack.filterExons(transcript_data["input"][1])[1];
        var right = exon.get('end') + 3;
        var left = exon.get('start');
        outTranscript = editTrack.resizeExon(refSeq, transcript_data["input"][1], exon, left, right);
        expect(compareFeatures(transcript_data["resize"][2], outTranscript)).toBe(true);
    });

    it( 'tests areOnSameStrand', function() {
        expect(editTrack.areOnSameStrand([transcript_data.input[0], transcript_data.input[2]])).toBe(true);
        expect(editTrack.areOnSameStrand([transcript_data.input[0], transcript_data.input[1]])).toBe(false);
    });

    it( 'tests mergeTranscripts', function() {
        expect(compareFeatures(
                editTrack.mergeTranscripts(refSeq_2,
                    [transcript_data.input[7], transcript_data.input[7]]),
                transcript_data.input[7])).toBe(true);

        expect(compareFeatures(
                editTrack.mergeTranscripts(refSeq_2,
                    [transcript_data.input[6], transcript_data.input[7]]),
                transcript_data.input[6])).toBe(true);

            expect(compareFeatures(
                    editTrack.mergeTranscripts(refSeq_2,
                        [transcript_data.input[4], transcript_data.input[5]]),
                    transcript_data.merge[0])).toBe(true);

    });

    it( 'tests normalizeFeature', function() {
        exon = editTrack.filterExons(transcript_data.input[7])[0];
        expect(compareFeatures(
                editTrack.normalizeFeature(exon, track),
                transcript_data.normalize[0])).toBe(true);
    });
});
});
<commit_msg>added new test "filterFeatures"<commit_after>define([
        'underscore',
        'jquery',
        'JBrowse/Browser',
        'JBrowse/Model/SimpleFeature',
        '../tests/data/RefSeq_1',
        '../tests/data/RefSeq_2',
        '../tests/data/transcripts/transcript_data',
        '../tests/data/tracks',
        ], function (
            _,
            $,
            Browser,
            SimpleFeature,
            refSeq,
            refSeq_2,
            transcript_data,
            track
            ) {

describe( "Edit Track", function() {

    var baseURL = '/data/jbrowse/Solenopsis_invicta/Si_gnF';
    var jbrowse = new Browser({
        containerID: 'genome',
        baseUrl: baseURL,
        include: [baseURL + '/trackList.json', '/data/jbrowse/edit-track.json'],
        refSeqs: baseURL + '/seq/refSeqs.json'
    });

    var editTrack;
    var sortAnnotations = function(annots) {

        if (!_.isArray(annots)) return;

        return annots.sort(function(annot1, annot2) {
            var start1 = annot1.get("start");
            var end1 = annot1.get("end");
            var start2 = annot2.get("start");
            var end2 = annot2.get("end");
            var type1 = annot1.get("type");
            var type2 = annot2.get("type");

            if (start1 != start2)  { return start1 - start2; }
            else if (end1 != end2) { return end1 - end2; }
            else                   { if (type1 === type2) {
                                       return 0;
                                   }
                                   else {
                                       if(type1 < type2) {
                                           return -1;
                                       }
                                       else {
                                           return 1;
                                       }
                                   }
                               }
        });
    };

    /**
     * Returns `true` if the given SimpleFeature objects are "equal" and false
     * if they aren't.
     * Two SimpleFeature A and B are to be considered equal if
     * 1. If the type, start, end, strand and seq_id of A is same that of B.
     * 2. If any of A or B contains subfeatures then the set of subfeatures of
     *    A should be "equal" to the set of subfeatures of B.
     **/
    var compareFeatures = function(feature_a, feature_b) {
        var a = feature_a.data;
        var b = feature_b.data;

        if (a.type === b.type
                && a.seq_id === b.seq_id
                && a.start === b.start
                && a.end === b.end
                && a.strand === b.strand) {
            if (a.subfeatures !== undefined || b.subfeatures !== undefined) {
                return _.every(_.zip(sortAnnotations(a.subfeatures),
                            sortAnnotations(b.subfeatures)), function (sub_pair) {
                                return compareFeatures(sub_pair[0], sub_pair[1]);
                            });
            }
            return true;
        }
        return false;
    };

    beforeEach(function(done) {
        setTimeout(function () {
            editTrack = jbrowse.getEditTrack();
            done();
        }, 1000);
    });

    it( 'constructs', function() {
        expect(editTrack).toBeTruthy();
        expect(compareFeatures).toBeDefined();
        expect(refSeq).toBeDefined();
        expect(refSeq_2).toBeDefined();
        expect(transcript_data).toBeDefined();
        expect(track).toBeDefined();
    });

    it( 'tests comparison function', function() {
        expect(compareFeatures(transcript_data["input"][0], transcript_data["input"][0])).toBe(true);
    });

    it('tests getWholeCDSCoordinates', function() {
        expect(editTrack.getWholeCDSCoordinates(transcript_data.input[0])).toEqual([undefined, undefined]);
        expect(editTrack.getWholeCDSCoordinates(transcript_data.input[1])).toEqual([19977, 18796]);
    });

    it('tests flipStrand', function() {
        expect(editTrack.flipStrand(transcript_data.input[0]).get('strand')).toEqual(-1);
    });

    it('tests setLongestORF', function() {
        expect(compareFeatures(transcript_data.orf[2], editTrack.setLongestORF(refSeq, transcript_data.input[1]))).toEqual(true);
    });

    it('tests markNonCanonicalSpliceSites', function() {
        expect(editTrack.markNonCanonicalSpliceSites(transcript_data.input[0],
            refSeq).get('subfeatures')[2].get('type')).toEqual('non_canonical_splice_site');
    });

    it('tests markNonCanonicalTranslationStartSite', function() {
        expect(editTrack.markNonCanonicalTranslationStartSite(transcript_data.non_canonical[1],
            refSeq).get('subfeatures')[2].get('type')).toEqual('non_canonical_translation_start_site');
    });

    it('tests markNonCanonicalTranslationStopSite', function() {
        expect(editTrack.markNonCanonicalTranslationStopSite(transcript_data.non_canonical[0],
            refSeq).get('subfeatures')[0].get('type')).toEqual('non_canonical_translation_stop_site');
    });

    it('tests filterFeatures', function() {
        expect(editTrack.filterFeatures(transcript_data.input[0], 'exon')[0].get('start')).toEqual(16946);
    });

    it('tests transcriptToCDNA', function() {
        expect(editTrack.transcriptToCDNA(transcript_data.input[3], 4)).toEqual(0);
    });

    it('tests CDNAToTranscript', function() {
        expect(editTrack.CDNAToTranscript(transcript_data.input[3], 0)).toEqual(4);
    });

    it('tests getCDNA', function() {
        expect(editTrack.getCDNA(refSeq_2, transcript_data.input[2])).toEqual(refSeq_2.slice(1));
    });

    it('tests getCDS', function() {
        expect(editTrack.getCDS(refSeq_2, transcript_data.input[2])).toEqual(refSeq_2.slice(1));
    });

    it ('test setORF', function() {
        expect(compareFeatures(
                editTrack.setORF(refSeq_2, transcript_data.input[2]),
                transcript_data.orf[0])).toBe(true);

        expect(compareFeatures(
                editTrack.setORF(refSeq_2, transcript_data.input[3]),
                transcript_data.orf[1])).toBe(true);
    });

    it ('tests setCDS', function() {
        expect(compareFeatures(
                editTrack.setCDS(transcript_data.input[4], 0, 24),
                transcript_data.cds[0])).toBe(true);
    });

    it( 'tests resizeExon', function() {
        exon = editTrack.filterExons(transcript_data["input"][0])[0];
        var right = 17120;
        var left = exon.get('start');
        outTranscript = editTrack.resizeExon(refSeq, transcript_data["input"][0], exon, left, right);
        expect(compareFeatures(transcript_data["resize"][0], outTranscript)).toBe(true);

        exon = editTrack.filterExons(transcript_data["input"][1])[1];
        var right = exon.get('end') + 3;
        var left = exon.get('start');
        outTranscript = editTrack.resizeExon(refSeq, transcript_data["input"][1], exon, left, right);
        expect(compareFeatures(transcript_data["resize"][2], outTranscript)).toBe(true);
    });

    it( 'tests areOnSameStrand', function() {
        expect(editTrack.areOnSameStrand([transcript_data.input[0], transcript_data.input[2]])).toBe(true);
        expect(editTrack.areOnSameStrand([transcript_data.input[0], transcript_data.input[1]])).toBe(false);
    });

    it( 'tests mergeTranscripts', function() {
        expect(compareFeatures(
                editTrack.mergeTranscripts(refSeq_2,
                    [transcript_data.input[7], transcript_data.input[7]]),
                transcript_data.input[7])).toBe(true);

        expect(compareFeatures(
                editTrack.mergeTranscripts(refSeq_2,
                    [transcript_data.input[6], transcript_data.input[7]]),
                transcript_data.input[6])).toBe(true);

            expect(compareFeatures(
                    editTrack.mergeTranscripts(refSeq_2,
                        [transcript_data.input[4], transcript_data.input[5]]),
                    transcript_data.merge[0])).toBe(true);

    });

    it( 'tests normalizeFeature', function() {
        exon = editTrack.filterExons(transcript_data.input[7])[0];
        expect(compareFeatures(
                editTrack.normalizeFeature(exon, track),
                transcript_data.normalize[0])).toBe(true);
    });
});
});
<|endoftext|>


<commit_before>'use strict';

var letsGoRunning = false;
var letsGoTicketsOut = 0;
var letsGoTicketsDone = 0;

var letsGo = function(target, command, attribute, queue) {
    var queueMatters = false;

    var checkIfAttribute = function(element, attribute, attributeIsClass) {
        if (!attribute || attributeIsClass) {
            attribute = (attribute) ? attribute : 'letsGo-hide';
            return (' ' + element.className + ' ').indexOf(' ' + attribute + ' ') > -1;
        } else if (attribute.indexOf('=') > -1) {
            attribute = attribute.split('=');
            return (element.hasAttribute(attribute[0])) && (element.getAttribute(attribute[0]) === attribute[1]);
        } else {
            return (element.hasAttribute(attribute) && (element.getAttribute(attribute) === ''));
        }
    }

    var findAnimateTime = function(times) {
        if (times.indexOf(',') > -1) {
            times = times.split(',');
            for (var i = 0; i < times.length; i++) {
                times[i] = Number(times[i].slice(0, -1));
            }
            times = Math.max.apply(null, times);
        } else {
            times = Number(times.slice(0, -1));
        }
        return times;
    };

    var alterAttribute = function(element, styles, add, attribute, attributeIsClass, lastOne) {
        var command = (add) ? 'add' : 'remove';

        if (attributeIsClass) {
            var alterAttributeDone = function() {
                element.removeEventListener('animationend', alterAttributeDone, false);
                if (add) {
                    element.classList.add(attribute);
                }
                element.classList.remove(attribute + '-' + command);
                element.classList.remove(attribute + '-' + command + '-active');
                element.classList.remove('letsGo-animate');
                if (queueMatters && lastOne) {
                    letsGoTicketsDone++;
                    letsGoRunning = false;
                }
            };

            element.classList.add('letsGo-animate');
            element.classList.add(attribute + '-' + command);
            if (!add) {
                element.classList.remove(attribute);
            }
            setTimeout(function() {
                if ((styles.transitionDuration !== '0s') || (styles.animationDuration !== '0s')) {
                    element.classList.add(attribute + '-' + command + '-active');
                    var maxTransitionTime = findAnimateTime(styles.transitionDuration);
                    var maxAnimationTime = findAnimateTime(styles.animationDuration);
                    var maxTime = Math.ceil(Math.max(maxTransitionTime, maxAnimationTime)*1000);
                    setTimeout(alterAttributeDone, maxTime);
                    if (styles.animationDuration !== '0s') {
                        element.addEventListener('animationend', alterAttributeDone, false);
                    }
                } else {
                    alterAttributeDone();
                }
            }, 0);
        } else {
            // var setTheAttribute = function() {
            //     element.setAttribute(attribute[0], attribute[1]);
            // }
            if (add) {
                if (attribute.indexOf('=') > -1) {
                     attribute = attribute.split('=');
                     element.setAttribute(attribute[0], attribute[1]);
                } else {
                    element.setAttribute(attribute, '');
                }
            } else {
                if (attribute.indexOf('=') > -1) {
                     attribute = attribute.split('=');
                     element.removeAttribute(attribute[0]);
                } else {
                    element.removeAttribute(attribute);
                }
            }
            if (queueMatters && lastOne) {
                letsGoTicketsDone++;
                letsGoRunning = false;
            }
        }
    };

    var router = function(target, command, attribute) {
        if (target) {
            if (command) {
                if (typeof target === 'string') {
                    var targetType = null;
                    var attributeIsClass = null;
                    var lastOne = false;
                    if (target.charAt(0) === '#') {
                        targetType = 'id';
                        target = target.substring(1);
                        var element = document.getElementById(target);
                        if (element !== null) {
                            var styles = window.getComputedStyle(element, null);
                            if (command === 'show' || command === 'hide') {
                                if (!attribute) {
                                    if (command === 'show') {
                                        alterAttribute(element, styles, false, 'letsGo-hide', true, true);
                                    } else if (command === 'hide') {
                                        alterAttribute(element, styles, true, 'letsGo-hide', true, true);
                                    }
                                } else {
                                    console.log('letsGo: using \'show\' or \'hide\' command can not have an \'attribute\' parameter.');
                                }
                            } else if ((command === 'add') || (command === 'remove')) {
                                if (attribute) {
                                    if (attribute.charAt(0) === '.') {
                                        attributeIsClass = true;
                                        attribute = attribute.substring(1);
                                    } else if (attribute.charAt(0) === '#') {
                                        attribute = 'id=' + attribute.substring(1);
                                    }
                                    if (command === 'add') {
                                        alterAttribute(element, styles, true, attribute, attributeIsClass, true);
                                    } else if (command === 'remove') {
                                        alterAttribute(element, styles, false, attribute, attributeIsClass, true);
                                    }
                                } else {
                                    console.log('letsGo: using \'add\' or \'remove\' command must also have an \'attribute\' parameter.');
                                }
                            } else if (command === 'toggle') {
                                if (attribute && attribute.charAt(0) === '.') {
                                    attributeIsClass = true;
                                    attribute = attribute.substring(1);
                                } else if (attribute && attribute.charAt(0) === '#') {
                                    attribute = 'id=' + attribute.substring(1);
                                } else if (!attribute) {
                                    attributeIsClass = true;
                                    attribute = 'letsGo-hide';
                                }
                                if (checkIfAttribute(element, attribute, attributeIsClass)) {
                                    alterAttribute(element, styles, false, attribute, attributeIsClass, true);
                                } else {
                                    alterAttribute(element, styles, true, attribute, attributeIsClass, true);
                                }
                            } else {
                                console.log('letsGo: \'command\' parameter is not the string \'show\', \'hide\', \'add\', \'remove\', or \'toggle\'.');
                            }
                        } else {
                            console.log('letsGo: no element of ' + targetType + ' \'' + target + '\' found on page.');
                        }
                    } else {
                        var element = [];
                        if (target.charAt(0) === '.') {
                            targetType = 'class';
                            target = target.substring(1);
                            element = document.getElementsByClassName(target);
                        } else {
                            targetType = 'tag';
                            element = document.getElementsByTagName(target);
                        }
                        if (element.length > 0) {
                            if ((command === 'show') || (command === 'hide')) {
                                if (!attribute) {
                                    if (command === 'show') {
                                        for (var i = 0; i < element.length; i++) {
                                            var styles = window.getComputedStyle(element[i], null);
                                            if (i === (element.length - 1) ) {
                                                lastOne = true;
                                            }
                                            alterAttribute(element[i], styles, false, 'letsGo-hide', true, lastOne);
                                        }
                                    } else if (command === 'hide') {
                                        for (var i = 0; i < element.length; i++) {
                                            var styles = window.getComputedStyle(element[i], null);
                                            if (i === (element.length - 1) ) {
                                                lastOne = true;
                                            }
                                            alterAttribute(element[i], styles, true, 'letsGo-hide', true, lastOne);
                                        }
                                    }
                                } else {
                                    console.log('letsGo: using \'show\' or \'hide\' command can not have an \'attribute\' parameter.');
                                }
                            } else if ((command === 'add') || (command === 'remove')) {
                                if (attribute) {
                                    if (attribute.charAt(0) === '.') {
                                        attributeIsClass = true;
                                        attribute = attribute.substring(1);
                                    } else if (attribute.charAt(0) === '#') {
                                        attribute = 'id=' + attribute.substring(1);
                                    }
                                    if (command === 'add') {
                                        for (var i = 0; i < element.length; i++) {
                                            var styles = window.getComputedStyle(element[i], null);
                                            if (i === (element.length - 1) ) {
                                                lastOne = true;
                                            }
                                            alterAttribute(element[i], styles, true, attribute, attributeIsClass, lastOne);
                                        }
                                    } else if (command === 'remove') {
                                        for (var i = 0; i < element.length; i++) {
                                            var styles = window.getComputedStyle(element[i], null);
                                            if (i === (element.length - 1) ) {
                                                lastOne = true;
                                            }
                                            alterAttribute(element[i], styles, false, attribute, attributeIsClass, lastOne);
                                        }
                                    }
                                } else {
                                    console.log('letsGo: using \'add\' or \'remove\' command must also have an \'attribute\' parameter.');
                                }
                            } else if (command === 'toggle') {
                                if (attribute && attribute.charAt(0) === '.') {
                                    attributeIsClass = true;
                                    attribute = attribute.substring(1);
                                } else if (attribute && attribute.charAt(0) === '#') {
                                    attribute = 'id=' + attribute.substring(1);
                                }
                                for (var i = 0; i < element.length; i++) {
                                    var styles = window.getComputedStyle(element[i], null);
                                    if (i === (element.length - 1) ) {
                                        lastOne = true;
                                    }
                                    if (checkIfAttribute(element[i], attribute, attributeIsClass)) {
                                        alterAttribute(element[i], styles, false, attribute, attributeIsClass, lastOne);
                                    } else {
                                        alterAttribute(element[i], styles, true, attribute, attributeIsClass, lastOne);
                                    }
                                }
                            } else {
                                console.log('letsGo: \'command\' parameter is not the string \'show\', \'hide\', \'add\', \'remove\', or \'toggle\'.');
                            }
                        } else {
                            console.log('letsGo: no element of ' + targetType + ' \'' + target + '\' found on page.');
                        }
                    }
                } else {
                    console.log('letsGo: \'target\' parameter is not a string type.');
                }
            } else {
                console.log('letsGo: missing \'command\' parameter.');
            }
        } else {
            console.log('letsGo: missing \'target\' parameter.');
        }
    };

    var queueControl = function(target, command, attribute, claimedTicket) {
        if (!claimedTicket) {
            claimedTicket = letsGoTicketsOut++;
        }
        if (letsGoRunning && letsGoTicketsDone !== claimedTicket) {
            setTimeout(function () {
                queueControl(target, command, attribute, claimedTicket);
            }, 0);
        } else {
            letsGoRunning = true;
            router(target, command, attribute);
        }
    };

    if (queue || attribute === true) {
        queueMatters = true;
        if (attribute === true) {
            queueControl(target, command);
        } else {
            if (typeof queue === 'boolean') {
                queueControl(target, command, attribute);
            } else {
                console.log('letsGo: \'queue\' parameter is not a boolean');
            }
        }
    } else {
        router(target, command, attribute);
    }
};
<commit_msg>feat(queue): switch to array queue method<commit_after>/*!
 * letsGo
 * http://useletsGo.com/
 *
 * By: Cody Sherman <cody@beg.in> (codysherman.com)
 */

'use strict';

var letsGoRunning = false;
var letsGoQueue = [];

var letsGo = function(target, command, attribute, queue) {
    var queueMatters = false;

    var nextInQueue = function(lastOne) {
        if (queueMatters && lastOne) {
            letsGoQueue.shift();
            if (letsGoQueue.length > 0) {
                router(letsGoQueue[0][0], letsGoQueue[0][1], letsGoQueue[0][3]);
            } else {
                letsGoRunning = false;
            }
        }
    };

    var checkIfAttribute = function(element, attribute, attributeIsClass) {
        if (!attribute || attributeIsClass) {
            attribute = (attribute) ? attribute : 'letsGo-hide';
            return (' ' + element.className + ' ').indexOf(' ' + attribute + ' ') > -1;
        } else if (attribute.indexOf('=') > -1) {
            attribute = attribute.split('=');
            return (element.hasAttribute(attribute[0])) && (element.getAttribute(attribute[0]) === attribute[1]);
        } else {
            return (element.hasAttribute(attribute) && (element.getAttribute(attribute) === ''));
        }
    }

    var findAnimateTime = function(times) {
        if (times.indexOf(',') > -1) {
            times = times.split(',');
            for (var i = 0; i < times.length; i++) {
                times[i] = Number(times[i].slice(0, -1));
            }
            times = Math.max.apply(null, times);
        } else {
            times = Number(times.slice(0, -1));
        }
        return times;
    };

    var alterAttribute = function(element, styles, add, attribute, attributeIsClass, lastOne) {
        var command = (add) ? 'add' : 'remove';

        if (attributeIsClass) {
            var alterAttributeDone = function() {
                element.removeEventListener('animationend', alterAttributeDone, false);
                if (add) {
                    element.classList.add(attribute);
                }
                element.classList.remove(attribute + '-' + command);
                element.classList.remove(attribute + '-' + command + '-active');
                element.classList.remove('letsGo-animate');
                nextInQueue(lastOne);
            };

            element.classList.add('letsGo-animate');
            element.classList.add(attribute + '-' + command);
            if (!add) {
                element.classList.remove(attribute);
            }
            setTimeout(function() {
                if ((styles.transitionDuration !== '0s') || (styles.animationDuration !== '0s')) {
                    element.classList.add(attribute + '-' + command + '-active');
                    var maxTransitionTime = findAnimateTime(styles.transitionDuration);
                    var maxAnimationTime = findAnimateTime(styles.animationDuration);
                    var maxTime = Math.ceil(Math.max(maxTransitionTime, maxAnimationTime)*1000);
                    setTimeout(alterAttributeDone, maxTime);
                    if (styles.animationDuration !== '0s') {
                        element.addEventListener('animationend', alterAttributeDone, false);
                    }
                } else {
                    alterAttributeDone();
                }
            }, 0);
        } else {
            // var setTheAttribute = function() {
            //     element.setAttribute(attribute[0], attribute[1]);
            // }
            if (add) {
                if (attribute.indexOf('=') > -1) {
                     attribute = attribute.split('=');
                     element.setAttribute(attribute[0], attribute[1]);
                } else {
                    element.setAttribute(attribute, '');
                }
            } else {
                if (attribute.indexOf('=') > -1) {
                     attribute = attribute.split('=');
                     element.removeAttribute(attribute[0]);
                } else {
                    element.removeAttribute(attribute);
                }
            }
            nextInQueue(lastOne);
        }
    };

    var router = function(target, command, attribute) {
        if (target) {
            if (command) {
                if (typeof target === 'string') {
                    var targetType = null;
                    var attributeIsClass = null;
                    var lastOne = false;
                    if (target.charAt(0) === '#') {
                        targetType = 'id';
                        target = target.substring(1);
                        var element = document.getElementById(target);
                        if (element !== null) {
                            var styles = window.getComputedStyle(element, null);
                            if (command === 'show' || command === 'hide') {
                                if (!attribute) {
                                    if (command === 'show') {
                                        alterAttribute(element, styles, false, 'letsGo-hide', true, true);
                                    } else if (command === 'hide') {
                                        alterAttribute(element, styles, true, 'letsGo-hide', true, true);
                                    }
                                } else {
                                    console.log('letsGo: using \'show\' or \'hide\' command can not have an \'attribute\' parameter.');
                                }
                            } else if ((command === 'add') || (command === 'remove')) {
                                if (attribute) {
                                    if (attribute.charAt(0) === '.') {
                                        attributeIsClass = true;
                                        attribute = attribute.substring(1);
                                    } else if (attribute.charAt(0) === '#') {
                                        attribute = 'id=' + attribute.substring(1);
                                    }
                                    if (command === 'add') {
                                        alterAttribute(element, styles, true, attribute, attributeIsClass, true);
                                    } else if (command === 'remove') {
                                        alterAttribute(element, styles, false, attribute, attributeIsClass, true);
                                    }
                                } else {
                                    console.log('letsGo: using \'add\' or \'remove\' command must also have an \'attribute\' parameter.');
                                }
                            } else if (command === 'toggle') {
                                if (attribute && attribute.charAt(0) === '.') {
                                    attributeIsClass = true;
                                    attribute = attribute.substring(1);
                                } else if (attribute && attribute.charAt(0) === '#') {
                                    attribute = 'id=' + attribute.substring(1);
                                } else if (!attribute) {
                                    attributeIsClass = true;
                                    attribute = 'letsGo-hide';
                                }
                                if (checkIfAttribute(element, attribute, attributeIsClass)) {
                                    alterAttribute(element, styles, false, attribute, attributeIsClass, true);
                                } else {
                                    alterAttribute(element, styles, true, attribute, attributeIsClass, true);
                                }
                            } else {
                                console.log('letsGo: \'command\' parameter is not the string \'show\', \'hide\', \'add\', \'remove\', or \'toggle\'.');
                            }
                        } else {
                            console.log('letsGo: no element of ' + targetType + ' \'' + target + '\' found on page.');
                        }
                    } else {
                        var element = [];
                        if (target.charAt(0) === '.') {
                            targetType = 'class';
                            target = target.substring(1);
                            element = document.getElementsByClassName(target);
                        } else {
                            targetType = 'tag';
                            element = document.getElementsByTagName(target);
                        }
                        if (element.length > 0) {
                            if ((command === 'show') || (command === 'hide')) {
                                if (!attribute) {
                                    if (command === 'show') {
                                        for (var i = 0; i < element.length; i++) {
                                            var styles = window.getComputedStyle(element[i], null);
                                            if (i === (element.length - 1) ) {
                                                lastOne = true;
                                            }
                                            alterAttribute(element[i], styles, false, 'letsGo-hide', true, lastOne);
                                        }
                                    } else if (command === 'hide') {
                                        for (var i = 0; i < element.length; i++) {
                                            var styles = window.getComputedStyle(element[i], null);
                                            if (i === (element.length - 1) ) {
                                                lastOne = true;
                                            }
                                            alterAttribute(element[i], styles, true, 'letsGo-hide', true, lastOne);
                                        }
                                    }
                                } else {
                                    console.log('letsGo: using \'show\' or \'hide\' command can not have an \'attribute\' parameter.');
                                }
                            } else if ((command === 'add') || (command === 'remove')) {
                                if (attribute) {
                                    if (attribute.charAt(0) === '.') {
                                        attributeIsClass = true;
                                        attribute = attribute.substring(1);
                                    } else if (attribute.charAt(0) === '#') {
                                        attribute = 'id=' + attribute.substring(1);
                                    }
                                    if (command === 'add') {
                                        for (var i = 0; i < element.length; i++) {
                                            var styles = window.getComputedStyle(element[i], null);
                                            if (i === (element.length - 1) ) {
                                                lastOne = true;
                                            }
                                            alterAttribute(element[i], styles, true, attribute, attributeIsClass, lastOne);
                                        }
                                    } else if (command === 'remove') {
                                        for (var i = 0; i < element.length; i++) {
                                            var styles = window.getComputedStyle(element[i], null);
                                            if (i === (element.length - 1) ) {
                                                lastOne = true;
                                            }
                                            alterAttribute(element[i], styles, false, attribute, attributeIsClass, lastOne);
                                        }
                                    }
                                } else {
                                    console.log('letsGo: using \'add\' or \'remove\' command must also have an \'attribute\' parameter.');
                                }
                            } else if (command === 'toggle') {
                                if (attribute && attribute.charAt(0) === '.') {
                                    attributeIsClass = true;
                                    attribute = attribute.substring(1);
                                } else if (attribute && attribute.charAt(0) === '#') {
                                    attribute = 'id=' + attribute.substring(1);
                                }
                                for (var i = 0; i < element.length; i++) {
                                    var styles = window.getComputedStyle(element[i], null);
                                    if (i === (element.length - 1) ) {
                                        lastOne = true;
                                    }
                                    if (checkIfAttribute(element[i], attribute, attributeIsClass)) {
                                        alterAttribute(element[i], styles, false, attribute, attributeIsClass, lastOne);
                                    } else {
                                        alterAttribute(element[i], styles, true, attribute, attributeIsClass, lastOne);
                                    }
                                }
                            } else {
                                console.log('letsGo: \'command\' parameter is not the string \'show\', \'hide\', \'add\', \'remove\', or \'toggle\'.');
                            }
                        } else {
                            console.log('letsGo: no element of ' + targetType + ' \'' + target + '\' found on page.');
                        }
                    }
                } else {
                    console.log('letsGo: \'target\' parameter is not a string type.');
                }
            } else {
                console.log('letsGo: missing \'command\' parameter.');
            }
        } else {
            console.log('letsGo: missing \'target\' parameter.');
        }
    };

    var queueControl = function(target, command, attribute) {
        // if (!claimedTicket) {
        //     claimedTicket = ++letsGoTicketsOut;
        // }
        // if (letsGoRunning && letsGoTicketsDone !== claimedTicket) {
        //     setTimeout(function () {
        //         queueControl(target, command, attribute, claimedTicket);
        //     }, 0);
        // } else {
        //     console.log('Doing', claimedTicket, target);
        //     letsGoRunning = true;
        //     router(target, command, attribute);
        // }
        setTimeout(function () {
            letsGoQueue.push([target, command, attribute]);
            if (!letsGoRunning) {
                letsGoRunning = true;
                router(letsGoQueue[0][0], letsGoQueue[0][1], letsGoQueue[0][3]);
            }
        }, 0);
    };

    if (queue || attribute === true) {
        queueMatters = true;
        if (attribute === true) {
            queueControl(target, command);
        } else {
            if (typeof queue === 'boolean') {
                queueControl(target, command, attribute);
            } else {
                console.log('letsGo: \'queue\' parameter is not a boolean');
            }
        }
    } else {
        router(target, command, attribute);
    }
};
<|endoftext|>