client/js/paper-renderer.js
changeset 160 408da84d4dc0
parent 159 1796e0220bef
child 161 c7a503c80ef4
equal deleted inserted replaced
159:1796e0220bef 160:408da84d4dc0
    14     _AUTOSCALE_MARGIN: 50,
    14     _AUTOSCALE_MARGIN: 50,
    15     _MOUSEMOVE_RATE: 80,
    15     _MOUSEMOVE_RATE: 80,
    16     _DOUBLETAP_DELAY: 800,
    16     _DOUBLETAP_DELAY: 800,
    17     _DOUBLETAP_DISTANCE: 20*20,
    17     _DOUBLETAP_DISTANCE: 20*20,
    18     _USER_PLACEHOLDER : function(_renkan) {
    18     _USER_PLACEHOLDER : function(_renkan) {
    19     	return {
    19         return {
    20     		color: _renkan.options.default_user_color,
    20             color: _renkan.options.default_user_color,
    21 	        title: _renkan.translate("(unknown user)"),
    21             title: _renkan.translate("(unknown user)"),
    22 	        get: function(attr) {
    22             get: function(attr) {
    23 	            return this[attr] || false;
    23                 return this[attr] || false;
    24 	        }
    24             }
    25     	}
    25         }
    26     },
    26     },
    27     _BOOKMARKLET_CODE: function(_renkan) {
    27     _BOOKMARKLET_CODE: function(_renkan) {
    28     	return "(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='<p_style=\"position:fixed;top:0;right:0;font:bold_18px_sans-serif;color:#fff;background:#909;padding:10px;z-index:100000;\">"
    28         return "(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='<p_style=\"position:fixed;top:0;right:0;font:bold_18px_sans-serif;color:#fff;background:#909;padding:10px;z-index:100000;\">"
    29 	    + _renkan.translate("Drag items from this website, drop them in Renkan").replace(/ /g,"_")
    29         + _renkan.translate("Drag items from this website, drop them in Renkan").replace(/ /g,"_")
    30 	    + "</p>'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\/\\/[^\\/]*twitter\\.com\\//,s:'.tweet',n:'twitter'},{r:/https?:\\/\\/[^\\/]*google\\.[^\\/]+\\//,s:'.g',n:'google'},{r:/https?:\\/\\/[^\\/]*lemonde\\.fr\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();"
    30         + "</p>'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\/\\/[^\\/]*twitter\\.com\\//,s:'.tweet',n:'twitter'},{r:/https?:\\/\\/[^\\/]*google\\.[^\\/]+\\//,s:'.g',n:'google'},{r:/https?:\\/\\/[^\\/]*lemonde\\.fr\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();"
    31     },
    31     },
    32     shortenText : function(_text, _maxlength) {
    32     shortenText : function(_text, _maxlength) {
    33 		return (_text.length > _maxlength ? (_text.substr(0,_maxlength) + '…') : _text);
    33         return (_text.length > _maxlength ? (_text.substr(0,_maxlength) + '…') : _text);
    34 	},
    34     },
    35     drawEditBox : function(_options, _coords, _path, _xmargin, _selector) {
    35     drawEditBox : function(_options, _coords, _path, _xmargin, _selector) {
    36     	_selector.css({
    36         _selector.css({
    37             width: ( _options.tooltip_width - 2* _options.tooltip_padding ),
    37             width: ( _options.tooltip_width - 2* _options.tooltip_padding ),
    38         })
    38         })
    39         var _height = _selector.outerHeight() + 2* _options.tooltip_padding,
    39         var _height = _selector.outerHeight() + 2* _options.tooltip_padding,
    40             _isLeft = (_coords.x < paper.view.center.x ? 1 : -1),
    40             _isLeft = (_coords.x < paper.view.center.x ? 1 : -1),
    41             _left = _coords.x + _isLeft * ( _xmargin + _options.tooltip_arrow_length ),
    41             _left = _coords.x + _isLeft * ( _xmargin + _options.tooltip_arrow_length ),
    91                 _this.redraw();
    91                 _this.redraw();
    92             }
    92             }
    93             this._removeBinding = function() {
    93             this._removeBinding = function() {
    94                 _renderer.removeRepresentation(_this);
    94                 _renderer.removeRepresentation(_this);
    95                 _(function() {
    95                 _(function() {
    96                 	_renderer.redraw()
    96                     _renderer.redraw()
    97             	}).defer();
    97                 }).defer();
    98             }
    98             }
    99             this.model.on("change", this._changeBinding );
    99             this.model.on("change", this._changeBinding );
   100             this.model.on("remove", this._removeBinding );
   100             this.model.on("remove", this._removeBinding );
   101         }
   101         }
   102     }
   102     }
   173     this.type = "Node";
   173     this.type = "Node";
   174     this.circle = new paper.Path.Circle([0, 0], 1);
   174     this.circle = new paper.Path.Circle([0, 0], 1);
   175     this.circle.__representation = this;
   175     this.circle.__representation = this;
   176     this.circle.fillColor = this.options.node_fill_color;
   176     this.circle.fillColor = this.options.node_fill_color;
   177     if (this.options.show_node_circles) {
   177     if (this.options.show_node_circles) {
   178 	    this.circle.strokeWidth = this.options.node_stroke_width;
   178         this.circle.strokeWidth = this.options.node_stroke_width;
   179 	    this.h_ratio = 1;
   179         this.h_ratio = 1;
   180     } else {
   180     } else {
   181     	this.circle.opacity = .01;
   181         this.circle.opacity = .01;
   182     	this.h_ratio = 0;
   182         this.h_ratio = 0;
   183     }
   183     }
   184     this.title = Rkns.$('<div class="Rk-Label">').appendTo(this.renderer.labels_$);
   184     this.title = Rkns.$('<div class="Rk-Label">').appendTo(this.renderer.labels_$);
   185     if (this.options.editor_mode) {
   185     if (this.options.editor_mode) {
   186     	this.buttons = [
   186         this.buttons = [
   187     		new Rkns.Renderer.NodeEditButton(this.renderer, null),
   187             new Rkns.Renderer.NodeEditButton(this.renderer, null),
   188     		new Rkns.Renderer.NodeRemoveButton(this.renderer, null),
   188             new Rkns.Renderer.NodeRemoveButton(this.renderer, null),
   189     		new Rkns.Renderer.NodeLinkButton(this.renderer, null),
   189             new Rkns.Renderer.NodeLinkButton(this.renderer, null),
   190     		new Rkns.Renderer.NodeEnlargeButton(this.renderer, null),
   190             new Rkns.Renderer.NodeEnlargeButton(this.renderer, null),
   191     		new Rkns.Renderer.NodeShrinkButton(this.renderer, null)
   191             new Rkns.Renderer.NodeShrinkButton(this.renderer, null)
   192     	];
   192         ];
   193     	for (var i = 0; i < this.buttons.length; i++) {
   193         for (var i = 0; i < this.buttons.length; i++) {
   194     		this.buttons[i].source_representation = this;
   194             this.buttons[i].source_representation = this;
   195     	}
   195         }
   196     } else {
   196     } else {
   197     	this.buttons = [];
   197         this.buttons = [];
   198     }
   198     }
   199     this.last_circle_radius = 1;
   199     this.last_circle_radius = 1;
   200 //    this.title.paragraphStyle.justification = 'center';
   200 //    this.title.paragraphStyle.justification = 'center';
   201     
   201     
   202     if (this.renderer.minimap) {
   202     if (this.renderer.minimap) {
   203 	    this.renderer.minimap.node_layer.activate();
   203         this.renderer.minimap.node_layer.activate();
   204 	    this.minimap_circle = new paper.Path.Circle([0, 0], 1);
   204         this.minimap_circle = new paper.Path.Circle([0, 0], 1);
   205 	    this.minimap_circle.__representation = this.renderer.minimap.miniframe.__representation;
   205         this.minimap_circle.__representation = this.renderer.minimap.miniframe.__representation;
   206 	    this.renderer.minimap.node_group.addChild(this.minimap_circle);
   206         this.renderer.minimap.node_group.addChild(this.minimap_circle);
   207     }
   207     }
   208 }
   208 }
   209 
   209 
   210 Rkns.Renderer.Node.prototype.redraw = function(_dontRedrawEdges) {
   210 Rkns.Renderer.Node.prototype.redraw = function(_dontRedrawEdges) {
   211     var _model_coords = new paper.Point(this.model.get("position")),
   211     var _model_coords = new paper.Point(this.model.get("position")),
   212     	_baseRadius = this.options.node_size_base * Math.exp((this.model.get("size") || 0) * Rkns.Renderer._NODE_SIZE_STEP);
   212         _baseRadius = this.options.node_size_base * Math.exp((this.model.get("size") || 0) * Rkns.Renderer._NODE_SIZE_STEP);
   213     if (!this.is_dragging || !this.paper_coords) {
   213     if (!this.is_dragging || !this.paper_coords) {
   214         this.paper_coords = this.renderer.toPaperCoords(_model_coords);
   214         this.paper_coords = this.renderer.toPaperCoords(_model_coords);
   215     }
   215     }
   216     this.circle_radius = _baseRadius * this.renderer.scale;
   216     this.circle_radius = _baseRadius * this.renderer.scale;
   217     if (this.last_circle_radius !== this.circle_radius) {
   217     if (this.last_circle_radius !== this.circle_radius) {
   218     	this.buttons.forEach(function(b) {
   218         this.buttons.forEach(function(b) {
   219     		b.setSectorSize();
   219             b.setSectorSize();
   220     	});
   220         });
   221 	    var square = new paper.Size(this.circle_radius, this.circle_radius),
   221         var square = new paper.Size(this.circle_radius, this.circle_radius),
   222 	    	topleft = this.paper_coords.subtract(square),
   222             topleft = this.paper_coords.subtract(square),
   223 	    	bounds = new paper.Rectangle(topleft, square.multiply(2));
   223             bounds = new paper.Rectangle(topleft, square.multiply(2));
   224     	this.circle.fitBounds(bounds);
   224         this.circle.fitBounds(bounds);
   225 	    if (this.node_image) {
   225         if (this.node_image) {
   226 	    	this.node_image.fitBounds(bounds);
   226             this.node_image.fitBounds(bounds);
   227 	    }
   227         }
   228     } else {
   228     } else {
   229     	this.circle.position = this.paper_coords;
   229         this.circle.position = this.paper_coords;
   230     	if (this.node_image) {
   230         if (this.node_image) {
   231             this.node_image.position = this.paper_coords;
   231             this.node_image.position = this.paper_coords;
   232         }
   232         }
   233     }
   233     }
   234     this.last_circle_radius = this.circle_radius;
   234     this.last_circle_radius = this.circle_radius;
   235     
   235     
   236     var _text = this.model.get("title") || this.renkan.translate(this.options.label_untitled_nodes) || "";
   236     var _text = this.model.get("title") || this.renkan.translate(this.options.label_untitled_nodes) || "";
   237 	_text = Rkns.Renderer.shortenText(_text, this.options.node_label_max_length);
   237     _text = Rkns.Renderer.shortenText(_text, this.options.node_label_max_length);
   238 	this.title.text(_text);
   238     this.title.text(_text);
   239 	this.title.css({
   239     this.title.css({
   240 		left: this.paper_coords.x,
   240         left: this.paper_coords.x,
   241 		top: this.paper_coords.y + this.circle_radius * this.h_ratio + this.options.node_label_distance
   241         top: this.paper_coords.y + this.circle_radius * this.h_ratio + this.options.node_label_distance
   242 	})
   242     })
   243     var _color = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color");
   243     var _color = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color");
   244     this.circle.strokeColor = _color;
   244     this.circle.strokeColor = _color;
   245     var _pc = this.paper_coords;
   245     var _pc = this.paper_coords;
   246 	this.buttons.forEach(function(b) {
   246     this.buttons.forEach(function(b) {
   247 		b.moveTo(_pc);
   247         b.moveTo(_pc);
   248 	});
   248     });
   249     var _img = this.model.get("image");
   249     var _img = this.model.get("image");
   250     if (_img && _img !== this.img) {
   250     if (_img && _img !== this.img) {
   251         var _image = new Image(),
   251         var _image = new Image(),
   252             _this = this;
   252             _this = this;
   253         _image.onload = function() {
   253         _image.onload = function() {
   255                 _this.node_image.remove();
   255                 _this.node_image.remove();
   256             }
   256             }
   257             _this.renderer.node_layer.activate();
   257             _this.renderer.node_layer.activate();
   258             var _ratio = Math.min(2 / _image.width, 2 / _image.height );
   258             var _ratio = Math.min(2 / _image.width, 2 / _image.height );
   259             if (!_this.options.show_node_circles) {
   259             if (!_this.options.show_node_circles) {
   260             	_this.h_ratio = Math.min(1, _image.height / _image.width);
   260                 _this.h_ratio = Math.min(1, _image.height / _image.width);
   261             }
   261             }
   262             var _raster = new paper.Raster(_image);
   262             var _raster = new paper.Raster(_image);
   263             if (_this.options.clip_node_images) {
   263             if (_this.options.clip_node_images) {
   264 	            var _clip = new paper.Path.Circle([0, 0], 1);
   264                 var _clip = new paper.Path.Circle([0, 0], 1);
   265 	            _raster.scale(_ratio);
   265                 _raster.scale(_ratio);
   266 	            _this.node_image = new paper.Group(_clip, _raster);
   266                 _this.node_image = new paper.Group(_clip, _raster);
   267 	            _this.node_image.opacity = .99;
   267                 _this.node_image.opacity = .99;
   268 	            /* This is a workaround to allow clipping at group level
   268                 /* This is a workaround to allow clipping at group level
   269 	             * If opacity was set to 1, paper.js would merge all clipping groups in one (known bug).
   269                  * If opacity was set to 1, paper.js would merge all clipping groups in one (known bug).
   270 	            */
   270                 */
   271 	            _this.node_image.clipped = true;
   271                 _this.node_image.clipped = true;
   272             	_clip.__representation = _this;
   272                 _clip.__representation = _this;
   273             } else {
   273             } else {
   274             	_this.node_image = _raster;
   274                 _this.node_image = _raster;
   275             }
   275             }
   276             _this.node_image.__representation = _this;
   276             _this.node_image.__representation = _this;
   277 		    var square = new paper.Size(_this.circle_radius, _this.circle_radius),
   277             var square = new paper.Size(_this.circle_radius, _this.circle_radius),
   278 		    	topleft = _this.paper_coords.subtract(square),
   278                 topleft = _this.paper_coords.subtract(square),
   279 		    	bounds = new paper.Rectangle(topleft, square.multiply(2));
   279                 bounds = new paper.Rectangle(topleft, square.multiply(2));
   280 		    _this.node_image.fitBounds(bounds);
   280             _this.node_image.fitBounds(bounds);
   281             _this.redraw();
   281             _this.redraw();
   282     		paper.view.draw();
   282             paper.view.draw();
   283         }
   283         }
   284         _image.src = _img;
   284         _image.src = _img;
   285     }
   285     }
   286     this.img = _img;
   286     this.img = _img;
   287     if (this.node_image && !this.img) {
   287     if (this.node_image && !this.img) {
   288         this.node_image.remove();
   288         this.node_image.remove();
   289         delete this.node_image;
   289         delete this.node_image;
   290     }
   290     }
   291     
   291     
   292     if (this.renderer.minimap) {
   292     if (this.renderer.minimap) {
   293 	    this.minimap_circle.fillColor = _color;
   293         this.minimap_circle.fillColor = _color;
   294 	    var minipos = this.renderer.toMinimapCoords(_model_coords),
   294         var minipos = this.renderer.toMinimapCoords(_model_coords),
   295 	    	miniradius = this.renderer.minimap.scale * _baseRadius,
   295             miniradius = this.renderer.minimap.scale * _baseRadius,
   296 	    	minisize = new paper.Size([miniradius, miniradius]);
   296             minisize = new paper.Size([miniradius, miniradius]);
   297 	    this.minimap_circle.fitBounds(minipos.subtract(minisize), minisize.multiply(2));
   297         this.minimap_circle.fitBounds(minipos.subtract(minisize), minisize.multiply(2));
   298     }
   298     }
   299     
   299     
   300     if (!_dontRedrawEdges) {
   300     if (!_dontRedrawEdges) {
   301     	Rkns._.each(this.project.get("edges").filter(function (ed) { return ((ed.to === this.model) || (ed.from === this.model));}), function(edge, index, list){
   301         Rkns._.each(this.project.get("edges").filter(function (ed) { return ((ed.to === this.model) || (ed.from === this.model));}), function(edge, index, list){
   302 	        var repr = this.renderer.getRepresentationByModel(edge);
   302             var repr = this.renderer.getRepresentationByModel(edge);
   303 	    	if(repr != null && typeof repr.from_representation.paper_coords !== "undefined" && typeof repr.to_representation.paper_coords !== "undefined") {
   303             if(repr != null && typeof repr.from_representation.paper_coords !== "undefined" && typeof repr.to_representation.paper_coords !== "undefined") {
   304 	    		repr.redraw();
   304                 repr.redraw();
   305 	    	}
   305             }
   306 	    }, this);
   306         }, this);
   307     }
   307     }
   308 
   308 
   309 }
   309 }
   310 
   310 
   311 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
   311 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
   312 	if (this.options.editor_mode) {
   312     if (this.options.editor_mode) {
   313 		if (!this.renkan.read_only) {
   313         if (!this.renkan.read_only) {
   314 			this.is_dragging = true;
   314             this.is_dragging = true;
   315 			this.paper_coords = this.paper_coords.add(_delta);
   315             this.paper_coords = this.paper_coords.add(_delta);
   316 	    	this.redraw();
   316             this.redraw();
   317     	}
   317         }
   318 	} else {
   318     } else {
   319 		this.renderer.paperShift(_delta);
   319         this.renderer.paperShift(_delta);
   320 	}
   320     }
   321 }
   321 }
   322 
   322 
   323 Rkns.Renderer.Node.prototype.openEditor = function() {
   323 Rkns.Renderer.Node.prototype.openEditor = function() {
   324     this.renderer.removeRepresentationsOfType("editor");
   324     this.renderer.removeRepresentationsOfType("editor");
   325     var _editor = this.renderer.addRepresentation("NodeEditor",null);
   325     var _editor = this.renderer.addRepresentation("NodeEditor",null);
   326     _editor.source_representation = this;
   326     _editor.source_representation = this;
   327     _editor.draw();
   327     _editor.draw();
   328 }
   328 }
   329 
   329 
   330 Rkns.Renderer.Node.prototype.select = function() {
   330 Rkns.Renderer.Node.prototype.select = function() {
   331 	this.selected = true;
   331     this.selected = true;
   332     this.circle.strokeWidth = this.options.selected_node_stroke_width;
   332     this.circle.strokeWidth = this.options.selected_node_stroke_width;
   333     if (this.renderer.isEditable()) {
   333     if (this.renderer.isEditable()) {
   334     	this.buttons.forEach(function(b) {
   334         this.buttons.forEach(function(b) {
   335     		b.show();
   335             b.show();
   336     	});
   336         });
   337     }
   337     }
   338     var _uri = this.model.get("uri");
   338     var _uri = this.model.get("uri");
   339     if (_uri) {
   339     if (_uri) {
   340     	Rkns.$('.Rk-Bin-Item').each(function() {
   340         Rkns.$('.Rk-Bin-Item').each(function() {
   341 	        var _el = Rkns.$(this);
   341             var _el = Rkns.$(this);
   342 	        if (_el.attr("data-uri") == _uri) {
   342             if (_el.attr("data-uri") == _uri) {
   343 	            _el.addClass("selected");
   343                 _el.addClass("selected");
   344 	        }
   344             }
   345 	    });
   345         });
   346     }
   346     }
   347     if (!this.options.editor_mode) {
   347     if (!this.options.editor_mode) {
   348         this.openEditor();
   348         this.openEditor();
   349     }
   349     }
   350     
   350     
   351     if (this.renderer.minimap) {
   351     if (this.renderer.minimap) {
   352 		this.minimap_circle.strokeWidth = this.options.minimap_highlight_weight;
   352         this.minimap_circle.strokeWidth = this.options.minimap_highlight_weight;
   353     	this.minimap_circle.strokeColor = this.options.minimap_highlight_color;
   353         this.minimap_circle.strokeColor = this.options.minimap_highlight_color;
   354     }
   354     }
   355 }
   355 }
   356 
   356 
   357 Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
   357 Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
   358 	this.selected = false;
   358     this.selected = false;
   359     if (!_newTarget || _newTarget.source_representation !== this) {
   359     if (!_newTarget || _newTarget.source_representation !== this) {
   360     	this.buttons.forEach(function(b) {
   360         this.buttons.forEach(function(b) {
   361     		b.hide();
   361             b.hide();
   362     	});
   362         });
   363     	this.circle.strokeWidth = this.options.node_stroke_width;
   363         this.circle.strokeWidth = this.options.node_stroke_width;
   364         Rkns.$('.Rk-Bin-Item').removeClass("selected");
   364         Rkns.$('.Rk-Bin-Item').removeClass("selected");
   365     	if (this.renderer.minimap) {
   365         if (this.renderer.minimap) {
   366     		this.minimap_circle.strokeColor = undefined;
   366             this.minimap_circle.strokeColor = undefined;
   367     	}
   367         }
   368     }
   368     }
   369 }
   369 }
   370 	
   370     
   371 Rkns.Renderer.Node.prototype.highlight = function() {
   371 Rkns.Renderer.Node.prototype.highlight = function() {
   372     this.circle.fillColor = this.options.highlighted_node_fill_color;
   372     this.circle.fillColor = this.options.highlighted_node_fill_color;
   373     if (this.node_image) {
   373     if (this.node_image) {
   374         this.node_image.opacity = .5;
   374         this.node_image.opacity = .5;
   375     }
   375     }
   389                 x: _coords.x,
   389                 x: _coords.x,
   390                 y: _coords.y
   390                 y: _coords.y
   391             }
   391             }
   392         };
   392         };
   393     if (this.renderer.isEditable()) {
   393     if (this.renderer.isEditable()) {
   394     	this.model.set(_data);
   394         this.model.set(_data);
   395     }
   395     }
   396 }
   396 }
   397 
   397 
   398 Rkns.Renderer.Node.prototype.mousedown = function(_event, _isTouch) {
   398 Rkns.Renderer.Node.prototype.mousedown = function(_event, _isTouch) {
   399 	if (_isTouch) {
   399     if (_isTouch) {
   400 		this.renderer.unselectAll();
   400         this.renderer.unselectAll();
   401 		this.select();
   401         this.select();
   402 	}
   402     }
   403 }
   403 }
   404 
   404 
   405 Rkns.Renderer.Node.prototype.mouseup = function(_event, _isTouch) {
   405 Rkns.Renderer.Node.prototype.mouseup = function(_event, _isTouch) {
   406     if (this.renderer.isEditable() && this.renderer.is_dragging) {
   406     if (this.renderer.isEditable() && this.renderer.is_dragging) {
   407         this.saveCoords();
   407         this.saveCoords();
   408     } else {
   408     } else {
   409     	if (!_isTouch) {
   409         if (!_isTouch) {
   410     		this.openEditor();
   410             this.openEditor();
   411     	}
   411         }
   412     }
   412     }
   413     this.renderer.click_target = null;
   413     this.renderer.click_target = null;
   414     this.renderer.is_dragging = false;
   414     this.renderer.is_dragging = false;
   415     this.is_dragging = false;
   415     this.is_dragging = false;
   416 }
   416 }
   417 
   417 
   418 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   418 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   419     this.super("destroy");
   419     this.super("destroy");
   420 	this.buttons.forEach(function(b) {
   420     this.buttons.forEach(function(b) {
   421 		b.destroy();
   421         b.destroy();
   422 	});
   422     });
   423     this.circle.remove();
   423     this.circle.remove();
   424     this.title.remove();
   424     this.title.remove();
   425     if (this.renderer.minimap) {
   425     if (this.renderer.minimap) {
   426     	this.minimap_circle.remove();
   426         this.minimap_circle.remove();
   427     }
   427     }
   428     if (this.node_image) {
   428     if (this.node_image) {
   429         this.node_image.remove();
   429         this.node_image.remove();
   430     }
   430     }
   431 }
   431 }
   444     this.line.add([0,0],[0,0],[0,0]);
   444     this.line.add([0,0],[0,0],[0,0]);
   445     this.line.__representation = this;
   445     this.line.__representation = this;
   446     this.line.strokeWidth = this.options.edge_stroke_width;
   446     this.line.strokeWidth = this.options.edge_stroke_width;
   447     this.arrow = new paper.Path();
   447     this.arrow = new paper.Path();
   448     this.arrow.add(
   448     this.arrow.add(
   449     	[ 0, 0 ],
   449         [ 0, 0 ],
   450     	[ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],
   450         [ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],
   451     	[ 0, this.options.edge_arrow_width ]
   451         [ 0, this.options.edge_arrow_width ]
   452 	);
   452     );
   453     this.arrow.__representation = this;
   453     this.arrow.__representation = this;
   454     this.text = Rkns.$('<div class="Rk-Label Rk-Edge-Label">').appendTo(this.renderer.labels_$);
   454     this.text = Rkns.$('<div class="Rk-Label Rk-Edge-Label">').appendTo(this.renderer.labels_$);
   455     this.arrow_angle = 0;
   455     this.arrow_angle = 0;
   456     if (this.options.editor_mode) {
   456     if (this.options.editor_mode) {
   457         this.edit_button = new Rkns.Renderer.EdgeEditButton(this.renderer, null);
   457         this.edit_button = new Rkns.Renderer.EdgeEditButton(this.renderer, null);
   459         this.remove_button = new Rkns.Renderer.EdgeRemoveButton(this.renderer, null);
   459         this.remove_button = new Rkns.Renderer.EdgeRemoveButton(this.renderer, null);
   460         this.remove_button.source_representation = this;
   460         this.remove_button.source_representation = this;
   461     }
   461     }
   462     
   462     
   463     if (this.renderer.minimap) {
   463     if (this.renderer.minimap) {
   464     	this.renderer.minimap.edge_layer.activate();
   464         this.renderer.minimap.edge_layer.activate();
   465 	    this.minimap_line = new paper.Path();
   465         this.minimap_line = new paper.Path();
   466 	    this.minimap_line.add([0,0],[0,0]);
   466         this.minimap_line.add([0,0],[0,0]);
   467 	    this.minimap_line.__representation = this.renderer.minimap.miniframe.__representation;
   467         this.minimap_line.__representation = this.renderer.minimap.miniframe.__representation;
   468 	    this.minimap_line.strokeWidth = 1;
   468         this.minimap_line.strokeWidth = 1;
   469     }
   469     }
   470 }
   470 }
   471 
   471 
   472 Rkns.Renderer.Edge.prototype.redraw = function() {
   472 Rkns.Renderer.Edge.prototype.redraw = function() {
   473     this.from_representation = this.renderer.getRepresentationByModel(this.model.get("from"));
   473     this.from_representation = this.renderer.getRepresentationByModel(this.model.get("from"));
   474     this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
   474     this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
   475     if (!this.from_representation || !this.to_representation) {
   475     if (!this.from_representation || !this.to_representation) {
   476     	return;
   476         return;
   477     }
   477     }
   478     var _p0a = this.from_representation.paper_coords,
   478     var _p0a = this.from_representation.paper_coords,
   479         _p1a = this.to_representation.paper_coords,
   479         _p1a = this.to_representation.paper_coords,
   480         _v = _p1a.subtract(_p0a),
   480         _v = _p1a.subtract(_p0a),
   481         _r = _v.length,
   481         _r = _v.length,
   507     if (_a < -90) {
   507     if (_a < -90) {
   508         _a += 180;
   508         _a += 180;
   509         _textdelta = _textdelta.multiply(-1);
   509         _textdelta = _textdelta.multiply(-1);
   510     }
   510     }
   511     var _text = this.model.get("title") || this.renkan.translate(this.options.label_untitled_edges) || "";
   511     var _text = this.model.get("title") || this.renkan.translate(this.options.label_untitled_edges) || "";
   512 	_text = Rkns.Renderer.shortenText(_text, this.options.node_label_max_length);
   512     _text = Rkns.Renderer.shortenText(_text, this.options.node_label_max_length);
   513     this.text.text(_text);
   513     this.text.text(_text);
   514     var _textpos = this.paper_coords.add(_textdelta);
   514     var _textpos = this.paper_coords.add(_textdelta);
   515     this.text.css({
   515     this.text.css({
   516     	left: _textpos.x,
   516         left: _textpos.x,
   517     	top: _textpos.y,
   517         top: _textpos.y,
   518     	transform: "rotate(" + _a + "deg)",
   518         transform: "rotate(" + _a + "deg)",
   519     	"-moz-transform": "rotate(" + _a + "deg)",
   519         "-moz-transform": "rotate(" + _a + "deg)",
   520     	"-webkit-transform": "rotate(" + _a + "deg)"
   520         "-webkit-transform": "rotate(" + _a + "deg)"
   521     });
   521     });
   522     this.text_angle = _a;
   522     this.text_angle = _a;
   523     if (this.options.editor_mode) {
   523     if (this.options.editor_mode) {
   524 	    this.edit_button.moveTo(this.paper_coords);
   524         this.edit_button.moveTo(this.paper_coords);
   525 	    this.remove_button.moveTo(this.paper_coords);
   525         this.remove_button.moveTo(this.paper_coords);
   526     }
   526     }
   527     
   527     
   528     if (this.renderer.minimap) {
   528     if (this.renderer.minimap) {
   529 	    this.minimap_line.strokeColor = _color;
   529         this.minimap_line.strokeColor = _color;
   530 	    this.minimap_line.segments[0].point = this.renderer.toMinimapCoords(new paper.Point(this.from_representation.model.get("position")));
   530         this.minimap_line.segments[0].point = this.renderer.toMinimapCoords(new paper.Point(this.from_representation.model.get("position")));
   531  	    this.minimap_line.segments[1].point = this.renderer.toMinimapCoords(new paper.Point(this.to_representation.model.get("position")));
   531          this.minimap_line.segments[1].point = this.renderer.toMinimapCoords(new paper.Point(this.to_representation.model.get("position")));
   532     }
   532     }
   533 }
   533 }
   534 
   534 
   535 Rkns.Renderer.Edge.prototype.openEditor = function() {
   535 Rkns.Renderer.Edge.prototype.openEditor = function() {
   536     this.renderer.removeRepresentationsOfType("editor");
   536     this.renderer.removeRepresentationsOfType("editor");
   538     _editor.source_representation = this;
   538     _editor.source_representation = this;
   539     _editor.draw();
   539     _editor.draw();
   540 }
   540 }
   541 
   541 
   542 Rkns.Renderer.Edge.prototype.select = function() {
   542 Rkns.Renderer.Edge.prototype.select = function() {
   543 	this.selected = true;
   543     this.selected = true;
   544     this.line.strokeWidth = this.options.selected_edge_stroke_width;
   544     this.line.strokeWidth = this.options.selected_edge_stroke_width;
   545     if (this.renderer.isEditable()) {
   545     if (this.renderer.isEditable()) {
   546 	    this.edit_button.show();
   546         this.edit_button.show();
   547 	    this.remove_button.show();
   547         this.remove_button.show();
   548    	}
   548        }
   549     if (!this.options.editor_mode) {
   549     if (!this.options.editor_mode) {
   550         this.openEditor();
   550         this.openEditor();
   551     }
   551     }
   552 }
   552 }
   553 
   553 
   554 Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) {
   554 Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) {
   555 	this.selected = false;
   555     this.selected = false;
   556     if (!_newTarget || _newTarget.source_representation !== this) {
   556     if (!_newTarget || _newTarget.source_representation !== this) {
   557     	if (this.options.editor_mode) {
   557         if (this.options.editor_mode) {
   558 	        this.edit_button.hide();
   558             this.edit_button.hide();
   559 	        this.remove_button.hide();
   559             this.remove_button.hide();
   560         }
   560         }
   561         this.line.strokeWidth = this.options.edge_stroke_width;
   561         this.line.strokeWidth = this.options.edge_stroke_width;
   562     }
   562     }
   563 }
   563 }
   564 
   564 
   565 Rkns.Renderer.Edge.prototype.mousedown = function(_event, _isTouch) {
   565 Rkns.Renderer.Edge.prototype.mousedown = function(_event, _isTouch) {
   566 	if (_isTouch) {
   566     if (_isTouch) {
   567 		this.renderer.unselectAll();
   567         this.renderer.unselectAll();
   568 		this.select();
   568         this.select();
   569 	}
   569     }
   570 }
   570 }
   571 
   571 
   572 Rkns.Renderer.Edge.prototype.mouseup = function(_event, _isTouch) {
   572 Rkns.Renderer.Edge.prototype.mouseup = function(_event, _isTouch) {
   573     if (!this.renkan.read_only && this.renderer.is_dragging) {
   573     if (!this.renkan.read_only && this.renderer.is_dragging) {
   574         this.from_representation.saveCoords();
   574         this.from_representation.saveCoords();
   575         this.to_representation.saveCoords();
   575         this.to_representation.saveCoords();
   576         this.from_representation.is_dragging = false;
   576         this.from_representation.is_dragging = false;
   577         this.to_representation.is_dragging = false;
   577         this.to_representation.is_dragging = false;
   578     } else {
   578     } else {
   579     	if (!_isTouch) {
   579         if (!_isTouch) {
   580     		this.openEditor();
   580             this.openEditor();
   581     	}
   581         }
   582 	}
   582     }
   583     this.renderer.click_target = null;
   583     this.renderer.click_target = null;
   584     this.renderer.is_dragging = false;
   584     this.renderer.is_dragging = false;
   585 }
   585 }
   586 
   586 
   587 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
   587 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
   588 	if (this.options.editor_mode) {
   588     if (this.options.editor_mode) {
   589 		if (!this.options.read_only) {
   589         if (!this.options.read_only) {
   590 		    this.from_representation.paperShift(_delta);
   590             this.from_representation.paperShift(_delta);
   591 		    this.to_representation.paperShift(_delta);
   591             this.to_representation.paperShift(_delta);
   592 	    }
   592         }
   593 	} else {
   593     } else {
   594 		this.renderer.paperShift(_delta);
   594         this.renderer.paperShift(_delta);
   595 	}
   595     }
   596 }
   596 }
   597 
   597 
   598 Rkns.Renderer.Edge.prototype.destroy = function() {
   598 Rkns.Renderer.Edge.prototype.destroy = function() {
   599     this.super("destroy");
   599     this.super("destroy");
   600     this.line.remove();
   600     this.line.remove();
   601     this.arrow.remove();
   601     this.arrow.remove();
   602     this.text.remove();
   602     this.text.remove();
   603     if (this.renderer.minimap) {
   603     if (this.renderer.minimap) {
   604    	    this.minimap_line.remove();
   604         this.minimap_line.remove();
   605     }
   605     }
   606     if (this.options.editor_mode) {
   606     if (this.options.editor_mode) {
   607 	    this.edit_button.destroy();
   607         this.edit_button.destroy();
   608 	    this.remove_button.destroy();
   608         this.remove_button.destroy();
   609    	}
   609     }
   610     var _this = this;
   610     var _this = this;
   611     this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
   611     this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
   612         return _edge === _this;
   612         return _edge === _this;
   613     });
   613     });
   614 }
   614 }
   629     this.line.add([0,0],[0,0]);
   629     this.line.add([0,0],[0,0]);
   630     this.line.__representation = this;
   630     this.line.__representation = this;
   631     this.arrow = new paper.Path();
   631     this.arrow = new paper.Path();
   632     this.arrow.fillColor = _color;
   632     this.arrow.fillColor = _color;
   633     this.arrow.add(
   633     this.arrow.add(
   634     	[ 0, 0 ],
   634         [ 0, 0 ],
   635     	[ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],
   635         [ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],
   636     	[ 0, this.options.edge_arrow_width ]
   636         [ 0, this.options.edge_arrow_width ]
   637 	);
   637     );
   638     this.arrow.__representation = this;
   638     this.arrow.__representation = this;
   639     this.arrow_angle = 0;
   639     this.arrow_angle = 0;
   640 }
   640 }
   641 
   641 
   642 Rkns.Renderer.TempEdge.prototype.redraw = function() {
   642 Rkns.Renderer.TempEdge.prototype.redraw = function() {
   650     this.arrow.position = _c;
   650     this.arrow.position = _c;
   651     this.arrow_angle = _a;
   651     this.arrow_angle = _a;
   652 }
   652 }
   653 
   653 
   654 Rkns.Renderer.TempEdge.prototype.paperShift = function(_delta) {
   654 Rkns.Renderer.TempEdge.prototype.paperShift = function(_delta) {
   655 	if (!this.renderer.isEditable()) {
   655     if (!this.renderer.isEditable()) {
   656 		this.renderer.removeRepresentation(_this);
   656         this.renderer.removeRepresentation(_this);
   657     	paper.view.draw();
   657         paper.view.draw();
   658     	return;
   658         return;
   659 	}
   659     }
   660     this.end_pos = this.end_pos.add(_delta);
   660     this.end_pos = this.end_pos.add(_delta);
   661     var _hitResult = paper.project.hitTest(this.end_pos);
   661     var _hitResult = paper.project.hitTest(this.end_pos);
   662     this.renderer.findTarget(_hitResult);
   662     this.renderer.findTarget(_hitResult);
   663     this.redraw();
   663     this.redraw();
   664 }
   664 }
   668         _model = this.from_representation.model,
   668         _model = this.from_representation.model,
   669         _endDrag = true;
   669         _endDrag = true;
   670     if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
   670     if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
   671         var _target = _hitResult.item.__representation;
   671         var _target = _hitResult.item.__representation;
   672         if (_target.type.substr(0,4) === "Node") {
   672         if (_target.type.substr(0,4) === "Node") {
   673         	var _destmodel = _target.model || _target.source_representation.model;
   673             var _destmodel = _target.model || _target.source_representation.model;
   674         	if (_model !== _destmodel) {
   674             if (_model !== _destmodel) {
   675 	            var _data = {
   675                 var _data = {
   676 	                id: Rkns.Utils.getUID('edge'),
   676                     id: Rkns.Utils.getUID('edge'),
   677 	                created_by: this.renkan.current_user,
   677                     created_by: this.renkan.current_user,
   678 	                from: _model,
   678                     from: _model,
   679 	                to: _destmodel
   679                     to: _destmodel
   680 	            };
   680                 };
   681 	            if (this.renderer.isEditable()) {
   681                 if (this.renderer.isEditable()) {
   682 	            	this.project.addEdge(_data);
   682                     this.project.addEdge(_data);
   683 	            }
   683                 }
   684 	        }
   684             }
   685         }
   685         }
   686         
   686         
   687         if (_model === _target.model || (_target.source_representation && _target.source_representation.model === _model)) {
   687         if (_model === _target.model || (_target.source_representation && _target.source_representation.model === _model)) {
   688             _endDrag = false;
   688             _endDrag = false;
   689             this.renderer.is_dragging = true;
   689             this.renderer.is_dragging = true;
   745         _image_placeholder = this.options.static_url + "img/image-placeholder.png",
   745         _image_placeholder = this.options.static_url + "img/image-placeholder.png",
   746         _size = (_model.get("size") || 0);
   746         _size = (_model.get("size") || 0);
   747     this.editor_$
   747     this.editor_$
   748         .html(_template({
   748         .html(_template({
   749             node: {
   749             node: {
   750             	has_creator: !!_model.get("created_by"),
   750                 has_creator: !!_model.get("created_by"),
   751                 title: _model.get("title"),
   751                 title: _model.get("title"),
   752                 uri: _model.get("uri"),
   752                 uri: _model.get("uri"),
   753                 short_uri:  Rkns.Renderer.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40),
   753                 short_uri:  Rkns.Renderer.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40),
   754                 description: _model.get("description"),
   754                 description: _model.get("description"),
   755                 image: _model.get("image") || "",
   755                 image: _model.get("image") || "",
   761             },
   761             },
   762             renkan: this.renkan
   762             renkan: this.renkan
   763         }));
   763         }));
   764     this.redraw();
   764     this.redraw();
   765     var _this = this,
   765     var _this = this,
   766     	closeEditor = function() {
   766         closeEditor = function() {
   767     		_this.renderer.removeRepresentation(_this);
   767             _this.renderer.removeRepresentation(_this);
   768         	paper.view.draw();
   768             paper.view.draw();
   769     	}
   769         }
   770     	
   770         
   771     this.editor_$.find(".Rk-CloseX").click(closeEditor);
   771     this.editor_$.find(".Rk-CloseX").click(closeEditor);
   772     
   772     
   773     if (this.renderer.isEditable()) {
   773     if (this.renderer.isEditable()) {
   774     	
   774         
   775     	var onFieldChange = Rkns._(function() {
   775         var onFieldChange = Rkns._(function() {
   776     		Rkns._(function() {
   776             Rkns._(function() {
   777 	            if (_this.renderer.isEditable()) {
   777                 if (_this.renderer.isEditable()) {
   778 		            var _uri = _this.editor_$.find(".Rk-Edit-URI").val(),
   778                     var _uri = _this.editor_$.find(".Rk-Edit-URI").val(),
   779 		                _image = _this.editor_$.find(".Rk-Edit-Image").val();
   779                         _image = _this.editor_$.find(".Rk-Edit-Image").val();
   780 		            _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _image || _image_placeholder);
   780                     _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _image || _image_placeholder);
   781 		            _this.editor_$.find(".Rk-Edit-Goto").attr("href",_uri);
   781                     _this.editor_$.find(".Rk-Edit-Goto").attr("href",_uri);
   782 		            var _data = {
   782                     var _data = {
   783 		                title: _this.editor_$.find(".Rk-Edit-Title").val(),
   783                         title: _this.editor_$.find(".Rk-Edit-Title").val(),
   784 		                description: _this.editor_$.find(".Rk-Edit-Description").val(),
   784                         description: _this.editor_$.find(".Rk-Edit-Description").val(),
   785 		                uri: _uri,
   785                         uri: _uri,
   786 		                image: _image
   786                         image: _image
   787 		            }
   787                     }
   788 	            	_model.set(_data);
   788                     _model.set(_data);
   789 	            	_this.redraw();
   789                     _this.redraw();
   790 	            } else {
   790                 } else {
   791 	            	closeEditor();
   791                     closeEditor();
   792 	            }
   792                 }
   793 	            
   793                 
   794     		}).defer();
   794             }).defer();
   795     	}).throttle(500);
   795         }).throttle(500);
   796     	
   796         
   797     	this.editor_$.on("keyup", function(_e) {
   797         this.editor_$.on("keyup", function(_e) {
   798     		if (_e.keyCode === 27) {
   798             if (_e.keyCode === 27) {
   799     			closeEditor();
   799                 closeEditor();
   800     		}
   800             }
   801     	});
   801         });
   802     	
   802         
   803     	this.editor_$.find("input, textarea").on("change keyup paste", onFieldChange);
   803         this.editor_$.find("input, textarea").on("change keyup paste", onFieldChange);
   804     	
   804         
   805         this.editor_$.find(".Rk-Edit-Image-File").change(function() {
   805         this.editor_$.find(".Rk-Edit-Image-File").change(function() {
   806         	if (this.files.length) {
   806             if (this.files.length) {
   807         		var f = this.files[0],
   807                 var f = this.files[0],
   808         			fr = new FileReader();
   808                     fr = new FileReader();
   809     			if (f.type.substr(0,5) !== "image") {
   809                 if (f.type.substr(0,5) !== "image") {
   810     				alert(_this.renkan.translate("This file is not an image"));
   810                     alert(_this.renkan.translate("This file is not an image"));
   811     				return;
   811                     return;
   812     			}
   812                 }
   813     			if (f.size > (Rkns.Renderer._IMAGE_MAX_KB * 1024)) {
   813                 if (f.size > (Rkns.Renderer._IMAGE_MAX_KB * 1024)) {
   814     				alert(_this.renkan.translate("Image size must be under ")+Rkns.Renderer._IMAGE_MAX_KB+_this.renkan.translate("KB"));
   814                     alert(_this.renkan.translate("Image size must be under ")+Rkns.Renderer._IMAGE_MAX_KB+_this.renkan.translate("KB"));
   815     				return;
   815                     return;
   816     			}
   816                 }
   817         		fr.onload = function(e) {
   817                 fr.onload = function(e) {
   818         			_this.editor_$.find(".Rk-Edit-Image").val(e.target.result);
   818                     _this.editor_$.find(".Rk-Edit-Image").val(e.target.result);
   819         			onFieldChange();
   819                     onFieldChange();
   820         		}
   820                 }
   821         		fr.readAsDataURL(f);
   821                 fr.readAsDataURL(f);
   822         	}
   822             }
   823         });
   823         });
   824         this.editor_$.find(".Rk-Edit-Title")[0].focus();
   824         this.editor_$.find(".Rk-Edit-Title")[0].focus();
   825         
   825         
   826         var _picker = _this.editor_$.find(".Rk-Edit-ColorPicker");
   826         var _picker = _this.editor_$.find(".Rk-Edit-ColorPicker");
   827         
   827         
   828         this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(
   828         this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(
   829             function(_e) {
   829             function(_e) {
   830             	_e.preventDefault();
   830                 _e.preventDefault();
   831             	_picker.show();
   831                 _picker.show();
   832         	},
   832             },
   833             function(_e) {
   833             function(_e) {
   834             	_e.preventDefault();
   834                 _e.preventDefault();
   835             	_picker.hide();
   835                 _picker.hide();
   836         	}
   836             }
   837         );
   837         );
   838         
   838         
   839         _picker.find("li").hover(
   839         _picker.find("li").hover(
   840             function(_e) {
   840             function(_e) {
   841             	_e.preventDefault();
   841                 _e.preventDefault();
   842             	_this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color"));
   842                 _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color"));
   843         	},
   843             },
   844             function(_e) {
   844             function(_e) {
   845             	_e.preventDefault();
   845                 _e.preventDefault();
   846             	_this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(_this.renkan)).get("color"))
   846                 _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(_this.renkan)).get("color"))
   847         	}
   847             }
   848         ).click(function(_e) {
   848         ).click(function(_e) {
   849         	_e.preventDefault();
   849             _e.preventDefault();
   850             if (_this.renderer.isEditable()) {
   850             if (_this.renderer.isEditable()) {
   851 	            _model.set("color", $(this).attr("data-color"));
   851                 _model.set("color", $(this).attr("data-color"));
   852             	_picker.hide();
   852                 _picker.hide();
   853 				paper.view.draw();
   853                 paper.view.draw();
   854             } else {
   854             } else {
   855             	closeEditor();
   855                 closeEditor();
   856             }
   856             }
   857         });
   857         });
   858         
   858         
   859         function shiftSize(n) {
   859         function shiftSize(n) {
   860         	if (_this.renderer.isEditable()) {
   860             if (_this.renderer.isEditable()) {
   861 	        	var _newsize = n+(_model.get("size") || 0);
   861                 var _newsize = n+(_model.get("size") || 0);
   862 	        	_this.editor_$.find(".Rk-Edit-Size-Value").text((_newsize > 0 ? "+" : "") + _newsize);
   862                 _this.editor_$.find(".Rk-Edit-Size-Value").text((_newsize > 0 ? "+" : "") + _newsize);
   863 	        	_model.set("size", _newsize);
   863                 _model.set("size", _newsize);
   864 				paper.view.draw();
   864                 paper.view.draw();
   865 			} else {
   865             } else {
   866 				closeEditor();
   866                 closeEditor();
   867 			}
   867             }
   868         }
   868         }
   869         
   869         
   870         this.editor_$.find(".Rk-Edit-Size-Down").click(function() {
   870         this.editor_$.find(".Rk-Edit-Size-Down").click(function() {
   871         	shiftSize(-1);
   871             shiftSize(-1);
   872         	return false;
   872             return false;
   873         });
   873         });
   874         this.editor_$.find(".Rk-Edit-Size-Up").click(function() {
   874         this.editor_$.find(".Rk-Edit-Size-Up").click(function() {
   875         	shiftSize(1);
   875             shiftSize(1);
   876         	return false;
   876             return false;
   877         });
   877         });
   878     }
   878     }
   879     this.editor_$.find("img").load(function() {
   879     this.editor_$.find("img").load(function() {
   880         _this.redraw();
   880         _this.redraw();
   881     });
   881     });
   944         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan),
   944         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan),
   945         _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate);
   945         _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate);
   946     this.editor_$
   946     this.editor_$
   947         .html(_template({
   947         .html(_template({
   948             edge: {
   948             edge: {
   949             	has_creator: !!_model.get("created_by"),
   949                 has_creator: !!_model.get("created_by"),
   950                 title: _model.get("title"),
   950                 title: _model.get("title"),
   951                 uri: _model.get("uri"),
   951                 uri: _model.get("uri"),
   952                 short_uri:  Rkns.Renderer.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40),
   952                 short_uri:  Rkns.Renderer.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40),
   953                 description: _model.get("description"),
   953                 description: _model.get("description"),
   954                 color: _model.get("color") || _created_by.get("color"),
   954                 color: _model.get("color") || _created_by.get("color"),
   962             renkan: this.renkan,
   962             renkan: this.renkan,
   963             properties: this.options.properties
   963             properties: this.options.properties
   964         }));
   964         }));
   965     this.redraw();
   965     this.redraw();
   966     var _this = this,
   966     var _this = this,
   967     	closeEditor = function() {
   967         closeEditor = function() {
   968 	        _this.renderer.removeRepresentation(_this);
   968             _this.renderer.removeRepresentation(_this);
   969 	        paper.view.draw();
   969             paper.view.draw();
   970     	}
   970         }
   971     this.editor_$.find(".Rk-CloseX").click(closeEditor);
   971     this.editor_$.find(".Rk-CloseX").click(closeEditor);
   972     
   972     
   973     if (this.renderer.isEditable()) {
   973     if (this.renderer.isEditable()) {
   974     	
   974         
   975     	var onFieldChange = Rkns._(function() {
   975         var onFieldChange = Rkns._(function() {
   976     		Rkns._(function() {
   976             Rkns._(function() {
   977     			if (_this.renderer.isEditable()) {
   977                 if (_this.renderer.isEditable()) {
   978 	    			_this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val());
   978                     _this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val());
   979 		            var _data = {
   979                     var _data = {
   980 		                title: _this.editor_$.find(".Rk-Edit-Title").val(),
   980                         title: _this.editor_$.find(".Rk-Edit-Title").val(),
   981 		                uri: _this.editor_$.find(".Rk-Edit-URI").val()
   981                         uri: _this.editor_$.find(".Rk-Edit-URI").val()
   982 		            }
   982                     }
   983 		            _model.set(_data);
   983                     _model.set(_data);
   984 		            paper.view.draw();
   984                     paper.view.draw();
   985 	           	} else {
   985                 } else {
   986 	           		closeEditor();
   986                     closeEditor();
   987 	           	}
   987                 }
   988     		}).defer();
   988             }).defer();
   989     	}).throttle(500);
   989         }).throttle(500);
   990     	
   990         
   991     	this.editor_$.on("keyup", function(_e) {
   991         this.editor_$.on("keyup", function(_e) {
   992     		if (_e.keyCode === 27) {
   992             if (_e.keyCode === 27) {
   993     			closeEditor();
   993                 closeEditor();
   994     		}
   994             }
   995     	});
   995         });
   996     	
   996         
   997         this.editor_$.find("input").on("keyup change paste", onFieldChange);
   997         this.editor_$.find("input").on("keyup change paste", onFieldChange);
   998         
   998         
   999         this.editor_$.find(".Rk-Edit-Vocabulary").change(function() {
   999         this.editor_$.find(".Rk-Edit-Vocabulary").change(function() {
  1000         	var e = $(this),
  1000             var e = $(this),
  1001         		v = e.val();
  1001                 v = e.val();
  1002         	if (v) {
  1002             if (v) {
  1003         		_this.editor_$.find(".Rk-Edit-Title").val(e.find(":selected").text());
  1003                 _this.editor_$.find(".Rk-Edit-Title").val(e.find(":selected").text());
  1004         		_this.editor_$.find(".Rk-Edit-URI").val(v);
  1004                 _this.editor_$.find(".Rk-Edit-URI").val(v);
  1005         		onFieldChange();
  1005                 onFieldChange();
  1006         	}
  1006             }
  1007         });
  1007         });
  1008         this.editor_$.find(".Rk-Edit-Direction").click(function() {
  1008         this.editor_$.find(".Rk-Edit-Direction").click(function() {
  1009 			if (_this.renderer.isEditable()) {
  1009             if (_this.renderer.isEditable()) {
  1010 	        	_model.set({
  1010                 _model.set({
  1011 	        		from: _model.get("to"),
  1011                     from: _model.get("to"),
  1012 	        		to: _model.get("from")
  1012                     to: _model.get("from")
  1013 	        	});
  1013                 });
  1014 	        	_this.draw();
  1014                 _this.draw();
  1015 	       	} else {
  1015             } else {
  1016 	       		closeEditor();
  1016                 closeEditor();
  1017 	       	}
  1017             }
  1018         });
  1018         });
  1019         
  1019         
  1020         var _picker = _this.editor_$.find(".Rk-Edit-ColorPicker");
  1020         var _picker = _this.editor_$.find(".Rk-Edit-ColorPicker");
  1021         
  1021         
  1022         this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(
  1022         this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(
  1023             function(_e) {
  1023             function(_e) {
  1024             	_e.preventDefault();
  1024                 _e.preventDefault();
  1025             	_picker.show();
  1025                 _picker.show();
  1026         	},
  1026             },
  1027             function(_e) {
  1027             function(_e) {
  1028             	_e.preventDefault();
  1028                 _e.preventDefault();
  1029             	_picker.hide();
  1029                 _picker.hide();
  1030         	}
  1030             }
  1031         );
  1031         );
  1032         
  1032         
  1033         _picker.find("li").hover(
  1033         _picker.find("li").hover(
  1034             function(_e) {
  1034             function(_e) {
  1035             	_e.preventDefault();
  1035                 _e.preventDefault();
  1036             	_this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color"));
  1036                 _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color"));
  1037         	},
  1037             },
  1038             function(_e) {
  1038             function(_e) {
  1039             	_e.preventDefault();
  1039                 _e.preventDefault();
  1040             	_this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(_this.renkan)).get("color"))
  1040                 _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(_this.renkan)).get("color"))
  1041         	}
  1041             }
  1042         ).click(function(_e) {
  1042         ).click(function(_e) {
  1043         	_e.preventDefault();
  1043             _e.preventDefault();
  1044             if (_this.renderer.isEditable()) {
  1044             if (_this.renderer.isEditable()) {
  1045 	            _model.set("color", $(this).attr("data-color"));
  1045                 _model.set("color", $(this).attr("data-color"));
  1046             	_picker.hide();
  1046                 _picker.hide();
  1047 				paper.view.draw();
  1047                 paper.view.draw();
  1048             } else {
  1048             } else {
  1049             	closeEditor();
  1049                 closeEditor();
  1050             }
  1050             }
  1051         });
  1051         });
  1052     }
  1052     }
  1053 }
  1053 }
  1054 
  1054 
  1082 /* */
  1082 /* */
  1083 
  1083 
  1084 Rkns.Renderer._NodeButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton);
  1084 Rkns.Renderer._NodeButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton);
  1085 
  1085 
  1086 Rkns.Renderer._NodeButton.prototype.setSectorSize = function() {
  1086 Rkns.Renderer._NodeButton.prototype.setSectorSize = function() {
  1087 	var sectorInner = this.source_representation.circle_radius;
  1087     var sectorInner = this.source_representation.circle_radius;
  1088 	if (sectorInner !== this.lastSectorInner) {
  1088     if (sectorInner !== this.lastSectorInner) {
  1089 		if (this.sector) {
  1089         if (this.sector) {
  1090 			this.sector.destroy();
  1090             this.sector.destroy();
  1091 		}
  1091         }
  1092 		this.sector = this.renderer.drawSector(
  1092         this.sector = this.renderer.drawSector(
  1093 			this, 1 + sectorInner,
  1093             this, 1 + sectorInner,
  1094 			Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner,
  1094             Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner,
  1095 			this.startAngle,
  1095             this.startAngle,
  1096 			this.endAngle,
  1096             this.endAngle,
  1097 			1,
  1097             1,
  1098 			this.imageName,
  1098             this.imageName,
  1099 			this.renkan.translate(this.text)
  1099             this.renkan.translate(this.text)
  1100 		);
  1100         );
  1101 		this.lastSectorInner = sectorInner;
  1101         this.lastSectorInner = sectorInner;
  1102 	}
  1102     }
  1103 }
  1103 }
  1104 
  1104 
  1105 /* */
  1105 /* */
  1106 
  1106 
  1107 Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
  1107 Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
  1156     this.text = "Link to another node";
  1156     this.text = "Link to another node";
  1157 }
  1157 }
  1158 
  1158 
  1159 Rkns.Renderer.NodeLinkButton.prototype.mousedown = function(_event, _isTouch) {
  1159 Rkns.Renderer.NodeLinkButton.prototype.mousedown = function(_event, _isTouch) {
  1160     if (this.renderer.isEditable()) {
  1160     if (this.renderer.isEditable()) {
  1161 	    var _off = this.renderer.canvas_$.offset(),
  1161         var _off = this.renderer.canvas_$.offset(),
  1162 	    	_point = new paper.Point([
  1162             _point = new paper.Point([
  1163 	            _event.pageX - _off.left,
  1163                 _event.pageX - _off.left,
  1164 	            _event.pageY - _off.top
  1164                 _event.pageY - _off.top
  1165 	        ]);
  1165             ]);
  1166         this.renderer.click_target = null;
  1166         this.renderer.click_target = null;
  1167         this.renderer.removeRepresentationsOfType("editor");
  1167         this.renderer.removeRepresentationsOfType("editor");
  1168         this.renderer.addTempEdge(this.source_representation, _point);
  1168         this.renderer.addTempEdge(this.source_representation, _point);
  1169     }
  1169     }
  1170 }
  1170 }
  1181     this.imageName = "enlarge";
  1181     this.imageName = "enlarge";
  1182     this.text = "Enlarge";
  1182     this.text = "Enlarge";
  1183 }
  1183 }
  1184 
  1184 
  1185 Rkns.Renderer.NodeEnlargeButton.prototype.mouseup = function() {
  1185 Rkns.Renderer.NodeEnlargeButton.prototype.mouseup = function() {
  1186 	var _newsize = 1 + (this.source_representation.model.get("size") || 0);
  1186     var _newsize = 1 + (this.source_representation.model.get("size") || 0);
  1187 	this.source_representation.model.set("size", _newsize);
  1187     this.source_representation.model.set("size", _newsize);
  1188 	this.source_representation.select();
  1188     this.source_representation.select();
  1189 	this.select();
  1189     this.select();
  1190 	paper.view.draw();
  1190     paper.view.draw();
  1191 }
  1191 }
  1192 
  1192 
  1193 /* */
  1193 /* */
  1194 
  1194 
  1195 Rkns.Renderer.NodeShrinkButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
  1195 Rkns.Renderer.NodeShrinkButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
  1202     this.imageName = "shrink";
  1202     this.imageName = "shrink";
  1203     this.text = "Shrink";
  1203     this.text = "Shrink";
  1204 }
  1204 }
  1205 
  1205 
  1206 Rkns.Renderer.NodeShrinkButton.prototype.mouseup = function() {
  1206 Rkns.Renderer.NodeShrinkButton.prototype.mouseup = function() {
  1207 	var _newsize = -1 + (this.source_representation.model.get("size") || 0);
  1207     var _newsize = -1 + (this.source_representation.model.get("size") || 0);
  1208 	this.source_representation.model.set("size", _newsize);
  1208     this.source_representation.model.set("size", _newsize);
  1209 	this.source_representation.select();
  1209     this.source_representation.select();
  1210 	this.select();
  1210     this.select();
  1211 	paper.view.draw();
  1211     paper.view.draw();
  1212 }
  1212 }
  1213 
  1213 
  1214 /* */
  1214 /* */
  1215 
  1215 
  1216 Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton);
  1216 Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton);
  1247 /* */
  1247 /* */
  1248 
  1248 
  1249 Rkns.Renderer.MiniFrame = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1249 Rkns.Renderer.MiniFrame = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1250 
  1250 
  1251 Rkns.Renderer.MiniFrame.prototype.paperShift = function(_delta) {
  1251 Rkns.Renderer.MiniFrame.prototype.paperShift = function(_delta) {
  1252 	this.renderer.offset = this.renderer.offset.subtract(_delta.divide(this.renderer.minimap.scale).multiply(this.renderer.scale));
  1252     this.renderer.offset = this.renderer.offset.subtract(_delta.divide(this.renderer.minimap.scale).multiply(this.renderer.scale));
  1253     this.renderer.redraw();
  1253     this.renderer.redraw();
  1254 }
  1254 }
  1255 
  1255 
  1256 Rkns.Renderer.MiniFrame.prototype.mouseup = function(_delta) {
  1256 Rkns.Renderer.MiniFrame.prototype.mouseup = function(_delta) {
  1257 	this.renderer.click_target = null;
  1257     this.renderer.click_target = null;
  1258     this.renderer.is_dragging = false;
  1258     this.renderer.is_dragging = false;
  1259 }
  1259 }
  1260 
  1260 
  1261 /* */
  1261 /* */
  1262 
  1262 
  1280     this.edge_layer = new paper.Layer();
  1280     this.edge_layer = new paper.Layer();
  1281     this.node_layer = new paper.Layer();
  1281     this.node_layer = new paper.Layer();
  1282     this.buttons_layer = new paper.Layer();
  1282     this.buttons_layer = new paper.Layer();
  1283     
  1283     
  1284     if (_renkan.options.show_minimap) {
  1284     if (_renkan.options.show_minimap) {
  1285 	    this.minimap = {
  1285         this.minimap = {
  1286 	    	background_layer: new paper.Layer(),
  1286             background_layer: new paper.Layer(),
  1287 	    	edge_layer: new paper.Layer(),
  1287             edge_layer: new paper.Layer(),
  1288 	    	node_layer: new paper.Layer(),
  1288             node_layer: new paper.Layer(),
  1289 	    	node_group: new paper.Group(),
  1289             node_group: new paper.Group(),
  1290 	    	size: new paper.Size( _renkan.options.minimap_width, _renkan.options.minimap_height )
  1290             size: new paper.Size( _renkan.options.minimap_width, _renkan.options.minimap_height )
  1291 	    }
  1291         }
  1292 	    
  1292         
  1293 	    this.minimap.background_layer.activate();
  1293         this.minimap.background_layer.activate();
  1294 	    this.minimap.topleft = paper.view.bounds.bottomRight.subtract(this.minimap.size);
  1294         this.minimap.topleft = paper.view.bounds.bottomRight.subtract(this.minimap.size);
  1295 	    this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4]));
  1295         this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4]));
  1296 	    this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color;
  1296         this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color;
  1297 	    this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color;
  1297         this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color;
  1298 	    this.minimap.rectangle.strokeWidth = 4;
  1298         this.minimap.rectangle.strokeWidth = 4;
  1299 	    this.minimap.offset = new paper.Point(this.minimap.size.divide(2));
  1299         this.minimap.offset = new paper.Point(this.minimap.size.divide(2));
  1300 	    this.minimap.scale = .1;
  1300         this.minimap.scale = .1;
  1301 	    
  1301         
  1302 	    this.minimap.node_layer.activate();
  1302         this.minimap.node_layer.activate();
  1303 	    this.minimap.cliprectangle = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);
  1303         this.minimap.cliprectangle = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);
  1304 	    this.minimap.node_group.addChild(this.minimap.cliprectangle);
  1304         this.minimap.node_group.addChild(this.minimap.cliprectangle);
  1305 	    this.minimap.node_group.clipped = true;
  1305         this.minimap.node_group.clipped = true;
  1306 	    this.minimap.miniframe = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);
  1306         this.minimap.miniframe = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);
  1307 	    this.minimap.node_group.addChild(this.minimap.miniframe);
  1307         this.minimap.node_group.addChild(this.minimap.miniframe);
  1308 	    this.minimap.miniframe.fillColor = '#c0c0ff';
  1308         this.minimap.miniframe.fillColor = '#c0c0ff';
  1309 	    this.minimap.miniframe.opacity = .3;
  1309         this.minimap.miniframe.opacity = .3;
  1310 	    this.minimap.miniframe.strokeColor = '#000080';
  1310         this.minimap.miniframe.strokeColor = '#000080';
  1311 	    this.minimap.miniframe.strokeWidth = 3;
  1311         this.minimap.miniframe.strokeWidth = 3;
  1312 	    this.minimap.miniframe.__representation = new Rkns.Renderer.MiniFrame(this, null);
  1312         this.minimap.miniframe.__representation = new Rkns.Renderer.MiniFrame(this, null);
  1313     }
  1313     }
  1314     
  1314     
  1315     this.throttledPaperDraw = Rkns._(function() {
  1315     this.throttledPaperDraw = Rkns._(function() {
  1316     	paper.view.draw();
  1316         paper.view.draw();
  1317     }).throttle(100);
  1317     }).throttle(100);
  1318     
  1318     
  1319     this.bundles = [];
  1319     this.bundles = [];
  1320     this.click_mode = false;
  1320     this.click_mode = false;
  1321     
  1321     
  1328         _lastTapY;
  1328         _lastTapY;
  1329     
  1329     
  1330     this.imageCache = {};
  1330     this.imageCache = {};
  1331     
  1331     
  1332     ['edit', 'remove', 'link', 'enlarge', 'shrink'].forEach(function(imgname) {
  1332     ['edit', 'remove', 'link', 'enlarge', 'shrink'].forEach(function(imgname) {
  1333     	var img = new Image();
  1333         var img = new Image();
  1334     	img.src = _renkan.options.static_url + 'img/' + imgname + '.png';
  1334         img.src = _renkan.options.static_url + 'img/' + imgname + '.png';
  1335     	_this.imageCache[imgname] = img;
  1335         _this.imageCache[imgname] = img;
  1336     });
  1336     });
  1337     
  1337     
  1338     var throttledMouseMove = _.throttle(function(_event, _isTouch) {
  1338     var throttledMouseMove = _.throttle(function(_event, _isTouch) {
  1339     	_this.onMouseMove(_event, _isTouch);
  1339         _this.onMouseMove(_event, _isTouch);
  1340     }, Rkns.Renderer._MOUSEMOVE_RATE);
  1340     }, Rkns.Renderer._MOUSEMOVE_RATE);
  1341     
  1341     
  1342     this.canvas_$.on({
  1342     this.canvas_$.on({
  1343     	mousedown: function(_event) {
  1343         mousedown: function(_event) {
  1344     		_event.preventDefault();
  1344             _event.preventDefault();
  1345     		_this.onMouseDown(_event, false);
  1345             _this.onMouseDown(_event, false);
  1346     	},
  1346         },
  1347     	mousemove: function(_event) {
  1347         mousemove: function(_event) {
  1348     		_event.preventDefault();
  1348             _event.preventDefault();
  1349         	throttledMouseMove(_event, false);
  1349             throttledMouseMove(_event, false);
  1350 	    },
  1350         },
  1351 	    mouseup: function(_event) {
  1351         mouseup: function(_event) {
  1352     		_event.preventDefault();
  1352             _event.preventDefault();
  1353 	        _this.onMouseUp(_event, false);
  1353             _this.onMouseUp(_event, false);
  1354 	    },
  1354         },
  1355 	    mousewheel: function(_event, _delta) {
  1355         mousewheel: function(_event, _delta) {
  1356     		_event.preventDefault();
  1356             _event.preventDefault();
  1357 	        if (_allowScroll) {
  1357             if (_allowScroll) {
  1358 	        	_this.onScroll(_event, _delta);
  1358                 _this.onScroll(_event, _delta);
  1359 	        }
  1359             }
  1360 	    },
  1360         },
  1361 	    touchstart: function(_event) {
  1361         touchstart: function(_event) {
  1362 	    	_event.preventDefault();
  1362             _event.preventDefault();
  1363 	    	var _touches = _event.originalEvent.touches[0];
  1363             var _touches = _event.originalEvent.touches[0];
  1364     		if (
  1364             if (
  1365     			_renkan.options.allow_double_click
  1365                 _renkan.options.allow_double_click
  1366     			&& new Date() - _lastTap < Rkns.Renderer._DOUBLETAP_DELAY
  1366                 && new Date() - _lastTap < Rkns.Renderer._DOUBLETAP_DELAY
  1367     			&& ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Rkns.Renderer._DOUBLETAP_DISTANCE )
  1367                 && ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Rkns.Renderer._DOUBLETAP_DISTANCE )
  1368 			) {
  1368             ) {
  1369     			_lastTap = 0;
  1369                 _lastTap = 0;
  1370     			_this.onDoubleClick(_touches);
  1370                 _this.onDoubleClick(_touches);
  1371     		} else {
  1371             } else {
  1372     			_lastTap = new Date();
  1372                 _lastTap = new Date();
  1373     			_lastTapX = _touches.pageX;
  1373                 _lastTapX = _touches.pageX;
  1374     			_lastTapY = _touches.pageY;
  1374                 _lastTapY = _touches.pageY;
  1375 		    	_originalScale = _this.scale;
  1375                 _originalScale = _this.scale;
  1376 		    	_zooming = false;
  1376                 _zooming = false;
  1377 		    	_this.onMouseDown(_touches, true);
  1377                 _this.onMouseDown(_touches, true);
  1378     		}
  1378             }
  1379 	    },
  1379         },
  1380 	    touchmove: function(_event) {
  1380         touchmove: function(_event) {
  1381 	    	_event.preventDefault();
  1381             _event.preventDefault();
  1382     		_lastTap = 0;
  1382             _lastTap = 0;
  1383 	    	if (_event.originalEvent.touches.length == 1) {
  1383             if (_event.originalEvent.touches.length == 1) {
  1384 	    		_this.onMouseMove(_event.originalEvent.touches[0], true);
  1384                 _this.onMouseMove(_event.originalEvent.touches[0], true);
  1385 	    	} else {
  1385             } else {
  1386 	    		if (!_zooming) {
  1386                 if (!_zooming) {
  1387 	    			_this.onMouseUp(_event.originalEvent.touches[0], true);
  1387                     _this.onMouseUp(_event.originalEvent.touches[0], true);
  1388 			        _this.click_target = null;
  1388                     _this.click_target = null;
  1389 			        _this.is_dragging = false;
  1389                     _this.is_dragging = false;
  1390 			        _zooming = true;
  1390                     _zooming = true;
  1391 	    		}
  1391                 }
  1392 	    		if (_event.originalEvent.scale === "undefined") {
  1392                 if (_event.originalEvent.scale === "undefined") {
  1393 	    			return;
  1393                     return;
  1394 	    		}
  1394                 }
  1395 	    		var _newScale = _event.originalEvent.scale * _originalScale,
  1395                 var _newScale = _event.originalEvent.scale * _originalScale,
  1396 	    			_scaleRatio = _newScale / _this.scale,
  1396                     _scaleRatio = _newScale / _this.scale,
  1397 	    			_newOffset = new paper.Point([
  1397                     _newOffset = new paper.Point([
  1398 			            _this.canvas_$.width(),
  1398                         _this.canvas_$.width(),
  1399 			            _this.canvas_$.height()
  1399                         _this.canvas_$.height()
  1400 			        ]).multiply( .5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio ));
  1400                     ]).multiply( .5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio ));
  1401 	    		_this.setScale(_newScale, _this.offset);
  1401                 _this.setScale(_newScale, _this.offset);
  1402 	    	}
  1402             }
  1403 	    },
  1403         },
  1404 	    touchend: function(_event) {
  1404         touchend: function(_event) {
  1405 	    	_event.preventDefault();
  1405             _event.preventDefault();
  1406 	    	_this.onMouseUp(_event.originalEvent.changedTouches[0], true);
  1406             _this.onMouseUp(_event.originalEvent.changedTouches[0], true);
  1407 	    },
  1407         },
  1408 	    dblclick: function(_event) {
  1408         dblclick: function(_event) {
  1409     		_event.preventDefault();
  1409             _event.preventDefault();
  1410     		if (_renkan.options.allow_double_click) {
  1410             if (_renkan.options.allow_double_click) {
  1411     			_this.onDoubleClick(_event);
  1411                 _this.onDoubleClick(_event);
  1412     		}
  1412             }
  1413 	    },
  1413         },
  1414 	    mouseleave: function(_event) {
  1414         mouseleave: function(_event) {
  1415     		_event.preventDefault();
  1415             _event.preventDefault();
  1416 	        _this.onMouseUp(_event, false);
  1416             _this.onMouseUp(_event, false);
  1417 	        _this.click_target = null;
  1417             _this.click_target = null;
  1418 	        _this.is_dragging = false;
  1418             _this.is_dragging = false;
  1419 	    },
  1419         },
  1420 	    dragover: function(_event) {
  1420         dragover: function(_event) {
  1421 	    	_event.preventDefault();
  1421             _event.preventDefault();
  1422 	    },
  1422         },
  1423 	    dragenter: function(_event) {
  1423         dragenter: function(_event) {
  1424 	    	_event.preventDefault();
  1424             _event.preventDefault();
  1425 	    	_allowScroll = false;
  1425             _allowScroll = false;
  1426 	    },
  1426         },
  1427 	    dragleave: function(_event) {
  1427         dragleave: function(_event) {
  1428 	    	_event.preventDefault();
  1428             _event.preventDefault();
  1429 	    	_allowScroll = true;
  1429             _allowScroll = true;
  1430 	    },
  1430         },
  1431 	    drop: function(_event) {
  1431         drop: function(_event) {
  1432 	    	_event.preventDefault();
  1432             _event.preventDefault();
  1433 	    	_allowScroll = true;
  1433             _allowScroll = true;
  1434 	    	var res = {};
  1434             var res = {};
  1435 	    	Rkns._(_event.originalEvent.dataTransfer.types).each(function(t) {
  1435             Rkns._(_event.originalEvent.dataTransfer.types).each(function(t) {
  1436 	    		try {
  1436                 try {
  1437 	    			res[t] = _event.originalEvent.dataTransfer.getData(t);
  1437                     res[t] = _event.originalEvent.dataTransfer.getData(t);
  1438 	    		} catch(e) {}
  1438                 } catch(e) {}
  1439 	    	});
  1439             });
  1440 			var text = _event.originalEvent.dataTransfer.getData("Text");
  1440             var text = _event.originalEvent.dataTransfer.getData("Text");
  1441 			if (typeof text === "string") {
  1441             if (typeof text === "string") {
  1442 				switch(text[0]) {
  1442                 switch(text[0]) {
  1443 	    			case "{":
  1443                     case "{":
  1444 	    			case "[":
  1444                     case "[":
  1445 	    				try {
  1445                         try {
  1446 	    					var data = JSON.parse(text);
  1446                             var data = JSON.parse(text);
  1447 	    					_(res).extend(data);
  1447                             _(res).extend(data);
  1448 	    				}
  1448                         }
  1449 	    				catch(e) {
  1449                         catch(e) {
  1450 	    					if (!res["text/plain"]) {
  1450                             if (!res["text/plain"]) {
  1451 	    						res["text/plain"] = text;
  1451                                 res["text/plain"] = text;
  1452 	    					}
  1452                             }
  1453 	    				}
  1453                         }
  1454 					break;
  1454                     break;
  1455 					case "<":
  1455                     case "<":
  1456 						if (!res["text/html"]) {
  1456                         if (!res["text/html"]) {
  1457 							res["text/html"] = text;
  1457                             res["text/html"] = text;
  1458 						}
  1458                         }
  1459 					break;
  1459                     break;
  1460 					default:
  1460                     default:
  1461 						if (!res["text/plain"]) {
  1461                         if (!res["text/plain"]) {
  1462 							res["text/plain"] = text;
  1462                             res["text/plain"] = text;
  1463 						}
  1463                         }
  1464 	    		}
  1464                 }
  1465 			}
  1465             }
  1466 			var url = _event.originalEvent.dataTransfer.getData("URL");
  1466             var url = _event.originalEvent.dataTransfer.getData("URL");
  1467 			if (url && !res["text/uri-list"]) {
  1467             if (url && !res["text/uri-list"]) {
  1468 				res["text/uri-list"] = url;
  1468                 res["text/uri-list"] = url;
  1469 			}
  1469             }
  1470 			_this.dropData(res, _event.originalEvent);
  1470             _this.dropData(res, _event.originalEvent);
  1471 	    }
  1471         }
  1472     });
  1472     });
  1473     this.editor_$.find(".Rk-ZoomOut").click(function() {
  1473     this.editor_$.find(".Rk-ZoomOut").click(function() {
  1474     	var _newScale = _this.scale * Math.SQRT1_2,
  1474         var _newScale = _this.scale * Math.SQRT1_2,
  1475     		_offset = new paper.Point([
  1475             _offset = new paper.Point([
  1476 	            _this.canvas_$.width(),
  1476                 _this.canvas_$.width(),
  1477 	            _this.canvas_$.height()
  1477                 _this.canvas_$.height()
  1478 	        ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 ));
  1478             ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 ));
  1479         _this.setScale( _newScale, _offset );
  1479         _this.setScale( _newScale, _offset );
  1480     });
  1480     });
  1481     this.editor_$.find(".Rk-ZoomIn").click(function() {
  1481     this.editor_$.find(".Rk-ZoomIn").click(function() {
  1482     	var _newScale = _this.scale * Math.SQRT2,
  1482         var _newScale = _this.scale * Math.SQRT2,
  1483     		_offset = new paper.Point([
  1483             _offset = new paper.Point([
  1484 	            _this.canvas_$.width(),
  1484                 _this.canvas_$.width(),
  1485 	            _this.canvas_$.height()
  1485                 _this.canvas_$.height()
  1486 	        ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
  1486             ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
  1487         _this.setScale( _newScale, _offset );
  1487         _this.setScale( _newScale, _offset );
  1488     });
  1488     });
  1489     this.$.find(".Rk-CurrentUser").mouseenter(
  1489     this.$.find(".Rk-CurrentUser").mouseenter(
  1490         function() { _this.$.find(".Rk-UserList").slideDown() }
  1490         function() { _this.$.find(".Rk-UserList").slideDown() }
  1491     );
  1491     );
  1530             _this.click_mode = Rkns.Renderer._CLICKMODE_STARTEDGE;
  1530             _this.click_mode = Rkns.Renderer._CLICKMODE_STARTEDGE;
  1531             _this.notif_$.text(_renkan.translate("Click on a first node to start the edge")).fadeIn();
  1531             _this.notif_$.text(_renkan.translate("Click on a first node to start the edge")).fadeIn();
  1532         }
  1532         }
  1533     });
  1533     });
  1534     this.$.find(".Rk-Bookmarklet-Button")
  1534     this.$.find(".Rk-Bookmarklet-Button")
  1535 	    .attr("href","javascript:" + Rkns.Renderer._BOOKMARKLET_CODE(_renkan))
  1535         .attr("href","javascript:" + Rkns.Renderer._BOOKMARKLET_CODE(_renkan))
  1536 		.click(function(){
  1536         .click(function(){
  1537 	    	_this.notif_$
  1537             _this.notif_$
  1538 	    		.text(_renkan.translate("Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan."))
  1538                 .text(_renkan.translate("Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan."))
  1539 	    		.fadeIn()
  1539                 .fadeIn()
  1540 	    		.delay(5000)
  1540                 .delay(5000)
  1541 	    		.fadeOut();
  1541                 .fadeOut();
  1542 			return false;
  1542             return false;
  1543 	    });
  1543         });
  1544     this.$.find(".Rk-TopBar-Button").mouseover(function() {
  1544     this.$.find(".Rk-TopBar-Button").mouseover(function() {
  1545         Rkns.$(this).find(".Rk-TopBar-Tooltip").show();
  1545         Rkns.$(this).find(".Rk-TopBar-Tooltip").show();
  1546     }).mouseout(function() {
  1546     }).mouseout(function() {
  1547         Rkns.$(this).find(".Rk-TopBar-Tooltip").hide();
  1547         Rkns.$(this).find(".Rk-TopBar-Tooltip").hide();
  1548     });
  1548     });
  1549     this.$.find(".Rk-Fold-Bins").click(function() {
  1549     this.$.find(".Rk-Fold-Bins").click(function() {
  1550     	var bins = _renkan.$.find(".Rk-Bins");
  1550         var bins = _renkan.$.find(".Rk-Bins");
  1551     	if (bins.offset().left < 0) {
  1551         if (bins.offset().left < 0) {
  1552     		bins.animate({left: 0},250);
  1552             bins.animate({left: 0},250);
  1553     		_this.$.animate({left: 300},250,function() {
  1553             _this.$.animate({left: 300},250,function() {
  1554     			var w = _this.$.width();
  1554                 var w = _this.$.width();
  1555     			paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);
  1555                 paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);
  1556     		});
  1556             });
  1557     		$(this).html("&laquo;");
  1557             $(this).html("&laquo;");
  1558     	} else {
  1558         } else {
  1559     		bins.animate({left: -300},250);
  1559             bins.animate({left: -300},250);
  1560     		_this.$.animate({left: 0},250,function() {
  1560             _this.$.animate({left: 0},250,function() {
  1561     			var w = _this.$.width();
  1561                 var w = _this.$.width();
  1562     			paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);
  1562                 paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);
  1563     		});
  1563             });
  1564     		$(this).html("&raquo;");
  1564             $(this).html("&raquo;");
  1565     	}
  1565         }
  1566     });
  1566     });
  1567     
  1567     
  1568     paper.view.onResize = function(_event) {
  1568     paper.view.onResize = function(_event) {
  1569     	_this.offset = _this.offset.add(_event.delta.divide(2));
  1569         _this.offset = _this.offset.add(_event.delta.divide(2));
  1570     	if (_this.minimap) {
  1570         if (_this.minimap) {
  1571 	        _this.minimap.topleft = paper.view.bounds.bottomRight.subtract(_this.minimap.size)
  1571             _this.minimap.topleft = paper.view.bounds.bottomRight.subtract(_this.minimap.size)
  1572 	        _this.minimap.rectangle.fitBounds(_this.minimap.topleft.subtract([2,2]), _this.minimap.size.add([4,4]));
  1572             _this.minimap.rectangle.fitBounds(_this.minimap.topleft.subtract([2,2]), _this.minimap.size.add([4,4]));
  1573 	        _this.minimap.cliprectangle.fitBounds(_this.minimap.topleft, _this.minimap.size);
  1573             _this.minimap.cliprectangle.fitBounds(_this.minimap.topleft, _this.minimap.size);
  1574         }
  1574         }
  1575         _this.redraw();
  1575         _this.redraw();
  1576     }
  1576     }
  1577     
  1577     
  1578     var _thRedraw = Rkns._.throttle(function() {
  1578     var _thRedraw = Rkns._.throttle(function() {
  1614             el.text(_title);
  1614             el.text(_title);
  1615         }
  1615         }
  1616     });
  1616     });
  1617     
  1617     
  1618     if (_renkan.options.size_bug_fix) {
  1618     if (_renkan.options.size_bug_fix) {
  1619 	    window.setTimeout(
  1619         window.setTimeout(
  1620 	    	function() {
  1620             function() {
  1621 	    		var w = _this.$.width(),
  1621                 var w = _this.$.width(),
  1622 	    			h = _this.$.height();
  1622                     h = _this.$.height();
  1623 				if (_renkan.options.show_top_bar) {
  1623                 if (_renkan.options.show_top_bar) {
  1624 					h -= _this.$.find(".Rk-TopBar").height();
  1624                     h -= _this.$.find(".Rk-TopBar").height();
  1625 				}
  1625                 }
  1626 				_this.canvas_$.attr({
  1626                 _this.canvas_$.attr({
  1627 					width: w,
  1627                     width: w,
  1628 					height: h
  1628                     height: h
  1629 				});
  1629                 });
  1630 				
  1630                 
  1631 	    		paper.view.viewSize = new paper.Size([w, h]);
  1631                 paper.view.viewSize = new paper.Size([w, h]);
  1632 	    		_this.autoScale();
  1632                 _this.autoScale();
  1633 	    	},
  1633             },
  1634 	    	500
  1634             500
  1635 	    );
  1635         );
  1636     }
  1636     }
  1637     
  1637     
  1638     this.redraw();
  1638     this.redraw();
  1639     
  1639     
  1640     if (this.minimap) {
  1640     if (this.minimap) {
  1641 	    window.setInterval(function() {
  1641         window.setInterval(function() {
  1642 	    	_this.rescaleMinimap()
  1642             _this.rescaleMinimap()
  1643 	    }, 2000);
  1643         }, 2000);
  1644     }
  1644     }
  1645 
  1645 
  1646 }
  1646 }
  1647 
  1647 
  1648 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
  1648 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
  1665     + '</div></div>'
  1665     + '</div></div>'
  1666 );
  1666 );
  1667 
  1667 
  1668 Rkns.Renderer.Scene.prototype.drawSector = function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgname, _caption) {
  1668 Rkns.Renderer.Scene.prototype.drawSector = function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgname, _caption) {
  1669     var _options = this.renkan.options,
  1669     var _options = this.renkan.options,
  1670     	_startRads = _startAngle * Math.PI / 180,
  1670         _startRads = _startAngle * Math.PI / 180,
  1671         _endRads = _endAngle * Math.PI / 180,
  1671         _endRads = _endAngle * Math.PI / 180,
  1672         _img = this.imageCache[_imgname],
  1672         _img = this.imageCache[_imgname],
  1673         _span = _endRads - _startRads,
  1673         _span = _endRads - _startRads,
  1674         _startdx = - Math.sin(_startRads),
  1674         _startdx = - Math.sin(_startRads),
  1675         _startdy = Math.cos(_startRads),
  1675         _startdy = Math.cos(_startRads),
  1692         _centerYIn = Math.sin(_centerRads) * _inR,
  1692         _centerYIn = Math.sin(_centerRads) * _inR,
  1693         _centerYOut = Math.sin(_centerRads) * _outR,
  1693         _centerYOut = Math.sin(_centerRads) * _outR,
  1694         _textX = Math.cos(_centerRads) * (_outR + 3),
  1694         _textX = Math.cos(_centerRads) * (_outR + 3),
  1695         _textY = Math.sin(_centerRads) * (_outR + _options.buttons_label_font_size) + _options.buttons_label_font_size / 2,
  1695         _textY = Math.sin(_centerRads) * (_outR + _options.buttons_label_font_size) + _options.buttons_label_font_size / 2,
  1696         _segments = [];
  1696         _segments = [];
  1697 	this.buttons_layer.activate();
  1697     this.buttons_layer.activate();
  1698     var _path = new paper.Path();
  1698     var _path = new paper.Path();
  1699     _path.add([_startXIn, _startYIn]);
  1699     _path.add([_startXIn, _startYIn]);
  1700     _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]);
  1700     _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]);
  1701     _path.lineTo([_endXOut,  _endYOut]);
  1701     _path.lineTo([_endXOut,  _endYOut]);
  1702     _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]);
  1702     _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]);
  1754         destroy: function() {
  1754         destroy: function() {
  1755             _grp.remove();
  1755             _grp.remove();
  1756         }
  1756         }
  1757     }
  1757     }
  1758     function showImage() {
  1758     function showImage() {
  1759     	var _raster = new paper.Raster(_img);
  1759         var _raster = new paper.Raster(_img);
  1760 	    _raster.position = _imgdelta.add(_grp.position).subtract(_delta);
  1760         _raster.position = _imgdelta.add(_grp.position).subtract(_delta);
  1761 	   	_grp.addChild(_raster);
  1761         _grp.addChild(_raster);
  1762     }
  1762     }
  1763     if (_img.width) {
  1763     if (_img.width) {
  1764     	showImage();
  1764         showImage();
  1765     } else {
  1765     } else {
  1766     	Rkns.$(_img).on("load",showImage);
  1766         Rkns.$(_img).on("load",showImage);
  1767     }
  1767     }
  1768     
  1768     
  1769     return _res
  1769     return _res
  1770 }
  1770 }
  1771 
  1771 
  1792     }
  1792     }
  1793     return _bundle;
  1793     return _bundle;
  1794 }
  1794 }
  1795 
  1795 
  1796 Rkns.Renderer.Scene.prototype.isEditable = function() {
  1796 Rkns.Renderer.Scene.prototype.isEditable = function() {
  1797 	return (this.renkan.options.editor_mode && !this.renkan.read_only)
  1797     return (this.renkan.options.editor_mode && !this.renkan.read_only)
  1798 }
  1798 }
  1799 
  1799 
  1800 Rkns.Renderer.Scene.prototype.onStatusChange = function() {
  1800 Rkns.Renderer.Scene.prototype.onStatusChange = function() {
  1801 	var savebtn = this.$.find(".Rk-Save-Button"),
  1801     var savebtn = this.$.find(".Rk-Save-Button"),
  1802 		tip = savebtn.find(".Rk-TopBar-Tooltip-Contents");
  1802         tip = savebtn.find(".Rk-TopBar-Tooltip-Contents");
  1803 	if (this.renkan.read_only) {
  1803     if (this.renkan.read_only) {
  1804 		savebtn.removeClass("disabled Rk-Save-Online").addClass("Rk-Save-ReadOnly");
  1804         savebtn.removeClass("disabled Rk-Save-Online").addClass("Rk-Save-ReadOnly");
  1805 		tip.text(this.renkan.translate("Connection lost"));
  1805         tip.text(this.renkan.translate("Connection lost"));
  1806 	} else {
  1806     } else {
  1807 		if (this.renkan.options.snapshot_mode) {
  1807         if (this.renkan.options.snapshot_mode) {
  1808 			savebtn.removeClass("Rk-Save-ReadOnly Rk-Save-Online");
  1808             savebtn.removeClass("Rk-Save-ReadOnly Rk-Save-Online");
  1809 			tip.text(this.renkan.translate("Archive Project"));
  1809             tip.text(this.renkan.translate("Archive Project"));
  1810 		} else {
  1810         } else {
  1811 			savebtn.removeClass("disabled Rk-Save-ReadOnly").addClass("Rk-Save-Online");
  1811             savebtn.removeClass("disabled Rk-Save-ReadOnly").addClass("Rk-Save-Online");
  1812 			tip.text(this.renkan.translate("Auto-save enabled"));
  1812             tip.text(this.renkan.translate("Auto-save enabled"));
  1813 		}
  1813         }
  1814 	}
  1814     }
  1815 }
  1815 }
  1816 
  1816 
  1817 Rkns.Renderer.Scene.prototype.setScale = function(_newScale, _offset) {
  1817 Rkns.Renderer.Scene.prototype.setScale = function(_newScale, _offset) {
  1818 	if (_newScale > Rkns.Renderer._MIN_SCALE && _newScale < Rkns.Renderer._MAX_SCALE) {
  1818     if (_newScale > Rkns.Renderer._MIN_SCALE && _newScale < Rkns.Renderer._MAX_SCALE) {
  1819 	    this.scale = _newScale;
  1819         this.scale = _newScale;
  1820 	    if (_offset) {
  1820         if (_offset) {
  1821 	    	this.offset = _offset
  1821             this.offset = _offset
  1822 	    }
  1822         }
  1823 	    this.redraw();
  1823         this.redraw();
  1824     }
  1824     }
  1825 }
  1825 }
  1826 
  1826 
  1827 Rkns.Renderer.Scene.prototype.autoScale = function() {
  1827 Rkns.Renderer.Scene.prototype.autoScale = function() {
  1828     var nodes = this.renkan.project.get("nodes")
  1828     var nodes = this.renkan.project.get("nodes")
  1832             _minx = Math.min.apply(Math, _xx),
  1832             _minx = Math.min.apply(Math, _xx),
  1833             _miny = Math.min.apply(Math, _yy),
  1833             _miny = Math.min.apply(Math, _yy),
  1834             _maxx = Math.max.apply(Math, _xx),
  1834             _maxx = Math.max.apply(Math, _xx),
  1835             _maxy = Math.max.apply(Math, _yy);
  1835             _maxy = Math.max.apply(Math, _yy);
  1836         var _scale = Math.max(Rkns.Renderer._MIN_SCALE, Math.min(Rkns.Renderer._MAX_SCALE, (paper.view.size.width - 2 * Rkns.Renderer._AUTOSCALE_MARGIN) / (_maxx - _minx), (paper.view.size.height - 2 * Rkns.Renderer._AUTOSCALE_MARGIN) / (_maxy - _miny)));
  1836         var _scale = Math.max(Rkns.Renderer._MIN_SCALE, Math.min(Rkns.Renderer._MAX_SCALE, (paper.view.size.width - 2 * Rkns.Renderer._AUTOSCALE_MARGIN) / (_maxx - _minx), (paper.view.size.height - 2 * Rkns.Renderer._AUTOSCALE_MARGIN) / (_maxy - _miny)));
  1837 		this.setScale(_scale, paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale)));
  1837         this.setScale(_scale, paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale)));
  1838     }
  1838     }
  1839     if (nodes.length === 1) {
  1839     if (nodes.length === 1) {
  1840         this.setScale(1, paper.view.center.subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y])));
  1840         this.setScale(1, paper.view.center.subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y])));
  1841     }
  1841     }
  1842 }
  1842 }
  1843 
  1843 
  1844 Rkns.Renderer.Scene.prototype.redrawMiniframe = function() {
  1844 Rkns.Renderer.Scene.prototype.redrawMiniframe = function() {
  1845 	var topleft = this.toMinimapCoords(this.toModelCoords(new paper.Point([0,0]))),
  1845     var topleft = this.toMinimapCoords(this.toModelCoords(new paper.Point([0,0]))),
  1846 		bottomright = this.toMinimapCoords(this.toModelCoords(paper.view.bounds.bottomRight));
  1846         bottomright = this.toMinimapCoords(this.toModelCoords(paper.view.bounds.bottomRight));
  1847 	this.minimap.miniframe.fitBounds(topleft, bottomright);
  1847     this.minimap.miniframe.fitBounds(topleft, bottomright);
  1848 }
  1848 }
  1849 
  1849 
  1850 Rkns.Renderer.Scene.prototype.rescaleMinimap = function() {
  1850 Rkns.Renderer.Scene.prototype.rescaleMinimap = function() {
  1851     var nodes = this.renkan.project.get("nodes")
  1851     var nodes = this.renkan.project.get("nodes")
  1852     if (nodes.length > 1) {
  1852     if (nodes.length > 1) {
  1855             _minx = Math.min.apply(Math, _xx),
  1855             _minx = Math.min.apply(Math, _xx),
  1856             _miny = Math.min.apply(Math, _yy),
  1856             _miny = Math.min.apply(Math, _yy),
  1857             _maxx = Math.max.apply(Math, _xx),
  1857             _maxx = Math.max.apply(Math, _xx),
  1858             _maxy = Math.max.apply(Math, _yy);
  1858             _maxy = Math.max.apply(Math, _yy);
  1859         var _scale = Math.min(
  1859         var _scale = Math.min(
  1860         	this.scale * .8 * this.renkan.options.minimap_width / paper.view.bounds.width,
  1860             this.scale * .8 * this.renkan.options.minimap_width / paper.view.bounds.width,
  1861         	this.scale * .8 * this.renkan.options.minimap_height / paper.view.bounds.height,
  1861             this.scale * .8 * this.renkan.options.minimap_height / paper.view.bounds.height,
  1862         	( this.renkan.options.minimap_width - 2 * Rkns.Renderer._MINIMAP_MARGIN ) / (_maxx - _minx),
  1862             ( this.renkan.options.minimap_width - 2 * Rkns.Renderer._MINIMAP_MARGIN ) / (_maxx - _minx),
  1863         	( this.renkan.options.minimap_height - 2 * Rkns.Renderer._MINIMAP_MARGIN ) / (_maxy - _miny)
  1863             ( this.renkan.options.minimap_height - 2 * Rkns.Renderer._MINIMAP_MARGIN ) / (_maxy - _miny)
  1864     	);
  1864         );
  1865         this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale));
  1865         this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale));
  1866         this.minimap.scale = _scale;
  1866         this.minimap.scale = _scale;
  1867     }
  1867     }
  1868     if (nodes.length === 1) {
  1868     if (nodes.length === 1) {
  1869     	this.minimap.scale = .1;
  1869         this.minimap.scale = .1;
  1870         this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y]).multiply(this.minimap.scale));
  1870         this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y]).multiply(this.minimap.scale));
  1871     }
  1871     }
  1872     this.redraw();
  1872     this.redraw();
  1873 }
  1873 }
  1874 
  1874 
  1961     });
  1961     });
  1962 }
  1962 }
  1963 
  1963 
  1964 Rkns.Renderer.Scene.prototype.redraw = function() {
  1964 Rkns.Renderer.Scene.prototype.redraw = function() {
  1965     Rkns._(this.representations).each(function(_representation) {
  1965     Rkns._(this.representations).each(function(_representation) {
  1966     	_representation.redraw(true);
  1966         _representation.redraw(true);
  1967     });
  1967     });
  1968     if (this.minimap) {
  1968     if (this.minimap) {
  1969     	this.redrawMiniframe();
  1969         this.redrawMiniframe();
  1970     }
  1970     }
  1971     paper.view.draw();
  1971     paper.view.draw();
  1972 }
  1972 }
  1973 
  1973 
  1974 Rkns.Renderer.Scene.prototype.addTempEdge = function(_from, _point) {
  1974 Rkns.Renderer.Scene.prototype.addTempEdge = function(_from, _point) {
  1996         this.selected_target = null;
  1996         this.selected_target = null;
  1997     }
  1997     }
  1998 }
  1998 }
  1999 
  1999 
  2000 Rkns.Renderer.Scene.prototype.paperShift = function(_delta) {
  2000 Rkns.Renderer.Scene.prototype.paperShift = function(_delta) {
  2001 	this.offset = this.offset.add(_delta);
  2001     this.offset = this.offset.add(_delta);
  2002     this.redraw();
  2002     this.redraw();
  2003 }
  2003 }
  2004 
  2004 
  2005 Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) {
  2005 Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) {
  2006     var _off = this.canvas_$.offset(),
  2006     var _off = this.canvas_$.offset(),
  2007     	_point = new paper.Point([
  2007         _point = new paper.Point([
  2008             _event.pageX - _off.left,
  2008             _event.pageX - _off.left,
  2009             _event.pageY - _off.top
  2009             _event.pageY - _off.top
  2010         ]),
  2010         ]),
  2011         _delta = _point.subtract(this.last_point);
  2011         _delta = _point.subtract(this.last_point);
  2012 	this.last_point = _point;
  2012     this.last_point = _point;
  2013     if (!this.is_dragging && this.mouse_down && _delta.length > Rkns.Renderer._MIN_DRAG_DISTANCE) {
  2013     if (!this.is_dragging && this.mouse_down && _delta.length > Rkns.Renderer._MIN_DRAG_DISTANCE) {
  2014     	this.is_dragging = true;
  2014         this.is_dragging = true;
  2015     }
  2015     }
  2016     var _hitResult = paper.project.hitTest(_point);
  2016     var _hitResult = paper.project.hitTest(_point);
  2017     if (this.is_dragging) {
  2017     if (this.is_dragging) {
  2018         if (this.click_target && typeof this.click_target.paperShift === "function") {
  2018         if (this.click_target && typeof this.click_target.paperShift === "function") {
  2019             this.click_target.paperShift(_delta);
  2019             this.click_target.paperShift(_delta);
  2026     paper.view.draw();
  2026     paper.view.draw();
  2027 }
  2027 }
  2028 
  2028 
  2029 Rkns.Renderer.Scene.prototype.onMouseDown = function(_event, _isTouch) {
  2029 Rkns.Renderer.Scene.prototype.onMouseDown = function(_event, _isTouch) {
  2030     var _off = this.canvas_$.offset(),
  2030     var _off = this.canvas_$.offset(),
  2031     	_point = new paper.Point([
  2031         _point = new paper.Point([
  2032             _event.pageX - _off.left,
  2032             _event.pageX - _off.left,
  2033             _event.pageY - _off.top
  2033             _event.pageY - _off.top
  2034         ]);
  2034         ]);
  2035     this.last_point = _point;
  2035     this.last_point = _point;
  2036     this.mouse_down = true;
  2036     this.mouse_down = true;
  2073     }
  2073     }
  2074     paper.view.draw();
  2074     paper.view.draw();
  2075 }
  2075 }
  2076 
  2076 
  2077 Rkns.Renderer.Scene.prototype.onMouseUp = function(_event, _isTouch) {
  2077 Rkns.Renderer.Scene.prototype.onMouseUp = function(_event, _isTouch) {
  2078 	this.mouse_down = false;
  2078     this.mouse_down = false;
  2079     if (this.click_target) {
  2079     if (this.click_target) {
  2080         var _off = this.canvas_$.offset();
  2080         var _off = this.canvas_$.offset();
  2081         this.click_target.mouseup(
  2081         this.click_target.mouseup(
  2082             {
  2082             {
  2083                 point: new paper.Point([
  2083                 point: new paper.Point([
  2089         );
  2089         );
  2090     } else {
  2090     } else {
  2091         this.click_target = null;
  2091         this.click_target = null;
  2092         this.is_dragging = false;
  2092         this.is_dragging = false;
  2093         if (_isTouch) {
  2093         if (_isTouch) {
  2094         	this.unselectAll();
  2094             this.unselectAll();
  2095         }
  2095         }
  2096     }
  2096     }
  2097     paper.view.draw();
  2097     paper.view.draw();
  2098 }
  2098 }
  2099 
  2099 
  2104             _delta = new paper.Point([
  2104             _delta = new paper.Point([
  2105                 _event.pageX - _off.left,
  2105                 _event.pageX - _off.left,
  2106                 _event.pageY - _off.top
  2106                 _event.pageY - _off.top
  2107             ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );
  2107             ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );
  2108         if (this.totalScroll > 0) {
  2108         if (this.totalScroll > 0) {
  2109         	this.setScale( this.scale * Math.SQRT2, this.offset.subtract(_delta) );
  2109             this.setScale( this.scale * Math.SQRT2, this.offset.subtract(_delta) );
  2110         } else {
  2110         } else {
  2111         	this.setScale( this.scale * Math.SQRT1_2, this.offset.add(_delta.divide(Math.SQRT2)));
  2111             this.setScale( this.scale * Math.SQRT1_2, this.offset.add(_delta.divide(Math.SQRT2)));
  2112         }
  2112         }
  2113         this.totalScroll = 0;
  2113         this.totalScroll = 0;
  2114     }
  2114     }
  2115 }
  2115 }
  2116 
  2116 
  2139     }
  2139     }
  2140     paper.view.draw();
  2140     paper.view.draw();
  2141 }
  2141 }
  2142 
  2142 
  2143 Rkns.Renderer.Scene.prototype.dropData = function(_data, _event) {
  2143 Rkns.Renderer.Scene.prototype.dropData = function(_data, _event) {
  2144 	if (!this.isEditable()) {
  2144     if (!this.isEditable()) {
  2145 		return;
  2145         return;
  2146 	}
  2146     }
  2147 	if (_data["text/json"] || _data["application/json"]) {
  2147     if (_data["text/json"] || _data["application/json"]) {
  2148 		try {
  2148         try {
  2149 			var jsondata = JSON.parse(_data["text/json"] || _data["application/json"]);
  2149             var jsondata = JSON.parse(_data["text/json"] || _data["application/json"]);
  2150 			_(_data).extend(jsondata);
  2150             _(_data).extend(jsondata);
  2151 		}
  2151         }
  2152 		catch(e) {}
  2152         catch(e) {}
  2153 	}
  2153     }
  2154 	var newNode = {};
  2154     var newNode = {};
  2155 	switch(_data["text/x-iri-specific-site"]) {
  2155     switch(_data["text/x-iri-specific-site"]) {
  2156 		case "twitter":
  2156         case "twitter":
  2157 			var snippet = Rkns.$('<div>').html(_data["text/x-iri-selected-html"]),
  2157             var snippet = Rkns.$('<div>').html(_data["text/x-iri-selected-html"]),
  2158 				tweetdiv = snippet.find(".tweet")
  2158                 tweetdiv = snippet.find(".tweet")
  2159 			newNode.title = _renkan.translate("Tweet by ") + tweetdiv.attr("data-name");
  2159             newNode.title = _renkan.translate("Tweet by ") + tweetdiv.attr("data-name");
  2160 			newNode.uri = "http://twitter.com/" + tweetdiv.attr("data-screen-name") + "/status/" + tweetdiv.attr("data-tweet-id");
  2160             newNode.uri = "http://twitter.com/" + tweetdiv.attr("data-screen-name") + "/status/" + tweetdiv.attr("data-tweet-id");
  2161 			newNode.image = tweetdiv.find(".avatar").attr("src");
  2161             newNode.image = tweetdiv.find(".avatar").attr("src");
  2162 			newNode.description = tweetdiv.find(".js-tweet-text:first").text();
  2162             newNode.description = tweetdiv.find(".js-tweet-text:first").text();
  2163 		break;
  2163         break;
  2164 		case "google":
  2164         case "google":
  2165 			var snippet = Rkns.$('<div>').html(_data["text/x-iri-selected-html"]);
  2165             var snippet = Rkns.$('<div>').html(_data["text/x-iri-selected-html"]);
  2166 			newNode.title = snippet.find("h3:first").text().trim();
  2166             newNode.title = snippet.find("h3:first").text().trim();
  2167 			newNode.uri = snippet.find("h3 a").attr("href");
  2167             newNode.uri = snippet.find("h3 a").attr("href");
  2168 			newNode.description = snippet.find(".st:first").text().trim();
  2168             newNode.description = snippet.find(".st:first").text().trim();
  2169 		break;
  2169         break;
  2170 		case undefined:
  2170         case undefined:
  2171     	default:
  2171         default:
  2172 	    	if (_data["text/x-iri-source-uri"]) {
  2172             if (_data["text/x-iri-source-uri"]) {
  2173 	    		newNode.uri = _data["text/x-iri-source-uri"];
  2173                 newNode.uri = _data["text/x-iri-source-uri"];
  2174 	    	}
  2174             }
  2175 	    	if (_data["text/plain"] || _data["text/x-iri-selected-text"]) {
  2175             if (_data["text/plain"] || _data["text/x-iri-selected-text"]) {
  2176 	    		newNode.description = (_data["text/plain"] || _data["text/x-iri-selected-text"]).replace(/[\s\n]+/gm,' ').trim();
  2176                 newNode.description = (_data["text/plain"] || _data["text/x-iri-selected-text"]).replace(/[\s\n]+/gm,' ').trim();
  2177 	    	}
  2177             }
  2178 	    	if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
  2178             if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
  2179 	    		var snippet = Rkns.$('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]);
  2179                 var snippet = Rkns.$('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]);
  2180 	    		var _imgs = snippet.find("img");
  2180                 var _imgs = snippet.find("img");
  2181 	    		if (_imgs.length) {
  2181                 if (_imgs.length) {
  2182 	    			newNode.image = _imgs[0].src;
  2182                     newNode.image = _imgs[0].src;
  2183 	    		}
  2183                 }
  2184 	    		var _as = snippet.find("a");
  2184                 var _as = snippet.find("a");
  2185 	    		if (_as.length) {
  2185                 if (_as.length) {
  2186 	    			newNode.uri = _as[0].href;
  2186                     newNode.uri = _as[0].href;
  2187 	    		}
  2187                 }
  2188 	    		newNode.title = snippet.find("[title]").attr("title") || newNode.title;
  2188                 newNode.title = snippet.find("[title]").attr("title") || newNode.title;
  2189 	    		newNode.description = snippet.text().replace(/[\s\n]+/gm,' ').trim();
  2189                 newNode.description = snippet.text().replace(/[\s\n]+/gm,' ').trim();
  2190 	    	}
  2190             }
  2191 	    	if (_data["text/uri-list"]) {
  2191             if (_data["text/uri-list"]) {
  2192 	    		newNode.uri = _data["text/uri-list"];
  2192                 newNode.uri = _data["text/uri-list"];
  2193 	    	}
  2193             }
  2194 	    	if (_data["text/x-moz-url"] && !newNode.title) {
  2194             if (_data["text/x-moz-url"] && !newNode.title) {
  2195 	    		newNode.title = (_data["text/x-moz-url"].split("\n")[1] || "").trim();
  2195                 newNode.title = (_data["text/x-moz-url"].split("\n")[1] || "").trim();
  2196 	    		if (newNode.title === newNode.uri) {
  2196                 if (newNode.title === newNode.uri) {
  2197 	    			newNode.title = false;
  2197                     newNode.title = false;
  2198 	    		}
  2198                 }
  2199 	    	}
  2199             }
  2200 	    	if (_data["text/x-iri-source-title"] && !newNode.title) {
  2200             if (_data["text/x-iri-source-title"] && !newNode.title) {
  2201 	    		newNode.title = _data["text/x-iri-source-title"];
  2201                 newNode.title = _data["text/x-iri-source-title"];
  2202 	    	}
  2202             }
  2203 	    	if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
  2203             if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
  2204 	    		newNode.image = snippet.find("[data-image]").attr("data-image") || newNode.image;
  2204                 newNode.image = snippet.find("[data-image]").attr("data-image") || newNode.image;
  2205 	    		newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri;
  2205                 newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri;
  2206 	    		newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title;
  2206                 newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title;
  2207 	    		newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description;
  2207                 newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description;
  2208 	    	}
  2208             }
  2209 	}
  2209     }
  2210 	if (!newNode.title) {
  2210     if (!newNode.title) {
  2211 		newNode.title = this.renkan.translate("Dragged resource");
  2211         newNode.title = this.renkan.translate("Dragged resource");
  2212 	}
  2212     }
  2213 	var fields = ["title", "description", "uri", "image"];
  2213     var fields = ["title", "description", "uri", "image"];
  2214 	for (var i = 0; i < fields.length; i++) {
  2214     for (var i = 0; i < fields.length; i++) {
  2215 		var f = fields[i];
  2215         var f = fields[i];
  2216 		if (_data["text/x-iri-" + f] || _data[f]) {
  2216         if (_data["text/x-iri-" + f] || _data[f]) {
  2217 			newNode[f] = _data["text/x-iri-" + f] || _data[f];
  2217             newNode[f] = _data["text/x-iri-" + f] || _data[f];
  2218 		}
  2218         }
  2219 		if (newNode[f] === "none" || newNode[f] === "null") {
  2219         if (newNode[f] === "none" || newNode[f] === "null") {
  2220 			newNode[f] = undefined;
  2220             newNode[f] = undefined;
  2221 		}
  2221         }
  2222 	}
  2222     }
  2223 	var _off = this.canvas_$.offset(),
  2223     var _off = this.canvas_$.offset(),
  2224         _point = new paper.Point([
  2224         _point = new paper.Point([
  2225             _event.pageX - _off.left,
  2225             _event.pageX - _off.left,
  2226             _event.pageY - _off.top
  2226             _event.pageY - _off.top
  2227         ]),
  2227         ]),
  2228         _coords = this.toModelCoords(_point),
  2228         _coords = this.toModelCoords(_point),
  2237             position: {
  2237             position: {
  2238                 x: _coords.x,
  2238                 x: _coords.x,
  2239                 y: _coords.y
  2239                 y: _coords.y
  2240             }
  2240             }
  2241         };
  2241         };
  2242 	var _node = this.renkan.project.addNode(_nodedata),
  2242     var _node = this.renkan.project.addNode(_nodedata),
  2243 		_repr = this.getRepresentationByModel(_node);
  2243         _repr = this.getRepresentationByModel(_node);
  2244 	if (_event.type === "drop") {
  2244     if (_event.type === "drop") {
  2245     	_repr.openEditor();
  2245         _repr.openEditor();
  2246     }
  2246     }
  2247 }
  2247 }