<commit_before>/*global define*/

define([
  'jquery',
  'underscore',
  'backbone',
  'templates',
  '../collections/official',
  '../collections/org',
  '../collections/province',
  '../collections/municipal',
  '../collections/dong',
  './officials'
], function ($, _, Backbone, JST, Officials, Orgs, Provinces, Municipals, Dongs, OfficialsView) {
  'use strict'

  var SearchView = Backbone.View.extend({
    template: JST['app/scripts/templates/search.ejs'],

    el: '#search',

    events: {
      'change #selected-orgs'            : 'selectOrgs',
      'change #selected-years'           : 'selectYears',
      'change #selected-provinces'       : 'selectProvince',
      'change #selected-municipals'      : 'selectMunicipal',
      'submit form#form-search-default'  : 'submitDefaultSearch',
      'submit form#form-search-election' : 'submitElectionSearch',
      'click .chip > i'                  : 'closeAChip'
    },

    initialize: function (params) {
      var self = this

      this.params = params
      this.orgs = new Orgs()
      this.provinces = new Provinces()

      this.orgs.reset()
      this.provinces.reset()

      this.orgs.fetch({success: function() {
        self.provinces.fetch({success: function() {
          self.render()
        }})
      }})
    },

    render: function () {
      this.$el.html(this.template())
      this.afterRender()
    },

    afterRender: function() {
      // initialize tabs
      $('#search-tabs > ul.tabs').tabs();
      this.setInitSelectOptions()
      this.drawForms()

      if (!_.isEmpty(this.params)) {
        this.setParams()
        this.getResult(this.params)

        /**
         * if use request with default search option
         */
        if (this.params['keyword'] !== undefined) {
          this.resetTags('default', 'orgs', $('#selected-orgs > option:selected'))
          this.resetTags('default', 'years', $('#selected-years > option:selected'))
        } else if (this.params['election'] !== undefined) {
          /**
         * if use request with election cadidates search option
         */
          $('#search-tabs > ul.tabs').tabs('select_tab', 'search-election');
          this.setParams()
          this.getResult(this.params)
        }
      } else {
        this.hideLoadingDiv()
      }

    },

    showLoadingDiv: function() {
      $('#page-search .search-loading').show()
    },

    hideLoadingDiv: function() {
      $('#page-search .search-loading').hide()
    },

    setInitSelectOptions: function() {
      var self = this

      this.orgs.models.forEach(function(m) {
        $('#selected-orgs').append($('<option>', {
          id: 'option-orgs-id-' + m.get('id'),
          value: m.get('title'),
          text: m.get('title')
        }))
      })

      this.provinces.forEach(function(p) {
        $('#selected-provinces').append($('<option>', {
          id: 'option-provinces-id-' + p.get('id'),
          value: p.get('name'),
          text: p.get('name')
        }))
      })
    },

    /**
     * [setParams description]
     * set options in form if url has parameters like keyword, provinces, and so on
     */
    setParams: function() {
      var self = this
      var params = this.params

      if (params.org) {
        var orgOps = $('#selected-orgs > option')

        if (typeof params.org === 'string') {
          params.org = params.org.split(',')
        }

        for (var i = 0; i < orgOps.length; i++) {
          if (params.org.indexOf($(orgOps[i]).val()) > -1) $(orgOps[i]).attr('selected', 'selected')
        }
      }

      if (params.year) {
        var yearOps = $('#selected-years > option')

        if (typeof params.year === 'string') {
          params.year = params.year.split(',')
        }

        for (var i = 0; i < yearOps.length; i++) {
          if (params.year.indexOf($(yearOps[i]).val()) > -1) $(yearOps[i]).attr('selected', 'selected')
        }
      }

      if (params.election) {
        if (params.keyword) {
          $('#selected-keyword-election').val(params.keyword)
        }

        var provinceOps = $('#selected-provinces > option:not(:disabled)')

        for (var i = 0; i < provinceOps.length; i++) {
          if (params.province === $(provinceOps[i]).val()) {
            $(provinceOps[i]).prop('selected', true)
            $('#selected-provinces').material_select()
            break;
          }
        }

        this.selectProvince(function() {
          var municipalOps = $('#selected-municipals > option:not(:disabled)')

          for (var i = 0; i < municipalOps.length; i++) {
            if (params.municipal === $(municipalOps[i]).val()) {
              $(municipalOps[i]).prop('selected', true)
              $('#selected-municipals').material_select()
              break;
            }
          }

          self.selectMunicipal(function() {
            var dongOps = $('#selected-dongs > option:not(:disabled)')

            for (var i = 0; i < dongOps.length; i++) {
              if (params.dong === $(dongOps[i]).val()) {
                $(dongOps[i]).prop('selected', true)
                $('#selected-dongs').material_select()
                break;
              }
            }

          })
        })
      }
    },
    /**
     * end of setParams
     */

    drawForms: function() {
      $('#selected-orgs').material_select();
      $('#selected-years').material_select();
      $('#selected-provinces').material_select();
      $('#selected-municipals').material_select();
      $('#selected-dongs').material_select();
    },

    selectOrgs: function(e) {
      this.resetTags('default', 'orgs', $('#selected-orgs > option:selected'))
    },

    selectYears: function() {
      this.resetTags('default', 'years', $('#selected-years > option:selected'))
    },

    selectProvince: function(callback) {
      var self = this
      var cb = callback ? callback : function(){}
      // this.resetTags('election', 'provinces', $('#selected-provinces > option:selected'))

      self.initRegionOptions($('#selected-municipals'))
      self.initRegionOptions($('#selected-dongs'))

      this.municipals = new Municipals()
      this.municipals.fetch({data: 'province=' + $('#selected-provinces').val(), success: function() {
        self.municipals.models.forEach(function(m) {
          $('#selected-municipals').append($('<option>', {
            id: 'option-municipals-id-' + m.get('id'),
            value: m.get('name'),
            text: m.get('name')
          }))
        })

        $('#selected-municipals').material_select()

        cb()
      }})
    },

    selectMunicipal: function(callback) {
      var self = this
      var cb = callback ? callback : function(){}
      // this.resetTags('election', 'municipals', $('#selected-municipals > option:selected'))
      self.initRegionOptions($('#selected-dongs'))

      this.dongs = new Dongs()
      this.dongs.fetch({data: 'municipal=' + $('#selected-municipals').val(), success: function() {
        self.dongs.models.forEach(function(m) {
          $('#selected-dongs').append($('<option>', {
            id: 'option-dongs-id-' + m.get('id'),
            value: m.get('name'),
            text: m.get('name')
          }))
        })

        $('#selected-dongs').material_select()
        cb()
      }})
    },

    initRegionOptions: function(target) {
      var text = target.attr('id') === 'selected-municipals' ? '시/군/구를 선택하세요' : '읍/면/동을 선택하세요'
      target.html('')

      target.append($('<option>', {
        selected: true,
        disabled: true,
        value: text,
        text: text
      }))

      target.material_select()
    },

    submitDefaultSearch: function(e) {
      var self = this

      // if user click the submit button
      if (e) e.preventDefault()

      var params = {}
      params.org = $('#selected-orgs').val()
      params.year = $('#selected-years').val()
      params.keyword = $('#selected-keyword').val()

      // set current url with query parameters
      Backbone.history.navigate('?' + this.fixEncodeURI($.param(params)))
      // find results
      this.getResult(params)
    },

    submitElectionSearch: function(e) {
      var self = this

      // if user click the submit button
      if (e) e.preventDefault()

      var params = {}
      if ($('#selected-provinces').val()) {
        params.province = $('#selected-provinces').val()
      }

      if ($('#selected-municipals').val()) {
        params.municipal = $('#selected-municipals').val()
      }

      if ($('#selected-dongs').val()) {
        params.dong = $('#selected-dongs').val()
      }

      if ($('#selected-keyword-election').val()) {
        params.keyword = $('#selected-keyword-election').val()
      }

      params.election = 1

      // set current url with query parameters
      Backbone.history.navigate('?' + this.fixEncodeURI($.param(params)))
      // find results
      this.getResult(params)
    },

    fixEncodeURI: function(param) {
      return param.replace(/%5B/g, '').replace(/%5D/g, '');
    },

    getResult: function(params) {
      if (this.resultView) {
        this.resultView.destroy()
      }

      // show results in the active tab
      // between #search-default and #search-election
      params.el = $('#search-tabs li.tab > a.active').attr('href') + '-result'
      this.resultView = new OfficialsView(params)
    },

    resetTags: function(category, subcategory, values) {
      if (category === 'default') {
        var valLength = values.length - 1
        var initNum = 1
      } else {
        var valLength = values.length
        var initNum = 0
      }
      var chips = $('#tags-' + category + ' > .col > .chip.chip-' + subcategory)

      if (valLength > chips.length) {
        // if user added a tag
        for (; initNum < values.length; initNum++) {
          var id = $(values[initNum]).attr('id').split('-')[3]

          if ($('#chip-' + subcategory + '-id-' + id).length === 0) {
            $('#tags-' + category + ' > .col').append('' + $(values[initNum]).val() + 'close')
          }
        }
      } else {
        // if user removed a tag
        for (var i = 0; i < chips.length; i++) {
          var id = $(chips[i]).attr('id').split('-')[3]

          if ($('#option-' + subcategory + '-id-' + id).prop('selected') === false) {
             $('#chip-' + subcategory + '-id-' + id).remove()
          }
        }
      }
    },

    closeAChip: function(e) {
      var id = 'option-' + $(e.target).closest('.chip').attr('id').split('-').slice(1).join('-')

      $('option#' + id).prop('selected', false)
      $('#selected-' + $(e.target).closest('.chip').attr('id').split('-')[1]).material_select()
    },

    destroy: function() {
      this.undelegateEvents();
      this.$el.empty();
      this.stopListening();
      return this;
    }
  })

  return SearchView
})
<commit_msg>chage order to render search page and load collection<commit_after>/*global define*/

