Automatic commit Wed Jan 22 03:00:07 PST 2014

This commit is contained in:
ellen.spertus 2014-01-22 03:00:07 -08:00
parent 63d30fda56
commit c7a1b36c86
20 changed files with 1188 additions and 114 deletions

View file

@ -76,15 +76,15 @@ Puzzle.init = function() {
var blocksCities = [];
var i = 1;
while (BlocklyApps.getMsgOrNull('Puzzle_country' + i)) {
var block = new Blockly.Block(Blockly.mainWorkspace, 'country');
var block = Blockly.Block.obtain(Blockly.mainWorkspace, 'country');
block.populate(i);
blocksCountries.push(block);
var block = new Blockly.Block(Blockly.mainWorkspace, 'flag');
var block = Blockly.Block.obtain(Blockly.mainWorkspace, 'flag');
block.populate(i);
blocksFlags.push(block);
var j = 1;
while (BlocklyApps.getMsgOrNull('Puzzle_country' + i + 'City' + j)) {
var block = new Blockly.Block(Blockly.mainWorkspace, 'city');
var block = Blockly.Block.obtain(Blockly.mainWorkspace, 'city');
block.populate(i, j);
blocksCities.push(block);
j++;

View file

@ -94,7 +94,7 @@ goog.array.zip=function(a){if(!arguments.length)return[];for(var b=[],c=0;;c++){
goog.debug.entryPointRegistry.monitorAll=function(a){goog.debug.entryPointRegistry.monitorsMayExist_=!0;for(var b=goog.bind(a.wrap,a),c=0;c<goog.debug.entryPointRegistry.refList_.length;c++)goog.debug.entryPointRegistry.refList_[c](b);goog.debug.entryPointRegistry.monitors_.push(a)};
goog.debug.entryPointRegistry.unmonitorAllIfPossible=function(a){var b=goog.debug.entryPointRegistry.monitors_;goog.asserts.assert(a==b[b.length-1],"Only the most recent monitor can be unwrapped.");a=goog.bind(a.unwrap,a);for(var c=0;c<goog.debug.entryPointRegistry.refList_.length;c++)goog.debug.entryPointRegistry.refList_[c](a);b.length--};goog.events={};
goog.events.BrowserFeature={HAS_W3C_BUTTON:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),HAS_W3C_EVENT_SUPPORT:!goog.userAgent.IE||goog.userAgent.isDocumentModeOrHigher(9),SET_KEY_CODE_TO_PREVENT_DEFAULT:goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),HAS_NAVIGATOR_ONLINE_PROPERTY:!goog.userAgent.WEBKIT||goog.userAgent.isVersionOrHigher("528"),HAS_HTML5_NETWORK_EVENT_SUPPORT:goog.userAgent.GECKO&&goog.userAgent.isVersionOrHigher("1.9b")||goog.userAgent.IE&&goog.userAgent.isVersionOrHigher("8")||
goog.userAgent.OPERA&&goog.userAgent.isVersionOrHigher("9.5")||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("528"),HTML5_NETWORK_EVENTS_FIRE_ON_BODY:goog.userAgent.GECKO&&!goog.userAgent.isVersionOrHigher("8")||goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),TOUCH_ENABLED:"ontouchstart"in goog.global||!!(goog.global.document&&document.documentElement&&"ontouchstart"in document.documentElement)||!(!goog.global.navigator||!goog.global.navigator.msMaxTouchPoints)};goog.events.Event=function(a,b){this.type=a;this.currentTarget=this.target=b};goog.events.Event.prototype.disposeInternal=function(){};goog.events.Event.prototype.dispose=function(){};goog.events.Event.prototype.propagationStopped_=!1;goog.events.Event.prototype.defaultPrevented=!1;goog.events.Event.prototype.returnValue_=!0;goog.events.Event.prototype.stopPropagation=function(){this.propagationStopped_=!0};
goog.userAgent.OPERA&&goog.userAgent.isVersionOrHigher("9.5")||goog.userAgent.WEBKIT&&goog.userAgent.isVersionOrHigher("528"),HTML5_NETWORK_EVENTS_FIRE_ON_BODY:goog.userAgent.GECKO&&!goog.userAgent.isVersionOrHigher("8")||goog.userAgent.IE&&!goog.userAgent.isVersionOrHigher("9"),TOUCH_ENABLED:"ontouchstart"in goog.global||!!(goog.global.document&&document.documentElement&&"ontouchstart"in document.documentElement)||!(!goog.global.navigator||!goog.global.navigator.msMaxTouchPoints)};goog.events.EventId=function(a){this.id=a};goog.events.EventId.prototype.toString=function(){return this.id};goog.events.Event=function(a,b){this.type=a instanceof goog.events.EventId?String(a):a;this.currentTarget=this.target=b};goog.events.Event.prototype.disposeInternal=function(){};goog.events.Event.prototype.dispose=function(){};goog.events.Event.prototype.propagationStopped_=!1;goog.events.Event.prototype.defaultPrevented=!1;goog.events.Event.prototype.returnValue_=!0;goog.events.Event.prototype.stopPropagation=function(){this.propagationStopped_=!0};
goog.events.Event.prototype.preventDefault=function(){this.defaultPrevented=!0;this.returnValue_=!1};goog.events.Event.stopPropagation=function(a){a.stopPropagation()};goog.events.Event.preventDefault=function(a){a.preventDefault()};goog.events.getVendorPrefixedName_=function(a){return goog.userAgent.WEBKIT?"webkit"+a:goog.userAgent.OPERA?"o"+a.toLowerCase():a.toLowerCase()};
goog.events.EventType={CLICK:"click",DBLCLICK:"dblclick",MOUSEDOWN:"mousedown",MOUSEUP:"mouseup",MOUSEOVER:"mouseover",MOUSEOUT:"mouseout",MOUSEMOVE:"mousemove",MOUSEENTER:"mouseenter",MOUSELEAVE:"mouseleave",SELECTSTART:"selectstart",KEYPRESS:"keypress",KEYDOWN:"keydown",KEYUP:"keyup",BLUR:"blur",FOCUS:"focus",DEACTIVATE:"deactivate",FOCUSIN:goog.userAgent.IE?"focusin":"DOMFocusIn",FOCUSOUT:goog.userAgent.IE?"focusout":"DOMFocusOut",CHANGE:"change",SELECT:"select",SUBMIT:"submit",INPUT:"input",PROPERTYCHANGE:"propertychange",
DRAGSTART:"dragstart",DRAG:"drag",DRAGENTER:"dragenter",DRAGOVER:"dragover",DRAGLEAVE:"dragleave",DROP:"drop",DRAGEND:"dragend",TOUCHSTART:"touchstart",TOUCHMOVE:"touchmove",TOUCHEND:"touchend",TOUCHCANCEL:"touchcancel",BEFOREUNLOAD:"beforeunload",CONSOLEMESSAGE:"consolemessage",CONTEXTMENU:"contextmenu",DOMCONTENTLOADED:"DOMContentLoaded",ERROR:"error",HELP:"help",LOAD:"load",LOSECAPTURE:"losecapture",ORIENTATIONCHANGE:"orientationchange",READYSTATECHANGE:"readystatechange",RESIZE:"resize",SCROLL:"scroll",
@ -108,7 +108,7 @@ goog.events.BrowserEvent.prototype.init=function(a,b){var c=this.type=a.type;goo
a.offsetY?a.offsetY:a.layerY;this.clientX=void 0!==a.clientX?a.clientX:a.pageX;this.clientY=void 0!==a.clientY?a.clientY:a.pageY;this.screenX=a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.platformModifierKey=goog.userAgent.MAC?a.metaKey:a.ctrlKey;this.state=a.state;this.event_=a;a.defaultPrevented&&this.preventDefault();
delete this.propagationStopped_};goog.events.BrowserEvent.prototype.isButton=function(a){return goog.events.BrowserFeature.HAS_W3C_BUTTON?this.event_.button==a:"click"==this.type?a==goog.events.BrowserEvent.MouseButton.LEFT:!!(this.event_.button&goog.events.BrowserEvent.IEButtonMap[a])};goog.events.BrowserEvent.prototype.isMouseActionButton=function(){return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT)&&!(goog.userAgent.WEBKIT&&goog.userAgent.MAC&&this.ctrlKey)};
goog.events.BrowserEvent.prototype.stopPropagation=function(){goog.events.BrowserEvent.superClass_.stopPropagation.call(this);this.event_.stopPropagation?this.event_.stopPropagation():this.event_.cancelBubble=!0};
goog.events.BrowserEvent.prototype.preventDefault=function(){goog.events.BrowserEvent.superClass_.preventDefault.call(this);var a=this.event_;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};goog.events.BrowserEvent.prototype.getBrowserEvent=function(){return this.event_};goog.events.BrowserEvent.prototype.disposeInternal=function(){};goog.events.EventId=function(a){this.id=a};goog.events.EventId.prototype.toString=function(){return this.id};goog.events.Listenable=function(){};goog.events.Listenable.IMPLEMENTED_BY_PROP="closure_listenable_"+(1E6*Math.random()|0);goog.events.Listenable.addImplementation=function(a){a.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP]=!0};goog.events.Listenable.isImplementedBy=function(a){try{return!(!a||!a[goog.events.Listenable.IMPLEMENTED_BY_PROP])}catch(b){return!1}};goog.events.ListenableKey=function(){};goog.events.ListenableKey.counter_=0;goog.events.ListenableKey.reserveKey=function(){return++goog.events.ListenableKey.counter_};goog.events.Listener=function(a,b,c,d,e,f){goog.events.Listener.ENABLE_MONITORING&&(this.creationStack=Error().stack);this.listener=a;this.proxy=b;this.src=c;this.type=d;this.capture=!!e;this.handler=f;this.key=goog.events.ListenableKey.reserveKey();this.removed=this.callOnce=!1};goog.events.Listener.ENABLE_MONITORING=!1;goog.events.Listener.prototype.markAsRemoved=function(){this.removed=!0;this.handler=this.src=this.proxy=this.listener=null};goog.object={};goog.object.forEach=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)};goog.object.filter=function(a,b,c){var d={},e;for(e in a)b.call(c,a[e],e,a)&&(d[e]=a[e]);return d};goog.object.map=function(a,b,c){var d={},e;for(e in a)d[e]=b.call(c,a[e],e,a);return d};goog.object.some=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return!0;return!1};goog.object.every=function(a,b,c){for(var d in a)if(!b.call(c,a[d],d,a))return!1;return!0};
goog.events.BrowserEvent.prototype.preventDefault=function(){goog.events.BrowserEvent.superClass_.preventDefault.call(this);var a=this.event_;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};goog.events.BrowserEvent.prototype.getBrowserEvent=function(){return this.event_};goog.events.BrowserEvent.prototype.disposeInternal=function(){};goog.events.Listenable=function(){};goog.events.Listenable.IMPLEMENTED_BY_PROP="closure_listenable_"+(1E6*Math.random()|0);goog.events.Listenable.addImplementation=function(a){a.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP]=!0};goog.events.Listenable.isImplementedBy=function(a){try{return!(!a||!a[goog.events.Listenable.IMPLEMENTED_BY_PROP])}catch(b){return!1}};goog.events.ListenableKey=function(){};goog.events.ListenableKey.counter_=0;goog.events.ListenableKey.reserveKey=function(){return++goog.events.ListenableKey.counter_};goog.events.Listener=function(a,b,c,d,e,f){goog.events.Listener.ENABLE_MONITORING&&(this.creationStack=Error().stack);this.listener=a;this.proxy=b;this.src=c;this.type=d;this.capture=!!e;this.handler=f;this.key=goog.events.ListenableKey.reserveKey();this.removed=this.callOnce=!1};goog.events.Listener.ENABLE_MONITORING=!1;goog.events.Listener.prototype.markAsRemoved=function(){this.removed=!0;this.handler=this.src=this.proxy=this.listener=null};goog.object={};goog.object.forEach=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)};goog.object.filter=function(a,b,c){var d={},e;for(e in a)b.call(c,a[e],e,a)&&(d[e]=a[e]);return d};goog.object.map=function(a,b,c){var d={},e;for(e in a)d[e]=b.call(c,a[e],e,a);return d};goog.object.some=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return!0;return!1};goog.object.every=function(a,b,c){for(var d in a)if(!b.call(c,a[d],d,a))return!1;return!0};
goog.object.getCount=function(a){var b=0,c;for(c in a)b++;return b};goog.object.getAnyKey=function(a){for(var b in a)return b};goog.object.getAnyValue=function(a){for(var b in a)return a[b]};goog.object.contains=function(a,b){return goog.object.containsValue(a,b)};goog.object.getValues=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};goog.object.getKeys=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b};
goog.object.getValueByKeys=function(a,b){for(var c=goog.isArrayLike(b),d=c?b:arguments,c=c?0:1;c<d.length&&(a=a[d[c]],goog.isDef(a));c++);return a};goog.object.containsKey=function(a,b){return b in a};goog.object.containsValue=function(a,b){for(var c in a)if(a[c]==b)return!0;return!1};goog.object.findKey=function(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};goog.object.findValue=function(a,b,c){return(b=goog.object.findKey(a,b,c))&&a[b]};
goog.object.isEmpty=function(a){for(var b in a)return!1;return!0};goog.object.clear=function(a){for(var b in a)delete a[b]};goog.object.remove=function(a,b){var c;(c=b in a)&&delete a[b];return c};goog.object.add=function(a,b,c){if(b in a)throw Error('The object already contains the key "'+b+'"');goog.object.set(a,b,c)};goog.object.get=function(a,b,c){return b in a?a[b]:c};goog.object.set=function(a,b,c){a[b]=c};goog.object.setIfUndefined=function(a,b,c){return b in a?a[b]:a[b]=c};
@ -189,7 +189,7 @@ goog.math.Size.prototype.fitsInside=function(a){return this.width<=a.width&&this
goog.math.Size.prototype.scaleToFit=function(a){a=this.aspectRatio()>a.aspectRatio()?a.width/this.width:a.height/this.height;return this.scale(a)};goog.dom.ASSUME_QUIRKS_MODE=!1;goog.dom.ASSUME_STANDARDS_MODE=!1;goog.dom.COMPAT_MODE_KNOWN_=goog.dom.ASSUME_QUIRKS_MODE||goog.dom.ASSUME_STANDARDS_MODE;goog.dom.getDomHelper=function(a){return a?new goog.dom.DomHelper(goog.dom.getOwnerDocument(a)):goog.dom.defaultDomHelper_||(goog.dom.defaultDomHelper_=new goog.dom.DomHelper)};goog.dom.getDocument=function(){return document};goog.dom.getElement=function(a){return goog.dom.getElementHelper_(document,a)};
goog.dom.getElementHelper_=function(a,b){return goog.isString(b)?a.getElementById(b):b};goog.dom.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(document,a)};goog.dom.getRequiredElementHelper_=function(a,b){goog.asserts.assertString(b);var c=goog.dom.getElementHelper_(a,b);return c=goog.asserts.assertElement(c,"No element found with id: "+b)};goog.dom.$=goog.dom.getElement;
goog.dom.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(document,a,b,c)};goog.dom.getElementsByClass=function(a,b){var c=b||document;return goog.dom.canUseQuerySelector_(c)?c.querySelectorAll("."+a):c.getElementsByClassName?c.getElementsByClassName(a):goog.dom.getElementsByTagNameAndClass_(document,"*",a,b)};
goog.dom.getElementByClass=function(a,b){var c=b||document,d=null;return(d=goog.dom.canUseQuerySelector_(c)?c.querySelector("."+a):goog.dom.getElementsByClass(a,b)[0])||null};goog.dom.canUseQuerySelector_=function(a){return!(!a.querySelectorAll||!a.querySelector)};
goog.dom.getElementByClass=function(a,b){var c=b||document,d=null;return(d=goog.dom.canUseQuerySelector_(c)?c.querySelector("."+a):goog.dom.getElementsByClass(a,b)[0])||null};goog.dom.getRequiredElementByClass=function(a,b){var c=goog.dom.getElementByClass(a,b);return goog.asserts.assert(c,"No element found with className: "+a)};goog.dom.canUseQuerySelector_=function(a){return!(!a.querySelectorAll||!a.querySelector)};
goog.dom.getElementsByTagNameAndClass_=function(a,b,c,d){a=d||a;b=b&&"*"!=b?b.toUpperCase():"";if(goog.dom.canUseQuerySelector_(a)&&(b||c))return a.querySelectorAll(b+(c?"."+c:""));if(c&&a.getElementsByClassName){a=a.getElementsByClassName(c);if(b){d={};for(var e=0,f=0,g;g=a[f];f++)b==g.nodeName&&(d[e++]=g);d.length=e;return d}return a}a=a.getElementsByTagName(b||"*");if(c){d={};for(f=e=0;g=a[f];f++)b=g.className,"function"==typeof b.split&&goog.array.contains(b.split(/\s+/),c)&&(d[e++]=g);d.length=
e;return d}return a};goog.dom.$$=goog.dom.getElementsByTagNameAndClass;goog.dom.setProperties=function(a,b){goog.object.forEach(b,function(b,d){"style"==d?a.style.cssText=b:"class"==d?a.className=b:"for"==d?a.htmlFor=b:d in goog.dom.DIRECT_ATTRIBUTE_MAP_?a.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[d],b):goog.string.startsWith(d,"aria-")||goog.string.startsWith(d,"data-")?a.setAttribute(d,b):a[d]=b})};
goog.dom.DIRECT_ATTRIBUTE_MAP_={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"};goog.dom.getViewportSize=function(a){return goog.dom.getViewportSize_(a||window)};goog.dom.getViewportSize_=function(a){a=a.document;a=goog.dom.isCss1CompatMode_(a)?a.documentElement:a.body;return new goog.math.Size(a.clientWidth,a.clientHeight)};
@ -228,16 +228,16 @@ goog.dom.getAncestorByClass=function(a,b){return goog.dom.getAncestorByTagNameAn
goog.dom.getPixelRatio=goog.functions.cacheReturnValue(function(){var a=goog.dom.getWindow(),b=goog.userAgent.GECKO&&goog.userAgent.MOBILE;return goog.isDef(a.devicePixelRatio)&&!b?a.devicePixelRatio:a.matchMedia?goog.dom.matchesPixelRatio_(0.75)||goog.dom.matchesPixelRatio_(1.5)||goog.dom.matchesPixelRatio_(2)||goog.dom.matchesPixelRatio_(3)||1:1});
goog.dom.matchesPixelRatio_=function(a){return goog.dom.getWindow().matchMedia("(-webkit-min-device-pixel-ratio: "+a+"),(min--moz-device-pixel-ratio: "+a+"),(min-resolution: "+a+"dppx)").matches?a:0};goog.dom.DomHelper=function(a){this.document_=a||goog.global.document||document};goog.dom.DomHelper.prototype.getDomHelper=goog.dom.getDomHelper;goog.dom.DomHelper.prototype.setDocument=function(a){this.document_=a};goog.dom.DomHelper.prototype.getDocument=function(){return this.document_};
goog.dom.DomHelper.prototype.getElement=function(a){return goog.dom.getElementHelper_(this.document_,a)};goog.dom.DomHelper.prototype.getRequiredElement=function(a){return goog.dom.getRequiredElementHelper_(this.document_,a)};goog.dom.DomHelper.prototype.$=goog.dom.DomHelper.prototype.getElement;goog.dom.DomHelper.prototype.getElementsByTagNameAndClass=function(a,b,c){return goog.dom.getElementsByTagNameAndClass_(this.document_,a,b,c)};
goog.dom.DomHelper.prototype.getElementsByClass=function(a,b){return goog.dom.getElementsByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.getElementByClass=function(a,b){return goog.dom.getElementByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.$$=goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;goog.dom.DomHelper.prototype.setProperties=goog.dom.setProperties;goog.dom.DomHelper.prototype.getViewportSize=function(a){return goog.dom.getViewportSize(a||this.getWindow())};
goog.dom.DomHelper.prototype.getDocumentHeight=function(){return goog.dom.getDocumentHeight_(this.getWindow())};goog.dom.DomHelper.prototype.createDom=function(a,b,c){return goog.dom.createDom_(this.document_,arguments)};goog.dom.DomHelper.prototype.$dom=goog.dom.DomHelper.prototype.createDom;goog.dom.DomHelper.prototype.createElement=function(a){return this.document_.createElement(a)};goog.dom.DomHelper.prototype.createTextNode=function(a){return this.document_.createTextNode(String(a))};
goog.dom.DomHelper.prototype.createTable=function(a,b,c){return goog.dom.createTable_(this.document_,a,b,!!c)};goog.dom.DomHelper.prototype.htmlToDocumentFragment=function(a){return goog.dom.htmlToDocumentFragment_(this.document_,a)};goog.dom.DomHelper.prototype.isCss1CompatMode=function(){return goog.dom.isCss1CompatMode_(this.document_)};goog.dom.DomHelper.prototype.getWindow=function(){return goog.dom.getWindow_(this.document_)};goog.dom.DomHelper.prototype.getDocumentScrollElement=function(){return goog.dom.getDocumentScrollElement_(this.document_)};
goog.dom.DomHelper.prototype.getDocumentScroll=function(){return goog.dom.getDocumentScroll_(this.document_)};goog.dom.DomHelper.prototype.getActiveElement=function(a){return goog.dom.getActiveElement(a||this.document_)};goog.dom.DomHelper.prototype.appendChild=goog.dom.appendChild;goog.dom.DomHelper.prototype.append=goog.dom.append;goog.dom.DomHelper.prototype.canHaveChildren=goog.dom.canHaveChildren;goog.dom.DomHelper.prototype.removeChildren=goog.dom.removeChildren;
goog.dom.DomHelper.prototype.insertSiblingBefore=goog.dom.insertSiblingBefore;goog.dom.DomHelper.prototype.insertSiblingAfter=goog.dom.insertSiblingAfter;goog.dom.DomHelper.prototype.insertChildAt=goog.dom.insertChildAt;goog.dom.DomHelper.prototype.removeNode=goog.dom.removeNode;goog.dom.DomHelper.prototype.replaceNode=goog.dom.replaceNode;goog.dom.DomHelper.prototype.flattenElement=goog.dom.flattenElement;goog.dom.DomHelper.prototype.getChildren=goog.dom.getChildren;
goog.dom.DomHelper.prototype.getFirstElementChild=goog.dom.getFirstElementChild;goog.dom.DomHelper.prototype.getLastElementChild=goog.dom.getLastElementChild;goog.dom.DomHelper.prototype.getNextElementSibling=goog.dom.getNextElementSibling;goog.dom.DomHelper.prototype.getPreviousElementSibling=goog.dom.getPreviousElementSibling;goog.dom.DomHelper.prototype.getNextNode=goog.dom.getNextNode;goog.dom.DomHelper.prototype.getPreviousNode=goog.dom.getPreviousNode;
goog.dom.DomHelper.prototype.isNodeLike=goog.dom.isNodeLike;goog.dom.DomHelper.prototype.isElement=goog.dom.isElement;goog.dom.DomHelper.prototype.isWindow=goog.dom.isWindow;goog.dom.DomHelper.prototype.getParentElement=goog.dom.getParentElement;goog.dom.DomHelper.prototype.contains=goog.dom.contains;goog.dom.DomHelper.prototype.compareNodeOrder=goog.dom.compareNodeOrder;goog.dom.DomHelper.prototype.findCommonAncestor=goog.dom.findCommonAncestor;goog.dom.DomHelper.prototype.getOwnerDocument=goog.dom.getOwnerDocument;
goog.dom.DomHelper.prototype.getFrameContentDocument=goog.dom.getFrameContentDocument;goog.dom.DomHelper.prototype.getFrameContentWindow=goog.dom.getFrameContentWindow;goog.dom.DomHelper.prototype.setTextContent=goog.dom.setTextContent;goog.dom.DomHelper.prototype.getOuterHtml=goog.dom.getOuterHtml;goog.dom.DomHelper.prototype.findNode=goog.dom.findNode;goog.dom.DomHelper.prototype.findNodes=goog.dom.findNodes;goog.dom.DomHelper.prototype.isFocusableTabIndex=goog.dom.isFocusableTabIndex;
goog.dom.DomHelper.prototype.setFocusableTabIndex=goog.dom.setFocusableTabIndex;goog.dom.DomHelper.prototype.isFocusable=goog.dom.isFocusable;goog.dom.DomHelper.prototype.getTextContent=goog.dom.getTextContent;goog.dom.DomHelper.prototype.getNodeTextLength=goog.dom.getNodeTextLength;goog.dom.DomHelper.prototype.getNodeTextOffset=goog.dom.getNodeTextOffset;goog.dom.DomHelper.prototype.getNodeAtOffset=goog.dom.getNodeAtOffset;goog.dom.DomHelper.prototype.isNodeList=goog.dom.isNodeList;
goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass=goog.dom.getAncestorByTagNameAndClass;goog.dom.DomHelper.prototype.getAncestorByClass=goog.dom.getAncestorByClass;goog.dom.DomHelper.prototype.getAncestor=goog.dom.getAncestor;goog.dom.vendor={};goog.dom.vendor.getVendorJsPrefix=function(){return goog.userAgent.WEBKIT?"Webkit":goog.userAgent.GECKO?"Moz":goog.userAgent.IE?"ms":goog.userAgent.OPERA?"O":null};goog.dom.vendor.getVendorPrefix=function(){return goog.userAgent.WEBKIT?"-webkit":goog.userAgent.GECKO?"-moz":goog.userAgent.IE?"-ms":goog.userAgent.OPERA?"-o":null};
goog.dom.DomHelper.prototype.getElementsByClass=function(a,b){return goog.dom.getElementsByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.getElementByClass=function(a,b){return goog.dom.getElementByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.getRequiredElementByClass=function(a,b){return goog.dom.getRequiredElementByClass(a,b||this.document_)};goog.dom.DomHelper.prototype.$$=goog.dom.DomHelper.prototype.getElementsByTagNameAndClass;
goog.dom.DomHelper.prototype.setProperties=goog.dom.setProperties;goog.dom.DomHelper.prototype.getViewportSize=function(a){return goog.dom.getViewportSize(a||this.getWindow())};goog.dom.DomHelper.prototype.getDocumentHeight=function(){return goog.dom.getDocumentHeight_(this.getWindow())};goog.dom.DomHelper.prototype.createDom=function(a,b,c){return goog.dom.createDom_(this.document_,arguments)};goog.dom.DomHelper.prototype.$dom=goog.dom.DomHelper.prototype.createDom;
goog.dom.DomHelper.prototype.createElement=function(a){return this.document_.createElement(a)};goog.dom.DomHelper.prototype.createTextNode=function(a){return this.document_.createTextNode(String(a))};goog.dom.DomHelper.prototype.createTable=function(a,b,c){return goog.dom.createTable_(this.document_,a,b,!!c)};goog.dom.DomHelper.prototype.htmlToDocumentFragment=function(a){return goog.dom.htmlToDocumentFragment_(this.document_,a)};goog.dom.DomHelper.prototype.isCss1CompatMode=function(){return goog.dom.isCss1CompatMode_(this.document_)};
goog.dom.DomHelper.prototype.getWindow=function(){return goog.dom.getWindow_(this.document_)};goog.dom.DomHelper.prototype.getDocumentScrollElement=function(){return goog.dom.getDocumentScrollElement_(this.document_)};goog.dom.DomHelper.prototype.getDocumentScroll=function(){return goog.dom.getDocumentScroll_(this.document_)};goog.dom.DomHelper.prototype.getActiveElement=function(a){return goog.dom.getActiveElement(a||this.document_)};goog.dom.DomHelper.prototype.appendChild=goog.dom.appendChild;
goog.dom.DomHelper.prototype.append=goog.dom.append;goog.dom.DomHelper.prototype.canHaveChildren=goog.dom.canHaveChildren;goog.dom.DomHelper.prototype.removeChildren=goog.dom.removeChildren;goog.dom.DomHelper.prototype.insertSiblingBefore=goog.dom.insertSiblingBefore;goog.dom.DomHelper.prototype.insertSiblingAfter=goog.dom.insertSiblingAfter;goog.dom.DomHelper.prototype.insertChildAt=goog.dom.insertChildAt;goog.dom.DomHelper.prototype.removeNode=goog.dom.removeNode;
goog.dom.DomHelper.prototype.replaceNode=goog.dom.replaceNode;goog.dom.DomHelper.prototype.flattenElement=goog.dom.flattenElement;goog.dom.DomHelper.prototype.getChildren=goog.dom.getChildren;goog.dom.DomHelper.prototype.getFirstElementChild=goog.dom.getFirstElementChild;goog.dom.DomHelper.prototype.getLastElementChild=goog.dom.getLastElementChild;goog.dom.DomHelper.prototype.getNextElementSibling=goog.dom.getNextElementSibling;goog.dom.DomHelper.prototype.getPreviousElementSibling=goog.dom.getPreviousElementSibling;
goog.dom.DomHelper.prototype.getNextNode=goog.dom.getNextNode;goog.dom.DomHelper.prototype.getPreviousNode=goog.dom.getPreviousNode;goog.dom.DomHelper.prototype.isNodeLike=goog.dom.isNodeLike;goog.dom.DomHelper.prototype.isElement=goog.dom.isElement;goog.dom.DomHelper.prototype.isWindow=goog.dom.isWindow;goog.dom.DomHelper.prototype.getParentElement=goog.dom.getParentElement;goog.dom.DomHelper.prototype.contains=goog.dom.contains;goog.dom.DomHelper.prototype.compareNodeOrder=goog.dom.compareNodeOrder;
goog.dom.DomHelper.prototype.findCommonAncestor=goog.dom.findCommonAncestor;goog.dom.DomHelper.prototype.getOwnerDocument=goog.dom.getOwnerDocument;goog.dom.DomHelper.prototype.getFrameContentDocument=goog.dom.getFrameContentDocument;goog.dom.DomHelper.prototype.getFrameContentWindow=goog.dom.getFrameContentWindow;goog.dom.DomHelper.prototype.setTextContent=goog.dom.setTextContent;goog.dom.DomHelper.prototype.getOuterHtml=goog.dom.getOuterHtml;goog.dom.DomHelper.prototype.findNode=goog.dom.findNode;
goog.dom.DomHelper.prototype.findNodes=goog.dom.findNodes;goog.dom.DomHelper.prototype.isFocusableTabIndex=goog.dom.isFocusableTabIndex;goog.dom.DomHelper.prototype.setFocusableTabIndex=goog.dom.setFocusableTabIndex;goog.dom.DomHelper.prototype.isFocusable=goog.dom.isFocusable;goog.dom.DomHelper.prototype.getTextContent=goog.dom.getTextContent;goog.dom.DomHelper.prototype.getNodeTextLength=goog.dom.getNodeTextLength;goog.dom.DomHelper.prototype.getNodeTextOffset=goog.dom.getNodeTextOffset;
goog.dom.DomHelper.prototype.getNodeAtOffset=goog.dom.getNodeAtOffset;goog.dom.DomHelper.prototype.isNodeList=goog.dom.isNodeList;goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass=goog.dom.getAncestorByTagNameAndClass;goog.dom.DomHelper.prototype.getAncestorByClass=goog.dom.getAncestorByClass;goog.dom.DomHelper.prototype.getAncestor=goog.dom.getAncestor;goog.dom.vendor={};goog.dom.vendor.getVendorJsPrefix=function(){return goog.userAgent.WEBKIT?"Webkit":goog.userAgent.GECKO?"Moz":goog.userAgent.IE?"ms":goog.userAgent.OPERA?"O":null};goog.dom.vendor.getVendorPrefix=function(){return goog.userAgent.WEBKIT?"-webkit":goog.userAgent.GECKO?"-moz":goog.userAgent.IE?"-ms":goog.userAgent.OPERA?"-o":null};
goog.dom.vendor.getPrefixedPropertyName=function(a,b){if(b&&a in b)return a;var c=goog.dom.vendor.getVendorJsPrefix();return c?(c=c.toLowerCase(),c+=goog.string.toTitleCase(a),!goog.isDef(b)||c in b?c:null):null};goog.dom.vendor.getPrefixedEventType=function(a){return((goog.dom.vendor.getVendorJsPrefix()||"")+a).toLowerCase()};goog.math.Box=function(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d};goog.math.Box.boundingBox=function(a){for(var b=new goog.math.Box(arguments[0].y,arguments[0].x,arguments[0].y,arguments[0].x),c=1;c<arguments.length;c++){var d=arguments[c];b.top=Math.min(b.top,d.y);b.right=Math.max(b.right,d.x);b.bottom=Math.max(b.bottom,d.y);b.left=Math.min(b.left,d.x)}return b};goog.math.Box.prototype.clone=function(){return new goog.math.Box(this.top,this.right,this.bottom,this.left)};
goog.DEBUG&&(goog.math.Box.prototype.toString=function(){return"("+this.top+"t, "+this.right+"r, "+this.bottom+"b, "+this.left+"l)"});goog.math.Box.prototype.contains=function(a){return goog.math.Box.contains(this,a)};goog.math.Box.prototype.expand=function(a,b,c,d){goog.isObject(a)?(this.top-=a.top,this.right+=a.right,this.bottom+=a.bottom,this.left-=a.left):(this.top-=a,this.right+=b,this.bottom+=c,this.left-=d);return this};
goog.math.Box.prototype.expandToInclude=function(a){this.left=Math.min(this.left,a.left);this.top=Math.min(this.top,a.top);this.right=Math.max(this.right,a.right);this.bottom=Math.max(this.bottom,a.bottom)};goog.math.Box.equals=function(a,b){return a==b?!0:a&&b?a.top==b.top&&a.right==b.right&&a.bottom==b.bottom&&a.left==b.left:!1};
@ -315,11 +315,12 @@ d&&b==a)return!1;switch(a){case goog.events.KeyCodes.ENTER:return!(goog.userAgen
goog.events.KeyCodes.isCharacterKey=function(a){if(a>=goog.events.KeyCodes.ZERO&&a<=goog.events.KeyCodes.NINE||a>=goog.events.KeyCodes.NUM_ZERO&&a<=goog.events.KeyCodes.NUM_MULTIPLY||a>=goog.events.KeyCodes.A&&a<=goog.events.KeyCodes.Z||goog.userAgent.WEBKIT&&0==a)return!0;switch(a){case goog.events.KeyCodes.SPACE:case goog.events.KeyCodes.QUESTION_MARK:case goog.events.KeyCodes.NUM_PLUS:case goog.events.KeyCodes.NUM_MINUS:case goog.events.KeyCodes.NUM_PERIOD:case goog.events.KeyCodes.NUM_DIVISION:case goog.events.KeyCodes.SEMICOLON:case goog.events.KeyCodes.FF_SEMICOLON:case goog.events.KeyCodes.DASH:case goog.events.KeyCodes.EQUALS:case goog.events.KeyCodes.FF_EQUALS:case goog.events.KeyCodes.COMMA:case goog.events.KeyCodes.PERIOD:case goog.events.KeyCodes.SLASH:case goog.events.KeyCodes.APOSTROPHE:case goog.events.KeyCodes.SINGLE_QUOTE:case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:case goog.events.KeyCodes.BACKSLASH:case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:return!0;
default:return!1}};goog.events.KeyCodes.normalizeKeyCode=function(a){return goog.userAgent.GECKO?goog.events.KeyCodes.normalizeGeckoKeyCode(a):goog.userAgent.MAC&&goog.userAgent.WEBKIT?goog.events.KeyCodes.normalizeMacWebKitKeyCode(a):a};
goog.events.KeyCodes.normalizeGeckoKeyCode=function(a){switch(a){case goog.events.KeyCodes.FF_EQUALS:return goog.events.KeyCodes.EQUALS;case goog.events.KeyCodes.FF_SEMICOLON:return goog.events.KeyCodes.SEMICOLON;case goog.events.KeyCodes.FF_DASH:return goog.events.KeyCodes.DASH;case goog.events.KeyCodes.MAC_FF_META:return goog.events.KeyCodes.META;case goog.events.KeyCodes.WIN_KEY_FF_LINUX:return goog.events.KeyCodes.WIN_KEY;default:return a}};
goog.events.KeyCodes.normalizeMacWebKitKeyCode=function(a){switch(a){case goog.events.KeyCodes.MAC_WK_CMD_RIGHT:return goog.events.KeyCodes.META;default:return a}};goog.events.EventHandler=function(a){goog.Disposable.call(this);this.handler_=a;this.keys_={}};goog.inherits(goog.events.EventHandler,goog.Disposable);goog.events.EventHandler.typeArray_=[];goog.events.EventHandler.prototype.listen=function(a,b,c,d,e){goog.isArray(b)||(goog.events.EventHandler.typeArray_[0]=b,b=goog.events.EventHandler.typeArray_);for(var f=0;f<b.length;f++){var g=goog.events.listen(a,b[f],c||this.handleEvent,d||!1,e||this.handler_||this);if(!g)break;this.keys_[g.key]=g}return this};
goog.events.EventHandler.prototype.listenOnce=function(a,b,c,d,e){if(goog.isArray(b))for(var f=0;f<b.length;f++)this.listenOnce(a,b[f],c,d,e);else{a=goog.events.listenOnce(a,b,c||this.handleEvent,d,e||this.handler_||this);if(!a)return this;this.keys_[a.key]=a}return this};goog.events.EventHandler.prototype.listenWithWrapper=function(a,b,c,d,e){b.listen(a,c,d,e||this.handler_||this,this);return this};
goog.events.EventHandler.prototype.getListenerCount=function(){var a=0,b;for(b in this.keys_)Object.prototype.hasOwnProperty.call(this.keys_,b)&&a++;return a};goog.events.EventHandler.prototype.unlisten=function(a,b,c,d,e){if(goog.isArray(b))for(var f=0;f<b.length;f++)this.unlisten(a,b[f],c,d,e);else if(a=goog.events.getListener(a,b,c||this.handleEvent,d,e||this.handler_||this))goog.events.unlistenByKey(a),delete this.keys_[a.key];return this};
goog.events.EventHandler.prototype.unlistenWithWrapper=function(a,b,c,d,e){b.unlisten(a,c,d,e||this.handler_||this,this);return this};goog.events.EventHandler.prototype.removeAll=function(){goog.object.forEach(this.keys_,goog.events.unlistenByKey);this.keys_={}};goog.events.EventHandler.prototype.disposeInternal=function(){goog.events.EventHandler.superClass_.disposeInternal.call(this);this.removeAll()};
goog.events.EventHandler.prototype.handleEvent=function(a){throw Error("EventHandler.handleEvent not implemented");};goog.ui={};goog.ui.IdGenerator=function(){};goog.addSingletonGetter(goog.ui.IdGenerator);goog.ui.IdGenerator.prototype.nextId_=0;goog.ui.IdGenerator.prototype.getNextUniqueId=function(){return":"+(this.nextId_++).toString(36)};goog.ui.IdGenerator.instance=goog.ui.IdGenerator.getInstance();goog.ui.Component=function(a){goog.events.EventTarget.call(this);this.dom_=a||goog.dom.getDomHelper();this.rightToLeft_=goog.ui.Component.defaultRightToLeft_};goog.inherits(goog.ui.Component,goog.events.EventTarget);goog.ui.Component.ALLOW_DETACHED_DECORATION=!1;goog.ui.Component.prototype.idGenerator_=goog.ui.IdGenerator.getInstance();goog.ui.Component.defaultRightToLeft_=null;
goog.events.KeyCodes.normalizeMacWebKitKeyCode=function(a){switch(a){case goog.events.KeyCodes.MAC_WK_CMD_RIGHT:return goog.events.KeyCodes.META;default:return a}};goog.events.EventHandler=function(a){goog.Disposable.call(this);this.handler_=a;this.keys_={}};goog.inherits(goog.events.EventHandler,goog.Disposable);goog.events.EventHandler.typeArray_=[];goog.events.EventHandler.prototype.listen=function(a,b,c,d,e){return this.listen_(a,b,c,d,e)};goog.events.EventHandler.prototype.listenWithScope=function(a,b,c,d,e){return this.listen_(a,b,c,d,e)};
goog.events.EventHandler.prototype.listen_=function(a,b,c,d,e){goog.isArray(b)||(goog.events.EventHandler.typeArray_[0]=b,b=goog.events.EventHandler.typeArray_);for(var f=0;f<b.length;f++){var g=goog.events.listen(a,b[f],c||this.handleEvent,d||!1,e||this.handler_||this);if(!g)break;this.keys_[g.key]=g}return this};goog.events.EventHandler.prototype.listenOnce=function(a,b,c,d,e){return this.listenOnce_(a,b,c,d,e)};
goog.events.EventHandler.prototype.listenOnceWithScope=function(a,b,c,d,e){return this.listenOnce_(a,b,c,d,e)};goog.events.EventHandler.prototype.listenOnce_=function(a,b,c,d,e){if(goog.isArray(b))for(var f=0;f<b.length;f++)this.listenOnce(a,b[f],c,d,e);else{a=goog.events.listenOnce(a,b,c||this.handleEvent,d,e||this.handler_||this);if(!a)return this;this.keys_[a.key]=a}return this};goog.events.EventHandler.prototype.listenWithWrapper=function(a,b,c,d,e){return this.listenWithWrapper_(a,b,c,d,e)};
goog.events.EventHandler.prototype.listenWithWrapperAndScope=function(a,b,c,d,e){return this.listenWithWrapper_(a,b,c,d,e)};goog.events.EventHandler.prototype.listenWithWrapper_=function(a,b,c,d,e){b.listen(a,c,d,e||this.handler_||this,this);return this};goog.events.EventHandler.prototype.getListenerCount=function(){var a=0,b;for(b in this.keys_)Object.prototype.hasOwnProperty.call(this.keys_,b)&&a++;return a};
goog.events.EventHandler.prototype.unlisten=function(a,b,c,d,e){if(goog.isArray(b))for(var f=0;f<b.length;f++)this.unlisten(a,b[f],c,d,e);else if(a=goog.events.getListener(a,b,c||this.handleEvent,d,e||this.handler_||this))goog.events.unlistenByKey(a),delete this.keys_[a.key];return this};goog.events.EventHandler.prototype.unlistenWithWrapper=function(a,b,c,d,e){b.unlisten(a,c,d,e||this.handler_||this,this);return this};
goog.events.EventHandler.prototype.removeAll=function(){goog.object.forEach(this.keys_,goog.events.unlistenByKey);this.keys_={}};goog.events.EventHandler.prototype.disposeInternal=function(){goog.events.EventHandler.superClass_.disposeInternal.call(this);this.removeAll()};goog.events.EventHandler.prototype.handleEvent=function(a){throw Error("EventHandler.handleEvent not implemented");};goog.ui={};goog.ui.IdGenerator=function(){};goog.addSingletonGetter(goog.ui.IdGenerator);goog.ui.IdGenerator.prototype.nextId_=0;goog.ui.IdGenerator.prototype.getNextUniqueId=function(){return":"+(this.nextId_++).toString(36)};goog.ui.Component=function(a){goog.events.EventTarget.call(this);this.dom_=a||goog.dom.getDomHelper();this.rightToLeft_=goog.ui.Component.defaultRightToLeft_};goog.inherits(goog.ui.Component,goog.events.EventTarget);goog.ui.Component.ALLOW_DETACHED_DECORATION=!1;goog.ui.Component.prototype.idGenerator_=goog.ui.IdGenerator.getInstance();goog.ui.Component.defaultRightToLeft_=null;
goog.ui.Component.EventType={BEFORE_SHOW:"beforeshow",SHOW:"show",HIDE:"hide",DISABLE:"disable",ENABLE:"enable",HIGHLIGHT:"highlight",UNHIGHLIGHT:"unhighlight",ACTIVATE:"activate",DEACTIVATE:"deactivate",SELECT:"select",UNSELECT:"unselect",CHECK:"check",UNCHECK:"uncheck",FOCUS:"focus",BLUR:"blur",OPEN:"open",CLOSE:"close",ENTER:"enter",LEAVE:"leave",ACTION:"action",CHANGE:"change"};
goog.ui.Component.Error={NOT_SUPPORTED:"Method not supported",DECORATE_INVALID:"Invalid element to decorate",ALREADY_RENDERED:"Component already rendered",PARENT_UNABLE_TO_BE_SET:"Unable to set parent component",CHILD_INDEX_OUT_OF_BOUNDS:"Child component index out of bounds",NOT_OUR_CHILD:"Child is not in parent component",NOT_IN_DOCUMENT:"Operation not supported while component is not in document",STATE_INVALID:"Invalid component state"};
goog.ui.Component.State={ALL:255,DISABLED:1,HOVER:2,ACTIVE:4,SELECTED:8,CHECKED:16,FOCUSED:32,OPENED:64};
@ -371,7 +372,7 @@ goog.a11y.aria.setRole=function(a,b){b?(goog.asserts.ENABLE_ASSERTS&&goog.assert
goog.a11y.aria.setState=function(a,b,c){goog.isArrayLike(c)&&(c=c.join(" "));var d=goog.a11y.aria.getAriaAttributeName_(b);""===c||void 0==c?(c=goog.a11y.aria.datatables.getDefaultValuesMap(),b in c?a.setAttribute(d,c[b]):a.removeAttribute(d)):a.setAttribute(d,c)};goog.a11y.aria.removeState=function(a,b){a.removeAttribute(goog.a11y.aria.getAriaAttributeName_(b))};goog.a11y.aria.getState=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));return null==c||void 0==c?"":String(c)};
goog.a11y.aria.getActiveDescendant=function(a){var b=goog.a11y.aria.getState(a,goog.a11y.aria.State.ACTIVEDESCENDANT);return goog.dom.getOwnerDocument(a).getElementById(b)};goog.a11y.aria.setActiveDescendant=function(a,b){var c="";b&&(c=b.id,goog.asserts.assert(c,"The active element should have an id."));goog.a11y.aria.setState(a,goog.a11y.aria.State.ACTIVEDESCENDANT,c)};goog.a11y.aria.getLabel=function(a){return goog.a11y.aria.getState(a,goog.a11y.aria.State.LABEL)};
goog.a11y.aria.setLabel=function(a,b){goog.a11y.aria.setState(a,goog.a11y.aria.State.LABEL,b)};goog.a11y.aria.assertRoleIsSetInternalUtil=function(a,b){if(!goog.array.contains(goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_,a.tagName)){var c=goog.a11y.aria.getRole(a);goog.asserts.assert(null!=c,"The element ARIA role cannot be null.");goog.asserts.assert(goog.array.contains(b,c),'Non existing or incorrect role set for element.The role set is "'+c+'". The role should be any of "'+b+'". Check the ARIA specification for more details http://www.w3.org/TR/wai-aria/roles.')}};
goog.a11y.aria.getStateBoolean=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert(goog.isBoolean(c)||null==c||"true"==c||"false"==c);return null==c?null:Boolean(c)};goog.a11y.aria.getStateNumber=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert((null==c||!isNaN(Number(c)))&&!goog.isBoolean(c));return null==c?null:Number(c)};
goog.a11y.aria.getStateBoolean=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert(goog.isBoolean(c)||null==c||"true"==c||"false"==c);return null==c?c:goog.isBoolean(c)?c:"true"==c};goog.a11y.aria.getStateNumber=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert((null==c||!isNaN(Number(c)))&&!goog.isBoolean(c));return null==c?null:Number(c)};
goog.a11y.aria.getStateString=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));goog.asserts.assert((null==c||goog.isString(c))&&isNaN(Number(c))&&"true"!=c&&"false"!=c);return null==c?null:c};goog.a11y.aria.getStringArrayStateInternalUtil=function(a,b){var c=a.getAttribute(goog.a11y.aria.getAriaAttributeName_(b));return goog.a11y.aria.splitStringOnWhitespace_(c)};goog.a11y.aria.splitStringOnWhitespace_=function(a){return a?a.split(/\s+/):[]};
goog.a11y.aria.getAriaAttributeName_=function(a){goog.asserts.ENABLE_ASSERTS&&(goog.asserts.assert(a,"ARIA attribute cannot be empty."),goog.asserts.assert(goog.object.containsValue(goog.a11y.aria.State,a),"No such ARIA attribute "+a));return goog.a11y.aria.ARIA_PREFIX_+a};goog.ui.ControlRenderer=function(){};goog.addSingletonGetter(goog.ui.ControlRenderer);goog.ui.ControlRenderer.getCustomRenderer=function(a,b){var c=new a;c.getCssClass=function(){return b};return c};goog.ui.ControlRenderer.CSS_CLASS="goog-control";goog.ui.ControlRenderer.IE6_CLASS_COMBINATIONS=[];goog.ui.ControlRenderer.prototype.getAriaRole=function(){};
goog.ui.ControlRenderer.prototype.createDom=function(a){var b=a.getDomHelper().createDom("div",this.getClassNames(a).join(" "),a.getContent());this.setAriaStates(a,b);return b};goog.ui.ControlRenderer.prototype.getContentElement=function(a){return a};
@ -472,8 +473,8 @@ goog.ui.Palette.prototype.setContentInternal=function(a){goog.ui.Palette.superCl
goog.ui.Palette.prototype.getCaption=function(){return""};goog.ui.Palette.prototype.setCaption=function(a){};goog.ui.Palette.prototype.handleMouseOver=function(a){goog.ui.Palette.superClass_.handleMouseOver.call(this,a);var b=this.getRenderer().getContainingItem(this,a.target);b&&a.relatedTarget&&goog.dom.contains(b,a.relatedTarget)||b!=this.getHighlightedItem()&&this.setHighlightedItem(b)};
goog.ui.Palette.prototype.handleMouseOut=function(a){goog.ui.Palette.superClass_.handleMouseOut.call(this,a);var b=this.getRenderer().getContainingItem(this,a.target);b&&a.relatedTarget&&goog.dom.contains(b,a.relatedTarget)||b==this.getHighlightedItem()&&this.setHighlightedItem(null)};goog.ui.Palette.prototype.handleMouseDown=function(a){goog.ui.Palette.superClass_.handleMouseDown.call(this,a);this.isActive()&&(a=this.getRenderer().getContainingItem(this,a.target),a!=this.getHighlightedItem()&&this.setHighlightedItem(a))};
goog.ui.Palette.prototype.performActionInternal=function(a){var b=this.getHighlightedItem();return b?(this.setSelectedItem(b),goog.ui.Palette.superClass_.performActionInternal.call(this,a)):!1};
goog.ui.Palette.prototype.handleKeyEvent=function(a){var b=this.getContent(),b=b?b.length:0,c=this.size_.width;if(0==b||!this.isEnabled())return!1;if(a.keyCode==goog.events.KeyCodes.ENTER||a.keyCode==goog.events.KeyCodes.SPACE)return this.performActionInternal(a);if(a.keyCode==goog.events.KeyCodes.HOME)return this.setHighlightedIndex(0),!0;if(a.keyCode==goog.events.KeyCodes.END)return this.setHighlightedIndex(b-1),!0;var d=0>this.highlightedIndex_?this.getSelectedIndex():this.highlightedIndex_;switch(a.keyCode){case goog.events.KeyCodes.LEFT:-1==
d&&(d=b);if(0<d)return this.setHighlightedIndex(d-1),a.preventDefault(),!0;break;case goog.events.KeyCodes.RIGHT:if(d<b-1)return this.setHighlightedIndex(d+1),a.preventDefault(),!0;break;case goog.events.KeyCodes.UP:-1==d&&(d=b+c-1);if(d>=c)return this.setHighlightedIndex(d-c),a.preventDefault(),!0;break;case goog.events.KeyCodes.DOWN:if(-1==d&&(d=-c),d<b-c)return this.setHighlightedIndex(d+c),a.preventDefault(),!0}return!1};goog.ui.Palette.prototype.handleSelectionChange=function(a){};
goog.ui.Palette.prototype.handleKeyEvent=function(a){var b=this.getContent(),b=b?b.length:0,c=this.size_.width;if(0==b||!this.isEnabled())return!1;if(a.keyCode==goog.events.KeyCodes.ENTER||a.keyCode==goog.events.KeyCodes.SPACE)return this.performActionInternal(a);if(a.keyCode==goog.events.KeyCodes.HOME)return this.setHighlightedIndex(0),!0;if(a.keyCode==goog.events.KeyCodes.END)return this.setHighlightedIndex(b-1),!0;var d=0>this.highlightedIndex_?this.getSelectedIndex():this.highlightedIndex_;switch(a.keyCode){case goog.events.KeyCodes.LEFT:if(-1==
d||0==d)d=b;this.setHighlightedIndex(d-1);a.preventDefault();return!0;case goog.events.KeyCodes.RIGHT:return d==b-1&&(d=-1),this.setHighlightedIndex(d+1),a.preventDefault(),!0;case goog.events.KeyCodes.UP:-1==d&&(d=b+c-1);if(d>=c)return this.setHighlightedIndex(d-c),a.preventDefault(),!0;break;case goog.events.KeyCodes.DOWN:if(-1==d&&(d=-c),d<b-c)return this.setHighlightedIndex(d+c),a.preventDefault(),!0}return!1};goog.ui.Palette.prototype.handleSelectionChange=function(a){};
goog.ui.Palette.prototype.getSize=function(){return this.size_};goog.ui.Palette.prototype.setSize=function(a,b){if(this.getElement())throw Error(goog.ui.Component.Error.ALREADY_RENDERED);this.size_=goog.isNumber(a)?new goog.math.Size(a,b):a;this.adjustSize_()};goog.ui.Palette.prototype.getHighlightedIndex=function(){return this.highlightedIndex_};goog.ui.Palette.prototype.getHighlightedItem=function(){var a=this.getContent();return a&&a[this.highlightedIndex_]};
goog.ui.Palette.prototype.getHighlightedCellElement_=function(){return this.getRenderer().getCellForItem(this.getHighlightedItem())};goog.ui.Palette.prototype.setHighlightedIndex=function(a){a!=this.highlightedIndex_&&(this.highlightIndex_(this.highlightedIndex_,!1),this.highlightedIndex_=a,this.highlightIndex_(a,!0),this.dispatchEvent(goog.ui.Palette.EventType.AFTER_HIGHLIGHT))};
goog.ui.Palette.prototype.setHighlightedItem=function(a){var b=this.getContent();this.setHighlightedIndex(b?goog.array.indexOf(b,a):-1)};goog.ui.Palette.prototype.getSelectedIndex=function(){return this.selectionModel_?this.selectionModel_.getSelectedIndex():-1};goog.ui.Palette.prototype.getSelectedItem=function(){return this.selectionModel_?this.selectionModel_.getSelectedItem():null};goog.ui.Palette.prototype.setSelectedIndex=function(a){this.selectionModel_&&this.selectionModel_.setSelectedIndex(a)};
@ -702,25 +703,26 @@ this.svgGroup_);this.svgLid_.setAttributeNS("http://www.w3.org/1999/xlink","xlin
Blockly.Trashcan.prototype.position_=function(){var a=this.workspace_.getMetrics();a&&(this.left_=Blockly.RTL?this.MARGIN_SIDE_:a.viewWidth+a.absoluteLeft-this.WIDTH_-this.MARGIN_SIDE_,this.top_=a.viewHeight+a.absoluteTop-(this.BODY_HEIGHT_+this.LID_HEIGHT_)-this.MARGIN_BOTTOM_,this.svgGroup_.setAttribute("transform","translate("+this.left_+","+this.top_+")"))};
Blockly.Trashcan.prototype.onMouseMove=function(a){if(this.svgGroup_){a=Blockly.mouseToSvg(a);var b=Blockly.getSvgXY_(this.svgGroup_);a=a.x>b.x&&a.x<b.x+this.WIDTH_&&a.y>b.y&&a.y<b.y+this.BODY_HEIGHT_+this.LID_HEIGHT_;this.isOpen!=a&&this.setOpen_(a)}};Blockly.Trashcan.prototype.setOpen_=function(a){this.isOpen!=a&&(goog.Timer.clear(this.lidTask_),this.isOpen=a,this.animateLid_())};
Blockly.Trashcan.prototype.animateLid_=function(){this.lidAngle_+=this.isOpen?10:-10;this.lidAngle_=Math.max(0,this.lidAngle_);this.svgLid_.setAttribute("transform","rotate("+(Blockly.RTL?-this.lidAngle_:this.lidAngle_)+", "+(Blockly.RTL?4:this.WIDTH_-4)+", "+(this.LID_HEIGHT_-2)+")");if(this.isOpen?45>this.lidAngle_:0<this.lidAngle_)this.lidTask_=goog.Timer.callOnce(this.animateLid_,5,this)};Blockly.Trashcan.prototype.close=function(){this.setOpen_(!1)};Blockly.Xml={};Blockly.Xml.workspaceToDom=function(a){var b=Blockly.svgSize().width,c=goog.dom.createDom("xml");a=a.getTopBlocks(!0);for(var d=0,e;e=a[d];d++){var f=Blockly.Xml.blockToDom_(e);e=e.getRelativeToSurfaceXY();f.setAttribute("x",Blockly.RTL?b-e.x:e.x);f.setAttribute("y",e.y);c.appendChild(f)}return c};
Blockly.Xml.blockToDom_=function(a){var b=goog.dom.createDom("block");b.setAttribute("type",a.type);if(a.mutationToDom){var c=a.mutationToDom();c&&b.appendChild(c)}for(var d=0;c=a.inputList[d];d++)for(var e=0,f;f=c.fieldRow[e];e++)if(f.name&&f.EDITABLE){var g=goog.dom.createDom("field",null,f.getValue());g.setAttribute("name",f.name);b.appendChild(g)}a.comment&&(c=goog.dom.createDom("comment",null,a.comment.getText()),c.setAttribute("pinned",a.comment.isVisible()),d=a.comment.getBubbleSize(),c.setAttribute("h",
d.height),c.setAttribute("w",d.width),b.appendChild(c));d=!1;for(e=0;c=a.inputList[e];e++){var h;f=!0;c.type!=Blockly.DUMMY_INPUT&&(g=c.connection.targetBlock(),c.type==Blockly.INPUT_VALUE?(h=goog.dom.createDom("value"),d=!0):c.type==Blockly.NEXT_STATEMENT&&(h=goog.dom.createDom("statement")),g&&(h.appendChild(Blockly.Xml.blockToDom_(g)),f=!1),h.setAttribute("name",c.name),f||b.appendChild(h))}d&&b.setAttribute("inline",a.inputsInline);a.isCollapsed()&&b.setAttribute("collapsed",!0);a.disabled&&b.setAttribute("disabled",
!0);a.isDeletable()||b.setAttribute("deletable",!1);a.isMovable()||b.setAttribute("movable",!1);a.isEditable()||b.setAttribute("editable",!1);a.nextConnection&&(a=a.nextConnection.targetBlock())&&(h=goog.dom.createDom("next",null,Blockly.Xml.blockToDom_(a)),b.appendChild(h));return b};Blockly.Xml.domToText=function(a){return(new XMLSerializer).serializeToString(a)};
Blockly.Xml.blockToDom_=function(a){var b=goog.dom.createDom("block");b.setAttribute("type",a.type);b.setAttribute("id",a.id);if(a.mutationToDom){var c=a.mutationToDom();c&&b.appendChild(c)}for(var d=0;c=a.inputList[d];d++)for(var e=0,f;f=c.fieldRow[e];e++)if(f.name&&f.EDITABLE){var g=goog.dom.createDom("field",null,f.getValue());g.setAttribute("name",f.name);b.appendChild(g)}a.comment&&(c=goog.dom.createDom("comment",null,a.comment.getText()),c.setAttribute("pinned",a.comment.isVisible()),d=a.comment.getBubbleSize(),
c.setAttribute("h",d.height),c.setAttribute("w",d.width),b.appendChild(c));d=!1;for(e=0;c=a.inputList[e];e++){var h;f=!0;c.type!=Blockly.DUMMY_INPUT&&(g=c.connection.targetBlock(),c.type==Blockly.INPUT_VALUE?(h=goog.dom.createDom("value"),d=!0):c.type==Blockly.NEXT_STATEMENT&&(h=goog.dom.createDom("statement")),g&&(h.appendChild(Blockly.Xml.blockToDom_(g)),f=!1),h.setAttribute("name",c.name),f||b.appendChild(h))}d&&b.setAttribute("inline",a.inputsInline);a.isCollapsed()&&b.setAttribute("collapsed",
!0);a.disabled&&b.setAttribute("disabled",!0);a.isDeletable()||b.setAttribute("deletable",!1);a.isMovable()||b.setAttribute("movable",!1);a.isEditable()||b.setAttribute("editable",!1);a.nextConnection&&(a=a.nextConnection.targetBlock())&&(h=goog.dom.createDom("next",null,Blockly.Xml.blockToDom_(a)),b.appendChild(h));return b};Blockly.Xml.domToText=function(a){return(new XMLSerializer).serializeToString(a)};
Blockly.Xml.domToPrettyText=function(a){a=Blockly.Xml.domToText(a).split("<");for(var b="",c=1;c<a.length;c++){var d=a[c];"/"==d[0]&&(b=b.substring(2));a[c]=b+"<"+d;"/"!=d[0]&&"/>"!=d.slice(-2)&&(b+=" ")}a=a.join("\n");a=a.replace(/(<(\w+)\b[^>]*>[^\n]*)\n *<\/\2>/g,"$1</$2>");return a.replace(/^\n/,"")};
Blockly.Xml.textToDom=function(a){a=(new DOMParser).parseFromString(a,"text/xml");if(!a||!a.firstChild||"xml"!=a.firstChild.nodeName.toLowerCase()||a.firstChild!==a.lastChild)throw"Blockly.Xml.textToDom did not obtain a valid XML tree.";return a.firstChild};
Blockly.Xml.domToWorkspace=function(a,b){for(var c=Blockly.svgSize().width,d=0,e;e=b.childNodes[d];d++)if("block"==e.nodeName.toLowerCase()){var f=Blockly.Xml.domToBlock_(a,e),g=parseInt(e.getAttribute("x"),10);e=parseInt(e.getAttribute("y"),10);isNaN(g)||isNaN(e)||f.moveBy(Blockly.RTL?c-g:g,e)}};
Blockly.Xml.domToBlock_=function(a,b){var c=b.getAttribute("type");if(!c)throw"Block type unspecified: \n"+b.outerHTML;var d=new Blockly.Block(a,c);d.initSvg();var e=b.getAttribute("inline");e&&d.setInputsInline("true"==e);(e=b.getAttribute("disabled"))&&d.setDisabled("true"==e);(e=b.getAttribute("deletable"))&&d.setDeletable("true"==e);(e=b.getAttribute("movable"))&&d.setMovable("true"==e);(e=b.getAttribute("editable"))&&d.setEditable("true"==e);for(var f=null,e=0,g;g=b.childNodes[e];e++)if(3!=g.nodeType||
!g.data.match(/^\s*$/)){for(var f=null,h=0,k;k=g.childNodes[h];h++)3==k.nodeType&&k.data.match(/^\s*$/)||(f=k);h=g.getAttribute("name");switch(g.nodeName.toLowerCase()){case "mutation":d.domToMutation&&d.domToMutation(g);break;case "comment":d.setCommentText(g.textContent);(f=g.getAttribute("pinned"))&&d.comment.setVisible("true"==f);f=parseInt(g.getAttribute("w"),10);g=parseInt(g.getAttribute("h"),10);isNaN(f)||isNaN(g)||d.comment.setBubbleSize(f,g);break;case "title":case "field":d.setFieldValue(g.textContent,
h);break;case "value":case "statement":g=d.getInput(h);if(!g)throw"Input "+h+" does not exist in block "+c;if(f&&"block"==f.nodeName.toLowerCase())if(f=Blockly.Xml.domToBlock_(a,f),f.outputConnection)g.connection.connect(f.outputConnection);else if(f.previousConnection)g.connection.connect(f.previousConnection);else throw"Child block does not have output or previous statement.";break;case "next":if(f&&"block"==f.nodeName.toLowerCase()){if(!d.nextConnection)throw"Next statement does not exist.";if(d.nextConnection.targetConnection)throw"Next statement is already connected.";
f=Blockly.Xml.domToBlock_(a,f);if(!f.previousConnection)throw"Next block does not have previous statement.";d.nextConnection.connect(f.previousConnection)}}}(c=d.nextConnection&&d.nextConnection.targetBlock())?c.render():d.render();(c=b.getAttribute("collapsed"))&&d.setCollapsed("true"==c);return d};Blockly.Xml.deleteNext=function(a){for(var b=0,c;c=a.childNodes[b];b++)if("next"==c.nodeName.toLowerCase()){a.removeChild(c);break}};Blockly.Xml=Blockly.Xml;Blockly.Xml.domToText=Blockly.Xml.domToText;
Blockly.Xml.domToWorkspace=Blockly.Xml.domToWorkspace;Blockly.Xml.textToDom=Blockly.Xml.textToDom;Blockly.Xml.workspaceToDom=Blockly.Xml.workspaceToDom;Blockly.Workspace=function(a,b){this.getMetrics=a;this.setMetrics=b;this.isFlyout=!1;this.topBlocks_=[];this.maxBlocks=Infinity;Blockly.ConnectionDB.init(this)};Blockly.Workspace.SCAN_ANGLE=3;Blockly.Workspace.prototype.dragMode=!1;Blockly.Workspace.prototype.scrollX=0;Blockly.Workspace.prototype.scrollY=0;Blockly.Workspace.prototype.trashcan=null;Blockly.Workspace.prototype.fireChangeEventPid_=null;Blockly.Workspace.prototype.scrollbar=null;
Blockly.Xml.domToWorkspace=function(a,b){for(var c=Blockly.svgSize().width,d=0,e;e=b.childNodes[d];d++)if("block"==e.nodeName.toLowerCase()){var f=Blockly.Xml.domToBlock(a,e),g=parseInt(e.getAttribute("x"),10);e=parseInt(e.getAttribute("y"),10);isNaN(g)||isNaN(e)||f.moveBy(Blockly.RTL?c-g:g,e)}};
Blockly.Xml.domToBlock=function(a,b,c){var d=null,e=b.getAttribute("type");if(!e)throw"Block type unspecified: \n"+b.outerHTML;var f=b.getAttribute("id");if(c&&f){d=Blockly.Block.getById(f,a);if(!d)throw"Couldn't get Block with id: "+f;f=d.getParent();d.workspace&&d.dispose(!0,!1,!0);d.fill(a,e);d.parent_=f}else d=Blockly.Block.obtain(a,e);d.svg_||d.initSvg();(f=b.getAttribute("inline"))&&d.setInputsInline("true"==f);(f=b.getAttribute("disabled"))&&d.setDisabled("true"==f);(f=b.getAttribute("deletable"))&&
d.setDeletable("true"==f);(f=b.getAttribute("movable"))&&d.setMovable("true"==f);(f=b.getAttribute("editable"))&&d.setEditable("true"==f);for(var g=null,f=0,h;h=b.childNodes[f];f++)if(3!=h.nodeType||!h.data.match(/^\s*$/)){for(var g=null,k=0,l;l=h.childNodes[k];k++)3==l.nodeType&&l.data.match(/^\s*$/)||(g=l);k=h.getAttribute("name");switch(h.nodeName.toLowerCase()){case "mutation":d.domToMutation&&d.domToMutation(h);break;case "comment":d.setCommentText(h.textContent);(g=h.getAttribute("pinned"))&&
d.comment.setVisible("true"==g);g=parseInt(h.getAttribute("w"),10);h=parseInt(h.getAttribute("h"),10);isNaN(g)||isNaN(h)||d.comment.setBubbleSize(g,h);break;case "title":case "field":d.setFieldValue(h.textContent,k);break;case "value":case "statement":h=d.getInput(k);if(!h)throw"Input "+k+" does not exist in block "+e;if(g&&"block"==g.nodeName.toLowerCase())if(g=Blockly.Xml.domToBlock(a,g,c),g.outputConnection)h.connection.connect(g.outputConnection);else if(g.previousConnection)h.connection.connect(g.previousConnection);
else throw"Child block does not have output or previous statement.";break;case "next":if(g&&"block"==g.nodeName.toLowerCase()){if(!d.nextConnection)throw"Next statement does not exist.";if(d.nextConnection.targetConnection)throw"Next statement is already connected.";g=Blockly.Xml.domToBlock(a,g,c);if(!g.previousConnection)throw"Next block does not have previous statement.";d.nextConnection.connect(g.previousConnection)}}}(a=d.nextConnection&&d.nextConnection.targetBlock())?a.render():d.render();(b=
b.getAttribute("collapsed"))&&d.setCollapsed("true"==b);return d};Blockly.Xml.deleteNext=function(a){for(var b=0,c;c=a.childNodes[b];b++)if("next"==c.nodeName.toLowerCase()){a.removeChild(c);break}};Blockly.Xml=Blockly.Xml;Blockly.Xml.domToText=Blockly.Xml.domToText;Blockly.Xml.domToWorkspace=Blockly.Xml.domToWorkspace;Blockly.Xml.textToDom=Blockly.Xml.textToDom;Blockly.Xml.workspaceToDom=Blockly.Xml.workspaceToDom;Blockly.Workspace=function(a,b){this.getMetrics=a;this.setMetrics=b;this.isFlyout=!1;this.topBlocks_=[];this.maxBlocks=Infinity;Blockly.ConnectionDB.init(this)};Blockly.Workspace.SCAN_ANGLE=3;Blockly.Workspace.prototype.dragMode=!1;Blockly.Workspace.prototype.scrollX=0;Blockly.Workspace.prototype.scrollY=0;Blockly.Workspace.prototype.trashcan=null;Blockly.Workspace.prototype.fireChangeEventPid_=null;Blockly.Workspace.prototype.scrollbar=null;
Blockly.Workspace.prototype.createDom=function(){this.svgGroup_=Blockly.createSvgElement("g",{},null);this.svgBlockCanvas_=Blockly.createSvgElement("g",{},this.svgGroup_);this.svgBubbleCanvas_=Blockly.createSvgElement("g",{},this.svgGroup_);this.fireChangeEvent();return this.svgGroup_};
Blockly.Workspace.prototype.dispose=function(){this.svgGroup_&&(goog.dom.removeNode(this.svgGroup_),this.svgGroup_=null);this.svgBubbleCanvas_=this.svgBlockCanvas_=null;this.trashcan&&(this.trashcan.dispose(),this.trashcan=null)};Blockly.Workspace.prototype.addTrashcan=function(){if(Blockly.hasTrashcan&&!Blockly.readOnly){this.trashcan=new Blockly.Trashcan(this);var a=this.trashcan.createDom();this.svgGroup_.insertBefore(a,this.svgBlockCanvas_);this.trashcan.init()}};
Blockly.Workspace.prototype.getCanvas=function(){return this.svgBlockCanvas_};Blockly.Workspace.prototype.getBubbleCanvas=function(){return this.svgBubbleCanvas_};Blockly.Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a);this.fireChangeEvent()};Blockly.Workspace.prototype.removeTopBlock=function(a){for(var b=!1,c,d=0;c=this.topBlocks_[d];d++)if(c==a){this.topBlocks_.splice(d,1);b=!0;break}if(!b)throw"Block not present in workspace's list of top-most blocks.";this.fireChangeEvent()};
Blockly.Workspace.prototype.getCanvas=function(){return this.svgBlockCanvas_};Blockly.Workspace.prototype.getBubbleCanvas=function(){return this.svgBubbleCanvas_};Blockly.Workspace.prototype.addTopBlock=function(a){this.topBlocks_.push(a);Blockly.isRealtimeEnabled()&&this==Blockly.mainWorkspace&&Blockly.Realtime.addTopBlock(a);this.fireChangeEvent()};
Blockly.Workspace.prototype.removeTopBlock=function(a){for(var b=!1,c,d=0;c=this.topBlocks_[d];d++)if(c==a){this.topBlocks_.splice(d,1);b=!0;break}if(!b)throw"Block not present in workspace's list of top-most blocks.";Blockly.isRealtimeEnabled()&&this==Blockly.mainWorkspace&&Blockly.Realtime.removeTopBlock(a);this.fireChangeEvent()};
Blockly.Workspace.prototype.getTopBlocks=function(a){var b=[].concat(this.topBlocks_);if(a&&1<b.length){var c=Math.sin(Blockly.Workspace.SCAN_ANGLE/180*Math.PI);Blockly.RTL&&(c*=-1);b.sort(function(a,b){var f=a.getRelativeToSurfaceXY(),g=b.getRelativeToSurfaceXY();return f.y+c*f.x-(g.y+c*g.x)})}return b};Blockly.Workspace.prototype.getAllBlocks=function(){for(var a=this.getTopBlocks(!1),b=0;b<a.length;b++)a=a.concat(a[b].getChildren());return a};Blockly.Workspace.prototype.clear=function(){for(Blockly.hideChaff();this.topBlocks_.length;)this.topBlocks_[0].dispose()};
Blockly.Workspace.prototype.render=function(){for(var a=this.getAllBlocks(),b=0,c;c=a[b];b++)c.getChildren().length||c.render()};Blockly.Workspace.prototype.getBlockById=function(a){for(var b=this.getAllBlocks(),c=0,d;d=b[c];c++)if(d.id==a)return d;return null};
Blockly.Workspace.prototype.traceOn=function(a){this.traceOn_=a;this.traceWrapper_&&(Blockly.unbindEvent_(this.traceWrapper_),this.traceWrapper_=null);a&&(this.traceWrapper_=Blockly.bindEvent_(this.svgBlockCanvas_,"blocklySelectChange",this,function(){this.traceOn_=!1}))};Blockly.Workspace.prototype.highlightBlock=function(a){if(this.traceOn_){var b=null;if(a&&(b=this.getBlockById(a),!b))return;this.traceOn(!1);b?b.select():Blockly.selected&&Blockly.selected.unselect();this.traceOn(!0)}};
Blockly.Workspace.prototype.fireChangeEvent=function(){this.fireChangeEventPid_&&window.clearTimeout(this.fireChangeEventPid_);var a=this.svgBlockCanvas_;a&&(this.fireChangeEventPid_=window.setTimeout(function(){Blockly.fireUiEvent(a,"blocklyWorkspaceChange")},0))};
Blockly.Workspace.prototype.paste=function(a){if(!(a.getElementsByTagName("block").length>=this.remainingCapacity())){var b=Blockly.Xml.domToBlock_(this,a),c=parseInt(a.getAttribute("x"),10);a=parseInt(a.getAttribute("y"),10);if(!isNaN(c)&&!isNaN(a)){Blockly.RTL&&(c=-c);do for(var d=!1,e=this.getAllBlocks(),f=0,g;g=e[f];f++)g=g.getRelativeToSurfaceXY(),1>=Math.abs(c-g.x)&&1>=Math.abs(a-g.y)&&(c=Blockly.RTL?c-Blockly.SNAP_RADIUS:c+Blockly.SNAP_RADIUS,a+=2*Blockly.SNAP_RADIUS,d=!0);while(d);b.moveBy(c,
Blockly.Workspace.prototype.paste=function(a){if(!(a.getElementsByTagName("block").length>=this.remainingCapacity())){var b=Blockly.Xml.domToBlock(this,a),c=parseInt(a.getAttribute("x"),10);a=parseInt(a.getAttribute("y"),10);if(!isNaN(c)&&!isNaN(a)){Blockly.RTL&&(c=-c);do for(var d=!1,e=this.getAllBlocks(),f=0,g;g=e[f];f++)g=g.getRelativeToSurfaceXY(),1>=Math.abs(c-g.x)&&1>=Math.abs(a-g.y)&&(c=Blockly.RTL?c-Blockly.SNAP_RADIUS:c+Blockly.SNAP_RADIUS,a+=2*Blockly.SNAP_RADIUS,d=!0);while(d);b.moveBy(c,
a)}b.select()}};Blockly.Workspace.prototype.remainingCapacity=function(){return Infinity==this.maxBlocks?Infinity:this.maxBlocks-this.getAllBlocks().length};Blockly.Workspace.prototype.clear=Blockly.Workspace.prototype.clear;Blockly.Bubble=function(a,b,c,d,e,f,g){var h=Blockly.Bubble.ARROW_ANGLE;Blockly.RTL&&(h=-h);this.arrow_radians_=h/360*Math.PI*2;this.workspace_=a;this.content_=b;this.shape_=c;a.getBubbleCanvas().appendChild(this.createDom_(b,!(!f||!g)));this.setAnchorLocation(d,e);f&&g||(a=this.content_.getBBox(),f=a.width+2*Blockly.Bubble.BORDER_WIDTH,g=a.height+2*Blockly.Bubble.BORDER_WIDTH);this.setBubbleSize(f,g);this.positionBubble_();this.renderArrow_();this.rendered_=!0;Blockly.readOnly||(Blockly.bindEvent_(this.bubbleBack_,
"mousedown",this,this.bubbleMouseDown_),this.resizeGroup_&&Blockly.bindEvent_(this.resizeGroup_,"mousedown",this,this.resizeMouseDown_))};Blockly.Bubble.BORDER_WIDTH=6;Blockly.Bubble.ARROW_THICKNESS=10;Blockly.Bubble.ARROW_ANGLE=20;Blockly.Bubble.ARROW_BEND=4;Blockly.Bubble.ANCHOR_RADIUS=8;Blockly.Bubble.onMouseUpWrapper_=null;Blockly.Bubble.onMouseMoveWrapper_=null;
Blockly.Bubble.unbindDragEvents_=function(){Blockly.Bubble.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Bubble.onMouseUpWrapper_),Blockly.Bubble.onMouseUpWrapper_=null);Blockly.Bubble.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Bubble.onMouseMoveWrapper_),Blockly.Bubble.onMouseMoveWrapper_=null)};Blockly.Bubble.prototype.rendered_=!1;Blockly.Bubble.prototype.anchorX_=0;Blockly.Bubble.prototype.anchorY_=0;Blockly.Bubble.prototype.relativeLeft_=0;Blockly.Bubble.prototype.relativeTop_=0;
@ -776,7 +778,7 @@ Blockly.ContextMenu.show=function(a,b){if(b.length){goog.dom.removeChildren(Bloc
Blockly.noEvent);f.enabled?(Blockly.bindEvent_(g,"mouseup",null,f.callback),Blockly.bindEvent_(g,"mouseup",null,Blockly.ContextMenu.hide)):g.setAttribute("class","blocklyMenuDivDisabled");c=Math.max(c,k.getComputedTextLength())}c+=2*Blockly.ContextMenu.X_PADDING;for(e=0;e<d.length;e++)d[e].setAttribute("width",c);if(Blockly.RTL)for(e=0;g=Blockly.ContextMenu.svgOptions.childNodes[e];e++)k=g.lastChild,k.setAttribute("text-anchor","end"),k.setAttribute("x",c-Blockly.ContextMenu.X_PADDING);Blockly.ContextMenu.svgBackground.setAttribute("height",
b.length*Blockly.ContextMenu.Y_HEIGHT+8);Blockly.ContextMenu.svgShadow.setAttribute("height",b.length*Blockly.ContextMenu.Y_HEIGHT+10);c=a.x;d=a.y;e=Blockly.ContextMenu.svgGroup.getBBox();f=Blockly.svgSize();d+e.height>f.height&&(d-=e.height-10);Blockly.RTL?0>=c-e.width?c++:c-=e.width:c+e.width>f.width?c-=e.width:c++;Blockly.ContextMenu.svgGroup.setAttribute("transform","translate("+c+", "+d+")");Blockly.ContextMenu.visible=!0}else Blockly.ContextMenu.hide()};
Blockly.ContextMenu.optionToDom=function(a){var b=Blockly.createSvgElement("g",{"class":"blocklyMenuDiv"},null);Blockly.createSvgElement("rect",{height:Blockly.ContextMenu.Y_HEIGHT},b);var c=Blockly.createSvgElement("text",{"class":"blocklyMenuText",x:Blockly.ContextMenu.X_PADDING,y:15},b);a=document.createTextNode(a);c.appendChild(a);return b};Blockly.ContextMenu.hide=function(){Blockly.ContextMenu.visible&&(Blockly.ContextMenu.svgGroup.style.display="none",Blockly.ContextMenu.visible=!1)};
Blockly.ContextMenu.callbackFactory=function(a,b){return function(){var c=Blockly.Xml.domToBlock_(a.workspace,b),d=a.getRelativeToSurfaceXY();d.x=Blockly.RTL?d.x-Blockly.SNAP_RADIUS:d.x+Blockly.SNAP_RADIUS;d.y+=2*Blockly.SNAP_RADIUS;c.moveBy(d.x,d.y);c.select()}};Blockly.Field=function(a){this.sourceBlock_=null;this.fieldGroup_=Blockly.createSvgElement("g",{},null);this.borderRect_=Blockly.createSvgElement("rect",{rx:4,ry:4,x:-Blockly.BlockSvg.SEP_SPACE_X/2,y:-12,height:16},this.fieldGroup_);this.textElement_=Blockly.createSvgElement("text",{"class":"blocklyText"},this.fieldGroup_);this.size_={height:25,width:0};this.setText(a);this.visible_=!0};Blockly.Field.prototype.clone=function(){goog.asserts.fail("There should never be an instance of Field, only its derived classes.")};
Blockly.ContextMenu.callbackFactory=function(a,b){return function(){var c=Blockly.Xml.domToBlock(a.workspace,b),d=a.getRelativeToSurfaceXY();d.x=Blockly.RTL?d.x-Blockly.SNAP_RADIUS:d.x+Blockly.SNAP_RADIUS;d.y+=2*Blockly.SNAP_RADIUS;c.moveBy(d.x,d.y);c.select()}};Blockly.Field=function(a){this.sourceBlock_=null;this.fieldGroup_=Blockly.createSvgElement("g",{},null);this.borderRect_=Blockly.createSvgElement("rect",{rx:4,ry:4,x:-Blockly.BlockSvg.SEP_SPACE_X/2,y:-12,height:16},this.fieldGroup_);this.textElement_=Blockly.createSvgElement("text",{"class":"blocklyText"},this.fieldGroup_);this.size_={height:25,width:0};this.setText(a);this.visible_=!0};Blockly.Field.prototype.clone=function(){goog.asserts.fail("There should never be an instance of Field, only its derived classes.")};
Blockly.Field.NBSP="\u00a0";Blockly.Field.prototype.EDITABLE=!0;Blockly.Field.prototype.init=function(a){if(this.sourceBlock_)throw"Field has already been initialized once.";this.sourceBlock_=a;this.updateEditable();a.getSvgRoot().appendChild(this.fieldGroup_);this.mouseUpWrapper_=Blockly.bindEvent_(this.fieldGroup_,"mouseup",this,this.onMouseUp_);this.setText(null)};
Blockly.Field.prototype.dispose=function(){this.mouseUpWrapper_&&(Blockly.unbindEvent_(this.mouseUpWrapper_),this.mouseUpWrapper_=null);this.sourceBlock_=null;goog.dom.removeNode(this.fieldGroup_);this.borderRect_=this.textElement_=this.fieldGroup_=null};
Blockly.Field.prototype.updateEditable=function(){this.EDITABLE&&(this.sourceBlock_.isEditable()?(Blockly.addClass_(this.fieldGroup_,"blocklyEditableText"),Blockly.removeClass_(this.fieldGroup_,"blocklyNoNEditableText"),this.fieldGroup_.style.cursor=this.CURSOR):(Blockly.addClass_(this.fieldGroup_,"blocklyNonEditableText"),Blockly.removeClass_(this.fieldGroup_,"blocklyEditableText"),this.fieldGroup_.style.cursor=""))};Blockly.Field.prototype.isVisible=function(){return this.visible_};
@ -811,23 +813,25 @@ this.block_.render(),this.resizeBubble_(),this.block_.workspace.fireChangeEvent(
Blockly.Warning.prototype.createIcon_=function(){Blockly.Icon.prototype.createIcon_.call(this);Blockly.createSvgElement("path",{"class":"blocklyIconShield",d:"M 2,15 Q -1,15 0.5,12 L 6.5,1.7 Q 8,-1 9.5,1.7 L 15.5,12 Q 17,15 14,15 z"},this.iconGroup_);this.iconMark_=Blockly.createSvgElement("text",{"class":"blocklyIconMark",x:Blockly.Icon.RADIUS,y:2*Blockly.Icon.RADIUS-3},this.iconGroup_);this.iconMark_.appendChild(document.createTextNode("!"))};
Blockly.Warning.prototype.textToDom_=function(a){var b=Blockly.createSvgElement("text",{"class":"blocklyText",y:Blockly.Bubble.BORDER_WIDTH},null);a=a.split("\n");for(var c=0;c<a.length;c++){var d=Blockly.createSvgElement("tspan",{dy:"1em",x:Blockly.Bubble.BORDER_WIDTH},b),e=document.createTextNode(a[c]);d.appendChild(e)}return b};
Blockly.Warning.prototype.setVisible=function(a){if(a!=this.isVisible())if(a){a=this.textToDom_(this.text_);this.bubble_=new Blockly.Bubble(this.block_.workspace,a,this.block_.svg_.svgGroup_,this.iconX_,this.iconY_,null,null);if(Blockly.RTL)for(var b=a.getBBox().width,c=0,d;d=a.childNodes[c];c++)d.setAttribute("text-anchor","end"),d.setAttribute("x",b+Blockly.Bubble.BORDER_WIDTH);this.updateColour();a=this.bubble_.getBubbleSize();this.bubble_.setBubbleSize(a.width,a.height)}else this.bubble_.dispose(),
this.foreignObject_=this.body_=this.bubble_=null};Blockly.Warning.prototype.bodyFocus_=function(a){this.bubble_.promote_()};Blockly.Warning.prototype.setText=function(a){this.text_=a;this.isVisible()&&(this.setVisible(!1),this.setVisible(!0))};Blockly.Warning.prototype.dispose=function(){this.block_.warning=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.uidCounter_=0;
Blockly.Block=function(a,b){this.id=++Blockly.uidCounter_;this.previousConnection=this.nextConnection=this.outputConnection=null;this.inputList=[];this.disabled=this.rendered=this.inputsInline=!1;this.tooltip="";this.contextMenu=!0;this.parentBlock_=null;this.childBlocks_=[];this.editable_=this.movable_=this.deletable_=!0;this.collapsed_=!1;this.workspace=a;this.isInFlyout=a.isFlyout;a.addTopBlock(this);if(b){this.type=b;var c=Blockly.Blocks[b];goog.asserts.assertObject(c,'Error: "%s" is an unknown language block.',b);
goog.mixin(this,c)}goog.isFunction(this.init)&&this.init();goog.isFunction(this.onchange)&&Blockly.bindEvent_(a.getCanvas(),"blocklyWorkspaceChange",this,this.onchange)};Blockly.Block.prototype.svg_=null;Blockly.Block.prototype.mutator=null;Blockly.Block.prototype.comment=null;Blockly.Block.prototype.warning=null;Blockly.Block.prototype.getIcons=function(){var a=[];this.mutator&&a.push(this.mutator);this.comment&&a.push(this.comment);this.warning&&a.push(this.warning);return a};
this.foreignObject_=this.body_=this.bubble_=null};Blockly.Warning.prototype.bodyFocus_=function(a){this.bubble_.promote_()};Blockly.Warning.prototype.setText=function(a){this.text_=a;this.isVisible()&&(this.setVisible(!1),this.setVisible(!0))};Blockly.Warning.prototype.dispose=function(){this.block_.warning=null;Blockly.Icon.prototype.dispose.call(this)};Blockly.uidCounter_=0;Blockly.getUidCounter=function(){return Blockly.uidCounter_};Blockly.setUidCounter=function(a){Blockly.uidCounter_=a};Blockly.isRealtimeEnabled=function(){return"undefined"!=typeof Blockly.Realtime&&Blockly.Realtime&&Blockly.Realtime.isEnabled()};Blockly.Block=function(){goog.asserts.assert(0==arguments.length,"Please use Blockly.Block.obtain.")};
Blockly.Block.obtain=function(a,b){if(Blockly.isRealtimeEnabled())return Blockly.Realtime.obtainBlock(a,b);var c=new Blockly.Block;c.initialize(a,b);return c};Blockly.Block.prototype.initialize=function(a,b){this.id=++Blockly.uidCounter_;a.addTopBlock(this);this.fill(a,b);goog.isFunction(this.onchange)&&Blockly.bindEvent_(a.getCanvas(),"blocklyWorkspaceChange",this,this.onchange)};
Blockly.Block.prototype.fill=function(a,b){this.previousConnection=this.nextConnection=this.outputConnection=null;this.inputList=[];this.disabled=this.rendered=this.inputsInline=!1;this.tooltip="";this.contextMenu=!0;this.parentBlock_=null;this.childBlocks_=[];this.editable_=this.movable_=this.deletable_=!0;this.collapsed_=!1;this.workspace=a;this.isInFlyout=a.isFlyout;if(b){this.type=b;var c=Blockly.Blocks[b];goog.asserts.assertObject(c,'Error: "%s" is an unknown language block.',b);goog.mixin(this,
c)}goog.isFunction(this.init)&&this.init()};Blockly.Block.getById=function(a,b){return Blockly.isRealtimeEnabled()?Blockly.Realtime.getBlockById(a):b.getBlockById(a)};Blockly.Block.prototype.svg_=null;Blockly.Block.prototype.mutator=null;Blockly.Block.prototype.comment=null;Blockly.Block.prototype.warning=null;Blockly.Block.prototype.getIcons=function(){var a=[];this.mutator&&a.push(this.mutator);this.comment&&a.push(this.comment);this.warning&&a.push(this.warning);return a};
Blockly.Block.prototype.initSvg=function(){this.svg_=new Blockly.BlockSvg(this);this.svg_.init();Blockly.readOnly||Blockly.bindEvent_(this.svg_.getRootElement(),"mousedown",this,this.onMouseDown_);this.workspace.getCanvas().appendChild(this.svg_.getRootElement())};Blockly.Block.prototype.getSvgRoot=function(){return this.svg_&&this.svg_.getRootElement()};Blockly.Block.dragMode_=0;Blockly.Block.onMouseUpWrapper_=null;Blockly.Block.onMouseMoveWrapper_=null;
Blockly.Block.terminateDrag_=function(){Blockly.Block.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Block.onMouseUpWrapper_),Blockly.Block.onMouseUpWrapper_=null);Blockly.Block.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Block.onMouseMoveWrapper_),Blockly.Block.onMouseMoveWrapper_=null);var a=Blockly.selected;if(2==Blockly.Block.dragMode_&&a){var b=a.getRelativeToSurfaceXY();a.moveConnections_(b.x-a.startDragX,b.y-a.startDragY);delete a.draggedBubbles_;a.setDragging_(!1);a.render();goog.Timer.callOnce(a.bumpNeighbours_,
Blockly.BUMP_DELAY,a);Blockly.fireUiEvent(window,"resize")}a&&a.workspace.fireChangeEvent();Blockly.Block.dragMode_=0};Blockly.Block.prototype.select=function(){goog.asserts.assertObject(this.svg_,"Block is not rendered.");Blockly.selected&&Blockly.selected.unselect();Blockly.selected=this;this.svg_.addSelect();Blockly.fireUiEvent(this.workspace.getCanvas(),"blocklySelectChange")};
Blockly.Block.prototype.unselect=function(){goog.asserts.assertObject(this.svg_,"Block is not rendered.");Blockly.selected=null;this.svg_.removeSelect();Blockly.fireUiEvent(this.workspace.getCanvas(),"blocklySelectChange")};
Blockly.Block.prototype.dispose=function(a,b){this.rendered=!1;this.unplug(a);b&&this.svg_&&this.svg_.disposeUiEffect();this.workspace.removeTopBlock(this);this.workspace=null;Blockly.selected==this&&(Blockly.selected=null,Blockly.terminateDrag_());for(var c=this.childBlocks_.length-1;0<=c;c--)this.childBlocks_[c].dispose(!1);for(var d=this.getIcons(),c=0;c<d.length;c++)d[c].dispose();for(c=0;d=this.inputList[c];c++)d.dispose();this.inputList=[];d=this.getConnections_(!0);for(c=0;c<d.length;c++){var e=
d[c];e.targetConnection&&e.disconnect();d[c].dispose()}this.svg_&&(this.svg_.dispose(),this.svg_=null)};
Blockly.Block.prototype.dispose=function(a,b,c){this.rendered=!1;this.unplug(a);b&&this.svg_&&this.svg_.disposeUiEffect();this.workspace&&!c&&(this.workspace.removeTopBlock(this),this.workspace=null);Blockly.selected==this&&(Blockly.selected=null,Blockly.terminateDrag_());for(a=this.childBlocks_.length-1;0<=a;a--)this.childBlocks_[a].dispose(!1);b=this.getIcons();for(a=0;a<b.length;a++)b[a].dispose();for(a=0;b=this.inputList[a];a++)b.dispose();this.inputList=[];b=this.getConnections_(!0);for(a=0;a<
b.length;a++)c=b[a],c.targetConnection&&c.disconnect(),b[a].dispose();this.svg_&&(this.svg_.dispose(),this.svg_=null);Blockly.isRealtimeEnabled()&&!Blockly.Realtime.withinSync&&Blockly.Realtime.removeBlock(this)};
Blockly.Block.prototype.unplug=function(a,b){b=b&&!!this.getParent();if(this.outputConnection)this.outputConnection.targetConnection&&this.setParent(null);else{var c=null;this.previousConnection&&this.previousConnection.targetConnection&&(c=this.previousConnection.targetConnection,this.setParent(null));if(a&&this.nextConnection&&this.nextConnection.targetConnection){var d=this.nextConnection.targetConnection;this.nextConnection.targetBlock().setParent(null);c&&c.connect(d)}}b&&this.moveBy(Blockly.SNAP_RADIUS*
(Blockly.RTL?-1:1),2*Blockly.SNAP_RADIUS)};Blockly.Block.prototype.getRelativeToSurfaceXY=function(){var a=0,b=0;if(this.svg_){var c=this.svg_.getRootElement();do var d=Blockly.getRelativeXY_(c),a=a+d.x,b=b+d.y,c=c.parentNode;while(c&&c!=this.workspace.getCanvas())}return{x:a,y:b}};Blockly.Block.prototype.moveBy=function(a,b){var c=this.getRelativeToSurfaceXY();this.svg_.getRootElement().setAttribute("transform","translate("+(c.x+a)+", "+(c.y+b)+")");this.moveConnections_(a,b)};
(Blockly.RTL?-1:1),2*Blockly.SNAP_RADIUS)};Blockly.Block.prototype.getRelativeToSurfaceXY=function(){var a=0,b=0;if(this.svg_){var c=this.svg_.getRootElement();do var d=Blockly.getRelativeXY_(c),a=a+d.x,b=b+d.y,c=c.parentNode;while(c&&c!=this.workspace.getCanvas())}return{x:a,y:b}};
Blockly.Block.prototype.moveBy=function(a,b){var c=this.getRelativeToSurfaceXY();this.svg_.getRootElement().setAttribute("transform","translate("+(c.x+a)+", "+(c.y+b)+")");this.moveConnections_(a,b);Blockly.isRealtimeEnabled()&&!Blockly.Realtime.withinSync&&Blockly.Realtime.blockChanged(this)};
Blockly.Block.prototype.getHeightWidth=function(){try{var a=this.getSvgRoot().getBBox(),b=a.height}catch(c){return{height:0,width:0}}Blockly.BROKEN_CONTROL_POINTS&&(b-=10,this.nextConnection&&(b+=4));return{height:b-1,width:a.width}};
Blockly.Block.prototype.onMouseDown_=function(a){if(!this.isInFlyout){Blockly.svgResize();Blockly.terminateDrag_();this.select();Blockly.hideChaff();if(Blockly.isRightButton(a))Blockly.ContextMenu&&this.showContextMenu_(Blockly.mouseToSvg(a));else if(this.isMovable()){Blockly.removeAllRanges();Blockly.setCursorHand_(!0);var b=this.getRelativeToSurfaceXY();this.startDragX=b.x;this.startDragY=b.y;this.startDragMouseX=a.clientX;this.startDragMouseY=a.clientY;Blockly.Block.dragMode_=1;Blockly.Block.onMouseUpWrapper_=
Blockly.bindEvent_(document,"mouseup",this,this.onMouseUp_);Blockly.Block.onMouseMoveWrapper_=Blockly.bindEvent_(document,"mousemove",this,this.onMouseMove_);this.draggedBubbles_=[];for(var b=this.getDescendants(),c=0,d;d=b[c];c++){d=d.getIcons();for(var e=0;e<d.length;e++){var f=d[e].getIconLocation();f.bubble=d[e];this.draggedBubbles_.push(f)}}}else return;a.stopPropagation()}};
Blockly.Block.prototype.onMouseUp_=function(a){Blockly.terminateDrag_();Blockly.selected&&Blockly.highlightedConnection_?(Blockly.localConnection_.connect(Blockly.highlightedConnection_),this.svg_&&(Blockly.localConnection_.isSuperior()?Blockly.highlightedConnection_:Blockly.localConnection_).sourceBlock_.svg_.connectionUiEffect(),this.workspace.trashcan&&this.workspace.trashcan.isOpen&&this.workspace.trashcan.close()):this.workspace.trashcan&&this.workspace.trashcan.isOpen&&(a=this.workspace.trashcan,
goog.Timer.callOnce(a.close,100,a),Blockly.selected.dispose(!1,!0),Blockly.fireUiEvent(window,"resize"));Blockly.highlightedConnection_&&(Blockly.highlightedConnection_.unhighlight(),Blockly.highlightedConnection_=null)};Blockly.Block.prototype.showHelp_=function(){var a=goog.isFunction(this.helpUrl)?this.helpUrl():this.helpUrl;a&&window.open(a)};
Blockly.Block.prototype.duplicate_=function(){var a=Blockly.Xml.blockToDom_(this);Blockly.Xml.deleteNext(a);var a=Blockly.Xml.domToBlock_(this.workspace,a),b=this.getRelativeToSurfaceXY();b.x=Blockly.RTL?b.x-Blockly.SNAP_RADIUS:b.x+Blockly.SNAP_RADIUS;b.y+=2*Blockly.SNAP_RADIUS;a.moveBy(b.x,b.y);return a};
Blockly.Block.prototype.duplicate_=function(){var a=Blockly.Xml.blockToDom_(this);Blockly.Xml.deleteNext(a);var a=Blockly.Xml.domToBlock(this.workspace,a),b=this.getRelativeToSurfaceXY();b.x=Blockly.RTL?b.x-Blockly.SNAP_RADIUS:b.x+Blockly.SNAP_RADIUS;b.y+=2*Blockly.SNAP_RADIUS;a.moveBy(b.x,b.y);return a};
Blockly.Block.prototype.showContextMenu_=function(a){if(!Blockly.readOnly&&this.contextMenu){var b=this,c=[];if(this.isDeletable()&&!b.isInFlyout){var d={text:Blockly.Msg.DUPLICATE_BLOCK,enabled:!0,callback:function(){b.duplicate_()}};this.getDescendants().length>this.workspace.remainingCapacity()&&(d.enabled=!1);c.push(d);this.isEditable()&&!this.collapsed_&&(d={enabled:!0},this.comment?(d.text=Blockly.Msg.REMOVE_COMMENT,d.callback=function(){b.setCommentText(null)}):(d.text=Blockly.Msg.ADD_COMMENT,
d.callback=function(){b.setCommentText("")}),c.push(d));if(!this.collapsed_)for(d=0;d<this.inputList.length;d++)if(this.inputList[d].type==Blockly.INPUT_VALUE){d={enabled:!0};d.text=this.inputsInline?Blockly.Msg.EXTERNAL_INPUTS:Blockly.Msg.INLINE_INPUTS;d.callback=function(){b.setInputsInline(!b.inputsInline)};c.push(d);break}Blockly.collapse&&(this.collapsed_?(d={enabled:!0},d.text=Blockly.Msg.EXPAND_BLOCK,d.callback=function(){b.setCollapsed(!1)}):(d={enabled:!0},d.text=Blockly.Msg.COLLAPSE_BLOCK,
d.callback=function(){b.setCollapsed(!0)}),c.push(d));d={text:this.disabled?Blockly.Msg.ENABLE_BLOCK:Blockly.Msg.DISABLE_BLOCK,enabled:!this.getInheritedDisabled(),callback:function(){b.setDisabled(!b.disabled)}};c.push(d);d=this.getDescendants().length;b.nextConnection&&b.nextConnection.targetConnection&&(d-=this.nextConnection.targetBlock().getDescendants().length);d={text:1==d?Blockly.Msg.DELETE_BLOCK:Blockly.Msg.DELETE_X_BLOCKS.replace("%1",d),enabled:!0,callback:function(){b.dispose(!0,!0)}};
@ -840,9 +844,9 @@ d+", "+e+")");for(d=0;d<this.draggedBubbles_.length;d++)e=this.draggedBubbles_[d
Blockly.Block.prototype.bumpNeighbours_=function(){if(0==Blockly.Block.dragMode_){var a=this.getRootBlock();if(!a.isInFlyout)for(var b=this.getConnections_(!1),c=0;c<b.length;c++){var d=b[c];d.targetConnection&&d.isSuperior()&&d.targetBlock().bumpNeighbours_();for(var e=d.neighbours_(Blockly.SNAP_RADIUS),f=0;f<e.length;f++){var g=e[f];d.targetConnection&&g.targetConnection||g.sourceBlock_.getRootBlock()!=a&&(d.isSuperior()?g.bumpAwayFrom_(d):d.bumpAwayFrom_(g))}}}};
Blockly.Block.prototype.getParent=function(){return this.parentBlock_};Blockly.Block.prototype.getSurroundParent=function(){for(var a=this;;){do{var b=a,a=a.getParent();if(!a)return null}while(a.nextConnection&&a.nextConnection.targetBlock()==b);return a}};Blockly.Block.prototype.getRootBlock=function(){var a,b=this;do a=b,b=a.parentBlock_;while(b);return a};Blockly.Block.prototype.getChildren=function(){return this.childBlocks_};
Blockly.Block.prototype.setParent=function(a){if(this.parentBlock_){for(var b=this.parentBlock_.childBlocks_,c,d=0;c=b[d];d++)if(c==this){b.splice(d,1);break}b=this.getRelativeToSurfaceXY();this.workspace.getCanvas().appendChild(this.svg_.getRootElement());this.svg_.getRootElement().setAttribute("transform","translate("+b.x+", "+b.y+")");this.parentBlock_=null;this.previousConnection&&this.previousConnection.targetConnection&&this.previousConnection.disconnect();this.outputConnection&&this.outputConnection.targetConnection&&
this.outputConnection.disconnect()}else this.workspace.removeTopBlock(this);(this.parentBlock_=a)?(a.childBlocks_.push(this),b=this.getRelativeToSurfaceXY(),a.svg_&&this.svg_&&a.svg_.getRootElement().appendChild(this.svg_.getRootElement()),a=this.getRelativeToSurfaceXY(),this.moveConnections_(a.x-b.x,a.y-b.y)):this.workspace.addTopBlock(this)};Blockly.Block.prototype.getDescendants=function(){for(var a=[this],b,c=0;b=this.childBlocks_[c];c++)a=a.concat(b.getDescendants());return a};
Blockly.Block.prototype.isDeletable=function(){return this.deletable_&&!Blockly.readOnly};Blockly.Block.prototype.setDeletable=function(a){this.deletable_=a;this.svg_&&this.svg_.updateMovable()};Blockly.Block.prototype.isMovable=function(){return this.movable_&&!Blockly.readOnly};Blockly.Block.prototype.setMovable=function(a){this.movable_=a};Blockly.Block.prototype.isEditable=function(){return this.editable_&&!Blockly.readOnly};
Blockly.Block.prototype.setEditable=function(a){this.editable_=a;a=0;for(var b;b=this.inputList[a];a++)for(var c=0,d;d=b.fieldRow[c];c++)d.updateEditable();b=this.getIcons();for(a=0;a<b.length;a++)b[a].updateEditable()};Blockly.Block.prototype.setHelpUrl=function(a){this.helpUrl=a};Blockly.Block.prototype.getColour=function(){return this.colourHue_};
this.outputConnection.disconnect()}else goog.array.contains(this.workspace.getTopBlocks(!1),this)&&this.workspace.removeTopBlock(this);(this.parentBlock_=a)?(a.childBlocks_.push(this),b=this.getRelativeToSurfaceXY(),a.svg_&&this.svg_&&a.svg_.getRootElement().appendChild(this.svg_.getRootElement()),a=this.getRelativeToSurfaceXY(),this.moveConnections_(a.x-b.x,a.y-b.y)):this.workspace.addTopBlock(this)};
Blockly.Block.prototype.getDescendants=function(){for(var a=[this],b,c=0;b=this.childBlocks_[c];c++)a=a.concat(b.getDescendants());return a};Blockly.Block.prototype.isDeletable=function(){return this.deletable_&&!Blockly.readOnly};Blockly.Block.prototype.setDeletable=function(a){this.deletable_=a;this.svg_&&this.svg_.updateMovable()};Blockly.Block.prototype.isMovable=function(){return this.movable_&&!Blockly.readOnly};Blockly.Block.prototype.setMovable=function(a){this.movable_=a};
Blockly.Block.prototype.isEditable=function(){return this.editable_&&!Blockly.readOnly};Blockly.Block.prototype.setEditable=function(a){this.editable_=a;a=0;for(var b;b=this.inputList[a];a++)for(var c=0,d;d=b.fieldRow[c];c++)d.updateEditable();b=this.getIcons();for(a=0;a<b.length;a++)b[a].updateEditable()};Blockly.Block.prototype.setHelpUrl=function(a){this.helpUrl=a};Blockly.Block.prototype.getColour=function(){return this.colourHue_};
Blockly.Block.prototype.setColour=function(a){this.colourHue_=a;this.svg_&&this.svg_.updateColour();var b=this.getIcons();for(a=0;a<b.length;a++)b[a].updateColour();if(this.rendered){for(a=0;b=this.inputList[a];a++)for(var c=0,d;d=b.fieldRow[c];c++)d.setText(null);this.render()}};Blockly.Block.prototype.getField_=function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(e.name===a)return e;return null};
Blockly.Block.prototype.getFieldValue=function(a){return(a=this.getField_(a))?a.getValue():null};Blockly.Block.prototype.getTitleValue=function(a){console.log("Deprecated call to getTitleValue, use getFieldValue instead.");return this.getFieldValue(a)};Blockly.Block.prototype.setFieldValue=function(a,b){var c=this.getField_(b);goog.asserts.assertObject(c,'Field "%s" not found.',b);c.setValue(a)};
Blockly.Block.prototype.setTitleValue=function(a,b){console.log("Deprecated call to setTitleValue, use setFieldValue instead.");this.setFieldValue(a,b)};Blockly.Block.prototype.setTooltip=function(a){this.tooltip=a};
@ -863,7 +867,8 @@ Blockly.Block.prototype.moveNumberedInputBefore=function(a,b){goog.asserts.asser
Blockly.Block.prototype.removeInput=function(a,b){for(var c=0,d;d=this.inputList[c];c++)if(d.name==a){d.connection&&d.connection.targetConnection&&d.connection.targetBlock().setParent(null);d.dispose();this.inputList.splice(c,1);this.rendered&&(this.render(),this.bumpNeighbours_());return}b||goog.asserts.fail('Input "%s" not found.',a)};Blockly.Block.prototype.getInput=function(a){for(var b=0,c;c=this.inputList[b];b++)if(c.name==a)return c;return null};
Blockly.Block.prototype.getInputTargetBlock=function(a){return(a=this.getInput(a))&&a.connection&&a.connection.targetBlock()};Blockly.Block.prototype.setMutator=function(a){this.mutator&&this.mutator!==a&&this.mutator.dispose();a&&(a.block_=this,this.mutator=a,this.svg_&&a.createIcon())};Blockly.Block.prototype.getCommentText=function(){return this.comment?this.comment.getText().replace(/\s+$/,"").replace(/ +\n/g,"\n"):""};
Blockly.Block.prototype.setCommentText=function(a){var b=!1;goog.isString(a)?(this.comment||(this.comment=new Blockly.Comment(this),b=!0),this.comment.setText(a)):this.comment&&(this.comment.dispose(),b=!0);this.rendered&&(this.render(),b&&this.bumpNeighbours_())};
Blockly.Block.prototype.setWarningText=function(a){this.isInFlyout&&(a=null);var b=!1;goog.isString(a)?(this.warning||(this.warning=new Blockly.Warning(this),b=!0),this.warning.setText(a)):this.warning&&(this.warning.dispose(),b=!0);b&&this.rendered&&(this.render(),this.bumpNeighbours_())};Blockly.Block.prototype.render=function(){goog.asserts.assertObject(this.svg_,"Uninitialized block cannot be rendered. Call block.initSvg()");this.svg_.render()};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a);this.changeHandler_=b};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.prototype.clone=function(){return new Blockly.FieldTextInput(this.getText(),this.changeHandler_)};Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfField(this);Blockly.FieldTextInput.superClass_.dispose.call(this)};
Blockly.Block.prototype.setWarningText=function(a){this.isInFlyout&&(a=null);var b=!1;goog.isString(a)?(this.warning||(this.warning=new Blockly.Warning(this),b=!0),this.warning.setText(a)):this.warning&&(this.warning.dispose(),b=!0);b&&this.rendered&&(this.render(),this.bumpNeighbours_())};
Blockly.Block.prototype.render=function(){goog.asserts.assertObject(this.svg_,"Uninitialized block cannot be rendered. Call block.initSvg()");this.svg_.render();Blockly.isRealtimeEnabled()&&!Blockly.Realtime.withinSync&&Blockly.Realtime.blockChanged(this)};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a);this.changeHandler_=b};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.prototype.clone=function(){return new Blockly.FieldTextInput(this.getText(),this.changeHandler_)};Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfField(this);Blockly.FieldTextInput.superClass_.dispose.call(this)};
Blockly.FieldTextInput.prototype.setText=function(a){if(null!==a){if(this.changeHandler_){var b=this.changeHandler_(a);null!==b&&void 0!==b&&(a=b)}Blockly.Field.prototype.setText.call(this,a)}};
Blockly.FieldTextInput.prototype.showEditor_=function(){if(goog.userAgent.MOBILE){var a=window.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_);if(this.changeHandler_){var b=this.changeHandler_(a);void 0!==b&&(a=b)}null!==a&&this.setText(a)}else Blockly.WidgetDiv.show(this,this.dispose_()),b=Blockly.WidgetDiv.DIV,a=goog.dom.createDom("input","blocklyHtmlInput"),Blockly.FieldTextInput.htmlInput_=a,b.appendChild(a),a.value=a.defaultValue=this.text_,a.oldValue_=null,this.validate_(),this.resizeEditor_(),
a.focus(),a.select(),a.onKeyUpWrapper_=Blockly.bindEvent_(a,"keyup",this,this.onHtmlInputChange_),a.onKeyPressWrapper_=Blockly.bindEvent_(a,"keypress",this,this.onHtmlInputChange_),b=this.sourceBlock_.workspace.getCanvas(),a.onWorkspaceChangeWrapper_=Blockly.bindEvent_(b,"blocklyWorkspaceChange",this,this.resizeEditor_)};
@ -906,7 +911,7 @@ Blockly.Flyout.prototype.init=function(a,b){this.targetWorkspace_=a;b&&(this.scr
Blockly.Flyout.prototype.position_=function(){if(this.isVisible()){var a=this.targetWorkspace_.getMetrics();if(a){var b=this.width_-this.CORNER_RADIUS;Blockly.RTL&&(b*=-1);var c=["M "+(Blockly.RTL?this.width_:0)+",0"];c.push("h",b);c.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,Blockly.RTL?0:1,Blockly.RTL?-this.CORNER_RADIUS:this.CORNER_RADIUS,this.CORNER_RADIUS);c.push("v",Math.max(0,a.viewHeight-2*this.CORNER_RADIUS));c.push("a",this.CORNER_RADIUS,this.CORNER_RADIUS,0,0,Blockly.RTL?0:1,Blockly.RTL?
this.CORNER_RADIUS:-this.CORNER_RADIUS,this.CORNER_RADIUS);c.push("h",-b);c.push("z");this.svgBackground_.setAttribute("d",c.join(" "));b=a.absoluteLeft;Blockly.RTL&&(b+=a.viewWidth,b-=this.width_);this.svgGroup_.setAttribute("transform","translate("+b+","+a.absoluteTop+")");this.height_=a.viewHeight;this.scrollbar_&&this.scrollbar_.resize()}}};Blockly.Flyout.prototype.isVisible=function(){return"block"==this.svgGroup_.style.display};
Blockly.Flyout.prototype.hide=function(){if(this.isVisible()){this.svgGroup_.style.display="none";for(var a=0,b;b=this.listeners_[a];a++)Blockly.unbindEvent_(b);this.listeners_.splice(0);this.reflowWrapper_&&(Blockly.unbindEvent_(this.reflowWrapper_),this.reflowWrapper_=null);b=this.workspace_.getTopBlocks(!1);for(var a=0,c;c=b[a];a++)c.workspace==this.workspace_&&c.dispose(!1,!1);for(a=0;b=this.buttons_[a];a++)goog.dom.removeNode(b);this.buttons_.splice(0)}};
Blockly.Flyout.prototype.show=function(a){this.hide();var b=this.CORNER_RADIUS;this.svgGroup_.style.display="block";var c=[],d=[];if(a==Blockly.Variables.NAME_TYPE)Blockly.Variables.flyoutCategory(c,d,b,this.workspace_);else if(a==Blockly.Procedures.NAME_TYPE)Blockly.Procedures.flyoutCategory(c,d,b,this.workspace_);else for(var e=0,f;f=a[e];e++)f.tagName&&"BLOCK"==f.tagName.toUpperCase()&&(f=Blockly.Xml.domToBlock_(this.workspace_,f),c.push(f),d.push(3*b));a=b;for(e=0;f=c[e];e++){for(var g=f.getDescendants(),
Blockly.Flyout.prototype.show=function(a){this.hide();var b=this.CORNER_RADIUS;this.svgGroup_.style.display="block";var c=[],d=[];if(a==Blockly.Variables.NAME_TYPE)Blockly.Variables.flyoutCategory(c,d,b,this.workspace_);else if(a==Blockly.Procedures.NAME_TYPE)Blockly.Procedures.flyoutCategory(c,d,b,this.workspace_);else for(var e=0,f;f=a[e];e++)f.tagName&&"BLOCK"==f.tagName.toUpperCase()&&(f=Blockly.Xml.domToBlock(this.workspace_,f),c.push(f),d.push(3*b));a=b;for(e=0;f=c[e];e++){for(var g=f.getDescendants(),
h=0,k;k=g[h];h++)k.isInFlyout=!0,Blockly.Comment&&k.setCommentText(null);f.render();g=f.getSvgRoot();h=f.getHeightWidth();f.moveBy(Blockly.RTL?0:b+Blockly.BlockSvg.TAB_WIDTH,a);a+=h.height+d[e];h=Blockly.createSvgElement("rect",{"fill-opacity":0},null);this.workspace_.getCanvas().insertBefore(h,f.getSvgRoot());f.flyoutRect_=h;this.buttons_[e]=h;this.autoClose?this.listeners_.push(Blockly.bindEvent_(g,"mousedown",null,this.createBlockFunc_(f))):this.listeners_.push(Blockly.bindEvent_(g,"mousedown",
null,this.blockMouseDown_(f)));this.listeners_.push(Blockly.bindEvent_(g,"mouseover",f.svg_,f.svg_.addSelect));this.listeners_.push(Blockly.bindEvent_(g,"mouseout",f.svg_,f.svg_.removeSelect));this.listeners_.push(Blockly.bindEvent_(h,"mousedown",null,this.createBlockFunc_(f)));this.listeners_.push(Blockly.bindEvent_(h,"mouseover",f.svg_,f.svg_.addSelect));this.listeners_.push(Blockly.bindEvent_(h,"mouseout",f.svg_,f.svg_.removeSelect))}this.width_=0;this.reflow();this.filterForCapacity_();Blockly.fireUiEvent(window,
"resize");this.reflowWrapper_=Blockly.bindEvent_(this.workspace_.getCanvas(),"blocklyWorkspaceChange",this,this.reflow);this.workspace_.fireChangeEvent()};
@ -914,7 +919,7 @@ Blockly.Flyout.prototype.reflow=function(){for(var a=0,b=this.CORNER_RADIUS,c=th
f.height),e.flyoutRect_.setAttribute("x",Blockly.RTL?g.x-f.width:g.x),e.flyoutRect_.setAttribute("y",g.y))}this.width_=a;Blockly.fireUiEvent(window,"resize")}};Blockly.Block.prototype.moveTo=function(a,b){var c=this.getRelativeToSurfaceXY();this.svg_.getRootElement().setAttribute("transform","translate("+a+", "+b+")");this.moveConnections_(a-c.x,b-c.y)};
Blockly.Flyout.prototype.blockMouseDown_=function(a){var b=this;return function(c){Blockly.terminateDrag_();Blockly.hideChaff();Blockly.isRightButton(c)?Blockly.ContextMenu&&a.showContextMenu_(Blockly.mouseToSvg(c)):(Blockly.removeAllRanges(),Blockly.setCursorHand_(!0),Blockly.Flyout.startDownEvent_=c,Blockly.Flyout.startBlock_=a,Blockly.Flyout.startFlyout_=b,Blockly.Flyout.onMouseUpWrapper_=Blockly.bindEvent_(document,"mouseup",this,Blockly.terminateDrag_),Blockly.Flyout.onMouseMoveWrapper_=Blockly.bindEvent_(document,
"mousemove",this,b.onMouseMove_));c.stopPropagation()}};Blockly.Flyout.prototype.onMouseMove_=function(a){if("mousemove"==a.type&&1>=a.clientX&&0==a.clientY&&0==a.button)a.stopPropagation();else{Blockly.removeAllRanges();var b=a.clientY-Blockly.Flyout.startDownEvent_.clientY;Math.sqrt(Math.pow(a.clientX-Blockly.Flyout.startDownEvent_.clientX,2)+Math.pow(b,2))>Blockly.DRAG_RADIUS&&Blockly.Flyout.startFlyout_.createBlockFunc_(Blockly.Flyout.startBlock_)(Blockly.Flyout.startDownEvent_)}};
Blockly.Flyout.prototype.createBlockFunc_=function(a){var b=this;return function(c){if(!Blockly.isRightButton(c)&&!a.disabled){var d=Blockly.Xml.blockToDom_(a),d=Blockly.Xml.domToBlock_(b.targetWorkspace_,d),e=a.getSvgRoot();if(!e)throw"originBlock is not rendered.";var e=Blockly.getSvgXY_(e),f=d.getSvgRoot();if(!f)throw"block is not rendered.";f=Blockly.getSvgXY_(f);d.moveBy(e.x-f.x,e.y-f.y);b.autoClose?b.hide():b.filterForCapacity_();d.onMouseDown_(c)}}};
Blockly.Flyout.prototype.createBlockFunc_=function(a){var b=this;return function(c){if(!Blockly.isRightButton(c)&&!a.disabled){var d=Blockly.Xml.blockToDom_(a),d=Blockly.Xml.domToBlock(b.targetWorkspace_,d),e=a.getSvgRoot();if(!e)throw"originBlock is not rendered.";var e=Blockly.getSvgXY_(e),f=d.getSvgRoot();if(!f)throw"block is not rendered.";f=Blockly.getSvgXY_(f);d.moveBy(e.x-f.x,e.y-f.y);b.autoClose?b.hide():b.filterForCapacity_();d.onMouseDown_(c)}}};
Blockly.Flyout.prototype.filterForCapacity_=function(){for(var a=this.targetWorkspace_.remainingCapacity(),b=this.workspace_.getTopBlocks(!1),c=0,d;d=b[c];c++){var e=d.getDescendants().length>a;d.setDisabled(e)}};
Blockly.Flyout.terminateDrag_=function(){Blockly.Flyout.onMouseUpWrapper_&&(Blockly.unbindEvent_(Blockly.Flyout.onMouseUpWrapper_),Blockly.Flyout.onMouseUpWrapper_=null);Blockly.Flyout.onMouseMoveWrapper_&&(Blockly.unbindEvent_(Blockly.Flyout.onMouseMoveWrapper_),Blockly.Flyout.onMouseMoveWrapper_=null);Blockly.Flyout.startDownEvent_=null;Blockly.Flyout.startBlock_=null;Blockly.Flyout.startFlyout_=null};Blockly.Toolbox={};Blockly.Toolbox.width=0;Blockly.Toolbox.selectedOption_=null;Blockly.Toolbox.CONFIG_={indentWidth:19,cssRoot:"blocklyTreeRoot",cssHideRoot:"blocklyHidden",cssItem:"",cssTreeRow:"blocklyTreeRow",cssItemLabel:"blocklyTreeLabel",cssTreeIcon:"blocklyTreeIcon",cssExpandedFolderIcon:"blocklyTreeIconOpen",cssFileIcon:"blocklyTreeIconNone",cssSelectedRow:"blocklyTreeSelected"};
Blockly.Toolbox.createDom=function(a,b){Blockly.Toolbox.HtmlDiv=goog.dom.createDom("div","blocklyToolboxDiv");Blockly.Toolbox.HtmlDiv.setAttribute("dir",Blockly.RTL?"RTL":"LTR");b.appendChild(Blockly.Toolbox.HtmlDiv);Blockly.Toolbox.flyout_=new Blockly.Flyout;a.appendChild(Blockly.Toolbox.flyout_.createDom());Blockly.bindEvent_(Blockly.Toolbox.HtmlDiv,"mousedown",null,function(a){Blockly.isRightButton(a)||a.target==Blockly.Toolbox.HtmlDiv?Blockly.hideChaff(!1):Blockly.hideChaff(!0)})};
@ -927,8 +932,8 @@ Blockly.Toolbox.TreeControl.prototype.createNode=function(a){return new Blockly.
Blockly.Toolbox.TreeNode=function(a,b,c){goog.ui.tree.TreeNode.call(this,a,b,c);a=function(){Blockly.fireUiEvent(window,"resize")};goog.events.listen(Blockly.Toolbox.tree_,goog.ui.tree.BaseNode.EventType.EXPAND,a);goog.events.listen(Blockly.Toolbox.tree_,goog.ui.tree.BaseNode.EventType.COLLAPSE,a)};goog.inherits(Blockly.Toolbox.TreeNode,goog.ui.tree.TreeNode);Blockly.Toolbox.TreeNode.prototype.getExpandIconHtml=function(){return"<span></span>"};
Blockly.Toolbox.TreeNode.prototype.getExpandIconElement=function(){return null};Blockly.Toolbox.TreeNode.prototype.onMouseDown=function(a){this.hasChildren()&&this.isUserCollapsible_?(this.toggle(),this.select()):this.isSelected()?this.getTree().setSelectedItem(null):this.select();this.updateRow()};Blockly.Toolbox.TreeNode.prototype.onDoubleClick_=function(a){};Blockly.Variables={};Blockly.Variables.NAME_TYPE="VARIABLE";Blockly.Variables.allVariables=function(a){var b;b=a?a.getDescendants():Blockly.mainWorkspace.getAllBlocks();a=Object.create(null);for(var c=0;c<b.length;c++){var d=b[c].getVars;if(d)for(var d=d.call(b[c]),e=0;e<d.length;e++){var f=d[e];f&&(a[f.toLowerCase()]=f)}}b=[];for(var g in a)b.push(a[g]);return b};
Blockly.Variables.renameVariable=function(a,b){for(var c=Blockly.mainWorkspace.getAllBlocks(),d=0;d<c.length;d++){var e=c[d].renameVar;e&&e.call(c[d],a,b)}};
Blockly.Variables.flyoutCategory=function(a,b,c,d){var e=Blockly.Variables.allVariables();e.sort(goog.string.caseInsensitiveCompare);e.unshift(null);for(var f=void 0,g=0;g<e.length;g++)if(e[g]!==f){var h=Blockly.Blocks.variables_get?new Blockly.Block(d,"variables_get"):null;h&&h.initSvg();var k=Blockly.Blocks.variables_set?new Blockly.Block(d,"variables_set"):null;k&&k.initSvg();null===e[g]?f=(h||k).getVars()[0]:(h&&h.setFieldValue(e[g],"VAR"),k&&k.setFieldValue(e[g],"VAR"));k&&a.push(k);h&&a.push(h);
h&&k?b.push(c,3*c):b.push(2*c)}};Blockly.Variables.generateUniqueName=function(){var a=Blockly.Variables.allVariables(),b="";if(a.length){a.sort(goog.string.caseInsensitiveCompare);for(var c=0,d="i",e=0,f=!1;!b;){e=0;for(f=!1;e<a.length&&!f;)a[e].toLowerCase()==d&&(f=!0),e++;f?("z"===d[0]?(c++,d="a"):(d=String.fromCharCode(d.charCodeAt(0)+1),"l"==d[0]&&(d=String.fromCharCode(d.charCodeAt(0)+1))),0<c&&(d+=c)):b=d}}else b="i";return b};Blockly.FieldVariable=function(a,b){var c;if(b){var d=this;c=function(a){var c=Blockly.FieldVariable.dropdownChange.call(d,a);a=void 0===c?a:null===c?d.getValue():c;b.call(d,a);return c}}else c=Blockly.FieldVariable.dropdownChange;Blockly.FieldVariable.superClass_.constructor.call(this,Blockly.FieldVariable.dropdownCreate,c);a?this.setValue(a):this.setValue(Blockly.Variables.generateUniqueName())};goog.inherits(Blockly.FieldVariable,Blockly.FieldDropdown);
Blockly.Variables.flyoutCategory=function(a,b,c,d){var e=Blockly.Variables.allVariables();e.sort(goog.string.caseInsensitiveCompare);e.unshift(null);for(var f=void 0,g=0;g<e.length;g++)if(e[g]!==f){var h=Blockly.Blocks.variables_get?Blockly.Block.obtain(d,"variables_get"):null;h&&h.initSvg();var k=Blockly.Blocks.variables_set?Blockly.Block.obtain(d,"variables_set"):null;k&&k.initSvg();null===e[g]?f=(h||k).getVars()[0]:(h&&h.setFieldValue(e[g],"VAR"),k&&k.setFieldValue(e[g],"VAR"));k&&a.push(k);h&&
a.push(h);h&&k?b.push(c,3*c):b.push(2*c)}};Blockly.Variables.generateUniqueName=function(){var a=Blockly.Variables.allVariables(),b="";if(a.length){a.sort(goog.string.caseInsensitiveCompare);for(var c=0,d="i",e=0,f=!1;!b;){e=0;for(f=!1;e<a.length&&!f;)a[e].toLowerCase()==d&&(f=!0),e++;f?("z"===d[0]?(c++,d="a"):(d=String.fromCharCode(d.charCodeAt(0)+1),"l"==d[0]&&(d=String.fromCharCode(d.charCodeAt(0)+1))),0<c&&(d+=c)):b=d}}else b="i";return b};Blockly.FieldVariable=function(a,b){var c;if(b){var d=this;c=function(a){var c=Blockly.FieldVariable.dropdownChange.call(d,a);a=void 0===c?a:null===c?d.getValue():c;b.call(d,a);return c}}else c=Blockly.FieldVariable.dropdownChange;Blockly.FieldVariable.superClass_.constructor.call(this,Blockly.FieldVariable.dropdownCreate,c);a?this.setValue(a):this.setValue(Blockly.Variables.generateUniqueName())};goog.inherits(Blockly.FieldVariable,Blockly.FieldDropdown);
Blockly.FieldVariable.prototype.clone=function(){return new Blockly.FieldVariable(this.getValue(),this.changeHandler_)};Blockly.FieldVariable.prototype.getValue=function(){return this.getText()};Blockly.FieldVariable.prototype.setValue=function(a){this.value_=a;this.setText(a)};
Blockly.FieldVariable.dropdownCreate=function(){var a=Blockly.Variables.allVariables(),b=this.getText();b&&-1==a.indexOf(b)&&a.push(b);a.sort(goog.string.caseInsensitiveCompare);a.push(Blockly.Msg.RENAME_VARIABLE);a.push(Blockly.Msg.NEW_VARIABLE);for(var b=[],c=0;c<a.length;c++)b[c]=[a[c],a[c]];return b};
Blockly.FieldVariable.dropdownChange=function(a){function b(a,b){Blockly.hideChaff();var c=window.prompt(a,b);return c&&c.replace(/[\s\xa0]+/g," ").replace(/^ | $/g,"")}if(a==Blockly.Msg.RENAME_VARIABLE){var c=this.getText();(a=b(Blockly.Msg.RENAME_VARIABLE_TITLE.replace("%1",c),c))&&Blockly.Variables.renameVariable(c,a);return null}if(a==Blockly.Msg.NEW_VARIABLE)return(a=b(Blockly.Msg.NEW_VARIABLE_TITLE,""))?(Blockly.Variables.renameVariable(a,a),a):null};Blockly.Generator=function(a){this.name_=a;this.RESERVED_WORDS_=""};Blockly.Generator.NAME_TYPE="generated_function";
@ -941,9 +946,23 @@ Blockly.Generator.prototype.FUNCTION_NAME_PLACEHOLDER_REGEXP_=RegExp(Blockly.Gen
Blockly.Names.prototype.getDistinctName=function(a,b){for(var c=this.safeName_(a),d="";this.dbReverse_[c+d]||c+d in this.reservedDict_;)d=d?d+1:2;c+=d;this.dbReverse_[c]=!0;return c};Blockly.Names.prototype.safeName_=function(a){a?(a=encodeURI(a.replace(/ /g,"_")).replace(/[^\w]/g,"_"),-1!="0123456789".indexOf(a[0])&&(a="my_"+a)):a="unnamed";return a};Blockly.Names.equals=function(a,b){return a.toLowerCase()==b.toLowerCase()};Blockly.Procedures={};Blockly.Procedures.NAME_TYPE="PROCEDURE";Blockly.Procedures.allProcedures=function(){for(var a=Blockly.mainWorkspace.getAllBlocks(),b=[],c=[],d=0;d<a.length;d++){var e=a[d].getProcedureDef;e&&(e=e.call(a[d]))&&(e[2]?b.push(e):c.push(e))}c.sort(Blockly.Procedures.procTupleComparator_);b.sort(Blockly.Procedures.procTupleComparator_);return[c,b]};Blockly.Procedures.procTupleComparator_=function(a,b){var c=a[0].toLowerCase(),d=b[0].toLowerCase();return c>d?1:c<d?-1:0};
Blockly.Procedures.findLegalName=function(a,b){if(b.isInFlyout)return a;for(;!Blockly.Procedures.isLegalName(a,b.workspace,b);){var c=a.match(/^(.*?)(\d+)$/);a=c?c[1]+(parseInt(c[2],10)+1):a+"2"}return a};Blockly.Procedures.isLegalName=function(a,b,c){b=b.getAllBlocks();for(var d=0;d<b.length;d++)if(b[d]!=c){var e=b[d].getProcedureDef;if(e&&(e=e.call(b[d]),Blockly.Names.equals(e[0],a)))return!1}return!0};
Blockly.Procedures.rename=function(a){a=a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"");a=Blockly.Procedures.findLegalName(a,this.sourceBlock_);for(var b=this.sourceBlock_.workspace.getAllBlocks(),c=0;c<b.length;c++){var d=b[c].renameProcedure;d&&d.call(b[c],this.text_,a)}return a};
Blockly.Procedures.flyoutCategory=function(a,b,c,d){function e(e,f){for(var k=0;k<e.length;k++){var l=new Blockly.Block(d,f);l.setFieldValue(e[k][0],"NAME");for(var q=[],m=0;m<e[k][1].length;m++)q[m]="ARG"+m;l.setProcedureParameters(e[k][1],q);l.initSvg();a.push(l);b.push(2*c)}}if(Blockly.Blocks.procedures_defnoreturn){var f=new Blockly.Block(d,"procedures_defnoreturn");f.initSvg();a.push(f);b.push(2*c)}Blockly.Blocks.procedures_defreturn&&(f=new Blockly.Block(d,"procedures_defreturn"),f.initSvg(),
a.push(f),b.push(2*c));Blockly.Blocks.procedures_ifreturn&&(f=new Blockly.Block(d,"procedures_ifreturn"),f.initSvg(),a.push(f),b.push(2*c));b.length&&(b[b.length-1]=3*c);f=Blockly.Procedures.allProcedures();e(f[0],"procedures_callnoreturn");e(f[1],"procedures_callreturn")};Blockly.Procedures.getCallers=function(a,b){for(var c=[],d=b.getAllBlocks(),e=0;e<d.length;e++){var f=d[e].getProcedureCall;f&&(f=f.call(d[e]))&&Blockly.Names.equals(f,a)&&c.push(d[e])}return c};
Blockly.Procedures.disposeCallers=function(a,b){for(var c=Blockly.Procedures.getCallers(a,b),d=0;d<c.length;d++)c[d].dispose(!0,!1)};Blockly.Procedures.mutateCallers=function(a,b,c,d){a=Blockly.Procedures.getCallers(a,b);for(b=0;b<a.length;b++)a[b].setProcedureParameters(c,d)};Blockly.Procedures.getDefinition=function(a,b){for(var c=b.getAllBlocks(),d=0;d<c.length;d++){var e=c[d].getProcedureDef;if(e&&(e=e.call(c[d]))&&Blockly.Names.equals(e[0],a))return c[d]}return null};Blockly.Css={};Blockly.Css.inject=function(){var a=Blockly.Css.CONTENT.join("\n"),b=Blockly.pathToBlockly.replace(/[\\\/]$/,""),a=a.replace(/<<<PATH>>>/g,b);goog.cssom.addCssText(a)};
Blockly.Procedures.flyoutCategory=function(a,b,c,d){function e(e,f){for(var k=0;k<e.length;k++){var l=Blockly.Block.obtain(d,f);l.setFieldValue(e[k][0],"NAME");for(var q=[],m=0;m<e[k][1].length;m++)q[m]="ARG"+m;l.setProcedureParameters(e[k][1],q);l.initSvg();a.push(l);b.push(2*c)}}if(Blockly.Blocks.procedures_defnoreturn){var f=Blockly.Block.obtain(d,"procedures_defnoreturn");f.initSvg();a.push(f);b.push(2*c)}Blockly.Blocks.procedures_defreturn&&(f=Blockly.Block.obtain(d,"procedures_defreturn"),f.initSvg(),
a.push(f),b.push(2*c));Blockly.Blocks.procedures_ifreturn&&(f=Blockly.Block.obtain(d,"procedures_ifreturn"),f.initSvg(),a.push(f),b.push(2*c));b.length&&(b[b.length-1]=3*c);f=Blockly.Procedures.allProcedures();e(f[0],"procedures_callnoreturn");e(f[1],"procedures_callreturn")};Blockly.Procedures.getCallers=function(a,b){for(var c=[],d=b.getAllBlocks(),e=0;e<d.length;e++){var f=d[e].getProcedureCall;f&&(f=f.call(d[e]))&&Blockly.Names.equals(f,a)&&c.push(d[e])}return c};
Blockly.Procedures.disposeCallers=function(a,b){for(var c=Blockly.Procedures.getCallers(a,b),d=0;d<c.length;d++)c[d].dispose(!0,!1)};Blockly.Procedures.mutateCallers=function(a,b,c,d){a=Blockly.Procedures.getCallers(a,b);for(b=0;b<a.length;b++)a[b].setProcedureParameters(c,d)};Blockly.Procedures.getDefinition=function(a,b){for(var c=b.getAllBlocks(),d=0;d<c.length;d++){var e=c[d].getProcedureDef;if(e&&(e=e.call(c[d]))&&Blockly.Names.equals(e[0],a))return c[d]}return null};Blockly.Realtime={};Blockly.Realtime.enabled_=!1;Blockly.Realtime.model_=null;Blockly.Realtime.initUi_=null;Blockly.Realtime.blocksMap_=null;Blockly.Realtime.withinSync=!1;Blockly.Realtime.realtimeLoader_=null;Blockly.Realtime.isEnabled=function(){return Blockly.Realtime.enabled_};
Blockly.Realtime.initializeModel_=function(a){Blockly.Realtime.model_=a;var b=a.createMap();a.getRoot().set("blocks",b);b=a.createList();a.getRoot().set("topBlocks",b);b=a.createString("Chat with your collaborator by typing in this box!");a.getRoot().set("text",b)};Blockly.Realtime.removeBlock=function(a){Blockly.Realtime.blocksMap_["delete"](a.id.toString())};Blockly.Realtime.addTopBlock=function(a){-1==Blockly.Realtime.topBlocks_.indexOf(a)&&Blockly.Realtime.topBlocks_.push(a)};
Blockly.Realtime.removeTopBlock=function(a){Blockly.Realtime.topBlocks_.removeValue(a)};Blockly.Realtime.obtainBlock=function(a,b){return Blockly.Realtime.model_.create(Blockly.Block,a,b)};Blockly.Realtime.getBlockById=function(a){return Blockly.Realtime.blocksMap_.get(a)};
Blockly.Realtime.onObjectChange_=function(a){var b=a.events;a=a.events.length;for(var c=0;c<a;c++){var d=b[c];if(!d.isLocal&&"value_changed"==d.type)if("xmlDom"==d.property){var e=d.target;Blockly.Realtime.doWithinSync_(function(){Blockly.Realtime.placeBlockOnWorkspace_(e,!1);Blockly.Realtime.moveBlock_(e)})}else if("relativeX"==d.property||"relativeY"==d.property){var f=d.target;Blockly.Realtime.doWithinSync_(function(){f.svg_||Blockly.Realtime.placeBlockOnWorkspace_(f,!1);Blockly.Realtime.moveBlock_(f)})}}};
Blockly.Realtime.onBlocksMapChange_=function(a){console.log("Blocks Map event:");console.log(" id: "+a.property);if(!a.isLocal){var b=a.newValue;b?Blockly.Realtime.placeBlockOnWorkspace_(b,!a.oldValue):(b=a.oldValue,Blockly.Realtime.deleteBlock(b))}};Blockly.Realtime.doWithinSync_=function(a){if(Blockly.Realtime.withinSync)a();else try{Blockly.Realtime.withinSync=!0,a()}finally{Blockly.Realtime.withinSync=!1}};
Blockly.Realtime.placeBlockOnWorkspace_=function(a,b){Blockly.Realtime.doWithinSync_(function(){var c=Blockly.Xml.textToDom(a.xmlDom).firstChild;if(c=Blockly.Xml.domToBlock(Blockly.mainWorkspace,c,!0))b&&c.workspace.addTopBlock(c),(b||goog.array.contains(Blockly.Realtime.topBlocks_,c))&&Blockly.Realtime.moveBlock_(c)})};
Blockly.Realtime.moveBlock_=function(a){if(!isNaN(a.relativeX)&&!isNaN(a.relativeY)){var b=Blockly.svgSize().width,c=a.getRelativeToSurfaceXY(),d=a.relativeX-c.x;a.moveBy(Blockly.RTL?b-d:d,a.relativeY-c.y)}};Blockly.Realtime.deleteBlock=function(a){Blockly.Realtime.doWithinSync_(function(){a.dispose(!0,!0,!0)})};
Blockly.Realtime.loadBlocks_=function(){for(var a=Blockly.Realtime.blocksMap_.values(),b=0;b<a.length;b++){var c=parseInt(a[b].id,10);c>Blockly.getUidCounter()&&Blockly.setUidCounter(c+1)}a=Blockly.Realtime.topBlocks_;for(b=0;b<a.length;b++)c=a.get(b),Blockly.Realtime.placeBlockOnWorkspace_(c,!0)};
Blockly.Realtime.blockChanged=function(a){if(a.workspace==Blockly.mainWorkspace){a=a.getRootBlock();var b=a.getRelativeToSurfaceXY(),c=!1,d=Blockly.Xml.blockToDom_(a);d.setAttribute("id",a.id);var e=goog.dom.createDom("xml");e.appendChild(d);d=Blockly.Xml.domToText(e);d!=a.xmlDom&&(c=!0,a.xmlDom=d);if(a.relativeX!=b.x||a.relativeY!=b.y)a.relativeX=b.x,a.relativeY=b.y,c=!0;c&&Blockly.Realtime.blocksMap_.set(a.id.toString(),a)}};
Blockly.Realtime.onFileLoaded_=function(a){Blockly.Realtime.model_=a.getModel();Blockly.Realtime.blocksMap_=Blockly.Realtime.model_.getRoot().get("blocks");Blockly.Realtime.topBlocks_=Blockly.Realtime.model_.getRoot().get("topBlocks");Blockly.Realtime.model_.getRoot().addEventListener(gapi.drive.realtime.EventType.OBJECT_CHANGED,Blockly.Realtime.onObjectChange_);Blockly.Realtime.blocksMap_.addEventListener(gapi.drive.realtime.EventType.VALUE_CHANGED,Blockly.Realtime.onBlocksMapChange_);a=Blockly.Realtime.model_.getRoot().get("text");
var b=document.getElementById("chatbox");gapi.drive.realtime.databinding.bindString(a,b);b.disabled=!1;Blockly.Realtime.initUi_();Blockly.Realtime.loadBlocks_()};
Blockly.Realtime.registerTypes_=function(){var a=gapi.drive.realtime.custom;a.registerType(Blockly.Block,"Block");Blockly.Block.prototype.id=a.collaborativeField("id");Blockly.Block.prototype.type=a.collaborativeField("type");Blockly.Block.prototype.xmlDom=a.collaborativeField("xmlDom");Blockly.Block.prototype.relativeX=a.collaborativeField("relativeX");Blockly.Block.prototype.relativeY=a.collaborativeField("relativeY");a.setInitializer(Blockly.Block,Blockly.Block.prototype.initialize)};
Blockly.Realtime.REAUTH_INTERVAL_IN_MILLISECONDS_=18E5;Blockly.Realtime.afterAuth_=function(){window.setTimeout(function(){Blockly.Realtime.realtimeLoader_.authorizer.authorize(Blockly.Realtime.afterAuth_)},Blockly.Realtime.REAUTH_INTERVAL_IN_MILLISECONDS_)};
Blockly.Realtime.realtimeOptions_={clientId:"922110111899.apps.googleusercontent.com",authButtonElementId:"authorizeButton",initializeModel:Blockly.Realtime.initializeModel_,autoCreate:!0,defaultTitle:"New Realtime Blockly File",newFileMimeType:null,onFileLoaded:Blockly.Realtime.onFileLoaded_,registerTypes:Blockly.Realtime.registerTypes_,afterAuth:Blockly.Realtime.afterAuth_};
Blockly.Realtime.startRealtime=function(a){Blockly.Realtime.enabled_=!0;Blockly.Realtime.initUi_=a;Blockly.Realtime.realtimeLoader_=new rtclient.RealtimeLoader(Blockly.Realtime.realtimeOptions_);Blockly.Realtime.realtimeLoader_.start()};Blockly.Css={};Blockly.Css.inject=function(){var a=Blockly.Css.CONTENT.join("\n"),b=Blockly.pathToBlockly.replace(/[\\\/]$/,""),a=a.replace(/<<<PATH>>>/g,b);goog.cssom.addCssText(a)};
Blockly.Css.CONTENT=[".blocklySvg {"," background-color: #fff;"," border: 1px solid #ddd;","}",".blocklyWidgetDiv {"," position: absolute;"," display: none;"," z-index: 999;","}",".blocklyDraggable {"," /* Hotspot coordinates are baked into the CUR file, but they are still"," required in the CSS due to a Chrome bug."," http://code.google.com/p/chromium/issues/detail?id=1446 */"," cursor: url(<<<PATH>>>/media/handopen.cur) 8 5, auto;","}",".blocklyResizeSE {"," fill: #aaa;"," cursor: se-resize;",
"}",".blocklyResizeSW {"," fill: #aaa;"," cursor: sw-resize;","}",".blocklyResizeLine {"," stroke-width: 1;"," stroke: #888;","}",".blocklyHighlightedConnectionPath {"," stroke-width: 4px;"," stroke: #fc3;"," fill: none;","}",".blocklyPathLight {"," fill: none;"," stroke-width: 2;"," stroke-linecap: round;","}",".blocklySelected>.blocklyPath {"," stroke-width: 3px;"," stroke: #fc3;","}",".blocklySelected>.blocklyPathLight {"," display: none;","}",".blocklyDragging>.blocklyPath,",".blocklyDragging>.blocklyPathLight {",
" fill-opacity: 0.8;"," stroke-opacity: 0.8;","}",".blocklyDragging>.blocklyPathDark {"," display: none;","}",".blocklyDisabled>.blocklyPath {"," fill-opacity: 0.50;"," stroke-opacity: 0.50;","}",".blocklyDisabled>.blocklyPathLight,",".blocklyDisabled>.blocklyPathDark {"," display: none;","}",".blocklyText {"," cursor: default;"," font-family: sans-serif;"," font-size: 11pt;"," fill: #fff;","}",".blocklyNonEditableText>text {"," pointer-events: none;","}",".blocklyNonEditableText>rect,",

View file

@ -24,9 +24,9 @@ if (!window.goog) {
// Build map of all dependencies (used and unused).
var dir = window.BLOCKLY_DIR.match(/[^\/]+$/)[0];
goog.addDependency("../../../" + dir + "/core/block.js", ['Blockly.Block'], ['Blockly.BlockSvg', 'Blockly.Blocks', 'Blockly.Comment', 'Blockly.Connection', 'Blockly.ContextMenu', 'Blockly.Input', 'Blockly.Msg', 'Blockly.Mutator', 'Blockly.Warning', 'Blockly.Workspace', 'Blockly.Xml', 'goog.asserts', 'goog.string', 'goog.Timer']);
goog.addDependency("../../../" + dir + "/core/block.js", ['Blockly.Block'], ['Blockly.BlockSvg', 'Blockly.Blocks', 'Blockly.Comment', 'Blockly.Connection', 'Blockly.ContextMenu', 'Blockly.Input', 'Blockly.Msg', 'Blockly.Mutator', 'Blockly.Warning', 'Blockly.Workspace', 'Blockly.Xml', 'goog.asserts', 'goog.string', 'goog.Timer', 'goog.array']);
goog.addDependency("../../../" + dir + "/core/block_svg.js", ['Blockly.BlockSvg'], ['goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/blockly.js", ['Blockly'], ['Blockly.Block', 'Blockly.Connection', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.Generator', 'Blockly.Msg', 'Blockly.Procedures', 'Blockly.Toolbox', 'Blockly.WidgetDiv', 'Blockly.Workspace', 'Blockly.inject', 'Blockly.utils', 'goog.dom', 'goog.color', 'goog.events', 'goog.string', 'goog.ui.ColorPicker', 'goog.ui.tree.TreeControl', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/blockly.js", ['Blockly'], ['Blockly.Block', 'Blockly.Connection', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.Generator', 'Blockly.Msg', 'Blockly.Procedures', 'Blockly.Realtime', 'Blockly.Toolbox', 'Blockly.WidgetDiv', 'Blockly.Workspace', 'Blockly.inject', 'Blockly.utils', 'goog.dom', 'goog.color', 'goog.events', 'goog.string', 'goog.ui.ColorPicker', 'goog.ui.tree.TreeControl', 'goog.userAgent']);
goog.addDependency("../../../" + dir + "/core/blocks.js", ['Blockly.Blocks'], ['goog.asserts']);
goog.addDependency("../../../" + dir + "/core/bubble.js", ['Blockly.Bubble'], ['Blockly.Workspace']);
goog.addDependency("../../../" + dir + "/core/comment.js", ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Icon']);
@ -61,6 +61,8 @@ goog.addDependency("../../../" + dir + "/core/warning.js", ['Blockly.Warning'],
goog.addDependency("../../../" + dir + "/core/widgetdiv.js", ['Blockly.WidgetDiv'], ['Blockly.Css', 'goog.dom']);
goog.addDependency("../../../" + dir + "/core/workspace.js", ['Blockly.Workspace'], ['Blockly.ScrollbarPair', 'Blockly.Trashcan', 'Blockly.Xml']);
goog.addDependency("../../../" + dir + "/core/xml.js", ['Blockly.Xml'], []);
goog.addDependency("../../../" + dir + "/realtime/realtime-client-utils.js", [], []);
goog.addDependency("../../../" + dir + "/realtime/realtime.js", ['Blockly.Realtime'], ['goog.array']);
goog.addDependency("../../alltests.js", [], []);
goog.addDependency("base.js", [], []);
goog.addDependency("deps.js", [], []);
@ -951,6 +953,7 @@ goog.require('Blockly.Msg');
goog.require('Blockly.Mutator');
goog.require('Blockly.Names');
goog.require('Blockly.Procedures');
goog.require('Blockly.Realtime');
goog.require('Blockly.Scrollbar');
goog.require('Blockly.ScrollbarPair');
goog.require('Blockly.Toolbox');

View file

@ -75,12 +75,12 @@ Blockly.Blocks['lists_create_with'] = {
}
},
decompose: function(workspace) {
var containerBlock = new Blockly.Block(workspace,
'lists_create_with_container');
var containerBlock =
Blockly.Block.obtain(workspace, 'lists_create_with_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var x = 0; x < this.itemCount_; x++) {
var itemBlock = new Blockly.Block(workspace, 'lists_create_with_item');
var itemBlock = Blockly.Block.obtain(workspace, 'lists_create_with_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;

View file

@ -88,17 +88,17 @@ Blockly.Blocks['controls_if'] = {
}
},
decompose: function(workspace) {
var containerBlock = new Blockly.Block(workspace, 'controls_if_if');
var containerBlock = Blockly.Block.obtain(workspace, 'controls_if_if');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var x = 1; x <= this.elseifCount_; x++) {
var elseifBlock = new Blockly.Block(workspace, 'controls_if_elseif');
var elseifBlock = Blockly.Block.obtain(workspace, 'controls_if_elseif');
elseifBlock.initSvg();
connection.connect(elseifBlock.previousConnection);
connection = elseifBlock.nextConnection;
}
if (this.elseCount_) {
var elseBlock = new Blockly.Block(workspace, 'controls_if_else');
var elseBlock = Blockly.Block.obtain(workspace, 'controls_if_else');
elseBlock.initSvg();
connection.connect(elseBlock.previousConnection);
}

View file

@ -89,12 +89,12 @@ Blockly.Blocks['procedures_defnoreturn'] = {
this.updateParams_();
},
decompose: function(workspace) {
var containerBlock = new Blockly.Block(workspace,
var containerBlock = Blockly.Block.obtain(workspace,
'procedures_mutatorcontainer');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var x = 0; x < this.arguments_.length; x++) {
var paramBlock = new Blockly.Block(workspace, 'procedures_mutatorarg');
var paramBlock = Blockly.Block.obtain(workspace, 'procedures_mutatorarg');
paramBlock.initSvg();
paramBlock.setFieldValue(this.arguments_[x], 'NAME');
// Store the old location.

View file

@ -82,12 +82,12 @@ Blockly.Blocks['text_join'] = {
}
},
decompose: function(workspace) {
var containerBlock = new Blockly.Block(workspace,
var containerBlock = Blockly.Block.obtain(workspace,
'text_create_join_container');
containerBlock.initSvg();
var connection = containerBlock.getInput('STACK').connection;
for (var x = 0; x < this.itemCount_; x++) {
var itemBlock = new Blockly.Block(workspace, 'text_create_join_item');
var itemBlock = Blockly.Block.obtain(workspace, 'text_create_join_item');
itemBlock.initSvg();
connection.connect(itemBlock.previousConnection);
connection = itemBlock.nextConnection;

View file

@ -8,7 +8,7 @@ this.setOutput(!0,"Colour");this.setTooltip(Blockly.Msg.COLOUR_RGB_TOOLTIP)}};
Blockly.Blocks.colour_blend={init:function(){this.setHelpUrl(Blockly.Msg.COLOUR_BLEND_HELPURL);this.setColour(20);this.appendValueInput("COLOUR1").setCheck("Colour").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.COLOUR_BLEND_TITLE).appendField(Blockly.Msg.COLOUR_BLEND_COLOUR1);this.appendValueInput("COLOUR2").setCheck("Colour").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.COLOUR_BLEND_COLOUR2);this.appendValueInput("RATIO").setCheck("Number").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.COLOUR_BLEND_RATIO);this.setOutput(!0,
"Colour");this.setTooltip(Blockly.Msg.COLOUR_BLEND_TOOLTIP)}};Blockly.Blocks.lists={};Blockly.Blocks.lists_create_empty={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_EMPTY_HELPURL);this.setColour(260);this.setOutput(!0,"Array");this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);this.setTooltip(Blockly.Msg.LISTS_CREATE_EMPTY_TOOLTIP)}};
Blockly.Blocks.lists_create_with={init:function(){this.setColour(260);this.appendValueInput("ADD0").appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH);this.appendValueInput("ADD1");this.appendValueInput("ADD2");this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP);this.itemCount_=3},mutationToDom:function(a){a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){for(var b=
0;b<this.itemCount_;b++)this.removeInput("ADD"+b);this.itemCount_=parseInt(a.getAttribute("items"),10);for(b=0;b<this.itemCount_;b++)a=this.appendValueInput("ADD"+b),0==b&&a.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH);0==this.itemCount_&&this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE)},decompose:function(a){var b=new Blockly.Block(a,"lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=new Blockly.Block(a,
0;b<this.itemCount_;b++)this.removeInput("ADD"+b);this.itemCount_=parseInt(a.getAttribute("items"),10);for(b=0;b<this.itemCount_;b++)a=this.appendValueInput("ADD"+b),0==b&&a.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH);0==this.itemCount_&&this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE)},decompose:function(a){var b=Blockly.Block.obtain(a,"lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=Blockly.Block.obtain(a,
"lists_create_with_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){if(0==this.itemCount_)this.removeInput("EMPTY");else for(var b=this.itemCount_-1;0<=b;b--)this.removeInput("ADD"+b);this.itemCount_=0;for(a=a.getInputTargetBlock("STACK");a;)b=this.appendValueInput("ADD"+this.itemCount_),0==this.itemCount_&&b.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH),a.valueConnection_&&b.connection.connect(a.valueConnection_),this.itemCount_++,a=a.nextConnection&&
a.nextConnection.targetBlock();0==this.itemCount_&&this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}}};
Blockly.Blocks.lists_create_with_container={init:function(){this.setColour(260);this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);this.appendStatementInput("STACK");this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);this.contextMenu=!1}};
@ -32,8 +32,8 @@ Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly
this.appendDummyInput("AT"+a);var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var e="FROM_START"==c||"FROM_END"==c;if(e!=b){var f=this.sourceBlock_;f.updateAt(a,e);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&this.moveInputBefore("ORDINAL1","AT2"));Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.moveInputBefore("TAIL",null)}};Blockly.Blocks.logic={};
Blockly.Blocks.controls_if={init:function(){this.setHelpUrl(Blockly.Msg.CONTROLS_IF_HELPURL);this.setColour(210);this.appendValueInput("IF0").setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);this.appendStatementInput("DO0").appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setMutator(new Blockly.Mutator(["controls_if_elseif","controls_if_else"]));var a=this;this.setTooltip(function(){if(a.elseifCount_||a.elseCount_){if(!a.elseifCount_&&
a.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;if(a.elseifCount_&&!a.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;if(a.elseifCount_&&a.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_4}else return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;return""});this.elseCount_=this.elseifCount_=0},mutationToDom:function(){if(!this.elseifCount_&&!this.elseCount_)return null;var a=document.createElement("mutation");this.elseifCount_&&a.setAttribute("elseif",this.elseifCount_);this.elseCount_&&a.setAttribute("else",
1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10);this.elseCount_=parseInt(a.getAttribute("else"),10);for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)},decompose:function(a){var b=new Blockly.Block(a,
"controls_if_if");b.initSvg();for(var c=b.getInput("STACK").connection,d=1;d<=this.elseifCount_;d++){var e=new Blockly.Block(a,"controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=new Blockly.Block(a,"controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){this.elseCount_&&this.removeInput("ELSE");this.elseCount_=0;for(var b=this.elseifCount_;0<b;b--)this.removeInput("IF"+b),this.removeInput("DO"+b);this.elseifCount_=
1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10);this.elseCount_=parseInt(a.getAttribute("else"),10);for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)},decompose:function(a){var b=Blockly.Block.obtain(a,
"controls_if_if");b.initSvg();for(var c=b.getInput("STACK").connection,d=1;d<=this.elseifCount_;d++){var e=Blockly.Block.obtain(a,"controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=Blockly.Block.obtain(a,"controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){this.elseCount_&&this.removeInput("ELSE");this.elseCount_=0;for(var b=this.elseifCount_;0<b;b--)this.removeInput("IF"+b),this.removeInput("DO"+b);this.elseifCount_=
0;for(a=a.getInputTargetBlock("STACK");a;){switch(a.type){case "controls_if_elseif":this.elseifCount_++;var b=this.appendValueInput("IF"+this.elseifCount_).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),c=this.appendStatementInput("DO"+this.elseifCount_);c.appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);a.valueConnection_&&b.connection.connect(a.valueConnection_);a.statementConnection_&&c.connection.connect(a.statementConnection_);break;case "controls_if_else":this.elseCount_++;
b=this.appendStatementInput("ELSE");b.appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE);a.statementConnection_&&b.connection.connect(a.statementConnection_);break;default:throw"Unknown block type.";}a=a.nextConnection&&a.nextConnection.targetBlock()}},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=1;a;){switch(a.type){case "controls_if_elseif":var c=this.getInput("IF"+b),d=this.getInput("DO"+b);a.valueConnection_=c&&c.connection.targetConnection;a.statementConnection_=d&&d.connection.targetConnection;
b++;break;case "controls_if_else":d=this.getInput("ELSE");a.statementConnection_=d&&d.connection.targetConnection;break;default:throw"Unknown block type.";}a=a.nextConnection&&a.nextConnection.targetBlock()}}};Blockly.Blocks.controls_if_if={init:function(){this.setColour(210);this.appendDummyInput().appendField(Blockly.Msg.CONTROLS_IF_IF_TITLE_IF);this.appendStatementInput("STACK");this.setTooltip(Blockly.Msg.CONTROLS_IF_IF_TOOLTIP);this.contextMenu=!1}};
@ -78,8 +78,8 @@ Blockly.Blocks.math_random_int={init:function(){this.setHelpUrl(Blockly.Msg.MATH
Blockly.Blocks.math_random_float={init:function(){this.setHelpUrl(Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL);this.setColour(230);this.setOutput(!0,"Number");this.appendDummyInput().appendField(Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM);this.setTooltip(Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP)}};Blockly.Blocks.procedures={};
Blockly.Blocks.procedures_defnoreturn={init:function(){this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.setColour(290);var a=Blockly.Procedures.findLegalName(Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE,this);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(new Blockly.FieldTextInput(a,Blockly.Procedures.rename),"NAME").appendField("","PARAMS");this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));
this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.arguments_=[]},updateParams_:function(){for(var a=!1,b={},c=0;c<this.arguments_.length;c++){if(b["arg_"+this.arguments_[c].toLowerCase()]){a=!0;break}b["arg_"+this.arguments_[c].toLowerCase()]=!0}a?this.setWarningText(Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING):this.setWarningText(null);a="";this.arguments_.length&&(a=Blockly.Msg.PROCEDURES_BEFORE_PARAMS+" "+this.arguments_.join(", "));this.setFieldValue(a,"PARAMS")},mutationToDom:function(){for(var a=
document.createElement("mutation"),b=0;b<this.arguments_.length;b++){var c=document.createElement("arg");c.setAttribute("name",this.arguments_[b]);a.appendChild(c)}return a},domToMutation:function(a){this.arguments_=[];for(var b=0,c;c=a.childNodes[b];b++)"arg"==c.nodeName.toLowerCase()&&this.arguments_.push(c.getAttribute("name"));this.updateParams_()},decompose:function(a){var b=new Blockly.Block(a,"procedures_mutatorcontainer");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.arguments_.length;d++){var e=
new Blockly.Block(a,"procedures_mutatorarg");e.initSvg();e.setFieldValue(this.arguments_[d],"NAME");e.oldLocation=d;c.connect(e.previousConnection);c=e.nextConnection}Blockly.Procedures.mutateCallers(this.getFieldValue("NAME"),this.workspace,this.arguments_,null);return b},compose:function(a){this.arguments_=[];this.paramIds_=[];for(a=a.getInputTargetBlock("STACK");a;)this.arguments_.push(a.getFieldValue("NAME")),this.paramIds_.push(a.id),a=a.nextConnection&&a.nextConnection.targetBlock();this.updateParams_();
document.createElement("mutation"),b=0;b<this.arguments_.length;b++){var c=document.createElement("arg");c.setAttribute("name",this.arguments_[b]);a.appendChild(c)}return a},domToMutation:function(a){this.arguments_=[];for(var b=0,c;c=a.childNodes[b];b++)"arg"==c.nodeName.toLowerCase()&&this.arguments_.push(c.getAttribute("name"));this.updateParams_()},decompose:function(a){var b=Blockly.Block.obtain(a,"procedures_mutatorcontainer");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.arguments_.length;d++){var e=
Blockly.Block.obtain(a,"procedures_mutatorarg");e.initSvg();e.setFieldValue(this.arguments_[d],"NAME");e.oldLocation=d;c.connect(e.previousConnection);c=e.nextConnection}Blockly.Procedures.mutateCallers(this.getFieldValue("NAME"),this.workspace,this.arguments_,null);return b},compose:function(a){this.arguments_=[];this.paramIds_=[];for(a=a.getInputTargetBlock("STACK");a;)this.arguments_.push(a.getFieldValue("NAME")),this.paramIds_.push(a.id),a=a.nextConnection&&a.nextConnection.targetBlock();this.updateParams_();
Blockly.Procedures.mutateCallers(this.getFieldValue("NAME"),this.workspace,this.arguments_,this.paramIds_)},dispose:function(){var a=this.getFieldValue("NAME");Blockly.Procedures.disposeCallers(a,this.workspace);Blockly.Block.prototype.dispose.apply(this,arguments)},getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!1]},getVars:function(){return this.arguments_},renameVar:function(a,b){for(var c=!1,d=0;d<this.arguments_.length;d++)Blockly.Names.equals(a,this.arguments_[d])&&
(this.arguments_[d]=b,c=!0);if(c&&(this.updateParams_(),this.mutator.isVisible_()))for(var c=this.mutator.workspace_.getAllBlocks(),d=0,e;e=c[d];d++)"procedures_mutatorarg"==e.type&&Blockly.Names.equals(a,e.getFieldValue("NAME"))&&e.setFieldValue(b,"NAME")},customContextMenu:function(a){var b={enabled:!0},c=this.getFieldValue("NAME");b.text=Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1",c);var d=goog.dom.createDom("mutation");d.setAttribute("name",c);for(var e=0;e<this.arguments_.length;e++)c=goog.dom.createDom("arg"),
c.setAttribute("name",this.arguments_[e]),d.appendChild(c);d=goog.dom.createDom("block",null,d);d.setAttribute("type",this.callType_);b.callback=Blockly.ContextMenu.callbackFactory(this,d);a.push(b);for(e=0;e<this.arguments_.length;e++)b={enabled:!0},c=this.arguments_[e],b.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c),d=goog.dom.createDom("field",null,c),d.setAttribute("name","VAR"),d=goog.dom.createDom("block",null,d),d.setAttribute("type","variables_get"),b.callback=Blockly.ContextMenu.callbackFactory(this,
@ -101,8 +101,8 @@ Blockly.Blocks.procedures_ifreturn={init:function(){this.setHelpUrl("http://c2.c
document.createElement("mutation");a.setAttribute("value",Number(this.hasReturnValue_));return a},domToMutation:function(a){this.hasReturnValue_=1==a.getAttribute("value");this.hasReturnValue_||(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN))},onchange:function(){if(this.workspace){var a=!1,b=this;do{if("procedures_defnoreturn"==b.type||"procedures_defreturn"==b.type){a=!0;break}b=b.getSurroundParent()}while(b);a?("procedures_defnoreturn"==
b.type&&this.hasReturnValue_?(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!1):"procedures_defreturn"!=b.type||this.hasReturnValue_||(this.removeInput("VALUE"),this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!0),this.setWarningText(null)):this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING)}}};Blockly.Blocks.text={};Blockly.Blocks.text={init:function(){this.setHelpUrl(Blockly.Msg.TEXT_TEXT_HELPURL);this.setColour(160);this.appendDummyInput().appendField(new Blockly.FieldImage(Blockly.pathToBlockly+"media/quote0.png",12,12,'"')).appendField(new Blockly.FieldTextInput(""),"TEXT").appendField(new Blockly.FieldImage(Blockly.pathToBlockly+"media/quote1.png",12,12,'"'));this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_TEXT_TOOLTIP)}};
Blockly.Blocks.text_join={init:function(){this.setHelpUrl(Blockly.Msg.TEXT_JOIN_HELPURL);this.setColour(160);this.appendValueInput("ADD0").appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH);this.appendValueInput("ADD1");this.setOutput(!0,"String");this.setMutator(new Blockly.Mutator(["text_create_join_item"]));this.setTooltip(Blockly.Msg.TEXT_JOIN_TOOLTIP);this.itemCount_=2},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){for(var b=
0;b<this.itemCount_;b++)this.removeInput("ADD"+b);this.itemCount_=parseInt(a.getAttribute("items"),10);for(b=0;b<this.itemCount_;b++)a=this.appendValueInput("ADD"+b),0==b&&a.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH);0==this.itemCount_&&this.appendDummyInput("EMPTY").appendField(new Blockly.FieldImage(Blockly.pathToBlockly+"media/quote0.png",12,12,'"')).appendField(new Blockly.FieldImage(Blockly.pathToBlockly+"media/quote1.png",12,12,'"'))},decompose:function(a){var b=new Blockly.Block(a,
"text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=new Blockly.Block(a,"text_create_join_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){if(0==this.itemCount_)this.removeInput("EMPTY");else for(var b=this.itemCount_-1;0<=b;b--)this.removeInput("ADD"+b);this.itemCount_=0;for(a=a.getInputTargetBlock("STACK");a;)b=this.appendValueInput("ADD"+this.itemCount_),0==this.itemCount_&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH),
0;b<this.itemCount_;b++)this.removeInput("ADD"+b);this.itemCount_=parseInt(a.getAttribute("items"),10);for(b=0;b<this.itemCount_;b++)a=this.appendValueInput("ADD"+b),0==b&&a.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH);0==this.itemCount_&&this.appendDummyInput("EMPTY").appendField(new Blockly.FieldImage(Blockly.pathToBlockly+"media/quote0.png",12,12,'"')).appendField(new Blockly.FieldImage(Blockly.pathToBlockly+"media/quote1.png",12,12,'"'))},decompose:function(a){var b=Blockly.Block.obtain(a,
"text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=Blockly.Block.obtain(a,"text_create_join_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){if(0==this.itemCount_)this.removeInput("EMPTY");else for(var b=this.itemCount_-1;0<=b;b--)this.removeInput("ADD"+b);this.itemCount_=0;for(a=a.getInputTargetBlock("STACK");a;)b=this.appendValueInput("ADD"+this.itemCount_),0==this.itemCount_&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH),
a.valueConnection_&&b.connection.connect(a.valueConnection_),this.itemCount_++,a=a.nextConnection&&a.nextConnection.targetBlock();0==this.itemCount_&&this.appendDummyInput("EMPTY").appendField(new Blockly.FieldImage(Blockly.pathToBlockly+"media/quote0.png",12,12,'"')).appendField(new Blockly.FieldImage(Blockly.pathToBlockly+"media/quote1.png",12,12,'"'))},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;
b++;a=a.nextConnection&&a.nextConnection.targetBlock()}}};Blockly.Blocks.text_create_join_container={init:function(){this.setColour(160);this.appendDummyInput().appendField(Blockly.Msg.TEXT_CREATE_JOIN_TITLE_JOIN);this.appendStatementInput("STACK");this.setTooltip(Blockly.Msg.TEXT_CREATE_JOIN_TOOLTIP);this.contextMenu=!1}};
Blockly.Blocks.text_create_join_item={init:function(){this.setColour(160);this.appendDummyInput().appendField(Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TOOLTIP);this.contextMenu=!1}};

