From 1ea9bcefd2d3c2be4ffe6e0b2fdc267a7675ffe0 Mon Sep 17 00:00:00 2001 From: Raeskaa Date: Fri, 3 Sep 2021 16:35:36 +0530 Subject: [PATCH] Added login page --- .vs/slnx.sqlite | Bin 512000 -> 516096 bytes appengine/Login/README.markdown | 7 + appengine/Login/dist/index.html | 123 +++++++++++ appengine/Login/dist/script.js | 203 ++++++++++++++++++ appengine/Login/dist/style.css | 142 ++++++++++++ appengine/Login/src/index.html | 106 +++++++++ appengine/Login/src/script.js | 203 ++++++++++++++++++ appengine/Login/src/style.scss | 87 ++++++++ appengine/app.yaml | 2 +- appengine/bird/generated/en/compressed.js | 4 +- appengine/common/back.js | 2 +- appengine/generated/en/soy.js | 2 +- appengine/js/lib-interface.js | 2 +- .../pond/duck/generated/en/compressed.js | 4 +- .../pond/tutor/generated/en/compressed.js | 4 +- appengine/puzzle/generated/en/compressed.js | 4 +- appengine/template.soy | 2 +- .../third-party/JS-Interpreter/docs.html | 2 +- appengine/third-party/ace/snippets/ruby.js | 2 +- appengine/third-party/base.js | 2 +- .../third-party/blockly/msg/json/qqq.json | 14 +- appengine/third-party/blockly/msg/messages.js | 14 +- appengine/turtle/template.soy | 2 +- json/qqq.json | 2 +- third-party/base.js | 2 +- 25 files changed, 904 insertions(+), 33 deletions(-) create mode 100644 appengine/Login/README.markdown create mode 100644 appengine/Login/dist/index.html create mode 100644 appengine/Login/dist/script.js create mode 100644 appengine/Login/dist/style.css create mode 100644 appengine/Login/src/index.html create mode 100644 appengine/Login/src/script.js create mode 100644 appengine/Login/src/style.scss diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite index 066195f78a8078f0fbaedd4c883790569fb92de6..9696b5cc6ae1188e3d41370e53fd8265045cc69e 100644 GIT binary patch delta 2964 zcmZ`4Yfx0z`JTr;cQ1Q)FUV_QLBNW9Kc=7RFD}uD{HC>ZBC)Ti>!YD!)3LJON2W0 z8}(DQUA?6atApx!^$%)Ob2QBC+H9SvDqOxvLJ;aj{jXi^l|lZx5jmGL*Jw=LA>9er zU}Yt`Vod2ubTld^T?p1(3Pna72H`XDb1EG1dZ2&8b!W!`Xt?33s@;f<3BnZDhqcxy zWihUV(6%vw8x#lNCeC7oPLuzg1p*1;+^j5Gp+w2>{{{!KC3KLV$)V zUR;D;oeSJhgv^X#ryks=S5+9RT}Ng=s8F^bH)vr}7Tf`roCe213pl9VbnJsu1U(9a z70wbKKA1NN*G=HUXRJ3HJ~I_{qckQtpbcP@CMGb)7I*`gLUAmFIq4~Bndx&X3aU02 zRc^H_J<2;Q&k2t!l6p({416LmV*?}rf=_7BPFRZ7d+I3Nu@jb=f>7*Z*6)O&1Zs7{ zP!{wXIAoa4qa_tiBZ`8~!m2VyHIG#pe3lqkCS-q`1E(*xsKSK>-eczXb&81mc%j$ zN6$J$2Q(-+7{a15XEpcR%l-w$;ACvW9}2W#zch<2u!stxmah?JX{q8D5s>)N`Brfd z%ERnCt2hcUF`+niXQLR1>P;yAr`|y6F`y_=;BeUNC1rLS)cFg~{=`!$JzS9RklNG# zPt7=?rd96p1zHm`N3qxrv~Do6pi=S6h2Sz1+r>iOTG_Pps5p~ z(ugeb56D{&W)tV)X-Gw1qQ9Z{P#-#l+R$t84b*__Xg$h+U%;Dc6CB`nW1n|&dXwIo zO-ukAEkZ6mpF?6atb*RoA@dh{s=CZxWP8z@<38o$qpV)V?T@3t#6v*-5*e$>_kLKd z5$b7LKKWH(jWBQQa@u9p-wHAGSU$NP#KTFRoEA>2^py={I~qkQm8>KMqo1L0y247n zg-B&f3&<4^>xV+&%1T~|N{`m{lLEZ>2<>J|3dztc(hlZ}yeyuzh`Z=Me<|Z&inxb0 zH4-DB_5)ih#TDQCy2R;gvW6 zKaInvZkSw!SYbDY$y3Oz;85VbCO^}FL;2#;mX^-#HTrDPc1^DOV z`tX)?BE&$MOq!s5x|?>-UJPqVBSMrW9G~XnvhbEvui>Oe7#D`MEcY2s%()4tDHBfX zy*r|JOc>r`dCcp$FtBAA5dxu(cqZeRNmR>HBE<3_A6so>8bK||L(#n&-=#|E#|iusg`d z>-X}mF0#?ToRO|@Z|i=ynw{v9g0*OW{9p@ncT4p;&M$d>l%@4bZiu5Kowv8xKDX2j zu;ef4_*ny(wuebr;pa4aI;S5sG1I%!r#hV<&-(kaW5Q}GU;}Ydhu9VE9|ApQX$s$= z9y7iyZCB}H-3&Q_96|I*MG7MvVn{PhKIuvM5OAN(h@_oFp>haYNKGo2;y5@n}#;V4r z?4yx?q!swk=aHPE={7dL3N0^vlG^_=oY0k0&zRT*V~kBac*QSfRyWku#*{^P*PN=`FN@~SGlPd{9K;?H%810n4uUfa>1?Ag z#!l1bp%^_Z9p%MQUNFkJQO+La^eCr}^0X)?k8+}B<)Jw2Lf^mziBl;h22%f#*z%L( z=(rL^cpXYOiVmRNXq(pi?Ssb}^Wp6mv5&aO1a-U^FG?a2QmRA{uSS$*l4n%#3EYoh z>PI9|l{Vl#cC0@96}n@LWcjKxTQEo9-iRw<-9}v1Rv1qvkW2_P-~<)-H13U^rX%B; zhBZ2KDEB*@@f|idwc>59sb)D z6-jjiv-mu^o%oGy?Rj;1jcJCu9blg#T_0qt8hVV4 zBfv{(ld7m-zeO~bBqJ49$%eC0uVS5SC4%Z*ECc->Uf#tXMh$Rt7Yo3|)m*B;ZuYvD zg1%DK_OMkLF6XmJz}rP3^n~$vaQ~f5f_e3H7A9fHImOnirk(r+WR8^dMXN+DKEvh` zZkW;fR@ZiLt<`&u{b?ELK+Pb0e74H<@l4cKWUJ=Me2ar>fTi=nI9>BqC<7%R>)V1c z)U9;B$%Rn`Y{=#Bz~Xm_50+uxqORrf$zwg*@f_NNoqf(u`Kl_ z-1W1qs=SRm2(IL_iP4X+Dob9Imt`OE%iD5Tcb;C^qq|O6cIh6pU8Xo;Cr1WjEA3(F zw>Qgl*(x{77P%IRPBJe%(auke{eO0&pUk!2bwIg?#4u7h9lVmeql=c;I;q{vXuE>& zD?AA4S40i`Y6qVRy;sBoB+bqTb3im{@Wa{xQ3hWRh@hU$gP&g=S3j@%E4fE~-p{=yT)#${)-Tew#$!j+Kfz zp&R?Q!*gZg(}W{`n_HXg9?uPAAzn$$k86*)U+XlXrCgk4-M3FP9t|xyxIjl-`Qu)A zX}MUV@znmh?tn;5WQVVn?7FVf*NXmZ(uFT65f;Tr3*3O<(p%!Z-ml5NrS?Wdyw-7Y z&-CA@p5KXIntDC(#VS>BT=Zb-6^RD?%+EGKXFE5QbCV>Y=%3jLDes7hI@l!&!H)$~ J-m~H}^MAeu9^3!` diff --git a/appengine/Login/README.markdown b/appengine/Login/README.markdown new file mode 100644 index 0000000..6d7fb8d --- /dev/null +++ b/appengine/Login/README.markdown @@ -0,0 +1,7 @@ +# Animated SVG Avatar + +A Pen created on CodePen.io. Original URL: [https://codepen.io/dsenneff/pen/2d338b0adf97472ebc5d473cf1fa910b](https://codepen.io/dsenneff/pen/2d338b0adf97472ebc5d473cf1fa910b). + +Created a login form with an SVG avatar that responds to the input in the email field. Used the GSAP TweenMax library + GSAP's MorphSVG plugin for the animating. + +Email validation is very simple and crude just for the purposes of getting this prototype working. diff --git a/appengine/Login/dist/index.html b/appengine/Login/dist/index.html new file mode 100644 index 0000000..f9780c9 --- /dev/null +++ b/appengine/Login/dist/index.html @@ -0,0 +1,123 @@ + + + + + CodePen - Animated SVG Avatar + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + +

email@domain.com

+ +
+
+ + +
+
+ +
+
+ + + + + + diff --git a/appengine/Login/dist/script.js b/appengine/Login/dist/script.js new file mode 100644 index 0000000..11e9466 --- /dev/null +++ b/appengine/Login/dist/script.js @@ -0,0 +1,203 @@ +var email = document.querySelector('#email'), password = document.querySelector('#password'), mySVG = document.querySelector('.svgContainer'), armL = document.querySelector('.armL'), armR = document.querySelector('.armR'), eyeL = document.querySelector('.eyeL'), eyeR = document.querySelector('.eyeR'), nose = document.querySelector('.nose'), mouth = document.querySelector('.mouth'), mouthBG = document.querySelector('.mouthBG'), mouthSmallBG = document.querySelector('.mouthSmallBG'), mouthMediumBG = document.querySelector('.mouthMediumBG'), mouthLargeBG = document.querySelector('.mouthLargeBG'), mouthMaskPath = document.querySelector('#mouthMaskPath'), mouthOutline = document.querySelector('.mouthOutline'), tooth = document.querySelector('.tooth'), tongue = document.querySelector('.tongue'), chin = document.querySelector('.chin'), face = document.querySelector('.face'), eyebrow = document.querySelector('.eyebrow'), outerEarL = document.querySelector('.earL .outerEar'), outerEarR = document.querySelector('.earR .outerEar'), earHairL = document.querySelector('.earL .earHair'), earHairR = document.querySelector('.earR .earHair'), hair = document.querySelector('.hair'); +var caretPos, curEmailIndex, screenCenter, svgCoords, eyeMaxHorizD = 20, eyeMaxVertD = 10, noseMaxHorizD = 23, noseMaxVertD = 10, dFromC, eyeDistH, eyeLDistV, eyeRDistV, eyeDistR, mouthStatus = "small"; + +function getCoord(e) { + var carPos = email.selectionEnd, + div = document.createElement('div'), + span = document.createElement('span'), + copyStyle = getComputedStyle(email), + emailCoords = {}, caretCoords = {}, centerCoords = {} + ; + [].forEach.call(copyStyle, function(prop){ + div.style[prop] = copyStyle[prop]; + }); + div.style.position = 'absolute'; + document.body.appendChild(div); + div.textContent = email.value.substr(0, carPos); + span.textContent = email.value.substr(carPos) || '.'; + div.appendChild(span); + + emailCoords = getPosition(email); //console.log("emailCoords.x: " + emailCoords.x + ", emailCoords.y: " + emailCoords.y); + caretCoords = getPosition(span); //console.log("caretCoords.x " + caretCoords.x + ", caretCoords.y: " + caretCoords.y); + centerCoords = getPosition(mySVG); //console.log("centerCoords.x: " + centerCoords.x); + svgCoords = getPosition(mySVG); + screenCenter = centerCoords.x + (mySVG.offsetWidth / 2); //console.log("screenCenter: " + screenCenter); + caretPos = caretCoords.x + emailCoords.x; //console.log("caretPos: " + caretPos); + + dFromC = screenCenter - caretPos; //console.log("dFromC: " + dFromC); + var pFromC = Math.round((caretPos / screenCenter) * 100) / 100; + if(pFromC < 1) { + + } else if(pFromC > 1) { + pFromC -= 2; + pFromC = Math.abs(pFromC); + } + + eyeDistH = -dFromC * .05; + if(eyeDistH > eyeMaxHorizD) { + eyeDistH = eyeMaxHorizD; + } else if(eyeDistH < -eyeMaxHorizD) { + eyeDistH = -eyeMaxHorizD; + } + + var eyeLCoords = {x: svgCoords.x + 84, y: svgCoords.y + 76}; + var eyeRCoords = {x: svgCoords.x + 113, y: svgCoords.y + 76}; + var noseCoords = {x: svgCoords.x + 97, y: svgCoords.y + 81}; + var mouthCoords = {x: svgCoords.x + 100, y: svgCoords.y + 100}; + var eyeLAngle = getAngle(eyeLCoords.x, eyeLCoords.y, emailCoords.x + caretCoords.x, emailCoords.y + 25); + var eyeLX = Math.cos(eyeLAngle) * eyeMaxHorizD; + var eyeLY = Math.sin(eyeLAngle) * eyeMaxVertD; + var eyeRAngle = getAngle(eyeRCoords.x, eyeRCoords.y, emailCoords.x + caretCoords.x, emailCoords.y + 25); + var eyeRX = Math.cos(eyeRAngle) * eyeMaxHorizD; + var eyeRY = Math.sin(eyeRAngle) * eyeMaxVertD; + var noseAngle = getAngle(noseCoords.x, noseCoords.y, emailCoords.x + caretCoords.x, emailCoords.y + 25); + var noseX = Math.cos(noseAngle) * noseMaxHorizD; + var noseY = Math.sin(noseAngle) * noseMaxVertD; + var mouthAngle = getAngle(mouthCoords.x, mouthCoords.y, emailCoords.x + caretCoords.x, emailCoords.y + 25); + var mouthX = Math.cos(mouthAngle) * noseMaxHorizD; + var mouthY = Math.sin(mouthAngle) * noseMaxVertD; + var mouthR = Math.cos(mouthAngle) * 6; + var chinX = mouthX * .8; + var chinY = mouthY * .5; + var chinS = 1 - ((dFromC * .15) / 100); + if(chinS > 1) {chinS = 1 - (chinS - 1);} + var faceX = mouthX * .3; + var faceY = mouthY * .4; + var faceSkew = Math.cos(mouthAngle) * 5; + var eyebrowSkew = Math.cos(mouthAngle) * 25; + var outerEarX = Math.cos(mouthAngle) * 4; + var outerEarY = Math.cos(mouthAngle) * 5; + var hairX = Math.cos(mouthAngle) * 6; + var hairS = 1.2; + + TweenMax.to(eyeL, 1, {x: -eyeLX , y: -eyeLY, ease: Expo.easeOut}); + TweenMax.to(eyeR, 1, {x: -eyeRX , y: -eyeRY, ease: Expo.easeOut}); + TweenMax.to(nose, 1, {x: -noseX, y: -noseY, rotation: mouthR, transformOrigin: "center center", ease: Expo.easeOut}); + TweenMax.to(mouth, 1, {x: -mouthX , y: -mouthY, rotation: mouthR, transformOrigin: "center center", ease: Expo.easeOut}); + TweenMax.to(chin, 1, {x: -chinX, y: -chinY, scaleY: chinS, ease: Expo.easeOut}); + TweenMax.to(face, 1, {x: -faceX, y: -faceY, skewX: -faceSkew, transformOrigin: "center top", ease: Expo.easeOut}); + TweenMax.to(eyebrow, 1, {x: -faceX, y: -faceY, skewX: -eyebrowSkew, transformOrigin: "center top", ease: Expo.easeOut}); + TweenMax.to(outerEarL, 1, {x: outerEarX, y: -outerEarY, ease: Expo.easeOut}); + TweenMax.to(outerEarR, 1, {x: outerEarX, y: outerEarY, ease: Expo.easeOut}); + TweenMax.to(earHairL, 1, {x: -outerEarX, y: -outerEarY, ease: Expo.easeOut}); + TweenMax.to(earHairR, 1, {x: -outerEarX, y: outerEarY, ease: Expo.easeOut}); + TweenMax.to(hair, 1, {x: hairX, scaleY: hairS, transformOrigin: "center bottom", ease: Expo.easeOut}); + + document.body.removeChild(div); +}; + +function onEmailInput(e) { + getCoord(e); + var value = e.target.value; + curEmailIndex = value.length; + + // very crude email validation for now to trigger effects + if(curEmailIndex > 0) { + if(mouthStatus == "small") { + mouthStatus = "medium"; + TweenMax.to([mouthBG, mouthOutline, mouthMaskPath], 1, {morphSVG: mouthMediumBG, shapeIndex: 8, ease: Expo.easeOut}); + TweenMax.to(tooth, 1, {x: 0, y: 0, ease: Expo.easeOut}); + TweenMax.to(tongue, 1, {x: 0, y: 1, ease: Expo.easeOut}); + TweenMax.to([eyeL, eyeR], 1, {scaleX: .85, scaleY: .85, ease: Expo.easeOut}); + } + if(value.includes("@")) { + mouthStatus = "large"; + TweenMax.to([mouthBG, mouthOutline, mouthMaskPath], 1, {morphSVG: mouthLargeBG, ease: Expo.easeOut}); + TweenMax.to(tooth, 1, {x: 3, y: -2, ease: Expo.easeOut}); + TweenMax.to(tongue, 1, {y: 2, ease: Expo.easeOut}); + TweenMax.to([eyeL, eyeR], 1, {scaleX: .65, scaleY: .65, ease: Expo.easeOut, transformOrigin: "center center"}); + } else { + mouthStatus = "medium"; + TweenMax.to([mouthBG, mouthOutline, mouthMaskPath], 1, {morphSVG: mouthMediumBG, ease: Expo.easeOut}); + TweenMax.to(tooth, 1, {x: 0, y: 0, ease: Expo.easeOut}); + TweenMax.to(tongue, 1, {x: 0, y: 1, ease: Expo.easeOut}); + TweenMax.to([eyeL, eyeR], 1, {scaleX: .85, scaleY: .85, ease: Expo.easeOut}); + } + } else { + mouthStatus = "small"; + TweenMax.to([mouthBG, mouthOutline, mouthMaskPath], 1, {morphSVG: mouthSmallBG, shapeIndex: 9, ease: Expo.easeOut}); + TweenMax.to(tooth, 1, {x: 0, y: 0, ease: Expo.easeOut}); + TweenMax.to(tongue, 1, {y: 0, ease: Expo.easeOut}); + TweenMax.to([eyeL, eyeR], 1, {scaleX: 1, scaleY: 1, ease: Expo.easeOut}); + } +} + +function onEmailFocus(e) { + e.target.parentElement.classList.add("focusWithText"); + getCoord(); +} + +function onEmailBlur(e) { + if(e.target.value == "") { + e.target.parentElement.classList.remove("focusWithText"); + } + resetFace(); +} + +function onPasswordFocus(e) { + coverEyes(); +} + +function onPasswordBlur(e) { + uncoverEyes(); +} + +function coverEyes() { + TweenMax.to(armL, .45, {x: -93, y: 2, rotation: 0, ease: Quad.easeOut}); + TweenMax.to(armR, .45, {x: -93, y: 2, rotation: 0, ease: Quad.easeOut, delay: .1}); +} + +function uncoverEyes() { + TweenMax.to(armL, 1.35, {y: 220, ease: Quad.easeOut}); + TweenMax.to(armL, 1.35, {rotation: 105, ease: Quad.easeOut, delay: .1}); + TweenMax.to(armR, 1.35, {y: 220, ease: Quad.easeOut}); + TweenMax.to(armR, 1.35, {rotation: -105, ease: Quad.easeOut, delay: .1}); +} + +function resetFace() { + TweenMax.to([eyeL, eyeR], 1, {x: 0, y: 0, ease: Expo.easeOut}); + TweenMax.to(nose, 1, {x: 0, y: 0, scaleX: 1, scaleY: 1, ease: Expo.easeOut}); + TweenMax.to(mouth, 1, {x: 0, y: 0, rotation: 0, ease: Expo.easeOut}); + TweenMax.to(chin, 1, {x: 0, y: 0, scaleY: 1, ease: Expo.easeOut}); + TweenMax.to([face, eyebrow], 1, {x: 0, y: 0, skewX: 0, ease: Expo.easeOut}); + TweenMax.to([outerEarL, outerEarR, earHairL, earHairR, hair], 1, {x: 0, y: 0, scaleY: 1, ease: Expo.easeOut}); +} + +function getAngle(x1, y1, x2, y2) { + var angle = Math.atan2(y1 - y2, x1 - x2); + return angle; +} + +function getPosition(el) { + var xPos = 0; + var yPos = 0; + + while (el) { + if (el.tagName == "BODY") { + // deal with browser quirks with body/window/document and page scroll + var xScroll = el.scrollLeft || document.documentElement.scrollLeft; + var yScroll = el.scrollTop || document.documentElement.scrollTop; + + xPos += (el.offsetLeft - xScroll + el.clientLeft); + yPos += (el.offsetTop - yScroll + el.clientTop); + } else { + // for all other non-BODY elements + xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft); + yPos += (el.offsetTop - el.scrollTop + el.clientTop); + } + + el = el.offsetParent; + } + return { + x: xPos, + y: yPos + }; +} + +email.addEventListener('focus', onEmailFocus); +email.addEventListener('blur', onEmailBlur); +email.addEventListener('input', onEmailInput); +password.addEventListener('focus', onPasswordFocus); +password.addEventListener('blur', onPasswordBlur); +TweenMax.set(armL, {x: -93, y: 220, rotation: 105, transformOrigin: "top left"}); +TweenMax.set(armR, {x: -93, y: 220, rotation: -105, transformOrigin: "top right"}); \ No newline at end of file diff --git a/appengine/Login/dist/style.css b/appengine/Login/dist/style.css new file mode 100644 index 0000000..13c8268 --- /dev/null +++ b/appengine/Login/dist/style.css @@ -0,0 +1,142 @@ +/* colors */ +html { + width: 100%; + height: 100%; +} + +body { + background-color: #eff3f4; + position: relative; + width: 100%; + height: 100%; + font-size: 16px; + font-family: "Source Sans Pro", sans-serif; + font-weight: 400; + -webkit-font-smoothing: antialiased; +} + +form { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: block; + width: 100%; + max-width: 400px; + background-color: #FFF; + margin: 0; + padding: 2.25em; + box-sizing: border-box; + border: solid 1px #DDD; + border-radius: 0.5em; + font-family: "Source Sans Pro", sans-serif; +} +form .svgContainer { + position: relative; + width: 200px; + height: 200px; + margin: 0 auto 1em; + border-radius: 50%; + background: none; + border: solid 2.5px #3A5E77; + overflow: hidden; + pointer-events: none; +} +form .svgContainer div { + position: relative; + width: 100%; + height: 0; + overflow: hidden; + padding-bottom: 100%; +} +form .svgContainer .mySVG { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + pointer-events: none; +} +form .inputGroup { + margin: 0 0 2em; + padding: 0; + position: relative; +} +form .inputGroup:last-of-type { + margin-bottom: 0; +} +form label { + margin: 0 0 12px; + display: block; + font-size: 1.25em; + color: #217093; + font-weight: 700; + font-family: inherit; +} +form input[type=email], form input[type=text], form input[type=password] { + display: block; + margin: 0; + padding: 0 1em 0; + background-color: #f3fafd; + border: solid 2px #217093; + border-radius: 4px; + -webkit-appearance: none; + box-sizing: border-box; + width: 100%; + height: 65px; + font-size: 1.55em; + color: #353538; + font-weight: 600; + font-family: inherit; + transition: box-shadow 0.2s linear, border-color 0.25s ease-out; +} +form input[type=email]:focus, form input[type=text]:focus, form input[type=password]:focus { + outline: none; + box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1); + border: solid 2px #4eb8dd; +} +form input[type=email], form input[type=text] { + padding: 14px 1em 0px; +} +form button { + display: block; + margin: 0; + padding: 0.65em 1em 1em; + background-color: #4eb8dd; + border: none; + border-radius: 4px; + box-sizing: border-box; + box-shadow: none; + width: 100%; + height: 65px; + font-size: 1.55em; + color: #FFF; + font-weight: 600; + font-family: inherit; + transition: background-color 0.2s ease-out; +} +form button:hover, form button:active { + background-color: #217093; +} +form .inputGroup1 .helper { + position: absolute; + z-index: 1; + font-family: inherit; +} +form .inputGroup1 .helper1 { + top: 0; + left: 0; + transform: translate(1.4em, 2.6em) scale(1); + transform-origin: 0 0; + color: #217093; + font-size: 1.25em; + font-weight: 400; + opacity: 0.65; + pointer-events: none; + transition: transform 0.2s ease-out, opacity 0.2s linear; +} +form .inputGroup1.focusWithText .helper { + /*input[type='email']:focus + .helper {*/ + transform: translate(1.4em, 2em) scale(0.65); + opacity: 1; +} \ No newline at end of file diff --git a/appengine/Login/src/index.html b/appengine/Login/src/index.html new file mode 100644 index 0000000..98b06e7 --- /dev/null +++ b/appengine/Login/src/index.html @@ -0,0 +1,106 @@ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + +

email@domain.com

+ +
+
+ + +
+
+ +
+
\ No newline at end of file diff --git a/appengine/Login/src/script.js b/appengine/Login/src/script.js new file mode 100644 index 0000000..11e9466 --- /dev/null +++ b/appengine/Login/src/script.js @@ -0,0 +1,203 @@ +var email = document.querySelector('#email'), password = document.querySelector('#password'), mySVG = document.querySelector('.svgContainer'), armL = document.querySelector('.armL'), armR = document.querySelector('.armR'), eyeL = document.querySelector('.eyeL'), eyeR = document.querySelector('.eyeR'), nose = document.querySelector('.nose'), mouth = document.querySelector('.mouth'), mouthBG = document.querySelector('.mouthBG'), mouthSmallBG = document.querySelector('.mouthSmallBG'), mouthMediumBG = document.querySelector('.mouthMediumBG'), mouthLargeBG = document.querySelector('.mouthLargeBG'), mouthMaskPath = document.querySelector('#mouthMaskPath'), mouthOutline = document.querySelector('.mouthOutline'), tooth = document.querySelector('.tooth'), tongue = document.querySelector('.tongue'), chin = document.querySelector('.chin'), face = document.querySelector('.face'), eyebrow = document.querySelector('.eyebrow'), outerEarL = document.querySelector('.earL .outerEar'), outerEarR = document.querySelector('.earR .outerEar'), earHairL = document.querySelector('.earL .earHair'), earHairR = document.querySelector('.earR .earHair'), hair = document.querySelector('.hair'); +var caretPos, curEmailIndex, screenCenter, svgCoords, eyeMaxHorizD = 20, eyeMaxVertD = 10, noseMaxHorizD = 23, noseMaxVertD = 10, dFromC, eyeDistH, eyeLDistV, eyeRDistV, eyeDistR, mouthStatus = "small"; + +function getCoord(e) { + var carPos = email.selectionEnd, + div = document.createElement('div'), + span = document.createElement('span'), + copyStyle = getComputedStyle(email), + emailCoords = {}, caretCoords = {}, centerCoords = {} + ; + [].forEach.call(copyStyle, function(prop){ + div.style[prop] = copyStyle[prop]; + }); + div.style.position = 'absolute'; + document.body.appendChild(div); + div.textContent = email.value.substr(0, carPos); + span.textContent = email.value.substr(carPos) || '.'; + div.appendChild(span); + + emailCoords = getPosition(email); //console.log("emailCoords.x: " + emailCoords.x + ", emailCoords.y: " + emailCoords.y); + caretCoords = getPosition(span); //console.log("caretCoords.x " + caretCoords.x + ", caretCoords.y: " + caretCoords.y); + centerCoords = getPosition(mySVG); //console.log("centerCoords.x: " + centerCoords.x); + svgCoords = getPosition(mySVG); + screenCenter = centerCoords.x + (mySVG.offsetWidth / 2); //console.log("screenCenter: " + screenCenter); + caretPos = caretCoords.x + emailCoords.x; //console.log("caretPos: " + caretPos); + + dFromC = screenCenter - caretPos; //console.log("dFromC: " + dFromC); + var pFromC = Math.round((caretPos / screenCenter) * 100) / 100; + if(pFromC < 1) { + + } else if(pFromC > 1) { + pFromC -= 2; + pFromC = Math.abs(pFromC); + } + + eyeDistH = -dFromC * .05; + if(eyeDistH > eyeMaxHorizD) { + eyeDistH = eyeMaxHorizD; + } else if(eyeDistH < -eyeMaxHorizD) { + eyeDistH = -eyeMaxHorizD; + } + + var eyeLCoords = {x: svgCoords.x + 84, y: svgCoords.y + 76}; + var eyeRCoords = {x: svgCoords.x + 113, y: svgCoords.y + 76}; + var noseCoords = {x: svgCoords.x + 97, y: svgCoords.y + 81}; + var mouthCoords = {x: svgCoords.x + 100, y: svgCoords.y + 100}; + var eyeLAngle = getAngle(eyeLCoords.x, eyeLCoords.y, emailCoords.x + caretCoords.x, emailCoords.y + 25); + var eyeLX = Math.cos(eyeLAngle) * eyeMaxHorizD; + var eyeLY = Math.sin(eyeLAngle) * eyeMaxVertD; + var eyeRAngle = getAngle(eyeRCoords.x, eyeRCoords.y, emailCoords.x + caretCoords.x, emailCoords.y + 25); + var eyeRX = Math.cos(eyeRAngle) * eyeMaxHorizD; + var eyeRY = Math.sin(eyeRAngle) * eyeMaxVertD; + var noseAngle = getAngle(noseCoords.x, noseCoords.y, emailCoords.x + caretCoords.x, emailCoords.y + 25); + var noseX = Math.cos(noseAngle) * noseMaxHorizD; + var noseY = Math.sin(noseAngle) * noseMaxVertD; + var mouthAngle = getAngle(mouthCoords.x, mouthCoords.y, emailCoords.x + caretCoords.x, emailCoords.y + 25); + var mouthX = Math.cos(mouthAngle) * noseMaxHorizD; + var mouthY = Math.sin(mouthAngle) * noseMaxVertD; + var mouthR = Math.cos(mouthAngle) * 6; + var chinX = mouthX * .8; + var chinY = mouthY * .5; + var chinS = 1 - ((dFromC * .15) / 100); + if(chinS > 1) {chinS = 1 - (chinS - 1);} + var faceX = mouthX * .3; + var faceY = mouthY * .4; + var faceSkew = Math.cos(mouthAngle) * 5; + var eyebrowSkew = Math.cos(mouthAngle) * 25; + var outerEarX = Math.cos(mouthAngle) * 4; + var outerEarY = Math.cos(mouthAngle) * 5; + var hairX = Math.cos(mouthAngle) * 6; + var hairS = 1.2; + + TweenMax.to(eyeL, 1, {x: -eyeLX , y: -eyeLY, ease: Expo.easeOut}); + TweenMax.to(eyeR, 1, {x: -eyeRX , y: -eyeRY, ease: Expo.easeOut}); + TweenMax.to(nose, 1, {x: -noseX, y: -noseY, rotation: mouthR, transformOrigin: "center center", ease: Expo.easeOut}); + TweenMax.to(mouth, 1, {x: -mouthX , y: -mouthY, rotation: mouthR, transformOrigin: "center center", ease: Expo.easeOut}); + TweenMax.to(chin, 1, {x: -chinX, y: -chinY, scaleY: chinS, ease: Expo.easeOut}); + TweenMax.to(face, 1, {x: -faceX, y: -faceY, skewX: -faceSkew, transformOrigin: "center top", ease: Expo.easeOut}); + TweenMax.to(eyebrow, 1, {x: -faceX, y: -faceY, skewX: -eyebrowSkew, transformOrigin: "center top", ease: Expo.easeOut}); + TweenMax.to(outerEarL, 1, {x: outerEarX, y: -outerEarY, ease: Expo.easeOut}); + TweenMax.to(outerEarR, 1, {x: outerEarX, y: outerEarY, ease: Expo.easeOut}); + TweenMax.to(earHairL, 1, {x: -outerEarX, y: -outerEarY, ease: Expo.easeOut}); + TweenMax.to(earHairR, 1, {x: -outerEarX, y: outerEarY, ease: Expo.easeOut}); + TweenMax.to(hair, 1, {x: hairX, scaleY: hairS, transformOrigin: "center bottom", ease: Expo.easeOut}); + + document.body.removeChild(div); +}; + +function onEmailInput(e) { + getCoord(e); + var value = e.target.value; + curEmailIndex = value.length; + + // very crude email validation for now to trigger effects + if(curEmailIndex > 0) { + if(mouthStatus == "small") { + mouthStatus = "medium"; + TweenMax.to([mouthBG, mouthOutline, mouthMaskPath], 1, {morphSVG: mouthMediumBG, shapeIndex: 8, ease: Expo.easeOut}); + TweenMax.to(tooth, 1, {x: 0, y: 0, ease: Expo.easeOut}); + TweenMax.to(tongue, 1, {x: 0, y: 1, ease: Expo.easeOut}); + TweenMax.to([eyeL, eyeR], 1, {scaleX: .85, scaleY: .85, ease: Expo.easeOut}); + } + if(value.includes("@")) { + mouthStatus = "large"; + TweenMax.to([mouthBG, mouthOutline, mouthMaskPath], 1, {morphSVG: mouthLargeBG, ease: Expo.easeOut}); + TweenMax.to(tooth, 1, {x: 3, y: -2, ease: Expo.easeOut}); + TweenMax.to(tongue, 1, {y: 2, ease: Expo.easeOut}); + TweenMax.to([eyeL, eyeR], 1, {scaleX: .65, scaleY: .65, ease: Expo.easeOut, transformOrigin: "center center"}); + } else { + mouthStatus = "medium"; + TweenMax.to([mouthBG, mouthOutline, mouthMaskPath], 1, {morphSVG: mouthMediumBG, ease: Expo.easeOut}); + TweenMax.to(tooth, 1, {x: 0, y: 0, ease: Expo.easeOut}); + TweenMax.to(tongue, 1, {x: 0, y: 1, ease: Expo.easeOut}); + TweenMax.to([eyeL, eyeR], 1, {scaleX: .85, scaleY: .85, ease: Expo.easeOut}); + } + } else { + mouthStatus = "small"; + TweenMax.to([mouthBG, mouthOutline, mouthMaskPath], 1, {morphSVG: mouthSmallBG, shapeIndex: 9, ease: Expo.easeOut}); + TweenMax.to(tooth, 1, {x: 0, y: 0, ease: Expo.easeOut}); + TweenMax.to(tongue, 1, {y: 0, ease: Expo.easeOut}); + TweenMax.to([eyeL, eyeR], 1, {scaleX: 1, scaleY: 1, ease: Expo.easeOut}); + } +} + +function onEmailFocus(e) { + e.target.parentElement.classList.add("focusWithText"); + getCoord(); +} + +function onEmailBlur(e) { + if(e.target.value == "") { + e.target.parentElement.classList.remove("focusWithText"); + } + resetFace(); +} + +function onPasswordFocus(e) { + coverEyes(); +} + +function onPasswordBlur(e) { + uncoverEyes(); +} + +function coverEyes() { + TweenMax.to(armL, .45, {x: -93, y: 2, rotation: 0, ease: Quad.easeOut}); + TweenMax.to(armR, .45, {x: -93, y: 2, rotation: 0, ease: Quad.easeOut, delay: .1}); +} + +function uncoverEyes() { + TweenMax.to(armL, 1.35, {y: 220, ease: Quad.easeOut}); + TweenMax.to(armL, 1.35, {rotation: 105, ease: Quad.easeOut, delay: .1}); + TweenMax.to(armR, 1.35, {y: 220, ease: Quad.easeOut}); + TweenMax.to(armR, 1.35, {rotation: -105, ease: Quad.easeOut, delay: .1}); +} + +function resetFace() { + TweenMax.to([eyeL, eyeR], 1, {x: 0, y: 0, ease: Expo.easeOut}); + TweenMax.to(nose, 1, {x: 0, y: 0, scaleX: 1, scaleY: 1, ease: Expo.easeOut}); + TweenMax.to(mouth, 1, {x: 0, y: 0, rotation: 0, ease: Expo.easeOut}); + TweenMax.to(chin, 1, {x: 0, y: 0, scaleY: 1, ease: Expo.easeOut}); + TweenMax.to([face, eyebrow], 1, {x: 0, y: 0, skewX: 0, ease: Expo.easeOut}); + TweenMax.to([outerEarL, outerEarR, earHairL, earHairR, hair], 1, {x: 0, y: 0, scaleY: 1, ease: Expo.easeOut}); +} + +function getAngle(x1, y1, x2, y2) { + var angle = Math.atan2(y1 - y2, x1 - x2); + return angle; +} + +function getPosition(el) { + var xPos = 0; + var yPos = 0; + + while (el) { + if (el.tagName == "BODY") { + // deal with browser quirks with body/window/document and page scroll + var xScroll = el.scrollLeft || document.documentElement.scrollLeft; + var yScroll = el.scrollTop || document.documentElement.scrollTop; + + xPos += (el.offsetLeft - xScroll + el.clientLeft); + yPos += (el.offsetTop - yScroll + el.clientTop); + } else { + // for all other non-BODY elements + xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft); + yPos += (el.offsetTop - el.scrollTop + el.clientTop); + } + + el = el.offsetParent; + } + return { + x: xPos, + y: yPos + }; +} + +email.addEventListener('focus', onEmailFocus); +email.addEventListener('blur', onEmailBlur); +email.addEventListener('input', onEmailInput); +password.addEventListener('focus', onPasswordFocus); +password.addEventListener('blur', onPasswordBlur); +TweenMax.set(armL, {x: -93, y: 220, rotation: 105, transformOrigin: "top left"}); +TweenMax.set(armR, {x: -93, y: 220, rotation: -105, transformOrigin: "top right"}); \ No newline at end of file diff --git a/appengine/Login/src/style.scss b/appengine/Login/src/style.scss new file mode 100644 index 0000000..e965c5c --- /dev/null +++ b/appengine/Login/src/style.scss @@ -0,0 +1,87 @@ +/* colors */ +$darkBlue: #217093; +$medBlue: #4eb8dd; +$lightBlue: #ddf1fa; +$inputBG: #f3fafd; + +html {width: 100%; height: 100%;} +body { + background-color: #eff3f4; position: relative; width: 100%; height: 100%; + font-size: 16px; font-family: 'Source Sans Pro', sans-serif; font-weight: 400; + -webkit-font-smoothing: antialiased; +} +form { + position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); + display: block; width: 100%; max-width: 400px; background-color: #FFF; + margin: 0; padding: 2.25em; box-sizing: border-box; border: solid 1px #DDD; border-radius: .5em; + font-family: 'Source Sans Pro', sans-serif; + .svgContainer { + position: relative; width: 200px; height: 200px; margin: 0 auto 1em; + border-radius: 50%; background: none; border: solid 2.5px #3A5E77; overflow: hidden; + pointer-events: none; + div { + position: relative; width: 100%; height: 0; overflow: hidden; + padding-bottom: 100%; + } + .mySVG { + position: absolute; left: 0; top: 0; width: 100%; height: 100%; + pointer-events: none; + } + } + .inputGroup { + margin: 0 0 2em; padding: 0; position: relative; + &:last-of-type { + margin-bottom: 0; + } + } + label { + margin: 0 0 12px; display: block; + font-size: 1.25em; color: #217093; font-weight: 700; font-family: inherit; + } + input[type='email'], input[type="text"], input[type='password'] { + display: block; margin: 0; padding: 0 1em 0; + background-color: $inputBG; border: solid 2px $darkBlue; border-radius: 4px; -webkit-appearance: none; + box-sizing: border-box; + width: 100%; height: 65px; + font-size: 1.55em; color: #353538; font-weight: 600; font-family: inherit; + transition: box-shadow .2s linear, border-color .25s ease-out; + &:focus { + outline: none; + box-shadow: 0px 2px 10px rgba(0,0,0,.1); + border: solid 2px #4eb8dd; + } + } + input[type='email'], input[type="text"] { + padding: 14px 1em 0px; + } + button { + display: block; margin: 0; padding: .65em 1em 1em; + background-color: $medBlue; border: none; border-radius: 4px; + box-sizing: border-box; box-shadow: none; + width: 100%; height: 65px; + font-size: 1.55em; color: #FFF; font-weight: 600; font-family: inherit; + transition: background-color .2s ease-out; + &:hover, &:active { + background-color: $darkBlue; + } + } + + .inputGroup1 { + .helper { + position: absolute; z-index: 1; + font-family: inherit; + } + .helper1 { + top: 0; left: 0; + transform: translate(1.4em, 2.6em) scale(1); transform-origin: 0 0; + color: $darkBlue; font-size: 1.25em; font-weight: 400; opacity: .65; + pointer-events: none; + transition: transform .2s ease-out, opacity .2s linear; + } + + &.focusWithText .helper { + /*input[type='email']:focus + .helper {*/ + transform: translate(1.4em, 2.0em) scale(.65); opacity: 1; + } + } +} \ No newline at end of file diff --git a/appengine/app.yaml b/appengine/app.yaml index 0910b90..d952ae3 100644 --- a/appengine/app.yaml +++ b/appengine/app.yaml @@ -12,7 +12,7 @@ handlers: # Index page. - url: / - static_files: index.html + static_files: Home.html upload: index\.html secure: always - url: /index/ diff --git a/appengine/bird/generated/en/compressed.js b/appengine/bird/generated/en/compressed.js index ee55544..c035071 100644 --- a/appengine/bird/generated/en/compressed.js +++ b/appengine/bird/generated/en/compressed.js @@ -526,7 +526,7 @@ h.Ib.bird_and={Ca:function(){this.Ag=h.o.LOGIC_OPERATION_HELPURL;this.Nd(h.o.LOG h.Ib.bird_ifElse={Ca:function(){this.Ag=h.o.CONTROLS_IF_HELPURL;this.Nd(h.o.LOGIC_HUE);K(Yb(this,"CONDITION"),h.o.CONTROLS_IF_MSG_IF).dd("Boolean");K(this.Ie(h.Ga.Ec,"DO"),h.o.CONTROLS_IF_MSG_THEN);K(this.Ie(h.Ga.Ec,"ELSE"),h.o.CONTROLS_IF_MSG_ELSE);this.zm=!1;this.we(h.o.CONTROLS_IF_TOOLTIP_2)}};h.s.bird_ifElse=function(a){var c=Q(h.s,a,"CONDITION",h.s.ac)||"false",d=id(a,"DO");a=id(a,"ELSE");return"if ("+c+") {\n"+d+"} else {\n"+a+"}\n"};h.Ib.controls_if.$F=h.Ib.controls_if.Ca; h.Ib.controls_if.Ca=function(){this.$F();this.In(!1);this.Jq(!1);this.zm=!1};var Ed=Ed||{};function Fd(a,c){function d(){}d.prototype=c.prototype;a.A=c.prototype;a.prototype=new d;a.prototype.constructor=a;a.cL=function(e,f,g){return c.prototype[f].apply(e,Array.prototype.slice.call(arguments,2))}}if(!Gd){var Gd,Hd="";"undefined"!==typeof navigator&&navigator&&"string"==typeof navigator.userAgent&&(Hd=navigator.userAgent);var Id=0==Hd.indexOf("Opera");Gd={LL:{MI:"ScriptEngine"in window},VJ:Id,De:!Id&&-1!=Hd.indexOf("MSIE"),px:!Id&&-1!=Hd.indexOf("WebKit")}}if(!Jd)var Jd={}; if(!Kd)var Kd={};if(!Ld)var Ld={};if(!Md)var Md={};if(!Nd)var Nd={};if(!Od)var Od={};var Pd=Ed.cI?{WL:!0}:{};function Qd(){throw Error("Do not instantiate directly");}Qd.prototype.Wx=null;Qd.prototype.toString=function(){return this.content};function Rd(a){if(null!=a)switch(a.Wx){case 1:return 1;case -1:return-1;case 0:return 0}return null}function Sd(){Qd.call(this)}Fd(Sd,Qd);Sd.prototype.hE=Pd;function V(a){return null!=a&&a.hE===Pd?a:Td(String(String(a)).replace(Ud,Vd),Rd(a))} -var Td=function(a){function c(){}c.prototype=a.prototype;return function(d,e){var f=new c;f.content=String(d);void 0!==e&&(f.Wx=e);return f}}(Sd),Wd={"\x00":"�",'"':""","&":"&","'":"'","<":"<",">":">","\t":" ","\n":" ","\x0B":" ","\f":" ","\r":" "," ":" ","-":"-","/":"/","=":"=","`":"`","\u0085":"…","\u00a0":" ","\u2028":"
","\u2029":"
"};function Vd(a){return Wd[a]}var Ud=/[\x00\x22\x26\x27\x3c\x3e]/g;function Xd(){var a='

'+((od?'':'')+"Technothlon Games : "+V("Bird")+"");if(S){var c="   ";for(var d=1;11>d;d++){var e="?lang="+V(R)+"&level="+V(d);c+=" "+(d==S?''+V(d)+"":10==d?''+V(d)+"":'')}}else c= +var Td=function(a){function c(){}c.prototype=a.prototype;return function(d,e){var f=new c;f.content=String(d);void 0!==e&&(f.Wx=e);return f}}(Sd),Wd={"\x00":"�",'"':""","&":"&","'":"'","<":"<",">":">","\t":" ","\n":" ","\x0B":" ","\f":" ","\r":" "," ":" ","-":"-","/":"/","=":"=","`":"`","\u0085":"…","\u00a0":" ","\u2028":"
","\u2029":"
"};function Vd(a){return Wd[a]}var Ud=/[\x00\x22\x26\x27\x3c\x3e]/g;function Xd(){var a='

'+((od?'':'')+"Technothlon Games : "+V("Bird")+"");if(S){var c="   ";for(var d=1;11>d;d++){var e="?lang="+V(R)+"&level="+V(d);c+=" "+(d==S?''+V(d)+"":10==d?''+V(d)+"":'')}}else c= "";return'
Technothlon GamesPuzzleMazeBirdTurtleMovieMusicPond TutorPondGeneticsYou solved this level with 1 line of JavaScript:You solved this level with %1 lines of JavaScript:Are you ready for level %1?Are you ready for the next challenge?Title:Save and link to blocks.Run the program you wrote.Run ProgramStop the program and reset the level.ResetHelpLogicLoopsMathTextListsColourVariablesFunctionsThere was a problem with the request.Share your blocks with this link:\\n\\n%1Sorry, \'%1\' doesn\'t correspond with any saved program.Could not load your saved file. Perhaps it was created with a different version of Blockly?Thank you for this program! If our staff of trained monkeys like it, they will publish it to the gallery within a couple of days.listtextOnce you start editing JavaScript, you can\'t go back to editing blocks. Is this OK?Blocks
does not have wormheadingThe condition when the bird has not gotten the worm.Move in the direction of the given angle: 0 is to the right, 90 is straight up, etc.x and y mark the bird\'s position. When x = 0 the bird is near the left edge, when x = 100 it\'s near the right edge. When y = 0 the bird is at the bottom, when y = 100 it\'s at the top.
'+ (a+c+'

 
')+ ((2<=S?(4==S||5==S?'':'')+(4<=S?'LTX50'+(5<=S?'LTY50'+ @@ -689,7 +689,7 @@ function De(a,c){Fe["/storage"]&&Fe["/storage"].abort();Fe["/storage"]=new XMLHt function Ee(){window.location.hash=this.responseText.trim();Ge(T("Games_linkAlert").replace("%1",window.location.href));Be=ze()}function He(){var a=this.responseText.trim();a.length?Ae(a):Ge(T("Games_hashError").replace("%1",window.location.hash));Be=ze()}function Ge(a){if("object"===typeof X){var c=document.getElementById("linkButton");X.mH(c,a)}else alert(a)};var x=null,Ie="",Je="";function Ke(){td();var a=document.getElementById("linkButton");a&&(od?a.style.display="none":(ze=Le,Ae=Me,xd(a,Ce)));(a=document.getElementById("languageMenu"))&&a.addEventListener("change",Ne,!0)} function Oe(){var a=1==S?'':5>S?'':'';if(!od&&1=c.length?"?lang="+a:/[?&]lang=[^&]*/.test(c)?c.replace(/([?&]lang=)[^&]*/,"$1"+a):c.replace(/\?/,"?lang="+a+"&");window.location=window.location.protocol+"//"+window.location.host+window.location.pathname+c} function Se(){10>S?window.location=window.location.protocol+"//"+window.location.host+window.location.pathname+"?lang="+R+"&level="+(S+1):Re()}function Te(a){if(a){var c=a.match(/^block_id_([^']+)$/);c&&(a=c[1])}Nc(a,void 0)}function Ue(a){a=a.replace(/(,\s*)?'block_id_[^']+'\)/g,")");return a.replace(/\s+$/,"")}function Ve(a){if("click"==a.type&&"touchend"==We&&Xe+2E3>Date.now()||We==a.type&&Xe+400>Date.now())return a.preventDefault(),a.stopPropagation(),!0;We=a.type;Xe=Date.now();return!1} var We=null,Xe=0;function Ye(){setTimeout(function(){var a=document.createElement("script");a.type="text/javascript";a.src="third-party/JS-Interpreter/compressed.js";document.head.appendChild(a)},1)}function Ze(){setTimeout(function(){var a=document.createElement("link");a.rel="stylesheet";a.type="text/css";a.href="common/prettify.css";document.head.appendChild(a);a=document.createElement("script");a.type="text/javascript";a.src="common/prettify.js";document.head.appendChild(a)},1)};var X={gj:!1,ey:null,Ep:null,Nq:function(a,c,d,e,f,g){function k(){if(X.gj){l.style.visibility="visible";l.style.zIndex=10;m.style.visibility="hidden";var q=a.getElementsByClassName("primary");q.length||(q=a.getElementsByClassName("secondary"),q.length||(q=a.getElementsByTagName("button")));q.length&&q[0].focus()}}if(!a)throw TypeError("Content not found: "+a);X.gj&&X.Lh(!1);h.Fh()&&h.rc(!0);X.gj=!0;X.ey=c;X.Ep=g;var l=document.getElementById("dialog");g=document.getElementById("dialogShadow");var m= diff --git a/appengine/common/back.js b/appengine/common/back.js index 4f7ee1f..18e9f63 100644 --- a/appengine/common/back.js +++ b/appengine/common/back.js @@ -15,5 +15,5 @@ // Append the language. var IS_HTML = /\.html$/.test(window.location.pathname); document.getElementById('back').href = - (IS_HTML ? 'index.html' : '/') + location.search; + (IS_HTML ? 'Home.html' : '/') + location.search; })(); diff --git a/appengine/generated/en/soy.js b/appengine/generated/en/soy.js index 0a68051..073f515 100644 --- a/appengine/generated/en/soy.js +++ b/appengine/generated/en/soy.js @@ -28,7 +28,7 @@ if (goog.DEBUG) { BlocklyGames.soy.titleSpan = function(opt_data, opt_ignored, opt_ijData) { - return '' + ((opt_ijData.html) ? '' : '') + 'Technothlon Games : ' + soy.$$escapeHtml(opt_data.appName) + ''; + return '' + ((opt_ijData.html) ? '' : '') + 'Technothlon Games : ' + soy.$$escapeHtml(opt_data.appName) + ''; }; if (goog.DEBUG) { BlocklyGames.soy.titleSpan.soyTemplateName = 'BlocklyGames.soy.titleSpan'; diff --git a/appengine/js/lib-interface.js b/appengine/js/lib-interface.js index 93c6263..d8ae825 100644 --- a/appengine/js/lib-interface.js +++ b/appengine/js/lib-interface.js @@ -218,7 +218,7 @@ BlocklyInterface.saveToLocalStorage = function() { * Go to the index page. */ BlocklyInterface.indexPage = function() { - window.location = (BlocklyGames.IS_HTML ? 'index.html' : './') + + window.location = (BlocklyGames.IS_HTML ? 'Home.html' : './') + '?lang=' + BlocklyGames.LANG; }; diff --git a/appengine/pond/duck/generated/en/compressed.js b/appengine/pond/duck/generated/en/compressed.js index 7130aa3..905fd2d 100644 --- a/appengine/pond/duck/generated/en/compressed.js +++ b/appengine/pond/duck/generated/en/compressed.js @@ -581,7 +581,7 @@ g.i.WORKSPACE_ARIA_LABEL="Blockly Workspace";g.i.WORKSPACE_COMMENT_DEFAULT_TEXT= g.i.LISTS_GET_SUBLIST_INPUT_IN_LIST=g.i.LISTS_INLIST;g.i.LISTS_INDEX_OF_INPUT_IN_LIST=g.i.LISTS_INLIST;g.i.LISTS_SET_INDEX_INPUT_IN_LIST=g.i.LISTS_INLIST;g.i.MATH_CHANGE_TITLE_ITEM=g.i.VARIABLES_DEFAULT_NAME;g.i.PROCEDURES_DEFRETURN_COMMENT=g.i.PROCEDURES_DEFNORETURN_COMMENT;g.i.PROCEDURES_DEFRETURN_PROCEDURE=g.i.PROCEDURES_DEFNORETURN_PROCEDURE;g.i.PROCEDURES_DEFRETURN_TITLE=g.i.PROCEDURES_DEFNORETURN_TITLE;g.i.MATH_HUE="230";g.i.LOOPS_HUE="120";g.i.LISTS_HUE="260";g.i.LOGIC_HUE="210"; g.i.VARIABLES_HUE="330";g.i.PROCEDURES_HUE="290";var BlocklyStorage={},Hd=null,Id=null;function Jd(){var a=Hd();Kd("xml="+encodeURIComponent(a))}var Ld={};function Kd(a){var c=Md;Ld["/storage"]&&Ld["/storage"].abort();Ld["/storage"]=new XMLHttpRequest;Ld["/storage"].onload=function(){200===this.status?c&&c.call(this):Nd(R("Games_httpRequestError")+"\nXHR status: "+this.status);Ld["/storage"]=null};Ld["/storage"].open("POST","/storage");Ld["/storage"].setRequestHeader("Content-Type","application/x-www-form-urlencoded");Ld["/storage"].send(a)} function Md(){window.location.hash=this.responseText.trim();Nd(R("Games_linkAlert").replace("%1",window.location.href));Id=Hd()}function Nd(a){if("object"===typeof S){var c=document.getElementById("linkButton");S.dL(c,a)}else alert(a)};var w=null,Od=null,Pd=!1;function Qd(){Bd();var a=document.getElementById("linkButton");a&&(vd?a.style.display="none":(Hd=Rd,Fd(a,Jd)));(a=document.getElementById("languageMenu"))&&a.addEventListener("change",Sd,!0)}function Rd(){if(Pd)var a=Od.getValue();else{a=g.P.BL();if(1==w.yc(!1).length&&a.querySelector){var c=a.querySelector("block");c&&(c.removeAttribute("x"),c.removeAttribute("y"))}a=g.P.re(a)}return a} -function Td(){"object"==typeof BlocklyStorage&&null!==Id&&Id!=Rd()&&(window.location.hash="",Id=null)}function Ud(){window.location=(vd?"index.html":"./")+"?lang="+td} +function Td(){"object"==typeof BlocklyStorage&&null!==Id&&Id!=Rd()&&(window.location.hash="",Id=null)}function Ud(){window.location=(vd?"Home.html":"./")+"?lang="+td} function Sd(){window.sessionStorage&&(window.sessionStorage.tP=Rd());var a=document.getElementById("languageMenu");a=encodeURIComponent(a.options[a.selectedIndex].value);var c=window.location.search;c=1>=c.length?"?lang="+a:/[?&]lang=[^&]*/.test(c)?c.replace(/([?&]lang=)[^&]*/,"$1"+a):c.replace(/\?/,"?lang="+a+"&");window.location=window.location.protocol+"//"+window.location.host+window.location.pathname+c} function Vd(){10>wd?window.location=window.location.protocol+"//"+window.location.host+window.location.pathname+"?lang="+td+"&level="+(wd+1):Ud()}function Wd(){var a="".replace(/(,\s*)?'block_id_[^']+'\)/g,")");return a.replace(/\s+$/,"")}function Xd(a){if("click"==a.type&&"touchend"==Yd&&Zd+2E3>Date.now()||Yd==a.type&&Zd+400>Date.now())return a.preventDefault(),a.stopPropagation(),!0;Yd=a.type;Zd=Date.now();return!1}var Yd=null,Zd=0; function $d(){setTimeout(function(){var a=document.createElement("script");a.type="text/javascript";a.src="third-party/JS-Interpreter/compressed.js";document.head.appendChild(a)},1)}function ae(){setTimeout(function(){var a=document.createElement("link");a.rel="stylesheet";a.type="text/css";a.href="common/prettify.css";document.head.appendChild(a);a=document.createElement("script");a.type="text/javascript";a.src="common/prettify.js";document.head.appendChild(a)},1)};function be(){setTimeout(function(){var a=document.createElement("script");a.type="text/javascript";a.src="third-party/babel.min.js";document.head.appendChild(a)},1)} @@ -902,7 +902,7 @@ ABS:g.i.MATH_SINGLE_TOOLTIP_ABS,SIN:g.i.MATH_TRIG_TOOLTIP_SIN,COS:g.i.MATH_TRIG_ g.j.pond_math_single=function(a){var c=C(a,"OP");a=X(g.j,a,"NUM",g.j.gb)||"0";switch(c){case "ABS":c="Math.abs("+a+")";break;case "ROOT":c="Math.sqrt("+a+")";break;case "SIN":c="Math.sin_deg("+a+")";break;case "COS":c="Math.cos_deg("+a+")";break;case "TAN":c="Math.tan_deg("+a+")";break;case "ASIN":c="Math.asin_deg("+a+")";break;case "ACOS":c="Math.acos_deg("+a+")";break;case "ATAN":c="Math.atan_deg("+a+")";break;default:throw Error("Unknown math operator: "+c);}return[c,g.j.tb]}; g.j.pond_math_number=g.j.math_number;g.O.pond_loc_x=g.O.pond_getX;g.j.pond_loc_x=g.j.pond_getX;g.O.pond_loc_y=g.O.pond_getY;g.j.pond_loc_y=g.j.pond_getY;g.O.pond_controls_if=g.O.controls_if;g.j.pond_controls_if=g.j.controls_if;g.O.pond_loops_while=g.O.controls_whileUntil;g.j.pond_loops_while=g.j.controls_whileUntil;g.O.pond_math_arithmetic=g.O.math_arithmetic;g.j.pond_math_arithmetic=g.j.math_arithmetic;g.O.pond_math_change=g.O.math_change;g.j.pond_math_change=g.j.math_change;var xf=xf||{};function yf(a,c){function d(){}d.prototype=c.prototype;a.v=c.prototype;a.prototype=new d;a.prototype.constructor=a;a.TO=function(e,f,h){return c.prototype[f].apply(e,Array.prototype.slice.call(arguments,2))}}if(!zf){var zf,Af="";"undefined"!==typeof navigator&&navigator&&"string"==typeof navigator.userAgent&&(Af=navigator.userAgent);var Bf=0==Af.indexOf("Opera");zf={sP:{FM:"ScriptEngine"in window},RN:Bf,bf:!Bf&&-1!=Af.indexOf("MSIE"),zA:!Bf&&-1!=Af.indexOf("WebKit")}}if(!Cf)var Cf={}; if(!Df)var Df={};if(!Ef)var Ef={};if(!Ff)var Ff={};if(!Gf)var Gf={};if(!Hf)var Hf={};var If=xf.YL?{AP:!0}:{};function Jf(){throw Error("Do not instantiate directly");}Jf.prototype.jB=null;Jf.prototype.toString=function(){return this.content};function Kf(a){if(null!=a)switch(a.jB){case 1:return 1;case -1:return-1;case 0:return 0}return null}function Lf(){Jf.call(this)}yf(Lf,Jf);Lf.prototype.UH=If;function Z(a){return null!=a&&a.UH===If?a:Mf(String(String(a)).replace(Nf,Of),Kf(a))} -var Mf=function(a){function c(){}c.prototype=a.prototype;return function(d,e){var f=new c;f.content=String(d);void 0!==e&&(f.jB=e);return f}}(Lf),Pf={"\x00":"�",'"':""","&":"&","'":"'","<":"<",">":">","\t":" ","\n":" ","\x0B":" ","\f":" ","\r":" "," ":" ","-":"-","/":"/","=":"=","`":"`","\u0085":"…","\u00a0":" ","\u2028":"
","\u2029":"
"};function Of(a){return Pf[a]}var Nf=/[\x00\x22\x26\x27\x3c\x3e]/g;function Qf(){var a={lang:td,gJ:vd},c='

'+((a.gJ?'':'')+"Technothlon Games : "+Z("Pond")+"");if(a.level){for(var d="   ",e=a.BJ+1,f=1;f'+Z(f)+"":f==a.BJ?''+Z(f)+"":'":">","\t":" ","\n":" ","\x0B":" ","\f":" ","\r":" "," ":" ","-":"-","/":"/","=":"=","`":"`","\u0085":"…","\u00a0":" ","\u2028":"
","\u2029":"
"};function Of(a){return Pf[a]}var Nf=/[\x00\x22\x26\x27\x3c\x3e]/g;function Qf(){var a={lang:td,gJ:vd},c='

'+((a.gJ?'':'')+"Technothlon Games : "+Z("Pond")+"");if(a.level){for(var d="   ",e=a.BJ+1,f=1;f'+Z(f)+"":f==a.BJ?''+Z(f)+"":'')}a=d}else a="";return'
Technothlon GamesPuzzleMazeBirdTurtleMovieMusicPond TutorPondGeneticsYou solved this level with 1 line of JavaScript:You solved this level with %1 lines of JavaScript:Are you ready for level %1?Are you ready for the next challenge?Title:Save and link to blocks.Run the program you wrote.Run ProgramStop the program and reset the level.ResetHelpLogicLoopsMathTextListsColourVariablesFunctionsThere was a problem with the request.Share your blocks with this link:\\n\\n%1Sorry, \'%1\' doesn\'t correspond with any saved program.Could not load your saved file. Perhaps it was created with a different version of Blockly?Thank you for this program! If our staff of trained monkeys like it, they will publish it to the gallery within a couple of days.listtextOnce you start editing JavaScript, you can\'t go back to editing blocks. Is this OK?Blocks
Scan for enemies. Specify a direction (0-360). Returns the distance to the closest enemy in that direction. Returns Infinity if no enemy found.Fire the cannon. Specify a direction (0-360) and a range (0-70).Swim forward. Specify a direction (0-360).Stop swimming. Player will slow to a stop.Returns the player\'s current health (0 is dead, 100 is healthy).Returns the current speed of the player (0 is stopped, 100 is full speed).Returns the X coordinate of the player (0 is the left edge, 100 is the right edge).Returns the Y coordinate of the player (0 is the bottom edge, 100 is the top edge).Prints a number to your browser\'s console.
Player
'+ (c+a+'

Blocks
JavaScript
07000123119
')} ;var Ed="pond-duck",Rf=null,Sf=!0,Tf=U=null; diff --git a/appengine/pond/tutor/generated/en/compressed.js b/appengine/pond/tutor/generated/en/compressed.js index a27cb2d..9540471 100644 --- a/appengine/pond/tutor/generated/en/compressed.js +++ b/appengine/pond/tutor/generated/en/compressed.js @@ -568,7 +568,7 @@ h.i.VARIABLES_HUE="330";h.i.PROCEDURES_HUE="290";var BlocklyStorage={},Cd=null,D function Gd(a,c){Id["/storage"]&&Id["/storage"].abort();Id["/storage"]=new XMLHttpRequest;Id["/storage"].onload=function(){200===this.status?c&&c.call(this):Jd(S("Games_httpRequestError")+"\nXHR status: "+this.status);Id["/storage"]=null};Id["/storage"].open("POST","/storage");Id["/storage"].setRequestHeader("Content-Type","application/x-www-form-urlencoded");Id["/storage"].send(a)} function Hd(){window.location.hash=this.responseText.trim();Jd(S("Games_linkAlert").replace("%1",window.location.href));Ed=Cd()}function Kd(){var a=this.responseText.trim();a.length?Dd(a):Jd(S("Games_hashError").replace("%1",window.location.hash));Ed=Cd()}function Jd(a){if("object"===typeof T){var c=document.getElementById("linkButton");T.EK(c,a)}else alert(a)};var w=null,Ld=null,Md=!1,Nd="",Od="";function Pd(){wd();var a=document.getElementById("linkButton");a&&(rd?a.style.display="none":(Cd=Qd,Dd=Rd,Ad(a,Fd)));(a=document.getElementById("languageMenu"))&&a.addEventListener("change",Sd,!0)}function Td(a){if(!rd&&1=c.length?"?lang="+a:/[?&]lang=[^&]*/.test(c)?c.replace(/([?&]lang=)[^&]*/,"$1"+a):c.replace(/\?/,"?lang="+a+"&");window.location=window.location.protocol+"//"+window.location.host+window.location.pathname+c} function Xd(){10>R?window.location=window.location.protocol+"//"+window.location.host+window.location.pathname+"?lang="+pd+"&level="+(R+1):Wd()}function Yd(a){a=a.replace(/(,\s*)?'block_id_[^']+'\)/g,")");return a.replace(/\s+$/,"")}function Zd(a){if("click"==a.type&&"touchend"==$d&&ae+2E3>Date.now()||$d==a.type&&ae+400>Date.now())return a.preventDefault(),a.stopPropagation(),!0;$d=a.type;ae=Date.now();return!1}var $d=null,ae=0; function be(){setTimeout(function(){var a=document.createElement("script");a.type="text/javascript";a.src="third-party/JS-Interpreter/compressed.js";document.head.appendChild(a)},1)}function ce(){setTimeout(function(){var a=document.createElement("link");a.rel="stylesheet";a.type="text/css";a.href="common/prettify.css";document.head.appendChild(a);a=document.createElement("script");a.type="text/javascript";a.src="common/prettify.js";document.head.appendChild(a)},1)};function de(){setTimeout(function(){var a=document.createElement("script");a.type="text/javascript";a.src="third-party/babel.min.js";document.head.appendChild(a)},1)}function ee(){var a=window.ace;a.require("ace/ext/language_tools");Ld=a=a.edit("editor");a.setTheme("ace/theme/chrome");a.setShowPrintMargin(!1);a.setOptions({enableBasicAutocompletion:!0,enableLiveAutocompletion:!0});a=a.getSession();a.setMode("ace/mode/javascript");a.setTabSize(2);a.setUseSoftTabs(!0);a.on("change",Ud);fe()} @@ -890,7 +890,7 @@ ABS:h.i.MATH_SINGLE_TOOLTIP_ABS,SIN:h.i.MATH_TRIG_TOOLTIP_SIN,COS:h.i.MATH_TRIG_ h.j.pond_math_single=function(a){var c=C(a,"OP");a=X(h.j,a,"NUM",h.j.fb)||"0";switch(c){case "ABS":c="Math.abs("+a+")";break;case "ROOT":c="Math.sqrt("+a+")";break;case "SIN":c="Math.sin_deg("+a+")";break;case "COS":c="Math.cos_deg("+a+")";break;case "TAN":c="Math.tan_deg("+a+")";break;case "ASIN":c="Math.asin_deg("+a+")";break;case "ACOS":c="Math.acos_deg("+a+")";break;case "ATAN":c="Math.atan_deg("+a+")";break;default:throw Error("Unknown math operator: "+c);}return[c,h.j.ub]}; h.j.pond_math_number=h.j.math_number;h.N.pond_loc_x=h.N.pond_getX;h.j.pond_loc_x=h.j.pond_getX;h.N.pond_loc_y=h.N.pond_getY;h.j.pond_loc_y=h.j.pond_getY;h.N.pond_controls_if=h.N.controls_if;h.j.pond_controls_if=h.j.controls_if;h.N.pond_loops_while=h.N.controls_whileUntil;h.j.pond_loops_while=h.j.controls_whileUntil;h.N.pond_math_arithmetic=h.N.math_arithmetic;h.j.pond_math_arithmetic=h.j.math_arithmetic;h.N.pond_math_change=h.N.math_change;h.j.pond_math_change=h.j.math_change;var Af=Af||{};function Bf(a,c){function d(){}d.prototype=c.prototype;a.v=c.prototype;a.prototype=new d;a.prototype.constructor=a;a.tO=function(e,f,g){return c.prototype[f].apply(e,Array.prototype.slice.call(arguments,2))}}if(!Cf){var Cf,Df="";"undefined"!==typeof navigator&&navigator&&"string"==typeof navigator.userAgent&&(Df=navigator.userAgent);var Ef=0==Df.indexOf("Opera");Cf={UO:{fM:"ScriptEngine"in window},qN:Ef,af:!Ef&&-1!=Df.indexOf("MSIE"),iA:!Ef&&-1!=Df.indexOf("WebKit")}}if(!Ff)var Ff={}; if(!Gf)var Gf={};if(!Hf)var Hf={};if(!If)var If={};if(!Jf)var Jf={};if(!Kf)var Kf={};var Lf=Af.yL?{aP:!0}:{};function Mf(){throw Error("Do not instantiate directly");}Mf.prototype.SA=null;Mf.prototype.toString=function(){return this.content};function Nf(a){if(null!=a)switch(a.SA){case 1:return 1;case -1:return-1;case 0:return 0}return null}function Of(){Mf.call(this)}Bf(Of,Mf);Of.prototype.uH=Lf;function Z(a){return null!=a&&a.uH===Lf?a:Pf(String(String(a)).replace(Qf,Rf),Nf(a))} -var Pf=function(a){function c(){}c.prototype=a.prototype;return function(d,e){var f=new c;f.content=String(d);void 0!==e&&(f.SA=e);return f}}(Of),Sf={"\x00":"�",'"':""","&":"&","'":"'","<":"<",">":">","\t":" ","\n":" ","\x0B":" ","\f":" ","\r":" "," ":" ","-":"-","/":"/","=":"=","`":"`","\u0085":"…","\u00a0":" ","\u2028":"
","\u2029":"
"};function Rf(a){return Sf[a]}var Qf=/[\x00\x22\x26\x27\x3c\x3e]/g;function Tf(){return'
'};function Uf(){var a='

'+((rd?'':'')+"Technothlon Games : "+Z("Pond Tutor")+"");if(R){var c="   ";for(var d=1;11>d;d++){var e="?lang="+Z(pd)+"&level="+Z(d);c+=" "+(d==R?''+Z(d)+"":10==d?''+Z(d)+"":'":">","\t":" ","\n":" ","\x0B":" ","\f":" ","\r":" "," ":" ","-":"-","/":"/","=":"=","`":"`","\u0085":"…","\u00a0":" ","\u2028":"
","\u2029":"
"};function Rf(a){return Sf[a]}var Qf=/[\x00\x22\x26\x27\x3c\x3e]/g;function Tf(){return'
'};function Uf(){var a='

'+((rd?'':'')+"Technothlon Games : "+Z("Pond Tutor")+"");if(R){var c="   ";for(var d=1;11>d;d++){var e="?lang="+Z(pd)+"&level="+Z(d);c+=" "+(d==R?''+Z(d)+"":10==d?''+Z(d)+"":'')}}else c="";a='
Technothlon GamesPuzzleMazeBirdTurtleMovieMusicPond TutorPondGeneticsYou solved this level with 1 line of JavaScript:You solved this level with %1 lines of JavaScript:Are you ready for level %1?Are you ready for the next challenge?Title:Save and link to blocks.Run the program you wrote.Run ProgramStop the program and reset the level.ResetHelpLogicLoopsMathTextListsColourVariablesFunctionsThere was a problem with the request.Share your blocks with this link:\\n\\n%1Sorry, \'%1\' doesn\'t correspond with any saved program.Could not load your saved file. Perhaps it was created with a different version of Blockly?Thank you for this program! If our staff of trained monkeys like it, they will publish it to the gallery within a couple of days.listtextOnce you start editing JavaScript, you can\'t go back to editing blocks. Is this OK?Blocks
Scan for enemies. Specify a direction (0-360). Returns the distance to the closest enemy in that direction. Returns Infinity if no enemy found.Fire the cannon. Specify a direction (0-360) and a range (0-70).Swim forward. Specify a direction (0-360).Stop swimming. Player will slow to a stop.Returns the player\'s current health (0 is dead, 100 is healthy).Returns the current speed of the player (0 is stopped, 100 is full speed).Returns the X coordinate of the player (0 is the left edge, 100 is the right edge).Returns the Y coordinate of the player (0 is the bottom edge, 100 is the top edge).Prints a number to your browser\'s console.
PlayerTargetPendulumScared
'+ (a+c+'

  
'); switch(R){case 1:case 3:case 5:case 7:case 9:a+='070'+(5<=R?'0': diff --git a/appengine/puzzle/generated/en/compressed.js b/appengine/puzzle/generated/en/compressed.js index b1e92cd..ea93013 100644 --- a/appengine/puzzle/generated/en/compressed.js +++ b/appengine/puzzle/generated/en/compressed.js @@ -518,7 +518,7 @@ b.Fw=function(a){a?(this.ub.setAttribute("filter","url(#"+this.ab.$m+")"),this.e h.L.DUPLICATE_BLOCK="Duplicate";h.L.DUPLICATE_COMMENT="Duplicate Comment";h.L.ENABLE_BLOCK="Enable Block";h.L.EXPAND_ALL="Expand Blocks";h.L.EXPAND_BLOCK="Expand Block";h.L.EXTERNAL_INPUTS="External Inputs";h.L.HELP="Help";h.L.INLINE_INPUTS="Inline Inputs";h.L.NEW_VARIABLE="Create variable...";h.L.NEW_VARIABLE_TITLE="New variable name:";h.L.PROCEDURES_DEFNORETURN_PROCEDURE="do something";h.L.REDO="Redo";h.L.REMOVE_COMMENT="Remove Comment";h.L.RENAME_VARIABLE="Rename variable..."; h.L.RENAME_VARIABLE_TITLE="Rename all '%1' variables to:";h.L.UNDO="Undo";h.L.UNNAMED_KEY="unnamed";h.L.VARIABLE_ALREADY_EXISTS="A variable named '%1' already exists.";h.L.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE="A variable named '%1' already exists for another type: '%2'.";h.L.WORKSPACE_ARIA_LABEL="Blockly Workspace";h.L.WORKSPACE_COMMENT_DEFAULT_TEXT="Say something...";h.L.PROCEDURES_DEFRETURN_PROCEDURE=h.L.PROCEDURES_DEFNORETURN_PROCEDURE;var BlocklyStorage={},gd=null,hd=null;function id(){var a=gd();jd("xml="+encodeURIComponent(a))}var X={};function jd(a){var c=ld;X["/storage"]&&X["/storage"].abort();X["/storage"]=new XMLHttpRequest;X["/storage"].onload=function(){200===this.status?c&&c.call(this):md(V("Games_httpRequestError")+"\nXHR status: "+this.status);X["/storage"]=null};X["/storage"].open("POST","/storage");X["/storage"].setRequestHeader("Content-Type","application/x-www-form-urlencoded");X["/storage"].send(a)} function ld(){window.location.hash=this.responseText.trim();md(V("Games_linkAlert").replace("%1",window.location.href));hd=gd()}function md(a){if("object"===typeof Y){var c=document.getElementById("linkButton");Y.eD(c,a)}else alert(a)};var y=null,nd="";function od(){Hc();var a=document.getElementById("linkButton");a&&(Bc?a.style.display="none":(gd=pd,Mc(a,id)));(a=document.getElementById("languageMenu"))&&a.addEventListener("change",qd,!0)}function pd(){var a=h.I.tD();if(1==y.fc(!1).length&&a.querySelector){var c=a.querySelector("block");c&&(c.removeAttribute("x"),c.removeAttribute("y"))}return h.I.Be(a)}function rd(){"object"==typeof BlocklyStorage&&null!==hd&&hd!=pd()&&(window.location.hash="",hd=null)} -function sd(a){var c=document.getElementById("toolbox");c&&(a.toolbox=c);a.media="third-party/blockly/media/";a.oneBasedIndex=!1;y=h.rg("blockly",a);y.xf.push(rd)}function td(){window.location=(Bc?"index.html":"./")+"?lang="+zc} +function sd(a){var c=document.getElementById("toolbox");c&&(a.toolbox=c);a.media="third-party/blockly/media/";a.oneBasedIndex=!1;y=h.rg("blockly",a);y.xf.push(rd)}function td(){window.location=(Bc?"Home.html":"./")+"?lang="+zc} function qd(){window.sessionStorage&&(window.sessionStorage.Bv=pd());var a=document.getElementById("languageMenu");a=encodeURIComponent(a.options[a.selectedIndex].value);var c=window.location.search;c=1>=c.length?"?lang="+a:/[?&]lang=[^&]*/.test(c)?c.replace(/([?&]lang=)[^&]*/,"$1"+a):c.replace(/\?/,"?lang="+a+"&");window.location=window.location.protocol+"//"+window.location.host+window.location.pathname+c} function ud(){10>U?window.location=window.location.protocol+"//"+window.location.host+window.location.pathname+"?lang="+zc+"&level="+(U+1):td()}function vd(){var a="".replace(/(,\s*)?'block_id_[^']+'\)/g,")");return a.replace(/\s+$/,"")};var Y={vf:!1,xu:null,Sm:null,Cl:function(a,c,d,e,f,g){function k(){if(Y.vf){l.style.visibility="visible";l.style.zIndex=10;m.style.visibility="hidden";var q=a.getElementsByClassName("primary");q.length||(q=a.getElementsByClassName("secondary"),q.length||(q=a.getElementsByTagName("button")));q.length&&q[0].focus()}}if(!a)throw TypeError("Content not found: "+a);Y.vf&&Y.Dh(!1);h.yh()&&h.hc(!0);Y.vf=!0;Y.xu=c;Y.Sm=g;var l=document.getElementById("dialog");g=document.getElementById("dialogShadow");var m= document.getElementById("dialogBorder"),n;for(n in f)l.style[n]=f[n];e&&(g.style.visibility="visible",g.style.opacity=.3,g.style.zIndex=9,e=document.createElement("div"),e.id="dialogHeader",l.appendChild(e),Y.Mp=h.mp(e,"mousedown",null,Y.pA));f=a.getElementsByClassName("dialogOk");for(e=0;e":">","\t":" ","\n":" ","\x0B":" ","\f":" ","\r":" "," ":" ","-":"-","/":"/","=":"=","`":"`","\u0085":"…","\u00a0":" ","\u2028":"
","\u2029":"
"}; -function Od(a){return Pd[a]}var Nd=/[\x00\x22\x26\x27\x3c\x3e]/g;function Qd(){return'
'};function Rd(){var a={lang:zc,nB:Bc},c='

'+((a.nB?'':'')+"Technothlon Games : "+Z("Puzzle")+"");if(a.level){for(var d="   ",e=a.IB+1,f=1;f'+Z(f)+"":f==a.IB?''+Z(f)+"":''};function Rd(){var a={lang:zc,nB:Bc},c='

'+((a.nB?'':'')+"Technothlon Games : "+Z("Puzzle")+"");if(a.level){for(var d="   ",e=a.IB+1,f=1;f'+Z(f)+"":f==a.IB?''+Z(f)+"":'')}a=d}else a="";return'
Duckduck.jpg70100  2  FeathersBeakhttps://en.wikipedia.org/wiki/DuckCatcat.jpg70100  4  WhiskersFurhttps://en.wikipedia.org/wiki/CatBeebee.jpg70100  6  HoneyStingerhttps://en.wikipedia.org/wiki/BeeSnailsnail.jpg70100  0  ShellSlimehttps://en.wikipedia.org/wiki/Snailpicture:legs:choose...traits:Perfect!\\nAll %1 blocks are correct.Almost! One block is incorrect.%1 blocks are incorrect.The highlighted block is not correct.\\nKeep trying.
'+ (c+a+'

  '+(''.qu===Id?"zSoyz":'')+'
