<commit_before>/*
  Convert the contents of an HTML DOM element into a
  styled text document for an easier reading
  experience or to bring out certain features in the
  document. You can create your own README document.

  if (redistribute == true) {
    return credit;
  }

  --------------------------------------------------

  @DocTyp
  @author: Alexander Hovy
  @param:
    exports - Contains all the public variables and functions of the module.
    doc - The elements text that will be Docified.
    elements - An array of Elements.
  @credit:
    Prism, Highlight, SHJS, Rainbow, Prettify
*/
(function(exports) {
  /*============================================================
  ===========================Variables==========================
  ============================================================*/
  var prefix = 'doctyp-';
  var header = {
    'header4': {pattern: /\#{4,}/gm, regex: /\#{4,}.+/gm},
    'header3': {pattern: /\#{3}/gm, regex: /\#{3}.+/gm},
    'header2': {pattern: /\#{2}/gm, regex: /\#{2}.+/gm},
    'header1': {pattern: /\#/gm, regex: /\#.+/gm}
  };
  var style = {
    'bold': {pattern: /\*{2}/gm, regex: /\*{2}(?!\*{2,})(.*?)\*{2}/gm},
    'italic': {pattern: /\*/gm, regex: /\*(?!\*{3,})(.*?)\*/gm},
    'underline': {pattern: /\_/gm, regex: /\_{2}(?!\_{2,})(.*?)\_{2}/gm},
    'strike': {pattern: /\~/gm, regex: /\~{2}(?!\~{2,})(.*?)\~{2}/gm},
    'highlight': {pattern: /\=/gm, regex: /\={2}(?!\={2,})(.*?)\={2}/gm},
    'superscript': {pattern: /\+/gm, regex: /\+{2}(?!\+{2,})(.*?)\+{2}/gm},
    'subscript': {pattern: /\-/gm, regex: /\-{2}(?!\-{2,})(.*?)\-{2}/gm}
  };
  var rule = {
    'rule-solid': {pattern: /[]/gm, regex: /\_{4,}/gm},
    'rule-dash': {pattern: /[]/gm, regex: /\-{4,}/gm},
    'rule-dotted': {pattern: /[]/gm, regex: /\.{4,}/gm},
    'rule-double': {pattern: /[]/gm, regex: /\={4,}/gm},
    'rule-thick': {pattern: /[]/gm, regex: /\+{4,}/gm}
  };
  var quote = {
    'quote-code': {pattern: /\`/gm, regex: /\`(.*?)\`/gm},
    'quote-extra': {pattern: /[]/gm, regex: /\[(.*?)\]\{\[([\s\S]*?)\]\}/gm},
    'quote-plain': {pattern: /(\{\[|\]\})/gm, regex: /\{\[([\s\S]*?)\]\}/gm}
  };
  var code = {
    'code-extra': {pattern: /[]/gm, regex: /\[(.*?)\]\{\(([\s\S]*?)\)\}/gm},
    'code-plain': {pattern: /(\{\(|\)\})/gm, regex: /\{\(([\s\S]*?)\)\}/gm}
  };
  var list = {
    'list-disc': {pattern: /(\-)/gm, regex: /(^\-(?!\-{3,}).+\n){1,}/gm},
    'list-circle': {pattern: /(\*)/gm, regex: /(^\*(?!\*{3,}).+\n){1,}/gm},
    'list-square': {pattern: /(\@)/gm, regex: /(^\@(?!\@{3,}).+\n){1,}/gm},
    'list-decimal': {pattern: /(\o\.)/gm, regex: /(^\o\..+\n){1,}/igm},
    'list-roman': {pattern: /(\i\.)/gm, regex: /(^\i\..+\n){1,}/igm},
    'list-alpha': {pattern: /(\a\.)/gm, regex: /(^\a\..+\n){1,}/igm},
    'checklist': {pattern: /\[[Xx\s]?\]/gm, regex: /(^\[[Xx\s]?\].+\n){1,}/gm}
  };
  var link = {
    'url': {pattern: /[]/gm, regex: /(\!\[(.*?)\]\((.*?)\)|\[(.*?)\]\((.*?)(https?|ftp|file)\:\/{2}(.*?)\)|\b((https?|ftp|file)\:\/{2}([\w\d\.]+)([\/\?\&\w\d\=\,\.\+\:\;\@\$\%\#\!\_\-]+)?)\b)/gm},
    'email': {pattern: /[]/gm, regex: /\b(([\w\d\.\_\%\+\-]+)\@([\w\d\.\-]+)(\.\w{2,}))\b/gm}
  };
  var image = {
    'image': {pattern: /[]/gm, regex: /\!\[(.*?)\]\((.*?)\)/gm}
  };
  var table = {
    'table': {pattern: /\&gt\;/gm, regex: /\{\|([\s\S]*?)\|\}/gm}
  };

  /*============================================================
  ============================Private===========================
  ============================================================*/

  /*============================================================
  ============================Header============================
  ============================================================*/
  exports.Header = function(doc) {
    for (key in header) {
      doc = doc.replace(header[key].regex, function(match) {
        var temp = exports.Prepare(match).replace(header[key].pattern, '');
        if (key == 'header1' || key == 'header2') {
          return '' + exports.Trim(temp) + '
';
        } else {
          return '' + exports.Trim(temp) + '';
        }
      });
    }
    return doc;
  };

  /*============================================================
  ============================Style=============================
  ============================================================*/
  exports.Style = function(doc) {
    for (key in style) {
      doc = doc.replace(style[key].regex, function(match) {
        var temp = exports.Prepare(match).replace(style[key].pattern, '');
        return '' + exports.Trim(temp) + '';
      });
    }
    return doc;
  };

  /*============================================================
  =============================Rule=============================
  ============================================================*/
  exports.Rule = function(doc) {
    for (key in rule) {
      doc = doc.replace(rule[key].regex, function(match) {
        return '
';
      });
    }
    return doc;
  };

  /*============================================================
  ============================Quote=============================
  ============================================================*/
  exports.Quote = function(doc) {
    for (key in quote) {
      doc = doc.replace(quote[key].regex, function(match) {
        if (key == 'quote-code') {
          var temp = exports.Prepare(match).replace(quote[key].pattern, ''),
            classes = prefix + key + ' nohighlight language-none';
          return '' + exports.Trim(temp) + '';
        } else if (key == 'quote-extra') {
          var extra = exports.Prepare(match).split(']{['),
            credit = extra[0].split('[')[1],
            content = extra[1].split(']}')[0],
            classes = prefix + key;
          return '
"' + exports.Trim(content) + '"
' + exports.Trim(credit) + '
';
        } else {
          var temp = exports.Prepare(match).replace(quote[key].pattern, ''),
            classes = prefix + key;
          return '
"' + exports.Trim(temp) + '"
';
        }
      });
    }
    return doc;
  };

  /*============================================================
  ============================Code==============================
  ============================================================*/
  exports.Code = function(doc) {
    for (key in code) {
      doc = doc.replace(code[key].regex, function(match) {
        if (key == 'code-extra') {
          var extra = exports.Prepare(match).split(']{('),
            first = extra[0].split('[')[1].split('|'),
            second = extra[1].split(')}')[0],
            language = exports.Trim(first[0]).toLowerCase(),
            service = exports.Trim(first[1]).toLowerCase(),
            classes = prefix + key + ' language-' + language + ' sh_' + language + ' prettyprint lang-' + language,
            dataClasses = language;
          exports.LoadScript('Syntax/' + service + '/script.js');
          exports.LoadStyle('Syntax/' + service + '/' + exports.theme + '.css');
          return '
' + second + '
';
        } else {
          var temp = exports.Prepare(match).replace(code[key].pattern, ''),
            classes = 'nohighlight language-none';
          return '
' + temp + '
';
        }
      });
    }
    return doc;
  };

  /*============================================================
  =============================List=============================
  ============================================================*/
  exports.List = function(doc) {
    for (key in list) {
      doc = doc.replace(list[key].regex, function(match) {
        if (key == 'list-disc' || key == 'list-circle' || key == 'list-square') {
          return '
' + match.replace(/.+\n/gm, function(line) {
            var temp = exports.Prepare(line).replace(list[key].pattern, '');
            return '
' + exports.Trim(temp) + '
';
          }) + '
';
        } else if (key == 'list-decimal' || key == 'list-roman' || key == 'list-alpha') {
          return '
' + match.replace(/.+\n/gm, function(line) {
            var temp = exports.Prepare(line).replace(list[key].pattern, '');
            return '
' + exports.Trim(temp) + '
';
          }) + '
';
        } else {
          return '
' + match.replace(/.+\n/gm, function(line) {
            var temp = exports.Prepare(line).replace(/\[[Xx\s]?\]/gm, ''),
              tag = (new RegExp(/\[\s?\]/gm)).test(line) ? 'unchecked' : 'checked';
            return '' + exports.Trim(temp) + '
';
          }) + '
';
        }
      });
    }
    return doc;
  };

  /*============================================================
  =============================Link=============================
  ============================================================*/
  exports.Link = function(doc) {
    for (key in link) {
      doc = doc.replace(link[key].regex, function(match) {
        if (key == 'url') {
          if ((new RegExp(/^\[(.*?)\]\((.*?)(https?|ftp|file)\:\/{2}(.*?)\)$/gm)).test(match)) {
            var extra = exports.Prepare(match).split(']('),
              title = extra[0].split('[')[1],
              url = extra[1].split(']')[0];
            return '' + exports.Trim(title) + '';
          } else if ((new RegExp(/^\b((https?|ftp|file)\:\/{2}([\w\d\.]+)([\/\?\&\w\d\=\,\.\+\:\;\@\$\%\#\!\_\-]+)?)\b$/gm)).test(match)) {
            return '' + exports.Trim(match) + '';
          }
        } else {
          return '' + exports.Trim(match) + '';
        }
      });
    }
    return doc;
  };

  /*============================================================
  ============================Image=============================
  ============================================================*/
  exports.Image = function(doc) {
    for (key in image) {
      doc = doc.replace(image[key].regex, function(match) {
        var extra = exports.Prepare(match).split(']('),
          alt = exports.Trim(extra[0].split('![')[1]).toLowerCase(),
          url = exports.Trim(extra[1].split(')')[0]).toLowerCase();
        return '';
      });
    }
    return doc;
  };

  /*============================================================
  ============================Table=============================
  ============================================================*/
  exports.Table = function(doc) {
    for (key in table) {
      doc = '

' + doc.replace(table[key].regex, function(match) {
        var extra = exports.Prepare(match).split('{|')[1].split('|}')[0],
          tBody = extra.split('||');
        for (var a = 0; a < tBody.length; a++) {
          var tRow = tBody[a];
          console.log(tRow);
          //Check if Title
          if ((new RegExp(/(\&gt\;){2}/gm)).test(tRow)) {
            return '
' + tRow.replace(/.+\n/gm, function(row) {
              var temp = row.replace(table[key].pattern, '');
              return '' + exports.Trim(temp) + '	';
            }) + '
';
          } else {
            return '
' + tRow.replace(/.+\n/gm, function(row) {
              var temp = row.replace(table[key].pattern, '');
              return '' + exports.Trim(temp) + '	';
            }) + '
';
          }
        }
      }) + '

';
    }
    return doc;
  };

  /*============================================================
  ===========================Cleaning===========================
  ============================================================*/
  exports.Prepare = function(doc) {
    return doc.replace(/\<(\/)?span(.*?)\>/gm, '').replace(/\>/gm, '>');
  };
  exports.Trim = function(doc) {
    return doc.replace(/(^\s+|\s+$)/gm, '');
  };
  exports.Clean = function(doc) {
    return doc.replace(/\n/gm, '
');
  };

  /*============================================================
  ============================Syntax============================
  ============================================================*/
  exports.Syntax = function(elements) {
    for (var a = 0; a < elements.length; a++) {
      var element = elements[a],
        code = element.innerHTML,
        fixed = code.replace(/\
/gm, '\n');
      element.innerHTML = fixed;
    }
  };

  /*============================================================
  ============================Export============================
  ============================================================*/
  return exports;
})(DocTyp || {});
<commit_msg>Update extension.js<commit_after>/*
  Convert the contents of an HTML DOM element into a
  styled text document for an easier reading
  experience or to bring out certain features in the
  document. You can create your own README document.

  if (redistribute == true) {
    return credit;
  }

  --------------------------------------------------

  @DocTyp
  @author: Alexander Hovy
  @param:
    exports - Contains all the public variables and functions of the module.
    doc - The elements text that will be Docified.
    elements - An array of Elements.
  @credit:
    Prism, Highlight, SHJS, Rainbow, Prettify
*/
(function(exports) {
  /*============================================================
  ===========================Variables==========================
  ============================================================*/
  var prefix = 'doctyp-';
  var header = {
    'header4': {pattern: /\#{4,}/gm, regex: /\#{4,}.+/gm},
    'header3': {pattern: /\#{3}/gm, regex: /\#{3}.+/gm},
    'header2': {pattern: /\#{2}/gm, regex: /\#{2}.+/gm},
    'header1': {pattern: /\#/gm, regex: /\#.+/gm}
  };
  var style = {
    'bold': {pattern: /\*{2}/gm, regex: /\*{2}(?!\*{2,})(.*?)\*{2}/gm},
    'italic': {pattern: /\*/gm, regex: /\*(?!\*{3,})(.*?)\*/gm},
    'underline': {pattern: /\_/gm, regex: /\_{2}(?!\_{2,})(.*?)\_{2}/gm},
    'strike': {pattern: /\~/gm, regex: /\~{2}(?!\~{2,})(.*?)\~{2}/gm},
    'highlight': {pattern: /\=/gm, regex: /\={2}(?!\={2,})(.*?)\={2}/gm},
    'superscript': {pattern: /\+/gm, regex: /\+{2}(?!\+{2,})(.*?)\+{2}/gm},
    'subscript': {pattern: /\-/gm, regex: /\-{2}(?!\-{2,})(.*?)\-{2}/gm}
  };
  var rule = {
    'rule-solid': {pattern: /[]/gm, regex: /\_{4,}/gm},
    'rule-dash': {pattern: /[]/gm, regex: /\-{4,}/gm},
    'rule-dotted': {pattern: /[]/gm, regex: /\.{4,}/gm},
    'rule-double': {pattern: /[]/gm, regex: /\={4,}/gm},
    'rule-thick': {pattern: /[]/gm, regex: /\+{4,}/gm}
  };
  var quote = {
    'quote-code': {pattern: /\`/gm, regex: /\`(.*?)\`/gm},
    'quote-extra': {pattern: /[]/gm, regex: /\[(.*?)\]\{\[([\s\S]*?)\]\}/gm},
    'quote-plain': {pattern: /(\{\[|\]\})/gm, regex: /\{\[([\s\S]*?)\]\}/gm}
  };
  var code = {
    'code-extra': {pattern: /[]/gm, regex: /\[(.*?)\]\{\(([\s\S]*?)\)\}/gm},
    'code-plain': {pattern: /(\{\(|\)\})/gm, regex: /\{\(([\s\S]*?)\)\}/gm}
  };
  var list = {
    'list-disc': {pattern: /(\-)/gm, regex: /(^\-(?!\-{3,}).+\n){1,}/gm},
    'list-circle': {pattern: /(\*)/gm, regex: /(^\*(?!\*{3,}).+\n){1,}/gm},
    'list-square': {pattern: /(\@)/gm, regex: /(^\@(?!\@{3,}).+\n){1,}/gm},
    'list-decimal': {pattern: /(\o\.)/gm, regex: /(^\o\..+\n){1,}/igm},
    'list-roman': {pattern: /(\i\.)/gm, regex: /(^\i\..+\n){1,}/igm},
    'list-alpha': {pattern: /(\a\.)/gm, regex: /(^\a\..+\n){1,}/igm},
    'checklist': {pattern: /\[[Xx\s]?\]/gm, regex: /(^\[[Xx\s]?\].+\n){1,}/gm}
  };
  var link = {
    'url': {pattern: /[]/gm, regex: /(\!\[(.*?)\]\((.*?)\)|\[(.*?)\]\((.*?)(https?|ftp|file)\:\/{2}(.*?)\)|\b((https?|ftp|file)\:\/{2}([\w\d\.]+)([\/\?\&\w\d\=\,\.\+\:\;\@\$\%\#\!\_\-]+)?)\b)/gm},
    'email': {pattern: /[]/gm, regex: /\b(([\w\d\.\_\%\+\-]+)\@([\w\d\.\-]+)(\.\w{2,}))\b/gm}
  };
  var image = {
    'image': {pattern: /[]/gm, regex: /\!\[(.*?)\]\((.*?)\)/gm}
  };
  var table = {
    'table': {pattern: /\&gt\;/gm, regex: /\{\|([\s\S]*?)\|\}/gm}
  };

  /*============================================================
  ============================Private===========================
  ============================================================*/

  /*============================================================
  ============================Header============================
  ============================================================*/
  exports.Header = function(doc) {
    for (key in header) {
      doc = doc.replace(header[key].regex, function(match) {
        var temp = exports.Prepare(match).replace(header[key].pattern, '');
        if (key == 'header1' || key == 'header2') {
          return '' + exports.Trim(temp) + '
';
        } else {
          return '' + exports.Trim(temp) + '';
        }
      });
    }
    return doc;
  };

  /*============================================================
  ============================Style=============================
  ============================================================*/
  exports.Style = function(doc) {
    for (key in style) {
      doc = doc.replace(style[key].regex, function(match) {
        var temp = exports.Prepare(match).replace(style[key].pattern, '');
        return '' + exports.Trim(temp) + '';
      });
    }
    return doc;
  };

  /*============================================================
  =============================Rule=============================
  ============================================================*/
  exports.Rule = function(doc) {
    for (key in rule) {
      doc = doc.replace(rule[key].regex, function(match) {
        return '
';
      });
    }
    return doc;
  };

  /*============================================================
  ============================Quote=============================
  ============================================================*/
  exports.Quote = function(doc) {
    for (key in quote) {
      doc = doc.replace(quote[key].regex, function(match) {
        if (key == 'quote-code') {
          var temp = exports.Prepare(match).replace(quote[key].pattern, ''),
            classes = prefix + key + ' nohighlight language-none';
          return '' + exports.Trim(temp) + '';
        } else if (key == 'quote-extra') {
          var extra = exports.Prepare(match).split(']{['),
            credit = extra[0].split('[')[1],
            content = extra[1].split(']}')[0],
            classes = prefix + key;
          return '
"' + exports.Trim(content) + '"
' + exports.Trim(credit) + '
';
        } else {
          var temp = exports.Prepare(match).replace(quote[key].pattern, ''),
            classes = prefix + key;
          return '
"' + exports.Trim(temp) + '"
';
        }
      });
    }
    return doc;
  };

  /*============================================================
  ============================Code==============================
  ============================================================*/
  exports.Code = function(doc) {
    for (key in code) {
      doc = doc.replace(code[key].regex, function(match) {
        if (key == 'code-extra') {
          var extra = exports.Prepare(match).split(']{('),
            first = extra[0].split('[')[1].split('|'),
            second = extra[1].split(')}')[0],
            language = exports.Trim(first[0]).toLowerCase(),
            service = exports.Trim(first[1]).toLowerCase(),
            classes = prefix + key + ' language-' + language + ' sh_' + language + ' prettyprint lang-' + language,
            dataClasses = language;
          exports.LoadScript('Syntax/' + service + '/script.js');
          exports.LoadStyle('Syntax/' + service + '/' + exports.theme + '.css');
          return '
' + second + '
';
        } else {
          var temp = exports.Prepare(match).replace(code[key].pattern, ''),
            classes = 'nohighlight language-none';
          return '
' + temp + '
';
        }
      });
    }
    return doc;
  };

  /*============================================================
  =============================List=============================
  ============================================================*/
  exports.List = function(doc) {
    for (key in list) {
      doc = doc.replace(list[key].regex, function(match) {
        if (key == 'list-disc' || key == 'list-circle' || key == 'list-square') {
          return '
' + match.replace(/.+\n/gm, function(line) {
            var temp = exports.Prepare(line).replace(list[key].pattern, '');
            return '
' + exports.Trim(temp) + '
';
          }) + '
';
        } else if (key == 'list-decimal' || key == 'list-roman' || key == 'list-alpha') {
          return '
' + match.replace(/.+\n/gm, function(line) {
            var temp = exports.Prepare(line).replace(list[key].pattern, '');
            return '
' + exports.Trim(temp) + '
';
          }) + '
';
        } else {
          return '
' + match.replace(/.+\n/gm, function(line) {
            var temp = exports.Prepare(line).replace(/\[[Xx\s]?\]/gm, ''),
              tag = (new RegExp(/\[\s?\]/gm)).test(line) ? 'unchecked' : 'checked';
            return '' + exports.Trim(temp) + '
';
          }) + '
';
        }
      });
    }
    return doc;
  };

  /*============================================================
  =============================Link=============================
  ============================================================*/
  exports.Link = function(doc) {
    for (key in link) {
      doc = doc.replace(link[key].regex, function(match) {
        if (key == 'url') {
          if ((new RegExp(/^\[(.*?)\]\((.*?)(https?|ftp|file)\:\/{2}(.*?)\)$/gm)).test(match)) {
            var extra = exports.Prepare(match).split(']('),
              title = extra[0].split('[')[1],
              url = extra[1].split(']')[0];
            return '' + exports.Trim(title) + '';
          } else if ((new RegExp(/^\b((https?|ftp|file)\:\/{2}([\w\d\.]+)([\/\?\&\w\d\=\,\.\+\:\;\@\$\%\#\!\_\-]+)?)\b$/gm)).test(match)) {
            return '' + exports.Trim(match) + '';
          }
        } else {
          return '' + exports.Trim(match) + '';
        }
      });
    }
    return doc;
  };

  /*============================================================
  ============================Image=============================
  ============================================================*/
  exports.Image = function(doc) {
    for (key in image) {
      doc = doc.replace(image[key].regex, function(match) {
        var extra = exports.Prepare(match).split(']('),
          alt = exports.Trim(extra[0].split('![')[1]).toLowerCase(),
          url = exports.Trim(extra[1].split(')')[0]).toLowerCase();
        return '';
      });
    }
    return doc;
  };

  /*============================================================
  ============================Table=============================
  ============================================================*/
  exports.Table = function(doc) {
    for (key in table) {
      doc = '

' + doc.replace(table[key].regex, function(match) {
        var extra = exports.Prepare(match).split('{|')[1].split('|}')[0],
          tBody = extra.split('||');
        for (var a = 0; a < tBody.length; a++) {
          var tRow = tBody[a];
          console.log(tBody);
          //Check if Title
          if ((new RegExp(/(\&gt\;){2}/gm)).test(tRow)) {
            return '
' + tRow.replace(/.+\n/gm, function(row) {
              var temp = row.replace(table[key].pattern, '');
              return '' + exports.Trim(temp) + '	';
            }) + '
';
          } else {
            return '
' + tRow.replace(/.+\n/gm, function(row) {
              var temp = row.replace(table[key].pattern, '');
              return '' + exports.Trim(temp) + '	';
            }) + '
';
          }
        }
      }) + '

';
    }
    return doc;
  };

  /*============================================================
  ===========================Cleaning===========================
  ============================================================*/
  exports.Prepare = function(doc) {
    return doc.replace(/\<(\/)?span(.*?)\>/gm, '').replace(/\>/gm, '>');
  };
  exports.Trim = function(doc) {
    return doc.replace(/(^\s+|\s+$)/gm, '');
  };
  exports.Clean = function(doc) {
    return doc.replace(/\n/gm, '
');
  };

  /*============================================================
  ============================Syntax============================
  ============================================================*/
  exports.Syntax = function(elements) {
    for (var a = 0; a < elements.length; a++) {
      var element = elements[a],
        code = element.innerHTML,
        fixed = code.replace(/\
/gm, '\n');
      element.innerHTML = fixed;
    }
  };

  /*============================================================
  ============================Export============================
  ============================================================*/
  return exports;
})(DocTyp || {});
<|endoftext|>


<commit_before>function solid(){
function cback(e) {
    var t = [];
    for (var n = inputs.length; n--;) {
        if (!inputs[n].value.length) t.push(inputs[n]);
    }
    var r = t.length;
    var i = inputs.length;
    var s = document.querySelectorAll(".top");
    for (var o = s.length; o--;) {
        s[o].style.width = 100 - r / i * 100 + "%";
    }
}
var forms = document.querySelectorAll(".form"),
    inputs = [];
for (var i = forms.length; i--;) {
    var els = forms[i].querySelectorAll("input, textarea, select");
    for (var j = els.length; j--;) {
        if (els[j].type != "button" && els[j].type != "submit") {
            inputs.push(els[j]);
            els[j].addEventListener("input", cback, false);
        }
    }
}
}
function flash(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
    s[o].style.background = cols[i-r-1];
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}

var cols = ["#1ABC9C","#EC7063","#3498DB"];
}

function gradient(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}
}
function sections(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}

function generateCSSGradient(colours) {
var l = colours.length, i;
for( i=0; i<l; i++) colours[i] = colours[i].join(" ");
return "linear-gradient( to right, "+colours.join(", ")+")";
}

//Edit your colors here. Enter the color twice.
var cols = [
["#1ABC9C","0%"],
["#1ABC9C","33.3%"],
["#EC7063","33.3%"],
["#EC7063","66.6%"],
["#3498DB","66.6%"],
["#3498DB","100%"]
];
document.getElementsByClassName('top').innerHTML = '

';
document.querySelector(".colors").style.background = generateCSSGradient(cols);

var window_width = window.innerWidth + "px";
document.querySelector(".colors").style.width = window_width;

};
<commit_msg>Comments<commit_after>function solid(){
function cback(e) {
    var t = [];
    for (var n = inputs.length; n--;) {
        if (!inputs[n].value.length) t.push(inputs[n]);
    }
    var r = t.length;
    var i = inputs.length;
    var s = document.querySelectorAll(".top");
    for (var o = s.length; o--;) {
        s[o].style.width = 100 - r / i * 100 + "%";
    }
}
var forms = document.querySelectorAll(".form"),
    inputs = [];
for (var i = forms.length; i--;) {
    var els = forms[i].querySelectorAll("input, textarea, select");
    for (var j = els.length; j--;) {
        if (els[j].type != "button" && els[j].type != "submit") {
            inputs.push(els[j]);
            els[j].addEventListener("input", cback, false);
        }
    }
}
}
function flash(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
    s[o].style.background = cols[i-r-1];
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}
//Edit colors here
var cols = ["#1ABC9C","#EC7063","#3498DB"];
}

function gradient(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}
}
function sections(){
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
    if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
    s[o].style.width = 100 - r / i * 100 + "%";
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
    if (els[j].type != "button" && els[j].type != "submit") {
        inputs.push(els[j]);
        els[j].addEventListener("input", cback, false);
    }
}
}

function generateCSSGradient(colours) {
var l = colours.length, i;
for( i=0; i<l; i++) colours[i] = colours[i].join(" ");
return "linear-gradient( to right, "+colours.join(", ")+")";
}

//Edit your colors here. Enter the color twice.
var cols = [
["#1ABC9C","0%"],
["#1ABC9C","33.3%"],
["#EC7063","33.3%"],
["#EC7063","66.6%"],
["#3498DB","66.6%"],
["#3498DB","100%"]
];
document.getElementsByClassName('top').innerHTML = '

';
document.querySelector(".colors").style.background = generateCSSGradient(cols);

var window_width = window.innerWidth + "px";
document.querySelector(".colors").style.width = window_width;

};
<|endoftext|>


<commit_before>import { getProfessorLink, getProfessorInfo } from './pagination';

document.addEventListener('DOMContentLoaded', onInit(), false);

function onInit () {
  let table = document.querySelector('.datadisplaytable');
  if (table.getAttribute('summary').includes('sections')){
    let tableBody = table.querySelector('tbody');
    updateHeaderColumns(tableBody);
    updateContentColumns(tableBody);
  }
}

function updateHeaderColumns (tableBody) {
  let rateMyProfessorColumn = document.createElement('th');
  let tableHeaders = tableBody.querySelector('tr:nth-child(3)');
  let teacherColumn = tableHeaders.querySelector('th:nth-child(20)');
  rateMyProfessorColumn.appendChild(document.createTextNode('Rate My Professor'));
  rateMyProfessorColumn.classList.add('ddheader');
  tableHeaders.insertBefore(rateMyProfessorColumn, teacherColumn);
}

function updateContentColumns (tableBody) {
  let contentRows = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4)'));

  contentRows.forEach(row => {
    let [first, last] = parseFirstAndLast(row.querySelector('td:nth-child(18)').innerText);
    let url = `http://www.ratemyprofessors.com/search.jsp?query=portland+state+university+${first}+${last}`;
    getProfessorLink(url).then(link => {
      return getProfessorInfo(link);
    }).then(info => {
      populateRateMyProfessorCell(info, row);
    });
  });
}

function parseFirstAndLast (name) {
  name = name.split(' ');
  // Remove the (P) tag from the name
  let isPrimaryTeacherIndex = name.indexOf('(P)');
  if (isPrimaryTeacherIndex > -1) {
    name.pop();
  }
  // Returns only the first and last name - excluding the middle (if it
  // exists)
  return [name.shift(), name.pop()]
}

function populateRateMyProfessorCell (info, row) {
  let contentCell = document.createElement('td');
  contentCell.setAttribute('style', 'font-size: .75em');
  contentCell.classList.add('dddefault');
  if (!info) {
    let noInfo = insertIntoDiv(document.createTextNode('N/A'));
    contentCell = addChildren(contentCell, noInfo);
  } else {
    let quality = insertIntoDiv(document.createTextNode(`Quality: ${info.quality}`));
    let easiness = insertIntoDiv(document.createTextNode(`Easiness: ${info.easiness}`));
    let link = document.createElement('a');
    link.setAttribute('href', info.url);
    link.setAttribute('target', '_blank');
    link.appendChild(document.createTextNode('More info...'));
    link = insertIntoDiv(link);
    contentCell = addChildren(contentCell, quality, easiness, link);
  }
  row.insertBefore(contentCell, row.querySelector('td:nth-child(19)'));
}

function insertIntoDiv (element) {
  let div = document.createElement('div');
  div.appendChild(element);
  return div;
}

function addChildren (parent, ...children) {
  children.forEach(child => {
    parent.appendChild(child);
  });
  return parent;
}

<commit_msg>retrieve a set of all the teachers on the page<commit_after>import { getProfessorLink, getProfessorInfo } from './pagination';
import { uniq } from 'lodash';

document.addEventListener('DOMContentLoaded', onInit(), false);

function onInit () {
  let table = document.querySelector('.datadisplaytable');
  if (table.getAttribute('summary').includes('sections')) {
    let tableBody = table.querySelector('tbody');
    console.log(getTeacherNames(tableBody));
    updateHeader(tableBody);
    updateRows(tableBody);
  }
}

function getTeacherNames (tableBody) {
  let teacherNameList = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4) td:nth-child(18)'));
  return uniq(teacherNameList.map(element => {
    return element.innerText;
  })).map(name => {
    return parseFirstAndLast(name);
  });
}

function updateHeader (tableBody) {
  let rateMyProfessorColumn = document.createElement('th');
  let tableHeaders = tableBody.querySelector('tr:nth-child(3)');
  let teacherColumn = tableHeaders.querySelector('th:nth-child(20)');
  rateMyProfessorColumn.appendChild(document.createTextNode('Rate My Professor'));
  rateMyProfessorColumn.classList.add('ddheader');
  tableHeaders.insertBefore(rateMyProfessorColumn, teacherColumn);
}

function updateRows (tableBody) {
  let contentRows = Array.from(tableBody.querySelectorAll('tr:nth-child(n+4)'));

  contentRows.forEach(row => {
    let name = parseFirstAndLast(row.querySelector('td:nth-child(18)').innerText);
    let url = `http://www.ratemyprofessors.com/search.jsp?query=portland+state+university+${name.first}+${name.last}`;
    getProfessorLink(url).then(link => {
      return getProfessorInfo(link);
    }).then(info => {
      populateRateMyProfessorCell(info, row);
    });
  });
}

function parseFirstAndLast (name) {
  name = name.split(' ');
  // Remove the (P) tag from the name
  let isPrimaryTeacherIndex = name.indexOf('(P)');
  if (isPrimaryTeacherIndex > -1) {
    name.pop();
  }
  // Returns only the first and last name - excluding the middle (if it
  // exists)
  let first = name.shift();
  let last = name.pop();
  return {
    first: first,
    last: last
  };
}

function populateRateMyProfessorCell (info, row) {
  let contentCell = document.createElement('td');
  contentCell.setAttribute('style', 'font-size: .75em');
  contentCell.classList.add('dddefault');
  if (!info) {
    let noInfo = insertIntoDiv(document.createTextNode('N/A'));
    contentCell = addChildren(contentCell, noInfo);
  } else {
    let quality = insertIntoDiv(document.createTextNode(`Quality: ${info.quality}`));
    let easiness = insertIntoDiv(document.createTextNode(`Easiness: ${info.easiness}`));
    let link = document.createElement('a');
    link.setAttribute('href', info.url);
    link.setAttribute('target', '_blank');
    link.appendChild(document.createTextNode('More info...'));
    link = insertIntoDiv(link);
    contentCell = addChildren(contentCell, quality, easiness, link);
  }
  row.insertBefore(contentCell, row.querySelector('td:nth-child(19)'));
}

function insertIntoDiv (element) {
  let div = document.createElement('div');
  div.appendChild(element);
  return div;
}

function addChildren (parent, ...children) {
  children.forEach(child => {
    parent.appendChild(child);
  });
  return parent;
}

<|endoftext|>


<commit_before><commit_msg>else if added<commit_after><|endoftext|>


<commit_before><commit_msg>working in port<commit_after><|endoftext|>


<commit_before><commit_msg>fix callback in feed_url & add initial link support<commit_after><|endoftext|>


<commit_before>//@flow

export default (component: string, newLayout: string) => ({
  type: "CHANGE_MAIN_LAYOUT",
  component,
  newLayout
});
<commit_msg>Update breakpoint action to pass query object<commit_after>//@flow

export default (component: string, query: { [string]: string }) => ({
  type: "CHANGE_MAIN_LAYOUT",
  component,
  query
});
<|endoftext|>


<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope) {

  // imports

  var extend = scope.extend;
  var apis = scope.api.declaration;
  var queue = scope.queue;
  var whenPolymerReady = scope.whenPolymerReady;

  // imperative implementation: Polymer()

  // specify an 'own' prototype for tag `name`
  function element(name, prototype) {
    //console.log('registering prototype [' + name + ']');
    // cache the prototype
    prototypesByName[name] = prototype || {};
    // notify the registrar waiting for 'name', if any
    notifyPrototype(name);
  }

  // declarative implementation: <polymer-element>

  var prototype = extend(Object.create(HTMLElement.prototype), {
    createdCallback: function() {
      // fetch the element name
      this.name = this.getAttribute('name');
      //console.log('createdCallback', this.name);
      // fetch our extendee name
      this.extends = this.getAttribute('extends');
      this.loadResources();
      this.registerWhenReady();
    },
    registerWhenReady: function() {
      if (this.registered) {
        return;
      }
      // if we have no prototype, wait
      if (this.waitingForPrototype(this.name)) {
        return;
      }
      if (this.waitingForQueue()) {
        return;
      }
      if (this.waitingForResources()) {
        return;
      }
      this._register();
    },
    _register: function() {
      //console.group('registering', this.name);
      this.register(this.name, this.extends);
      this.registered = true;
      //console.groupEnd();
      // tell the queue this element has registered
      queue.notify(this);
    },
    waitingForPrototype: function(name) {
      if (!getRegisteredPrototype(name)) {
        // then wait for a prototype
        waitPrototype[name] = this;
        // if explicitly marked as 'noscript'
        if (this.hasAttribute('noscript')) {
          // TODO(sorvell): CustomElements polyfill awareness:
          // noscript elements should upgrade in logical order
          // script injection ensures this under native custom elements;
          // under imports + ce polyfills, scripts run before upgrades.
          // dependencies should be ready at upgrade time so register
          // prototype at this time.
          if (window.CustomElements && !CustomElements.useNative) {
            element(name);
          } else {
            var script = document.createElement('script');
            script.textContent = 'Polymer(\'' + name + '\');';
            this.appendChild(script);
          }
        }
        return true;
      }
    },
    waitingForResources: function() {
      return this._needsResources;
    },
    // NOTE: Elements must be queued in proper order for inheritance/composition
    // dependency resolution. Previously this was enforced for inheritance
    // and by rule for composition. It's now entirely by rule.
    waitingForQueue: function() {
      return queue.wait(this);
    },
    loadResources: function() {
      this._needsResources = true;
      this.loadStyles(function() {
        this._needsResources = false;
        this.registerWhenReady();
      }.bind(this));
    }
  });

  // semi-pluggable APIs
  // TODO(sjmiles): should be fully pluggable (aka decoupled, currently
  // the various plugins are allowed to depend on each other directly)
  Object.keys(apis).forEach(function(n) {
    extend(prototype, apis[n]);
  });

  // utility and bookkeeping

  // maps tag names to prototypes
  var prototypesByName = {};

  function getRegisteredPrototype(name) {
    return prototypesByName[name];
  }

  // elements waiting for prototype, by name
  var waitPrototype = {};

  function notifyPrototype(name) {
    if (waitPrototype[name]) {
      waitPrototype[name].registerWhenReady();
      delete waitPrototype[name];
    }
  }

  // track document.register'ed tag names
  var registered = {};

  function isRegistered(name) {
    return registered[name];
  }

  // exports
  scope.getRegisteredPrototype = getRegisteredPrototype;

  // namespace shenanigans so we can expose our scope on the registration
  // function

  // TODO(sjmiles): find a way to do this that is less terrible
  // copy window.Polymer properties onto `element()`
  extend(element, scope);
  // make window.Polymer reference `element()`
  window.Polymer = element;

  // Under the HTMLImports polyfill, scripts in the main document
  // do not block on imports; we want to allow calls to Polymer in the main
  // document. We do so via coordination with Platform:
  var declarations = Platform.deliverDeclarations();
  if (declarations) {
    for (var i=0, l=declarations.length, d; (i<l) && (d=declarations[i]); i++) {
      element.apply(null, d);
    }
  }

  whenPolymerReady(function() {
    console.log('fire polymer ready');
    document.dispatchEvent(
      new CustomEvent('polymer-ready', {bubbles: true})
    );
  });

  // register polymer-element with document
  document.registerElement('polymer-element', {prototype: prototype});
})(Polymer);
<commit_msg>remove logging<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope) {

  // imports

  var extend = scope.extend;
  var apis = scope.api.declaration;
  var queue = scope.queue;
  var whenPolymerReady = scope.whenPolymerReady;

  // imperative implementation: Polymer()

  // specify an 'own' prototype for tag `name`
  function element(name, prototype) {
    //console.log('registering prototype [' + name + ']');
    // cache the prototype
    prototypesByName[name] = prototype || {};
    // notify the registrar waiting for 'name', if any
    notifyPrototype(name);
  }

  // declarative implementation: <polymer-element>

  var prototype = extend(Object.create(HTMLElement.prototype), {
    createdCallback: function() {
      // fetch the element name
      this.name = this.getAttribute('name');
      //console.log('createdCallback', this.name);
      // fetch our extendee name
      this.extends = this.getAttribute('extends');
      this.loadResources();
      this.registerWhenReady();
    },
    registerWhenReady: function() {
      if (this.registered) {
        return;
      }
      // if we have no prototype, wait
      if (this.waitingForPrototype(this.name)) {
        return;
      }
      if (this.waitingForQueue()) {
        return;
      }
      if (this.waitingForResources()) {
        return;
      }
      this._register();
    },
    _register: function() {
      //console.group('registering', this.name);
      this.register(this.name, this.extends);
      this.registered = true;
      //console.groupEnd();
      // tell the queue this element has registered
      queue.notify(this);
    },
    waitingForPrototype: function(name) {
      if (!getRegisteredPrototype(name)) {
        // then wait for a prototype
        waitPrototype[name] = this;
        // if explicitly marked as 'noscript'
        if (this.hasAttribute('noscript')) {
          // TODO(sorvell): CustomElements polyfill awareness:
          // noscript elements should upgrade in logical order
          // script injection ensures this under native custom elements;
          // under imports + ce polyfills, scripts run before upgrades.
          // dependencies should be ready at upgrade time so register
          // prototype at this time.
          if (window.CustomElements && !CustomElements.useNative) {
            element(name);
          } else {
            var script = document.createElement('script');
            script.textContent = 'Polymer(\'' + name + '\');';
            this.appendChild(script);
          }
        }
        return true;
      }
    },
    waitingForResources: function() {
      return this._needsResources;
    },
    // NOTE: Elements must be queued in proper order for inheritance/composition
    // dependency resolution. Previously this was enforced for inheritance
    // and by rule for composition. It's now entirely by rule.
    waitingForQueue: function() {
      return queue.wait(this);
    },
    loadResources: function() {
      this._needsResources = true;
      this.loadStyles(function() {
        this._needsResources = false;
        this.registerWhenReady();
      }.bind(this));
    }
  });

  // semi-pluggable APIs
  // TODO(sjmiles): should be fully pluggable (aka decoupled, currently
  // the various plugins are allowed to depend on each other directly)
  Object.keys(apis).forEach(function(n) {
    extend(prototype, apis[n]);
  });

  // utility and bookkeeping

  // maps tag names to prototypes
  var prototypesByName = {};

  function getRegisteredPrototype(name) {
    return prototypesByName[name];
  }

  // elements waiting for prototype, by name
  var waitPrototype = {};

  function notifyPrototype(name) {
    if (waitPrototype[name]) {
      waitPrototype[name].registerWhenReady();
      delete waitPrototype[name];
    }
  }

  // track document.register'ed tag names
  var registered = {};

  function isRegistered(name) {
    return registered[name];
  }

  // exports
  scope.getRegisteredPrototype = getRegisteredPrototype;

  // namespace shenanigans so we can expose our scope on the registration
  // function

  // TODO(sjmiles): find a way to do this that is less terrible
  // copy window.Polymer properties onto `element()`
  extend(element, scope);
  // make window.Polymer reference `element()`
  window.Polymer = element;

  // Under the HTMLImports polyfill, scripts in the main document
  // do not block on imports; we want to allow calls to Polymer in the main
  // document. We do so via coordination with Platform:
  var declarations = Platform.deliverDeclarations();
  if (declarations) {
    for (var i=0, l=declarations.length, d; (i<l) && (d=declarations[i]); i++) {
      element.apply(null, d);
    }
  }

  whenPolymerReady(function() {
    document.dispatchEvent(
      new CustomEvent('polymer-ready', {bubbles: true})
    );
  });

  // register polymer-element with document
  document.registerElement('polymer-element', {prototype: prototype});
})(Polymer);
<|endoftext|>


