<commit_before>import React from 'react';

import { humanReadableTimeStamp } from '../utillities'

class ProfileSummary extends React.Component {

  render() {
    const user = this.props.user;

    let userImage;

    if (user && user.image) {
      userImage = ();
    } else {
      userImage = (

      );
    }

    return (

          { userImage }

last seen: { user && humanReadableTimeStamp(user.lastSeenAt) }

{ user && user.firstName } { user && user.lastName }

{ user && user.headline }

{ user && this.renderEmail(user.email) }

{ user && this.renderPhone(user.phone) }

            {
              user && !!user.twitter &&
{ this.renderTwitterHandle(user.twitter) }

            }

          {user && user.location && (

{ user.location.address }

{ user.location.zipcode }, { user.location.city }

{ user.location.country }

)}

              384

              189

              95

              114

    );
  }

  renderEmail(email) {
    const url = `mailto:${ email }`;
    return ({ email });
  }

  renderPhone(phone) {
    const url = `tel:${ phone }`;
    return ({ phone });
  }

  renderTwitterHandle(handle) {
    const url = `https://twitter.com/${ handle }`;
    return (twitter.com/{ handle });
  }
}

ProfileSummary.propTypes = {
  user: React.PropTypes.object,
};

export default ProfileSummary;
<commit_msg>temporary comment out static data on profile<commit_after>import React from 'react';

import { humanReadableTimeStamp } from '../utillities'

class ProfileSummary extends React.Component {

  render() {
    const user = this.props.user;

    let userImage;

    if (user && user.image) {
      userImage = ();
    } else {
      userImage = (

      );
    }

    return (

          { userImage }

last seen: { user && humanReadableTimeStamp(user.lastSeenAt) }

{ user && user.firstName } { user && user.lastName }

{ user && user.headline }

{ user && this.renderEmail(user.email) }

{ user && this.renderPhone(user.phone) }

            {
              user && !!user.twitter &&
{ this.renderTwitterHandle(user.twitter) }

            }

          {user && user.location && (

{ user.location.address }

{ user.location.zipcode }, { user.location.city }

{ user.location.country }

)}

        {/*

              384

              189

              95

              114

        */}

    );
  }

  renderEmail(email) {
    const url = `mailto:${ email }`;
    return ({ email });
  }

  renderPhone(phone) {
    const url = `tel:${ phone }`;
    return ({ phone });
  }

  renderTwitterHandle(handle) {
    const url = `https://twitter.com/${ handle }`;
    return (twitter.com/{ handle });
  }
}

ProfileSummary.propTypes = {
  user: React.PropTypes.object,
};

export default ProfileSummary;
<|endoftext|>


<commit_before>/**
 * The AnalysisView selector view.
 *
 * @return AnalysisView instance (extends Backbone.View).
 */
define([
  'underscore',
  'handlebars',
  'amplify',
  'chosen',
  'map/presenters/tabs/AnalysisPresenter',
  'text!map/templates/tabs/analysis.handlebars'
], function(_, Handlebars, amplify, chosen, Presenter, tpl) {

  'use strict';

  var AnalysisModel = Backbone.Model.extend({
    hidden: true
  });

  var AnalysisView = Backbone.View.extend({

    el: '#analysis-tab',

    template: Handlebars.compile(tpl),

    events: {
      //tabs
      'click #analysis-nav li' : 'toggleTabs',

      //draw
      'click #start-analysis' : '_onClickAnalysis',
      'click #done-analysis' : '_onClickDone',

      //countries
      'change #analysis-country-select' : 'changeIso',
      'change #analysis-region-select' : 'changeArea',
      'click #analysis-country-button' : 'analysisCountry',
    },

    initialize: function(map) {
      _.bindAll(this, '_onOverlayComplete', '_cartodbLayerDone');
      this.map = map;
      this.presenter = new Presenter(this);
      this.model = new AnalysisModel();
      this.render();
      this.setListeners();
    },

    cacheVars: function(){
      this.$button = $('#'+this.$el.attr('id')+'-button');
      //draw
      this.$start = $('#start-analysis');
      this.$done = $('#done-analysis');

      //country
      this.$selects = $('.chosen-select');
      this.$countrySelect = $('#analysis-country-select');
      this.$regionSelect = $('#analysis-region-select');

      //tabs
      this.$tabs = $('#analysis-nav li');
      this.$tabsContent = $('.analysis-tab-content');

      //delete
      this.timeout = null;

    },

    setListeners: function(){

    },

    render: function(){
      this.$el.html(this.template());
      this.cacheVars();
      this.inits();
    },

    inits: function(){
      this.getCountries();
    },

    // navigate between tabs
    toggleTabs: function(e){

      if (!$(e.currentTarget).hasClass('disabled')) {
        var tab = $(e.currentTarget).data('analysis');

        // Current tab
        this.$tabs.removeClass('active');
        $(e.currentTarget).addClass('active');

        // Current content tab
        this.$tabsContent.removeClass('active');
        $('#'+tab).addClass('active');

        // prevent changes between tabs without reset drawing
        if (this.model.get('is_drawing')) {
          this._stopDrawing();
          this.presenter.deleteAnalysis();
        }
      }else{
        this.$deletebtn = $('#analysis-delete');
        clearTimeout(this.timeout);
        this.$deletebtn.addClass('pulse');
        this.timeout = setTimeout(_.bind(function(){
          this.$deletebtn.removeClass('pulse');
        }, this ),3000)
      }
    },

    openTab: function(type){
      var current;
      switch(type){
        case 'geojson':
          current = '#draw-tab-button';
          $('#draw-tab-button').removeClass('disabled').trigger('click');
        break;
        case 'iso':
          current = '#country-tab-button';
          $('#country-tab-button').removeClass('disabled').trigger('click');
        break;
        case 'other':
          current = '#data-tab-button';
          $('#data-tab-button').removeClass('disabled').trigger('click');
        break;
      }
      this.fixTab(current);
    },

    fixTab: function(current){
      // function to fix current tab and prevent user for changing tab with an analysis rendered
      this.$tabs.addClass('disabled');
      $(current).removeClass('disabled');
    },

    /**
     * Set geojson style.
     */
    setStyle: function(opacity) {
      this.style = {
        strokeWeight: 2,
        fillOpacity: opacity,
        fillColor: '#FFF',
        strokeColor: '#A2BC28',
        icon: new google.maps.MarkerImage(
          '/assets/icons/marker_exclamation.png',
          new google.maps.Size(36, 36), // size
          new google.maps.Point(0, 0), // offset
          new google.maps.Point(18, 18) // anchor
        )
      };

      this.map.data.setStyle(this.style);
    },

    /**
     * COUNTRY
     */

    /**
     * Ajax for getting countries.
     */
    getCountries: function(){
      if (!amplify.store('countries')) {
        var sql = ['SELECT c.iso, c.name FROM gfw2_countries c WHERE c.enabled = true'];
        $.ajax({
          url: 'https://wri-01.cartodb.com/api/v2/sql?q='+sql,
          dataType: 'json',
          success: _.bind(function(data){
            amplify.store('countries', data.rows);
            this.printCountries();
          }, this ),
          error: function(error){
            console.log(error);
          }
        });
      }else{
        this.printCountries()
      }
    },

    getSubCountries: function(){
      this.$regionSelect.attr('disabled', true).trigger("liszt:updated");
      var sql = ["SELECT gadm_1_all.cartodb_id, gadm_1_all.iso, gadm2_provinces_simple.id_1, gadm2_provinces_simple.name_1 as name_1 FROM gadm_1_all, gadm2_provinces_simple where gadm_1_all.iso = '"+this.iso+"' AND gadm2_provinces_simple.iso = '"+this.iso+"' AND gadm2_provinces_simple.id_1 = gadm_1_all.id_1 order by id_1 asc"];
      $.ajax({
        url: 'https://wri-01.cartodb.com/api/v2/sql?q='+sql,
        dataType: 'json',
        success: _.bind(function(data){
          this.printSubareas(data.rows);
        }, this ),
        error: function(error){
          console.log(error);
        }
      });
    },

    /**
     * Print countries.
     */
    printCountries: function(){
      //Country select
      this.countries = amplify.store('countries');

      //Loop for print options
      var options = "<option></option>";
      _.each(_.sortBy(this.countries, function(country){ return country.name }), _.bind(function(country, i){
        options += '<option value="'+ country.iso +'">'+ country.name + '</option>';
      }, this ));
      this.$countrySelect.append(options);
      this.$selects.chosen({
        width: '100%',
        allow_single_deselect: true,
        inherit_select_classes: true,
        no_results_text: "Oops, nothing found!"
      });
    },

    printSubareas: function(subareas){
      var subareas = subareas;
      var options = "<option></option>";
      _.each(_.sortBy(subareas, function(area){ return area.name_1 }), _.bind(function(area, i){
        options += '<option value="'+ area.id_1 +'">'+ area.name_1 + '</option>';
      }, this ));
      this.$regionSelect.empty().append(options).removeAttr('disabled');
      this.$regionSelect.val(this.area).trigger("liszt:updated");
    },

    // Select change iso
    changeIso: function(e){
      this.iso = $(e.currentTarget).val();
      this.area = null;
      ($(e.currentTarget).val()) ? this.getSubCountries() : this.$regionSelect.val(null).attr('disabled', true).trigger("liszt:updated");
    },
    changeArea: function(e){
      this.area = $(e.currentTarget).val();
    },

    // For autoselect country and region when youn reload page
    setSelects: function(iso){
      this.iso = iso.country;
      this.area = iso.region;

      this.$countrySelect.val(this.iso).trigger("liszt:updated");
      this.getSubCountries();
    },

    analysisCountry: function(){
      if (this.iso) {
        var iso = {
          country: this.iso,
          region: this.area
        }
        this.presenter._analyzeIso(iso);
      }
    },

    /**
     * DRAWING
     */
    /**
     * Triggered when the user clicks on the analysis draw button.
     */
    _onClickAnalysis: function() {
      if (!this.$start.hasClass('in_use')) {
        ga('send', 'event', 'Map', 'Analysis', 'Click: start');
        this.toggleUseBtn(true);
        this._startDrawingManager();
        this.presenter.startDrawing();
      }else{
        ga('send', 'event', 'Map', 'Analysis', 'Click: cancel');
        this._stopDrawing();
        this.presenter.deleteAnalysis();
      }
    },

    /**
     * Triggered when the user clicks on done
     * to get the analysis of the new polygon.
     */
    _onClickDone: function() {
      if (!this.$done.hasClass('disabled')) {
        ga('send', 'event', 'Map', 'Analysis', 'Click: done');
        this._stopDrawing();
        this.presenter.doneDrawing();
      }
    },

    /**
     * Star drawing manager and add an overlaycomplete
     * listener.
     */
    _startDrawingManager: function() {
      this.setStyle(0.45);
      this.model.set('is_drawing', true);
      this.drawingManager = new google.maps.drawing.DrawingManager({
        drawingControl: false,
        drawingMode: google.maps.drawing.OverlayType.POLYGON,
        polygonOptions: _.extend({
          editable: true
        }, this.style),
        panControl: false,
        map: this.map
      });
      // cache cartodb infowindows
      this.$infowindows = $('.cartodb-infowindow');
      this.$infowindows.addClass('hidden');

      google.maps.event.addListener(this.drawingManager,
        'overlaycomplete', this._onOverlayComplete);
    },

    /**
     * Triggered when the user finished drawing a polygon.
     *
     * @param  {Object} e event
     */
    _onOverlayComplete: function(e) {
      ga('send', 'event', 'Map', 'Analysis', 'Polygon: complete');
      this.presenter.onOverlayComplete(e);
      this._resetDrawing();
      // buttons clases
      this.toggleDoneBtn(false);
    },

    /**
     * Stop drawing manager, set drawing box to hidden.
     */
    _stopDrawing: function() {
      this.presenter.stopDrawing();
      this._resetDrawing();
      // buttons clases
      this.toggleUseBtn(false);
      this.toggleDoneBtn(true);
    },

    _resetDrawing: function(){
      this.model.set('is_drawing', false);
      if(this.$infowindows)
        this.$infowindows.hide(0).removeClass('hidden');
      if (this.drawingManager) {
        this.drawingManager.setDrawingMode(null);
        this.drawingManager.setMap(null);
      }
    },

    /**
     * Deletes a overlay from the map.
     *
     * @param  {object} resource overlay/multipolygon
     */
    deleteGeom: function(resource) {
      if (resource.overlay) {
        resource.overlay.setMap(null);
        resource.overlay = null;
      }

      if (resource.multipolygon) {
        this.map.data.remove(resource.multipolygon);
        this._removeCartodblayer();
      }

      this.$tabs.removeClass('disabled');
    },

    setEditable: function(overlay, to) {
      overlay.setEditable(to);
    },

    /**
     * Draw Geojson polygon on the map.
     *
     * @param  {String} geojson Geojson polygon as a string
     */
    drawPaths: function(paths) {
      var overlay = new google.maps.Polygon(
        _.extend({}, {paths: paths}, this.style));

      overlay.setMap(this.map);
      this.presenter.setOverlay(overlay);
    },

    /**
     * Draw a multypoligon on the map.
     *
     * @param  {Object} topojson
     */
    drawMultipolygon: function(geojson) {
      var multipolygon = this.map.data.addGeoJson(geojson)[0];
      this.presenter.setMultipolygon(multipolygon, geojson);
    },

    // COUNTRY MASK
    drawMaskCountry: function(geojson, iso){
      this.setStyle(0);
      this._removeCartodblayer();

      this.mask = cartodb.createLayer(this.map, {
        user_name: 'wri-01',
        type: 'cartodb',
        cartodb_logo: false,
        sublayers: [{
          name: 'mask',
          sql: "SELECT * FROM country_mask",
          cartocss: "\
            #country_mask {\
              polygon-fill: #373737;\
              polygon-opacity: 0.5;\
              line-color: #333;\
              line-width: 0;\
              line-opacity: 0;\
            }\
            #country_mask[code='" + iso + "'] {\
              polygon-opacity: 0;\
              line-color: #97Bd3d;\
              line-width: 1;\
              line-opacity: 0;\
            }"
        }]
      });
      this.mask.addTo(this.map, 1000)
      this.mask.done(this._cartodbLayerDone);

      var multipolygon = this.map.data.addGeoJson(geojson)[0];
      this.presenter.setMultipolygon(multipolygon, geojson);

    },

    // COUNTRY MASK
    drawMaskArea: function(geojson, iso, region){
      this.setStyle(0);
      this._removeCartodblayer();

      this.mask = cartodb.createLayer(this.map, {
        user_name: 'wri-01',
        type: 'cartodb',
        cartodb_logo: false,
        sublayers: [{
          sql: "SELECT * FROM country_mask",
          cartocss: "\
            #country_mask {\
              polygon-fill: #373737;\
              polygon-opacity: 0.5;\
              line-color: #333;\
              line-width: 0;\
              line-opacity: 0;\
            }\
            #country_mask[code='" + iso + "'] {\
              polygon-opacity: 0;\
              line-color: #333;\
              line-width: 1;\
              line-opacity: 1;\
            }"
        }, {
          sql: "SELECT * FROM gadm_1_all WHERE iso LIKE '" + iso +"' ",
          cartocss: "\
            #gadm_1_all {\
              polygon-fill: #373737;\
              polygon-opacity: 0.5;\
              line-color: #333;\
              line-width: 0;\
              line-opacity: 0;\
              [id_1=" + region + "]{\
                polygon-opacity: 0;\
              }\
              ::active[id_1=" + region + "] {\
                polygon-opacity: 0;\
                line-color: #73707D;\
                line-width: 1;\
                line-opacity: 1;\
              }\
            }"
        }]
      })
      this.mask.addTo(this.map, 1000)
      this.mask.done(this._cartodbLayerDone);

      var multipolygon = this.map.data.addGeoJson(geojson)[0];
      this.presenter.setMultipolygon(multipolygon, geojson);

    },

    _removeCartodblayer: function() {
      if (this.cartodbLayer) {
        this.cartodbLayer.remove();
      }
    },

    _cartodbLayerDone: function(layer) {
      this.cartodbLayer = layer;
    },

    /**
     * BUTTONS.
     */
    toggleBtn: function(to) {
      if (to) {
        (this.$button.hasClass('active')) ? this.$button.trigger('click') : null;
        this.$button.removeClass('in_use').addClass('disabled');
      }else{
        this.$button.removeClass('disabled');
      }
      $('.cartodb-popup').toggleClass('dont_analyze', to);
    },

    toggleUseBtn: function(to){
      this.$start.toggleClass('in_use', to);
      (to) ? this.$start.removeClass('green').addClass('gray').text('Cancel') : this.$start.removeClass('gray').addClass('green').text('Start drawing');
      $('.cartodb-popup').toggleClass('dont_analyze', to);
    },

    toggleDoneBtn: function(to){
      $('#draw-analysis').toggleClass('one', to);
      this.$done.parent().toggleClass('hidden', to);
    },

  });
  return AnalysisView;

});
<commit_msg>Map: setStyle of geojson when you reload<commit_after>/**
 * The AnalysisView selector view.
 *
 * @return AnalysisView instance (extends Backbone.View).
 */
