<commit_before>/* ===========================================================
 * bootstrap-tooltip.js v2.1.1
 * http://twitter.github.com/bootstrap/javascript.html#tooltips
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ===========================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

  "use strict"; // jshint ;_;

 /* TOOLTIP PUBLIC CLASS DEFINITION
  * =============================== */

  var Tooltip = function (element, options) {
    this.init('tooltip', element, options)
  }

  Tooltip.prototype = {

    constructor: Tooltip

  , init: function (type, element, options) {
      var eventIn
        , eventOut

      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true

      if (this.options.trigger == 'click') {
        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
      } else if (this.options.trigger != 'manual') {
        eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
        this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
      }

      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
    }

  , getOptions: function (options) {
      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())

      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
        }
      }

      return options
    }

  , enter: function (e) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (!self.options.delay || !self.options.delay.show) return self.show()

      clearTimeout(this.timeout)
      self.hoverState = 'in'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'in') self.show()
      }, self.options.delay.show)
    }

  , leave: function (e) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (this.timeout) clearTimeout(this.timeout)
      if (!self.options.delay || !self.options.delay.hide) return self.hide()

      self.hoverState = 'out'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'out') self.hide()
      }, self.options.delay.hide)
    }

  , show: function () {
      var $tip
        , inside
        , pos
        , actualWidth
        , actualHeight
        , placement
        , tp

      if (this.hasContent() && this.enabled) {
        $tip = this.tip()
        this.setContent()

        if (this.options.animation) {
          $tip.addClass('fade')
        }

        placement = typeof this.options.placement == 'function' ?
          this.options.placement.call(this, $tip[0], this.$element[0]) :
          this.options.placement

        inside = /in/.test(placement)

        $tip
          .remove()
          .css({ top: 0, left: 0, display: 'block' })
          .appendTo(inside ? this.$element : document.body)

        pos = this.getPosition(inside)

        actualWidth = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight

        switch (inside ? placement.split(' ')[1] : placement) {
          case 'bottom':
            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'top':
            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'left':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
            break
          case 'right':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
            break
        }

        $tip
          .css(tp)
          .addClass(placement)
          .addClass('in')
      }
    }

  , setContent: function () {
      var $tip = this.tip()
        , title = this.getTitle()

      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
      $tip.removeClass('fade in top bottom left right')
    }

  , hide: function () {
      var that = this
        , $tip = this.tip()

      $tip.removeClass('in')

      function removeWithAnimation() {
        var timeout = setTimeout(function () {
          $tip.off($.support.transition.end).remove()
        }, 500)

        $tip.one($.support.transition.end, function () {
          clearTimeout(timeout)
          $tip.remove()
        })
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        removeWithAnimation() :
        $tip.remove()

      return this
    }

  , fixTitle: function () {
      var $e = this.$element
      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
        $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
      }
    }

  , hasContent: function () {
      return this.getTitle()
    }

  , getPosition: function (inside) {
      var location = $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
        width: this.$element[0].offsetWidth || 0
      , height: this.$element[0].offsetHeight || 0
      })
      if (
        // this is an svg element
        this.$element[0].getBBox &&
         // this isn't a browser which emulates html elements for svg
         // (that is, this isn't chrome)
        this.$element[0].offsetWidth == null
      ) {
        location.width  += this.$element[0].getBBox().width;
        location.height += this.$element[0].getBBox().height;
        location.top    += this.$element[0].getBBox().y;
        location.left   += this.$element[0].getBBox().x;
      }
      return location
    }

  , getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      return title
    }

  , tip: function () {
      return this.$tip = this.$tip || $(this.options.template)
    }

  , validate: function () {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function () {
      this.enabled = true
    }

  , disable: function () {
      this.enabled = false
    }

  , toggleEnabled: function () {
      this.enabled = !this.enabled
    }

  , toggle: function () {
      this[this.tip().hasClass('in') ? 'hide' : 'show']()
    }

  , destroy: function () {
      this.hide().$element.off('.' + this.type).removeData(this.type)
    }

  }

 /* TOOLTIP PLUGIN DEFINITION
  * ========================= */

  $.fn.tooltip = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tooltip')
        , options = typeof option == 'object' && option
      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip

  $.fn.tooltip.defaults = {
    animation: true
  , placement: 'top'
  , selector: false
  , template: '

'
  , trigger: 'hover'
  , title: ''
  , delay: 0
  , html: true
  }

}(window.jQuery);
<commit_msg>Hopefully a better fix for #127<commit_after>/* ===========================================================
 * bootstrap-tooltip.js v2.1.1
 * http://twitter.github.com/bootstrap/javascript.html#tooltips
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ===========================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

  "use strict"; // jshint ;_;

 /* TOOLTIP PUBLIC CLASS DEFINITION
  * =============================== */

  var Tooltip = function (element, options) {
    this.init('tooltip', element, options)
  }

  Tooltip.prototype = {

    constructor: Tooltip

  , init: function (type, element, options) {
      var eventIn
        , eventOut

      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true

      if (this.options.trigger == 'click') {
        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
      } else if (this.options.trigger != 'manual') {
        eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
        this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
      }

      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
    }

  , getOptions: function (options) {
      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())

      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
        }
      }

      return options
    }

  , enter: function (e) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (!self.options.delay || !self.options.delay.show) return self.show()

      clearTimeout(this.timeout)
      self.hoverState = 'in'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'in') self.show()
      }, self.options.delay.show)
    }

  , leave: function (e) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (this.timeout) clearTimeout(this.timeout)
      if (!self.options.delay || !self.options.delay.hide) return self.hide()

      self.hoverState = 'out'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'out') self.hide()
      }, self.options.delay.hide)
    }

  , show: function () {
      var $tip
        , inside
        , pos
        , actualWidth
        , actualHeight
        , placement
        , tp

      if (this.hasContent() && this.enabled) {
        $tip = this.tip()
        this.setContent()

        if (this.options.animation) {
          $tip.addClass('fade')
        }

        placement = typeof this.options.placement == 'function' ?
          this.options.placement.call(this, $tip[0], this.$element[0]) :
          this.options.placement

        inside = /in/.test(placement)

        $tip
          .remove()
          .css({ top: 0, left: 0, display: 'block' })
          .appendTo(inside ? this.$element : document.body)

        pos = this.getPosition(inside)

        actualWidth = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight

        switch (inside ? placement.split(' ')[1] : placement) {
          case 'bottom':
            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'top':
            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'left':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
            break
          case 'right':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
            break
        }

        $tip
          .css(tp)
          .addClass(placement)
          .addClass('in')
      }
    }

  , setContent: function () {
      var $tip = this.tip()
        , title = this.getTitle()

      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
      $tip.removeClass('fade in top bottom left right')
    }

  , hide: function () {
      var that = this
        , $tip = this.tip()

      $tip.removeClass('in')

      function removeWithAnimation() {
        var timeout = setTimeout(function () {
          $tip.off($.support.transition.end).remove()
        }, 500)

        $tip.one($.support.transition.end, function () {
          clearTimeout(timeout)
          $tip.remove()
        })
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        removeWithAnimation() :
        $tip.remove()

      return this
    }

  , fixTitle: function () {
      var $e = this.$element
      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
        $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
      }
    }

  , hasContent: function () {
      return this.getTitle()
    }

  , getPosition: function (inside) {

      if(this.$element[0].getBBox) {
        var container = this.$element.parents().filter(function() {
          return !this.getBBox;
        }).first();
        var bbox = this.$element[0].getBBox();
        var offset = container.offset();
        return {
          width: bbox.width,
          height: bbox.height,
          top: bbox.y+offset.top,
          left: bbox.x+offset.left,
        };
      }

      return $.extend({
        width: this.$element[0].offsetWidth,
        height: this.$element[0].offsetHeight,
      }, inside ? {top: 0, left: 0} : this.$element.offset());
    }

  , getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      return title
    }

  , tip: function () {
      return this.$tip = this.$tip || $(this.options.template)
    }

  , validate: function () {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function () {
      this.enabled = true
    }

  , disable: function () {
      this.enabled = false
    }

  , toggleEnabled: function () {
      this.enabled = !this.enabled
    }

  , toggle: function () {
      this[this.tip().hasClass('in') ? 'hide' : 'show']()
    }

  , destroy: function () {
      this.hide().$element.off('.' + this.type).removeData(this.type)
    }

  }

 /* TOOLTIP PLUGIN DEFINITION
  * ========================= */

  $.fn.tooltip = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tooltip')
        , options = typeof option == 'object' && option
      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip

  $.fn.tooltip.defaults = {
    animation: true
  , placement: 'top'
  , selector: false
  , template: '

'
  , trigger: 'hover'
  , title: ''
  , delay: 0
  , html: true
  }

}(window.jQuery);
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2008-2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// SaveWidget
//============================================================================