<commit_before>import { find, findOne } from './find';

let docClient;
let TableName = 'w00t';
let tableKeyDefinition = { id: 'N', name: 'S' };
let params = { id: 1 };

describe('find', () => {
  it('Should reject when docClient is invalid', () => {
    docClient = null;
    find({ docClient, TableName, tableKeyDefinition, params })
      .catch(err => expect(err).toBeDefined());
    docClient = {};
    find({ docClient, TableName, tableKeyDefinition, params })
      .catch(err => expect(err).toBeDefined());
  });

  it('Should reject on callback errors', () => {
    docClient = {
      get: jest.fn((params, cb) => cb('Something went wrong')),
    };
    find({ docClient, TableName, tableKeyDefinition, params })
      .catch(err => expect(err).toBeDefined());
  });

  it('Should call `get` for table keys and `scan` for other keys', () => {
    docClient = {
      get: jest.fn(),
      scan: jest.fn(),
    };
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5 } });
    expect(docClient.get.mock.calls.length).toBe(1);
    find({ docClient, TableName, tableKeyDefinition, params: { blorg: 5 } });
    expect(docClient.scan.mock.calls.length).toBe(1);
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5, name: 'Pony' } });
    expect(docClient.get.mock.calls.length).toBe(2);
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5, name: 'Pony', isPink: true } });
    expect(docClient.scan.mock.calls.length).toBe(2);
  });

  it('Should return an array if resolved', () => {
    docClient = {
      get: jest.fn((params, cb) => cb(null, {
        Item: { id: 1 }
      })),
      scan: jest.fn((params, cb) => cb(null, {
        Items: [ { id: 1 }, { id: 2 } ]
      })),
    };

    find({ docClient, TableName, tableKeyDefinition, params: { id: 5 } })
      .then(res => expect(Array.isArray(res) && res.length === 1).toBeTruthy());
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5, isPirple: 'huh?' } })
      .then(res => expect(Array.isArray(res) && res.length === 2).toBeTruthy());
  });

  it('Should return an empty array when resolved without Item or Items keys', () => {
    docClient = {
      get: jest.fn((params, cb) => cb(null, { id: 1 })),
      scan: jest.fn((params, cb) => cb(null,
        [ { id: 1 }, { id: 2 } ]
      )),
    };

    find({ docClient, TableName, tableKeyDefinition, params: { id: 5 } })
      .then(res => expect(Array.isArray(res) && res.length === 0).toBeTruthy());
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5, isPirple: 'huh?' } })
      .then(res => expect(Array.isArray(res) && res.length === 0).toBeTruthy());
  });
});
<commit_msg>Added tests to ensure `findOne` returns the first result, or null on no result<commit_after>import { find, findOne } from './find';