define([
  'underscore',
  'handlebars',
  'amplify',
  'chosen',
  'map/presenters/tabs/AnalysisPresenter',
  'text!map/templates/tabs/analysis.handlebars'
], function(_, Handlebars, amplify, chosen, Presenter, tpl) {

  'use strict';

  var AnalysisModel = Backbone.Model.extend({
    hidden: true
  });

  var AnalysisView = Backbone.View.extend({

    el: '#analysis-tab',

    template: Handlebars.compile(tpl),

    events: {
      //tabs
      'click #analysis-nav li' : 'toggleTabs',

      //draw
      'click #start-analysis' : '_onClickAnalysis',
      'click #done-analysis' : '_onClickDone',

      //countries
      'change #analysis-country-select' : 'changeIso',
      'change #analysis-region-select' : 'changeArea',
      'click #analysis-country-button' : 'analysisCountry',
    },

    initialize: function(map) {
      _.bindAll(this, '_onOverlayComplete', '_cartodbLayerDone');
      this.map = map;
      this.presenter = new Presenter(this);
      this.model = new AnalysisModel();
      this.render();
      this.setListeners();
    },

    cacheVars: function(){
      this.$button = $('#'+this.$el.attr('id')+'-button');
      //draw
      this.$start = $('#start-analysis');
      this.$done = $('#done-analysis');

      //country
      this.$selects = $('.chosen-select');
      this.$countrySelect = $('#analysis-country-select');
      this.$regionSelect = $('#analysis-region-select');

      //tabs
      this.$tabs = $('#analysis-nav li');
      this.$tabsContent = $('.analysis-tab-content');

      //delete
      this.timeout = null;

    },

    setListeners: function(){

    },

    render: function(){
      this.$el.html(this.template());
      this.cacheVars();
      this.inits();
    },

    inits: function(){
      this.setStyle(0.45);
      this.getCountries();
    },

    // navigate between tabs
    toggleTabs: function(e){

      if (!$(e.currentTarget).hasClass('disabled')) {
        var tab = $(e.currentTarget).data('analysis');

        // Current tab
        this.$tabs.removeClass('active');
        $(e.currentTarget).addClass('active');

        // Current content tab
        this.$tabsContent.removeClass('active');
        $('#'+tab).addClass('active');

        // prevent changes between tabs without reset drawing
        if (this.model.get('is_drawing')) {
          this._stopDrawing();
          this.presenter.deleteAnalysis();
        }
      }else{
        this.$deletebtn = $('#analysis-delete');
        clearTimeout(this.timeout);
        this.$deletebtn.addClass('pulse');
        this.timeout = setTimeout(_.bind(function(){
          this.$deletebtn.removeClass('pulse');
        }, this ),3000)
      }
    },

    openTab: function(type){
      var current;
      switch(type){
        case 'geojson':
          current = '#draw-tab-button';
          $('#draw-tab-button').removeClass('disabled').trigger('click');
        break;
        case 'iso':
          current = '#country-tab-button';
          $('#country-tab-button').removeClass('disabled').trigger('click');
        break;
        case 'other':
          current = '#data-tab-button';
          $('#data-tab-button').removeClass('disabled').trigger('click');
        break;
      }
      this.fixTab(current);
    },

    fixTab: function(current){
      // function to fix current tab and prevent user for changing tab with an analysis rendered
      this.$tabs.addClass('disabled');
      $(current).removeClass('disabled');
    },

    /**
     * Set geojson style.
     */
    setStyle: function(opacity) {
      this.style = {
        strokeWeight: 2,
        fillOpacity: opacity,
        fillColor: '#FFF',
        strokeColor: '#A2BC28',
        icon: new google.maps.MarkerImage(
          '/assets/icons/marker_exclamation.png',
          new google.maps.Size(36, 36), // size
          new google.maps.Point(0, 0), // offset
          new google.maps.Point(18, 18) // anchor
        )
      };

      this.map.data.setStyle(this.style);
    },

    /**
     * COUNTRY
     */

    /**
     * Ajax for getting countries.
     */
    getCountries: function(){
      if (!amplify.store('countries')) {
        var sql = ['SELECT c.iso, c.name FROM gfw2_countries c WHERE c.enabled = true'];
        $.ajax({
          url: 'https://wri-01.cartodb.com/api/v2/sql?q='+sql,
          dataType: 'json',
          success: _.bind(function(data){
            amplify.store('countries', data.rows);
            this.printCountries();
          }, this ),
          error: function(error){
            console.log(error);
          }
        });
      }else{
        this.printCountries()
      }
    },

    getSubCountries: function(){
      this.$regionSelect.attr('disabled', true).trigger("liszt:updated");
      var sql = ["SELECT gadm_1_all.cartodb_id, gadm_1_all.iso, gadm2_provinces_simple.id_1, gadm2_provinces_simple.name_1 as name_1 FROM gadm_1_all, gadm2_provinces_simple where gadm_1_all.iso = '"+this.iso+"' AND gadm2_provinces_simple.iso = '"+this.iso+"' AND gadm2_provinces_simple.id_1 = gadm_1_all.id_1 order by id_1 asc"];
      $.ajax({
        url: 'https://wri-01.cartodb.com/api/v2/sql?q='+sql,
        dataType: 'json',
        success: _.bind(function(data){
          this.printSubareas(data.rows);
        }, this ),
        error: function(error){
          console.log(error);
        }
      });
    },

    /**
     * Print countries.
     */
    printCountries: function(){
      //Country select
      this.countries = amplify.store('countries');

      //Loop for print options
      var options = "<option></option>";
      _.each(_.sortBy(this.countries, function(country){ return country.name }), _.bind(function(country, i){
        options += '<option value="'+ country.iso +'">'+ country.name + '</option>';
      }, this ));
      this.$countrySelect.append(options);
      this.$selects.chosen({
        width: '100%',
        allow_single_deselect: true,
        inherit_select_classes: true,
        no_results_text: "Oops, nothing found!"
      });
    },

    printSubareas: function(subareas){
      var subareas = subareas;
      var options = "<option></option>";
      _.each(_.sortBy(subareas, function(area){ return area.name_1 }), _.bind(function(area, i){
        options += '<option value="'+ area.id_1 +'">'+ area.name_1 + '</option>';
      }, this ));
      this.$regionSelect.empty().append(options).removeAttr('disabled');
      this.$regionSelect.val(this.area).trigger("liszt:updated");
    },

    // Select change iso
    changeIso: function(e){
      this.iso = $(e.currentTarget).val();
      this.area = null;
      ($(e.currentTarget).val()) ? this.getSubCountries() : this.$regionSelect.val(null).attr('disabled', true).trigger("liszt:updated");
    },
    changeArea: function(e){
      this.area = $(e.currentTarget).val();
    },

    // For autoselect country and region when youn reload page
    setSelects: function(iso){
      this.iso = iso.country;
      this.area = iso.region;

      this.$countrySelect.val(this.iso).trigger("liszt:updated");
      this.getSubCountries();
    },

    analysisCountry: function(){
      if (this.iso) {
        var iso = {
          country: this.iso,
          region: this.area
        }
        this.presenter._analyzeIso(iso);
      }
    },

    /**
     * DRAWING
     */
    /**
     * Triggered when the user clicks on the analysis draw button.
     */
    _onClickAnalysis: function() {
      if (!this.$start.hasClass('in_use')) {
        ga('send', 'event', 'Map', 'Analysis', 'Click: start');
        this.toggleUseBtn(true);
        this._startDrawingManager();
        this.presenter.startDrawing();
      }else{
        ga('send', 'event', 'Map', 'Analysis', 'Click: cancel');
        this._stopDrawing();
        this.presenter.deleteAnalysis();
      }
    },

    /**
     * Triggered when the user clicks on done
     * to get the analysis of the new polygon.
     */
    _onClickDone: function() {
      if (!this.$done.hasClass('disabled')) {
        ga('send', 'event', 'Map', 'Analysis', 'Click: done');
        this._stopDrawing();
        this.presenter.doneDrawing();
      }
    },

    /**
     * Star drawing manager and add an overlaycomplete
     * listener.
     */
    _startDrawingManager: function() {
      this.setStyle(0.45);
      this.model.set('is_drawing', true);
      this.drawingManager = new google.maps.drawing.DrawingManager({
        drawingControl: false,
        drawingMode: google.maps.drawing.OverlayType.POLYGON,
        polygonOptions: _.extend({
          editable: true
        }, this.style),
        panControl: false,
        map: this.map
      });
      // cache cartodb infowindows
      this.$infowindows = $('.cartodb-infowindow');
      this.$infowindows.addClass('hidden');

      google.maps.event.addListener(this.drawingManager,
        'overlaycomplete', this._onOverlayComplete);
    },

    /**
     * Triggered when the user finished drawing a polygon.
     *
     * @param  {Object} e event
     */
    _onOverlayComplete: function(e) {
      ga('send', 'event', 'Map', 'Analysis', 'Polygon: complete');
      this.presenter.onOverlayComplete(e);
      this._resetDrawing();
      // buttons clases
      this.toggleDoneBtn(false);
    },

    /**
     * Stop drawing manager, set drawing box to hidden.
     */
    _stopDrawing: function() {
      this.presenter.stopDrawing();
      this._resetDrawing();
      // buttons clases
      this.toggleUseBtn(false);
      this.toggleDoneBtn(true);
    },

    _resetDrawing: function(){
      this.model.set('is_drawing', false);
      if(this.$infowindows)
        this.$infowindows.hide(0).removeClass('hidden');
      if (this.drawingManager) {
        this.drawingManager.setDrawingMode(null);
        this.drawingManager.setMap(null);
      }
    },

    /**
     * Deletes a overlay from the map.
     *
     * @param  {object} resource overlay/multipolygon
     */
    deleteGeom: function(resource) {
      if (resource.overlay) {
        resource.overlay.setMap(null);
        resource.overlay = null;
      }

      if (resource.multipolygon) {
        this.map.data.remove(resource.multipolygon);
        this._removeCartodblayer();
      }

      this.$tabs.removeClass('disabled');
    },

    setEditable: function(overlay, to) {
      overlay.setEditable(to);
    },

    /**
     * Draw Geojson polygon on the map.
     *
     * @param  {String} geojson Geojson polygon as a string
     */
    drawPaths: function(paths) {
      var overlay = new google.maps.Polygon(
        _.extend({}, {paths: paths}, this.style));

      overlay.setMap(this.map);
      this.presenter.setOverlay(overlay);
    },

    /**
     * Draw a multypoligon on the map.
     *
     * @param  {Object} topojson
     */
    drawMultipolygon: function(geojson) {
      var multipolygon = this.map.data.addGeoJson(geojson)[0];
      this.presenter.setMultipolygon(multipolygon, geojson);
    },

    // COUNTRY MASK
    drawMaskCountry: function(geojson, iso){
      this.setStyle(0);
      this._removeCartodblayer();

      this.mask = cartodb.createLayer(this.map, {
        user_name: 'wri-01',
        type: 'cartodb',
        cartodb_logo: false,
        sublayers: [{
          name: 'mask',
          sql: "SELECT * FROM country_mask",
          cartocss: "\
            #country_mask {\
              polygon-fill: #373737;\
              polygon-opacity: 0.5;\
              line-color: #333;\
              line-width: 0;\
              line-opacity: 0;\
            }\
            #country_mask[code='" + iso + "'] {\
              polygon-opacity: 0;\
              line-color: #97Bd3d;\
              line-width: 1;\
              line-opacity: 0;\
            }"
        }]
      });
      this.mask.addTo(this.map, 1000)
      this.mask.done(this._cartodbLayerDone);

      var multipolygon = this.map.data.addGeoJson(geojson)[0];
      this.presenter.setMultipolygon(multipolygon, geojson);

    },

    // COUNTRY MASK
    drawMaskArea: function(geojson, iso, region){
      this.setStyle(0);
      this._removeCartodblayer();

      this.mask = cartodb.createLayer(this.map, {
        user_name: 'wri-01',
        type: 'cartodb',
        cartodb_logo: false,
        sublayers: [{
          sql: "SELECT * FROM country_mask",
          cartocss: "\
            #country_mask {\
              polygon-fill: #373737;\
              polygon-opacity: 0.5;\
              line-color: #333;\
              line-width: 0;\
              line-opacity: 0;\
            }\
            #country_mask[code='" + iso + "'] {\
              polygon-opacity: 0;\
              line-color: #333;\
              line-width: 1;\
              line-opacity: 1;\
            }"
        }, {
          sql: "SELECT * FROM gadm_1_all WHERE iso LIKE '" + iso +"' ",
          cartocss: "\
            #gadm_1_all {\
              polygon-fill: #373737;\
              polygon-opacity: 0.5;\
              line-color: #333;\
              line-width: 0;\
              line-opacity: 0;\
              [id_1=" + region + "]{\
                polygon-opacity: 0;\
              }\
              ::active[id_1=" + region + "] {\
                polygon-opacity: 0;\
                line-color: #73707D;\
                line-width: 1;\
                line-opacity: 1;\
              }\
            }"
        }]
      })
      this.mask.addTo(this.map, 1000)
      this.mask.done(this._cartodbLayerDone);

      var multipolygon = this.map.data.addGeoJson(geojson)[0];
      this.presenter.setMultipolygon(multipolygon, geojson);

    },

    _removeCartodblayer: function() {
      if (this.cartodbLayer) {
        this.cartodbLayer.remove();
      }
    },

    _cartodbLayerDone: function(layer) {
      this.cartodbLayer = layer;
    },

    /**
     * BUTTONS.
     */
    toggleBtn: function(to) {
      if (to) {
        (this.$button.hasClass('active')) ? this.$button.trigger('click') : null;
        this.$button.removeClass('in_use').addClass('disabled');
      }else{
        this.$button.removeClass('disabled');
      }
      $('.cartodb-popup').toggleClass('dont_analyze', to);
    },

    toggleUseBtn: function(to){
      this.$start.toggleClass('in_use', to);
      (to) ? this.$start.removeClass('green').addClass('gray').text('Cancel') : this.$start.removeClass('gray').addClass('green').text('Start drawing');
      $('.cartodb-popup').toggleClass('dont_analyze', to);
    },

    toggleDoneBtn: function(to){
      $('#draw-analysis').toggleClass('one', to);
      this.$done.parent().toggleClass('hidden', to);
    },

  });
  return AnalysisView;

});
<|endoftext|>