View file

@ -108,6 +108,9 @@ var dir = window.BLOCKLY_DIR.match(/[^\\/]+$/)[0];
m = re.search('[\\/]([^\\/]+)[\\/]core[\\/]blockly.js', add_dependency)
add_dependency = re.sub('([\\/])' + re.escape(m.group(1)) +
'([\\/]core[\\/])', '\\1" + dir + "\\2', add_dependency)
m = re.search('[\\/]([^\\/]+)[\\/]realtime[\\/]realtime.js', add_dependency)
add_dependency = re.sub('([\\/])' + re.escape(m.group(1)) +
'([\\/]realtime[\\/])', '\\1" + dir + "\\2', add_dependency)
f.write(add_dependency + '\n')
provides = []
@ -386,7 +389,7 @@ if __name__ == '__main__':
http://code.google.com/p/blockly/wiki/Closure""")
sys.exit(1)
search_paths = calcdeps.ExpandDirectories(
['core', os.path.join(os.path.pardir, 'closure-library-read-only')])
['core', 'realtime', os.path.join(os.path.pardir, 'closure-library-read-only')])
# Run both tasks in parallel threads.
# Uncompressed is limited by processor speed.

View file

@ -39,6 +39,7 @@ goog.require('Blockly.Xml');
goog.require('goog.asserts');
goog.require('goog.string');
goog.require('goog.Timer');
goog.require('goog.array');
/**
@ -48,14 +49,81 @@ goog.require('goog.Timer');
Blockly.uidCounter_ = 0;
/**
* Class for one block.
* Get the Blockly.uidCounter_
* @returns {number}
*/
Blockly.getUidCounter = function() {
return Blockly.uidCounter_;
}
/**
* Set the Blockly.uidCounter_
* @param {number} val The value to set the counter to.
*/
Blockly.setUidCounter = function(val) {
Blockly.uidCounter_ = val;
}
/**
* Check is realtime collaboration is enabled for this Blockly app.
* @returns {Blockly.Realtime|*|boolean}
*/
Blockly.isRealtimeEnabled = function() {
return (typeof Blockly.Realtime != 'undefined') &&
Blockly.Realtime && Blockly.Realtime.isEnabled();
};
/**
* Class for one block.
* @constructor
*/
Blockly.Block = function() {
// We assert this here because there may be users of the previous form of
// this constructor, which took arguments.
goog.asserts.assert(arguments.length == 0,
'Please use Blockly.Block.obtain.');
};
/**
* Obtain a newly created block.
* @param {!Blockly.Workspace} workspace The block's workspace.
* @param {?string} prototypeName Name of the language object containing
* type-specific functions for this block.
* @return {!Blockly.Block} The created block
*/
Blockly.Block.obtain = function(workspace, prototypeName) {
if (Blockly.isRealtimeEnabled()) {
return Blockly.Realtime.obtainBlock(workspace, prototypeName);
} else {
var newBlock = new Blockly.Block();
newBlock.initialize(workspace, prototypeName);
return newBlock;
}
};
/**
* Initialization for one block.
* @param {!Blockly.Workspace} workspace The new block's workspace.
* @param {?string} prototypeName Name of the language object containing
* type-specific functions for this block.
* @constructor
*/
Blockly.Block = function(workspace, prototypeName) {
Blockly.Block.prototype.initialize = function(workspace, prototypeName) {
this.id = ++Blockly.uidCounter_;
workspace.addTopBlock(this);
this.fill(workspace, prototypeName);
// Bind an onchange function, if it exists.
if (goog.isFunction(this.onchange)) {
Blockly.bindEvent_(workspace.getCanvas(), 'blocklyWorkspaceChange', this,
this.onchange);
}
};
/**
* Fill a block with initial values.
* @param {!Blockly.Workspace} workspace The workspace to use.
* @param {string} prototypeName The typename of the block.
*/
Blockly.Block.prototype.fill = function(workspace, prototypeName) {
this.outputConnection = null;
this.nextConnection = null;
this.previousConnection = null;
@ -76,8 +144,6 @@ Blockly.Block = function(workspace, prototypeName) {
this.workspace = workspace;
this.isInFlyout = workspace.isFlyout;
workspace.addTopBlock(this);
// Copy the type-specific functions and data from the prototype.
if (prototypeName) {
this.type = prototypeName;
@ -90,10 +156,19 @@ Blockly.Block = function(workspace, prototypeName) {
if (goog.isFunction(this.init)) {
this.init();
}
// Bind an onchange function, if it exists.
if (goog.isFunction(this.onchange)) {
Blockly.bindEvent_(workspace.getCanvas(), 'blocklyWorkspaceChange', this,
this.onchange);
};
/**
* Get an existing block.
* @param {string} id The block's id.
* @param {!Blockly.Workspace} workspace The block's workspace.
* @return {Blockly.Block} The found block, or null if not found.
*/
Blockly.Block.getById = function(id, workspace) {
if (Blockly.isRealtimeEnabled()) {
return Blockly.Realtime.getBlockById(id);
} else {
return workspace.getBlockById(id);
}
};
@ -251,8 +326,11 @@ Blockly.Block.prototype.unselect = function() {
* the next statement with the previous statement. Otherwise, dispose of
* all children of this block.
* @param {boolean} animate If true, show a disposal animation and sound.
* @param {boolean} dontRemoveFromWorkspace If true, don't remove this block
* from the workspace's list of top blocks.
*/
Blockly.Block.prototype.dispose = function(healStack, animate) {
Blockly.Block.prototype.dispose = function(healStack, animate,
dontRemoveFromWorkspace) {
// Switch off rerendering.
this.rendered = false;
this.unplug(healStack);
@ -261,10 +339,12 @@ Blockly.Block.prototype.dispose = function(healStack, animate) {
this.svg_.disposeUiEffect();
}
//This block is now at the top of the workspace.
// This block is now at the top of the workspace.
// Remove this block from the workspace's list of top-most blocks.
this.workspace.removeTopBlock(this);
this.workspace = null;
if (this.workspace && !dontRemoveFromWorkspace) {
this.workspace.removeTopBlock(this);
this.workspace = null;
}
// Just deleting this block from the DOM would result in a memory leak as
// well as corruption of the connection database. Therefore we must
@ -304,6 +384,10 @@ Blockly.Block.prototype.dispose = function(healStack, animate) {
this.svg_.dispose();
this.svg_ = null;
}
// Remove from Realtime set of blocks.
if (Blockly.isRealtimeEnabled() && !Blockly.Realtime.withinSync) {
Blockly.Realtime.removeBlock(this);
}
};
/**
@ -378,6 +462,9 @@ Blockly.Block.prototype.moveBy = function(dx, dy) {
this.svg_.getRootElement().setAttribute('transform',
'translate(' + (xy.x + dx) + ', ' + (xy.y + dy) + ')');
this.moveConnections_(dx, dy);
if (Blockly.isRealtimeEnabled() && !Blockly.Realtime.withinSync) {
Blockly.Realtime.blockChanged(this);
}
};
/**
@ -527,7 +614,7 @@ Blockly.Block.prototype.duplicate_ = function() {
// Create a duplicate via XML.
var xmlBlock = Blockly.Xml.blockToDom_(this);
Blockly.Xml.deleteNext(xmlBlock);
var newBlock = Blockly.Xml.domToBlock_(
var newBlock = Blockly.Xml.domToBlock(
/** @type {!Blockly.Workspace} */ (this.workspace), xmlBlock);
// Move the duplicate next to the old block.
var xy = this.getRelativeToSurfaceXY();
@ -958,7 +1045,11 @@ Blockly.Block.prototype.setParent = function(newParent) {
// its connection locations.
} else {
// Remove this block from the workspace's list of top-most blocks.
this.workspace.removeTopBlock(this);
// Note that during realtime sync we sometimes create child blocks that are
// not top level so we check first before removing.
if (goog.array.contains(this.workspace.getTopBlocks(false), this)) {
this.workspace.removeTopBlock(this);
}
}
this.parentBlock_ = newParent;
@ -1761,4 +1852,7 @@ Blockly.Block.prototype.render = function() {
goog.asserts.assertObject(this.svg_,
'Uninitialized block cannot be rendered. Call block.initSvg()');
this.svg_.render();
if (Blockly.isRealtimeEnabled() && !Blockly.Realtime.withinSync) {
Blockly.Realtime.blockChanged(this);
}
};

View file

@ -39,6 +39,7 @@ goog.require('Blockly.FieldVariable');
goog.require('Blockly.Generator');
goog.require('Blockly.Msg');
goog.require('Blockly.Procedures');
goog.require('Blockly.Realtime');
goog.require('Blockly.Toolbox');
goog.require('Blockly.WidgetDiv');
goog.require('Blockly.Workspace');

View file

@ -210,7 +210,7 @@ Blockly.ContextMenu.hide = function() {
*/
Blockly.ContextMenu.callbackFactory = function(block, xml) {
return function() {
var newBlock = Blockly.Xml.domToBlock_(block.workspace, xml);
var newBlock = Blockly.Xml.domToBlock(block.workspace, xml);
// Move the new block next to the old block.
var xy = block.getRelativeToSurfaceXY();
if (Blockly.RTL) {

View file

@ -339,7 +339,7 @@ Blockly.Flyout.prototype.show = function(xmlList) {
} else {
for (var i = 0, xml; xml = xmlList[i]; i++) {
if (xml.tagName && xml.tagName.toUpperCase() == 'BLOCK') {
var block = Blockly.Xml.domToBlock_(
var block = Blockly.Xml.domToBlock(
/** @type {!Blockly.Workspace} */ (this.workspace_), xml);
blocks.push(block);
gaps.push(margin * 3);
@ -541,7 +541,7 @@ Blockly.Flyout.prototype.createBlockFunc_ = function(originBlock) {
}
// Create the new block by cloning the block in the flyout (via XML).
var xml = Blockly.Xml.blockToDom_(originBlock);
var block = Blockly.Xml.domToBlock_(flyout.targetWorkspace_, xml);
var block = Blockly.Xml.domToBlock(flyout.targetWorkspace_, xml);
// Place it in the same spot as the flyout copy.
var svgRootOld = originBlock.getSvgRoot();
if (!svgRootOld) {

View file

@ -169,19 +169,19 @@ Blockly.Procedures.rename = function(text) {
*/
Blockly.Procedures.flyoutCategory = function(blocks, gaps, margin, workspace) {
if (Blockly.Blocks['procedures_defnoreturn']) {
var block = new Blockly.Block(workspace, 'procedures_defnoreturn');
var block = Blockly.Block.obtain(workspace, 'procedures_defnoreturn');
block.initSvg();
blocks.push(block);
gaps.push(margin * 2);
}
if (Blockly.Blocks['procedures_defreturn']) {
var block = new Blockly.Block(workspace, 'procedures_defreturn');
var block = Blockly.Block.obtain(workspace, 'procedures_defreturn');
block.initSvg();
blocks.push(block);
gaps.push(margin * 2);
}
if (Blockly.Blocks['procedures_ifreturn']) {
var block = new Blockly.Block(workspace, 'procedures_ifreturn');
var block = Blockly.Block.obtain(workspace, 'procedures_ifreturn');
block.initSvg();
blocks.push(block);
gaps.push(margin * 2);
@ -193,7 +193,7 @@ Blockly.Procedures.flyoutCategory = function(blocks, gaps, margin, workspace) {
function populateProcedures(procedureList, templateName) {
for (var x = 0; x < procedureList.length; x++) {
var block = new Blockly.Block(workspace, templateName);
var block = Blockly.Block.obtain(workspace, templateName);
block.setFieldValue(procedureList[x][0], 'NAME');
var tempIds = [];
for (var t = 0; t < procedureList[x][1].length; t++) {

View file

@ -109,10 +109,10 @@ Blockly.Variables.flyoutCategory = function(blocks, gaps, margin, workspace) {
continue;
}
var getBlock = Blockly.Blocks['variables_get'] ?
new Blockly.Block(workspace, 'variables_get') : null;
Blockly.Block.obtain(workspace, 'variables_get') : null;
getBlock && getBlock.initSvg();
var setBlock = Blockly.Blocks['variables_set'] ?
new Blockly.Block(workspace, 'variables_set') : null;
Blockly.Block.obtain(workspace, 'variables_set') : null;
setBlock && setBlock.initSvg();
if (variableList[i] === null) {
defaultVariable = (getBlock || setBlock).getVars()[0];

View file

@ -172,6 +172,9 @@ Blockly.Workspace.prototype.getBubbleCanvas = function() {
*/
Blockly.Workspace.prototype.addTopBlock = function(block) {
this.topBlocks_.push(block);
if (Blockly.isRealtimeEnabled() && this == Blockly.mainWorkspace) {
Blockly.Realtime.addTopBlock(block);
}
this.fireChangeEvent();
};
@ -191,6 +194,9 @@ Blockly.Workspace.prototype.removeTopBlock = function(block) {
if (!found) {
throw 'Block not present in workspace\'s list of top-most blocks.';
}
if (Blockly.isRealtimeEnabled() && this == Blockly.mainWorkspace) {
Blockly.Realtime.removeTopBlock(block);
}
this.fireChangeEvent();
};
@ -339,7 +345,7 @@ Blockly.Workspace.prototype.paste = function(xmlBlock) {
this.remainingCapacity()) {
return;
}
var block = Blockly.Xml.domToBlock_(this, xmlBlock);
var block = Blockly.Xml.domToBlock(this, xmlBlock);
// Move the duplicate to original position.
var blockX = parseInt(xmlBlock.getAttribute('x'), 10);
var blockY = parseInt(xmlBlock.getAttribute('y'), 10);

View file

@ -57,6 +57,7 @@ Blockly.Xml.workspaceToDom = function(workspace) {
Blockly.Xml.blockToDom_ = function(block) {
var element = goog.dom.createDom('block');
element.setAttribute('type', block.type);
element.setAttribute('id', block.id);
if (block.mutationToDom) {
// Custom data for an advanced block.
var mutation = block.mutationToDom();
@ -212,7 +213,7 @@ Blockly.Xml.domToWorkspace = function(workspace, xml) {
var width = Blockly.svgSize().width;
for (var x = 0, xmlChild; xmlChild = xml.childNodes[x]; x++) {
if (xmlChild.nodeName.toLowerCase() == 'block') {
var block = Blockly.Xml.domToBlock_(workspace, xmlChild);
var block = Blockly.Xml.domToBlock(workspace, xmlChild);
var blockX = parseInt(xmlChild.getAttribute('x'), 10);
var blockY = parseInt(xmlChild.getAttribute('y'), 10);
if (!isNaN(blockX) && !isNaN(blockY)) {
@ -223,23 +224,45 @@ Blockly.Xml.domToWorkspace = function(workspace, xml) {
};
/**
* Decode an XML block tag and create a block (and possibly sub-blocks) on the
* Decode an XML block tag and create a block (and possibly sub blocks) on the
* workspace.
* Throws an error if the block cannot be created, for example, if the block
* type is not specified, that type has not been defined, or an non-existent
* input is provided.
* @param {!Blockly.Workspace} workspace The workspace.
* @param {!Element} xmlBlock XML block element.
* @param {boolean=} opt_reuseBlock Optional arg indicating whether to
* reinitialize an existing block.
* @return {!Blockly.Block} The root block created.
* @private
*/
Blockly.Xml.domToBlock_ = function(workspace, xmlBlock) {
Blockly.Xml.domToBlock = function(workspace, xmlBlock, opt_reuseBlock) {
var block = null;
var prototypeName = xmlBlock.getAttribute('type');
if (!prototypeName) {
throw 'Block type unspecified: \n' + xmlBlock.outerHTML;
}
var block = new Blockly.Block(workspace, prototypeName);
block.initSvg();
var id = xmlBlock.getAttribute('id');
if (opt_reuseBlock && id) {
block = Blockly.Block.getById(id, workspace);
// TODO: The following is for debugging. It should never actually happen.
if (!block) {
throw 'Couldn\'t get Block with id: ' + id;
}
var parentBlock = block.getParent();
// If we've already filled this block then we will dispose of it and then
// re-fill it.
if (block.workspace) {
block.dispose(true, false, true);
}
block.fill(workspace, prototypeName);
block.parent_ = parentBlock;
} else {
block = Blockly.Block.obtain(workspace, prototypeName);
// if (id) {
// block.id = parseInt(id, 10);
// }
}
if (!block.svg_) {
block.initSvg();
}
var inline = xmlBlock.getAttribute('inline');
if (inline) {
@ -313,7 +336,8 @@ Blockly.Xml.domToBlock_ = function(workspace, xmlBlock) {
}
if (firstRealGrandchild &&
firstRealGrandchild.nodeName.toLowerCase() == 'block') {
blockChild = Blockly.Xml.domToBlock_(workspace, firstRealGrandchild);
blockChild = Blockly.Xml.domToBlock(workspace, firstRealGrandchild,
opt_reuseBlock);
if (blockChild.outputConnection) {
input.connection.connect(blockChild.outputConnection);
} else if (blockChild.previousConnection) {
@ -332,7 +356,8 @@ Blockly.Xml.domToBlock_ = function(workspace, xmlBlock) {
// This could happen if there is more than one XML 'next' tag.
throw 'Next statement is already connected.';
}
blockChild = Blockly.Xml.domToBlock_(workspace, firstRealGrandchild);
blockChild = Blockly.Xml.domToBlock(workspace, firstRealGrandchild,
opt_reuseBlock);
if (!blockChild.previousConnection) {
throw 'Next block does not have previous statement.';
}

View file

@ -0,0 +1,401 @@
/**
* Copyright 2013 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
/**
* @fileoverview Common utility functionality for Google Drive Realtime API,
* including authorization and file loading. This functionality should serve
* mostly as a well-documented example, though is usable in its own right.
*
* You can find this code as part of the Google Drive Realtime API Quickstart at
* https://developers.google.com/drive/realtime/realtime-quickstart and also as
* part of the Google Drive Realtime Playground code at
* https://github.com/googledrive/realtime-playground/blob/master/js/realtime-client-utils.js
*/
/**
* Realtime client utilities namespace.
*/
var rtclient = rtclient || {};
/**
* OAuth 2.0 scope for installing Drive Apps.
* @const
*/
rtclient.INSTALL_SCOPE = 'https://www.googleapis.com/auth/drive.install';
/**
* OAuth 2.0 scope for opening and creating files.
* @const
*/
rtclient.FILE_SCOPE = 'https://www.googleapis.com/auth/drive.file';
/**
* OAuth 2.0 scope for accessing the user's ID.
* @const
*/
rtclient.OPENID_SCOPE = 'openid';
/**
* MIME type for newly created Realtime files.
* @const
*/
rtclient.REALTIME_MIMETYPE = 'application/vnd.google-apps.drive-sdk';
/**
* Parses the hash parameters to this page and returns them as an object.
* @return {!Object} Parameter object.
*/
rtclient.getParams = function() {
var params = {};
var hashFragment = window.location.hash;
if (hashFragment) {
// split up the query string and store in an object
var paramStrs = hashFragment.slice(1).split('&');
for (var i = 0; i < paramStrs.length; i++) {
var paramStr = paramStrs[i].split('=');
params[paramStr[0]] = unescape(paramStr[1]);
}
}
// Opening from Drive will encode the state in a query search parameter
var searchFragment = window.location.search;
if (searchFragment) {
// split up the query string and store in an object
var paramStrs2 = searchFragment.slice(1).split("&");
for (var j = 0; j < paramStrs2.length; j++) {
var paramStr2 = paramStrs2[j].split("=");
params[paramStr2[0]] = unescape(paramStr2[1]);
}
}
console.log(params);
return params;
};
/**
* Instance of the query parameters.
*/
rtclient.params = rtclient.getParams();
/**
* Fetches an option from options or a default value, logging an error if
* neither is available.
* @param {!Object} options Containing options.
* @param {string} key Option key.
* @param {*} defaultValue Default option value (optional).
* @return {*} Option value.
*/
rtclient.getOption = function(options, key, defaultValue) {
if (options.hasOwnProperty(key)) {
return options[key];
}
console.error(key + ' should be present in the options.');
return defaultValue;
};
/**
* Creates a new Authorizer from the options.
* @constructor
* @param {!Object} options For authorizer. Two keys are required as mandatory,
* these are:
*
* 1. "clientId", the Client ID from the console
*/
rtclient.Authorizer = function(options) {
this.clientId = rtclient.getOption(options, 'clientId');
// Get the user ID if it's available in the state query parameter.
this.userId = rtclient.params['userId'];
this.authButton = document.getElementById(rtclient.getOption(options,
'authButtonElementId'));
};
/**
* Start the authorization process.
* @param {Function} onAuthComplete To call once authorization has completed.
*/
rtclient.Authorizer.prototype.start = function(onAuthComplete) {
var _this = this;
gapi.load('auth:client,drive-realtime,drive-share', function() {
_this.authorize(onAuthComplete);
});
};
/**
* Reauthorize the client with no callback (used for authorization failure).
* @param {Function} onAuthComplete To call once authorization has completed.
*/
rtclient.Authorizer.prototype.authorize = function(onAuthComplete) {
var clientId = this.clientId;
var userId = this.userId;
var _this = this;
var handleAuthResult = function(authResult) {
if (authResult && !authResult.error) {
_this.authButton.disabled = true;
_this.fetchUserId(onAuthComplete);
} else {
_this.authButton.disabled = false;
_this.authButton.onclick = authorizeWithPopup;
}
};
var authorizeWithPopup = function() {
gapi.auth.authorize({
client_id: clientId,
scope: [
rtclient.INSTALL_SCOPE,
rtclient.FILE_SCOPE,
rtclient.OPENID_SCOPE
],
user_id: userId,
immediate: false
}, handleAuthResult);
console.log(clientId);
};
// Try with no popups first.
gapi.auth.authorize({
client_id: clientId,
scope: [
rtclient.INSTALL_SCOPE,
rtclient.FILE_SCOPE,
rtclient.OPENID_SCOPE
],
user_id: userId,
immediate: true
}, handleAuthResult);
};
/**
* Fetch the user ID using the UserInfo API and save it locally.
* @param {Function} callback The callback to call after user ID has been
* fetched.
*/
rtclient.Authorizer.prototype.fetchUserId = function(callback) {
var _this = this;
gapi.client.load('oauth2', 'v2', function() {
gapi.client.oauth2.userinfo.get().execute(function(resp) {
if (resp.id) {
_this.userId = resp.id;
}
if (callback) {
callback();
}
});
});
};
/**
* Creates a new Realtime file.
* @param {string} title Title of the newly created file.
* @param {string} mimeType The MIME type of the new file.
* @param {Function} callback The callback to call after creation.
*/
rtclient.createRealtimeFile = function(title, mimeType, callback) {
gapi.client.load('drive', 'v2', function() {
gapi.client.drive.files.insert({
'resource': {
mimeType: mimeType,
title: title
}
}).execute(callback);
});
};
/**
* Fetches the metadata for a Realtime file.
* @param {string} fileId The file to load metadata for.
* @param {Function} callback The callback to be called on completion,
* with signature:
*
* function onGetFileMetadata(file) {}
*
* where the file parameter is a Google Drive API file resource instance.
*/
rtclient.getFileMetadata = function(fileId, callback) {
gapi.client.load('drive', 'v2', function() {
gapi.client.drive.files.get({
'fileId' : fileId
}).execute(callback);
});
};
/**
* Parses the state parameter passed from the Drive user interface after
* Open With operations.
* @param {string} stateParam The state query parameter as a JSON string.
* @return {Object} The state query parameter as an object or null if
* parsing failed.
*/
rtclient.parseState = function(stateParam) {
try {
var stateObj = JSON.parse(stateParam);
return stateObj;
} catch (e) {
return null;
}
};
/**
* Handles authorizing, parsing query parameters, loading and creating Realtime
* documents.
* @constructor
* @param {!Object} options Options for loader. Four keys are required as
* mandatory, these are:
*
* 1. "clientId", the Client ID from the console
* 2. "initializeModel", the callback to call when the file is loaded.
* 3. "onFileLoaded", the callback to call when the model is first created.
*
* and one key is optional:
*
* 1. "defaultTitle", the title of newly created Realtime files.
*/
rtclient.RealtimeLoader = function(options) {
// Initialize configuration variables.
this.onFileLoaded = rtclient.getOption(options, 'onFileLoaded');
this.newFileMimeType = rtclient.getOption(options, 'newFileMimeType',
rtclient.REALTIME_MIMETYPE);
this.initializeModel = rtclient.getOption(options, 'initializeModel');
this.registerTypes = rtclient.getOption(options, 'registerTypes',
function() {});
this.afterAuth = rtclient.getOption(options, 'afterAuth', function() {});
// This tells us if need to we automatically create a file after auth.
this.autoCreate = rtclient.getOption(options, 'autoCreate', false);
this.defaultTitle = rtclient.getOption(options, 'defaultTitle',
'New Realtime File');
this.authorizer = new rtclient.Authorizer(options);
};
/**
* Redirects the browser back to the current page with an appropriate file ID.
* @param {Array.<string>} fileIds The IDs of the files to open.
* @param {string} userId The ID of the user.
*/
rtclient.RealtimeLoader.prototype.redirectTo = function(fileIds, userId) {
var params = [];
if (fileIds) {
params.push('fileIds=' + fileIds.join(','));
}
if (userId) {
params.push('userId=' + userId);
}
// Naive URL construction.
var newUrl = params.length == 0
? window.location.pathname
: (window.location.pathname + '#' + params.join('&'));
// Using HTML URL re-write if available.
if (window.history && window.history.replaceState) {
window.history.replaceState('Google Drive Realtime API Playground',
'Google Drive Realtime API Playground', newUrl);
} else {
window.location.href = newUrl;
}
// We are still here that means the page didn't reload.
rtclient.params = rtclient.getParams();
for (var index in fileIds) {
gapi.drive.realtime.load(fileIds[index], this.onFileLoaded,
this.initializeModel, this.handleErrors);
}
};
/**
* Starts the loader by authorizing.
*/
rtclient.RealtimeLoader.prototype.start = function() {
// Bind to local context to make them suitable for callbacks.
var _this = this;
this.authorizer.start(function() {
if (_this.registerTypes) {
_this.registerTypes();
}
if (_this.afterAuth) {
_this.afterAuth();
}
_this.load();
});
};
/**
* Handles errors thrown by the Realtime API.
* @param {!Error} e Error.
*/
rtclient.RealtimeLoader.prototype.handleErrors = function(e) {
if (e.type == gapi.drive.realtime.ErrorType.TOKEN_REFRESH_REQUIRED) {
this.authorizer.authorize();
} else if (e.type == gapi.drive.realtime.ErrorType.CLIENT_ERROR) {
alert('An Error happened: ' + e.message);
window.location.href = '/';
} else if (e.type == gapi.drive.realtime.ErrorType.NOT_FOUND) {
alert('The file was not found. It does not exist or you do not have ' +
'read access to the file.');
window.location.href = '/';
}
};
/**
* Loads or creates a Realtime file depending on the fileId and state query
* parameters.
*/
rtclient.RealtimeLoader.prototype.load = function() {
var fileIds = rtclient.params['fileIds'];
if (fileIds) {
fileIds = fileIds.split(',');
}
var userId = this.authorizer.userId;
var state = rtclient.params['state'];
// Creating the error callback.
var authorizer = this.authorizer;
// We have file IDs in the query parameters, so we will use them to load a
// file.
if (fileIds) {
for (var index in fileIds) {
gapi.drive.realtime.load(fileIds[index], this.onFileLoaded,
this.initializeModel, this.handleErrors);
}
return;
}
// We have a state parameter being redirected from the Drive UI.
// We will parse it and redirect to the fileId contained.
else if (state) {
var stateObj = rtclient.parseState(state);
// If opening a file from Drive.
if (stateObj.action == 'open') {
fileIds = stateObj.ids;
userId = stateObj.userId;
this.redirectTo(fileIds, userId);
return;
}
}
if (this.autoCreate) {
this.createNewFileAndRedirect();
}
};
/**
* Creates a new file and redirects to the URL to load it.
*/
rtclient.RealtimeLoader.prototype.createNewFileAndRedirect = function() {
// No fileId or state have been passed. We create a new Realtime file and
// redirect to it.
var _this = this;
rtclient.createRealtimeFile(this.defaultTitle, this.newFileMimeType,
function(file) {
if (file.id) {
_this.redirectTo([file.id], _this.authorizer.userId);
} else {
// File failed to be created, log why and do not attempt to redirect.
console.error('Error creating file.');
console.error(file);
}
});
};

478
realtime/realtime.js Normal file
View file

@ -0,0 +1,478 @@
/**
* This file contains functions used by any Blockly app that wants to provide
* realtime collaboration functionality.
*
* Note that it depends on the existence of particularly named UI elements.
*
* TODO: Inject the UI element names
*/
/**
* @fileoverview Common support code for Blockly apps using realtime
* collaboration.
* Note that to use this you must set up a project via the Google Developers
* Console. Instructions on how to do that can be found in the Blockly wiki page
* at https://code.google.com/p/blockly/wiki/RealtimeCollaboration
* Once you do that you can set the clientId in
* Blockly.Realtime.realtimeOptions_
* @author markf@google.com (Mark Friedman)
*/
'use strict';
goog.provide('Blockly.Realtime');
goog.require('goog.array');
/**
* Is realtime collaboration enabled?
* @type {boolean}
* @private
*/
Blockly.Realtime.enabled_ = false;
/**
* The Realtime model of this doc.
* @type {gapi.drive.realtime.Model}
* @private
*/
Blockly.Realtime.model_ = null;
/**
* The function used to initialize the UI after realtime is initialized.
* @type {Function()}
* @private
*/
Blockly.Realtime.initUi_ = null;
/**
* A map from block id to blocks.
* @type {gapi.drive.realtime.CollaborativeMap}
* @private
*/
Blockly.Realtime.blocksMap_ = null;
/**
* Are currently syncing from another instance of this realtime doc.
* @type {boolean}
*/
Blockly.Realtime.withinSync = false;
/**
* The current instance of the realtime loader client
* @type {rtclient.RealtimeLoader}
* @private
*/
Blockly.Realtime.realtimeLoader_ = null;
/**
* Returns whether realtime collaboration is enabled.
* @returns {boolean}
*/
Blockly.Realtime.isEnabled = function() {
return Blockly.Realtime.enabled_;
};
/**
* This function is called the first time that the Realtime model is created
* for a file. This function should be used to initialize any values of the
* model.
* @param model {gapi.drive.realtime.Model} model The Realtime root model
* object.
*/
Blockly.Realtime.initializeModel_ = function(model) {
Blockly.Realtime.model_ = model;
var blocksMap = model.createMap();
model.getRoot().set('blocks', blocksMap);
var topBlocks = model.createList();
model.getRoot().set('topBlocks', topBlocks);
var string =
model.createString('Chat with your collaborator by typing in this box!');
model.getRoot().set('text', string);
};
/**
* Delete a block from the realtime blocks map.
* @param {!Blockly.Block} block The block to remove.
*/
Blockly.Realtime.removeBlock = function(block) {
Blockly.Realtime.blocksMap_.delete(block.id.toString());
};
/**
* Add to the list of top-level blocks.
* @param {!Blockly.Block} block The block to add.
*/
Blockly.Realtime.addTopBlock = function(block) {
if (Blockly.Realtime.topBlocks_.indexOf(block) == -1) {
Blockly.Realtime.topBlocks_.push(block);
}
};
/**
* Delete a block from the list of top-level blocks.
* @param {!Blockly.Block} block The block to remove.
*/
Blockly.Realtime.removeTopBlock = function(block) {
Blockly.Realtime.topBlocks_.removeValue(block);
};
/**
* Obtain a newly created block known by the Realtime API.
* @param {!Blockly.Workspace} workspace The workspace to put the block in.
* @param {string} prototypeName The name of the prototype for the block
* @return {!Blockly.Block}
*/
Blockly.Realtime.obtainBlock = function(workspace, prototypeName) {
var newBlock =
Blockly.Realtime.model_.create(Blockly.Block, workspace, prototypeName);
return newBlock;
};
/**
* Get an existing block by id.
* @param {string} id The block's id.
* @return {Blockly.Block} The found block.
*/
Blockly.Realtime.getBlockById = function(id) {
return Blockly.Realtime.blocksMap_.get(id);
};
/**
* Event handler to call when a block is changed.
* @param {gapi.drive.realtime.ObjectChangedEvent} evt The event that occurred.
* @private
*/
Blockly.Realtime.onObjectChange_ = function(evt) {
var events = evt.events;
var eventCount = evt.events.length;
for (var i = 0; i < eventCount; i++) {
var event = events[i];
if (!event.isLocal) {
if (event.type == 'value_changed') {
if (event.property == 'xmlDom') {
var block = event.target;
Blockly.Realtime.doWithinSync_(function(){
Blockly.Realtime.placeBlockOnWorkspace_(block, false);
Blockly.Realtime.moveBlock_(block);
});
} else if (event.property == 'relativeX' ||
event.property == 'relativeY') {
var block2 = event.target;
Blockly.Realtime.doWithinSync_(function () {
if (!block2.svg_) {
// If this is a move of a newly disconnected (i.e newly top level)
// block it will not have any svg (because it has been disposed of
// by it's parent), so we need to handle that here.
Blockly.Realtime.placeBlockOnWorkspace_(block2, false);
}
Blockly.Realtime.moveBlock_(block2);
});
}
}
}
}
};
/**
* Event handler to call when there is a change to the realtime blocks map.
* @param {gapi.drive.realtime.ValueChangedEvent} evt The event that occurred.
* @private
*/
Blockly.Realtime.onBlocksMapChange_ = function(evt) {
console.log('Blocks Map event:');
console.log(' id: ' + evt.property);
if (!evt.isLocal) {
var block = evt.newValue;
if (block) {
Blockly.Realtime.placeBlockOnWorkspace_(block, !(evt.oldValue));
} else {
block = evt.oldValue;
Blockly.Realtime.deleteBlock(block);
}
}
};
/**
* A convenient wrapper around code that synchronizes the local model being
* edited with changes from another non-local model.
* @param {!Function()} thunk A thunk of code to call.
* @private
*/
Blockly.Realtime.doWithinSync_ = function(thunk) {
if (Blockly.Realtime.withinSync) {
thunk();
} else {
try {
Blockly.Realtime.withinSync = true;
thunk();
} finally {
Blockly.Realtime.withinSync = false;
}
}
};
/**
* Places a block to be synced on this docs main workspace. The block might
* already exist on this doc, in which case it is updated and/or moved.
* @param {!Blockly.Block} block The block.
* @param {boolean} addToTop Whether to add the block to the workspace/s list of
* top-level blocks.
* @private
*/
Blockly.Realtime.placeBlockOnWorkspace_ = function(block, addToTop) {
Blockly.Realtime.doWithinSync_(function() {
var blockDom = Blockly.Xml.textToDom(block.xmlDom).firstChild;
var newBlock =
Blockly.Xml.domToBlock(Blockly.mainWorkspace, blockDom, true);
// TODO: The following is for debugging. It should never actually happen.
if (!newBlock) {
return;
}
// Since Blockly.Xml.blockDomToBlock() purposely won't add blocks to
// workspace.topBlocks_ we sometimes need to do it explicitly here.
if (addToTop) {
newBlock.workspace.addTopBlock(newBlock);
}
if (addToTop ||
goog.array.contains(Blockly.Realtime.topBlocks_, newBlock)) {
Blockly.Realtime.moveBlock_(newBlock);
}
});
};
/**
* Move a block
* @param {Blockly.Block} block The block to move.
* @private
*/
Blockly.Realtime.moveBlock_ = function(block) {
if (!isNaN(block.relativeX) && !isNaN(block.relativeY)) {
var width = Blockly.svgSize().width;
var curPos = block.getRelativeToSurfaceXY();
var dx = block.relativeX - curPos.x;
var dy = block.relativeY - curPos.y;
block.moveBy(Blockly.RTL ? width - dx : dx, dy);
}
};
/**
* Delete a block.
* @param {!Blockly.Block} block The block to delete.
* @private
*/
Blockly.Realtime.deleteBlock = function(block) {
Blockly.Realtime.doWithinSync_(function() {
block.dispose(true, true, true);
});
};
/**
* Load all the blocks from the realtime model's blocks map and place them
* appropriately on the main Blockly workspace.
* @private
*/
Blockly.Realtime.loadBlocks_ = function() {
var blocks = Blockly.Realtime.blocksMap_.values();
for (var i = 0; i < blocks.length; i++) {
var block = blocks[i];
// Since we now have blocks with already existing ids, we have to make sure
// that new blocks don't get any of the existing ids.
var blockIdNum = parseInt(block.id, 10);
if (blockIdNum > Blockly.getUidCounter()) {
Blockly.setUidCounter(blockIdNum + 1);
}
}
var topBlocks = Blockly.Realtime.topBlocks_;
for (var j = 0; j < topBlocks.length; j++) {
var topBlock = topBlocks.get(j);
Blockly.Realtime.placeBlockOnWorkspace_(topBlock, true);
}
};
/**
* Cause a changed block to update the realtime model, and therefore to be
* synced with other apps editing this same doc.
* @param {!Blockly.Block} block The block that changed.
*/
Blockly.Realtime.blockChanged = function(block) {
if (block.workspace == Blockly.mainWorkspace) {
var rootBlock = block.getRootBlock();
var xy = rootBlock.getRelativeToSurfaceXY();
var changed = false;
var xml = Blockly.Xml.blockToDom_(rootBlock);
xml.setAttribute('id', rootBlock.id);
var topXml = goog.dom.createDom('xml');
topXml.appendChild(xml);
var newXml = Blockly.Xml.domToText(topXml);
if (newXml != rootBlock.xmlDom) {
changed = true;
rootBlock.xmlDom = newXml;
}
if (rootBlock.relativeX != xy.x || rootBlock.relativeY != xy.y){
rootBlock.relativeX = xy.x;
rootBlock.relativeY = xy.y;
changed = true;
}
if (changed) {
var blockId = rootBlock.id.toString();
Blockly.Realtime.blocksMap_.set(blockId, rootBlock);
}
}
};
/**
* This function is called when the Realtime file has been loaded. It should
* be used to initialize any user interface components and event handlers
* depending on the Realtime model. In this case, create a text control binder
* and bind it to our string model that we created in initializeModel.
* @param {!gapi.drive.realtime.Document} doc The Realtime document.
* @private
*/
Blockly.Realtime.onFileLoaded_ = function(doc) {
Blockly.Realtime.model_ = doc.getModel();
Blockly.Realtime.blocksMap_ =
Blockly.Realtime.model_.getRoot().get('blocks');
Blockly.Realtime.topBlocks_ =
Blockly.Realtime.model_.getRoot().get('topBlocks');
Blockly.Realtime.model_.getRoot().addEventListener(
gapi.drive.realtime.EventType.OBJECT_CHANGED,
Blockly.Realtime.onObjectChange_);
Blockly.Realtime.blocksMap_.addEventListener(
gapi.drive.realtime.EventType.VALUE_CHANGED,
Blockly.Realtime.onBlocksMapChange_);
var string = Blockly.Realtime.model_.getRoot().get('text');
// Keeping one box updated with a String binder.
var textArea1 = document.getElementById('chatbox');
gapi.drive.realtime.databinding.bindString(string, textArea1);
// Enabling UI Elements.
textArea1.disabled = false;
Blockly.Realtime.initUi_();
Blockly.Realtime.loadBlocks_();
// Add logic for undo button.
// TODO: Uncomment this when undo/redo are fixed.
/*
var undoButton = document.getElementById('undoButton');
var redoButton = document.getElementById('redoButton');
undoButton.onclick = function(e) {
Blockly.Realtime.model_.undo();
};
redoButton.onclick = function(e) {
Blockly.Realtime.model_.redo();
};
// Add event handler for UndoRedoStateChanged events.
var onUndoRedoStateChanged = function(e) {
undoButton.disabled = !e.canUndo;
redoButton.disabled = !e.canRedo;
};
Blockly.Realtime.model_.addEventListener(
gapi.drive.realtime.EventType.UNDO_REDO_STATE_CHANGED,
onUndoRedoStateChanged);
*/
};
/**
* Register the Blockly types and attributes that are reflected in the realtime
* model.
* @private
*/
Blockly.Realtime.registerTypes_ = function() {
var custom = gapi.drive.realtime.custom;
custom.registerType(Blockly.Block, 'Block');
Blockly.Block.prototype.id = custom.collaborativeField('id');
Blockly.Block.prototype.type = custom.collaborativeField('type');
Blockly.Block.prototype.xmlDom = custom.collaborativeField('xmlDom');
Blockly.Block.prototype.relativeX = custom.collaborativeField('relativeX');
Blockly.Block.prototype.relativeY = custom.collaborativeField('relativeY');
custom.setInitializer(Blockly.Block, Blockly.Block.prototype.initialize);
};
Blockly.Realtime.REAUTH_INTERVAL_IN_MILLISECONDS_ = 30 * 60 * 1000;
/**
* What to do after Realtime authorization.
* @private
*/
Blockly.Realtime.afterAuth_ = function() {
// This is a workaround for the fact that the code in realtime-client-utils.js
// doesn't deal with auth timeouts correctly. So we explicitly reauthorize at
// regular intervals.
window.setTimeout(
function() {
Blockly.Realtime.realtimeLoader_.authorizer.authorize(
Blockly.Realtime.afterAuth_);
},
Blockly.Realtime.REAUTH_INTERVAL_IN_MILLISECONDS_);
};
/**
* Options for the Realtime loader.
*/
Blockly.Realtime.realtimeOptions_ = {
/**
* Client ID from the console.
*/
clientId: 'INSERT YOUR CLIENT ID HERE',
/**
* The ID of the button to click to authorize. Must be a DOM element ID.
*/
authButtonElementId: 'authorizeButton',
/**
* Function to be called when a Realtime model is first created.
*/
initializeModel: Blockly.Realtime.initializeModel_,
/**
* Autocreate files right after auth automatically.
*/
autoCreate: true,
/**
* The name of newly created Drive files.
*/
defaultTitle: 'New Realtime Blockly File',
/**
* The MIME type of newly created Drive Files. By default the application
* specific MIME type will be used:
* application/vnd.google-apps.drive-sdk.
*/
newFileMimeType: null, // Using default.
/**
* Function to be called every time a Realtime file is loaded.
*/
onFileLoaded: Blockly.Realtime.onFileLoaded_,
/**
* Function to be called to initialize custom Collaborative Objects types.
*/
registerTypes: Blockly.Realtime.registerTypes_,
/**
* Function to be called after authorization and before loading files.
*/
afterAuth: Blockly.Realtime.afterAuth_
};
/**
* Start the Realtime loader with the options.
*/
Blockly.Realtime.startRealtime = function (uiInitialize) {
Blockly.Realtime.enabled_ = true;
Blockly.Realtime.initUi_ = uiInitialize;
Blockly.Realtime.realtimeLoader_ =
new rtclient.RealtimeLoader(Blockly.Realtime.realtimeOptions_);
Blockly.Realtime.realtimeLoader_.start();
};

View file

@ -40,6 +40,12 @@
<script type="text/javascript" src="../blocks/colour.js"></script>
<script type="text/javascript" src="../blocks/variables.js"></script>
<script type="text/javascript" src="../blocks/procedures.js"></script>
<!-- Load the Google Drive SDK Realtime libraries. -->
<script type="text/javascript" src="https://apis.google.com/js/api.js"></script>
<!-- Load the generic Realtime utility library. -->
<script type="text/javascript" src="../realtime/realtime-client-utils.js"></script>
<!-- Load the Blockly apps realtime library. -->
<!--<script type="text/javascript" src="../realtime/realtime.js"></script>-->
<script type="text/javascript">
'use strict';
// Depending on the URL argument, render as LTR or RTL.
@ -47,9 +53,24 @@ var rtl = (document.location.search == '?rtl');
var block = null;
function start() {
var toolbox = document.getElementById('toolbox');
Blockly.inject(document.getElementById('blocklyDiv'),
{'rtl': rtl, path: '../', toolbox: toolbox});
var startUi = function () {
var toolbox = document.getElementById('toolbox');
Blockly.inject(document.getElementById('blocklyDiv'),
{rtl: rtl, path: '../', toolbox: toolbox});
};
// Set up realtime collaboration.
// If you want to use the realtime collaboration features then uncomment out
// the next 2 lines and comment out the call to startUi() below.
// document.getElementById("realtime").style.display = "block";
// Blockly.Realtime.startRealtime(startUi);
// If you don't want to use the realtime collaboration features then uncomment
// out the next line and comment out the call to
// Blockly.Realtime.startRealtime() above it. You can also comment out
// (or delete) the loading of the realtime related libraries up above in this
// case, if you want.
startUi();
}
function toXml() {
@ -80,7 +101,7 @@ function airstrike(n) {
}
for (var x = 0; x < n; x++) {
var prototype = prototypes[Math.floor(Math.random() * prototypes.length)];
var block = new Blockly.Block(Blockly.mainWorkspace, prototype);
var block = Blockly.Block.obtain(Blockly.mainWorkspace, prototype);
block.initSvg();
block.getSvgRoot().setAttribute('transform', 'translate(' +
Math.round(Math.random() * 450 + 40) + ', ' +
@ -315,7 +336,30 @@ h1 {
Stress test with an <input type="button" value="Airstrike!" onclick="airstrike(100)">
</p>
</form>
<!-- Realtime setup buttons. -->
<div id="realtime" style="display: none">
<p>Test realtime collaboration by opening
<a target="_blank" href="#" onmouseover="this.href = window.location.href">this link in a separate
browser window or tab</a> and they will be synchronized. If this is the first time you've used
realtime collaboration with Blockly you'll need to authorize using the following button if it is enabled.</p>
<button id="authorizeButton">You must authorize</button>
<br>
<br>
<!-- Undo and redo buttons. -->
<!--
<button id="undoButton" disabled>Undo</button>
<button id="redoButton" disabled>Redo</button>
<br />
-->
<!-- Text area that will be used for our collaborative chat box. -->
<textarea id="chatbox" style="width: 26%; height: 12em" disabled="true"></textarea>
</div>
</body>
</html>