let docClient;
let TableName = 'w00t';
let tableKeyDefinition = { id: 'N', name: 'S' };
let params = { id: 1 };

describe('find', () => {
  it('Should reject when docClient is invalid', () => {
    docClient = null;
    find({ docClient, TableName, tableKeyDefinition, params })
      .catch(err => expect(err).toBeDefined());
    docClient = {};
    find({ docClient, TableName, tableKeyDefinition, params })
      .catch(err => expect(err).toBeDefined());
  });

  it('Should reject on callback errors', () => {
    docClient = {
      get: jest.fn((params, cb) => cb('Something went wrong')),
    };
    find({ docClient, TableName, tableKeyDefinition, params })
      .catch(err => expect(err).toBeDefined());
  });

  it('Should call `get` for table keys and `scan` for other keys', () => {
    docClient = {
      get: jest.fn(),
      scan: jest.fn(),
    };
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5 } });
    expect(docClient.get.mock.calls.length).toBe(1);
    find({ docClient, TableName, tableKeyDefinition, params: { blorg: 5 } });
    expect(docClient.scan.mock.calls.length).toBe(1);
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5, name: 'Pony' } });
    expect(docClient.get.mock.calls.length).toBe(2);
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5, name: 'Pony', isPink: true } });
    expect(docClient.scan.mock.calls.length).toBe(2);
  });

  it('Should return an array if resolved', () => {
    docClient = {
      get: jest.fn((params, cb) => cb(null, {
        Item: { id: 1 }
      })),
      scan: jest.fn((params, cb) => cb(null, {
        Items: [ { id: 1 }, { id: 2 } ]
      })),
    };

    find({ docClient, TableName, tableKeyDefinition, params: { id: 5 } })
      .then(res => expect(Array.isArray(res) && res.length === 1).toBeTruthy());
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5, isPirple: 'huh?' } })
      .then(res => expect(Array.isArray(res) && res.length === 2).toBeTruthy());
  });

  it('Should return an empty array when resolved without Item or Items keys', () => {
    docClient = {
      get: jest.fn((params, cb) => cb(null, { id: 1 })),
      scan: jest.fn((params, cb) => cb(null,
        [ { id: 1 }, { id: 2 } ]
      )),
    };

    find({ docClient, TableName, tableKeyDefinition, params: { id: 5 } })
      .then(res => expect(Array.isArray(res) && res.length === 0).toBeTruthy());
    find({ docClient, TableName, tableKeyDefinition, params: { id: 5, isPirple: 'huh?' } })
      .then(res => expect(Array.isArray(res) && res.length === 0).toBeTruthy());
  });
});