<commit_before><commit_msg>cursor.js: refactoring<commit_after><|endoftext|>


<commit_before>import {Confirm} from 'reactjs-components';
/* eslint-disable no-unused-vars */
import React from 'react';
/* eslint-enable no-unused-vars */

import MarathonStore from '../../stores/MarathonStore';
import ServiceTree from '../../structs/ServiceTree';
import ServiceActionModal from './ServiceActionModal';

class ServiceSuspendModal extends ServiceActionModal {
  constructor() {
    super();

    this.store_listeners = [
      {
        name: 'marathon',
        events: [
          'serviceEditError',
          'serviceEditSuccess',
          'groupEditError',
          'groupEditSuccess'
        ],
        suppressUpdate: true
      }
    ];

    this.onMarathonStoreServiceEditError = this.onError;
    this.onMarathonStoreServiceEditSuccess = this.closeDialog;
    this.onMarathonStoreGroupEditError = this.onError;
    this.onMarathonStoreGroupEditSuccess =
      this.onMarathonStoreServiceEditSuccess;
  }

  handleConfirmClick() {
    super.handleConfirmClick();

    let {service} = this.props;
    let isGroup = service instanceof ServiceTree;
    let serviceID = service.getId();
    let forceUpdate = this.shouldForceUpdate(this.state.errorMsg);

    if (isGroup) {
      MarathonStore.editGroup({id: serviceID, scaleBy: 0}, forceUpdate);
    } else {
      MarathonStore.editService({id: serviceID, instances: 0}, forceUpdate);
    }
  }

  render() {
    const {open, service} = this.props;
    let itemText = 'Service';
    let serviceName = '';

    if (service instanceof ServiceTree) {
      itemText = 'Group';
    }

    if (service) {
      serviceName = service.getId();
    }

    return (
      <Confirm
        disabled={this.state.disabled}
        open={open}
        onClose={this.handleCloseClick}
        leftButtonCallback={this.handleCloseClick}
        rightButtonText={`Suspend ${itemText}`}
        rightButtonCallback={this.handleConfirmClick}>

            Suspend {itemText}

            Are you sure you want to suspend {serviceName} by scaling to 0 instances?

          {this.getErrorMessage()}

      </Confirm>
    );
  }
}

module.exports = ServiceSuspendModal;
<commit_msg>Make sure to pass arguments to super<commit_after>import {Confirm} from 'reactjs-components';
/* eslint-disable no-unused-vars */
import React from 'react';
/* eslint-enable no-unused-vars */

import MarathonStore from '../../stores/MarathonStore';
import ServiceTree from '../../structs/ServiceTree';
import ServiceActionModal from './ServiceActionModal';

class ServiceSuspendModal extends ServiceActionModal {
  constructor() {
    super(...arguments);

    this.store_listeners = [
      {
        name: 'marathon',
        events: [
          'serviceEditError',
          'serviceEditSuccess',
          'groupEditError',
          'groupEditSuccess'
        ],
        suppressUpdate: true
      }
    ];

    this.onMarathonStoreServiceEditError = this.onError;
    this.onMarathonStoreServiceEditSuccess = this.closeDialog;
    this.onMarathonStoreGroupEditError = this.onError;
    this.onMarathonStoreGroupEditSuccess =
      this.onMarathonStoreServiceEditSuccess;
  }