var IPython = (function (IPython) {

    var utils = IPython.utils;

    var SaveWidget = function (selector) {
        this.selector = selector;
        this.notebook_name_blacklist_re = /[\/\\]/;
        this.last_saved_name = '';
        if (this.selector !== undefined) {
            this.element = $(selector);
            this.style();
            this.bind_events();
        }
    };

    SaveWidget.prototype.style = function () {
        this.element.find('span#save_widget').addClass('ui-widget');
        this.element.find('span#notebook_name').addClass('ui-widget ui-widget-content');
        this.element.find('span#save_status').addClass('ui-widget ui-widget-content')
            .css({border: 'none', 'margin-left': '20px'});
    };

    SaveWidget.prototype.bind_events = function () {
        var that = this;
        this.element.find('span#notebook_name').click(function () {
            that.rename_notebook();
        });
        this.element.find('span#notebook_name').hover(function () {
            $(this).addClass("ui-state-hover");
        }, function () {
            $(this).removeClass("ui-state-hover");
        });
    };

    SaveWidget.prototype.save_notebook = function () {
        IPython.notebook.save_notebook();
    };

    SaveWidget.prototype.rename_notebook = function () {
        var that = this;
        var dialog = $('<div/>');
        dialog.append(
            $('<h3/>').html('Enter a new notebook name:')
            .css({'margin-bottom': '10px'})
        );
        dialog.append(
            $('<input/>').attr('type','text').attr('size','25')
            .addClass('ui-widget ui-widget-content')
            .attr('value',that.get_notebook_name())
        );
        // $(document).append(dialog);
        dialog.dialog({
            resizable: false,
            modal: true,
            title: "Rename Notebook",
            closeText: "",
            close: function(event, ui) {$(this).dialog('destroy').remove();},
            buttons : {
                "OK": function () {
                    var new_name = $(this).find('input').attr('value');
                    if (!that.test_notebook_name(new_name)) {
                        $(this).find('h3').html(
                            "Invalid notebook name. " +
                            "Notebook names can contain any characters " +
                            "except / and \\. Please enter a new notebook name:"
                        );
                    } else {
                        that.set_notebook_name(new_name);
                        that.save_notebook();
                        $(this).dialog('close');
                    }
                },
                "Cancel": function () {
                    $(this).dialog('close');
                }
            }
        });
    }

    SaveWidget.prototype.notebook_saved = function () {
        this.set_document_title();
        this.last_saved_name = this.get_notebook_name();
    };

    SaveWidget.prototype.get_notebook_name = function () {
        return this.element.find('span#notebook_name').html();
    };

    SaveWidget.prototype.set_notebook_name = function (nbname) {
        this.element.find('span#notebook_name').html(nbname);
        this.set_document_title();
        this.last_saved_name = nbname;
    };

    SaveWidget.prototype.set_document_title = function () {
        nbname = this.get_notebook_name();
        document.title = nbname;
    };

    SaveWidget.prototype.get_notebook_id = function () {
        return $('body').data('notebookId');
    };

    SaveWidget.prototype.update_url = function () {
        var notebook_id = this.get_notebook_id();
        if (notebook_id !== '') {
            var new_url = '/'+notebook_id;
            window.history.replaceState({}, '', new_url);
        };
    };

    SaveWidget.prototype.test_notebook_name = function (nbname) {
        if (this.notebook_name_blacklist_re.test(nbname) == false) {
            return true;
        } else {
            return false;
        };
    };

    SaveWidget.prototype.set_last_saved = function () {
        var d = new Date();
        $('#save_status').html('Last saved: '+d.format('mmm dd h:MM TT'));

    };

    SaveWidget.prototype.reset_status = function () {
        this.element.find('span#save_status').html('');
    };

    SaveWidget.prototype.status_last_saved = function () {
        this.set_last_saved();
    };

    SaveWidget.prototype.status_saving = function () {
        this.element.find('span#save_status').html('Saving...');
    };

    SaveWidget.prototype.status_save_failed = function () {
        this.element.find('span#save_status').html('Save failed');
    };

    SaveWidget.prototype.status_loading = function () {
        this.element.find('span#save_status').html('Loading...');
    };

    IPython.SaveWidget = SaveWidget;

    return IPython;

}(IPython));

<commit_msg>Disallow empty notebook names.<commit_after>//----------------------------------------------------------------------------
//  Copyright (C) 2008-2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// SaveWidget
//============================================================================

var IPython = (function (IPython) {

    var utils = IPython.utils;

    var SaveWidget = function (selector) {
        this.selector = selector;
        this.notebook_name_blacklist_re = /[\/\\]/;
        this.last_saved_name = '';
        if (this.selector !== undefined) {
            this.element = $(selector);
            this.style();
            this.bind_events();
        }
    };

    SaveWidget.prototype.style = function () {
        this.element.find('span#save_widget').addClass('ui-widget');
        this.element.find('span#notebook_name').addClass('ui-widget ui-widget-content');
        this.element.find('span#save_status').addClass('ui-widget ui-widget-content')
            .css({border: 'none', 'margin-left': '20px'});
    };

    SaveWidget.prototype.bind_events = function () {
        var that = this;
        this.element.find('span#notebook_name').click(function () {
            that.rename_notebook();
        });
        this.element.find('span#notebook_name').hover(function () {
            $(this).addClass("ui-state-hover");
        }, function () {
            $(this).removeClass("ui-state-hover");
        });
    };

    SaveWidget.prototype.save_notebook = function () {
        IPython.notebook.save_notebook();
    };

    SaveWidget.prototype.rename_notebook = function () {
        var that = this;
        var dialog = $('<div/>');
        dialog.append(
            $('<h3/>').html('Enter a new notebook name:')
            .css({'margin-bottom': '10px'})
        );
        dialog.append(
            $('<input/>').attr('type','text').attr('size','25')
            .addClass('ui-widget ui-widget-content')
            .attr('value',that.get_notebook_name())
        );
        // $(document).append(dialog);
        dialog.dialog({
            resizable: false,
            modal: true,
            title: "Rename Notebook",
            closeText: "",
            close: function(event, ui) {$(this).dialog('destroy').remove();},
            buttons : {
                "OK": function () {
                    var new_name = $(this).find('input').attr('value');
                    if (!that.test_notebook_name(new_name)) {
                        $(this).find('h3').html(
                            "Invalid notebook name. Notebook names must "+
                            "have 1 or more characters and can contain any characters " +
                            "except / and \\. Please enter a new notebook name:"
                        );
                    } else {
                        that.set_notebook_name(new_name);
                        that.save_notebook();
                        $(this).dialog('close');
                    }
                },
                "Cancel": function () {
                    $(this).dialog('close');
                }
            }
        });
    }

    SaveWidget.prototype.notebook_saved = function () {
        this.set_document_title();
        this.last_saved_name = this.get_notebook_name();
    };

    SaveWidget.prototype.get_notebook_name = function () {
        return this.element.find('span#notebook_name').html();
    };

    SaveWidget.prototype.set_notebook_name = function (nbname) {
        this.element.find('span#notebook_name').html(nbname);
        this.set_document_title();
        this.last_saved_name = nbname;
    };

    SaveWidget.prototype.set_document_title = function () {
        nbname = this.get_notebook_name();
        document.title = nbname;
    };

    SaveWidget.prototype.get_notebook_id = function () {
        return $('body').data('notebookId');
    };

    SaveWidget.prototype.update_url = function () {
        var notebook_id = this.get_notebook_id();
        if (notebook_id !== '') {
            var new_url = '/'+notebook_id;
            window.history.replaceState({}, '', new_url);
        };
    };

    SaveWidget.prototype.test_notebook_name = function (nbname) {
        nbname = nbname || '';
        if (this.notebook_name_blacklist_re.test(nbname) == false && nbname.length>0) {
            return true;
        } else {
            return false;
        };
    };

    SaveWidget.prototype.set_last_saved = function () {
        var d = new Date();
        $('#save_status').html('Last saved: '+d.format('mmm dd h:MM TT'));

    };

    SaveWidget.prototype.reset_status = function () {
        this.element.find('span#save_status').html('');
    };

    SaveWidget.prototype.status_last_saved = function () {
        this.set_last_saved();
    };

    SaveWidget.prototype.status_saving = function () {
        this.element.find('span#save_status').html('Saving...');
    };

    SaveWidget.prototype.status_save_failed = function () {
        this.element.find('span#save_status').html('Save failed');
    };

    SaveWidget.prototype.status_loading = function () {
        this.element.find('span#save_status').html('Loading...');
    };

    IPython.SaveWidget = SaveWidget;

    return IPython;

}(IPython));

<|endoftext|>