define([
  'jquery',
  'underscore',
  'backbone',
  'templates',
  '../collections/official',
  '../collections/org',
  '../collections/province',
  '../collections/municipal',
  '../collections/dong',
  './officials'
], function ($, _, Backbone, JST, Officials, Orgs, Provinces, Municipals, Dongs, OfficialsView) {
  'use strict'

  var SearchView = Backbone.View.extend({
    template: JST['app/scripts/templates/search.ejs'],

    el: '#search',

    events: {
      'change #selected-orgs'            : 'selectOrgs',
      'change #selected-years'           : 'selectYears',
      'change #selected-provinces'       : 'selectProvince',
      'change #selected-municipals'      : 'selectMunicipal',
      'submit form#form-search-default'  : 'submitDefaultSearch',
      'submit form#form-search-election' : 'submitElectionSearch',
      'click .chip > i'                  : 'closeAChip'
    },

    initialize: function (params) {
      var self = this
      this.params = params
      this.render()
    },

    render: function () {
      this.$el.html(this.template())
      this.afterRender()
    },

    afterRender: function() {
      var self = this
      this.orgs = new Orgs()
      this.provinces = new Provinces()

      this.orgs.reset()
      this.provinces.reset()

      this.orgs.fetch({success: function() {
        self.provinces.fetch({success: function() {
          $('#search-tabs > ul.tabs').tabs();
          self.setInitSelectOptions()
          self.drawForms()

          if (!_.isEmpty(self.params)) {
            self.setParams()
            self.getResult(self.params)

            /**
             * if use request with default search option
             */
            if (self.params['keyword'] !== undefined) {
              self.resetTags('default', 'orgs', $('#selected-orgs > option:selected'))
              self.resetTags('default', 'years', $('#selected-years > option:selected'))
            } else if (self.params['election'] !== undefined) {
              /**
             * if use request with election cadidates search option
             */
              $('#search-tabs > ul.tabs').tabs('select_tab', 'search-election');
              self.setParams()
              self.getResult(self.params)
            }
          } else {
            self.hideLoadingDiv()
          }

        }})
      }})
      // initialize tabs

    },

    showLoadingDiv: function() {
      $('#page-search .search-loading').show()
    },

    hideLoadingDiv: function() {
      $('#page-search .search-loading').hide()
    },

    setInitSelectOptions: function() {
      var self = this

      this.orgs.models.forEach(function(m) {
        $('#selected-orgs').append($('<option>', {
          id: 'option-orgs-id-' + m.get('id'),
          value: m.get('title'),
          text: m.get('title')
        }))
      })

      this.provinces.forEach(function(p) {
        $('#selected-provinces').append($('<option>', {
          id: 'option-provinces-id-' + p.get('id'),
          value: p.get('name'),
          text: p.get('name')
        }))
      })
    },

    /**
     * [setParams description]
     * set options in form if url has parameters like keyword, provinces, and so on
     */
    setParams: function() {
      var self = this
      var params = this.params

      if (params.org) {
        var orgOps = $('#selected-orgs > option')

        if (typeof params.org === 'string') {
          params.org = params.org.split(',')
        }

        for (var i = 0; i < orgOps.length; i++) {
          if (params.org.indexOf($(orgOps[i]).val()) > -1) $(orgOps[i]).attr('selected', 'selected')
        }
      }

      if (params.year) {
        var yearOps = $('#selected-years > option')

        if (typeof params.year === 'string') {
          params.year = params.year.split(',')
        }

        for (var i = 0; i < yearOps.length; i++) {
          if (params.year.indexOf($(yearOps[i]).val()) > -1) $(yearOps[i]).attr('selected', 'selected')
        }
      }

      if (params.election) {
        if (params.keyword) {
          $('#selected-keyword-election').val(params.keyword)
        }

        var provinceOps = $('#selected-provinces > option:not(:disabled)')

        for (var i = 0; i < provinceOps.length; i++) {
          if (params.province === $(provinceOps[i]).val()) {
            $(provinceOps[i]).prop('selected', true)
            $('#selected-provinces').material_select()
            break;
          }
        }

        this.selectProvince(function() {
          var municipalOps = $('#selected-municipals > option:not(:disabled)')

          for (var i = 0; i < municipalOps.length; i++) {
            if (params.municipal === $(municipalOps[i]).val()) {
              $(municipalOps[i]).prop('selected', true)
              $('#selected-municipals').material_select()
              break;
            }
          }

          self.selectMunicipal(function() {
            var dongOps = $('#selected-dongs > option:not(:disabled)')

            for (var i = 0; i < dongOps.length; i++) {
              if (params.dong === $(dongOps[i]).val()) {
                $(dongOps[i]).prop('selected', true)
                $('#selected-dongs').material_select()
                break;
              }
            }

          })
        })
      }
    },
    /**
     * end of setParams
     */

    drawForms: function() {
      $('#selected-orgs').material_select();
      $('#selected-years').material_select();
      $('#selected-provinces').material_select();
      $('#selected-municipals').material_select();
      $('#selected-dongs').material_select();
    },

    selectOrgs: function(e) {
      this.resetTags('default', 'orgs', $('#selected-orgs > option:selected'))
    },

    selectYears: function() {
      this.resetTags('default', 'years', $('#selected-years > option:selected'))
    },

    selectProvince: function(callback) {
      var self = this
      var cb = callback ? callback : function(){}
      // this.resetTags('election', 'provinces', $('#selected-provinces > option:selected'))

      self.initRegionOptions($('#selected-municipals'))
      self.initRegionOptions($('#selected-dongs'))

      this.municipals = new Municipals()
      this.municipals.fetch({data: 'province=' + $('#selected-provinces').val(), success: function() {
        self.municipals.models.forEach(function(m) {
          $('#selected-municipals').append($('<option>', {
            id: 'option-municipals-id-' + m.get('id'),
            value: m.get('name'),
            text: m.get('name')
          }))
        })

        $('#selected-municipals').material_select()

        cb()
      }})
    },

    selectMunicipal: function(callback) {
      var self = this
      var cb = callback ? callback : function(){}
      // this.resetTags('election', 'municipals', $('#selected-municipals > option:selected'))
      self.initRegionOptions($('#selected-dongs'))

      this.dongs = new Dongs()
      this.dongs.fetch({data: 'municipal=' + $('#selected-municipals').val(), success: function() {
        self.dongs.models.forEach(function(m) {
          $('#selected-dongs').append($('<option>', {
            id: 'option-dongs-id-' + m.get('id'),
            value: m.get('name'),
            text: m.get('name')
          }))
        })

        $('#selected-dongs').material_select()
        cb()
      }})
    },

    initRegionOptions: function(target) {
      var text = target.attr('id') === 'selected-municipals' ? '시/군/구를 선택하세요' : '읍/면/동을 선택하세요'
      target.html('')

      target.append($('<option>', {
        selected: true,
        disabled: true,
        value: text,
        text: text
      }))

      target.material_select()
    },

    submitDefaultSearch: function(e) {
      var self = this

      // if user click the submit button
      if (e) e.preventDefault()

      var params = {}
      params.org = $('#selected-orgs').val()
      params.year = $('#selected-years').val()
      params.keyword = $('#selected-keyword').val()

      // set current url with query parameters
      Backbone.history.navigate('?' + this.fixEncodeURI($.param(params)))
      // find results
      this.getResult(params)
    },

    submitElectionSearch: function(e) {
      var self = this

      // if user click the submit button
      if (e) e.preventDefault()

      var params = {}
      if ($('#selected-provinces').val()) {
        params.province = $('#selected-provinces').val()
      }

      if ($('#selected-municipals').val()) {
        params.municipal = $('#selected-municipals').val()
      }

      if ($('#selected-dongs').val()) {
        params.dong = $('#selected-dongs').val()
      }

      if ($('#selected-keyword-election').val()) {
        params.keyword = $('#selected-keyword-election').val()
      }

      params.election = 1

      // set current url with query parameters
      Backbone.history.navigate('?' + this.fixEncodeURI($.param(params)))
      // find results
      this.getResult(params)
    },

    fixEncodeURI: function(param) {
      return param.replace(/%5B/g, '').replace(/%5D/g, '');
    },

    getResult: function(params) {
      if (this.resultView) {
        this.resultView.destroy()
      }

      // show results in the active tab
      // between #search-default and #search-election
      params.el = $('#search-tabs li.tab > a.active').attr('href') + '-result'
      this.resultView = new OfficialsView(params)
    },

    resetTags: function(category, subcategory, values) {
      if (category === 'default') {
        var valLength = values.length - 1
        var initNum = 1
      } else {
        var valLength = values.length
        var initNum = 0
      }
      var chips = $('#tags-' + category + ' > .col > .chip.chip-' + subcategory)

      if (valLength > chips.length) {
        // if user added a tag
        for (; initNum < values.length; initNum++) {
          var id = $(values[initNum]).attr('id').split('-')[3]

          if ($('#chip-' + subcategory + '-id-' + id).length === 0) {
            $('#tags-' + category + ' > .col').append('' + $(values[initNum]).val() + 'close')
          }
        }
      } else {
        // if user removed a tag
        for (var i = 0; i < chips.length; i++) {
          var id = $(chips[i]).attr('id').split('-')[3]

          if ($('#option-' + subcategory + '-id-' + id).prop('selected') === false) {
             $('#chip-' + subcategory + '-id-' + id).remove()
          }
        }
      }
    },

    closeAChip: function(e) {
      var id = 'option-' + $(e.target).closest('.chip').attr('id').split('-').slice(1).join('-')

      $('option#' + id).prop('selected', false)
      $('#selected-' + $(e.target).closest('.chip').attr('id').split('-')[1]).material_select()
    },

    destroy: function() {
      this.undelegateEvents();
      this.$el.empty();
      this.stopListening();
      return this;
    }
  })

  return SearchView
})
<|endoftext|>