describe('findOne', () => {
  it('Should return the first item', () => {
    docClient = {
      get: jest.fn((params, cb) => cb(null, {
        Item: { id: 1 }
      })),
      scan: jest.fn((params, cb) => cb(null, {
        Items: [ { id: 1 }, { id: 2 } ]
      })),
    };

    findOne({ docClient, TableName, tableKeyDefinition, params: { id: 1 } })
      .then(res => expect(res).toEqual({ id: 1 }));
    findOne({ docClient, TableName, tableKeyDefinition, params: { id: 1, whois: 'Mr. Poopybutthole' } })
      .then(res => expect(res).toEqual({ id: 1 }));
  });

  it('Should return null when no result', () => {
    docClient = {
      get: jest.fn((params, cb) => cb(null, {})),
      scan: jest.fn((params, cb) => cb(null, {
        Items: []
      })),
    };

    findOne({ docClient, TableName, tableKeyDefinition, params: { id: 1 } })
      .then(res => expect(res).toBe(null));
    findOne({ docClient, TableName, tableKeyDefinition, params: { id: 1, whois: 'Mr. Poopybutthole' } })
      .then(res => expect(res).toBe(null));
  });
});
<|endoftext|>


<commit_before>// =================================================================
// Logtalk - Object oriented extension to Prolog
// Release 2.29.6
//
// Copyright (c) 1998-2007 Paulo Moura.  All Rights Reserved.
// =================================================================