  handleConfirmClick() {
    super.handleConfirmClick();

    let {service} = this.props;
    let isGroup = service instanceof ServiceTree;
    let serviceID = service.getId();
    let forceUpdate = this.shouldForceUpdate(this.state.errorMsg);

    if (isGroup) {
      MarathonStore.editGroup({id: serviceID, scaleBy: 0}, forceUpdate);
    } else {
      MarathonStore.editService({id: serviceID, instances: 0}, forceUpdate);
    }
  }

  render() {
    const {open, service} = this.props;
    let itemText = 'Service';
    let serviceName = '';

    if (service instanceof ServiceTree) {
      itemText = 'Group';
    }

    if (service) {
      serviceName = service.getId();
    }

    return (
      <Confirm
        disabled={this.state.disabled}
        open={open}
        onClose={this.handleCloseClick}
        leftButtonCallback={this.handleCloseClick}
        rightButtonText={`Suspend ${itemText}`}
        rightButtonCallback={this.handleConfirmClick}>

            Suspend {itemText}

            Are you sure you want to suspend {serviceName} by scaling to 0 instances?

          {this.getErrorMessage()}

      </Confirm>
    );
  }
}

module.exports = ServiceSuspendModal;
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import {AutoSizer, Column, Table, SortDirection} from 'react-virtualized';
import {apiFetchJson} from '../helpers/apiFetchJson';
import {rankedByGradeLevel} from '../helpers/SortHelpers';
import {toSchoolYear} from '../helpers/schoolYear';
import {maybeCapitalize} from '../helpers/pretty';
import {shortSchoolName, supportsCounselor} from '../helpers/PerDistrict';
import {updateGlobalStylesToTakeFullHeight} from '../helpers/globalStylingWorkarounds';
import GenericLoader from '../components/GenericLoader';
import SectionHeading from '../components/SectionHeading';
import School from '../components/School';
import StudentPhotoCropped from '../components/StudentPhotoCropped';
import FilterStudentsBar from './FilterStudentsBar';
import {hasNote, isStarred} from './helpers';

export default class TransitionsPage extends React.Component {
  constructor(props) {
    super(props);
    this.fetchStudents = this.fetchStudents.bind(this);
    this.renderStudents = this.renderStudents.bind(this);
  }

  componentDidMount() {
    updateGlobalStylesToTakeFullHeight();
  }

  fetchStudents() {
    const url = `/api/second_transition_notes/transition_students_json`;
    return apiFetchJson(url);
  }

  render() {
    return (

        <GenericLoader
          promiseFn={this.fetchStudents}
          style={styles.flexVertical}
          render={this.renderStudents} />

    );
  }

  renderStudents(json) {
    const {students} = json;
    return <TransitionsView students={students} />;
  }
}

export class TransitionsView extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      sortBy: 'starred',
      sortDirection: SortDirection.ASC,
    };
    this.onTableSort = this.onTableSort.bind(this);
    this.renderName = this.renderName.bind(this);
    this.renderSchool = this.renderSchool.bind(this);
    this.renderNote = this.renderNote.bind(this);
    this.renderStarred = this.renderStarred.bind(this);
  }

  orderedStudents(students) {
    const {districtKey} = this.context;
    const {sortBy, sortDirection} = this.state;

    // map dataKey to an accessor/sort function
    const sortFns = {
      fallback(student) { return student[sortBy]; },

      name(student) { return `${student.last_name}, ${student.first_name}`; },
      school(student) { return shortSchoolName(districtKey, student.school.local_id); },
      grade(student) { return rankedByGradeLevel(student.grade); },
      counselor(student) { return maybeCapitalize(student.counselor); },
      note(student) { return hasNote(student); } ,
      starred(student) { return isStarred(student); }
    };
    const sortFn = sortFns[sortBy] || sortFns.fallback;
    const studentsByName = _.sortBy(students, sortFns.name);
    const sortedRows = _.sortBy(studentsByName, sortFn);

    // respect direction
    return (sortDirection == SortDirection.DESC)
      ? sortedRows.reverse()
      : sortedRows;
  }

  onTableSort({defaultSortDirection, event, sortBy, sortDirection}) {
    if (sortBy === this.state.sortBy) {
      const oppositeSortDirection = (this.state.sortDirection == SortDirection.DESC)
        ? SortDirection.ASC
        : SortDirection.DESC;
      this.setState({ sortDirection: oppositeSortDirection });
    } else {
      this.setState({sortBy});
    }
  }

  render() {
    const {nowFn, districtKey} = this.context;
    const schoolYear = toSchoolYear(nowFn());
    const {students} = this.props;

    return (

        <SectionHeading>School transitions for {schoolYear + 1}</SectionHeading>
        <FilterStudentsBar
          students={students}
          style={{...styles.flexVertical, marginLeft: 10, marginTop: 20}}
          includeCounselor={supportsCounselor(districtKey)}>
          {filteredStudents => this.renderTable(filteredStudents)}
        </FilterStudentsBar>

    );
  }

  renderTable(filteredStudents) {
    const {districtKey} = this.context;
    const {sortDirection, sortBy} = this.state;
    const sortedStudents = this.orderedStudents(filteredStudents);
    const rowHeight = 60; // for two lines of student names

    // In conjuction with the filtering, this can lead to a warning in development.
    // See https://github.com/bvaughn/react-virtualized/issues/1119 for more.
    return (
      <AutoSizer style={{marginTop: 20}}>
        {({width, height}) => (

 sortedStudents[index]}
            sort={this.onTableSort}
            sortBy={sortBy}
            sortDirection={sortDirection}
            >
            <Column
              label='Name'
              dataKey='name'
              cellRenderer={this.renderName}
              width={280}
            />
            <Column
              label='School'
              dataKey='school'
              cellRenderer={this.renderSchool}
              width={150}
            />
            <Column
              label='Grade'
              dataKey='grade'
              width={100}
            />
            {supportsCounselor(districtKey) &&
              <Column
                label='Counselor'
                dataKey='counselor'
                cellDataGetter={({rowData}) => maybeCapitalize(rowData.counselor)}
                width={100}
              />
            }
            <Column
              label='Note?'
              dataKey='note'
              cellRenderer={this.renderNote}
              width={120} />
            <Column
              label={Starred
 for discussion?}
              dataKey='starred'
              cellRenderer={this.renderStarred}
              width={140} />

        )}
      </AutoSizer>
    );
  }

  renderNote(cellProps) {
    const student = cellProps.rowData;
    if (!hasNote(student)) return null;
    return this.renderStudentLink(student, 📝);
  }

  renderStarred(cellProps) {
    const student = cellProps.rowData;
    if (!isStarred(student)) return null;
    return this.renderStudentLink(student, ⭐);
  }

  renderName(cellProps) {
    const student = cellProps.rowData;
    return (

        {this.renderStudentLink(student, `${student.first_name} ${student.last_name}`)}
        {student.has_photo && (
          <StudentPhotoCropped
            studentId={student.id}
            style={styles.photo}
          />
        )}

    );
  }

  renderSchool(cellProps) {
    const {school} = cellProps.rowData;
    const {districtKey} = this.context;
    const shortName = shortSchoolName(districtKey, school.local_id);
    return <School id={school.id} name={shortName} style={{marginRight: 10}} />;
  }

  renderStudentLink(student, children) {
    return <a style={{fontSize: 14}} href={`/students/${student.id}`} target="_blank" rel="noopener noreferrer">{children};
  }
}
TransitionsView.contextTypes = {
  districtKey: PropTypes.string.isRequired,
  nowFn: PropTypes.func.isRequired
};
TransitionsView.propTypes = {
  students: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.number.isRequired,
    first_name: PropTypes.string.isRequired,
    last_name: PropTypes.string.isRequired,
    counselor: PropTypes.string,
    grade: PropTypes.string.isRequired,
    has_photo: PropTypes.bool.isRequired,
    school: PropTypes.shape({
      id: PropTypes.number.isRequired,
      local_id: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired
    }).isRequired,
  })).isRequired
};

const styles = {
  flexVertical: {
    display: 'flex',
    flex: 1,
    flexDirection: 'column'
  },
  nameBlock: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center'
  },
  photo: {
    display: 'inline-block',
    marginLeft: 20,
    marginRight: 20
  }
};
<commit_msg>Transitions: Fix default sort order for starred<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import {AutoSizer, Column, Table, SortDirection} from 'react-virtualized';
import {apiFetchJson} from '../helpers/apiFetchJson';
import {rankedByGradeLevel} from '../helpers/SortHelpers';
import {toSchoolYear} from '../helpers/schoolYear';
import {maybeCapitalize} from '../helpers/pretty';
import {shortSchoolName, supportsCounselor} from '../helpers/PerDistrict';
import {updateGlobalStylesToTakeFullHeight} from '../helpers/globalStylingWorkarounds';
import GenericLoader from '../components/GenericLoader';
import SectionHeading from '../components/SectionHeading';
import School from '../components/School';
import StudentPhotoCropped from '../components/StudentPhotoCropped';
import FilterStudentsBar from './FilterStudentsBar';
import {hasNote, isStarred} from './helpers';

export default class TransitionsPage extends React.Component {
  constructor(props) {
    super(props);
    this.fetchStudents = this.fetchStudents.bind(this);
    this.renderStudents = this.renderStudents.bind(this);
  }

  componentDidMount() {
    updateGlobalStylesToTakeFullHeight();
  }

  fetchStudents() {
    const url = `/api/second_transition_notes/transition_students_json`;
    return apiFetchJson(url);
  }

  render() {
    return (

        <GenericLoader
          promiseFn={this.fetchStudents}
          style={styles.flexVertical}
          render={this.renderStudents} />

    );
  }

  renderStudents(json) {
    const {students} = json;
    return <TransitionsView students={students} />;
  }
}