<commit_before>// MIT License:
//
// Copyright (c) 2010, Joe Walnes
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/**
 * Smoothie Charts - http://smoothiecharts.org/
 * (c) 2010, Joe Walnes
 *
 * v1.0: Main charting library, by Joe Walnes
 * v1.1: Auto scaling of axis, by Neil Dunn
 * v1.2: fps (frames per second) option, by Mathias Petterson
 */

function TimeSeries() {
  this.data = [];
  /**
   * The maximum value ever seen in this time series.
   */
  this.max = Number.NaN;
  /**
   * The minimum value ever seen in this time series.
   */
  this.min = Number.NaN;
}

TimeSeries.prototype.append = function(timestamp, value) {
  this.data.push([timestamp, value]);
  this.maxValue = !isNaN(this.maxValue) ? Math.max(this.maxValue, value) : value;
  this.minValue = !isNaN(this.minValue) ? Math.min(this.minValue, value) : value;
};

function SmoothieChart(options) {
  // Defaults
  options = options || {};
  options.grid = options.grid || { fillStyle:'#000000', strokeStyle: '#777777', lineWidth: 1, millisPerLine: 1000, verticalSections: 2 };
  options.millisPerPixel = options.millisPerPixel || 20;
  options.fps = options.fps || 20;
  options.labels = options.labels || { fillStyle:'#ffffff' }
  this.options = options;
  this.seriesSet = [];
}

SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) {
  this.seriesSet.push({timeSeries: timeSeries, options: options || {}});
};

SmoothieChart.prototype.streamTo = function(canvas, delay) {
  var self = this;
  (function render() {
    self.render(canvas, new Date().getTime() - (delay || 0));
    setTimeout(render, 1000/self.options.fps);
  })()
};

SmoothieChart.prototype.render = function(canvas, time) {
  var canvasContext = canvas.getContext("2d");
  var options = this.options;
  var dimensions = {top: 0, left: 0, width: canvas.clientWidth, height: canvas.clientHeight};

  // Save the state of the canvas context, any transformations applied in this method
  // will get removed from the stack at the end of this method when .restore() is called.
  canvasContext.save();

  // Round time down to pixel granularity, so motion appears smoother.
  time = time - time % options.millisPerPixel;

  // Move the origin.
  canvasContext.translate(dimensions.left, dimensions.top);

  // Create a clipped rectangle - anything we draw will be constrained to this rectangle.
  // This prevents the occasional pixels from curves near the edges overrunning and creating
  // screen cheese (that phrase should neeed no explanation).
  canvasContext.beginPath();
  canvasContext.rect(0, 0, dimensions.width, dimensions.height);
  canvasContext.clip();

  // Clear the working area.
  canvasContext.save();
  canvasContext.fillStyle = options.grid.fillStyle;
  canvasContext.fillRect(0, 0, dimensions.width, dimensions.height);
  canvasContext.restore();

  // Grid lines....
  canvasContext.save();
  canvasContext.lineWidth = options.grid.lineWidth || 1;
  canvasContext.strokeStyle = options.grid.strokeStyle || '#ffffff';
  // Vertical (time) dividers.
  if (options.grid.millisPerLine > 0) {
    for (var t = time - (time % options.grid.millisPerLine); t >= time - (dimensions.width * options.millisPerPixel); t -= options.grid.millisPerLine) {
      canvasContext.beginPath();
      var gx = Math.round(dimensions.width - ((time - t) / options.millisPerPixel));
      canvasContext.moveTo(gx, 0);
      canvasContext.lineTo(gx, dimensions.height);
      canvasContext.stroke();
      canvasContext.closePath();
    }
  }

  // Horizontal (value) dividers.
  for (var v = 1; v < options.grid.verticalSections; v++) {
    var gy = Math.round(v * dimensions.height / options.grid.verticalSections);
    canvasContext.beginPath();
    canvasContext.moveTo(0, gy);
    canvasContext.lineTo(dimensions.width, gy);
    canvasContext.stroke();
    canvasContext.closePath();
  }
  // Bounding rectangle.
  canvasContext.beginPath();
  canvasContext.strokeRect(0, 0, dimensions.width, dimensions.height);
  canvasContext.closePath();
  canvasContext.restore();

  // Calculate the current scale of the chart, from all time series.
  var maxValue = Number.NaN;
  var minValue = Number.NaN;

  for (var d = 0; d < this.seriesSet.length; d++) {
      // TODO(ndunn): We could calculate / track these values as they stream in.
      var timeSeries = this.seriesSet[d].timeSeries;
      if (!isNaN(timeSeries.maxValue)) {
          maxValue = !isNaN(maxValue) ? Math.max(maxValue, timeSeries.maxValue) : timeSeries.maxValue;
      }

      if (!isNaN(timeSeries.minValue)) {
          minValue = !isNaN(minValue) ? Math.min(minValue, timeSeries.minValue) : timeSeries.minValue;
      }
  }

  if (isNaN(maxValue) && isNaN(minValue)) {
      return;
  }

  var valueRange = maxValue - minValue;

  // For each data set...
  for (var d = 0; d < this.seriesSet.length; d++) {
    canvasContext.save();
    var timeSeries = this.seriesSet[d].timeSeries;
    var dataSet = timeSeries.data;
    var seriesOptions = this.seriesSet[d].options;

    // Delete old data that's moved off the left of the chart.
    // We must always keep the last expired data point as we need this to draw the
    // line that comes into the chart, but any points prior to that can be removed.
    while (dataSet.length >= 2 && dataSet[1][0] < time - (dimensions.width * options.millisPerPixel)) {
      dataSet.splice(0, 1);
    }

    // Set style for this dataSet.
    canvasContext.lineWidth = seriesOptions.lineWidth || 1;
    canvasContext.fillStyle = seriesOptions.fillStyle;
    canvasContext.strokeStyle = seriesOptions.strokeStyle || '#ffffff';
    // Draw the line...
    canvasContext.beginPath();
    // Retain lastX, lastY for calculating the control points of bezier curves.
    var firstX = 0, lastX = 0, lastY = 0;
    for (var i = 0; i < dataSet.length; i++) {
      // TODO: Deal with dataSet.length < 2.
      var x = Math.round(dimensions.width - ((time - dataSet[i][0]) / options.millisPerPixel));
      var value = dataSet[i][1];
      var offset = maxValue - value;
      var scaledValue = valueRange ? Math.round((offset / valueRange) * dimensions.height) : 0;
      var y = Math.max(Math.min(scaledValue, dimensions.height - 1), 1); // Ensure line is always on chart.

      if (i == 0) {
        firstX = x;
        canvasContext.moveTo(x, y);
      }
      // Great explanation of Bezier curves: http://en.wikipedia.org/wiki/B�zier_curve#Quadratic_curves
      //
      // Assuming A was the last point in the line plotted and B is the new point,
      // we draw a curve with control points P and Q as below.
      //
      // A---P
      //     |
      //     |
      //     |
      //     Q---B
      //
      // Importantly, A and P are at the same y coordinate, as are B and Q. This is
      // so adjacent curves appear to flow as one.
      //
      else {
        canvasContext.bezierCurveTo( // startPoint (A) is implicit from last iteration of loop
          Math.round((lastX + x) / 2), lastY, // controlPoint1 (P)
          Math.round((lastX + x)) / 2, y, // controlPoint2 (Q)
          x, y); // endPoint (B)
      }

      lastX = x, lastY = y;
    }
    if (dataSet.length > 0 && seriesOptions.fillStyle) {
      // Close up the fill region.
      canvasContext.lineTo(dimensions.width + seriesOptions.lineWidth + 1, lastY);
      canvasContext.lineTo(dimensions.width + seriesOptions.lineWidth + 1, dimensions.height + seriesOptions.lineWidth + 1);
      canvasContext.lineTo(firstX, dimensions.height + seriesOptions.lineWidth);
      canvasContext.fill();
    }
    canvasContext.stroke();
    canvasContext.closePath();
    canvasContext.restore();
  }

  // Draw the axis values on the chart.
  if (!options.labels.disabled) {
      canvasContext.fillStyle = options.labels.fillStyle;
      var maxValueString = maxValue.toFixed(2);
      var minValueString = minValue.toFixed(2);
      canvasContext.fillText(maxValueString, dimensions.width - canvasContext.measureText(maxValueString).width - 2, 10);
      canvasContext.fillText(minValueString, dimensions.width - canvasContext.measureText(minValueString).width - 2, dimensions.height - 2);
  }

  canvasContext.restore(); // See .save() above.
}
<commit_msg>Credited pftg<commit_after>// MIT License:
//
// Copyright (c) 2010, Joe Walnes
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/**
 * Smoothie Charts - http://smoothiecharts.org/
 * (c) 2010, Joe Walnes
 *
 * v1.0: Main charting library, by Joe Walnes
 * v1.1: Auto scaling of axis, by Neil Dunn
 * v1.2: fps (frames per second) option, by Mathias Petterson
 * v1.3: Fix for divide by zero, by Paul Nikitochkin
 */

function TimeSeries() {
  this.data = [];
  /**
   * The maximum value ever seen in this time series.
   */
  this.max = Number.NaN;
  /**
   * The minimum value ever seen in this time series.
   */
  this.min = Number.NaN;
}

TimeSeries.prototype.append = function(timestamp, value) {
  this.data.push([timestamp, value]);
  this.maxValue = !isNaN(this.maxValue) ? Math.max(this.maxValue, value) : value;
  this.minValue = !isNaN(this.minValue) ? Math.min(this.minValue, value) : value;
};

function SmoothieChart(options) {
  // Defaults
  options = options || {};
  options.grid = options.grid || { fillStyle:'#000000', strokeStyle: '#777777', lineWidth: 1, millisPerLine: 1000, verticalSections: 2 };
  options.millisPerPixel = options.millisPerPixel || 20;
  options.fps = options.fps || 20;
  options.labels = options.labels || { fillStyle:'#ffffff' }
  this.options = options;
  this.seriesSet = [];
}

SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) {
  this.seriesSet.push({timeSeries: timeSeries, options: options || {}});
};

SmoothieChart.prototype.streamTo = function(canvas, delay) {
  var self = this;
  (function render() {
    self.render(canvas, new Date().getTime() - (delay || 0));
    setTimeout(render, 1000/self.options.fps);
  })()
};

SmoothieChart.prototype.render = function(canvas, time) {
  var canvasContext = canvas.getContext("2d");
  var options = this.options;
  var dimensions = {top: 0, left: 0, width: canvas.clientWidth, height: canvas.clientHeight};

  // Save the state of the canvas context, any transformations applied in this method
  // will get removed from the stack at the end of this method when .restore() is called.
  canvasContext.save();

  // Round time down to pixel granularity, so motion appears smoother.
  time = time - time % options.millisPerPixel;

  // Move the origin.
  canvasContext.translate(dimensions.left, dimensions.top);

  // Create a clipped rectangle - anything we draw will be constrained to this rectangle.
  // This prevents the occasional pixels from curves near the edges overrunning and creating
  // screen cheese (that phrase should neeed no explanation).
  canvasContext.beginPath();
  canvasContext.rect(0, 0, dimensions.width, dimensions.height);
  canvasContext.clip();

  // Clear the working area.
  canvasContext.save();
  canvasContext.fillStyle = options.grid.fillStyle;
  canvasContext.fillRect(0, 0, dimensions.width, dimensions.height);
  canvasContext.restore();

  // Grid lines....
  canvasContext.save();
  canvasContext.lineWidth = options.grid.lineWidth || 1;
  canvasContext.strokeStyle = options.grid.strokeStyle || '#ffffff';
  // Vertical (time) dividers.
  if (options.grid.millisPerLine > 0) {
    for (var t = time - (time % options.grid.millisPerLine); t >= time - (dimensions.width * options.millisPerPixel); t -= options.grid.millisPerLine) {
      canvasContext.beginPath();
      var gx = Math.round(dimensions.width - ((time - t) / options.millisPerPixel));
      canvasContext.moveTo(gx, 0);
      canvasContext.lineTo(gx, dimensions.height);
      canvasContext.stroke();
      canvasContext.closePath();
    }
  }

  // Horizontal (value) dividers.
  for (var v = 1; v < options.grid.verticalSections; v++) {
    var gy = Math.round(v * dimensions.height / options.grid.verticalSections);
    canvasContext.beginPath();
    canvasContext.moveTo(0, gy);
    canvasContext.lineTo(dimensions.width, gy);
    canvasContext.stroke();
    canvasContext.closePath();
  }
  // Bounding rectangle.
  canvasContext.beginPath();
  canvasContext.strokeRect(0, 0, dimensions.width, dimensions.height);
  canvasContext.closePath();
  canvasContext.restore();

  // Calculate the current scale of the chart, from all time series.
  var maxValue = Number.NaN;
  var minValue = Number.NaN;

  for (var d = 0; d < this.seriesSet.length; d++) {
      // TODO(ndunn): We could calculate / track these values as they stream in.
      var timeSeries = this.seriesSet[d].timeSeries;
      if (!isNaN(timeSeries.maxValue)) {
          maxValue = !isNaN(maxValue) ? Math.max(maxValue, timeSeries.maxValue) : timeSeries.maxValue;
      }

      if (!isNaN(timeSeries.minValue)) {
          minValue = !isNaN(minValue) ? Math.min(minValue, timeSeries.minValue) : timeSeries.minValue;
      }
  }

  if (isNaN(maxValue) && isNaN(minValue)) {
      return;
  }

  var valueRange = maxValue - minValue;

  // For each data set...
  for (var d = 0; d < this.seriesSet.length; d++) {
    canvasContext.save();
    var timeSeries = this.seriesSet[d].timeSeries;
    var dataSet = timeSeries.data;
    var seriesOptions = this.seriesSet[d].options;

    // Delete old data that's moved off the left of the chart.
    // We must always keep the last expired data point as we need this to draw the
    // line that comes into the chart, but any points prior to that can be removed.
    while (dataSet.length >= 2 && dataSet[1][0] < time - (dimensions.width * options.millisPerPixel)) {
      dataSet.splice(0, 1);
    }

    // Set style for this dataSet.
    canvasContext.lineWidth = seriesOptions.lineWidth || 1;
    canvasContext.fillStyle = seriesOptions.fillStyle;
    canvasContext.strokeStyle = seriesOptions.strokeStyle || '#ffffff';
    // Draw the line...
    canvasContext.beginPath();
    // Retain lastX, lastY for calculating the control points of bezier curves.
    var firstX = 0, lastX = 0, lastY = 0;
    for (var i = 0; i < dataSet.length; i++) {
      // TODO: Deal with dataSet.length < 2.
      var x = Math.round(dimensions.width - ((time - dataSet[i][0]) / options.millisPerPixel));
      var value = dataSet[i][1];
      var offset = maxValue - value;
      var scaledValue = valueRange ? Math.round((offset / valueRange) * dimensions.height) : 0;
      var y = Math.max(Math.min(scaledValue, dimensions.height - 1), 1); // Ensure line is always on chart.

      if (i == 0) {
        firstX = x;
        canvasContext.moveTo(x, y);
      }
      // Great explanation of Bezier curves: http://en.wikipedia.org/wiki/B�zier_curve#Quadratic_curves
      //
      // Assuming A was the last point in the line plotted and B is the new point,
      // we draw a curve with control points P and Q as below.
      //
      // A---P
      //     |
      //     |
      //     |
      //     Q---B
      //
      // Importantly, A and P are at the same y coordinate, as are B and Q. This is
      // so adjacent curves appear to flow as one.
      //
      else {
        canvasContext.bezierCurveTo( // startPoint (A) is implicit from last iteration of loop
          Math.round((lastX + x) / 2), lastY, // controlPoint1 (P)
          Math.round((lastX + x)) / 2, y, // controlPoint2 (Q)
          x, y); // endPoint (B)
      }

      lastX = x, lastY = y;
    }
    if (dataSet.length > 0 && seriesOptions.fillStyle) {
      // Close up the fill region.
      canvasContext.lineTo(dimensions.width + seriesOptions.lineWidth + 1, lastY);
      canvasContext.lineTo(dimensions.width + seriesOptions.lineWidth + 1, dimensions.height + seriesOptions.lineWidth + 1);
      canvasContext.lineTo(firstX, dimensions.height + seriesOptions.lineWidth);
      canvasContext.fill();
    }
    canvasContext.stroke();
    canvasContext.closePath();
    canvasContext.restore();
  }

  // Draw the axis values on the chart.
  if (!options.labels.disabled) {
      canvasContext.fillStyle = options.labels.fillStyle;
      var maxValueString = maxValue.toFixed(2);
      var minValueString = minValue.toFixed(2);
      canvasContext.fillText(maxValueString, dimensions.width - canvasContext.measureText(maxValueString).width - 2, 10);
      canvasContext.fillText(minValueString, dimensions.width - canvasContext.measureText(minValueString).width - 2, dimensions.height - 2);
  }

  canvasContext.restore(); // See .save() above.
}
<|endoftext|>


<commit_before>$.fn.scrollTo = function( target, options, callback ){
  if(typeof options == 'function' && arguments.length == 2){ callback = options; options = target; }
  var settings = $.extend({
    scrollTarget  : target,
    offsetTop     : 50,
    duration      : 500,
    easing        : 'swing'
  }, options);
  return this.each(function(){
    var scrollPane = $(this);
    var scrollTarget = (typeof settings.scrollTarget == "number") ? settings.scrollTarget : $(settings.scrollTarget);
    var scrollY = (typeof scrollTarget == "number") ? scrollTarget : scrollTarget.offset().top + scrollPane.scrollTop() - parseInt(settings.offsetTop);
    scrollPane.animate({scrollTop : scrollY }, parseInt(settings.duration), settings.easing, function(){
      if (typeof callback == 'function') { callback.call(this); }
    });
  });
}<commit_msg>remove unused ScrollTo.js<commit_after><|endoftext|>


<commit_before>/* yunmai-new-token

 Copyright Conor O'Neill 2017 (conor@conoroneill.com)
 LICENSE: MIT

This app grabs a new Yunmai code and token from a connected Android device.

Run this app with your phone connected via USB and then launch the Yunmai app.
After a few seconds it should print the new token and code to the console which you can then paste into conf.toml. If more than one pair is printed, use the last one presented, as the others may be just from the log history.

Note you must have [Android Platform Tools](https://developer.android.com/studio/releases/platform-tools.html#download) installed in Windows where adb can be found at C:\Program Files (x86)\Android\android-sdk\platform-tools\\adb.exe

Users of OSX and Linux can just tweak the adb command below to get what they need.

*/
var fs = require('fs');
var readline = require('readline');
var spawn = require('child_process').spawn;
const URL = require('url').URL;

require('toml-require');
require('./conf.toml');

console.log("If you get more than one set of settings for conf.toml, always use the last set shown.\n\n");

adb = spawn('C:\\Program Files (x86)\\Android\\android-sdk\\platform-tools\\adb.exe', ['logcat']);

adb.stdout.on('data', function (data) {
  const regex = /http:\/\/int\.api\.iyunmai\.com\/api\/android\/scale\/[0-9]+\/list\.json\?code=[0-9]+&%26startTime=[0-9]+&lang=2&userId=[0-9]+&token=[0-9a-fA-F]+/mi;

  let m;

  var code = "not found";
  var token = "not found";
  var scale = "not found";
  var userId = "not found";

  if ((m = regex.exec(data)) !== null) {
      m.forEach((match, groupIndex) => {
          const myURL = new URL(match);
          code = myURL.searchParams.get('code');
          token = myURL.searchParams.get('token');
          userId = myURL.searchParams.get('userId');

          var pathArray = match.split( '/' );
          for (i = 0; i < pathArray.length; i++) {
            if (pathArray[i] == "scale"){
              scale = pathArray[i+1];
            }
          }
      });

      console.log("Save this output in conf.toml:");
      console.log("scale = \"" + scale + "\"");
      console.log("userId = \"" + userId + "\"");
      console.log("code = \"" + code + "\"");
      console.log("token = \"" + token  + "\"" + "\n\n");
  }
});