if (ScriptEngineMajorVersion() < 5 || ScriptEngineMajorVersion() == 5 && ScriptEngineMinorVersion() < 6) {
	WScript.Echo('Error! WSH 5.6 or later version needed for running this script.');
	WScript.Quit(1);
}

var prolog_path = "C:\\XSB\\config\\x86-pc-windows\\bin\\xsb.exe";

if (WScript.Arguments.Unnamed.Length > 0) {
	usage_help();
	WScript.Quit(0);
}

WScript.Echo('');
WScript.Echo('Creating a shortcut named "Logtalk - XSB" for running Logtalk');
WScript.Echo('with XSB...');
WScript.Echo('');

var FSObject = new ActiveXObject("Scripting.FileSystemObject");

if (!FSObject.FileExists(prolog_path)) {
	WScript.Echo("Error! Cannot find xsb.exe at the expected place!");
	WScript.Echo("Please edit the script and update the location of the xsb.exe executable.");
	WScript.Quit(1);
}

var WshShell = new ActiveXObject("WScript.Shell");

var WshSystemEnv = WshShell.Environment("SYSTEM");
var WshUserEnv = WshShell.Environment("USER");
var logtalk_home;

if (WshSystemEnv.Item("LOGTALKHOME"))
	logtalk_home = WshSystemEnv.Item("LOGTALKHOME");
else if (WshUserEnv.Item("LOGTALKHOME"))
	logtalk_home = WshUserEnv.Item("LOGTALKHOME")
else {
	WScript.Echo("Error! The environment variable LOGTALKHOME must be defined first!");
	usage_help();
	WScript.Quit(1);
}

if (!FSObject.FolderExists(logtalk_home)) {
	WScript.Echo("The environment variable LOGTALKHOME points to a non-existing directory!");
	WScript.Echo("Its current value is: %LOGTALKHOME%");
	WScript.Echo("The variable must be set to your Logtalk installation directory!");
	WScript.Echo("");
	usage_help();
	WScript.Quit(1);
}

logtalk_home = logtalk_home.replace(/\\/g, "\\\\");

if (!FSObject.FolderExists(logtalk_home + "\\bin"))
	FSObject.CreateFolder(logtalk_home + "\\bin");

var f = FSObject.CreateTextFile(logtalk_home + "\\bin\\logtalk_xsb.pl", true);

f.WriteLine(":- expand_filename('configs/xsb.pl', Path), reconsult(Path).");
f.WriteLine(":- reconsult('" + logtalk_home + "\\\\compiler\\\\logtalk.pl').");
f.WriteLine(":- expand_filename('libpaths/libpaths_no_env_var.pl', Path), reconsult(Path).");
f.Close();

var ProgramsPath = WshShell.SpecialFolders("AllUsersPrograms");

if (!FSObject.FolderExists(ProgramsPath + "\\Logtalk"))
	FSObject.CreateFolder(ProgramsPath + "\\Logtalk");

var link = WshShell.CreateShortcut(ProgramsPath + "\\Logtalk\\Logtalk - XSB.lnk");
link.Arguments = "-l -e \"['%LOGTALKUSER%\\\\configs\\\\xsb.pl', '%LOGTALKHOME%\\\\compiler\\\\logtalk.pl', '%LOGTALKUSER%\\\\libpaths\\\\libpaths_no_env_var.pl']).\"";
link.Description = "Runs Logtalk with XSB";
link.IconLocation = "app.exe,1";
link.TargetPath = prolog_path;
link.WindowStyle = 1;
link.WorkingDirectory = "%LOGTALKUSER%";
link.Save();

WScript.Echo('Done. The "Logtalk - XSB" shortcut was been added to the Start Menu');
WScript.Echo('Programs.  Make sure that the environment variables LOGTALKHOME and');
WScript.Echo('LOGTALKUSER are defined for all users wishing to use the shortcut.');
WScript.Echo('');
WScript.Echo('The first call to the shortcut must be made by a user with');
WScript.Echo('administrative rights.');
WScript.Echo('');
WScript.Echo('Users must run the batch script "cplgtdirs" once before using the');
WScript.Echo('"Logtalk - XSB" shortcut. Users must edit the contents of the');
WScript.Echo('"libpaths_no_env_var.pl" file on the "libpaths" directory in order');
WScript.Echo('to replace all occurrences of the LOGTALKUSER environment variable');
WScript.Echo('by its value.');
WScript.Echo('');

WScript.Quit(0);

function usage_help() {
	WScript.Echo('');
	WScript.Echo('This script creates a shortcut named "Logtalk - XSB" for running Logtalk');
	WScript.Echo('with XSB. The script must be run by a user with administrative rights.');
	WScript.Echo('The LOGTALKHOME environment variable must be defined before running this');
	WScript.Echo('script.');
	WScript.Echo('');
	WScript.Echo('Usage:');
	WScript.Echo('  ' + WScript.ScriptName + ' help');
	WScript.Echo('  ' + WScript.ScriptName);
	WScript.Echo('');
}
<commit_msg>New, much improved installation and integration scripts.<commit_after>// =================================================================
// Logtalk - Object oriented extension to Prolog
// Release 2.29.6
//
// Copyright (c) 1998-2007 Paulo Moura.  All Rights Reserved.
// =================================================================

if (ScriptEngineMajorVersion() < 5 || ScriptEngineMajorVersion() == 5 && ScriptEngineMinorVersion() < 6) {
	WScript.Echo('Error! WSH 5.6 or later version needed for running this script.');
	WScript.Quit(1);
}

var prolog_path = "C:\\XSB\\config\\x86-pc-windows\\bin\\xsb.exe";

if (WScript.Arguments.Unnamed.Length > 0) {
	usage_help();
	WScript.Quit(0);
}

WScript.Echo('');
WScript.Echo('Creating a shortcut named "Logtalk - XSB" for running Logtalk');
WScript.Echo('with XSB...');
WScript.Echo('');

var FSObject = new ActiveXObject("Scripting.FileSystemObject");

if (!FSObject.FileExists(prolog_path)) {
	WScript.Echo("Error! Cannot find xsb.exe at the expected place!");
	WScript.Echo("Please edit the script and update the location of the xsb.exe executable.");
	WScript.Quit(1);
}

var WshShell = new ActiveXObject("WScript.Shell");

var WshSystemEnv = WshShell.Environment("SYSTEM");
var WshUserEnv = WshShell.Environment("USER");
var logtalk_home;

if (WshSystemEnv.Item("LOGTALKHOME"))
	logtalk_home = WshSystemEnv.Item("LOGTALKHOME");
else if (WshUserEnv.Item("LOGTALKHOME"))
	logtalk_home = WshUserEnv.Item("LOGTALKHOME")
else {
	WScript.Echo("Error! The environment variable LOGTALKHOME must be defined first!");
	usage_help();
	WScript.Quit(1);
}

if (!FSObject.FolderExists(logtalk_home)) {
	WScript.Echo("The environment variable LOGTALKHOME points to a non-existing directory!");
	WScript.Echo("Its current value is: %LOGTALKHOME%");
	WScript.Echo("The variable must be set to your Logtalk installation directory!");
	WScript.Echo("");
	usage_help();
	WScript.Quit(1);
}

logtalk_home = logtalk_home.replace(/\\/g, "\\\\");

if (!FSObject.FolderExists(logtalk_home + "\\bin"))
	FSObject.CreateFolder(logtalk_home + "\\bin");

var f = FSObject.CreateTextFile(logtalk_home + "\\bin\\logtalk_xsb.pl", true);

f.WriteLine(":- expand_filename('configs/xsb.pl', Path), reconsult(Path).");
f.WriteLine(":- reconsult('" + logtalk_home + "\\\\compiler\\\\logtalk.pl').");
f.WriteLine(":- expand_filename('libpaths/libpaths_no_env_var.pl', Path), reconsult(Path).");
f.Close();

var ProgramsPath = WshShell.SpecialFolders("AllUsersPrograms");

if (!FSObject.FolderExists(ProgramsPath + "\\Logtalk"))
	FSObject.CreateFolder(ProgramsPath + "\\Logtalk");

var link = WshShell.CreateShortcut(ProgramsPath + "\\Logtalk\\Logtalk - XSB.lnk");
link.Arguments = "-l -e \"['%LOGTALKUSER%\\\\configs\\\\xsb.pl', '%LOGTALKHOME%\\\\compiler\\\\logtalk.pl', '%LOGTALKUSER%\\\\libpaths\\\\libpaths_no_env_var.pl'].\"";
link.Description = "Runs Logtalk with XSB";
link.IconLocation = "app.exe,1";
link.TargetPath = prolog_path;
link.WindowStyle = 1;
link.WorkingDirectory = "%LOGTALKUSER%";
link.Save();