export class TransitionsView extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      sortBy: 'starred',
      sortDirection: SortDirection.DESC,
    };
    this.onTableSort = this.onTableSort.bind(this);
    this.renderName = this.renderName.bind(this);
    this.renderSchool = this.renderSchool.bind(this);
    this.renderNote = this.renderNote.bind(this);
    this.renderStarred = this.renderStarred.bind(this);
  }

  orderedStudents(students) {
    const {districtKey} = this.context;
    const {sortBy, sortDirection} = this.state;

    // map dataKey to an accessor/sort function
    const sortFns = {
      fallback(student) { return student[sortBy]; },

      name(student) { return `${student.last_name}, ${student.first_name}`; },
      school(student) { return shortSchoolName(districtKey, student.school.local_id); },
      grade(student) { return rankedByGradeLevel(student.grade); },
      counselor(student) { return maybeCapitalize(student.counselor); },
      note(student) { return hasNote(student); } ,
      starred(student) { return isStarred(student); }
    };
    const sortFn = sortFns[sortBy] || sortFns.fallback;
    const studentsByName = _.sortBy(students, sortFns.name);
    const sortedRows = _.sortBy(studentsByName, sortFn);

    // respect direction
    return (sortDirection == SortDirection.DESC)
      ? sortedRows.reverse()
      : sortedRows;
  }

  onTableSort({defaultSortDirection, event, sortBy, sortDirection}) {
    if (sortBy === this.state.sortBy) {
      const oppositeSortDirection = (this.state.sortDirection == SortDirection.DESC)
        ? SortDirection.ASC
        : SortDirection.DESC;
      this.setState({ sortDirection: oppositeSortDirection });
    } else {
      this.setState({sortBy});
    }
  }

  render() {
    const {nowFn, districtKey} = this.context;
    const schoolYear = toSchoolYear(nowFn());
    const {students} = this.props;

    return (

        <SectionHeading>School transitions for {schoolYear + 1}</SectionHeading>
        <FilterStudentsBar
          students={students}
          style={{...styles.flexVertical, marginLeft: 10, marginTop: 20}}
          includeCounselor={supportsCounselor(districtKey)}>
          {filteredStudents => this.renderTable(filteredStudents)}
        </FilterStudentsBar>

    );
  }

  renderTable(filteredStudents) {
    const {districtKey} = this.context;
    const {sortDirection, sortBy} = this.state;
    const sortedStudents = this.orderedStudents(filteredStudents);
    const rowHeight = 60; // for two lines of student names

    // In conjuction with the filtering, this can lead to a warning in development.
    // See https://github.com/bvaughn/react-virtualized/issues/1119 for more.
    return (
      <AutoSizer style={{marginTop: 20}}>
        {({width, height}) => (

 sortedStudents[index]}
            sort={this.onTableSort}
            sortBy={sortBy}
            sortDirection={sortDirection}
            >
            <Column
              label='Name'
              dataKey='name'
              cellRenderer={this.renderName}
              width={280}
            />
            <Column
              label='School'
              dataKey='school'
              cellRenderer={this.renderSchool}
              width={150}
            />
            <Column
              label='Grade'
              dataKey='grade'
              width={100}
            />
            {supportsCounselor(districtKey) &&
              <Column
                label='Counselor'
                dataKey='counselor'
                cellDataGetter={({rowData}) => maybeCapitalize(rowData.counselor)}
                width={100}
              />
            }
            <Column
              label='Note?'
              dataKey='note'
              cellRenderer={this.renderNote}
              width={120} />
            <Column
              label={Starred
 for discussion?}
              dataKey='starred'
              cellRenderer={this.renderStarred}
              width={140} />

        )}
      </AutoSizer>
    );
  }

  renderNote(cellProps) {
    const student = cellProps.rowData;
    if (!hasNote(student)) return null;
    return this.renderStudentLink(student, 📝);
  }

  renderStarred(cellProps) {
    const student = cellProps.rowData;
    if (!isStarred(student)) return null;
    return this.renderStudentLink(student, ⭐);
  }

  renderName(cellProps) {
    const student = cellProps.rowData;
    return (

        {this.renderStudentLink(student, `${student.first_name} ${student.last_name}`)}
        {student.has_photo && (
          <StudentPhotoCropped
            studentId={student.id}
            style={styles.photo}
          />
        )}

    );
  }

  renderSchool(cellProps) {
    const {school} = cellProps.rowData;
    const {districtKey} = this.context;
    const shortName = shortSchoolName(districtKey, school.local_id);
    return <School id={school.id} name={shortName} style={{marginRight: 10}} />;
  }

  renderStudentLink(student, children) {
    return <a style={{fontSize: 14}} href={`/students/${student.id}`} target="_blank" rel="noopener noreferrer">{children};
  }
}
TransitionsView.contextTypes = {
  districtKey: PropTypes.string.isRequired,
  nowFn: PropTypes.func.isRequired
};
TransitionsView.propTypes = {
  students: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.number.isRequired,
    first_name: PropTypes.string.isRequired,
    last_name: PropTypes.string.isRequired,
    counselor: PropTypes.string,
    grade: PropTypes.string.isRequired,
    has_photo: PropTypes.bool.isRequired,
    school: PropTypes.shape({
      id: PropTypes.number.isRequired,
      local_id: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired
    }).isRequired,
  })).isRequired
};

const styles = {
  flexVertical: {
    display: 'flex',
    flex: 1,
    flexDirection: 'column'
  },
  nameBlock: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center'
  },
  photo: {
    display: 'inline-block',
    marginLeft: 20,
    marginRight: 20
  }
};
<|endoftext|>