For each animal (green), attach its picture, choose its number of legs, and make a stack of its traits.
')+ Qd()+'
'+Qd()+"
"};h.cb=function(a,c,d){"function"!=typeof a&&h.cb.Jw(a);this.dl=a;this.$r=this.Br=this.cn=null;a=this.dl;if(Array.isArray(a)){for(var e=!1,f=0;fa.length)){e=[];for(f=0;f {if $ij.html} -
+ {else} {/if} diff --git a/appengine/third-party/JS-Interpreter/docs.html b/appengine/third-party/JS-Interpreter/docs.html index f1cf8de..214d76a 100644 --- a/appengine/third-party/JS-Interpreter/docs.html +++ b/appengine/third-party/JS-Interpreter/docs.html @@ -15,7 +15,7 @@

JS-Interpreter Documentation

instances of the JS-Interpreter allow for multi-threaded concurrent JavaScript without the use of Web Workers.

-

Play with the JS-Interpreter demo.

+

Play with the JS-Interpreter demo.

Get the source code.

diff --git a/appengine/third-party/ace/snippets/ruby.js b/appengine/third-party/ace/snippets/ruby.js index 866688f..087a4e7 100644 --- a/appengine/third-party/ace/snippets/ruby.js +++ b/appengine/third-party/ace/snippets/ruby.js @@ -1,4 +1,4 @@ -ace.define("ace/snippets/ruby",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='########################################\n# Ruby snippets - for Rails, see below #\n########################################\n\n# encoding for Ruby 1.9\nsnippet enc\n # encoding: utf-8\n\n# #!/usr/bin/env ruby\nsnippet #!\n #!/usr/bin/env ruby\n # encoding: utf-8\n\n# New Block\nsnippet =b\n =begin rdoc\n ${1}\n =end\nsnippet y\n :yields: ${1:arguments}\nsnippet rb\n #!/usr/bin/env ruby -wKU\nsnippet beg\n begin\n ${3}\n rescue ${1:Exception} => ${2:e}\n end\n\nsnippet req require\n require "${1}"${2}\nsnippet #\n # =>\nsnippet end\n __END__\nsnippet case\n case ${1:object}\n when ${2:condition}\n ${3}\n end\nsnippet when\n when ${1:condition}\n ${2}\nsnippet def\n def ${1:method_name}\n ${2}\n end\nsnippet deft\n def test_${1:case_name}\n ${2}\n end\nsnippet if\n if ${1:condition}\n ${2}\n end\nsnippet ife\n if ${1:condition}\n ${2}\n else\n ${3}\n end\nsnippet elsif\n elsif ${1:condition}\n ${2}\nsnippet unless\n unless ${1:condition}\n ${2}\n end\nsnippet while\n while ${1:condition}\n ${2}\n end\nsnippet for\n for ${1:e} in ${2:c}\n ${3}\n end\nsnippet until\n until ${1:condition}\n ${2}\n end\nsnippet cla class .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n ${2}\n end\nsnippet cla class .. initialize .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n def initialize(${2:args})\n ${3}\n end\n end\nsnippet cla class .. < ParentClass .. initialize .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} < ${2:ParentClass}\n def initialize(${3:args})\n ${4}\n end\n end\nsnippet cla ClassName = Struct .. do .. end\n ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} = Struct.new(:${2:attr_names}) do\n def ${3:method_name}\n ${4}\n end\n end\nsnippet cla class BlankSlate .. initialize .. end\n class ${1:BlankSlate}\n instance_methods.each { |meth| undef_method(meth) unless meth =~ /\\A__/ }\n end\nsnippet cla class << self .. end\n class << ${1:self}\n ${2}\n end\n# class .. < DelegateClass .. initialize .. end\nsnippet cla-\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} < DelegateClass(${2:ParentClass})\n def initialize(${3:args})\n super(${4:del_obj})\n\n ${5}\n end\n end\nsnippet mod module .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n ${2}\n end\nsnippet mod module .. module_function .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n module_function\n\n ${2}\n end\nsnippet mod module .. ClassMethods .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n module ClassMethods\n ${2}\n end\n\n module InstanceMethods\n\n end\n\n def self.included(receiver)\n receiver.extend ClassMethods\n receiver.send :include, InstanceMethods\n end\n end\n# attr_reader\nsnippet r\n attr_reader :${1:attr_names}\n# attr_writer\nsnippet w\n attr_writer :${1:attr_names}\n# attr_accessor\nsnippet rw\n attr_accessor :${1:attr_names}\nsnippet atp\n attr_protected :${1:attr_names}\nsnippet ata\n attr_accessible :${1:attr_names}\n# include Enumerable\nsnippet Enum\n include Enumerable\n\n def each(&block)\n ${1}\n end\n# include Comparable\nsnippet Comp\n include Comparable\n\n def <=>(other)\n ${1}\n end\n# extend Forwardable\nsnippet Forw-\n extend Forwardable\n# def self\nsnippet defs\n def self.${1:class_method_name}\n ${2}\n end\n# def method_missing\nsnippet defmm\n def method_missing(meth, *args, &blk)\n ${1}\n end\nsnippet defd\n def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}\nsnippet defds\n def_delegators :${1:@del_obj}, :${2:del_methods}\nsnippet am\n alias_method :${1:new_name}, :${2:old_name}\nsnippet app\n if __FILE__ == $PROGRAM_NAME\n ${1}\n end\n# usage_if()\nsnippet usai\n if ARGV.${1}\n abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n end\n# usage_unless()\nsnippet usau\n unless ARGV.${1}\n abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n end\nsnippet array\n Array.new(${1:10}) { |${2:i}| ${3} }\nsnippet hash\n Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} }\nsnippet file File.foreach() { |line| .. }\n File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} }\nsnippet file File.read()\n File.read(${1:"path/to/file"})${2}\nsnippet Dir Dir.global() { |file| .. }\n Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} }\nsnippet Dir Dir[".."]\n Dir[${1:"glob/**/*.rb"}]${2}\nsnippet dir\n Filename.dirname(__FILE__)\nsnippet deli\n delete_if { |${1:e}| ${2} }\nsnippet fil\n fill(${1:range}) { |${2:i}| ${3} }\n# flatten_once()\nsnippet flao\n inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3}\nsnippet zip\n zip(${1:enums}) { |${2:row}| ${3} }\n# downto(0) { |n| .. }\nsnippet dow\n downto(${1:0}) { |${2:n}| ${3} }\nsnippet ste\n step(${1:2}) { |${2:n}| ${3} }\nsnippet tim\n times { |${1:n}| ${2} }\nsnippet upt\n upto(${1:1.0/0.0}) { |${2:n}| ${3} }\nsnippet loo\n loop { ${1} }\nsnippet ea\n each { |${1:e}| ${2} }\nsnippet ead\n each do |${1:e}|\n ${2}\n end\nsnippet eab\n each_byte { |${1:byte}| ${2} }\nsnippet eac- each_char { |chr| .. }\n each_char { |${1:chr}| ${2} }\nsnippet eac- each_cons(..) { |group| .. }\n each_cons(${1:2}) { |${2:group}| ${3} }\nsnippet eai\n each_index { |${1:i}| ${2} }\nsnippet eaid\n each_index do |${1:i}|\n ${2}\n end\nsnippet eak\n each_key { |${1:key}| ${2} }\nsnippet eakd\n each_key do |${1:key}|\n ${2}\n end\nsnippet eal\n each_line { |${1:line}| ${2} }\nsnippet eald\n each_line do |${1:line}|\n ${2}\n end\nsnippet eap\n each_pair { |${1:name}, ${2:val}| ${3} }\nsnippet eapd\n each_pair do |${1:name}, ${2:val}|\n ${3}\n end\nsnippet eas-\n each_slice(${1:2}) { |${2:group}| ${3} }\nsnippet easd-\n each_slice(${1:2}) do |${2:group}|\n ${3}\n end\nsnippet eav\n each_value { |${1:val}| ${2} }\nsnippet eavd\n each_value do |${1:val}|\n ${2}\n end\nsnippet eawi\n each_with_index { |${1:e}, ${2:i}| ${3} }\nsnippet eawid\n each_with_index do |${1:e},${2:i}|\n ${3}\n end\nsnippet reve\n reverse_each { |${1:e}| ${2} }\nsnippet reved\n reverse_each do |${1:e}|\n ${2}\n end\nsnippet inj\n inject(${1:init}) { |${2:mem}, ${3:var}| ${4} }\nsnippet injd\n inject(${1:init}) do |${2:mem}, ${3:var}|\n ${4}\n end\nsnippet map\n map { |${1:e}| ${2} }\nsnippet mapd\n map do |${1:e}|\n ${2}\n end\nsnippet mapwi-\n enum_with_index.map { |${1:e}, ${2:i}| ${3} }\nsnippet sor\n sort { |a, b| ${1} }\nsnippet sorb\n sort_by { |${1:e}| ${2} }\nsnippet ran\n sort_by { rand }\nsnippet all\n all? { |${1:e}| ${2} }\nsnippet any\n any? { |${1:e}| ${2} }\nsnippet cl\n classify { |${1:e}| ${2} }\nsnippet col\n collect { |${1:e}| ${2} }\nsnippet cold\n collect do |${1:e}|\n ${2}\n end\nsnippet det\n detect { |${1:e}| ${2} }\nsnippet detd\n detect do |${1:e}|\n ${2}\n end\nsnippet fet\n fetch(${1:name}) { |${2:key}| ${3} }\nsnippet fin\n find { |${1:e}| ${2} }\nsnippet find\n find do |${1:e}|\n ${2}\n end\nsnippet fina\n find_all { |${1:e}| ${2} }\nsnippet finad\n find_all do |${1:e}|\n ${2}\n end\nsnippet gre\n grep(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet sub\n ${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} }\nsnippet sca\n scan(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet scad\n scan(${1:/pattern/}) do |${2:match}|\n ${3}\n end\nsnippet max\n max { |a, b| ${1} }\nsnippet min\n min { |a, b| ${1} }\nsnippet par\n partition { |${1:e}| ${2} }\nsnippet pard\n partition do |${1:e}|\n ${2}\n end\nsnippet rej\n reject { |${1:e}| ${2} }\nsnippet rejd\n reject do |${1:e}|\n ${2}\n end\nsnippet sel\n select { |${1:e}| ${2} }\nsnippet seld\n select do |${1:e}|\n ${2}\n end\nsnippet lam\n lambda { |${1:args}| ${2} }\nsnippet doo\n do\n ${1}\n end\nsnippet dov\n do |${1:variable}|\n ${2}\n end\nsnippet :\n :${1:key} => ${2:"value"}${3}\nsnippet ope\n open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} }\n# path_from_here()\nsnippet fpath\n File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2}\n# unix_filter {}\nsnippet unif\n ARGF.each_line${1} do |${2:line}|\n ${3}\n end\n# option_parse {}\nsnippet optp\n require "optparse"\n\n options = {${1:default => "args"}}\n\n ARGV.options do |opts|\n opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}\nsnippet opt\n opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String},\n "${4:Option description.}") do |${5:opt}|\n ${6}\n end\nsnippet tc\n require "test/unit"\n\n require "${1:library_file_name}"\n\n class Test${2:$1} < Test::Unit::TestCase\n def test_${3:case_name}\n ${4}\n end\n end\nsnippet ts\n require "test/unit"\n\n require "tc_${1:test_case_file}"\n require "tc_${2:test_case_file}"${3}\nsnippet as\n assert ${1:test}, "${2:Failure message.}"${3}\nsnippet ase\n assert_equal ${1:expected}, ${2:actual}${3}\nsnippet asne\n assert_not_equal ${1:unexpected}, ${2:actual}${3}\nsnippet asid\n assert_in_delta ${1:expected_float}, ${2:actual_float}, ${3:2 ** -20}${4}\nsnippet asio\n assert_instance_of ${1:ExpectedClass}, ${2:actual_instance}${3}\nsnippet asko\n assert_kind_of ${1:ExpectedKind}, ${2:actual_instance}${3}\nsnippet asn\n assert_nil ${1:instance}${2}\nsnippet asnn\n assert_not_nil ${1:instance}${2}\nsnippet asm\n assert_match /${1:expected_pattern}/, ${2:actual_string}${3}\nsnippet asnm\n assert_no_match /${1:unexpected_pattern}/, ${2:actual_string}${3}\nsnippet aso\n assert_operator ${1:left}, :${2:operator}, ${3:right}${4}\nsnippet asr\n assert_raise ${1:Exception} { ${2} }\nsnippet asrd\n assert_raise ${1:Exception} do\n ${2}\n end\nsnippet asnr\n assert_nothing_raised ${1:Exception} { ${2} }\nsnippet asnrd\n assert_nothing_raised ${1:Exception} do\n ${2}\n end\nsnippet asrt\n assert_respond_to ${1:object}, :${2:method}${3}\nsnippet ass assert_same(..)\n assert_same ${1:expected}, ${2:actual}${3}\nsnippet ass assert_send(..)\n assert_send [${1:object}, :${2:message}, ${3:args}]${4}\nsnippet asns\n assert_not_same ${1:unexpected}, ${2:actual}${3}\nsnippet ast\n assert_throws :${1:expected} { ${2} }\nsnippet astd\n assert_throws :${1:expected} do\n ${2}\n end\nsnippet asnt\n assert_nothing_thrown { ${1} }\nsnippet asntd\n assert_nothing_thrown do\n ${1}\n end\nsnippet fl\n flunk "${1:Failure message.}"${2}\n# Benchmark.bmbm do .. end\nsnippet bm-\n TESTS = ${1:10_000}\n Benchmark.bmbm do |results|\n ${2}\n end\nsnippet rep\n results.report("${1:name}:") { TESTS.times { ${2} }}\n# Marshal.dump(.., file)\nsnippet Md\n File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4}\n# Mashal.load(obj)\nsnippet Ml\n File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3}\n# deep_copy(..)\nsnippet deec\n Marshal.load(Marshal.dump(${1:obj_to_copy}))${2}\nsnippet Pn-\n PStore.new(${1:"file_name.pstore"})${2}\nsnippet tra\n transaction(${1:true}) { ${2} }\n# xmlread(..)\nsnippet xml-\n REXML::Document.new(File.read(${1:"path/to/file"}))${2}\n# xpath(..) { .. }\nsnippet xpa\n elements.each(${1:"//Xpath"}) do |${2:node}|\n ${3}\n end\n# class_from_name()\nsnippet clafn\n split("::").inject(Object) { |par, const| par.const_get(const) }\n# singleton_class()\nsnippet sinc\n class << self; self end\nsnippet nam\n namespace :${1:`Filename()`} do\n ${2}\n end\nsnippet tas\n desc "${1:Task description}"\n task :${2:task_name => [:dependent, :tasks]} do\n ${3}\n end\n# block\nsnippet b\n { |${1:var}| ${2} }\nsnippet begin\n begin\n raise \'A test exception.\'\n rescue Exception => e\n puts e.message\n puts e.backtrace.inspect\n else\n # other exception\n ensure\n # always executed\n end\n\n#debugging\nsnippet debug\n require \'ruby-debug\'; debugger; true;\nsnippet pry\n require \'pry\'; binding.pry\n\n#############################################\n# Rails snippets - for pure Ruby, see above #\n#############################################\nsnippet art\n assert_redirected_to ${1::action => "${2:index}"}\nsnippet artnp\n assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}, ${4:@$2})\nsnippet artnpp\n assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1})\nsnippet artp\n assert_redirected_to ${1:model}_path(${2:@$1})\nsnippet artpp\n assert_redirected_to ${1:model}s_path\nsnippet asd\n assert_difference "${1:Model}.${2:count}", $1 do\n ${3}\n end\nsnippet asnd\n assert_no_difference "${1:Model}.${2:count}" do\n ${3}\n end\nsnippet asre\n assert_response :${1:success}, @response.body${2}\nsnippet asrj\n assert_rjs :${1:replace}, "${2:dom id}"\nsnippet ass assert_select(..)\n assert_select \'${1:path}\', :${2:text} => \'${3:inner_html\' ${4:do}\nsnippet bf\n before_filter :${1:method}\nsnippet bt\n belongs_to :${1:association}\nsnippet crw\n cattr_accessor :${1:attr_names}\nsnippet defcreate\n def create\n @${1:model_class_name} = ${2:ModelClassName}.new(params[:$1])\n\n respond_to do |wants|\n if @$1.save\n flash[:notice] = \'$2 was successfully created.\'\n wants.html { redirect_to(@$1) }\n wants.xml { render :xml => @$1, :status => :created, :location => @$1 }\n else\n wants.html { render :action => "new" }\n wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity }\n end\n end\n end${3}\nsnippet defdestroy\n def destroy\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n @$1.destroy\n\n respond_to do |wants|\n wants.html { redirect_to($1s_url) }\n wants.xml { head :ok }\n end\n end${3}\nsnippet defedit\n def edit\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n end\nsnippet defindex\n def index\n @${1:model_class_name} = ${2:ModelClassName}.all\n\n respond_to do |wants|\n wants.html # index.html.erb\n wants.xml { render :xml => @$1s }\n end\n end${3}\nsnippet defnew\n def new\n @${1:model_class_name} = ${2:ModelClassName}.new\n\n respond_to do |wants|\n wants.html # new.html.erb\n wants.xml { render :xml => @$1 }\n end\n end${3}\nsnippet defshow\n def show\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n respond_to do |wants|\n wants.html # show.html.erb\n wants.xml { render :xml => @$1 }\n end\n end${3}\nsnippet defupdate\n def update\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n respond_to do |wants|\n if @$1.update_attributes(params[:$1])\n flash[:notice] = \'$2 was successfully updated.\'\n wants.html { redirect_to(@$1) }\n wants.xml { head :ok }\n else\n wants.html { render :action => "edit" }\n wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity }\n end\n end\n end${3}\nsnippet flash\n flash[:${1:notice}] = "${2}"\nsnippet habtm\n has_and_belongs_to_many :${1:object}, :join_table => "${2:table_name}", :foreign_key => "${3}_id"${4}\nsnippet hm\n has_many :${1:object}\nsnippet hmd\n has_many :${1:other}s, :class_name => "${2:$1}", :foreign_key => "${3:$1}_id", :dependent => :destroy${4}\nsnippet hmt\n has_many :${1:object}, :through => :${2:object}\nsnippet ho\n has_one :${1:object}\nsnippet i18\n I18n.t(\'${1:type.key}\')${2}\nsnippet ist\n <%= image_submit_tag("${1:agree.png}", :id => "${2:id}"${3} %>\nsnippet log\n Rails.logger.${1:debug} ${2}\nsnippet log2\n RAILS_DEFAULT_LOGGER.${1:debug} ${2}\nsnippet logd\n logger.debug { "${1:message}" }${2}\nsnippet loge\n logger.error { "${1:message}" }${2}\nsnippet logf\n logger.fatal { "${1:message}" }${2}\nsnippet logi\n logger.info { "${1:message}" }${2}\nsnippet logw\n logger.warn { "${1:message}" }${2}\nsnippet mapc\n ${1:map}.${2:connect} \'${3:controller/:action/:id}\'\nsnippet mapca\n ${1:map}.catch_all "*${2:anything}", :controller => "${3:default}", :action => "${4:error}"${5}\nsnippet mapr\n ${1:map}.resource :${2:resource}\nsnippet maprs\n ${1:map}.resources :${2:resource}\nsnippet mapwo\n ${1:map}.with_options :${2:controller} => \'${3:thing}\' do |$3|\n ${4}\n end\nsnippet mbs\n before_save :${1:method}\nsnippet mcht\n change_table :${1:table_name} do |t|\n ${2}\n end\nsnippet mp\n map(&:${1:id})\nsnippet mrw\n mattr_accessor :${1:attr_names}\nsnippet oa\n order("${1:field}")\nsnippet od\n order("${1:field} DESC")\nsnippet pa\n params[:${1:id}]${2}\nsnippet ra\n render :action => "${1:action}"\nsnippet ral\n render :action => "${1:action}", :layout => "${2:layoutname}"\nsnippet rest\n respond_to do |wants|\n wants.${1:html} { ${2} }\n end\nsnippet rf\n render :file => "${1:filepath}"\nsnippet rfu\n render :file => "${1:filepath}", :use_full_path => ${2:false}\nsnippet ri\n render :inline => "${1:<%= \'hello\' %>}"\nsnippet ril\n render :inline => "${1:<%= \'hello\' %>}", :locals => { ${2::name} => "${3:value}"${4} }\nsnippet rit\n render :inline => "${1:<%= \'hello\' %>}", :type => ${2::rxml}\nsnippet rjson\n render :json => ${1:text to render}\nsnippet rl\n render :layout => "${1:layoutname}"\nsnippet rn\n render :nothing => ${1:true}\nsnippet rns\n render :nothing => ${1:true}, :status => ${2:401}\nsnippet rp\n render :partial => "${1:item}"\nsnippet rpc\n render :partial => "${1:item}", :collection => ${2:@$1s}\nsnippet rpl\n render :partial => "${1:item}", :locals => { :${2:$1} => ${3:@$1}\nsnippet rpo\n render :partial => "${1:item}", :object => ${2:@$1}\nsnippet rps\n render :partial => "${1:item}", :status => ${2:500}\nsnippet rt\n render :text => "${1:text to render}"\nsnippet rtl\n render :text => "${1:text to render}", :layout => "${2:layoutname}"\nsnippet rtlt\n render :text => "${1:text to render}", :layout => ${2:true}\nsnippet rts\n render :text => "${1:text to render}", :status => ${2:401}\nsnippet ru\n render :update do |${1:page}|\n $1.${2}\n end\nsnippet rxml\n render :xml => ${1:text to render}\nsnippet sc\n scope :${1:name}, :where(:@${2:field} => ${3:value})\nsnippet sl\n scope :${1:name}, lambda do |${2:value}|\n where("${3:field = ?}", ${4:bind var})\n end\nsnippet sha1\n Digest::SHA1.hexdigest(${1:string})\nsnippet sweeper\n class ${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper\n observe $1\n\n def after_save(${2:model_class_name})\n expire_cache($2)\n end\n\n def after_destroy($2)\n expire_cache($2)\n end\n\n def expire_cache($2)\n expire_page\n end\n end\nsnippet tcb\n t.boolean :${1:title}\n ${2}\nsnippet tcbi\n t.binary :${1:title}, :limit => ${2:2}.megabytes\n ${3}\nsnippet tcd\n t.decimal :${1:title}, :precision => ${2:10}, :scale => ${3:2}\n ${4}\nsnippet tcda\n t.date :${1:title}\n ${2}\nsnippet tcdt\n t.datetime :${1:title}\n ${2}\nsnippet tcf\n t.float :${1:title}\n ${2}\nsnippet tch\n t.change :${1:name}, :${2:string}, :${3:limit} => ${4:80}\n ${5}\nsnippet tci\n t.integer :${1:title}\n ${2}\nsnippet tcl\n t.integer :lock_version, :null => false, :default => 0\n ${1}\nsnippet tcr\n t.references :${1:taggable}, :polymorphic => { :default => \'${2:Photo}\' }\n ${3}\nsnippet tcs\n t.string :${1:title}\n ${2}\nsnippet tct\n t.text :${1:title}\n ${2}\nsnippet tcti\n t.time :${1:title}\n ${2}\nsnippet tcts\n t.timestamp :${1:title}\n ${2}\nsnippet tctss\n t.timestamps\n ${1}\nsnippet va\n validates_associated :${1:attribute}\nsnippet vao\n validates_acceptance_of :${1:terms}\nsnippet vc\n validates_confirmation_of :${1:attribute}\nsnippet ve\n validates_exclusion_of :${1:attribute}, :in => ${2:%w( mov avi )}\nsnippet vf\n validates_format_of :${1:attribute}, :with => /${2:regex}/\nsnippet vi\n validates_inclusion_of :${1:attribute}, :in => %w(${2: mov avi })\nsnippet vl\n validates_length_of :${1:attribute}, :within => ${2:3}..${3:20}\nsnippet vn\n validates_numericality_of :${1:attribute}\nsnippet vpo\n validates_presence_of :${1:attribute}\nsnippet vu\n validates_uniqueness_of :${1:attribute}\nsnippet wants\n wants.${1:js|xml|html} { ${2} }\nsnippet wc\n where(${1:"conditions"}${2:, bind_var})\nsnippet wh\n where(${1:field} => ${2:value})\nsnippet xdelete\n xhr :delete, :${1:destroy}, :id => ${2:1}${3}\nsnippet xget\n xhr :get, :${1:show}, :id => ${2:1}${3}\nsnippet xpost\n xhr :post, :${1:create}, :${2:object} => { ${3} }\nsnippet xput\n xhr :put, :${1:update}, :id => ${2:1}, :${3:object} => { ${4} }${5}\nsnippet test\n test "should ${1:do something}" do\n ${2}\n end\n#migrations\nsnippet mac\n add_column :${1:table_name}, :${2:column_name}, :${3:data_type}\nsnippet mrc\n remove_column :${1:table_name}, :${2:column_name}\nsnippet mrnc\n rename_column :${1:table_name}, :${2:old_column_name}, :${3:new_column_name}\nsnippet mcc\n change_column :${1:table}, :${2:column}, :${3:type}\nsnippet mccc\n t.column :${1:title}, :${2:string}\nsnippet mct\n create_table :${1:table_name} do |t|\n t.column :${2:name}, :${3:type}\n end\nsnippet migration\n class ${1:class_name} < ActiveRecord::Migration\n def self.up\n ${2}\n end\n\n def self.down\n end\n end\n\nsnippet trc\n t.remove :${1:column}\nsnippet tre\n t.rename :${1:old_column_name}, :${2:new_column_name}\n ${3}\nsnippet tref\n t.references :${1:model}\n\n#rspec\nsnippet it\n it "${1:spec_name}" do\n ${2}\n end\nsnippet itp\n it "${1:spec_name}"\n ${2}\nsnippet desc\n describe ${1:class_name} do\n ${2}\n end\nsnippet cont\n context "${1:message}" do\n ${2}\n end\nsnippet bef\n before :${1:each} do\n ${2}\n end\nsnippet aft\n after :${1:each} do\n ${2}\n end\n',t.scope="ruby"}); (function() { +ace.define("ace/snippets/ruby",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='########################################\n# Ruby snippets - for Rails, see below #\n########################################\n\n# encoding for Ruby 1.9\nsnippet enc\n # encoding: utf-8\n\n# #!/usr/bin/env ruby\nsnippet #!\n #!/usr/bin/env ruby\n # encoding: utf-8\n\n# New Block\nsnippet =b\n =begin rdoc\n ${1}\n =end\nsnippet y\n :yields: ${1:arguments}\nsnippet rb\n #!/usr/bin/env ruby -wKU\nsnippet beg\n begin\n ${3}\n rescue ${1:Exception} => ${2:e}\n end\n\nsnippet req require\n require "${1}"${2}\nsnippet #\n # =>\nsnippet end\n __END__\nsnippet case\n case ${1:object}\n when ${2:condition}\n ${3}\n end\nsnippet when\n when ${1:condition}\n ${2}\nsnippet def\n def ${1:method_name}\n ${2}\n end\nsnippet deft\n def test_${1:case_name}\n ${2}\n end\nsnippet if\n if ${1:condition}\n ${2}\n end\nsnippet ife\n if ${1:condition}\n ${2}\n else\n ${3}\n end\nsnippet elsif\n elsif ${1:condition}\n ${2}\nsnippet unless\n unless ${1:condition}\n ${2}\n end\nsnippet while\n while ${1:condition}\n ${2}\n end\nsnippet for\n for ${1:e} in ${2:c}\n ${3}\n end\nsnippet until\n until ${1:condition}\n ${2}\n end\nsnippet cla class .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n ${2}\n end\nsnippet cla class .. initialize .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n def initialize(${2:args})\n ${3}\n end\n end\nsnippet cla class .. < ParentClass .. initialize .. end\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} < ${2:ParentClass}\n def initialize(${3:args})\n ${4}\n end\n end\nsnippet cla ClassName = Struct .. do .. end\n ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} = Struct.new(:${2:attr_names}) do\n def ${3:method_name}\n ${4}\n end\n end\nsnippet cla class BlankSlate .. initialize .. end\n class ${1:BlankSlate}\n instance_methods.each { |meth| undef_method(meth) unless meth =~ /\\A__/ }\n end\nsnippet cla class << self .. end\n class << ${1:self}\n ${2}\n end\n# class .. < DelegateClass .. initialize .. end\nsnippet cla-\n class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} < DelegateClass(${2:ParentClass})\n def initialize(${3:args})\n super(${4:del_obj})\n\n ${5}\n end\n end\nsnippet mod module .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n ${2}\n end\nsnippet mod module .. module_function .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n module_function\n\n ${2}\n end\nsnippet mod module .. ClassMethods .. end\n module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n module ClassMethods\n ${2}\n end\n\n module InstanceMethods\n\n end\n\n def self.included(receiver)\n receiver.extend ClassMethods\n receiver.send :include, InstanceMethods\n end\n end\n# attr_reader\nsnippet r\n attr_reader :${1:attr_names}\n# attr_writer\nsnippet w\n attr_writer :${1:attr_names}\n# attr_accessor\nsnippet rw\n attr_accessor :${1:attr_names}\nsnippet atp\n attr_protected :${1:attr_names}\nsnippet ata\n attr_accessible :${1:attr_names}\n# include Enumerable\nsnippet Enum\n include Enumerable\n\n def each(&block)\n ${1}\n end\n# include Comparable\nsnippet Comp\n include Comparable\n\n def <=>(other)\n ${1}\n end\n# extend Forwardable\nsnippet Forw-\n extend Forwardable\n# def self\nsnippet defs\n def self.${1:class_method_name}\n ${2}\n end\n# def method_missing\nsnippet defmm\n def method_missing(meth, *args, &blk)\n ${1}\n end\nsnippet defd\n def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}\nsnippet defds\n def_delegators :${1:@del_obj}, :${2:del_methods}\nsnippet am\n alias_method :${1:new_name}, :${2:old_name}\nsnippet app\n if __FILE__ == $PROGRAM_NAME\n ${1}\n end\n# usage_if()\nsnippet usai\n if ARGV.${1}\n abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n end\n# usage_unless()\nsnippet usau\n unless ARGV.${1}\n abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n end\nsnippet array\n Array.new(${1:10}) { |${2:i}| ${3} }\nsnippet hash\n Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} }\nsnippet file File.foreach() { |line| .. }\n File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} }\nsnippet file File.read()\n File.read(${1:"path/to/file"})${2}\nsnippet Dir Dir.global() { |file| .. }\n Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} }\nsnippet Dir Dir[".."]\n Dir[${1:"glob/**/*.rb"}]${2}\nsnippet dir\n Filename.dirname(__FILE__)\nsnippet deli\n delete_if { |${1:e}| ${2} }\nsnippet fil\n fill(${1:range}) { |${2:i}| ${3} }\n# flatten_once()\nsnippet flao\n inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3}\nsnippet zip\n zip(${1:enums}) { |${2:row}| ${3} }\n# downto(0) { |n| .. }\nsnippet dow\n downto(${1:0}) { |${2:n}| ${3} }\nsnippet ste\n step(${1:2}) { |${2:n}| ${3} }\nsnippet tim\n times { |${1:n}| ${2} }\nsnippet upt\n upto(${1:1.0/0.0}) { |${2:n}| ${3} }\nsnippet loo\n loop { ${1} }\nsnippet ea\n each { |${1:e}| ${2} }\nsnippet ead\n each do |${1:e}|\n ${2}\n end\nsnippet eab\n each_byte { |${1:byte}| ${2} }\nsnippet eac- each_char { |chr| .. }\n each_char { |${1:chr}| ${2} }\nsnippet eac- each_cons(..) { |group| .. }\n each_cons(${1:2}) { |${2:group}| ${3} }\nsnippet eai\n each_index { |${1:i}| ${2} }\nsnippet eaid\n each_index do |${1:i}|\n ${2}\n end\nsnippet eak\n each_key { |${1:key}| ${2} }\nsnippet eakd\n each_key do |${1:key}|\n ${2}\n end\nsnippet eal\n each_line { |${1:line}| ${2} }\nsnippet eald\n each_line do |${1:line}|\n ${2}\n end\nsnippet eap\n each_pair { |${1:name}, ${2:val}| ${3} }\nsnippet eapd\n each_pair do |${1:name}, ${2:val}|\n ${3}\n end\nsnippet eas-\n each_slice(${1:2}) { |${2:group}| ${3} }\nsnippet easd-\n each_slice(${1:2}) do |${2:group}|\n ${3}\n end\nsnippet eav\n each_value { |${1:val}| ${2} }\nsnippet eavd\n each_value do |${1:val}|\n ${2}\n end\nsnippet eawi\n each_with_index { |${1:e}, ${2:i}| ${3} }\nsnippet eawid\n each_with_index do |${1:e},${2:i}|\n ${3}\n end\nsnippet reve\n reverse_each { |${1:e}| ${2} }\nsnippet reved\n reverse_each do |${1:e}|\n ${2}\n end\nsnippet inj\n inject(${1:init}) { |${2:mem}, ${3:var}| ${4} }\nsnippet injd\n inject(${1:init}) do |${2:mem}, ${3:var}|\n ${4}\n end\nsnippet map\n map { |${1:e}| ${2} }\nsnippet mapd\n map do |${1:e}|\n ${2}\n end\nsnippet mapwi-\n enum_with_index.map { |${1:e}, ${2:i}| ${3} }\nsnippet sor\n sort { |a, b| ${1} }\nsnippet sorb\n sort_by { |${1:e}| ${2} }\nsnippet ran\n sort_by { rand }\nsnippet all\n all? { |${1:e}| ${2} }\nsnippet any\n any? { |${1:e}| ${2} }\nsnippet cl\n classify { |${1:e}| ${2} }\nsnippet col\n collect { |${1:e}| ${2} }\nsnippet cold\n collect do |${1:e}|\n ${2}\n end\nsnippet det\n detect { |${1:e}| ${2} }\nsnippet detd\n detect do |${1:e}|\n ${2}\n end\nsnippet fet\n fetch(${1:name}) { |${2:key}| ${3} }\nsnippet fin\n find { |${1:e}| ${2} }\nsnippet find\n find do |${1:e}|\n ${2}\n end\nsnippet fina\n find_all { |${1:e}| ${2} }\nsnippet finad\n find_all do |${1:e}|\n ${2}\n end\nsnippet gre\n grep(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet sub\n ${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} }\nsnippet sca\n scan(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet scad\n scan(${1:/pattern/}) do |${2:match}|\n ${3}\n end\nsnippet max\n max { |a, b| ${1} }\nsnippet min\n min { |a, b| ${1} }\nsnippet par\n partition { |${1:e}| ${2} }\nsnippet pard\n partition do |${1:e}|\n ${2}\n end\nsnippet rej\n reject { |${1:e}| ${2} }\nsnippet rejd\n reject do |${1:e}|\n ${2}\n end\nsnippet sel\n select { |${1:e}| ${2} }\nsnippet seld\n select do |${1:e}|\n ${2}\n end\nsnippet lam\n lambda { |${1:args}| ${2} }\nsnippet doo\n do\n ${1}\n end\nsnippet dov\n do |${1:variable}|\n ${2}\n end\nsnippet :\n :${1:key} => ${2:"value"}${3}\nsnippet ope\n open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} }\n# path_from_here()\nsnippet fpath\n File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2}\n# unix_filter {}\nsnippet unif\n ARGF.each_line${1} do |${2:line}|\n ${3}\n end\n# option_parse {}\nsnippet optp\n require "optparse"\n\n options = {${1:default => "args"}}\n\n ARGV.options do |opts|\n opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}\nsnippet opt\n opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String},\n "${4:Option description.}") do |${5:opt}|\n ${6}\n end\nsnippet tc\n require "test/unit"\n\n require "${1:library_file_name}"\n\n class Test${2:$1} < Test::Unit::TestCase\n def test_${3:case_name}\n ${4}\n end\n end\nsnippet ts\n require "test/unit"\n\n require "tc_${1:test_case_file}"\n require "tc_${2:test_case_file}"${3}\nsnippet as\n assert ${1:test}, "${2:Failure message.}"${3}\nsnippet ase\n assert_equal ${1:expected}, ${2:actual}${3}\nsnippet asne\n assert_not_equal ${1:unexpected}, ${2:actual}${3}\nsnippet asid\n assert_in_delta ${1:expected_float}, ${2:actual_float}, ${3:2 ** -20}${4}\nsnippet asio\n assert_instance_of ${1:ExpectedClass}, ${2:actual_instance}${3}\nsnippet asko\n assert_kind_of ${1:ExpectedKind}, ${2:actual_instance}${3}\nsnippet asn\n assert_nil ${1:instance}${2}\nsnippet asnn\n assert_not_nil ${1:instance}${2}\nsnippet asm\n assert_match /${1:expected_pattern}/, ${2:actual_string}${3}\nsnippet asnm\n assert_no_match /${1:unexpected_pattern}/, ${2:actual_string}${3}\nsnippet aso\n assert_operator ${1:left}, :${2:operator}, ${3:right}${4}\nsnippet asr\n assert_raise ${1:Exception} { ${2} }\nsnippet asrd\n assert_raise ${1:Exception} do\n ${2}\n end\nsnippet asnr\n assert_nothing_raised ${1:Exception} { ${2} }\nsnippet asnrd\n assert_nothing_raised ${1:Exception} do\n ${2}\n end\nsnippet asrt\n assert_respond_to ${1:object}, :${2:method}${3}\nsnippet ass assert_same(..)\n assert_same ${1:expected}, ${2:actual}${3}\nsnippet ass assert_send(..)\n assert_send [${1:object}, :${2:message}, ${3:args}]${4}\nsnippet asns\n assert_not_same ${1:unexpected}, ${2:actual}${3}\nsnippet ast\n assert_throws :${1:expected} { ${2} }\nsnippet astd\n assert_throws :${1:expected} do\n ${2}\n end\nsnippet asnt\n assert_nothing_thrown { ${1} }\nsnippet asntd\n assert_nothing_thrown do\n ${1}\n end\nsnippet fl\n flunk "${1:Failure message.}"${2}\n# Benchmark.bmbm do .. end\nsnippet bm-\n TESTS = ${1:10_000}\n Benchmark.bmbm do |results|\n ${2}\n end\nsnippet rep\n results.report("${1:name}:") { TESTS.times { ${2} }}\n# Marshal.dump(.., file)\nsnippet Md\n File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4}\n# Mashal.load(obj)\nsnippet Ml\n File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3}\n# deep_copy(..)\nsnippet deec\n Marshal.load(Marshal.dump(${1:obj_to_copy}))${2}\nsnippet Pn-\n PStore.new(${1:"file_name.pstore"})${2}\nsnippet tra\n transaction(${1:true}) { ${2} }\n# xmlread(..)\nsnippet xml-\n REXML::Document.new(File.read(${1:"path/to/file"}))${2}\n# xpath(..) { .. }\nsnippet xpa\n elements.each(${1:"//Xpath"}) do |${2:node}|\n ${3}\n end\n# class_from_name()\nsnippet clafn\n split("::").inject(Object) { |par, const| par.const_get(const) }\n# singleton_class()\nsnippet sinc\n class << self; self end\nsnippet nam\n namespace :${1:`Filename()`} do\n ${2}\n end\nsnippet tas\n desc "${1:Task description}"\n task :${2:task_name => [:dependent, :tasks]} do\n ${3}\n end\n# block\nsnippet b\n { |${1:var}| ${2} }\nsnippet begin\n begin\n raise \'A test exception.\'\n rescue Exception => e\n puts e.message\n puts e.backtrace.inspect\n else\n # other exception\n ensure\n # always executed\n end\n\n#debugging\nsnippet debug\n require \'ruby-debug\'; debugger; true;\nsnippet pry\n require \'pry\'; binding.pry\n\n#############################################\n# Rails snippets - for pure Ruby, see above #\n#############################################\nsnippet art\n assert_redirected_to ${1::action => "${2:index}"}\nsnippet artnp\n assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}, ${4:@$2})\nsnippet artnpp\n assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1})\nsnippet artp\n assert_redirected_to ${1:model}_path(${2:@$1})\nsnippet artpp\n assert_redirected_to ${1:model}s_path\nsnippet asd\n assert_difference "${1:Model}.${2:count}", $1 do\n ${3}\n end\nsnippet asnd\n assert_no_difference "${1:Model}.${2:count}" do\n ${3}\n end\nsnippet asre\n assert_response :${1:success}, @response.body${2}\nsnippet asrj\n assert_rjs :${1:replace}, "${2:dom id}"\nsnippet ass assert_select(..)\n assert_select \'${1:path}\', :${2:text} => \'${3:inner_html\' ${4:do}\nsnippet bf\n before_filter :${1:method}\nsnippet bt\n belongs_to :${1:association}\nsnippet crw\n cattr_accessor :${1:attr_names}\nsnippet defcreate\n def create\n @${1:model_class_name} = ${2:ModelClassName}.new(params[:$1])\n\n respond_to do |wants|\n if @$1.save\n flash[:notice] = \'$2 was successfully created.\'\n wants.html { redirect_to(@$1) }\n wants.xml { render :xml => @$1, :status => :created, :location => @$1 }\n else\n wants.html { render :action => "new" }\n wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity }\n end\n end\n end${3}\nsnippet defdestroy\n def destroy\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n @$1.destroy\n\n respond_to do |wants|\n wants.html { redirect_to($1s_url) }\n wants.xml { head :ok }\n end\n end${3}\nsnippet defedit\n def edit\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n end\nsnippet defindex\n def index\n @${1:model_class_name} = ${2:ModelClassName}.all\n\n respond_to do |wants|\n wants.html # Home.html.erb\n wants.xml { render :xml => @$1s }\n end\n end${3}\nsnippet defnew\n def new\n @${1:model_class_name} = ${2:ModelClassName}.new\n\n respond_to do |wants|\n wants.html # new.html.erb\n wants.xml { render :xml => @$1 }\n end\n end${3}\nsnippet defshow\n def show\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n respond_to do |wants|\n wants.html # show.html.erb\n wants.xml { render :xml => @$1 }\n end\n end${3}\nsnippet defupdate\n def update\n @${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n respond_to do |wants|\n if @$1.update_attributes(params[:$1])\n flash[:notice] = \'$2 was successfully updated.\'\n wants.html { redirect_to(@$1) }\n wants.xml { head :ok }\n else\n wants.html { render :action => "edit" }\n wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity }\n end\n end\n end${3}\nsnippet flash\n flash[:${1:notice}] = "${2}"\nsnippet habtm\n has_and_belongs_to_many :${1:object}, :join_table => "${2:table_name}", :foreign_key => "${3}_id"${4}\nsnippet hm\n has_many :${1:object}\nsnippet hmd\n has_many :${1:other}s, :class_name => "${2:$1}", :foreign_key => "${3:$1}_id", :dependent => :destroy${4}\nsnippet hmt\n has_many :${1:object}, :through => :${2:object}\nsnippet ho\n has_one :${1:object}\nsnippet i18\n I18n.t(\'${1:type.key}\')${2}\nsnippet ist\n <%= image_submit_tag("${1:agree.png}", :id => "${2:id}"${3} %>\nsnippet log\n Rails.logger.${1:debug} ${2}\nsnippet log2\n RAILS_DEFAULT_LOGGER.${1:debug} ${2}\nsnippet logd\n logger.debug { "${1:message}" }${2}\nsnippet loge\n logger.error { "${1:message}" }${2}\nsnippet logf\n logger.fatal { "${1:message}" }${2}\nsnippet logi\n logger.info { "${1:message}" }${2}\nsnippet logw\n logger.warn { "${1:message}" }${2}\nsnippet mapc\n ${1:map}.${2:connect} \'${3:controller/:action/:id}\'\nsnippet mapca\n ${1:map}.catch_all "*${2:anything}", :controller => "${3:default}", :action => "${4:error}"${5}\nsnippet mapr\n ${1:map}.resource :${2:resource}\nsnippet maprs\n ${1:map}.resources :${2:resource}\nsnippet mapwo\n ${1:map}.with_options :${2:controller} => \'${3:thing}\' do |$3|\n ${4}\n end\nsnippet mbs\n before_save :${1:method}\nsnippet mcht\n change_table :${1:table_name} do |t|\n ${2}\n end\nsnippet mp\n map(&:${1:id})\nsnippet mrw\n mattr_accessor :${1:attr_names}\nsnippet oa\n order("${1:field}")\nsnippet od\n order("${1:field} DESC")\nsnippet pa\n params[:${1:id}]${2}\nsnippet ra\n render :action => "${1:action}"\nsnippet ral\n render :action => "${1:action}", :layout => "${2:layoutname}"\nsnippet rest\n respond_to do |wants|\n wants.${1:html} { ${2} }\n end\nsnippet rf\n render :file => "${1:filepath}"\nsnippet rfu\n render :file => "${1:filepath}", :use_full_path => ${2:false}\nsnippet ri\n render :inline => "${1:<%= \'hello\' %>}"\nsnippet ril\n render :inline => "${1:<%= \'hello\' %>}", :locals => { ${2::name} => "${3:value}"${4} }\nsnippet rit\n render :inline => "${1:<%= \'hello\' %>}", :type => ${2::rxml}\nsnippet rjson\n render :json => ${1:text to render}\nsnippet rl\n render :layout => "${1:layoutname}"\nsnippet rn\n render :nothing => ${1:true}\nsnippet rns\n render :nothing => ${1:true}, :status => ${2:401}\nsnippet rp\n render :partial => "${1:item}"\nsnippet rpc\n render :partial => "${1:item}", :collection => ${2:@$1s}\nsnippet rpl\n render :partial => "${1:item}", :locals => { :${2:$1} => ${3:@$1}\nsnippet rpo\n render :partial => "${1:item}", :object => ${2:@$1}\nsnippet rps\n render :partial => "${1:item}", :status => ${2:500}\nsnippet rt\n render :text => "${1:text to render}"\nsnippet rtl\n render :text => "${1:text to render}", :layout => "${2:layoutname}"\nsnippet rtlt\n render :text => "${1:text to render}", :layout => ${2:true}\nsnippet rts\n render :text => "${1:text to render}", :status => ${2:401}\nsnippet ru\n render :update do |${1:page}|\n $1.${2}\n end\nsnippet rxml\n render :xml => ${1:text to render}\nsnippet sc\n scope :${1:name}, :where(:@${2:field} => ${3:value})\nsnippet sl\n scope :${1:name}, lambda do |${2:value}|\n where("${3:field = ?}", ${4:bind var})\n end\nsnippet sha1\n Digest::SHA1.hexdigest(${1:string})\nsnippet sweeper\n class ${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper\n observe $1\n\n def after_save(${2:model_class_name})\n expire_cache($2)\n end\n\n def after_destroy($2)\n expire_cache($2)\n end\n\n def expire_cache($2)\n expire_page\n end\n end\nsnippet tcb\n t.boolean :${1:title}\n ${2}\nsnippet tcbi\n t.binary :${1:title}, :limit => ${2:2}.megabytes\n ${3}\nsnippet tcd\n t.decimal :${1:title}, :precision => ${2:10}, :scale => ${3:2}\n ${4}\nsnippet tcda\n t.date :${1:title}\n ${2}\nsnippet tcdt\n t.datetime :${1:title}\n ${2}\nsnippet tcf\n t.float :${1:title}\n ${2}\nsnippet tch\n t.change :${1:name}, :${2:string}, :${3:limit} => ${4:80}\n ${5}\nsnippet tci\n t.integer :${1:title}\n ${2}\nsnippet tcl\n t.integer :lock_version, :null => false, :default => 0\n ${1}\nsnippet tcr\n t.references :${1:taggable}, :polymorphic => { :default => \'${2:Photo}\' }\n ${3}\nsnippet tcs\n t.string :${1:title}\n ${2}\nsnippet tct\n t.text :${1:title}\n ${2}\nsnippet tcti\n t.time :${1:title}\n ${2}\nsnippet tcts\n t.timestamp :${1:title}\n ${2}\nsnippet tctss\n t.timestamps\n ${1}\nsnippet va\n validates_associated :${1:attribute}\nsnippet vao\n validates_acceptance_of :${1:terms}\nsnippet vc\n validates_confirmation_of :${1:attribute}\nsnippet ve\n validates_exclusion_of :${1:attribute}, :in => ${2:%w( mov avi )}\nsnippet vf\n validates_format_of :${1:attribute}, :with => /${2:regex}/\nsnippet vi\n validates_inclusion_of :${1:attribute}, :in => %w(${2: mov avi })\nsnippet vl\n validates_length_of :${1:attribute}, :within => ${2:3}..${3:20}\nsnippet vn\n validates_numericality_of :${1:attribute}\nsnippet vpo\n validates_presence_of :${1:attribute}\nsnippet vu\n validates_uniqueness_of :${1:attribute}\nsnippet wants\n wants.${1:js|xml|html} { ${2} }\nsnippet wc\n where(${1:"conditions"}${2:, bind_var})\nsnippet wh\n where(${1:field} => ${2:value})\nsnippet xdelete\n xhr :delete, :${1:destroy}, :id => ${2:1}${3}\nsnippet xget\n xhr :get, :${1:show}, :id => ${2:1}${3}\nsnippet xpost\n xhr :post, :${1:create}, :${2:object} => { ${3} }\nsnippet xput\n xhr :put, :${1:update}, :id => ${2:1}, :${3:object} => { ${4} }${5}\nsnippet test\n test "should ${1:do something}" do\n ${2}\n end\n#migrations\nsnippet mac\n add_column :${1:table_name}, :${2:column_name}, :${3:data_type}\nsnippet mrc\n remove_column :${1:table_name}, :${2:column_name}\nsnippet mrnc\n rename_column :${1:table_name}, :${2:old_column_name}, :${3:new_column_name}\nsnippet mcc\n change_column :${1:table}, :${2:column}, :${3:type}\nsnippet mccc\n t.column :${1:title}, :${2:string}\nsnippet mct\n create_table :${1:table_name} do |t|\n t.column :${2:name}, :${3:type}\n end\nsnippet migration\n class ${1:class_name} < ActiveRecord::Migration\n def self.up\n ${2}\n end\n\n def self.down\n end\n end\n\nsnippet trc\n t.remove :${1:column}\nsnippet tre\n t.rename :${1:old_column_name}, :${2:new_column_name}\n ${3}\nsnippet tref\n t.references :${1:model}\n\n#rspec\nsnippet it\n it "${1:spec_name}" do\n ${2}\n end\nsnippet itp\n it "${1:spec_name}"\n ${2}\nsnippet desc\n describe ${1:class_name} do\n ${2}\n end\nsnippet cont\n context "${1:message}" do\n ${2}\n end\nsnippet bef\n before :${1:each} do\n ${2}\n end\nsnippet aft\n after :${1:each} do\n ${2}\n end\n',t.scope="ruby"}); (function() { ace.require(["ace/snippets/ruby"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/appengine/third-party/base.js b/appengine/third-party/base.js index 82cd100..5fb448a 100644 --- a/appengine/third-party/base.js +++ b/appengine/third-party/base.js @@ -43,7 +43,7 @@ var goog = goog || {}; /** * Reference to the global object. - * https://www.ecma-international.org/ecma-262/9.0/index.html#sec-global-object + * https://www.ecma-international.org/ecma-262/9.0/Home.html#sec-global-object * * More info on this implementation here: * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI/edit diff --git a/appengine/third-party/blockly/msg/json/qqq.json b/appengine/third-party/blockly/msg/json/qqq.json index f2b7d17..4c4b01f 100644 --- a/appengine/third-party/blockly/msg/json/qqq.json +++ b/appengine/third-party/blockly/msg/json/qqq.json @@ -239,7 +239,7 @@ "TEXT_CHARAT_FIRST": "block text - Indicates that the first letter of the following piece of text should be retrieved. See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]", "TEXT_CHARAT_LAST": "block text - Indicates that the last letter (or number, punctuation mark, etc.) of the following piece of text should be retrieved. See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]", "TEXT_CHARAT_RANDOM": "block text - Indicates that any letter (or number, punctuation mark, etc.) in the following piece of text should be randomly selected. See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]", - "TEXT_CHARAT_TAIL": "block text - Text that goes after the rightmost block/dropdown when getting a single letter from a piece of text, as in [https://blockly-demo.appspot.com/static/apps/code/index.html#3m23km these blocks] or shown below. For most languages, this will be blank. [[File:Blockly-text-get.png]]", + "TEXT_CHARAT_TAIL": "block text - Text that goes after the rightmost block/dropdown when getting a single letter from a piece of text, as in [https://blockly-demo.appspot.com/static/apps/code/Home.html#3m23km these blocks] or shown below. For most languages, this will be blank. [[File:Blockly-text-get.png]]", "TEXT_CHARAT_TOOLTIP": "tooltip - See [https://github.com/google/blockly/wiki/Text#extracting-a-single-character https://github.com/google/blockly/wiki/Text#extracting-a-single-character]. [[File:Blockly-text-get.png]]", "TEXT_GET_SUBSTRING_TOOLTIP": "See [https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text].", "TEXT_GET_SUBSTRING_HELPURL": "{{Optional}} url - Information about extracting characters from text. Reminder: urls are the lowest priority translations. Feel free to skip.", @@ -371,15 +371,15 @@ "VARIABLES_SET_TOOLTIP": "tooltip - This initializes or changes the value of the named variable.", "VARIABLES_SET_CREATE_GET": "context menu - Selecting this creates a block to get (change) the value of this variable.\n\nParameters:\n* %1 - the name of the variable.", "PROCEDURES_DEFNORETURN_HELPURL": "{{Optional}} url - Information about defining [https://en.wikipedia.org/wiki/Subroutine functions] that do not have return values.", - "PROCEDURES_DEFNORETURN_TITLE": "block text - This precedes the name of the function when defining it. See [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#c84aoc this sample function definition].", - "PROCEDURES_DEFNORETURN_PROCEDURE": "default name - This acts as a placeholder for the name of a function on a function definition block, as shown on [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#w7cfju this block]. The user will replace it with the function's name.", - "PROCEDURES_BEFORE_PARAMS": "block text - This precedes the list of parameters on a function's definition block. See [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample function with parameters].", - "PROCEDURES_CALL_BEFORE_PARAMS": "block text - This precedes the list of parameters on a function's caller block. See [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample function with parameters].", - "PROCEDURES_DEFNORETURN_DO": "block text - This appears next to the function's 'body', the blocks that should be run when the function is called, as shown in [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample function definition].", + "PROCEDURES_DEFNORETURN_TITLE": "block text - This precedes the name of the function when defining it. See [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#c84aoc this sample function definition].", + "PROCEDURES_DEFNORETURN_PROCEDURE": "default name - This acts as a placeholder for the name of a function on a function definition block, as shown on [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#w7cfju this block]. The user will replace it with the function's name.", + "PROCEDURES_BEFORE_PARAMS": "block text - This precedes the list of parameters on a function's definition block. See [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#voztpd this sample function with parameters].", + "PROCEDURES_CALL_BEFORE_PARAMS": "block text - This precedes the list of parameters on a function's caller block. See [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#voztpd this sample function with parameters].", + "PROCEDURES_DEFNORETURN_DO": "block text - This appears next to the function's 'body', the blocks that should be run when the function is called, as shown in [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#voztpd this sample function definition].", "PROCEDURES_DEFNORETURN_TOOLTIP": "tooltip", "PROCEDURES_DEFNORETURN_COMMENT": "Placeholder text that the user is encouraged to replace with a description of what their function does.", "PROCEDURES_DEFRETURN_HELPURL": "{{Optional}} url - Information about defining [https://en.wikipedia.org/wiki/Subroutine functions] that have return values.", - "PROCEDURES_DEFRETURN_RETURN": "block text - This imperative or infinite verb precedes the value that is used as the return value (output) of this function. See [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#6ot5y5 this sample function that returns a value].", + "PROCEDURES_DEFRETURN_RETURN": "block text - This imperative or infinite verb precedes the value that is used as the return value (output) of this function. See [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#6ot5y5 this sample function that returns a value].", "PROCEDURES_DEFRETURN_TOOLTIP": "tooltip", "PROCEDURES_ALLOW_STATEMENTS": "Label for a checkbox that controls if statements are allowed in a function.", "PROCEDURES_DEF_DUPLICATE_WARNING": "alert - The user has created a function with two parameters that have the same name. Every parameter must have a different name.", diff --git a/appengine/third-party/blockly/msg/messages.js b/appengine/third-party/blockly/msg/messages.js index a142f6f..547889c 100644 --- a/appengine/third-party/blockly/msg/messages.js +++ b/appengine/third-party/blockly/msg/messages.js @@ -919,7 +919,7 @@ Blockly.Msg.TEXT_CHARAT_LAST = 'get last letter'; Blockly.Msg.TEXT_CHARAT_RANDOM = 'get random letter'; /** @type {string} */ /// block text - Text that goes after the rightmost block/dropdown when getting a single letter from -/// a piece of text, as in [https://blockly-demo.appspot.com/static/apps/code/index.html#3m23km these +/// a piece of text, as in [https://blockly-demo.appspot.com/static/apps/code/Home.html#3m23km these /// blocks] or shown below. For most languages, this will be blank. /// [[File:Blockly-text-get.png]] Blockly.Msg.TEXT_CHARAT_TAIL = ''; @@ -1500,29 +1500,29 @@ Blockly.Msg.VARIABLES_SET_CREATE_GET = 'Create "get %1"'; Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL = 'https://en.wikipedia.org/wiki/Subroutine'; /** @type {string} */ /// block text - This precedes the name of the function when defining it. See -/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#c84aoc this sample +/// [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#c84aoc this sample /// function definition]. Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE = 'to'; /** @type {string} */ /// default name - This acts as a placeholder for the name of a function on a /// function definition block, as shown on -/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#w7cfju this block]. +/// [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#w7cfju this block]. /// The user will replace it with the function's name. Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE = 'do something'; /** @type {string} */ /// block text - This precedes the list of parameters on a function's definition block. See -/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample +/// [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#voztpd this sample /// function with parameters]. Blockly.Msg.PROCEDURES_BEFORE_PARAMS = 'with:'; /** @type {string} */ /// block text - This precedes the list of parameters on a function's caller block. See -/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample +/// [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#voztpd this sample /// function with parameters]. Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS = 'with:'; /** @type {string} */ /// block text - This appears next to the function's "body", the blocks that should be /// run when the function is called, as shown in -/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#voztpd this sample +/// [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#voztpd this sample /// function definition]. Blockly.Msg.PROCEDURES_DEFNORETURN_DO = ''; /** @type {string} */ @@ -1545,7 +1545,7 @@ Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_CO /** @type {string} */ /// block text - This imperative or infinite verb precedes the value that is used as the return value /// (output) of this function. See -/// [https://blockly-demo.appspot.com/static/apps/code/index.html?lang=en#6ot5y5 this sample +/// [https://blockly-demo.appspot.com/static/apps/code/Home.html?lang=en#6ot5y5 this sample /// function that returns a value]. Blockly.Msg.PROCEDURES_DEFRETURN_RETURN = 'return'; /** @type {string} */ diff --git a/appengine/turtle/template.soy b/appengine/turtle/template.soy index d7285ba..96e3237 100644 --- a/appengine/turtle/template.soy +++ b/appengine/turtle/template.soy @@ -18,7 +18,7 @@
// Block text and their associated tooltips and URLs (interleaved to // assist with translation). - {msg meaning="Turtle.moveTooltip" desc="tooltip - In this and subsequent messages, 'turtle' refers to a stylized turtle on the screen to represent a position and direction. This imaginary turtle is carrying a pen in its tail, so moving the turtle draws a line (or curve, etc.). You are encouraged to play with the [https://blockly-demo.appspot.com/static/apps/turtle/index.html Turtle application] before doing this translation."}Moves the turtle forward or backward by the specified amount.{/msg} + {msg meaning="Turtle.moveTooltip" desc="tooltip - In this and subsequent messages, 'turtle' refers to a stylized turtle on the screen to represent a position and direction. This imaginary turtle is carrying a pen in its tail, so moving the turtle draws a line (or curve, etc.). You are encouraged to play with the [https://blockly-demo.appspot.com/static/apps/turtle/Home.html Turtle application] before doing this translation."}Moves the turtle forward or backward by the specified amount.{/msg} {msg meaning="Turtle.moveForward" desc="[[Translating:Blockly#Drop-Down_Menus dropdown]] - Infinitive or imperative of a verb telling a turtle to move (walk) in the direction he/she is facing. This is followed by a number indicating how far (how many pixels) to go. Prefer a translation that has text in common with the translation of 'move backward'. See [[Translating:Blockly#Drop-Down_Menus]]."}move forward by{/msg} {msg meaning="Turtle.moveBackward" desc="[[Translating:Blockly#Drop-Down_Menus dropdown]] - Infinitive or imperative of a verb telling a turtle to move (walk) in the direction opposite to where he/she is facing. This is followed by a number indicating how far (how many pixels) to go. Prefer a translation that has text in common with the translation of 'move forward'."}move backward by{/msg} diff --git a/json/qqq.json b/json/qqq.json index cf7cd79..d0d4705 100644 --- a/json/qqq.json +++ b/json/qqq.json @@ -125,7 +125,7 @@ "Bird.helpElseIf": "callout - This is shown when the user first needs to modify an 'if' block to have an 'else if' and an 'else'.\n\nMake sure to translate consistently with:\n* {{msg-blockly|CONTROLS IF MSG ELSEIF}}\n* {{msg-blockly|CONTROLS IF MSG ELSE}}", "Bird.helpAnd": "callout - This is shown to introduce the user to the logical 'and' block.\n\nMake sure to translate consistently with:\n* {{msg-blockly|LOGIC OPERATION AND}}", "Bird.helpMutator": "callout - This is shown to demonstrate how to drag a block.\n\nTranslate consistently with:\n* {{msg-blockly|CONTROLS IF MSG ELSE}}\n* {{msg-blockly|CONTROLS IF MSG IF}}", - "Turtle.moveTooltip": "tooltip - In this and subsequent messages, 'turtle' refers to a stylized turtle on the screen to represent a position and direction. This imaginary turtle is carrying a pen in its tail, so moving the turtle draws a line (or curve, etc.). You are encouraged to play with the [https://blockly-demo.appspot.com/static/apps/turtle/index.html Turtle application] before doing this translation.", + "Turtle.moveTooltip": "tooltip - In this and subsequent messages, 'turtle' refers to a stylized turtle on the screen to represent a position and direction. This imaginary turtle is carrying a pen in its tail, so moving the turtle draws a line (or curve, etc.). You are encouraged to play with the [https://blockly-demo.appspot.com/static/apps/turtle/Home.html Turtle application] before doing this translation.", "Turtle.moveForward": "[[Translating:Blockly#Drop-Down_Menus dropdown]] - Infinitive or imperative of a verb telling a turtle to move (walk) in the direction he/she is facing. This is followed by a number indicating how far (how many pixels) to go. Prefer a translation that has text in common with the translation of 'move backward'. See [[Translating:Blockly#Drop-Down_Menus]].", "Turtle.moveBackward": "[[Translating:Blockly#Drop-Down_Menus dropdown]] - Infinitive or imperative of a verb telling a turtle to move (walk) in the direction opposite to where he/she is facing. This is followed by a number indicating how far (how many pixels) to go. Prefer a translation that has text in common with the translation of 'move forward'.", "Turtle.turnTooltip": "'Left' means counter-clockwise/anti-clockwise, and 'right' means clockwise.", diff --git a/third-party/base.js b/third-party/base.js index 82cd100..5fb448a 100644 --- a/third-party/base.js +++ b/third-party/base.js @@ -43,7 +43,7 @@ var goog = goog || {}; /** * Reference to the global object. - * https://www.ecma-international.org/ecma-262/9.0/index.html#sec-global-object + * https://www.ecma-international.org/ecma-262/9.0/Home.html#sec-global-object * * More info on this implementation here: * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI/edit