WScript.Echo('Done. The "Logtalk - XSB" shortcut was been added to the Start Menu');
WScript.Echo('Programs.  Make sure that the environment variables LOGTALKHOME and');
WScript.Echo('LOGTALKUSER are defined for all users wishing to use the shortcut.');
WScript.Echo('');
WScript.Echo('The first call to the shortcut must be made by a user with');
WScript.Echo('administrative rights.');
WScript.Echo('');
WScript.Echo('Users must run the batch script "cplgtdirs" once before using the');
WScript.Echo('"Logtalk - XSB" shortcut. Users must edit the contents of the');
WScript.Echo('"libpaths_no_env_var.pl" file on the "libpaths" directory in order');
WScript.Echo('to replace all occurrences of the LOGTALKUSER environment variable');
WScript.Echo('by its value.');
WScript.Echo('');

WScript.Quit(0);

function usage_help() {
	WScript.Echo('');
	WScript.Echo('This script creates a shortcut named "Logtalk - XSB" for running Logtalk');
	WScript.Echo('with XSB. The script must be run by a user with administrative rights.');
	WScript.Echo('The LOGTALKHOME environment variable must be defined before running this');
	WScript.Echo('script.');
	WScript.Echo('');
	WScript.Echo('Usage:');
	WScript.Echo('  ' + WScript.ScriptName + ' help');
	WScript.Echo('  ' + WScript.ScriptName);
	WScript.Echo('');
}
<|endoftext|>


<commit_before>
/**
 * @fileoverview The configuration.
 */

(function(host, util, data, fn) {

  var config = data.config;

  var noCachePrefix = 'seajs-ts=';
  var noCacheTimeStamp = noCachePrefix + util.now();

  // Async inserted script.
  var loaderScript = document.getElementById('seajsnode');

  // Static script.
  if (!loaderScript) {
    var scripts = document.getElementsByTagName('script');
    loaderScript = scripts[scripts.length - 1];
  }

  var loaderSrc = util.getScriptAbsoluteSrc(loaderScript) ||
      util.pageUrl; // When sea.js is inline, set base to pageUrl.

  var base = util.dirname(loaderSrc);
  util.loaderDir = base;

  // When src is "http://test.com/libs/seajs/1.0.0/sea.js", redirect base
  // to "http://test.com/libs/"
  var match = base.match(/^(.+\/)seajs\/[\d\.]+\/$/);
  if (match) {
    base = match[1];
  }

  config.base = base;

  var mainAttr = loaderScript.getAttribute('data-main');
  if (mainAttr) {
    // data-main="abc" is equivalent to data-main="./abc"
    if (util.isTopLevel(mainAttr)) {
      mainAttr = './' + mainAttr;
    }
    config.main = mainAttr;
  }

  // The max time to load a script file.
  config.timeout = 20000;

  /**
   * The function to configure the framework.
   * config({
   *   'base': 'path/to/base',
   *   'alias': {
   *     'app': 'biz/xx',
   *     'jquery': 'jquery-1.5.2',
   *     'cart': 'cart?t=20110419'
   *   },
   *   'map': [
   *     ['test.cdn.cn', 'localhost']
   *   ],
   *   preload: [],
   *   charset: 'utf-8',
   *   timeout: 20000, // 20s
   *   debug: false
   * });
   *
   * @param {Object} o The config object.
   */
  fn.config = function(o) {
    for (var k in o) {
      var previous = config[k];
      var current = o[k];

      if (previous && k === 'alias') {
        for (var p in current) {
          if (current.hasOwnProperty(p)) {
            checkAliasConflict(previous[p], current[p]);
            previous[p] = current[p];
          }
        }
      }
      else if (previous && (k === 'map' || k === 'preload')) {
        // for config({ preload: 'some-module' })
        if (!util.isArray(current)) {
          current = [current];
        }
        util.forEach(current, function(item) {
          if (item) { // Ignore empty string.
            previous.push(item);
          }
        });
        // NOTICE: no need to check conflict for map and preload.
      }
      else {
        config[k] = current;
      }
    }

    // Make sure config.base is absolute path.
    var base = config.base;
    if (base && !util.isAbsolute(base)) {
      config.base = util.id2Uri('./' + base + '#');
    }

    // Use map to implement nocache
    if (config.debug === 2) {
      config.debug = 1;
      fn.config({
        map: [
          [/.*/, function(url) {
            if (url.indexOf(noCachePrefix) === -1) {
              url += (url.indexOf('?') === -1 ? '?' : '&') + noCacheTimeStamp;
            }
            return url;
          }]
        ]
      });
    }

    // Sync
    if (config.debug) {
      host.debug = config.debug;
    }

    return this;
  };

  function checkAliasConflict(previous, current) {
    if (previous && previous !== current) {
      util.error('Alias is conflicted:', current);
    }
  }

})(seajs, seajs._util, seajs._data, seajs._fn);
<commit_msg>code refactoring<commit_after>
/**
 * @fileoverview The configuration.
 */

(function(host, util, data, fn) {

  var config = data.config;

  var noCachePrefix = 'seajs-ts=';
  var noCacheTimeStamp = noCachePrefix + util.now();

  // Async inserted script.
  var loaderScript = document.getElementById('seajsnode');

  // Static script.
  if (!loaderScript) {
    var scripts = document.getElementsByTagName('script');
    loaderScript = scripts[scripts.length - 1];
  }

  var loaderSrc = util.getScriptAbsoluteSrc(loaderScript) ||
      util.pageUrl; // When sea.js is inline, set base to pageUrl.

  var base = util.dirname(loaderSrc);
  util.loaderDir = base;

  // When src is "http://test.com/libs/seajs/1.0.0/sea.js", redirect base
  // to "http://test.com/libs/"
  var match = base.match(/^(.+\/)seajs\/[\d\.]+\/$/);
  if (match) {
    base = match[1];
  }

  config.base = base;

  var dataMain = loaderScript.getAttribute('data-main');
  if (dataMain) {
    // data-main="abc" is equivalent to data-main="./abc"
    if (util.isTopLevel(dataMain)) {
      dataMain = './' + dataMain;
    }
    config.main = dataMain;
  }

  // The max time to load a script file.
  config.timeout = 20000;

  /**
   * The function to configure the framework.
   * config({
   *   'base': 'path/to/base',
   *   'alias': {
   *     'app': 'biz/xx',
   *     'jquery': 'jquery-1.5.2',
   *     'cart': 'cart?t=20110419'
   *   },
   *   'map': [
   *     ['test.cdn.cn', 'localhost']
   *   ],
   *   preload: [],
   *   charset: 'utf-8',
   *   timeout: 20000, // 20s
   *   debug: false
   * });
   *
   * @param {Object} o The config object.
   */
  fn.config = function(o) {
    for (var k in o) {
      var previous = config[k];
      var current = o[k];

      if (previous && k === 'alias') {
        for (var p in current) {
          if (current.hasOwnProperty(p)) {
            checkAliasConflict(previous[p], current[p]);
            previous[p] = current[p];
          }
        }
      }
      else if (previous && (k === 'map' || k === 'preload')) {
        // for config({ preload: 'some-module' })
        if (!util.isArray(current)) {
          current = [current];
        }
        util.forEach(current, function(item) {
          if (item) { // Ignore empty string.
            previous.push(item);
          }
        });
        // NOTICE: no need to check conflict for map and preload.
      }
      else {
        config[k] = current;
      }
    }

    // Make sure config.base is absolute path.
    var base = config.base;
    if (base && !util.isAbsolute(base)) {
      config.base = util.id2Uri('./' + base + '#');
    }

    // Use map to implement nocache
    if (config.debug === 2) {
      config.debug = 1;
      fn.config({
        map: [
          [/.*/, function(url) {
            if (url.indexOf(noCachePrefix) === -1) {
              url += (url.indexOf('?') === -1 ? '?' : '&') + noCacheTimeStamp;
            }
            return url;
          }]
        ]
      });
    }

    // Sync
    if (config.debug) {
      host.debug = config.debug;
    }

    return this;
  };

  function checkAliasConflict(previous, current) {
    if (previous && previous !== current) {
      util.error('Alias is conflicted:', current);
    }
  }

})(seajs, seajs._util, seajs._data, seajs._fn);
<|endoftext|>


<commit_before>// We import the CSS which is extracted to its own file by esbuild.
// Remove this line if you add a your own CSS build pipeline (e.g postcss).
import "../css/app.css"

// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
// import "./user_socket.js"

// You can include dependencies in two ways.
//
// The simplest option is to put them in assets/vendor and
// import them using relative paths:
//
//     import "./vendor/some-package.js"
//
// Alternatively, you can `npm install some-package` and import
// them using a path starting with the package name:
//
//     import "some-package"
//
<%= if @html do %>
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
import "phoenix_html"
// Establish Phoenix Socket and LiveView configuration.
<%= @live_comment %>import {Socket} from "<%= @phoenix_js_path %>"
<%= @live_comment %>import {LiveSocket} from "phoenix_live_view"
<%= @live_comment %>import topbar from "../vendor/topbar"

<%= @live_comment %>let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
<%= @live_comment %>let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})

// Show progress bar on live navigation and form submits
<%= @live_comment %>topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
<%= @live_comment %>window.addEventListener("phx:page-loading-start", info => topbar.show())
<%= @live_comment %>window.addEventListener("phx:page-loading-stop", info => topbar.hide())

// connect if there are any LiveViews on the page
<%= @live_comment %>liveSocket.connect()

// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000)  // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
<%= @live_comment %>window.liveSocket = liveSocket
<% end %><commit_msg>assets app.js: Fix relative path in comment (#4552)<commit_after>// We import the CSS which is extracted to its own file by esbuild.
// Remove this line if you add a your own CSS build pipeline (e.g postcss).
import "../css/app.css"

// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
// import "./user_socket.js"

// You can include dependencies in two ways.
//
// The simplest option is to put them in assets/vendor and
// import them using relative paths:
//
//     import "../vendor/some-package.js"
//
// Alternatively, you can `npm install some-package` and import
// them using a path starting with the package name:
//
//     import "some-package"
//
<%= if @html do %>
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
import "phoenix_html"
// Establish Phoenix Socket and LiveView configuration.
<%= @live_comment %>import {Socket} from "<%= @phoenix_js_path %>"
<%= @live_comment %>import {LiveSocket} from "phoenix_live_view"
<%= @live_comment %>import topbar from "../vendor/topbar"

<%= @live_comment %>let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
<%= @live_comment %>let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})

// Show progress bar on live navigation and form submits
<%= @live_comment %>topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
<%= @live_comment %>window.addEventListener("phx:page-loading-start", info => topbar.show())
<%= @live_comment %>window.addEventListener("phx:page-loading-stop", info => topbar.hide())

// connect if there are any LiveViews on the page
<%= @live_comment %>liveSocket.connect()

// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000)  // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
<%= @live_comment %>window.liveSocket = liveSocket
<% end %><|endoftext|>


<commit_before>import RowNode from "./RowNode.js";
import Actions from "./Actions.js";
import TabNode from "./TabNode.js";
import JsonConverter from "../JsonConverter.js";

/**
 * Class containing the Model used by the FlexLayout component
 */
class Model
{
	constructor()
	{
		this._nodeMap = {};
		this._idMap = {};
		this._root = new RowNode(this);
		this._listeners = [];
		this._rect = null;
		this._activeTabSet = null;
		jsonConverter.setDefaults(this);

		this._addNode(this._root);
	}

	/**
	 * Get the currently active tabset node
	 * @returns {null|tabsetNode}
	 */
	getActiveTabset()
	{
		// check activeTabSet is still in tree
		var found = false;
		this.visitNodes((node)=>{
			if (!found && node == this._activeTabSet)
			{
				found = true;
			}
		});

		if (!found)
		{
			this._activeTabSet = null;
		}
		return this._activeTabSet;
	}