<commit_before>(function() {

    // Storing common selections
    var allEndpoints = $('li.endpoint'),
        allEndpointsLength = allEndpoints.length,
        allMethodLists = $('ul.methods'),
        allMethodListsLength = allMethodLists.length;

    function listMethods(context) {
        var methodsList = $('ul.methods', context || null);

        for (var i = 0, len = methodsList.length; i < len; i++) {
            $(methodsList[i]).slideDown();
        }
    }

    // Toggle show/hide of method details, form, and results
    $('li.method > div.title').click(function() {
        $('form', this.parentNode).slideToggle();
    })

    // Toggle an endpoint
    $('li.endpoint > h3.title span.name').click(function() {
        $('ul.methods', this.parentNode.parentNode).slideToggle();
        $(this.parentNode.parentNode).toggleClass('expanded')
    })

    // Toggle all endpoints
    $('#toggle-endpoints').click(function(event) {
        event.preventDefault();

        // Check for collapsed endpoints (hidden methods)
        var endpoints = $('ul.methods:not(:visible)'),
            endpointsLength = endpoints.length;

        if (endpointsLength > 0) {
            // Some endpoints are collapsed, expand them.
            for (var x = 0; x < endpointsLength; x++) {
                var methodsList = $(endpoints[x]);
                methodsList.slideDown();
                methodsList.parent().toggleClass('expanded', true)

            }
        } else {
            // All endpoints are expanded, collapse them
            var endpoints = $('ul.methods'),
                endpointsLength = endpoints.length;

            for (var x = 0; x < endpointsLength; x++) {
                var methodsList = $(endpoints[x]);
                methodsList.slideUp();
                methodsList.parent().toggleClass('expanded', false)
            }
        }

    })

    // Toggle all methods
    $('#toggle-methods').click(function(event) {
        event.preventDefault();

        var methodForms = $('ul.methods form:not(:visible)'), // Any hidden method forms
            methodFormsLength = methodForms.length;

        // Check if any method is not visible. If so, expand all methods.
        if (methodFormsLength > 0) {
            var methodLists = $('ul.methods:not(:visible)'), // Any hidden methods
            methodListsLength = methodLists.length;

            // First make sure all the hidden endpoints are expanded.
            for (var x = 0; x < methodListsLength; x++) {
                $(methodLists[x]).slideDown();
            }

            // Now make sure all the hidden methods are expanded.
            for (var y = 0; y < methodFormsLength; y++) {
                $(methodForms[y]).slideDown();
            }

        } else {
            // Hide all visible method forms
            var visibleMethodForms = $('ul.methods form:visible'),
                visibleMethodFormsLength = visibleMethodForms.length;

            for (var i = 0; i < visibleMethodFormsLength; i++) {
                $(visibleMethodForms[i]).slideUp();
            }
        }

        for (var z = 0; z < allEndpointsLength; z++) {
            $(allEndpoints[z]).toggleClass('expanded', true);
        }
    })

    // List methods for a particular endpoint.
    // Hide all forms if visible
    $('li.list-methods a').click(function(event) {
        event.preventDefault();

        // Make sure endpoint is expanded
        var endpoint = $(this).closest('li.endpoint'),
            methods = $('li.method form', endpoint);

        listMethods(endpoint);

        // Make sure all method forms are collapsed
        var visibleMethods = $.grep(methods, function(method) {
            return $(method).is(':visible')
        })

        $(visibleMethods).each(function(i, method) {
            $(method).slideUp();
        })

        $(endpoint).toggleClass('expanded', true);

    })

    // Expand methods for a particular endpoint.
    // Show all forms and list all methods
    $('li.expand-methods a').click(function(event) {
        event.preventDefault();

        // Make sure endpoint is expanded
        var endpoint = $(this).closest('li.endpoint'),
            methods = $('li.method form', endpoint);

        listMethods(endpoint);

        // Make sure all method forms are expanded
        var hiddenMethods = $.grep(methods, function(method) {
            return $(method).not(':visible')
        })

        $(hiddenMethods).each(function(i, method) {
            $(method).slideDown();
        })

        $(endpoint).toggleClass('expanded', true);

    });

    // Toggle headers section
    $('div.headers h4').click(function(event) {
        event.preventDefault();

        $(this.parentNode).toggleClass('expanded');

        $('div.fields', this.parentNode).slideToggle();
    });

    // Auth with OAuth
    $('#credentials').submit(function(event) {
        event.preventDefault();

        var params = $(this).serializeArray();

        $.post('/auth', params, function(result) {
            if (result.signin) {
                window.open(result.signin,"_blank","height=900,width=800,menubar=0,resizable=1,scrollbars=1,status=0,titlebar=0,toolbar=0");
            }
        })
    });

    /*
        Try it! button. Submits the method params, apikey and secret if any, and apiName
    */
    $('li.method form').submit(function(event) {
        var self = this;

        event.preventDefault();

        var params = $(this).serializeArray(),
            apiKey = { name: 'apiKey', value: $('input[name=key]').val() },
            apiSecret = { name: 'apiSecret', value: $('input[name=secret]').val() },
            apiName = { name: 'apiName', value: $('input[name=apiName]').val() };

        params.push(apiKey, apiSecret, apiName);

        // Setup results container
        var resultContainer = $('.result', self);
        if (resultContainer.length === 0) {
            resultContainer = $(document.createElement('div')).attr('class', 'result');
            $(self).append(resultContainer);
        }

        if ($('pre.response', resultContainer).length === 0) {

            // Clear results link
            var clearLink = $(document.createElement('a'))
                .text('Clear results')
                .addClass('clear-results')
                .attr('href', '#')
                .click(function(e) {
                    e.preventDefault();

                    var thislink = this;
                    $('.result', self)
                        .slideUp(function() {
                            $(this).remove();
                            $(thislink).remove();
                        });
                })
                .insertAfter($('input[type=submit]', self));

            // Call that was made, add pre elements
            resultContainer.append($(document.createElement('h4')).text('Call'));
            resultContainer.append($(document.createElement('pre')).addClass('call'));

            // Code
            resultContainer.append($(document.createElement('h4')).text('Response Code'));
            resultContainer.append($(document.createElement('pre')).addClass('code prettyprint'));

            // Header
            resultContainer.append($(document.createElement('h4')).text('Response Headers'));
            resultContainer.append($(document.createElement('pre')).addClass('headers prettyprint'));

            // Response
            resultContainer.append($(document.createElement('h4'))
                .text('Response Body')
                .append($(document.createElement('a'))
                    .text('Select body')
                    .addClass('select-all')
                    .attr('href', '#')
                    .click(function(e) {
                        e.preventDefault();
                        selectElementText($(this.parentNode).siblings('.response')[0]);
                    })
                )
            );

            resultContainer.append($(document.createElement('pre'))
                .addClass('response prettyprint'));
        }

        console.log(params);

        $.post('/processReq', params, function(result, text) {
            // If we get passed a signin property, open a window to allow the user to signin/link their account
            if (result.signin) {
                window.open(result.signin,"_blank","height=900,width=800,menubar=0,resizable=1,scrollbars=1,status=0,titlebar=0,toolbar=0");
            } else {
                var response,
                    responseContentType = result.headers['content-type'];
                // Format output according to content-type
                response = livedocs.formatData(result.response, result.headers['content-type'])

                $('pre.response', resultContainer)
                    .toggleClass('error', false)
                    .text(response);
            }

        })
        // Complete, runs on error and success
        .complete(function(result, text) {
            var response = JSON.parse(result.responseText);

            if (response.call) {
                $('pre.call', resultContainer)
                    .text(response.call);
            }

            if (response.code) {
                $('pre.code', resultContainer)
                    .text(response.code);
            }

            if (response.headers) {
                $('pre.headers', resultContainer)
                    .text(formatJSON(response.headers));
            }

            // Syntax highlighting
            prettyPrint();
        })
        .error(function(err, text) {
            var response;

            if (err.responseText !== '') {
                var result = JSON.parse(err.responseText),
                    headers = formatJSON(result.headers);

                if (result.headers && result.headers['content-type']) {
                    // Format the result.response and assign it to response
                    response = livedocs.formatData(result.response, result.headers['content-type']);
                } else {
                    response = result.response;
                }

            } else {
                response = 'Error';
            }

            $('pre.response', resultContainer)
                .toggleClass('error', true)
                .text(response);
        })
    })

})();
<commit_msg>Behaviour for optional and repeatable parameters<commit_after>(function(apiView) {

    // Storing common selections
    var allEndpoints = $('li.endpoint'),
        allEndpointsLength = allEndpoints.length,
        allMethodLists = $('ul.methods'),
        allMethodListsLength = allMethodLists.length;

    function listMethods(context) {
        var methodsList = $('ul.methods', context || null);

        for (var i = 0, len = methodsList.length; i < len; i++) {
            $(methodsList[i]).slideDown();
        }
    }

    // Toggle show/hide of method details, form, and results
    $('li.method > div.title').click(function() {
        $('form', this.parentNode).slideToggle();
    })

    // Toggle an endpoint
    $('li.endpoint > h3.title span.name').click(function() {
        $('ul.methods', this.parentNode.parentNode).slideToggle();
        $(this.parentNode.parentNode).toggleClass('expanded')
    })

    $('input.variable-param').change(function(event) {
      event.preventDefault();
      var nameInput = $(this);
      nameInput.closest('tr').find('td.parameter input').attr({name: 'params[' + nameInput.val() + ']'});
    });

    // Toggle all endpoints
    $('#toggle-endpoints').click(function(event) {
        event.preventDefault();

        // Check for collapsed endpoints (hidden methods)
        var endpoints = $('ul.methods:not(:visible)'),
            endpointsLength = endpoints.length;

        if (endpointsLength > 0) {
            // Some endpoints are collapsed, expand them.
            for (var x = 0; x < endpointsLength; x++) {
                var methodsList = $(endpoints[x]);
                methodsList.slideDown();
                methodsList.parent().toggleClass('expanded', true)

            }
        } else {
            // All endpoints are expanded, collapse them
            var endpoints = $('ul.methods'),
                endpointsLength = endpoints.length;

            for (var x = 0; x < endpointsLength; x++) {
                var methodsList = $(endpoints[x]);
                methodsList.slideUp();
                methodsList.parent().toggleClass('expanded', false)
            }
        }

    })

    // Toggle all methods
    $('#toggle-methods').click(function(event) {
        event.preventDefault();

        var methodForms = $('ul.methods form:not(:visible)'), // Any hidden method forms
            methodFormsLength = methodForms.length;

        // Check if any method is not visible. If so, expand all methods.
        if (methodFormsLength > 0) {
            var methodLists = $('ul.methods:not(:visible)'), // Any hidden methods
            methodListsLength = methodLists.length;

            // First make sure all the hidden endpoints are expanded.
            for (var x = 0; x < methodListsLength; x++) {
                $(methodLists[x]).slideDown();
            }

            // Now make sure all the hidden methods are expanded.
            for (var y = 0; y < methodFormsLength; y++) {
                $(methodForms[y]).slideDown();
            }

        } else {
            // Hide all visible method forms
            var visibleMethodForms = $('ul.methods form:visible'),
                visibleMethodFormsLength = visibleMethodForms.length;

            for (var i = 0; i < visibleMethodFormsLength; i++) {
                $(visibleMethodForms[i]).slideUp();
            }
        }

        for (var z = 0; z < allEndpointsLength; z++) {
            $(allEndpoints[z]).toggleClass('expanded', true);
        }
    })

    // List methods for a particular endpoint.
    // Hide all forms if visible
    $('li.list-methods a').click(function(event) {
        event.preventDefault();

        // Make sure endpoint is expanded
        var endpoint = $(this).closest('li.endpoint'),
            methods = $('li.method form', endpoint);

        listMethods(endpoint);

        // Make sure all method forms are collapsed
        var visibleMethods = $.grep(methods, function(method) {
            return $(method).is(':visible')
        })

        $(visibleMethods).each(function(i, method) {
            $(method).slideUp();
        })

        $(endpoint).toggleClass('expanded', true);

    });

    $(function() {
      var hash;
      if (hash = window.location.hash) {
        $(hash + ' li.list-methods a').click();
      }
    });

    // Expand methods for a particular endpoint.
    // Show all forms and list all methods
    $('li.expand-methods a').click(function(event) {
        event.preventDefault();

        // Make sure endpoint is expanded
        var endpoint = $(this).closest('li.endpoint'),
            methods = $('li.method form', endpoint);

        listMethods(endpoint);

        // Make sure all method forms are expanded
        var hiddenMethods = $.grep(methods, function(method) {
            return $(method).not(':visible')
        })

        $(hiddenMethods).each(function(i, method) {
            $(method).slideDown();
        })

        $(endpoint).toggleClass('expanded', true);

    });

    // Toggle headers section
    $('div.headers h4').click(function(event) {
        event.preventDefault();

        $(this.parentNode).toggleClass('expanded');

        $('div.fields', this.parentNode).slideToggle();
    });

    // Auth with OAuth
    $('#credentials').submit(function(event) {
        event.preventDefault();

        var params = $(this).serializeArray();

        $.post('/auth', params, function(result) {
            if (result.signin) {
                window.open(result.signin,"_blank","height=900,width=800,menubar=0,resizable=1,scrollbars=1,status=0,titlebar=0,toolbar=0");
            }
        })
    });

    /*
     * Enable checkboxes for optional parameters when values are supplied.
     */
    $('td.parameter select')
      .add('td.parameter input')
      .add('td.parameter textarea').change(function(evt) {
      evt.preventDefault();
      var $widget = $(this);
      var $chbox = $('.provide-' + this.name.match(/params\[(.*)\]/)[1], $widget.closest('tr'));
      $chbox.attr({checked: $widget.val()});
    });

    /*
     * Repeatable parameters.
     */
    $('input.repeatable').change(function(event) {
      var self = this;
      var $input = $(this);
      event.preventDefault();

      var $tr = $input.closest('tr');

      // Only append new inputs at the end of the
      // list of repeated rows.
      if ($tr.next().attr('id') === $tr.attr('id')) {
        return false;
      }

      var clone = $tr.clone(true);
      clone.find('td.parameter input').val('');
      // \u3003 is the ditto mark (〃).
      var td_name = clone.find('td.name');
      if (td_name.children('input').length) {
        td_name.children('input').val('');
      } else {
        td_name.text('\u3003');
      }
      $('<button title="Remove parameter" class="remove">x</button>').prependTo(td_name).click(function(event) {
        event.preventDefault();
        clone.remove();
      });
      clone.find('td.type').text('\u3003');
      clone.find('td.description p').text('\u3003');
      //clone.find('td.enabled ').text('\u3003');
      clone.insertAfter($tr);

    });

    $('a.version').each(function() {
      var $a = $(this);
      $.ajax($a.attr('href'), { dataType: "text" }).done(function(version) {
        $a.text(version);
      }).fail(function(error) {
        $a.addClass('error').text("Not available");
      });
    });

    /*
        Try it! button. Submits the method params, apikey and secret if any, and apiName
    */
    $('li.method form').submit(function(event) {
        var self = this;

        event.preventDefault();

        var params = $(this).serializeArray(),
            apiKey = { name: 'apiKey', value: $('input[name=key]').val() },
            apiSecret = { name: 'apiSecret', value: $('input[name=secret]').val() },
            apiName = { name: 'apiName', value: $('input[name=apiName]').val() };

        // Exclude optional parameters with unchecked boxes.
        params = params.filter(function(p) {
          if (!p.name.match(/params/)) return true;
          var $chxbox = $('.provide-' + p.name.match(/params\[(.*)\]/)[1], self);
          return ($chxbox.length) ? $chxbox.is(':checked') : true;
        });

        params.push(apiKey, apiSecret, apiName);

        // Setup results container
        var resultContainer = $('.result', self);
        if (resultContainer.length === 0) {
            resultContainer = $(document.createElement('div')).attr('class', 'result');
            $(self).append(resultContainer);
        }

        if ($('pre.response', resultContainer).length === 0) {

            // Clear results link
            var clearLink = $(document.createElement('a'))
                .text('Clear results')
                .addClass('clear-results')
                .attr('href', '#')
                .click(function(e) {
                    e.preventDefault();

                    var thislink = this;
                    $('.result', self)
                        .slideUp(function() {
                            $(this).remove();
                            $(thislink).remove();
                        });
                })
                .insertAfter($('input[type=submit]', self));

            // Call that was made, add pre elements
            resultContainer.append($(document.createElement('h4')).text('Call'));
            resultContainer.append($(document.createElement('pre')).addClass('call'));

            // Code
            resultContainer.append($(document.createElement('h4')).text('Response Code'));
            resultContainer.append($(document.createElement('pre')).addClass('code prettyprint'));

            // Header
            resultContainer.append($(document.createElement('h4')).text('Response Headers'));
            resultContainer.append($(document.createElement('pre')).addClass('headers prettyprint'));

            // Response
            resultContainer.append($(document.createElement('h4'))
                .text('Response Body')
                .append($(document.createElement('a'))
                    .text('Select body')
                    .addClass('select-all')
                    .attr('href', '#')
                    .click(function(e) {
                        e.preventDefault();
                        selectElementText($(this.parentNode).siblings('.response')[0]);
                    })
                )
            );

            resultContainer.append($(document.createElement('pre'))
                .addClass('response prettyprint'));
        }

        console.log(params);

        $.post('/processReq', params, function(result, text) {
            // If we get passed a signin property, open a window to allow the user to signin/link their account
            if (result.signin) {
                window.open(result.signin,"_blank","height=900,width=800,menubar=0,resizable=1,scrollbars=1,status=0,titlebar=0,toolbar=0");
            } else {
                var response,
                    responseContentType = result.headers['content-type'];
                // Format output according to content-type
                response = livedocs.formatData(result.response, result.headers['content-type'])

                $('pre.response', resultContainer)
                    .toggleClass('error', false)
                    .text(response);
            }

        })
        // Complete, runs on error and success
        .complete(function(result, text) {
            var response = JSON.parse(result.responseText);

            if (response.call) {
                $('pre.call', resultContainer)
                    .text(response.call);
            }

            if (response.code) {
                $('pre.code', resultContainer)
                    .text(response.code);
            }

            if (response.headers) {
                $('pre.headers', resultContainer)
                    .text(formatJSON(response.headers));
            }

            // Syntax highlighting
            prettyPrint();
        })
        .error(function(err, text) {
            var response;

            if (err.responseText !== '') {
                var result = JSON.parse(err.responseText),
                    headers = formatJSON(result.headers);

                if (result.headers && result.headers['content-type']) {
                    // Format the result.response and assign it to response
                    response = livedocs.formatData(result.response, result.headers['content-type']);
                } else {
                    response = result.response;
                }

            } else {
                response = 'Error';
            }

            $('pre.response', resultContainer)
                .toggleClass('error', true)
                .text(response);
        })
    });

    /* It would be nice to do xml validation here...
    $('textarea').each(function(i, e) {
      var $textarea = $(this), schema_uri;
      if (schema_uri = $textarea.data('xmlschema')) {
        $.get(schema_uri).then(function(schema) {
          $textarea.change(function(event) {
            var opts = {
              xml: $textarea.val(),
              schema: schema,
              arguments: ['--noout']
            };
      }
    });
    */

})();
<|endoftext|>