<commit_before>if (!Physics.Circle || KAPhy.version !== KAPhy.current) {
  Physics.Circle = function(config) {
    /** Position and Velocity **/
    this.pos = config.pos || new Vector2(config.x, config.y);
    this.vel = config.vel || new Vector2();

    /** Bounciness **/
    this.bcf = config.bcf || 0.75;

    /** Radius **/
    this.rad = config.rad || 15;

    /** Array of Constraints **/
    this.constraints = [];

    /** Physical Sleep **/
    this.asleep = false;

    /** Array of Position Adjustments **/
    this.posAdjustments = [];

    /** Mass **/
    this.mass = config.mass || 1;

    /** Fixed or Not **/
    this.fixed = config.fixed || false;

    /** Variables Used When Submerged**/
    this.buoyancyForce = 0;
    this.waterDrag = 1;
  };
  Physics.Circle.prototype.update = function() {
    if (this.fixed) {
      this.asleep = false;
      this.vel = new Vector2();
      return;
    }

    if (this.vel.magSq() > Physics.sleepThreshold * Physics.sleepThreshold || this.buoyancyForce > 0) {
      this.asleep = false;
    }
    this.pos.add(this.vel) //Add velocity to position

    this.vel.y += Canvas.getY(Physics.gravityForce - this.buoyancyForce); //Gravity

    this.vel.mult(this.waterDrag * (this.asleep ? Physics.asleepAirResistance : Physics.airResistance)); //Air resistance

    this.buoyancyForce = 0;
    this.waterDrag = 1;

    this.manageAdjustments();
  };
  Physics.Circle.prototype.draw = function() {
    Draw.ellipse(this.pos.x, this.pos.y, this.rad * 2, this.rad * 2);
  };
  Physics.Circle.prototype.display = function() {
    if (this.move) {
      this.move();
    }
    this.update();
    this.draw();
  };
  Physics.Circle.prototype.moveTowards = function(target, force) {
    this.applyForce(Vector2.mult(Vector2.normalize(Vector2.sub(target, this.pos)), force));
  };
  Physics.Circle.prototype.moveFrom = function(target, force) {
    this.applyForce(Vector2.mult(Vector2.normalize(Vector2.sub(this.pos, target)), force));
  };
  Physics.Circle.prototype.manageAdjustments = function() {
    if (this.posAdjustments.length === 0) {
      return;
    }

    var adjustmentAvg = new Vector2();
    for (var i = 0; i < this.posAdjustments.length; i++) {
      adjustmentAvg.add(this.posAdjustments[i]);
    }
    this.pos = Vector2.lerp(this.pos, Vector2.div(adjustmentAvg, this.posAdjustments.length), Physics.constraintAdjustment);

    this.posAdjustments = [];
  };
  Physics.Circle.prototype.trySleep = function() {
    if (Vector2.magSq(this.vel) < Physics.sleepThreshold * Physics.sleepThreshold) {
      this.asleep = true;
    }
  };
  Physics.Circle.prototype.collideLine = function(line) {
    if (line.one.x === line.two.x ||
      line.one.y === line.two.y) {
      return;
    }

    if (!circleCollidingLine(line.one, line.two, this.pos, this.rad + line.rad)) {
      return;
    }
    if (!intersecting(this.pos, Vector2.reflect(this.pos, line.one, line.two), line.one, line.two)) {
      var n = (Vector2.dist(this.pos, line.one) < Vector2.dist(this.pos, line.two)) ? line.one : line.two;
      this.vel = Vector2.mult(Vector2.sub(Vector2.reflect(Vector2.sub(this.pos, this.vel), n, this.pos), this.pos), line.bcf * this.bcf);
      this.pos = Vector2.sub(n, Vector2.mult(Vector2.normalize(Vector2.sub(n, this.pos)), this.rad + line.rad));
    } else {
      var n = intersection(this.pos, Vector2.reflect(this.pos, line.one, line.two), line.one, line.two);
      this.vel = Vector2.mult(Vector2.sub(n, Vector2.reflect(Vector2.sub(n, this.vel), n, Vector2.add(n, [1, PM(line.one, line.two)]))), -line.bcf * this.bcf);
      this.pos = Vector2.add(n, Vector2.mult(Vector2.norm(new Vector2(1, PM(line.one, line.two))), (this.rad + line.rad) * (this.pos.y > n.y ? -1 : 1) * (line.one.x > line.two.x ? -1 : 1) * (line.one.y > line.two.y ? -1 : 1)));
    }
    this.trySleep();
  };
  Physics.Circle.prototype.collideStaticDynamic = function(that) {
    that.pos = Vector2.lerp(
      that.pos,
      Vector2.add(this.pos,
        Vector2.mult(
          Vector2.normalize(
            Vector2.sub(that.pos, this.pos)
          ),
          this.rad + that.rad)
      ),
      Physics.circleAdjustment
    );
    that.vel = Vector2.mult(
      Vector2.sub(
        Vector2.reflect(
          Vector2.sub(that.pos, that.vel),
          this.pos, that.pos),
        that.pos),
      this.bcf * that.bcf);
    that.pos = Vector2.add(that.pos, that.vel);
  };
  Physics.Circle.prototype.collideDynamicStatic = function(that) {
    this.pos = Vector2.lerp(
      this.pos,
      Vector2.add(that.pos,
        Vector2.mult(
          Vector2.normalize(
            Vector2.sub(this.pos, that.pos)
          ),
          this.rad + that.rad)
      ),
      Physics.circleAdjustment
    );
    this.vel = Vector2.mult(
      Vector2.sub(
        Vector2.reflect(
          Vector2.sub(this.pos, this.vel),
          that.pos, this.pos),
        this.pos),
      this.bcf * that.bcf);
    this.pos = Vector2.add(this.pos, this.vel);
  };
  Physics.Circle.prototype.collideDynamicDynamic = function(that) {
    var mid = Vector2.mid(this.pos, that.pos);
    var difference = Vector2.norm(Vector2.sub(this.pos, that.pos));

    this.pos = Vector2.lerp(this.pos, Vector2.add(mid, Vector2.mult(difference, this.rad + that.rad)), Physics.circleAdjustment);
    that.pos = Vector2.lerp(that.pos, Vector2.sub(mid, Vector2.mult(difference, this.rad + that.rad)), Physics.circleAdjustment);

    var thisComponentOld = Vector2.dot(this.vel, difference);
    var thatComponentOld = Vector2.dot(that.vel, difference);

    var thisComponentNew = thatComponentOld * that.mass / this.mass;
    var thatComponentNew = thisComponentOld * this.mass / that.mass;

    this.vel = Vector2.add(this.vel, Vector2.mult(difference, (thisComponentNew - thisComponentOld) * this.bcf * that.bcf));
    that.vel = Vector2.add(that.vel, Vector2.mult(difference, (thatComponentNew - thatComponentOld) * this.bcf * that.bcf));
  };
  Physics.Circle.prototype.collideCircle = function(that) {
    if (this.fixed && that.fixed) {
      return;
    }
    if (Vector2.magSq(Vector2.sub(this.pos, that.pos)) > ((this.rad + that.rad) * (this.rad + that.rad))) {
      return;
    }
    if (this.fixed) {
      this.collideStaticDynamic(that);
      return;
    }
    if (that.fixed) {
      this.collideDynamicStatic(that);
      return;
    }
    this.collideDynamicDynamic(that);
  };
  Physics.Circle.prototype.applyForce = function(velChange) {
    this.vel = Vector2.add(this.vel, Vector2.div(velChange, this.mass));
  };
}
<commit_msg>Update circle.js<commit_after>if (!Physics.Circle || KAPhy.version !== KAPhy.current) {
  Physics.Circle = function(config) {
    /** Position and Velocity **/
    this.pos = config.pos || new Vector2(config.x, config.y);
    this.vel = config.vel || new Vector2();

    /** Bounciness **/
    this.bcf = config.bcf || 0.75;

    /** Radius **/
    this.rad = config.rad || 15;

    /** Array of Constraints **/
    this.constraints = [];

    /** Physical Sleep **/
    this.asleep = false;

    /** Array of Position Adjustments **/
    this.posAdjustments = [];

    /** Mass **/
    this.mass = config.mass || 1;

    /** Fixed or Not **/
    this.fixed = config.fixed || false;

    /** Variables Used When Submerged**/
    this.buoyancyForce = 0;
    this.waterDrag = 1;
  };
  Physics.Circle.prototype.update = function() {
    if (this.fixed) {
      this.asleep = false;
      this.vel = new Vector2();
      return;
    }

    if (this.vel.magSq() > Physics.sleepThreshold * Physics.sleepThreshold || this.buoyancyForce > 0) {
      this.asleep = false;
    }
    this.pos.add(this.vel) //Add velocity to position

    this.vel.y += Canvas.getY(Physics.gravityForce - this.buoyancyForce); //Gravity

    this.vel.mult(this.waterDrag * (this.asleep ? Physics.asleepAirResistance : Physics.airResistance)); //Air resistance

    this.buoyancyForce = 0;
    this.waterDrag = 1;

    this.manageAdjustments();
  };
  Physics.Circle.prototype.draw = function() {
    Draw.ellipse(this.pos.x, this.pos.y, this.rad * 2, this.rad * 2);
  };
  Physics.Circle.prototype.display = function() {
    if (this.move) {
      this.move();
    }
    this.update();
    this.draw();
  };
  Physics.Circle.prototype.moveTowards = function(target, force) {
    this.applyForce(Vector2.mult(Vector2.normalize(Vector2.sub(target, this.pos)), force));
  };
  Physics.Circle.prototype.moveFrom = function(target, force) {
    this.applyForce(Vector2.mult(Vector2.normalize(Vector2.sub(this.pos, target)), force));
  };
  Physics.Circle.prototype.manageAdjustments = function() {
    if (this.posAdjustments.length === 0) {
      return;
    }

    var adjustmentAvg = new Vector2();
    for (var i = 0; i < this.posAdjustments.length; i++) {
      adjustmentAvg.add(this.posAdjustments[i]);
    }
    this.pos = Vector2.lerp(this.pos, Vector2.div(adjustmentAvg, this.posAdjustments.length), Physics.constraintAdjustment);

    this.posAdjustments = [];
  };
  Physics.Circle.prototype.trySleep = function() {
    if (Vector2.magSq(this.vel) < Physics.sleepThreshold * Physics.sleepThreshold) {
      this.asleep = true;
    }
  };
  Physics.Circle.prototype.collideLine = function(line) {
    if (line.one.x === line.two.x ||
      line.one.y === line.two.y) {
      return;
    }

    if (!circleCollidingLine(line.one, line.two, this.pos, this.rad + line.rad)) {
      return;
    }
    if (!intersecting(this.pos, Vector2.reflect(this.pos, line.one, line.two), line.one, line.two)) {
      var n = (Vector2.dist(this.pos, line.one) < Vector2.dist(this.pos, line.two)) ? line.one : line.two;
      this.vel = Vector2.mult(Vector2.sub(Vector2.reflect(Vector2.sub(this.pos, this.vel), n, this.pos), this.pos), line.bcf * this.bcf);
      this.pos = Vector2.sub(n, Vector2.mult(Vector2.normalize(Vector2.sub(n, this.pos)), this.rad + line.rad));
    } else {
      var n = intersection(this.pos, Vector2.reflect(this.pos, line.one, line.two), line.one, line.two);
      this.vel = Vector2.mult(Vector2.sub(n, Vector2.reflect(Vector2.sub(n, this.vel), n, Vector2.add(n, new Vector2(1, PM(line.one, line.two))))), -line.bcf * this.bcf);
      this.pos = Vector2.add(n, Vector2.mult(Vector2.norm(new Vector2(1, PM(line.one, line.two))), (this.rad + line.rad) * (this.pos.y > n.y ? -1 : 1) * (line.one.x > line.two.x ? -1 : 1) * (line.one.y > line.two.y ? -1 : 1)));
    }
    this.trySleep();
  };
  Physics.Circle.prototype.collideStaticDynamic = function(that) {
    that.pos = Vector2.lerp(
      that.pos,
      Vector2.add(this.pos,
        Vector2.mult(
          Vector2.normalize(
            Vector2.sub(that.pos, this.pos)
          ),
          this.rad + that.rad)
      ),
      Physics.circleAdjustment
    );
    that.vel = Vector2.mult(
      Vector2.sub(
        Vector2.reflect(
          Vector2.sub(that.pos, that.vel),
          this.pos, that.pos),
        that.pos),
      this.bcf * that.bcf);
    that.pos = Vector2.add(that.pos, that.vel);
  };
  Physics.Circle.prototype.collideDynamicStatic = function(that) {
    this.pos = Vector2.lerp(
      this.pos,
      Vector2.add(that.pos,
        Vector2.mult(
          Vector2.normalize(
            Vector2.sub(this.pos, that.pos)
          ),
          this.rad + that.rad)
      ),
      Physics.circleAdjustment
    );
    this.vel = Vector2.mult(
      Vector2.sub(
        Vector2.reflect(
          Vector2.sub(this.pos, this.vel),
          that.pos, this.pos),
        this.pos),
      this.bcf * that.bcf);
    this.pos = Vector2.add(this.pos, this.vel);
  };
  Physics.Circle.prototype.collideDynamicDynamic = function(that) {
    var mid = Vector2.mid(this.pos, that.pos);
    var difference = Vector2.norm(Vector2.sub(this.pos, that.pos));

    this.pos = Vector2.lerp(this.pos, Vector2.add(mid, Vector2.mult(difference, this.rad + that.rad)), Physics.circleAdjustment);
    that.pos = Vector2.lerp(that.pos, Vector2.sub(mid, Vector2.mult(difference, this.rad + that.rad)), Physics.circleAdjustment);

    var thisComponentOld = Vector2.dot(this.vel, difference);
    var thatComponentOld = Vector2.dot(that.vel, difference);

    var thisComponentNew = thatComponentOld * that.mass / this.mass;
    var thatComponentNew = thisComponentOld * this.mass / that.mass;

    this.vel = Vector2.add(this.vel, Vector2.mult(difference, (thisComponentNew - thisComponentOld) * this.bcf * that.bcf));
    that.vel = Vector2.add(that.vel, Vector2.mult(difference, (thatComponentNew - thatComponentOld) * this.bcf * that.bcf));
  };
  Physics.Circle.prototype.collideCircle = function(that) {
    if (this.fixed && that.fixed) {
      return;
    }
    if (Vector2.magSq(Vector2.sub(this.pos, that.pos)) > ((this.rad + that.rad) * (this.rad + that.rad))) {
      return;
    }
    if (this.fixed) {
      this.collideStaticDynamic(that);
      return;
    }
    if (that.fixed) {
      this.collideDynamicStatic(that);
      return;
    }
    this.collideDynamicDynamic(that);
  };
  Physics.Circle.prototype.applyForce = function(velChange) {
    this.vel = Vector2.add(this.vel, Vector2.div(velChange, this.mass));
  };
}
<|endoftext|>