	/**
	 * Gets the root RowNode of the model
	 * @returns {RowNode|*}
	 */
	getRoot()
	{
		return this._root;
	}

	/**
	 * Gets the rectangle of the associated Layout control
	 * @returns {Rect}
	 */
	getRect()
	{
		return this._rect;
	}

	/**
	 * Visits all the nodes in the model and call the given function for each
	 * @param fn a function that takes visited node as its only parameter
	 */
	visitNodes(fn)
	{
		this._root._forEachNode(fn);
	}

	/**
	 * Gets a node by its id (where an id has been set in the initial json)
	 * @param id the id to find
	 * @returns {null|Node}
	 */
	getNodeById(id)
	{
		return this._idMap[id];
	}

	/**
	 * Update the model by performing the given action,
	 * Actions should be generated via static methods on the Actions class
	 * @param action the action to perform
	 */
	doAction(action)
	{
		console.log(action);
		switch (action.name)
		{
			case Actions.SET_RECT:
			{
				this._rect = action.rect;
				break;
			}
			case Actions.ADJUST_SPLIT:
			{
				let splitterNode = this._nodeMap[action.nodeKey];
				splitterNode.getParent()._adjustSplit(splitterNode, action.value);
				break;
			}
			case Actions.MOVE_NODE:
			{
				let toNode =  this._nodeMap[action.toNode];
				let fromNode =  this._nodeMap[action.fromNode];
				toNode._drop(fromNode, action.location, action.index);
				break;
			}
			case Actions.SELECT_TAB:
			{
				let tabNode =  this._nodeMap[action.tabset];
				if (tabNode.getSelected() != action.index) {
					tabNode._setSelected(action.index);
				}
				this._activeTabSet = tabNode;

				break;
			}
			case Actions.MAXIMIZE_TOGGLE:
			{
				let node =  this._nodeMap[action.node];
				node._setMaximized(!node.isMaximized());
				node._fireEvent("maximize", {maximized: node.isMaximized()});
				this._activeTabSet = node;

				break;
			}
			case Actions.RENAME_TAB:
			{
				let node =  this._nodeMap[action.node];
				node._setName(action.text);
				break;
			}
			case Actions.DELETE_TAB:
			{
				let node =  this._nodeMap[action.node];
				node._delete();
				break;
			}
			case Actions.ADD_TAB:
			{
				let tabsetNode =  this._nodeMap[action.tabsetNode];
				var newNode =  this._nodeMap[action.tabNode];
				var pos = tabsetNode._addChild(newNode);
				tabsetNode._setSelected(pos);
				this._activeTabSet = tabsetNode;

				break;
			}
			case Actions.SET_ACTIVE_TABSET:
			{
				let tabsetNode =  this._nodeMap[action.tabsetNode];
				this._activeTabSet = tabsetNode;

				break;
			}

		}
		this._layout(this._rect);
		this._fireChange();
	}

	/**
	 * Converts the model to json that can be serialized and restored via the fromJson() method
	 * @returns {*} json object that represents this model
	 */
	toJson()
	{
		var json = {config:{}, layout:{}};
		jsonConverter.toJson(json.config, this);
		this._root._forEachNode((node)=>{node._fireEvent("save", null);});
		json.layout = this._root._toJson();
		return json;
	}

	/**
	 * Loads the model from the given json representation
	 * @param json the json model to load
	 * @returns {Model} a new Model object
	 */
	static fromJson(json)
	{
		var model = new Model();
		jsonConverter.fromJson(json.config, model);

		model._root = RowNode._fromJson(json.layout, model);
		model._addNode(model._root);
		return model;
	}

	/**
	 * Adds a change listener to the model
	 * @param listener function with a onLayoutChange method, that will be called when the model changes
	 */
	addListener(listener)
	{
		this._listeners.push(listener);
	}

	/**
	 * Remove a previously added change listener
	 * @param listener
	 */
	removeListener(listener)
	{
		var index = this._listeners.indexOf(listener);
		if (index != -1)
		{
			this._listeners.splice(index, 1);
		}
	}

	getSplitterSize()
	{
		return this._splitterSize;
	}

	isEnableEdgeDock()
	{
		return this._enableEdgeDock;
	}

	_addNode(node)
	{
		this._nodeMap[node._key] = node;
		if (node._id != null)
		{
			this._idMap[node._id] = node;
		}
	}

	_fireChange()
	{
		this._listeners.forEach((listener) => {listener.onLayoutChange(this)});
	}

	_layout(rect)
	{
		var start = Date.now();
		this._root._layout(rect);
		console.log("layout time: " + (Date.now() - start));
	}

	_tidy()
	{
		//console.log("before _tidy", this.toString());
		this._root._tidy();
		//console.log("after _tidy", this.toString());
	}

	toString()
	{
		var lines = [];
		this._root.toString(lines, "");
		return lines.join("\n");
	}
}

var jsonConverter = new JsonConverter();

// splitter
jsonConverter.addConversion("_splitterSize", "splitterSize", 5);
jsonConverter.addConversion("_enableEdgeDock", "enableEdgeDock", true);

// tab
jsonConverter.addConversion("_tabEnableClose", "tabEnableClose", true);
jsonConverter.addConversion("_tabEnableDrag", "tabEnableDrag", true);
jsonConverter.addConversion("_tabEnableRename", "tabEnableRename", true);
jsonConverter.addConversion("_tabClassName", "tabClassName", null);
jsonConverter.addConversion("_tabIcon", "tabIcon", null);

// tabset
jsonConverter.addConversion("_tabSetEnableClose", "tabSetEnableClose", true);
jsonConverter.addConversion("_tabSetEnableDrop", "tabSetEnableDrop", true);
jsonConverter.addConversion("_tabSetEnableDrag", "tabSetEnableDrag", true);
jsonConverter.addConversion("_tabSetEnableDivide", "tabSetEnableDivide", true);
jsonConverter.addConversion("_tabSetEnableMaximize", "tabSetEnableMaximize", true);
jsonConverter.addConversion("_tabSetClassNameTabStrip", "tabSetClassNameTabStrip", null);
jsonConverter.addConversion("_tabSetClassNameHeader", "tabSetClassNameHeader", null);
jsonConverter.addConversion("_tabSetEnableTabStrip", "tabSetEnableTabStrip", true);
jsonConverter.addConversion("_tabSetHeaderHeight", "tabSetHeaderHeight", 20);
jsonConverter.addConversion("_tabSetTabStripHeight", "tabSetTabStripHeight", 20);

console.log(jsonConverter.toTable());

// model callbacks allowDrag, allowDrop(from, to, location), using _canDockInto
// or model listener for all attributes enables etc
export default Model;<commit_msg>default splitter to 8 px<commit_after>import RowNode from "./RowNode.js";
import Actions from "./Actions.js";
import TabNode from "./TabNode.js";
import JsonConverter from "../JsonConverter.js";

/**
 * Class containing the Model used by the FlexLayout component
 */
class Model
{
	constructor()
	{
		this._nodeMap = {};
		this._idMap = {};
		this._root = new RowNode(this);
		this._listeners = [];
		this._rect = null;
		this._activeTabSet = null;
		jsonConverter.setDefaults(this);

		this._addNode(this._root);
	}

	/**
	 * Get the currently active tabset node
	 * @returns {null|tabsetNode}
	 */
	getActiveTabset()
	{
		// check activeTabSet is still in tree
		var found = false;
		this.visitNodes((node)=>{
			if (!found && node == this._activeTabSet)
			{
				found = true;
			}
		});

		if (!found)
		{
			this._activeTabSet = null;
		}
		return this._activeTabSet;
	}

	/**
	 * Gets the root RowNode of the model
	 * @returns {RowNode|*}
	 */
	getRoot()
	{
		return this._root;
	}

	/**
	 * Gets the rectangle of the associated Layout control
	 * @returns {Rect}
	 */
	getRect()
	{
		return this._rect;
	}

	/**
	 * Visits all the nodes in the model and call the given function for each
	 * @param fn a function that takes visited node as its only parameter
	 */
	visitNodes(fn)
	{
		this._root._forEachNode(fn);
	}

	/**
	 * Gets a node by its id (where an id has been set in the initial json)
	 * @param id the id to find
	 * @returns {null|Node}
	 */
	getNodeById(id)
	{
		return this._idMap[id];
	}

	/**
	 * Update the model by performing the given action,
	 * Actions should be generated via static methods on the Actions class
	 * @param action the action to perform
	 */
	doAction(action)
	{
		console.log(action);
		switch (action.name)
		{
			case Actions.SET_RECT:
			{
				this._rect = action.rect;
				break;
			}
			case Actions.ADJUST_SPLIT:
			{
				let splitterNode = this._nodeMap[action.nodeKey];
				splitterNode.getParent()._adjustSplit(splitterNode, action.value);
				break;
			}
			case Actions.MOVE_NODE:
			{
				let toNode =  this._nodeMap[action.toNode];
				let fromNode =  this._nodeMap[action.fromNode];
				toNode._drop(fromNode, action.location, action.index);
				break;
			}
			case Actions.SELECT_TAB:
			{
				let tabNode =  this._nodeMap[action.tabset];
				if (tabNode.getSelected() != action.index) {
					tabNode._setSelected(action.index);
				}
				this._activeTabSet = tabNode;

				break;
			}
			case Actions.MAXIMIZE_TOGGLE:
			{
				let node =  this._nodeMap[action.node];
				node._setMaximized(!node.isMaximized());
				node._fireEvent("maximize", {maximized: node.isMaximized()});
				this._activeTabSet = node;

				break;
			}
			case Actions.RENAME_TAB:
			{
				let node =  this._nodeMap[action.node];
				node._setName(action.text);
				break;
			}
			case Actions.DELETE_TAB:
			{
				let node =  this._nodeMap[action.node];
				node._delete();
				break;
			}
			case Actions.ADD_TAB:
			{
				let tabsetNode =  this._nodeMap[action.tabsetNode];
				var newNode =  this._nodeMap[action.tabNode];
				var pos = tabsetNode._addChild(newNode);
				tabsetNode._setSelected(pos);
				this._activeTabSet = tabsetNode;

				break;
			}
			case Actions.SET_ACTIVE_TABSET:
			{
				let tabsetNode =  this._nodeMap[action.tabsetNode];
				this._activeTabSet = tabsetNode;

				break;
			}

		}
		this._layout(this._rect);
		this._fireChange();
	}

	/**
	 * Converts the model to json that can be serialized and restored via the fromJson() method
	 * @returns {*} json object that represents this model
	 */
	toJson()
	{
		var json = {config:{}, layout:{}};
		jsonConverter.toJson(json.config, this);
		this._root._forEachNode((node)=>{node._fireEvent("save", null);});
		json.layout = this._root._toJson();
		return json;
	}

	/**
	 * Loads the model from the given json representation
	 * @param json the json model to load
	 * @returns {Model} a new Model object
	 */
	static fromJson(json)
	{
		var model = new Model();
		jsonConverter.fromJson(json.config, model);

		model._root = RowNode._fromJson(json.layout, model);
		model._addNode(model._root);
		return model;
	}

	/**
	 * Adds a change listener to the model
	 * @param listener function with a onLayoutChange method, that will be called when the model changes
	 */
	addListener(listener)
	{
		this._listeners.push(listener);
	}

	/**
	 * Remove a previously added change listener
	 * @param listener
	 */
	removeListener(listener)
	{
		var index = this._listeners.indexOf(listener);
		if (index != -1)
		{
			this._listeners.splice(index, 1);
		}
	}

	getSplitterSize()
	{
		return this._splitterSize;
	}

	isEnableEdgeDock()
	{
		return this._enableEdgeDock;
	}

	_addNode(node)
	{
		this._nodeMap[node._key] = node;
		if (node._id != null)
		{
			this._idMap[node._id] = node;
		}
	}