<commit_before>/**
 * Requires: avc-codec.js
 **/

assert (Module);

HEAP8 = Module.HEAP8;
HEAPU8 = Module.HEAPU8;
HEAP16 = Module.HEAP16;
HEAP32 = Module.HEAP32;
_h264bsdClip = Module._get_h264bsdClip();

var Avc = (function avc() {
  const MAX_STREAM_BUFFER_LENGTH = 1024 * 1024;

  function constructor() {
    Module._broadwayInit();
    this.streamBuffer = toU8Array(Module._broadwayCreateStream(MAX_STREAM_BUFFER_LENGTH), MAX_STREAM_BUFFER_LENGTH);
    this.pictureBuffers = {};

    this.onPictureDecoded = function (buffer, width, height) {
      // console.info(buffer.length);
    }

    Module.patch(null, "_broadwayOnHeadersDecoded", function () {

    });

    Module.patch(null, "_broadwayOnPictureDecoded", function ($buffer, width, height) {
      var buffer = this.pictureBuffers[$buffer];
      if (!buffer) {
        buffer = this.pictureBuffers[$buffer] = toU8Array($buffer, (width * height * 3) / 2);
      }
      this.onPictureDecoded(buffer, width, height);
    }.bind(this));

  }

  /**
   * Creates a typed array from a HEAP8 pointer.
   */
  function toU8Array(ptr, length) {
    return HEAPU8.subarray(ptr, ptr + length);
  }

  constructor.prototype = {
    /**
     * Decodes a stream buffer. This may be one single (unframed) NAL unit without the
     * start code, or a sequence of NAL units with framing start code prefixes. This
     * function overwrites stream buffer allocated by the codec with the supplied buffer.
     */
    decode: function decode(buffer) {
      // console.info("Decoding: " + buffer.length);
      this.streamBuffer.set(buffer);
      Module._broadwaySetStreamLength(buffer.length);
      Module._broadwayPlayStream();
    },
    configure: function (config) {
      patchOptimizations(config, patches);
      console.info("Broadway Configured: " + JSON.stringify(config));
    }
  };

  return constructor;
})();

function patchOptimizations(config, patches) {
  var scope = getGlobalScope();
  for (var name in patches) {
    var patch = patches[name];
    if (patch) {
      var option = config[name];
      if (!option) option = "original";
      console.info(name + ": " + option);
      assert (option in patch.options);
      var fn = patch.options[option].fn;
      if (fn) {
        scope[patch.original] = Module.patch(null, patch.name, fn);
        console.info("Patching: " + patch.name + ", with: " + option);
      }
    }
  }
}

var patches = {
  "filter": {
    name: "_h264bsdFilterPicture",
    display: "Filter Picture",
    original: "Original_h264bsdFilterPicture",
    options: {
      none: {display: "None", fn: function () {}},
      original: {display: "Original", fn: null},
    }
  },
  "filterHorLuma": {
    name: "_FilterHorLuma",
    display: "Filter Hor Luma",
    original: "OriginalFilterHorLuma",
    options: {
      none: {display: "None", fn: function () {}},
      original: {display: "Original", fn: null},
      optimized: {display: "Optimized", fn: OptimizedFilterHorLuma}
    }
  },
  "filterVerLumaEdge": {
    name: "_FilterVerLumaEdge",
    display: "Filter Ver Luma Edge",
    original: "OriginalFilterVerLumaEdge",
    options: {
      none: {display: "None", fn: function () {}},
      original: {display: "Original", fn: null},
      optimized: {display: "Optimized", fn: OptimizedFilterVerLumaEdge}
    }
  },
  "getBoundaryStrengthsA": {
    name: "_GetBoundaryStrengthsA",
    display: "Get Boundary Strengths",
    original: "OriginalGetBoundaryStrengthsA",
    options: {
      none: {display: "None", fn: function () {}},
      original: {display: "Original", fn: null},
      optimized: {display: "Optimized", fn: OptimizedGetBoundaryStrengthsA}
    }
  }
};

function getGlobalScope() {
  return function () { return this; }.call(null);
}

/* Optimizations */

function clip(x, y, z) {
  return z < x ? x : (z > y ? y : z);
}

function OptimizedGetBoundaryStrengthsA($mb, $bS) {
  var $totalCoeff = $mb + 28;

  var tc0 = HEAP16[$totalCoeff + 0 >> 1];
  var tc1 = HEAP16[$totalCoeff + 2 >> 1];
  var tc2 = HEAP16[$totalCoeff + 4 >> 1];
  var tc3 = HEAP16[$totalCoeff + 6 >> 1];
  var tc4 = HEAP16[$totalCoeff + 8 >> 1];
  var tc5 = HEAP16[$totalCoeff + 10 >> 1];
  var tc6 = HEAP16[$totalCoeff + 12 >> 1];
  var tc7 = HEAP16[$totalCoeff + 14 >> 1];
  var tc8 = HEAP16[$totalCoeff + 16 >> 1];
  var tc9 = HEAP16[$totalCoeff + 18 >> 1];
  var tc10 = HEAP16[$totalCoeff + 20 >> 1];
  var tc11 = HEAP16[$totalCoeff + 22 >> 1];
  var tc12 = HEAP16[$totalCoeff + 24 >> 1];
  var tc13 = HEAP16[$totalCoeff + 26 >> 1];
  var tc14 = HEAP16[$totalCoeff + 28 >> 1];
  var tc15 = HEAP16[$totalCoeff + 30 >> 1];

  HEAP32[$bS + 32 >> 2] = tc2 || tc0 ? 2 : 0;
  HEAP32[$bS + 40 >> 2] = tc3 || tc1 ? 2 : 0;
  HEAP32[$bS + 48 >> 2] = tc6 || tc4 ? 2 : 0;
  HEAP32[$bS + 56 >> 2] = tc7 || tc5 ? 2 : 0;
  HEAP32[$bS + 64 >> 2] = tc8 || tc2 ? 2 : 0;
  HEAP32[$bS + 72 >> 2] = tc9 || tc3 ? 2 : 0;
  HEAP32[$bS + 80 >> 2] = tc12 || tc6 ? 2 : 0;
  HEAP32[$bS + 88 >> 2] = tc13 || tc7 ? 2 : 0;
  HEAP32[$bS + 96 >> 2] = tc10 || tc8 ? 2 : 0;
  HEAP32[$bS + 104 >> 2] = tc11 || tc9 ? 2 : 0;
  HEAP32[$bS + 112 >> 2] = tc14 || tc12 ? 2 : 0;
  HEAP32[$bS + 120 >> 2] = tc15 || tc13 ? 2 : 0;

  HEAP32[$bS + 12 >> 2] = tc1 || tc0 ? 2 : 0;
  HEAP32[$bS + 20 >> 2] = tc4 || tc1 ? 2 : 0;
  HEAP32[$bS + 28 >> 2] = tc5 || tc4 ? 2 : 0;
  HEAP32[$bS + 44 >> 2] = tc3 || tc2 ? 2 : 0;
  HEAP32[$bS + 52 >> 2] = tc6 || tc3 ? 2 : 0;
  HEAP32[$bS + 60 >> 2] = tc7 || tc6 ? 2 : 0;
  HEAP32[$bS + 76 >> 2] = tc9 || tc8 ? 2 : 0;
  HEAP32[$bS + 84 >> 2] = tc12 || tc9 ? 2 : 0;
  HEAP32[$bS + 92 >> 2] = tc13 || tc12 ? 2 : 0;
  HEAP32[$bS + 108 >> 2] = tc11 || tc10 ? 2 : 0;
  HEAP32[$bS + 116 >> 2] = tc14 || tc11 ? 2 : 0;
  HEAP32[$bS + 124 >> 2] = tc15 || tc14 ? 2 : 0;
}

function OptimizedFilterVerLumaEdge ($data, bS, $thresholds, imageWidth) {
  var delta, tc, tmp;
  var p0, q0, p1, q1, p2, q2;
  var tmpFlag;
  var $clp = _h264bsdClip + 512;
  var alpha = HEAP32[$thresholds + 4 >> 2];
  var beta = HEAP32[$thresholds + 8 >> 2];
  var val;

  if (bS < 4) {
    tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255;
    for (var i = 4; i > 0; i--) {
      p1 = HEAPU8[$data + -2] & 255;
      p0 = HEAPU8[$data + -1] & 255;
      q0 = HEAPU8[$data] & 255;
      q1 = HEAPU8[$data + 1] & 255;
      if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) {
        p2 = HEAPU8[$data - 3] & 255;
        if (Math.abs(p2 - p0) < beta) {
          val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1;
          HEAP8[$data - 2] = p1 + clip(-tc, tc, val);
          tmp++;
        }

        q2 = HEAPU8[$data + 2] & 255;
        if (Math.abs(q2 - q0) < beta) {
          val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1;
          HEAP8[$data + 1] = (q1 + clip(-tc, tc, val));
          tmp++;
        }

        val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3);
        delta = clip(-tmp, tmp, val);

        p0 = HEAPU8[$clp + (p0 + delta)] & 255;
        q0 = HEAPU8[$clp + (q0 - delta)] & 255;
        tmp = tc;
        HEAP8[$data - 1] = p0;
        HEAP8[$data] = q0;

        $data += imageWidth;
      }
    }
  } else {
    OriginalFilterVerLumaEdge($data, bS, $thresholds, imageWidth);
  }
}

/**
 * Filter all four successive horizontal 4-pixel luma edges. This can be done when bS is equal to all four edges.
 */
function OptimizedFilterHorLuma ($data, bS, $thresholds, imageWidth) {
  var delta, tc, tmp;
  var p0, q0, p1, q1, p2, q2;
  var tmpFlag;
  var $clp = _h264bsdClip + 512;
  var alpha = HEAP32[$thresholds + 4 >> 2];
  var beta = HEAP32[$thresholds + 8 >> 2];
  var val;

  if (bS < 4) {
    tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255;
    for (var i = 16; i > 0; i--) {
      p1 = HEAPU8[$data + (-imageWidth << 1)] & 255;
      p0 = HEAPU8[$data + -imageWidth] & 255;
      q0 = HEAPU8[$data] & 255;
      q1 = HEAPU8[$data + imageWidth] & 255;

      if ((Math.abs(p0 - q0) < alpha) && (Math.abs(p1 - p0) < beta) && (Math.abs(q1 - q0) < beta)) {
        p2 = HEAPU8[$data + (-imageWidth * 3)] & 255;
        if (Math.abs(p2 - p0) < beta) {
          val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1;
          HEAP8[$data + (-imageWidth << 1)] = p1 + clip(-tc, tc, val);
          tmp++;
        }

        q2 = HEAPU8[$data + (imageWidth << 2)] & 255;
        if (Math.abs(q2 - q0) < beta) {
            val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1;
            HEAP8[$data + imageWidth] = (q1 + clip(-tc, tc, val));
            tmp++;
        }

        val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3);
        delta = clip(-tmp, tmp, val);

        p0 = HEAPU8[$clp + (p0 + delta)] & 255;
        q0 = HEAPU8[$clp + (q0 - delta)] & 255;
        tmp = tc;
        HEAP8[$data - imageWidth] = p0;
        HEAP8[$data] = q0;

        $data ++;
      }
    }
  } else {
    OriginalFilterHorLuma($data, bS, $thresholds, imageWidth);
  }
}
<commit_msg>cleanup global namespace, make strict conform.<commit_after>/**
 * Requires: avc-codec.js
 **/

assert (Module);

