<commit_before>(function ($) {
  var yasqeOptions = {
    createShareLink: false,
    language: yasqeLocale,
    lineNumbers: false,
    persistent: null,
    readOnly: true,
    theme: "sparqlab"
  };
  var textAreaToYasqe = function (element) {
    if (element) {
      var query = element.value,
          yasqe = YASQE.fromTextArea(element, yasqeOptions);
      yasqe.setValue(query);
      return yasqe;
    }
  };
  var getExerciseId = function () {
    var path = document.location.pathname,
        index = path.lastIndexOf("/");
    if (index !== -1) {
      return path.substring(index + 1);
    }
  };
  var shortenIri = function (iri) {
    for (p in prefixes) {
      if (iri.indexOf(prefixes[p]) == 0) {
        return p + ":" + iri.substring(prefixes[p].length);
      }
    }
    return "<" + iri + ">";
  };
  var formatBinding = function (binding) {
    switch (binding.type) {
      case "literal":
        if (binding.hasOwnProperty("xml:lang")) {
          return '"' + binding.value + '"@' + binding["xml:lang"] + '';
        } else if (binding.hasOwnProperty("datatype")) {
          return ('"' + binding.value + '"^^' + shortenIri(binding["datatype"]) + '');
        } else {
          return '"' + binding.value + '"';
        }
      case "uri":
        return '' + shortenIri(binding.value) + '';
      default: return binding.value;
    }
  };
  var parseSelectResults = function (data) {
    var head = data.head.vars,
        bindings = data.results.bindings;
    return [head].concat(bindings.map(function (binding) {
      return head.map(function (variable) { return formatBinding(binding[variable]); });
    }));
  };
  var renderTable = function (data) {
    var head = data[0].map(function (variable) {
          return "" + variable + "	"; }
        ).join(""),
        body = data.slice(1).map(function (row) {
          return "
" + row.map(function (value) { return "" + value + "	"; }).join("") + "
";
        }).join("");
    return "

" +
           head +
           "

" +
           body +
           "

";
  };
  var showMergeView = function ($mergeView, query, canonicalQuery) {
    $mergeView.removeClass("hidden");
    CodeMirror.MergeView($mergeView[0], {
      connect: "align",
      mode: "sparql11",
      origLeft: query,
      revertButtons: false,
      theme: "sparqlab",
      value: canonicalQuery
    });
    $(".CodeMirror-merge-scrolllock").attr("title", sparqlabLocale.lockedScrolling);
  };

  $(document).ready(function () {
    var parse = function (mimetype, text) {
      return (mimetype === "application/json") ? JSON.parse(text) : text;
    };
    var query = document.getElementById("query"),
        canonicalQuery = document.getElementById("canonical-query"),
        $qr = $("#results"),
        qrType = $qr.data("type"),
        qr = parse(qrType, $qr.val()),
        $qrResults = $("#query-results"),
        $cr = $("#canonical-results"),
        crType = $cr.data("type"),
        cr = parse(crType, $cr.val()),
        $crResults = $("#canonical-query-results"),
        $revealSolution = $("#reveal-solution"),
        $mergeView = $("#mergeview");

    // Show YASQE if query is incorrect and solution not revealed.
    // Show MergeView if query is correct or solution is revealed.
    if ($mergeView.hasClass("hidden")) {
      textAreaToYasqe(query);
    } else {
      showMergeView($mergeView, query.value, canonicalQuery.value);
    }

    // .daff class is used when both results are SELECT results.
    if ($qrResults.hasClass("daff")) {
      // In that case we present a tabular diff.
      var queryData = parseSelectResults(qr),
          canonicalData = parseSelectResults(cr),
          queryTable = new daff.TableView(queryData),
          canonicalTable = new daff.TableView(canonicalData);
      queryTable.trim();
      canonicalTable.trim();
      var alignment = daff.compareTables(canonicalTable, queryTable).align(),
          tableDiff = new daff.TableView([]);
          flags = new daff.CompareFlags(),
      flags.show_unchanged = false;
      flags.always_show_header = true;
      (new daff.TableDiff(alignment,flags)).hilite(tableDiff);
      var diff2html = new daff.DiffRender();
      diff2html.render(tableDiff);
      var tableDiffHtml = diff2html.html();
      $qrResults.html(tableDiffHtml);
      $crResults.html(renderTable(canonicalData));
    } else {
      // Otherwise we show the results using YASR
      var config = $.extend(yasrConfig, {getUsedPrefixes: function () { return prefixes; }});
          qrYasr = YASR($qrResults[0], config),
          crYasr = YASR($crResults[0], config);
      qrYasr.setResponse({
        response: qr,
        contentType: qrType
      });
      crYasr.setResponse({
        response: cr,
        contentType: crType
      });
    }

    $revealSolution.on("click", function (e) {
      var exerciseId = getExerciseId();
      $.get("../../api/exercise-solution",
        {id: exerciseId},
        function (solution) {
          $(".yasqe").hide();
          showMergeView($mergeView, query.value, solution);
          $("#reveal-solution-button").hide();
        }
      );
    });
  });
})(jQuery);
<commit_msg>Prefer longer namespaces when shortening IRIs<commit_after>(function ($) {
  var yasqeOptions = {
    createShareLink: false,
    language: yasqeLocale,
    lineNumbers: false,
    persistent: null,
    readOnly: true,
    theme: "sparqlab"
  };
  var textAreaToYasqe = function (element) {
    if (element) {
      var query = element.value,
          yasqe = YASQE.fromTextArea(element, yasqeOptions);
      yasqe.setValue(query);
      return yasqe;
    }
  };
  var getExerciseId = function () {
    var path = document.location.pathname,
        index = path.lastIndexOf("/");
    if (index !== -1) {
      return path.substring(index + 1);
    }
  };
  var shortenIri = function (prefixPairs, iri) {
    for (var i = 0; i < prefixPairs.length; i++) {
      if (iri.indexOf(prefixPairs[i][1]) == 0) {
        return prefixPairs[i][0] + ":" + iri.substring(prefixPairs[i][1].length);
      }
    }
    return "<" + iri + ">";
  };
  var formatBinding = function (prefixPairs, binding) {
    switch (binding.type) {
      case "literal":
        if (binding.hasOwnProperty("xml:lang")) {
          return '"' + binding.value + '"@' + binding["xml:lang"] + '';
        } else if (binding.hasOwnProperty("datatype")) {
          return ('"' + binding.value + '"^^' + shortenIri(prefixPairs, binding["datatype"]) + '');
        } else {
          return '"' + binding.value + '"';
        }
      case "uri":
        return '' + shortenIri(prefixPairs, binding.value) + '';
      default: return binding.value;
    }
  };
  var parseSelectResults = function (prefixPairs, data) {
    var head = data.head.vars,
        bindings = data.results.bindings;
    return [head].concat(bindings.map(function (binding) {
      return head.map(function (variable) { return formatBinding(prefixPairs, binding[variable]); });
    }));
  };
  var renderTable = function (data) {
    var head = data[0].map(function (variable) {
          return "" + variable + "	"; }
        ).join(""),
        body = data.slice(1).map(function (row) {
          return "
" + row.map(function (value) { return "" + value + "	"; }).join("") + "
";
        }).join("");
    return "

" +
           head +
           "

" +
           body +
           "

";
  };
  var showMergeView = function ($mergeView, query, canonicalQuery) {
    $mergeView.removeClass("hidden");
    CodeMirror.MergeView($mergeView[0], {
      connect: "align",
      mode: "sparql11",
      origLeft: query,
      revertButtons: false,
      theme: "sparqlab",
      value: canonicalQuery
    });
    $(".CodeMirror-merge-scrolllock").attr("title", sparqlabLocale.lockedScrolling);
  };

  $(document).ready(function () {
    var parse = function (mimetype, text) {
      return (mimetype === "application/json") ? JSON.parse(text) : text;
    };
    var query = document.getElementById("query"),
        canonicalQuery = document.getElementById("canonical-query"),
        $qr = $("#results"),
        qrType = $qr.data("type"),
        qr = parse(qrType, $qr.val()),
        $qrResults = $("#query-results"),
        $cr = $("#canonical-results"),
        crType = $cr.data("type"),
        cr = parse(crType, $cr.val()),
        $crResults = $("#canonical-query-results"),
        $revealSolution = $("#reveal-solution"),
        $mergeView = $("#mergeview");

    // Show YASQE if query is incorrect and solution not revealed.
    // Show MergeView if query is correct or solution is revealed.
    if ($mergeView.hasClass("hidden")) {
      textAreaToYasqe(query);
    } else {
      showMergeView($mergeView, query.value, canonicalQuery.value);
    }

    // .daff class is used when both results are SELECT results.
    if ($qrResults.hasClass("daff")) {
      // In that case we present a tabular diff.
      var prefixPairs = [];
      for (p in prefixes) {
        prefixPairs.push([p, prefixes[p]]);
      }
      // Sort prefixes by namespace length in descending order.
      prefixPairs.sort(function (a, b) {
        return b[1].length - a[1].length;
      });
      var queryData = parseSelectResults(prefixPairs, qr),
          canonicalData = parseSelectResults(prefixPairs, cr),
          queryTable = new daff.TableView(queryData),
          canonicalTable = new daff.TableView(canonicalData);
      queryTable.trim();
      canonicalTable.trim();
      var alignment = daff.compareTables(canonicalTable, queryTable).align(),
          tableDiff = new daff.TableView([]);
          flags = new daff.CompareFlags(),
      flags.show_unchanged = false;
      flags.always_show_header = true;
      (new daff.TableDiff(alignment,flags)).hilite(tableDiff);
      var diff2html = new daff.DiffRender();
      diff2html.render(tableDiff);
      var tableDiffHtml = diff2html.html();
      $qrResults.html(tableDiffHtml);
      $crResults.html(renderTable(canonicalData));
    } else {
      // Otherwise we show the results using YASR
      var config = $.extend(yasrConfig, {getUsedPrefixes: function () { return prefixes; }});
          qrYasr = YASR($qrResults[0], config),
          crYasr = YASR($crResults[0], config);
      qrYasr.setResponse({
        response: qr,
        contentType: qrType
      });
      crYasr.setResponse({
        response: cr,
        contentType: crType
      });
    }

    $revealSolution.on("click", function (e) {
      var exerciseId = getExerciseId();
      $.get("../../api/exercise-solution",
        {id: exerciseId},
        function (solution) {
          $(".yasqe").hide();
          showMergeView($mergeView, query.value, solution);
          $("#reveal-solution-button").hide();
        }
      );
    });
  });
})(jQuery);
<|endoftext|>