<commit_before>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

/* jshint sub:true, laxcomma:true, laxbreak:true */

/*
A class for holidng the information currently stored in plugin.xml
It should also be able to answer questions like whether the plugin
is compatible with a given engine version.

TODO (kamrik): refactor this to not use sync functions and return promises.
*/

var path = require('path')
  , fs = require('fs')
  , xml_helpers = require('../util/xml-helpers')
  , CordovaError = require('../CordovaError/CordovaError')
  ;

function PluginInfo(dirname) {
    var self = this;

    // METHODS
    // Defined inside the constructor to avoid the "this" binding problems.

    // <preference> tag
    // Example: <preference name="API_KEY" />
    // Used to require a variable to be specified via --variable when installing the plugin.
    // returns { key : default | null}
    self.getPreferences = getPreferences;
    function getPreferences(platform) {
        return _getTags(self._et, 'preference', platform, _parsePreference)
        .reduce(function (preferences, pref) {
            preferences[pref.preference] = pref.default;
            return preferences;
        }, {});
    }

    function _parsePreference(prefTag) {
        var name = prefTag.attrib.name.toUpperCase();
        var def = prefTag.attrib.default || null;
        return {preference: name, default: def};
    }

    // <asset>
    self.getAssets = getAssets;
    function getAssets(platform) {
        var assets = _getTags(self._et, 'asset', platform, _parseAsset);
        return assets;
    }

    function _parseAsset(tag) {
        var src = tag.attrib.src;
        var target = tag.attrib.target;

        if ( !src || !target) {
            var msg =
                'Malformed <asset> tag. Both "src" and "target" attributes'
                + 'must be specified in\n'
                + self.filepath
                ;
            throw new Error(msg);
        }

        var asset = {
            itemType: 'asset',
            src: src,
            target: target
        };
        return asset;
    }

    // <dependency>
    // Example:
    // <dependency id="com.plugin.id"
    //     url="https://github.com/myuser/someplugin"
    //     commit="428931ada3891801"
    //     subdir="some/path/here" />
    self.getDependencies = getDependencies;
    function getDependencies(platform) {
        var deps = _getTags(
                self._et,
                'dependency',
                platform,
                _parseDependency
        );
        return deps;
    }

    function _parseDependency(tag) {
        var dep =
            { id : tag.attrib.id
            , version: tag.attrib.version || ''
            , url : tag.attrib.url || ''
            , subdir : tag.attrib.subdir || ''
            , commit : tag.attrib.commit
            };

        dep.git_ref = dep.commit;

        if ( !dep.id ) {
            var msg =
                '<dependency> tag is missing id attribute in '
                + self.filepath
                ;
            throw new CordovaError(msg);
        }
        return dep;
    }

    // <config-file> tag
    self.getConfigFiles = getConfigFiles;
    function getConfigFiles(platform) {
        var configFiles = _getTags(self._et, 'config-file', platform, _parseConfigFile);
        return configFiles;
    }

    function _parseConfigFile(tag) {
        var configFile =
            { target : tag.attrib['target']
            , parent : tag.attrib['parent']
            , after : tag.attrib['after']
            , xmls : tag.getchildren()
            // To support demuxing via versions
            , versions : tag.attrib['versions']
            , deviceTarget: tag.attrib['device-target']
            };
        return configFile;
    }

    self.getEditConfigs = getEditConfigs;
    function getEditConfigs(platform) {
        var editConfigs = _getTags(self._et, 'edit-config', platform, _parseEditConfigs);
        return editConfigs;
    }

    function _parseEditConfigs(tag) {
        var editConfig =
        { file : tag.attrib['file']
        , target : tag.attrib['target']
        , mode : tag.attrib['mode']
        , xmls : tag.getchildren()
        };
        return editConfig;
    }

    // <info> tags, both global and within a <platform>
    // TODO (kamrik): Do we ever use <info> under <platform>? Example wanted.
    self.getInfo = getInfo;
    function getInfo(platform) {
        var infos = _getTags(
                self._et,
                'info',
                platform,
                function(elem) { return elem.text; }
        );
        // Filter out any undefined or empty strings.
        infos = infos.filter(Boolean);
        return infos;
    }

    // <source-file>
    // Examples:
    // <source-file src="src/ios/someLib.a" framework="true" />
    // <source-file src="src/ios/someLib.a" compiler-flags="-fno-objc-arc" />
    self.getSourceFiles = getSourceFiles;
    function getSourceFiles(platform) {
        var sourceFiles = _getTagsInPlatform(self._et, 'source-file', platform, _parseSourceFile);
        return sourceFiles;
    }

    function _parseSourceFile(tag) {
        return {
            itemType: 'source-file',
            src: tag.attrib.src,
            framework: isStrTrue(tag.attrib.framework),
            weak: isStrTrue(tag.attrib.weak),
            compilerFlags: tag.attrib['compiler-flags'],
            targetDir: tag.attrib['target-dir']
        };
    }

    // <header-file>
    // Example:
    // <header-file src="CDVFoo.h" />
    self.getHeaderFiles = getHeaderFiles;
    function getHeaderFiles(platform) {
        var headerFiles = _getTagsInPlatform(self._et, 'header-file', platform, function(tag) {
            return {
                itemType: 'header-file',
                src: tag.attrib.src,
                targetDir: tag.attrib['target-dir']
            };
        });
        return headerFiles;
    }

    // <resource-file>
    // Example:
    // <resource-file src="FooPluginStrings.xml" target="res/values/FooPluginStrings.xml" device-target="win" arch="x86" versions=">=8.1" />
    self.getResourceFiles = getResourceFiles;
    function getResourceFiles(platform) {
        var resourceFiles = _getTagsInPlatform(self._et, 'resource-file', platform, function(tag) {
            return {
                itemType: 'resource-file',
                src: tag.attrib.src,
                target: tag.attrib.target,
                versions: tag.attrib.versions,
                deviceTarget: tag.attrib['device-target'],
                arch: tag.attrib.arch,
                reference: tag.attrib.reference
            };
        });
        return resourceFiles;
    }

    // <lib-file>
    // Example:
    // <lib-file src="src/BlackBerry10/native/device/libfoo.so" arch="device" />
    self.getLibFiles = getLibFiles;
    function getLibFiles(platform) {
        var libFiles = _getTagsInPlatform(self._et, 'lib-file', platform, function(tag) {
            return {
                itemType: 'lib-file',
                src: tag.attrib.src,
                arch: tag.attrib.arch,
                Include: tag.attrib.Include,
                versions: tag.attrib.versions,
                deviceTarget: tag.attrib['device-target'] || tag.attrib.target
            };
        });
        return libFiles;
    }

    // <hook>
    // Example:
    // <hook type="before_build" src="scripts/beforeBuild.js" />
    self.getHookScripts = getHookScripts;
    function getHookScripts(hook, platforms) {
        var scriptElements =  self._et.findall('./hook');

        if(platforms) {
            platforms.forEach(function (platform) {
                scriptElements = scriptElements.concat(self._et.findall('./platform[@name="' + platform + '"]/hook'));
            });
        }

        function filterScriptByHookType(el) {
            return el.attrib.src && el.attrib.type && el.attrib.type.toLowerCase() === hook;
        }

        return scriptElements.filter(filterScriptByHookType);
    }

    self.getJsModules = getJsModules;
    function getJsModules(platform) {
        var modules = _getTags(self._et, 'js-module', platform, _parseJsModule);
        return modules;
    }

    function _parseJsModule(tag) {
        var ret = {
            itemType: 'js-module',
            name: tag.attrib.name,
            src: tag.attrib.src,
            clobbers: tag.findall('clobbers').map(function(tag) { return { target: tag.attrib.target }; }),
            merges: tag.findall('merges').map(function(tag) { return { target: tag.attrib.target }; }),
            runs: tag.findall('runs').length > 0
        };

        return ret;
    }

    self.getEngines = function() {
        return self._et.findall('engines/engine').map(function(n) {
            return {
                name: n.attrib.name,
                version: n.attrib.version,
                platform: n.attrib.platform,
                scriptSrc: n.attrib.scriptSrc
            };
        });
    };

    self.getPlatforms = function() {
        return self._et.findall('platform').map(function(n) {
            return { name: n.attrib.name };
        });
    };

    self.getPlatformsArray = function() {
        return self._et.findall('platform').map(function(n) {
            return n.attrib.name;
        });
    };
    self.getFrameworks = function(platform) {
        return _getTags(self._et, 'framework', platform, function(el) {
            var ret = {
                itemType: 'framework',
                type: el.attrib.type,
                parent: el.attrib.parent,
                custom: isStrTrue(el.attrib.custom),
                src: el.attrib.src,
                spec: el.attrib.spec,
                weak: isStrTrue(el.attrib.weak),
                versions: el.attrib.versions,
                targetDir: el.attrib['target-dir'],
                deviceTarget: el.attrib['device-target'] || el.attrib.target,
                arch: el.attrib.arch,
                implementation: el.attrib.implementation
            };
            return ret;
        });
    };

    self.getFilesAndFrameworks = getFilesAndFrameworks;
    function getFilesAndFrameworks(platform) {
        // Please avoid changing the order of the calls below, files will be
        // installed in this order.
        var items = [].concat(
            self.getSourceFiles(platform),
            self.getHeaderFiles(platform),
            self.getResourceFiles(platform),
            self.getFrameworks(platform),
            self.getLibFiles(platform)
        );
        return items;
    }
    ///// End of PluginInfo methods /////

    ///// PluginInfo Constructor logic  /////
    self.filepath = path.join(dirname, 'plugin.xml');
    if (!fs.existsSync(self.filepath)) {
        throw new CordovaError('Cannot find plugin.xml for plugin "' + path.basename(dirname) + '". Please try adding it again.');
    }

    self.dir = dirname;
    var et = self._et = xml_helpers.parseElementtreeSync(self.filepath);
    var pelem = et.getroot();
    self.id = pelem.attrib.id;
    self.version = pelem.attrib.version;

    // Optional fields
    self.name = pelem.findtext('name');
    self.description = pelem.findtext('description');
    self.license = pelem.findtext('license');
    self.repo = pelem.findtext('repo');
    self.issue = pelem.findtext('issue');
    self.keywords = pelem.findtext('keywords');
    self.info = pelem.findtext('info');
    if (self.keywords) {
        self.keywords = self.keywords.split(',').map( function(s) { return s.trim(); } );
    }
    self.getKeywordsAndPlatforms = function () {
        var ret = self.keywords || [];
        return ret.concat('ecosystem:cordova').concat(addCordova(self.getPlatformsArray()));
    };
}  // End of PluginInfo constructor.

