Initial commit

This commit is contained in:
pasketti
2026-04-05 16:14:49 -04:00
commit ebee3a5534
14059 changed files with 2588797 additions and 0 deletions

44
node_modules/node-blockly/blockly/appengine/README.txt generated vendored Normal file
View File

@@ -0,0 +1,44 @@
Running an App Engine server
This directory contains the files needed to setup the optional Blockly server.
Although Blockly itself is 100% client-side, the server enables cloud storage
and sharing. Store your programs in Datastore and get a unique URL that allows
you to load the program on any computer.
To run your own App Engine instance you'll need to create this directory
structure:
blockly/
|- app.yaml
|- index.yaml
|- index_redirect.py
|- README.txt
|- storage.js
|- storage.py
|- closure-library/ (Optional)
`- static/
|- blocks/
|- core/
|- demos/
|- generators/
|- media/
|- msg/
|- tests/
|- blockly_compressed.js
|- blockly_uncompressed.js (Optional)
|- blocks_compressed.js
|- dart_compressed.js
|- javascript_compressed.js
|- lua_compressed.js
|- php_compressed.js
`- python_compressed.js
Instructions for fetching the optional Closure library may be found here:
https://developers.google.com/blockly/guides/modify/web/closure
Go to https://appengine.google.com/ and create your App Engine application.
Modify the 'application' name of app.yaml to your App Engine application name.
Finally, upload this directory structure to your App Engine account,
wait a minute, then go to http://YOURAPPNAME.appspot.com/

87
node_modules/node-blockly/blockly/appengine/app.yaml generated vendored Normal file
View File

@@ -0,0 +1,87 @@
application: blockly-demo
version: 1
runtime: python27
api_version: 1
threadsafe: no
handlers:
# Redirect obsolete URLs.
# Blockly files moved from /blockly to /static on 5 Dec 2012.
- url: /blockly/.*
static_files: redirect.html
upload: redirect.html
# Code, Maze and Turtle moved from demos on 29 Dec 2012.
- url: /static/demos/(maze|turtle)/.*
static_files: redirect.html
upload: redirect.html
# Apps was disbanded on 20 Nov 2014.
- url: /static/apps/.*
static_files: redirect.html
upload: redirect.html
# Storage API.
- url: /storage
script: storage.py
secure: always
- url: /storage\.js
static_files: storage.js
upload: storage\.js
secure: always
# Blockly files.
- url: /static
static_dir: static
secure: always
# Closure library for uncompressed Blockly.
- url: /closure-library
static_dir: closure-library
secure: always
# Redirect for root directory.
- url: /
script: index_redirect.py
secure: always
# Favicon.
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
secure: always
expiration: "30d"
# Apple icon.
- url: /apple-touch-icon\.png
static_files: apple-touch-icon.png
upload: apple-touch-icon\.png
secure: always
expiration: "30d"
# robot.txt
- url: /robots\.txt
static_files: robots.txt
upload: robots\.txt
secure: always
skip_files:
# App Engine default patterns.
- ^(.*/)?#.*#$
- ^(.*/)?.*~$
- ^(.*/)?.*\.py[co]$
- ^(.*/)?.*/RCS/.*$
- ^(.*/)?\..*$
# Custom skip patterns.
- ^static/appengine/.*$
- ^static/demos/plane/soy/.+\.jar$
- ^static/demos/plane/template.soy$
- ^static/demos/plane/xlf/.*$
- ^static/i18n/.*$
- ^static/msg/json/.*$
- ^.+\.soy$
- ^closure-library/.*_test.html$
- ^closure-library/.*_test.js$
- ^closure-library/closure/bin/.*$
- ^closure-library/doc/.*$
- ^closure-library/scripts/.*$

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
node_modules/node-blockly/blockly/appengine/favicon.ico generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

11
node_modules/node-blockly/blockly/appengine/index.yaml generated vendored Normal file
View File

@@ -0,0 +1,11 @@
indexes:
# AUTOGENERATED
# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run. If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED"). If you want to manage some indexes
# manually, move them above the marker line. The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.