<commit_before>import React from 'react'
import {Layout, Drawer, Navigation, Header, HeaderRow, Content} from 'react-mdl/lib/Layout';
import Textfield from 'react-mdl/lib/Textfield';
import NavLink from './NavLink';
import CongregationLink from './CongregationLink';

class Sermons extends React.Component {

  constructor(props) {
    super(props);
    this.state = {searchTerm: ''};
    this.handleChange = this.handleChange.bind(this);
  }

  formatHeadline() {
    var self = this;
    if (this.props.params.congregationId) {
      var congregation = this.props.congregations.find(function(congregation) {
        return congregation.bucketID === self.props.params.congregationId;
      });
      if (congregation) {
        return congregation.displayName;
      }
    }
    return 'Recent Sermons'
  }

  handleChange(event){
    this.setState({searchTerm: event.target.value});
  }

  render() {
    var self = this;

    var children = React.Children.map(this.props.children, function (child) {
        return React.cloneElement(child, {
          base:self.props.base,
          congregations:self.props.congregations,
          sermons:self.props.sermons,
          searchTerm:self.state.searchTerm
        })
      })

    return (
      <Layout fixedHeader fixedDrawer>
      <Header style={{color: 'white'}}>
        <HeaderRow title={self.formatHeadline()}>
          <Textfield
              value={self.state.searchTerm}
              onChange={self.handleChange}
              label="Search"
              expandable
              expandableIcon="search"
          />
        </HeaderRow>
      </Header>

      <Drawer title="Congregations">
        <Navigation>

        <NavLink
          to={"/sermons/all"}
          key={'sermons'}>
            All ({self.props.sermons.length})
          </NavLink>
        { this.props.congregations.map((congregation) => (
          <CongregationLink
            key={congregation.key}
            sermons={self.props.sermons}
            congregation={congregation} />
        ))}

        </Navigation>
      </Drawer>

    <Content>
      {children}
    </Content>

    </Layout>
    )
  }
}

export default Sermons
<commit_msg>collapse drawer when selecting a congregation<commit_after>import React from 'react'
import {Layout, Drawer, Navigation, Header, HeaderRow, Content} from 'react-mdl/lib/Layout';
import Textfield from 'react-mdl/lib/Textfield';
import NavLink from './NavLink';
import CongregationLink from './CongregationLink';

class Sermons extends React.Component {

  constructor(props) {
    super(props);
    this.state = {searchTerm: ''};
    this.handleChange = this.handleChange.bind(this);
  }

  formatHeadline() {
    var self = this;
    if (this.props.params.congregationId) {
      var congregation = this.props.congregations.find(function(congregation) {
        return congregation.bucketID === self.props.params.congregationId;
      });
      if (congregation) {
        return congregation.displayName;
      }
    }
    return 'Recent Sermons'
  }

  handleChange(event){
    this.setState({searchTerm: event.target.value});
  }

  componentDidUpdate(prevProps, prevState){
    var layout = document.querySelector('.mdl-layout');
    var drawer = document.querySelector('.mdl-layout__drawer');
    if (layout.classList.contains('is-small-screen') && drawer.classList.contains('is-visible')) {
      layout.MaterialLayout.toggleDrawer();
    }
  }

  render() {
    var self = this;

    var children = React.Children.map(this.props.children, function (child) {
        return React.cloneElement(child, {
          base:self.props.base,
          congregations:self.props.congregations,
          sermons:self.props.sermons,
          searchTerm:self.state.searchTerm
        })
      })

    return (
      <Layout fixedHeader fixedDrawer>
      <Header style={{color: 'white'}}>
        <HeaderRow title={self.formatHeadline()}>
          <Textfield
              value={self.state.searchTerm}
              onChange={self.handleChange}
              label="Search"
              expandable
              expandableIcon="search"
          />
        </HeaderRow>
      </Header>

      <Drawer title="Congregations">
        <Navigation>

        <NavLink
          to={"/sermons/all"}
          key={'sermons'}>
            All ({self.props.sermons.length})
          </NavLink>
        { this.props.congregations.map((congregation) => (
          <CongregationLink
            key={congregation.key}
            sermons={self.props.sermons}
            congregation={congregation} />
        ))}

        </Navigation>
      </Drawer>

    <Content>
      {children}
    </Content>

    </Layout>
    )
  }
}

export default Sermons
<|endoftext|>


<commit_before>/*
 * This contains common functions we need for processing the respinse
 */

/*
 * function to create list elements `<li>` and append to element with id `id`
 */