// Helper function used to prefix every element of an array with cordova-
// Useful when we want to modify platforms to be cordova-platform
function addCordova(someArray) {
    var newArray = someArray.map(function(element) {
        return 'cordova-' + element;
    });
    return newArray;
}

// Helper function used by most of the getSomething methods of PluginInfo.
// Get all elements of a given name. Both in root and in platform sections
// for the given platform. If transform is given and is a function, it is
// applied to each element.
function _getTags(pelem, tag, platform, transform) {
    var platformTag = pelem.find('./platform[@name="' + platform + '"]');
    var tagsInRoot = pelem.findall(tag);
    tagsInRoot = tagsInRoot || [];
    var tagsInPlatform = platformTag ? platformTag.findall(tag) : [];
    var tags = tagsInRoot.concat(tagsInPlatform);
    if ( typeof transform === 'function' ) {
        tags = tags.map(transform);
    }
    return tags;
}

// Same as _getTags() but only looks inside a platform section.
function _getTagsInPlatform(pelem, tag, platform, transform) {
    var platformTag = pelem.find('./platform[@name="' + platform + '"]');
    var tags = platformTag ? platformTag.findall(tag) : [];
    if ( typeof transform === 'function' ) {
        tags = tags.map(transform);
    }
    return tags;
}

// Check if x is a string 'true'.
function isStrTrue(x) {
    return String(x).toLowerCase() == 'true';
}

module.exports = PluginInfo;
// Backwards compat:
PluginInfo.PluginInfo = PluginInfo;
PluginInfo.loadPluginsDir = function(dir) {
    var PluginInfoProvider = require('./PluginInfoProvider');
    return new PluginInfoProvider().getAllWithinSearchPath(dir);
};
<commit_msg>CB-11233 - Support installing frameworks into 'Embedded Binaries' section of the Xcode project<commit_after>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

/* jshint sub:true, laxcomma:true, laxbreak:true */

/*
A class for holidng the information currently stored in plugin.xml
It should also be able to answer questions like whether the plugin
is compatible with a given engine version.

TODO (kamrik): refactor this to not use sync functions and return promises.
*/

var path = require('path')
  , fs = require('fs')
  , xml_helpers = require('../util/xml-helpers')
  , CordovaError = require('../CordovaError/CordovaError')
  ;

function PluginInfo(dirname) {
    var self = this;

    // METHODS
    // Defined inside the constructor to avoid the "this" binding problems.

    // <preference> tag
    // Example: <preference name="API_KEY" />
    // Used to require a variable to be specified via --variable when installing the plugin.
    // returns { key : default | null}
    self.getPreferences = getPreferences;
    function getPreferences(platform) {
        return _getTags(self._et, 'preference', platform, _parsePreference)
        .reduce(function (preferences, pref) {
            preferences[pref.preference] = pref.default;
            return preferences;
        }, {});
    }

    function _parsePreference(prefTag) {
        var name = prefTag.attrib.name.toUpperCase();
        var def = prefTag.attrib.default || null;
        return {preference: name, default: def};
    }

    // <asset>
    self.getAssets = getAssets;
    function getAssets(platform) {
        var assets = _getTags(self._et, 'asset', platform, _parseAsset);
        return assets;
    }

    function _parseAsset(tag) {
        var src = tag.attrib.src;
        var target = tag.attrib.target;

        if ( !src || !target) {
            var msg =
                'Malformed <asset> tag. Both "src" and "target" attributes'
                + 'must be specified in\n'
                + self.filepath
                ;
            throw new Error(msg);
        }

        var asset = {
            itemType: 'asset',
            src: src,
            target: target
        };
        return asset;
    }

    // <dependency>
    // Example:
    // <dependency id="com.plugin.id"
    //     url="https://github.com/myuser/someplugin"
    //     commit="428931ada3891801"
    //     subdir="some/path/here" />
    self.getDependencies = getDependencies;
    function getDependencies(platform) {
        var deps = _getTags(
                self._et,
                'dependency',
                platform,
                _parseDependency
        );
        return deps;
    }

    function _parseDependency(tag) {
        var dep =
            { id : tag.attrib.id
            , version: tag.attrib.version || ''
            , url : tag.attrib.url || ''
            , subdir : tag.attrib.subdir || ''
            , commit : tag.attrib.commit
            };

        dep.git_ref = dep.commit;

        if ( !dep.id ) {
            var msg =
                '<dependency> tag is missing id attribute in '
                + self.filepath
                ;
            throw new CordovaError(msg);
        }
        return dep;
    }

    // <config-file> tag
    self.getConfigFiles = getConfigFiles;
    function getConfigFiles(platform) {
        var configFiles = _getTags(self._et, 'config-file', platform, _parseConfigFile);
        return configFiles;
    }

    function _parseConfigFile(tag) {
        var configFile =
            { target : tag.attrib['target']
            , parent : tag.attrib['parent']
            , after : tag.attrib['after']
            , xmls : tag.getchildren()
            // To support demuxing via versions
            , versions : tag.attrib['versions']
            , deviceTarget: tag.attrib['device-target']
            };
        return configFile;
    }

    self.getEditConfigs = getEditConfigs;
    function getEditConfigs(platform) {
        var editConfigs = _getTags(self._et, 'edit-config', platform, _parseEditConfigs);
        return editConfigs;
    }

    function _parseEditConfigs(tag) {
        var editConfig =
        { file : tag.attrib['file']
        , target : tag.attrib['target']
        , mode : tag.attrib['mode']
        , xmls : tag.getchildren()
        };
        return editConfig;
    }

    // <info> tags, both global and within a <platform>
    // TODO (kamrik): Do we ever use <info> under <platform>? Example wanted.
    self.getInfo = getInfo;
    function getInfo(platform) {
        var infos = _getTags(
                self._et,
                'info',
                platform,
                function(elem) { return elem.text; }
        );
        // Filter out any undefined or empty strings.
        infos = infos.filter(Boolean);
        return infos;
    }

    // <source-file>
    // Examples:
    // <source-file src="src/ios/someLib.a" framework="true" />
    // <source-file src="src/ios/someLib.a" compiler-flags="-fno-objc-arc" />
    self.getSourceFiles = getSourceFiles;
    function getSourceFiles(platform) {
        var sourceFiles = _getTagsInPlatform(self._et, 'source-file', platform, _parseSourceFile);
        return sourceFiles;
    }

    function _parseSourceFile(tag) {
        return {
            itemType: 'source-file',
            src: tag.attrib.src,
            framework: isStrTrue(tag.attrib.framework),
            weak: isStrTrue(tag.attrib.weak),
            compilerFlags: tag.attrib['compiler-flags'],
            targetDir: tag.attrib['target-dir']
        };
    }

    // <header-file>
    // Example:
    // <header-file src="CDVFoo.h" />
    self.getHeaderFiles = getHeaderFiles;
    function getHeaderFiles(platform) {
        var headerFiles = _getTagsInPlatform(self._et, 'header-file', platform, function(tag) {
            return {
                itemType: 'header-file',
                src: tag.attrib.src,
                targetDir: tag.attrib['target-dir']
            };
        });
        return headerFiles;
    }

    // <resource-file>
    // Example:
    // <resource-file src="FooPluginStrings.xml" target="res/values/FooPluginStrings.xml" device-target="win" arch="x86" versions=">=8.1" />
    self.getResourceFiles = getResourceFiles;
    function getResourceFiles(platform) {
        var resourceFiles = _getTagsInPlatform(self._et, 'resource-file', platform, function(tag) {
            return {
                itemType: 'resource-file',
                src: tag.attrib.src,
                target: tag.attrib.target,
                versions: tag.attrib.versions,
                deviceTarget: tag.attrib['device-target'],
                arch: tag.attrib.arch,
                reference: tag.attrib.reference
            };
        });
        return resourceFiles;
    }

    // <lib-file>
    // Example:
    // <lib-file src="src/BlackBerry10/native/device/libfoo.so" arch="device" />
    self.getLibFiles = getLibFiles;
    function getLibFiles(platform) {
        var libFiles = _getTagsInPlatform(self._et, 'lib-file', platform, function(tag) {
            return {
                itemType: 'lib-file',
                src: tag.attrib.src,
                arch: tag.attrib.arch,
                Include: tag.attrib.Include,
                versions: tag.attrib.versions,
                deviceTarget: tag.attrib['device-target'] || tag.attrib.target
            };
        });
        return libFiles;
    }

    // <hook>
    // Example:
    // <hook type="before_build" src="scripts/beforeBuild.js" />
    self.getHookScripts = getHookScripts;
    function getHookScripts(hook, platforms) {
        var scriptElements =  self._et.findall('./hook');

        if(platforms) {
            platforms.forEach(function (platform) {
                scriptElements = scriptElements.concat(self._et.findall('./platform[@name="' + platform + '"]/hook'));
            });
        }

        function filterScriptByHookType(el) {
            return el.attrib.src && el.attrib.type && el.attrib.type.toLowerCase() === hook;
        }

        return scriptElements.filter(filterScriptByHookType);
    }

    self.getJsModules = getJsModules;
    function getJsModules(platform) {
        var modules = _getTags(self._et, 'js-module', platform, _parseJsModule);
        return modules;
    }

    function _parseJsModule(tag) {
        var ret = {
            itemType: 'js-module',
            name: tag.attrib.name,
            src: tag.attrib.src,
            clobbers: tag.findall('clobbers').map(function(tag) { return { target: tag.attrib.target }; }),
            merges: tag.findall('merges').map(function(tag) { return { target: tag.attrib.target }; }),
            runs: tag.findall('runs').length > 0
        };

        return ret;
    }

    self.getEngines = function() {
        return self._et.findall('engines/engine').map(function(n) {
            return {
                name: n.attrib.name,
                version: n.attrib.version,
                platform: n.attrib.platform,
                scriptSrc: n.attrib.scriptSrc
            };
        });
    };

    self.getPlatforms = function() {
        return self._et.findall('platform').map(function(n) {
            return { name: n.attrib.name };
        });
    };

    self.getPlatformsArray = function() {
        return self._et.findall('platform').map(function(n) {
            return n.attrib.name;
        });
    };
    self.getFrameworks = function(platform) {
        return _getTags(self._et, 'framework', platform, function(el) {
            var ret = {
                itemType: 'framework',
                type: el.attrib.type,
                parent: el.attrib.parent,
                custom: isStrTrue(el.attrib.custom),
                embed: isStrTrue(el.attrib.embed),
                src: el.attrib.src,
                spec: el.attrib.spec,
                weak: isStrTrue(el.attrib.weak),
                versions: el.attrib.versions,
                targetDir: el.attrib['target-dir'],
                deviceTarget: el.attrib['device-target'] || el.attrib.target,
                arch: el.attrib.arch,
                implementation: el.attrib.implementation
            };
            return ret;
        });
    };

    self.getFilesAndFrameworks = getFilesAndFrameworks;
    function getFilesAndFrameworks(platform) {
        // Please avoid changing the order of the calls below, files will be
        // installed in this order.
        var items = [].concat(
            self.getSourceFiles(platform),
            self.getHeaderFiles(platform),
            self.getResourceFiles(platform),
            self.getFrameworks(platform),
            self.getLibFiles(platform)
        );
        return items;
    }
    ///// End of PluginInfo methods /////

    ///// PluginInfo Constructor logic  /////
    self.filepath = path.join(dirname, 'plugin.xml');
    if (!fs.existsSync(self.filepath)) {
        throw new CordovaError('Cannot find plugin.xml for plugin "' + path.basename(dirname) + '". Please try adding it again.');
    }

    self.dir = dirname;
    var et = self._et = xml_helpers.parseElementtreeSync(self.filepath);
    var pelem = et.getroot();
    self.id = pelem.attrib.id;
    self.version = pelem.attrib.version;

    // Optional fields
    self.name = pelem.findtext('name');
    self.description = pelem.findtext('description');
    self.license = pelem.findtext('license');
    self.repo = pelem.findtext('repo');
    self.issue = pelem.findtext('issue');
    self.keywords = pelem.findtext('keywords');
    self.info = pelem.findtext('info');
    if (self.keywords) {
        self.keywords = self.keywords.split(',').map( function(s) { return s.trim(); } );
    }
    self.getKeywordsAndPlatforms = function () {
        var ret = self.keywords || [];
        return ret.concat('ecosystem:cordova').concat(addCordova(self.getPlatformsArray()));
    };
}  // End of PluginInfo constructor.

