text: 
  //      JointJS library.
  //      (c) 2011-2013 client IO
  
  
  if (typeof exports === 'object') {
  
      var joint = {
          util: require('../src/core').util,
          shapes: {},
          dia: {
              Element: require('../src/joint.dia.element').Element,
              ElementView: require('../src/joint.dia.element').ElementView
          }
      };
      var _ = require('lodash');
  }
  
  
  joint.shapes.basic = {};
  
  
  joint.shapes.basic.Generic = joint.dia.Element.extend({
  
      defaults: joint.util.deepSupplement({
          
          type: 'basic.Generic',
          attrs: {
              '.': { fill: '#FFFFFF', stroke: 'none' }
          }
          
      }, joint.dia.Element.prototype.defaults)
  });
  
  joint.shapes.basic.Rect = joint.shapes.basic.Generic.extend({
  
      markup: '<g class="rotatable"><g class="scalable"><rect/></g><text/></g>',
      
      defaults: joint.util.deepSupplement({
      
          type: 'basic.Rect',
          attrs: {
              'rect': { fill: '#FFFFFF', stroke: 'black', width: 100, height: 60 },
              'text': { 'font-size': 14, text: '', 'ref-x': .5, 'ref-y': .5, ref: 'rect', 'y-alignment': 'middle', 'x-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
          }
          
      }, joint.shapes.basic.Generic.prototype.defaults)
  });
  
  joint.shapes.basic.Text = joint.shapes.basic.Generic.extend({
  
      markup: '<g class="rotatable"><g class="scalable"><text/></g></g>',
      
      defaults: joint.util.deepSupplement({
          
          type: 'basic.Text',
          attrs: {
              'text': { 'font-size': 18, fill: 'black' }
          }
          
      }, joint.shapes.basic.Generic.prototype.defaults)
  });
  
  joint.shapes.basic.Circle = joint.shapes.basic.Generic.extend({
  
      markup: '<g class="rotatable"><g class="scalable"><circle/></g><text/></g>',
      
      defaults: joint.util.deepSupplement({
  
          type: 'basic.Circle',
          size: { width: 60, height: 60 },
          attrs: {
              'circle': { fill: '#FFFFFF', stroke: 'black', r: 30, transform: 'translate(30, 30)' },
              'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-y': .5, ref: 'circle', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
          }
      }, joint.shapes.basic.Generic.prototype.defaults)
  });
  
  joint.shapes.basic.Image = joint.shapes.basic.Generic.extend({
  
      markup: '<g class="rotatable"><g class="scalable"><image/></g><text/></g>',
      
      defaults: joint.util.deepSupplement({
  
          type: 'basic.Image',
          attrs: {
              'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'image', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
          }
      }, joint.shapes.basic.Generic.prototype.defaults)
  });
  
  joint.shapes.basic.Path = joint.shapes.basic.Generic.extend({
  
      markup: '<g class="rotatable"><g class="scalable"><path/></g><text/></g>',
      
      defaults: joint.util.deepSupplement({
  
          type: 'basic.Path',
          size: { width: 60, height: 60 },
          attrs: {
              'path': { fill: '#FFFFFF', stroke: 'black' },
              'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'path', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
          }
      }, joint.shapes.basic.Generic.prototype.defaults)
  });
  
  joint.shapes.basic.Rhombus = joint.shapes.basic.Path.extend({
  
      defaults: joint.util.deepSupplement({
      
          type: 'basic.Rhombus',
          attrs: {
              'path': { d: 'M 30 0 L 60 30 30 60 0 30 z' },
              'text': { 'ref-y': .5 }
          }
          
      }, joint.shapes.basic.Path.prototype.defaults)
  });
  
  
  // PortsModelInterface is a common interface for shapes that have ports. This interface makes it easy
  // to create new shapes with ports functionality. It is assumed that the new shapes have
  // `inPorts` and `outPorts` array properties. Only these properties should be used to set ports.
  // In other words, using this interface, it is no longer recommended to set ports directly through the
  // `attrs` object.
  
  // Usage:
  // joint.shapes.custom.MyElementWithPorts = joint.shapes.basic.Path.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
  //     getPortAttrs: function(portName, index, total, selector, type) {
  //         var attrs = {};
  //         var portClass = 'port' + index;
  //         var portSelector = selector + '>.' + portClass;
  //         var portTextSelector = portSelector + '>text';
  //         var portCircleSelector = portSelector + '>circle';
  //
  //         attrs[portTextSelector] = { text: portName };
  //         attrs[portCircleSelector] = { port: { id: portName || _.uniqueId(type) , type: type } };
  //         attrs[portSelector] = { ref: 'rect', 'ref-y': (index + 0.5) * (1 / total) };
  //
  //         if (selector === '.outPorts') { attrs[portSelector]['ref-dx'] = 0; }
  //
  //         return attrs;
  //     }
  //}));
  joint.shapes.basic.PortsModelInterface = {
  
      initialize: function() {
  
          this.updatePortsAttrs();
          this.on('change:inPorts change:outPorts', this.updatePortsAttrs, this);
  
          // Call the `initialize()` of the parent.
          this.constructor.__super__.constructor.__super__.initialize.apply(this, arguments);
      },
      
      updatePortsAttrs: function(eventName) {
  
          // Delete previously set attributes for ports.
          var currAttrs = this.get('attrs');
          _.each(this._portSelectors, function(selector) {
              if (currAttrs[selector]) delete currAttrs[selector];
          });
          
          // This holds keys to the `attrs` object for all the port specific attribute that
          // we set in this method. This is necessary in order to remove previously set
          // attributes for previous ports.
          this._portSelectors = [];
          
          var attrs = {};
          
          _.each(this.get('inPorts'), function(portName, index, ports) {
              var portAttributes = this.getPortAttrs(portName, index, ports.length, '.inPorts', 'in');
              this._portSelectors = this._portSelectors.concat(_.keys(portAttributes));
              _.extend(attrs, portAttributes);
          }, this);
          
          _.each(this.get('outPorts'), function(portName, index, ports) {
              var portAttributes = this.getPortAttrs(portName, index, ports.length, '.outPorts', 'out');
              this._portSelectors = this._portSelectors.concat(_.keys(portAttributes));
              _.extend(attrs, portAttributes);
          }, this);
  
          // Silently set `attrs` on the cell so that noone knows the attrs have changed. This makes sure
          // that, for example, command manager does not register `change:attrs` command but only
          // the important `change:inPorts`/`change:outPorts` command.
          this.attr(attrs, { silent: true });
          // Manually call the `processPorts()` method that is normally called on `change:attrs` (that we just made silent).
          this.processPorts();
          // Let the outside world (mainly the `ModelView`) know that we're done configuring the `attrs` object.
          this.trigger('process:ports');
      },
  
      getPortSelector: function(name) {
  
          var selector = '.inPorts';
          var index = this.get('inPorts').indexOf(name);
  
          if (index < 0) {
              selector = '.outPorts';
              index = this.get('outPorts').indexOf(name);
  
              if (index < 0) throw new Error("getPortSelector(): Port doesn't exist.");
          }
  
          return selector + '>g:nth-child(' + (index + 1) + ')>circle';
      }
  };
  
  joint.shapes.basic.PortsViewInterface = {
      
      initialize: function() {
  
          // `Model` emits the `process:ports` whenever it's done configuring the `attrs` object for ports.
          this.listenTo(this.model, 'process:ports', this.update);
          
          joint.dia.ElementView.prototype.initialize.apply(this, arguments);
      },
  
      update: function() {
  
          // First render ports so that `attrs` can be applied to those newly created DOM elements
          // in `ElementView.prototype.update()`.
          this.renderPorts();
          joint.dia.ElementView.prototype.update.apply(this, arguments);
      },
  
      renderPorts: function() {
  
          var $inPorts = this.$('.inPorts').empty();
          var $outPorts = this.$('.outPorts').empty();
  
          var portTemplate = _.template(this.model.portMarkup);
  
          _.each(_.filter(this.model.ports, function(p) { return p.type === 'in' }), function(port, index) {
  
              $inPorts.append(V(portTemplate({ id: index, port: port })).node);
          });
          _.each(_.filter(this.model.ports, function(p) { return p.type === 'out' }), function(port, index) {
  
              $outPorts.append(V(portTemplate({ id: index, port: port })).node);
          });
      }
  };
  
  joint.shapes.basic.TextBlock = joint.shapes.basic.Generic.extend({
  
      markup: ['<g class="rotatable"><g class="scalable"><rect/></g><switch>',
  
               // if foreignObject supported
  
               '<foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" class="fobj">',
               '<body xmlns="http://www.w3.org/1999/xhtml"><div/></body>',
               '</foreignObject>',
  
               // else foreignObject is not supported (fallback for IE)
               '<text class="content"/>',
  
               '</switch></g>'].join(''),
  
      defaults: joint.util.deepSupplement({
  
          type: 'basic.TextBlock',
  
          // see joint.css for more element styles
          attrs: {
              rect: {
                  fill: '#ffffff',
                  stroke: '#000000',
                  width: 80,
                  height: 100
              },
              text: {
                  fill: '#000000',
                  'font-size': 14,
                  'font-family': 'Arial, helvetica, sans-serif'
              },
              '.content': {
                  text: '',
                  ref: 'rect',
                  'ref-x': .5,
                  'ref-y': .5,
                  'y-alignment': 'middle',
                  'x-alignment': 'middle'
              }
          },
  
          content: ''
  
      }, joint.shapes.basic.Generic.prototype.defaults),
  
      initialize: function() {
  
          if (typeof SVGForeignObjectElement !== 'undefined') {
  
              // foreignObject supported
              this.setForeignObjectSize(this, this.get('size'));
              this.setDivContent(this, this.get('content'));
              this.listenTo(this, 'change:size', this.setForeignObjectSize);
              this.listenTo(this, 'change:content', this.setDivContent);
  
          }
  
          joint.shapes.basic.Generic.prototype.initialize.apply(this, arguments);
      },
  
      setForeignObjectSize: function(cell, size) {
  
          // Selector `foreignObject' doesn't work accross all browsers, we'r using class selector instead.
          // We have to clone size as we don't want attributes.div.style to be same object as attributes.size.
          cell.attr({
              '.fobj': _.clone(size),
              div: { style: _.clone(size) }
          });
      },
  
      setDivContent: function(cell, content) {
  
          // Append the content to div as html.
          cell.attr({ div : {
              html: content
          }});
      }
  
  });
  
  // TextBlockView implements the fallback for IE when no foreignObject exists and
  // the text needs to be manually broken.
  joint.shapes.basic.TextBlockView = joint.dia.ElementView.extend({
  
      initialize: function() {
  
          joint.dia.ElementView.prototype.initialize.apply(this, arguments);
  
          if (typeof SVGForeignObjectElement === 'undefined') {
  
              this.noSVGForeignObjectElement = true;
  
              this.listenTo(this.model, 'change:content', function(cell) {
                  // avoiding pass of extra paramters
                  this.updateContent(cell);
              });
          }
      },
  
      update: function(cell, renderingOnlyAttrs) {
  
          if (this.noSVGForeignObjectElement) {
  
              var model = this.model;
  
              // Update everything but the content first.
              var noTextAttrs = _.omit(renderingOnlyAttrs || model.get('attrs'), '.content');
              joint.dia.ElementView.prototype.update.call(this, model, noTextAttrs);
  
              if (!renderingOnlyAttrs || _.has(renderingOnlyAttrs, '.content')) {
                  // Update the content itself.
                  this.updateContent(model, renderingOnlyAttrs);
              }
  
          } else {
  
              joint.dia.ElementView.prototype.update.call(this, model, renderingOnlyAttrs);
          }
      },
  
      updateContent: function(cell, renderingOnlyAttrs) {
  
          // Create copy of the text attributes
          var textAttrs = _.merge({}, (renderingOnlyAttrs || cell.get('attrs'))['.content']);
  
          delete textAttrs.text;
  
          // Break the content to fit the element size taking into account the attributes
          // set on the model.
          var text = joint.util.breakText(cell.get('content'), cell.get('size'), textAttrs, {
              // measuring sandbox svg document
              svgDocument: this.paper.svg
          });
  
          // Create a new attrs with same structure as the model attrs { text: { *textAttributes* }}
          var attrs = joint.util.setByPath({}, '.content', textAttrs,'/');
  
          // Replace text attribute with the one we just processed.
          attrs['.content'].text = text;
  
          // Update the view using renderingOnlyAttributes parameter.
          joint.dia.ElementView.prototype.update.call(this, cell, attrs);
      }
  });
  
  if (typeof exports === 'object') {
  
      module.exports = joint.shapes.basic;
  }
  