var displayListElements = function (id, elements, selected) {
    'use strict';
    var target = document.getElementById(id),
        fragment = document.createDocumentFragment(),
        len = elements.length;

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    elements.forEach(function (element) {
        var li = document.createElement('li'),
            content = document.createTextNode(element);
        li.setAttribute('id', element.toLowerCase());
        if (selected && selected === element.toLowerCase()) {
            li.setAttribute('class', 'active');
        }
        li.appendChild(content);
        fragment.appendChild(li);
    });
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * function to create `option` and append to select box with id `id`
 */
var displayOptions = function (id, elements, selected) {
    'use strict';
    var target= document.getElementById(id),
        fragment =  document.createDocumentFragment();

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    for (var key in elements) {
        if (elements.hasOwnProperty(key)){
            var option = document.createElement('option'), content = document.createTextNode(elements[key]);
            option.setAttribute('value', key);
            if (selected && selected === key) {
                option.setAttribute('selected', 'selected');
            }
            option.appendChild(content);
            fragment.appendChild(option);
        }
    }
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * function to display underlyings
 *
 * we need different function for this because we need to add submarket
 * name as classname to underlyings option
 */
var displayUnderlyings = function (selected) {
    'use strict';
    var target= document.getElementById('underlying'),
        fragment =  document.createDocumentFragment(),
        elements = Offerings.underlyings();

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    for (var key in elements) {
        if (elements.hasOwnProperty(key)){
            var option = document.createElement('option'), content = document.createTextNode(elements[key].display);
            option.setAttribute('value', key);
            option.setAttribute('class', elements[key].classname);
            if (selected && selected === key) {
                option.setAttribute('selected', 'selected');
            }
            option.appendChild(content);
            fragment.appendChild(option);
        }
    }
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * This maps the form name and barrierCategory we display on
 * trading form to the actual we send it to backend
 * for e.g risefall is mapped to callput with barrierCategory euro_atm
 */
var getFormNameBarrierCategory = function (displayFormName) {
    'use strict';
    var obj = {};
    if (displayFormName) {
        if(displayFormName === 'risefall') {
            obj['formName'] = 'callput';
            obj['barrierCategory'] = 'euro_atm';
        } else if (displayFormName === 'higherlower') {
            obj['formName'] = 'callput';
            obj['barrierCategory'] = 'euro_non_atm';
        } else if (displayFormName === 'callput'){
            obj['formName'] = displayFormName;
            obj['barrierCategory'] = 'euro_atm';
        } else {
            obj['formName'] = displayFormName;
            obj['barrierCategory'] = '';
        }
    } else {
        obj['formName'] = 'callput';
        obj['barrierCategory'] = 'euro_atm';
    }
    return obj;
};

/*
 * This maps the contract type to where we display on trading form
 * and as there is no mapping on server side so need to create it
 * on front end
 *
 * for example we display CALL on top and PUT to bottom
 */
var contractTypeDisplayMapping = function (type) {
    'use strict';
    var obj = {
        CALL: "top",
        PUT: "bottom",
        ASIANU: "top",
        ASIAND: "bottom",
        DIGITMATCH: "top",
        DIGITDIFF: "bottom",
        EXPIRYRANGE: "top",
        EXPIRYMISS: "bottom",
        RANGE: "top",
        UPORDOWN: "bottom",
        ONETOUCH: "top",
        NOTOUCH: "bottom",
        SPREADU: "top",
        SPREADD: "bottom"
    };

    return type ? obj[type] : 'top';
};

/*
 * function to check if element is visible or not
 *
 * alternative to jquery $('#id').is(':visible')
 */
var isVisible = function (elem) {
    'use strict';
    if (elem.offsetWidth === 0 && elem.offsetHeight === 0) {
        return false;
    } else {
        return true;
    }
};

/*
 * function to hide and display the loading icon for price container
 */
var hidePriceLoadingIcon = function () {
    'use strict';
    var elm = document.getElementById('loading_container');
    if (elm) {
        elm.style.display = 'none';
    }
};

var showPriceLoadingIcon = function () {
    'use strict';
    var elm = document.getElementById('loading_container');
    if (elm) {
        elm.style.display = 'block';
    }
};

/*
 * function to hide contract confirmation overlay container
 */
var hideOverlayContainer = function () {
    'use strict';
    var elm = document.getElementById('contract_confirmation_container');
    if (elm) {
        elm.style.display = 'none';
    }
};

/*
 * function to assign sorting to market list
 */
function compareMarkets(a, b) {
    var sortedMarkets = {
        'forex': 0,
        'indices': 1,
        'stocks': 2,
        'commodities': 3,
        'random': 4
    };

    if (sortedMarkets[a.toLowerCase()] < sortedMarkets[b.toLowerCase()]) {
        return -1;
    }
    if (sortedMarkets[a.toLowerCase()] > sortedMarkets[b.toLowerCase()]) {
        return 1;
    }
    return 0;
}

/*
 * function to assign sorting to contract category
 */
function compareContractCategory(a, b) {
    var sortedContractCategory = {
        'risefall': 0,
        'higherlower': 1,
        'touchnotouch': 2,
        'endsinout': 3,
        'staysinout': 4,
        'asian': 5,
        'digits': 6,
        'spreads': 7
    };

    if (sortedContractCategory[a.toLowerCase()] < sortedContractCategory[b.toLowerCase()]) {
        return -1;
    }
    if (sortedContractCategory[a.toLowerCase()] > sortedContractCategory[b.toLowerCase()]) {
        return 1;
    }
    return 0;
}

/*
 * function to get cookie javascript way (use if you don't want to use jquery)
 */
function getCookieItem(sKey) {
    if (!sKey) { return null; }
    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}
<commit_msg>function to display price/spot up down movement<commit_after>/*
 * This contains common functions we need for processing the respinse
 */

/*
 * function to create list elements `<li>` and append to element with id `id`
 */
var displayListElements = function (id, elements, selected) {
    'use strict';
    var target = document.getElementById(id),
        fragment = document.createDocumentFragment(),
        len = elements.length;

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    elements.forEach(function (element) {
        var li = document.createElement('li'),
            content = document.createTextNode(element);
        li.setAttribute('id', element.toLowerCase());
        if (selected && selected === element.toLowerCase()) {
            li.setAttribute('class', 'active');
        }
        li.appendChild(content);
        fragment.appendChild(li);
    });
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * function to create `option` and append to select box with id `id`
 */
var displayOptions = function (id, elements, selected) {
    'use strict';
    var target= document.getElementById(id),
        fragment =  document.createDocumentFragment();

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    for (var key in elements) {
        if (elements.hasOwnProperty(key)){
            var option = document.createElement('option'), content = document.createTextNode(elements[key]);
            option.setAttribute('value', key);
            if (selected && selected === key) {
                option.setAttribute('selected', 'selected');
            }
            option.appendChild(content);
            fragment.appendChild(option);
        }
    }
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * function to display underlyings
 *
 * we need different function for this because we need to add submarket
 * name as classname to underlyings option
 */
var displayUnderlyings = function (selected) {
    'use strict';
    var target= document.getElementById('underlying'),
        fragment =  document.createDocumentFragment(),
        elements = Offerings.underlyings();

    while (target && target.firstChild) {
        target.removeChild(target.firstChild);
    }

    for (var key in elements) {
        if (elements.hasOwnProperty(key)){
            var option = document.createElement('option'), content = document.createTextNode(elements[key].display);
            option.setAttribute('value', key);
            option.setAttribute('class', elements[key].classname);
            if (selected && selected === key) {
                option.setAttribute('selected', 'selected');
            }
            option.appendChild(content);
            fragment.appendChild(option);
        }
    }
    if (target) {
        target.appendChild(fragment);
    }
};

/*
 * This maps the form name and barrierCategory we display on
 * trading form to the actual we send it to backend
 * for e.g risefall is mapped to callput with barrierCategory euro_atm
 */
var getFormNameBarrierCategory = function (displayFormName) {
    'use strict';
    var obj = {};
    if (displayFormName) {
        if(displayFormName === 'risefall') {
            obj['formName'] = 'callput';
            obj['barrierCategory'] = 'euro_atm';
        } else if (displayFormName === 'higherlower') {
            obj['formName'] = 'callput';
            obj['barrierCategory'] = 'euro_non_atm';
        } else if (displayFormName === 'callput'){
            obj['formName'] = displayFormName;
            obj['barrierCategory'] = 'euro_atm';
        } else {
            obj['formName'] = displayFormName;
            obj['barrierCategory'] = '';
        }
    } else {
        obj['formName'] = 'callput';
        obj['barrierCategory'] = 'euro_atm';
    }
    return obj;
};

/*
 * This maps the contract type to where we display on trading form
 * and as there is no mapping on server side so need to create it
 * on front end
 *
 * for example we display CALL on top and PUT to bottom
 */
var contractTypeDisplayMapping = function (type) {
    'use strict';
    var obj = {
        CALL: "top",
        PUT: "bottom",
        ASIANU: "top",
        ASIAND: "bottom",
        DIGITMATCH: "top",
        DIGITDIFF: "bottom",
        EXPIRYRANGE: "top",
        EXPIRYMISS: "bottom",
        RANGE: "top",
        UPORDOWN: "bottom",
        ONETOUCH: "top",
        NOTOUCH: "bottom",
        SPREADU: "top",
        SPREADD: "bottom"
    };

    return type ? obj[type] : 'top';
};

/*
 * function to check if element is visible or not
 *
 * alternative to jquery $('#id').is(':visible')
 */
var isVisible = function (elem) {
    'use strict';
    if (elem.offsetWidth === 0 && elem.offsetHeight === 0) {
        return false;
    } else {
        return true;
    }
};

/*
 * function to hide and display the loading icon for price container
 */
var hidePriceLoadingIcon = function () {
    'use strict';
    var elm = document.getElementById('loading_container');
    if (elm) {
        elm.style.display = 'none';
    }
};

var showPriceLoadingIcon = function () {
    'use strict';
    var elm = document.getElementById('loading_container');
    if (elm) {
        elm.style.display = 'block';
    }
};

/*
 * function to hide contract confirmation overlay container
 */
var hideOverlayContainer = function () {
    'use strict';
    var elm = document.getElementById('contract_confirmation_container');
    if (elm) {
        elm.style.display = 'none';
    }
};

/*
 * function to assign sorting to market list
 */
var compareMarkets = function (a, b) {
    var sortedMarkets = {
        'forex': 0,
        'indices': 1,
        'stocks': 2,
        'commodities': 3,
        'random': 4
    };

    if (sortedMarkets[a.toLowerCase()] < sortedMarkets[b.toLowerCase()]) {
        return -1;
    }
    if (sortedMarkets[a.toLowerCase()] > sortedMarkets[b.toLowerCase()]) {
        return 1;
    }
    return 0;
}

/*
 * function to assign sorting to contract category
 */
var compareContractCategory = function (a, b) {
    var sortedContractCategory = {
        'risefall': 0,
        'higherlower': 1,
        'touchnotouch': 2,
        'endsinout': 3,
        'staysinout': 4,
        'asian': 5,
        'digits': 6,
        'spreads': 7
    };

    if (sortedContractCategory[a.toLowerCase()] < sortedContractCategory[b.toLowerCase()]) {
        return -1;
    }
    if (sortedContractCategory[a.toLowerCase()] > sortedContractCategory[b.toLowerCase()]) {
        return 1;
    }
    return 0;
}

/*
 * function to get cookie javascript way (use if you don't want to use jquery)
 */
var getCookieItem = function (sKey) {
    if (!sKey) { return null; }
    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}

/*
 * Display price/spot movement variation to depict price moved up or down
 */
var displayPriceMovement = function (element, oldValue, currentValue) {
    element.classList.remove('price_moved_down');
    element.classList.remove('price_moved_up');
    if (parseFloat(currentValue) > parseFloat(oldValue)) {
        element.classList.remove('price_moved_down');
        element.classList.add('price_moved_up');
    } else if (parseFloat(currentValue) < parseFloat(oldValue)) {
        element.classList.remove('price_moved_up');
        element.classList.add('price_moved_down');
    }
};
<|endoftext|>


<commit_before>/**
  Copyright 2010-2011 Ondrej Certik <ondrej@certik.cz>
  Copyright 2010-2011 Mateusz Paprocki <mattpap@gmail.com>
  Copyright 2011 Christian Iversen <ci@sikkerhed.org>

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
**/

var tuple = __inherit(object, "tuple");

$PY.tuple = tuple;

tuple.PY$__init__ = function(seq) {
    if (arguments.length > 1) {
        throw py_builtins.TypeError("tuple() takes at most 1 argument (" + arguments.length + " given)");
    } else if (!defined(seq)) {
        this._items = [];
    } else {
        var that = this;
        this._items = [];
        iterate(seq, function(elm) {
                    if (typeof(elm) == 'number')
                        that._items.push(int(elm));
                    else if (typeof(elm) == 'string')
                        that._items.push(str(elm));
                    else
                        that._items.push(elm);
                });
    }
};

tuple.PY$__str__ = function () {
    if (js(this.PY$__len__()) === 0) {
        return str("()");
    } else if (js(this.PY$__len__()) == 1) {
        return str("(" + str(this._items[0]) + ",)");
    } else {
        var items = py_builtins.map(function (i) {return str(i);}, this._items);
        return str("(" + str(", ").PY$join(items) + ")");
    }
};

tuple.PY$__repr__ = tuple.PY$__str__;

tuple.PY$__eq__ = function (other) {
    if (other.PY$__class__ == this.PY$__class__) {
        if (js(py_builtins.len(this)) != js(py_builtins.len(other))) {
            return False;
        }
        var len = js(py_builtins.len(this));
        for (var i = 0; i < len; i++) {
            if (this._items[i].PY$__ne__(other._items[i]) == true) {
                return False;
            }
        }
        return True;
    } else {
        return False;
    }
};

tuple._js_ = function () {
    var items = [];

    iterate(this, function(item) {
        items.push(js(item));
    });

    return items;
};

tuple.PY$__hash__ = function () {
    var value = 0x345678;
    var length = js(this.PY$__len__());

    for (var index in this._items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ py_builtins.hash(this._items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

tuple.PY$__len__ = function() {
    return int(this._items.length);
};

tuple.PY$__iter__ = function() {
    return iter(this._items);
};

tuple.PY$__contains__ = function(item) {
    for (var index in this._items) {
        if (this._items[index].PY$__eq__(item) == true) {
            return True;
        }
    }

    return False;
};

tuple.PY$__getitem__ = function(index) {
    if (typeof(index) === 'number') index = int(index);
    var seq;
    if (py_builtins.isinstance(index, slice) == true) {
        var s = index;
        var inds = js(s.PY$indices(py_builtins.len(this)));
        var start = inds[0];
        var stop = inds[1];
        var step = inds[2];
        seq = [];
        for (var i = start; i < stop; i += step) {
            seq.push(this.PY$__getitem__(i));
        }
        return this.PY$__class__(seq);
    } else {
        if (py_builtins.isinstance(index, int) == false) {
            index = int(index);
        }

        if (js(index.PY$__ge__($c0)) && js(index.PY$__lt__(py_builtins.len(this)))) {
            return this._items[index.PY$__int__()];
        } else if (js(index.PY$__lt__($c0)) && js(index.PY$__ge__(py_builtins.len(this).PY$__neg__()))) {
            return this._items[index.PY$__add__(py_builtins.len(this)).PY$__int__()];
        } else {
            throw py_builtins.IndexError("list index out of range");
        }
    }
};

tuple.PY$__setitem__ = function() {
    throw py_builtins.TypeError("'tuple' object doesn't support item assignment");
};

tuple.PY$__delitem__ = function() {
    throw py_builtins.TypeError("'tuple' object doesn't support item deletion");
};

tuple.PY$count = function(value) {
    var count = 0;

    for (var index in this._items) {
        if (this._items[index].PY$__eq__(value) == true) {
            count += 1;
        }
    }

    return count;
};

tuple.PY$index = function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = start; !defined(end) || (start < end); i++) {
        var _value = this._items[i];

        if (!defined(_value)) {
            break;
        }

        if (_value.PY$__eq__(value) == true) {
            return i;
        }
    }

    throw py_builtins.ValueError("tuple.index(x): x not in list");
};
<commit_msg> + Added speed improvement in in tuple/list constructor: if passed a tuple or list, copy the internal objects instead of creating the entire iterator structure<commit_after>/**
  Copyright 2010-2011 Ondrej Certik <ondrej@certik.cz>
  Copyright 2010-2011 Mateusz Paprocki <mattpap@gmail.com>
  Copyright 2011 Christian Iversen <ci@sikkerhed.org>

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
**/

var tuple = __inherit(object, "tuple");

$PY.tuple = tuple;

tuple.PY$__init__ = function(seq) {
    if (arguments.length > 1) {
        throw py_builtins.TypeError("tuple() takes at most 1 argument (" + arguments.length + " given)");
    } else if (!defined(seq)) {
        this._items = [];
    } else if (seq.PY$__class__ === list || seq.PY$__class__ === tuple) {
        this._items = [];
        for (var i = 0; i < seq._items.length; i++) {
            this._items.push(seq._items[i]);
        }
    } else {
        var that = this;
        this._items = [];
        iterate(seq, function(elm) {
                    if (typeof(elm) == 'number')
                        that._items.push(int(elm));
                    else if (typeof(elm) == 'string')
                        that._items.push(str(elm));
                    else
                        that._items.push(elm);
                });
    }
};

tuple.PY$__str__ = function () {
    if (js(this.PY$__len__()) === 0) {
        return str("()");
    } else if (js(this.PY$__len__()) == 1) {
        return str("(" + str(this._items[0]) + ",)");
    } else {
        var items = py_builtins.map(function (i) {return str(i);}, this._items);
        return str("(" + str(", ").PY$join(items) + ")");
    }
};

tuple.PY$__repr__ = tuple.PY$__str__;

tuple.PY$__eq__ = function (other) {
    if (other.PY$__class__ == this.PY$__class__) {
        if (js(py_builtins.len(this)) != js(py_builtins.len(other))) {
            return False;
        }
        var len = js(py_builtins.len(this));
        for (var i = 0; i < len; i++) {
            if (this._items[i].PY$__ne__(other._items[i]) == true) {
                return False;
            }
        }
        return True;
    } else {
        return False;
    }
};

tuple._js_ = function () {
    var items = [];

    iterate(this, function(item) {
        items.push(js(item));
    });

    return items;
};

tuple.PY$__hash__ = function () {
    var value = 0x345678;
    var length = js(this.PY$__len__());

    for (var index in this._items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ py_builtins.hash(this._items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

tuple.PY$__len__ = function() {
    return int(this._items.length);
};

tuple.PY$__iter__ = function() {
    return iter(this._items);
};

tuple.PY$__contains__ = function(item) {
    for (var index in this._items) {
        if (this._items[index].PY$__eq__(item) == true) {
            return True;
        }
    }

    return False;
};

tuple.PY$__getitem__ = function(index) {
    if (typeof(index) === 'number') index = int(index);
    var seq;
    if (py_builtins.isinstance(index, slice) == true) {
        var s = index;
        var inds = js(s.PY$indices(py_builtins.len(this)));
        var start = inds[0];
        var stop = inds[1];
        var step = inds[2];
        seq = [];
        for (var i = start; i < stop; i += step) {
            seq.push(this.PY$__getitem__(i));
        }
        return this.PY$__class__(seq);
    } else {
        if (py_builtins.isinstance(index, int) == false) {
            index = int(index);
        }

        if (js(index.PY$__ge__($c0)) && js(index.PY$__lt__(py_builtins.len(this)))) {
            return this._items[index.PY$__int__()];
        } else if (js(index.PY$__lt__($c0)) && js(index.PY$__ge__(py_builtins.len(this).PY$__neg__()))) {
            return this._items[index.PY$__add__(py_builtins.len(this)).PY$__int__()];
        } else {
            throw py_builtins.IndexError("list index out of range");
        }
    }
};

tuple.PY$__setitem__ = function() {
    throw py_builtins.TypeError("'tuple' object doesn't support item assignment");
};

tuple.PY$__delitem__ = function() {
    throw py_builtins.TypeError("'tuple' object doesn't support item deletion");
};

tuple.PY$count = function(value) {
    var count = 0;

    for (var index in this._items) {
        if (this._items[index].PY$__eq__(value) == true) {
            count += 1;
        }
    }

    return count;
};

tuple.PY$index = function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = start; !defined(end) || (start < end); i++) {
        var _value = this._items[i];

        if (!defined(_value)) {
            break;
        }

        if (_value.PY$__eq__(value) == true) {
            return i;
        }
    }

    throw py_builtins.ValueError("tuple.index(x): x not in list");
};
<|endoftext|>


<commit_before>/**
  Copyright 2010-2011 Ondrej Certik <ondrej@certik.cz>
  Copyright 2010-2011 Mateusz Paprocki <mattpap@gmail.com>
  Copyright 2011 Christian Iversen <ci@sikkerhed.org>

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
**/

var tuple = __inherit(object, "tuple");

tuple.prototype.__init__ = function(seq) {

    if (arguments.length > 1) {
        throw py_builtins.TypeError.__call__("tuple() takes at most 1 argument (" + arguments.length + " given)");
    } else if (!defined(seq)) {
        this._items = [];
    } else {
        var count = 0;
        var that = this;
        this._items = [];
        iterate(iter.__call__(seq), function(elm) {
                    if (typeof(elm) == 'number')
                        that._items[count++] = _int.__call__(elm);
                    else if (typeof(elm) == 'string')
                        that._items[count++] = str.__call__(elm);
                    else
                        that._items[count++] = elm;
                });
    }
};

tuple.prototype.__str__ = function () {
    if (js(this.__len__()) === 0) {
        return str.__call__("()");
    } else if (js(this.__len__()) == 1) {
        return str.__call__("(" + str.__call__(this._items[0]) + ",)");
    } else {
        var items = map(function (i) {return str.__call__(i);}, this._items);
        return str.__call__("(" + str.__call__(", ").join(items) + ")");
    }
};

tuple.prototype.__repr__ = tuple.prototype.__str__;

tuple.prototype.__eq__ = function (other) {
    if (other.__class__ == this.__class__) {
        if (js(len(this)) != js(len(other))) {
            return False;
        }
        for (var i = 0; i < js(len(this)); i++) {
            if (js(this._items[i].__ne__(other._items[i]))) {
                return False;
            }
        }
        return True;
        // This doesn't take into account hash collisions:
        //return hash(this) == hash(other)
    } else {
        return False;
    }
};

tuple.prototype._js_ = function () {
    var items = [];

    iterate(iter.__call__(this), function(item) {
        items.push(js(item));
    });

    return items;
};

tuple.prototype.__hash__ = function () {
    var value = 0x345678;
    var length = js(this.__len__());

    for (var index in this._items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ hash(this._items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

tuple.prototype.__len__ = function() {
    return _int.__call__(this._items.length);
};

tuple.prototype.__iter__ = function() {
    return iter.__call__(this._items);
};

tuple.prototype.__contains__ = function(item) {
    for (var index in this._items) {
        if (js(py_builtins.eq(item, this._items[index]))) {
            return True;
        }
    }

    return False;
};

tuple.prototype.__getitem__ = function(index) {
    if (typeof(index) === 'number') index = _int.__call__(index);
    var seq;
    if (js(isinstance.__call__(index, slice))) {
        var s = index;
        var inds = js(s.indices(len(this)));
        var start = inds[0];
        var stop = inds[1];
        var step = inds[2];
        seq = [];
        for (var i = js(start); i < js(stop); i += js(step)) {
            seq.push(this.__getitem__(i));
        }
        return this.__class__.__call__(seq);
    } else {
        if (!js(isinstance.__call__(index, _int)))
            index = _int.__call__(index);

        if (js(index.__ge__(_int.__call__(0)).__and__(index.__lt__(len(this))))) {
            return this._items[index.__int__()];
        } else if (js(index.__lt__(_int.__call__(0)).__and__(index.__ge__(len(this).__neg__())))) {
            return this._items[index.__add__(len(this)).__int__()];
        } else {
            throw py_builtins.IndexError.__call__("list index out of range");
        }
    }
};

tuple.prototype.__setitem__ = function(index, value) {
    throw py_builtins.TypeError.__call__("'tuple' object doesn't support item assignment");
};

tuple.prototype.__delitem__ = function(index) {
    throw py_builtins.TypeError.__call__("'tuple' object doesn't support item deletion");
};

tuple.prototype.count = Function(function(value) {
    var count = 0;

    for (var index in this._items) {
        if (js(this._items[index].__eq__(value))) {
            count += 1;
        }
    }

    return count;
});

tuple.prototype.index = Function(function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = start; !defined(end) || (start < end); i++) {
        var _value = this._items[i];

        if (!defined(_value)) {
            break;
        }

        if (js(_value.__eq__(value))) {
            return i;
        }
    }

    throw py_builtins.ValueError.__call__("tuple.index(x): x not in list");
});
<commit_msg> * Simplified tuple constructor<commit_after>/**
  Copyright 2010-2011 Ondrej Certik <ondrej@certik.cz>
  Copyright 2010-2011 Mateusz Paprocki <mattpap@gmail.com>
  Copyright 2011 Christian Iversen <ci@sikkerhed.org>

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
**/

var tuple = __inherit(object, "tuple");

tuple.prototype.__init__ = function(seq) {

    if (arguments.length > 1) {
        throw py_builtins.TypeError.__call__("tuple() takes at most 1 argument (" + arguments.length + " given)");
    } else if (!defined(seq)) {
        this._items = [];
    } else {
        var that = this;
        this._items = [];
        iterate(iter.__call__(seq), function(elm) {
                    if (typeof(elm) == 'number')
                        that._items.push(_int.__call__(elm));
                    else if (typeof(elm) == 'string')
                        that._items.push(str.__call__(elm));
                    else
                        that._items.push(elm);
                });
    }
};

tuple.prototype.__str__ = function () {
    if (js(this.__len__()) === 0) {
        return str.__call__("()");
    } else if (js(this.__len__()) == 1) {
        return str.__call__("(" + str.__call__(this._items[0]) + ",)");
    } else {
        var items = map(function (i) {return str.__call__(i);}, this._items);
        return str.__call__("(" + str.__call__(", ").join(items) + ")");
    }
};

tuple.prototype.__repr__ = tuple.prototype.__str__;

tuple.prototype.__eq__ = function (other) {
    if (other.__class__ == this.__class__) {
        if (js(len(this)) != js(len(other))) {
            return False;
        }
        for (var i = 0; i < js(len(this)); i++) {
            if (js(this._items[i].__ne__(other._items[i]))) {
                return False;
            }
        }
        return True;
        // This doesn't take into account hash collisions:
        //return hash(this) == hash(other)
    } else {
        return False;
    }
};

tuple.prototype._js_ = function () {
    var items = [];

    iterate(iter.__call__(this), function(item) {
        items.push(js(item));
    });

    return items;
};

tuple.prototype.__hash__ = function () {
    var value = 0x345678;
    var length = js(this.__len__());

    for (var index in this._items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ hash(this._items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

tuple.prototype.__len__ = function() {
    return _int.__call__(this._items.length);
};

tuple.prototype.__iter__ = function() {
    return iter.__call__(this._items);
};

tuple.prototype.__contains__ = function(item) {
    for (var index in this._items) {
        if (js(py_builtins.eq(item, this._items[index]))) {
            return True;
        }
    }

    return False;
};

tuple.prototype.__getitem__ = function(index) {
    if (typeof(index) === 'number') index = _int.__call__(index);
    var seq;
    if (js(isinstance.__call__(index, slice))) {
        var s = index;
        var inds = js(s.indices(len(this)));
        var start = inds[0];
        var stop = inds[1];
        var step = inds[2];
        seq = [];
        for (var i = js(start); i < js(stop); i += js(step)) {
            seq.push(this.__getitem__(i));
        }
        return this.__class__.__call__(seq);
    } else {
        if (!js(isinstance.__call__(index, _int)))
            index = _int.__call__(index);

        if (js(index.__ge__(_int.__call__(0)).__and__(index.__lt__(len(this))))) {
            return this._items[index.__int__()];
        } else if (js(index.__lt__(_int.__call__(0)).__and__(index.__ge__(len(this).__neg__())))) {
            return this._items[index.__add__(len(this)).__int__()];
        } else {
            throw py_builtins.IndexError.__call__("list index out of range");
        }
    }
};

tuple.prototype.__setitem__ = function(index, value) {
    throw py_builtins.TypeError.__call__("'tuple' object doesn't support item assignment");
};

tuple.prototype.__delitem__ = function(index) {
    throw py_builtins.TypeError.__call__("'tuple' object doesn't support item deletion");
};

tuple.prototype.count = Function(function(value) {
    var count = 0;

    for (var index in this._items) {
        if (js(this._items[index].__eq__(value))) {
            count += 1;
        }
    }

    return count;
});

tuple.prototype.index = Function(function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = start; !defined(end) || (start < end); i++) {
        var _value = this._items[i];

        if (!defined(_value)) {
            break;
        }

        if (js(_value.__eq__(value))) {
            return i;
        }
    }

    throw py_builtins.ValueError.__call__("tuple.index(x): x not in list");
});
<|endoftext|>


<commit_before>var controller = function($scope, $log, $rootScope, $modal, growl, $window, $timeout, $analytics,
  $q, Post, $sce, UserMentions, Comment, $dialog, CurrentUser) {

  var post = $scope.post;

  if (!post.comments) {
    $scope.loading = true;

    Post.findComments({id: post.id}, function(comments) {
      post.comments = comments;
      $scope.loading = false;
    }, function(resp) {
      if (_.contains([401, 403], resp.status)) {
        $scope.$emit('unauthorized', {context: 'comment'});
      }
    });
  }

  $scope.currentUser = CurrentUser.get();

  $scope.canDelete = function(comment) {
    if (!CurrentUser.isLoggedIn()) return false;
    if (CurrentUser.is(comment.user.id)) return true;
    return CurrentUser.get().canModerate(post.community);
  };

  $scope.commentOwner = function(comment) {
    return CurrentUser.is(comment.user.id);
  };

  $scope.create = function() {
    if ($scope.commentLength() > 0) {
      $scope.createDisabled = true;
      Post.comment({id: post.id, text: $scope.commentInput.trim()}, function(comment) {
        post.comments.push(comment);
        post.numComments++;

        $scope.commentInput = '';
        $scope.createDisabled = false;
        $scope.commenting = false;
        $scope.hasMention = false;

        $analytics.eventTrack('Post: Comment: Add', {post_id: post.id, has_mention: $scope.hasMention});

        if (!_.findWhere(post.followers, {id: comment.user.id})) {
          post.followers.push(comment.user);
        }

      }, function() {
        $scope.createDisabled = false;
        growl.addErrorMessage("Error posting comment.  Please try again later", {ttl: 5000});
        $analytics.eventTrack('Post: Comment: Adding a Comment Failed.', {post_id: post.id});
      });
    }
  };

  $scope.thank = function(comment) {
    comment.isThanked = !comment.isThanked;

    Comment.thank({id: comment.id}, function() {
      $analytics.eventTrack('Post: Comment: Thank', {
        post_id: post.id,
        comment_id: comment.id,
        state: (comment.isThanked ? 'on' : 'off')
      });
    });
  };

  $scope['delete'] = function(comment) {
    $dialog.confirm({
      message: 'Are you sure you want to remove this comment? This cannot be undone.'
    }).then(function() {
      growl.addSuccessMessage("Comment deleted.", {ttl: 5000});
      Comment.delete({id: comment.id}, function() {
        $analytics.eventTrack('Post: Comment: Delete', {
          post_id: post.id,
          comment_id: comment.id,
          comment_text: comment.comment_text
        });
        post.comments.splice(post.comments.indexOf(comment), 1);
        post.numComments--;
      });
    });
  };

  $scope.searchPeople = function(query) {
    var context, id;
    if ($rootScope.userMentionContext) {
      context = $rootScope.userMentionContext.context;
      id = $rootScope.userMentionContext.id;
    } else {
      context = 'community';
      id = post.community.id;
    }
    UserMentions.searchPeople(query, context, id).$promise.then(function(items) {
      $scope.people = items;
    });
  };

  $scope.getPeopleTextRaw = function(user) {
    $analytics.eventTrack('Post: Comment: @-mention: Lookup', {query: user.name});
    $scope.hasMention = true;
    return UserMentions.userTextRaw(user);
  };

  $scope.commentLength = function() {
    return angular.element('
' + ($scope.commentInput || '') + '
').text().length;
  }
};

module.exports = function(angularModule) {
  angularModule.controller('CommentsCtrl', controller);
};
<commit_msg>less indentation<commit_after>var controller = function($scope, $log, $rootScope, $modal, growl, $window, $timeout, $analytics,
  $q, Post, $sce, UserMentions, Comment, $dialog, CurrentUser) {

  var post = $scope.post;

  if (!post.comments) {
    $scope.loading = true;

    Post.findComments({id: post.id}, function(comments) {
      post.comments = comments;
      $scope.loading = false;
    }, function(resp) {
      if (_.contains([401, 403], resp.status)) {
        $scope.$emit('unauthorized', {context: 'comment'});
      }
    });
  }

  $scope.currentUser = CurrentUser.get();

  $scope.canDelete = function(comment) {
    if (!CurrentUser.isLoggedIn()) return false;
    if (CurrentUser.is(comment.user.id)) return true;
    return CurrentUser.get().canModerate(post.community);
  };

  $scope.commentOwner = function(comment) {
    return CurrentUser.is(comment.user.id);
  };

  $scope.create = function() {
    if ($scope.commentLength() == 0) return;

    $scope.createDisabled = true;
    Post.comment({id: post.id, text: $scope.commentInput.trim()}, function(comment) {
      post.comments.push(comment);
      post.numComments++;

      $scope.commentInput = '';
      $scope.createDisabled = false;
      $scope.commenting = false;
      $scope.hasMention = false;

      $analytics.eventTrack('Post: Comment: Add', {post_id: post.id, has_mention: $scope.hasMention});

      if (!_.findWhere(post.followers, {id: comment.user.id})) {
        post.followers.push(comment.user);
      }

    }, function() {
      $scope.createDisabled = false;
      growl.addErrorMessage("Error posting comment.  Please try again later", {ttl: 5000});
      $analytics.eventTrack('Post: Comment: Adding a Comment Failed.', {post_id: post.id});
    });
  };

  $scope.thank = function(comment) {
    comment.isThanked = !comment.isThanked;

    Comment.thank({id: comment.id}, function() {
      $analytics.eventTrack('Post: Comment: Thank', {
        post_id: post.id,
        comment_id: comment.id,
        state: (comment.isThanked ? 'on' : 'off')
      });
    });
  };

  $scope['delete'] = function(comment) {
    $dialog.confirm({
      message: 'Are you sure you want to remove this comment? This cannot be undone.'
    }).then(function() {
      growl.addSuccessMessage("Comment deleted.", {ttl: 5000});
      Comment.delete({id: comment.id}, function() {
        $analytics.eventTrack('Post: Comment: Delete', {
          post_id: post.id,
          comment_id: comment.id,
          comment_text: comment.comment_text
        });
        post.comments.splice(post.comments.indexOf(comment), 1);
        post.numComments--;
      });
    });
  };

  $scope.searchPeople = function(query) {
    var context, id;
    if ($rootScope.userMentionContext) {
      context = $rootScope.userMentionContext.context;
      id = $rootScope.userMentionContext.id;
    } else {
      context = 'community';
      id = post.community.id;
    }
    UserMentions.searchPeople(query, context, id).$promise.then(function(items) {
      $scope.people = items;
    });
  };

  $scope.getPeopleTextRaw = function(user) {
    $analytics.eventTrack('Post: Comment: @-mention: Lookup', {query: user.name});
    $scope.hasMention = true;
    return UserMentions.userTextRaw(user);
  };

  $scope.commentLength = function() {
    return angular.element('
' + ($scope.commentInput || '') + '
').text().length;
  }
};

module.exports = function(angularModule) {
  angularModule.controller('CommentsCtrl', controller);
};
<|endoftext|>


<commit_before>/* global HTMLSlotElement */

import WebComponent from './web-component'
import MotorHTMLNode from './node'
import { observeChildren, getShadowRootVersion, hasShadowDomV0, hasShadowDomV1,
    getAncestorShadowRootIfAny } from '../motor/Utility'

var DeclarativeBase

// Override HTMLElement.prototype.attachShadow in v1, and
// HTMLElement.prototype.createShadowRoot in v0, so that we can make a Map of
// motor- elements to their shadow roots, so we can always get a reference to
// the element's shadow root even if it is closed.
const observers = new WeakMap
function hijack(original) {
    return function(...args) {
        // In v0, shadow roots can be replaced, but in v1 calling attachShadow
        // on an element that already has a root throws. So, we can set this to
        // true, and if the try-catch passes then we know we have a v0 root and
        // that the root was just replaced.
        const oldRoot = this.shadowRoot
        let root = null
        try {
            root = original.call(this, ...args)
        }
        catch (e) { throw e }
        if (this instanceof DeclarativeBase) {
            this._hasShadowRoot = true
            if (oldRoot) {
                onV0ShadowRootReplaced.call(this, oldRoot)
            }
            const observer = observeChildren(root, shadowRootChildAdded.bind(this), shadowRootChildRemoved.bind(this))
            observers.set(root, observer)

            for (const child of this.children) {
                if (child instanceof DeclarativeBase) {
                    child._isPossiblyDistributed = true
                }
            }
        }
        return root
    }
}
function shadowRootChildAdded(child) {
    if (!(child instanceof DeclarativeBase)) return
    this.imperativeCounterpart.addChild(child.imperativeCounterpart)
}
function shadowRootChildRemoved(child) {
    if (!(child instanceof DeclarativeBase)) return
    this.imperativeCounterpart.removeChild(child.imperativeCounterpart)
}
function onV0ShadowRootReplaced(oldRoot) {
    observers.get(oldRoot).disconnect()
    observers.delete(oldRoot)
    let i = 0
    for (let child of oldRoot.childNodes) {
        if (child instanceof DeclarativeBase) {
            // We should disconnect the imperative connection (f.e. so it is
            // not rendered in WebGL)...
            this.imperativeCounterpart.removeChild(child.imperativeCounterpart)
            // ...but we should place the element back where it was so there's
            // no surprises to the HTML-API user who might go looking for the
            // element. Due to the fact that the observer on the oldRoot was
            // removed, adding the element back to the oldRoot won't cause it
            // to be reconnected on the imperative side.
            oldRoot.insertBefore(child, oldRoot.childNodes[i])
        }
        i += 1
    }
}
if (HTMLElement.prototype.createShadowRoot instanceof Function)
    HTMLElement.prototype.createShadowRoot = hijack(HTMLElement.prototype.createShadowRoot)
if (HTMLElement.prototype.attachShadow instanceof Function)
    HTMLElement.prototype.attachShadow = hijack(HTMLElement.prototype.attachShadow)

// ... Little did I know that the `WebComponent` function I made is
// considered a form of mixin. ...
// TODO: follow the mixin pattern as with Node and Scene classes.

initMotorHTMLBase()
export function initMotorHTMLBase() {
    if (DeclarativeBase) return

    /**
     * @implements {EventListener}
     */
    DeclarativeBase = class DeclarativeBase extends WebComponent(window.HTMLElement) {
        createdCallback() {
            super.createdCallback()

            this.imperativeCounterpart = null // to hold the imperative API Node instance.

            // true if this node has a shadow root (even if it is "closed", see
            // hijack function above). Once true always true because shadow
            // roots cannot be removed.
            this._hasShadowRoot = false

            // True when this node has a parent that has a shadow root. When
            // using the HTML API, Imperative API can look at this to determine
            // whether to render this node or not, in the case of WebGL.
            this._isPossiblyDistributed = false

            // A map of the slot elements that are children of this node and
            // their last-known assigned nodes. When a slotchange happens while
            // this node is in a shadow root and has a slot child, we can
            // detect what the difference is between the last known and the new
            // assignments, and notate the new distribution of child nodes. See
            // issue #40 for background on why we do this.
            this._slotElementsAssignedNodes = new WeakMap

            // If this node is distributed into a shadow tree, this will
            // reference the parent of the <slot> or <content> element.
            // Basically, this node will render as a child of that parent node
            // in the flat tree.
            this._shadowParent = null

            // If this element has a child <slot> or <content> element while in
            // a shadow root, then this will be a Set of the nodes distributed
            // into the <slot> or <content>, and those nodes render relatively
            // to this node in the flat tree. We instantiate this later, only
            // when/if needed.
            this._shadowChildren = null

            // XXX: "this.ready" seems to be more intuitive on the HTML side than
            // "this.mountPromise" because if the user has a reference to a
            // motor-node or a motor-scene and it exists in DOM, then it is already
            // "mounted" from the HTML API perspective although not necessarily
            // ready because `connectedCallback`. Maybe we can use "mountPromise"
            // for the imperative API, and "ready" for the HTML API. For example:
            //
            // await $('motor-scene')[0].ready // When using the HTML API
            // await node.mountPromise // When using the imperative API
            //
            // Or, maybe we can just use ".ready" in both APIs?...
            this._resolveReadyPromise = null
            this.ready = new Promise(r => this._resolveReadyPromise = r)
        }

        // called by WebComponent#connectedCallback()
        init() {

            // XXX: we call this._associateImperativeNode() before super.init() because
            // super.init() may call this.childConnectedCallback() which depends
            // on the imperative counterpart existing.
            this._associateImperativeNode()

            super.init()
        }

        /**
         * This method creates the association between this MotorHTMLNode instance
         * and the imperative Node instance.
         *
         * This method may get called by this.init, but can also be called by
         * the Node class if Node is used imperatively. See Node#constructor.
         *
         * @private
         *
         * @param {Object} imperativeCounterpart The imperative counterpart to
         * associate with this MotorHTML element. This parameter is only used in the
         * imperative API constructors, and this happens when using the imperative
         * form of infamous instead of the HTML interface to infamous. When the HTML
         * interface is used, this gets called first without an
         * imperativeCounterpart argument and the call to this in an imperative
         * constructor will be a noop. Basically, either this gets called first by a
         * MotorHTML element, or first by an imperative instance, depending on which
         * API is used first.
         */
        _associateImperativeNode(imperativeCounterpart) {
            // if the association is made already, noop
            if (this.imperativeCounterpart) return

            // if called from an imperative-side class' constructor, associate
            // the passed instance.
            if (imperativeCounterpart) this.imperativeCounterpart = imperativeCounterpart

            // otherwise if called from a MotorHTML class without an argument
            else this.imperativeCounterpart = this._makeImperativeCounterpart()

            this._signalWhenReady()
        }

        /**
         * This method should be overriden by child classes. It should return the
         * imperative-side instance that the HTML-side class (this) corresponds to.
         * @abstract
         */
        _makeImperativeCounterpart() {
            throw new TypeError('This method should be implemented by classes extending DeclarativeBase.')
        }

        async _signalWhenReady() {
            await this.imperativeCounterpart.mountPromise
            this._resolveReadyPromise()
        }

        childConnectedCallback(child) {

            // mirror the DOM connections in the imperative API's virtual scene graph.
            if (child instanceof MotorHTMLNode) {
                if (this._hasShadowRoot) child._isPossiblyDistributed = true
                this.imperativeCounterpart.addChild(child.imperativeCounterpart)
            }

            // TODO: There's no way currently to detect v0 vs v1 ShadowRoots,
            // so these conditional checks assume the end user is using
            // <content> elements in v0 roots, and <slot> elements in v1 roots.
            // Doing otherwise may have unknown and undersirable behavior. See
            // the TODO for getShadowRootVersion in ../motor/Utility for more
            // info.
            else if (
                hasShadowDomV0
                && child instanceof HTMLContentElement
                &&
                //getShadowRootVersion(
                    getAncestorShadowRootIfAny(this)
                //) == 'v0'
            ) {
                // TODO observe <content> elements.
            }
            else if (
                hasShadowDomV1
                && child instanceof HTMLSlotElement
                &&
                //getShadowRootVersion(
                    getAncestorShadowRootIfAny(this)
                //) == 'v1'
            ) {
                child.addEventListener('slotchange', this)
                this._handleDistributedChildren(child)
            }
        }

        // This method is part of the EventListener interface.
        handleEvent(event) {
            if (event.type == 'slotchange') {
                const slot = event.target
                this._handleDistributedChildren(slot)
            }
        }

        _handleDistributedChildren(slot) {
            const diff = this._getDistributedChildDifference(slot)

            for (const addedNode of diff.added) {
                if (!(addedNode instanceof DeclarativeBase)) continue

                // We do this because if the given slot is assigned to another
                // slot, then this logic will run again for the next slot on
                // that next slot's slotchange, so we remove the distributed
                // node from the previous shadowParent and add it to the next
                // one. If we don't do this, then the distributed node will
                // exist in multiple shadowChildren lists when there is a
                // chain of assigned slots. For more info, see
                // https://github.com/w3c/webcomponents/issues/611
                if (addedNode._shadowParent && addedNode._shadowParent._shadowChildren) {
                    addedNode._shadowParent._shadowChildren.delete(addedNode)
                    if (!addedNode._shadowParent._shadowChildren.size)
                        addedNode._shadowParent._shadowChildren = null
                }

                addedNode._shadowParent = this
                if (!this._shadowChildren) this._shadowChildren = new Set
                this._shadowChildren.add(addedNode)
            }

            for (const removedNode of diff.removed) {
                if (!(removedNode instanceof DeclarativeBase)) continue
                removedNode._shadowParent = null
                this._shadowChildren.delete(removedNode)
                if (!this._shadowChildren.size) this._shadowChildren = null
            }
        }

        _getDistributedChildDifference(slot) {
            let previousNodes

            if (this._slotElementsAssignedNodes.has(slot))
                previousNodes = this._slotElementsAssignedNodes.get(slot)
            else
                previousNodes = []

            const newNodes = slot.assignedNodes({flatten: true})

            // save the newNodes to be used as the previousNodes for next time.
            this._slotElementsAssignedNodes.set(slot, newNodes)

            const diff = {
                removed: [],
            }

            for (let i=0, l=previousNodes.length; i<l; i+=1) {
                let oldNode = previousNodes[i]
                let newIndex = newNodes.indexOf(oldNode)

                // if it exists in the previousNodes but not the newNodes, then
                // the node was removed.
                if (!(newIndex >= 0)) {
                    diff.removed.push(oldNode)
                }

                // otherwise the node wasn't added or removed.
                else {
                    newNodes.splice(i, 1)
                }
            }

            // Remaining nodes in newNodes must have been added.
            diff.added = newNodes

            return diff
        }

        childDisconnectedCallback(child) {
            // mirror the connection in the imperative API's virtual scene graph.
            if (child instanceof MotorHTMLNode) {
                child._isPossiblyDistributed = false
                this.imperativeCounterpart.removeChild(child.imperativeCounterpart)
            }
            else if (
                hasShadowDomV0
                && child instanceof HTMLContentElement
                &&
                //getShadowRootVersion(
                    getAncestorShadowRootIfAny(this)
                //) == 'v0'
            ) {
                // TODO: unobserve <content> element
            }
            else if (
                hasShadowDomV1
                && child instanceof HTMLSlotElement
                &&
                //getShadowRootVersion(
                    getAncestorShadowRootIfAny(this)
                //) == 'v1'
            ) {
                child.removeEventListener('slotchange', this)
                this._handleDistributedChildren(child)
                this._slotElementsAssignedNodes.delete(child)
            }
        }
    }
}

export {DeclarativeBase as default}
<commit_msg>Less indentation and cleaner code with reversed conditional checks.<commit_after>/* global HTMLSlotElement */

import WebComponent from './web-component'
import MotorHTMLNode from './node'
import { observeChildren, getShadowRootVersion, hasShadowDomV0, hasShadowDomV1,
    getAncestorShadowRootIfAny } from '../motor/Utility'

var DeclarativeBase

// Override HTMLElement.prototype.attachShadow in v1, and
// HTMLElement.prototype.createShadowRoot in v0, so that we can make a Map of
// motor- elements to their shadow roots, so we can always get a reference to
// the element's shadow root even if it is closed.
const observers = new WeakMap
function hijack(original) {
    return function(...args) {
        // In v0, shadow roots can be replaced, but in v1 calling attachShadow
        // on an element that already has a root throws. So, we can set this to
        // true, and if the try-catch passes then we know we have a v0 root and
        // that the root was just replaced.
        const oldRoot = this.shadowRoot
        let root = null
        try {
            root = original.call(this, ...args)
        }
        catch (e) { throw e }
        if (this instanceof DeclarativeBase) {
            this._hasShadowRoot = true
            if (oldRoot) {
                onV0ShadowRootReplaced.call(this, oldRoot)
            }
            const observer = observeChildren(root, shadowRootChildAdded.bind(this), shadowRootChildRemoved.bind(this))
            observers.set(root, observer)

            for (const child of this.children) {
                if (!(child instanceof DeclarativeBase)) continue
                child._isPossiblyDistributed = true
            }
        }
        return root
    }
}
function shadowRootChildAdded(child) {
    if (!(child instanceof DeclarativeBase)) return
    this.imperativeCounterpart.addChild(child.imperativeCounterpart)
}
function shadowRootChildRemoved(child) {
    if (!(child instanceof DeclarativeBase)) return
    this.imperativeCounterpart.removeChild(child.imperativeCounterpart)
}
function onV0ShadowRootReplaced(oldRoot) {
    observers.get(oldRoot).disconnect()
    observers.delete(oldRoot)
    let i = 0
    for (let child of oldRoot.childNodes) {
        if (!(child instanceof DeclarativeBase)) { i += 1; continue }

        // We should disconnect the imperative connection (f.e. so it is
        // not rendered in WebGL)...
        this.imperativeCounterpart.removeChild(child.imperativeCounterpart)

        // ...but we should place the element back where it was so there's
        // no surprises to the HTML-API user who might go looking for the
        // element. Due to the fact that the observer on the oldRoot was
        // removed, adding the element back to the oldRoot won't cause it
        // to be reconnected on the imperative side.
        oldRoot.insertBefore(child, oldRoot.childNodes[i])

        i += 1
    }
}
if (HTMLElement.prototype.createShadowRoot instanceof Function)
    HTMLElement.prototype.createShadowRoot = hijack(HTMLElement.prototype.createShadowRoot)
if (HTMLElement.prototype.attachShadow instanceof Function)
    HTMLElement.prototype.attachShadow = hijack(HTMLElement.prototype.attachShadow)

// ... Little did I know that the `WebComponent` function I made is
// considered a form of mixin. ...
// TODO: follow the mixin pattern as with Node and Scene classes.

initMotorHTMLBase()
export function initMotorHTMLBase() {
    if (DeclarativeBase) return

    /**
     * @implements {EventListener}
     */
    DeclarativeBase = class DeclarativeBase extends WebComponent(window.HTMLElement) {
        createdCallback() {
            super.createdCallback()

            this.imperativeCounterpart = null // to hold the imperative API Node instance.

            // true if this node has a shadow root (even if it is "closed", see
            // hijack function above). Once true always true because shadow
            // roots cannot be removed.
            this._hasShadowRoot = false

            // True when this node has a parent that has a shadow root. When
            // using the HTML API, Imperative API can look at this to determine
            // whether to render this node or not, in the case of WebGL.
            this._isPossiblyDistributed = false

            // A map of the slot elements that are children of this node and
            // their last-known assigned nodes. When a slotchange happens while
            // this node is in a shadow root and has a slot child, we can
            // detect what the difference is between the last known and the new
            // assignments, and notate the new distribution of child nodes. See
            // issue #40 for background on why we do this.
            this._slotElementsAssignedNodes = new WeakMap

            // If this node is distributed into a shadow tree, this will
            // reference the parent of the <slot> or <content> element.
            // Basically, this node will render as a child of that parent node
            // in the flat tree.
            this._shadowParent = null

            // If this element has a child <slot> or <content> element while in
            // a shadow root, then this will be a Set of the nodes distributed
            // into the <slot> or <content>, and those nodes render relatively
            // to this node in the flat tree. We instantiate this later, only
            // when/if needed.
            this._shadowChildren = null

            // XXX: "this.ready" seems to be more intuitive on the HTML side than
            // "this.mountPromise" because if the user has a reference to a
            // motor-node or a motor-scene and it exists in DOM, then it is already
            // "mounted" from the HTML API perspective although not necessarily
            // ready because `connectedCallback`. Maybe we can use "mountPromise"
            // for the imperative API, and "ready" for the HTML API. For example:
            //
            // await $('motor-scene')[0].ready // When using the HTML API
            // await node.mountPromise // When using the imperative API
            //
            // Or, maybe we can just use ".ready" in both APIs?...
            this._resolveReadyPromise = null
            this.ready = new Promise(r => this._resolveReadyPromise = r)
        }

        // called by WebComponent#connectedCallback()
        init() {

            // XXX: we call this._associateImperativeNode() before super.init() because
            // super.init() may call this.childConnectedCallback() which depends
            // on the imperative counterpart existing.
            this._associateImperativeNode()

            super.init()
        }

        /**
         * This method creates the association between this MotorHTMLNode instance
         * and the imperative Node instance.
         *
         * This method may get called by this.init, but can also be called by
         * the Node class if Node is used imperatively. See Node#constructor.
         *
         * @private
         *
         * @param {Object} imperativeCounterpart The imperative counterpart to
         * associate with this MotorHTML element. This parameter is only used in the
         * imperative API constructors, and this happens when using the imperative
         * form of infamous instead of the HTML interface to infamous. When the HTML
         * interface is used, this gets called first without an
         * imperativeCounterpart argument and the call to this in an imperative
         * constructor will be a noop. Basically, either this gets called first by a
         * MotorHTML element, or first by an imperative instance, depending on which
         * API is used first.
         */
        _associateImperativeNode(imperativeCounterpart) {
            // if the association is made already, noop
            if (this.imperativeCounterpart) return

            // if called from an imperative-side class' constructor, associate
            // the passed instance.
            if (imperativeCounterpart) this.imperativeCounterpart = imperativeCounterpart

            // otherwise if called from a MotorHTML class without an argument
            else this.imperativeCounterpart = this._makeImperativeCounterpart()

            this._signalWhenReady()
        }

        /**
         * This method should be overriden by child classes. It should return the
         * imperative-side instance that the HTML-side class (this) corresponds to.
         * @abstract
         */
        _makeImperativeCounterpart() {
            throw new TypeError('This method should be implemented by classes extending DeclarativeBase.')
        }

        async _signalWhenReady() {
            await this.imperativeCounterpart.mountPromise
            this._resolveReadyPromise()
        }

        childConnectedCallback(child) {

            // mirror the DOM connections in the imperative API's virtual scene graph.
            if (child instanceof MotorHTMLNode) {
                if (this._hasShadowRoot) child._isPossiblyDistributed = true
                this.imperativeCounterpart.addChild(child.imperativeCounterpart)
            }

            // TODO: There's no way currently to detect v0 vs v1 ShadowRoots,
            // so these conditional checks assume the end user is using
            // <content> elements in v0 roots, and <slot> elements in v1 roots.
            // Doing otherwise may have unknown and undersirable behavior. See
            // the TODO for getShadowRootVersion in ../motor/Utility for more
            // info.
            else if (
                hasShadowDomV0
                && child instanceof HTMLContentElement
                &&
                //getShadowRootVersion(
                    getAncestorShadowRootIfAny(this)
                //) == 'v0'
            ) {
                // TODO observe <content> elements.
            }
            else if (
                hasShadowDomV1
                && child instanceof HTMLSlotElement
                &&
                //getShadowRootVersion(
                    getAncestorShadowRootIfAny(this)
                //) == 'v1'
            ) {
                child.addEventListener('slotchange', this)
                this._handleDistributedChildren(child)
            }
        }

        // This method is part of the EventListener interface.
        handleEvent(event) {
            if (event.type == 'slotchange') {
                const slot = event.target
                this._handleDistributedChildren(slot)
            }
        }

        _handleDistributedChildren(slot) {
            const diff = this._getDistributedChildDifference(slot)

            for (const addedNode of diff.added) {
                if (!(addedNode instanceof DeclarativeBase)) continue

                // We do this because if the given slot is assigned to another
                // slot, then this logic will run again for the next slot on
                // that next slot's slotchange, so we remove the distributed
                // node from the previous shadowParent and add it to the next
                // one. If we don't do this, then the distributed node will
                // exist in multiple shadowChildren lists when there is a
                // chain of assigned slots. For more info, see
                // https://github.com/w3c/webcomponents/issues/611
                if (addedNode._shadowParent && addedNode._shadowParent._shadowChildren) {
                    addedNode._shadowParent._shadowChildren.delete(addedNode)
                    if (!addedNode._shadowParent._shadowChildren.size)
                        addedNode._shadowParent._shadowChildren = null
                }

                addedNode._shadowParent = this
                if (!this._shadowChildren) this._shadowChildren = new Set
                this._shadowChildren.add(addedNode)
            }

            for (const removedNode of diff.removed) {
                if (!(removedNode instanceof DeclarativeBase)) continue
                removedNode._shadowParent = null
                this._shadowChildren.delete(removedNode)
                if (!this._shadowChildren.size) this._shadowChildren = null
            }
        }

        _getDistributedChildDifference(slot) {
            let previousNodes

            if (this._slotElementsAssignedNodes.has(slot))
                previousNodes = this._slotElementsAssignedNodes.get(slot)
            else
                previousNodes = []

            const newNodes = slot.assignedNodes({flatten: true})

            // save the newNodes to be used as the previousNodes for next time.
            this._slotElementsAssignedNodes.set(slot, newNodes)

            const diff = {
                removed: [],
            }

            for (let i=0, l=previousNodes.length; i<l; i+=1) {
                let oldNode = previousNodes[i]
                let newIndex = newNodes.indexOf(oldNode)

                // if it exists in the previousNodes but not the newNodes, then
                // the node was removed.
                if (!(newIndex >= 0)) {
                    diff.removed.push(oldNode)
                }

                // otherwise the node wasn't added or removed.
                else {
                    newNodes.splice(i, 1)
                }
            }

            // Remaining nodes in newNodes must have been added.
            diff.added = newNodes

            return diff
        }

        childDisconnectedCallback(child) {
            // mirror the connection in the imperative API's virtual scene graph.
            if (child instanceof MotorHTMLNode) {
                child._isPossiblyDistributed = false
                this.imperativeCounterpart.removeChild(child.imperativeCounterpart)
            }
            else if (
                hasShadowDomV0
                && child instanceof HTMLContentElement
                &&
                //getShadowRootVersion(
                    getAncestorShadowRootIfAny(this)
                //) == 'v0'
            ) {
                // TODO: unobserve <content> element
            }
            else if (
                hasShadowDomV1
                && child instanceof HTMLSlotElement
                &&
                //getShadowRootVersion(
                    getAncestorShadowRootIfAny(this)
                //) == 'v1'
            ) {
                child.removeEventListener('slotchange', this)
                this._handleDistributedChildren(child)
                this._slotElementsAssignedNodes.delete(child)
            }
        }
    }
}

export {DeclarativeBase as default}
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Gleam.io Autosolve
// @namespace    GLEAM
// @version      1.7.1
// @description  lets save some time
// @author       Tackyou
// @license      https://raw.githubusercontent.com/Tackyou/Gleam.io-Autosolve/master/LICENSE
// @icon         http://i.imgur.com/6PuVE2l.png
// @match        https://gleam.io/*
// @supportURL   https://github.com/Tackyou/Gleam.io-Autosolve/issues
// @updateURL    https://raw.githubusercontent.com/Tackyou/Gleam.io-Autosolve/master/gleamio.user.js
// @downloadURL  https://raw.githubusercontent.com/Tackyou/Gleam.io-Autosolve/master/gleamio.user.js
// @grant        none
// ==/UserScript==

var wo = window.open;
function non(){
   return;
}
var ytstatus = 0;
var elements = 0;
console.log('[GLEAM] Welcome!');
$(window).load(function(){
    elements = $('.entry-method').length;
    gleam();
    if ($("#current-entries") != undefined) {
        $('.span4.blue-square.ng-scope').after('
NaNWinning Chance
');
        $("div.square-row.row-fluid.center.ng-scope > .span4").width('25%');
        setTimeout(setChance, 400);
    }
});
function gleam(){
    if($("div.redeem-container").is(':visible')){
        console.log('[GLEAM] already completed');
        $('div.incentive-description h3.ng-binding.ng-scope').append('
Already completed!
');
    }else{
        solveStep(0);
    }
}
function solveStep(m){
    if(m > elements){
        checkStatus();
        return;
    }
    var elem = $('.entry-method:eq('+m+')');
    var scop = elem.data('$scope');
    if(scop != null){ scop.entry_method.mandatory = true; }
    if(!elem.hasClass('completed-entry-method') && elem.is(':visible')){
        window.open = non;
        var type = $('span.icon-wrapper i', elem);
        var text = '#'+m+' '+$.trim($('.text .ng-binding.ng-scope', elem).text());
        console.log("[GLEAM] Processing: "+text);
        if(!type.hasClass('fa-heart')){
            if(type.hasClass('fa-youtube')){
                var ys = true;
                var yt = $('iframe.youtube', elem);
                if(ytstatus == 0){
                    $('.tally', elem).trigger('click');
                    ytstatus = 1;
                }else{
                    if(ytstatus == 1){
                        if(yt.attr('src') != undefined){
                            var yl = yt.attr('src').replace('autoplay=0', 'autoplay=1');
                            yt.attr('src', yl+'&start=99999999999');
                            ytstatus = 2;
                        }else{
                            ys = false;
                            ytstatus = 0;
                        }
                    }else{
                        if(ytstatus == 2){
                            var b = $('button.btn[ng-click]', elem);
                            if(b.is(':visible')){
                                b.trigger('click');
                                ytstatus = 0;
                                m++;
                            }
                        }
                    }
                }
                if(ys){ setTimeout(function(){solveStep(m);}, 100); return; }
            }
            $('.btn', elem).trigger('click');
            $('.tally', elem).trigger('click');
        }
        window.open = wo;
    }
    m++;
    solveStep(m);
}
function checkStatus(){
    $('.entry-method').each(function(){
        var elem = $(this);
        var tally = $('[ng-class*="tallyIcon"]', elem);
        if(!tally.hasClass('fa-spin')){
            if(tally.hasClass('fa-chevron-down')){
                $('.tally', elem).trigger('click');
            }
            if(!tally.hasClass('fa-check') && !tally.hasClass('fa-clock-o')){
                $('.tally', elem).css('background', '#F2C32E');
            }
        }
    });
    setChance();
}
function setChance(){
    var own = parseInt($(".status.ng-binding").text());
    var total = parseInt($(".current.ng-binding").text());
    var chance = Math.round(10000 * own / total) / 100;
    $("#winning-chance").text(chance+"%");
}
<commit_msg>Version 1.8 improved script, faster yt solving<commit_after>// ==UserScript==
// @name         Gleam.io Autosolve
// @namespace    GLEAM
// @version      1.8
// @description  lets save some time
// @author       Tackyou
// @license      https://raw.githubusercontent.com/Tackyou/Gleam.io-Autosolve/master/LICENSE
// @icon         http://i.imgur.com/6PuVE2l.png
// @match        https://gleam.io/*
// @supportURL   https://github.com/Tackyou/Gleam.io-Autosolve/issues
// @updateURL    https://raw.githubusercontent.com/Tackyou/Gleam.io-Autosolve/master/gleamio.user.js
// @downloadURL  https://raw.githubusercontent.com/Tackyou/Gleam.io-Autosolve/master/gleamio.user.js
// @grant        none
// ==/UserScript==

var ytstatus = 0;
var elements = 0;
var gleam = null;
console.log('[GLEAM] Welcome!');
$(window).load(function(){
    elements = $('.entry-method');
    elements.each(function() {
        $(this).data('$scope').entry_method.mandatory = true;
    });
    elements = elements.length;
    gg();
    if ($("#current-entries") != undefined) {
        $('.span4.blue-square.ng-scope').after('
NaNWinning Chance
');
        $("div.square-row.row-fluid.center.ng-scope > .span4").width('25%');
        setTimeout(setChance, 400);
    }
});
function gg(){
    if($("div.redeem-container").is(':visible')){
        console.log('[GLEAM] already completed');
        $('div.incentive-description h3.ng-binding.ng-scope').append('
Already completed!
');
    }else{
        gleam = angular.element($(".popup-blocks-container")).scope();
        solveStep(0);
    }
}
function solveStep(m){
    if(m > elements){
        setChance();
        return;
    }
    var elem = $('.entry-method:eq('+m+')');
    var scop = elem.data('$scope');
    if(scop != null) {
        var sype = scop.entry_method.entry_type;
        if(sype != 'share_action' && gleam.canEnter(scop.entry_method) && !gleam.isEntered(scop.entry_method)){
            var type = $('span.icon-wrapper i', elem);
            var text = '#'+m+' '+$.trim($('.text .ng-binding.ng-scope', elem).text());
            console.log("[GLEAM] Processing: "+text);
            scop.entry_method.entering = true;
            switch(sype) {
                case "youtube_watch":
                case "vimeo_watch":
                    scop.entry_method.watched = true;
                    scop.videoWatched(scop.entry_method);
                    break;
                default:
                    scop.triggerVisit(scop.entry_method.id);
                    break;
            }
            scop.entry_method.entering = false;
            scop.enterLinkClick(scop.entry_method);
            scop.verifyEntryMethod();
        }
        setTimeout(function(){
            if(!gleam.isEntered(scop.entry_method) || sype == 'share_action'){
                var tally = $('[ng-class*="tallyIcon"]', elem);
                if(tally.hasClass('fa-chevron-down')){
                    $('.tally', elem).trigger('click');
                }
                $('.tally', elem).css('background', '#F2C32E');
            }
        }, 1500);
    }
    m++;
    solveStep(m);
}
function setChance(){
    var own = parseInt($(".status.ng-binding").text());
    var total = parseInt($(".current.ng-binding").text());
    var chance = Math.round(10000 * own / total) / 100;
    $("#winning-chance").text(chance+"%");
}
<|endoftext|>


<commit_before>Ext.define('doweown.view.WorldCatView', {
    extend: 'Ext.DataView',
    xtype: 'worldcatview',

    config: {
           //title: 'WorldCat Listings',
	   title: 'No, we don\'t, but...',
           store: 'WorldCatStore',
           /*onItemDisclosure: function( record, btn, index ) {
                                Ext.Msg.alert( record.get('collection.collectionname'), Ext.emptyFn);
            },*/
            //itemTpl: '
 {repository.name} <tpl for="collection">
 {collectionname}<tpl for="items">
 <tpl switch="isavail"><tpl case="N" case="n">Not Available<tpl default>Available</tpl>  :{stat}
 Call#: {call}
 {req.content}
</tpl> <tpl for="holdtag">
 {availkey} {availval.content}
</tpl>  <tpl for="online"> {content}
</tpl> </tpl>

'
	itemTpl: '
<tpl if="thumbnail"></tpl> {title}
{author}
 {date}
 {publisher}
{description}

<tpl if="totalLibCount > 0">Available at Other Libraries:
 <tpl for="library">{institutionName}
 View this library\'s catalog record
</tpl>
Get It from Borrow Direct
 or
 </tpl>
Ask Us to Get It

',
	listeners: {
                initialize: function() {
			var btns = Ext.ComponentQuery.query('#scanreset2');
                        var rButton = new Ext.Button({text: 'Press Here to Scan Again', itemId: 'scanreset2', renderTo: 'renderResetButton2'});
                        this.add(rButton);
                }
            }
     }

});
<commit_msg>added spacing to bottom of reset btn<commit_after>Ext.define('doweown.view.WorldCatView', {
    extend: 'Ext.DataView',
    xtype: 'worldcatview',

    config: {
           //title: 'WorldCat Listings',
	   title: 'No, we don\'t, but...',
           store: 'WorldCatStore',
           /*onItemDisclosure: function( record, btn, index ) {
                                Ext.Msg.alert( record.get('collection.collectionname'), Ext.emptyFn);
            },*/
            //itemTpl: '
 {repository.name} <tpl for="collection">
 {collectionname}<tpl for="items">
 <tpl switch="isavail"><tpl case="N" case="n">Not Available<tpl default>Available</tpl>  :{stat}
 Call#: {call}
 {req.content}
</tpl> <tpl for="holdtag">
 {availkey} {availval.content}
</tpl>  <tpl for="online"> {content}
</tpl> </tpl>

'
	itemTpl: '
<tpl if="thumbnail"></tpl> {title}
{author}
 {date}
 {publisher}
{description}

<tpl if="totalLibCount > 0">Available at Other Libraries:
 <tpl for="library">{institutionName}
 View this library\'s catalog record
</tpl>
Get It from Borrow Direct
 or
 </tpl>
Ask Us to Get It

',
	listeners: {
                initialize: function() {
			var btns = Ext.ComponentQuery.query('#scanreset2');
                        var rButton = new Ext.Button({text: 'Press Here to Scan Again', itemId: 'scanreset2', renderTo: 'renderResetButton2'});
                        this.add(rButton);
                }
            }
     }

});
<|endoftext|>