// Helper function used to prefix every element of an array with cordova-
// Useful when we want to modify platforms to be cordova-platform
function addCordova(someArray) {
    var newArray = someArray.map(function(element) {
        return 'cordova-' + element;
    });
    return newArray;
}

// Helper function used by most of the getSomething methods of PluginInfo.
// Get all elements of a given name. Both in root and in platform sections
// for the given platform. If transform is given and is a function, it is
// applied to each element.
function _getTags(pelem, tag, platform, transform) {
    var platformTag = pelem.find('./platform[@name="' + platform + '"]');
    var tagsInRoot = pelem.findall(tag);
    tagsInRoot = tagsInRoot || [];
    var tagsInPlatform = platformTag ? platformTag.findall(tag) : [];
    var tags = tagsInRoot.concat(tagsInPlatform);
    if ( typeof transform === 'function' ) {
        tags = tags.map(transform);
    }
    return tags;
}

// Same as _getTags() but only looks inside a platform section.
function _getTagsInPlatform(pelem, tag, platform, transform) {
    var platformTag = pelem.find('./platform[@name="' + platform + '"]');
    var tags = platformTag ? platformTag.findall(tag) : [];
    if ( typeof transform === 'function' ) {
        tags = tags.map(transform);
    }
    return tags;
}

// Check if x is a string 'true'.
function isStrTrue(x) {
    return String(x).toLowerCase() == 'true';
}

module.exports = PluginInfo;
// Backwards compat:
PluginInfo.PluginInfo = PluginInfo;
PluginInfo.loadPluginsDir = function(dir) {
    var PluginInfoProvider = require('./PluginInfoProvider');
    return new PluginInfoProvider().getAllWithinSearchPath(dir);
};
<|endoftext|>


<commit_before>import Morph from "./Morph.js"

import d3 from 'src/external/d3.v4.js';

import { Graph } from 'src/client/triples/triples.js';
import * as drawTools from 'src/client/triples/drawTools.js';
import * as math from 'src/client/triples/math.js';

const MIN_MAGNIFICATION = 0.01;
const MAX_MAGNIFICATION = 4;

const NODE_BY_KNOT = new Map();
function getNodeByKnot(knot) {
  if(!NODE_BY_KNOT.has(knot)) {
    NODE_BY_KNOT.set(knot, new Node(knot));
  }
  return NODE_BY_KNOT.get(knot);
}

class RectangleTools {
  static distanceToBorder(rect, dx, dy) {
  	var width = rect.width(),
  		height = rect.height();

  	var innerDistance,
  		m_link = Math.abs(dy / dx),
  		m_rect = height / width;

  	if (m_link <= m_rect) {
  		var timesX = dx / (width / 2),
  			rectY = dy / timesX;
  		innerDistance = Math.sqrt(Math.pow(width / 2, 2) + Math.pow(rectY, 2));
  	} else {
  		var timesY = dy / (height / 2),
  			rectX = dx / timesY;
  		innerDistance = Math.sqrt(Math.pow(height / 2, 2) + Math.pow(rectX, 2));
  	}

  	return innerDistance;
  };
}

const cssClassesByFileType = {
  'png': ['image'],
  'PNG': ['image'],
  'jpg': ['image'],
  'svg': ['image'],
  'mp3': ['audio'],
  'mov': ['movie'],
  'mp4': ['movie'],
  'avi': ['movie'],
  'pptx': ['presentation'],
  'md': ['markdown'],
  'htm': ['html'],
  'html': ['html'],
  'json': ['data'],
  'csv': ['data']
}
const cssClassesByTagURL = {
  'https://lively4/dropbox/tag.md': ['tag'],
  'https://lively4/dropbox/is_a.md': ['is-a'],
  'https://lively4/dropbox/same_as.md': ['same-as'],
  'https://lively4/dropbox/contains.md': ['contains'],
}
class Node {
  static getCSSClassesByType(node) {

  }
  constructor(knot, label) {
    this.knot = knot;
    //this.r = ~~d3.randomUniform(8, 28)();
    const fileEnding = this.getFileEnding();
    const shouldRenderSizeAware = (fileEnding === 'md' || fileEnding === 'html') &&
     this.knot.content && this.knot.content.split;
    this._radius = shouldRenderSizeAware ?
      Math.min((this.knot.content.split(/\r?\n/).length + 10) * 0.9, 100) :
	    40;
	 this._width = 60;
	 this._height = 20;
  }
  getKnot() { return this.knot; }
  label() { return this.knot.label(); }
  isTriple() { return this.knot.isTriple(); }
  isExternal() {  return Graph.isExternalURL(new URL(this.knot.url)); }
  getFileEnding() { return this.knot.url.split('#').shift().split('?').shift().split('.').pop(); }

  draw(parentElement, additionalCssClasses) {
    let cssClasses;

    if(this.knot.isTriple()) {
      cssClasses = cssClassesByTagURL[this.knot.predicate.url] || ['unspecified'];
      cssClasses.push('nostroke')
    } else {
      const fileEnding = this.getFileEnding();
      //lively.notify(fileEnding)
  		cssClasses = cssClassesByFileType[fileEnding] ?
  		  cssClassesByFileType[fileEnding] :
  		  (lively.notify(fileEnding), ['white']);
    }

    if(this.knot.isTriple()) {
      drawTools.appendRectangularClass(parentElement, 60, 20, cssClasses, this.label());
    } else {
		  drawTools.appendCircularClass(parentElement, this.actualRadius(), cssClasses, this.label());
    }

		//that.postDrawActions(parentElement);
	}

	actualRadius() {
	  return this._radius;
	}
	width() { return this._width; }
	height() { return this._height; }
	distanceToBorder(dx, dy) { return this.isTriple() ?
	  RectangleTools.distanceToBorder(this, dx, dy) :
	  this.actualRadius();
	}
}

class Link extends Node {
  constructor(node) {
    super(node.getKnot());

    this._subject = getNodeByKnot(this.getKnot().subject);
    this._predicate = getNodeByKnot(this.getKnot().predicate);
    this._object = getNodeByKnot(this.getKnot().object);
    this._triple = getNodeByKnot(this.getKnot());

    this.frontPart = new LinkPart({
      source: this._subject,
      target: this._triple
    });
    this.backPart = new LinkPart({
      source: this._triple,
      target: this._object
    });
  }
  get subject() { return this._subject; }
  get predicate() { return this._predicate; }
  get object() { return this._object; }
  get triple() { return this._triple; }

  //TODO: support loops specially
  isLoop() {
    return this.subject === this.object;
  }
  linkParts() {
    return [this.frontPart, this.backPart];
  }

  draw(linkGroup, markerContainer) {
  	linkGroup.append("path")
  		.classed("link-path", true)
  		//.classed(this.domain().cssClassOfNode(), true)
  		//.classed(this.range().cssClassOfNode(), true)
      //.classed(property.linkType(), true);
  }

  // TODO: if we are self-referencial: compute the number of self references from the graph
  loops() {
    return 3;
  }
}

class LinkPart {
  constructor({ source, target }) {
    this.source = source;
    this.target = target;
  }
}

export default class TripleNotes extends Morph {