	_fireChange()
	{
		this._listeners.forEach((listener) => {listener.onLayoutChange(this)});
	}

	_layout(rect)
	{
		var start = Date.now();
		this._root._layout(rect);
		console.log("layout time: " + (Date.now() - start));
	}

	_tidy()
	{
		//console.log("before _tidy", this.toString());
		this._root._tidy();
		//console.log("after _tidy", this.toString());
	}

	toString()
	{
		var lines = [];
		this._root.toString(lines, "");
		return lines.join("\n");
	}
}

var jsonConverter = new JsonConverter();

// splitter
jsonConverter.addConversion("_splitterSize", "splitterSize", 8);
jsonConverter.addConversion("_enableEdgeDock", "enableEdgeDock", true);

// tab
jsonConverter.addConversion("_tabEnableClose", "tabEnableClose", true);
jsonConverter.addConversion("_tabEnableDrag", "tabEnableDrag", true);
jsonConverter.addConversion("_tabEnableRename", "tabEnableRename", true);
jsonConverter.addConversion("_tabClassName", "tabClassName", null);
jsonConverter.addConversion("_tabIcon", "tabIcon", null);

// tabset
jsonConverter.addConversion("_tabSetEnableClose", "tabSetEnableClose", true);
jsonConverter.addConversion("_tabSetEnableDrop", "tabSetEnableDrop", true);
jsonConverter.addConversion("_tabSetEnableDrag", "tabSetEnableDrag", true);
jsonConverter.addConversion("_tabSetEnableDivide", "tabSetEnableDivide", true);
jsonConverter.addConversion("_tabSetEnableMaximize", "tabSetEnableMaximize", true);
jsonConverter.addConversion("_tabSetClassNameTabStrip", "tabSetClassNameTabStrip", null);
jsonConverter.addConversion("_tabSetClassNameHeader", "tabSetClassNameHeader", null);
jsonConverter.addConversion("_tabSetEnableTabStrip", "tabSetEnableTabStrip", true);
jsonConverter.addConversion("_tabSetHeaderHeight", "tabSetHeaderHeight", 20);
jsonConverter.addConversion("_tabSetTabStripHeight", "tabSetTabStripHeight", 20);

console.log(jsonConverter.toTable());

// model callbacks allowDrag, allowDrop(from, to, location), using _canDockInto
// or model listener for all attributes enables etc
export default Model;<|endoftext|>


<commit_before><commit_msg>Another crash fix.<commit_after><|endoftext|>


<commit_before>/* eslint-disable no-undef */
const chai = require('chai');
const assert = chai.assert;
chai.should();

describe('Testing Hierarchy 5', () => {
  it('Should display all aspects when "Vis Flere" is clicked', () => {
    browser.url('/#!/hierarchy/40');

    let topics = browser.getText('.selected .hierarchy-topics');
    assert.lengthOf(topics[0].split('\n'), 5);
    assert.lengthOf(browser.getText('.selected .hidden .hierarchy-topics'), 0);

    browser.click('.toggle-button');

    topics = browser.getText('.selected .hierarchy-topics');
    assert.lengthOf(topics[0].split('\n'), 5);
    assert.lengthOf(topics[1].split('\n'), 6);
    assert.isTrue(browser.isExisting('.selected .show .hierarchy-topics'));
  });
});
<commit_msg>New mock has 12 entries<commit_after>/* eslint-disable no-undef */
const chai = require('chai');
const assert = chai.assert;
chai.should();

describe('Testing Hierarchy 5', () => {
  it('Should display all aspects when "Vis Flere" is clicked', () => {
    browser.url('/#!/hierarchy/40');

    let topics = browser.getText('.selected .hierarchy-topics');
    assert.lengthOf(topics[0].split('\n'), 5);
    assert.lengthOf(browser.getText('.selected .hidden .hierarchy-topics'), 0);

    browser.click('.toggle-button');

    topics = browser.getText('.selected .hierarchy-topics');
    assert.lengthOf(topics[0].split('\n'), 5);
    assert.lengthOf(topics[1].split('\n'), 12);
    assert.isTrue(browser.isExisting('.selected .show .hierarchy-topics'));
  });
});
<|endoftext|>


<commit_before>
function minMax( d, index ) {

  var min = Number.MAX_VALUE;
  var max = -Number.MAX_VALUE;

  for ( var i = 0 ; i < d.length ; i++ ) {
    if ( d[i][index] < min ) min = d[i][index];
    if ( d[i][index] > max ) max = d[i][index];
  }

  return { min: min, max: max };

}

function linspace( a, b, points ) {

  var result = [];
  var step = ( b - a ) / ( points - 1 );
  for ( var i = 0 ; i < points - 1 ; i++ ) result.push( a + i * step );
  result.push( b );

  return result;

}

// rounding functions

function roundTo( x, n, significant=true ) {

  if ( x === 0 ) return x;

  if ( Array.isArray(x) ) {
    var v = [];
    for ( var i = 0 ; i < x.length ; i++ ) v[i] = roundTo( x[i], n, significant );
    return v;
  }

  if ( significant ) {
    var exponent = Math.floor( Math.log10( Math.abs(x) ) );
    n = n - exponent - 1;
  }

  return Math.round( 10**n * x ) / 10**n;

}

function ceilTo( x, n, significant=true ) {

  if ( x === 0 ) return x;

  if ( Array.isArray(x) ) {
    var v = [];
    for ( var i = 0 ; i < x.length ; i++ ) v[i] = ceilTo( x[i], n, significant );
    return v;
  }

  if ( significant ) {
    var exponent = Math.floor( Math.log10( Math.abs(x) ) );
    n = n - exponent - 1;
  }

  return Math.ceil( 10**n * x ) / 10**n;

}

function floorTo( x, n, significant=true ) {

  if ( x === 0 ) return x;

  if ( Array.isArray(x) ) {
    var v = [];
    for ( var i = 0 ; i < x.length ; i++ ) v[i] = floorTo( x[i], n, significant );
    return v;
  }

  if ( significant ) {
    var exponent = Math.floor( Math.log10( Math.abs(x) ) );
    n = n - exponent - 1;
  }

  return Math.floor( 10**n * x ) / 10**n;

}

// transformation functions

function translate( points, vector ) {

  for ( var i = 0 ; i < points.length ; i++ )
    for ( var j = 0 ; j < vector.length ; j++ )
      points[i][j] += vector[j];

  return points;

}

function rotate( points, angle=0, vector=[0,0,1] ) {

  var dimension = points[0].length;

  switch( dimension ) {

    case 2:

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

        var v = points[i];

        var x = v[0]*Math.cos(angle) - v[1]*Math.sin(angle);
        var y = v[0]*Math.sin(angle) + v[1]*Math.cos(angle);

        points[i] = [ x, y ];

      }

      break;

    case 3:

      var n = vector;
      var norm = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
      if ( norm === 0 ) break;
      if ( norm !== 1 )
        for ( var i = 0 ; i < 3 ; i++ ) n[i] /= Math.sqrt(norm);

      var n1 = n[0];
      var n2 = n[1];
      var n3 = n[2];
      var c = Math.cos(angle);
      var s = Math.sin(angle);

      // Rodrigues in matrix form
      var M = [ [ c + (1-c)*n1**2, -s*n3 + (1-c)*n1*n2, s*n2 + (1-c)*n1*n3 ],
                [ s*n3 + (1-c)*n1*n2, c + (1-c)*n2**2, -s*n1 + (1-c)*n2*n3 ],
                [ -s*n2 + (1-c)*n1*n3, s*n1 + (1-c)*n2*n3, c + (1-c)*n3**2 ] ];

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

        var v = points[i];
        var x = 0, y = 0, z = 0;

        for ( var j = 0 ; j < v.length ; j++ ) {
          x += M[0][j]*v[j];
          y += M[1][j]*v[j];
          z += M[2][j]*v[j];
        }

        points[i] = [ x, y, z ];

      }

      break;

    default:

      throw 'Unsupported rotation dimension';

    }

}

<commit_msg>Cleanup<commit_after>
function minMax( d, index ) {

  var min = Number.MAX_VALUE;
  var max = -Number.MAX_VALUE;

  for ( var i = 0 ; i < d.length ; i++ ) {
    if ( d[i][index] < min ) min = d[i][index];
    if ( d[i][index] > max ) max = d[i][index];
  }

  return { min: min, max: max };

}

function linspace( a, b, points ) {

  var result = [];
  var step = ( b - a ) / ( points - 1 );
  for ( var i = 0 ; i < points - 1 ; i++ ) result.push( a + i * step );
  result.push( b );

  return result;

}

// rounding functions

function roundTo( x, n, significant=true ) {

  if ( x === 0 ) return x;

  if ( Array.isArray(x) ) {
    var v = [];
    for ( var i = 0 ; i < x.length ; i++ ) v[i] = roundTo( x[i], n, significant );
    return v;
  }

  if ( significant ) {
    var exponent = Math.floor( Math.log10( Math.abs(x) ) );
    n = n - exponent - 1;
  }

  return Math.round( 10**n * x ) / 10**n;

}

function ceilTo( x, n, significant=true ) {

  if ( x === 0 ) return x;

  if ( Array.isArray(x) ) {
    var v = [];
    for ( var i = 0 ; i < x.length ; i++ ) v[i] = ceilTo( x[i], n, significant );
    return v;
  }

  if ( significant ) {
    var exponent = Math.floor( Math.log10( Math.abs(x) ) );
    n = n - exponent - 1;
  }

  return Math.ceil( 10**n * x ) / 10**n;

}

function floorTo( x, n, significant=true ) {

  if ( x === 0 ) return x;

  if ( Array.isArray(x) ) {
    var v = [];
    for ( var i = 0 ; i < x.length ; i++ ) v[i] = floorTo( x[i], n, significant );
    return v;
  }

  if ( significant ) {
    var exponent = Math.floor( Math.log10( Math.abs(x) ) );
    n = n - exponent - 1;
  }

  return Math.floor( 10**n * x ) / 10**n;

}

// transformation functions

function translate( points, vector ) {

  for ( var i = 0 ; i < points.length ; i++ )
    for ( var j = 0 ; j < vector.length ; j++ )
      points[i][j] += vector[j];

  return points;

}

function rotate( points, angle=0, vector=[0,0,1] ) {

  var dimension = points[0].length;

  switch( dimension ) {

    case 2:

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

        var v = points[i];

        var x = v[0]*Math.cos(angle) - v[1]*Math.sin(angle);
        var y = v[0]*Math.sin(angle) + v[1]*Math.cos(angle);

        points[i] = [ x, y ];

      }

      break;

    case 3:

      var n = vector;
      var norm = Math.sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
      if ( norm === 0 ) break;
      if ( norm !== 1 )
        for ( var i = 0 ; i < 3 ; i++ ) n[i] /= norm;

      var n1 = n[0];
      var n2 = n[1];
      var n3 = n[2];
      var c = Math.cos(angle);
      var s = Math.sin(angle);

      // Rodrigues in matrix form
      var M = [ [ c + (1-c)*n1**2, -s*n3 + (1-c)*n1*n2, s*n2 + (1-c)*n1*n3 ],
                [ s*n3 + (1-c)*n1*n2, c + (1-c)*n2**2, -s*n1 + (1-c)*n2*n3 ],
                [ -s*n2 + (1-c)*n1*n3, s*n1 + (1-c)*n2*n3, c + (1-c)*n3**2 ] ];

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

        var v = points[i];
        var x = 0, y = 0, z = 0;

        for ( var j = 0 ; j < v.length ; j++ ) {
          x += M[0][j]*v[j];
          y += M[1][j]*v[j];
          z += M[2][j]*v[j];
        }

        points[i] = [ x, y, z ];

      }

      break;

    default:

      throw 'Unsupported rotation dimension';

    }

}

<|endoftext|>