View File

@@ -0,0 +1,2 @@
print("Status: 302")
print("Location: /static/demos/index.html")

View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html>
<head>
<script>
var loc = location.href;
// Blockly files moved from /blockly to /static on 5 Dec 2012.
if (loc.match('/blockly/')) {
loc = loc.replace('/blockly/', '/static/');
}
// Maze and Turtle moved from demos to apps on 29 Dec 2012.
if (loc.match(/\/demos\/(maze|turtle)\//)) {
loc = loc.replace('/demos/', '/apps/');
}
// Vietnamese apps moved from vn to vi on 9 Jun 2012.
if (loc.match('/vn.html')) {
loc = loc.replace('/vn.html', '/vi.html');
}
if (loc.match('/code/code.html')) {
// Code moved to index.html on 7 Aug 2013.
loc = loc.replace('/code.html', '/index.html');
} else if (loc.match('/apps/code/zh_tw.html')) {
// zh-tw was changed to zh-hans on 25 Nov 2013.
loc = loc.replace('/zh_tw.html', '/index.html?lang=zh-hans');
} else if (loc.match('/apps/code/index.html')) {
// NOP.
} else if (loc.match(/\/apps\/code\/[-a-z]+\.html/)) {
// Code became language-agnostic on 20 Jul 2013.
loc = loc.replace(/\/([-a-z]+)\.html/, '/index.html?lang=$1');
}
if (loc.match('/apps/plane/plane.html')) {
// Plane moved to index.html on 7 Aug 2013.
loc = loc.replace('/plane.html', '/index.html');
} else if (loc.match('/apps/code/plane.html')) {
// NOP.
} else if (loc.match(/\/apps\/plane\/[\d_]*[-a-z]+\.html/)) {
// Plane became language-agnostic on 20 Jul 2013.
loc = loc.replace('vn.html', 'vi.html');
if (location.search) {
loc = loc.replace(/\/[\d_]*([-a-z]+)\.html\?/, '/index.html?lang=$1&');
} else {
loc = loc.replace(/\/[\d_]*([-a-z]+)\.html/, '/index.html?lang=$1');
}
}
if (loc.match('/apps/puzzle/')) {
// Puzzle moved to Blockly Games on 15 Oct 2014.
loc = 'https://blockly-games.appspot.com/puzzle';
} else if (loc.match('/apps/maze/')) {
// Maze moved to Blockly Games on 10 Nov 2014.
loc = 'https://blockly-games.appspot.com/maze';
} else if (loc.match('/apps/turtle/')) {
// Turtle moved to Blockly Games on 10 Nov 2014.
loc = 'https://blockly-games.appspot.com/turtle';
} else if (loc.match('/apps/')) {
// Remaining apps moved to demos on 20 Nov 2014.
loc = loc.replace('/apps/', '/demos/');
}
location = loc;
</script>
</head>
</html>

View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: /storage

203
node_modules/node-blockly/blockly/appengine/storage.js generated vendored Normal file
View File

@@ -0,0 +1,203 @@
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Loading and saving blocks with localStorage and cloud storage.
* @author q.neutron@gmail.com (Quynh Neutron)
*/
'use strict';
// Create a namespace.
var BlocklyStorage = {};
/**
* Backup code blocks to localStorage.
* @param {!Blockly.WorkspaceSvg} workspace Workspace.
* @private
*/
BlocklyStorage.backupBlocks_ = function(workspace) {
if ('localStorage' in window) {
var xml = Blockly.Xml.workspaceToDom(workspace);
// Gets the current URL, not including the hash.
var url = window.location.href.split('#')[0];
window.localStorage.setItem(url, Blockly.Xml.domToText(xml));
}
};
/**
* Bind the localStorage backup function to the unload event.
* @param {Blockly.WorkspaceSvg=} opt_workspace Workspace.
*/
BlocklyStorage.backupOnUnload = function(opt_workspace) {
var workspace = opt_workspace || Blockly.getMainWorkspace();
window.addEventListener('unload',
function() {BlocklyStorage.backupBlocks_(workspace);}, false);
};
/**
* Restore code blocks from localStorage.
* @param {Blockly.WorkspaceSvg=} opt_workspace Workspace.
*/
BlocklyStorage.restoreBlocks = function(opt_workspace) {
var url = window.location.href.split('#')[0];
if ('localStorage' in window && window.localStorage[url]) {
var workspace = opt_workspace || Blockly.getMainWorkspace();
var xml = Blockly.Xml.textToDom(window.localStorage[url]);
Blockly.Xml.domToWorkspace(xml, workspace);
}
};
/**
* Save blocks to database and return a link containing key to XML.
* @param {Blockly.WorkspaceSvg=} opt_workspace Workspace.
*/
BlocklyStorage.link = function(opt_workspace) {
var workspace = opt_workspace || Blockly.getMainWorkspace();
var xml = Blockly.Xml.workspaceToDom(workspace, true);
// Remove x/y coordinates from XML if there's only one block stack.
// There's no reason to store this, removing it helps with anonymity.
if (workspace.getTopBlocks(false).length == 1 && xml.querySelector) {
var block = xml.querySelector('block');
if (block) {
block.removeAttribute('x');
block.removeAttribute('y');
}
}
var data = Blockly.Xml.domToText(xml);
BlocklyStorage.makeRequest_('/storage', 'xml', data, workspace);
};
/**
* Retrieve XML text from database using given key.
* @param {string} key Key to XML, obtained from href.
* @param {Blockly.WorkspaceSvg=} opt_workspace Workspace.
*/
BlocklyStorage.retrieveXml = function(key, opt_workspace) {
var workspace = opt_workspace || Blockly.getMainWorkspace();
BlocklyStorage.makeRequest_('/storage', 'key', key, workspace);
};
/**
* Global reference to current AJAX request.
* @type {XMLHttpRequest}
* @private
*/
BlocklyStorage.httpRequest_ = null;
/**
* Fire a new AJAX request.
* @param {string} url URL to fetch.
* @param {string} name Name of parameter.
* @param {string} content Content of parameter.
* @param {!Blockly.WorkspaceSvg} workspace Workspace.
* @private
*/
BlocklyStorage.makeRequest_ = function(url, name, content, workspace) {
if (BlocklyStorage.httpRequest_) {
// AJAX call is in-flight.
BlocklyStorage.httpRequest_.abort();
}
BlocklyStorage.httpRequest_ = new XMLHttpRequest();
BlocklyStorage.httpRequest_.name = name;
BlocklyStorage.httpRequest_.onreadystatechange =
BlocklyStorage.handleRequest_;
BlocklyStorage.httpRequest_.open('POST', url);
BlocklyStorage.httpRequest_.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
BlocklyStorage.httpRequest_.send(name + '=' + encodeURIComponent(content));
BlocklyStorage.httpRequest_.workspace = workspace;
};
/**
* Callback function for AJAX call.
* @private
*/
BlocklyStorage.handleRequest_ = function() {
if (BlocklyStorage.httpRequest_.readyState == 4) {
if (BlocklyStorage.httpRequest_.status != 200) {
BlocklyStorage.alert(BlocklyStorage.HTTPREQUEST_ERROR + '\n' +
'httpRequest_.status: ' + BlocklyStorage.httpRequest_.status);
} else {
var data = BlocklyStorage.httpRequest_.responseText.trim();
if (BlocklyStorage.httpRequest_.name == 'xml') {
window.location.hash = data;
BlocklyStorage.alert(BlocklyStorage.LINK_ALERT.replace('%1',
window.location.href));
} else if (BlocklyStorage.httpRequest_.name == 'key') {
if (!data.length) {
BlocklyStorage.alert(BlocklyStorage.HASH_ERROR.replace('%1',
window.location.hash));
} else {
BlocklyStorage.loadXml_(data, BlocklyStorage.httpRequest_.workspace);
}
}
BlocklyStorage.monitorChanges_(BlocklyStorage.httpRequest_.workspace);
}
BlocklyStorage.httpRequest_ = null;
}
};
/**
* Start monitoring the workspace. If a change is made that changes the XML,
* clear the key from the URL. Stop monitoring the workspace once such a
* change is detected.
* @param {!Blockly.WorkspaceSvg} workspace Workspace.
* @private
*/
BlocklyStorage.monitorChanges_ = function(workspace) {
var startXmlDom = Blockly.Xml.workspaceToDom(workspace);
var startXmlText = Blockly.Xml.domToText(startXmlDom);
function change() {
var xmlDom = Blockly.Xml.workspaceToDom(workspace);
var xmlText = Blockly.Xml.domToText(xmlDom);
if (startXmlText != xmlText) {
window.location.hash = '';
workspace.removeChangeListener(bindData);
}
}
var bindData = workspace.addChangeListener(change);
};
/**
* Load blocks from XML.
* @param {string} xml Text representation of XML.
* @param {!Blockly.WorkspaceSvg} workspace Workspace.
* @private
*/
BlocklyStorage.loadXml_ = function(xml, workspace) {
try {
xml = Blockly.Xml.textToDom(xml);
} catch (e) {
BlocklyStorage.alert(BlocklyStorage.XML_ERROR + '\nXML: ' + xml);
return;
}
// Clear the workspace to avoid merge.
workspace.clear();
Blockly.Xml.domToWorkspace(xml, workspace);
};
/**
* Present a text message to the user.
* Designed to be overridden if an app has custom dialogs, or a butter bar.
* @param {string} message Text to alert.
*/
BlocklyStorage.alert = function(message) {
window.alert(message);
};

85
node_modules/node-blockly/blockly/appengine/storage.py generated vendored Normal file
View File

@@ -0,0 +1,85 @@
"""Blockly Demo: Storage
Copyright 2012 Google Inc.
https://developers.google.com/blockly/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
"""Store and retrieve XML with App Engine.
"""
__author__ = "q.neutron@gmail.com (Quynh Neutron)"
import cgi
from random import randint
from google.appengine.ext import db
from google.appengine.api import memcache
import logging
print "Content-Type: text/plain\n"
def keyGen():
# Generate a random string of length KEY_LEN.
KEY_LEN = 6
CHARS = "abcdefghijkmnopqrstuvwxyz23456789" # Exclude l, 0, 1.
max_index = len(CHARS) - 1
return "".join([CHARS[randint(0, max_index)] for x in range(KEY_LEN)])
class Xml(db.Model):
# A row in the database.
xml_hash = db.IntegerProperty()
xml_content = db.TextProperty()
forms = cgi.FieldStorage()
if "xml" in forms:
# Store XML and return a generated key.
xml_content = forms["xml"].value
xml_hash = hash(xml_content)
lookup_query = db.Query(Xml)
lookup_query.filter("xml_hash =", xml_hash)
lookup_result = lookup_query.get()
if lookup_result:
xml_key = lookup_result.key().name()
else:
trials = 0
result = True
while result:
trials += 1
if trials == 100:
raise Exception("Sorry, the generator failed to get a key for you.")
xml_key = keyGen()
result = db.get(db.Key.from_path("Xml", xml_key))
xml = db.Text(xml_content, encoding="utf_8")
row = Xml(key_name = xml_key, xml_hash = xml_hash, xml_content = xml)
row.put()
print xml_key
if "key" in forms:
# Retrieve stored XML based on the provided key.
key_provided = forms["key"].value
# Normalize the string.
key_provided = key_provided.lower().strip()
# Check memcache for a quick match.
xml = memcache.get("XML_" + key_provided)
if xml is None:
# Check datastore for a definitive match.
result = db.get(db.Key.from_path("Xml", key_provided))
if not result:
xml = ""
else:
xml = result.xml_content
# Save to memcache for next hit.
if not memcache.add("XML_" + key_provided, xml, 3600):
logging.error("Memcache set failed.")
print xml.encode("utf-8")