  async initialize() {
    this.windowTitle = "Knot Explorer";

    let parentElement = this.get('#graph');
    var width,height;
    var chartWidth, chartHeight;
    var margin;
    var svg = d3.select(parentElement)
      .append("svg");
    var graphContainer = svg.append("g").classed("graphContainer", true);

    setSize();

    let graph = await Graph.getInstance();

    let knots = graph.knots;
    this.updateStatistics(knots);

    let nodes = knots.map(getNodeByKnot);
    let links = nodes
      .filter(node => node.isTriple())
      .map(node => new Link(node));

    let hiddenLinks = [];
		links.forEach(link => hiddenLinks = hiddenLinks.concat(link.linkParts()));

    drawChart.call(this, {
      nodes,
      links,
      hiddenLinks
    });

    lively.addEventListener("triple-notes", this, "extent-changed", e => { setSize(); });

    function setSize() {
      width = parentElement.clientWidth;
      height = parentElement.clientHeight;

      margin = {top:0, left:0, bottom:0, right:0 };

      chartWidth = width - (margin.left+margin.right)
      chartHeight = height - (margin.top+margin.bottom)

      svg
        .attr("width", chartWidth)
        .attr("height", chartHeight)
        .attr("transform", "translate("+[margin.left, margin.top]+")");
    }

    function zoomed() {
      graphContainer.attr("transform", d3.event.transform);
    }

    svg.call(d3.zoom()
			.duration(150)
    	.scaleExtent([MIN_MAGNIFICATION, MAX_MAGNIFICATION])
      .on("zoom", zoomed));

    function drawChart({ nodes, links, hiddenLinks }) {

      // hidden link parts
      let linkPartContainer = graphContainer.append("g").classed("linkPartContainer", true);
      var hiddenLinkElements = linkPartContainer.selectAll("line")
        .data(hiddenLinks).enter()
        .append("line")
        .style("stroke", "black")
        .style("stroke-opacity", 0.1)
        .style("stroke-width", 10);

      // Curved, visible  Links
      let linkContainer = graphContainer.append("g").classed("linkContainer", true);
      let markerContainer = linkContainer.append("defs");
      createPropertyMarker(markerContainer);
      function createPropertyMarker(markerContainer) {
      	var marker = appendBasicMarker(markerContainer);
      	//marker.attr("refX", 12);
          var m1X = -12 ;
          var m1Y = 8 ;
          var m2X = -12;
          var m2Y = -8 ;
      	marker.append("path")
      		//.attr("d", "M0,-8L12,0L0,8Z")
              .attr("d", "M0,0L " + m1X + "," + m1Y + "L" + m2X + "," + m2Y + "L" + 0 + "," + 0 )
      		.classed("basic-triple-link", true);
      }

      function appendBasicMarker(markerContainer) {
      	return markerContainer.append("marker")
      		.datum({})
      		.attr("id", "triple-notes-basic-triple-link")

      		.attr("viewBox", "-14 -10 28 20")
      		.attr("markerWidth",10)
      		.attr("markerHeight", 10)
      		//.attr("markerUnits", "userSpaceOnUse")
      		.attr("orient", "auto");
      }

  		// Draw links
  		let linkGroups = linkContainer.selectAll(".link")
  			.data(links).enter()
  			.append("g")
  			.classed("link", true);

  		linkGroups.each(function (link) {
  		  d3.select(this).attr("marker-end", "url(#triple-notes-basic-triple-link)");
  			link.draw(d3.select(this), markerContainer);
  		});

  		// Select the path for direct access to receive a better performance
      let linkPathElements = linkGroups.selectAll("path");

      let curveFunction = d3.line()
  			.x(function (d) {
  				return d.x;
  			})
  			.y(function (d) {
  				return d.y;
  			})
        .curve(d3.curveNatural);

      // Visible Knots -> Nodes
      let nodeContainer = graphContainer.append("g").classed("nodeContainer", true);
      let nodeElements = nodeContainer.selectAll(".node")
        .data(nodes).enter()
        .append("g")
        .attr("class", "node")
        .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended))
          .on("dblclick", async node => {
            d3.event.stopPropagation();

            let knotView = await lively.openComponentInWindow("knot-view");
            knotView.loadKnotForURL(node.getKnot().url);
          });

      nodeElements.each(function (node) {
  			node.draw(d3.select(this));
      });

      nodeElements.append("text")
        .attr("class", "text")
        .style("text-anchor", "middle")
        .style("alignment-baseline", "middle")
        .text(d => d.label());

      var simulation = d3.forceSimulation()
        .force("link", d3.forceLink().id(d => d.index).distance(200))
        //.force("collide",d3.forceCollide(d => d.r + 8).iterations(16) )
        .force("charge", d3.forceManyBody().strength(node => node.isTriple() ? -190*0.5 : -190))
        .force("center", d3.forceCenter(chartWidth / 2, chartWidth / 2))
        .force("y", d3.forceY(0).strength(0.001))
        .force("x", d3.forceX(0).strength(0.001));

      // Define Simulation
      simulation
        .nodes(nodes)
        .on("tick", function recalculatePositions() {
          nodeElements.attr("transform", d => "translate(" + d.x + "," + d.y + ")");

          hiddenLinkElements
            .attr("x1", d => d.source.x)
            .attr("y1", d => d.source.y)
            .attr("x2", d => d.target.x)
            .attr("y2", d => d.target.y);

      		// Set link paths and calculate additional information
      		linkPathElements.attr("d", function (link) {
      			if (link.isLoop()) {
      				return math.calculateLoopPath(link);
      			}
      			var curvePoint = link.triple;
      			var pathStart = math.calculateIntersection(curvePoint, link.subject, 1);
      			var pathEnd = math.calculateIntersection(curvePoint, link.object, 1);

      			return curveFunction([pathStart, curvePoint, pathEnd]);
          });
        });

      simulation.force("link")
        .links(hiddenLinks);

      function dragstarted(d) {
        if (!d3.event.active) simulation.alphaTarget(0.3).restart();
        d.fx = d.x;
        d.fy = d.y;
      }

      function dragged(d) {
        d.fx = d3.event.x;
        d.fy = d3.event.y;
      }

      function dragended(d) {
        if (!d3.event.active) simulation.alphaTarget(0);
        d.fx = null;
        d.fy = null;
      }

      var linkDistance = this.get('#link-distance');
      linkDistance.addEventListener('onchange', function () {
        lively.notify('dwdw' +linkDistance.value);
        return;
        document.getElementById('currentValue').innerHtml = slider.value;
        window.resizeTo( slider.value, 400 );

      });
    }
  }

  updateStatistics(knots) {
    this.get('#number-of-knots').innerHTML = knots.length;
    this.get('#number-of-triples').innerHTML = knots.filter(k => k.isTriple()).length;
  }
}<commit_msg>AUTO-COMMIT templates/triple-notes.js<commit_after>import Morph from "./Morph.js"

import d3 from 'src/external/d3.v4.js';

import { Graph } from 'src/client/triples/triples.js';
import * as drawTools from 'src/client/triples/drawTools.js';
import * as math from 'src/client/triples/math.js';

const MIN_MAGNIFICATION = 0.01;
const MAX_MAGNIFICATION = 4;

const NODE_BY_KNOT = new Map();
function getNodeByKnot(knot) {
  if(!NODE_BY_KNOT.has(knot)) {
    NODE_BY_KNOT.set(knot, new Node(knot));
  }
  return NODE_BY_KNOT.get(knot);
}

class RectangleTools {
  static distanceToBorder(rect, dx, dy) {
  	var width = rect.width(),
  		height = rect.height();

  	var innerDistance,
  		m_link = Math.abs(dy / dx),
  		m_rect = height / width;

  	if (m_link <= m_rect) {
  		var timesX = dx / (width / 2),
  			rectY = dy / timesX;
  		innerDistance = Math.sqrt(Math.pow(width / 2, 2) + Math.pow(rectY, 2));
  	} else {
  		var timesY = dy / (height / 2),
  			rectX = dx / timesY;
  		innerDistance = Math.sqrt(Math.pow(height / 2, 2) + Math.pow(rectX, 2));
  	}

  	return innerDistance;
  };
}

const cssClassesByFileType = {
  'png': ['image'],
  'PNG': ['image'],
  'jpg': ['image'],
  'svg': ['image'],
  'mp3': ['audio'],
  'mov': ['movie'],
  'mp4': ['movie'],
  'avi': ['movie'],
  'pptx': ['presentation'],
  'md': ['markdown'],
  'htm': ['html'],
  'html': ['html'],
  'json': ['data'],
  'csv': ['data']
}
const cssClassesByTagURL = {
  'https://lively4/dropbox/tag.md': ['tag'],
  'https://lively4/dropbox/is_a.md': ['is-a'],
  'https://lively4/dropbox/same_as.md': ['same-as'],
  'https://lively4/dropbox/contains.md': ['contains'],
}
class Node {
  static getCSSClassesByType(node) {

  }
  constructor(knot, label) {
    this.knot = knot;
    //this.r = ~~d3.randomUniform(8, 28)();
    const fileEnding = this.getFileEnding();
    const shouldRenderSizeAware = (fileEnding === 'md' || fileEnding === 'html') &&
     this.knot.content && this.knot.content.split;
    this._radius = shouldRenderSizeAware ?
      Math.min((this.knot.content.split(/\r?\n/).length + 10) * 0.9, 100) :
	    40;
	 this._width = 60;
	 this._height = 20;
  }
  getKnot() { return this.knot; }
  label() { return this.knot.label(); }
  isTriple() { return this.knot.isTriple(); }
  isExternal() {  return Graph.isExternalURL(new URL(this.knot.url)); }
  getFileEnding() { return this.knot.url.split('#').shift().split('?').shift().split('.').pop(); }

  draw(parentElement, additionalCssClasses) {
    let cssClasses;

    if(this.knot.isTriple()) {
      cssClasses = cssClassesByTagURL[this.knot.predicate.url] || ['unspecified'];
      cssClasses.push('nostroke')
    } else {
      const fileEnding = this.getFileEnding();
      //lively.notify(fileEnding)
  		cssClasses = cssClassesByFileType[fileEnding] ?
  		  cssClassesByFileType[fileEnding] :
  		  (lively.notify(fileEnding), ['white']);
    }

    if(this.knot.isTriple()) {
      drawTools.appendRectangularClass(parentElement, 60, 20, cssClasses, this.label());
    } else {
		  drawTools.appendCircularClass(parentElement, this.actualRadius(), cssClasses, this.label());
    }

		//that.postDrawActions(parentElement);
	}

	actualRadius() {
	  return this._radius;
	}
	width() { return this._width; }
	height() { return this._height; }
	distanceToBorder(dx, dy) { return this.isTriple() ?
	  RectangleTools.distanceToBorder(this, dx, dy) :
	  this.actualRadius();
	}
}

class Link extends Node {
  constructor(node) {
    super(node.getKnot());

    this._subject = getNodeByKnot(this.getKnot().subject);
    this._predicate = getNodeByKnot(this.getKnot().predicate);
    this._object = getNodeByKnot(this.getKnot().object);
    this._triple = getNodeByKnot(this.getKnot());

    this.frontPart = new LinkPart({
      source: this._subject,
      target: this._triple
    });
    this.backPart = new LinkPart({
      source: this._triple,
      target: this._object
    });
  }
  get subject() { return this._subject; }
  get predicate() { return this._predicate; }
  get object() { return this._object; }
  get triple() { return this._triple; }

  //TODO: support loops specially
  isLoop() {
    return this.subject === this.object;
  }
  linkParts() {
    return [this.frontPart, this.backPart];
  }

  draw(linkGroup, markerContainer) {
  	linkGroup.append("path")
  		.classed("link-path", true)
  		//.classed(this.domain().cssClassOfNode(), true)
  		//.classed(this.range().cssClassOfNode(), true)
      //.classed(property.linkType(), true);
  }