var Avc = (function avc() {
    'use strict';

    var MAX_STREAM_BUFFER_LENGTH = 1024 * 1024,
        HEAP8 = Module.HEAP8,
        HEAPU8 = Module.HEAPU8,
        HEAP16 = Module.HEAP16,
        HEAP32 = Module.HEAP32,
        _h264bsdClip = Module._get_h264bsdClip(),
        patches = {
            "filter": {
                name: "_h264bsdFilterPicture",
                display: "Filter Picture",
                original: "Original_h264bsdFilterPicture",
                options: {
                none: {display: "None", fn: function () {}},
                original: {display: "Original", fn: null},
                }
            },
            "filterHorLuma": {
                name: "_FilterHorLuma",
                display: "Filter Hor Luma",
                original: "OriginalFilterHorLuma",
                options: {
                none: {display: "None", fn: function () {}},
                original: {display: "Original", fn: null},
                optimized: {display: "Optimized", fn: OptimizedFilterHorLuma}
                }
            },
            "filterVerLumaEdge": {
                name: "_FilterVerLumaEdge",
                display: "Filter Ver Luma Edge",
                original: "OriginalFilterVerLumaEdge",
                options: {
                none: {display: "None", fn: function () {}},
                original: {display: "Original", fn: null},
                optimized: {display: "Optimized", fn: OptimizedFilterVerLumaEdge}
                }
            },
            "getBoundaryStrengthsA": {
                name: "_GetBoundaryStrengthsA",
                display: "Get Boundary Strengths",
                original: "OriginalGetBoundaryStrengthsA",
                options: {
                none: {display: "None", fn: function () {}},
                original: {display: "Original", fn: null},
                optimized: {display: "Optimized", fn: OptimizedGetBoundaryStrengthsA}
                }
            }
        },
        origFn = {};

    function clip(x, y, z) {
        return z < x ? x : (z > y ? y : z);
    }

    function OptimizedGetBoundaryStrengthsA($mb, $bS) {
        var $totalCoeff = $mb + 28;

        var tc0 = HEAP16[$totalCoeff + 0 >> 1];
        var tc1 = HEAP16[$totalCoeff + 2 >> 1];
        var tc2 = HEAP16[$totalCoeff + 4 >> 1];
        var tc3 = HEAP16[$totalCoeff + 6 >> 1];
        var tc4 = HEAP16[$totalCoeff + 8 >> 1];
        var tc5 = HEAP16[$totalCoeff + 10 >> 1];
        var tc6 = HEAP16[$totalCoeff + 12 >> 1];
        var tc7 = HEAP16[$totalCoeff + 14 >> 1];
        var tc8 = HEAP16[$totalCoeff + 16 >> 1];
        var tc9 = HEAP16[$totalCoeff + 18 >> 1];
        var tc10 = HEAP16[$totalCoeff + 20 >> 1];
        var tc11 = HEAP16[$totalCoeff + 22 >> 1];
        var tc12 = HEAP16[$totalCoeff + 24 >> 1];
        var tc13 = HEAP16[$totalCoeff + 26 >> 1];
        var tc14 = HEAP16[$totalCoeff + 28 >> 1];
        var tc15 = HEAP16[$totalCoeff + 30 >> 1];

        HEAP32[$bS + 32 >> 2] = tc2 || tc0 ? 2 : 0;
        HEAP32[$bS + 40 >> 2] = tc3 || tc1 ? 2 : 0;
        HEAP32[$bS + 48 >> 2] = tc6 || tc4 ? 2 : 0;
        HEAP32[$bS + 56 >> 2] = tc7 || tc5 ? 2 : 0;
        HEAP32[$bS + 64 >> 2] = tc8 || tc2 ? 2 : 0;
        HEAP32[$bS + 72 >> 2] = tc9 || tc3 ? 2 : 0;
        HEAP32[$bS + 80 >> 2] = tc12 || tc6 ? 2 : 0;
        HEAP32[$bS + 88 >> 2] = tc13 || tc7 ? 2 : 0;
        HEAP32[$bS + 96 >> 2] = tc10 || tc8 ? 2 : 0;
        HEAP32[$bS + 104 >> 2] = tc11 || tc9 ? 2 : 0;
        HEAP32[$bS + 112 >> 2] = tc14 || tc12 ? 2 : 0;
        HEAP32[$bS + 120 >> 2] = tc15 || tc13 ? 2 : 0;

        HEAP32[$bS + 12 >> 2] = tc1 || tc0 ? 2 : 0;
        HEAP32[$bS + 20 >> 2] = tc4 || tc1 ? 2 : 0;
        HEAP32[$bS + 28 >> 2] = tc5 || tc4 ? 2 : 0;
        HEAP32[$bS + 44 >> 2] = tc3 || tc2 ? 2 : 0;
        HEAP32[$bS + 52 >> 2] = tc6 || tc3 ? 2 : 0;
        HEAP32[$bS + 60 >> 2] = tc7 || tc6 ? 2 : 0;
        HEAP32[$bS + 76 >> 2] = tc9 || tc8 ? 2 : 0;
        HEAP32[$bS + 84 >> 2] = tc12 || tc9 ? 2 : 0;
        HEAP32[$bS + 92 >> 2] = tc13 || tc12 ? 2 : 0;
        HEAP32[$bS + 108 >> 2] = tc11 || tc10 ? 2 : 0;
        HEAP32[$bS + 116 >> 2] = tc14 || tc11 ? 2 : 0;
        HEAP32[$bS + 124 >> 2] = tc15 || tc14 ? 2 : 0;
    }

    function OptimizedFilterVerLumaEdge ($data, bS, $thresholds, imageWidth) {
        var delta, tc, tmp;
        var p0, q0, p1, q1, p2, q2;
        var tmpFlag;
        var $clp = _h264bsdClip + 512;
        var alpha = HEAP32[$thresholds + 4 >> 2];
        var beta = HEAP32[$thresholds + 8 >> 2];
        var val;

        if (bS < 4) {
            tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255;
            for (var i = 4; i > 0; i--) {
                p1 = HEAPU8[$data + -2] & 255;
                p0 = HEAPU8[$data + -1] & 255;
                q0 = HEAPU8[$data] & 255;
                q1 = HEAPU8[$data + 1] & 255;
                if (
                    (Math.abs(p0 - q0) < alpha) &&
                    (Math.abs(p1 - p0) < beta) &&
                    (Math.abs(q1 - q0) < beta)
                ) {
                    p2 = HEAPU8[$data - 3] & 255;
                    if (Math.abs(p2 - p0) < beta) {
                        val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1;
                        HEAP8[$data - 2] = p1 + clip(-tc, tc, val);
                        tmp++;
                    }

                    q2 = HEAPU8[$data + 2] & 255;
                    if (Math.abs(q2 - q0) < beta) {
                        val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1;
                        HEAP8[$data + 1] = (q1 + clip(-tc, tc, val));
                        tmp++;
                    }

                    val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3);
                    delta = clip(-tmp, tmp, val);

                    p0 = HEAPU8[$clp + (p0 + delta)] & 255;
                    q0 = HEAPU8[$clp + (q0 - delta)] & 255;
                    tmp = tc;
                    HEAP8[$data - 1] = p0;
                    HEAP8[$data] = q0;

                    $data += imageWidth;
                }
            }
        } else {
            origFn.OriginalFilterVerLumaEdge($data, bS, $thresholds, imageWidth);
        }
    }

   /**
    * Filter all four successive horizontal 4-pixel luma edges. This can be
    * done when bS is equal to all four edges.
    */
    function OptimizedFilterHorLuma ($data, bS, $thresholds, imageWidth) {
        var delta, tc, tmp;
        var p0, q0, p1, q1, p2, q2;
        var tmpFlag;
        var $clp = _h264bsdClip + 512;
        var alpha = HEAP32[$thresholds + 4 >> 2];
        var beta = HEAP32[$thresholds + 8 >> 2];
        var val;

        if (bS < 4) {
            tmp = tc = HEAPU8[HEAP32[$thresholds >> 2] + (bS - 1)] & 255;
            for (var i = 16; i > 0; i--) {
                p1 = HEAPU8[$data + (-imageWidth << 1)] & 255;
                p0 = HEAPU8[$data + -imageWidth] & 255;
                q0 = HEAPU8[$data] & 255;
                q1 = HEAPU8[$data + imageWidth] & 255;

                if (
                    (Math.abs(p0 - q0) < alpha) &&
                    (Math.abs(p1 - p0) < beta) &&
                    (Math.abs(q1 - q0) < beta)
                ) {
                    p2 = HEAPU8[$data + (-imageWidth * 3)] & 255;
                    if (Math.abs(p2 - p0) < beta) {
                        val = (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1;
                        HEAP8[$data + (-imageWidth << 1)] = p1 + clip(-tc, tc, val);
                        tmp++;
                    }

                    q2 = HEAPU8[$data + (imageWidth << 2)] & 255;
                    if (Math.abs(q2 - q0) < beta) {
                        val = (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1;
                        HEAP8[$data + imageWidth] = (q1 + clip(-tc, tc, val));
                        tmp++;
                    }

                    val = ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3);
                    delta = clip(-tmp, tmp, val);

                    p0 = HEAPU8[$clp + (p0 + delta)] & 255;
                    q0 = HEAPU8[$clp + (q0 - delta)] & 255;
                    tmp = tc;
                    HEAP8[$data - imageWidth] = p0;
                    HEAP8[$data] = q0;

                    $data ++;
                }
            }
        } else {
            origFn.OriginalFilterHorLuma($data, bS, $thresholds, imageWidth);
        }
    }

    function patchOptimizations(config, patches) {
        for (var name in patches) {
            var patch = patches[name];
            if (patch) {
                var option = config[name];
                if (!option) option = "original";
                console.info(name + ": " + option);
                assert (option in patch.options);
                var fn = patch.options[option].fn;
                if (fn) {
                    origFn[patch.original] = Module.patch(null, patch.name, fn);
                    console.info("Patching: " + patch.name + ", with: " + option);
                    console.log(patch.name, origFn[patch.original]);
                }
            }
        }
    }

    function constructor() {
        Module._broadwayInit();
        this.streamBuffer = toU8Array(Module._broadwayCreateStream(MAX_STREAM_BUFFER_LENGTH), MAX_STREAM_BUFFER_LENGTH);
        this.pictureBuffers = {};

        this.onPictureDecoded = function (buffer, width, height) {
            // console.info(buffer.length);
        };

        Module.patch(null, "_broadwayOnHeadersDecoded", function (x,y,z) {});

        Module.patch(null, "_broadwayOnPictureDecoded", function ($buffer, width, height) {
            var buffer = this.pictureBuffers[$buffer];
            if (!buffer) {
                buffer = this.pictureBuffers[$buffer] = toU8Array($buffer, (width * height * 3) / 2);
            }
            this.onPictureDecoded(buffer, width, height);
        }.bind(this));
    }

   /**
    * Creates a typed array from a HEAP8 pointer.
    */
    function toU8Array(ptr, length) {
        return HEAPU8.subarray(ptr, ptr + length);
    }

    constructor.prototype = {
       /**
        * Decodes a stream buffer. This may be one single (unframed) NAL unit
        * without the start code, or a sequence of NAL units with framing start
        * code prefixes. This function overwrites stream buffer allocated by
        * the codec with the supplied buffer.
        */
        decode: function decode(buffer) {
            // console.info("Decoding: " + buffer.length);
            this.streamBuffer.set(buffer);
            Module._broadwaySetStreamLength(buffer.length);
            Module._broadwayPlayStream();
        },
        configure: function (config) {
            patchOptimizations(config, patches);
            console.info("Broadway Configured: " + JSON.stringify(config));
        }
    };

    return constructor;
})();
<|endoftext|>