adb.stderr.on('data', function (data) {
  console.log('stderr: ' + data.toString());
});

adb.on('exit', function (code) {
  console.log('child process exited with code ' + code.toString());
});
<commit_msg>Update yunmai-new-token.js<commit_after>/* yunmai-new-token

 Copyright Conor O'Neill 2017 (conor@conoroneill.com)
 LICENSE: MIT

This app grabs a new Yunmai code and token from a connected Android device.

Run this app with your phone connected via USB and then launch the Yunmai app.
After a few seconds it should print the new token and code to the console which you can then paste into conf.toml. If more than one pair is printed, use the last one presented, as the others may be just from the log history.

Note you must have [Android Platform Tools](https://developer.android.com/studio/releases/platform-tools.html#download) installed in Windows where adb can be found at C:\Program Files (x86)\Android\android-sdk\platform-tools\\adb.exe

Users of OSX and Linux can just tweak the adb command below to get what they need.

*/
var fs = require('fs');
var readline = require('readline');
var spawn = require('child_process').spawn;
const URL = require('url').URL;

require('toml-require');
require('./conf.toml');

console.log("If you get more than one set of settings for conf.toml, always use the last set shown.\n\n");

adb = spawn('C:\\Program Files (x86)\\Android\\android-sdk\\platform-tools\\adb.exe', ['logcat']);

adb.stdout.on('data', function (data) {
  const regex = /http:\/\/intapi\.iyunmai\.com\/api\/android\/scale\/[0-9]+\/chart-list\.json\?code=[0-9]+&startTime=[0-9]+&lang=2&userId=[0-9]+&token=[0-9a-fA-F]+/mi;

  let m;

  var code = "not found";
  var token = "not found";
  var scale = "not found";
  var userId = "not found";

  if ((m = regex.exec(data)) !== null) {
      m.forEach((match, groupIndex) => {
          const myURL = new URL(match);
          code = myURL.searchParams.get('code');
          token = myURL.searchParams.get('token');
          userId = myURL.searchParams.get('userId');

          var pathArray = match.split( '/' );
          for (i = 0; i < pathArray.length; i++) {
            if (pathArray[i] == "scale"){
              scale = pathArray[i+1];
            }
          }
      });

      console.log("Save this output in conf.toml:");
      console.log("scale = \"" + scale + "\"");
      console.log("userId = \"" + userId + "\"");
      console.log("code = \"" + code + "\"");
      console.log("token = \"" + token  + "\"" + "\n\n");
  }
});

adb.stderr.on('data', function (data) {
  console.log('stderr: ' + data.toString());
});

adb.on('exit', function (code) {
  console.log('child process exited with code ' + code.toString());
});
<|endoftext|>


