<commit_before>CodeMirror.defineMode("go", function(config, parserConfig) {
  var indentUnit = config.indentUnit;

  var keywords = {
    "break":true, "case":true, "chan":true, "const":true, "continue":true,
    "default":true, "defer":true, "else":true, "fallthrough":true, "for":true,
    "func":true, "go":true, "goto":true, "if":true, "import":true,
    "interface":true, "map":true, "package":true, "range":true, "return":true,
    "select":true, "struct":true, "switch":true, "type":true, "var":true,
    "bool":true, "byte":true, "complex64":true, "complex128":true,
    "float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
    "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
    "uint64":true, "int":true, "uint":true, "uintptr":true
  };

  var atoms = {
    "true":true, "false":true, "iota":true, "nil":true, "append":true,
    "cap":true, "close":true, "complex":true, "copy":true, "imag":true,
    "len":true, "make":true, "new":true, "panic":true, "print":true,
    "println":true, "real":true, "recover":true
  };

  var blockKeywords = {
    "else":true, "for":true, "func":true, "if":true, "interface":true,
    "select":true, "struct":true, "switch":true
  };

  var isOperatorChar = /[+\-*&^%:=<>!|\/]/;

  var curPunc;

  function tokenBase(stream, state) {
    var ch = stream.next();
    if (ch == '"' || ch == "'" || ch == "`") {
      state.tokenize = tokenString(ch);
      return state.tokenize(stream, state);
    }
    if (/[\d\.]/.test(ch)) {
      if (ch == ".") {
        stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
      } else if (ch == "0") {
        stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
      } else {
        stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
      }
      return "number";
    }
    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
      curPunc = ch;
      return null;
    }
    if (ch == "/") {
      if (stream.eat("*")) {
        state.tokenize = tokenComment;
        return tokenComment(stream, state);
      }
      if (stream.eat("/")) {
        stream.skipToEnd();
        return "comment";
      }
    }
    if (isOperatorChar.test(ch)) {
      stream.eatWhile(isOperatorChar);
      return "operator";
    }
    stream.eatWhile(/[\w\$_]/);
    var cur = stream.current();
    if (keywords.propertyIsEnumerable(cur)) {
      if (cur == "case" || cur == "default") curPunc = "case";
      return "keyword";
    }
    if (atoms.propertyIsEnumerable(cur)) return "atom";
    return "variable";
  }

  function tokenString(quote) {
    return function(stream, state) {
      var escaped = false, next, end = false;
      while ((next = stream.next()) != null) {
        if (next == quote && !escaped) {end = true; break;}
        escaped = !escaped && next == "\\";
      }
      if (end || !(escaped || quote == "`"))
        state.tokenize = tokenBase;
      return "string";
    };
  }

  function tokenComment(stream, state) {
    var maybeEnd = false, ch;
    while (ch = stream.next()) {
      if (ch == "/" && maybeEnd) {
        state.tokenize = tokenBase;
        break;
      }
      maybeEnd = (ch == "*");
    }
    return "comment";
  }

  function Context(indented, column, type, align, prev) {
    this.indented = indented;
    this.column = column;
    this.type = type;
    this.align = align;
    this.prev = prev;
  }
  function pushContext(state, col, type) {
    return state.context = new Context(state.indented, col, type, null, state.context);
  }
  function popContext(state) {
    var t = state.context.type;
    if (t == ")" || t == "]" || t == "}")
      state.indented = state.context.indented;
    return state.context = state.context.prev;
  }

  // Interface

  return {
    startState: function(basecolumn) {
      return {
        tokenize: null,
        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
        indented: 0,
        startOfLine: true
      };
    },

    token: function(stream, state) {
      var ctx = state.context;
      if (stream.sol()) {
        if (ctx.align == null) ctx.align = false;
        state.indented = stream.indentation();
        state.startOfLine = true;
        if (ctx.type == "case") ctx.type = "}";
      }
      if (stream.eatSpace()) return null;
      curPunc = null;
      var style = (state.tokenize || tokenBase)(stream, state);
      if (style == "comment") return style;
      if (ctx.align == null) ctx.align = true;

      if (curPunc == "{") pushContext(state, stream.column(), "}");
      else if (curPunc == "[") pushContext(state, stream.column(), "]");
      else if (curPunc == "(") pushContext(state, stream.column(), ")");
      else if (curPunc == "case") ctx.type = "case";
      else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state);
      else if (curPunc == ctx.type) popContext(state);
      state.startOfLine = false;
      return style;
    },

    indent: function(state, textAfter) {
      if (state.tokenize != tokenBase && state.tokenize != null) return 0;
      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
      if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
        state.context.type = "}";
        return ctx.indented;
      }
      var closing = firstChar == ctx.type;
      if (ctx.align) return ctx.column + (closing ? 0 : 1);
      else return ctx.indented + (closing ? 0 : indentUnit);
    },

    electricChars: "{}:"
  };
});

CodeMirror.defineMIME("text/x-go", "go");
<commit_msg>go-tour: add missing delete predeclared identifier for Syntax-Highlighting<commit_after>CodeMirror.defineMode("go", function(config, parserConfig) {
  var indentUnit = config.indentUnit;

  var keywords = {
    "break":true, "case":true, "chan":true, "const":true, "continue":true,
    "default":true, "defer":true, "else":true, "fallthrough":true, "for":true,
    "func":true, "go":true, "goto":true, "if":true, "import":true,
    "interface":true, "map":true, "package":true, "range":true, "return":true,
    "select":true, "struct":true, "switch":true, "type":true, "var":true,
    "bool":true, "byte":true, "complex64":true, "complex128":true,
    "float32":true, "float64":true, "int8":true, "int16":true, "int32":true,
    "int64":true, "string":true, "uint8":true, "uint16":true, "uint32":true,
    "uint64":true, "int":true, "uint":true, "uintptr":true
  };

  var atoms = {
    "true":true, "false":true, "iota":true, "nil":true, "append":true,
    "cap":true, "close":true, "complex":true, "copy":true, "delete":true, "imag":true,
    "len":true, "make":true, "new":true, "panic":true, "print":true,
    "println":true, "real":true, "recover":true
  };

  var blockKeywords = {
    "else":true, "for":true, "func":true, "if":true, "interface":true,
    "select":true, "struct":true, "switch":true
  };

  var isOperatorChar = /[+\-*&^%:=<>!|\/]/;

  var curPunc;

  function tokenBase(stream, state) {
    var ch = stream.next();
    if (ch == '"' || ch == "'" || ch == "`") {
      state.tokenize = tokenString(ch);
      return state.tokenize(stream, state);
    }
    if (/[\d\.]/.test(ch)) {
      if (ch == ".") {
        stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
      } else if (ch == "0") {
        stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
      } else {
        stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
      }
      return "number";
    }
    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
      curPunc = ch;
      return null;
    }
    if (ch == "/") {
      if (stream.eat("*")) {
        state.tokenize = tokenComment;
        return tokenComment(stream, state);
      }
      if (stream.eat("/")) {
        stream.skipToEnd();
        return "comment";
      }
    }
    if (isOperatorChar.test(ch)) {
      stream.eatWhile(isOperatorChar);
      return "operator";
    }
    stream.eatWhile(/[\w\$_]/);
    var cur = stream.current();
    if (keywords.propertyIsEnumerable(cur)) {
      if (cur == "case" || cur == "default") curPunc = "case";
      return "keyword";
    }
    if (atoms.propertyIsEnumerable(cur)) return "atom";
    return "variable";
  }

  function tokenString(quote) {
    return function(stream, state) {
      var escaped = false, next, end = false;
      while ((next = stream.next()) != null) {
        if (next == quote && !escaped) {end = true; break;}
        escaped = !escaped && next == "\\";
      }
      if (end || !(escaped || quote == "`"))
        state.tokenize = tokenBase;
      return "string";
    };
  }

  function tokenComment(stream, state) {
    var maybeEnd = false, ch;
    while (ch = stream.next()) {
      if (ch == "/" && maybeEnd) {
        state.tokenize = tokenBase;
        break;
      }
      maybeEnd = (ch == "*");
    }
    return "comment";
  }

  function Context(indented, column, type, align, prev) {
    this.indented = indented;
    this.column = column;
    this.type = type;
    this.align = align;
    this.prev = prev;
  }
  function pushContext(state, col, type) {
    return state.context = new Context(state.indented, col, type, null, state.context);
  }
  function popContext(state) {
    var t = state.context.type;
    if (t == ")" || t == "]" || t == "}")
      state.indented = state.context.indented;
    return state.context = state.context.prev;
  }

  // Interface

  return {
    startState: function(basecolumn) {
      return {
        tokenize: null,
        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
        indented: 0,
        startOfLine: true
      };
    },

    token: function(stream, state) {
      var ctx = state.context;
      if (stream.sol()) {
        if (ctx.align == null) ctx.align = false;
        state.indented = stream.indentation();
        state.startOfLine = true;
        if (ctx.type == "case") ctx.type = "}";
      }
      if (stream.eatSpace()) return null;
      curPunc = null;
      var style = (state.tokenize || tokenBase)(stream, state);
      if (style == "comment") return style;
      if (ctx.align == null) ctx.align = true;

      if (curPunc == "{") pushContext(state, stream.column(), "}");
      else if (curPunc == "[") pushContext(state, stream.column(), "]");
      else if (curPunc == "(") pushContext(state, stream.column(), ")");
      else if (curPunc == "case") ctx.type = "case";
      else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state);
      else if (curPunc == ctx.type) popContext(state);
      state.startOfLine = false;
      return style;
    },

    indent: function(state, textAfter) {
      if (state.tokenize != tokenBase && state.tokenize != null) return 0;
      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
      if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) {
        state.context.type = "}";
        return ctx.indented;
      }
      var closing = firstChar == ctx.type;
      if (ctx.align) return ctx.column + (closing ? 0 : 1);
      else return ctx.indented + (closing ? 0 : indentUnit);
    },

    electricChars: "{}:"
  };
});

CodeMirror.defineMIME("text/x-go", "go");
<|endoftext|>


<commit_before>import React, {
  View,
  Text,
  TouchableWithoutFeedback,
} from 'react-native'

import Styles from '../styles/Styles'
import Icon from 'react-native-vector-icons/FontAwesome'

const Header = React.createClass ({
  propTypes: {
    navigator: React.PropTypes.object,
  },

  getInitialState() {
    return {
      index: 0,
      title: '',
      path: 'none'
    }
  },

  immediatelyRefresh() {
    // NoOp https://github.com/facebook/react-native/issues/6205
  },

  componentWillReceiveProps(nextProps) {
    try {
      let position = nextProps.navState.routeStack.length - 1
      let nextTitle = nextProps.navState.routeStack[nextProps.navState.routeStack.length-1].title
      if (nextTitle && nextTitle !== this.state.title) {
        this.setState({
          title: nextTitle,
          index: position,
        })
      }
    } catch(e) {
      console.warn(e)
    }
  },

  renderDrawer() {
    if (typeof this.props.openDrawer === 'undefined') return;
    return (
      <View style={Styles.header.navBarRightButton}>
        <TouchableWithoutFeedback onPress={this.props.openDrawer}>
          <Icon name="bars" size={30} color="#FFFFFF" />
        </TouchableWithoutFeedback>
      </View>
    );
  },

  /* Methods */
  navigateBack() {
    this.props.navigator.pop()
  },

  /* Render */
  render() {
    return (
      <View style={Styles.header.navBar}>
        {
          this.state.index > 0 ?
          <View style={Styles.header.navBarLeftButton}>
            <TouchableWithoutFeedback onPress={this.navigateBack}>
              <Icon name="chevron-left" size={30} color="#FFFFFF" />
            </TouchableWithoutFeedback>
          </View>
          : null
        }
        <View>
          <Text>
            {this.state.title}
          </Text>
        </View>
        {this.renderDrawer()}
      </View>
    )
  }
})