  // TODO: if we are self-referencial: compute the number of self references from the graph
  loops() {
    return 3;
  }
}

class LinkPart {
  constructor({ source, target }) {
    this.source = source;
    this.target = target;
  }
}

export default class TripleNotes extends Morph {

  async initialize() {
    this.windowTitle = "Knot Explorer";

    let parentElement = this.get('#graph');
    var width,height;
    var chartWidth, chartHeight;
    var margin;
    var svg = d3.select(parentElement)
      .append("svg");
    var graphContainer = svg.append("g").classed("graphContainer", true);

    setSize();

    let graph = await Graph.getInstance();

    let knots = graph.knots;
    this.updateStatistics(knots);

    let nodes = knots.map(getNodeByKnot);
    let links = nodes
      .filter(node => node.isTriple())
      .map(node => new Link(node));

    let hiddenLinks = [];
		links.forEach(link => hiddenLinks = hiddenLinks.concat(link.linkParts()));

    drawChart.call(this, {
      nodes,
      links,
      hiddenLinks
    });

    lively.addEventListener("triple-notes", this, "extent-changed", e => { setSize(); });

    function setSize() {
      width = parentElement.clientWidth;
      height = parentElement.clientHeight;

      margin = {top:0, left:0, bottom:0, right:0 };

      chartWidth = width - (margin.left+margin.right)
      chartHeight = height - (margin.top+margin.bottom)

      svg
        .attr("width", chartWidth)
        .attr("height", chartHeight)
        .attr("transform", "translate("+[margin.left, margin.top]+")");
    }

    function zoomed() {
      graphContainer.attr("transform", d3.event.transform);
    }

    svg.call(d3.zoom()
			.duration(150)
    	.scaleExtent([MIN_MAGNIFICATION, MAX_MAGNIFICATION])
      .on("zoom", zoomed));

    function drawChart({ nodes, links, hiddenLinks }) {

      // hidden link parts
      let linkPartContainer = graphContainer.append("g").classed("linkPartContainer", true);
      var hiddenLinkElements = linkPartContainer.selectAll("line")
        .data(hiddenLinks).enter()
        .append("line")
        .style("stroke", "black")
        .style("stroke-opacity", 0.1)
        .style("stroke-width", 10);

      // Curved, visible  Links
      let linkContainer = graphContainer.append("g").classed("linkContainer", true);
      let markerContainer = linkContainer.append("defs");
      createPropertyMarker(markerContainer);
      function createPropertyMarker(markerContainer) {
      	var marker = appendBasicMarker(markerContainer);
      	//marker.attr("refX", 12);
          var m1X = -12 ;
          var m1Y = 8 ;
          var m2X = -12;
          var m2Y = -8 ;
      	marker.append("path")
      		//.attr("d", "M0,-8L12,0L0,8Z")
              .attr("d", "M0,0L " + m1X + "," + m1Y + "L" + m2X + "," + m2Y + "L" + 0 + "," + 0 )
      		.classed("basic-triple-link", true);
      }

      function appendBasicMarker(markerContainer) {
      	return markerContainer.append("marker")
      		.datum({})
      		.attr("id", "triple-notes-basic-triple-link")

      		.attr("viewBox", "-14 -10 28 20")
      		.attr("markerWidth",10)
      		.attr("markerHeight", 10)
      		//.attr("markerUnits", "userSpaceOnUse")
      		.attr("orient", "auto");
      }

  		// Draw links
  		let linkGroups = linkContainer.selectAll(".link")
  			.data(links).enter()
  			.append("g")
  			.classed("link", true);

  		linkGroups.each(function (link) {
  		  d3.select(this).attr("marker-end", "url(#triple-notes-basic-triple-link)");
  			link.draw(d3.select(this), markerContainer);
  		});

  		// Select the path for direct access to receive a better performance
      let linkPathElements = linkGroups.selectAll("path");

      let curveFunction = d3.line()
  			.x(function (d) {
  				return d.x;
  			})
  			.y(function (d) {
  				return d.y;
  			})
        .curve(d3.curveNatural);

      // Visible Knots -> Nodes
      let nodeContainer = graphContainer.append("g").classed("nodeContainer", true);
      let nodeElements = nodeContainer.selectAll(".node")
        .data(nodes).enter()
        .append("g")
        .attr("class", "node")
        .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended))
          .on("dblclick", async node => {
            d3.event.stopPropagation();

            let knotView = await lively.openComponentInWindow("knot-view");
            knotView.loadKnotForURL(node.getKnot().url);
          });

      nodeElements.each(function (node) {
  			node.draw(d3.select(this));
      });

      nodeElements.append("text")
        .attr("class", "text")
        .style("text-anchor", "middle")
        .style("alignment-baseline", "middle")
        .text(d => d.label());

      var simulation = d3.forceSimulation()
        .force("link", d3.forceLink().id(d => d.index).distance(200))
        //.force("collide",d3.forceCollide(d => d.r + 8).iterations(16) )
        .force("charge", d3.forceManyBody().strength(node => node.isTriple() ? -190*0.5 : -190))
        .force("center", d3.forceCenter(chartWidth / 2, chartWidth / 2))
        .force("y", d3.forceY(0).strength(0.001))
        .force("x", d3.forceX(0).strength(0.001));

      // Define Simulation
      simulation
        .nodes(nodes)
        .on("tick", function recalculatePositions() {
          nodeElements.attr("transform", d => "translate(" + d.x + "," + d.y + ")");

          hiddenLinkElements
            .attr("x1", d => d.source.x)
            .attr("y1", d => d.source.y)
            .attr("x2", d => d.target.x)
            .attr("y2", d => d.target.y);

      		// Set link paths and calculate additional information
      		linkPathElements.attr("d", function (link) {
      			if (link.isLoop()) {
      				return math.calculateLoopPath(link);
      			}
      			var curvePoint = link.triple;
      			var pathStart = math.calculateIntersection(curvePoint, link.subject, 1);
      			var pathEnd = math.calculateIntersection(curvePoint, link.object, 1);

      			return curveFunction([pathStart, curvePoint, pathEnd]);
          });
        });

      simulation.force("link")
        .links(hiddenLinks);

      function dragstarted(d) {
        if (!d3.event.active) simulation.alphaTarget(0.3).restart();
        d.fx = d.x;
        d.fy = d.y;
      }

      function dragged(d) {
        d.fx = d3.event.x;
        d.fy = d3.event.y;
      }

      function dragended(d) {
        if (!d3.event.active) simulation.alphaTarget(0);
        d.fx = null;
        d.fy = null;
      }

      var linkDistance = this.get('#link-distance');
      linkDistance.addEventListener('change', function () {
        lively.notify('dwdw' +linkDistance.value);
        return;
        document.getElementById('currentValue').innerHtml = slider.value;
        window.resizeTo( slider.value, 400 );

      });
    }
  }

  updateStatistics(knots) {
    this.get('#number-of-knots').innerHTML = knots.length;
    this.get('#number-of-triples').innerHTML = knots.filter(k => k.isTriple()).length;
  }
}<|endoftext|>


<commit_before>'use strict'

module.exports = {
  types: [
    { value: 'feat', name: 'feat:     A new feature' },
    { value: 'fix', name: 'fix:      A bug fix' },
    { value: 'docs', name: 'docs:     Documentation only changes' },
    {
      value: 'style',
      name:
        'style:    Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
    },
    {
      value: 'refactor',
      name: 'refactor: A code change that neither fixes a bug nor adds a feature',
    },
    { value: 'perf', name: 'perf:     A code change that improves performance' },
    { value: 'test', name: 'test:     Adding missing tests' },
    {
      value: 'chore',
      name:
        'chore:    Changes to the build process or auxiliary tools and libraries such as documentation generation',
    },
    { value: 'revert', name: 'revert:   Revert to a commit' },
    { value: 'WIP', name: 'WIP:      Work in progress' },
  ],

  scopes: [
    { name: 'components' },
    { name: 'styles' },
    { name: 'documentation' },
    { name: 'configs' },
  ],

  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix', 'style', 'refactor', 'perf', 'chore'],
}
<commit_msg>chore: 🔮 commit messages<commit_after>'use strict'

module.exports = {
  types: [
    { value: 'feat', name: '🎉 feat:       A new feature' },
    { value: 'fix', name: '👍 fix:        A bug fix' },
    {
      value: 'refactor',
      name:
        '🔩 refactor:   A code change that neither fixes a bug nor adds a feature',
    },
    {
      value: 'test',
      name: '✅ test:       Updating tests or adding missing tests',
    },
    {
      value: 'chore',
      name:
        '⚙  chore:      Changes to the build process, development tools, project configs, etc.',
    },
    { value: 'docs', name: '📝 docs:       Documentation only changes' },
    { value: 'WIP', name: '🚧 wip:        Work in progress' },
    { value: 'revert', name: '↩  revert:     Revert to a commit' },
  ],

  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix', 'style', 'refactor', 'perf', 'chore'],
  scopes: [
    { name: 'components' },
    { name: 'styles' },
    { name: 'documentation' },
    { name: 'configs' },
  ],
}
<|endoftext|>


<commit_before>import pxtorem from 'postcss-pxtorem';

export default {
  "entry": "src/index.js",
  "disableCSSModules": false,
  "publicPath": "/",
  "autoprefixer": {
    "browsers": [
      "iOS >= 8",
      "Android >= 4"
    ]
  },
  "proxy": null,
  "extraPostCSSPlugins": [
    pxtorem({
      rootValue: 100,
      propWhiteList: [],
    }),
  ],
  "extraBabelPlugins": [
    "transform-runtime",
    ["import", { "libraryName": "antd-mobile", "style": true }]
  ],
  "env": {
    "development": {
      "extraBabelPlugins": [
        "dva-hmr"
      ]
    }
  }
};
<commit_msg>chore(roadhog): change file type<commit_after>import pxtorem from 'postcss-pxtorem';

export default {
  'entry': 'src/index.js',
  'disableCSSModules': false,
  'publicPath': '/',
  'autoprefixer': {
    'browsers': [
      'iOS >= 8',
      'Android >= 4'
    ]
  },
  'proxy': null,
  'extraPostCSSPlugins': [
    pxtorem({
      rootValue: 100,
      propWhiteList: [],
    }),
  ],
  'extraBabelPlugins': [
    'transform-runtime',
    ['import', {
      'libraryName': 'antd-mobile',
      'style': true
    }]
  ],
  'env': {
    'development': {
      'extraBabelPlugins': [
        'dva-hmr'
      ]
    }
  }
};
<|endoftext|>