<commit_before>module('users.timfelgentreff.z3.CommandLineZ3').requires('users.timfelgentreff.z3.NaClZ3', "lively.ide.CommandLineInterface").toRun(function() {
    NaCLZ3.subclass("CommandLineZ3", {
        loadModule: function () {
            // No module used
        },
    get strength() {
        return {
            required: undefined, // default strength
            strong: 10,
            medium: 5,
            weak: 1
        }
    },

        postMessage: function (string) {
            string = "(set-option :pp.decimal true)\n" +
                string +
                ("\n(check-sat)\n(get-value (" + this.variables.inject("", function (acc, v) {
                    return acc + v.name + " "
                }) + "))");
            // console.log(string);
            var commandString = this.constructor.z3Path + '.sh',
                self = this;

            if (!this.sync) {
                lively.ide.CommandLineInterface.run(
                    commandString,
                    {sync: this.sync, stdin: string},
                    function (r) {
                        this.applyResult(r.getStdout() + r.getStderr());
                    }.bind(this)
                );
            } else {
                var r = lively.ide.CommandLineInterface.run(
                    commandString,
                    {sync: this.sync, stdin: string}
                );
                this.applyResult(r.getStdout() + r.getStderr());
            }
        },
        initialize: function($super, sync) {
            this.sync = !!(sync || true);
            $super();
        },
        applyResult: function(result) {
            result = result.replace(/ ?\|->.*\n/m, ""); // Z3-opt has this in the beginning
            result = result.replace(/\(error.*\n/m, "");
            if (result.startsWith("sat")/* || result.indexOf("\nsat\n") != -1 */) {
                var idx = result.indexOf("sat\n");
                result = result.slice(idx + "sat".length, result.length - 1);
                // remove outer parens
                result = result.trim().slice(1, result.length - 1);

                var assignments = result.split("\n").map(function (str) {
                    var both = str.trim().slice(1, str.length - 1).split(" ");
                    if (both.length < 2) return;
                    both = [both[0].trim(), both.slice(1, both.length).join(" ").trim()];

                    var name = both[0];
                    var value = this.parseAndEvalSexpr(both[1], name);
                    return {name: name, value: value};
                }.bind(this));
                assignments.each(function (a) {
                    this.varsByName[a.name].value = a.value;
                    this.varsByName[a.name].updateStay();
                    if (!this.sync) {
                        this.cvarsByName[a.name].suggestValue(a.value);
                    }
                }.bind(this));
            } else if (result.startsWith("unsat")) {
                throw new Error("Unsatisfiable constraint system");
            } else {
                throw new Error("Z3 failed to solve this system");
            }
        },
    printConstraints: function () {
        return ["\n"].concat(this.constraints).reduce(function (acc, c) {
            if (c.strength) {
                return acc + "\n" + "(assert-soft " + c.print() + " :weight " + c.strength + ")"
            } else {
                return acc + "\n" + "(assert " + c.print() + ")";
            }
        });
    },
    constraintVariableFor: function($super, value, ivarname, cvar) {
        var cvar = $super(value, ivarname, cvar);
        if (cvar && this.constructor === CommandLineZ3) {
            // XXX: only add stays for this specific solver for now
            cvar.stay();
        }
        return cvar;
    },
    always: function($super, opts, func) {
        var prio = opts.priority;
        if (prio instanceof String || typeof(prio) == "string") {
            prio = this.strength[prio];
        }
        delete opts.priority; // not supported by NaClZ3
        var result = cop.withLayers([CommandLineZ3Layer], function () {
            return $super(opts, func);
        });
        if (prio && prio !== this.strength.required) {
            result.priority = prio;
        }
        return result;
    },
    });
if (window.Config && window.Config.codeBase) {
    // Only in Lively
    Object.extend(CommandLineZ3, {
        modulePath: module('users.timfelgentreff.z3.CommandLineZ3').relativePath().replace("CommandLineZ3.js", "")
    });
    Object.extend(CommandLineZ3, {
        z3Path: lively.ide.CommandLineInterface.cwd() + "/" + Config.codeBase.replace(Config.rootPath, "") + CommandLineZ3.modulePath + "z3"
    });
} else {
    Object.extend(CommandLineZ3, {
        get z3Path() {
            if (!CommandLineZ3Path) {
                console.error("Standalone deployment must define CommandLineZ3Path");
            } else {
                return CommandLineZ3Path;
            }
        }
    });
}
cop.create('CommandLineZ3Layer').
refineObject(Global, {
    get NaCLZ3Variable() {
        return CommandLineZ3Variable
    }
}).
refineClass(NaCLZ3Constraint, {
    enable: function (strength) {
        this.strength = strength;
        this.solver.addConstraint(this);
    }
})
NaCLZ3Variable.subclass('CommandLineZ3Variable', {
    stay: function (strength) {
        strength = strength || this.solver.strength.weak;
        if (!this._stayCn) {
            this._stayCn = new NaCLZ3BinaryExpression("=", this, this.value, this.solver);
            this._stayCn.strength = strength;
            this.solver.addConstraint(this._stayCn);
        }
    },
    removeStay: function() {
        if (this._stayCn) {
            this._stayCn.disable();
            delete this._stayCn;
        }
    },
    updateStay: function () {
        if (this._stayCn) {
            var s = this._stayCn.strength;
            this.solver.removeConstraint(this._stayCn);
            this._stayCn = new NaCLZ3BinaryExpression("=", this, this.value, this.solver);
            this._stayCn.strength = s;
            this.solver.addConstraint(this._stayCn);
        }
    },
    cnIn: function($super, domain) {
        debugger
        this.removeStay();
        return $super(domain);
    }
});

}) // end of module
<commit_msg>Allow the user to disable stays for commandline Z3<commit_after>module('users.timfelgentreff.z3.CommandLineZ3').requires('users.timfelgentreff.z3.NaClZ3', "lively.ide.CommandLineInterface").toRun(function() {
    NaCLZ3.subclass("CommandLineZ3", {
        loadModule: function () {
            // No module used
        },
    get strength() {
        return {
            required: undefined, // default strength
            strong: 10,
            medium: 5,
            weak: 1
        }
    },

        postMessage: function (string) {
            string = "(set-option :pp.decimal true)\n" +
                string +
                ("\n(check-sat)\n(get-value (" + this.variables.inject("", function (acc, v) {
                    return acc + v.name + " "
                }) + "))");
            // console.log(string);
            var commandString = this.constructor.z3Path + '.sh',
                self = this;

            if (!this.sync) {
                lively.ide.CommandLineInterface.run(
                    commandString,
                    {sync: this.sync, stdin: string},
                    function (r) {
                        this.applyResult(r.getStdout() + r.getStderr());
                    }.bind(this)
                );
            } else {
                var r = lively.ide.CommandLineInterface.run(
                    commandString,
                    {sync: this.sync, stdin: string}
                );
                this.applyResult(r.getStdout() + r.getStderr());
            }
        },
        initialize: function($super, sync) {
            this.sync = !!(sync || true);
            $super();
        },
        applyResult: function(result) {
            result = result.replace(/ ?\|->.*\n/m, ""); // Z3-opt has this in the beginning
            result = result.replace(/\(error.*\n/m, "");
            if (result.startsWith("sat")/* || result.indexOf("\nsat\n") != -1 */) {
                var idx = result.indexOf("sat\n");
                result = result.slice(idx + "sat".length, result.length - 1);
                // remove outer parens
                result = result.trim().slice(1, result.length - 1);

                var assignments = result.split("\n").map(function (str) {
                    var both = str.trim().slice(1, str.length - 1).split(" ");
                    if (both.length < 2) return;
                    both = [both[0].trim(), both.slice(1, both.length).join(" ").trim()];

                    var name = both[0];
                    var value = this.parseAndEvalSexpr(both[1], name);
                    return {name: name, value: value};
                }.bind(this));
                assignments.each(function (a) {
                    this.varsByName[a.name].value = a.value;
                    this.varsByName[a.name].updateStay();
                    if (!this.sync) {
                        this.cvarsByName[a.name].suggestValue(a.value);
                    }
                }.bind(this));
            } else if (result.startsWith("unsat")) {
                throw new Error("Unsatisfiable constraint system");
            } else {
                throw new Error("Z3 failed to solve this system");
            }
        },
    printConstraints: function () {
        return ["\n"].concat(this.constraints).reduce(function (acc, c) {
            if (c.strength) {
                return acc + "\n" + "(assert-soft " + c.print() + " :weight " + c.strength + ")"
            } else {
                return acc + "\n" + "(assert " + c.print() + ")";
            }
        });
    },
    constraintVariableFor: function($super, value, ivarname, cvar) {
        var cvar = $super(value, ivarname, cvar);
        if (cvar && this.constructor === CommandLineZ3) {
            // XXX: only add stays for this specific solver for now
            cvar.stay();
        }
        return cvar;
    },
    always: function($super, opts, func) {
        var prio = opts.priority;
        if (prio instanceof String || typeof(prio) == "string") {
            prio = this.strength[prio];
        }
        delete opts.priority; // not supported by NaClZ3
        var result = cop.withLayers([CommandLineZ3Layer], function () {
            return $super(opts, func);
        });
        if (prio && prio !== this.strength.required) {
            result.priority = prio;
        }
        return result;
    },
    });
if (window.Config && window.Config.codeBase) {
    // Only in Lively
    Object.extend(CommandLineZ3, {
        modulePath: module('users.timfelgentreff.z3.CommandLineZ3').relativePath().replace("CommandLineZ3.js", "")
    });
    Object.extend(CommandLineZ3, {
        z3Path: lively.ide.CommandLineInterface.cwd() + "/" + Config.codeBase.replace(Config.rootPath, "") + CommandLineZ3.modulePath + "z3"
    });
} else {
    Object.extend(CommandLineZ3, {
        get z3Path() {
            if (!CommandLineZ3Path) {
                console.error("Standalone deployment must define CommandLineZ3Path");
            } else {
                return CommandLineZ3Path;
            }
        }
    });
}
cop.create('CommandLineZ3Layer').
refineObject(Global, {
    get NaCLZ3Variable() {
        return CommandLineZ3Variable
    }
}).
refineClass(NaCLZ3Constraint, {
    enable: function (strength) {
        this.strength = strength;
        this.solver.addConstraint(this);
    }
})
NaCLZ3Variable.subclass('CommandLineZ3Variable', {
    stay: function (strength) {
        if (this.solver.disableStay) return;
        strength = strength || this.solver.strength.weak;
        if (!this._stayCn) {
            this._stayCn = new NaCLZ3BinaryExpression("=", this, this.value, this.solver);
            this._stayCn.strength = strength;
            this.solver.addConstraint(this._stayCn);
        }
    },
    removeStay: function() {
        if (this._stayCn) {
            this._stayCn.disable();
            delete this._stayCn;
        }
    },
    updateStay: function () {
        if (this._stayCn) {
            var s = this._stayCn.strength;
            this.solver.removeConstraint(this._stayCn);
            this._stayCn = new NaCLZ3BinaryExpression("=", this, this.value, this.solver);
            this._stayCn.strength = s;
            this.solver.addConstraint(this._stayCn);
        }
    },
    cnIn: function($super, domain) {
        debugger
        this.removeStay();
        return $super(domain);
    }
});

}) // end of module
<|endoftext|>


<commit_before>var currentTable;
var tempSelection;

// Add onclick function to tabs
$("[id$=-tab]").each(function () {
    $(this).click(function(){
        var oldtable = $('.tab.active').data('name') || 'zone';
        $('.tab').removeClass("active");
        $(this).addClass("active");

        // Remember scroll position
        var scroll = $('.tabulator-tableHolder').scrollTop();

        // Store previously selected buildings before creating new table
        if (inputstore.getData(oldtable).length) {
            if (inputstore.getSelected()) {
                tempSelection = [...inputstore.getSelected()];
            }
        }

        var name = $(this).data('name');
        $('#property-table').empty();
        createTable("property-table",`${name}`,
            inputstore.getData(name),
            inputstore.getColumns(name),
            inputstore.getColumnTypes(name)
        );

        // Restore previous selected
        inputstore.setSelected(tempSelection);
        if (inputstore.getSelected()) {
            currentTable.selectRow(inputstore.getSelected());
        }
        filterSelection(inputstore.getSelected());

        currentTable.redraw();
        $('.tabulator-tableHolder').scrollTop(scroll);

    });
});

function createTable(parent, name, values, columns, types) {
    var placeholder = '';
    var tool = '';
    if (!inputstore.getData(name).length) {
        placeholder = '
File cannot be found.
';
        if (name === 'zone') {
            tool = 'zone-helper';
        } else if (name === 'district') {
            tool = 'district-helper';
        } else {
            tool = 'data-helper';
        }

        placeholder += `<div>You can create the file using the <a href="/tools/${tool}">${tool}</a> tool.</div>`;
    } else {
        placeholder = '
No matching records found.
';
    }

    $(`#${parent}`).append(`<div id="${name}-table"></div>`);
    currentTable = new Tabulator(`#${name}-table`, {
        index: 'Name',
        data: values,
        columns: defineColumns(columns, types),
        placeholder: placeholder,

        layout: (['occupancy','architecture'].includes(name)) ? 'fitDataFill' : 'fitColumns',
        height: '300px',
        cellClick:selectRow,
        cellEdited: updateData,
        rowSelectionChanged: addToSelection

    });

    $('#select-all-button').prop('disabled', !values.length);
    $('#filter-button').prop('disabled', !values.length);
}

function defineColumns(columns, column_types) {
    var out = [];
    var editor = '';
    $.each(columns, function (index, column) {
        if (column === 'Name' || column === 'REFERENCE') {
            out.push({title: column, field: column});
        } else {
            if (column_types[column] === 'str') {
                editor = "input";
            } else  {
                editor = "number";
            }
            out.push({title: column, field: column, editor: editor});
        }
    });
    return out
}

function updateData(data) {
    var name = data.getData()['Name'];
    var column = data.getField();
    var value = data.getValue();

    // Find the layer of the property
    var table = $('.tab.active').data('name');

    // TODO: Move updates to InputStore class
    // FIXME: Not very efficient. Too many loops to find index of data
    // Update table data
    var row = currentTable.getRow(name).getData();
    row[column] = value;
    if (row['REFERENCE']) {
        row['REFERENCE'] = 'User - assumption';
        $('.tab.active').trigger('click');
    }

    // Update geometries
    if (table === 'zone' || table === 'district') {
        var properties = inputstore.getGeojson(table)['features'][inputstore.getGeojsonID(table, name)]['properties'];
        properties[column] = value;
        if (properties['REFERENCE']) {
            properties['REFERENCE'] = 'User - assumption';
        }
        if (column === 'height_ag') {
            inputstore.createNewGeojson(table);
            redrawBuildings();
        }
    }

    inputstore.addChange('update', table, data.getData()['Name'], data.getField(), data.getValue());

}

function selectRow(e, cell) {
    var value = cell.getValue();
    if(cell.getField() === 'Name') {
        if (cell.getRow().isSelected()) {
            currentTable.deselectRow(value);
        } else {
            currentTable.selectRow(value);
        }
    }
}

function addToSelection(data, row) {
    var buttons = [$('#clear-button'),$('#delete-button'),$('#edit-button')];
    $.each(buttons, function (_, button) {
        if (data.length) {
            button.show();
        } else {
            button.hide();
        }
    });

    var out = [];
    $.each(data, function (_, building) {
        out.push(building['Name']);
    });

    inputstore.setSelected(out);
    if (currentTable) {
        var scroll = $('.tabulator-tableHolder').scrollTop();
        filterSelection(out);
        $('.tabulator-tableHolder').scrollTop(scroll);
    }

    redrawBuildings();
}

function filterSelection(selection) {
    if ($('#filter-button').hasClass('btn-success')){
        currentTable.setFilter("Name", "in", selection);
    } else {
        currentTable.clearFilter();
    }
}

$(window).load(function () {
    $('#cea-inputs').show();

    $('#zone-tab').trigger('click');

    $('#select-all-button').click(function () {
        currentTable.selectRow();
    }).show();

    $('#filter-button').click(function () {
        $(this).toggleClass('btn-success');
        filterSelection(inputstore.getSelected());
    });

    $('#edit-button').click(function () {
        var table = $('.tab.active').data('name');
        var selected = inputstore.getSelected().join(', ');
        var columns = inputstore.getColumns(table);

        $('#cea-column-editor .modal-title').text(`Editing ${table} table`);
        $('#selected-buildings').text(`Buidlings selected: ${selected}`);
        // TODO: Add input validation
        $('#cea-column-editor-form').empty();
        $.each(columns, function (_, column) {
            var type = (inputstore.getColumnTypes(table)[column] === 'str') ? 'text':'number';
            if (column !== 'Name' && column !== 'REFERENCE') {
                var input =
                    `

                      ${ column }

                        <input type="${ type }" id="cea-input-${ column }" name="${ column }" placeholder="unchanged"
                               class="form-control col-md-7 col-xs-12">

`;
                $('#cea-column-editor-form').append(input);
                if (type === 'text') {
                    $(`#cea-input-${ column }`).prop('pattern', '[T][0-9]+')
                        .prop('title', 'T[number]');
                }
            }
        });

        $('#cea-column-editor').modal({'show': true, 'backdrop': 'static'});
    });

    $('#delete-button').click(function () {
        var selected = inputstore.getSelected();
        var layer = ($('.tab.active').data('name') !== 'district') ? 'zone':'district';
        var out = '\n';
        $.each(selected, function (_, building) {
            out += `${building}\n`
        });
        if (confirm("This will delete the following buildings from every table:" + out)) {
            inputstore.deleteBuildings(layer, selected);
            $('.tab.active').trigger('click');
        }
    });

    $('#clear-button').click(function () {
        currentTable.deselectRow();
        filterSelection(inputstore.getSelected());
    });

    $('#discard-button').click(function () {
        var changes = inputstore.changes;
        if (!Object.keys(changes['update']).length && !Object.keys(changes['delete']).length) {
            alert('No changes detected');
        } else {
            if (confirm("This will discard all unsaved changes.\n" + inputstore.changesToString())) {
                inputstore.resetChanges();
                $('.tab.active').trigger('click');
            }
        }
    });

    $('#save-button').click(function () {
        var changes = inputstore.changes;
        if (!Object.keys(changes['update']).length && !Object.keys(changes['delete']).length) {
            alert('No changes detected');
        } else {
            if (confirm("Save these changes?\n" +
                "WARNING: Any buildings deleted this way cannot be recovered once saved!\n" +
                inputstore.changesToString())) {
                $('#saving-text').text('Saving Changes...');
                $('#saving-popup').modal({'show': true, 'backdrop': 'static'});

                $.ajax({
                    type: 'POST',
                    url: '/inputs/building-properties',
                    data: JSON.stringify({
                        changes: changes,
                        geojson: inputstore.geojsondata,
                        tables: inputstore.data
                    }),
                    contentType: 'application/json'
                }).done(function (data) {
                    // TODO: Either refresh page or do applyChanges()
                    inputstore.applyChanges(data);

                    $('#saving-text').text('✔ Changes Saved!');
                    setTimeout(function(){
                        $('#saving-popup').modal('hide');
                    }, 1500);
                }).fail(function () {
                    var header =
                        '<button type="button" class="close cea-modal-close" data-dismiss="modal">' +
                        'Back' +
                        '</button>';
                    $('#saving-text').text('Something went wrong')
                        .append(header);
                });
            }
        }
    });

    $('#cea-column-editor-form').submit(function (e) {
        e.preventDefault();
        var table = $('.tab.active').data('name');
        var props = {};
        var form = $('#cea-column-editor-form').serialize().split('&');
        $.each(form, function (_, prop) {
            var temp = prop.split('=');
            if (temp[1] !== '') {
                var value = temp[1];
                if (inputstore.getColumnTypes(table)[temp[0]] !== 'str'){
                    value = Number(value);
                }
                props[temp[0]] = value;
            }
        });

        var data = [];
        $.each(inputstore.getSelected(), function (_, building) {
            // Add to changes
            $.each(props, function (key, value) {
                inputstore.addChange('update', table, building, key, value);
            });

            // Update table data
            var out = {Name: building, ...props};
            var row = currentTable.getRow(building).getData();
            if (row['REFERENCE']) {
                out['REFERENCE'] = 'User - assumption';
            }
            data.push(out);

            // Update geojsons
            // FIXME: Copied from updateData()
            if (table === 'zone' || table === 'district') {
                Object.assign(inputstore.getGeojson(table)['features'][inputstore.getGeojsonID(table, building)]['properties'], out);
            }
        });

        if (props['height_ag']) {
            inputstore.createNewGeojson(table);
            redrawBuildings();
        }

        currentTable.updateData(data);

        $('#cea-column-editor').modal('hide');
    });
});
<commit_msg>Print out data of selected buildings<commit_after>var currentTable;
var tempSelection;

// Add onclick function to tabs
$("[id$=-tab]").each(function () {
    $(this).click(function(){
        var oldtable = $('.tab.active').data('name') || 'zone';
        $('.tab').removeClass("active");
        $(this).addClass("active");

        // Remember scroll position
        var scroll = $('.tabulator-tableHolder').scrollTop();

        // Store previously selected buildings before creating new table
        if (inputstore.getData(oldtable).length) {
            if (inputstore.getSelected()) {
                tempSelection = [...inputstore.getSelected()];
            }
        }

        var name = $(this).data('name');
        $('#property-table').empty();
        createTable("property-table",`${name}`,
            inputstore.getData(name),
            inputstore.getColumns(name),
            inputstore.getColumnTypes(name)
        );

        // Restore previous selected
        inputstore.setSelected(tempSelection);
        if (inputstore.getSelected()) {
            currentTable.selectRow(inputstore.getSelected());
        }
        filterSelection(inputstore.getSelected());

        currentTable.redraw();
        $('.tabulator-tableHolder').scrollTop(scroll);

    });
});

function createTable(parent, name, values, columns, types) {
    var placeholder = '';
    var tool = '';
    if (!inputstore.getData(name).length) {
        placeholder = '
File cannot be found.
';
        if (name === 'zone') {
            tool = 'zone-helper';
        } else if (name === 'district') {
            tool = 'district-helper';
        } else {
            tool = 'data-helper';
        }

        placeholder += `<div>You can create the file using the <a href="/tools/${tool}">${tool}</a> tool.</div>`;
    } else {
        placeholder = '
No matching records found.
';
    }

    $(`#${parent}`).append(`<div id="${name}-table"></div>`);
    currentTable = new Tabulator(`#${name}-table`, {
        index: 'Name',
        data: values,
        columns: defineColumns(columns, types),
        placeholder: placeholder,

        layout: (['occupancy','architecture'].includes(name)) ? 'fitDataFill' : 'fitColumns',
        height: '300px',
        cellClick:selectRow,
        cellEdited: updateData,
        rowSelectionChanged: addToSelection

    });

    $('#select-all-button').prop('disabled', !values.length);
    $('#filter-button').prop('disabled', !values.length);
}

function defineColumns(columns, column_types) {
    var out = [];
    var editor = '';
    $.each(columns, function (index, column) {
        if (column === 'Name' || column === 'REFERENCE') {
            out.push({title: column, field: column});
        } else {
            if (column_types[column] === 'str') {
                editor = "input";
            } else  {
                editor = "number";
            }
            out.push({title: column, field: column, editor: editor});
        }
    });
    return out
}

function updateData(data) {
    var name = data.getData()['Name'];
    var column = data.getField();
    var value = data.getValue();

    // Find the layer of the property
    var table = $('.tab.active').data('name');

    // TODO: Move updates to InputStore class
    // FIXME: Not very efficient. Too many loops to find index of data
    // Update table data
    var row = currentTable.getRow(name).getData();
    row[column] = value;
    if (row['REFERENCE']) {
        row['REFERENCE'] = 'User - assumption';
        $('.tab.active').trigger('click');
    }

    // Update geometries
    if (table === 'zone' || table === 'district') {
        var properties = inputstore.getGeojson(table)['features'][inputstore.getGeojsonID(table, name)]['properties'];
        properties[column] = value;
        if (properties['REFERENCE']) {
            properties['REFERENCE'] = 'User - assumption';
        }
        if (column === 'height_ag') {
            inputstore.createNewGeojson(table);
            redrawBuildings();
        }
    }

    inputstore.addChange('update', table, data.getData()['Name'], data.getField(), data.getValue());

}

function selectRow(e, cell) {
    var value = cell.getValue();
    if(cell.getField() === 'Name') {
        if (cell.getRow().isSelected()) {
            currentTable.deselectRow(value);
        } else {
            currentTable.selectRow(value);
        }
    }
}

function addToSelection(data, row) {
    var buttons = [$('#clear-button'),$('#delete-button'),$('#edit-button')];
    $.each(buttons, function (_, button) {
        if (data.length) {
            button.show();
        } else {
            button.hide();
        }
    });

    var out = [];
    $.each(data, function (_, building) {
        out.push(building['Name']);
    });

    inputstore.setSelected(out);
    if (currentTable) {
        var scroll = $('.tabulator-tableHolder').scrollTop();
        filterSelection(out);
        $('.tabulator-tableHolder').scrollTop(scroll);
    }

    redrawBuildings();
}

function filterSelection(selection) {
    if ($('#filter-button').hasClass('btn-success')){
        currentTable.setFilter("Name", "in", selection);
    } else {
        currentTable.clearFilter();
    }
}

$(window).load(function () {
    $('#cea-inputs').show();

    $('#zone-tab').trigger('click');

    $('#select-all-button').click(function () {
        currentTable.selectRow();
    }).show();

    $('#filter-button').click(function () {
        $(this).toggleClass('btn-success');
        filterSelection(inputstore.getSelected());
    });

    $('#edit-button').click(function () {
        var table = $('.tab.active').data('name');
        var columns = inputstore.getColumns(table);

        $('#cea-column-editor .modal-title').text(`Editing ${table} table`);
        $('#selected-buildings').text(`Buidlings selected:`);
        $.each(inputstore.getSelected(), function (_, building) {
            var row = currentTable.getRow(building).getData();
            var out = {};
            $.each(inputstore.getColumns(table), function (_, column) {
                out[column] = row[column];
            });
            delete out['Name'];
            delete out['REFERENCE'];
            out = JSON.stringify(out);
            $('#selected-buildings').append(`<div>${building}: ${out}</div>`);
        });

        // TODO: Add input validation
        $('#cea-column-editor-form').empty();
        $.each(columns, function (_, column) {
            var type = (inputstore.getColumnTypes(table)[column] === 'str') ? 'text':'number';
            if (column !== 'Name' && column !== 'REFERENCE') {
                var input =
                    `

                      ${ column }

                        <input type="${ type }" id="cea-input-${ column }" name="${ column }" placeholder="unchanged"
                               class="form-control col-md-7 col-xs-12">

`;
                $('#cea-column-editor-form').append(input);
                if (type === 'text') {
                    $(`#cea-input-${ column }`).prop('pattern', '[T][0-9]+')
                        .prop('title', 'T[number]');
                }
            }
        });

        $('#cea-column-editor').modal({'show': true, 'backdrop': 'static'});
    });

    $('#delete-button').click(function () {
        var selected = inputstore.getSelected();
        var layer = ($('.tab.active').data('name') !== 'district') ? 'zone':'district';
        var out = '\n';
        $.each(selected, function (_, building) {
            out += `${building}\n`
        });
        if (confirm("This will delete the following buildings from every table:" + out)) {
            inputstore.deleteBuildings(layer, selected);
            $('.tab.active').trigger('click');
        }
    });

    $('#clear-button').click(function () {
        currentTable.deselectRow();
        filterSelection(inputstore.getSelected());
    });

    $('#discard-button').click(function () {
        var changes = inputstore.changes;
        if (!Object.keys(changes['update']).length && !Object.keys(changes['delete']).length) {
            alert('No changes detected');
        } else {
            if (confirm("This will discard all unsaved changes.\n" + inputstore.changesToString())) {
                inputstore.resetChanges();
                $('.tab.active').trigger('click');
            }
        }
    });

    $('#save-button').click(function () {
        var changes = inputstore.changes;
        if (!Object.keys(changes['update']).length && !Object.keys(changes['delete']).length) {
            alert('No changes detected');
        } else {
            if (confirm("Save these changes?\n" +
                "WARNING: Any buildings deleted this way cannot be recovered once saved!\n" +
                inputstore.changesToString())) {
                $('#saving-text').text('Saving Changes...');
                $('#saving-popup').modal({'show': true, 'backdrop': 'static'});

                $.ajax({
                    type: 'POST',
                    url: '/inputs/building-properties',
                    data: JSON.stringify({
                        changes: changes,
                        geojson: inputstore.geojsondata,
                        tables: inputstore.data
                    }),
                    contentType: 'application/json'
                }).done(function (data) {
                    // TODO: Either refresh page or do applyChanges()
                    inputstore.applyChanges(data);

                    $('#saving-text').text('✔ Changes Saved!');
                    setTimeout(function(){
                        $('#saving-popup').modal('hide');
                    }, 1500);
                }).fail(function () {
                    var header =
                        '<button type="button" class="close cea-modal-close" data-dismiss="modal">' +
                        'Back' +
                        '</button>';
                    $('#saving-text').text('Something went wrong')
                        .append(header);
                });
            }
        }
    });

    $('#cea-column-editor-form').submit(function (e) {
        e.preventDefault();
        var table = $('.tab.active').data('name');
        var props = {};
        var form = $('#cea-column-editor-form').serialize().split('&');
        $.each(form, function (_, prop) {
            var temp = prop.split('=');
            if (temp[1] !== '') {
                var value = temp[1];
                if (inputstore.getColumnTypes(table)[temp[0]] !== 'str'){
                    value = Number(value);
                }
                props[temp[0]] = value;
            }
        });

        var data = [];
        $.each(inputstore.getSelected(), function (_, building) {
            // Add to changes
            $.each(props, function (key, value) {
                inputstore.addChange('update', table, building, key, value);
            });

            // Update table data
            var out = {Name: building, ...props};
            var row = currentTable.getRow(building).getData();
            if (row['REFERENCE']) {
                out['REFERENCE'] = 'User - assumption';
            }
            data.push(out);

            // Update geojsons
            // FIXME: Copied from updateData()
            if (table === 'zone' || table === 'district') {
                Object.assign(inputstore.getGeojson(table)['features'][inputstore.getGeojsonID(table, building)]['properties'], out);
            }
        });

        if (props['height_ag']) {
            inputstore.createNewGeojson(table);
            redrawBuildings();
        }

        currentTable.updateData(data);

        $('#cea-column-editor').modal('hide');
    });
});
<|endoftext|>


<commit_before>/*global Backbone, _, $, i18n*/
var template = require('./templates/virtualMachine-save');
var form_helper = require('../lib/form_helper');
var VmSvc = require('../service/ServiceVirtualMachine');
var _url = require('../lib/url_helper');

module.exports = Backbone.View.extend({
	tagName: 'div',
	template: template,
	events: {
		"click button[type='submit']": "save",
		"click button#btnCancel": "cancelEdition",
	},
	initialize: function initializeVirtualMachine() {
		this.model.on('change', this.render, this);
		//this.model.on('sync', this.treatServerResponse, this);
		this.listenTo(this.model, 'validated:valid', this.modelValid);
		this.listenTo(this.model, 'validated:invalid', this.modelInValid);
		this.listenTo(this.model, 'save:success', this.saveSuccess);
		this.listenTo(this.model, 'save:error', this.saveError);
		if (this.model.has('id')) {
			this.model.fetch();
		}
		this.osList = [{
			id: "1",
			label: "Windows 8"
		}, {
			id: "2",
			label: "Linux"
		}, {
			id: "3",
			label: "Mac os X"
		}];
	},
	save: function saveVm(event) {
		event.preventDefault();
		form_helper.formModelBinder({
			inputs: $('input', this.$el) //, options: $('')
		}, this.model);
		this.model.validate();

	},
	saveSuccess: function saveSuccess(model) {
		Backbone.Notification.addNotification({
			type: 'success',
			message: i18n.t('virtualMachine.save.' + (this.model.get('isCreate') ? 'create' : 'update') + 'success')
		});
		Backbone.history.navigate('virtualMachine/' + model.get('id'), true);
		//console.log('succeess', model);
	},
	saveError: function saveError(errors) {
		console.log('error', errors);
		this.model.set({
			'errors': errors.fieldErrors
		});
		_.each(errors.globalErrors, function(error) {
			Backbone.Notification.addNotification({
				type: 'error',
				message: error
			},true);
		})
	},
	//When there is a validation problem, we put the errors into the model in order to display them in the form.
	modelInValid: function vmModelInValid(model, errors) {
		this.model.set({
			'errors': errors
		});
		//this.render();
	},

	//When the model is valid, the  process continue.
	modelValid: function vmModelValid() {
		this.model.unset('errors', {
			silent: true
		});
		VmSvc.save(this.model);
	},

	cancelEdition: function cancelEdition(){
		var url = _url.generateUrl(["virtualMachine", this.model.get("id")], {});
		Backbone.Notification.clearNotifications();
		Backbone.history.navigate(url, true);
	},

	render: function renderVirtualMachine() {
		var jsonModel = this.model.toJSON();
		_.extend(jsonModel, {
			osList: this.osList
		});
		this.$el.html(this.template(jsonModel));
		return this;
	}
});<commit_msg>Add the promisify handle inside the view.<commit_after>/*global Backbone, _, $, i18n*/
var template = require('./templates/virtualMachine-save');
var form_helper = require('../lib/form_helper');
var VmSvc = require('../service/ServiceVirtualMachine');
var _url = require('../lib/url_helper');
var ErrorHelper = require('../lib/error_helper');

module.exports = Backbone.View.extend({
	tagName: 'div',
	template: template,
	events: {
		"click button[type='submit']": "save",
		"click button#btnCancel": "cancelEdition",
	},
	initialize: function initializeVirtualMachine() {
		this.model.on('change', this.render, this);
		//this.model.on('sync', this.treatServerResponse, this);
		this.listenTo(this.model, 'validated:valid', this.modelValid);
		this.listenTo(this.model, 'validated:invalid', this.modelInValid);
		this.listenTo(this.model, 'save:success', this.saveSuccess);
		this.listenTo(this.model, 'save:error', this.saveError);
		if (this.model.has('id')) {
			this.model.fetch();
		}
		this.osList = [{
			id: "1",
			label: "Windows 8"
		}, {
			id: "2",
			label: "Linux"
		}, {
			id: "3",
			label: "Mac os X"
		}];
	},
	save: function saveVm(event) {
		event.preventDefault();
		form_helper.formModelBinder({
			inputs: $('input', this.$el) //, options: $('')
		}, this.model);
		this.model.validate();

	},
	saveSuccess: function saveSuccess(jsonModel) {
		Backbone.Notification.addNotification({
			type: 'success',
			message: i18n.t('virtualMachine.save.' + (jsonModel.isCreate ? 'create' : 'update') + 'success')
		});
		Backbone.history.navigate('virtualMachine/' + jsonModel.id, true);
	},
	saveError: function saveError(errors) {
		ErrorHelper.manageResponseErrors(errors, {model: this.model});
	},
	//When there is a validation problem, we put the errors into the model in order to display them in the form.
	modelInValid: function vmModelInValid(model, errors) {
		this.model.set({
			'errors': errors
		});
		//this.render();
	},

	//When the model is valid, the  process continue.
	modelValid: function vmModelValid() {
		this.model.unset('errors', {
			silent: true
		});
		var model = this.model;
		VmSvc.save(this.model.toJSON())
			.then(
				function success(successResponse) {
					model.trigger('save:success', successResponse);
				},function error(errorResponse) {
					model.trigger('save:error', errorResponse);
				}
		);
	},

	cancelEdition: function cancelEdition() {
		var url = _url.generateUrl(["virtualMachine", this.model.get("id")], {});
		Backbone.Notification.clearNotifications();
		Backbone.history.navigate(url, true);
	},

	render: function renderVirtualMachine() {
		var jsonModel = this.model.toJSON();
		_.extend(jsonModel, {
			osList: this.osList
		});
		this.$el.html(this.template(jsonModel));
		return this;
	}
});<|endoftext|>