module.exports = Header
<commit_msg>Update index position even when title is empty<commit_after>import React, {
  View,
  Text,
  TouchableWithoutFeedback,
} from 'react-native'

import Styles from '../styles/Styles'
import Icon from 'react-native-vector-icons/FontAwesome'

const Header = React.createClass ({
  propTypes: {
    navigator: React.PropTypes.object,
  },

  getInitialState() {
    return {
      index: 0,
      title: '',
      path: 'none'
    }
  },

  immediatelyRefresh() {
    // NoOp https://github.com/facebook/react-native/issues/6205
  },

  componentWillReceiveProps(nextProps) {
    try {
      let title = this.state.title
      let position = nextProps.navState.routeStack.length - 1
      let nextTitle = nextProps.navState.routeStack[nextProps.navState.routeStack.length-1].title
      if (nextTitle && nextTitle !== title) {
        title = nextTitle
      }
      this.setState({
        title: title,
        index: position
      })
    } catch(e) {
      console.warn(e)
    }
  },

  renderDrawer() {
    if (typeof this.props.openDrawer === 'undefined') return;
    return (
      <View style={Styles.header.navBarRightButton}>
        <TouchableWithoutFeedback onPress={this.props.openDrawer}>
          <Icon name="bars" size={30} color="#FFFFFF" />
        </TouchableWithoutFeedback>
      </View>
    );
  },

  /* Methods */
  navigateBack() {
    this.props.navigator.pop()
  },

  /* Render */
  render() {
    return (
      <View style={Styles.header.navBar}>
        {
          this.state.index > 0 ?
          <View style={Styles.header.navBarLeftButton}>
            <TouchableWithoutFeedback onPress={this.navigateBack}>
              <Icon name="chevron-left" size={30} color="#FFFFFF" />
            </TouchableWithoutFeedback>
          </View>
          : null
        }
        <View>
          <Text>
            {this.state.title}
          </Text>
        </View>
        {this.renderDrawer()}
      </View>
    )
  }
})

module.exports = Header
<|endoftext|>


