Compare commits
34 Commits
travis_siz
...
ros-book
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d383a1c858 | ||
|
|
d15eb7785e | ||
|
|
bb9d8edb78 | ||
|
|
4a2fbf3e22 | ||
|
|
c3b549df0d | ||
|
|
21d922beb2 | ||
|
|
88ef00e043 | ||
|
|
1b85a9cdf2 | ||
|
|
d5a79babad | ||
|
|
4d80e6f6cf | ||
|
|
8ce4de191b | ||
|
|
ecaab1650f | ||
|
|
a62107132d | ||
|
|
423490304b | ||
|
|
ee9c956fc7 | ||
|
|
14e49a4f7b | ||
|
|
d4d25c61a2 | ||
|
|
106209d79b | ||
|
|
333cf9655f | ||
|
|
2ddf831842 | ||
|
|
68f23babcc | ||
|
|
4f0a099152 | ||
|
|
acfb858598 | ||
|
|
c0f15fc1e6 | ||
|
|
852b854676 | ||
|
|
e94e552da3 | ||
|
|
72491ade0e | ||
|
|
f5ee72940c | ||
|
|
b6cedecdf0 | ||
|
|
8b1dddce67 | ||
|
|
a89bc82f2b | ||
|
|
156527641a | ||
|
|
4f9e4b1a28 | ||
|
|
46f8f6eb89 |
2
.gitattributes
vendored
@@ -4,3 +4,5 @@ eventemitter2.js linguist-vendored
|
||||
ros3d.js linguist-vendored
|
||||
three.min.js linguist-vendored
|
||||
aruco_pose/vendor/* linguist-vendored
|
||||
blockly/* linguist-vendored
|
||||
highlight/* linguist-vendored
|
||||
|
||||
2
.gitignore
vendored
@@ -4,3 +4,5 @@
|
||||
node_modules/
|
||||
_book/
|
||||
package-lock.json
|
||||
clover_blocks/programs/*.*
|
||||
!clover_blocks/programs/examples/*
|
||||
|
||||
11
.travis.yml
@@ -100,14 +100,6 @@ jobs:
|
||||
verbose: true
|
||||
on:
|
||||
branch: master
|
||||
- stage: Annotate
|
||||
name: Auto-generate changelog
|
||||
language: python
|
||||
python: 3.6
|
||||
install:
|
||||
- pip install GitPython PyGithub
|
||||
script:
|
||||
- PYTHONUNBUFFERED=1 python ./gen_changelog.py
|
||||
- stage: Build
|
||||
name: Editorconfig-lint
|
||||
language: generic
|
||||
@@ -115,10 +107,9 @@ jobs:
|
||||
- wget https://github.com/okalachev/editorconfig-checker/releases/download/1.2.1-disable-spaces-amount/ec-linux-amd64
|
||||
- chmod +x ec-linux-amd64
|
||||
script:
|
||||
- ./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf|\.dae"
|
||||
- ./ec-linux-amd64 -spaces-after-tabs -e "roslib.js|ros3d.js|eventemitter2.js|draw.cpp|BinUtils.swift|\.idea|apps/android/app|blockly/|clover_blocks/programs/|highlight/|python.js|Assets.xcassets|test_parser_pass.txt|test_node_failure.txt|aruco_pose/vendor|\.stl|\.dxf|\.dae"
|
||||
stages:
|
||||
- Build
|
||||
- Annotate
|
||||
# More info there
|
||||
# https://github.com/travis-ci/travis-ci/issues/6893
|
||||
# https://docs.travis-ci.com/user/customizing-the-build/
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"richquotes@https://github.com/okalachev/gitbook-plugin-richquotes.git",
|
||||
"yametrika",
|
||||
"anchors",
|
||||
"collapsible-menu",
|
||||
"validate-links",
|
||||
"bulk-redirect@https://github.com/okalachev/gitbook-plugin-bulk-redirect.git",
|
||||
"sitemap@https://github.com/okalachev/plugin-sitemap.git",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Information: https://clover.coex.tech/en/snippets.html#block-nav
|
||||
# Information: https://clover.coex.tech/en/snippets.html#navigate_wait
|
||||
|
||||
import math
|
||||
import rospy
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<arg name="aruco" default="false"/>
|
||||
<arg name="rangefinder_vl53l1x" default="true"/>
|
||||
<arg name="led" default="true"/>
|
||||
<arg name="blocks" default="false"/>
|
||||
<arg name="rc" default="true"/>
|
||||
<arg name="shell" default="true"/>
|
||||
|
||||
@@ -55,6 +56,7 @@
|
||||
<param name="reference_frames/body" value="map"/>
|
||||
<param name="reference_frames/base_link" value="map"/>
|
||||
<param name="reference_frames/navigate_target" value="map"/>
|
||||
<param name="reference_frames/main_camera_optical" value="map"/>
|
||||
</node>
|
||||
|
||||
<!-- main camera -->
|
||||
@@ -80,6 +82,9 @@
|
||||
<arg name="simulator" value="$(arg simulator)"/>
|
||||
</include>
|
||||
|
||||
<!-- Clover Blocks -->
|
||||
<node name="clover_blocks" pkg="clover_blocks" type="clover_blocks" output="screen" if="$(arg blocks)"/>
|
||||
|
||||
<!-- rc backend -->
|
||||
<node name="rc" pkg="clover" type="rc" output="screen" if="$(arg rc)" clear_params="true">
|
||||
<!-- Send fake GCS heartbeats. Set to "true" for upstream PX4 -->
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <clover/SetRates.h>
|
||||
|
||||
using std::string;
|
||||
using std::isnan;
|
||||
using namespace geometry_msgs;
|
||||
using namespace sensor_msgs;
|
||||
using namespace clover;
|
||||
@@ -507,25 +508,84 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
|
||||
if (busy)
|
||||
throw std::runtime_error("Busy");
|
||||
|
||||
ENSURE_FINITE(x);
|
||||
ENSURE_FINITE(y);
|
||||
ENSURE_FINITE(z);
|
||||
ENSURE_FINITE(vx);
|
||||
ENSURE_FINITE(vy);
|
||||
ENSURE_FINITE(vz);
|
||||
ENSURE_FINITE(pitch);
|
||||
ENSURE_FINITE(roll);
|
||||
ENSURE_FINITE(pitch_rate);
|
||||
ENSURE_FINITE(roll_rate);
|
||||
ENSURE_FINITE(lat);
|
||||
ENSURE_FINITE(lon);
|
||||
ENSURE_FINITE(thrust);
|
||||
|
||||
busy = true;
|
||||
|
||||
// Checks
|
||||
checkState();
|
||||
|
||||
// default frame is local frame
|
||||
if (frame_id.empty())
|
||||
frame_id = local_frame;
|
||||
|
||||
// look up for reference frame
|
||||
auto search = reference_frames.find(frame_id);
|
||||
const string& reference_frame = search == reference_frames.end() ? frame_id : search->second;
|
||||
|
||||
// Serve "partial" commands
|
||||
|
||||
if (!auto_arm && std::isfinite(yaw) &&
|
||||
isnan(x) && isnan(y) && isnan(z) && isnan(vx) && isnan(vy) && isnan(vz) &&
|
||||
isnan(pitch) && isnan(roll) && isnan(thrust) &&
|
||||
isnan(lat) && isnan(lon)) {
|
||||
// change only the yaw
|
||||
if (setpoint_type == POSITION || setpoint_type == NAVIGATE || setpoint_type == NAVIGATE_GLOBAL || setpoint_type == VELOCITY) {
|
||||
if (!waitTransform(setpoint_position.header.frame_id, frame_id, stamp, transform_timeout))
|
||||
throw std::runtime_error("Can't transform from " + frame_id + " to " + setpoint_position.header.frame_id);
|
||||
|
||||
message = "Changing yaw only";
|
||||
|
||||
QuaternionStamped q;
|
||||
q.header.frame_id = frame_id;
|
||||
q.header.stamp = stamp;
|
||||
q.quaternion = tf::createQuaternionMsgFromYaw(yaw); // TODO: pitch=0, roll=0 is not totally correct
|
||||
setpoint_position.pose.orientation = tf_buffer.transform(q, setpoint_position.header.frame_id).quaternion;
|
||||
setpoint_yaw_type = YAW;
|
||||
goto publish_setpoint;
|
||||
} else {
|
||||
throw std::runtime_error("Setting yaw is possible only when position or velocity setpoints active");
|
||||
}
|
||||
}
|
||||
|
||||
if (!auto_arm && std::isfinite(yaw_rate) &&
|
||||
isnan(x) && isnan(y) && isnan(z) && isnan(vx) && isnan(vy) && isnan(vz) &&
|
||||
isnan(pitch) && isnan(roll) && isnan(yaw) && isnan(thrust) &&
|
||||
isnan(lat) && isnan(lon)) {
|
||||
// change only the yaw rate
|
||||
if (setpoint_type == POSITION || setpoint_type == NAVIGATE || setpoint_type == NAVIGATE_GLOBAL || setpoint_type == VELOCITY) {
|
||||
message = "Changing yaw rate only";
|
||||
|
||||
setpoint_yaw_type = YAW_RATE;
|
||||
setpoint_yaw_rate = yaw_rate;
|
||||
goto publish_setpoint;
|
||||
} else {
|
||||
throw std::runtime_error("Setting yaw rate is possible only when position or velocity setpoints active");
|
||||
}
|
||||
}
|
||||
|
||||
// Serve normal commands
|
||||
|
||||
if (sp_type == NAVIGATE || sp_type == POSITION) {
|
||||
ENSURE_FINITE(x);
|
||||
ENSURE_FINITE(y);
|
||||
ENSURE_FINITE(z);
|
||||
} else if (sp_type == NAVIGATE_GLOBAL) {
|
||||
ENSURE_FINITE(lat);
|
||||
ENSURE_FINITE(lon);
|
||||
ENSURE_FINITE(z);
|
||||
} else if (sp_type == VELOCITY) {
|
||||
ENSURE_FINITE(vx);
|
||||
ENSURE_FINITE(vy);
|
||||
ENSURE_FINITE(vz);
|
||||
} else if (sp_type == ATTITUDE) {
|
||||
ENSURE_FINITE(pitch);
|
||||
ENSURE_FINITE(roll);
|
||||
ENSURE_FINITE(thrust);
|
||||
} else if (sp_type == RATES) {
|
||||
ENSURE_FINITE(pitch_rate);
|
||||
ENSURE_FINITE(roll_rate);
|
||||
ENSURE_FINITE(thrust);
|
||||
}
|
||||
|
||||
if (sp_type == NAVIGATE || sp_type == NAVIGATE_GLOBAL) {
|
||||
if (TIMEOUT(local_position, local_position_timeout))
|
||||
throw std::runtime_error("No local position, check settings");
|
||||
@@ -550,14 +610,6 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
|
||||
throw std::runtime_error("No global position");
|
||||
}
|
||||
|
||||
// default frame is local frame
|
||||
if (frame_id.empty())
|
||||
frame_id = local_frame;
|
||||
|
||||
// look up for reference frame
|
||||
auto search = reference_frames.find(frame_id);
|
||||
const string& reference_frame = search == reference_frames.end() ? frame_id : search->second;
|
||||
|
||||
if (sp_type == NAVIGATE || sp_type == NAVIGATE_GLOBAL || sp_type == POSITION || sp_type == VELOCITY || sp_type == ATTITUDE) {
|
||||
// make sure transform from frame_id to reference frame available
|
||||
if (!waitTransform(reference_frame, frame_id, stamp, transform_timeout))
|
||||
@@ -625,7 +677,7 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
|
||||
} else {
|
||||
setpoint_yaw_type = YAW;
|
||||
setpoint_yaw_rate = 0;
|
||||
ps.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(roll, pitch, yaw);
|
||||
ps.pose.orientation = tf::createQuaternionMsgFromYaw(yaw);
|
||||
}
|
||||
|
||||
tf_buffer.transform(ps, setpoint_position, reference_frame);
|
||||
@@ -653,6 +705,7 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
|
||||
|
||||
wait_armed = auto_arm;
|
||||
|
||||
publish_setpoint:
|
||||
publish(stamp); // calculate initial transformed messages first
|
||||
setpoint_timer.start();
|
||||
|
||||
@@ -693,27 +746,27 @@ bool serve(enum setpoint_type_t sp_type, float x, float y, float z, float vx, fl
|
||||
}
|
||||
|
||||
bool navigate(Navigate::Request& req, Navigate::Response& res) {
|
||||
return serve(NAVIGATE, req.x, req.y, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, req.speed, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
return serve(NAVIGATE, req.x, req.y, req.z, NAN, NAN, NAN, NAN, NAN, req.yaw, NAN, NAN, req.yaw_rate, NAN, NAN, NAN, req.speed, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
}
|
||||
|
||||
bool navigateGlobal(NavigateGlobal::Request& req, NavigateGlobal::Response& res) {
|
||||
return serve(NAVIGATE_GLOBAL, 0, 0, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, req.lat, req.lon, 0, req.speed, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
return serve(NAVIGATE_GLOBAL, NAN, NAN, req.z, NAN, NAN, NAN, NAN, NAN, req.yaw, NAN, NAN, req.yaw_rate, req.lat, req.lon, NAN, req.speed, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
}
|
||||
|
||||
bool setPosition(SetPosition::Request& req, SetPosition::Response& res) {
|
||||
return serve(POSITION, req.x, req.y, req.z, 0, 0, 0, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
return serve(POSITION, req.x, req.y, req.z, NAN, NAN, NAN, NAN, NAN, req.yaw, NAN, NAN, req.yaw_rate, NAN, NAN, NAN, NAN, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
}
|
||||
|
||||
bool setVelocity(SetVelocity::Request& req, SetVelocity::Response& res) {
|
||||
return serve(VELOCITY, 0, 0, 0, req.vx, req.vy, req.vz, 0, 0, req.yaw, 0, 0, req.yaw_rate, 0, 0, 0, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
return serve(VELOCITY, NAN, NAN, NAN, req.vx, req.vy, req.vz, NAN, NAN, req.yaw, NAN, NAN, req.yaw_rate, NAN, NAN, NAN, NAN, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
}
|
||||
|
||||
bool setAttitude(SetAttitude::Request& req, SetAttitude::Response& res) {
|
||||
return serve(ATTITUDE, 0, 0, 0, 0, 0, 0, req.pitch, req.roll, req.yaw, 0, 0, 0, 0, 0, req.thrust, 0, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
return serve(ATTITUDE, NAN, NAN, NAN, NAN, NAN, NAN, req.pitch, req.roll, req.yaw, NAN, NAN, NAN, NAN, NAN, req.thrust, NAN, req.frame_id, req.auto_arm, res.success, res.message);
|
||||
}
|
||||
|
||||
bool setRates(SetRates::Request& req, SetRates::Response& res) {
|
||||
return serve(RATES, 0, 0, 0, 0, 0, 0, 0, 0, 0, req.pitch_rate, req.roll_rate, req.yaw_rate, 0, 0, req.thrust, 0, "", req.auto_arm, res.success, res.message);
|
||||
return serve(RATES, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, req.pitch_rate, req.roll_rate, req.yaw_rate, NAN, NAN, req.thrust, NAN, "", req.auto_arm, res.success, res.message);
|
||||
}
|
||||
|
||||
bool land(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<li><a href="" id="butterfly">Open web terminal</a> (<code>Butterfly</code>)</li>
|
||||
<li><a href="viz.html">View 3D visualization</a> (<code>ros3djs</code>)</li>
|
||||
<li><a href="aruco_map.html">3D visualization for markers map</a> (<code>ros3djs</code>)</li>
|
||||
<li><a href="../clover_blocks/">Blocks programming</a> (<code>Blockly</code>)</li>
|
||||
</ul>
|
||||
|
||||
<div class="version"></div>
|
||||
|
||||
87
clover_blocks/CMakeLists.txt
Normal file
@@ -0,0 +1,87 @@
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(clover_blocks)
|
||||
|
||||
find_package(catkin REQUIRED COMPONENTS message_generation)
|
||||
|
||||
add_message_files(
|
||||
FILES
|
||||
Prompt.msg
|
||||
)
|
||||
|
||||
add_service_files(
|
||||
FILES
|
||||
Run.srv
|
||||
Load.srv
|
||||
Store.srv
|
||||
)
|
||||
|
||||
generate_messages(
|
||||
DEPENDENCIES
|
||||
# std_msgs # Or other packages containing msgs
|
||||
)
|
||||
|
||||
catkin_package(
|
||||
# INCLUDE_DIRS include
|
||||
# LIBRARIES roslaunch_editor
|
||||
CATKIN_DEPENDS message_runtime
|
||||
# DEPENDS system_lib
|
||||
)
|
||||
|
||||
#############
|
||||
## Install ##
|
||||
#############
|
||||
|
||||
# all install targets should use catkin DESTINATION variables
|
||||
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
|
||||
|
||||
## Mark executable scripts (Python etc.) for installation
|
||||
## in contrast to setup.py, you can choose the destination
|
||||
# install(PROGRAMS
|
||||
# scripts/my_python_script
|
||||
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
# )
|
||||
|
||||
## Mark executables for installation
|
||||
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
|
||||
# install(TARGETS ${PROJECT_NAME}_node
|
||||
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
# )
|
||||
|
||||
## Mark libraries for installation
|
||||
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
|
||||
# install(TARGETS ${PROJECT_NAME}
|
||||
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
|
||||
# )
|
||||
|
||||
## Mark cpp header files for installation
|
||||
# install(DIRECTORY include/${PROJECT_NAME}/
|
||||
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
|
||||
# FILES_MATCHING PATTERN "*.h"
|
||||
# PATTERN ".svn" EXCLUDE
|
||||
# )
|
||||
|
||||
## Mark other files for installation (e.g. launch and bag files, etc.)
|
||||
# install(FILES
|
||||
# # myfile1
|
||||
# # myfile2
|
||||
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||
# )
|
||||
|
||||
catkin_install_python(PROGRAMS src/clover_blocks
|
||||
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
)
|
||||
|
||||
#############
|
||||
## Testing ##
|
||||
#############
|
||||
|
||||
## Add gtest based cpp test target and link libraries
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_roslaunch_editor.cpp)
|
||||
# if(TARGET ${PROJECT_NAME}-test)
|
||||
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
|
||||
# endif()
|
||||
|
||||
## Add folders to be run by python nosetests
|
||||
# catkin_add_nosetests(test)
|
||||
52
clover_blocks/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# clover_blocks
|
||||
|
||||
Blockly programming support for Clover.
|
||||
|
||||
<img src="screenshot.png" width=700>
|
||||
|
||||
See user documentation at the [main Clover documentation site](https://clover.coex.tech/en/blocks.html).
|
||||
|
||||
Internal package documentation is given below.
|
||||
|
||||
## Frontend
|
||||
|
||||
The frontend files are located in [`www`](./www/) subdirectory. The frontend application uses [`roblib.js`](http://wiki.ros.org/roslibjs) library for communicating with backend node and other ROS resources.
|
||||
|
||||
## `clover_blocks` node
|
||||
|
||||
`clover_blocks` is the blocks programming backend, implementing all the services and topics needed for running Blockly-generated Python script.
|
||||
|
||||
### Services
|
||||
|
||||
* `~run` ([*clover_blocks/Run*](srv/Run.srv)) – run Blockly-generated program (in Python).
|
||||
* `~stop` ([*std_srvs/Trigger*](http://docs.ros.org/melodic/api/std_srvs/html/srv/Trigger.html)) – terminate the running program.
|
||||
* `~store` ([*clover_blocks/load*](srv/Store.srv)) – store a user program (to `<package_path>/programs` by default).
|
||||
* `~load` ([*clover_blocks/load*](srv/Load.srv)) – load all the stored programs.
|
||||
|
||||
### Parameters
|
||||
|
||||
* `~programs_dir` (*string*) – directory for user programs.
|
||||
|
||||
Parameters read by frontend:
|
||||
|
||||
* `~navigate_tolerance` (*float*) – distance tolerance in meters, used for navigate-like blocks (default: 0.2).
|
||||
* `~sleep_time` (*float*) – duration of sleep in loop cycles, used for navigate-like blocks (default: 0.2).
|
||||
|
||||
These parameters also can be set as URL GET-parameters, for example:
|
||||
|
||||
```
|
||||
http://<hostname>/clover_blocks/?navigate_tolerance=0.5&sleep_time=0.1
|
||||
```
|
||||
|
||||
### Topics
|
||||
|
||||
#### Published
|
||||
|
||||
* `~running` ([*std_msgs/Bool*](http://docs.ros.org/melodic/api/std_msgs/html/msg/Bool.html)) – indicates if the program is currently running.
|
||||
* `~block` ([*std_msgs/String*](http://docs.ros.org/melodic/api/std_msgs/html/msg/String.html)) – current executing block (maximum topic rate is limited).
|
||||
* `~error` ([*std_msgs/String*](http://docs.ros.org/melodic/api/std_msgs/html/msg/String.html)) – user program errors and exceptions.
|
||||
* `~prompt` ([*clover_blocks/Prompt*](msg/Prompt.msg)) – user input request (includes random request ID string).
|
||||
|
||||
This topic is published from the frontend side:
|
||||
|
||||
* `~prompt/<request_id>` ([*std_msgs/String*](http://docs.ros.org/melodic/api/std_msgs/html/msg/String.html)) – user input response.
|
||||
2
clover_blocks/msg/Prompt.msg
Normal file
@@ -0,0 +1,2 @@
|
||||
string message # message for prompt
|
||||
string id # user response should be published to ~input/<id> topic
|
||||
48
clover_blocks/package.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0"?>
|
||||
<package format="2">
|
||||
<name>clover_blocks</name>
|
||||
<version>0.0.0</version>
|
||||
<description>Blockly programming support for Clover</description>
|
||||
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
|
||||
<license>MIT</license>
|
||||
|
||||
<!-- Url tags are optional, but multiple are allowed, one per tag -->
|
||||
<!-- Optional attribute type can be: website, bugtracker, or repository -->
|
||||
<url type="repository">https://github.com/CopterExpress/clover</url>
|
||||
|
||||
<!-- Author tags are optional, multiple are allowed, one per tag -->
|
||||
<!-- Authors do not have to be maintainers, but could be -->
|
||||
<author email="okalachev@gmail.com">Oleg Kalachev</author>
|
||||
|
||||
<!-- The *depend tags are used to specify dependencies -->
|
||||
<!-- Dependencies can be catkin packages or system dependencies -->
|
||||
<!-- Examples: -->
|
||||
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
|
||||
<!-- <depend>roscpp</depend> -->
|
||||
<!-- Note that this is equivalent to the following: -->
|
||||
<!-- <build_depend>roscpp</build_depend> -->
|
||||
<!-- <exec_depend>roscpp</exec_depend> -->
|
||||
<!-- Use build_depend for packages you need at compile time: -->
|
||||
<!-- <build_depend>message_generation</build_depend> -->
|
||||
<!-- Use build_export_depend for packages you need in order to build against this package: -->
|
||||
<!-- <build_export_depend>message_generation</build_export_depend> -->
|
||||
<!-- Use buildtool_depend for build tool packages: -->
|
||||
<!-- <buildtool_depend>catkin</buildtool_depend> -->
|
||||
<!-- Use exec_depend for packages you need at runtime: -->
|
||||
<!-- <exec_depend>message_runtime</exec_depend> -->
|
||||
<!-- Use test_depend for packages you need only for testing: -->
|
||||
<!-- <test_depend>gtest</test_depend> -->
|
||||
<!-- Use doc_depend for packages you need only for building documentation: -->
|
||||
<!-- <doc_depend>doxygen</doc_depend> -->
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
|
||||
<depend>message_generation</depend>
|
||||
<depend>message_runtime</depend>
|
||||
<depend>rospy</depend>
|
||||
|
||||
<!-- The export tag contains other, unspecified, tags -->
|
||||
<export>
|
||||
<!-- Other tools can request additional information be placed here -->
|
||||
|
||||
</export>
|
||||
</package>
|
||||
73
clover_blocks/programs/examples/aruco-map.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="take_off" id="w4,Hi[}0b.mX68K|hOJv" x="38" y="63">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="q!Ln!d`jutn*3Gy56B0A">
|
||||
<field name="NUM">1.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="controls_repeat_ext" id="fD/HWb]kb!^pYK{UkM;0">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number" id="%FP0k|kaf~A`0N;M{Oiy">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<statement name="DO">
|
||||
<block type="navigate" id="qM5ROiq4r:$lq}8U_wol">
|
||||
<field name="FRAME_ID">ARUCO_MAP</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="=MBV;9zGH8S`Xh57/E;C">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="text_prompt_ext" id="rUDMP2~yFR!7E`Q]pR/i">
|
||||
<mutation type="NUMBER"></mutation>
|
||||
<field name="TYPE">NUMBER</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="z+Q3vS?)kxHl?HTcuI?(">
|
||||
<field name="TEXT">Enter X</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="%$`av8A.w}vNqG-]1GOn">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="text_prompt_ext" id=".AjhH^Rh*i}+14s)K-:g">
|
||||
<mutation type="NUMBER"></mutation>
|
||||
<field name="TYPE">NUMBER</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="x#)(kg5PB;0uZA5;{(GT">
|
||||
<field name="TEXT">Enter Y</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="T,]q+-@V;tCYLy$-(o3}">
|
||||
<field name="NUM">1.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="VRo?s#0d)Gl@9fsK@gR=">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="mmZc+d=W})w.AN*B_dSe">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</statement>
|
||||
<next>
|
||||
<block type="land" id="JB%yj/X~K=8A2=Q*7cRs">
|
||||
<field name="WAIT">TRUE</field>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
64
clover_blocks/programs/examples/aruco-marker.xml
Normal file
@@ -0,0 +1,64 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="take_off" id="R@=3~Fq;AxFaRO{ZDFUM" x="37" y="63">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="cf8/,N48N;Fvn@EWB%,B">
|
||||
<field name="NUM">1.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="controls_repeat_ext" id="qc$F96[A^%lj,-l[fhX+">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number" id="v0QgNIpGzMIb`P@8D@}.">
|
||||
<field name="NUM">3</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<statement name="DO">
|
||||
<block type="navigate" id="]kCOMt@NSf$9:N1Fx~dE">
|
||||
<field name="FRAME_ID">ARUCO</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="}(7P5,{6%^::Gzb;kRaf">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="hz#sFvY/;IL5IRLQVa.K">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="n0ULZn64%k.:,l(,D?TZ">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="P4^twyJo6as#G1}^Dlq8">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="text_prompt_ext" id="ot;{twL$8`H*Wiafz3D,">
|
||||
<mutation type="NUMBER"></mutation>
|
||||
<field name="TYPE">NUMBER</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="@P[TyPj[n1*;EcUC?lwF">
|
||||
<field name="TEXT">Enter marker ID</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="WrsUXacZ2w)D]d?:@ec_">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</statement>
|
||||
<next>
|
||||
<block type="land" id="G5+Fs.6Y4(K9Dw`wjgua">
|
||||
<field name="WAIT">TRUE</field>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
97
clover_blocks/programs/examples/flight-led.xml
Normal file
@@ -0,0 +1,97 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="take_off" id="R@=3~Fq;AxFaRO{ZDFUM" x="162" y="63">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="cf8/,N48N;Fvn@EWB%,B">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="set_effect" id="5K8qDD0/@Ab!k+ad6IPj">
|
||||
<field name="EFFECT">FILL</field>
|
||||
<value name="COLOR">
|
||||
<shadow type="colour_picker" id="=*Y*L:1DI7y$.RR$6jNQ">
|
||||
<field name="COLOUR">#ff0000</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="navigate" id="kE7TL3+{PI.GiXby~SyO">
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="W$eQ*Xv/e(*`e%8--W:P">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="i~r{%5mpU|}FL|9p!5yG">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="fZ{Cz~^LoWvM#,#;!co_">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="z$Hj|-?4e3zy@Jx$/THh">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="FjRM:aex=:/l_``^zcO]">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="set_effect" id="Q^DQoW/6G$7#YPlXc}%]">
|
||||
<field name="EFFECT">FILL</field>
|
||||
<value name="COLOR">
|
||||
<shadow type="colour_picker" id="mjOY6]=uMY4$r8^n:n|}">
|
||||
<field name="COLOUR">#3333ff</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="navigate" id=";|j@sXR{9)9@ran7g[;~">
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="TH(htYn}*/a{[::sFQ[x">
|
||||
<field name="NUM">-1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="h@`=v?y+Tuh,I)wv?+`f">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="pzz:U%?m/~~B$-FF!fD?">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="Ze2Nun;[K{X.1kE0anMF">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="+[A5TSXF:hw4T1M]e~Wu">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="land" id="G5+Fs.6Y4(K9Dw`wjgua">
|
||||
<field name="WAIT">TRUE</field>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
308
clover_blocks/programs/examples/flip.xml
Normal file
@@ -0,0 +1,308 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<variables>
|
||||
<variable id="MEu_bi$Xk5e(#Q`Yu=k0">start_x</variable>
|
||||
<variable id="GtS.)8^|(~RL*T4.~#VV">start_y</variable>
|
||||
<variable id="jksdQ,]0F47Xan8{_(?+">start_z</variable>
|
||||
</variables>
|
||||
<block type="procedures_defnoreturn" id="Uo{/lI4(1i[O|U^jyh]y" x="188" y="62">
|
||||
<field name="NAME">flip</field>
|
||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
||||
<statement name="STACK">
|
||||
<block type="procedures_callnoreturn" id="G7`l2OBCg~ISh(XsrkRv">
|
||||
<mutation name="memorize position"></mutation>
|
||||
<next>
|
||||
<block type="setpoint" id="8%(,J3=!CEUALDr5gFT+">
|
||||
<field name="TYPE">RATES</field>
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<comment pinned="false" h="80" w="160">bump up</comment>
|
||||
<value name="VX">
|
||||
<shadow type="math_number" id="!@rHW+cG*U6.Py:.;qc)">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="VY">
|
||||
<shadow type="math_number" id="n#I~l7$%1m^@Oz+w;k[H">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="VZ">
|
||||
<shadow type="math_number" id="l0EphD#!^4jX#%UA-rxX">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="PITCH">
|
||||
<shadow type="math_number" id="Ad.[@07QtZcb;(:^,Kjg">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ROLL">
|
||||
<shadow type="math_number" id="50,,4i.p6KR:e3/l|k2i">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="YAW">
|
||||
<shadow type="math_number" id="(:O}={3*LZ#KDiC@;b[F">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="THRUST">
|
||||
<shadow type="math_number" id="EC6yU;oHb#y-8?W`B/JC">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="k.X^bynEZH2dyG1=Y6lr">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="wait" id="#ga)cR4TsF[9t?;zc1H~">
|
||||
<value name="TIME">
|
||||
<shadow type="math_number" id="zg5fX7[;O,lQt*Txg|tn">
|
||||
<field name="NUM">0.2</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="setpoint" id="j,yf}/lrx*2J}X%^5LG{">
|
||||
<field name="TYPE">RATES</field>
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<comment pinned="false" h="80" w="160">maximum pitch rate</comment>
|
||||
<value name="VX">
|
||||
<shadow type="math_number" id="^WF12EBPyIXhZdpsj;=D">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="VY">
|
||||
<shadow type="math_number" id="C/uBsz]ObzwyHxGqzUP_">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="VZ">
|
||||
<shadow type="math_number" id="4?)O3G/j`UuVTMImLq{T">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="PITCH">
|
||||
<shadow type="math_number" id="sdCVFTmVkc0v2|*3Fy~h">
|
||||
<field name="NUM">30</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ROLL">
|
||||
<shadow type="math_number" id="V1o!AV[`!OnhrUP4~$=!">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="YAW">
|
||||
<shadow type="math_number" id="0e;`*B;ghV*%=ETSvzSM">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="THRUST">
|
||||
<shadow type="math_number" id="K@VAeOH2bEwc#@7_M!@l">
|
||||
<field name="NUM">0.2</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="c6ycgS!D}bIK8pl8oAv+">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="controls_whileUntil" id="H_6do.wf6H.E$?5;$uw8">
|
||||
<field name="MODE">WHILE</field>
|
||||
<value name="BOOL">
|
||||
<block type="logic_boolean" id="pu%GH9}wZvUV{RnGk6Se">
|
||||
<field name="BOOL">TRUE</field>
|
||||
</block>
|
||||
</value>
|
||||
<statement name="DO">
|
||||
<block type="controls_if" id="l0w?CSzU]S(K9eL-1(1r">
|
||||
<value name="IF0">
|
||||
<block type="logic_operation" id="gtXXJ7OFs=1BynL@|R{.">
|
||||
<field name="OP">OR</field>
|
||||
<value name="A">
|
||||
<block type="logic_compare" id="2%9ns$Jk(8M[8$~9o(=*">
|
||||
<field name="OP">GT</field>
|
||||
<value name="A">
|
||||
<block type="math_single" id="#gr7h89vpJyc8bnbWU9O">
|
||||
<field name="OP">ABS</field>
|
||||
<value name="NUM">
|
||||
<shadow type="math_number" id="5paq?]87z}}+@~NALY}.">
|
||||
<field name="NUM">9</field>
|
||||
</shadow>
|
||||
<block type="get_attitude" id="awk0-~@[jWFVQ+ZPi=Dc">
|
||||
<field name="FIELD">PITCH</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="B">
|
||||
<block type="math_number" id=",4p]fd#kwxy`DtCMtraW">
|
||||
<field name="NUM">90</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="B">
|
||||
<block type="logic_compare" id="?TPG3^?eg4l~CKM,3DfO">
|
||||
<field name="OP">GT</field>
|
||||
<value name="A">
|
||||
<block type="math_single" id="yS*/-+E3TMpZ]%`1j*Up">
|
||||
<field name="OP">ABS</field>
|
||||
<value name="NUM">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">9</field>
|
||||
</shadow>
|
||||
<block type="get_attitude" id="~E3RS!on]G(?IZ?SVA#J">
|
||||
<field name="FIELD">ROLL</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="B">
|
||||
<block type="math_number" id="#y??I}u#OmOTK:`!pkNS">
|
||||
<field name="NUM">90</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<statement name="DO0">
|
||||
<block type="controls_flow_statements" id="X|V=r3BDKw9fv)u5EY3.">
|
||||
<field name="FLOW">BREAK</field>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
</statement>
|
||||
<next>
|
||||
<block type="procedures_callnoreturn" id="?;sq{#xJ+]bD`yJ#(]o1">
|
||||
<mutation name="navigate to memorized position"></mutation>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
<block type="procedures_defnoreturn" id="!Tv!F*.A}=]dW=C6X@-`" x="538" y="62">
|
||||
<field name="NAME">memorize position</field>
|
||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
||||
<statement name="STACK">
|
||||
<block type="variables_set" id="s,o|q7_A/fSV+c0E)b^k">
|
||||
<field name="VAR" id="MEu_bi$Xk5e(#Q`Yu=k0">start_x</field>
|
||||
<value name="VALUE">
|
||||
<block type="get_position" id="f#,.s%hV^19JJ;G/DO):">
|
||||
<field name="FIELD">X</field>
|
||||
<field name="FRAME_ID">MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="rJRRE#;#JFg}gY+34LVi">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="variables_set" id="E+2Pfn3JOB{r=DQ3f1b`">
|
||||
<field name="VAR" id="GtS.)8^|(~RL*T4.~#VV">start_y</field>
|
||||
<value name="VALUE">
|
||||
<block type="get_position" id="J#y+_prX(DI;j8gFO81H">
|
||||
<field name="FIELD">Y</field>
|
||||
<field name="FRAME_ID">MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="_bnV`SCa:|Vl#sRlYA@}">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="variables_set" id="t*TI?p-h#qC_kC)jM8q0">
|
||||
<field name="VAR" id="jksdQ,]0F47Xan8{_(?+">start_z</field>
|
||||
<value name="VALUE">
|
||||
<block type="get_position" id="Xh#8yLEMxT|bQ}jYvk6/">
|
||||
<field name="FIELD">Z</field>
|
||||
<field name="FRAME_ID">MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="z3FTv/jt^H7dVYx1`$$C">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
<block type="procedures_defnoreturn" id="$p3=p^fBz}k5Pg1]svL," x="563" y="213">
|
||||
<field name="NAME">navigate to memorized position</field>
|
||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
||||
<statement name="STACK">
|
||||
<block type="navigate" id="#7b*(J_t9t)V,Arb)3;R">
|
||||
<field name="FRAME_ID">MAP</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="X#O!NcMac+a9WKL;l7?W">
|
||||
<field name="VAR" id="MEu_bi$Xk5e(#Q`Yu=k0">start_x</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="C(=1.r0+01|e3+3qs%SD">
|
||||
<field name="VAR" id="GtS.)8^|(~RL*T4.~#VV">start_y</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="?v;YVETEO%vUqgmiro^/">
|
||||
<field name="VAR" id="jksdQ,]0F47Xan8{_(?+">start_z</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="ALt.9P$^_]upK}Q9_M,5">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="ObO|OuF^d,1|Bx{Y`O-R">
|
||||
<field name="NUM">5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
<block type="take_off" id="I1oP(b3wChmK?WgPtULz" x="563" y="612">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="N1EX*JgURuG783yO+B^X">
|
||||
<field name="NUM">2</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="procedures_callnoreturn" id="(Dc3I{36Kt@1KHN7Ef.m">
|
||||
<mutation name="flip"></mutation>
|
||||
<next>
|
||||
<block type="land" id=";c+lM(v6`13$VK`~jZ|5">
|
||||
<field name="WAIT">TRUE</field>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
184
clover_blocks/programs/examples/functions.xml
Normal file
@@ -0,0 +1,184 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<variables>
|
||||
<variable id="MEu_bi$Xk5e(#Q`Yu=k0">start_x</variable>
|
||||
<variable id="GtS.)8^|(~RL*T4.~#VV">start_y</variable>
|
||||
<variable id="jksdQ,]0F47Xan8{_(?+">start_z</variable>
|
||||
</variables>
|
||||
<block type="procedures_defnoreturn" id="X0i)DAnNpakX]gr;CC0}" x="588" y="88">
|
||||
<field name="NAME">memorize position</field>
|
||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
||||
<statement name="STACK">
|
||||
<block type="variables_set" id="Ma4s0pE-i`P:(-|?c88v">
|
||||
<field name="VAR" id="MEu_bi$Xk5e(#Q`Yu=k0">start_x</field>
|
||||
<value name="VALUE">
|
||||
<block type="get_position" id="~uz[sPf[(s,15#x]3tAw">
|
||||
<field name="FIELD">X</field>
|
||||
<field name="FRAME_ID">MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="V#rB*5s3W^*q75}gScM(">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="variables_set" id="I07,0;W#gn1CNY697O9n">
|
||||
<field name="VAR" id="GtS.)8^|(~RL*T4.~#VV">start_y</field>
|
||||
<value name="VALUE">
|
||||
<block type="get_position" id="z(5A+nNX@tWO[J/X6Hb(">
|
||||
<field name="FIELD">Y</field>
|
||||
<field name="FRAME_ID">MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="6dM^zy88YqX`3ch{IH{1">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="variables_set" id="AGgAbxz?+u_2^h;Xo4oc">
|
||||
<field name="VAR" id="jksdQ,]0F47Xan8{_(?+">start_z</field>
|
||||
<value name="VALUE">
|
||||
<block type="get_position" id="k~cMq+jvE^,Ip*kKUmw]">
|
||||
<field name="FIELD">Z</field>
|
||||
<field name="FRAME_ID">MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="Q8RU-5,2UG*IfCeZg0cy">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
<block type="take_off" id=".0#}q|m$C-GD,.fM/9:/" x="137" y="162">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="H6G+npH8DS90OnBKP;qy">
|
||||
<field name="NUM">2</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="procedures_callnoreturn" id="_r_hGwEy6uksz}DtrwxW">
|
||||
<mutation name="memorize position"></mutation>
|
||||
<next>
|
||||
<block type="navigate" id="e{_?bCxQ}za#e~~A2GmJ">
|
||||
<field name="FRAME_ID">ARUCO_MAP</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="}P]lFX9(He:*{Rvp8[.q">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="text_prompt_ext" id="L:~.WP`isNJ/TBBP75.{">
|
||||
<mutation type="NUMBER"></mutation>
|
||||
<field name="TYPE">NUMBER</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="v87(;,:4$T8wgbByRv`z">
|
||||
<field name="TEXT">Input X</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="eMbKtnF{B^P*p7zRD8SX">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="text_prompt_ext" id="fp[sLcO^N:q}9k6zYwnN">
|
||||
<mutation type="NUMBER"></mutation>
|
||||
<field name="TYPE">NUMBER</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="2Bqk0Rm@h*Vef,,:0c!+">
|
||||
<field name="TEXT">Input Y</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="1sLNKuRa}07Ek(eHK;/S">
|
||||
<field name="NUM">2</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="guM,}nHUz^a?_H3(b{FW">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id=".EckPx#fD.[:qSk}5/-J">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="text_print" id="d,aouAR0nE80mk6qTAti">
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="Yr%NvOOvCnrBP8}m]bn`">
|
||||
<field name="TEXT">Point reached. Going back.</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="procedures_callnoreturn" id="B0o:6T%+wpg{O%s27:bH">
|
||||
<mutation name="navigate to memorized position"></mutation>
|
||||
<next>
|
||||
<block type="land" id="~%g;%HDPtF!lqHY}KO@/">
|
||||
<field name="WAIT">TRUE</field>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
<block type="procedures_defnoreturn" id="POzAJb%[yRgBrEn9K*x{" x="587" y="362">
|
||||
<field name="NAME">navigate to memorized position</field>
|
||||
<comment pinned="false" h="80" w="160">Describe this function...</comment>
|
||||
<statement name="STACK">
|
||||
<block type="navigate" id="VX|`@L*bU=aY`4!l=Pbw">
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="c$==spjA=Vin//l1(1V@">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="LxP$oVs*8[{CH4o^RY._">
|
||||
<field name="VAR" id="MEu_bi$Xk5e(#Q`Yu=k0">start_x</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="a)/FEG4j=.584f/:2$?H">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="_-Ib6#usbp0NS}DZ7OGS">
|
||||
<field name="VAR" id="GtS.)8^|(~RL*T4.~#VV">start_y</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="q*MDfPe,V]rfhC1pnltq">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="VY4xW2Y|=*AH3`s2C@)5">
|
||||
<field name="VAR" id="jksdQ,]0F47Xan8{_(?+">start_z</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="OiuYE,a3PqUW.vst+Qc$">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="X2Ou?:=kt:`aOq,#Q-)+">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
</xml>
|
||||
106
clover_blocks/programs/examples/led-compass.xml
Normal file
@@ -0,0 +1,106 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<variables>
|
||||
<variable id="_{V-S5HPBUl]CcJkL1Jw">led_count</variable>
|
||||
</variables>
|
||||
<block type="variables_set" id="{)^J~:UMX%D;RWvztWLN" x="113" y="87">
|
||||
<field name="VAR" id="_{V-S5HPBUl]CcJkL1Jw">led_count</field>
|
||||
<value name="VALUE">
|
||||
<block type="math_number" id="V_W$3,VFwZjcc|?|1o`l">
|
||||
<field name="NUM">58</field>
|
||||
</block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="controls_whileUntil" id="U1it{GcGuSS:=[xiwZr1">
|
||||
<field name="MODE">WHILE</field>
|
||||
<value name="BOOL">
|
||||
<block type="logic_boolean" id="]7ZDRwde}/RqjQCX}aVW">
|
||||
<field name="BOOL">TRUE</field>
|
||||
</block>
|
||||
</value>
|
||||
<statement name="DO">
|
||||
<block type="set_effect" id="WI0zqOz/z3].cR/6UWHn">
|
||||
<field name="EFFECT">FILL</field>
|
||||
<value name="COLOR">
|
||||
<shadow type="colour_picker" id="B`6;Xv{s2TFp8Yd=ZpSD">
|
||||
<field name="COLOUR">#000000</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="set_led" id="^Vcs}ki?#ctf7rAchix$">
|
||||
<value name="INDEX">
|
||||
<shadow type="math_number" id="U;VWW$[*LOF7Gf,~?YR7">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="math_arithmetic" id="AI6PZBd`]_Z%_~4c-%dB">
|
||||
<field name="OP">MULTIPLY</field>
|
||||
<value name="A">
|
||||
<shadow type="math_number" id="|p}X]`SedK3).F/;}NlB">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
<block type="math_arithmetic" id="-haE#:,cg{-J=NZERA;F">
|
||||
<field name="OP">DIVIDE</field>
|
||||
<value name="A">
|
||||
<shadow type="math_number" id="::st;ot}[r]csqceURu*">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
<block type="math_arithmetic" id="a%+LN)F~=Igg+,p02[qo">
|
||||
<field name="OP">ADD</field>
|
||||
<value name="A">
|
||||
<shadow type="math_number" id="*yIGN((y)/^z0:f5:VDw">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
<block type="get_yaw" id="mf%77q30bEqNfc/3`Mtb">
|
||||
<field name="FRAME_ID">MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="xb32G.N#ip`|^Xv*MOmY">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="B">
|
||||
<shadow type="math_number" id="T/fTrm;j2Azgav;gI{ZW">
|
||||
<field name="NUM">180</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="B">
|
||||
<shadow type="math_number" id="Wo1/ZCeir,u6/.e1H+BB">
|
||||
<field name="NUM">360</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="B">
|
||||
<shadow type="math_number" id="jENTcXz0C5/=)Xpd!}LL">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="Ko,`n=i88FY~`YbQLA?[">
|
||||
<field name="VAR" id="_{V-S5HPBUl]CcJkL1Jw">led_count</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<value name="COLOR">
|
||||
<shadow type="colour_picker" id="+vw3bff.5c[=_w,Xm^C(">
|
||||
<field name="COLOUR">#3366ff</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="wait" id="DT%f$bn1*1El5zsgUW8Y">
|
||||
<value name="TIME">
|
||||
<shadow type="math_number" id="~Y0hNY[_^#v@aZkE-TH[">
|
||||
<field name="NUM">0.1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
30
clover_blocks/programs/examples/led.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="controls_whileUntil" id="A:_Z_27?K?HlScug%u|5" x="113" y="113">
|
||||
<field name="MODE">WHILE</field>
|
||||
<value name="BOOL">
|
||||
<block type="logic_boolean" id="/rlzePJ6XJcv22J(Q4bs">
|
||||
<field name="BOOL">TRUE</field>
|
||||
</block>
|
||||
</value>
|
||||
<statement name="DO">
|
||||
<block type="set_effect" id="GT~AX(j]r)u^,f_n0agS">
|
||||
<field name="EFFECT">WIPE</field>
|
||||
<value name="COLOR">
|
||||
<shadow type="colour_picker" id="G`I)ZAuIGcnWNyO@N(sH">
|
||||
<field name="COLOUR">#ff0000</field>
|
||||
</shadow>
|
||||
<block type="colour_random" id="}(${|~%[}eJ.QUY?FWi_"></block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="wait" id="Ux(J;l+?5Gq2n^*!jXj^">
|
||||
<value name="TIME">
|
||||
<shadow type="math_number" id=")As9bASkedr9x@M)*)Pf">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
</xml>
|
||||
29
clover_blocks/programs/examples/print-range.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="controls_whileUntil" id="^{D$=!y=ahJx0.^n?Ycr" x="88" y="137">
|
||||
<field name="MODE">WHILE</field>
|
||||
<value name="BOOL">
|
||||
<block type="logic_boolean" id="a;~UtFPf9O3B)#QBJxL6">
|
||||
<field name="BOOL">TRUE</field>
|
||||
</block>
|
||||
</value>
|
||||
<statement name="DO">
|
||||
<block type="text_print" id="doqF#i]/ulE{Z0l/{9`K">
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="Y$c,rIaw^bNs2wIw%[^(">
|
||||
<field name="TEXT">abc</field>
|
||||
</shadow>
|
||||
<block type="rangefinder_distance" id="Pi+WekHZvZ0p}JY-^CLQ"></block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="wait" id="=$,8TaKwL75Pb,_tsCVU">
|
||||
<value name="TIME">
|
||||
<shadow type="math_number" id="/r+hzH#G0Ru#ES+}MxUl">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</statement>
|
||||
</block>
|
||||
</xml>
|
||||
88
clover_blocks/programs/examples/rotation.xml
Normal file
@@ -0,0 +1,88 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="take_off" id="R@=3~Fq;AxFaRO{ZDFUM" x="162" y="112">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="cf8/,N48N;Fvn@EWB%,B">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="navigate" id="[r%uJ2rw#3j.sLSBFf`N">
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="5;@1vq|;OnlHl#FFDm/}">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="Jhe8@=gRxwj0oO*Q1F7V">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="wms+rWijPhnI/K++At;P">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id=".^-h~@m]zg3il)O.9eFy">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="3L3FgAO(:aZp/:V%u=P7">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="set_yaw" id="nE,tYuHO--PmXN:*g@D%">
|
||||
<field name="FRAME_ID">body</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="YAW">
|
||||
<shadow type="angle" id="DoJ$Yj+fVT~cj=E%N:4+">
|
||||
<field name="ANGLE">180</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="navigate" id="H6W4@QtAT{_xo0.fO^z4">
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="|.KN1m1O$/3=C,WG3sx}">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="oyc7mxrbA/@[_1wtPER^">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="dh}ac~kErkIIFeIZB,)d">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="q+{la-yiw61v9BSV-y};">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id=";dk@RJGfZ)5w*:m4kp==">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="land" id="53Ssv6^lEHoD?tBO{5Sh">
|
||||
<field name="WAIT">TRUE</field>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
86
clover_blocks/programs/examples/simple-flight.xml
Normal file
@@ -0,0 +1,86 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="take_off" id="R@=3~Fq;AxFaRO{ZDFUM" x="62" y="88">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="cf8/,N48N;Fvn@EWB%,B">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
<block type="text_prompt_ext" id="#BO!OX5u-GHwsu!KzBT5">
|
||||
<mutation type="NUMBER"></mutation>
|
||||
<field name="TYPE">NUMBER</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="unay$W?6.WiDB!|[3GN3">
|
||||
<field name="TEXT">Enter flight altitude</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="navigate" id="BOHP@mRbJamp}]6/yc,n">
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="hzjq`v(`k6vZN],.8%Hf">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="FIVk1Hm_+CU8XB~t@?S;">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="B{LoNO6}MgJ.JeN+8]tR">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="w!F}PhAG[Gn;5XsIg$XL">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="AjhS9Wf?M`%}A(H_bW9K">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="navigate" id="|Aa[hh]OAUS+b7I?;3VJ">
|
||||
<field name="FRAME_ID">BODY</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="=n#)78Bd*!iJyzF=dSA*">
|
||||
<field name="NUM">-1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="YqC+GQF/[G=li}/s_o)q">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="~xsT!Ug+uMeU5F/Y4;k5">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="%WRn|02iTTwCG:zB}dSf">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="A#q.M,b1D*,13Ldp.F2w">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="land" id="_U*W_q1)l+l@#^TC%w)w">
|
||||
<field name="WAIT">TRUE</field>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
60
clover_blocks/programs/examples/takeoff-land.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="text_print" id="2p:*N].+8c=|ZJXCWVn[" x="162" y="88">
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="9H+7z4A.pZ:Zz)7}H3Y7">
|
||||
<field name="TEXT">Start mission</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="take_off" id="R@=3~Fq;AxFaRO{ZDFUM">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="cf8/,N48N;Fvn@EWB%,B">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="text_print" id="|Tdajnf]Rz@ajSW`0Skv">
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="Wqr:Hf~r2d.A%S7%%4.)">
|
||||
<field name="TEXT">Take off complete, wait</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="wait" id="-]MH9NMT#N-w!5yI1$F)">
|
||||
<value name="TIME">
|
||||
<shadow type="math_number" id="?k~ZUNcrx-iC;LFmarbm">
|
||||
<field name="NUM">3</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="text_print" id="SXJsfN{P13FL~n9;|%P:">
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="[Z5,f|El:VX5zcRaMtXa">
|
||||
<field name="TEXT">Land</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="land" id="G5+Fs.6Y4(K9Dw`wjgua">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<next>
|
||||
<block type="text_print" id="o?bvXARz^4_U0oXC-#.V">
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="`tadiS,[OZ`#f:=u.:9~">
|
||||
<field name="TEXT">Mission finished</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
137
clover_blocks/programs/examples/variables.xml
Normal file
@@ -0,0 +1,137 @@
|
||||
<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<variables>
|
||||
<variable id="]gc9ItU#$!=G*S._3$n~">start_x</variable>
|
||||
<variable id="D9Oy(29I!!k9+(#zI,4}">start_y</variable>
|
||||
</variables>
|
||||
<block type="take_off" id="X]W2Bs=WFxFsco{Yr`bH" x="87" y="88">
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="ALT">
|
||||
<shadow type="math_number" id="{7ezr;C@IT-IJ3ylt?];">
|
||||
<field name="NUM">1.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="variables_set" id="IWR_j|7pUxrIGrxGLP#Z">
|
||||
<field name="VAR" id="]gc9ItU#$!=G*S._3$n~">start_x</field>
|
||||
<value name="VALUE">
|
||||
<block type="get_position" id="ze{FI]Vv*E3kZ1Zw6Bmn">
|
||||
<field name="FIELD">X</field>
|
||||
<field name="FRAME_ID">ARUCO_MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="s~^V?k;dKa(($OG9mAK)">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="variables_set" id="s3rE=-6+;f(Lua_uKGY[">
|
||||
<field name="VAR" id="D9Oy(29I!!k9+(#zI,4}">start_y</field>
|
||||
<value name="VALUE">
|
||||
<block type="get_position" id="?t+jp;7Bk#wzoz=DY{sO">
|
||||
<field name="FIELD">Y</field>
|
||||
<field name="FRAME_ID">ARUCO_MAP</field>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="KybjD~@_RFIx=8Dzbz4v">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</value>
|
||||
<next>
|
||||
<block type="text_print" id="|xj}5M(:.~`Vpq-GKi/0">
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="{o^2v+y6L^1#[Y8r_sdW">
|
||||
<field name="TEXT">Fly to point 0, 0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="navigate" id="-8]peWQRtTK$1X0J0w!2">
|
||||
<field name="FRAME_ID">ARUCO_MAP</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id="PT`K-=?U^uL#BXouoi~G">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="d_1oBZdx#`_kbWf_Qu$g">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="}Y,E=*pJaG+HOSB*f=aX">
|
||||
<field name="NUM">1.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id=")/%?zNt|6thYwjowvbk/">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="MH}%@OvXa*FK-Vx63RTd">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="text_print" id="IVsd5hFEwp@V?3f02p},">
|
||||
<value name="TEXT">
|
||||
<shadow type="text" id="0gcgp`mZ,9oDTS[4vWpT">
|
||||
<field name="TEXT">Fly to initial point</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="navigate" id=":;b$YH+6#3h/_$Fa}0w_">
|
||||
<field name="FRAME_ID">ARUCO_MAP</field>
|
||||
<field name="WAIT">TRUE</field>
|
||||
<value name="X">
|
||||
<shadow type="math_number" id=";GL$bb^Yu;vQrhxy(o:S">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="tsqWR~saO6UU^*iLmDZ(">
|
||||
<field name="VAR" id="]gc9ItU#$!=G*S._3$n~">start_x</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Y">
|
||||
<shadow type="math_number" id="y5|y58G[s-,qnfB/@Xr%">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
<block type="variables_get" id="Hfzk#prb}M2BbEWIAX3k">
|
||||
<field name="VAR" id="D9Oy(29I!!k9+(#zI,4}">start_y</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="Z">
|
||||
<shadow type="math_number" id="B%NGa`:z=[Kpij2$0p}T">
|
||||
<field name="NUM">1.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="ID">
|
||||
<shadow type="math_number" id="KaLkf?/NkD_7q@=J1G|I">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="SPEED">
|
||||
<shadow type="math_number" id="Agwx#kYhdE}!dY!St:L1">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<next>
|
||||
<block type="land" id="8y]p?)Zm2}*+;0HP]p1$">
|
||||
<field name="WAIT">TRUE</field>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</next>
|
||||
</block>
|
||||
</xml>
|
||||
BIN
clover_blocks/screenshot.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
176
clover_blocks/src/clover_blocks
Executable file
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import rospy
|
||||
import os
|
||||
import threading
|
||||
import re
|
||||
import uuid
|
||||
from std_msgs.msg import Bool, String
|
||||
from std_srvs.srv import Trigger
|
||||
from clover_blocks.msg import Prompt
|
||||
from clover_blocks.srv import Run, Load, Store
|
||||
|
||||
|
||||
rospy.init_node('clover_blocks')
|
||||
|
||||
stop = None
|
||||
block = ''
|
||||
published_block = None
|
||||
running_lock = threading.Lock()
|
||||
|
||||
running_pub = rospy.Publisher('~running', Bool, queue_size=1, latch=True)
|
||||
block_pub = rospy.Publisher('~block', String, queue_size=1, latch=True)
|
||||
print_pub = rospy.Publisher('~print', String, queue_size=10)
|
||||
prompt_pub = rospy.Publisher('~prompt', Prompt, queue_size=10)
|
||||
error_pub = rospy.Publisher('~error', String, queue_size=10)
|
||||
|
||||
|
||||
running_pub.publish(False)
|
||||
|
||||
|
||||
class Stop(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def publish_block(event):
|
||||
global published_block, block
|
||||
if published_block != block:
|
||||
block_pub.publish(block)
|
||||
published_block = block
|
||||
|
||||
|
||||
rospy.Timer(rospy.Duration(rospy.get_param('block_rate', 0.2)), publish_block)
|
||||
|
||||
|
||||
def change_block(_block):
|
||||
global block
|
||||
block = _block
|
||||
if stop: raise Stop
|
||||
|
||||
|
||||
rospy_sleep = rospy.sleep
|
||||
|
||||
|
||||
def sleep(duration):
|
||||
time_start = rospy.get_time()
|
||||
|
||||
if isinstance(duration, rospy.Duration):
|
||||
duration = duration.to_sec()
|
||||
|
||||
time_until = time_start + duration
|
||||
|
||||
while not rospy.is_shutdown():
|
||||
if stop: raise Stop # check stop condition every half-second
|
||||
if (time_until - rospy.get_time()) > 0.5:
|
||||
print('sleep 0.5')
|
||||
rospy_sleep(0.5)
|
||||
else:
|
||||
rospy_sleep(time_until - rospy.get_time())
|
||||
return
|
||||
|
||||
|
||||
rospy.sleep = sleep
|
||||
rospy.init_node = lambda *args, **kwargs: None
|
||||
|
||||
|
||||
def _print(s):
|
||||
rospy.loginfo(str(s))
|
||||
print_pub.publish(str(s))
|
||||
|
||||
|
||||
def _input(s):
|
||||
rospy.loginfo('Input with message %s', s)
|
||||
prompt_id = str(uuid.uuid4()).replace('-', '')
|
||||
prompt_pub.publish(message=str(s), id=prompt_id)
|
||||
return rospy.wait_for_message('~input/' + prompt_id, String, timeout=30).data;
|
||||
|
||||
|
||||
def run(req):
|
||||
if not running_lock.acquire(False):
|
||||
return {'message': 'Already running'}
|
||||
|
||||
try:
|
||||
rospy.loginfo('Run program')
|
||||
running_pub.publish(True)
|
||||
|
||||
def program_thread():
|
||||
global stop
|
||||
stop = False
|
||||
g = {'rospy': rospy,
|
||||
'_b': change_block,
|
||||
'print': _print,
|
||||
'raw_input': _input}
|
||||
try:
|
||||
exec req.code in g
|
||||
except Stop:
|
||||
rospy.loginfo('Program forced to stop')
|
||||
except Exception as e:
|
||||
rospy.logerr(str(e))
|
||||
error_pub.publish(str(e))
|
||||
|
||||
rospy.loginfo('Program terminated')
|
||||
running_lock.release()
|
||||
running_pub.publish(False)
|
||||
change_block('')
|
||||
|
||||
t = threading.Thread(target=program_thread)
|
||||
t.start()
|
||||
|
||||
return {'success': True}
|
||||
|
||||
except Exception as e:
|
||||
running_lock.release()
|
||||
return {'message': str(e)}
|
||||
|
||||
|
||||
def stop(req):
|
||||
global stop
|
||||
rospy.loginfo('Stop program')
|
||||
stop = True
|
||||
return {'success': True}
|
||||
|
||||
|
||||
programs_path = rospy.get_param('~programs_dir', os.path.dirname(os.path.abspath(__file__)) + '/../programs')
|
||||
|
||||
|
||||
def load(req):
|
||||
res = {'names': [], 'programs': [], 'success': True}
|
||||
try:
|
||||
for currentpath, folders, files in os.walk(programs_path):
|
||||
for f in files:
|
||||
if not f.endswith('.xml'):
|
||||
continue
|
||||
filename = os.path.join(currentpath, f)
|
||||
res['names'].append(os.path.relpath(filename, programs_path))
|
||||
res['programs'].append(open(filename, 'r').read())
|
||||
return res
|
||||
except Exception as e:
|
||||
rospy.logerr(e)
|
||||
return {'names': [], 'programs': [], 'message': str(e)}
|
||||
|
||||
|
||||
name_regexp = re.compile(r'^[a-zA-Z-_.]{0,20}$')
|
||||
|
||||
def store(req):
|
||||
if not name_regexp.match(req.name):
|
||||
return {'message': 'Bad program name'}
|
||||
|
||||
filename = os.path.abspath(os.path.join(programs_path, req.name))
|
||||
try:
|
||||
open(filename, 'w').write(req.program)
|
||||
return {'success': True, 'message': 'Stored to ' + filename}
|
||||
except Exception as e:
|
||||
rospy.logerr(e)
|
||||
return {'names': [], 'programs': [], 'message': str(e)}
|
||||
|
||||
|
||||
rospy.Service('~run', Run, run)
|
||||
rospy.Service('~stop', Trigger, stop)
|
||||
rospy.Service('~load', Load, load)
|
||||
rospy.Service('~store', Store, store)
|
||||
|
||||
|
||||
rospy.loginfo('Ready')
|
||||
rospy.spin()
|
||||
5
clover_blocks/srv/Load.srv
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
bool success
|
||||
string message
|
||||
string[] names
|
||||
string[] programs
|
||||
4
clover_blocks/srv/Run.srv
Normal file
@@ -0,0 +1,4 @@
|
||||
string code # code in Python
|
||||
---
|
||||
bool success
|
||||
string message
|
||||
5
clover_blocks/srv/Store.srv
Normal file
@@ -0,0 +1,5 @@
|
||||
string name
|
||||
string program
|
||||
---
|
||||
bool success
|
||||
string message
|
||||
202
clover_blocks/www/blockly/LICENSE
Executable file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
60
clover_blocks/www/blockly/README.md
Executable file
@@ -0,0 +1,60 @@
|
||||
# Blockly [](https://travis-ci.org/google/blockly)
|
||||
|
||||
|
||||
Google's Blockly is a web-based, visual programming editor. Users can drag
|
||||
blocks together to build programs. All code is free and open source.
|
||||
|
||||
**The project page is https://developers.google.com/blockly/**
|
||||
|
||||

|
||||
|
||||
Blockly has an active [developer forum](https://groups.google.com/forum/#!forum/blockly). Please drop by and say hello. Show us your prototypes early; collectively we have a lot of experience and can offer hints which will save you time. We actively monitor the forums and typically respond to questions within 2 working days.
|
||||
|
||||
Help us focus our development efforts by telling us [what you are doing with
|
||||
Blockly](https://developers.google.com/blockly/registration). The questionnaire only takes
|
||||
a few minutes and will help us better support the Blockly community.
|
||||
|
||||
Cross-browser Testing Platform and Open Source <3 Provided by [Sauce Labs](https://saucelabs.com)
|
||||
|
||||
We support IE11 and test it using [BrowserStack](https://browserstack.com)
|
||||
|
||||
Want to contribute? Great! First, read [our guidelines for contributors](https://developers.google.com/blockly/guides/modify/contributing).
|
||||
|
||||
## Releases
|
||||
|
||||
The next major release will be **June 26th, 2020**.
|
||||
|
||||
We release by pushing the latest code to the master branch, followed by updating our [docs](https://developers.google.com/blockly) and [demo pages](https://blockly-demo.appspot.com). We typically release a new version of Blockly once a quarter (every 3 months). If there are breaking bugs, such as a crash when performing a standard action or a rendering issue that makes Blockly unusable, we will cherry-pick fixes to master between releases to fix them. The [releases page](https://github.com/google/blockly/releases) has a list of all releases.
|
||||
|
||||
Releases are tagged by the release date (YYYYMMDD) with a leading '2.' and a trailing '.0' in case we ever need a major or minor version (such as [2.20190722.1](https://github.com/google/blockly/tree/2.20190722.1)). If you're using npm, you can install the ``blockly`` package on npm:
|
||||
```bash
|
||||
npm install blockly
|
||||
```
|
||||
|
||||
### New APIs
|
||||
|
||||
Once a new API is merged into master it is considered beta until the following release. We generally try to avoid changing an API after it has been merged to master, but sometimes we need to make changes after seeing how an API is used. If an API has been around for at least two releases we'll do our best to avoid breaking it.
|
||||
|
||||
Unreleased APIs may change radically. Anything that is in `develop` but not `master` is subject to change without warning.
|
||||
|
||||
### Branches
|
||||
|
||||
There are two main branches for Blockly.
|
||||
|
||||
**[master](https://github.com/google/blockly)** - This is the (mostly) stable current release of Blockly.
|
||||
|
||||
**[develop](https://github.com/google/blockly/tree/develop)** - This is where most of our work happens. Pull requests should always be made against develop. This branch will generally be usable, but may be less stable than the master branch. Once something is in develop we expect it to merge to master in the next release.
|
||||
|
||||
**other branches:** - Larger changes may have their own branches until they are good enough for people to try out. These will be developed separately until we think they are almost ready for release. These branches typically get merged into develop immediately after a release to allow extra time for testing.
|
||||
|
||||
## Issues and Milestones
|
||||
|
||||
We typically triage all bugs within 2 working days, which includes adding any appropriate labels and assigning it to a milestone. Please keep in mind, we are a small team so even feature requests that everyone agrees on may not be prioritized.
|
||||
|
||||
### Milestones
|
||||
|
||||
**Upcoming release** - The upcoming release milestone is for all bugs we plan on fixing before the next release. This typically has the form of `year_quarter_release` (such as `2019_q2_release`). Some bugs will be added to this release when they are triaged, others may be added closer to a release.
|
||||
|
||||
**Bug Bash Backlog** - These are bugs that we're still prioritizing. They haven't been added to a specific release yet, but we'll consider them for each release depending on relative priority and available time.
|
||||
|
||||
**Icebox** - These are bugs that we do not intend to spend time on. They are either too much work or minor enough that we don't expect them to ever take priority. We are still happy to accept pull requests for these bugs.
|
||||
1409
clover_blocks/www/blockly/blockly_compressed.js
Executable file
1
clover_blocks/www/blockly/blockly_compressed.js.map
Executable file
182
clover_blocks/www/blockly/blocks_compressed.js
Executable file
@@ -0,0 +1,182 @@
|
||||
// Do not edit this file; automatically generated by gulp.
|
||||
|
||||
/* eslint-disable */
|
||||
;(function(root, factory) {
|
||||
if (typeof define === 'function' && define.amd) { // AMD
|
||||
define(['./blockly_compressed.js'], factory);
|
||||
} else if (typeof exports === 'object') { // Node.js
|
||||
module.exports = factory(require('./blockly_compressed.js'));
|
||||
} else { // Browser
|
||||
root.Blockly.Blocks = factory(root.Blockly);
|
||||
}
|
||||
}(this, function(Blockly) {
|
||||
'use strict';Blockly.Blocks.colour={};Blockly.Constants={};Blockly.Constants.Colour={};Blockly.Constants.Colour.HUE=20;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"colour_picker",message0:"%1",args0:[{type:"field_colour",name:"COLOUR",colour:"#ff0000"}],output:"Colour",helpUrl:"%{BKY_COLOUR_PICKER_HELPURL}",style:"colour_blocks",tooltip:"%{BKY_COLOUR_PICKER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"colour_random",message0:"%{BKY_COLOUR_RANDOM_TITLE}",output:"Colour",helpUrl:"%{BKY_COLOUR_RANDOM_HELPURL}",style:"colour_blocks",tooltip:"%{BKY_COLOUR_RANDOM_TOOLTIP}"},{type:"colour_rgb",message0:"%{BKY_COLOUR_RGB_TITLE} %{BKY_COLOUR_RGB_RED} %1 %{BKY_COLOUR_RGB_GREEN} %2 %{BKY_COLOUR_RGB_BLUE} %3",
|
||||
args0:[{type:"input_value",name:"RED",check:"Number",align:"RIGHT"},{type:"input_value",name:"GREEN",check:"Number",align:"RIGHT"},{type:"input_value",name:"BLUE",check:"Number",align:"RIGHT"}],output:"Colour",helpUrl:"%{BKY_COLOUR_RGB_HELPURL}",style:"colour_blocks",tooltip:"%{BKY_COLOUR_RGB_TOOLTIP}"},{type:"colour_blend",message0:"%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} %1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3",args0:[{type:"input_value",name:"COLOUR1",check:"Colour",
|
||||
align:"RIGHT"},{type:"input_value",name:"COLOUR2",check:"Colour",align:"RIGHT"},{type:"input_value",name:"RATIO",check:"Number",align:"RIGHT"}],output:"Colour",helpUrl:"%{BKY_COLOUR_BLEND_HELPURL}",style:"colour_blocks",tooltip:"%{BKY_COLOUR_BLEND_TOOLTIP}"}]);Blockly.Blocks.lists={};Blockly.Constants.Lists={};Blockly.Constants.Lists.HUE=260;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"lists_create_empty",message0:"%{BKY_LISTS_CREATE_EMPTY_TITLE}",output:"Array",style:"list_blocks",tooltip:"%{BKY_LISTS_CREATE_EMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_CREATE_EMPTY_HELPURL}"},{type:"lists_repeat",message0:"%{BKY_LISTS_REPEAT_TITLE}",args0:[{type:"input_value",name:"ITEM"},{type:"input_value",name:"NUM",check:"Number"}],output:"Array",style:"list_blocks",tooltip:"%{BKY_LISTS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_LISTS_REPEAT_HELPURL}"},{type:"lists_reverse",
|
||||
message0:"%{BKY_LISTS_REVERSE_MESSAGE0}",args0:[{type:"input_value",name:"LIST",check:"Array"}],output:"Array",inputsInline:!0,style:"list_blocks",tooltip:"%{BKY_LISTS_REVERSE_TOOLTIP}",helpUrl:"%{BKY_LISTS_REVERSE_HELPURL}"},{type:"lists_isEmpty",message0:"%{BKY_LISTS_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Boolean",style:"list_blocks",tooltip:"%{BKY_LISTS_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_ISEMPTY_HELPURL}"},{type:"lists_length",message0:"%{BKY_LISTS_LENGTH_TITLE}",
|
||||
args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",style:"list_blocks",tooltip:"%{BKY_LISTS_LENGTH_TOOLTIP}",helpUrl:"%{BKY_LISTS_LENGTH_HELPURL}"}]);
|
||||
Blockly.Blocks.lists_create_with={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);this.setStyle("list_blocks");this.itemCount_=3;this.updateShape_();this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP)},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),
|
||||
10);this.updateShape_()},decompose:function(a){var b=a.newBlock("lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("lists_create_with_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;
|
||||
c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||
|
||||
this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a).setAlign(Blockly.ALIGN_RIGHT);0==a&&b.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH)}for(;this.getInput("ADD"+a);)this.removeInput("ADD"+a),a++}};
|
||||
Blockly.Blocks.lists_create_with_container={init:function(){this.setStyle("list_blocks");this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);this.appendStatementInput("STACK");this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);this.contextMenu=!1}};
|
||||
Blockly.Blocks.lists_create_with_item={init:function(){this.setStyle("list_blocks");this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);this.contextMenu=!1}};
|
||||
Blockly.Blocks.lists_indexOf={init:function(){var a=[[Blockly.Msg.LISTS_INDEX_OF_FIRST,"FIRST"],[Blockly.Msg.LISTS_INDEX_OF_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_INDEX_OF_HELPURL);this.setStyle("list_blocks");this.setOutput(!0,"Number");this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST);this.appendValueInput("FIND").appendField(new Blockly.FieldDropdown(a),"END");this.setInputsInline(!0);var b=this;this.setTooltip(function(){return Blockly.Msg.LISTS_INDEX_OF_TOOLTIP.replace("%1",
|
||||
b.workspace.options.oneBasedIndex?"0":"-1")})}};
|
||||
Blockly.Blocks.lists_getIndex={init:function(){var a=[[Blockly.Msg.LISTS_GET_INDEX_GET,"GET"],[Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE,"GET_REMOVE"],[Blockly.Msg.LISTS_GET_INDEX_REMOVE,"REMOVE"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);this.setStyle("list_blocks");
|
||||
a=new Blockly.FieldDropdown(a,function(a){a="REMOVE"==a;this.getSourceBlock().updateStatement_(a)});this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST);this.appendDummyInput().appendField(a,"MODE").appendField("","SPACE");this.appendDummyInput("AT");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);this.setInputsInline(!0);this.setOutput(!0);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=
|
||||
b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "GET FROM_START":case "GET FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM;break;case "GET FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST;break;case "GET LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST;break;case "GET RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM;break;case "GET_REMOVE FROM_START":case "GET_REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM;break;case "GET_REMOVE FIRST":e=
|
||||
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST;break;case "GET_REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST;break;case "GET_REMOVE RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM;break;case "REMOVE FROM_START":case "REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM;break;case "REMOVE FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST;break;case "REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST;break;case "REMOVE RANDOM":e=
|
||||
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+("FROM_START"==d?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP).replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("statement",!this.outputConnection);var b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){var b=
|
||||
"true"==a.getAttribute("statement");this.updateStatement_(b);a="false"!=a.getAttribute("at");this.updateAt_(a)},updateStatement_:function(a){a!=!this.outputConnection&&(this.unplug(!0,!0),a?(this.setOutput(!1),this.setPreviousStatement(!0),this.setNextStatement(!0)):(this.setPreviousStatement(!1),this.setNextStatement(!1),this.setOutput(!0)))},updateAt_:function(a){this.removeInput("AT");this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&
|
||||
this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.getSourceBlock();e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.getInput("AT").appendField(b,"WHERE");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.moveInputBefore("TAIL",null)}};
|
||||
Blockly.Blocks.lists_setIndex={init:function(){var a=[[Blockly.Msg.LISTS_SET_INDEX_SET,"SET"],[Blockly.Msg.LISTS_SET_INDEX_INSERT,"INSERT"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_SET_INDEX_HELPURL);this.setStyle("list_blocks");this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST);
|
||||
this.appendDummyInput().appendField(new Blockly.FieldDropdown(a),"MODE").appendField("","SPACE");this.appendDummyInput("AT");this.appendValueInput("TO").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_TO);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_SET_INDEX_TOOLTIP);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "SET FROM_START":case "SET FROM_END":e=
|
||||
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM;break;case "SET FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST;break;case "SET LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST;break;case "SET RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM;break;case "INSERT FROM_START":case "INSERT FROM_END":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM;break;case "INSERT FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST;break;case "INSERT LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST;
|
||||
break;case "INSERT RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP.replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation"),b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT");
|
||||
this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.getSourceBlock();e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.moveInputBefore("AT","TO");this.getInput("ORDINAL")&&this.moveInputBefore("ORDINAL",
|
||||
"TO");this.getInput("AT").appendField(b,"WHERE")}};
|
||||
Blockly.Blocks.lists_getSublist={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);this.setStyle("list_blocks");
|
||||
this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);this.setInputsInline(!0);this.setOutput(!0,"Array");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP)},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation"),
|
||||
b=this.getInput("AT1").type==Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT"+a);var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var e="FROM_START"==c||"FROM_END"==c;if(e!=b){var d=this.getSourceBlock();d.updateAt_(a,e);d.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&this.moveInputBefore("ORDINAL1","AT2"));Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.moveInputBefore("TAIL",null)}};
|
||||
Blockly.Blocks.lists_sort={init:function(){this.jsonInit({message0:Blockly.Msg.LISTS_SORT_TITLE,args0:[{type:"field_dropdown",name:"TYPE",options:[[Blockly.Msg.LISTS_SORT_TYPE_NUMERIC,"NUMERIC"],[Blockly.Msg.LISTS_SORT_TYPE_TEXT,"TEXT"],[Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE,"IGNORE_CASE"]]},{type:"field_dropdown",name:"DIRECTION",options:[[Blockly.Msg.LISTS_SORT_ORDER_ASCENDING,"1"],[Blockly.Msg.LISTS_SORT_ORDER_DESCENDING,"-1"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Array",style:"list_blocks",
|
||||
tooltip:Blockly.Msg.LISTS_SORT_TOOLTIP,helpUrl:Blockly.Msg.LISTS_SORT_HELPURL})}};
|
||||
Blockly.Blocks.lists_split={init:function(){var a=this,b=new Blockly.FieldDropdown([[Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT,"SPLIT"],[Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST,"JOIN"]],function(b){a.updateType_(b)});this.setHelpUrl(Blockly.Msg.LISTS_SPLIT_HELPURL);this.setStyle("list_blocks");this.appendValueInput("INPUT").setCheck("String").appendField(b,"MODE");this.appendValueInput("DELIM").setCheck("String").appendField(Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER);this.setInputsInline(!0);this.setOutput(!0,
|
||||
"Array");this.setTooltip(function(){var b=a.getFieldValue("MODE");if("SPLIT"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT;if("JOIN"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN;throw Error("Unknown mode: "+b);})},updateType_:function(a){if(this.getFieldValue("MODE")!=a){var b=this.getInput("INPUT").connection;b.setShadowDom(null);var c=b.targetBlock();c&&(b.disconnect(),c.isShadow()?c.dispose():this.bumpNeighbours())}"SPLIT"==a?(this.outputConnection.setCheck("Array"),this.getInput("INPUT").setCheck("String")):
|
||||
(this.outputConnection.setCheck("String"),this.getInput("INPUT").setCheck("Array"))},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("mode",this.getFieldValue("MODE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("mode"))}};Blockly.Blocks.logic={};Blockly.Constants.Logic={};Blockly.Constants.Logic.HUE=210;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"logic_boolean",message0:"%1",args0:[{type:"field_dropdown",name:"BOOL",options:[["%{BKY_LOGIC_BOOLEAN_TRUE}","TRUE"],["%{BKY_LOGIC_BOOLEAN_FALSE}","FALSE"]]}],output:"Boolean",style:"logic_blocks",tooltip:"%{BKY_LOGIC_BOOLEAN_TOOLTIP}",helpUrl:"%{BKY_LOGIC_BOOLEAN_HELPURL}"},{type:"controls_if",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",
|
||||
name:"DO0"}],previousStatement:null,nextStatement:null,style:"logic_blocks",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",mutator:"controls_if_mutator",extensions:["controls_if_tooltip"]},{type:"controls_ifelse",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",name:"DO0"}],message2:"%{BKY_CONTROLS_IF_MSG_ELSE} %1",args2:[{type:"input_statement",name:"ELSE"}],previousStatement:null,nextStatement:null,
|
||||
style:"logic_blocks",tooltip:"%{BKYCONTROLS_IF_TOOLTIP_2}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",extensions:["controls_if_tooltip"]},{type:"logic_compare",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A"},{type:"field_dropdown",name:"OP",options:[["=","EQ"],["\u2260","NEQ"],["\u200f<","LT"],["\u200f\u2264","LTE"],["\u200f>","GT"],["\u200f\u2265","GTE"]]},{type:"input_value",name:"B"}],inputsInline:!0,output:"Boolean",style:"logic_blocks",helpUrl:"%{BKY_LOGIC_COMPARE_HELPURL}",extensions:["logic_compare",
|
||||
"logic_op_tooltip"]},{type:"logic_operation",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Boolean"},{type:"field_dropdown",name:"OP",options:[["%{BKY_LOGIC_OPERATION_AND}","AND"],["%{BKY_LOGIC_OPERATION_OR}","OR"]]},{type:"input_value",name:"B",check:"Boolean"}],inputsInline:!0,output:"Boolean",style:"logic_blocks",helpUrl:"%{BKY_LOGIC_OPERATION_HELPURL}",extensions:["logic_op_tooltip"]},{type:"logic_negate",message0:"%{BKY_LOGIC_NEGATE_TITLE}",args0:[{type:"input_value",name:"BOOL",
|
||||
check:"Boolean"}],output:"Boolean",style:"logic_blocks",tooltip:"%{BKY_LOGIC_NEGATE_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NEGATE_HELPURL}"},{type:"logic_null",message0:"%{BKY_LOGIC_NULL}",output:null,style:"logic_blocks",tooltip:"%{BKY_LOGIC_NULL_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NULL_HELPURL}"},{type:"logic_ternary",message0:"%{BKY_LOGIC_TERNARY_CONDITION} %1",args0:[{type:"input_value",name:"IF",check:"Boolean"}],message1:"%{BKY_LOGIC_TERNARY_IF_TRUE} %1",args1:[{type:"input_value",name:"THEN"}],message2:"%{BKY_LOGIC_TERNARY_IF_FALSE} %1",
|
||||
args2:[{type:"input_value",name:"ELSE"}],output:null,style:"logic_blocks",tooltip:"%{BKY_LOGIC_TERNARY_TOOLTIP}",helpUrl:"%{BKY_LOGIC_TERNARY_HELPURL}",extensions:["logic_ternary"]}]);
|
||||
Blockly.defineBlocksWithJsonArray([{type:"controls_if_if",message0:"%{BKY_CONTROLS_IF_IF_TITLE_IF}",nextStatement:null,enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_IF_TOOLTIP}"},{type:"controls_if_elseif",message0:"%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}",previousStatement:null,nextStatement:null,enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}"},{type:"controls_if_else",message0:"%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}",previousStatement:null,
|
||||
enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_ELSE_TOOLTIP}"}]);Blockly.Constants.Logic.TOOLTIPS_BY_OP={EQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_EQ}",NEQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_NEQ}",LT:"%{BKY_LOGIC_COMPARE_TOOLTIP_LT}",LTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_LTE}",GT:"%{BKY_LOGIC_COMPARE_TOOLTIP_GT}",GTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_GTE}",AND:"%{BKY_LOGIC_OPERATION_TOOLTIP_AND}",OR:"%{BKY_LOGIC_OPERATION_TOOLTIP_OR}"};
|
||||
Blockly.Extensions.register("logic_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Logic.TOOLTIPS_BY_OP));
|
||||
Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN={elseifCount_:0,elseCount_:0,suppressPrefixSuffix:!0,mutationToDom:function(){if(!this.elseifCount_&&!this.elseCount_)return null;var a=Blockly.utils.xml.createElement("mutation");this.elseifCount_&&a.setAttribute("elseif",this.elseifCount_);this.elseCount_&&a.setAttribute("else",1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10)||0;this.elseCount_=parseInt(a.getAttribute("else"),10)||0;this.rebuildShape_()},
|
||||
decompose:function(a){var b=a.newBlock("controls_if_if");b.initSvg();for(var c=b.nextConnection,d=1;d<=this.elseifCount_;d++){var e=a.newBlock("controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=a.newBlock("controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){a=a.nextConnection.targetBlock();this.elseCount_=this.elseifCount_=0;for(var b=[null],c=[null],d=null;a;){switch(a.type){case "controls_if_elseif":this.elseifCount_++;
|
||||
b.push(a.valueConnection_);c.push(a.statementConnection_);break;case "controls_if_else":this.elseCount_++;d=a.statementConnection_;break;default:throw TypeError("Unknown block type: "+a.type);}a=a.nextConnection&&a.nextConnection.targetBlock()}this.updateShape_();this.reconnectChildBlocks_(b,c,d)},saveConnections:function(a){a=a.nextConnection.targetBlock();for(var b=1;a;){switch(a.type){case "controls_if_elseif":var c=this.getInput("IF"+b),d=this.getInput("DO"+b);a.valueConnection_=c&&c.connection.targetConnection;
|
||||
a.statementConnection_=d&&d.connection.targetConnection;b++;break;case "controls_if_else":d=this.getInput("ELSE");a.statementConnection_=d&&d.connection.targetConnection;break;default:throw TypeError("Unknown block type: "+a.type);}a=a.nextConnection&&a.nextConnection.targetBlock()}},rebuildShape_:function(){var a=[null],b=[null],c=null;this.getInput("ELSE")&&(c=this.getInput("ELSE").connection.targetConnection);for(var d=1;this.getInput("IF"+d);){var e=this.getInput("IF"+d),f=this.getInput("DO"+
|
||||
d);a.push(e.connection.targetConnection);b.push(f.connection.targetConnection);d++}this.updateShape_();this.reconnectChildBlocks_(a,b,c)},updateShape_:function(){this.getInput("ELSE")&&this.removeInput("ELSE");for(var a=1;this.getInput("IF"+a);)this.removeInput("IF"+a),this.removeInput("DO"+a),a++;for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
|
||||
this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)},reconnectChildBlocks_:function(a,b,c){for(var d=1;d<=this.elseifCount_;d++)Blockly.Mutator.reconnect(a[d],this,"IF"+d),Blockly.Mutator.reconnect(b[d],this,"DO"+d);Blockly.Mutator.reconnect(c,this,"ELSE")}};Blockly.Extensions.registerMutator("controls_if_mutator",Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN,null,["controls_if_elseif","controls_if_else"]);
|
||||
Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){if(this.elseifCount_||this.elseCount_){if(!this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;if(this.elseifCount_&&!this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;if(this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_4}else return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;return""}.bind(this))};Blockly.Extensions.register("controls_if_tooltip",Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION);
|
||||
Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN={onchange:function(a){this.prevBlocks_||(this.prevBlocks_=[null,null]);var b=this.getInputTargetBlock("A"),c=this.getInputTargetBlock("B");b&&c&&!b.outputConnection.checkType(c.outputConnection)&&(Blockly.Events.setGroup(a.group),a=this.prevBlocks_[0],a!==b&&(b.unplug(),!a||a.isDisposed()||a.isShadow()||this.getInput("A").connection.connect(a.outputConnection)),b=this.prevBlocks_[1],b!==c&&(c.unplug(),!b||b.isDisposed()||b.isShadow()||this.getInput("B").connection.connect(b.outputConnection)),
|
||||
this.bumpNeighbours(),Blockly.Events.setGroup(!1));this.prevBlocks_[0]=this.getInputTargetBlock("A");this.prevBlocks_[1]=this.getInputTargetBlock("B")}};Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION=function(){this.mixin(Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN)};Blockly.Extensions.register("logic_compare",Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION);
|
||||
Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN={prevParentConnection_:null,onchange:function(a){var b=this.getInputTargetBlock("THEN"),c=this.getInputTargetBlock("ELSE"),d=this.outputConnection.targetConnection;if((b||c)&&d)for(var e=0;2>e;e++){var f=1==e?b:c;f&&!f.outputConnection.checkType(d)&&(Blockly.Events.setGroup(a.group),d===this.prevParentConnection_?(this.unplug(),d.getSourceBlock().bumpNeighbours()):(f.unplug(),f.bumpNeighbours()),Blockly.Events.setGroup(!1))}this.prevParentConnection_=
|
||||
d}};Blockly.Extensions.registerMixin("logic_ternary",Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);Blockly.Blocks.loops={};Blockly.Constants.Loops={};Blockly.Constants.Loops.HUE=120;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"controls_repeat_ext",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"input_value",name:"TIMES",check:"Number"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_repeat",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"field_number",name:"TIMES",value:10,
|
||||
min:0,precision:1}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_whileUntil",message0:"%1 %2",args0:[{type:"field_dropdown",name:"MODE",options:[["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}","WHILE"],["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}","UNTIL"]]},{type:"input_value",name:"BOOL",check:"Boolean"}],
|
||||
message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_WHILEUNTIL_HELPURL}",extensions:["controls_whileUntil_tooltip"]},{type:"controls_for",message0:"%{BKY_CONTROLS_FOR_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"FROM",check:"Number",align:"RIGHT"},{type:"input_value",name:"TO",check:"Number",align:"RIGHT"},{type:"input_value",name:"BY",
|
||||
check:"Number",align:"RIGHT"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],inputsInline:!0,previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FOR_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_for_tooltip"]},{type:"controls_forEach",message0:"%{BKY_CONTROLS_FOREACH_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"LIST",check:"Array"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
|
||||
args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FOREACH_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_forEach_tooltip"]},{type:"controls_flow_statements",message0:"%1",args0:[{type:"field_dropdown",name:"FLOW",options:[["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}","BREAK"],["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}","CONTINUE"]]}],previousStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}",
|
||||
extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS={WHILE:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",UNTIL:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"};Blockly.Extensions.register("controls_whileUntil_tooltip",Blockly.Extensions.buildTooltipForDropdown("MODE",Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS={BREAK:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",CONTINUE:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"};
|
||||
Blockly.Extensions.register("controls_flow_tooltip",Blockly.Extensions.buildTooltipForDropdown("FLOW",Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
|
||||
Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){var b=this.getField("VAR").getVariable(),c=b.name;if(!this.isCollapsed()&&null!=c){var d={enabled:!0};d.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c);b=Blockly.Variables.generateVariableFieldDom(b);c=Blockly.utils.xml.createElement("block");c.setAttribute("type","variables_get");c.appendChild(b);d.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(d)}}}};
|
||||
Blockly.Extensions.registerMixin("contextMenu_newGetVariableBlock",Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);Blockly.Extensions.register("controls_for_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOR_TOOLTIP}","VAR"));Blockly.Extensions.register("controls_forEach_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOREACH_TOOLTIP}","VAR"));
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],suppressPrefixSuffix:!0,getSurroundLoop:function(a){do{if(-1!=Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.indexOf(a.type))return a;a=a.getSurroundParent()}while(a);return null},onchange:function(a){if(this.workspace.isDragging&&!this.workspace.isDragging()&&a.type==Blockly.Events.BLOCK_MOVE&&a.blockId==this.id){var b=
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(this);this.setWarningText(b?null:Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING);if(!this.isInFlyout){var c=Blockly.Events.getGroup();Blockly.Events.setGroup(a.group);this.setEnabled(b);Blockly.Events.setGroup(c)}}}};Blockly.Extensions.registerMixin("controls_flow_in_loop_check",Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);Blockly.Blocks.math={};Blockly.Constants.Math={};Blockly.Constants.Math.HUE=230;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"math_number",message0:"%1",args0:[{type:"field_number",name:"NUM",value:0}],output:"Number",helpUrl:"%{BKY_MATH_NUMBER_HELPURL}",style:"math_blocks",tooltip:"%{BKY_MATH_NUMBER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"math_arithmetic",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Number"},{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ADDITION_SYMBOL}","ADD"],["%{BKY_MATH_SUBTRACTION_SYMBOL}","MINUS"],["%{BKY_MATH_MULTIPLICATION_SYMBOL}",
|
||||
"MULTIPLY"],["%{BKY_MATH_DIVISION_SYMBOL}","DIVIDE"],["%{BKY_MATH_POWER_SYMBOL}","POWER"]]},{type:"input_value",name:"B",check:"Number"}],inputsInline:!0,output:"Number",style:"math_blocks",helpUrl:"%{BKY_MATH_ARITHMETIC_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_single",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_SINGLE_OP_ROOT}","ROOT"],["%{BKY_MATH_SINGLE_OP_ABSOLUTE}","ABS"],["-","NEG"],["ln","LN"],["log10","LOG10"],["e^","EXP"],["10^","POW10"]]},
|
||||
{type:"input_value",name:"NUM",check:"Number"}],output:"Number",style:"math_blocks",helpUrl:"%{BKY_MATH_SINGLE_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_trig",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_TRIG_SIN}","SIN"],["%{BKY_MATH_TRIG_COS}","COS"],["%{BKY_MATH_TRIG_TAN}","TAN"],["%{BKY_MATH_TRIG_ASIN}","ASIN"],["%{BKY_MATH_TRIG_ACOS}","ACOS"],["%{BKY_MATH_TRIG_ATAN}","ATAN"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",style:"math_blocks",
|
||||
helpUrl:"%{BKY_MATH_TRIG_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_constant",message0:"%1",args0:[{type:"field_dropdown",name:"CONSTANT",options:[["\u03c0","PI"],["e","E"],["\u03c6","GOLDEN_RATIO"],["sqrt(2)","SQRT2"],["sqrt(\u00bd)","SQRT1_2"],["\u221e","INFINITY"]]}],output:"Number",style:"math_blocks",tooltip:"%{BKY_MATH_CONSTANT_TOOLTIP}",helpUrl:"%{BKY_MATH_CONSTANT_HELPURL}"},{type:"math_number_property",message0:"%1 %2",args0:[{type:"input_value",name:"NUMBER_TO_CHECK",check:"Number"},
|
||||
{type:"field_dropdown",name:"PROPERTY",options:[["%{BKY_MATH_IS_EVEN}","EVEN"],["%{BKY_MATH_IS_ODD}","ODD"],["%{BKY_MATH_IS_PRIME}","PRIME"],["%{BKY_MATH_IS_WHOLE}","WHOLE"],["%{BKY_MATH_IS_POSITIVE}","POSITIVE"],["%{BKY_MATH_IS_NEGATIVE}","NEGATIVE"],["%{BKY_MATH_IS_DIVISIBLE_BY}","DIVISIBLE_BY"]]}],inputsInline:!0,output:"Boolean",style:"math_blocks",tooltip:"%{BKY_MATH_IS_TOOLTIP}",mutator:"math_is_divisibleby_mutator"},{type:"math_change",message0:"%{BKY_MATH_CHANGE_TITLE}",args0:[{type:"field_variable",
|
||||
name:"VAR",variable:"%{BKY_MATH_CHANGE_TITLE_ITEM}"},{type:"input_value",name:"DELTA",check:"Number"}],previousStatement:null,nextStatement:null,style:"variable_blocks",helpUrl:"%{BKY_MATH_CHANGE_HELPURL}",extensions:["math_change_tooltip"]},{type:"math_round",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ROUND_OPERATOR_ROUND}","ROUND"],["%{BKY_MATH_ROUND_OPERATOR_ROUNDUP}","ROUNDUP"],["%{BKY_MATH_ROUND_OPERATOR_ROUNDDOWN}","ROUNDDOWN"]]},{type:"input_value",name:"NUM",
|
||||
check:"Number"}],output:"Number",style:"math_blocks",helpUrl:"%{BKY_MATH_ROUND_HELPURL}",tooltip:"%{BKY_MATH_ROUND_TOOLTIP}"},{type:"math_on_list",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ONLIST_OPERATOR_SUM}","SUM"],["%{BKY_MATH_ONLIST_OPERATOR_MIN}","MIN"],["%{BKY_MATH_ONLIST_OPERATOR_MAX}","MAX"],["%{BKY_MATH_ONLIST_OPERATOR_AVERAGE}","AVERAGE"],["%{BKY_MATH_ONLIST_OPERATOR_MEDIAN}","MEDIAN"],["%{BKY_MATH_ONLIST_OPERATOR_MODE}","MODE"],["%{BKY_MATH_ONLIST_OPERATOR_STD_DEV}",
|
||||
"STD_DEV"],["%{BKY_MATH_ONLIST_OPERATOR_RANDOM}","RANDOM"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Number",style:"math_blocks",helpUrl:"%{BKY_MATH_ONLIST_HELPURL}",mutator:"math_modes_of_list_mutator",extensions:["math_op_tooltip"]},{type:"math_modulo",message0:"%{BKY_MATH_MODULO_TITLE}",args0:[{type:"input_value",name:"DIVIDEND",check:"Number"},{type:"input_value",name:"DIVISOR",check:"Number"}],inputsInline:!0,output:"Number",style:"math_blocks",tooltip:"%{BKY_MATH_MODULO_TOOLTIP}",
|
||||
helpUrl:"%{BKY_MATH_MODULO_HELPURL}"},{type:"math_constrain",message0:"%{BKY_MATH_CONSTRAIN_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"Number"},{type:"input_value",name:"LOW",check:"Number"},{type:"input_value",name:"HIGH",check:"Number"}],inputsInline:!0,output:"Number",style:"math_blocks",tooltip:"%{BKY_MATH_CONSTRAIN_TOOLTIP}",helpUrl:"%{BKY_MATH_CONSTRAIN_HELPURL}"},{type:"math_random_int",message0:"%{BKY_MATH_RANDOM_INT_TITLE}",args0:[{type:"input_value",name:"FROM",check:"Number"},
|
||||
{type:"input_value",name:"TO",check:"Number"}],inputsInline:!0,output:"Number",style:"math_blocks",tooltip:"%{BKY_MATH_RANDOM_INT_TOOLTIP}",helpUrl:"%{BKY_MATH_RANDOM_INT_HELPURL}"},{type:"math_random_float",message0:"%{BKY_MATH_RANDOM_FLOAT_TITLE_RANDOM}",output:"Number",style:"math_blocks",tooltip:"%{BKY_MATH_RANDOM_FLOAT_TOOLTIP}",helpUrl:"%{BKY_MATH_RANDOM_FLOAT_HELPURL}"},{type:"math_atan2",message0:"%{BKY_MATH_ATAN2_TITLE}",args0:[{type:"input_value",name:"X",check:"Number"},{type:"input_value",
|
||||
name:"Y",check:"Number"}],inputsInline:!0,output:"Number",style:"math_blocks",tooltip:"%{BKY_MATH_ATAN2_TOOLTIP}",helpUrl:"%{BKY_MATH_ATAN2_HELPURL}"}]);
|
||||
Blockly.Constants.Math.TOOLTIPS_BY_OP={ADD:"%{BKY_MATH_ARITHMETIC_TOOLTIP_ADD}",MINUS:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MINUS}",MULTIPLY:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MULTIPLY}",DIVIDE:"%{BKY_MATH_ARITHMETIC_TOOLTIP_DIVIDE}",POWER:"%{BKY_MATH_ARITHMETIC_TOOLTIP_POWER}",ROOT:"%{BKY_MATH_SINGLE_TOOLTIP_ROOT}",ABS:"%{BKY_MATH_SINGLE_TOOLTIP_ABS}",NEG:"%{BKY_MATH_SINGLE_TOOLTIP_NEG}",LN:"%{BKY_MATH_SINGLE_TOOLTIP_LN}",LOG10:"%{BKY_MATH_SINGLE_TOOLTIP_LOG10}",EXP:"%{BKY_MATH_SINGLE_TOOLTIP_EXP}",POW10:"%{BKY_MATH_SINGLE_TOOLTIP_POW10}",
|
||||
SIN:"%{BKY_MATH_TRIG_TOOLTIP_SIN}",COS:"%{BKY_MATH_TRIG_TOOLTIP_COS}",TAN:"%{BKY_MATH_TRIG_TOOLTIP_TAN}",ASIN:"%{BKY_MATH_TRIG_TOOLTIP_ASIN}",ACOS:"%{BKY_MATH_TRIG_TOOLTIP_ACOS}",ATAN:"%{BKY_MATH_TRIG_TOOLTIP_ATAN}",SUM:"%{BKY_MATH_ONLIST_TOOLTIP_SUM}",MIN:"%{BKY_MATH_ONLIST_TOOLTIP_MIN}",MAX:"%{BKY_MATH_ONLIST_TOOLTIP_MAX}",AVERAGE:"%{BKY_MATH_ONLIST_TOOLTIP_AVERAGE}",MEDIAN:"%{BKY_MATH_ONLIST_TOOLTIP_MEDIAN}",MODE:"%{BKY_MATH_ONLIST_TOOLTIP_MODE}",STD_DEV:"%{BKY_MATH_ONLIST_TOOLTIP_STD_DEV}",RANDOM:"%{BKY_MATH_ONLIST_TOOLTIP_RANDOM}"};
|
||||
Blockly.Extensions.register("math_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Math.TOOLTIPS_BY_OP));
|
||||
Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN={mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation"),b="DIVISIBLE_BY"==this.getFieldValue("PROPERTY");a.setAttribute("divisor_input",b);return a},domToMutation:function(a){a="true"==a.getAttribute("divisor_input");this.updateShape_(a)},updateShape_:function(a){var b=this.getInput("DIVISOR");a?b||this.appendValueInput("DIVISOR").setCheck("Number"):b&&this.removeInput("DIVISOR")}};
|
||||
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION=function(){this.getField("PROPERTY").setValidator(function(a){a="DIVISIBLE_BY"==a;this.getSourceBlock().updateShape_(a)})};Blockly.Extensions.registerMutator("math_is_divisibleby_mutator",Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);Blockly.Extensions.register("math_change_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_MATH_CHANGE_TOOLTIP}","VAR"));
|
||||
Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN={updateType_:function(a){"MODE"==a?this.outputConnection.setCheck("Array"):this.outputConnection.setCheck("Number")},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("op",this.getFieldValue("OP"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("op"))}};Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION=function(){this.getField("OP").setValidator(function(a){this.updateType_(a)}.bind(this))};
|
||||
Blockly.Extensions.registerMutator("math_modes_of_list_mutator",Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);Blockly.Blocks.procedures={};
|
||||
Blockly.Blocks.procedures_defnoreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);
|
||||
this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:function(a){this.hasStatements_!==a&&(a?(this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO),this.getInput("RETURN")&&this.moveInputBefore("STACK","RETURN")):this.removeInput("STACK",!0),this.hasStatements_=
|
||||
a)},updateParams_:function(){var a="";this.arguments_.length&&(a=Blockly.Msg.PROCEDURES_BEFORE_PARAMS+" "+this.arguments_.join(", "));Blockly.Events.disable();try{this.setFieldValue(a,"PARAMS")}finally{Blockly.Events.enable()}},mutationToDom:function(a){var b=Blockly.utils.xml.createElement("mutation");a&&b.setAttribute("name",this.getFieldValue("NAME"));for(var c=0;c<this.argumentVarModels_.length;c++){var d=Blockly.utils.xml.createElement("arg"),e=this.argumentVarModels_[c];d.setAttribute("name",
|
||||
e.name);d.setAttribute("varid",e.getId());a&&this.paramIds_&&d.setAttribute("paramId",this.paramIds_[c]);b.appendChild(d)}this.hasStatements_||b.setAttribute("statements","false");return b},domToMutation:function(a){this.arguments_=[];this.argumentVarModels_=[];for(var b=0,c;c=a.childNodes[b];b++)if("arg"==c.nodeName.toLowerCase()){var d=c.getAttribute("name");c=c.getAttribute("varid")||c.getAttribute("varId");this.arguments_.push(d);c=Blockly.Variables.getOrCreateVariablePackage(this.workspace,c,
|
||||
d,"");null!=c?this.argumentVarModels_.push(c):console.log("Failed to create a variable with name "+d+", ignoring.")}this.updateParams_();Blockly.Procedures.mutateCallers(this);this.setStatements_("false"!==a.getAttribute("statements"))},decompose:function(a){var b=Blockly.utils.xml.createElement("block");b.setAttribute("type","procedures_mutatorcontainer");var c=Blockly.utils.xml.createElement("statement");c.setAttribute("name","STACK");b.appendChild(c);for(var d=0;d<this.arguments_.length;d++){var e=
|
||||
Blockly.utils.xml.createElement("block");e.setAttribute("type","procedures_mutatorarg");var f=Blockly.utils.xml.createElement("field");f.setAttribute("name","NAME");var g=Blockly.utils.xml.createTextNode(this.arguments_[d]);f.appendChild(g);e.appendChild(f);f=Blockly.utils.xml.createElement("next");e.appendChild(f);c.appendChild(e);c=f}a=Blockly.Xml.domToBlock(b,a);"procedures_defreturn"==this.type?a.setFieldValue(this.hasStatements_,"STATEMENTS"):a.removeInput("STATEMENT_INPUT");Blockly.Procedures.mutateCallers(this);
|
||||
return a},compose:function(a){this.arguments_=[];this.paramIds_=[];this.argumentVarModels_=[];for(var b=a.getInputTargetBlock("STACK");b;){var c=b.getFieldValue("NAME");this.arguments_.push(c);c=this.workspace.getVariable(c,"");this.argumentVarModels_.push(c);this.paramIds_.push(b.id);b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateParams_();Blockly.Procedures.mutateCallers(this);a=a.getFieldValue("STATEMENTS");if(null!==a&&(a="TRUE"==a,this.hasStatements_!=a))if(a)this.setStatements_(!0),
|
||||
Blockly.Mutator.reconnect(this.statementConnection_,this,"STACK"),this.statementConnection_=null;else{a=this.getInput("STACK").connection;if(this.statementConnection_=a.targetConnection)a=a.targetBlock(),a.unplug(),a.bumpNeighbours();this.setStatements_(!1)}},getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!1]},getVars:function(){return this.arguments_},getVarModels:function(){return this.argumentVarModels_},renameVarById:function(a,b){var c=this.workspace.getVariableById(a);
|
||||
if(""==c.type){c=c.name;b=this.workspace.getVariableById(b);for(var d=!1,e=0;e<this.argumentVarModels_.length;e++)this.argumentVarModels_[e].getId()==a&&(this.arguments_[e]=b.name,this.argumentVarModels_[e]=b,d=!0);d&&(this.displayRenamedVar_(c,b.name),Blockly.Procedures.mutateCallers(this))}},updateVarName:function(a){for(var b=a.name,c=!1,d=0;d<this.argumentVarModels_.length;d++)if(this.argumentVarModels_[d].getId()==a.getId()){var e=this.arguments_[d];this.arguments_[d]=b;c=!0}c&&(this.displayRenamedVar_(e,
|
||||
b),Blockly.Procedures.mutateCallers(this))},displayRenamedVar_:function(a,b){this.updateParams_();if(this.mutator&&this.mutator.isVisible())for(var c=this.mutator.workspace_.getAllBlocks(!1),d=0,e;e=c[d];d++)"procedures_mutatorarg"==e.type&&Blockly.Names.equals(a,e.getFieldValue("NAME"))&&e.setFieldValue(b,"NAME")},customContextMenu:function(a){if(!this.isInFlyout){var b={enabled:!0},c=this.getFieldValue("NAME");b.text=Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1",c);var d=Blockly.utils.xml.createElement("mutation");
|
||||
d.setAttribute("name",c);for(c=0;c<this.arguments_.length;c++){var e=Blockly.utils.xml.createElement("arg");e.setAttribute("name",this.arguments_[c]);d.appendChild(e)}c=Blockly.utils.xml.createElement("block");c.setAttribute("type",this.callType_);c.appendChild(d);b.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(b);if(!this.isCollapsed())for(c=0;c<this.argumentVarModels_.length;c++)b={enabled:!0},d=this.argumentVarModels_[c],b.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",d.name),
|
||||
d=Blockly.Variables.generateVariableFieldDom(d),e=Blockly.utils.xml.createElement("block"),e.setAttribute("type","variables_get"),e.appendChild(d),b.callback=Blockly.ContextMenu.callbackFactory(this,e),a.push(b)}},callType_:"procedures_callnoreturn"};
|
||||
Blockly.Blocks.procedures_defreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.appendValueInput("RETURN").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&
|
||||
this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:Blockly.Blocks.procedures_defnoreturn.setStatements_,updateParams_:Blockly.Blocks.procedures_defnoreturn.updateParams_,
|
||||
mutationToDom:Blockly.Blocks.procedures_defnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_defnoreturn.domToMutation,decompose:Blockly.Blocks.procedures_defnoreturn.decompose,compose:Blockly.Blocks.procedures_defnoreturn.compose,getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!0]},getVars:Blockly.Blocks.procedures_defnoreturn.getVars,getVarModels:Blockly.Blocks.procedures_defnoreturn.getVarModels,renameVarById:Blockly.Blocks.procedures_defnoreturn.renameVarById,
|
||||
updateVarName:Blockly.Blocks.procedures_defnoreturn.updateVarName,displayRenamedVar_:Blockly.Blocks.procedures_defnoreturn.displayRenamedVar_,customContextMenu:Blockly.Blocks.procedures_defnoreturn.customContextMenu,callType_:"procedures_callreturn"};
|
||||
Blockly.Blocks.procedures_mutatorcontainer={init:function(){this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE);this.appendStatementInput("STACK");this.appendDummyInput("STATEMENT_INPUT").appendField(Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS).appendField(new Blockly.FieldCheckbox("TRUE"),"STATEMENTS");this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP);this.contextMenu=!1}};
|
||||
Blockly.Blocks.procedures_mutatorarg={init:function(){var a=new Blockly.FieldTextInput(Blockly.Procedures.DEFAULT_ARG,this.validator_);a.oldShowEditorFn_=a.showEditor_;a.showEditor_=function(){this.createdVariables_=[];this.oldShowEditorFn_()};this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORARG_TITLE).appendField(a,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP);this.contextMenu=
|
||||
!1;a.onFinishEditing_=this.deleteIntermediateVars_;a.createdVariables_=[];a.onFinishEditing_("x")},validator_:function(a){var b=this.getSourceBlock(),c=Blockly.Mutator.findParentWs(b.workspace);a=a.replace(/[\s\xa0]+/g," ").replace(/^ | $/g,"");if(!a)return null;for(var d=(b.workspace.targetWorkspace||b.workspace).getAllBlocks(!1),e=a.toLowerCase(),f=0;f<d.length;f++)if(d[f].id!=this.getSourceBlock().id){var g=d[f].getFieldValue("NAME");if(g&&g.toLowerCase()==e)return null}if(b.isInFlyout)return a;
|
||||
(b=c.getVariable(a,""))&&b.name!=a&&c.renameVariableById(b.getId(),a);b||(b=c.createVariable(a,""))&&this.createdVariables_&&this.createdVariables_.push(b);return a},deleteIntermediateVars_:function(a){var b=Blockly.Mutator.findParentWs(this.getSourceBlock().workspace);if(b)for(var c=0;c<this.createdVariables_.length;c++){var d=this.createdVariables_[c];d.name!=a&&b.deleteVariableById(d.getId())}}};
|
||||
Blockly.Blocks.procedures_callnoreturn={init:function(){this.appendDummyInput("TOPROW").appendField(this.id,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousEnabledState_=!0},getProcedureCall:function(){return this.getFieldValue("NAME")},renameProcedure:function(a,b){Blockly.Names.equals(a,
|
||||
this.getProcedureCall())&&(this.setFieldValue(b,"NAME"),this.setTooltip((this.outputConnection?Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP:Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP).replace("%1",b)))},setProcedureParameters_:function(a,b){var c=Blockly.Procedures.getDefinition(this.getProcedureCall(),this.workspace),d=c&&c.mutator&&c.mutator.isVisible();d||(this.quarkConnections_={},this.quarkIds_=null);if(b)if(a.join("\n")==this.arguments_.join("\n"))this.quarkIds_=b;else{if(b.length!=a.length)throw RangeError("paramNames and paramIds must be the same length.");
|
||||
this.setCollapsed(!1);this.quarkIds_||(this.quarkConnections_={},this.quarkIds_=[]);c=this.rendered;this.rendered=!1;for(var e=0;e<this.arguments_.length;e++){var f=this.getInput("ARG"+e);f&&(f=f.connection.targetConnection,this.quarkConnections_[this.quarkIds_[e]]=f,d&&f&&-1==b.indexOf(this.quarkIds_[e])&&(f.disconnect(),f.getSourceBlock().bumpNeighbours()))}this.arguments_=[].concat(a);this.argumentVarModels_=[];for(e=0;e<this.arguments_.length;e++)a=Blockly.Variables.getOrCreateVariablePackage(this.workspace,
|
||||
null,this.arguments_[e],""),this.argumentVarModels_.push(a);this.updateShape_();if(this.quarkIds_=b)for(e=0;e<this.arguments_.length;e++)b=this.quarkIds_[e],b in this.quarkConnections_&&(f=this.quarkConnections_[b],Blockly.Mutator.reconnect(f,this,"ARG"+e)||delete this.quarkConnections_[b]);(this.rendered=c)&&this.render()}},updateShape_:function(){for(var a=0;a<this.arguments_.length;a++){var b=this.getField("ARGNAME"+a);if(b){Blockly.Events.disable();try{b.setValue(this.arguments_[a])}finally{Blockly.Events.enable()}}else b=
|
||||
new Blockly.FieldLabel(this.arguments_[a]),this.appendValueInput("ARG"+a).setAlign(Blockly.ALIGN_RIGHT).appendField(b,"ARGNAME"+a).init()}for(;this.getInput("ARG"+a);)this.removeInput("ARG"+a),a++;if(a=this.getInput("TOPROW"))this.arguments_.length?this.getField("WITH")||(a.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS,"WITH"),a.init()):this.getField("WITH")&&a.removeField("WITH")},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("name",this.getProcedureCall());
|
||||
for(var b=0;b<this.arguments_.length;b++){var c=Blockly.utils.xml.createElement("arg");c.setAttribute("name",this.arguments_[b]);a.appendChild(c)}return a},domToMutation:function(a){var b=a.getAttribute("name");this.renameProcedure(this.getProcedureCall(),b);b=[];for(var c=[],d=0,e;e=a.childNodes[d];d++)"arg"==e.nodeName.toLowerCase()&&(b.push(e.getAttribute("name")),c.push(e.getAttribute("paramId")));this.setProcedureParameters_(b,c)},getVars:function(){return this.arguments_},getVarModels:function(){return this.argumentVarModels_},
|
||||
onchange:function(a){if(this.workspace&&!this.workspace.isFlyout&&a.recordUndo)if(a.type==Blockly.Events.BLOCK_CREATE&&-1!=a.ids.indexOf(this.id)){var b=this.getProcedureCall();b=Blockly.Procedures.getDefinition(b,this.workspace);!b||b.type==this.defType_&&JSON.stringify(b.getVars())==JSON.stringify(this.arguments_)||(b=null);if(!b){Blockly.Events.setGroup(a.group);a=Blockly.utils.xml.createElement("xml");b=Blockly.utils.xml.createElement("block");b.setAttribute("type",this.defType_);var c=this.getRelativeToSurfaceXY(),
|
||||
d=c.y+2*Blockly.SNAP_RADIUS;b.setAttribute("x",c.x+Blockly.SNAP_RADIUS*(this.RTL?-1:1));b.setAttribute("y",d);c=this.mutationToDom();b.appendChild(c);c=Blockly.utils.xml.createElement("field");c.setAttribute("name","NAME");c.appendChild(Blockly.utils.xml.createTextNode(this.getProcedureCall()));b.appendChild(c);a.appendChild(b);Blockly.Xml.domToWorkspace(a,this.workspace);Blockly.Events.setGroup(!1)}}else a.type==Blockly.Events.BLOCK_DELETE?(b=this.getProcedureCall(),b=Blockly.Procedures.getDefinition(b,
|
||||
this.workspace),b||(Blockly.Events.setGroup(a.group),this.dispose(!0),Blockly.Events.setGroup(!1))):a.type==Blockly.Events.CHANGE&&"disabled"==a.element&&(b=this.getProcedureCall(),(b=Blockly.Procedures.getDefinition(b,this.workspace))&&b.id==a.blockId&&((b=Blockly.Events.getGroup())&&console.log("Saw an existing group while responding to a definition change"),Blockly.Events.setGroup(a.group),a.newValue?(this.previousEnabledState_=this.isEnabled(),this.setEnabled(!1)):this.setEnabled(this.previousEnabledState_),
|
||||
Blockly.Events.setGroup(b)))},customContextMenu:function(a){if(this.workspace.isMovable()){var b={enabled:!0};b.text=Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;var c=this.getProcedureCall(),d=this.workspace;b.callback=function(){var a=Blockly.Procedures.getDefinition(c,d);a&&(d.centerOnBlock(a.id),a.select())};a.push(b)}},defType_:"procedures_defnoreturn"};
|
||||
Blockly.Blocks.procedures_callreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setOutput(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousEnabledState_=!0},getProcedureCall:Blockly.Blocks.procedures_callnoreturn.getProcedureCall,renameProcedure:Blockly.Blocks.procedures_callnoreturn.renameProcedure,setProcedureParameters_:Blockly.Blocks.procedures_callnoreturn.setProcedureParameters_,
|
||||
updateShape_:Blockly.Blocks.procedures_callnoreturn.updateShape_,mutationToDom:Blockly.Blocks.procedures_callnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_callnoreturn.domToMutation,getVars:Blockly.Blocks.procedures_callnoreturn.getVars,getVarModels:Blockly.Blocks.procedures_callnoreturn.getVarModels,onchange:Blockly.Blocks.procedures_callnoreturn.onchange,customContextMenu:Blockly.Blocks.procedures_callnoreturn.customContextMenu,defType_:"procedures_defreturn"};
|
||||
Blockly.Blocks.procedures_ifreturn={init:function(){this.appendValueInput("CONDITION").setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_IFRETURN_HELPURL);this.hasReturnValue_=!0},mutationToDom:function(){var a=
|
||||
Blockly.utils.xml.createElement("mutation");a.setAttribute("value",Number(this.hasReturnValue_));return a},domToMutation:function(a){this.hasReturnValue_=1==a.getAttribute("value");this.hasReturnValue_||(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN))},onchange:function(a){if(this.workspace.isDragging&&!this.workspace.isDragging()){a=!1;var b=this;do{if(-1!=this.FUNCTION_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);
|
||||
a?("procedures_defnoreturn"==b.type&&this.hasReturnValue_?(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!1):"procedures_defreturn"!=b.type||this.hasReturnValue_||(this.removeInput("VALUE"),this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!0),this.setWarningText(null),this.isInFlyout||this.setEnabled(!0)):(this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING),
|
||||
this.isInFlyout||this.getInheritedDisabled()||this.setEnabled(!1))}},FUNCTION_TYPES:["procedures_defnoreturn","procedures_defreturn"]};Blockly.Blocks.texts={};Blockly.Constants.Text={};Blockly.Constants.Text.HUE=160;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"text",message0:"%1",args0:[{type:"field_input",name:"TEXT",text:""}],output:"String",style:"text_blocks",helpUrl:"%{BKY_TEXT_TEXT_HELPURL}",tooltip:"%{BKY_TEXT_TEXT_TOOLTIP}",extensions:["text_quotes","parent_tooltip_when_inline"]},{type:"text_multiline",message0:"%1 %2",args0:[{type:"field_image",src:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAARCAYAAADpPU2iAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAdhgAAHYYBXaITgQAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMS42/U4J6AAAAP1JREFUOE+Vks0KQUEYhjmRIja4ABtZ2dm5A3t3Ia6AUm7CylYuQRaUhZSlLZJiQbFAyRnPN33y01HOW08z8873zpwzM4F3GWOCruvGIE4/rLaV+Nq1hVGMBqzhqlxgCys4wJA65xnogMHsQ5lujnYHTejBBCK2mE4abjCgMGhNxHgDFWjDSG07kdfVa2pZMf4ZyMAdWmpZMfYOsLiDMYMjlMB+K613QISRhTnITnsYg5yUd0DETmEoMlkFOeIT/A58iyK5E18BuTBfgYXfwNJv4P9/oEBerLylOnRhygmGdPpTTBZAPkde61lbQe4moWUvYUZYLfUNftIY4zwA5X2Z9AYnQrEAAAAASUVORK5CYII=",width:12,
|
||||
height:17,alt:"\u00b6"},{type:"field_multilinetext",name:"TEXT",text:""}],output:"String",style:"text_blocks",helpUrl:"%{BKY_TEXT_TEXT_HELPURL}",tooltip:"%{BKY_TEXT_TEXT_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"text_join",message0:"",output:"String",style:"text_blocks",helpUrl:"%{BKY_TEXT_JOIN_HELPURL}",tooltip:"%{BKY_TEXT_JOIN_TOOLTIP}",mutator:"text_join_mutator"},{type:"text_create_join_container",message0:"%{BKY_TEXT_CREATE_JOIN_TITLE_JOIN} %1 %2",args0:[{type:"input_dummy"},
|
||||
{type:"input_statement",name:"STACK"}],style:"text_blocks",tooltip:"%{BKY_TEXT_CREATE_JOIN_TOOLTIP}",enableContextMenu:!1},{type:"text_create_join_item",message0:"%{BKY_TEXT_CREATE_JOIN_ITEM_TITLE_ITEM}",previousStatement:null,nextStatement:null,style:"text_blocks",tooltip:"%{BKY_TEXT_CREATE_JOIN_ITEM_TOOLTIP}",enableContextMenu:!1},{type:"text_append",message0:"%{BKY_TEXT_APPEND_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_TEXT_APPEND_VARIABLE}"},{type:"input_value",name:"TEXT"}],
|
||||
previousStatement:null,nextStatement:null,style:"text_blocks",extensions:["text_append_tooltip"]},{type:"text_length",message0:"%{BKY_TEXT_LENGTH_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",style:"text_blocks",tooltip:"%{BKY_TEXT_LENGTH_TOOLTIP}",helpUrl:"%{BKY_TEXT_LENGTH_HELPURL}"},{type:"text_isEmpty",message0:"%{BKY_TEXT_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Boolean",style:"text_blocks",tooltip:"%{BKY_TEXT_ISEMPTY_TOOLTIP}",
|
||||
helpUrl:"%{BKY_TEXT_ISEMPTY_HELPURL}"},{type:"text_indexOf",message0:"%{BKY_TEXT_INDEXOF_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"field_dropdown",name:"END",options:[["%{BKY_TEXT_INDEXOF_OPERATOR_FIRST}","FIRST"],["%{BKY_TEXT_INDEXOF_OPERATOR_LAST}","LAST"]]},{type:"input_value",name:"FIND",check:"String"}],output:"Number",style:"text_blocks",helpUrl:"%{BKY_TEXT_INDEXOF_HELPURL}",inputsInline:!0,extensions:["text_indexOf_tooltip"]},{type:"text_charAt",message0:"%{BKY_TEXT_CHARAT_TITLE}",
|
||||
args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"field_dropdown",name:"WHERE",options:[["%{BKY_TEXT_CHARAT_FROM_START}","FROM_START"],["%{BKY_TEXT_CHARAT_FROM_END}","FROM_END"],["%{BKY_TEXT_CHARAT_FIRST}","FIRST"],["%{BKY_TEXT_CHARAT_LAST}","LAST"],["%{BKY_TEXT_CHARAT_RANDOM}","RANDOM"]]}],output:"String",style:"text_blocks",helpUrl:"%{BKY_TEXT_CHARAT_HELPURL}",inputsInline:!0,mutator:"text_charAt_mutator"}]);
|
||||
Blockly.Blocks.text_getSubstring={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL);this.setStyle("text_blocks");
|
||||
this.appendValueInput("STRING").setCheck("String").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);this.setInputsInline(!0);this.setOutput(!0,"String");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP)},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation"),
|
||||
b=this.getInput("AT1").type==Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT"+a);2==a&&Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL));var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var e="FROM_START"==c||"FROM_END"==c;if(e!=b){var d=this.getSourceBlock();d.updateAt_(a,e);d.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&
|
||||
this.moveInputBefore("ORDINAL1","AT2"))}};Blockly.Blocks.text_changeCase={init:function(){var a=[[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE,"UPPERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE,"LOWERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE,"TITLECASE"]];this.setHelpUrl(Blockly.Msg.TEXT_CHANGECASE_HELPURL);this.setStyle("text_blocks");this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"CASE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_CHANGECASE_TOOLTIP)}};
|
||||
Blockly.Blocks.text_trim={init:function(){var a=[[Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH,"BOTH"],[Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT,"LEFT"],[Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT,"RIGHT"]];this.setHelpUrl(Blockly.Msg.TEXT_TRIM_HELPURL);this.setStyle("text_blocks");this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"MODE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_TRIM_TOOLTIP)}};
|
||||
Blockly.Blocks.text_print={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_PRINT_TITLE,args0:[{type:"input_value",name:"TEXT"}],previousStatement:null,nextStatement:null,style:"text_blocks",tooltip:Blockly.Msg.TEXT_PRINT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_PRINT_HELPURL})}};
|
||||
Blockly.Blocks.text_prompt_ext={init:function(){var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]];this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setStyle("text_blocks");var b=this;a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendValueInput("TEXT").appendField(a,"TYPE");this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},
|
||||
updateType_:function(a){this.outputConnection.setCheck("NUMBER"==a?"Number":"String")},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("type",this.getFieldValue("TYPE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("type"))}};
|
||||
Blockly.Blocks.text_prompt={init:function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]],b=this;this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setStyle("text_blocks");a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendDummyInput().appendField(a,"TYPE").appendField(this.newQuote_(!0)).appendField(new Blockly.FieldTextInput(""),"TEXT").appendField(this.newQuote_(!1));
|
||||
this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},updateType_:Blockly.Blocks.text_prompt_ext.updateType_,mutationToDom:Blockly.Blocks.text_prompt_ext.mutationToDom,domToMutation:Blockly.Blocks.text_prompt_ext.domToMutation};
|
||||
Blockly.Blocks.text_count={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_COUNT_MESSAGE0,args0:[{type:"input_value",name:"SUB",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"Number",inputsInline:!0,style:"text_blocks",tooltip:Blockly.Msg.TEXT_COUNT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_COUNT_HELPURL})}};
|
||||
Blockly.Blocks.text_replace={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_REPLACE_MESSAGE0,args0:[{type:"input_value",name:"FROM",check:"String"},{type:"input_value",name:"TO",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"String",inputsInline:!0,style:"text_blocks",tooltip:Blockly.Msg.TEXT_REPLACE_TOOLTIP,helpUrl:Blockly.Msg.TEXT_REPLACE_HELPURL})}};
|
||||
Blockly.Blocks.text_reverse={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_REVERSE_MESSAGE0,args0:[{type:"input_value",name:"TEXT",check:"String"}],output:"String",inputsInline:!0,style:"text_blocks",tooltip:Blockly.Msg.TEXT_REVERSE_TOOLTIP,helpUrl:Blockly.Msg.TEXT_REVERSE_HELPURL})}};
|
||||
Blockly.Constants.Text.QUOTE_IMAGE_MIXIN={QUOTE_IMAGE_LEFT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC",QUOTE_IMAGE_RIGHT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==",
|
||||
QUOTE_IMAGE_WIDTH:12,QUOTE_IMAGE_HEIGHT:12,quoteField_:function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(a==e.name){c.insertFieldAt(d,this.newQuote_(!0));c.insertFieldAt(d+2,this.newQuote_(!1));return}console.warn('field named "'+a+'" not found in '+this.toDevString())},newQuote_:function(a){a=this.RTL?!a:a;return new Blockly.FieldImage(a?this.QUOTE_IMAGE_LEFT_DATAURI:this.QUOTE_IMAGE_RIGHT_DATAURI,this.QUOTE_IMAGE_WIDTH,this.QUOTE_IMAGE_HEIGHT,a?"\u201c":"\u201d")}};
|
||||
Blockly.Constants.Text.TEXT_QUOTES_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.quoteField_("TEXT")};
|
||||
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN={mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),10);this.updateShape_()},decompose:function(a){var b=a.newBlock("text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("text_create_join_item");e.initSvg();c.connect(e.previousConnection);
|
||||
c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=
|
||||
this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||this.appendDummyInput("EMPTY").appendField(this.newQuote_(!0)).appendField(this.newQuote_(!1));for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a).setAlign(Blockly.ALIGN_RIGHT);0==a&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH)}for(;this.getInput("ADD"+
|
||||
a);)this.removeInput("ADD"+a),a++}};Blockly.Constants.Text.TEXT_JOIN_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.itemCount_=2;this.updateShape_();this.setMutator(new Blockly.Mutator(["text_create_join_item"]))};Blockly.Extensions.register("text_append_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_TEXT_APPEND_TOOLTIP}","VAR"));
|
||||
Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_INDEXOF_TOOLTIP.replace("%1",a.workspace.options.oneBasedIndex?"0":"-1")})};
|
||||
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN={mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("at",!!this.isAt_);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT",!0);this.removeInput("ORDINAL",!0);a&&(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX));Blockly.Msg.TEXT_CHARAT_TAIL&&
|
||||
(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_CHARAT_TAIL));this.isAt_=a}};
|
||||
Blockly.Constants.Text.TEXT_CHARAT_EXTENSION=function(){this.getField("WHERE").setValidator(function(a){a="FROM_START"==a||"FROM_END"==a;a!=this.isAt_&&this.getSourceBlock().updateAt_(a)});this.updateAt_(!0);var a=this;this.setTooltip(function(){var b=a.getFieldValue("WHERE"),c=Blockly.Msg.TEXT_CHARAT_TOOLTIP;("FROM_START"==b||"FROM_END"==b)&&(b="FROM_START"==b?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP)&&(c+=" "+b.replace("%1",a.workspace.options.oneBasedIndex?
|
||||
"#1":"#0"));return c})};Blockly.Extensions.register("text_indexOf_tooltip",Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);Blockly.Extensions.register("text_quotes",Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);Blockly.Extensions.registerMutator("text_join_mutator",Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN,Blockly.Constants.Text.TEXT_JOIN_EXTENSION);Blockly.Extensions.registerMutator("text_charAt_mutator",Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN,Blockly.Constants.Text.TEXT_CHARAT_EXTENSION);Blockly.Blocks.variables={};Blockly.Constants.Variables={};Blockly.Constants.Variables.HUE=330;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"variables_get",message0:"%1",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"}],output:null,style:"variable_blocks",helpUrl:"%{BKY_VARIABLES_GET_HELPURL}",tooltip:"%{BKY_VARIABLES_GET_TOOLTIP}",extensions:["contextMenu_variableSetterGetter"]},{type:"variables_set",message0:"%{BKY_VARIABLES_SET}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"},{type:"input_value",name:"VALUE"}],previousStatement:null,
|
||||
nextStatement:null,style:"variable_blocks",tooltip:"%{BKY_VARIABLES_SET_TOOLTIP}",helpUrl:"%{BKY_VARIABLES_SET_HELPURL}",extensions:["contextMenu_variableSetterGetter"]}]);
|
||||
Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){if("variables_get"==this.type)var b="variables_set",c=Blockly.Msg.VARIABLES_GET_CREATE_SET;else b="variables_get",c=Blockly.Msg.VARIABLES_SET_CREATE_GET;var d={enabled:0<this.workspace.remainingCapacity()},e=this.getField("VAR").getText();d.text=c.replace("%1",e);c=Blockly.utils.xml.createElement("field");c.setAttribute("name","VAR");c.appendChild(Blockly.utils.xml.createTextNode(e));
|
||||
e=Blockly.utils.xml.createElement("block");e.setAttribute("type",b);e.appendChild(c);d.callback=Blockly.ContextMenu.callbackFactory(this,e);a.push(d)}else if("variables_get"==this.type||"variables_get_reporter"==this.type)b={text:Blockly.Msg.RENAME_VARIABLE,enabled:!0,callback:Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY(this)},e=this.getField("VAR").getText(),d={text:Blockly.Msg.DELETE_VARIABLE.replace("%1",e),enabled:!0,callback:Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY(this)},
|
||||
a.unshift(b),a.unshift(d)}};Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();Blockly.Variables.renameVariable(b,c)}};Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();b.deleteVariableById(c.getId());b.refreshToolboxSelection()}};Blockly.Extensions.registerMixin("contextMenu_variableSetterGetter",Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);Blockly.Constants.VariablesDynamic={};Blockly.Constants.VariablesDynamic.HUE=310;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"variables_get_dynamic",message0:"%1",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"}],output:null,style:"variable_dynamic_blocks",helpUrl:"%{BKY_VARIABLES_GET_HELPURL}",tooltip:"%{BKY_VARIABLES_GET_TOOLTIP}",extensions:["contextMenu_variableDynamicSetterGetter"]},{type:"variables_set_dynamic",message0:"%{BKY_VARIABLES_SET}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"},{type:"input_value",
|
||||
name:"VALUE"}],previousStatement:null,nextStatement:null,style:"variable_dynamic_blocks",tooltip:"%{BKY_VARIABLES_SET_TOOLTIP}",helpUrl:"%{BKY_VARIABLES_SET_HELPURL}",extensions:["contextMenu_variableDynamicSetterGetter"]}]);
|
||||
Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){var b=this.getFieldValue("VAR");var c=this.workspace.getVariableById(b).type;if("variables_get_dynamic"==this.type){b="variables_set_dynamic";var d=Blockly.Msg.VARIABLES_GET_CREATE_SET}else b="variables_get_dynamic",d=Blockly.Msg.VARIABLES_SET_CREATE_GET;var e={enabled:0<this.workspace.remainingCapacity()},f=this.getField("VAR").getText();e.text=d.replace("%1",f);
|
||||
d=Blockly.utils.xml.createElement("field");d.setAttribute("name","VAR");d.setAttribute("variabletype",c);d.appendChild(Blockly.utils.xml.createTextNode(f));f=Blockly.utils.xml.createElement("block");f.setAttribute("type",b);f.appendChild(d);e.callback=Blockly.ContextMenu.callbackFactory(this,f);a.push(e)}else if("variables_get_dynamic"==this.type||"variables_get_reporter_dynamic"==this.type)b={text:Blockly.Msg.RENAME_VARIABLE,enabled:!0,callback:Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY(this)},
|
||||
f=this.getField("VAR").getText(),e={text:Blockly.Msg.DELETE_VARIABLE.replace("%1",f),enabled:!0,callback:Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY(this)},a.unshift(b),a.unshift(e)},onchange:function(a){a=this.getFieldValue("VAR");a=Blockly.Variables.getVariable(this.workspace,a);"variables_get_dynamic"==this.type?this.outputConnection.setCheck(a.type):this.getInput("VALUE").connection.setCheck(a.type)}};
|
||||
Blockly.Constants.VariablesDynamic.RENAME_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();Blockly.Variables.renameVariable(b,c)}};Blockly.Constants.VariablesDynamic.DELETE_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();b.deleteVariableById(c.getId());b.refreshToolboxSelection()}};Blockly.Extensions.registerMixin("contextMenu_variableDynamicSetterGetter",Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
|
||||
return Blockly.Blocks;
|
||||
}));
|
||||
|
||||
|
||||
//# sourceMappingURL=blocks_compressed.js.map
|
||||
1
clover_blocks/www/blockly/blocks_compressed.js.map
Executable file
BIN
clover_blocks/www/blockly/media/1x1.gif
Executable file
|
After Width: | Height: | Size: 43 B |
BIN
clover_blocks/www/blockly/media/click.mp3
Executable file
BIN
clover_blocks/www/blockly/media/click.ogg
Executable file
BIN
clover_blocks/www/blockly/media/click.wav
Executable file
BIN
clover_blocks/www/blockly/media/delete.mp3
Executable file
BIN
clover_blocks/www/blockly/media/delete.ogg
Executable file
BIN
clover_blocks/www/blockly/media/delete.wav
Executable file
BIN
clover_blocks/www/blockly/media/disconnect.mp3
Executable file
BIN
clover_blocks/www/blockly/media/disconnect.ogg
Executable file
BIN
clover_blocks/www/blockly/media/disconnect.wav
Executable file
1
clover_blocks/www/blockly/media/dropdown-arrow.svg
Executable file
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="12.71" height="8.79" viewBox="0 0 12.71 8.79"><title>dropdown-arrow</title><g opacity="0.1"><path d="M12.71,2.44A2.41,2.41,0,0,1,12,4.16L8.08,8.08a2.45,2.45,0,0,1-3.45,0L0.72,4.16A2.42,2.42,0,0,1,0,2.44,2.48,2.48,0,0,1,.71.71C1,0.47,1.43,0,6.36,0S11.75,0.46,12,.71A2.44,2.44,0,0,1,12.71,2.44Z" fill="#231f20"/></g><path d="M6.36,7.79a1.43,1.43,0,0,1-1-.42L1.42,3.45a1.44,1.44,0,0,1,0-2c0.56-.56,9.31-0.56,9.87,0a1.44,1.44,0,0,1,0,2L7.37,7.37A1.43,1.43,0,0,1,6.36,7.79Z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 569 B |
BIN
clover_blocks/www/blockly/media/handclosed.cur
Executable file
|
After Width: | Height: | Size: 326 B |
BIN
clover_blocks/www/blockly/media/handdelete.cur
Executable file
|
After Width: | Height: | Size: 766 B |
BIN
clover_blocks/www/blockly/media/handopen.cur
Executable file
|
After Width: | Height: | Size: 198 B |
BIN
clover_blocks/www/blockly/media/pilcrow.png
Executable file
|
After Width: | Height: | Size: 1010 B |
BIN
clover_blocks/www/blockly/media/quote0.png
Executable file
|
After Width: | Height: | Size: 771 B |
BIN
clover_blocks/www/blockly/media/quote1.png
Executable file
|
After Width: | Height: | Size: 738 B |
BIN
clover_blocks/www/blockly/media/sprites.png
Executable file
|
After Width: | Height: | Size: 2.5 KiB |
74
clover_blocks/www/blockly/media/sprites.svg
Executable file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="96px" height="124px">
|
||||
<style type="text/css">
|
||||
#background {
|
||||
fill: none;
|
||||
}
|
||||
.arrows {
|
||||
fill: #000;
|
||||
stroke: none;
|
||||
}
|
||||
.selected>.arrows {
|
||||
fill: #fff;
|
||||
}
|
||||
.checkmark {
|
||||
fill: #000;
|
||||
font-family: sans-serif;
|
||||
font-size: 10pt;
|
||||
text-anchor: middle;
|
||||
}
|
||||
.trash {
|
||||
fill: #888;
|
||||
}
|
||||
.zoom {
|
||||
fill: none;
|
||||
stroke: #888;
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
.zoom>.center {
|
||||
fill: #888;
|
||||
stroke-width: 0;
|
||||
}
|
||||
</style>
|
||||
<rect id="background" width="96" height="124" x="0" y="0" />
|
||||
|
||||
<g>
|
||||
<path class="arrows" d="M 13,1.5 13,14.5 1.74,8 z" />
|
||||
<path class="arrows" d="M 17.5,3 30.5,3 24,14.26 z" />
|
||||
<path class="arrows" d="M 35,1.5 35,14.5 46.26,8 z" />
|
||||
</g>
|
||||
<g class="selected" transform="translate(0, 16)">
|
||||
<path class="arrows" d="M 13,1.5 13,14.5 1.74,8 z" />
|
||||
<path class="arrows" d="M 17.5,3 30.5,3 24,14.26 z" />
|
||||
<path class="arrows" d="M 35,1.5 35,14.5 46.26,8 z" />
|
||||
</g>
|
||||
|
||||
<text class="checkmark" x="55.5" y="28">✓</text>
|
||||
|
||||
<g class="trash">
|
||||
<path d="M 2,41 v 6 h 42 v -6 h -10.5 l -3,-3 h -15 l -3,3 z" />
|
||||
<rect width="36" height="20" x="5" y="50" />
|
||||
<rect width="36" height="42" x="5" y="50" rx="4" ry="4" />
|
||||
</g>
|
||||
|
||||
<g class="zoom">
|
||||
<circle r="11.5" cx="16" cy="108" />
|
||||
<circle r="4.3" cx="16" cy="108" class="center" />
|
||||
<path d="m 28,108 h3" />
|
||||
<path d="m 1,108 h3" />
|
||||
<path d="m 16,120 v3" />
|
||||
<path d="m 16,93 v3" />
|
||||
</g>
|
||||
|
||||
<g class="zoom">
|
||||
<circle r="15" cx="48" cy="108" />
|
||||
<path d="m 48,101.6 v12.8" />
|
||||
<path d="m 41.6,108 h12.8" />
|
||||
</g>
|
||||
|
||||
<g class="zoom">
|
||||
<circle r="15" cx="80" cy="108" />
|
||||
<path d="m 73.6,108 h12.8" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
434
clover_blocks/www/blockly/msg/js/en.js
Executable file
@@ -0,0 +1,434 @@
|
||||
// This file was automatically generated. Do not modify.
|
||||
|
||||
'use strict';
|
||||
|
||||
Blockly.Msg["ADD_COMMENT"] = "Add Comment";
|
||||
Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";
|
||||
Blockly.Msg["CHANGE_VALUE_TITLE"] = "Change value:";
|
||||
Blockly.Msg["CLEAN_UP"] = "Clean up Blocks";
|
||||
Blockly.Msg["COLLAPSED_WARNINGS_WARNING"] = "Collapsed blocks contain warnings.";
|
||||
Blockly.Msg["COLLAPSE_ALL"] = "Collapse Blocks";
|
||||
Blockly.Msg["COLLAPSE_BLOCK"] = "Collapse Block";
|
||||
Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "colour 1";
|
||||
Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "colour 2";
|
||||
Blockly.Msg["COLOUR_BLEND_HELPURL"] = "https://meyerweb.com/eric/tools/color-blend/#:::rgbp";
|
||||
Blockly.Msg["COLOUR_BLEND_RATIO"] = "ratio";
|
||||
Blockly.Msg["COLOUR_BLEND_TITLE"] = "blend";
|
||||
Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Blends two colours together with a given ratio (0.0 - 1.0).";
|
||||
Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
|
||||
Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Choose a colour from the palette.";
|
||||
Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com";
|
||||
Blockly.Msg["COLOUR_RANDOM_TITLE"] = "random colour";
|
||||
Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Choose a colour at random.";
|
||||
Blockly.Msg["COLOUR_RGB_BLUE"] = "blue";
|
||||
Blockly.Msg["COLOUR_RGB_GREEN"] = "green";
|
||||
Blockly.Msg["COLOUR_RGB_HELPURL"] = "https://www.december.com/html/spec/colorpercompact.html";
|
||||
Blockly.Msg["COLOUR_RGB_RED"] = "red";
|
||||
Blockly.Msg["COLOUR_RGB_TITLE"] = "colour with";
|
||||
Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";
|
||||
Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";
|
||||
Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "break out of loop";
|
||||
Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "continue with next iteration of loop";
|
||||
Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Break out of the containing loop.";
|
||||
Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Skip the rest of this loop, and continue with the next iteration.";
|
||||
Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Warning: This block may only be used within a loop.";
|
||||
Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each";
|
||||
Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "for each item %1 in list %2";
|
||||
Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "For each item in a list, set the variable '%1' to the item, and then do some statements.";
|
||||
Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with";
|
||||
Blockly.Msg["CONTROLS_FOR_TITLE"] = "count with %1 from %2 to %3 by %4";
|
||||
Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";
|
||||
Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Add a condition to the if block.";
|
||||
Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Add a final, catch-all condition to the if block.";
|
||||
Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse";
|
||||
Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this if block.";
|
||||
Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "else";
|
||||
Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "else if";
|
||||
Blockly.Msg["CONTROLS_IF_MSG_IF"] = "if";
|
||||
Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "If a value is true, then do some statements.";
|
||||
Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";
|
||||
Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";
|
||||
Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";
|
||||
Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
|
||||
Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "do";
|
||||
Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "repeat %1 times";
|
||||
Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Do some statements several times.";
|
||||
Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat";
|
||||
Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "repeat until";
|
||||
Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "repeat while";
|
||||
Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "While a value is false, then do some statements.";
|
||||
Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "While a value is true, then do some statements.";
|
||||
Blockly.Msg["DELETE_ALL_BLOCKS"] = "Delete all %1 blocks?";
|
||||
Blockly.Msg["DELETE_BLOCK"] = "Delete Block";
|
||||
Blockly.Msg["DELETE_VARIABLE"] = "Delete the '%1' variable";
|
||||
Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Delete %1 uses of the '%2' variable?";
|
||||
Blockly.Msg["DELETE_X_BLOCKS"] = "Delete %1 Blocks";
|
||||
Blockly.Msg["DISABLE_BLOCK"] = "Disable Block";
|
||||
Blockly.Msg["DUPLICATE_BLOCK"] = "Duplicate";
|
||||
Blockly.Msg["DUPLICATE_COMMENT"] = "Duplicate Comment";
|
||||
Blockly.Msg["ENABLE_BLOCK"] = "Enable Block";
|
||||
Blockly.Msg["EXPAND_ALL"] = "Expand Blocks";
|
||||
Blockly.Msg["EXPAND_BLOCK"] = "Expand Block";
|
||||
Blockly.Msg["EXTERNAL_INPUTS"] = "External Inputs";
|
||||
Blockly.Msg["HELP"] = "Help";
|
||||
Blockly.Msg["INLINE_INPUTS"] = "Inline Inputs";
|
||||
Blockly.Msg["IOS_CANCEL"] = "Cancel";
|
||||
Blockly.Msg["IOS_ERROR"] = "Error";
|
||||
Blockly.Msg["IOS_OK"] = "OK";
|
||||
Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input";
|
||||
Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements";
|
||||
Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs.";
|
||||
Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS";
|
||||
Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add";
|
||||
Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable";
|
||||
Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Delete";
|
||||
Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "You can't use an empty variable name.";
|
||||
Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename";
|
||||
Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Variable name";
|
||||
Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
|
||||
Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "create empty list";
|
||||
Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Returns a list, of length 0, containing no data records";
|
||||
Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "list";
|
||||
Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this list block.";
|
||||
Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
|
||||
Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "create list with";
|
||||
Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Add an item to the list.";
|
||||
Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Create a list with any number of items.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "first";
|
||||
Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "# from end";
|
||||
Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "#";
|
||||
Blockly.Msg["LISTS_GET_INDEX_GET"] = "get";
|
||||
Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "get and remove";
|
||||
Blockly.Msg["LISTS_GET_INDEX_LAST"] = "last";
|
||||
Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "random";
|
||||
Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "remove";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TAIL"] = "";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Returns the first item in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Returns the item at the specified position in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Returns the last item in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Returns a random item in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Removes and returns the first item in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Removes and returns the item at the specified position in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Removes and returns the last item in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Removes and returns a random item in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Removes the first item in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Removes the item at the specified position in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Removes the last item in a list.";
|
||||
Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Removes a random item in a list.";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "to # from end";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "to #";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "to last";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "get sub-list from first";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "get sub-list from # from end";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "get sub-list from #";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = "";
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Creates a copy of the specified portion of a list.";
|
||||
Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "%1 is the last item.";
|
||||
Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "%1 is the first item.";
|
||||
Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "find first occurrence of item";
|
||||
Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";
|
||||
Blockly.Msg["LISTS_INDEX_OF_LAST"] = "find last occurrence of item";
|
||||
Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";
|
||||
Blockly.Msg["LISTS_INLIST"] = "in list";
|
||||
Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty";
|
||||
Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 is empty";
|
||||
Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Returns true if the list is empty.";
|
||||
Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of";
|
||||
Blockly.Msg["LISTS_LENGTH_TITLE"] = "length of %1";
|
||||
Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Returns the length of a list.";
|
||||
Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with";
|
||||
Blockly.Msg["LISTS_REPEAT_TITLE"] = "create list with item %1 repeated %2 times";
|
||||
Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Creates a list consisting of the given value repeated the specified number of times.";
|
||||
Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
|
||||
Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1";
|
||||
Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list.";
|
||||
Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set";
|
||||
Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = "as";
|
||||
Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "insert at";
|
||||
Blockly.Msg["LISTS_SET_INDEX_SET"] = "set";
|
||||
Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Inserts the item at the start of a list.";
|
||||
Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Inserts the item at the specified position in a list.";
|
||||
Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Append the item to the end of a list.";
|
||||
Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Inserts the item randomly in a list.";
|
||||
Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Sets the first item in a list.";
|
||||
Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Sets the item at the specified position in a list.";
|
||||
Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Sets the last item in a list.";
|
||||
Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Sets a random item in a list.";
|
||||
Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
|
||||
Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "ascending";
|
||||
Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "descending";
|
||||
Blockly.Msg["LISTS_SORT_TITLE"] = "sort %1 %2 %3";
|
||||
Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Sort a copy of a list.";
|
||||
Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "alphabetic, ignore case";
|
||||
Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "numeric";
|
||||
Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "alphabetic";
|
||||
Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
|
||||
Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "make list from text";
|
||||
Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "make text from list";
|
||||
Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Join a list of texts into one text, separated by a delimiter.";
|
||||
Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Split text into a list of texts, breaking at each delimiter.";
|
||||
Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "with delimiter";
|
||||
Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "false";
|
||||
Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values";
|
||||
Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Returns either true or false.";
|
||||
Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "true";
|
||||
Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
|
||||
Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Return true if both inputs equal each other.";
|
||||
Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Return true if the first input is greater than the second input.";
|
||||
Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Return true if the first input is greater than or equal to the second input.";
|
||||
Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Return true if the first input is smaller than the second input.";
|
||||
Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Return true if the first input is smaller than or equal to the second input.";
|
||||
Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Return true if both inputs are not equal to each other.";
|
||||
Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not";
|
||||
Blockly.Msg["LOGIC_NEGATE_TITLE"] = "not %1";
|
||||
Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Returns true if the input is false. Returns false if the input is true.";
|
||||
Blockly.Msg["LOGIC_NULL"] = "null";
|
||||
Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type";
|
||||
Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Returns null.";
|
||||
Blockly.Msg["LOGIC_OPERATION_AND"] = "and";
|
||||
Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations";
|
||||
Blockly.Msg["LOGIC_OPERATION_OR"] = "or";
|
||||
Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Return true if both inputs are true.";
|
||||
Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Return true if at least one of the inputs is true.";
|
||||
Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "test";
|
||||
Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:";
|
||||
Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "if false";
|
||||
Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "if true";
|
||||
Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";
|
||||
Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+";
|
||||
Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://en.wikipedia.org/wiki/Arithmetic";
|
||||
Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Return the sum of the two numbers.";
|
||||
Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Return the quotient of the two numbers.";
|
||||
Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Return the difference of the two numbers.";
|
||||
Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Return the product of the two numbers.";
|
||||
Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Return the first number raised to the power of the second number.";
|
||||
Blockly.Msg["MATH_ATAN2_HELPURL"] = "https://en.wikipedia.org/wiki/Atan2";
|
||||
Blockly.Msg["MATH_ATAN2_TITLE"] = "atan2 of X:%1 Y:%2";
|
||||
Blockly.Msg["MATH_ATAN2_TOOLTIP"] = "Return the arctangent of point (X, Y) in degrees from -180 to 180.";
|
||||
Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
|
||||
Blockly.Msg["MATH_CHANGE_TITLE"] = "change %1 by %2";
|
||||
Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Add a number to variable '%1'.";
|
||||
Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
|
||||
Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
|
||||
Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)";
|
||||
Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "constrain %1 low %2 high %3";
|
||||
Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Constrain a number to be between the specified limits (inclusive).";
|
||||
Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷";
|
||||
Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "is divisible by";
|
||||
Blockly.Msg["MATH_IS_EVEN"] = "is even";
|
||||
Blockly.Msg["MATH_IS_NEGATIVE"] = "is negative";
|
||||
Blockly.Msg["MATH_IS_ODD"] = "is odd";
|
||||
Blockly.Msg["MATH_IS_POSITIVE"] = "is positive";
|
||||
Blockly.Msg["MATH_IS_PRIME"] = "is prime";
|
||||
Blockly.Msg["MATH_IS_TOOLTIP"] = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";
|
||||
Blockly.Msg["MATH_IS_WHOLE"] = "is whole";
|
||||
Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
|
||||
Blockly.Msg["MATH_MODULO_TITLE"] = "remainder of %1 ÷ %2";
|
||||
Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Return the remainder from dividing the two numbers.";
|
||||
Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×";
|
||||
Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://en.wikipedia.org/wiki/Number";
|
||||
Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "A number.";
|
||||
Blockly.Msg["MATH_ONLIST_HELPURL"] = "";
|
||||
Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "average of list";
|
||||
Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "max of list";
|
||||
Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "median of list";
|
||||
Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "min of list";
|
||||
Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "modes of list";
|
||||
Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "random item of list";
|
||||
Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "standard deviation of list";
|
||||
Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "sum of list";
|
||||
Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Return the average (arithmetic mean) of the numeric values in the list.";
|
||||
Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Return the largest number in the list.";
|
||||
Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";
|
||||
Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Return the smallest number in the list.";
|
||||
Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Return a list of the most common item(s) in the list.";
|
||||
Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Return a random element from the list.";
|
||||
Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Return the standard deviation of the list.";
|
||||
Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Return the sum of all the numbers in the list.";
|
||||
Blockly.Msg["MATH_POWER_SYMBOL"] = "^";
|
||||
Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
|
||||
Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "random fraction";
|
||||
Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";
|
||||
Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
|
||||
Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "random integer from %1 to %2";
|
||||
Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Return a random integer between the two specified limits, inclusive.";
|
||||
Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
|
||||
Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "round";
|
||||
Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "round down";
|
||||
Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "round up";
|
||||
Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Round a number up or down.";
|
||||
Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://en.wikipedia.org/wiki/Square_root";
|
||||
Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absolute";
|
||||
Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "square root";
|
||||
Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Return the absolute value of a number.";
|
||||
Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Return e to the power of a number.";
|
||||
Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Return the natural logarithm of a number.";
|
||||
Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Return the base 10 logarithm of a number.";
|
||||
Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Return the negation of a number.";
|
||||
Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Return 10 to the power of a number.";
|
||||
Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Return the square root of a number.";
|
||||
Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-";
|
||||
Blockly.Msg["MATH_TRIG_ACOS"] = "acos";
|
||||
Blockly.Msg["MATH_TRIG_ASIN"] = "asin";
|
||||
Blockly.Msg["MATH_TRIG_ATAN"] = "atan";
|
||||
Blockly.Msg["MATH_TRIG_COS"] = "cos";
|
||||
Blockly.Msg["MATH_TRIG_HELPURL"] = "https://en.wikipedia.org/wiki/Trigonometric_functions";
|
||||
Blockly.Msg["MATH_TRIG_SIN"] = "sin";
|
||||
Blockly.Msg["MATH_TRIG_TAN"] = "tan";
|
||||
Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Return the arccosine of a number.";
|
||||
Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Return the arcsine of a number.";
|
||||
Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Return the arctangent of a number.";
|
||||
Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Return the cosine of a degree (not radian).";
|
||||
Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Return the sine of a degree (not radian).";
|
||||
Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Return the tangent of a degree (not radian).";
|
||||
Blockly.Msg["NEW_COLOUR_VARIABLE"] = "Create colour variable...";
|
||||
Blockly.Msg["NEW_NUMBER_VARIABLE"] = "Create number variable...";
|
||||
Blockly.Msg["NEW_STRING_VARIABLE"] = "Create string variable...";
|
||||
Blockly.Msg["NEW_VARIABLE"] = "Create variable...";
|
||||
Blockly.Msg["NEW_VARIABLE_TITLE"] = "New variable name:";
|
||||
Blockly.Msg["NEW_VARIABLE_TYPE_TITLE"] = "New variable type:";
|
||||
Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = "";
|
||||
Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "allow statements";
|
||||
Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "with:";
|
||||
Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
|
||||
Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Run the user-defined function '%1'.";
|
||||
Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
|
||||
Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";
|
||||
Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "with:";
|
||||
Blockly.Msg["PROCEDURES_CREATE_DO"] = "Create '%1'";
|
||||
Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Describe this function...";
|
||||
Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = "";
|
||||
Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
|
||||
Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "do something";
|
||||
Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "to";
|
||||
Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Creates a function with no output.";
|
||||
Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine";
|
||||
Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "return";
|
||||
Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Creates a function with an output.";
|
||||
Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Warning: This function has duplicate parameters.";
|
||||
Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Highlight function definition";
|
||||
Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause";
|
||||
Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "If a value is true, then return a second value.";
|
||||
Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Warning: This block may be used only within a function definition.";
|
||||
Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "input name:";
|
||||
Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Add an input to the function.";
|
||||
Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "inputs";
|
||||
Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Add, remove, or reorder inputs to this function.";
|
||||
Blockly.Msg["REDO"] = "Redo";
|
||||
Blockly.Msg["REMOVE_COMMENT"] = "Remove Comment";
|
||||
Blockly.Msg["RENAME_VARIABLE"] = "Rename variable...";
|
||||
Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Rename all '%1' variables to:";
|
||||
Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
|
||||
Blockly.Msg["TEXT_APPEND_TITLE"] = "to %1 append text %2";
|
||||
Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Append some text to variable '%1'.";
|
||||
Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";
|
||||
Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "to lower case";
|
||||
Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "to Title Case";
|
||||
Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "to UPPER CASE";
|
||||
Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Return a copy of the text in a different case.";
|
||||
Blockly.Msg["TEXT_CHARAT_FIRST"] = "get first letter";
|
||||
Blockly.Msg["TEXT_CHARAT_FROM_END"] = "get letter # from end";
|
||||
Blockly.Msg["TEXT_CHARAT_FROM_START"] = "get letter #";
|
||||
Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text";
|
||||
Blockly.Msg["TEXT_CHARAT_LAST"] = "get last letter";
|
||||
Blockly.Msg["TEXT_CHARAT_RANDOM"] = "get random letter";
|
||||
Blockly.Msg["TEXT_CHARAT_TAIL"] = "";
|
||||
Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2";
|
||||
Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Returns the letter at the specified position.";
|
||||
Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings";
|
||||
Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2";
|
||||
Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Count how many times some text occurs within some other text.";
|
||||
Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Add an item to the text.";
|
||||
Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "join";
|
||||
Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Add, remove, or reorder sections to reconfigure this text block.";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "to letter # from end";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "to letter #";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "to last letter";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "in text";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "get substring from first letter";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "get substring from letter # from end";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "get substring from letter #";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = "";
|
||||
Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Returns a specified portion of the text.";
|
||||
Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text";
|
||||
Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "find first occurrence of text";
|
||||
Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "find last occurrence of text";
|
||||
Blockly.Msg["TEXT_INDEXOF_TITLE"] = "in text %1 %2 %3";
|
||||
Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";
|
||||
Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";
|
||||
Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 is empty";
|
||||
Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Returns true if the provided text is empty.";
|
||||
Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation";
|
||||
Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "create text with";
|
||||
Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Create a piece of text by joining together any number of items.";
|
||||
Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification";
|
||||
Blockly.Msg["TEXT_LENGTH_TITLE"] = "length of %1";
|
||||
Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Returns the number of letters (including spaces) in the provided text.";
|
||||
Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text";
|
||||
Blockly.Msg["TEXT_PRINT_TITLE"] = "print %1";
|
||||
Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Print the specified text, number or other value.";
|
||||
Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";
|
||||
Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Prompt for user for a number.";
|
||||
Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Prompt for user for some text.";
|
||||
Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "prompt for number with message";
|
||||
Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "prompt for text with message";
|
||||
Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
|
||||
Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3";
|
||||
Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text.";
|
||||
Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text";
|
||||
Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1";
|
||||
Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text.";
|
||||
Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
|
||||
Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "A letter, word, or line of text.";
|
||||
Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";
|
||||
Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "trim spaces from both sides of";
|
||||
Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "trim spaces from left side of";
|
||||
Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "trim spaces from right side of";
|
||||
Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Return a copy of the text with spaces removed from one or both ends.";
|
||||
Blockly.Msg["TODAY"] = "Today";
|
||||
Blockly.Msg["UNDO"] = "Undo";
|
||||
Blockly.Msg["UNNAMED_KEY"] = "unnamed";
|
||||
Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "item";
|
||||
Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Create 'set %1'";
|
||||
Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get";
|
||||
Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Returns the value of this variable.";
|
||||
Blockly.Msg["VARIABLES_SET"] = "set %1 to %2";
|
||||
Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Create 'get %1'";
|
||||
Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set";
|
||||
Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Sets this variable to be equal to the input.";
|
||||
Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "A variable named '%1' already exists.";
|
||||
Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another type: '%2'.";
|
||||
Blockly.Msg["WORKSPACE_ARIA_LABEL"] = "Blockly Workspace";
|
||||
Blockly.Msg["WORKSPACE_COMMENT_DEFAULT_TEXT"] = "Say something...";
|
||||
Blockly.Msg["CONTROLS_FOREACH_INPUT_DO"] = Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"];
|
||||
Blockly.Msg["CONTROLS_FOR_INPUT_DO"] = Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"];
|
||||
Blockly.Msg["CONTROLS_IF_ELSEIF_TITLE_ELSEIF"] = Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"];
|
||||
Blockly.Msg["CONTROLS_IF_ELSE_TITLE_ELSE"] = Blockly.Msg["CONTROLS_IF_MSG_ELSE"];
|
||||
Blockly.Msg["CONTROLS_IF_IF_TITLE_IF"] = Blockly.Msg["CONTROLS_IF_MSG_IF"];
|
||||
Blockly.Msg["CONTROLS_IF_MSG_THEN"] = Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"];
|
||||
Blockly.Msg["CONTROLS_WHILEUNTIL_INPUT_DO"] = Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"];
|
||||
Blockly.Msg["LISTS_CREATE_WITH_ITEM_TITLE"] = Blockly.Msg["VARIABLES_DEFAULT_NAME"];
|
||||
Blockly.Msg["LISTS_GET_INDEX_HELPURL"] = Blockly.Msg["LISTS_INDEX_OF_HELPURL"];
|
||||
Blockly.Msg["LISTS_GET_INDEX_INPUT_IN_LIST"] = Blockly.Msg["LISTS_INLIST"];
|
||||
Blockly.Msg["LISTS_GET_SUBLIST_INPUT_IN_LIST"] = Blockly.Msg["LISTS_INLIST"];
|
||||
Blockly.Msg["LISTS_INDEX_OF_INPUT_IN_LIST"] = Blockly.Msg["LISTS_INLIST"];
|
||||
Blockly.Msg["LISTS_SET_INDEX_INPUT_IN_LIST"] = Blockly.Msg["LISTS_INLIST"];
|
||||
Blockly.Msg["MATH_CHANGE_TITLE_ITEM"] = Blockly.Msg["VARIABLES_DEFAULT_NAME"];
|
||||
Blockly.Msg["PROCEDURES_DEFRETURN_COMMENT"] = Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"];
|
||||
Blockly.Msg["PROCEDURES_DEFRETURN_DO"] = Blockly.Msg["PROCEDURES_DEFNORETURN_DO"];
|
||||
Blockly.Msg["PROCEDURES_DEFRETURN_PROCEDURE"] = Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"];
|
||||
Blockly.Msg["PROCEDURES_DEFRETURN_TITLE"] = Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"];
|
||||
Blockly.Msg["TEXT_APPEND_VARIABLE"] = Blockly.Msg["VARIABLES_DEFAULT_NAME"];
|
||||
Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TITLE_ITEM"] = Blockly.Msg["VARIABLES_DEFAULT_NAME"];
|
||||
|
||||
Blockly.Msg["MATH_HUE"] = "230";
|
||||
Blockly.Msg["LOOPS_HUE"] = "120";
|
||||
Blockly.Msg["LISTS_HUE"] = "260";
|
||||
Blockly.Msg["LOGIC_HUE"] = "210";
|
||||
Blockly.Msg["VARIABLES_HUE"] = "330";
|
||||
Blockly.Msg["TEXTS_HUE"] = "160";
|
||||
Blockly.Msg["PROCEDURES_HUE"] = "290";
|
||||
Blockly.Msg["COLOUR_HUE"] = "20";
|
||||
Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
|
||||
98
clover_blocks/www/blockly/python_compressed.js
Executable file
@@ -0,0 +1,98 @@
|
||||
// Do not edit this file; automatically generated by gulp.
|
||||
|
||||
/* eslint-disable */
|
||||
;(function(root, factory) {
|
||||
if (typeof define === 'function' && define.amd) { // AMD
|
||||
define(['./blockly_compressed.js'], factory);
|
||||
} else if (typeof exports === 'object') { // Node.js
|
||||
module.exports = factory(require('./blockly_compressed.js'));
|
||||
} else { // Browser
|
||||
root.Blockly.Python = factory(root.Blockly);
|
||||
}
|
||||
}(this, function(Blockly) {
|
||||
'use strict';Blockly.Python=new Blockly.Generator("Python");Blockly.Python.addReservedWords("False,None,True,and,as,assert,break,class,continue,def,del,elif,else,except,exec,finally,for,from,global,if,import,in,is,lambda,nonlocal,not,or,pass,print,raise,return,try,while,with,yield,NotImplemented,Ellipsis,__debug__,quit,exit,copyright,license,credits,ArithmeticError,AssertionError,AttributeError,BaseException,BlockingIOError,BrokenPipeError,BufferError,BytesWarning,ChildProcessError,ConnectionAbortedError,ConnectionError,ConnectionRefusedError,ConnectionResetError,DeprecationWarning,EOFError,Ellipsis,EnvironmentError,Exception,FileExistsError,FileNotFoundError,FloatingPointError,FutureWarning,GeneratorExit,IOError,ImportError,ImportWarning,IndentationError,IndexError,InterruptedError,IsADirectoryError,KeyError,KeyboardInterrupt,LookupError,MemoryError,ModuleNotFoundError,NameError,NotADirectoryError,NotImplemented,NotImplementedError,OSError,OverflowError,PendingDeprecationWarning,PermissionError,ProcessLookupError,RecursionError,ReferenceError,ResourceWarning,RuntimeError,RuntimeWarning,StandardError,StopAsyncIteration,StopIteration,SyntaxError,SyntaxWarning,SystemError,SystemExit,TabError,TimeoutError,TypeError,UnboundLocalError,UnicodeDecodeError,UnicodeEncodeError,UnicodeError,UnicodeTranslateError,UnicodeWarning,UserWarning,ValueError,Warning,ZeroDivisionError,_,__build_class__,__debug__,__doc__,__import__,__loader__,__name__,__package__,__spec__,abs,all,any,apply,ascii,basestring,bin,bool,buffer,bytearray,bytes,callable,chr,classmethod,cmp,coerce,compile,complex,copyright,credits,delattr,dict,dir,divmod,enumerate,eval,exec,execfile,exit,file,filter,float,format,frozenset,getattr,globals,hasattr,hash,help,hex,id,input,int,intern,isinstance,issubclass,iter,len,license,list,locals,long,map,max,memoryview,min,next,object,oct,open,ord,pow,print,property,quit,range,raw_input,reduce,reload,repr,reversed,round,set,setattr,slice,sorted,staticmethod,str,sum,super,tuple,type,unichr,unicode,vars,xrange,zip");
|
||||
Blockly.Python.ORDER_ATOMIC=0;Blockly.Python.ORDER_COLLECTION=1;Blockly.Python.ORDER_STRING_CONVERSION=1;Blockly.Python.ORDER_MEMBER=2.1;Blockly.Python.ORDER_FUNCTION_CALL=2.2;Blockly.Python.ORDER_EXPONENTIATION=3;Blockly.Python.ORDER_UNARY_SIGN=4;Blockly.Python.ORDER_BITWISE_NOT=4;Blockly.Python.ORDER_MULTIPLICATIVE=5;Blockly.Python.ORDER_ADDITIVE=6;Blockly.Python.ORDER_BITWISE_SHIFT=7;Blockly.Python.ORDER_BITWISE_AND=8;Blockly.Python.ORDER_BITWISE_XOR=9;Blockly.Python.ORDER_BITWISE_OR=10;
|
||||
Blockly.Python.ORDER_RELATIONAL=11;Blockly.Python.ORDER_LOGICAL_NOT=12;Blockly.Python.ORDER_LOGICAL_AND=13;Blockly.Python.ORDER_LOGICAL_OR=14;Blockly.Python.ORDER_CONDITIONAL=15;Blockly.Python.ORDER_LAMBDA=16;Blockly.Python.ORDER_NONE=99;
|
||||
Blockly.Python.ORDER_OVERRIDES=[[Blockly.Python.ORDER_FUNCTION_CALL,Blockly.Python.ORDER_MEMBER],[Blockly.Python.ORDER_FUNCTION_CALL,Blockly.Python.ORDER_FUNCTION_CALL],[Blockly.Python.ORDER_MEMBER,Blockly.Python.ORDER_MEMBER],[Blockly.Python.ORDER_MEMBER,Blockly.Python.ORDER_FUNCTION_CALL],[Blockly.Python.ORDER_LOGICAL_NOT,Blockly.Python.ORDER_LOGICAL_NOT],[Blockly.Python.ORDER_LOGICAL_AND,Blockly.Python.ORDER_LOGICAL_AND],[Blockly.Python.ORDER_LOGICAL_OR,Blockly.Python.ORDER_LOGICAL_OR]];
|
||||
Blockly.Python.init=function(a){Blockly.Python.PASS=this.INDENT+"pass\n";Blockly.Python.definitions_=Object.create(null);Blockly.Python.functionNames_=Object.create(null);Blockly.Python.variableDB_?Blockly.Python.variableDB_.reset():Blockly.Python.variableDB_=new Blockly.Names(Blockly.Python.RESERVED_WORDS_);Blockly.Python.variableDB_.setVariableMap(a.getVariableMap());for(var b=[],c=Blockly.Variables.allDeveloperVariables(a),d=0;d<c.length;d++)b.push(Blockly.Python.variableDB_.getName(c[d],Blockly.Names.DEVELOPER_VARIABLE_TYPE)+
|
||||
" = None");a=Blockly.Variables.allUsedVarModels(a);for(d=0;d<a.length;d++)b.push(Blockly.Python.variableDB_.getName(a[d].getId(),Blockly.VARIABLE_CATEGORY_NAME)+" = None");Blockly.Python.definitions_.variables=b.join("\n")};
|
||||
Blockly.Python.finish=function(a){var b=[],c=[],d;for(d in Blockly.Python.definitions_){var e=Blockly.Python.definitions_[d];e.match(/^(from\s+\S+\s+)?import\s+\S+/)?b.push(e):c.push(e)}delete Blockly.Python.definitions_;delete Blockly.Python.functionNames_;Blockly.Python.variableDB_.reset();return(b.join("\n")+"\n\n"+c.join("\n\n")).replace(/\n\n+/g,"\n\n").replace(/\n*$/,"\n\n\n")+a};Blockly.Python.scrubNakedValue=function(a){return a+"\n"};
|
||||
Blockly.Python.quote_=function(a){a=a.replace(/\\/g,"\\\\").replace(/\n/g,"\\\n");var b="'";-1!==a.indexOf("'")&&(-1===a.indexOf('"')?b='"':a=a.replace(/'/g,"\\'"));return b+a+b};Blockly.Python.multiline_quote_=function(a){a=a.replace(/'''/g,"\\'\\'\\'");return"'''"+a+"'''"};
|
||||
Blockly.Python.scrub_=function(a,b,c){var d="";if(!a.outputConnection||!a.outputConnection.targetConnection){var e=a.getCommentText();e&&(e=Blockly.utils.string.wrap(e,Blockly.Python.COMMENT_WRAP-3),d+=Blockly.Python.prefixLines(e+"\n","# "));for(var f=0;f<a.inputList.length;f++)a.inputList[f].type==Blockly.INPUT_VALUE&&(e=a.inputList[f].connection.targetBlock())&&(e=Blockly.Python.allNestedComments(e))&&(d+=Blockly.Python.prefixLines(e,"# "))}a=a.nextConnection&&a.nextConnection.targetBlock();c=
|
||||
c?"":Blockly.Python.blockToCode(a);return d+b+c};Blockly.Python.getAdjustedInt=function(a,b,c,d){c=c||0;a.workspace.options.oneBasedIndex&&c--;var e=a.workspace.options.oneBasedIndex?"1":"0";a=Blockly.Python.valueToCode(a,b,c?Blockly.Python.ORDER_ADDITIVE:Blockly.Python.ORDER_NONE)||e;Blockly.isNumber(a)?(a=parseInt(a,10)+c,d&&(a=-a)):(a=0<c?"int("+a+" + "+c+")":0>c?"int("+a+" - "+-c+")":"int("+a+")",d&&(a="-"+a));return a};Blockly.Python.colour={};Blockly.Python.colour_picker=function(a){return[Blockly.Python.quote_(a.getFieldValue("COLOUR")),Blockly.Python.ORDER_ATOMIC]};Blockly.Python.colour_random=function(a){Blockly.Python.definitions_.import_random="import random";return["'#%06x' % random.randint(0, 2**24 - 1)",Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.colour_rgb=function(a){var b=Blockly.Python.provideFunction_("colour_rgb",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(r, g, b):"," r = round(min(100, max(0, r)) * 2.55)"," g = round(min(100, max(0, g)) * 2.55)"," b = round(min(100, max(0, b)) * 2.55)"," return '#%02x%02x%02x' % (r, g, b)"]),c=Blockly.Python.valueToCode(a,"RED",Blockly.Python.ORDER_NONE)||0,d=Blockly.Python.valueToCode(a,"GREEN",Blockly.Python.ORDER_NONE)||0;a=Blockly.Python.valueToCode(a,"BLUE",Blockly.Python.ORDER_NONE)||
|
||||
0;return[b+"("+c+", "+d+", "+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.colour_blend=function(a){var b=Blockly.Python.provideFunction_("colour_blend",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(colour1, colour2, ratio):"," r1, r2 = int(colour1[1:3], 16), int(colour2[1:3], 16)"," g1, g2 = int(colour1[3:5], 16), int(colour2[3:5], 16)"," b1, b2 = int(colour1[5:7], 16), int(colour2[5:7], 16)"," ratio = min(1, max(0, ratio))"," r = round(r1 * (1 - ratio) + r2 * ratio)"," g = round(g1 * (1 - ratio) + g2 * ratio)"," b = round(b1 * (1 - ratio) + b2 * ratio)",
|
||||
" return '#%02x%02x%02x' % (r, g, b)"]),c=Blockly.Python.valueToCode(a,"COLOUR1",Blockly.Python.ORDER_NONE)||"'#000000'",d=Blockly.Python.valueToCode(a,"COLOUR2",Blockly.Python.ORDER_NONE)||"'#000000'";a=Blockly.Python.valueToCode(a,"RATIO",Blockly.Python.ORDER_NONE)||0;return[b+"("+c+", "+d+", "+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.lists={};Blockly.Python.lists_create_empty=function(a){return["[]",Blockly.Python.ORDER_ATOMIC]};Blockly.Python.lists_create_with=function(a){for(var b=Array(a.itemCount_),c=0;c<a.itemCount_;c++)b[c]=Blockly.Python.valueToCode(a,"ADD"+c,Blockly.Python.ORDER_NONE)||"None";return["["+b.join(", ")+"]",Blockly.Python.ORDER_ATOMIC]};
|
||||
Blockly.Python.lists_repeat=function(a){var b=Blockly.Python.valueToCode(a,"ITEM",Blockly.Python.ORDER_NONE)||"None";a=Blockly.Python.valueToCode(a,"NUM",Blockly.Python.ORDER_MULTIPLICATIVE)||"0";return["["+b+"] * "+a,Blockly.Python.ORDER_MULTIPLICATIVE]};Blockly.Python.lists_length=function(a){return["len("+(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"[]")+")",Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.lists_isEmpty=function(a){return["not len("+(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"[]")+")",Blockly.Python.ORDER_LOGICAL_NOT]};
|
||||
Blockly.Python.lists_indexOf=function(a){var b=Blockly.Python.valueToCode(a,"FIND",Blockly.Python.ORDER_NONE)||"[]",c=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"''";if(a.workspace.options.oneBasedIndex)var d=" 0",e=" + 1",f="";else d=" -1",e="",f=" - 1";if("FIRST"==a.getFieldValue("END"))return a=Blockly.Python.provideFunction_("first_index",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(my_list, elem):"," try: index = my_list.index(elem)"+e," except: index ="+d," return index"]),
|
||||
[a+"("+c+", "+b+")",Blockly.Python.ORDER_FUNCTION_CALL];a=Blockly.Python.provideFunction_("last_index",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(my_list, elem):"," try: index = len(my_list) - my_list[::-1].index(elem)"+f," except: index ="+d," return index"]);return[a+"("+c+", "+b+")",Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.lists_getIndex=function(a){var b=a.getFieldValue("MODE")||"GET",c=a.getFieldValue("WHERE")||"FROM_START",d=Blockly.Python.valueToCode(a,"VALUE","RANDOM"==c?Blockly.Python.ORDER_NONE:Blockly.Python.ORDER_MEMBER)||"[]";switch(c){case "FIRST":if("GET"==b)return[d+"[0]",Blockly.Python.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".pop(0)",Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".pop(0)\n";break;case "LAST":if("GET"==b)return[d+"[-1]",Blockly.Python.ORDER_MEMBER];if("GET_REMOVE"==
|
||||
b)return[d+".pop()",Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".pop()\n";break;case "FROM_START":a=Blockly.Python.getAdjustedInt(a,"AT");if("GET"==b)return[d+"["+a+"]",Blockly.Python.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".pop("+a+")",Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".pop("+a+")\n";break;case "FROM_END":a=Blockly.Python.getAdjustedInt(a,"AT",1,!0);if("GET"==b)return[d+"["+a+"]",Blockly.Python.ORDER_MEMBER];if("GET_REMOVE"==b)return[d+".pop("+a+")",
|
||||
Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==b)return d+".pop("+a+")\n";break;case "RANDOM":Blockly.Python.definitions_.import_random="import random";if("GET"==b)return["random.choice("+d+")",Blockly.Python.ORDER_FUNCTION_CALL];d=Blockly.Python.provideFunction_("lists_remove_random_item",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(myList):"," x = int(random.random() * len(myList))"," return myList.pop(x)"])+"("+d+")";if("GET_REMOVE"==b)return[d,Blockly.Python.ORDER_FUNCTION_CALL];if("REMOVE"==
|
||||
b)return d+"\n"}throw Error("Unhandled combination (lists_getIndex).");};
|
||||
Blockly.Python.lists_setIndex=function(a){var b=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_MEMBER)||"[]",c=a.getFieldValue("MODE")||"GET",d=a.getFieldValue("WHERE")||"FROM_START",e=Blockly.Python.valueToCode(a,"TO",Blockly.Python.ORDER_NONE)||"None";switch(d){case "FIRST":if("SET"==c)return b+"[0] = "+e+"\n";if("INSERT"==c)return b+".insert(0, "+e+")\n";break;case "LAST":if("SET"==c)return b+"[-1] = "+e+"\n";if("INSERT"==c)return b+".append("+e+")\n";break;case "FROM_START":a=Blockly.Python.getAdjustedInt(a,
|
||||
"AT");if("SET"==c)return b+"["+a+"] = "+e+"\n";if("INSERT"==c)return b+".insert("+a+", "+e+")\n";break;case "FROM_END":a=Blockly.Python.getAdjustedInt(a,"AT",1,!0);if("SET"==c)return b+"["+a+"] = "+e+"\n";if("INSERT"==c)return b+".insert("+a+", "+e+")\n";break;case "RANDOM":Blockly.Python.definitions_.import_random="import random";b.match(/^\w+$/)?a="":(a=Blockly.Python.variableDB_.getDistinctName("tmp_list",Blockly.VARIABLE_CATEGORY_NAME),d=a+" = "+b+"\n",b=a,a=d);d=Blockly.Python.variableDB_.getDistinctName("tmp_x",
|
||||
Blockly.VARIABLE_CATEGORY_NAME);a+=d+" = int(random.random() * len("+b+"))\n";if("SET"==c)return a+(b+"["+d+"] = "+e+"\n");if("INSERT"==c)return a+(b+".insert("+d+", "+e+")\n")}throw Error("Unhandled combination (lists_setIndex).");};
|
||||
Blockly.Python.lists_getSublist=function(a){var b=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_MEMBER)||"[]",c=a.getFieldValue("WHERE1"),d=a.getFieldValue("WHERE2");switch(c){case "FROM_START":c=Blockly.Python.getAdjustedInt(a,"AT1");"0"==c&&(c="");break;case "FROM_END":c=Blockly.Python.getAdjustedInt(a,"AT1",1,!0);break;case "FIRST":c="";break;default:throw Error("Unhandled option (lists_getSublist)");}switch(d){case "FROM_START":a=Blockly.Python.getAdjustedInt(a,"AT2",1);break;case "FROM_END":a=
|
||||
Blockly.Python.getAdjustedInt(a,"AT2",0,!0);Blockly.isNumber(String(a))?"0"==a&&(a=""):(Blockly.Python.definitions_.import_sys="import sys",a+=" or sys.maxsize");break;case "LAST":a="";break;default:throw Error("Unhandled option (lists_getSublist)");}return[b+"["+c+" : "+a+"]",Blockly.Python.ORDER_MEMBER]};
|
||||
Blockly.Python.lists_sort=function(a){var b=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_NONE)||"[]",c=a.getFieldValue("TYPE");a="1"===a.getFieldValue("DIRECTION")?"False":"True";return[Blockly.Python.provideFunction_("lists_sort",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(my_list, type, reverse):"," def try_float(s):"," try:"," return float(s)"," except:"," return 0"," key_funcs = {",' "NUMERIC": try_float,',' "TEXT": str,',' "IGNORE_CASE": lambda s: str(s).lower()',
|
||||
" }"," key_func = key_funcs[type]"," list_cpy = list(my_list)"," return sorted(list_cpy, key=key_func, reverse=reverse)"])+"("+b+', "'+c+'", '+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.lists_split=function(a){var b=a.getFieldValue("MODE");if("SPLIT"==b)b=Blockly.Python.valueToCode(a,"INPUT",Blockly.Python.ORDER_MEMBER)||"''",a=Blockly.Python.valueToCode(a,"DELIM",Blockly.Python.ORDER_NONE),a=b+".split("+a+")";else if("JOIN"==b)b=Blockly.Python.valueToCode(a,"INPUT",Blockly.Python.ORDER_NONE)||"[]",a=Blockly.Python.valueToCode(a,"DELIM",Blockly.Python.ORDER_MEMBER)||"''",a=a+".join("+b+")";else throw Error("Unknown mode: "+b);return[a,Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.lists_reverse=function(a){return["list(reversed("+(Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_NONE)||"[]")+"))",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.logic={};
|
||||
Blockly.Python.controls_if=function(a){var b=0,c="";Blockly.Python.STATEMENT_PREFIX&&(c+=Blockly.Python.injectId(Blockly.Python.STATEMENT_PREFIX,a));do{var d=Blockly.Python.valueToCode(a,"IF"+b,Blockly.Python.ORDER_NONE)||"False";var e=Blockly.Python.statementToCode(a,"DO"+b)||Blockly.Python.PASS;Blockly.Python.STATEMENT_SUFFIX&&(e=Blockly.Python.prefixLines(Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX,a),Blockly.Python.INDENT)+e);c+=(0==b?"if ":"elif ")+d+":\n"+e;++b}while(a.getInput("IF"+
|
||||
b));if(a.getInput("ELSE")||Blockly.Python.STATEMENT_SUFFIX)e=Blockly.Python.statementToCode(a,"ELSE")||Blockly.Python.PASS,Blockly.Python.STATEMENT_SUFFIX&&(e=Blockly.Python.prefixLines(Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX,a),Blockly.Python.INDENT)+e),c+="else:\n"+e;return c};Blockly.Python.controls_ifelse=Blockly.Python.controls_if;
|
||||
Blockly.Python.logic_compare=function(a){var b={EQ:"==",NEQ:"!=",LT:"<",LTE:"<=",GT:">",GTE:">="}[a.getFieldValue("OP")],c=Blockly.Python.ORDER_RELATIONAL,d=Blockly.Python.valueToCode(a,"A",c)||"0";a=Blockly.Python.valueToCode(a,"B",c)||"0";return[d+" "+b+" "+a,c]};
|
||||
Blockly.Python.logic_operation=function(a){var b="AND"==a.getFieldValue("OP")?"and":"or",c="and"==b?Blockly.Python.ORDER_LOGICAL_AND:Blockly.Python.ORDER_LOGICAL_OR,d=Blockly.Python.valueToCode(a,"A",c);a=Blockly.Python.valueToCode(a,"B",c);if(d||a){var e="and"==b?"True":"False";d||(d=e);a||(a=e)}else a=d="False";return[d+" "+b+" "+a,c]};Blockly.Python.logic_negate=function(a){return["not "+(Blockly.Python.valueToCode(a,"BOOL",Blockly.Python.ORDER_LOGICAL_NOT)||"True"),Blockly.Python.ORDER_LOGICAL_NOT]};
|
||||
Blockly.Python.logic_boolean=function(a){return["TRUE"==a.getFieldValue("BOOL")?"True":"False",Blockly.Python.ORDER_ATOMIC]};Blockly.Python.logic_null=function(a){return["None",Blockly.Python.ORDER_ATOMIC]};
|
||||
Blockly.Python.logic_ternary=function(a){var b=Blockly.Python.valueToCode(a,"IF",Blockly.Python.ORDER_CONDITIONAL)||"False",c=Blockly.Python.valueToCode(a,"THEN",Blockly.Python.ORDER_CONDITIONAL)||"None";a=Blockly.Python.valueToCode(a,"ELSE",Blockly.Python.ORDER_CONDITIONAL)||"None";return[c+" if "+b+" else "+a,Blockly.Python.ORDER_CONDITIONAL]};Blockly.Python.loops={};Blockly.Python.controls_repeat_ext=function(a){var b=a.getField("TIMES")?String(parseInt(a.getFieldValue("TIMES"),10)):Blockly.Python.valueToCode(a,"TIMES",Blockly.Python.ORDER_NONE)||"0";b=Blockly.isNumber(b)?parseInt(b,10):"int("+b+")";var c=Blockly.Python.statementToCode(a,"DO");c=Blockly.Python.addLoopTrap(c,a)||Blockly.Python.PASS;return"for "+Blockly.Python.variableDB_.getDistinctName("count",Blockly.VARIABLE_CATEGORY_NAME)+" in range("+b+"):\n"+c};
|
||||
Blockly.Python.controls_repeat=Blockly.Python.controls_repeat_ext;Blockly.Python.controls_whileUntil=function(a){var b="UNTIL"==a.getFieldValue("MODE"),c=Blockly.Python.valueToCode(a,"BOOL",b?Blockly.Python.ORDER_LOGICAL_NOT:Blockly.Python.ORDER_NONE)||"False",d=Blockly.Python.statementToCode(a,"DO");d=Blockly.Python.addLoopTrap(d,a)||Blockly.Python.PASS;b&&(c="not "+c);return"while "+c+":\n"+d};
|
||||
Blockly.Python.controls_for=function(a){var b=Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME),c=Blockly.Python.valueToCode(a,"FROM",Blockly.Python.ORDER_NONE)||"0",d=Blockly.Python.valueToCode(a,"TO",Blockly.Python.ORDER_NONE)||"0",e=Blockly.Python.valueToCode(a,"BY",Blockly.Python.ORDER_NONE)||"1",f=Blockly.Python.statementToCode(a,"DO");f=Blockly.Python.addLoopTrap(f,a)||Blockly.Python.PASS;var l="",h=function(){return Blockly.Python.provideFunction_("upRange",
|
||||
["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(start, stop, step):"," while start <= stop:"," yield start"," start += abs(step)"])},g=function(){return Blockly.Python.provideFunction_("downRange",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(start, stop, step):"," while start >= stop:"," yield start"," start -= abs(step)"])};a=function(a,b,c){return"("+a+" <= "+b+") and "+h()+"("+a+", "+b+", "+c+") or "+g()+"("+a+", "+b+", "+c+")"};if(Blockly.isNumber(c)&&Blockly.isNumber(d)&&
|
||||
Blockly.isNumber(e))c=Number(c),d=Number(d),e=Math.abs(Number(e)),0===c%1&&0===d%1&&0===e%1?(c<=d?(d++,a=0==c&&1==e?d:c+", "+d,1!=e&&(a+=", "+e)):(d--,a=c+", "+d+", -"+e),a="range("+a+")"):(a=c<d?h():g(),a+="("+c+", "+d+", "+e+")");else{var k=function(a,c){Blockly.isNumber(a)?a=Number(a):a.match(/^\w+$/)?a="float("+a+")":(c=Blockly.Python.variableDB_.getDistinctName(b+c,Blockly.VARIABLE_CATEGORY_NAME),l+=c+" = float("+a+")\n",a=c);return a};c=k(c,"_start");d=k(d,"_end");k(e,"_inc");a="number"==typeof c&&
|
||||
"number"==typeof d?c<d?h(c,d,e):g(c,d,e):a(c,d,e)}return l+="for "+b+" in "+a+":\n"+f};Blockly.Python.controls_forEach=function(a){var b=Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME),c=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_RELATIONAL)||"[]",d=Blockly.Python.statementToCode(a,"DO");d=Blockly.Python.addLoopTrap(d,a)||Blockly.Python.PASS;return"for "+b+" in "+c+":\n"+d};
|
||||
Blockly.Python.controls_flow_statements=function(a){var b="";Blockly.Python.STATEMENT_PREFIX&&(b+=Blockly.Python.injectId(Blockly.Python.STATEMENT_PREFIX,a));Blockly.Python.STATEMENT_SUFFIX&&(b+=Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX,a));if(Blockly.Python.STATEMENT_PREFIX){var c=Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(a);c&&!c.suppressPrefixSuffix&&(b+=Blockly.Python.injectId(Blockly.Python.STATEMENT_PREFIX,c))}switch(a.getFieldValue("FLOW")){case "BREAK":return b+
|
||||
"break\n";case "CONTINUE":return b+"continue\n"}throw Error("Unknown flow statement.");};Blockly.Python.math={};Blockly.Python.addReservedWords("math,random,Number");Blockly.Python.math_number=function(a){a=Number(a.getFieldValue("NUM"));if(Infinity==a){a='float("inf")';var b=Blockly.Python.ORDER_FUNCTION_CALL}else-Infinity==a?(a='-float("inf")',b=Blockly.Python.ORDER_UNARY_SIGN):b=0>a?Blockly.Python.ORDER_UNARY_SIGN:Blockly.Python.ORDER_ATOMIC;return[a,b]};
|
||||
Blockly.Python.math_arithmetic=function(a){var b={ADD:[" + ",Blockly.Python.ORDER_ADDITIVE],MINUS:[" - ",Blockly.Python.ORDER_ADDITIVE],MULTIPLY:[" * ",Blockly.Python.ORDER_MULTIPLICATIVE],DIVIDE:[" / ",Blockly.Python.ORDER_MULTIPLICATIVE],POWER:[" ** ",Blockly.Python.ORDER_EXPONENTIATION]}[a.getFieldValue("OP")],c=b[0];b=b[1];var d=Blockly.Python.valueToCode(a,"A",b)||"0";a=Blockly.Python.valueToCode(a,"B",b)||"0";return[d+c+a,b]};
|
||||
Blockly.Python.math_single=function(a){var b=a.getFieldValue("OP");if("NEG"==b){var c=Blockly.Python.valueToCode(a,"NUM",Blockly.Python.ORDER_UNARY_SIGN)||"0";return["-"+c,Blockly.Python.ORDER_UNARY_SIGN]}Blockly.Python.definitions_.import_math="import math";a="SIN"==b||"COS"==b||"TAN"==b?Blockly.Python.valueToCode(a,"NUM",Blockly.Python.ORDER_MULTIPLICATIVE)||"0":Blockly.Python.valueToCode(a,"NUM",Blockly.Python.ORDER_NONE)||"0";switch(b){case "ABS":c="math.fabs("+a+")";break;case "ROOT":c="math.sqrt("+
|
||||
a+")";break;case "LN":c="math.log("+a+")";break;case "LOG10":c="math.log10("+a+")";break;case "EXP":c="math.exp("+a+")";break;case "POW10":c="math.pow(10,"+a+")";break;case "ROUND":c="round("+a+")";break;case "ROUNDUP":c="math.ceil("+a+")";break;case "ROUNDDOWN":c="math.floor("+a+")";break;case "SIN":c="math.sin("+a+" / 180.0 * math.pi)";break;case "COS":c="math.cos("+a+" / 180.0 * math.pi)";break;case "TAN":c="math.tan("+a+" / 180.0 * math.pi)"}if(c)return[c,Blockly.Python.ORDER_FUNCTION_CALL];switch(b){case "ASIN":c=
|
||||
"math.asin("+a+") / math.pi * 180";break;case "ACOS":c="math.acos("+a+") / math.pi * 180";break;case "ATAN":c="math.atan("+a+") / math.pi * 180";break;default:throw Error("Unknown math operator: "+b);}return[c,Blockly.Python.ORDER_MULTIPLICATIVE]};
|
||||
Blockly.Python.math_constant=function(a){var b={PI:["math.pi",Blockly.Python.ORDER_MEMBER],E:["math.e",Blockly.Python.ORDER_MEMBER],GOLDEN_RATIO:["(1 + math.sqrt(5)) / 2",Blockly.Python.ORDER_MULTIPLICATIVE],SQRT2:["math.sqrt(2)",Blockly.Python.ORDER_MEMBER],SQRT1_2:["math.sqrt(1.0 / 2)",Blockly.Python.ORDER_MEMBER],INFINITY:["float('inf')",Blockly.Python.ORDER_ATOMIC]};a=a.getFieldValue("CONSTANT");"INFINITY"!=a&&(Blockly.Python.definitions_.import_math="import math");return b[a]};
|
||||
Blockly.Python.math_number_property=function(a){var b=Blockly.Python.valueToCode(a,"NUMBER_TO_CHECK",Blockly.Python.ORDER_MULTIPLICATIVE)||"0",c=a.getFieldValue("PROPERTY");if("PRIME"==c)return Blockly.Python.definitions_.import_math="import math",Blockly.Python.definitions_.from_numbers_import_Number="from numbers import Number",[Blockly.Python.provideFunction_("math_isPrime",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(n):"," # https://en.wikipedia.org/wiki/Primality_test#Naive_methods",
|
||||
" # If n is not a number but a string, try parsing it."," if not isinstance(n, Number):"," try:"," n = float(n)"," except:"," return False"," if n == 2 or n == 3:"," return True"," # False if n is negative, is 1, or not whole, or if n is divisible by 2 or 3."," if n <= 1 or n % 1 != 0 or n % 2 == 0 or n % 3 == 0:"," return False"," # Check all the numbers of form 6k +/- 1, up to sqrt(n)."," for x in range(6, int(math.sqrt(n)) + 2, 6):"," if n % (x - 1) == 0 or n % (x + 1) == 0:",
|
||||
" return False"," return True"])+"("+b+")",Blockly.Python.ORDER_FUNCTION_CALL];switch(c){case "EVEN":var d=b+" % 2 == 0";break;case "ODD":d=b+" % 2 == 1";break;case "WHOLE":d=b+" % 1 == 0";break;case "POSITIVE":d=b+" > 0";break;case "NEGATIVE":d=b+" < 0";break;case "DIVISIBLE_BY":a=Blockly.Python.valueToCode(a,"DIVISOR",Blockly.Python.ORDER_MULTIPLICATIVE);if(!a||"0"==a)return["False",Blockly.Python.ORDER_ATOMIC];d=b+" % "+a+" == 0"}return[d,Blockly.Python.ORDER_RELATIONAL]};
|
||||
Blockly.Python.math_change=function(a){Blockly.Python.definitions_.from_numbers_import_Number="from numbers import Number";var b=Blockly.Python.valueToCode(a,"DELTA",Blockly.Python.ORDER_ADDITIVE)||"0";a=Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME);return a+" = ("+a+" if isinstance("+a+", Number) else 0) + "+b+"\n"};Blockly.Python.math_round=Blockly.Python.math_single;Blockly.Python.math_trig=Blockly.Python.math_single;
|
||||
Blockly.Python.math_on_list=function(a){var b=a.getFieldValue("OP");a=Blockly.Python.valueToCode(a,"LIST",Blockly.Python.ORDER_NONE)||"[]";switch(b){case "SUM":b="sum("+a+")";break;case "MIN":b="min("+a+")";break;case "MAX":b="max("+a+")";break;case "AVERAGE":Blockly.Python.definitions_.from_numbers_import_Number="from numbers import Number";b=Blockly.Python.provideFunction_("math_mean",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(myList):"," localList = [e for e in myList if isinstance(e, Number)]",
|
||||
" if not localList: return"," return float(sum(localList)) / len(localList)"]);b=b+"("+a+")";break;case "MEDIAN":Blockly.Python.definitions_.from_numbers_import_Number="from numbers import Number";b=Blockly.Python.provideFunction_("math_median",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(myList):"," localList = sorted([e for e in myList if isinstance(e, Number)])"," if not localList: return"," if len(localList) % 2 == 0:"," return (localList[len(localList) // 2 - 1] + localList[len(localList) // 2]) / 2.0",
|
||||
" else:"," return localList[(len(localList) - 1) // 2]"]);b=b+"("+a+")";break;case "MODE":b=Blockly.Python.provideFunction_("math_modes",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(some_list):"," modes = []"," # Using a lists of [item, count] to keep count rather than dict",' # to avoid "unhashable" errors when the counted item is itself a list or dict.'," counts = []"," maxCount = 1"," for item in some_list:"," found = False"," for count in counts:"," if count[0] == item:",
|
||||
" count[1] += 1"," maxCount = max(maxCount, count[1])"," found = True"," if not found:"," counts.append([item, 1])"," for counted_item, item_count in counts:"," if item_count == maxCount:"," modes.append(counted_item)"," return modes"]);b=b+"("+a+")";break;case "STD_DEV":Blockly.Python.definitions_.import_math="import math";b=Blockly.Python.provideFunction_("math_standard_deviation",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(numbers):"," n = len(numbers)",
|
||||
" if n == 0: return"," mean = float(sum(numbers)) / n"," variance = sum((x - mean) ** 2 for x in numbers) / n"," return math.sqrt(variance)"]);b=b+"("+a+")";break;case "RANDOM":Blockly.Python.definitions_.import_random="import random";b="random.choice("+a+")";break;default:throw Error("Unknown operator: "+b);}return[b,Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.math_modulo=function(a){var b=Blockly.Python.valueToCode(a,"DIVIDEND",Blockly.Python.ORDER_MULTIPLICATIVE)||"0";a=Blockly.Python.valueToCode(a,"DIVISOR",Blockly.Python.ORDER_MULTIPLICATIVE)||"0";return[b+" % "+a,Blockly.Python.ORDER_MULTIPLICATIVE]};
|
||||
Blockly.Python.math_constrain=function(a){var b=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"0",c=Blockly.Python.valueToCode(a,"LOW",Blockly.Python.ORDER_NONE)||"0";a=Blockly.Python.valueToCode(a,"HIGH",Blockly.Python.ORDER_NONE)||"float('inf')";return["min(max("+b+", "+c+"), "+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.math_random_int=function(a){Blockly.Python.definitions_.import_random="import random";var b=Blockly.Python.valueToCode(a,"FROM",Blockly.Python.ORDER_NONE)||"0";a=Blockly.Python.valueToCode(a,"TO",Blockly.Python.ORDER_NONE)||"0";return["random.randint("+b+", "+a+")",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.math_random_float=function(a){Blockly.Python.definitions_.import_random="import random";return["random.random()",Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.math_atan2=function(a){Blockly.Python.definitions_.import_math="import math";var b=Blockly.Python.valueToCode(a,"X",Blockly.Python.ORDER_NONE)||"0";return["math.atan2("+(Blockly.Python.valueToCode(a,"Y",Blockly.Python.ORDER_NONE)||"0")+", "+b+") / math.pi * 180",Blockly.Python.ORDER_MULTIPLICATIVE]};Blockly.Python.procedures={};
|
||||
Blockly.Python.procedures_defreturn=function(a){for(var b=[],c,d=a.workspace,e=Blockly.Variables.allUsedVarModels(d)||[],f=0;c=e[f];f++)c=c.name,-1==a.getVars().indexOf(c)&&b.push(Blockly.Python.variableDB_.getName(c,Blockly.VARIABLE_CATEGORY_NAME));e=Blockly.Variables.allDeveloperVariables(d);for(f=0;f<e.length;f++)b.push(Blockly.Python.variableDB_.getName(e[f],Blockly.Names.DEVELOPER_VARIABLE_TYPE));b=b.length?Blockly.Python.INDENT+"global "+b.join(", ")+"\n":"";d=Blockly.Python.variableDB_.getName(a.getFieldValue("NAME"),Blockly.PROCEDURE_CATEGORY_NAME);
|
||||
c="";Blockly.Python.STATEMENT_PREFIX&&(c+=Blockly.Python.injectId(Blockly.Python.STATEMENT_PREFIX,a));Blockly.Python.STATEMENT_SUFFIX&&(c+=Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX,a));c&&(c=Blockly.Python.prefixLines(c,Blockly.Python.INDENT));var l="";Blockly.Python.INFINITE_LOOP_TRAP&&(l=Blockly.Python.prefixLines(Blockly.Python.injectId(Blockly.Python.INFINITE_LOOP_TRAP,a),Blockly.Python.INDENT));var h=Blockly.Python.statementToCode(a,"STACK"),g=Blockly.Python.valueToCode(a,"RETURN",
|
||||
Blockly.Python.ORDER_NONE)||"",k="";h&&g&&(k=c);g?g=Blockly.Python.INDENT+"return "+g+"\n":h||(h=Blockly.Python.PASS);var m=[];e=a.getVars();for(f=0;f<e.length;f++)m[f]=Blockly.Python.variableDB_.getName(e[f],Blockly.VARIABLE_CATEGORY_NAME);b="def "+d+"("+m.join(", ")+"):\n"+b+c+l+h+k+g;b=Blockly.Python.scrub_(a,b);Blockly.Python.definitions_["%"+d]=b;return null};Blockly.Python.procedures_defnoreturn=Blockly.Python.procedures_defreturn;
|
||||
Blockly.Python.procedures_callreturn=function(a){for(var b=Blockly.Python.variableDB_.getName(a.getFieldValue("NAME"),Blockly.PROCEDURE_CATEGORY_NAME),c=[],d=a.getVars(),e=0;e<d.length;e++)c[e]=Blockly.Python.valueToCode(a,"ARG"+e,Blockly.Python.ORDER_NONE)||"None";return[b+"("+c.join(", ")+")",Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.procedures_callnoreturn=function(a){return Blockly.Python.procedures_callreturn(a)[0]+"\n"};
|
||||
Blockly.Python.procedures_ifreturn=function(a){var b="if "+(Blockly.Python.valueToCode(a,"CONDITION",Blockly.Python.ORDER_NONE)||"False")+":\n";Blockly.Python.STATEMENT_SUFFIX&&(b+=Blockly.Python.prefixLines(Blockly.Python.injectId(Blockly.Python.STATEMENT_SUFFIX,a),Blockly.Python.INDENT));a.hasReturnValue_?(a=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"None",b+=Blockly.Python.INDENT+"return "+a+"\n"):b+=Blockly.Python.INDENT+"return\n";return b};Blockly.Python.texts={};Blockly.Python.text=function(a){return[Blockly.Python.quote_(a.getFieldValue("TEXT")),Blockly.Python.ORDER_ATOMIC]};Blockly.Python.text_multiline=function(a){return[Blockly.Python.multiline_quote_(a.getFieldValue("TEXT")),Blockly.Python.ORDER_ATOMIC]};Blockly.Python.text.forceString_=function(a){return Blockly.Python.text.forceString_.strRegExp.test(a)?a:"str("+a+")"};Blockly.Python.text.forceString_.strRegExp=/^\s*'([^']|\\')*'\s*$/;
|
||||
Blockly.Python.text_join=function(a){switch(a.itemCount_){case 0:return["''",Blockly.Python.ORDER_ATOMIC];case 1:return a=Blockly.Python.valueToCode(a,"ADD0",Blockly.Python.ORDER_NONE)||"''",a=Blockly.Python.text.forceString_(a),[a,Blockly.Python.ORDER_FUNCTION_CALL];case 2:var b=Blockly.Python.valueToCode(a,"ADD0",Blockly.Python.ORDER_NONE)||"''";a=Blockly.Python.valueToCode(a,"ADD1",Blockly.Python.ORDER_NONE)||"''";a=Blockly.Python.text.forceString_(b)+" + "+Blockly.Python.text.forceString_(a);
|
||||
return[a,Blockly.Python.ORDER_ADDITIVE];default:b=[];for(var c=0;c<a.itemCount_;c++)b[c]=Blockly.Python.valueToCode(a,"ADD"+c,Blockly.Python.ORDER_NONE)||"''";a=Blockly.Python.variableDB_.getDistinctName("x",Blockly.VARIABLE_CATEGORY_NAME);a="''.join([str("+a+") for "+a+" in ["+b.join(", ")+"]])";return[a,Blockly.Python.ORDER_FUNCTION_CALL]}};
|
||||
Blockly.Python.text_append=function(a){var b=Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME);a=Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_NONE)||"''";return b+" = str("+b+") + "+Blockly.Python.text.forceString_(a)+"\n"};Blockly.Python.text_length=function(a){return["len("+(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"''")+")",Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.text_isEmpty=function(a){return["not len("+(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"''")+")",Blockly.Python.ORDER_LOGICAL_NOT]};
|
||||
Blockly.Python.text_indexOf=function(a){var b="FIRST"==a.getFieldValue("END")?"find":"rfind",c=Blockly.Python.valueToCode(a,"FIND",Blockly.Python.ORDER_NONE)||"''";b=(Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_MEMBER)||"''")+"."+b+"("+c+")";return a.workspace.options.oneBasedIndex?[b+" + 1",Blockly.Python.ORDER_ADDITIVE]:[b,Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.text_charAt=function(a){var b=a.getFieldValue("WHERE")||"FROM_START",c=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_MEMBER)||"''";switch(b){case "FIRST":return[c+"[0]",Blockly.Python.ORDER_MEMBER];case "LAST":return[c+"[-1]",Blockly.Python.ORDER_MEMBER];case "FROM_START":return a=Blockly.Python.getAdjustedInt(a,"AT"),[c+"["+a+"]",Blockly.Python.ORDER_MEMBER];case "FROM_END":return a=Blockly.Python.getAdjustedInt(a,"AT",1,!0),[c+"["+a+"]",Blockly.Python.ORDER_MEMBER];case "RANDOM":return Blockly.Python.definitions_.import_random=
|
||||
"import random",[Blockly.Python.provideFunction_("text_random_letter",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(text):"," x = int(random.random() * len(text))"," return text[x];"])+"("+c+")",Blockly.Python.ORDER_FUNCTION_CALL]}throw Error("Unhandled option (text_charAt).");};
|
||||
Blockly.Python.text_getSubstring=function(a){var b=a.getFieldValue("WHERE1"),c=a.getFieldValue("WHERE2"),d=Blockly.Python.valueToCode(a,"STRING",Blockly.Python.ORDER_MEMBER)||"''";switch(b){case "FROM_START":b=Blockly.Python.getAdjustedInt(a,"AT1");"0"==b&&(b="");break;case "FROM_END":b=Blockly.Python.getAdjustedInt(a,"AT1",1,!0);break;case "FIRST":b="";break;default:throw Error("Unhandled option (text_getSubstring)");}switch(c){case "FROM_START":a=Blockly.Python.getAdjustedInt(a,"AT2",1);break;case "FROM_END":a=
|
||||
Blockly.Python.getAdjustedInt(a,"AT2",0,!0);Blockly.isNumber(String(a))?"0"==a&&(a=""):(Blockly.Python.definitions_.import_sys="import sys",a+=" or sys.maxsize");break;case "LAST":a="";break;default:throw Error("Unhandled option (text_getSubstring)");}return[d+"["+b+" : "+a+"]",Blockly.Python.ORDER_MEMBER]};
|
||||
Blockly.Python.text_changeCase=function(a){var b={UPPERCASE:".upper()",LOWERCASE:".lower()",TITLECASE:".title()"}[a.getFieldValue("CASE")];return[(Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''")+b,Blockly.Python.ORDER_FUNCTION_CALL]};Blockly.Python.text_trim=function(a){var b={LEFT:".lstrip()",RIGHT:".rstrip()",BOTH:".strip()"}[a.getFieldValue("MODE")];return[(Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''")+b,Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.text_print=function(a){return"print("+(Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_NONE)||"''")+")\n"};
|
||||
Blockly.Python.text_prompt_ext=function(a){var b=Blockly.Python.provideFunction_("text_prompt",["def "+Blockly.Python.FUNCTION_NAME_PLACEHOLDER_+"(msg):"," try:"," return raw_input(msg)"," except NameError:"," return input(msg)"]),c=a.getField("TEXT")?Blockly.Python.quote_(a.getFieldValue("TEXT")):Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_NONE)||"''";b=b+"("+c+")";"NUMBER"==a.getFieldValue("TYPE")&&(b="float("+b+")");return[b,Blockly.Python.ORDER_FUNCTION_CALL]};
|
||||
Blockly.Python.text_prompt=Blockly.Python.text_prompt_ext;Blockly.Python.text_count=function(a){var b=Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''";a=Blockly.Python.valueToCode(a,"SUB",Blockly.Python.ORDER_NONE)||"''";return[b+".count("+a+")",Blockly.Python.ORDER_MEMBER]};
|
||||
Blockly.Python.text_replace=function(a){var b=Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''",c=Blockly.Python.valueToCode(a,"FROM",Blockly.Python.ORDER_NONE)||"''";a=Blockly.Python.valueToCode(a,"TO",Blockly.Python.ORDER_NONE)||"''";return[b+".replace("+c+", "+a+")",Blockly.Python.ORDER_MEMBER]};Blockly.Python.text_reverse=function(a){return[(Blockly.Python.valueToCode(a,"TEXT",Blockly.Python.ORDER_MEMBER)||"''")+"[::-1]",Blockly.Python.ORDER_MEMBER]};Blockly.Python.variables={};Blockly.Python.variables_get=function(a){return[Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME),Blockly.Python.ORDER_ATOMIC]};Blockly.Python.variables_set=function(a){var b=Blockly.Python.valueToCode(a,"VALUE",Blockly.Python.ORDER_NONE)||"0";return Blockly.Python.variableDB_.getName(a.getFieldValue("VAR"),Blockly.VARIABLE_CATEGORY_NAME)+" = "+b+"\n"};Blockly.Python.variablesDynamic={};Blockly.Python.variables_get_dynamic=Blockly.Python.variables_get;Blockly.Python.variables_set_dynamic=Blockly.Python.variables_set;
|
||||
return Blockly.Python;
|
||||
}));
|
||||
|
||||
|
||||
//# sourceMappingURL=python_compressed.js.map
|
||||
1
clover_blocks/www/blockly/python_compressed.js.map
Executable file
564
clover_blocks/www/blocks.js
Normal file
@@ -0,0 +1,564 @@
|
||||
const COLOR_FLIGHT = 293;
|
||||
const COLOR_STATE = 36;
|
||||
const COLOR_LED = 143;
|
||||
const COLOR_GPIO = 200;
|
||||
const DOCS_URL = 'https://clover.coex.tech/en/blocks.html';
|
||||
|
||||
var frameIds = [["body", "BODY"], ["markers map", "ARUCO_MAP"], ["marker", "ARUCO"], ["last navigate target", "NAVIGATE_TARGET"], ["map", "MAP"]];
|
||||
|
||||
function considerFrameId(e) {
|
||||
if (!(e instanceof Blockly.Events.Change || e instanceof Blockly.Events.Create)) return;
|
||||
|
||||
var frameId = this.getFieldValue('FRAME_ID');
|
||||
// set appropriate coordinates labels
|
||||
if (this.getInput('X')) { // block has x-y-z fields
|
||||
if (frameId == 'BODY' || frameId == 'NAVIGATE_TARGET' || frameId == 'BASE_LINK') {
|
||||
this.getInput('X').fieldRow[0].setValue('forward');
|
||||
this.getInput('Y').fieldRow[0].setValue('left');
|
||||
this.getInput('Z').fieldRow[0].setValue('up');
|
||||
} else {
|
||||
this.getInput('X').fieldRow[0].setValue('x');
|
||||
this.getInput('Y').fieldRow[0].setValue('y');
|
||||
this.getInput('Z').fieldRow[0].setValue('z');
|
||||
}
|
||||
}
|
||||
if (this.getInput('ID')) { // block has marker id field
|
||||
this.getInput('ID').setVisible(frameId == 'ARUCO'); // toggle id field
|
||||
}
|
||||
this.render();
|
||||
}
|
||||
|
||||
function updateSetpointBlock(e) {
|
||||
if (!(e instanceof Blockly.Events.Change || e instanceof Blockly.Events.Create)) return;
|
||||
|
||||
considerFrameId.apply(this, arguments);
|
||||
|
||||
var type = this.getFieldValue('TYPE');
|
||||
var velocity = type == 'VELOCITY';
|
||||
var attitude = type == 'ATTITUDE' || type == 'RATES';
|
||||
|
||||
this.getInput('VX').setVisible(velocity);
|
||||
this.getInput('VY').setVisible(velocity);
|
||||
this.getInput('VZ').setVisible(velocity);
|
||||
this.getInput('YAW').setVisible(attitude);
|
||||
this.getInput('PITCH').setVisible(attitude);
|
||||
this.getInput('ROLL').setVisible(attitude);
|
||||
this.getInput('THRUST').setVisible(attitude);
|
||||
this.getInput('RELATIVE_TO').setVisible(type != 'RATES');
|
||||
|
||||
if (type == 'RATES') {
|
||||
this.getInput('ID').setVisible(false);
|
||||
}
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
Blockly.Blocks['navigate'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("navigate to point");
|
||||
this.appendValueInput("X")
|
||||
.setCheck("Number")
|
||||
.appendField("forward");
|
||||
this.appendValueInput("Y")
|
||||
.setCheck("Number")
|
||||
.appendField("left");
|
||||
this.appendValueInput("Z")
|
||||
.setCheck("Number")
|
||||
.appendField("up");
|
||||
this.appendDummyInput()
|
||||
.appendField("relative to")
|
||||
.appendField(new Blockly.FieldDropdown(frameIds), "FRAME_ID");
|
||||
this.appendValueInput("ID")
|
||||
.setCheck("Number")
|
||||
.appendField("with ID")
|
||||
.setVisible(false)
|
||||
this.appendValueInput("SPEED")
|
||||
.setCheck("Number")
|
||||
.appendField("with speed");
|
||||
this.appendDummyInput()
|
||||
.appendField("wait")
|
||||
.appendField(new Blockly.FieldCheckbox("TRUE"), "WAIT");
|
||||
this.setInputsInline(false);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_FLIGHT);
|
||||
this.setTooltip("Navigate to the specified point, coordinates are in meters.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
this.setOnChange(considerFrameId);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['set_velocity'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("set velocity");
|
||||
this.appendValueInput("X")
|
||||
.setCheck("Number")
|
||||
.appendField("forward");
|
||||
this.appendValueInput("Y")
|
||||
.setCheck("Number")
|
||||
.appendField("left");
|
||||
this.appendValueInput("Z")
|
||||
.setCheck("Number")
|
||||
.appendField("up");
|
||||
this.appendDummyInput()
|
||||
.appendField("relative to")
|
||||
.appendField(new Blockly.FieldDropdown(frameIds), "FRAME_ID");
|
||||
this.appendValueInput("ID")
|
||||
.setCheck("Number")
|
||||
.appendField("with ID")
|
||||
.setVisible(false)
|
||||
this.setInputsInline(false);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_FLIGHT);
|
||||
this.setTooltip("Set the drone velocity in meters per second (cancels navigation requests).");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
this.setOnChange(considerFrameId);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['setpoint'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("set");
|
||||
this.appendDummyInput()
|
||||
.appendField(new Blockly.FieldDropdown([["velocity", "VELOCITY"], ["attitude", "ATTITUDE"], ["angular rates", "RATES"]]), "TYPE");
|
||||
this.appendValueInput("VX")
|
||||
.setCheck("Number")
|
||||
.appendField("vx");
|
||||
this.appendValueInput("VY")
|
||||
.setCheck("Number")
|
||||
.appendField("vy");
|
||||
this.appendValueInput("VZ")
|
||||
.setCheck("Number")
|
||||
.appendField("vz");
|
||||
this.appendValueInput("PITCH")
|
||||
.setCheck("Number")
|
||||
.appendField("pitch")
|
||||
.setVisible(false);
|
||||
this.appendValueInput("ROLL")
|
||||
.setCheck("Number")
|
||||
.appendField("roll")
|
||||
.setVisible(false);
|
||||
this.appendValueInput("YAW")
|
||||
.setCheck("Number")
|
||||
.appendField("yaw")
|
||||
.setVisible(false);
|
||||
this.appendValueInput("THRUST")
|
||||
.setCheck("Number")
|
||||
.appendField("thrust")
|
||||
.setVisible(false);
|
||||
this.appendDummyInput('RELATIVE_TO')
|
||||
.appendField("relative to")
|
||||
.appendField(new Blockly.FieldDropdown(frameIds), "FRAME_ID");
|
||||
this.appendValueInput("ID")
|
||||
.setCheck("Number")
|
||||
.appendField("with ID")
|
||||
.setVisible(false);
|
||||
this.setInputsInline(false);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_FLIGHT);
|
||||
this.setTooltip("Set the drone's setpoints of different types (cancels navigation requests).");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
this.setOnChange(updateSetpointBlock);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['rangefinder_distance'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("current rangefinder distance");
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['get_position'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("current")
|
||||
.appendField(new Blockly.FieldDropdown([["x", "X"], ["y", "Y"], ["z", "Z"], ["vx", "VX"], ["vy", "VY"], ["vz", "VZ"]]), "FIELD")
|
||||
.appendField("relative to")
|
||||
.appendField(new Blockly.FieldDropdown(frameIds), "FRAME_ID");
|
||||
this.appendValueInput("ID")
|
||||
.setCheck("Number")
|
||||
.appendField("with ID")
|
||||
.setVisible(false)
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("Returns current position or velocity in meters or meters per second.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
this.setOnChange(considerFrameId);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['get_yaw'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("current yaw relative to")
|
||||
.appendField(new Blockly.FieldDropdown(frameIds), "FRAME_ID");
|
||||
this.appendValueInput("ID")
|
||||
.setCheck("Number")
|
||||
.appendField("with ID")
|
||||
.setVisible(false)
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("Returns current yaw in degree (not radian).");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
this.setOnChange(considerFrameId);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['get_attitude'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("current")
|
||||
.appendField(new Blockly.FieldDropdown([["pitch", "PITCH"], ["roll", "ROLL"], ["pitch rate", "PITCH_RATE"], ["roll rate", "ROLL_RATE"], ["yaw rate", "YAW_RATE"]]), "FIELD");
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("Returns current orientation or angle rates in degree or degree per second (not radian).");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['voltage'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("current")
|
||||
.appendField(new Blockly.FieldDropdown([["total", "VOLTAGE"], ["cell", "CELL_VOLTAGE"]]), "TYPE")
|
||||
.appendField("voltage");
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("Returns current battery voltage in volts.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Blockly.Blocks['armed'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("armed?");
|
||||
this.setOutput(true, "Boolean");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("Returns if the drone armed.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Blockly.Blocks['mode'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("current flight mode");
|
||||
this.setOutput(true, "String");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Blockly.Blocks['wait_arrival'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("wait arrival");
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_FLIGHT);
|
||||
this.setTooltip("Wait until the drone arrives to the navigation target.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['get_time'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("time");
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("Returns current timestamp in seconds.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['arrived'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("arrived?");
|
||||
this.setOutput(true, "Boolean");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("Returns if the drone arrived to the navigation target.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['set_led'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("set LED");
|
||||
this.appendValueInput("INDEX")
|
||||
.setCheck("Number");
|
||||
this.appendValueInput("COLOR")
|
||||
.setCheck("Colour")
|
||||
.appendField("to color");
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_LED);
|
||||
this.setTooltip("Set an individual LED to specified color.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['set_effect'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("set LED effect")
|
||||
.appendField(new Blockly.FieldDropdown([["fill", "FILL"], ["blink", "BLINK"], ["fast blink", "BLINK_FAST"], ["fade", "FADE"], ["wipe", "WIPE"], ["flash", "FLASH"], ["rainbow", "RAINBOW"], ["rainbow fill", "RAINBOW_FILL"]]), "EFFECT");
|
||||
this.appendValueInput("COLOR")
|
||||
.setCheck("Colour")
|
||||
.appendField("with color");
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_LED);
|
||||
this.setTooltip("Set desired LED strip effect.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
|
||||
this.setOnChange(function(e) {
|
||||
if (!(e instanceof Blockly.Events.Change || e instanceof Blockly.Events.Create)) return;
|
||||
|
||||
// Hide color field on some effects
|
||||
var effect = this.getFieldValue('EFFECT');
|
||||
var hideColor = effect == 'RAINBOW' || effect == 'RAINBOW_FILL';
|
||||
this.inputList[1].setVisible(!hideColor);
|
||||
this.render();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['take_off'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("ALT")
|
||||
.setCheck("Number")
|
||||
.appendField("take off to");
|
||||
this.appendDummyInput()
|
||||
.appendField("wait")
|
||||
.appendField(new Blockly.FieldCheckbox("TRUE"), "WAIT");
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_FLIGHT);
|
||||
this.setTooltip("Take off on desired altitude in meters");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['land'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("land");
|
||||
this.appendDummyInput()
|
||||
.appendField("wait")
|
||||
.appendField(new Blockly.FieldCheckbox("TRUE"), "WAIT");
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_FLIGHT);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['global_position'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("current")
|
||||
.appendField(new Blockly.FieldDropdown([["latitude", "LATITUDE"], ["longitude", "LONGITUDE"], ["altitude", "ALTITUDE"]]), "NAME");
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(230);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['on_take_off'] = {
|
||||
init: function () {
|
||||
this.appendStatementInput("TAKE_OFF")
|
||||
.setCheck(null)
|
||||
.appendField("When took off");
|
||||
this.setColour(230);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['on_landing'] = {
|
||||
init: function () {
|
||||
this.appendStatementInput("LAND")
|
||||
.setCheck(null)
|
||||
.appendField("When landed");
|
||||
this.setColour(230);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['on_armed'] = {
|
||||
init: function () {
|
||||
this.appendStatementInput("ARMED")
|
||||
.setCheck(null)
|
||||
.appendField("when armed");
|
||||
this.setColour(230);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.FieldAngle.WRAP = 180;
|
||||
Blockly.FieldAngle.ROUND = 10;
|
||||
|
||||
Blockly.Blocks['angle'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField(new Blockly.FieldAngle(90), "ANGLE");
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(230);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['set_yaw'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("YAW")
|
||||
.setCheck("Number")
|
||||
.appendField("rotate by");
|
||||
this.appendDummyInput()
|
||||
.appendField("relative to")
|
||||
.appendField(new Blockly.FieldDropdown([["body", "body"], ["markers map", "aruco_map"], ["last navigate target", "navigate_target"]]), "FRAME_ID");
|
||||
this.appendDummyInput()
|
||||
.appendField("wait")
|
||||
.appendField(new Blockly.FieldCheckbox("TRUE"), "WAIT");
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_FLIGHT);
|
||||
this.setTooltip("Rotate the drone to the specified angle in degree (not radian).");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['distance'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("distance to point");
|
||||
this.appendValueInput("X")
|
||||
.setCheck("Number")
|
||||
.appendField("x");
|
||||
this.appendValueInput("Y")
|
||||
.setCheck("Number")
|
||||
.appendField("y");
|
||||
this.appendValueInput("Z")
|
||||
.setCheck("Number")
|
||||
.appendField("z");
|
||||
this.appendDummyInput()
|
||||
.appendField("relative to")
|
||||
.appendField(new Blockly.FieldDropdown([["markers map", "ARUCO_MAP"], ["marker", "ARUCO"], ["last navigate target", "NAVIGATE_TARGET"]]), "FRAME_ID");
|
||||
this.appendValueInput("ID")
|
||||
.setCheck("Number")
|
||||
.appendField("with ID")
|
||||
.setVisible(false);
|
||||
this.setInputsInline(false);
|
||||
this.setOutput(true, "Number");
|
||||
this.setColour(COLOR_STATE);
|
||||
this.setTooltip("Returns the distance to the given point in meters.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
this.setOnChange(considerFrameId);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['wait'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("wait");
|
||||
this.appendValueInput("TIME")
|
||||
.setCheck("Number");
|
||||
this.appendDummyInput()
|
||||
.appendField("seconds");
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(COLOR_FLIGHT);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
var keys = [['up', 'UP'], ['down', 'DOWN'], ['left', 'LEFT'], ['right', 'RIGHT'], ['space', 'SPACE']];
|
||||
|
||||
Blockly.Blocks['key_pressed'] = {
|
||||
init: function () {
|
||||
this.appendDummyInput()
|
||||
.appendField("key")
|
||||
.appendField(new Blockly.FieldDropdown(keys, "NAME"))
|
||||
.appendField("pressed");
|
||||
this.appendStatementInput("PRESSED")
|
||||
.setCheck(null);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setColour(230);
|
||||
this.setTooltip("");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['gpio_read'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("PIN")
|
||||
.setCheck("Number")
|
||||
.appendField("read GPIO pin");
|
||||
this.setOutput(true, "Boolean");
|
||||
this.setColour(COLOR_GPIO);
|
||||
this.setTooltip("Returns if there is voltage on a GPIO pin.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['gpio_write'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("PIN")
|
||||
.setCheck("Number")
|
||||
.appendField("set GPIO pin");
|
||||
this.appendValueInput("LEVEL")
|
||||
.setCheck("Boolean")
|
||||
.appendField("to");
|
||||
this.setInputsInline(true);
|
||||
this.setColour(COLOR_GPIO);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip("Set GPIO pin level.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['set_servo'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("PIN")
|
||||
.setCheck("Number")
|
||||
.appendField("set GPIO pin");
|
||||
this.appendValueInput("PWM")
|
||||
.setCheck("Number")
|
||||
.appendField("to PWM");
|
||||
this.setInputsInline(true);
|
||||
this.setColour(COLOR_GPIO);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip("Set PWM on a GPIO pin to control servo. PWM is specified in range of 500–2500 ms.");
|
||||
this.setHelpUrl(DOCS_URL + '#' + this.type);
|
||||
}
|
||||
};
|
||||
6
clover_blocks/www/highlight/highlight.pack.js
Normal file
83
clover_blocks/www/highlight/styles/monokai-sublime.css
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
|
||||
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #23241f;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-tag,
|
||||
.hljs-subst {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-strong,
|
||||
.hljs-emphasis {
|
||||
color: #a8a8a2;
|
||||
}
|
||||
|
||||
.hljs-bullet,
|
||||
.hljs-quote,
|
||||
.hljs-number,
|
||||
.hljs-regexp,
|
||||
.hljs-literal,
|
||||
.hljs-link {
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.hljs-code,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-class {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-name,
|
||||
.hljs-attr {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-attribute {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.hljs-params,
|
||||
.hljs-class .hljs-title {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-type,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #75715e;
|
||||
}
|
||||
483
clover_blocks/www/index.html
Normal file
@@ -0,0 +1,483 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Clover Blocks</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link rel="stylesheet" href="main.css">
|
||||
<link rel="icon" href="data:,">
|
||||
<link rel="stylesheet" href="highlight/styles/monokai-sublime.css">
|
||||
<script src="highlight/highlight.pack.js"></script>
|
||||
<script src="roslib.js"></script>
|
||||
<script src="blockly/blockly_compressed.js"></script>
|
||||
<script src="blockly/python_compressed.js"></script>
|
||||
<script src="blockly/blocks_compressed.js"></script>
|
||||
<script src="blockly/msg/js/en.js"></script>
|
||||
<script type="module" src="main.js"></script>
|
||||
</head>
|
||||
|
||||
<body data-tab="blocks">
|
||||
<ul id="tabs">
|
||||
<li class="selected" data-tab="blocks">Blocks</li>
|
||||
<li data-tab="python">Python</li>
|
||||
</ul>
|
||||
|
||||
<div id="tools">
|
||||
<div class="disconnected">Disconnected</div>
|
||||
<div class="backend-fail">Failed to contact with <code>clover_blocks</code> node, see <a href="../clover/docs/en/blocks.html#configuration" target="_blank">configuration</a> documentation.</div>
|
||||
<div id="running">Running...</div>
|
||||
<select id="program-name" title="Files are saved in <package_path>/programs/.">
|
||||
<option value="" disabled selected><Unsaved></option>
|
||||
<option value="@clear">Clear...</option>
|
||||
<option style="font-style: italic;" value="@save">Save... (Ctrl+S)</option>
|
||||
<optgroup label="User" data-type="user"></optgroup>
|
||||
<optgroup label="Examples" data-type="example"></optgroup>
|
||||
</select>
|
||||
<button onclick="runProgram()" disabled id="run" disabled title="Run the program">Run</button>
|
||||
<button onclick="stopProgram()" title="Stop the program">Stop</button>
|
||||
<button onclick="land()" title="Stop the program and land">Land</button>
|
||||
</div>
|
||||
|
||||
<div id="notifications"></div>
|
||||
|
||||
<div id="blockly" class="content"></div>
|
||||
<pre id="python" class="content" contenteditable oncut="return false" onpaste="return false" onkeydown="if(!event.metaKey) return false" spellcheck="false"></pre>
|
||||
|
||||
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
|
||||
<category name="Flight" colour="#870b99">
|
||||
<block type="take_off">
|
||||
<value name="ALT"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
|
||||
</block>
|
||||
<block type="navigate">
|
||||
<value name="X"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="Y"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="Z"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="SPEED"><shadow type="math_number"><field name="NUM">0.5</field></shadow></value>
|
||||
<value name="ID"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
</block>
|
||||
<block type="land"></block>
|
||||
<block type="set_yaw">
|
||||
<value name="YAW"><shadow type="angle"></shadow></value>
|
||||
</block>
|
||||
<block type="wait">
|
||||
<value name="TIME"><shadow type="math_number"><field name="NUM">3</field></shadow></value>
|
||||
</block>
|
||||
<block type="wait_arrival"></block>
|
||||
<block type="setpoint">
|
||||
<value name="VX"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="VY"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="VZ"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="PITCH"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="ROLL"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="YAW"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="THRUST"><shadow type="math_number"><field name="NUM">0.5</field></shadow></value>
|
||||
<value name="ID"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
</block>
|
||||
<!-- <block type="key_pressed"></block> -->
|
||||
</category>
|
||||
<category name="State" colour="#ff9a00">
|
||||
<block type="get_position">
|
||||
<field name="FRAME_ID">ARUCO_MAP</field>
|
||||
<value name="ID"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
</block>
|
||||
<block type="get_yaw">
|
||||
<field name="FRAME_ID">ARUCO_MAP</field>
|
||||
<value name="ID"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
</block>
|
||||
<block type="get_attitude"></block>
|
||||
<block type="distance">
|
||||
<value name="X"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="Y"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="Z"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="ID"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
</block>
|
||||
<block type="get_time"></block>
|
||||
<block type="arrived"></block>
|
||||
<block type="rangefinder_distance"></block>
|
||||
<block type="mode"></block>
|
||||
<block type="armed"></block>
|
||||
<block type="voltage"></block>
|
||||
</category>
|
||||
<category name="LED" colour="#02d754">
|
||||
<block type="set_effect">
|
||||
<value name="COLOR"><shadow type="colour_picker"></shadow></value>
|
||||
</block>
|
||||
<block type="set_led">
|
||||
<value name="INDEX"><shadow type="math_number"><field name="NUM">0</field></shadow></value>
|
||||
<value name="COLOR"><shadow type="colour_picker"></shadow></value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="GPIO" colour="#5b97cc">
|
||||
<block type="gpio_read">
|
||||
<value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
|
||||
</block>
|
||||
<block type="gpio_write">
|
||||
<value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
|
||||
<value name="LEVEL"><shadow type="logic_boolean"></shadow></value>
|
||||
</block>
|
||||
<block type="set_servo">
|
||||
<value name="PIN"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
|
||||
<value name="PWM"><shadow type="math_number"><field name="NUM">1500</field></shadow></value>
|
||||
</block>
|
||||
</category>
|
||||
<sep></sep>
|
||||
<category name="Logic" colour="#5b80a5">
|
||||
<block type="controls_if"></block>
|
||||
<block type="logic_compare">
|
||||
<field name="OP">EQ</field>
|
||||
</block>
|
||||
<block type="logic_operation">
|
||||
<field name="OP">AND</field>
|
||||
</block>
|
||||
<block type="logic_negate"></block>
|
||||
<block type="logic_boolean">
|
||||
<field name="BOOL">TRUE</field>
|
||||
</block>
|
||||
<block type="logic_null"></block>
|
||||
<block type="logic_ternary"></block>
|
||||
</category>
|
||||
<category name="Loops" colour="#5ba55b">
|
||||
<block type="controls_repeat_ext">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="controls_whileUntil">
|
||||
<field name="MODE">WHILE</field>
|
||||
</block>
|
||||
<block type="controls_for">
|
||||
<field name="VAR" id="SMJ.7:a)p9(!mF0x)WK~">i</field>
|
||||
<value name="FROM">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="TO">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="BY">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="controls_forEach">
|
||||
<field name="VAR" id="#hg!+5qncbZDpf;c6Qiw">j</field>
|
||||
</block>
|
||||
<block type="controls_flow_statements">
|
||||
<field name="FLOW">BREAK</field>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Math" colour="#5b67a5">
|
||||
<block type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</block>
|
||||
<block type="math_arithmetic">
|
||||
<field name="OP">ADD</field>
|
||||
<value name="A">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="B">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="math_single">
|
||||
<field name="OP">ROOT</field>
|
||||
<value name="NUM">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">9</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="math_trig">
|
||||
<field name="OP">SIN</field>
|
||||
<value name="NUM">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">45</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="math_constant">
|
||||
<field name="CONSTANT">PI</field>
|
||||
</block>
|
||||
<block type="math_number_property">
|
||||
<mutation divisor_input="false"></mutation>
|
||||
<field name="PROPERTY">EVEN</field>
|
||||
<value name="NUMBER_TO_CHECK">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="math_round">
|
||||
<field name="OP">ROUND</field>
|
||||
<value name="NUM">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">3.1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="math_on_list">
|
||||
<mutation op="SUM"></mutation>
|
||||
<field name="OP">SUM</field>
|
||||
</block>
|
||||
<block type="math_modulo">
|
||||
<value name="DIVIDEND">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">64</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="DIVISOR">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="math_constrain">
|
||||
<value name="VALUE">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">50</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="LOW">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="HIGH">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">100</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="math_random_int">
|
||||
<value name="FROM">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="TO">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">100</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="math_random_float"></block>
|
||||
</category>
|
||||
<category name="Text" colour="#5ba58c">
|
||||
<block type="text">
|
||||
<field name="TEXT"></field>
|
||||
</block>
|
||||
<block type="text_join">
|
||||
<mutation items="2"></mutation>
|
||||
</block>
|
||||
<block type="text_append">
|
||||
<field name="VAR" id="SmwB.@#2p5}McHySTA:V">item</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT"></field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_length">
|
||||
<value name="VALUE">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_isEmpty">
|
||||
<value name="VALUE">
|
||||
<shadow type="text">
|
||||
<field name="TEXT"></field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_indexOf">
|
||||
<field name="END">FIRST</field>
|
||||
<value name="VALUE">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="C^Ay41*aH0(G-jwM$x4w">text</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="FIND">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_charAt">
|
||||
<mutation at="true"></mutation>
|
||||
<field name="WHERE">FROM_START</field>
|
||||
<value name="VALUE">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="C^Ay41*aH0(G-jwM$x4w">text</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_getSubstring">
|
||||
<mutation at1="true" at2="true"></mutation>
|
||||
<field name="WHERE1">FROM_START</field>
|
||||
<field name="WHERE2">FROM_START</field>
|
||||
<value name="STRING">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="C^Ay41*aH0(G-jwM$x4w">text</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_changeCase">
|
||||
<field name="CASE">UPPERCASE</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_trim">
|
||||
<field name="MODE">BOTH</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_print">
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_prompt_ext">
|
||||
<mutation type="TEXT"></mutation>
|
||||
<field name="TYPE">TEXT</field>
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Lists" colour="#745ba5">
|
||||
<block type="lists_create_with">
|
||||
<mutation items="0"></mutation>
|
||||
</block>
|
||||
<block type="lists_create_with">
|
||||
<mutation items="3"></mutation>
|
||||
</block>
|
||||
<block type="lists_repeat">
|
||||
<value name="NUM">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="lists_length"></block>
|
||||
<block type="lists_isEmpty"></block>
|
||||
<block type="lists_indexOf">
|
||||
<field name="END">FIRST</field>
|
||||
<value name="VALUE">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="+/w.~s(u:tRiXNBG5eR#">list</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
<block type="lists_getIndex">
|
||||
<mutation statement="false" at="true"></mutation>
|
||||
<field name="MODE">GET</field>
|
||||
<field name="WHERE">FROM_START</field>
|
||||
<value name="VALUE">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="+/w.~s(u:tRiXNBG5eR#">list</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
<block type="lists_setIndex">
|
||||
<mutation at="true"></mutation>
|
||||
<field name="MODE">SET</field>
|
||||
<field name="WHERE">FROM_START</field>
|
||||
<value name="LIST">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="+/w.~s(u:tRiXNBG5eR#">list</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
<block type="lists_getSublist">
|
||||
<mutation at1="true" at2="true"></mutation>
|
||||
<field name="WHERE1">FROM_START</field>
|
||||
<field name="WHERE2">FROM_START</field>
|
||||
<value name="LIST">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="+/w.~s(u:tRiXNBG5eR#">list</field>
|
||||
</block>
|
||||
</value>
|
||||
</block>
|
||||
<block type="lists_split">
|
||||
<mutation mode="SPLIT"></mutation>
|
||||
<field name="MODE">SPLIT</field>
|
||||
<value name="DELIM">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">,</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="lists_sort">
|
||||
<field name="TYPE">NUMERIC</field>
|
||||
<field name="DIRECTION">1</field>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Colour" colour="#a5745b">
|
||||
<block type="colour_picker">
|
||||
<field name="COLOUR">#ff0000</field>
|
||||
</block>
|
||||
<block type="colour_random"></block>
|
||||
<block type="colour_rgb">
|
||||
<value name="RED">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">100</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="GREEN">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">50</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="BLUE">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="colour_blend">
|
||||
<value name="COLOUR1">
|
||||
<shadow type="colour_picker">
|
||||
<field name="COLOUR">#ff0000</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="COLOUR2">
|
||||
<shadow type="colour_picker">
|
||||
<field name="COLOUR">#3333ff</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="RATIO">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0.5</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<sep></sep>
|
||||
<category name="Variables" colour="#a55b80" custom="VARIABLE"></category>
|
||||
<category name="Functions" colour="#995ba5" custom="PROCEDURE"></category>
|
||||
</xml>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
136
clover_blocks/www/main.css
Normal file
@@ -0,0 +1,136 @@
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"tabs tools"
|
||||
"content content";
|
||||
grid-template-rows: min-content 1fr;
|
||||
grid-template-columns: 1fr min-content ;
|
||||
font-family: sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#tools, #tabs {
|
||||
background: #dddddd;
|
||||
border-bottom: 2px rgb(192, 192, 192) solid;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#tools {
|
||||
grid-area: tools;
|
||||
white-space: nowrap;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#program-name {
|
||||
width: 150px;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
#program-name:focus {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.changed #program-name {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.disconnected {
|
||||
color: red;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.connected .disconnected { display: none; }
|
||||
|
||||
.backend-fail {
|
||||
margin-right: 20px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
#running {
|
||||
color: green;
|
||||
margin-right: 20px;
|
||||
animation: 1s blink linear infinite;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.running #running { display: block; }
|
||||
|
||||
#tools button {
|
||||
font-size: 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
grid-area: tabs;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
font-size: 18px;
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#tabs li.selected {
|
||||
background: white;
|
||||
}
|
||||
|
||||
#run {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
#notifications {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
max-width: 350px;
|
||||
top: 53px;
|
||||
/* border: white solid 3px; */
|
||||
z-index: 1;
|
||||
padding: 10px;
|
||||
font-family: monospace;
|
||||
font-size: 16px;
|
||||
white-space: pre;
|
||||
max-height: 400px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#notifications:empty { display: none; }
|
||||
|
||||
.content {
|
||||
display: none !important;
|
||||
grid-area: content;
|
||||
}
|
||||
|
||||
body[data-tab="blocks"] #blockly { display: block !important; }
|
||||
body[data-tab="python"] #python { display: block !important; }
|
||||
|
||||
#python {
|
||||
margin: 0px;
|
||||
padding: 10px;
|
||||
z-index: 999999; /* overlap some Blockly's popups */
|
||||
}
|
||||
313
clover_blocks/www/main.js
Normal file
@@ -0,0 +1,313 @@
|
||||
import * as ros from './ros.js';
|
||||
import './blocks.js';
|
||||
import {generateCode, generateUserCode} from './python.js';
|
||||
|
||||
// Tabs
|
||||
document.getElementById('tabs').addEventListener('click', function(e) {
|
||||
var tab = e.target.getAttribute('data-tab');
|
||||
if (tab) {
|
||||
for (let elem of e.target.parentElement.querySelectorAll('[data-tab]')) {
|
||||
elem.classList.remove('selected');
|
||||
}
|
||||
e.target.classList.add('selected');
|
||||
document.body.setAttribute('data-tab', tab);
|
||||
}
|
||||
});
|
||||
|
||||
var workspace = Blockly.inject('blockly', {
|
||||
toolbox: document.getElementById('toolbox'),
|
||||
grid: {
|
||||
spacing: 25,
|
||||
length: 3,
|
||||
colour: '#ccc',
|
||||
snap: true
|
||||
},
|
||||
zoom: { controls: true, wheel: true },
|
||||
media: 'blockly/media/',
|
||||
});
|
||||
|
||||
function readParams() {
|
||||
return Promise.all([
|
||||
ros.readParam('navigate_tolerance', true, 0.2),
|
||||
ros.readParam('sleep_time', true, 0.2)
|
||||
]);
|
||||
}
|
||||
|
||||
var ready = readParams(); // initialization complete promise
|
||||
|
||||
var pythonArea = document.getElementById('python');
|
||||
|
||||
// update Python code
|
||||
workspace.addChangeListener(function(e) {
|
||||
ready.then(function() {
|
||||
pythonArea.innerHTML = generateUserCode(workspace);
|
||||
hljs.highlightBlock(pythonArea);
|
||||
});
|
||||
});
|
||||
|
||||
var running = false;
|
||||
var runRequest = false;
|
||||
|
||||
new ROSLIB.Topic({ ros: ros.ros, name: ros.priv + 'block', messageType: 'std_msgs/String' }).subscribe(function(msg) {
|
||||
workspace.highlightBlock(msg.data);
|
||||
runRequest = false;
|
||||
update();
|
||||
});
|
||||
|
||||
new ROSLIB.Topic({ ros: ros.ros, name: ros.priv + 'running' }).subscribe(function(msg) {
|
||||
running = msg.data;
|
||||
runRequest = false;
|
||||
if (!running) {
|
||||
workspace.highlightBlock('');
|
||||
}
|
||||
update();
|
||||
});
|
||||
|
||||
var notifElem = document.getElementById('notifications');
|
||||
|
||||
function z(n) { return (n < 10 ? '0' : '') + n; } // add leading zero
|
||||
|
||||
new ROSLIB.Topic({ ros: ros.ros, name: ros.priv + 'print', messageType: 'std_msgs/String'}).subscribe(function(msg) {
|
||||
var d = new Date(); // TODO: use rosgraph_msgs/Log?
|
||||
var timestamp = `${z(d.getHours())}:${z(d.getMinutes())}:${z(d.getSeconds())}`;
|
||||
notifElem.innerHTML += `${timestamp}: ${msg.data}\n`;
|
||||
notifElem.scrollTop = notifElem.scrollHeight;
|
||||
});
|
||||
|
||||
new ROSLIB.Topic({ ros: ros.ros, name: ros.priv + 'error', messageType: 'std_msgs/String'}).subscribe(function(msg) {
|
||||
alert('Error: ' + msg.data);
|
||||
});
|
||||
|
||||
var runButton = document.getElementById('run');
|
||||
|
||||
function update() {
|
||||
document.body.classList.toggle('running', running);
|
||||
runButton.disabled = !ros.ros.isConnected || runRequest || running;
|
||||
}
|
||||
|
||||
var shownPrompts = new Set();
|
||||
|
||||
new ROSLIB.Topic({ ros: ros.ros, name: ros.priv + 'prompt', messageType: 'clover_blocks/Prompt'}).subscribe(function(msg) {
|
||||
if (shownPrompts.has(msg.id)) return;
|
||||
shownPrompts.add(msg.id);
|
||||
|
||||
var response = prompt(msg.message);
|
||||
new ROSLIB.Topic({
|
||||
ros: ros.ros,
|
||||
name: ros.priv + 'input/' + msg.id,
|
||||
messageType: 'std_msgs/String',
|
||||
latch: true
|
||||
}).publish(new ROSLIB.Message({ data: response }));
|
||||
});
|
||||
|
||||
window.stopProgram = function() {
|
||||
ros.stopService.callService(new ROSLIB.ServiceRequest(), function(res) {
|
||||
if (!res.success) alert(res.message);
|
||||
}, err => alert(err))
|
||||
}
|
||||
|
||||
ros.ros.on('connection', update);
|
||||
|
||||
ros.ros.on('close', update);
|
||||
|
||||
ready.then(() => runButton.disabled = false);
|
||||
|
||||
window.runProgram = function() {
|
||||
if (!confirm('Run program?')) return;
|
||||
|
||||
runRequest = true;
|
||||
update();
|
||||
var code = generateCode(workspace);
|
||||
console.log(code);
|
||||
ros.runService.callService(new ROSLIB.ServiceRequest({ code: code } ), function(res) {
|
||||
if (!res.success) {
|
||||
runRequest = false;
|
||||
update();
|
||||
alert(res.message);
|
||||
}
|
||||
}, function(err) {
|
||||
runRequest = false;
|
||||
update();
|
||||
alert(err);
|
||||
})
|
||||
}
|
||||
|
||||
window.land = function() {
|
||||
window.stopProgram();
|
||||
ros.landService.callService(new ROSLIB.ServiceRequest(), function(result) {
|
||||
}, function(err) {
|
||||
alert('Unable to land: ' + err);
|
||||
});
|
||||
}
|
||||
|
||||
function getProgramXml() {
|
||||
var xmlDom = Blockly.Xml.workspaceToDom(workspace);
|
||||
return Blockly.Xml.domToPrettyText(xmlDom);
|
||||
}
|
||||
|
||||
function setProgramXml(xml) {
|
||||
workspace.clear();
|
||||
if (xml) {
|
||||
let xmlDom = Blockly.Xml.textToDom(xml);
|
||||
Blockly.Xml.domToWorkspace(xmlDom, workspace);
|
||||
}
|
||||
}
|
||||
|
||||
workspace.addChangeListener(function(e) {
|
||||
localStorage.setItem('xml', getProgramXml());
|
||||
});
|
||||
|
||||
var programSelect = document.querySelector('#program-name');
|
||||
var userPrograms = programSelect.querySelector('optgroup[data-type=user]');
|
||||
var examplePrograms = programSelect.querySelector('optgroup[data-type=example]');
|
||||
|
||||
var programs = {};
|
||||
var program = '';
|
||||
|
||||
function loadWorkspace() {
|
||||
var xml = localStorage.getItem('xml');
|
||||
if (xml) {
|
||||
setProgramXml(xml);
|
||||
}
|
||||
program = localStorage.getItem('program') || '';
|
||||
}
|
||||
|
||||
loadWorkspace();
|
||||
|
||||
function loadPrograms() {
|
||||
ros.loadService.callService(new ROSLIB.ServiceRequest(), function(res) {
|
||||
if (!res.success) alert(res.message);
|
||||
|
||||
for (let i = 0; i < res.names.length; i++) {
|
||||
let name = res.names[i];
|
||||
let program = res.programs[i];
|
||||
let option = document.createElement('option');
|
||||
option.innerHTML = res.names[i];
|
||||
if (name.startsWith('examples/')) {
|
||||
examplePrograms.appendChild(option);
|
||||
} else {
|
||||
userPrograms.appendChild(option);
|
||||
}
|
||||
|
||||
programs[name] = program;
|
||||
}
|
||||
|
||||
if (program) {
|
||||
programSelect.value = program;
|
||||
}
|
||||
updateChanged();
|
||||
}, function(err) {
|
||||
document.querySelector('.backend-fail').style.display = 'inline';
|
||||
alert(`Error loading programs list.\n\nHave you enabled clover_blocks in clover.launch?`);
|
||||
runButton.disabled = true;
|
||||
})
|
||||
}
|
||||
|
||||
loadPrograms();
|
||||
|
||||
function getProgramName() {
|
||||
if (programSelect.value.startsWith('@')) {
|
||||
return ''
|
||||
}
|
||||
return programSelect.value;
|
||||
}
|
||||
|
||||
function updateChanged() {
|
||||
var name = program;
|
||||
document.body.classList.toggle('changed', name in programs && (programs[name].trim() != getProgramXml().trim()));
|
||||
}
|
||||
|
||||
workspace.addChangeListener(function(e) {
|
||||
if (e instanceof Blockly.Events.Change || e instanceof Blockly.Events.Create || e instanceof Blockly.Events.Delete) {
|
||||
updateChanged();
|
||||
}
|
||||
});
|
||||
|
||||
function saveProgram() {
|
||||
var name = getProgramName();
|
||||
|
||||
if (!name) {
|
||||
name = prompt('Enter new program name:');
|
||||
if (!name) {
|
||||
programSelect.value = program;
|
||||
return;
|
||||
}
|
||||
if (!name.endsWith('.xml')) {
|
||||
name += '.xml';
|
||||
}
|
||||
let option = document.createElement('option');
|
||||
option.innerHTML = name;
|
||||
userPrograms.appendChild(option);
|
||||
}
|
||||
|
||||
let xml = getProgramXml();
|
||||
ros.storeService.callService(new ROSLIB.ServiceRequest({
|
||||
name: name,
|
||||
program: xml
|
||||
}), function(result) {
|
||||
if (!result.success) {
|
||||
alert(result.message);
|
||||
return;
|
||||
}
|
||||
console.log(result.message);
|
||||
programSelect.blur();
|
||||
program = name;
|
||||
localStorage.setItem('program', name);
|
||||
programs[name] = xml;
|
||||
programSelect.value = program;
|
||||
updateChanged();
|
||||
}, function(err) {
|
||||
// TODO: restore previous state correctly
|
||||
alert('Unable to store: ' + err);
|
||||
programSelect.blur();
|
||||
programSelect.value = program;
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', function(e) {
|
||||
if ((e.metaKey || e.ctrlKey) && e.key == 's') { // ctrl+s/cmd+s
|
||||
e.preventDefault();
|
||||
if (!document.body.classList.contains('changed')) { // if not changed, ignore
|
||||
return;
|
||||
}
|
||||
saveProgram();
|
||||
}
|
||||
});
|
||||
|
||||
programSelect.addEventListener('change', function(e) {
|
||||
if (programSelect.value == '@clear') {
|
||||
if (!confirm('Clear workspace?')) {
|
||||
programSelect.value = program;
|
||||
return;
|
||||
}
|
||||
localStorage.removeItem('program');
|
||||
program = '';
|
||||
setProgramXml('');
|
||||
programSelect.value = program;
|
||||
programSelect.blur();
|
||||
} else if (programSelect.value == '@save') {
|
||||
saveProgram();
|
||||
} else {
|
||||
// load program
|
||||
if (program == '' || document.body.classList.contains('changed')) {
|
||||
if (!confirm('Discard changes?')) {
|
||||
programSelect.value = program;
|
||||
return;
|
||||
}
|
||||
}
|
||||
let name = programSelect.value;
|
||||
let lastProgram = getProgramXml();
|
||||
programSelect.blur();
|
||||
try {
|
||||
setProgramXml(programs[name]);
|
||||
program = name;
|
||||
localStorage.setItem('program', name);
|
||||
} catch(e) {
|
||||
alert(e);
|
||||
setProgramXml(lastProgram);
|
||||
program = ''
|
||||
programSelect.value = program;
|
||||
}
|
||||
updateChanged();
|
||||
}
|
||||
});
|
||||
434
clover_blocks/www/python.js
Normal file
@@ -0,0 +1,434 @@
|
||||
import {params} from './ros.js';
|
||||
|
||||
// If any new block imports any library, add that library name here.
|
||||
Blockly.Python.addReservedWords('_b,_print');
|
||||
Blockly.Python.addReservedWords('rospy,srv,Trigger,get_telemetry,navigate,set_velocity,land');
|
||||
Blockly.Python.addReservedWords('navigate_wait,land_wait,wait_arrival,wait_yaw,get_distance');
|
||||
Blockly.Python.addReservedWords('pigpio,pi,Range');
|
||||
Blockly.Python.addReservedWords('SetLEDEffect,set_effect');
|
||||
Blockly.Python.addReservedWords('SetLEDs,LEDState,set_leds');
|
||||
|
||||
// TODO: parametrize
|
||||
const navigate_tolerance = 0.2;
|
||||
const sleep_time = 0.2;
|
||||
|
||||
const IMPORT_SRV = `from clover import srv
|
||||
from std_srvs.srv import Trigger`;
|
||||
|
||||
// TODO: tolerance to parameters
|
||||
const NAVIGATE_WAIT = () => `\ndef navigate_wait(x=0, y=0, z=0, speed=0.5, frame_id='body', auto_arm=False):
|
||||
res = navigate(x=x, y=y, z=z, yaw=float('nan'), speed=speed, frame_id=frame_id, auto_arm=auto_arm)
|
||||
|
||||
if not res.success:
|
||||
raise Exception(res.message)
|
||||
|
||||
while not rospy.is_shutdown():
|
||||
telem = get_telemetry(frame_id='navigate_target')
|
||||
if math.sqrt(telem.x ** 2 + telem.y ** 2 + telem.z ** 2) < ${params.navigate_tolerance}:
|
||||
return
|
||||
rospy.sleep(${params.sleep_time})\n`;
|
||||
|
||||
const LAND_WAIT = () => `\ndef land_wait():
|
||||
land()
|
||||
while get_telemetry().armed:
|
||||
rospy.sleep(${params.sleep_time})\n`;
|
||||
|
||||
// TODO: tolerance to parameters
|
||||
const WAIT_YAW = () => `\ndef wait_yaw():
|
||||
while not rospy.is_shutdown():
|
||||
telem = get_telemetry(frame_id='navigate_target')
|
||||
if abs(telem.yaw) < math.radians(20):
|
||||
return
|
||||
rospy.sleep(${params.sleep_time})\n`;
|
||||
|
||||
// TODO: tolerance to parameters
|
||||
const WAIT_ARRIVAL = () => `\ndef wait_arrival():
|
||||
while not rospy.is_shutdown():
|
||||
telem = get_telemetry(frame_id='navigate_target')
|
||||
if math.sqrt(telem.x ** 2 + telem.y ** 2 + telem.z ** 2) < ${params.navigate_tolerance}:
|
||||
return
|
||||
rospy.sleep(${params.sleep_time})\n`;
|
||||
|
||||
// TODO: tolerance to parameters
|
||||
const ARRIVED = () => `\ndef arrived():
|
||||
telem = get_telemetry(frame_id='navigate_target')
|
||||
return math.sqrt(telem.x ** 2 + telem.y ** 2 + telem.z ** 2) < ${params.navigate_tolerance}\n`
|
||||
|
||||
const GET_DISTANCE = `\ndef get_distance(x, y, z, frame_id):
|
||||
telem = get_telemetry(frame_id)
|
||||
return math.sqrt((x - telem.x) ** 2 + (y - telem.y) ** 2 + (z - telem.z) ** 2)\n`;
|
||||
|
||||
var rosDefinitions = {};
|
||||
|
||||
function generateROSDefinitions() {
|
||||
// order for ROS definitions is significant, so generate all ROS definitions as one
|
||||
var code = `rospy.init_node('flight')\n\n`;
|
||||
if (rosDefinitions.offboard) {
|
||||
code += `get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)\n`;
|
||||
code += `navigate = rospy.ServiceProxy('navigate', srv.Navigate)\n`;
|
||||
if (rosDefinitions.setVelocity) {
|
||||
code += `set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)\n`;
|
||||
}
|
||||
if (rosDefinitions.setAttitude) {
|
||||
code += `set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)\n`;
|
||||
}
|
||||
if (rosDefinitions.setRates) {
|
||||
code += `set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)\n`;
|
||||
}
|
||||
code += `land = rospy.ServiceProxy('land', Trigger)\n`;
|
||||
}
|
||||
if (rosDefinitions.setEffect) {
|
||||
Blockly.Python.definitions_['import_led_effect'] = 'from clover.srv import SetLEDEffect';
|
||||
code += `set_effect = rospy.ServiceProxy('led/set_effect', SetLEDEffect, persistent=True)\n`;
|
||||
}
|
||||
if (rosDefinitions.setLeds) {
|
||||
Blockly.Python.definitions_['import_set_led'] = 'from led_msgs.srv import SetLEDs\nfrom led_msgs.msg import LEDState';
|
||||
code += `set_leds = rospy.ServiceProxy('led/set_leds', SetLEDs, persistent=True)\n`;
|
||||
}
|
||||
if (rosDefinitions.navigateWait) {
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
code += NAVIGATE_WAIT();
|
||||
}
|
||||
if (rosDefinitions.landWait) {
|
||||
code += LAND_WAIT();
|
||||
}
|
||||
if (rosDefinitions.waitArrival) {
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
code += WAIT_ARRIVAL();
|
||||
}
|
||||
if (rosDefinitions.arrived) {
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
code += ARRIVED();
|
||||
}
|
||||
if (rosDefinitions.waitYaw) {
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
code += WAIT_YAW();
|
||||
}
|
||||
if (rosDefinitions.distance) {
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
code += GET_DISTANCE;
|
||||
}
|
||||
Blockly.Python.definitions_['ros'] = code;
|
||||
}
|
||||
|
||||
function initNode() {
|
||||
Blockly.Python.definitions_['import_rospy'] = 'import rospy';
|
||||
generateROSDefinitions();
|
||||
}
|
||||
|
||||
function simpleOffboard() {
|
||||
rosDefinitions.offboard = true;
|
||||
Blockly.Python.definitions_['import_srv'] = IMPORT_SRV;
|
||||
initNode();
|
||||
}
|
||||
|
||||
// Adjust indentation
|
||||
Blockly.Python.INDENT = ' ';
|
||||
|
||||
export function generateUserCode(workspace) {
|
||||
rosDefinitions = {};
|
||||
Blockly.Python.STATEMENT_PREFIX = null;
|
||||
return Blockly.Python.workspaceToCode(workspace);
|
||||
}
|
||||
|
||||
export function generateCode(workspace) {
|
||||
rosDefinitions = {};
|
||||
Blockly.Python.STATEMENT_PREFIX = '_b(%1)\n';
|
||||
var code = Blockly.Python.workspaceToCode(workspace);
|
||||
return code;
|
||||
}
|
||||
|
||||
function buildFrameId(block) {
|
||||
let frame = block.getFieldValue('FRAME_ID').toLowerCase();
|
||||
let id = Blockly.Python.valueToCode(block, 'ID', Blockly.Python.ORDER_NONE);
|
||||
if (frame == 'aruco') { // aruco marker frame
|
||||
if (id.match(/^[0-9]+$/)) { // id is positive integer
|
||||
return `'${frame}_${id}'`;
|
||||
} else { // something else...
|
||||
return `'${frame}_' + str(int(${id}))`;
|
||||
}
|
||||
} else {
|
||||
return `'${frame}'`;
|
||||
}
|
||||
}
|
||||
|
||||
Blockly.Python.navigate = function(block) {
|
||||
let x = Blockly.Python.valueToCode(block, 'X', Blockly.Python.ORDER_NONE);
|
||||
let y = Blockly.Python.valueToCode(block, 'Y', Blockly.Python.ORDER_NONE);
|
||||
let z = Blockly.Python.valueToCode(block, 'Z', Blockly.Python.ORDER_NONE);
|
||||
let frameId = buildFrameId(block);
|
||||
let speed = Blockly.Python.valueToCode(block, 'SPEED', Blockly.Python.ORDER_NONE);
|
||||
|
||||
let params = [`x=${x}`, `y=${y}`, `z=${z}`, `frame_id=${frameId}`, `speed=${speed}`];
|
||||
|
||||
simpleOffboard();
|
||||
|
||||
if (block.getFieldValue('WAIT') == 'TRUE') {
|
||||
rosDefinitions.navigateWait = true;
|
||||
simpleOffboard();
|
||||
|
||||
return `navigate_wait(${params.join(', ')})\n`;
|
||||
|
||||
} else {
|
||||
if (frameId != 'body') {
|
||||
params.push(`yaw=float('nan')`);
|
||||
}
|
||||
return `navigate(${params.join(', ')})\n`;
|
||||
}
|
||||
}
|
||||
|
||||
Blockly.Python.set_velocity = function(block) {
|
||||
let x = Blockly.Python.valueToCode(block, 'X', Blockly.Python.ORDER_NONE);
|
||||
let y = Blockly.Python.valueToCode(block, 'Y', Blockly.Python.ORDER_NONE);
|
||||
let z = Blockly.Python.valueToCode(block, 'Z', Blockly.Python.ORDER_NONE);
|
||||
let frameId = buildFrameId(block);
|
||||
|
||||
simpleOffboard();
|
||||
|
||||
if (frameId == `'body'`) {
|
||||
return `set_velocity(vx=${x}, vy=${y}, vz=${z}, frame_id=${frameId})\n`;
|
||||
} else {
|
||||
return `set_velocity(vx=${x}, vy=${y}, vz=${z}, yaw=float('nan'), frame_id=${frameId})\n`;
|
||||
}
|
||||
}
|
||||
|
||||
Blockly.Python.take_off = function(block) {
|
||||
simpleOffboard();
|
||||
|
||||
let z = Blockly.Python.valueToCode(block, 'ALT', Blockly.Python.ORDER_NONE);
|
||||
|
||||
if (block.getFieldValue('WAIT') == 'TRUE') {
|
||||
rosDefinitions.navigateWait = true;
|
||||
simpleOffboard();
|
||||
|
||||
return `navigate_wait(z=${z}, frame_id='body', auto_arm=True)\n`;
|
||||
} else {
|
||||
return `navigate(z=${z}, frame_id='body', auto_arm=True)\n`;
|
||||
}
|
||||
}
|
||||
|
||||
Blockly.Python.land = function(block) {
|
||||
simpleOffboard();
|
||||
|
||||
if (block.getFieldValue('WAIT') == 'TRUE') {
|
||||
rosDefinitions.landWait = true;
|
||||
simpleOffboard();
|
||||
|
||||
return `land_wait()\n`;
|
||||
} else {
|
||||
return 'land()\n';
|
||||
}
|
||||
}
|
||||
|
||||
Blockly.Python.angle = function(block) {
|
||||
// return [block.getFieldValue('ANGLE'), Blockly.Python.ORDER_UNARY_SIGN];
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
return [`math.radians(${block.getFieldValue('ANGLE')})`, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
|
||||
}
|
||||
|
||||
Blockly.Python.set_yaw = function(block) {
|
||||
simpleOffboard();
|
||||
let yaw = Blockly.Python.valueToCode(block, 'YAW', Blockly.Python.ORDER_NONE);
|
||||
let frameId = buildFrameId(block);
|
||||
let code = `navigate(x=float('nan'), y=float('nan'), z=float('nan'), yaw=${yaw}, frame_id=${frameId})\n`;
|
||||
if (block.getFieldValue('WAIT') == 'TRUE') {
|
||||
rosDefinitions.waitYaw = true;
|
||||
simpleOffboard();
|
||||
code += 'wait_yaw()\n';
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
Blockly.Python.wait_arrival = function(block) {
|
||||
rosDefinitions.waitArrival = true;
|
||||
simpleOffboard();
|
||||
return 'wait_arrival()\n';
|
||||
}
|
||||
|
||||
Blockly.Python.get_time = function(block) {
|
||||
initNode();
|
||||
return ['rospy.get_time()', Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
|
||||
Blockly.Python.arrived = function(block) {
|
||||
rosDefinitions.arrived = true;
|
||||
simpleOffboard();
|
||||
return ['arrived()', Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
|
||||
Blockly.Python.wait = function(block) {
|
||||
initNode();
|
||||
return `rospy.sleep(${Blockly.Python.valueToCode(block, 'TIME', Blockly.Python.ORDER_NONE)})\n`;
|
||||
}
|
||||
|
||||
Blockly.Python.setpoint = function(block) {
|
||||
var type = block.getFieldValue('TYPE');
|
||||
let frameId = buildFrameId(block);
|
||||
let vx = Blockly.Python.valueToCode(block, 'VX', Blockly.Python.ORDER_NONE);
|
||||
let vy = Blockly.Python.valueToCode(block, 'VY', Blockly.Python.ORDER_NONE);
|
||||
let vz = Blockly.Python.valueToCode(block, 'VZ', Blockly.Python.ORDER_NONE);
|
||||
let yaw = Blockly.Python.valueToCode(block, 'YAW', Blockly.Python.ORDER_NONE);
|
||||
let pitch = Blockly.Python.valueToCode(block, 'PITCH', Blockly.Python.ORDER_NONE);
|
||||
let roll = Blockly.Python.valueToCode(block, 'ROLL', Blockly.Python.ORDER_NONE);
|
||||
let thrust = Blockly.Python.valueToCode(block, 'THRUST', Blockly.Python.ORDER_NONE);
|
||||
|
||||
if (type == 'VELOCITY') {
|
||||
rosDefinitions.setVelocity = true;
|
||||
simpleOffboard();
|
||||
return `set_velocity(vx=${vx}, vy=${vy}, vz=${vz}, frame_id=${frameId}, yaw=float('nan'))\n`;
|
||||
} else if (type == 'ATTITUDE') {
|
||||
rosDefinitions.setAttitude = true;
|
||||
simpleOffboard();
|
||||
return `set_attitude(pitch=${pitch}, roll=${roll}, yaw=${yaw}, thrust=${thrust}, frame_id=${frameId})\n`;
|
||||
} else if (type == 'RATES') {
|
||||
rosDefinitions.setRates = true;
|
||||
simpleOffboard();
|
||||
return `set_rates(pitch_rate=${pitch}, roll_rate=${roll}, yaw_rate=${yaw}, thrust=${thrust})\n`;
|
||||
}
|
||||
}
|
||||
|
||||
Blockly.Python.get_position = function(block) {
|
||||
simpleOffboard();
|
||||
let frameId = buildFrameId(block);
|
||||
var code = `get_telemetry(${frameId}).${block.getFieldValue('FIELD').toLowerCase()}`;
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
|
||||
Blockly.Python.get_yaw = function(block) {
|
||||
simpleOffboard();
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
let frameId = buildFrameId(block);
|
||||
var code = `math.degrees(get_telemetry(${frameId}).yaw)`;
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
|
||||
Blockly.Python.get_attitude = function(block) {
|
||||
simpleOffboard();
|
||||
Blockly.Python.definitions_['import_math'] = 'import math';
|
||||
var code = `math.degrees(get_telemetry().${block.getFieldValue('FIELD').toLowerCase()})`;
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
|
||||
Blockly.Python.distance = function(block) {
|
||||
rosDefinitions.distance = true;
|
||||
simpleOffboard();
|
||||
|
||||
let x = Blockly.Python.valueToCode(block, 'X', Blockly.Python.ORDER_NONE);
|
||||
let y = Blockly.Python.valueToCode(block, 'Y', Blockly.Python.ORDER_NONE);
|
||||
let z = Blockly.Python.valueToCode(block, 'Z', Blockly.Python.ORDER_NONE);
|
||||
let frameId = buildFrameId(block);
|
||||
|
||||
return [`get_distance(${x}, ${y}, ${z}, ${frameId})`, Blockly.Python.ORDER_FUNCTION_CALL]
|
||||
}
|
||||
|
||||
Blockly.Python.rangefinder_distance = function(block) {
|
||||
initNode();
|
||||
Blockly.Python.definitions_['import_range'] = 'from sensor_msgs.msg import Range';
|
||||
return [`rospy.wait_for_message('rangefinder/range', Range).range`, Blockly.Python.ORDER_FUNCTION_CALL]
|
||||
}
|
||||
|
||||
Blockly.Python.mode = function(block) {
|
||||
simpleOffboard();
|
||||
return [`get_telemetry().mode`, Blockly.Python.ORDER_FUNCTION_CALL]
|
||||
}
|
||||
|
||||
Blockly.Python.armed = function(block) {
|
||||
simpleOffboard();
|
||||
return [`get_telemetry().armed`, Blockly.Python.ORDER_FUNCTION_CALL]
|
||||
}
|
||||
|
||||
Blockly.Python.voltage = function(block) {
|
||||
simpleOffboard();
|
||||
var code = `get_telemetry().${block.getFieldValue('TYPE').toLowerCase()}`;
|
||||
return [code, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
|
||||
function parseColor(color) {
|
||||
return {
|
||||
r: parseInt(color.substr(2, 2), 16),
|
||||
g: parseInt(color.substr(4, 2), 16),
|
||||
b: parseInt(color.substr(6, 2), 16)
|
||||
}
|
||||
}
|
||||
|
||||
const PARSE_COLOR = `def ${Blockly.Python.FUNCTION_NAME_PLACEHOLDER_}(color):
|
||||
return {'r': int(color[1:3], 16), 'g': int(color[3:5], 16), 'b': int(color[5:7], 16)}`;
|
||||
|
||||
// TODO: weird code with colour_rgb block
|
||||
Blockly.Python.set_effect = function(block) {
|
||||
rosDefinitions.setEffect = true;
|
||||
initNode();
|
||||
|
||||
var effect = block.getFieldValue('EFFECT').toLowerCase();
|
||||
|
||||
if (effect == 'rainbow' || effect == 'rainbow_fill') {
|
||||
return `set_effect(effect='${effect}')\n`;
|
||||
} else {
|
||||
let colorCode = Blockly.Python.valueToCode(block, 'COLOR', Blockly.Python.ORDER_NONE);
|
||||
|
||||
if (/^'(.*)'$/.test(colorCode)) { // is simple string
|
||||
let color = parseColor(colorCode);
|
||||
return `set_effect(effect='${effect}', r=${color.r}, g=${color.g}, b=${color.b})\n`;
|
||||
} else {
|
||||
let parseColor = Blockly.Python.provideFunction_('parse_color', [PARSE_COLOR]);
|
||||
return `set_effect(effect='${effect}', **${parseColor}(${colorCode}))\n`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Blockly.Python.set_led = function(block) {
|
||||
rosDefinitions.setLeds = true;
|
||||
initNode();
|
||||
|
||||
var index = Blockly.Python.valueToCode(block, 'INDEX', Blockly.Python.ORDER_NONE);
|
||||
var colorCode = Blockly.Python.valueToCode(block, 'COLOR', Blockly.Python.ORDER_NONE);
|
||||
|
||||
if (/^'(.*)'$/.test(colorCode)) { // is simple string
|
||||
let color = parseColor(colorCode);
|
||||
return `set_leds([LEDState(index=${index}, r=${color.r}, g=${color.g}, b=${color.b})])\n`;
|
||||
} else {
|
||||
let parseColor = Blockly.Python.provideFunction_('parse_color', [PARSE_COLOR]);
|
||||
return `set_leds([LEDState(index=${index}, **${parseColor}(${colorCode})])\n`;
|
||||
}
|
||||
}
|
||||
|
||||
function pigpio() {
|
||||
Blockly.Python.definitions_['import_pigpio'] = 'import pigpio';
|
||||
Blockly.Python.definitions_['init_pigpio'] = 'pi = pigpio.pi()';
|
||||
}
|
||||
|
||||
const GPIO_READ = `\ndef gpio_read(pin):
|
||||
pi.set_mode(pin, pigpio.INPUT)
|
||||
return pi.read(pin)\n`;
|
||||
|
||||
const GPIO_WRITE = `\ndef gpio_write(pin, level):
|
||||
pi.set_mode(pin, pigpio.OUTPUT)
|
||||
pi.write(pin, level)\n`;
|
||||
|
||||
const SET_SERVO = `\ndef set_servo(pin, pwm):
|
||||
pi.set_mode(pin, pigpio.OUTPUT)
|
||||
pi.set_servo_pulsewidth(pin, pwm)\n`;
|
||||
|
||||
Blockly.Python.gpio_read = function(block) {
|
||||
pigpio();
|
||||
Blockly.Python.definitions_['gpio_read'] = GPIO_READ;
|
||||
var pin = Blockly.Python.valueToCode(block, 'PIN', Blockly.Python.ORDER_NONE);
|
||||
return [`gpio_read(${pin})`, Blockly.Python.ORDER_FUNCTION_CALL];
|
||||
}
|
||||
|
||||
Blockly.Python.gpio_write = function(block) {
|
||||
pigpio();
|
||||
Blockly.Python.definitions_['gpio_write'] = GPIO_WRITE;
|
||||
var pin = Blockly.Python.valueToCode(block, 'PIN', Blockly.Python.ORDER_NONE);
|
||||
var level = Blockly.Python.valueToCode(block, 'LEVEL', Blockly.Python.ORDER_NONE);
|
||||
return `gpio_write(${pin}, ${level})\n`;
|
||||
}
|
||||
|
||||
Blockly.Python.set_servo = function(block) {
|
||||
pigpio();
|
||||
Blockly.Python.definitions_['set_servo'] = SET_SERVO;
|
||||
var pin = Blockly.Python.valueToCode(block, 'PIN', Blockly.Python.ORDER_NONE);
|
||||
var pwm = Blockly.Python.valueToCode(block, 'PWM', Blockly.Python.ORDER_NONE);
|
||||
return `set_servo(${pin}, ${pwm})\n`;
|
||||
}
|
||||
59
clover_blocks/www/ros.js
Normal file
@@ -0,0 +1,59 @@
|
||||
var url = 'ws://' + location.hostname + ':9090';
|
||||
export var ros = new ROSLIB.Ros({ url });
|
||||
|
||||
ros.on('connection', function () {
|
||||
console.log('connection')
|
||||
document.body.classList.add('connected');
|
||||
});
|
||||
|
||||
ros.on('close', function () {
|
||||
console.log('close')
|
||||
document.body.classList.remove('connected');
|
||||
setTimeout(function() {
|
||||
ros.connect(url);
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
ros.on('error', function(err) {
|
||||
});
|
||||
|
||||
export const namespace = '/';
|
||||
export const priv = namespace + 'clover_blocks/';
|
||||
|
||||
export var params = {}; // parameters storage
|
||||
|
||||
export function readParam(name, fromUrl, _default) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (params[name] !== undefined) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
// read from url
|
||||
if (fromUrl && ((params[name] = new URL(window.location.href).searchParams.get(name)) !== null)) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
// read from ROS params
|
||||
new ROSLIB.Param({ ros: ros, name: priv + name }).get(function(val) {
|
||||
if (val === null) {
|
||||
if (_default === undefined) {
|
||||
alert('Cannot read required parameter ' + name);
|
||||
reject();
|
||||
} else {
|
||||
params[name] = _default;
|
||||
resolve();
|
||||
}
|
||||
return;
|
||||
}
|
||||
params[name] = val;
|
||||
resolve();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export var runService = new ROSLIB.Service({ ros: ros, name: priv + 'run', serviceType: 'clover_blocks/Run' });
|
||||
export var stopService = new ROSLIB.Service({ ros: ros, name: priv + 'stop', serviceType: 'std_srvs/Trigger' });
|
||||
export var loadService = new ROSLIB.Service({ ros: ros, name : priv + 'load', serviceType : 'clover_blocks/Load' });
|
||||
export var storeService = new ROSLIB.Service({ ros: ros, name : priv + 'store', serviceType : 'clover_blocks/Store' });
|
||||
export var landService = new ROSLIB.Service({ ros: ros, name : namespace + 'land', serviceType : 'std_srvs/Trigger' });
|
||||
4560
clover_blocks/www/roslib.js
vendored
Normal file
@@ -7,6 +7,7 @@
|
||||
</include>
|
||||
<include>
|
||||
<uri>model://parquet_plane</uri>
|
||||
<pose>0 0 -0.01 0 0 0</pose>
|
||||
</include>
|
||||
|
||||
<scene>
|
||||
|
||||
209
docs/assets/blocks/blockly.svg
Normal file
@@ -0,0 +1,209 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="104.11897mm"
|
||||
height="87.369049mm"
|
||||
viewBox="0 0 104.11897 87.369049"
|
||||
version="1.1"
|
||||
id="svg1512"
|
||||
inkscape:version="0.92.2pre0 (973e216, 2017-07-25)"
|
||||
sodipodi:docname="logo_vertical.svg"
|
||||
inkscape:export-filename="/usr/local/google/home/epastern/Documents/Blockly Logos/Square/logo_standard.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs1506">
|
||||
<clipPath
|
||||
id="clipPath5790"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5788"
|
||||
d="M 0,35 H 126 V 0 H 0 Z" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath5802"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5800"
|
||||
d="M 0,35 H 126 V 0 H 0 Z" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath5812"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5810"
|
||||
d="M -1.52588e-4,192 H 192 V -1.83105e-4 H -1.52588e-4 Z" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath5820"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5818"
|
||||
d="M -1.52588e-4,192 H 192 V -1.83105e-4 H -1.52588e-4 Z" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath5824"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5822"
|
||||
d="M 0,192 H 192 V 0 H 0 Z" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath5828"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5826"
|
||||
d="M 0,192 H 192 V 0 H 0 Z" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath5832"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5830"
|
||||
d="M 0,192 H 192 V 0 H 0 Z" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
id="linearGradient-1"
|
||||
y2="0.92900556"
|
||||
x2="1.0082812"
|
||||
y1="0.17021771"
|
||||
x1="-0.034921873">
|
||||
<stop
|
||||
id="stop6067"
|
||||
offset="0%"
|
||||
stop-opacity="0.1"
|
||||
stop-color="#FFFFFF" />
|
||||
<stop
|
||||
id="stop6069"
|
||||
offset="14%"
|
||||
stop-opacity="0.08"
|
||||
stop-color="#FFFFFF" />
|
||||
<stop
|
||||
id="stop6071"
|
||||
offset="61%"
|
||||
stop-opacity="0.02"
|
||||
stop-color="#FFFFFF" />
|
||||
<stop
|
||||
id="stop6073"
|
||||
offset="100%"
|
||||
stop-opacity="0"
|
||||
stop-color="#FFFFFF" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="path-2"
|
||||
d="M 82.97724,29.300104 C 82.790583,28.201973 82.006921,27.299698 80.945743,26.961124 79.884564,26.62255 78.723152,26.904241 77.935,27.691354 L 62.465677,43.197917 50.303229,20.042344 C 49.78815,19.063276 48.772957,18.45025 47.666667,18.45025 c -1.106291,0 -2.121484,0.613026 -2.636563,1.592094 L 38.379115,32.703802 21.695781,1.5864062 C 21.090714,0.45617231 19.83044,-0.16023716 18.566804,0.05600004 17.303168,0.27223724 16.319565,1.2726256 16.12474,2.5397396 L 0,105.76042 43.123438,129.93635 c 2.707936,1.51195 6.006125,1.51195 8.714062,0 l 43.495833,-24.17593 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path-4"
|
||||
d="m 106.68711,35.274174 c -0.186,-1.097652 -0.96693,-1.999535 -2.02439,-2.337961 -1.05747,-0.338426 -2.21482,-0.05686 -3.00022,0.729912 L 86.247266,49.165925 74.127344,26.020451 C 73.614066,25.04181 72.602423,24.429052 71.5,24.429052 c -1.102423,0 -2.114066,0.612758 -2.627344,1.591399 L 62.244922,38.676387 45.619922,7.5725628 C 45.01697,6.4428218 43.761103,5.8266812 42.501885,6.0428241 41.242667,6.258967 40.262504,7.2589191 40.068359,8.5254804 L 24,111.70114 66.972656,135.86653 c 2.698469,1.51129 5.985125,1.51129 8.683594,0 L 119,111.70114 Z"
|
||||
inkscape:connector-curvature="0" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="174.07912"
|
||||
inkscape:cy="254.2021"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:measure-start="215.162,827.567"
|
||||
inkscape:measure-end="164.907,827.567"
|
||||
fit-margin-top="10"
|
||||
fit-margin-right="10"
|
||||
fit-margin-bottom="10"
|
||||
fit-margin-left="10"
|
||||
inkscape:window-width="1619"
|
||||
inkscape:window-height="1119"
|
||||
inkscape:window-x="654"
|
||||
inkscape:window-y="124"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata1509">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(20.298455,-51.769323)">
|
||||
<g
|
||||
id="g6939"
|
||||
transform="translate(5.3026997)"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccssccc"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#4285f4;stroke-width:0.26458332"
|
||||
d="m 12.604934,61.770873 c -1.774567,-0.0015 -3.2136701,1.43764 -3.2122066,3.212207 v 27.706838 c -0.00146,1.774568 1.4376396,3.213669 3.2122066,3.212205 h 1.25057 c 0.616698,2.31294 2.710855,3.922673 5.104598,3.923792 2.392205,-0.003 4.484163,-1.612336 5.100464,-3.923792 h 1.281058 4.160987 c 1.169002,0 2.116666,-0.947663 2.116666,-2.116666 V 63.88754 l -2.116666,-2.116667 z"
|
||||
id="path906" />
|
||||
<path
|
||||
style="fill:#c8d1db;stroke-width:0.26458332"
|
||||
d="m 28.444794,61.769323 c -0.0028,4.683852 -0.0021,9.366881 -0.0021,14.053406 l -4.400251,-2.48667 c -0.634301,-0.357915 -1.419291,0.09954 -1.420585,0.827856 V 84.91158 c 0.0013,0.728311 0.786285,1.18577 1.420585,0.827855 l 4.400248,-2.487186 v 9.946164 0.587044 2.116666 h 2.116667 0.377238 9.539468 c 1.683266,-6.8e-5 3.047807,-1.364609 3.047876,-3.047875 V 64.808414 c -0.0057,-1.679229 -1.368601,-3.037482 -3.04784,-3.037541 z"
|
||||
id="path908"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccccccccc" />
|
||||
</g>
|
||||
<g
|
||||
aria-label="Blockly"
|
||||
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
||||
id="text5967">
|
||||
<path
|
||||
d="m -10.298455,123.04237 v -20.20711 h 7.3095554 q 2.37066664,0 4.0922221,1.58045 1.7497778,1.55222 1.7497778,3.92289 0,1.43933 -0.762,2.54 -0.7337778,1.10066 -1.9755555,1.66511 v 0.11289 q 1.4957777,0.508 2.4553333,1.74977 0.9595555,1.24178 0.9595555,2.87867 0,2.48356 -1.8344444,4.12044 -1.80622217,1.63689 -4.2897777,1.63689 z m 2.5964445,-11.54288 h 4.7131109 q 1.4675556,0 2.34244442,-0.95956 0.90311109,-0.98778 0.90311109,-2.14489 0,-1.15711 -0.87488887,-2.11667 -0.84666664,-0.95955 -2.25777774,-0.95955 h -4.8259998 z m 0,9.05933 h 5.2211109 q 1.49577777,0 2.42711107,-1.04422 0.93133331,-1.04423 0.93133331,-2.286 0,-1.24178 -0.95955553,-2.25778 -0.95955555,-1.04422 -2.51177775,-1.04422 h -5.108222 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.22222137px;font-family:'Product Sans';-inkscape-font-specification:'Product Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5f6368;fill-opacity:1;stroke-width:0.26458332"
|
||||
id="path9798" />
|
||||
<path
|
||||
d="M 8.6033786,123.04237 H 6.0069342 v -20.20711 h 2.5964444 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.22222137px;font-family:'Product Sans';-inkscape-font-specification:'Product Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5f6368;fill-opacity:1;stroke-width:0.26458332"
|
||||
id="path9800" />
|
||||
<path
|
||||
d="m 12.787764,110.8786 q 2.003778,-2.11667 5.108222,-2.11667 3.104444,0 5.108222,2.11667 2.003778,2.08844 2.003778,5.24933 0,3.16089 -2.003778,5.27755 -2.003778,2.08845 -5.108222,2.08845 -3.104444,0 -5.108222,-2.08845 -2.003778,-2.11666 -2.003778,-5.27755 0,-3.16089 2.003778,-5.24933 z m 1.919111,8.89 q 1.354667,1.35466 3.189111,1.35466 1.834444,0 3.160889,-1.35466 1.354666,-1.38289 1.354666,-3.64067 0,-2.25778 -1.354666,-3.61244 -1.326445,-1.38289 -3.160889,-1.38289 -1.834444,0 -3.189111,1.38289 -1.326445,1.35466 -1.326445,3.61244 0,2.25778 1.326445,3.64067 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.22222137px;font-family:'Product Sans';-inkscape-font-specification:'Product Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5f6368;fill-opacity:1;stroke-width:0.26458332"
|
||||
id="path9802" />
|
||||
<path
|
||||
d="m 33.715864,123.49393 q -3.104445,0 -5.108223,-2.08845 -2.003777,-2.11666 -2.003777,-5.27755 0,-3.16089 2.003777,-5.24933 2.003778,-2.11667 5.108223,-2.11667 2.314222,0 3.838222,1.12889 1.524,1.12889 2.229555,2.85044 l -2.370666,0.98778 q -1.072445,-2.59644 -3.866445,-2.59644 -1.721555,0 -3.048,1.41111 -1.298222,1.41111 -1.298222,3.58422 0,2.17311 1.298222,3.58422 1.326445,1.41111 3.048,1.41111 2.906889,0 4.007556,-2.59644 l 2.314222,0.98778 q -0.705556,1.69333 -2.286,2.85044 -1.552222,1.12889 -3.866444,1.12889 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.22222137px;font-family:'Product Sans';-inkscape-font-specification:'Product Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5f6368;fill-opacity:1;stroke-width:0.26458332"
|
||||
id="path9804" />
|
||||
<path
|
||||
d="m 44.707976,102.83526 v 12.446 l 5.983111,-6.06777 h 3.330222 v 0.11288 l -5.390445,5.39045 5.644445,8.21266 v 0.11289 h -3.132667 l -4.346222,-6.51933 -2.088444,2.08844 v 4.43089 h -2.596445 v -20.20711 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.22222137px;font-family:'Product Sans';-inkscape-font-specification:'Product Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5f6368;fill-opacity:1;stroke-width:0.26458332"
|
||||
id="path9806" />
|
||||
<path
|
||||
d="m 58.322996,123.04237 h -2.596444 v -20.20711 h 2.596444 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.22222137px;font-family:'Product Sans';-inkscape-font-specification:'Product Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5f6368;fill-opacity:1;stroke-width:0.26458332"
|
||||
id="path9808" />
|
||||
<path
|
||||
d="m 65.156299,129.13837 h -2.681111 l 3.217333,-6.97089 -5.700889,-12.95399 h 2.822222 l 4.120445,9.93422 h 0.05644 l 4.007555,-9.93422 h 2.822223 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:28.22222137px;font-family:'Product Sans';-inkscape-font-specification:'Product Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#5f6368;fill-opacity:1;stroke-width:0.26458332"
|
||||
id="path9810" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
BIN
docs/assets/blocks/blocks.png
Normal file
|
After Width: | Height: | Size: 254 KiB |
BIN
docs/assets/blocks/get-position.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/assets/blocks/land.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
docs/assets/blocks/navigate.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
docs/assets/blocks/random-color.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
docs/assets/blocks/save.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
docs/assets/blocks/set-effect.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/assets/blocks/take-off.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
docs/assets/blocks/wait-arrival.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
docs/assets/blocks/wait.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
3865
docs/assets/flight/basic_movements_multicopter.svg
Normal file
|
After Width: | Height: | Size: 408 KiB |
BIN
docs/assets/flight/buzzer.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
docs/assets/flight/buzzer_acb.jpg
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
docs/assets/flight/buzzer_connection.jpg
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/assets/flight/controller_arm.jpg
Normal file
|
After Width: | Height: | Size: 82 KiB |
569
docs/assets/flight/rc_basic_commands.svg
Normal file
@@ -0,0 +1,569 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1417.32 680.31" style="enable-background:new 0 0 1417.32 680.31;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#DD0C29;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#999998;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M1028.08,97.86v-33.6h14.45c3.5,0,6.24,0.91,8.21,2.74c2.02,1.78,3.02,4.13,3.02,7.01
|
||||
c0,2.93-1.01,5.33-3.02,7.2c-1.97,1.87-4.7,2.79-8.21,2.79h-9.17v13.87H1028.08z M1033.36,79.13h8.74c3.98,0,6.34-1.82,6.34-5.04
|
||||
s-2.35-4.99-6.34-4.99h-8.74V79.13z"/>
|
||||
<path class="st0" d="M1059.14,66.8c0-1.87,1.39-3.31,3.26-3.31c1.78,0,3.22,1.44,3.22,3.31c0,1.87-1.44,3.26-3.22,3.26
|
||||
C1060.53,70.06,1059.14,68.67,1059.14,66.8z M1059.81,97.86V74.29h5.18v23.57H1059.81z"/>
|
||||
<path class="st0" d="M1075.27,78.85h-5.04v-4.56h5.04v-6.87h5.19v6.87h7.44v4.56h-7.44v11.09c0,2.69,1.2,3.79,3.7,3.79
|
||||
c1.3,0,2.45-0.29,3.55-0.86v4.46c-1.1,0.77-2.88,1.15-5.23,1.15c-4.42,0-7.2-2.45-7.2-7.06V78.85z"/>
|
||||
<path class="st0" d="M1095.28,94.98c-2.45-2.35-3.7-5.33-3.7-8.98c0-3.6,1.25-6.58,3.7-8.88c2.5-2.3,5.52-3.46,9.07-3.46
|
||||
c2.64,0,5.04,0.53,7.1,1.63v4.46c-2.11-1.01-4.22-1.54-6.34-1.54c-2.35,0-4.32,0.72-5.95,2.21c-1.58,1.49-2.4,3.36-2.4,5.62
|
||||
s0.82,4.18,2.4,5.67c1.63,1.49,3.6,2.21,5.95,2.21c2.5,0,4.75-0.58,6.72-1.78v4.42c-2.26,1.3-4.75,1.92-7.54,1.92
|
||||
C1100.8,98.48,1097.78,97.33,1095.28,94.98z"/>
|
||||
<path class="st0" d="M1123.41,97.86h-5.19v-33.6h5.19v13.15c2.3-2.5,5.18-3.75,8.64-3.75c5.57,0,8.74,3.7,8.74,9.79v14.4h-5.18
|
||||
V84.61c0-2.26-0.53-3.84-1.63-4.75c-1.1-0.91-2.4-1.34-3.89-1.34c-2.64,0-5.33,1.68-6.67,3.84V97.86z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M1270.24,339.94v-33.6h15.31c3.41,0,6.14,0.86,8.11,2.64s2.98,4.08,2.98,6.91c0,4.61-2.69,8.16-7.3,9.27
|
||||
l10.56,14.79h-6.38l-10.13-14.21h-7.87v14.21H1270.24z M1275.52,321.07h9.7c3.84,0,6.1-1.78,6.1-4.99c0-3.07-2.26-4.9-6.1-4.9h-9.7
|
||||
V321.07z"/>
|
||||
<path class="st0" d="M1305.76,336.96c-2.45-2.4-3.65-5.33-3.65-8.83c0-3.46,1.2-6.38,3.65-8.78s5.52-3.6,9.31-3.6
|
||||
c3.74,0,6.82,1.2,9.26,3.6c2.45,2.4,3.65,5.33,3.65,8.78c0,3.46-1.2,6.38-3.65,8.83c-2.45,2.4-5.52,3.6-9.26,3.6
|
||||
C1311.28,340.56,1308.21,339.36,1305.76,336.96z M1320.6,333.75c1.49-1.49,2.21-3.36,2.21-5.62c0-2.21-0.72-4.08-2.21-5.57
|
||||
s-3.31-2.26-5.52-2.26c-2.21,0-4.08,0.77-5.57,2.26c-1.49,1.49-2.21,3.36-2.21,5.57c0,2.26,0.72,4.13,2.21,5.62
|
||||
c1.49,1.49,3.31,2.26,5.57,2.26C1317.28,336,1319.11,335.23,1320.6,333.75z"/>
|
||||
<path class="st0" d="M1333.7,334.37v-28.04h5.19v26.59c0,1.92,0.86,2.88,2.59,2.88c0.72,0,1.39-0.14,1.97-0.48v4.46
|
||||
c-1.01,0.53-2.3,0.77-3.84,0.77C1336.19,340.56,1333.7,338.83,1333.7,334.37z"/>
|
||||
<path class="st0" d="M1348.39,334.37v-28.04h5.18v26.59c0,1.92,0.86,2.88,2.59,2.88c0.72,0,1.39-0.14,1.97-0.48v4.46
|
||||
c-1.01,0.53-2.3,0.77-3.84,0.77C1350.88,340.56,1348.39,338.83,1348.39,334.37z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M87.85,339.94v-15.22l-13.01-18.39h6.14l9.6,13.58l9.6-13.58h5.95l-13.01,18.24v15.36H87.85z"/>
|
||||
<path class="st0" d="M129.03,335.57v3.94c-0.72,0.53-1.73,0.77-3.02,0.77c-2.64,0-4.32-1.1-4.94-3.36
|
||||
c-2.16,2.45-5.04,3.65-8.69,3.65c-2.54,0-4.66-0.72-6.34-2.11c-1.68-1.39-2.5-3.36-2.5-5.81c0-2.5,0.91-4.42,2.74-5.76
|
||||
c1.82-1.39,4.08-2.06,6.72-2.06c2.83,0,5.38,0.62,7.54,1.82v-1.3c0-3.41-2.3-5.14-6.91-5.14c-2.69,0-5.18,0.72-7.44,2.11v-4.56
|
||||
c2.35-1.34,5.18-2.02,8.59-2.02c6.53,0,10.9,3.26,10.9,9.03v8.78c0,1.49,0.82,2.35,1.97,2.35
|
||||
C128.17,335.91,128.6,335.81,129.03,335.57z M120.54,330.38c-1.97-1.1-4.08-1.68-6.29-1.68c-3.46,0-5.52,1.34-5.52,3.65
|
||||
c0,2.5,2.06,3.74,5.09,3.74c2.69,0,5.23-1.25,6.72-2.83V330.38z"/>
|
||||
<path class="st0" d="M139.25,340.13l-8.21-23.76h5.28l5.52,16.03l5.47-16.13h4.27l5.57,16.13l5.47-16.03h5.23l-8.26,23.76h-4.51
|
||||
l-5.71-16.27l-5.66,16.27H139.25z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g id="XMLID_4_">
|
||||
<g>
|
||||
<path d="M666.51,323.52c0,30.75-25.02,55.76-55.77,55.76s-55.76-25.01-55.76-55.76s25.01-55.77,55.76-55.77
|
||||
S666.51,292.77,666.51,323.52z M652.14,342.9v-38.25c0-6.03-4.91-10.93-10.94-10.93h-61.03c-6.04,0-10.94,4.9-10.94,10.93v38.25
|
||||
c0,6.03,4.9,10.94,10.94,10.94h61.03C647.23,353.84,652.14,348.93,652.14,342.9z"/>
|
||||
<path d="M650.78,235.12c1.18,0,2.14,0.96,2.14,2.14c0,1.18-0.96,2.14-2.14,2.14h-7.98c-1.18,0-2.14-0.96-2.14-2.14
|
||||
c0-1.18,0.96-2.14,2.14-2.14H650.78z"/>
|
||||
<path d="M650.78,234.12c1.73,0,3.14,1.41,3.14,3.14c0,0.22-0.02,0.43-0.06,0.63c-0.3,1.43-1.57,2.51-3.08,2.51h-7.98
|
||||
c-1.51,0-2.78-1.08-3.08-2.51c-0.04-0.2-0.06-0.41-0.06-0.63c0-1.73,1.41-3.14,3.14-3.14H650.78z M650.78,239.4
|
||||
c1.18,0,2.14-0.96,2.14-2.14c0-1.18-0.96-2.14-2.14-2.14h-7.98c-1.18,0-2.14,0.96-2.14,2.14c0,1.18,0.96,2.14,2.14,2.14H650.78z"
|
||||
/>
|
||||
<path d="M656.1,236.86c0,5.13-4.18,9.31-9.31,9.31s-9.31-4.18-9.31-9.31c0-5.13,4.18-9.31,9.31-9.31S656.1,231.73,656.1,236.86z
|
||||
M646.79,245.17c4.17,0,7.64-3.09,8.22-7.11c0.06-0.39,0.09-0.79,0.09-1.2c0-4.58-3.73-8.31-8.31-8.31
|
||||
c-4.58,0-8.31,3.73-8.31,8.31c0,0.41,0.03,0.81,0.09,1.2C639.15,242.08,642.62,245.17,646.79,245.17z"/>
|
||||
<path d="M611.32,298.51c13.93,0,25.26,11.34,25.26,25.27c0,13.93-11.33,25.26-25.26,25.26s-25.26-11.33-25.26-25.26
|
||||
C586.06,309.85,597.39,298.51,611.32,298.51z M620.36,323.78c0-4.99-4.06-9.05-9.04-9.05c-4.99,0-9.04,4.06-9.04,9.05
|
||||
c0,4.98,4.05,9.04,9.04,9.04C616.3,332.82,620.36,328.76,620.36,323.78z"/>
|
||||
<path d="M604.46,228.33c1.18,0,2.14,0.96,2.14,2.14c0,1.18-0.96,2.15-2.14,2.15h-7.98c-1.18,0-2.14-0.97-2.14-2.15
|
||||
c0-1.18,0.96-2.14,2.14-2.14H604.46z"/>
|
||||
<path d="M619.36,323.78c0-4.44-3.61-8.05-8.04-8.05c-4.44,0-8.04,3.61-8.04,8.05c0,4.43,3.6,8.04,8.04,8.04
|
||||
C615.75,331.82,619.36,328.21,619.36,323.78z M611.32,314.73c4.98,0,9.04,4.06,9.04,9.05c0,4.98-4.06,9.04-9.04,9.04
|
||||
c-4.99,0-9.04-4.06-9.04-9.04C602.28,318.79,606.33,314.73,611.32,314.73z"/>
|
||||
<path d="M621.85,404.58v-8.91h-26.3v8.91H621.85z M622.85,394.67v10.91h-28.3v-10.91H622.85z"/>
|
||||
<path d="M606.6,230.47c0-1.18-0.96-2.14-2.14-2.14h-7.98c-1.18,0-2.14,0.96-2.14,2.14c0,1.18,0.96,2.15,2.14,2.15h7.98
|
||||
C605.64,232.62,606.6,231.65,606.6,230.47z M604.46,227.33c1.73,0,3.14,1.41,3.14,3.14c0,0.22-0.02,0.43-0.06,0.64
|
||||
c-0.3,1.43-1.57,2.51-3.08,2.51h-7.98c-1.51,0-2.78-1.08-3.08-2.51c-0.04-0.21-0.06-0.42-0.06-0.64c0-1.73,1.41-3.14,3.14-3.14
|
||||
H604.46z"/>
|
||||
<path d="M608.69,231.28c0.06-0.39,0.09-0.8,0.09-1.21c0-4.58-3.73-8.3-8.31-8.3c-4.58,0-8.31,3.72-8.31,8.3
|
||||
c0,0.43,0.03,0.85,0.1,1.26c0.61,3.99,4.06,7.05,8.21,7.05C604.64,238.38,608.1,235.29,608.69,231.28z M609.78,230.07
|
||||
c0,5.14-4.18,9.31-9.31,9.31c-5.13,0-9.31-4.17-9.31-9.31c0-5.13,4.18-9.3,9.31-9.3C605.6,220.77,609.78,224.94,609.78,230.07z"
|
||||
/>
|
||||
<path d="M612.82,509.4v-29.85c0-2.06-1.67-3.73-3.73-3.73h-14.21c-2.06,0-3.74,1.67-3.74,3.73v29.85c0,2.05,1.68,3.73,3.74,3.73
|
||||
h14.21C611.15,513.13,612.82,511.45,612.82,509.4z M613.82,479.55v29.85c0,2.61-2.12,4.73-4.73,4.73h-14.21
|
||||
c-2.61,0-4.74-2.12-4.74-4.73v-29.85c0-2.61,2.13-4.73,4.74-4.73h14.21C611.7,474.82,613.82,476.94,613.82,479.55z"/>
|
||||
<path d="M613.23,452.87l-0.7-1.27h-16.79l-5.09,6.63l0.99,1.61h16.48L613.23,452.87z M613.12,450.6l1.29,2.35l-5.79,7.89h-17.54
|
||||
l-1.65-2.67l5.81-7.57H613.12z"/>
|
||||
<path d="M613.23,429.09l-0.7-1.27h-16.79l-5.09,6.63l0.99,1.61h16.48L613.23,429.09z M613.12,426.82l1.29,2.35l-5.79,7.89h-17.54
|
||||
l-1.65-2.67l5.81-7.57H613.12z"/>
|
||||
<path d="M585.76,112.73l0.99,19.03l-53.35,5.22c-4.6,0.45-9.25,0.34-13.81-0.33l-17.41-2.55l-1.82-21.37H585.76z"/>
|
||||
<path d="M611.32,349.04c13.93,0,25.26-11.33,25.26-25.26c0-13.93-11.33-25.27-25.26-25.27s-25.26,11.34-25.26,25.27
|
||||
C586.06,337.71,597.39,349.04,611.32,349.04z M611.32,297.51c14.48,0,26.26,11.79,26.26,26.27c0,14.48-11.78,26.26-26.26,26.26
|
||||
s-26.26-11.78-26.26-26.26C585.06,309.3,596.84,297.51,611.32,297.51z"/>
|
||||
<path d="M641.2,293.72c6.03,0,10.94,4.9,10.94,10.93v38.25c0,6.03-4.91,10.94-10.94,10.94h-61.03c-6.04,0-10.94-4.91-10.94-10.94
|
||||
v-38.25c0-6.03,4.9-10.93,10.94-10.93H641.2z M651.14,342.9v-38.25c0-5.48-4.46-9.93-9.94-9.93h-29.88h-31.15
|
||||
c-5.48,0-9.94,4.45-9.94,9.93v38.25c0,5.48,4.46,9.94,9.94,9.94h31.15h29.88C646.68,352.84,651.14,348.38,651.14,342.9z"/>
|
||||
<path d="M554.09,323.52c0-31.24,25.42-56.65,56.65-56.65c31.24,0,56.65,25.41,56.65,56.65c0,31.23-25.41,56.65-56.65,56.65
|
||||
C579.51,380.17,554.09,354.75,554.09,323.52z M610.74,267.75c-30.75,0-55.76,25.02-55.76,55.77s25.01,55.76,55.76,55.76
|
||||
s55.77-25.01,55.77-55.76S641.49,267.75,610.74,267.75z"/>
|
||||
<path d="M546.51,323.52c0-35.42,28.82-64.24,64.23-64.24c35.42,0,64.24,28.82,64.24,64.24s-28.82,64.23-64.24,64.23
|
||||
C575.33,387.75,546.51,358.94,546.51,323.52z M610.74,260.28c-34.86,0-63.23,28.37-63.23,63.24c0,34.86,28.37,63.23,63.23,63.23
|
||||
c34.87,0,63.24-28.37,63.24-63.23C673.98,288.65,645.61,260.28,610.74,260.28z"/>
|
||||
<path d="M532.71,345.38v-25.04h-9.19v25.04H532.71z M533.65,319.4v26.92h-11.07V319.4H533.65z"/>
|
||||
<path d="M537.22,203.84c0-6.61-5.38-12-12-12c-6.61,0-11.99,5.39-11.99,12c0,6.62,5.38,12,11.99,12
|
||||
C531.84,215.84,537.22,210.46,537.22,203.84z M525.22,190.9c7.14,0,12.94,5.81,12.94,12.94c0,7.14-5.8,12.94-12.94,12.94
|
||||
c-7.13,0-12.94-5.8-12.94-12.94C512.28,196.71,518.09,190.9,525.22,190.9z"/>
|
||||
<path d="M497.92,365.19v-66.7h-12.74h-12.74v66.7h12.74H497.92z M498.86,297.54v68.6h-13.68h-13.69v-68.6h13.69H498.86z"/>
|
||||
<path d="M468.18,134.1l-17.41,2.55c-4.57,0.67-9.22,0.78-13.81,0.33l-53.35-5.22l0.98-19.03H470L468.18,134.1z"/>
|
||||
<path d="M436.71,319.4h11.07v26.92h-11.07V319.4z M437.65,345.38h9.18v-25.04h-9.18V345.38z"/>
|
||||
<path d="M445.13,191.84c-6.61,0-12,5.39-12,12c0,6.62,5.39,12,12,12c6.62,0,12-5.38,12-12
|
||||
C457.13,197.23,451.75,191.84,445.13,191.84z M432.19,203.84c0-7.13,5.8-12.94,12.94-12.94c7.14,0,12.94,5.81,12.94,12.94
|
||||
c0,7.14-5.8,12.94-12.94,12.94C437.99,216.78,432.19,210.98,432.19,203.84z"/>
|
||||
<path d="M415.38,323.52c0,30.75-25.02,55.76-55.77,55.76s-55.77-25.01-55.77-55.76s25.02-55.77,55.77-55.77
|
||||
S415.38,292.77,415.38,323.52z M401.13,342.9v-38.25c0-6.03-4.91-10.93-10.94-10.93h-61.03c-6.03,0-10.94,4.9-10.94,10.93v38.25
|
||||
c0,6.03,4.91,10.94,10.94,10.94h61.03C396.22,353.84,401.13,348.93,401.13,342.9z"/>
|
||||
<path d="M404.65,511.81h80.53h80.52v-79.59h-80.52h-80.53V511.81z M485.18,512.81h-81.53v-81.59h81.53h81.52v81.59H485.18z"/>
|
||||
<path d="M382.32,109.67c0.36,0,0.7,0.14,0.96,0.41c0.28,0.27,0.41,0.64,0.39,1.03l-4.32,83.59c-0.02,0.28,0.1,0.57,0.3,0.77
|
||||
c0.21,0.2,0.49,0.3,0.78,0.28l19.05-1.47c1.18-0.1,2.33-0.48,3.34-1.12l15.15-9.67c0.43-0.27,0.92-0.44,1.43-0.47l22.45-1.55
|
||||
c0.57-0.04,1.05-0.43,1.19-0.99l0.98-3.65c0.06-0.22,0.25-0.38,0.48-0.39l19.55-0.9c0.92-0.04,1.67-0.76,1.74-1.68l5.53-64.85
|
||||
c0.08-0.93,0.69-1.74,1.57-2.05l12.29-4.43l12.28,4.43c0.88,0.31,1.5,1.12,1.58,2.05l5.52,64.85c0.08,0.92,0.83,1.64,1.75,1.68
|
||||
l19.55,0.9c0.22,0.01,0.42,0.17,0.48,0.39l0.97,3.65c0.15,0.56,0.63,0.95,1.2,0.99l22.45,1.55c0.5,0.03,1,0.2,1.42,0.47
|
||||
l15.16,9.67c1,0.64,2.15,1.02,3.34,1.12l19.04,1.47c0.29,0.02,0.57-0.08,0.78-0.28c0.21-0.2,0.32-0.49,0.3-0.77l-4.32-83.59
|
||||
c-0.02-0.39,0.12-0.76,0.39-1.03c0.27-0.28,0.63-0.42,1.02-0.41l9.53,0.36c0.8,0.03,1.52,0.53,1.82,1.28l11.49,28.41
|
||||
c0.07,0.16,0.12,0.33,0.15,0.49l12.66,57.96c0.14,0.62,0.66,1.1,1.3,1.19l39.52,5.48c1.5,0.21,2.81,1.13,3.53,2.46l20.4,37.99
|
||||
c0.48,0.91,0.74,1.92,0.74,2.95v261.47c0,1.65-0.69,3.26-1.88,4.41l-27.53,26.42c-2.14,2.06-4.96,3.19-7.93,3.19H318.46
|
||||
c-2.97,0-5.79-1.13-7.93-3.19l-27.52-26.42c-1.2-1.15-1.88-2.76-1.88-4.41V248.24c0-1.03,0.25-2.05,0.74-2.95l20.4-37.99
|
||||
c0.71-1.33,2.03-2.25,3.52-2.46l39.53-5.48c0.63-0.09,1.15-0.57,1.29-1.19l12.66-57.96c0.04-0.16,0.09-0.33,0.15-0.49
|
||||
l11.49-28.41c0.3-0.75,1.02-1.25,1.82-1.28l9.53-0.36C382.28,109.67,382.3,109.67,382.32,109.67z M610.74,387.75
|
||||
c35.42,0,64.24-28.81,64.24-64.23s-28.82-64.24-64.24-64.24c-35.41,0-64.23,28.82-64.23,64.24S575.33,387.75,610.74,387.75z
|
||||
M656.1,236.86c0-5.13-4.18-9.31-9.31-9.31s-9.31,4.18-9.31,9.31c0,5.13,4.18,9.31,9.31,9.31S656.1,241.99,656.1,236.86z
|
||||
M622.85,405.58v-10.91h-28.3v10.91H622.85z M614.41,429.17l-1.29-2.35h-17.88l-5.81,7.57l1.65,2.67h17.54L614.41,429.17z
|
||||
M614.41,452.95l-1.29-2.35h-17.88l-5.81,7.57l1.65,2.67h17.54L614.41,452.95z M613.82,509.4v-29.85c0-2.61-2.12-4.73-4.73-4.73
|
||||
h-14.21c-2.61,0-4.74,2.12-4.74,4.73v29.85c0,2.61,2.13,4.73,4.74,4.73h14.21C611.7,514.13,613.82,512.01,613.82,509.4z
|
||||
M609.78,230.07c0-5.13-4.18-9.3-9.31-9.3c-5.13,0-9.31,4.17-9.31,9.3c0,5.14,4.18,9.31,9.31,9.31
|
||||
C605.6,239.38,609.78,235.21,609.78,230.07z M566.7,512.81v-81.59h-81.52h-81.53v81.59h81.53H566.7z M538.16,203.84
|
||||
c0-7.13-5.8-12.94-12.94-12.94c-7.13,0-12.94,5.81-12.94,12.94c0,7.14,5.81,12.94,12.94,12.94
|
||||
C532.36,216.78,538.16,210.98,538.16,203.84z M533.65,346.32V319.4h-11.07v26.92H533.65z M498.86,366.14v-68.6h-13.68h-13.69
|
||||
v68.6h13.69H498.86z M445.13,216.78c7.14,0,12.94-5.8,12.94-12.94c0-7.13-5.8-12.94-12.94-12.94c-7.14,0-12.94,5.81-12.94,12.94
|
||||
C432.19,210.98,437.99,216.78,445.13,216.78z M447.78,346.32V319.4h-11.07v26.92H447.78z M359.61,387.75
|
||||
c35.42,0,64.24-28.81,64.24-64.23s-28.82-64.24-64.24-64.24s-64.24,28.82-64.24,64.24S324.19,387.75,359.61,387.75z
|
||||
M383.29,509.44c0-9.26-7.53-16.79-16.79-16.79s-16.8,7.53-16.8,16.79s7.54,16.8,16.8,16.8S383.29,518.7,383.29,509.44z
|
||||
M379.19,230.07c0-5.13-4.18-9.3-9.31-9.3s-9.3,4.17-9.3,9.3c0,5.14,4.17,9.31,9.3,9.31S379.19,235.21,379.19,230.07z
|
||||
M375.81,405.58v-10.91H347.5v10.91H375.81z M368.37,434.39l-5.81-7.57h-17.88l-1.29,2.35l5.79,7.89h17.54L368.37,434.39z
|
||||
M368.37,458.17l-5.81-7.57h-17.88l-1.29,2.35l5.79,7.89h17.54L368.37,458.17z M332.87,236.86c0-5.13-4.18-9.31-9.31-9.31
|
||||
s-9.3,4.18-9.3,9.31c0,5.13,4.17,9.31,9.3,9.31S332.87,241.99,332.87,236.86z"/>
|
||||
<path d="M373.87,228.33c1.19,0,2.15,0.96,2.15,2.14c0,1.18-0.96,2.15-2.15,2.15h-7.97c-1.18,0-2.15-0.97-2.15-2.15
|
||||
c0-1.18,0.97-2.14,2.15-2.14H373.87z"/>
|
||||
<path d="M366.5,496.51c3.61,0,6.54,2.94,6.54,6.55c0,3.61-2.93,6.55-6.54,6.55c-3.61,0-6.55-2.94-6.55-6.55
|
||||
C359.95,499.45,362.89,496.51,366.5,496.51z"/>
|
||||
<path d="M376.02,230.47c0-1.18-0.96-2.14-2.15-2.14h-7.97c-1.18,0-2.15,0.96-2.15,2.14c0,1.18,0.97,2.15,2.15,2.15h7.97
|
||||
C375.06,232.62,376.02,231.65,376.02,230.47z M377.02,230.47c0,0.22-0.02,0.43-0.06,0.64c-0.3,1.43-1.57,2.51-3.09,2.51h-7.97
|
||||
c-1.52,0-2.79-1.08-3.09-2.51c-0.04-0.21-0.06-0.42-0.06-0.64c0-1.73,1.41-3.14,3.15-3.14h7.97
|
||||
C375.61,227.33,377.02,228.74,377.02,230.47z"/>
|
||||
<path d="M369.88,238.38c4.17,0,7.63-3.09,8.22-7.1c0.06-0.39,0.09-0.8,0.09-1.21c0-4.58-3.73-8.3-8.31-8.3
|
||||
c-4.58,0-8.3,3.72-8.3,8.3c0,0.43,0.03,0.85,0.1,1.26C362.29,235.32,365.73,238.38,369.88,238.38z M369.88,220.77
|
||||
c5.13,0,9.31,4.17,9.31,9.3c0,5.14-4.18,9.31-9.31,9.31s-9.3-4.17-9.3-9.31C360.58,224.94,364.75,220.77,369.88,220.77z"/>
|
||||
<path d="M373.04,503.06c0-3.61-2.93-6.55-6.54-6.55c-3.61,0-6.55,2.94-6.55,6.55c0,3.61,2.94,6.55,6.55,6.55
|
||||
C370.11,509.61,373.04,506.67,373.04,503.06z M366.5,495.51c4.16,0,7.54,3.39,7.54,7.55s-3.38,7.55-7.54,7.55
|
||||
s-7.55-3.39-7.55-7.55S362.34,495.51,366.5,495.51z"/>
|
||||
<path d="M359.04,348.98c4.98,0,9.04-4.06,9.04-9.04c0-4.99-4.06-9.04-9.04-9.04c-4.99,0-9.05,4.05-9.05,9.04
|
||||
C349.99,344.92,354.05,348.98,359.04,348.98z M384.3,323.78c0,13.93-11.33,25.26-25.26,25.26c-13.93,0-25.27-11.33-25.27-25.26
|
||||
c0-13.93,11.34-25.27,25.27-25.27C372.97,298.51,384.3,309.85,384.3,323.78z"/>
|
||||
<path d="M349.7,509.44c0-9.26,7.54-16.79,16.8-16.79s16.79,7.53,16.79,16.79s-7.53,16.8-16.79,16.8S349.7,518.7,349.7,509.44z
|
||||
M366.5,525.24c8.71,0,15.79-7.09,15.79-15.8c0-8.7-7.08-15.79-15.79-15.79s-15.8,7.09-15.8,15.79
|
||||
C350.7,518.15,357.79,525.24,366.5,525.24z"/>
|
||||
<path d="M367.08,339.94c0-4.44-3.61-8.04-8.04-8.04c-4.44,0-8.05,3.6-8.05,8.04c0,4.43,3.61,8.04,8.05,8.04
|
||||
C363.47,347.98,367.08,344.37,367.08,339.94z M368.08,339.94c0,4.98-4.06,9.04-9.04,9.04c-4.99,0-9.05-4.06-9.05-9.04
|
||||
c0-4.99,4.06-9.04,9.05-9.04C364.02,330.9,368.08,334.95,368.08,339.94z"/>
|
||||
<path d="M374.81,404.58v-8.91H348.5v8.91H374.81z M375.81,394.67v10.91H347.5v-10.91H375.81z"/>
|
||||
<path d="M344.58,429.09l5.11,6.97h16.47l1-1.61l-5.09-6.63h-16.8L344.58,429.09z M362.56,426.82l5.81,7.57l-1.65,2.67h-17.54
|
||||
l-5.79-7.89l1.29-2.35H362.56z"/>
|
||||
<path d="M343.39,452.95l1.29-2.35h17.88l5.81,7.57l-1.65,2.67h-17.54L343.39,452.95z M344.58,452.87l5.11,6.97h16.47l1-1.61
|
||||
l-5.09-6.63h-16.8L344.58,452.87z"/>
|
||||
<path d="M359.04,297.51c14.48,0,26.26,11.79,26.26,26.27c0,14.48-11.78,26.26-26.26,26.26c-14.48,0-26.27-11.78-26.27-26.26
|
||||
C332.77,309.3,344.56,297.51,359.04,297.51z M359.04,349.04c13.93,0,25.26-11.33,25.26-25.26c0-13.93-11.33-25.27-25.26-25.27
|
||||
c-13.93,0-25.27,11.34-25.27,25.27C333.77,337.71,345.11,349.04,359.04,349.04z"/>
|
||||
<path d="M327.56,235.12c1.18,0,2.14,0.96,2.14,2.14c0,1.18-0.96,2.14-2.14,2.14h-7.98c-1.18,0-2.15-0.96-2.15-2.14
|
||||
c0-1.18,0.97-2.14,2.15-2.14H327.56z"/>
|
||||
<path d="M329.16,352.84h29.88h31.15c5.48,0,9.94-4.46,9.94-9.94v-38.25c0-5.48-4.46-9.93-9.94-9.93h-31.15h-29.88
|
||||
c-5.48,0-9.94,4.45-9.94,9.93v38.25C319.22,348.38,323.68,352.84,329.16,352.84z M390.19,353.84h-61.03
|
||||
c-6.03,0-10.94-4.91-10.94-10.94v-38.25c0-6.03,4.91-10.93,10.94-10.93h61.03c6.03,0,10.94,4.9,10.94,10.93v38.25
|
||||
C401.13,348.93,396.22,353.84,390.19,353.84z"/>
|
||||
<path d="M330.64,237.89c-0.3,1.43-1.57,2.51-3.08,2.51h-7.98c-1.52,0-2.79-1.08-3.09-2.51c-0.04-0.2-0.06-0.41-0.06-0.63
|
||||
c0-1.73,1.41-3.14,3.15-3.14h7.98c1.73,0,3.14,1.41,3.14,3.14C330.7,237.48,330.68,237.69,330.64,237.89z M327.56,239.4
|
||||
c1.18,0,2.14-0.96,2.14-2.14c0-1.18-0.96-2.14-2.14-2.14h-7.98c-1.18,0-2.15,0.96-2.15,2.14c0,1.18,0.97,2.14,2.15,2.14H327.56z"
|
||||
/>
|
||||
<path d="M323.56,245.17c4.17,0,7.64-3.09,8.22-7.11c0.06-0.39,0.09-0.79,0.09-1.2c0-4.58-3.73-8.31-8.31-8.31s-8.3,3.73-8.3,8.31
|
||||
c0,0.41,0.03,0.81,0.09,1.2C315.93,242.08,319.39,245.17,323.56,245.17z M332.87,236.86c0,5.13-4.18,9.31-9.31,9.31
|
||||
s-9.3-4.18-9.3-9.31c0-5.13,4.17-9.31,9.3-9.31S332.87,231.73,332.87,236.86z"/>
|
||||
<path d="M422.84,323.52c0-34.87-28.36-63.24-63.23-63.24s-63.23,28.37-63.23,63.24c0,34.86,28.36,63.23,63.23,63.23
|
||||
S422.84,358.38,422.84,323.52z M359.61,259.28c35.42,0,64.24,28.82,64.24,64.24s-28.82,64.23-64.24,64.23
|
||||
s-64.24-28.81-64.24-64.23S324.19,259.28,359.61,259.28z"/>
|
||||
<path d="M416.26,323.52c0,31.23-25.41,56.65-56.65,56.65s-56.65-25.42-56.65-56.65c0-31.24,25.41-56.65,56.65-56.65
|
||||
S416.26,292.28,416.26,323.52z M415.38,323.52c0-30.75-25.02-55.77-55.77-55.77s-55.77,25.02-55.77,55.77
|
||||
s25.02,55.76,55.77,55.76S415.38,354.27,415.38,323.52z"/>
|
||||
<path d="M470,112.73h-85.41l-0.98,19.03l53.35,5.22c4.59,0.45,9.24,0.34,13.81-0.33l17.41-2.55L470,112.73z M399.4,193.28
|
||||
c1.02-0.08,2.01-0.41,2.88-0.96l15.15-9.67c0.57-0.37,1.23-0.58,1.9-0.63l22.45-1.55c0.14-0.01,0.26-0.1,0.3-0.24l0.97-3.66
|
||||
c0.17-0.64,0.74-1.1,1.4-1.13l19.55-0.9c0.42-0.02,0.76-0.35,0.8-0.76l3.29-38.65l-17.18,2.51c-2.78,0.41-5.59,0.61-8.4,0.61
|
||||
c-1.89,0-3.77-0.09-5.65-0.27l-53.3-5.22l-3.21,61.99L399.4,193.28z M533.4,136.98l53.35-5.22l-0.99-19.03h-85.4l1.82,21.37
|
||||
l17.41,2.55C524.15,137.32,528.8,137.43,533.4,136.98z M552.92,182.65l15.16,9.67c0.86,0.55,1.86,0.88,2.88,0.96l19.04,1.48
|
||||
l-3.2-62l-53.3,5.22c-1.88,0.18-3.77,0.27-5.65,0.27c-2.81,0-5.63-0.2-8.41-0.61l-17.17-2.51l3.29,38.65
|
||||
c0.03,0.41,0.37,0.74,0.79,0.76l19.55,0.9c0.67,0.03,1.23,0.49,1.4,1.13l0.98,3.66c0.03,0.14,0.15,0.23,0.3,0.24l22.45,1.55
|
||||
C551.7,182.07,552.35,182.28,552.92,182.65z M372.73,110.03c-0.8,0.03-1.52,0.53-1.82,1.28l-11.49,28.41
|
||||
c-0.06,0.16-0.11,0.33-0.15,0.49l-12.66,57.96c-0.14,0.62-0.66,1.1-1.29,1.19l-39.53,5.48c-1.49,0.21-2.81,1.13-3.52,2.46
|
||||
l-20.4,37.99c-0.49,0.9-0.74,1.92-0.74,2.95v261.47c0,1.65,0.68,3.26,1.88,4.41l27.52,26.42c2.14,2.06,4.96,3.19,7.93,3.19
|
||||
h333.43c2.97,0,5.79-1.13,7.93-3.19l27.53-26.42c1.19-1.15,1.88-2.76,1.88-4.41V248.24c0-1.03-0.26-2.04-0.74-2.95l-20.4-37.99
|
||||
c-0.72-1.33-2.03-2.25-3.53-2.46l-39.52-5.48c-0.64-0.09-1.16-0.57-1.3-1.19l-12.66-57.96c-0.03-0.16-0.08-0.33-0.15-0.49
|
||||
l-11.49-28.41c-0.3-0.75-1.02-1.25-1.82-1.28l-9.53-0.36c-0.39-0.01-0.75,0.13-1.02,0.41c-0.27,0.27-0.41,0.64-0.39,1.03
|
||||
L591,194.7c0.02,0.28-0.09,0.57-0.3,0.77c-0.21,0.2-0.49,0.3-0.78,0.28l-19.04-1.47c-1.19-0.1-2.34-0.48-3.34-1.12l-15.16-9.67
|
||||
c-0.42-0.27-0.92-0.44-1.42-0.47l-22.45-1.55c-0.57-0.04-1.05-0.43-1.2-0.99l-0.97-3.65c-0.06-0.22-0.26-0.38-0.48-0.39
|
||||
l-19.55-0.9c-0.92-0.04-1.67-0.76-1.75-1.68l-5.52-64.85c-0.08-0.93-0.7-1.74-1.58-2.05l-12.28-4.43l-12.29,4.43
|
||||
c-0.88,0.31-1.49,1.12-1.57,2.05l-5.53,64.85c-0.07,0.92-0.82,1.64-1.74,1.68l-19.55,0.9c-0.23,0.01-0.42,0.17-0.48,0.39
|
||||
l-0.98,3.65c-0.14,0.56-0.62,0.95-1.19,0.99l-22.45,1.55c-0.51,0.03-1,0.2-1.43,0.47l-15.15,9.67c-1.01,0.64-2.16,1.02-3.34,1.12
|
||||
l-19.05,1.47c-0.29,0.02-0.57-0.08-0.78-0.28c-0.2-0.2-0.32-0.49-0.3-0.77l4.32-83.59c0.02-0.39-0.11-0.76-0.39-1.03
|
||||
c-0.26-0.27-0.6-0.41-0.96-0.41c-0.02,0-0.04,0-0.06,0L372.73,110.03z M369.99,110.93c0.44-1.11,1.51-1.85,2.71-1.9l9.52-0.36
|
||||
c0.66-0.03,1.31,0.23,1.77,0.71c0.47,0.47,0.72,1.12,0.68,1.78l-0.03,0.57h85.44l0.24-2.81c0.11-1.32,0.99-2.45,2.23-2.9
|
||||
l12.63-4.55l12.62,4.55c1.25,0.45,2.12,1.58,2.23,2.9l0.24,2.81h85.44l-0.03-0.57c-0.03-0.66,0.21-1.31,0.68-1.78
|
||||
c0.46-0.48,1.11-0.74,1.77-0.71l9.53,0.36c1.2,0.05,2.26,0.79,2.71,1.9l11.49,28.42c0.08,0.21,0.15,0.43,0.2,0.65l12.66,57.95
|
||||
c0.05,0.22,0.23,0.39,0.45,0.42l39.53,5.48c1.81,0.25,3.4,1.36,4.27,2.97l20.4,38c0.56,1.05,0.86,2.23,0.86,3.42v261.47
|
||||
c0,1.92-0.8,3.8-2.19,5.13l-27.52,26.42c-2.34,2.24-5.4,3.47-8.63,3.47H318.46c-3.23,0-6.29-1.23-8.62-3.47l-27.52-26.42
|
||||
c-1.4-1.33-2.19-3.21-2.19-5.13V248.24c0-1.19,0.29-2.37,0.86-3.42l20.4-38c0.86-1.61,2.46-2.72,4.27-2.97l39.52-5.48
|
||||
c0.22-0.03,0.4-0.2,0.45-0.42L358.29,140c0.05-0.22,0.12-0.44,0.21-0.65L369.99,110.93z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="486.29" y="240.91" class="st1" width="19.02" height="2.2"/>
|
||||
<rect x="486.29" y="263.95" class="st1" width="19.02" height="2.2"/>
|
||||
<rect x="486.29" y="252.37" class="st1" width="19.02" height="2.2"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M471.5,263.91c-5.38,0-9.81-4.1-10.35-9.34h-2.21c0.52,6.47,5.95,11.58,12.55,11.58
|
||||
c6.59,0,12.01-5.1,12.55-11.58h-2.2C481.31,259.81,476.87,263.91,471.5,263.91z"/>
|
||||
<path class="st1" d="M471.5,243.11c5.35,0,9.77,4.06,10.34,9.26h2.21c-0.58-6.42-5.98-11.46-12.54-11.46
|
||||
c-6.55,0-11.95,5.04-12.54,11.46h2.2C461.73,247.17,466.15,243.11,471.5,243.11z"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st1" points="529.24,244.84 529.24,244.84 532.71,240.91 529.77,240.91 521.58,250.2 523.04,251.87 "/>
|
||||
<polygon class="st1" points="520.11,251.86 520.11,251.87 510.45,240.91 507.51,240.91 518.64,253.53 507.51,266.15
|
||||
510.45,266.15 520.11,255.19 520.11,255.19 521.58,253.53 "/>
|
||||
<polygon class="st1" points="521.57,256.86 529.77,266.15 532.71,266.15 523.04,255.19 "/>
|
||||
</g>
|
||||
<path class="st1" d="M439.85,253.47c0-5.74,4.67-10.42,10.42-10.42h6.4v-2.2h-6.52c-6.89,0.08-12.49,5.74-12.49,12.62
|
||||
c0,6.87,5.4,12.41,12.31,12.62h6.75v-2.2h-6.44C444.52,263.89,439.85,259.22,439.85,253.47z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon class="st0" points="373.49,438.57 373.49,396.61 343.95,396.61 343.95,438.57 323.37,438.57 358.72,492.7 394.08,438.57
|
||||
"/>
|
||||
<rect x="343.95" y="376.14" class="st0" width="29.54" height="13.53"/>
|
||||
<rect x="343.95" y="362.44" class="st0" width="29.54" height="6.76"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st0" points="343.95,208.46 343.95,250.42 373.5,250.42 373.5,208.46 394.08,208.46 358.73,154.33 323.37,208.46
|
||||
"/>
|
||||
|
||||
<rect x="343.95" y="257.36" transform="matrix(-1 -1.224647e-16 1.224647e-16 -1 717.4507 528.2437)" class="st0" width="29.54" height="13.53"/>
|
||||
|
||||
<rect x="343.95" y="277.82" transform="matrix(-1 -1.224647e-16 1.224647e-16 -1 717.4507 562.4137)" class="st0" width="29.54" height="6.76"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st0" points="244.2,338.36 286.16,338.36 286.16,308.81 244.2,308.81 244.2,288.23 190.07,323.59 244.2,358.94
|
||||
"/>
|
||||
|
||||
<rect x="285.09" y="316.82" transform="matrix(-1.836970e-16 1 -1 -1.836970e-16 623.4445 23.7255)" class="st0" width="29.54" height="13.53"/>
|
||||
|
||||
<rect x="302.17" y="320.2" transform="matrix(-1.836970e-16 1 -1 -1.836970e-16 640.5295 6.6405)" class="st0" width="29.54" height="6.76"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st0" points="473.71,308.82 431.75,308.82 431.75,338.36 473.71,338.36 473.71,358.94 527.84,323.59
|
||||
473.71,288.23 "/>
|
||||
|
||||
<rect x="403.28" y="316.82" transform="matrix(6.123234e-17 -1 1 6.123234e-17 94.4599 741.6376)" class="st0" width="29.54" height="13.53"/>
|
||||
|
||||
<rect x="386.19" y="320.21" transform="matrix(6.123234e-17 -1 1 6.123234e-17 77.3748 724.5526)" class="st0" width="29.54" height="6.76"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g id="XMLID_5_">
|
||||
<g>
|
||||
<path d="M1163.1,248.24v261.47c0,1.92-0.8,3.8-2.19,5.13l-27.52,26.42c-2.34,2.24-5.4,3.47-8.63,3.47H791.33
|
||||
c-3.23,0-6.29-1.23-8.62-3.47l-27.52-26.42c-1.4-1.33-2.19-3.21-2.19-5.13V248.24c0-1.19,0.29-2.37,0.86-3.42l20.4-38
|
||||
c0.86-1.61,2.46-2.72,4.27-2.97l39.52-5.48c0.22-0.03,0.4-0.2,0.45-0.42L831.16,140c0.05-0.22,0.12-0.44,0.21-0.65l11.49-28.42
|
||||
c0.44-1.11,1.51-1.85,2.71-1.9l9.52-0.36c0.66-0.03,1.31,0.23,1.77,0.71c0.47,0.47,0.72,1.12,0.68,1.78l-0.03,0.57h85.44
|
||||
l0.24-2.81c0.11-1.32,0.99-2.45,2.23-2.9l12.63-4.55l12.62,4.55c1.25,0.45,2.12,1.58,2.23,2.9l0.24,2.81h85.44l-0.03-0.57
|
||||
c-0.03-0.66,0.21-1.31,0.68-1.78c0.46-0.48,1.11-0.74,1.77-0.71l9.53,0.36c1.2,0.05,2.26,0.79,2.71,1.9l11.49,28.42
|
||||
c0.08,0.21,0.15,0.43,0.2,0.65l12.66,57.95c0.05,0.22,0.23,0.39,0.45,0.42l39.53,5.48c1.81,0.25,3.4,1.36,4.27,2.97l20.4,38
|
||||
C1162.8,245.87,1163.1,247.05,1163.1,248.24z M1162.1,509.71V248.24c0-1.03-0.26-2.04-0.74-2.95l-20.4-37.99
|
||||
c-0.72-1.33-2.03-2.25-3.53-2.46l-39.52-5.48c-0.64-0.09-1.16-0.57-1.3-1.19l-12.66-57.96c-0.03-0.16-0.08-0.33-0.15-0.49
|
||||
l-11.49-28.41c-0.3-0.75-1.02-1.25-1.82-1.28l-9.53-0.36c-0.39-0.01-0.75,0.13-1.02,0.41c-0.27,0.27-0.41,0.64-0.39,1.03
|
||||
l4.32,83.59c0.02,0.28-0.09,0.57-0.3,0.77c-0.21,0.2-0.49,0.3-0.78,0.28l-19.04-1.47c-1.19-0.1-2.34-0.48-3.34-1.12l-15.16-9.67
|
||||
c-0.42-0.27-0.92-0.44-1.42-0.47l-22.45-1.55c-0.57-0.04-1.05-0.43-1.2-0.99l-0.97-3.65c-0.06-0.22-0.26-0.38-0.48-0.39
|
||||
l-19.55-0.9c-0.92-0.04-1.67-0.76-1.75-1.68l-5.52-64.85c-0.08-0.93-0.7-1.74-1.58-2.05l-12.28-4.43l-12.29,4.43
|
||||
c-0.88,0.31-1.49,1.12-1.57,2.05l-5.53,64.85c-0.07,0.92-0.82,1.64-1.74,1.68l-19.55,0.9c-0.23,0.01-0.42,0.17-0.48,0.39
|
||||
l-0.98,3.65c-0.14,0.56-0.62,0.95-1.19,0.99l-22.45,1.55c-0.51,0.03-1,0.2-1.43,0.47l-15.15,9.67c-1.01,0.64-2.16,1.02-3.34,1.12
|
||||
l-19.05,1.47c-0.29,0.02-0.57-0.08-0.78-0.28c-0.2-0.2-0.32-0.49-0.3-0.77l4.32-83.59c0.02-0.39-0.11-0.76-0.39-1.03
|
||||
c-0.26-0.27-0.6-0.41-0.96-0.41c-0.02,0-0.04,0-0.06,0l-9.53,0.36c-0.8,0.03-1.52,0.53-1.82,1.28l-11.49,28.41
|
||||
c-0.06,0.16-0.11,0.33-0.15,0.49l-12.66,57.96c-0.14,0.62-0.66,1.1-1.29,1.19l-39.53,5.48c-1.49,0.21-2.81,1.13-3.52,2.46
|
||||
l-20.4,37.99c-0.49,0.9-0.74,1.92-0.74,2.95v261.47c0,1.65,0.68,3.26,1.88,4.41l27.52,26.42c2.14,2.06,4.96,3.19,7.93,3.19
|
||||
h333.43c2.97,0,5.79-1.13,7.93-3.19l27.53-26.42C1161.41,512.97,1162.1,511.36,1162.1,509.71z M1062.87,194.76l-3.2-62
|
||||
l-53.3,5.22c-1.88,0.18-3.77,0.27-5.65,0.27c-2.81,0-5.63-0.2-8.41-0.61l-17.17-2.51l3.29,38.65c0.03,0.41,0.37,0.74,0.79,0.76
|
||||
l19.55,0.9c0.67,0.03,1.23,0.49,1.4,1.13l0.98,3.66c0.03,0.14,0.15,0.23,0.3,0.24l22.45,1.55c0.67,0.05,1.32,0.26,1.89,0.63
|
||||
l15.16,9.67c0.86,0.55,1.86,0.88,2.88,0.96L1062.87,194.76z M1059.62,131.76l-0.99-19.03h-85.4l1.82,21.37l17.41,2.55
|
||||
c4.56,0.67,9.21,0.78,13.81,0.33L1059.62,131.76z M941.05,134.1l1.82-21.37h-85.41l-0.98,19.03l53.35,5.22
|
||||
c4.59,0.45,9.24,0.34,13.81-0.33L941.05,134.1z M937.67,173.78l3.29-38.65l-17.18,2.51c-2.78,0.41-5.59,0.61-8.4,0.61
|
||||
c-1.89,0-3.77-0.09-5.65-0.27l-53.3-5.22l-3.21,61.99l19.05-1.47c1.02-0.08,2.01-0.41,2.88-0.96l15.15-9.67
|
||||
c0.57-0.37,1.23-0.58,1.9-0.63l22.45-1.55c0.14-0.01,0.26-0.1,0.3-0.24l0.97-3.66c0.17-0.64,0.74-1.1,1.4-1.13l19.55-0.9
|
||||
C937.29,174.52,937.63,174.19,937.67,173.78z"/>
|
||||
<path d="M1162.1,248.24v261.47c0,1.65-0.69,3.26-1.88,4.41l-27.53,26.42c-2.14,2.06-4.96,3.19-7.93,3.19H791.33
|
||||
c-2.97,0-5.79-1.13-7.93-3.19l-27.52-26.42c-1.2-1.15-1.88-2.76-1.88-4.41V248.24c0-1.03,0.25-2.05,0.74-2.95l20.4-37.99
|
||||
c0.71-1.33,2.03-2.25,3.52-2.46l39.53-5.48c0.63-0.09,1.15-0.57,1.29-1.19l12.66-57.96c0.04-0.16,0.09-0.33,0.15-0.49
|
||||
l11.49-28.41c0.3-0.75,1.02-1.25,1.82-1.28l9.53-0.36c0.02,0,0.04,0,0.06,0c0.36,0,0.7,0.14,0.96,0.41
|
||||
c0.28,0.27,0.41,0.64,0.39,1.03l-4.32,83.59c-0.02,0.28,0.1,0.57,0.3,0.77c0.21,0.2,0.49,0.3,0.78,0.28l19.05-1.47
|
||||
c1.18-0.1,2.33-0.48,3.34-1.12l15.15-9.67c0.43-0.27,0.92-0.44,1.43-0.47l22.45-1.55c0.57-0.04,1.05-0.43,1.19-0.99l0.98-3.65
|
||||
c0.06-0.22,0.25-0.38,0.48-0.39l19.55-0.9c0.92-0.04,1.67-0.76,1.74-1.68l5.53-64.85c0.08-0.93,0.69-1.74,1.57-2.05l12.29-4.43
|
||||
l12.28,4.43c0.88,0.31,1.5,1.12,1.58,2.05l5.52,64.85c0.08,0.92,0.83,1.64,1.75,1.68l19.55,0.9c0.22,0.01,0.42,0.17,0.48,0.39
|
||||
l0.97,3.65c0.15,0.56,0.63,0.95,1.2,0.99l22.45,1.55c0.5,0.03,1,0.2,1.42,0.47l15.16,9.67c1,0.64,2.15,1.02,3.34,1.12l19.04,1.47
|
||||
c0.29,0.02,0.57-0.08,0.78-0.28c0.21-0.2,0.32-0.49,0.3-0.77l-4.32-83.59c-0.02-0.39,0.12-0.76,0.39-1.03
|
||||
c0.27-0.28,0.63-0.42,1.02-0.41l9.53,0.36c0.8,0.03,1.52,0.53,1.82,1.28l11.49,28.41c0.07,0.16,0.12,0.33,0.15,0.49l12.66,57.96
|
||||
c0.14,0.62,0.66,1.1,1.3,1.19l39.52,5.48c1.5,0.21,2.81,1.13,3.53,2.46l20.4,37.99C1161.84,246.2,1162.1,247.21,1162.1,248.24z
|
||||
M1147.85,323.52c0-35.42-28.82-64.24-64.24-64.24c-35.41,0-64.23,28.82-64.23,64.24s28.82,64.23,64.23,64.23
|
||||
C1119.03,387.75,1147.85,358.94,1147.85,323.52z M1128.97,236.86c0-5.13-4.18-9.31-9.31-9.31s-9.31,4.18-9.31,9.31
|
||||
c0,5.13,4.18,9.31,9.31,9.31S1128.97,241.99,1128.97,236.86z M1095.72,405.58v-10.91h-28.3v10.91H1095.72z M1087.28,429.17
|
||||
l-1.29-2.35h-17.88l-5.81,7.57l1.65,2.67h17.54L1087.28,429.17z M1087.28,452.95l-1.29-2.35h-17.88l-5.81,7.57l1.65,2.67h17.54
|
||||
L1087.28,452.95z M1086.69,509.4v-29.85c0-2.61-2.12-4.73-4.73-4.73h-14.21c-2.61,0-4.74,2.12-4.74,4.73v29.85
|
||||
c0,2.61,2.13,4.73,4.74,4.73h14.21C1084.57,514.13,1086.69,512.01,1086.69,509.4z M1082.65,230.07c0-5.13-4.18-9.3-9.31-9.3
|
||||
c-5.13,0-9.31,4.17-9.31,9.3c0,5.14,4.18,9.31,9.31,9.31C1078.47,239.38,1082.65,235.21,1082.65,230.07z M1039.57,512.81v-81.59
|
||||
h-81.52h-81.53v81.59h81.53H1039.57z M1011.03,203.84c0-7.13-5.8-12.94-12.94-12.94c-7.13,0-12.94,5.81-12.94,12.94
|
||||
c0,7.14,5.81,12.94,12.94,12.94C1005.23,216.78,1011.03,210.98,1011.03,203.84z M1006.52,346.32V319.4h-11.07v26.92H1006.52z
|
||||
M971.73,366.14v-68.6h-13.68h-13.69v68.6h13.69H971.73z M930.94,203.84c0-7.13-5.8-12.94-12.94-12.94
|
||||
c-7.14,0-12.94,5.81-12.94,12.94c0,7.14,5.8,12.94,12.94,12.94C925.14,216.78,930.94,210.98,930.94,203.84z M920.65,346.32V319.4
|
||||
h-11.07v26.92H920.65z M896.72,323.52c0-35.42-28.82-64.24-64.24-64.24c-35.42,0-64.24,28.82-64.24,64.24
|
||||
s28.82,64.23,64.24,64.23C867.9,387.75,896.72,358.94,896.72,323.52z M856.16,509.44c0-9.26-7.53-16.79-16.79-16.79
|
||||
c-9.26,0-16.8,7.53-16.8,16.79s7.54,16.8,16.8,16.8C848.63,526.24,856.16,518.7,856.16,509.44z M852.06,230.07
|
||||
c0-5.13-4.18-9.3-9.31-9.3c-5.13,0-9.3,4.17-9.3,9.3c0,5.14,4.17,9.31,9.3,9.31C847.88,239.38,852.06,235.21,852.06,230.07z
|
||||
M848.68,405.58v-10.91h-28.31v10.91H848.68z M841.24,434.39l-5.81-7.57h-17.88l-1.29,2.35l5.79,7.89h17.54L841.24,434.39z
|
||||
M841.24,458.17l-5.81-7.57h-17.88l-1.29,2.35l5.79,7.89h17.54L841.24,458.17z M805.74,236.86c0-5.13-4.18-9.31-9.31-9.31
|
||||
c-5.13,0-9.3,4.18-9.3,9.31c0,5.13,4.17,9.31,9.3,9.31C801.56,246.17,805.74,241.99,805.74,236.86z"/>
|
||||
<path d="M1083.61,259.28c35.42,0,64.24,28.82,64.24,64.24s-28.82,64.23-64.24,64.23c-35.41,0-64.23-28.81-64.23-64.23
|
||||
S1048.2,259.28,1083.61,259.28z M1146.85,323.52c0-34.87-28.37-63.24-63.24-63.24c-34.86,0-63.23,28.37-63.23,63.24
|
||||
c0,34.86,28.37,63.23,63.23,63.23C1118.48,386.75,1146.85,358.38,1146.85,323.52z"/>
|
||||
<path d="M1126.79,237.26c0,0.22-0.02,0.43-0.06,0.63c-0.3,1.43-1.57,2.51-3.08,2.51h-7.98c-1.51,0-2.78-1.08-3.08-2.51
|
||||
c-0.04-0.2-0.06-0.41-0.06-0.63c0-1.73,1.41-3.14,3.14-3.14h7.98C1125.38,234.12,1126.79,235.53,1126.79,237.26z M1125.79,237.26
|
||||
c0-1.18-0.96-2.14-2.14-2.14h-7.98c-1.18,0-2.14,0.96-2.14,2.14c0,1.18,0.96,2.14,2.14,2.14h7.98
|
||||
C1124.83,239.4,1125.79,238.44,1125.79,237.26z"/>
|
||||
<path d="M1119.66,227.55c5.13,0,9.31,4.18,9.31,9.31c0,5.13-4.18,9.31-9.31,9.31s-9.31-4.18-9.31-9.31
|
||||
C1110.35,231.73,1114.53,227.55,1119.66,227.55z M1127.88,238.06c0.06-0.39,0.09-0.79,0.09-1.2c0-4.58-3.73-8.31-8.31-8.31
|
||||
s-8.31,3.73-8.31,8.31c0,0.41,0.03,0.81,0.09,1.2c0.58,4.02,4.05,7.11,8.22,7.11S1127.3,242.08,1127.88,238.06z"/>
|
||||
<path d="M1123.65,235.12c1.18,0,2.14,0.96,2.14,2.14c0,1.18-0.96,2.14-2.14,2.14h-7.98c-1.18,0-2.14-0.96-2.14-2.14
|
||||
c0-1.18,0.96-2.14,2.14-2.14H1123.65z"/>
|
||||
<path d="M1125.01,304.65v38.25c0,6.03-4.91,10.94-10.94,10.94h-61.03c-6.04,0-10.94-4.91-10.94-10.94v-38.25
|
||||
c0-6.03,4.9-10.93,10.94-10.93h61.03C1120.1,293.72,1125.01,298.62,1125.01,304.65z M1124.01,342.9v-38.25
|
||||
c0-5.48-4.46-9.93-9.94-9.93h-29.88h-31.15c-5.48,0-9.94,4.45-9.94,9.93v38.25c0,5.48,4.46,9.94,9.94,9.94h31.15h29.88
|
||||
C1119.55,352.84,1124.01,348.38,1124.01,342.9z"/>
|
||||
<path d="M1083.61,266.87c31.24,0,56.65,25.41,56.65,56.65c0,31.23-25.41,56.65-56.65,56.65c-31.23,0-56.65-25.42-56.65-56.65
|
||||
C1026.96,292.28,1052.38,266.87,1083.61,266.87z M1139.38,323.52c0-30.75-25.02-55.77-55.77-55.77s-55.76,25.02-55.76,55.77
|
||||
s25.01,55.76,55.76,55.76S1139.38,354.27,1139.38,323.52z"/>
|
||||
<path d="M1083.61,267.75c30.75,0,55.77,25.02,55.77,55.77s-25.02,55.76-55.77,55.76s-55.76-25.01-55.76-55.76
|
||||
S1052.86,267.75,1083.61,267.75z M1125.01,342.9v-38.25c0-6.03-4.91-10.93-10.94-10.93h-61.03c-6.04,0-10.94,4.9-10.94,10.93
|
||||
v38.25c0,6.03,4.9,10.94,10.94,10.94h61.03C1120.1,353.84,1125.01,348.93,1125.01,342.9z"/>
|
||||
<path d="M1084.19,297.51c14.48,0,26.26,11.79,26.26,26.27c0,14.48-11.78,26.26-26.26,26.26s-26.26-11.78-26.26-26.26
|
||||
C1057.93,309.3,1069.71,297.51,1084.19,297.51z M1109.45,323.78c0-13.93-11.33-25.27-25.26-25.27
|
||||
c-13.93,0-25.26,11.34-25.26,25.27c0,13.93,11.33,25.26,25.26,25.26C1098.12,349.04,1109.45,337.71,1109.45,323.78z"/>
|
||||
<path d="M1084.19,298.51c13.93,0,25.26,11.34,25.26,25.27c0,13.93-11.33,25.26-25.26,25.26c-13.93,0-25.26-11.33-25.26-25.26
|
||||
C1058.93,309.85,1070.26,298.51,1084.19,298.51z M1093.23,323.78c0-4.99-4.06-9.05-9.04-9.05c-4.99,0-9.04,4.06-9.04,9.05
|
||||
c0,4.98,4.05,9.04,9.04,9.04C1089.17,332.82,1093.23,328.76,1093.23,323.78z"/>
|
||||
<path d="M1095.72,394.67v10.91h-28.3v-10.91H1095.72z M1094.72,404.58v-8.91h-26.3v8.91H1094.72z"/>
|
||||
<path d="M1084.19,314.73c4.98,0,9.04,4.06,9.04,9.05c0,4.98-4.06,9.04-9.04,9.04c-4.99,0-9.04-4.06-9.04-9.04
|
||||
C1075.15,318.79,1079.2,314.73,1084.19,314.73z M1092.23,323.78c0-4.44-3.61-8.05-8.04-8.05c-4.44,0-8.04,3.61-8.04,8.05
|
||||
c0,4.43,3.6,8.04,8.04,8.04C1088.62,331.82,1092.23,328.21,1092.23,323.78z"/>
|
||||
<path d="M1085.99,426.82l1.29,2.35l-5.79,7.89h-17.54l-1.65-2.67l5.81-7.57H1085.99z M1086.1,429.09l-0.7-1.27h-16.79l-5.09,6.63
|
||||
l0.99,1.61h16.48L1086.1,429.09z"/>
|
||||
<path d="M1085.99,450.6l1.29,2.35l-5.79,7.89h-17.54l-1.65-2.67l5.81-7.57H1085.99z M1086.1,452.87l-0.7-1.27h-16.79l-5.09,6.63
|
||||
l0.99,1.61h16.48L1086.1,452.87z"/>
|
||||
<path d="M1086.69,479.55v29.85c0,2.61-2.12,4.73-4.73,4.73h-14.21c-2.61,0-4.74-2.12-4.74-4.73v-29.85
|
||||
c0-2.61,2.13-4.73,4.74-4.73h14.21C1084.57,474.82,1086.69,476.94,1086.69,479.55z M1085.69,509.4v-29.85
|
||||
c0-2.06-1.67-3.73-3.73-3.73h-14.21c-2.06,0-3.74,1.67-3.74,3.73v29.85c0,2.05,1.68,3.73,3.74,3.73h14.21
|
||||
C1084.02,513.13,1085.69,511.45,1085.69,509.4z"/>
|
||||
<path d="M1080.47,230.47c0,0.22-0.02,0.43-0.06,0.64c-0.3,1.43-1.57,2.51-3.08,2.51h-7.98c-1.51,0-2.78-1.08-3.08-2.51
|
||||
c-0.04-0.21-0.06-0.42-0.06-0.64c0-1.73,1.41-3.14,3.14-3.14h7.98C1079.06,227.33,1080.47,228.74,1080.47,230.47z
|
||||
M1079.47,230.47c0-1.18-0.96-2.14-2.14-2.14h-7.98c-1.18,0-2.14,0.96-2.14,2.14c0,1.18,0.96,2.15,2.14,2.15h7.98
|
||||
C1078.51,232.62,1079.47,231.65,1079.47,230.47z"/>
|
||||
<path d="M1073.34,220.77c5.13,0,9.31,4.17,9.31,9.3c0,5.14-4.18,9.31-9.31,9.31c-5.13,0-9.31-4.17-9.31-9.31
|
||||
C1064.03,224.94,1068.21,220.77,1073.34,220.77z M1081.56,231.28c0.06-0.39,0.09-0.8,0.09-1.21c0-4.58-3.73-8.3-8.31-8.3
|
||||
c-4.58,0-8.31,3.72-8.31,8.3c0,0.43,0.03,0.85,0.1,1.26c0.61,3.99,4.06,7.05,8.21,7.05
|
||||
C1077.51,238.38,1080.97,235.29,1081.56,231.28z"/>
|
||||
<path d="M1077.33,228.33c1.18,0,2.14,0.96,2.14,2.14c0,1.18-0.96,2.15-2.14,2.15h-7.98c-1.18,0-2.14-0.97-2.14-2.15
|
||||
c0-1.18,0.96-2.14,2.14-2.14H1077.33z"/>
|
||||
<path d="M1058.63,112.73l0.99,19.03l-53.35,5.22c-4.6,0.45-9.25,0.34-13.81-0.33l-17.41-2.55l-1.82-21.37H1058.63z"/>
|
||||
<path d="M1039.57,431.22v81.59h-81.52h-81.53v-81.59h81.53H1039.57z M1038.57,511.81v-79.59h-80.52h-80.53v79.59h80.53H1038.57z"
|
||||
/>
|
||||
<path d="M998.09,190.9c7.14,0,12.94,5.81,12.94,12.94c0,7.14-5.8,12.94-12.94,12.94c-7.13,0-12.94-5.8-12.94-12.94
|
||||
C985.15,196.71,990.96,190.9,998.09,190.9z M1010.09,203.84c0-6.61-5.38-12-12-12c-6.61,0-11.99,5.39-11.99,12
|
||||
c0,6.62,5.38,12,11.99,12C1004.71,215.84,1010.09,210.46,1010.09,203.84z"/>
|
||||
<path d="M1006.52,319.4v26.92h-11.07V319.4H1006.52z M1005.58,345.38v-25.04h-9.19v25.04H1005.58z"/>
|
||||
<path d="M971.73,297.54v68.6h-13.68h-13.69v-68.6h13.69H971.73z M970.79,365.19v-66.7h-12.74h-12.74v66.7h12.74H970.79z"/>
|
||||
<path d="M942.87,112.73l-1.82,21.37l-17.41,2.55c-4.57,0.67-9.22,0.78-13.81,0.33l-53.35-5.22l0.98-19.03H942.87z"/>
|
||||
<path d="M918,190.9c7.14,0,12.94,5.81,12.94,12.94c0,7.14-5.8,12.94-12.94,12.94c-7.14,0-12.94-5.8-12.94-12.94
|
||||
C905.06,196.71,910.86,190.9,918,190.9z M930,203.84c0-6.61-5.38-12-12-12c-6.61,0-12,5.39-12,12c0,6.62,5.39,12,12,12
|
||||
C924.62,215.84,930,210.46,930,203.84z"/>
|
||||
<path d="M920.65,319.4v26.92h-11.07V319.4H920.65z M919.7,345.38v-25.04h-9.18v25.04H919.7z"/>
|
||||
<path d="M832.48,259.28c35.42,0,64.24,28.82,64.24,64.24s-28.82,64.23-64.24,64.23c-35.42,0-64.24-28.81-64.24-64.23
|
||||
S797.06,259.28,832.48,259.28z M895.71,323.52c0-34.87-28.36-63.24-63.23-63.24s-63.23,28.37-63.23,63.24
|
||||
c0,34.86,28.36,63.23,63.23,63.23S895.71,358.38,895.71,323.52z"/>
|
||||
<path d="M874,304.65v38.25c0,6.03-4.91,10.94-10.94,10.94h-61.03c-6.03,0-10.94-4.91-10.94-10.94v-38.25
|
||||
c0-6.03,4.91-10.93,10.94-10.93h61.03C869.09,293.72,874,298.62,874,304.65z M873,342.9v-38.25c0-5.48-4.46-9.93-9.94-9.93
|
||||
h-31.15h-29.88c-5.48,0-9.94,4.45-9.94,9.93v38.25c0,5.48,4.46,9.94,9.94,9.94h29.88h31.15C868.54,352.84,873,348.38,873,342.9z"
|
||||
/>
|
||||
<path d="M832.48,266.87c31.24,0,56.65,25.41,56.65,56.65c0,31.23-25.41,56.65-56.65,56.65s-56.65-25.42-56.65-56.65
|
||||
C775.83,292.28,801.24,266.87,832.48,266.87z M888.25,323.52c0-30.75-25.02-55.77-55.77-55.77s-55.77,25.02-55.77,55.77
|
||||
s25.02,55.76,55.77,55.76S888.25,354.27,888.25,323.52z"/>
|
||||
<path d="M832.48,267.75c30.75,0,55.77,25.02,55.77,55.77s-25.02,55.76-55.77,55.76s-55.77-25.01-55.77-55.76
|
||||
S801.73,267.75,832.48,267.75z M874,342.9v-38.25c0-6.03-4.91-10.93-10.94-10.93h-61.03c-6.03,0-10.94,4.9-10.94,10.93v38.25
|
||||
c0,6.03,4.91,10.94,10.94,10.94h61.03C869.09,353.84,874,348.93,874,342.9z"/>
|
||||
<path d="M839.37,492.65c9.26,0,16.79,7.53,16.79,16.79s-7.53,16.8-16.79,16.8c-9.26,0-16.8-7.54-16.8-16.8
|
||||
S830.11,492.65,839.37,492.65z M855.16,509.44c0-8.7-7.08-15.79-15.79-15.79c-8.71,0-15.8,7.09-15.8,15.79
|
||||
c0,8.71,7.09,15.8,15.8,15.8C848.08,525.24,855.16,518.15,855.16,509.44z"/>
|
||||
<path d="M831.91,297.51c14.48,0,26.26,11.79,26.26,26.27c0,14.48-11.78,26.26-26.26,26.26s-26.27-11.78-26.27-26.26
|
||||
C805.64,309.3,817.43,297.51,831.91,297.51z M857.17,323.78c0-13.93-11.33-25.27-25.26-25.27s-25.27,11.34-25.27,25.27
|
||||
c0,13.93,11.34,25.26,25.27,25.26S857.17,337.71,857.17,323.78z"/>
|
||||
<path d="M831.91,298.51c13.93,0,25.26,11.34,25.26,25.27c0,13.93-11.33,25.26-25.26,25.26s-25.27-11.33-25.27-25.26
|
||||
C806.64,309.85,817.98,298.51,831.91,298.51z M840.95,339.94c0-4.99-4.06-9.04-9.04-9.04c-4.99,0-9.05,4.05-9.05,9.04
|
||||
c0,4.98,4.06,9.04,9.05,9.04C836.89,348.98,840.95,344.92,840.95,339.94z"/>
|
||||
<path d="M849.89,230.47c0,0.22-0.02,0.43-0.06,0.64c-0.3,1.43-1.57,2.51-3.09,2.51h-7.97c-1.52,0-2.79-1.08-3.09-2.51
|
||||
c-0.04-0.21-0.06-0.42-0.06-0.64c0-1.73,1.41-3.14,3.15-3.14h7.97C848.48,227.33,849.89,228.74,849.89,230.47z M848.89,230.47
|
||||
c0-1.18-0.96-2.14-2.15-2.14h-7.97c-1.18,0-2.15,0.96-2.15,2.14c0,1.18,0.97,2.15,2.15,2.15h7.97
|
||||
C847.93,232.62,848.89,231.65,848.89,230.47z"/>
|
||||
<path d="M842.75,220.77c5.13,0,9.31,4.17,9.31,9.3c0,5.14-4.18,9.31-9.31,9.31c-5.13,0-9.3-4.17-9.3-9.31
|
||||
C833.45,224.94,837.62,220.77,842.75,220.77z M850.97,231.28c0.06-0.39,0.09-0.8,0.09-1.21c0-4.58-3.73-8.3-8.31-8.3
|
||||
c-4.58,0-8.3,3.72-8.3,8.3c0,0.43,0.03,0.85,0.1,1.26c0.61,3.99,4.05,7.05,8.2,7.05C846.92,238.38,850.38,235.29,850.97,231.28z"
|
||||
/>
|
||||
<path d="M848.68,394.67v10.91h-28.31v-10.91H848.68z M847.68,404.58v-8.91h-26.31v8.91H847.68z"/>
|
||||
<path d="M846.74,228.33c1.19,0,2.15,0.96,2.15,2.14c0,1.18-0.96,2.15-2.15,2.15h-7.97c-1.18,0-2.15-0.97-2.15-2.15
|
||||
c0-1.18,0.97-2.14,2.15-2.14H846.74z"/>
|
||||
<path d="M839.37,495.51c4.16,0,7.54,3.39,7.54,7.55s-3.38,7.55-7.54,7.55c-4.16,0-7.55-3.39-7.55-7.55
|
||||
S835.21,495.51,839.37,495.51z M845.91,503.06c0-3.61-2.93-6.55-6.54-6.55c-3.61,0-6.55,2.94-6.55,6.55
|
||||
c0,3.61,2.94,6.55,6.55,6.55C842.98,509.61,845.91,506.67,845.91,503.06z"/>
|
||||
<path d="M839.37,496.51c3.61,0,6.54,2.94,6.54,6.55c0,3.61-2.93,6.55-6.54,6.55c-3.61,0-6.55-2.94-6.55-6.55
|
||||
C832.82,499.45,835.76,496.51,839.37,496.51z"/>
|
||||
<path d="M835.43,426.82l5.81,7.57l-1.65,2.67h-17.54l-5.79-7.89l1.29-2.35H835.43z M840.03,434.45l-5.09-6.63h-16.8l-0.69,1.27
|
||||
l5.11,6.97h16.47L840.03,434.45z"/>
|
||||
<path d="M835.43,450.6l5.81,7.57l-1.65,2.67h-17.54l-5.79-7.89l1.29-2.35H835.43z M840.03,458.23l-5.09-6.63h-16.8l-0.69,1.27
|
||||
l5.11,6.97h16.47L840.03,458.23z"/>
|
||||
<path d="M831.91,330.9c4.98,0,9.04,4.05,9.04,9.04c0,4.98-4.06,9.04-9.04,9.04c-4.99,0-9.05-4.06-9.05-9.04
|
||||
C822.86,334.95,826.92,330.9,831.91,330.9z M839.95,339.94c0-4.44-3.61-8.04-8.04-8.04c-4.44,0-8.05,3.6-8.05,8.04
|
||||
c0,4.43,3.61,8.04,8.05,8.04C836.34,347.98,839.95,344.37,839.95,339.94z"/>
|
||||
<path d="M803.57,237.26c0,0.22-0.02,0.43-0.06,0.63c-0.3,1.43-1.57,2.51-3.08,2.51h-7.98c-1.52,0-2.79-1.08-3.09-2.51
|
||||
c-0.04-0.2-0.06-0.41-0.06-0.63c0-1.73,1.41-3.14,3.15-3.14h7.98C802.16,234.12,803.57,235.53,803.57,237.26z M802.57,237.26
|
||||
c0-1.18-0.96-2.14-2.14-2.14h-7.98c-1.18,0-2.15,0.96-2.15,2.14c0,1.18,0.97,2.14,2.15,2.14h7.98
|
||||
C801.61,239.4,802.57,238.44,802.57,237.26z"/>
|
||||
<path d="M796.43,227.55c5.13,0,9.31,4.18,9.31,9.31c0,5.13-4.18,9.31-9.31,9.31c-5.13,0-9.3-4.18-9.3-9.31
|
||||
C787.13,231.73,791.3,227.55,796.43,227.55z M804.65,238.06c0.06-0.39,0.09-0.79,0.09-1.2c0-4.58-3.73-8.31-8.31-8.31
|
||||
c-4.58,0-8.3,3.73-8.3,8.31c0,0.41,0.03,0.81,0.09,1.2c0.58,4.02,4.04,7.11,8.21,7.11C800.6,245.17,804.07,242.08,804.65,238.06z
|
||||
"/>
|
||||
<path d="M800.43,235.12c1.18,0,2.14,0.96,2.14,2.14c0,1.18-0.96,2.14-2.14,2.14h-7.98c-1.18,0-2.15-0.96-2.15-2.14
|
||||
c0-1.18,0.97-2.14,2.15-2.14H800.43z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="959.16" y="240.91" class="st1" width="19.02" height="2.2"/>
|
||||
<rect x="959.16" y="263.95" class="st1" width="19.02" height="2.2"/>
|
||||
<rect x="959.16" y="252.37" class="st1" width="19.02" height="2.2"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M944.36,263.91c-5.38,0-9.81-4.1-10.35-9.34h-2.21c0.52,6.47,5.95,11.58,12.55,11.58
|
||||
c6.59,0,12.01-5.1,12.55-11.58h-2.2C954.18,259.81,949.74,263.91,944.36,263.91z"/>
|
||||
<path class="st1" d="M944.36,243.11c5.35,0,9.77,4.06,10.34,9.26h2.21c-0.58-6.42-5.98-11.46-12.54-11.46
|
||||
c-6.55,0-11.95,5.04-12.54,11.46h2.2C934.59,247.17,939.01,243.11,944.36,243.11z"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st1" points="1002.11,244.84 1002.11,244.84 1005.57,240.91 1002.64,240.91 994.44,250.2 995.91,251.87 "/>
|
||||
<polygon class="st1" points="992.98,251.86 992.98,251.87 983.31,240.91 980.38,240.91 991.51,253.53 980.38,266.15
|
||||
983.31,266.15 992.98,255.19 992.98,255.19 994.45,253.53 "/>
|
||||
<polygon class="st1" points="994.44,256.86 1002.64,266.15 1005.57,266.15 995.91,255.19 "/>
|
||||
</g>
|
||||
<path class="st1" d="M912.72,253.47c0-5.74,4.67-10.42,10.42-10.42h6.4v-2.2h-6.52c-6.89,0.08-12.49,5.74-12.49,12.62
|
||||
c0,6.87,5.4,12.41,12.31,12.62h6.75v-2.2h-6.44C917.39,263.89,912.72,259.22,912.72,253.47z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon class="st0" points="1098.73,438.57 1098.73,396.61 1069.18,396.61 1069.18,438.57 1048.6,438.57 1083.95,492.7
|
||||
1119.31,438.57 "/>
|
||||
<rect x="1069.18" y="376.14" class="st0" width="29.54" height="13.53"/>
|
||||
<rect x="1069.18" y="362.44" class="st0" width="29.54" height="6.76"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st0" points="1069.19,208.46 1069.19,250.42 1098.73,250.42 1098.73,208.46 1119.31,208.46 1083.96,154.33
|
||||
1048.6,208.46 "/>
|
||||
|
||||
<rect x="1069.19" y="257.36" transform="matrix(-1 -1.224647e-16 1.224647e-16 -1 2167.9158 528.2437)" class="st0" width="29.54" height="13.53"/>
|
||||
|
||||
<rect x="1069.19" y="277.82" transform="matrix(-1 -1.224647e-16 1.224647e-16 -1 2167.9158 562.4137)" class="st0" width="29.54" height="6.76"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st0" points="969.43,338.36 1011.39,338.36 1011.39,308.81 969.43,308.81 969.43,288.23 915.3,323.59
|
||||
969.43,358.94 "/>
|
||||
|
||||
<rect x="1010.32" y="316.82" transform="matrix(-1.836970e-16 1 -1 -1.836970e-16 1348.677 -701.5071)" class="st0" width="29.54" height="13.53"/>
|
||||
|
||||
<rect x="1027.41" y="320.2" transform="matrix(-1.836970e-16 1 -1 -1.836970e-16 1365.7621 -718.5921)" class="st0" width="29.54" height="6.76"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st0" points="1198.94,308.82 1156.98,308.82 1156.98,338.36 1198.94,338.36 1198.94,358.94 1253.07,323.59
|
||||
1198.94,288.23 "/>
|
||||
|
||||
<rect x="1128.51" y="316.82" transform="matrix(6.123234e-17 -1 1 6.123234e-17 819.6924 1466.8701)" class="st0" width="29.54" height="13.53"/>
|
||||
|
||||
<rect x="1111.42" y="320.21" transform="matrix(6.123234e-17 -1 1 6.123234e-17 802.6074 1449.7852)" class="st0" width="29.54" height="6.76"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st2" d="M410.44,624.16v-26.6h5.43l7.71,11.02l7.71-11.02h5.39v26.6h-5.39v-18.2l-6.12,8.55h-3.04l-6.23-8.55v18.2
|
||||
H410.44z"/>
|
||||
<path class="st2" d="M446.34,601.06c2.62-2.7,5.93-4.03,9.88-4.03c3.95,0,7.22,1.33,9.84,4.03c2.62,2.66,3.95,5.93,3.95,9.8
|
||||
c0,3.84-1.33,7.1-3.95,9.8c-2.62,2.7-5.89,4.03-9.84,4.03c-3.95,0-7.26-1.33-9.88-4.03c-2.62-2.7-3.91-5.97-3.91-9.8
|
||||
C442.43,606.99,443.72,603.72,446.34,601.06z M456.22,619.56c2.36,0,4.29-0.84,5.85-2.47s2.36-3.72,2.36-6.23s-0.8-4.6-2.36-6.23
|
||||
s-3.5-2.47-5.85-2.47s-4.33,0.84-5.89,2.47s-2.32,3.72-2.32,6.23s0.76,4.6,2.32,6.23S453.87,619.56,456.22,619.56z"/>
|
||||
<path class="st2" d="M475.72,624.16v-26.6h9.95c4.29,0,7.83,1.25,10.52,3.72c2.7,2.47,4.07,5.66,4.07,9.58
|
||||
c0,3.91-1.37,7.14-4.07,9.61c-2.7,2.47-6.23,3.69-10.52,3.69H475.72z M481.19,619.26h4.03c5.93,0,9.42-3.12,9.42-8.4
|
||||
s-3.5-8.4-9.42-8.4h-4.03V619.26z"/>
|
||||
<path class="st2" d="M505.97,624.16v-26.6h19.53v4.9h-14.06v5.13h11.32v4.83h-11.32v6.84h14.48v4.9H505.97z"/>
|
||||
<path class="st2" d="M539.94,624.16v-3.99l7.83-7.11c1.79-1.63,3-2.92,3.69-3.95c0.72-1.03,1.06-2.09,1.06-3.23
|
||||
c0-2.28-1.82-3.72-4.56-3.72c-2.51,0-4.9,1.03-7.18,3.04v-5.62c2.17-1.71,4.75-2.55,7.75-2.55c2.55,0,4.75,0.76,6.61,2.24
|
||||
c1.86,1.48,2.81,3.46,2.81,5.89c0,1.86-0.42,3.53-1.25,4.98c-0.8,1.44-2.28,3.12-4.37,5.05l-4.56,4.18h11.09v4.79H539.94z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st2" d="M883.3,624.16v-26.6h5.43l7.71,11.02l7.71-11.02h5.39v26.6h-5.39v-18.2l-6.12,8.55H895l-6.23-8.55v18.2H883.3z
|
||||
"/>
|
||||
<path class="st2" d="M919.21,601.06c2.62-2.7,5.93-4.03,9.88-4.03c3.95,0,7.22,1.33,9.84,4.03c2.62,2.66,3.95,5.93,3.95,9.8
|
||||
c0,3.84-1.33,7.1-3.95,9.8c-2.62,2.7-5.89,4.03-9.84,4.03c-3.95,0-7.26-1.33-9.88-4.03c-2.62-2.7-3.91-5.97-3.91-9.8
|
||||
C915.3,606.99,916.59,603.72,919.21,601.06z M929.09,619.56c2.36,0,4.29-0.84,5.85-2.47s2.36-3.72,2.36-6.23s-0.8-4.6-2.36-6.23
|
||||
s-3.5-2.47-5.85-2.47s-4.33,0.84-5.89,2.47s-2.32,3.72-2.32,6.23s0.76,4.6,2.32,6.23S926.73,619.56,929.09,619.56z"/>
|
||||
<path class="st2" d="M948.59,624.16v-26.6h9.95c4.29,0,7.83,1.25,10.52,3.72c2.7,2.47,4.07,5.66,4.07,9.58
|
||||
c0,3.91-1.37,7.14-4.07,9.61c-2.7,2.47-6.23,3.69-10.52,3.69H948.59z M954.06,619.26h4.03c5.93,0,9.42-3.12,9.42-8.4
|
||||
s-3.5-8.4-9.42-8.4h-4.03V619.26z"/>
|
||||
<path class="st2" d="M978.83,624.16v-26.6h19.53v4.9H984.3v5.13h11.32v4.83H984.3v6.84h14.48v4.9H978.83z"/>
|
||||
<path class="st2" d="M1012.8,624.16v-3.99l7.83-7.11c1.79-1.63,3-2.92,3.69-3.95c0.72-1.03,1.06-2.09,1.06-3.23
|
||||
c0-2.28-1.82-3.72-4.56-3.72c-2.51,0-4.9,1.03-7.18,3.04v-5.62c2.17-1.71,4.75-2.55,7.75-2.55c2.55,0,4.75,0.76,6.61,2.24
|
||||
c1.86,1.48,2.81,3.46,2.81,5.89c0,1.86-0.42,3.53-1.25,4.98c-0.8,1.44-2.28,3.12-4.37,5.05l-4.56,4.18h11.09v4.79H1012.8z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M263.39,64.25h27.51v4.85h-11.14v28.75h-5.28V69.1h-11.09V64.25z"/>
|
||||
<path class="st0" d="M301.36,97.86h-5.18v-33.6h5.18v13.15c2.3-2.5,5.18-3.74,8.64-3.74c5.57,0,8.74,3.7,8.74,9.79v14.4h-5.18
|
||||
V84.61c0-2.26-0.53-3.84-1.63-4.75c-1.1-0.91-2.4-1.34-3.89-1.34c-2.64,0-5.33,1.68-6.67,3.84V97.86z"/>
|
||||
<path class="st0" d="M325.64,97.86V74.29h5.18v4.08c1.58-2.74,5.04-4.71,8.69-4.71c0.19,0,0.34,0,0.48,0.05v5.18
|
||||
c-0.43-0.05-0.91-0.1-1.44-0.1c-3.7,0-6.62,2.16-7.73,4.61v14.45H325.64z"/>
|
||||
<path class="st0" d="M346.67,94.88c-2.45-2.4-3.65-5.33-3.65-8.83c0-3.46,1.2-6.38,3.65-8.78s5.52-3.6,9.31-3.6
|
||||
c3.74,0,6.82,1.2,9.26,3.6s3.65,5.33,3.65,8.78c0,3.46-1.2,6.38-3.65,8.83c-2.45,2.4-5.52,3.6-9.26,3.6
|
||||
C352.19,98.48,349.11,97.28,346.67,94.88z M361.5,91.66c1.49-1.49,2.21-3.36,2.21-5.62c0-2.21-0.72-4.08-2.21-5.57
|
||||
c-1.49-1.49-3.31-2.26-5.52-2.26c-2.21,0-4.08,0.77-5.57,2.26c-1.49,1.49-2.21,3.36-2.21,5.57c0,2.26,0.72,4.13,2.21,5.62
|
||||
c1.49,1.49,3.31,2.26,5.57,2.26C358.19,93.92,360.01,93.15,361.5,91.66z"/>
|
||||
<path class="st0" d="M376.38,78.85h-5.04v-4.56h5.04v-6.87h5.18v6.87H389v4.56h-7.44v11.09c0,2.69,1.2,3.79,3.7,3.79
|
||||
c1.3,0,2.45-0.29,3.55-0.86v4.46c-1.1,0.77-2.88,1.15-5.23,1.15c-4.42,0-7.2-2.45-7.2-7.06V78.85z"/>
|
||||
<path class="st0" d="M397.31,78.85h-5.04v-4.56h5.04v-6.87h5.18v6.87h7.44v4.56h-7.44v11.09c0,2.69,1.2,3.79,3.7,3.79
|
||||
c1.3,0,2.45-0.29,3.55-0.86v4.46c-1.1,0.77-2.88,1.15-5.23,1.15c-4.42,0-7.2-2.45-7.2-7.06V78.85z"/>
|
||||
<path class="st0" d="M415.79,92.29V64.25h5.18v26.59c0,1.92,0.86,2.88,2.59,2.88c0.72,0,1.39-0.14,1.97-0.48v4.46
|
||||
c-1.01,0.53-2.3,0.77-3.84,0.77C418.28,98.48,415.79,96.75,415.79,92.29z"/>
|
||||
<path class="st0" d="M432.15,77.21c2.26-2.35,5.14-3.55,8.74-3.55c2.4,0,4.46,0.62,6.19,1.92c3.5,2.5,4.99,6.38,4.99,10.66v1.34
|
||||
h-18.05c0.62,3.98,4.08,6.34,8.88,6.34c2.74,0,5.23-0.72,7.58-2.11v4.37c-2.16,1.54-5.04,2.3-8.69,2.3s-6.72-1.15-9.26-3.46
|
||||
c-2.5-2.3-3.74-5.28-3.74-8.98C428.79,82.54,429.9,79.57,432.15,77.21z M446.84,83.65c-0.05-1.44-0.58-2.74-1.68-3.89
|
||||
c-1.1-1.15-2.59-1.73-4.51-1.73c-3.79,0-6.24,2.54-6.58,5.62H446.84z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 49 KiB |
BIN
docs/assets/right-hand-rotate.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
87
docs/assets/right-hand-rule.svg
Normal file
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]>
|
||||
<svg version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
|
||||
x="0px" y="0px" width="507px" height="459px" viewBox="-21.914 -25.609 507 459" enable-background="new -21.914 -25.609 507 459"
|
||||
xml:space="preserve">
|
||||
<defs>
|
||||
</defs>
|
||||
<path fill="#E5D4B1" stroke="#000000" stroke-width="3" d="M466.982,303.788c-22-3-57-23-62-26s-28-28-40-47s-23-42-27-55
|
||||
s-8-26-9-33s1-23.5,4-30.5c-7-5-21-6-27,7s-11,33-11,46s22,55,8,61s-17,14-89-4s-102-20-109-6s34,20,56,24s72.021,22.634,65,32
|
||||
c-4.35,5.802-9.375,4.488-20.709,8.488c-19.611,6.922-19.308,9.966-43.791,18.345c-24.433,8.362-22.843,32.226-15.167,36.23
|
||||
s14.016,6.342,46.386-12.013c14.35-5.34,31.782-8.885,47.115-10.218s24.668,56,41.334,64.667s35.999,8,47.999,8
|
||||
s18.666,2.001,25.333-1.333s25.334,1.332,35.334,6.666c0,0,38.667,18.667,42,22.667"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M234.483,270.787c33.999-1.999,45.999,30.667,53.999,48.001"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M306.149,245.453c0.334,25.334,11.001,46.668,25.333,54.666"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M239.816,230.787c-8,1.333-17.333,20-13.333,25.333"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M197.149,220.12c-5.333,4-16,13.333-13.333,18.667"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M149.149,212.12c-6.667,4-8.834,15.501-10.167,18.167"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M222.483,280.121c8,4,12,17.332,9.333,26.666"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M201.296,287.393c6.667,4,7.248,23.993,4.581,27.993"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M175.848,298.59c8.648,6.485,9.591,15.534,5.089,26.466"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M293.982,236.288c-4,10-7,18-6,24"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M294.982,165.288c11.947,1.707,2.677,3.252,25-1"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M399.149,286.788c-4,12-8,15.999-14.667,19.999"/>
|
||||
<path fill="#E5D4B1" stroke="#000000" stroke-width="3" d="M299.816,374.455c15.905-3.181,27.334-5.333,36-8
|
||||
s21.332-10.001,24.666-16.667s0.667-7.999-1.333-12.666s-23.999-2-29.333,0s-10,4-32,7.333s-28,5-39.334,3.666
|
||||
c-9.292-1.094,1.335,22.333,6.001,25S269.816,380.455,299.816,374.455z"/>
|
||||
<path fill="#E5D4B1" stroke="#000000" stroke-width="3" d="M316.784,311.788c18.897-1.333,28.348-2.666,33.435,2.667
|
||||
s2.906,10.667,1.453,12s-18.171,8.666-26.893,11.333c-8.723,2.667-10.176,0.667-27.619,4.667c-17.444,4-18.897,5.333-23.986,7.333
|
||||
c-5.088,2-15.263,1.333-24.711-6c-9.449-7.333-7.996-20-7.269-24c0.727-4,1.455-12.667,19.625-14s12.354,4.666,35.614,5.333
|
||||
C319.691,311.788,316.784,311.788,316.784,311.788z"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M245.815,318.455c-1.923,17.305,1.109,18.166,10.667,25.333"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M275.149,318.787c0,5.333,1.333,17.333,1.333,17.333"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M308.149,317.12c0,2.667,1.334,13.333,1.334,17.333"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M314.815,347.122c0,4,6.667,17.333,6.667,17.333"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M282.482,354.788c1.333,2.667,2.667,14.666,6.667,16"/>
|
||||
<path fill="none" stroke="#897F6A" stroke-width="2" d="M405.815,318.788c-6.666,12-10.666,42.668-17.333,49.334"/>
|
||||
<line fill="none" stroke="#963C96" stroke-width="9" stroke-linecap="round" x1="323.482" y1="90.788" x2="322.814" y2="41.788"/>
|
||||
<polygon fill="#963C96" points="322.814,41.788 299.501,60.3 322.814,0 346.127,60.3 "/>
|
||||
<line fill="none" stroke="#2828FF" stroke-width="9" stroke-linecap="round" x1="88.996" y1="210.46" x2="40.9" y2="201.067"/>
|
||||
<polygon fill="#2828FF" points="40.9,201.067 54.24,227.68 0,192.5 63.799,182.044 "/>
|
||||
<line fill="none" stroke="#E12828" stroke-width="9" stroke-linecap="round" x1="126.377" y1="335.255" x2="95.585" y2="348.005"/>
|
||||
<polygon fill="#E12828" points="95.585,348.005 118.064,371.413 69.063,358.197 96.605,315.568 "/>
|
||||
<g>
|
||||
<path fill="#2828FF" d="M375.868,62.098l-0.308-0.103c-1.121,1.094-2.212,1.887-3.271,2.379s-2.184,0.738-3.373,0.738
|
||||
c-1.75,0-3.138-0.461-4.163-1.384s-1.538-2.157-1.538-3.702c0-2.01,0.987-3.592,2.963-4.748s4.974-1.883,8.993-2.184v-1.948
|
||||
c0-1.271-0.144-2.252-0.431-2.943s-0.656-1.176-1.107-1.456s-0.991-0.42-1.62-0.42s-1.173,0.109-1.63,0.328
|
||||
c-0.459,0.219-0.872,0.632-1.241,1.241s-0.643,1.453-0.82,2.533h-3.876v-3.732c1.572-0.697,2.902-1.22,3.988-1.569
|
||||
c1.088-0.349,2.099-0.605,3.035-0.769s1.836-0.246,2.697-0.246c1.654,0,2.977,0.219,3.969,0.656
|
||||
c0.99,0.438,1.732,1.148,2.225,2.133s0.738,2.345,0.738,4.081v7.998c0,1.162,0.034,1.986,0.103,2.471s0.175,0.837,0.317,1.056
|
||||
c0.145,0.219,0.328,0.39,0.555,0.513c0.225,0.123,0.639,0.26,1.24,0.41v1.354h-7.629L375.868,62.098z M375.191,55.104
|
||||
c-2.119,0.055-3.688,0.451-4.707,1.189s-1.527,1.818-1.527,3.24c0,0.848,0.232,1.494,0.697,1.938s1.107,0.667,1.928,0.667
|
||||
c0.629,0,1.224-0.167,1.784-0.502s1.005-0.783,1.333-1.343s0.492-1.155,0.492-1.784V55.104z"/>
|
||||
<path d="M403.971,52.808l9.208,9.311l-2.051,2.051l-9.188-9.372l-9.475,9.29l-1.907-1.928l9.372-9.352L390.6,43.6l2.051-2.051
|
||||
l9.29,9.27l9.29-9.27l1.928,1.907L403.971,52.808z"/>
|
||||
<path fill="#E12828" d="M422.54,42.492c0-1.299-0.021-2.242-0.062-2.83s-0.127-1.042-0.256-1.364
|
||||
c-0.131-0.321-0.328-0.574-0.596-0.759c-0.266-0.185-0.734-0.345-1.404-0.482v-1.354l5.722-0.287h2.522v11.751l0.021,0.021
|
||||
c1.217-1.135,2.32-1.931,3.312-2.389s2.007-0.687,3.046-0.687c2.434,0,4.259,0.858,5.476,2.574s1.825,4.283,1.825,7.701
|
||||
c0,3.568-0.804,6.248-2.409,8.039c-1.607,1.791-3.982,2.687-7.127,2.687c-2.16,0-4.136-0.39-5.927-1.169l-1.518,1.169l-2.625-0.369
|
||||
V42.492z M428.466,58.058c0,1.682,0.29,2.922,0.871,3.722s1.48,1.2,2.697,1.2c1.258,0,2.218-0.66,2.881-1.979
|
||||
s0.995-3.203,0.995-5.65c0-2.693-0.294-4.703-0.882-6.029s-1.504-1.989-2.748-1.989c-0.602,0-1.196,0.157-1.784,0.472
|
||||
s-1.073,0.762-1.456,1.343s-0.574,1.22-0.574,1.917V58.058z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#2828FF" d="M74.339,166.769l-0.308-0.103c-1.121,1.094-2.212,1.887-3.271,2.379s-2.184,0.738-3.373,0.738
|
||||
c-1.75,0-3.138-0.461-4.163-1.384s-1.538-2.157-1.538-3.702c0-2.01,0.987-3.592,2.963-4.748s4.974-1.883,8.993-2.184v-1.948
|
||||
c0-1.271-0.144-2.252-0.431-2.943s-0.656-1.176-1.107-1.456s-0.991-0.42-1.62-0.42s-1.173,0.109-1.63,0.328
|
||||
c-0.459,0.219-0.872,0.632-1.241,1.241s-0.643,1.453-0.82,2.533h-3.876v-3.732c1.572-0.697,2.902-1.22,3.988-1.569
|
||||
c1.088-0.349,2.099-0.605,3.035-0.769s1.836-0.246,2.697-0.246c1.654,0,2.977,0.219,3.969,0.656
|
||||
c0.99,0.438,1.732,1.148,2.225,2.133s0.738,2.345,0.738,4.081v7.998c0,1.162,0.034,1.986,0.103,2.471s0.175,0.837,0.317,1.056
|
||||
c0.145,0.219,0.328,0.39,0.555,0.513c0.225,0.123,0.639,0.26,1.24,0.41v1.354h-7.629L74.339,166.769z M73.663,159.775
|
||||
c-2.119,0.055-3.688,0.451-4.707,1.189s-1.527,1.818-1.527,3.24c0,0.848,0.232,1.494,0.697,1.938s1.107,0.667,1.928,0.667
|
||||
c0.629,0,1.224-0.167,1.784-0.502s1.005-0.783,1.333-1.343s0.492-1.155,0.492-1.784V159.775z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#E12828" d="M93.716,283.163c0-1.299-0.021-2.242-0.062-2.83s-0.127-1.042-0.256-1.363
|
||||
c-0.131-0.321-0.328-0.574-0.596-0.759c-0.266-0.185-0.734-0.345-1.404-0.481v-1.354l5.722-0.287h2.522v11.75l0.021,0.021
|
||||
c1.217-1.135,2.32-1.932,3.312-2.39s2.007-0.687,3.046-0.687c2.434,0,4.259,0.857,5.476,2.573s1.825,4.282,1.825,7.7
|
||||
c0,3.568-0.804,6.248-2.409,8.039c-1.607,1.791-3.982,2.688-7.127,2.688c-2.16,0-4.136-0.391-5.927-1.17l-1.518,1.17l-2.625-0.369
|
||||
V283.163z M99.643,298.729c0,1.682,0.29,2.922,0.871,3.722s1.48,1.2,2.697,1.2c1.258,0,2.218-0.66,2.881-1.979
|
||||
s0.995-3.202,0.995-5.649c0-2.693-0.294-4.703-0.882-6.029s-1.504-1.99-2.748-1.99c-0.602,0-1.196,0.158-1.784,0.473
|
||||
s-1.073,0.762-1.456,1.343s-0.574,1.22-0.574,1.917V298.729z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
BIN
docs/assets/versions/clover_2.jpg
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
docs/assets/versions/clover_3.jpg
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
docs/assets/versions/clover_4.jpg
Normal file
|
After Width: | Height: | Size: 68 KiB |
@@ -65,3 +65,15 @@ footer img {
|
||||
.type_table tr td {
|
||||
padding: 14px 20px;
|
||||
}
|
||||
|
||||
table.versions td {
|
||||
text-align: center;
|
||||
background: white;
|
||||
|
||||
.circle {
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
# Summary
|
||||
|
||||
* [Introduction](README.md)
|
||||
* [Glossary](gloss.md)
|
||||
* [Glossary](glossary.md)
|
||||
* [Safety tips](safety.md)
|
||||
* Assembly
|
||||
* [Assembly](assembly.md)
|
||||
* [Clover 4.2 assembly](assemble_4_2.md)
|
||||
* [Clover 4 assembly](assemble_4.md)
|
||||
* [Clover 3 assembly](assemble_3.md)
|
||||
* [Clover 2 assembly](assemble_2.md)
|
||||
* Configuration
|
||||
* [Initial setup](setup.md)
|
||||
* [Configuration](setup.md)
|
||||
* [Sensor calibration](calibration.md)
|
||||
* [RC setup](radio.md)
|
||||
* [Using FS-A8S](rc_flysky_a8s.md)
|
||||
* [Flight modes](modes.md)
|
||||
* [Power setup](power.md)
|
||||
* [Failsafe configuration](failsafe.md)
|
||||
* Working with Raspberry Pi
|
||||
* [Raspberry Pi](raspberry.md)
|
||||
* [Manual flight](flight.md)
|
||||
* [Basics](flight.md)
|
||||
* [Exercises](flight_exercises.md)
|
||||
* [Working with Raspberry Pi](raspberry.md)
|
||||
* [RPi Image](image.md)
|
||||
* [Wi-Fi connection](wifi.md)
|
||||
* [Connection to the Pixracer](connection.md)
|
||||
@@ -26,11 +27,9 @@
|
||||
* [Command line interface](cli.md)
|
||||
* [Automated self-checks](selfcheck.md)
|
||||
* [Viewing images from cameras](web_video_server.md)
|
||||
* Programming
|
||||
* [Overview](programming.md)
|
||||
* [Programming](programming.md)
|
||||
* [Camera setup](camera_setup.md)
|
||||
* Fiducial markers (ArUco)
|
||||
* [Overview](aruco.md)
|
||||
* [Fiducial markers (ArUco)](aruco.md)
|
||||
* [Marker detection](aruco_marker.md)
|
||||
* [Map-based navigation](aruco_map.md)
|
||||
* [Optical Flow](optical_flow.md)
|
||||
@@ -45,14 +44,14 @@
|
||||
* [Using rviz and rqt](rviz.md)
|
||||
* [Software autorun](autolaunch.md)
|
||||
* [Using JavaScript](javascript.md)
|
||||
* [ROS](ros.md)
|
||||
* [MAVROS](mavros.md)
|
||||
* Simulation
|
||||
* [Overview](simulation.md)
|
||||
* [Blocks programming](blocks.md)
|
||||
* [Simulation](simulation.md)
|
||||
* [Native setup](simulation_native.md)
|
||||
* [VM setup](simulation_vm.md)
|
||||
* [Usage](simulation_usage.md)
|
||||
* Supplementary materials
|
||||
* [ROS](ros.md)
|
||||
* [MAVROS](mavros.md)
|
||||
* [Supplementary materials](supplementary.md)
|
||||
* [COEX Pix](coex_pix.md)
|
||||
* [Guide on autonomous flight](auto_setup.md)
|
||||
* [Hostname](hostname.md)
|
||||
@@ -85,7 +84,7 @@
|
||||
* [LED strip (legacy)](leds_old.md)
|
||||
* [Contribution Guidelines](contributing.md)
|
||||
* [Migration to v0.20](migrate20.md)
|
||||
* Clover-based projects
|
||||
* [Clover-based projects](projects.md)
|
||||
* [Drone show](clever-show.md)
|
||||
* [Innopolis Open 2020 (L22_ÆRO)](innopolis_open_L22_AERO.md)
|
||||
* [Copter spheric guard](shield.md)
|
||||
|
||||
@@ -410,7 +410,7 @@ Check the quadrotor assembly:
|
||||
|
||||
<img src="../assets/assembling_clever4/final_1.png" width=300 class="zoom border center">
|
||||
|
||||
Be sure to install and setup the voltage indicator before flying, so as not to overdischarge the battery. To configure the indicator, use the button located at its base. The displayed numbers during setup indicate the minimum possible voltage in each [cell](gloss.md#battery-cell) of the battery, the recommended value is **3.5**.
|
||||
Be sure to install and setup the voltage indicator before flying, so as not to overdischarge the battery. To configure the indicator, use the button located at its base. The displayed numbers during setup indicate the minimum possible voltage in each [cell](glossary.md#battery-cell) of the battery, the recommended value is **3.5**.
|
||||
|
||||
> **Info** Sound indication means that your battery is low and needs to be charged.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Clover 4 assembly
|
||||
# Clover 4.2 assembly
|
||||
|
||||
## Fasteners size
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
<img src="../assets/assembling_clever4_2/frame_6.png" width=300 class="zoom border center">
|
||||
|
||||
6. Install 4 6mm nylon posts and fix them with the M3x8 screws.
|
||||
6. Install 4 6mm nylon posts and fix them with the M3x5 screws.
|
||||
|
||||
<img src="../assets/assembling_clever4_2/frame_7.png" width=300 class="zoom border center">
|
||||
|
||||
@@ -200,7 +200,7 @@ Install the damper struts, fix *COEX Pix* on them with nylon nuts.
|
||||
|
||||
<img src="../assets/assembling_clever4_2/raspberry_11.png" width=300 class="zoom border center">
|
||||
|
||||
## Installing LED strip
|
||||
## Installing LED strip and legs
|
||||
|
||||
1. Assemble the hoop for the LED strip by combining the lock on the ends.
|
||||
|
||||
|
||||
27
docs/en/assembly.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Clover drone assembly
|
||||
|
||||
This section contains articles describing the assembly of each version of Clover.
|
||||
|
||||
<table class=versions>
|
||||
<tr><th>Version</th><th>Image</th></tr>
|
||||
<tr>
|
||||
<td><a href="assemble_4_2.md">Clover 4.2</a></td>
|
||||
<td><img src="../assets/versions/clover_4.jpg" width=200></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="assemble_4_2.md">Clover 4.1</a></td>
|
||||
<td><img src="../assets/versions/clover_4.jpg" width=200></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="assemble_4_2.md">Clover 4</a></td>
|
||||
<td><img src="../assets/versions/clover_4.jpg" width=200></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="assemble_4_2.md">Clover 3</a></td>
|
||||
<td><img src="../assets/versions/clover_3.jpg" width=200></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="assemble_4_2.md">Clover 2</a></td>
|
||||
<td><img src="../assets/versions/clover_2.jpg" width=200></td>
|
||||
</tr>
|
||||
</table>
|
||||
110
docs/en/blocks.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Blocks programming for Clover
|
||||
|
||||
<img src="../assets/blocks/blockly.svg" width=200 align="right">
|
||||
|
||||
Visual blocks programming feature has been added to the [RPi image](image.md), starting with the version **0.21**. Blocks programming is implemented using [Google Blockly](https://developers.google.com/blockly) platform. Blocks programming integration can lower the entry barrier to a minimum.
|
||||
|
||||
## Configuration
|
||||
|
||||
For correct work of the blocks programming, `blocks` argument in the Clover launch-file (`~/catkin_ws/src/clover/clover/launch/clover.launch`) [should be equal to](cli.md#editing) `true`:
|
||||
|
||||
```xml
|
||||
<arg name="blocks" default="true"/>
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
To run Clover's blocks programming interface, [connect to Clover's Wi-Fi](wifi.md) and go to web-page http://192.168.11.1:8080/clover_blocks/ or click the link *Blocks programming* at the [main page](wifi.md#web-interface).
|
||||
|
||||
The page looks as follows:
|
||||
|
||||
<img src="../assets/blocks/blocks.png" width=600>
|
||||
|
||||
Assemble your program using blocks in the menu at the left and then click *Run* button for running. You can also view generated Python-code, switching to *Python* tab.
|
||||
|
||||
The *Stop* button stops the program. Clicking *Land* button also stops the program and lands the drone.
|
||||
|
||||
## Storing and loading
|
||||
|
||||
<img src="../assets/blocks/save.png" width=300 align=right>
|
||||
|
||||
To store the program, open the menu at the top right, select *Save* item and input your program's name. The name should contain only Latin characters, hyphen, underline and dot characters. All your stored programs are available at the same menu.
|
||||
|
||||
Your programs are stored as XML-files in the `/catkin_ws/src/clover/clover_blocks/programs/` directory of the SD-card.
|
||||
|
||||
> **Note** Note also example programs, available at the same menu.
|
||||
|
||||
## Blocks
|
||||
|
||||
The set of blocks is somewhat similar to the set of ROS-services of [Clover's autonomous flights API](simple_offboard.md). This section contains descriptions of some of them.
|
||||
|
||||
Clover's blocks are separated into 4 categories:
|
||||
|
||||
* <span style="padding:2px;color:white;background:#9d5ca6">Flight</span> – autonomous flight related commands.
|
||||
* <span style="padding:2px;color:white;background:#ff9b00">State</span> – blocks for obtaining the drone state parameters.
|
||||
* <span style="padding:2px;color:white;background:#01d754">LED</span> – blocks for controlling [LED strip](leds.md).
|
||||
* <span style="padding:2px;color:white;background:#5b97cc">GPIO</span> – blocks for working with [GPIO pins](gpio.md).
|
||||
|
||||
The rest of categories contains standard Blockly's blocks.
|
||||
|
||||
### take_off
|
||||
|
||||
<img src="../assets/blocks/take-off.png" srcset="../assets/blocks/take-off.png 2x">
|
||||
|
||||
Take off to specified altitude in meters. The altitude may be an arbitrary block, that returns a number.
|
||||
|
||||
The `wait` flag specifies, if the drone should wait until take off is complete, before executing the next block.
|
||||
|
||||
### navigate
|
||||
|
||||
<img src="../assets/blocks/navigate.png" srcset="../assets/blocks/navigate.png 2x">
|
||||
|
||||
Navigate to specified point. Coordinates are specified in meters.
|
||||
|
||||
The `wait` flag specifies, if the drone should wait until navigation is complete, before executing the next block.
|
||||
|
||||
#### *Relative to* field {#relative_to}
|
||||
|
||||
This block allows to specify the [coordinate frame](frames.md) of the target point:
|
||||
|
||||
* *body* – coordinates, relative to the drone: *forward*, *left*, *up*.
|
||||
* *markers map* – coordinates, relative to the [map of ArUco-markers](aruco_map.md).
|
||||
* *marker* – coordinates, relative to an [ArUco-marker](aruco_marker.md); marker's ID input fields appears.
|
||||
* *last navigate target* – coordinates, relative to the last specified navigate point.
|
||||
* *map* – drone's local coordinate system, linked with the point of its initialization.
|
||||
|
||||
### land
|
||||
|
||||
<img src="../assets/blocks/land.png" srcset="../assets/blocks/land.png 2x">
|
||||
|
||||
Land the drone.
|
||||
|
||||
The `wait` flag specifies, if the drone should wait until landing is complete, before executing the next block.
|
||||
|
||||
### wait
|
||||
|
||||
<img src="../assets/blocks/wait.png" srcset="../assets/blocks/wait.png 2x">
|
||||
|
||||
Wait specified time period in seconds. The time period may be an arbitrary block, that returns a number.
|
||||
|
||||
### wait_arrival
|
||||
|
||||
<img src="../assets/blocks/wait-arrival.png" srcset="../assets/blocks/wait-arrival.png 2x">
|
||||
|
||||
Wait, until the drone reaches [navigate](#navigate)-block's target point.
|
||||
|
||||
### get_position
|
||||
|
||||
<img src="../assets/blocks/get-position.png" srcset="../assets/blocks/get-position.png 2x">
|
||||
|
||||
The block returns current position, velocity or yaw angle of the drone relative to the specified [coordinate frame](#relative_to).
|
||||
|
||||
### set_effect
|
||||
|
||||
<img src="../assets/blocks/set-effect.png" srcset="../assets/blocks/set-effect.png 2x">
|
||||
|
||||
The block allows to set animations to LED strip, similarly to [`set_effect`](leds.md#set_effect) ROS-service.
|
||||
|
||||
Example of using the block with a random color (colors-related blocks are located in *Colour* category):
|
||||
|
||||
<img src="../assets/blocks/random-color.png" srcset="../assets/blocks/random-color.png 2x">
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"language": "en",
|
||||
"root": "."
|
||||
"root": ".",
|
||||
"structure": {"glossary": "_GLOSSARY.md" }
|
||||
}
|
||||
|
||||
110
docs/en/flight.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Flight
|
||||
|
||||
> **Info** See also official PX4 flying guide: https://docs.px4.io/v1.9.0/en/flying/.
|
||||
|
||||
This section explains the basics of manual controlling the quadcopter in different modes using radio remote control (for autonomous flying see "[Programming](programming.md)") section.
|
||||
|
||||
## Main features of radio remote control
|
||||
|
||||
Before you can launch your drone, you need to understand how the radio remote control works.
|
||||
|
||||
The drone is controlled using two sticks on the remote control. By default, the left stick controls throttle and yaw, and the right stick controls roll and pitch. These terms are used for all aircraft, from airplanes to quadcopters.
|
||||
|
||||
<img src="../assets/flight/rc_basic_commands.svg" width=400 class="zoom center">
|
||||
|
||||
* Throttle – is responsible for rotation speed of the motors.
|
||||
* Yaw – is responsible for rotation around the vertical axis (Z), clockwise (when tilted to the right) and counterclockwise (when tilted to the left).
|
||||
* Pitch – is responsible for tilting or moving forward / backward.
|
||||
* Roll – is responsible for tilting or moving left / right.
|
||||
|
||||
These descriptions assume the aircraft is turned with its back to the pilot.
|
||||
|
||||
<img src="../assets/flight/basic_movements_multicopter.svg" width=400 class="zoom center">
|
||||
|
||||
## Flight Modes
|
||||
|
||||
Manual flight using the PX4 flight controller can be performed in different flight modes. They determine the radio controller stick assignments and other flight characteristics. For the complete list of flight modes, see the article "[Flight modes](modes.md)".
|
||||
|
||||
The main manual modes are described below.
|
||||
|
||||
**STABILIZED** - horizontal angle stabilization mode. In this mode, the aircraft will hold the horizon if not controlled. Functions of sticks:
|
||||
|
||||
* Throttle – the average speed of rotation of the motors.
|
||||
* Yaw – angular velocity around the vertical axis.
|
||||
* Pitch – the angle of inclination around the transverse axis (forward / backward).
|
||||
* Roll – the angle of inclination around the longitudinal axis (left / right).
|
||||
|
||||
**POSCTL** - position holding mode (requires positioning system enabled). Functions of sticks:
|
||||
|
||||
* Throttle – vertical flight speed.
|
||||
* Yaw – angular velocity around the vertical axis.
|
||||
* Pitch – linear speed of the drone (forward / backward).
|
||||
* Roll – linear speed of the drone (left / right).
|
||||
|
||||
**ACRO** - controlling the average rotational speed of the motors and angular speeds of the drone. This mode is the most difficult to fly and is most often used by drone racers and 3D piloting shows to perform tricks. Functions of sticks:
|
||||
|
||||
* Throttle – the average speed of rotation of the motors.
|
||||
* Yaw – angular velocity around the vertical axis.
|
||||
* Pitch – angular velocity around the transverse axis (forward / backward).
|
||||
* Roll – angular velocity around the longitudinal axis (left / right).
|
||||
|
||||
> **Info** Other flight controllers may have different names for similar flight modes.
|
||||
|
||||
## Preparing to fly
|
||||
|
||||
### Installing propellers and batteries
|
||||
|
||||
1. Install the battery strap.
|
||||
|
||||
<img src="../assets/assembling_clever4_2/final_1.png" width=300 class="zoom border center">
|
||||
|
||||
2. Set the propellers according to the [motor direction pattern](#prop_rotation).
|
||||
|
||||
<img src="../assets/assembling_clever4_2/final_3.png" width=300 class="zoom border center">
|
||||
|
||||
3. Attach the buzzer and install the battery.
|
||||
|
||||
<div class="image-group">
|
||||
<img src="../assets/flight/buzzer_acb.jpg" width=200 class="zoom border">
|
||||
<img src="../assets/assembling_clever4_2/final_4.png" width=300 class="zoom border">
|
||||
</div>
|
||||
|
||||
### Setting the buzzer
|
||||
|
||||
In order not to over-discharge or damage the battery, it is recommended to use a voltage indicator (*buzzer*).
|
||||
|
||||
To configure the buzzer, connect it to the balance connector of your battery. By pressing the button, change the minimum voltage on the cells. The optimal value for the minimum voltage is *3.5-3.6 V*.
|
||||
|
||||
<div class="image-group">
|
||||
<img src="../assets/flight/buzzer_connection.jpg" width=300 class="zoom border">
|
||||
<img src="../assets/flight/buzzer.jpg" width=300 class="zoom border">
|
||||
</div>
|
||||
|
||||
### Flight readiness states
|
||||
|
||||
Before starting the flight, the aircraft must be in the *Armed* state.
|
||||
|
||||
* *Armed* state – motors rotate according to throttle stick position, copter is ready to fly.
|
||||
* *Disarmed* state – motors do not rotate, copter does not respond to throttle stick.
|
||||
|
||||
By default, the aircraft is in the *Disarmed* state and switches to it automatically if you do not take off for a long time.
|
||||
|
||||
There are several ways to change the copter's state to *Armed*:
|
||||
|
||||
* Using the stick – move the left stick down to the right and wait a couple of seconds.
|
||||
|
||||
<img src="../assets/flight/controller_arm.jpg" width=300 class="zoom center">
|
||||
|
||||
* Using the toggle switch – the Armed / Disarmed states can be set to one of the toggle switches. For more information on setting up, see the article on [flight modes](modes.md).
|
||||
* With QGC – you can arm your drone programmatically. To do this, click on the *Disarmed* label in the header and select another state.
|
||||
* In the [user program](programming.md) – the copter can switch to *Armed* state if the `auto_arm=True` argument is specified in the navigation command, such as `navigate`, `set_position`, etc.
|
||||
|
||||
### Kill switch
|
||||
|
||||
When the *Kill Switch* is activated, no control signals are sent to the motors and the motors stop rotating. This function is used in extreme cases, for example, if you lose control of the aircraft.
|
||||
|
||||
> **Caution** Be careful, *Kill Switch* does not put the copter into *Disarmed* state!
|
||||
|
||||
Before disabling the *Kill Switch*, make sure the throttle stick is its down position and the aircraft is in *Disarmed* state. If the throttle stick is not in the lower position, when the *Kill Switch* is turned off, a signal corresponding to the stick position will be sent to the motors, which will lead your copter to jerk.
|
||||
|
||||
**Next**: [Drone control exercises](flight_exercises.md).
|
||||
149
docs/en/flight_exercises.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# Drone control exercises
|
||||
|
||||
The following are the recommended exercises for novice pilots. Repeat each exercise as many times as necessary until you feel confident in it.
|
||||
|
||||
> **Hint** In case there is a person nearby who can control a copter, use [trainer mode](trainer_mode.md).
|
||||
|
||||
<!---->
|
||||
|
||||
> **Hint** The first flights are strongly recommended to be performed behind a protective grid. In the absence of such, the flight area must be at least 6x6 m.
|
||||
|
||||
## Turning on/off motors, changing flight modes
|
||||
|
||||
> **Hint** For convenience, connect to the aircraft using [QGC over Wi-Fi](gcs_bridge.md) and turn on the sound. This will allow you to monitor the change in flight modes. If you cannot connect via Wi-Fi, connect via USB to check flight modes.
|
||||
|
||||
Be sure to set the flight mode to one of the toggle switches. To do this, switch the toggle to different positions and make sure that the mode change.
|
||||
|
||||
It is recommended to configure *Kill Switch*. To check it, follow these steps:
|
||||
|
||||
* Turn on *Kill Switch*, make sure QGC has a notification.
|
||||
* Put the aircraft in *Armed* state and then enable *Kill Switch*. Make sure the motors stop. Then switch the *Kill Switch* to its original position. If the aircraft haven't automatically entered the *Disarmed* state due to inactivity, the motors will start rotating again.
|
||||
|
||||
> **Caution** Set the aircraft to *Armed* state on the flight zone only.
|
||||
|
||||
Make sure modes switching is assigned to toggle switch that is convenient for you. Otherwise, change it according to the [article on setting flight modes](modes.md). Repeat the above steps several times in order to remember which toggle switches are responsible for what.
|
||||
|
||||
## Working with throttle
|
||||
|
||||
The first step is to feel the responsiveness of the copter to the movement of the throttle stick and learn how to control it. Each drone has slightly different power reserves and therefore lifts off the ground at different stick positions.
|
||||
|
||||
For this exercise, only the throttle stick should be used. It is recommended not to use the rest of the sticks during the exercise.
|
||||
|
||||
The main tasks of the exercise:
|
||||
|
||||
1. Drift of the copter on the ground without taking off the ground.
|
||||
|
||||
### Preflight checks
|
||||
|
||||
Do the following before takeoff:
|
||||
|
||||
1. Check the integrity of the aircraft and the propellers are clear to rotate.
|
||||
2. Make sure the aircraft is with its back toward you.
|
||||
3. Turn on the aircraft by connecting the battery.
|
||||
4. Move back to a safe distance. It is recommended to maintain a minimum distance of 4-5 m to the aircraft.
|
||||
5. Make sure the aircraft is in *Stabilized* mode.
|
||||
|
||||
Do not try to lift the copter off the ground right away, find the lowest possible stick position for the copter to start drifting on the ground. Failure to do so may result in damage or injury.
|
||||
|
||||
> **Caution** If you lose control of the aircraft, you must immediately turn on *Kill Switch*.
|
||||
|
||||
**Exercise №1**. Slowly lift the throttle stick up until the aircraft starts to move. At this point, it will begin to slowly drift on the ground. Leave the throttle stick in this position and wait a couple of seconds, then move the throttle stick to its original position to land the aircraft. After landing the aircraft, turn off the motors by switching to *Disarmed* state. Repeat the exercise 5–10 times to get better feel for the copter's throttle stick response.
|
||||
|
||||
**Exercise №2**. Slowly lift the throttle stick up until the aircraft starts to lift slightly off the ground. Leave the throttle stick in this position and wait a couple of seconds, then land the aircraft as in Exercise №1. Repeat the exercise 5–10 times.
|
||||
|
||||
**Exercise №3**. Raise the throttle stick until the aircraft starts to drift on the ground, wait a second and continue increasing the throttle until the aircraft starts to lift off the ground, wait a second and land the aircraft. To consolidate, repeat the exercises 5–10 times, increasing the number of repetitions if necessary.
|
||||
|
||||
## Working with roll and pitch
|
||||
|
||||
After mastering the throttle control of the copter, it is necessary to learn how to control its horizontal position. The right stick on the remote control is responsible for this.
|
||||
|
||||
Manipulating these axes is intuitive:
|
||||
|
||||
* Stick tilted forward (up) - aircraft moves forward.
|
||||
* Stick tilted back (down) - aircraft moves backward.
|
||||
* Stick tilted to the right - aircraft moves to the right.
|
||||
* Stick tilted to the left - aircraft moves to the left.
|
||||
|
||||
The more the stick is tilted to the side, the more the aircraft will tilt to the side and the faster it moves.
|
||||
|
||||
The main tasks of the exercise:
|
||||
|
||||
1. Flying along the X axis, forward / backward.
|
||||
2. Flying along the Y axis, left / right.
|
||||
3. Stabilization of the copter in one place.
|
||||
4. Flying in a square clockwise and counterclockwise.
|
||||
|
||||
> **Hint** Always stay behind the aircraft with the rear facing towards you, otherwise you may lose control over it by mixing sides.
|
||||
|
||||
As with throttle control, perform [the following steps](#preflight-checks) before flying.
|
||||
|
||||
> **Hint** If the aircraft is spinning strongly around its axis, land it and recalibrate the magnetometer and gyroscope.
|
||||
|
||||
**Exercise №1**. Similar to throttle exercises, raise the throttle stick until the aircraft starts to drift on the ground or bounce a little, then release the throttle stick, leaving it in that position, and raise the pitch stick, first up for a second, then down. The copter will gradually move away from you and then towards you. Repeat the exercise 5–10 times until you feel the copter's responsiveness to the stick movement.
|
||||
|
||||
**Exercise №2**. Raise the throttle stick until the aircraft starts to drift, then leave it and move the roll stick first to the right for a second, then to the left. The aircraft will gradually move first to the right and then to the left. Repeat the exercise 5–10 times until you feel the copter's responsiveness to the stick movement.
|
||||
|
||||
**Exercise №3**. Raise the throttle stick until the aircraft starts to drift, then leave it. Combine the first and second exercises and try to stabilize the aircraft at one point, compensating for its drift with the stick. Hold the aircraft for 50–60 seconds.
|
||||
|
||||
**Exercise №4**. Raise the throttle stick until the aircraft starts to drift, then leave it. When you feel the copter's responsiveness to stick changes, make a "square" shape with a side of 1 m, first clockwise and then counterclockwise. Perform the figures 2–3 times.
|
||||
|
||||
## Air cushion and control in it
|
||||
|
||||
The concept of *air cushion* is very important for all flying vehicles. The air cushion itself is a zone of increased pressure created by the air being forced through the propellers. This area is characterized by turbulence and air currents affecting the flight of the copter.
|
||||
|
||||
Pilots try to avoid flying in an air cushion, but there is a stable area at the boundary where the aircraft can hover at minimum throttle. In this case, it feels like the copter has "sat down" on an air cushion.
|
||||
|
||||
The main feature and advantage of such a flight is that the copter will not change altitude with one throttle value.
|
||||
|
||||
Main tasks:
|
||||
|
||||
1. Stabilization of the copter in one place.
|
||||
2. Flying in a square.
|
||||
3. Flying in a circle.
|
||||
|
||||
Similarly to the previous exercises, perform [the following steps](#pre-flight-checks) before take off.
|
||||
|
||||
**Exercise №1**. Raise the throttle stick until the copter flies over the air cushion and is above it (height from floor ~ 25-30 cm, for Clover 4 copter). The aircraft should not climb up or fall down, the flight altitude should stabilize. As in the previous exercise, adjust the X and Y position of the aircraft using the roll and pitch sticks. As a result, the copter should hover at one point with slight wiggle to the sides. Hold the aircraft for 30–40 seconds.
|
||||
|
||||
**Exercise №2**. Raise the aircraft on the air cushion and stabilize it at one point. Next, fly over a square with a side of 1 m, first clockwise, then counterclockwise. Repeat the path 2–3 times in each direction.
|
||||
|
||||
**Exercise №3**. Raise the aircraft on the air cushion and stabilize it at one point. Try to fly a circle with the copter around 1 m in diameter, clockwise and counterclockwise. Repeat the path 2–3 times in each direction.
|
||||
|
||||
## Working with yaw
|
||||
|
||||
In the visual control of multicopter devices, yaw does not play as important role as with fixed wing vehicles, since the copter can move in any direction regardless of where it is directed.
|
||||
|
||||
> **Info** The term *yaw* refers to the rotation of the aircraft around the vertical axis.
|
||||
|
||||
Main tasks:
|
||||
|
||||
1. Rotate the copter, orienting the rear of the copter towards you.
|
||||
2. Turning around the copter, orienting the rear part towards you.
|
||||
|
||||
It is recommended that you find plenty of free space for the exercises presented.
|
||||
|
||||
Similarly to previous exercises, perform [preflight checks](#preflight-checks) before takeoff.
|
||||
|
||||
**Exercise №1**. Raise the aircraft on the air cushion and stabilize it at one point. Fly a circle around you with the copter, at a distance of 2–3 m, while rotating it so that the back of the copter is always directed towards you. Do the exercise clockwise and counterclockwise. Repeat the exercise 4–5 times.
|
||||
|
||||
**Exercise №2**. Raise the aircraft on the air cushion and stabilize it at one point. Walk around the aircraft while turning it so that the rear is facing you. Walk around the aircraft clockwise and counterclockwise. Repeat the exercise 4–5 times.
|
||||
|
||||
> **Caution** Additional exercises are much more difficult than usual and are not required. Only proceed with them if you are already confidently flying the copter.
|
||||
|
||||
**Additional exercise №1**. Raise the aircraft on the air cushion and stabilize it at one point. Face the aircraft with its front facing you and try to fly it backwards.
|
||||
|
||||
**Additional exercise №2**. Raise the aircraft on the air cushion and stabilize it at one point. Fly so that the front of the aircraft is always facing the direction of the aircraft.
|
||||
|
||||
## Free flight
|
||||
|
||||
If you can complete each of the exercises described above, chances are you already know how to freely take off and fly the aircraft. Some exercises will be presented below to consolidate the acquired skills.
|
||||
|
||||
Exercises:
|
||||
|
||||
* Flying in a vertical square.
|
||||
* Flying along the sides of the cube.
|
||||
* Flying in a vertical circle.
|
||||
* Flight of the eight.
|
||||
* Ascent of the copter in a spiral.
|
||||
|
||||
Strengthen the acquired skills as many times as necessary for you.
|
||||
@@ -8,7 +8,7 @@ Main frames in the `clover` package:
|
||||
* `map` has its origin at the flight controller initialization point and may be considered stationary. It is shown as a white grid on the image above;
|
||||
* `base_link` is rigidly bound to the drone. It is shown by the simplified drone model on the image above;
|
||||
* `body` is bound to the drone, but its Z axis points up regardless of the drone's pitch and roll. It is shown by the red, blue and green lines in the illustration;
|
||||
* `navigate_target` is bound to the current navigation target (as set by the [navigate](simple_offboard.md#navigate) service);
|
||||
* <a name="navigate_target"></a>`navigate_target` is bound to the current navigation target (as set by the [navigate](simple_offboard.md#navigate) service);
|
||||
* `setpoint` is current position setpoint.
|
||||
|
||||
Additional frames become available when [ArUco positioning system](aruco.md) is active:
|
||||
|
||||