<commit_before>$(document).ready(function () {
  var sheetUrl = "https://docs.google.com/spreadsheets/d/14nDVwVvubdeUDVDRKxkq1P5hgaqUNk_k1ekHLKyqooY/edit#gid=0";

  var category = null;
  var score = null;

  var noFee = false;
  var noBalanceTransferFee = false;
  var noForeignFee = false;

  var networkAmex = false;
  var networkDiscover = false;
  var networkVisaMastercard = false;

  var financialAmex = false;
  var financialBankOfAmerica = false;
  var financialBarclaycard = false;
  var financialCapitalOne = false;
  var financialChase = false;
  var financialCiti = false;
  var financialDiscover = false;
  var financialWellsFargo = false;

  var latinoFriendly = false;

  var cardsToCompare = [];

  var pageData = {
    'rewards': [
      'Rewards Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ],
    'cashback': [
      'Cash Back Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ],
    'travel': [
      'Travel Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ],
    'lowinterest': [
      'Low Interest Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ],
    'student': [
      'Student Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ]
  };

  loadData();
  updateView();
  loadCardsTable();

  $("a[id*='category-']").click(function () {
    updateSelection(this.id);
  });
  $("a[id*='score-']").click(function () {
    updateSelection(this.id);
  });
  $("input[id*='check-']").click(function () {
    updateSelection(this.id);
  });
  $('#btn-compare-cards').click(function () {
    compareCards();
  });
  $('#btn-reset-cards-to-compare').click(function () {
    resetCardsToCompare();
  });
  $('body').on('click', "input[id*='compare-card-']", function () {
    updateCardsToCompare(this.id);
  });
  $('body').on('click', "input[id*='label-compare-card-']", function () {
    updateCardsToCompare(this.id);
  });

  function updateView() {
    $("a[id*='category']").removeClass('active');
    $("a[id*='score']").removeClass('active');
    $("input[id*='check-']").prop('checked', false);

    $('#category-' + category).addClass('active');
    $('#score-' + score).addClass('active');

    $('#check-no-fee').prop('checked', noFee);
    $('#check-no-balance-transfer-fee').prop('checked', noBalanceTransferFee);
    $('#check-no-foreign-fee').prop('checked', noForeignFee);

    $('#check-network-amex').prop('checked', networkAmex);
    $('#check-network-discover').prop('checked', networkDiscover);
    $('#check-network-visa-mastercard').prop('checked', networkVisaMastercard);

    $('#check-financial-amex').prop('checked', financialAmex);
    $('#check-financial-bank-of-america').prop('checked', financialBankOfAmerica);
    $('#check-financial-barclaycard').prop('checked', financialBarclaycard);
    $('#check-financial-capital-one').prop('checked', financialCapitalOne);
    $('#check-financial-chase').prop('checked', financialChase);
    $('#check-financial-citi').prop('checked', financialCiti);
    $('#check-financial-discover').prop('checked', financialDiscover);
    $('#check-financial-wells-fargo').prop('checked', financialWellsFargo);

    $('#check-latino-friendly').prop('checked', latinoFriendly);

    if (cardsToCompare.length > 0) {
      cardsToCompare.length == 1 ? $('#btn-compare-cards').addClass('disabled') : $('#btn-compare-cards').removeClass('disabled');
      $('#badge-cards-to-compare-count').text(cardsToCompare.length);
      $("#footer-compare").slideDown("fast", function () { });
    }
    else {
      $("#footer-compare").slideUp("fast", function () { });
    }
  }

  function loadData() {
    category = url('?category') != 'undefined' ? url('?category') : category = 'improve';
    score = url('?score') != 'undefined' ? url('?score') : score = 'excellent';
  }

  function updateSelection(id) {
    var type = id.split('-')[0];
    var value = id.substring(id.indexOf('-') + 1)

    switch (type) {
      case 'category':
        category = value;
        break;
      case 'score':
        score = value;
        break;
      case 'check':
        switch (value) {
          case 'latino-friendly':
            latinoFriendly = $('#' + id).prop('checked');
            break;
          case 'no-fee':
            noFee = $('#' + id).prop('checked');
            break;
          case 'no-balance-transfer-fee':
            noBalanceTransferFee = $('#' + id).prop('checked');
            break;
          case 'no-foreign-fee':
            noForeignFee = $('#' + id).prop('checked');
            break;
          case 'network-amex':
            networkAmex = $('#' + id).prop('checked');
            break;
          case 'network-discover':
            networkDiscover = $('#' + id).prop('checked');
            break;
          case 'network-visa-mastercard':
            networkVisaMastercard = $('#' + id).prop('checked');
            break;
          case 'financial-amex':
            financialAmex = $('#' + id).prop('checked');
            break;
          case 'financial-bank-of-america':
            financialBankOfAmerica = $('#' + id).prop('checked');
            break;
          case 'financial-barclaycard':
            financialBarclaycard = $('#' + id).prop('checked');
            break;
          case 'financial-capital-one':
            financialCapitalOne = $('#' + id).prop('checked');
            break;
          case 'financial-chase':
            financialChase = $('#' + id).prop('checked');
            break;
          case 'financial-citi':
            financialCiti = $('#' + id).prop('checked');
            break;
          case 'financial-discover':
            financialDiscover = $('#' + id).prop('checked');
            break;
          case 'financial-wells-fargo':
            financialWellsFargo = $('#' + id).prop('checked');
            break;
        }
        break;
    }
    updateView();
    loadCardsTable();
  }

  function loadCardsTable() {
    $('#page-header').empty();
    $('#cards-table').empty().data('sheetrockLoaded', false);

    var pageHeaderTemplateHtml =
      "
%%page_title%%
\

%%page_subtitle%%
";

    var cardTemplateHtml =
      "
\

\

\

%%card_name%%
	\
              \

\

\

Apply Now
\

View Details
\

\
              	\

\

Annual Fee: %%card_annual_fee%%
\
            Rewards rate: %%card_rewards_rate%%
\

%%card_details%%

\

\
              \

\
                  <input type='checkbox' id='compare-card-%%card_id%%' %%checked%% data-id='%%card_id%%'>\
                  Compare this card\

\
              	\

\

\

";

    $('#loading-message').show();
    var cardsHtml = '';
    sheetrock({
      url: sheetUrl,
      query: generateQuery(),
      reset: true,
      callback: function (error, options, response) {
        if (!error) {
          if (response.rows.length > 1) {  // Because it always returns the first row
            rowNumber = 0;
            response.rows.forEach(function (item) {
              if (rowNumber > 0) {
                cardsHtml += fillCardTable(cardTemplateHtml, item.cellsArray);
              }
              else {
                rowNumber = 1;
              }
            });
          }
          else {
            cardsHtml = '
No Results

We currently don\'t have an offer that matches that criteria.
';
          }
          $('#loading-message').hide();
          $('#page-header').html(fillPageData(pageHeaderTemplateHtml, pageData[category]));
          $('#cards-table').html(cardsHtml);
        }
      }
    });
  }

  function fillPageData(html, values) {
    html = html.replace('%%page_title%%', values[0]);
    html = html.replace('%%page_subtitle%%', values[1]);
    return html;
  }

  function fillCardTable(html, values) {
    html = html.replace(/%%card_id%%/g, values[0]);
    html = html.replace(/%%card_name%%/g, values[1]);
    html = html.replace(/%%card_rewards_rate%%/g, values[2]);
    html = html.replace(/%%card_annual_fee%%/g, values[3]);
    html = html.replace(/%%card_image_url%%/g, values[4]);
    html = html.replace(/%%card_apply_now_url%%/g, values[5]);
    if ($.inArray(parseInt(values[0]), cardsToCompare) != -1) {
      html = html.replace(/%%checked%%/g, 'checked');
    }
    else {
      html = html.replace(/%%checked%%/g, '');
    }
    return html;
  }

  function generateQuery() {
    whereCategory = '';
    switch (category) {
      case 'rewards':
        whereCategory = 'F = "Y" ';
        break;
      case 'cashback':
        whereCategory = 'G = "Y" ';
        break;
      case 'travel':
        whereCategory = 'H = "Y" ';
        break;
      case 'lowinterest':
        whereCategory = 'I = "Y" ';
        break;
      case 'student':
        whereCategory = 'J = "Y" ';
        break;
    }

    whereScore = 'P LIKE "%' + score + '%" ';

    noFee === true ? whereNoAnnualFee = 'AND K = "N" ' : whereNoAnnualFee = '';
    noBalanceTransferFee === true ? whereNoBalanceTransferFee = 'AND L = "N" ' : whereNoBalanceTransferFee = '';
    noForeignFee === true ? whereNoForeignFee = 'AND M = "N" ' : whereNoForeignFee = '';
    latinoFriendly === true ? whereLatinoFriendly = 'AND E = "Y" ' : whereLatinoFriendly = '';

    query = 'SELECT A, B, T, Q, X, Y ';
    query += 'WHERE ' + whereCategory + 'AND ' + whereScore;
    query += whereNoAnnualFee;
    query += whereNoBalanceTransferFee;
    query += whereNoForeignFee;
    query += whereLatinoFriendly;
    query += 'ORDER BY B';
    return query;
  }

  function updateCardsToCompare(id) {
    var cardId = $('#' + id).data('id');
    if ($('#' + id).prop('checked') && $.inArray(cardId, cardsToCompare) === -1) {
      cardsToCompare.push(cardId);
    }
    else {
      cardsToCompare.splice($.inArray(cardId, cardsToCompare), 1);
    }
    updateView();
  }

  function resetCardsToCompare() {
    cardsToCompare = [];
    $("input[id*='compare-card-']").prop('checked', false);
    updateView();
  }

  function compareCards() {
    if (cardsToCompare.length > 0) {
      window.location.href = '/credit-cards-compare/?cards=' + cardsToCompare.join('-');
    }
  }
});<commit_msg>[#142797345] Add support for new categories<commit_after>$(document).ready(function () {
  var sheetUrl = "https://docs.google.com/spreadsheets/d/14nDVwVvubdeUDVDRKxkq1P5hgaqUNk_k1ekHLKyqooY/edit#gid=0";

  var category = null;
  var score = null;

  var noFee = false;
  var noBalanceTransferFee = false;
  var noForeignFee = false;

  var networkAmex = false;
  var networkDiscover = false;
  var networkVisaMastercard = false;

  var financialAmex = false;
  var financialBankOfAmerica = false;
  var financialBarclaycard = false;
  var financialCapitalOne = false;
  var financialChase = false;
  var financialCiti = false;
  var financialDiscover = false;
  var financialWellsFargo = false;

  var latinoFriendly = false;

  var cardsToCompare = [];

  var pageData = {
    'rewards': [
      'Rewards Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ],
    'cashback': [
      'Cash Back Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ],
    'travel': [
      'Travel Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ],
    'lowinterest': [
      'Low Interest Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ],
    'student': [
      'Student Credit Cards',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    ]
  };

  loadData();
  updateView();
  loadCardsTable();

  $("a[id*='category-']").click(function () {
    updateSelection(this.id);
  });
  $("a[id*='score-']").click(function () {
    updateSelection(this.id);
  });
  $("input[id*='check-']").click(function () {
    updateSelection(this.id);
  });
  $('#btn-compare-cards').click(function () {
    compareCards();
  });
  $('#btn-reset-cards-to-compare').click(function () {
    resetCardsToCompare();
  });
  $('body').on('click', "input[id*='compare-card-']", function () {
    updateCardsToCompare(this.id);
  });
  $('body').on('click', "input[id*='label-compare-card-']", function () {
    updateCardsToCompare(this.id);
  });

  function updateView() {
    $("a[id*='category']").removeClass('active');
    $("a[id*='score']").removeClass('active');
    $("input[id*='check-']").prop('checked', false);

    $('#category-' + category).addClass('active');
    $('#score-' + score).addClass('active');

    $('#check-no-fee').prop('checked', noFee);
    $('#check-no-balance-transfer-fee').prop('checked', noBalanceTransferFee);
    $('#check-no-foreign-fee').prop('checked', noForeignFee);

    $('#check-network-amex').prop('checked', networkAmex);
    $('#check-network-discover').prop('checked', networkDiscover);
    $('#check-network-visa-mastercard').prop('checked', networkVisaMastercard);

    $('#check-financial-amex').prop('checked', financialAmex);
    $('#check-financial-bank-of-america').prop('checked', financialBankOfAmerica);
    $('#check-financial-barclaycard').prop('checked', financialBarclaycard);
    $('#check-financial-capital-one').prop('checked', financialCapitalOne);
    $('#check-financial-chase').prop('checked', financialChase);
    $('#check-financial-citi').prop('checked', financialCiti);
    $('#check-financial-discover').prop('checked', financialDiscover);
    $('#check-financial-wells-fargo').prop('checked', financialWellsFargo);

    $('#check-latino-friendly').prop('checked', latinoFriendly);

    if (cardsToCompare.length > 0) {
      cardsToCompare.length == 1 ? $('#btn-compare-cards').addClass('disabled') : $('#btn-compare-cards').removeClass('disabled');
      $('#badge-cards-to-compare-count').text(cardsToCompare.length);
      $("#footer-compare").slideDown("fast");
    }
    else { $("#footer-compare").slideUp("fast"); }
  }

  function loadData() {
    category = url('?category') != 'undefined' ? url('?category') : category = 'improve';
    score = url('?score') != 'undefined' ? url('?score') : score = 'excellent';
  }

  function updateSelection(id) {
    var type = id.split('-')[0];
    var value = id.substring(id.indexOf('-') + 1)

    switch (type) {
      case 'category':
        category = value;
        break;
      case 'score':
        score = value;
        break;
      case 'check':
        switch (value) {
          case 'latino-friendly':
            latinoFriendly = $('#' + id).prop('checked');
            break;
          case 'no-fee':
            noFee = $('#' + id).prop('checked');
            break;
          case 'no-balance-transfer-fee':
            noBalanceTransferFee = $('#' + id).prop('checked');
            break;
          case 'no-foreign-fee':
            noForeignFee = $('#' + id).prop('checked');
            break;
          case 'network-amex':
            networkAmex = $('#' + id).prop('checked');
            break;
          case 'network-discover':
            networkDiscover = $('#' + id).prop('checked');
            break;
          case 'network-visa-mastercard':
            networkVisaMastercard = $('#' + id).prop('checked');
            break;
          case 'financial-amex':
            financialAmex = $('#' + id).prop('checked');
            break;
          case 'financial-bank-of-america':
            financialBankOfAmerica = $('#' + id).prop('checked');
            break;
          case 'financial-barclaycard':
            financialBarclaycard = $('#' + id).prop('checked');
            break;
          case 'financial-capital-one':
            financialCapitalOne = $('#' + id).prop('checked');
            break;
          case 'financial-chase':
            financialChase = $('#' + id).prop('checked');
            break;
          case 'financial-citi':
            financialCiti = $('#' + id).prop('checked');
            break;
          case 'financial-discover':
            financialDiscover = $('#' + id).prop('checked');
            break;
          case 'financial-wells-fargo':
            financialWellsFargo = $('#' + id).prop('checked');
            break;
        }
        break;
    }
    updateView();
    loadCardsTable();
  }

  function loadCardsTable() {
    $('#page-header').empty();
    $('#cards-table').empty().data('sheetrockLoaded', false);

    var pageHeaderTemplateHtml =
      "
%%page_title%%
\

%%page_subtitle%%
";

    var cardTemplateHtml =
      "
\

\

\

%%card_name%%
	\
              \

\

\

Apply Now
\

View Details
\

\
              	\

\

Annual Fee: %%card_annual_fee%%
\
            Rewards rate: %%card_rewards_rate%%
\

%%card_details%%

\

\
              \

\
                  <input type='checkbox' id='compare-card-%%card_id%%' %%checked%% data-id='%%card_id%%'>\
                  Compare this card\

\
              	\

\

\

";

    $('#loading-message').show();
    var cardsHtml = '';
    sheetrock({
      url: sheetUrl,
      query: generateQuery(),
      reset: true,
      callback: function (error, options, response) {
        if (!error) {
          if (response.rows.length > 1) {  // Because it always returns the first row
            rowNumber = 0;
            response.rows.forEach(function (item) {
              if (rowNumber > 0) {
                cardsHtml += fillCardTable(cardTemplateHtml, item.cellsArray);
              }
              else {
                rowNumber = 1;
              }
            });
          }
          else {
            cardsHtml = '
No Results

We currently don\'t have an offer that matches that criteria.
';
          }
          $('#loading-message').hide();
          $('#page-header').html(fillPageData(pageHeaderTemplateHtml, pageData[category]));
          $('#cards-table').html(cardsHtml);
        }
      }
    });
  }

  function fillPageData(html, values) {
    html = html.replace('%%page_title%%', values[0]);
    html = html.replace('%%page_subtitle%%', values[1]);
    return html;
  }

  function fillCardTable(html, values) {
    html = html.replace(/%%card_id%%/g, values[0]);
    html = html.replace(/%%card_name%%/g, values[1]);
    html = html.replace(/%%card_rewards_rate%%/g, values[2]);
    html = html.replace(/%%card_annual_fee%%/g, values[3]);
    html = html.replace(/%%card_image_url%%/g, values[4]);
    html = html.replace(/%%card_apply_now_url%%/g, values[5]);
    if ($.inArray(parseInt(values[0]), cardsToCompare) != -1) {
      html = html.replace(/%%checked%%/g, 'checked');
    }
    else {
      html = html.replace(/%%checked%%/g, '');
    }
    return html;
  }

  function generateQuery() {
    var whereCategory = '';
    switch (category) {
      case 'rewards':
        whereCategory = 'F = "Y" ';
        break;
      case 'cashback':
        whereCategory = 'G = "Y" ';
        break;
      case 'travel':
        whereCategory = 'H = "Y" ';
        break;
      case 'lowinterest':
        whereCategory = 'I = "Y" ';
        break;
      case 'student':
        whereCategory = 'J = "Y" ';
        break;
    }

    var whereScore = 'P LIKE "%' + score + '%" ';

    var whereNoAnnualFee = '';
    var whereNoBalanceTransferFee = '';
    var whereNoForeignFee = '';
    noFee === true ? whereNoAnnualFee = 'AND K = "N" ' : whereNoAnnualFee = '';
    noBalanceTransferFee === true ? whereNoBalanceTransferFee = 'AND L = "N" ' : whereNoBalanceTransferFee = '';
    noForeignFee === true ? whereNoForeignFee = 'AND M = "N" ' : whereNoForeignFee = '';

    var whereNetwork = '';
    if (networkAmex || networkDiscover || networkVisaMastercard) {
      var used = false;
      whereNetwork = 'AND (';
      if (networkAmex) {
        whereNetwork += 'C = "American Express"';
        used = true;
      }
      if (networkDiscover) {
        if (used) whereNetwork += ' OR ';
        whereNetwork += 'C = "Discover"';
        used = true;
      }
      if (networkVisaMastercard) {
        if (used) whereNetwork += ' OR ';
        whereNetwork += 'C = "Visa/Mastercard"';
      }
      whereNetwork += ') ';
    }

    var whereFinancial = '';
    if (financialAmex || financialBankOfAmerica || financialBarclaycard || financialCapitalOne || financialChase || financialCiti || financialDiscover || financialWellsFargo) {
      var used = false;
      whereFinancial = 'AND (';
      if (financialAmex) {
        whereFinancial += 'D = "American Express"';
        used = true;
      }
      if (financialBankOfAmerica) {
        if (used) whereFinancial += ' OR ';
        whereFinancial += 'D = "Bank of America"';
        used = true;
      }
      if (financialBarclaycard) {
        if (used) whereFinancial += ' OR ';
        whereFinancial += 'D = "Barclaycard"';
        used = true;
      }
      if (financialCapitalOne) {
        if (used) whereFinancial += ' OR ';
        whereFinancial += 'D = "Capital One"';
        used = true;
      }
      if (financialChase) {
        if (used) whereFinancial += ' OR ';
        whereFinancial += 'D = "Chase"';
        used = true;
      }
      if (financialCiti) {
        if (used) whereFinancial += ' OR ';
        whereFinancial += 'D = "Citi"';
        used = true;
      }
      if (financialDiscover) {
        if (used) whereFinancial += ' OR ';
        whereFinancial += 'D = "Discover"';
        used = true;
      }
      if (financialWellsFargo) {
        if (used) whereFinancial += ' OR ';
        whereFinancial += 'D = "Wells Fargo"';
      }
      whereFinancial += ') ';
    }

    latinoFriendly === true ? whereLatinoFriendly = 'AND E = "Y" ' : whereLatinoFriendly = '';

    query = 'SELECT A, B, T, Q, X, Y ';
    query += 'WHERE ' + whereCategory + 'AND ' + whereScore;
    query += whereNoAnnualFee;
    query += whereNoBalanceTransferFee;
    query += whereNoForeignFee;
    query += whereNetwork;
    query += whereFinancial;
    query += whereLatinoFriendly;
    query += 'ORDER BY B';
    console.log(query);
    return query;
  }

  function updateCardsToCompare(id) {
    var cardId = $('#' + id).data('id');
    if ($('#' + id).prop('checked') && $.inArray(cardId, cardsToCompare) === -1) {
      cardsToCompare.push(cardId);
    }
    else {
      cardsToCompare.splice($.inArray(cardId, cardsToCompare), 1);
    }
    updateView();
  }

  function resetCardsToCompare() {
    cardsToCompare = [];
    $("input[id*='compare-card-']").prop('checked', false);
    updateView();
  }

  function compareCards() {
    if (cardsToCompare.length > 0) {
      window.location.href = '/credit-cards-compare/?cards=' + cardsToCompare.join('-');
    }
  }
});<|endoftext|>


<commit_before>// Try to gracefully parse as many decks as possible
// Parsing data is like the worst
function parseDecklist() {
	deckmain = $("#deckmain").val()
	deckside = $("#deckside").val()

	// Let's store the lists in a tidy little array
	maindeck = [];
	sideboard = [];

	// And let's store their counts for future reference
	maindeck_count = 0;
	sideboard_count = 0;

	// Track unrecognized cards
	unrecognized = [];

	// Track lines that could not be parsed. (encoded to prevent XSS)
	unparseable = [];

	// Stop processing the function if there's no main deck
	if (deckmain == "") { return(null, null); }

	// Split main deck and sideboard by newlines
	deckmain = deckmain.split('\n');
	deckside = deckside.split('\n');

	mtgo_re = /^(\d+)x*\s(.+)/;             // MTGO deck format (4 Brainstorm) also TCG (4x Brainstorm)
	mtgosb_re = /^SB:\s+(\d+)\s(.+)/;       // Sideboard lines begin with SB:
	mws_re = /^\s*(\d+)\s+\[.*\]\s+(.+)/;       // MWS, what an ugly format
	mwssb_re = /^SB:\s*(\d+)\s+\[.*\]\s(.+)/;  // MWS, what an ugly format
	tosb_re = /^Sideboard/;                 // Tappedout looks like MTGO, except sideboard begins with Sideboard:  Salvation, same, but no colon

	// Loop through all the cards in the main deck field
	in_sb = false;
	for (i = 0; i < deckmain.length; i++) {

		// Parse for Magic Workstation style deck
		if (mws_re.exec(deckmain[i]) != null) {
			quantity = mws_re.exec(deckmain[i])[1];
			card = mws_re.exec(deckmain[i])[2];

			list_add("main", card, quantity);
		}

		// Parse for Magic Workstation sideboards
		else if (mwssb_re.exec(deckmain[i]) != null) {
			quantity = mwssb_re.exec(deckmain[i])[1];
			card = mwssb_re.exec(deckmain[i])[2];

			list_add("side", card, quantity);
		}

		// Parse for MTGO/TappedOut style decks
		else if (mtgo_re.exec(deckmain[i]) != null) {
			quantity = mtgo_re.exec(deckmain[i])[1];
			card = mtgo_re.exec(deckmain[i])[2];

			if (in_sb) {	// TappedOut style Sideboard listing
				list_add("side", card, quantity);
			} else {
				list_add("main", card, quantity);
			}
		}

		// Parse for MTGO style sideboard cards
		else if (mtgosb_re.exec(deckmain[i]) != null) {
			quantity = mtgosb_re.exec(deckmain[i])[1];
			card = mtgosb_re.exec(deckmain[i])[2];

			list_add("side", card, quantity);
		}

		// If we see "Sideboard:", then we're in the TappedOut style sideboard entries from now on
		else if (tosb_re.test(deckmain[i])) { in_sb = true; }

		// Could not be parsed, store in appropriate array
		else {
			// only store if it's not a falsey value (empty string, etc.)
			// or entirely composed of whitespace
			if (htmlEncode(deckmain[i]) && !htmlEncode(deckmain[i]).match(/^\s+$/)) {
				unparseable.push(htmlEncode(deckmain[i]));
			}
		}
	}

	// Now we get to do the same for the sideboard, but we only have to worry about TCG/MTGO style entries
	for (i = 0; i < deckside.length; i++) {
		// Parse for MTGO/TappedOut style decks
		if (mtgo_re.exec(deckside[i]) != null) {
			quantity = mtgo_re.exec(deckside[i])[1];
			card = mtgo_re.exec(deckside[i])[2];

			list_add("side", card, quantity);
		}
	}

	// Now we need to sort the deck lists, with the sideboard always being sorted alphabetically
	if ( $("#sortorderfloat input[name=sortorder]:checked").prop("id") == "sortorder1" ) { // alpabetical
		maindeck = sortDecklist(maindeck, 'alphabetically');
		sideboard = sortDecklist(sideboard, 'alphabetically');
	}
	else if ( $("#sortorderfloat input[name=sortorder]:checked").prop("id") == "sortorder2" ) { // CMC
		maindeck = sortDecklist(maindeck, 'cmc');
		sideboard = sortDecklist(sideboard, 'alphabetically');
	}
	else if ( $("#sortorderfloat input[name=sortorder]:checked").prop("id") == "sortorder3" ) { // color
		maindeck = sortDecklist(maindeck, 'color');
		sideboard = sortDecklist(sideboard, 'alphabetically');
	}
	else if ( $("#sortorderfloat input[name=sortorder]:checked").prop("id") == "sortorder4" ) { // numeric
		maindeck = sortDecklist(maindeck, 'numerically');
		sideboard = sortDecklist(sideboard, 'alphabetically');
	}
}

function sortDecklist(deck, sortorder) {

	// Sort the decklist alphabetically, if chosen
	if ( sortorder == 'alphabetically' ) {

		// Add a case insensitive field to sort by
		for (i = 0; i < deck.length; i++) { deck[i] = [ deck[i][0].toLowerCase(), deck[i][0], deck[i][1] ]; }

		deck.sort();

		// After sorting is done, we can remove the lower case index
		for (i = 0; i < deck.length; i++) { deck[i] = deck[i].splice(1, 2); }
	}

	// Sort the decklist by color, if chosen
	// White = A, Blue = B, Black = C, Red = D, Green = E, Gold = F, Artifact = G , Unknown = X, Land = Z
	else if ( sortorder == 'color' ) {
		var color_to_cards = {}

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

			// We're going to search by lower case
			var lcard = deck[i][0].toLowerCase();

			// Grab the card's color
			if (lcard in cards) { color = cards[ lcard ]['c']; }
			else { color = "X"; } // Unknown

			// Create the color subarray
			if ( !(color in color_to_cards ) ) { color_to_cards[color] = []; }

			// Fix the Aetherling issue until the PDF things supports it
			lcard = lcard.replace("\u00c6", "Ae").replace("\u00e6", "ae");
			deck[i][0] = deck[i][0].replace("\u00c6", "Ae").replace("\u00e6", "ae");

			// Add the card to that array, including lower-case (only used for sorting)
			color_to_cards[color].push( [ lcard, deck[i][0], deck[i][1] ] );

		}

		// Get the list of colors in the deck
		color_to_cards_keys = Object.keys(color_to_cards).sort();

		// Sort each subcolor, then append them to the final array
		deck = []
		for (i = 0; i < color_to_cards_keys.length; i++) {
			color = color_to_cards_keys[i];

			color_to_cards[ color ].sort();   // color_to_cards['A']

			for (j = 0; j < color_to_cards[color].length; j++) {
				card = color_to_cards[color][j][1];
				quantity = color_to_cards[color][j][2];

				deck.push([card, quantity]);
			}

			// Push a blank entry onto deck (to separate colors)
			deck.push(['', 0]);

		}

		// We must clear out the 32nd entry, if it's blank, as it's at the top of the 2nd row
		if (deck.length > 31) {
			if (deck[32][1] == 0) {
				deck.splice(32, 1);
			}
		}
	}

	// Sort the decklist by CMC, if chosen
	else if ( sortorder == 'cmc' ) {
		var cmc_to_cards = {}

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

			// We're going to search by lower case
			var lcard = deck[i][0].toLowerCase();

			// Grab the card's cmc
			if (lcard in cards) { cmc = cards[ lcard ]['m']; }
			else { cmc = 100; } // Unknown

			// Convert the CMC to a string, and pad zeroes (grr Javascript)
			cmc = cmc.toString();
			if ( cmc.length == 1 ) { cmc = "00" + cmc; }
			if ( cmc.length == 2 ) { cmc = "0" + cmc; }

			// Create the cmc subarray
			if ( !(cmc in cmc_to_cards ) ) { cmc_to_cards[cmc] = []; }

			// Fix the Aetherling issue until the PDF things supports it
			lcard = lcard.replace("\u00c6", "Ae").replace("\u00e6", "ae");
			deck[i][0] = deck[i][0].replace("\u00c6", "Ae").replace("\u00e6", "ae");

			// Add the card to that array, including lower-case (only used for sorting)
			cmc_to_cards[cmc].push( [ lcard, deck[i][0], deck[i][1] ] );

		}

		// Get the list of CMCs in the deck
		cmc_to_cards_keys = Object.keys(cmc_to_cards).sort();

		// Sort each CMC, then append them to the final array
		deck = []
		for (i = 0; i < cmc_to_cards_keys.length; i++) {
			cmc = cmc_to_cards_keys[i];

			cmc_to_cards[ cmc ].sort();   // cmc_to_cards[3]

			for (j = 0; j < cmc_to_cards[cmc].length; j++) {
				card = cmc_to_cards[cmc][j][1];
				quantity = cmc_to_cards[cmc][j][2];

				deck.push([card, quantity]);
			}

			// Push a blank entry onto deck (to separate CMCs)
			deck.push(['', 0]);

		}

		// We must clear out the 32nd entry, if it's blank, as it's at the top of the 2nd row
		if (deck.length > 31) {
			if (deck[32][1] == 0) {
				deck.splice(32, 1);
			}
		}
	}

	// Sort the decklist numerically, if chosen
	else if ( sortorder == 'numerically' ) {

		// Add a case insensitive field, swap order around
		for (i = 0; i < deck.length; i++) {
			deck[i] = [ deck[i][1], deck[i][0].toLowerCase(), deck[i][0] ]
		}

		deck.sort();

		// After sorting is done, we can remove the lower case index
		for (i = 0; i < deck.length; i++) { deck[i] = [ deck[i][2], deck[i][0] ] }
	}

	// Return the deck
	return(deck);

}

// Stub to simplify updating deck and sideboard counts
function list_add(type, card, quantity) {
	if (type === "main") {
		maindeck.push([card, quantity]);
		maindeck_count += parseInt(quantity);
	} else if (type === "side") {
		sideboard.push([card, quantity]);
		sideboard_count += parseInt(quantity);
	}
}

function htmlEncode(string) {
	return string.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
}
<commit_msg>less redundant comments<commit_after>// Try to gracefully parse as many decks as possible
// Parsing data is like the worst
function parseDecklist() {
	deckmain = $("#deckmain").val()
	deckside = $("#deckside").val()

	// Let's store the lists in a tidy little array
	maindeck = [];
	sideboard = [];

	// And let's store their counts for future reference
	maindeck_count = 0;
	sideboard_count = 0;

	// Track unrecognized cards and lines that can't be parsed.
	// (encoded to prevent XSS)
	unrecognized = [];
	unparseable = [];

	// Stop processing the function if there's no main deck
	if (deckmain == "") { return(null, null); }

	// Split main deck and sideboard by newlines
	deckmain = deckmain.split('\n');
	deckside = deckside.split('\n');

	mtgo_re = /^(\d+)x*\s(.+)/;             // MTGO deck format (4 Brainstorm) also TCG (4x Brainstorm)
	mtgosb_re = /^SB:\s+(\d+)\s(.+)/;       // Sideboard lines begin with SB:
	mws_re = /^\s*(\d+)\s+\[.*\]\s+(.+)/;       // MWS, what an ugly format
	mwssb_re = /^SB:\s*(\d+)\s+\[.*\]\s(.+)/;  // MWS, what an ugly format
	tosb_re = /^Sideboard/;                 // Tappedout looks like MTGO, except sideboard begins with Sideboard:  Salvation, same, but no colon

	// Loop through all the cards in the main deck field
	in_sb = false;
	for (i = 0; i < deckmain.length; i++) {

		// Parse for Magic Workstation style deck
		if (mws_re.exec(deckmain[i]) != null) {
			quantity = mws_re.exec(deckmain[i])[1];
			card = mws_re.exec(deckmain[i])[2];

			list_add("main", card, quantity);
		}

		// Parse for Magic Workstation sideboards
		else if (mwssb_re.exec(deckmain[i]) != null) {
			quantity = mwssb_re.exec(deckmain[i])[1];
			card = mwssb_re.exec(deckmain[i])[2];

			list_add("side", card, quantity);
		}

		// Parse for MTGO/TappedOut style decks
		else if (mtgo_re.exec(deckmain[i]) != null) {
			quantity = mtgo_re.exec(deckmain[i])[1];
			card = mtgo_re.exec(deckmain[i])[2];

			if (in_sb) {	// TappedOut style Sideboard listing
				list_add("side", card, quantity);
			} else {
				list_add("main", card, quantity);
			}
		}

		// Parse for MTGO style sideboard cards
		else if (mtgosb_re.exec(deckmain[i]) != null) {
			quantity = mtgosb_re.exec(deckmain[i])[1];
			card = mtgosb_re.exec(deckmain[i])[2];

			list_add("side", card, quantity);
		}

		// If we see "Sideboard:", then we're in the TappedOut style sideboard entries from now on
		else if (tosb_re.test(deckmain[i])) { in_sb = true; }

		// Could not be parsed, store in appropriate array
		else {
			// only store if it's not a falsey value (empty string, etc.)
			// or entirely composed of whitespace
			if (htmlEncode(deckmain[i]) && !htmlEncode(deckmain[i]).match(/^\s+$/)) {
				unparseable.push(htmlEncode(deckmain[i]));
			}
		}
	}

	// Now we get to do the same for the sideboard, but we only have to worry about TCG/MTGO style entries
	for (i = 0; i < deckside.length; i++) {
		// Parse for MTGO/TappedOut style decks
		if (mtgo_re.exec(deckside[i]) != null) {
			quantity = mtgo_re.exec(deckside[i])[1];
			card = mtgo_re.exec(deckside[i])[2];

			list_add("side", card, quantity);
		}
	}

	// Now we need to sort the deck lists, with the sideboard always being sorted alphabetically
	if ( $("#sortorderfloat input[name=sortorder]:checked").prop("id") == "sortorder1" ) { // alpabetical
		maindeck = sortDecklist(maindeck, 'alphabetically');
		sideboard = sortDecklist(sideboard, 'alphabetically');
	}
	else if ( $("#sortorderfloat input[name=sortorder]:checked").prop("id") == "sortorder2" ) { // CMC
		maindeck = sortDecklist(maindeck, 'cmc');
		sideboard = sortDecklist(sideboard, 'alphabetically');
	}
	else if ( $("#sortorderfloat input[name=sortorder]:checked").prop("id") == "sortorder3" ) { // color
		maindeck = sortDecklist(maindeck, 'color');
		sideboard = sortDecklist(sideboard, 'alphabetically');
	}
	else if ( $("#sortorderfloat input[name=sortorder]:checked").prop("id") == "sortorder4" ) { // numeric
		maindeck = sortDecklist(maindeck, 'numerically');
		sideboard = sortDecklist(sideboard, 'alphabetically');
	}
}

function sortDecklist(deck, sortorder) {

	// Sort the decklist alphabetically, if chosen
	if ( sortorder == 'alphabetically' ) {

		// Add a case insensitive field to sort by
		for (i = 0; i < deck.length; i++) { deck[i] = [ deck[i][0].toLowerCase(), deck[i][0], deck[i][1] ]; }

		deck.sort();

		// After sorting is done, we can remove the lower case index
		for (i = 0; i < deck.length; i++) { deck[i] = deck[i].splice(1, 2); }
	}

	// Sort the decklist by color, if chosen
	// White = A, Blue = B, Black = C, Red = D, Green = E, Gold = F, Artifact = G , Unknown = X, Land = Z
	else if ( sortorder == 'color' ) {
		var color_to_cards = {}

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

			// We're going to search by lower case
			var lcard = deck[i][0].toLowerCase();

			// Grab the card's color
			if (lcard in cards) { color = cards[ lcard ]['c']; }
			else { color = "X"; } // Unknown

			// Create the color subarray
			if ( !(color in color_to_cards ) ) { color_to_cards[color] = []; }

			// Fix the Aetherling issue until the PDF things supports it
			lcard = lcard.replace("\u00c6", "Ae").replace("\u00e6", "ae");
			deck[i][0] = deck[i][0].replace("\u00c6", "Ae").replace("\u00e6", "ae");

			// Add the card to that array, including lower-case (only used for sorting)
			color_to_cards[color].push( [ lcard, deck[i][0], deck[i][1] ] );

		}

		// Get the list of colors in the deck
		color_to_cards_keys = Object.keys(color_to_cards).sort();

		// Sort each subcolor, then append them to the final array
		deck = []
		for (i = 0; i < color_to_cards_keys.length; i++) {
			color = color_to_cards_keys[i];

			color_to_cards[ color ].sort();   // color_to_cards['A']

			for (j = 0; j < color_to_cards[color].length; j++) {
				card = color_to_cards[color][j][1];
				quantity = color_to_cards[color][j][2];

				deck.push([card, quantity]);
			}

			// Push a blank entry onto deck (to separate colors)
			deck.push(['', 0]);

		}

		// We must clear out the 32nd entry, if it's blank, as it's at the top of the 2nd row
		if (deck.length > 31) {
			if (deck[32][1] == 0) {
				deck.splice(32, 1);
			}
		}
	}

	// Sort the decklist by CMC, if chosen
	else if ( sortorder == 'cmc' ) {
		var cmc_to_cards = {}

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

			// We're going to search by lower case
			var lcard = deck[i][0].toLowerCase();

			// Grab the card's cmc
			if (lcard in cards) { cmc = cards[ lcard ]['m']; }
			else { cmc = 100; } // Unknown

			// Convert the CMC to a string, and pad zeroes (grr Javascript)
			cmc = cmc.toString();
			if ( cmc.length == 1 ) { cmc = "00" + cmc; }
			if ( cmc.length == 2 ) { cmc = "0" + cmc; }

			// Create the cmc subarray
			if ( !(cmc in cmc_to_cards ) ) { cmc_to_cards[cmc] = []; }

			// Fix the Aetherling issue until the PDF things supports it
			lcard = lcard.replace("\u00c6", "Ae").replace("\u00e6", "ae");
			deck[i][0] = deck[i][0].replace("\u00c6", "Ae").replace("\u00e6", "ae");

			// Add the card to that array, including lower-case (only used for sorting)
			cmc_to_cards[cmc].push( [ lcard, deck[i][0], deck[i][1] ] );

		}

		// Get the list of CMCs in the deck
		cmc_to_cards_keys = Object.keys(cmc_to_cards).sort();

		// Sort each CMC, then append them to the final array
		deck = []
		for (i = 0; i < cmc_to_cards_keys.length; i++) {
			cmc = cmc_to_cards_keys[i];

			cmc_to_cards[ cmc ].sort();   // cmc_to_cards[3]

			for (j = 0; j < cmc_to_cards[cmc].length; j++) {
				card = cmc_to_cards[cmc][j][1];
				quantity = cmc_to_cards[cmc][j][2];

				deck.push([card, quantity]);
			}

			// Push a blank entry onto deck (to separate CMCs)
			deck.push(['', 0]);

		}

		// We must clear out the 32nd entry, if it's blank, as it's at the top of the 2nd row
		if (deck.length > 31) {
			if (deck[32][1] == 0) {
				deck.splice(32, 1);
			}
		}
	}

	// Sort the decklist numerically, if chosen
	else if ( sortorder == 'numerically' ) {

		// Add a case insensitive field, swap order around
		for (i = 0; i < deck.length; i++) {
			deck[i] = [ deck[i][1], deck[i][0].toLowerCase(), deck[i][0] ]
		}

		deck.sort();

		// After sorting is done, we can remove the lower case index
		for (i = 0; i < deck.length; i++) { deck[i] = [ deck[i][2], deck[i][0] ] }
	}

	// Return the deck
	return(deck);

}

// Stub to simplify updating deck and sideboard counts
function list_add(type, card, quantity) {
	if (type === "main") {
		maindeck.push([card, quantity]);
		maindeck_count += parseInt(quantity);
	} else if (type === "side") {
		sideboard.push([card, quantity]);
		sideboard_count += parseInt(quantity);
	}
}

function htmlEncode(string) {
	return string.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(/</g, '<').replace(/>/g, '>');
}
<|endoftext|>


<commit_before>var Vis = require('vis');
var fs = require('fs');

var network;
var inc = 0;

$(document).ready(function () {
    $('#submit-btn').click(function () {
        if (network.body.data.nodes.get().length == 0) {
            createAlert("You have not added any nodes to the graph.");
            return;
        }
        if (network.body.data.edges.get().length == 0) {
            createAlert("You have not added any edges to the graph.");
            return;
        }
        var rootNode = findRootNode(network.body.data.nodes.get());
        if (!rootNode) {
            var nodes = network.body.data.nodes.get();
            rootNode = nodes[0];
            rootNode.root = true;
            network = rebuildNetwork(network, container, options, nodes);
            $("#algo-panel").prepend(alertUserThatNoRoot());
        }
        dijkstraAnimation(network.body.data.nodes.get());
    });
    $('#random-btn').click(function () {
        var numberOfNodes = Math.floor((Math.random() * 30) + 10);
        if (network !== null) {
            network.destroy();
            network = null;
        }
        var data = getFreeScaleNetworkWithWeights(numberOfNodes);
        network = new Vis.Network(container, data, options);
    });
});

// create a network
var container = $('#tree-simple')[0];

var options = {
    autoResize: true,
    manipulation: {
        initiallyActive: true,
        addNode: function (nodeData, callback) {
            if (network.body.nodes === {}) {
                inc = 1;
            }
            else {
                inc++;
            }
            nodeData.root = false;
            nodeData.label = inc;
            nodeData.color = '#009688';
            nodeData.font = {
                color: '#fff'
            };
            nodeData.visited = false;
            nodeData.adjacencyList = [];
            nodeData.predecessor = null;
            callback(nodeData);
        },
        editNode: function (nodeData, callback) {
            editNodeCustom(network, nodeData, callback);
        },
        addEdge: function (data, callback) {
            if ($('#directed-chechbox').prop('checked')){
                data.arrows = {};
                data.arrows.to = true;
            }
            if (data.from === data.to) {
                var r = confirm('Do you want to connect the node to itself?');
                if (r === true) {
                    callback(null);
                    return;
                }
            }
            editEdgeCustom(network, data, callback);
        },
        editEdge: {
            editWithoutDrag: function (data, callback) {
                editEdgeCustom(network, data, callback);
            }
        }
    },
    interaction: {
        navigationButtons: true
    },
    physics: {
        enabled: false
    }
};

network = new Vis.Network(container, [], options);

function dijkstraAnimation(nodes) {
    var nodeRoot = findRootNode(nodes);
    var S = [nodeRoot];
    var distances = [];
    var nodesArrayLength = nodes.length;
    highlightCodeLine(0);

    for (var i = 0; i < nodesArrayLength; i++) {
        (function (ind) {
            setTimeout(function() {
                unHighlightAllCodeLines();
                highlightCodeLine(1);
                if (nodes[ind] == nodeRoot) {
                    distances[nodes[ind].label] = 0;
                }
                else if (containsObject(nodes[ind], nodeRoot.adjacencyList)) {
                    distances[nodes[ind].label] = getEdgeWeight(nodeRoot, nodes[ind]);
                }
                else {
                    distances[nodes[ind].label] = Number.POSITIVE_INFINITY;
                }
                appendRowToTable(nodes[ind].label);
                setupDistance(nodes[ind].label, distances[nodes[ind].label]);
                if (ind > 0) {
                    nodes[ind-1].color = "#009688";
                    unHighlightTableRow(nodes[ind-1].label);
                }
                nodes[ind].color = "red";
                highlightTableRow(nodes[ind].label);
                network = rebuildNetwork(network, container, options, nodes);
            }, 2000 + 3000 * ind);
        })(i);
    }

    for (var z = 0; z < nodesArrayLength; z++) {
        (function (ind1) {
            setTimeout(function () {
                var minNode = findMinimumDistanceNode(nodes, S, distances);
                S.push(minNode);
                for (var j = 0; j < nodesArrayLength; j++) {
                    (function (ind2) {
                        setTimeout(function () {
                            if (!containsObject(nodes[j], S)) {
                                if (containsObject(nodes[j], minNode.adjacencyList)) {
                                    distances[nodes[j].label] =
                                        Math.min(distances[nodes[j].label], (distances[minNode.label] + getEdgeWeight(minNode, nodes[j])));
                                }
                            }
                        }, 3000);
                    })(j);
                }
            }, 2000 + 3000 * nodesArrayLength + 6000 * ind1);
        })(z);
    }
}

function findMinimumDistanceNode (nodes, S, distances) {
    var min = Number.MAX_VALUE;
    var minNode = null;
    var len = nodes.length;
    for (var i = 0; i < len; i++) {
        if (!containsObject(nodes[i], S)) {
            if (distances[nodes[i].label] < min) {
                min = distances[nodes[i].label];
                minNode = nodes[i];
            }
        }
    }
    return minNode;
}

function appendRowToTable(label) {
    var tr;
    tr = '
d(' + label + ')
';
    $('#distances-table').append(tr);
}

function setupDistance(index, distance) {
    if (distance === Number.POSITIVE_INFINITY) {
        $("#distance-" + index).append(" ∞ 	");
    }
    else {
        $("#distance-" + index).append("" +  distance + "	");
    }
}

function changeDistance(index, distance) {
    $("#distance-" + index).find("td:last").html(distance);
}

function highlightTableRow(index) {
    $("#distance-" + index).addClass("success");
}

function unHighlightTableRow(index) {
    $("#distance-" + index).removeClass("success");
}

function highlightTableCell(index) {
    $("#distance-" + index).find("td:last").addClass("success");
}

function unHighlightTableCell(index) {
    $("#distance-" + index).find("td:last").removeClass("success");
}

function containsObject(obj, list) {
    var i;
    for (i = 0; i < list.length; i++) {
        if (list[i].id == obj.id) {
            return true;
        }
    }
    return false;
}

function getEdgeWeight(nodeOne, nodeTwo) {
    var edgeBetweenNodes = network.body.data.edges.get().filter(function(x) {
        return (x.from === nodeOne.id && x.to === nodeTwo.id);
    });
    return parseInt(edgeBetweenNodes[0].label);
}
<commit_msg>solved errors regarding indexing in inner setTimeout<commit_after>var Vis = require('vis');
var fs = require('fs');

var network;
var inc = 0;

$(document).ready(function () {
    $('#submit-btn').click(function () {
        if (network.body.data.nodes.get().length == 0) {
            createAlert("You have not added any nodes to the graph.");
            return;
        }
        if (network.body.data.edges.get().length == 0) {
            createAlert("You have not added any edges to the graph.");
            return;
        }
        var rootNode = findRootNode(network.body.data.nodes.get());
        if (!rootNode) {
            var nodes = network.body.data.nodes.get();
            rootNode = nodes[0];
            rootNode.root = true;
            network = rebuildNetwork(network, container, options, nodes);
            $("#algo-panel").prepend(alertUserThatNoRoot());
        }
        dijkstraAnimation(network.body.data.nodes.get());
    });
    $('#random-btn').click(function () {
        var numberOfNodes = Math.floor((Math.random() * 30) + 10);
        if (network !== null) {
            network.destroy();
            network = null;
        }
        var data = getFreeScaleNetworkWithWeights(numberOfNodes);
        network = new Vis.Network(container, data, options);
    });
});

// create a network
var container = $('#tree-simple')[0];

var options = {
    autoResize: true,
    manipulation: {
        initiallyActive: true,
        addNode: function (nodeData, callback) {
            if (network.body.nodes === {}) {
                inc = 1;
            }
            else {
                inc++;
            }
            nodeData.root = false;
            nodeData.label = inc;
            nodeData.color = '#009688';
            nodeData.font = {
                color: '#fff'
            };
            nodeData.visited = false;
            nodeData.adjacencyList = [];
            nodeData.predecessor = null;
            callback(nodeData);
        },
        editNode: function (nodeData, callback) {
            editNodeCustom(network, nodeData, callback);
        },
        addEdge: function (data, callback) {
            if ($('#directed-chechbox').prop('checked')){
                data.arrows = {};
                data.arrows.to = true;
            }
            if (data.from === data.to) {
                var r = confirm('Do you want to connect the node to itself?');
                if (r === true) {
                    callback(null);
                    return;
                }
            }
            editEdgeCustom(network, data, callback);
        },
        editEdge: {
            editWithoutDrag: function (data, callback) {
                editEdgeCustom(network, data, callback);
            }
        }
    },
    interaction: {
        navigationButtons: true
    },
    physics: {
        enabled: false
    }
};

network = new Vis.Network(container, [], options);

function dijkstraAnimation(nodes) {
    var nodeRoot = findRootNode(nodes);
    var S = [nodeRoot];
    var distances = [];
    var nodesArrayLength = nodes.length;
    highlightCodeLine(0);

    for (var i = 0; i < nodesArrayLength; i++) {
        (function (ind) {
            setTimeout(function() {
                unHighlightAllCodeLines();
                highlightCodeLine(1);
                if (nodes[ind] == nodeRoot) {
                    distances[nodes[ind].label] = 0;
                }
                else if (containsObject(nodes[ind], nodeRoot.adjacencyList)) {
                    distances[nodes[ind].label] = getEdgeWeight(nodeRoot, nodes[ind]);
                }
                else {
                    distances[nodes[ind].label] = Number.POSITIVE_INFINITY;
                }
                appendRowToTable(nodes[ind].label);
                setupDistance(nodes[ind].label, distances[nodes[ind].label]);
                if (ind > 0) {
                    nodes[ind-1].color = "#009688";
                    unHighlightTableRow(nodes[ind-1].label);
                }
                nodes[ind].color = "red";
                highlightTableRow(nodes[ind].label);
                network = rebuildNetwork(network, container, options, nodes);
            }, 2000 + 3000 * ind);
        })(i);
    }

    for (var z = 0; z < nodesArrayLength; z++) {
        (function (ind1) {
            setTimeout(function () {
                var minNode = findMinimumDistanceNode(nodes, S, distances);
                S.push(minNode);
                for (var j = 0; j < nodesArrayLength; j++) {
                    (function (ind2) {
                        setTimeout(function () {
                            if (!containsObject(nodes[ind2], S)) {
                                if (containsObject(nodes[ind2], minNode.adjacencyList)) {
                                    distances[nodes[ind2].label] =
                                        Math.min(distances[nodes[ind2].label], (distances[minNode.label] + getEdgeWeight(minNode, nodes[ind2])));
                                }
                            }
                        }, ind2 * 6000 / nodesArrayLength);
                    })(j);
                }
            }, 2000 + 3000 * nodesArrayLength + 6000 * ind1);
        })(z);
    }
}

function findMinimumDistanceNode (nodes, S, distances) {
    var min = Number.MAX_VALUE;
    var minNode = null;
    var len = nodes.length;
    for (var i = 0; i < len; i++) {
        if (!containsObject(nodes[i], S)) {
            if (distances[nodes[i].label] < min) {
                min = distances[nodes[i].label];
                minNode = nodes[i];
            }
        }
    }
    return minNode;
}

function appendRowToTable(label) {
    var tr;
    tr = '
d(' + label + ')
';
    $('#distances-table').append(tr);
}

function setupDistance(index, distance) {
    if (distance === Number.POSITIVE_INFINITY) {
        $("#distance-" + index).append(" ∞ 	");
    }
    else {
        $("#distance-" + index).append("" +  distance + "	");
    }
}

function changeDistance(index, distance) {
    $("#distance-" + index).find("td:last").html(distance);
}

function highlightTableRow(index) {
    $("#distance-" + index).addClass("success");
}

function unHighlightTableRow(index) {
    $("#distance-" + index).removeClass("success");
}

function highlightTableCell(index) {
    $("#distance-" + index).find("td:last").addClass("success");
}

function unHighlightTableCell(index) {
    $("#distance-" + index).find("td:last").removeClass("success");
}

function containsObject(obj, list) {
    var i;
    for (i = 0; i < list.length; i++) {
        if (list[i].id == obj.id) {
            return true;
        }
    }
    return false;
}

function getEdgeWeight(nodeOne, nodeTwo) {
    var edgeBetweenNodes = network.body.data.edges.get().filter(function(x) {
        return (x.from === nodeOne.id && x.to === nodeTwo.id);
    });
    return parseInt(edgeBetweenNodes[0].label);
}
<|endoftext|>


<commit_before>//= require "../chrome/storage"

// shortcut method
var push = Array.prototype.push;

var Libraries = function () {
  this.init();

  this.userSpecified = JSON.parse(localStorage.getItem('libraries') || "[]");

  // read from storage
  for (var i = 0; i < this.userSpecified.length; i++) {
    push.call(this, this.userSpecified[i]);
  }
};

Libraries.prototype.init = function () {
  var libs = {
    yui: {
      text: 'YUI',
      scripts: [
        { text: 'YUI 3.3.0', url: 'http://yui.yahooapis.com/3.3.0/build/yui/yui-min.js'},
        { text: 'YUI 2.8.2', url: 'http://ajax.googleapis.com/ajax/libs/yui/2.8.2/build/yuiloader/yuiloader-min.js'}
      ]
    },
    mootools: {
      text: 'MooTools',
      scripts: [
        { text: 'Mootools 1.3.2', url: 'http://ajax.googleapis.com/ajax/libs/mootools/1.3.2/mootools-yui-compressed.js'},
        { text: 'Mootools 1.2.4', url: 'http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools-yui-compressed.js' }
      ]
    },
    prototype: {
      text: 'Prototype',
      scripts: [
        { text: 'Prototype latest', url: 'http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js' },
        { text: 'Prototype 1.7.0.0', url: 'http://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js'},
        { text: 'Prototype 1.6.1.0', url: 'http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js' },
        { text: 'script.aculo.us 1.8.3', url: 'http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js', requires: 'http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js' }
      ]
    },
    jquery: {
      text: 'jQuery',
      scripts: [
        { text: 'jQuery latest', url: 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' },
        { text: 'jQuery WIP (via git)', url: 'http://code.jquery.com/jquery-git.js' },
        { text: 'jQuery 1.6.4', url: 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js' },
        { text: 'jQuery 1.5.2', url: 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js' }
      ]
    },
    jqueryui : {
      text: 'jQuery UI',
      requires: 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js',
      style: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css',
      scripts: [
        { text: 'jQuery UI 1.8.13', url: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js' }
      ]
    },
    jquerymobile : {
      text: 'jQuery Mobile',
      requires: 'http://code.jquery.com/jquery-1.6.4.min.js',
      style: 'http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css',
      scripts: [
        { text: 'jQuery Mobile 1.0b3', url: 'http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.js' },
        { text: 'jQuery Mobile 1.0a4.1', url: 'http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js' }
      ]
    },
    others: {
      text: 'Others',
      scripts: [
        { text: 'Backbone 0.5.3', url: 'http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js' },
        { text: 'CoffeeScript', url: 'http://jashkenas.github.com/coffee-script/extras/coffee-script.js' },
        { text: 'ES5 shim 1.2.4', url: 'http://cdnjs.cloudflare.com/ajax/libs/es5-shim/1.2.4/es5-shim.min.js' },
        { text: 'ext-core 3.1.0', url: 'http://cdnjs.cloudflare.com/ajax/libs/ext-core/3.1.0/ext-core.js', style: 'http://extjs.cachefly.net/ext-3.1.0/resources/css/ext-all.css' },
        { text: 'Less 1.1.3', url: 'http://cdnjs.cloudflare.com/ajax/libs/less.js/1.1.3/less-1.1.3.min.js' },
        { text: 'Modernizr 2.0.6', url: 'http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.0.6/modernizr.min.js' },
        { text: 'Processing 1.2.3', url: 'http://cdnjs.cloudflare.com/ajax/libs/processing.js/1.2.3/processing-api.min.js' },
        { text: 'Raphaël 1.5.2', url: 'http://cdnjs.cloudflare.com/ajax/libs/raphael/1.5.2/raphael-min.js' },
        { text: 'Sammy 0.6.3', url: 'http://cdnjs.cloudflare.com/ajax/libs/sammy.js/0.6.3/sammy.min.js' },
        { text: 'Sencha Touch', url: 'http://cdn.sencha.io/touch/1.1.0/sencha-touch.js', style: 'http://cdn.sencha.io/touch/1.1.0/resources/css/sencha-touch.css' },
        { text: 'TwitterLib', url: 'http://remy.github.com/twitterlib/twitterlib.min.js' },
        { text: 'underscore 1.1.7', url: 'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.1.7/underscore-min.js' },
        { text: 'Zepto 0.6', url: 'http://cdnjs.cloudflare.com/ajax/libs/zepto/0.6/zepto.min.js' }
      ]
    },
    dojo : {
      text: 'Dojo',
      scripts: [
        { text: 'Dojo 1.6.0', url: 'http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js' },
        { text: 'Dojo 1.4.1', url: 'http://ajax.googleapis.com/ajax/libs/dojo/1.4.1/dojo/dojo.xd.js' }
      ]
    }
    // ext : {
    //   text: 'Ext Core',
    //   style: 'http://extjs.cachefly.net/ext-2.2/resources/css/ext-all.css',
    //   scripts: [
    //     { text: 'Ext Core 3.1', url: 'http://ajax.googleapis.com/ajax/libs/ext-core/3.1.0/ext-core.js' }
    //   ]
    // }
  },
  // NOTE if a new library category is added, you need to add it here
  order = 'jquery jqueryui jquerymobile prototype yui mootools dojo others'.split(' '),
  i = 0;

  this.length = 0; // triggers support for length prop
  for (i = 0; i < order.length; i++) {
    push.call(this, libs[order[i]]);
  }
};

Libraries.prototype.add = function (lib) {
  // save to localStorage
  this.userSpecified.push(lib);
  try {
    localStorage.setItem('libraries', JSON.stringify(this.userSpecified));
  } catch (e) {} // just in case of DOM_22 error, makes me so sad to use this :(
  push.call(this, lib);
  $('#library').trigger('init');
};

Libraries.prototype.clear = function () {
  this.userSpecified = [];
  localStorage.removeItem('libraries');
  this.init();
  $('#library').trigger('init');
};

// OO based to all me to fiddle the object to resemble an array
var libraries = new Libraries();
window.libraries = libraries; // expose a command line API
<commit_msg>+jQuery 1.7<commit_after>//= require "../chrome/storage"

// shortcut method
var push = Array.prototype.push;

var Libraries = function () {
  this.init();

  this.userSpecified = JSON.parse(localStorage.getItem('libraries') || "[]");

  // read from storage
  for (var i = 0; i < this.userSpecified.length; i++) {
    push.call(this, this.userSpecified[i]);
  }
};

Libraries.prototype.init = function () {
  var libs = {
    yui: {
      text: 'YUI',
      scripts: [
        { text: 'YUI 3.3.0', url: 'http://yui.yahooapis.com/3.3.0/build/yui/yui-min.js'},
        { text: 'YUI 2.8.2', url: 'http://ajax.googleapis.com/ajax/libs/yui/2.8.2/build/yuiloader/yuiloader-min.js'}
      ]
    },
    mootools: {
      text: 'MooTools',
      scripts: [
        { text: 'Mootools 1.3.2', url: 'http://ajax.googleapis.com/ajax/libs/mootools/1.3.2/mootools-yui-compressed.js'},
        { text: 'Mootools 1.2.4', url: 'http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools-yui-compressed.js' }
      ]
    },
    prototype: {
      text: 'Prototype',
      scripts: [
        { text: 'Prototype latest', url: 'http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js' },
        { text: 'Prototype 1.7.0.0', url: 'http://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js'},
        { text: 'Prototype 1.6.1.0', url: 'http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js' },
        { text: 'script.aculo.us 1.8.3', url: 'http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js', requires: 'http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js' }
      ]
    },
    jquery: {
      text: 'jQuery',
      scripts: [
        { text: 'jQuery latest', url: 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' },
        { text: 'jQuery WIP (via git)', url: 'http://code.jquery.com/jquery-git.js' },
        { text: 'jQuery 1.7.0', url: 'http://code.jquery.com/jquery-1.7.min.js' },
        { text: 'jQuery 1.6.4', url: 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js' }
      ]
    },
    jqueryui : {
      text: 'jQuery UI',
      requires: 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js',
      style: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css',
      scripts: [
        { text: 'jQuery UI 1.8.13', url: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js' }
      ]
    },
    jquerymobile : {
      text: 'jQuery Mobile',
      requires: 'http://code.jquery.com/jquery-1.6.4.min.js',
      style: 'http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css',
      scripts: [
        { text: 'jQuery Mobile 1.0b3', url: 'http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.js' },
        { text: 'jQuery Mobile 1.0a4.1', url: 'http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js' }
      ]
    },
    others: {
      text: 'Others',
      scripts: [
        { text: 'Backbone 0.5.3', url: 'http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js' },
        { text: 'CoffeeScript', url: 'http://jashkenas.github.com/coffee-script/extras/coffee-script.js' },
        { text: 'ES5 shim 1.2.4', url: 'http://cdnjs.cloudflare.com/ajax/libs/es5-shim/1.2.4/es5-shim.min.js' },
        { text: 'ext-core 3.1.0', url: 'http://cdnjs.cloudflare.com/ajax/libs/ext-core/3.1.0/ext-core.js', style: 'http://extjs.cachefly.net/ext-3.1.0/resources/css/ext-all.css' },
        { text: 'Less 1.1.3', url: 'http://cdnjs.cloudflare.com/ajax/libs/less.js/1.1.3/less-1.1.3.min.js' },
        { text: 'Modernizr 2.0.6', url: 'http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.0.6/modernizr.min.js' },
        { text: 'Processing 1.2.3', url: 'http://cdnjs.cloudflare.com/ajax/libs/processing.js/1.2.3/processing-api.min.js' },
        { text: 'Raphaël 1.5.2', url: 'http://cdnjs.cloudflare.com/ajax/libs/raphael/1.5.2/raphael-min.js' },
        { text: 'Sammy 0.6.3', url: 'http://cdnjs.cloudflare.com/ajax/libs/sammy.js/0.6.3/sammy.min.js' },
        { text: 'Sencha Touch', url: 'http://cdn.sencha.io/touch/1.1.0/sencha-touch.js', style: 'http://cdn.sencha.io/touch/1.1.0/resources/css/sencha-touch.css' },
        { text: 'TwitterLib', url: 'http://remy.github.com/twitterlib/twitterlib.min.js' },
        { text: 'underscore 1.1.7', url: 'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.1.7/underscore-min.js' },
        { text: 'Zepto 0.6', url: 'http://cdnjs.cloudflare.com/ajax/libs/zepto/0.6/zepto.min.js' }
      ]
    },
    dojo : {
      text: 'Dojo',
      scripts: [
        { text: 'Dojo 1.6.0', url: 'http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js' },
        { text: 'Dojo 1.4.1', url: 'http://ajax.googleapis.com/ajax/libs/dojo/1.4.1/dojo/dojo.xd.js' }
      ]
    }
    // ext : {
    //   text: 'Ext Core',
    //   style: 'http://extjs.cachefly.net/ext-2.2/resources/css/ext-all.css',
    //   scripts: [
    //     { text: 'Ext Core 3.1', url: 'http://ajax.googleapis.com/ajax/libs/ext-core/3.1.0/ext-core.js' }
    //   ]
    // }
  },
  // NOTE if a new library category is added, you need to add it here
  order = 'jquery jqueryui jquerymobile prototype yui mootools dojo others'.split(' '),
  i = 0;

  this.length = 0; // triggers support for length prop
  for (i = 0; i < order.length; i++) {
    push.call(this, libs[order[i]]);
  }
};

Libraries.prototype.add = function (lib) {
  // save to localStorage
  this.userSpecified.push(lib);
  try {
    localStorage.setItem('libraries', JSON.stringify(this.userSpecified));
  } catch (e) {} // just in case of DOM_22 error, makes me so sad to use this :(
  push.call(this, lib);
  $('#library').trigger('init');
};

Libraries.prototype.clear = function () {
  this.userSpecified = [];
  localStorage.removeItem('libraries');
  this.init();
  $('#library').trigger('init');
};

// OO based to all me to fiddle the object to resemble an array
var libraries = new Libraries();
window.libraries = libraries; // expose a command line API
<|endoftext|>


<commit_before>game.PlayerEntity = me.Entity.extend({
    init: function(x, y, settings){
        this.setSuper();
        this.setPlayerTimers();
        this.setAttributes();
        this.type = "PlayerEntity";
        this.setFlags();

        me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH);

        this.addAnimation();

        this.renderable.setCurrentAnimation("idle");
    },

    setSuper: function(x, y){
        this._super(me.Entity, 'init', [x, y, {
            image: "player",
            width: 64,
            height: 64,
            spritewidth: "64",
            spriteheight: "64",
            getShape: function(){
                return(new me.Rect(0, 0, 64, 64)).toPolygon();
            }
        }]);
    },

    setPlayerTimers: function(){
        this.now = new Date().getTime();
        this.lastHit = this.now;
        this.lastAttack = new Date().getTime(); //Haven't used this
    },

    setAttributes: function(){
        //this sets the attributes for the Player
        this.health = game.data.playerHealth;
        this.body.setVelocity(game.data.playerMoveSpeed, 20);
        this.attack = game.data.playerAttack;
    },

    setFlags: function(){
        //Keeps track of which direction your character is going
        this.facing = "right";
        this.dead = false;
        this.attacking = false;
    },

    addAnimation: function(){
        //sets the animation for player
        this.renderable.addAnimation("idle", [78]);
        this.renderable.addAnimation("walk", [117, 118, 119, 120, 121, 122, 123, 124, 125], 80);
        this.renderable.addAnimation("attack", [65, 67, 68, 69, 70, 71, 72], 80);
    },

    update: function(delta){
        this.now= new Date().getTime();
        this.dead = checkIfDead();
        this.checkKeyPressesAndMove();
        this.setAnimation();
        me.collision.check(this, true, this.collideHandler.bind(this), true);
        this.body.update(delta);
        this._super(me.Entity, "update", [delta]);
        return true;
    },

    checkIfDead: function(){
        //this checks if the Player is dead, and if he is dead then it is true
         if (this.health <= 0){
            this.dead = true;
        }
        return false;
    },

    checkKeyPressesAndMove: function(){
        //if the key is pressed than he moves to the right
        if(me.input.isKeyPressed("right")){
            this.moveRight();
        //if the key is pressed, than the player moves left
        }else if(me.input.isKeyPressed("left")){
            this.moveLeft();
        }else{
            this.body.vel.x = 0;
        }
        //if the key is pressed than he will jump
        if(me.input.isKeyPressed("jump") && !this.body.jumping && !this.body.falling){
            this.jump();
        }

        this.atatcking = me.input.isKeyPressed("attack");
    },

    moveRight: function(){
        //adds to the position of my x by the velocity defined above in
            //setVelocity() and multiplying it by me.timer.tick.
            //me.timer.tick makes the movement look smooth
            this.body.vel.x += this.body.accel.x * me.timer.tick;
            this.facing = "right";
            this.flipX(true);
    },

    moveLeft: function(){
        this.facing = "left";
            this.body.vel.x -=this.body.accel.x * me.timer.tick;
            this.flipX(false);
    },

    jump: function(){
        this.body.jumping = true;
        this.body.vel.y -= this.body.accel.y * me.timer.tick;
    },

    setAnimation: function(){
        if(this.attacking){
            if(!this.renderable.isCurrentAnimation("attack")){
                //Sets the current animation to attack and once that is over
                //goes back to the idle animation
                this.renderable.setCurrentAnimation("attack", "idle");
                //Makes it so that the next time we start this sequence we beign
                //from the first animation, not wherever we left off when we
                //switched to another animation
                this.renderable.setAnimationFrame();
            }
        }
        else if(this.body.vel.x !== 0 && !this.renderable.isCurrentAnimation("attack")){
            if(!this.renderable.isCurrentAnimation("walk")){
                this.renderable.setCurrentAnimation("walk");
            }
        }else if(!this.renderable.isCurrentAnimation("attack")){
            this.renderable.setCurrentAnimation("idle");
        }
    },

    loseHealth: function(damage){
        //if attacked than he loses health
        this.health = this.health - damage;
    },

    collideHandler: function(response){
        if(response.b.type==='EnemyBaseEntity'){
            var ydif = this.pos.y - response.b.pos.y;
            var xdif = this.pos.x - response.b.pos.x;

            if(ydif<-40 && xdif< 70 && xdif>-35){
                this.body.falling = false;
                this.body.vel.y = -1;
            }
            else if(xdif>-35 && this.facing==='right' && (xdif<0)){
                this.body.vel.x = 0;
               // this.pos.x = this.pos.x -1;
            }else if(xdif<70 && this.facing==='left' && xdif>0){
                this.body.vel.x = 0;
                this.pos.x = this.pos.x +1;
            }

            if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit >= game.data.playerAttackTimer){

                this.lastHit = this.now;
                response.b.loseHealth(game.data.playerAttack);
            }
        }else if(response.b.type==='EnemyCreep'){
            var xdif = this.pos.x - response.b.pos.x;
            var ydif = this.pos.y - response.b.pos.y;

            if (xdif>0){
                //this.pos.x = this.pos.x + 1;
                if(this.facing==="left"){
                    this.body.vel.x = 0;
                }
            }else{
                //this.pos.x = this.pos.x - 1;
                if(this.facing==="right"){
                    this.body.vel.x = 0;
                }
            }
            if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit >= game.data.playerAttackTimer
                    && (Math.abs(ydif) <=40) &&
                    (((xdif>0) && this.facing==="left") || ((xdif<0) && this.facing==="right"))
                    ){
                this.lastHit = this.now;
                //if the creeps health is less than our attack, execute code in if statement
                if(response.b.health <= game.data.playerAttack){
                    //adds one gold for a creep kill
                    game.data.gold += 1;
                    console.log("Current gold: " + game.data.gold);
                }

                response.b.loseHealth(game.data.playerAttack);
            }
        }
    }
});
    <commit_msg>puhsing<commit_after>game.PlayerEntity = me.Entity.extend({
    init: function(x, y, settings){
        this.setSuper();
        this.setPlayerTimers();
        this.setAttributes();
        this.type = "PlayerEntity";
        this.setFlags();

        me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH);

        this.addAnimation();

        this.renderable.setCurrentAnimation("idle");
    },

    setSuper: function(x, y){
        this._super(me.Entity, 'init', [x, y, {
            image: "player",
            width: 64,
            height: 64,
            spritewidth: "64",
            spriteheight: "64",
            getShape: function(){
                return(new me.Rect(0, 0, 64, 64)).toPolygon();
            }
        }]);
    },

    setPlayerTimers: function(){
        this.now = new Date().getTime();
        this.lastHit = this.now;
        this.lastAttack = new Date().getTime(); //Haven't used this
    },

    setAttributes: function(){
        //this sets the attributes for the Player
        this.health = game.data.playerHealth;
        this.body.setVelocity(game.data.playerMoveSpeed, 20);
        this.attack = game.data.playerAttack;
    },

    setFlags: function(){
        //Keeps track of which direction your character is going
        this.facing = "right";
        this.dead = false;
        this.attacking = false;
    },

    addAnimation: function(){
        //sets the animation for player
        this.renderable.addAnimation("idle", [78]);
        this.renderable.addAnimation("walk", [117, 118, 119, 120, 121, 122, 123, 124, 125], 80);
        this.renderable.addAnimation("attack", [65, 67, 68, 69, 70, 71, 72], 80);
    },

    update: function(delta){
        this.now= new Date().getTime();
        this.dead = this.checkIfDead();
        this.checkKeyPressesAndMove();
        this.setAnimation();
        me.collision.check(this, true, this.collideHandler.bind(this), true);
        this.body.update(delta);
        this._super(me.Entity, "update", [delta]);
        return true;
    },

    checkIfDead: function(){
        //this checks if the Player is dead, and if he is dead then it is true
         if (this.health <= 0){
            this.dead = true;
        }
        return false;
    },

    checkKeyPressesAndMove: function(){
        //if the key is pressed than he moves to the right
        if(me.input.isKeyPressed("right")){
            this.moveRight();
        //if the key is pressed, than the player moves left
        }else if(me.input.isKeyPressed("left")){
            this.moveLeft();
        }else{
            this.body.vel.x = 0;
        }
        //if the key is pressed than he will jump
        if(me.input.isKeyPressed("jump") && !this.body.jumping && !this.body.falling){
            this.jump();
        }

        this.atatcking = me.input.isKeyPressed("attack");
    },

    moveRight: function(){
        //adds to the position of my x by the velocity defined above in
            //setVelocity() and multiplying it by me.timer.tick.
            //me.timer.tick makes the movement look smooth
            this.body.vel.x += this.body.accel.x * me.timer.tick;
            this.facing = "right";
            this.flipX(true);
    },

    moveLeft: function(){
        this.facing = "left";
            this.body.vel.x -=this.body.accel.x * me.timer.tick;
            this.flipX(false);
    },

    jump: function(){
        this.body.jumping = true;
        this.body.vel.y -= this.body.accel.y * me.timer.tick;
    },

    setAnimation: function(){
        if(this.attacking){
            if(!this.renderable.isCurrentAnimation("attack")){
                //Sets the current animation to attack and once that is over
                //goes back to the idle animation
                this.renderable.setCurrentAnimation("attack", "idle");
                //Makes it so that the next time we start this sequence we beign
                //from the first animation, not wherever we left off when we
                //switched to another animation
                this.renderable.setAnimationFrame();
            }
        }
        else if(this.body.vel.x !== 0 && !this.renderable.isCurrentAnimation("attack")){
            if(!this.renderable.isCurrentAnimation("walk")){
                this.renderable.setCurrentAnimation("walk");
            }
        }else if(!this.renderable.isCurrentAnimation("attack")){
            this.renderable.setCurrentAnimation("idle");
        }
    },

    loseHealth: function(damage){
        //if attacked than he loses health
        this.health = this.health - damage;
    },

    collideHandler: function(response){
        if(response.b.type==='EnemyBaseEntity'){
            this.collideWithEnemyBase(response);
        }else if(response.b.type==='EnemyCreep'){
            this.collideWithEnemyCreep(response);
        }
    },

    collideWithEnemyBase: function(response){
            var ydif = this.pos.y - response.b.pos.y;
            var xdif = this.pos.x - response.b.pos.x;

            if(ydif<-40 && xdif< 70 && xdif>-35){
                this.body.falling = false;
                this.body.vel.y = -1;
            }
            else if(xdif>-35 && this.facing==='right' && (xdif<0)){
                this.body.vel.x = 0;
            }else if(xdif<70 && this.facing==='left' && xdif>0){
                this.body.vel.x = 0;
            }
            if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit >= game.data.playerAttackTimer){
                this.lastHit = this.now;
                response.b.loseHealth(game.data.playerAttack);
            }
    },

    collideWithEnemyCreep: function(response){
            var xdif = this.pos.x - response.b.pos.x;
            var ydif = this.pos.y - response.b.pos.y;

            this.stopMovement(xdif);

            if(this.checkAttack(xdif, ydif)){
               this.hitCreep(response);
            };
    },

    stopMovement: function(xdif){
        if (xdif>0){
                if(this.facing==="left"){
                    this.body.vel.x = 0;
                }
            }else{
                if(this.facing==="right"){
                    this.body.vel.x = 0;
                }
            }
    },

    checkAttack: function(xdif, ydif){
        if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit >= game.data.playerAttackTimer
                    && (Math.abs(ydif) <=40) &&
                    (((xdif>0) && this.facing==="left") || ((xdif<0) && this.facing==="right"))
                    ){
                this.lastHit = this.now;
                //if the creeps health is less than our attack, execute code in if statement
                return true;
        }
        return false;
    },

    hitCreep: function(response){
         if(response.b.health <= game.data.playerAttack){
                    //adds one gold for a creep kill
                    game.data.gold += 1;
                    console.log("Current gold: " + game.data.gold);
                }

                response.b.loseHealth(game.data.playerAttack);
    }
});
    <|endoftext|>