Compare commits

..

No commits in common. "master" and "release/v.0.6.0" have entirely different histories.

41 changed files with 268 additions and 2614 deletions

View file

@ -1,13 +1,14 @@
dist: trusty dist: trusty
group: edge group: edge
language: python language: python
#virtualenv:
# system_site_packages: true
python: python:
- 2.7.15 - "2.7.13"
before_install: before_install:
- openssl aes-256-cbc -K $encrypted_f5913d2a38b3_key -iv $encrypted_f5913d2a38b3_iv -in fabscan.key.enc -out fabscan.key -d
- sudo apt-get -qq update - sudo apt-get -qq update
- sudo apt-get install -y libcurl3 build-essential python-setuptools debhelper cdbs - sudo apt-get install -y build-essential python-setuptools debhelper cdbs dh-python fakeroot
dh-python fakeroot python-pip rsync python-pip rsync
before_script: before_script:
- CURRENT_DATE=$(date +%Y%m%d%H%M) - CURRENT_DATE=$(date +%Y%m%d%H%M)
- pip install mkdocs - pip install mkdocs
@ -17,14 +18,28 @@ before_script:
- echo $TRAVIS_TAG - echo $TRAVIS_TAG
script: sudo make deb script: sudo make deb
after_success: after_success:
- FILE_NAME=$(ls -a ../*.deb) - ls -alh ../*.deb
#- travis_wait curl -T $FILE_NAME -u $FTPUSER:$FTPPASSWORD ftp://mariolukas.de/release/ - travis_wait curl -T ../*.deb -u $FTPUSER:$FTPPASSWORD ftp://mariolukas.de/release/
- chmod 600 fabscan.key - NOW=`date +%Y-%m-%d-%H-%M`
- scp -o StrictHostKeyChecking=no -i fabscan.key $FILE_NAME $DEPLOY_USER@mariolukas.de:/var/deploy/release/. - mkdocs build
- cd ..
- mkdir tmp
- cd tmp
- git clone -b gh-pages https://github.com/mariolukas/FabScanPi-Server.git
- cd FabScanPi-Server
- git config --global user.email "dev@fabscan.org"
- git config --global user.name "Travis CI"
- git config credential.helper "store --file=.git/credentials"
- echo "https://${GITHUB_TOKEN}:@github.com" > .git/credentials
- rsync -a -v ../../FabScanPi-Server/site/ .
- git commit -am "travis doc update ${NOW}"
- git push
- cd ../../FabScanPi-Server/
env: env:
global: global:
- secure: k0Ms4zQL6KTWInxaS2G578OxmG2aJSicezcGESsDHg3RLI7zgyx4jn+3IdoGfZucXmMxjwPFpBvoVBYfJ4GY5ZrgV8ftvnReO7xn8obADtOmSupTy5eUX5S/K+b8VdjD/QQRO9Bn9lz7ekTauMqtv2usw93X3RTDFtEAtLwtBEuGMU4dhU1lHC/1HDxa0BGfhuEOsp9eedA641dwq3kVpw/6WRlpdyNLEL6l7HJ2ednOH+DXb5hTwSF+Wbg/Oe/pobn8xpFvYc8ZmlRVpiE0kL3lA4HZ5gdBCHAs9HuNsK8e3pKn9l71zqEFdZdbUylp/fFeN5uLYMnZSMKBOg03lRhtsICm6IN7d91Hazcd+vox5Jh0EBgKsEgrAoDSMjiMRj1ROnZXWgs/DYZh8nV+y23hY3BlvyD2AjwyxCHRLG4sIkGmhxe3EoaW1vBwZ4/QUp7AL6x9povUsJM4kU6sBu0+QaoKk1NKs+2xW4mpktS5i2WHuR/sJcmf8AWDkuTejSKBzmKJoSb2dluRYKHa7EpobA7hiCz+6Und13sGJDvF46QprCkuVmDeQc1wImpVj2Evn0KLRRq4z33mEtoMMbROJ1Pg7pXdaTvl9AxDHn60NIbfr7lWjcYIvaOpPSax5vCD6w2lDToDbwj/4K5mh80/bhOyWVCrfcJxQOYqxxQ= - secure: m+zIuupfcmWS8Sby7CB6gAG9cdPLS6DzS+ZjA+9JispYr1rQRYJMPPgP54/XE1UNp8wCU9cPLDHTcllkzKh2PBUXcDy0BOqA+2n1pz3sXloQKM+4uIpBywru4VLCIymw3f2AhfV//50X95w8p/9lH7/K0kUWHNpAkFeMfiVpYN9Fcj5V2NhJ1EYjU5fgwdJ9GACMyiwkxt/GQiiLSLcffHBvN+HOSU19xGBEQx7LEKMJzVs48DT9ZCsjOH4O+rYFyZUW2qzRqJFidSg8SbJAzxiXSiJpgexBji6PkheGAu3DzPLXQAjacW7V0gwqeyuEl9ETcnAt3ZN0UrsYh6zCSLJUBDdJjsypcxgAtz+RddgUCTLIM/TaLSDw6YaOhUsT5CtdDRIflK7LdHhK0oGzVrG8rA2VfKGEKlSC10ZyhenazM6MLTjErGqAcdg6QtN5JXVkubTSytJbs1vEqRTdwo9DI8p2RFa5o4wUobHleFN9GFWwdeKDob86bYna886q5fq6mCLNoOf/KCCMCAcy/hEaOyFb3JYRxhrTCa4lQQ1JNe3YveuiY2P5d+DF7liRpXXpMqBK6RfwmLVn3JfYS6Y33b6h9pYRtu6Cjcm+nc6UhTaM1qxqyJkd2X/yPByJYyt4JjKJkkyVzrN5jzxn3CTPXnNHyYF6uIs4Eoq7m+Q=
- secure: mtixe+yGZ0+mDmcvcFhlETHbmS0umal53U8rh+gvn0+QuuVY0WilLUf5eE3tLZtifyrC0XHkGXpOiaRKS0k5sWuryhEHc5nU7h85uw209hHMNuR2wsMFTln6vUpjZkXxCUuY1qBS9SRK6JrBro0j8aDm7/hj/ESyjp+eexA6hjX/EuYHT5TjuPgrgx8V6kJAWLM56H7pQqFX2sYlCfqSPm4HntA50JP84FcJ6DOczV3RgwKJLXftYWRfcw4ANtcM+5uoaNXkNzdRmqB91W+A+k/lKmtAdpldJhVpsLt43nk+m75+EUjqinuvwzVlz2xPxUC3L/t8HAxqudmg+41MSDhUUcDnPN0AkIE6lzYsBkSZ6fR36xgPVnGHnsTTiN+j7aOpnxjrGzofb0KGOCbfn8TWiw013F7fM5gVL94FkIWpDrfgBgU/tdkmjhnMEnNqyYXsrtRIG+PexZV4PFg5GtStIZsy/BVZRvroHBnmQs7AS19w6NnsdvLHM6P3U+K37shpZgWSXKKKLyqV/NRi/iSa8dbPRISoZCn8x84vEU8bsTIUqT+n9cN75RbcSOIdvj4cDE+GJqWJh+afBfacuiYtgMMrh0/w3ad2ldCkF6uzBSsvPnuc+NBBp0M2uKiKhhqLz/uB8iYS0Gzmso6defDGgocnut++cRW2f3IfdAE= - secure: Aimc+MrAZvmd+0XxaO5e8GcEFI9tLiAS/mC9cf+cB8hJfZqKPgVqZ5kfrG4GEC4ymQkZ+Uhbitc51+ml/8I5/3rkc7+cRDG7zn7e6k+E1TLPM/UYett8Qu60hK+QUA7ZgUIXbTOVIKzR/mluTfY38MOxNlLeLV6cSqyRj+OnXZw5H4rR/s/sKRscgS3oedj5lWQiwLED4PhqCnbLFTncC0FPIr8C3o3UKFK3jRlVGm1gAMJWDkFu/EM5K6HAP2SRBQBfC9wACjsqLyRw9jjIeoVD4vFsK9KJdvfgKh/w+UZR3vySrd2pn3L3/7B/+TNEdex3UpzePmHsfGkWPsqULO/OahpEmxS9BUpiqgTQkousaWEG5F9Zv+oJHvFgcAmMSXUGCWepiWhtNDYROnQwj2mNb1+GZv58bhzMLU6l2BXBxIs2Kju8RMLnFi+0vzUyo8pIQT0a0Up/rI40ljkuEzuw683TeryThUAwfFuqMHE/RalWkdujLpigJZS5E/5nNX+MZsCUv7v34PdMFWrkxr/6K/JnwamgNcmU1WKweYwGxIsorDqGEEGkjpbOt1ynZg3KEiLMlEkCMQpLJ1oAptItw8CnGJufHndoZIGktMffYSa+Xe4Gi7ficU25K4ckMRsAJzr9Zzub2Sr4wx8hswafos3xhgpXKOQk8EiUnRo=
- secure: iKV7rjdri+dxUlyr0C01195QFREbfIt0nL1ocdMrxDZdp8hb25pDl3UPrbC8pBSHIfOvbucfN7BMukS4EsD3Jxw0YCInwwUR5hZRZkiegU5TuUdzKHpbSCHl8+gtv9IcQKSYryHeFGAtCnW+52XIlNkLH8pzjKJyLkMB/uIVDdcQn1az7t8MR21ucTJdyGf/oJBmabmq9nwqEgumA+Ei+6J+/jdzK+M3do1iON1yHFJS2yGU21QdRIRxvEIat8Ss6JV/nfWFMbWQH/YRHKTrMXkgscqgDB/hJtfDgIvlObgsssrScRSoOm3a7vKEn4OoefUV0oFsPBrCKYEjWMqyEutz/nX25bV2gytrKbzyurI8Qr1QMJhcFZiobLkhMWTyAS/lJqQl45/Ffxj2pJFiUXvKCz+dwKYaQ/zjAu2ZUhxFw4f7KR7yTz3ifQFHy6imZ/1P/J7LLLiMXENN2xQCP80nsuLdRVFFms3z/nSbm/dLosudWHWu+x0tdbMd9XswfRqcaAr2WePNbGLAzb3mivKoP1hIG7yMVgc6dnLWoH2QPtcSdwSsBkkUZPMMRrk4Hy1GqYGPrqJ+CuHhffRKlnL+Irj3uMO0Uxxl0w/YK6h4UJu6bnvIsLIKNR84ZeoQqm8q10tXOZrlInAYYfYthRumBzNNNeCfneTHeqRL/PI=
before_deploy: before_deploy:
- export RELEASE_FILE_NAME=$(ls ../*.deb) - export RELEASE_FILE_NAME=$(ls ../*.deb)
after_deploy: after_deploy:
@ -41,7 +56,7 @@ deploy:
skip_cleanup: true skip_cleanup: true
file_glob: true file_glob: true
api_key: api_key:
secure: k0Ms4zQL6KTWInxaS2G578OxmG2aJSicezcGESsDHg3RLI7zgyx4jn+3IdoGfZucXmMxjwPFpBvoVBYfJ4GY5ZrgV8ftvnReO7xn8obADtOmSupTy5eUX5S/K+b8VdjD/QQRO9Bn9lz7ekTauMqtv2usw93X3RTDFtEAtLwtBEuGMU4dhU1lHC/1HDxa0BGfhuEOsp9eedA641dwq3kVpw/6WRlpdyNLEL6l7HJ2ednOH+DXb5hTwSF+Wbg/Oe/pobn8xpFvYc8ZmlRVpiE0kL3lA4HZ5gdBCHAs9HuNsK8e3pKn9l71zqEFdZdbUylp/fFeN5uLYMnZSMKBOg03lRhtsICm6IN7d91Hazcd+vox5Jh0EBgKsEgrAoDSMjiMRj1ROnZXWgs/DYZh8nV+y23hY3BlvyD2AjwyxCHRLG4sIkGmhxe3EoaW1vBwZ4/QUp7AL6x9povUsJM4kU6sBu0+QaoKk1NKs+2xW4mpktS5i2WHuR/sJcmf8AWDkuTejSKBzmKJoSb2dluRYKHa7EpobA7hiCz+6Und13sGJDvF46QprCkuVmDeQc1wImpVj2Evn0KLRRq4z33mEtoMMbROJ1Pg7pXdaTvl9AxDHn60NIbfr7lWjcYIvaOpPSax5vCD6w2lDToDbwj/4K5mh80/bhOyWVCrfcJxQOYqxxQ= secure: dmGlVHwZYiYEucvDsT4dVAkXRhD0DNM9Xrt5ALpwMdhH2nyu38E8aDXzMpRg4dR0DFAmhOIajOxBl4m+WhTAagZr4djND282+8u7YgTKKWaSCXdUmp7tJDvj7YtReJ2DpcLq/ydEwrvO5Ayt2RVZb1yiw8TXNw6hRaVwfcqNcQ0LFFgz8UwBXgrVaasJACQWU1T0kfG74Q3NuPU/CwKhPvaciMClw29n6eMBtNBV8lGLFFw5g/JnmMQrm4BcqeeuNEM3w4vWVUcETIhsOi69iotkWKcWNwXed48A/YvzK+UFefq/ErKmdiDVe6yseEUuF2d+04mSegqTOAho9QTMonmJcMnnyC3kYmcAcMYPTjDgJjot7AsBmCQvn9dppDeI4EUmdA4bMhQ/Gtg0W/dfpj3zQymrOhSIp/WiA1LLAuNegsTmBWXz8wQnize9c5GDKlpnIWhSm9aj3JVXVcY0HREUJ0uM/vCvXen5j48/aVvBU4R/KUlWRLKVn8XpKa4jVzcFI6gGF9yXMhyQ86mgLsM/v8n+4poBYud6nUL6hQHGd+COZ8vVG3NV+eHQrL/yXMMxMQHBajktLhL5+N6R89nvaVYDKPFHAV94vpSt35sTEmuLy9p08fyDxA8HdW/hxljzUCPWNXyRF95qHteRhd54d536X/JaIMOgV938k6A=
file: "${RELEASE_FILE_NAME}" file: "${RELEASE_FILE_NAME}"
on: on:
tags: true tags: true

View file

@ -4,35 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [0.8.0] - unreleased ## [Unreleased] - dev
### Added ### Added
### Changed ### Changed
### Fixed ### Fixed
## [0.7.0] - 2019-02-21
### Added
- new settings dialog options for hardware contolling
- moved calibration button to settings dialog
- added new configuraitons in general settings tab
- prepared platform independet firmware setup (aka cyclop compatible mode)
- api route for live log stream
- api route for debug log zip download
- new firmware version
- made fabscan discoverable in find.fabscan.org
- apscheduler library for registery servcie and future scheduling tasks
- added meshmixer to package dependencies
- added avrdude config to package dependencies
### Changed
- replaced old image build script by a new one, based on official raspbian build scripts
- FSUpdate is working for different stages now
### Fixed
- fixed camera driver (pi and usb)
- fixed random artifacts at the beginning of object scan
## [0.6.0] - 2018-11-23 ## [0.6.0] - 2018-11-23
### Added ### Added
- introduced Tornado Web Framework - introduced Tornado Web Framework

15
debian/changelog vendored
View file

@ -1,18 +1,3 @@
fabscanpi-server (0.7.0) UNRELEASED; urgency=medium
* api route for live log stream
* api route for debug log zip download
* new firmware version
* made fabscan discoverable in find.fabscan.org
* apscheduler library for registery servcie and future scheduling tasks
* added meshmixer to package dependencies
* added avrdude config to package dependencies
* replaced old image build script by a new one, based on official raspbian build scripts
* FSUpdate is working for different stages now
* fixed camera driver (pi and usb)
* fixed random artifacts at the beginning of object scan
-- Mario Lukas <info@fabscan.org> Thu, 21 Feb 2019 22:47:00 +0100
fabscanpi-server (0.6.0) UNRELEASED; urgency=medium fabscanpi-server (0.6.0) UNRELEASED; urgency=medium
* refactored webserver backend code * refactored webserver backend code
* introduced Tornado web framework * introduced Tornado web framework

2
debian/control vendored
View file

@ -10,6 +10,6 @@ Package: fabscanpi-server
Architecture: all Architecture: all
Homepage: http://fabscan.org Homepage: http://fabscan.org
X-Python-Version: ${python:Versions} X-Python-Version: ${python:Versions}
Depends: ${misc:Depends}, ${python:Depends}, meshlab, xvfb, avrdude, strace, python-opencv, python-funcsigs, python-apscheduler, python-tornado, libtbb2, python-pil, python-serial, python-pykka, python-picamera, python-requests, python-rpi.gpio, python-semver, xvfb, meshlab, strace, avrdude, python-scipy Depends: ${misc:Depends}, ${python:Depends}, python-opencv, python-tornado, libtbb2, python-pil, python-serial, python-pykka, python-picamera, python-rpi.gpio, python-semver, xvfb, meshlab, strace, avrdude, python-scipy
Description: Description:
FabScanPi Server ist the backend of the Stand-alone, Web-enabled, Open Source 3D laser scanner. FabScanPi Server ist the backend of the Stand-alone, Web-enabled, Open Source 3D laser scanner.

3
debian/postinst vendored
View file

@ -11,9 +11,6 @@ LOG_DIR=/var/log/fabscanpi
SCANS_DIR=/var/scans SCANS_DIR=/var/scans
PID_DIR=/var/run/fabscanpi PID_DIR=/var/run/fabscanpi
chmod 777 /usr/bin/autoreset
chmod 777 /usr/bin/avrdude-autoreset
# Allow $FABSCAN_USER to change the config and setting files # Allow $FABSCAN_USER to change the config and setting files
chown -R $FABSCAN_USER:nogroup $CONF_DIR chown -R $FABSCAN_USER:nogroup $CONF_DIR

8
debian/preinst vendored
View file

@ -10,12 +10,6 @@ SERVICE=fabscanpi-server
INIT_SCRIPT=/etc/init.d/$SERVICE INIT_SCRIPT=/etc/init.d/$SERVICE
SCANS_DIR=/var/scans SCANS_DIR=/var/scans
echo "KERNEL=="ttyAMA0", SYMLINK+="ttyS0",GROUP="dialout",MODE:=0666" > /etc/udev/rules.d/80-arduinopi.rules
if [ -f /etc/inittab ]; then
sed -i -e 's/T0:23:respawn:/#T0:23:respawn:/g' /etc/inittab
fi
if ps ax | grep -v grep | grep -v $0 | grep $SERVICE > /dev/null if ps ax | grep -v grep | grep -v $0 | grep $SERVICE > /dev/null
then then
if [ -f $INIT_SCRIPT ];then if [ -f $INIT_SCRIPT ];then
@ -27,6 +21,4 @@ fi
adduser --system $FABSCAN_USER --home $SCANS_DIR --no-create-home > /dev/null 2>&1 || true adduser --system $FABSCAN_USER --home $SCANS_DIR --no-create-home > /dev/null 2>&1 || true
usermod -a -G dialout -G pi -G sudo -G tty $FABSCAN_USER usermod -a -G dialout -G pi -G sudo -G tty $FABSCAN_USER
usermod -a -G dialout -G pi -G sudo -G tty pi
exit 0 exit 0

View file

@ -239,8 +239,7 @@ for 1 turntable stepper motor, 1 PiCam and 1 laser.
| (white square) | Ground (GND) | | (white square) | Ground (GND) |
| 5V | 5V output from regulator to FabScanPi HAT | | 5V | 5V output from regulator to FabScanPi HAT |
For the DC/DC converter option you can find further instructions and pictures on the [Watterott electronic website](https://learn.watterott.com/fabscan/hat_assembly.pdf). For the DC/DC converter option you can find further instructions and pictures on the [Watterott electronic website](https://github.com/watterott/RPi-FabScan-HAT/blob/master/hardware/RPi-FabScan-HAT_Assembly.pdf).
NOTE: For the final stage of constuction a more powerful power supply is needed. At the moment there are no technical specifications available. NOTE: For the final stage of constuction a more powerful power supply is needed. At the moment there are no technical specifications available.

View file

@ -1,19 +1,15 @@
var _paq = _paq || [];
var _paq = window._paq || []; _paq.push(["setCookieDomain", "*.fabscan.org"]);
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(['trackPageView']);
_paq.push(["setDocumentTitle", document.domain + "/" + document.title]); _paq.push(['enableLinkTracking']);
_paq.push(["setCookieDomain", "*.fabscan.org"]); (function() {
_paq.push(["setDomains", ["*.fabscan.org","*.www.fabscan.org"]]); var u="http://analytics.mariolukas.de/";
_paq.push(['trackPageView']); _paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['enableLinkTracking']); _paq.push(['setSiteId', 3]);
(function() {
var u="//analytics.mariolukas.de/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '3']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})(); })();
$.get('https://api.github.com/repos/mariolukas/FabScanPi-Build-Raspbian/releases/latest', function (data) { $.get('https://api.github.com/repos/mariolukas/FabScanPi-Build-Raspbian/releases/latest', function (data) {
var asset = data.assets[0]; var asset = data.assets[0];
var downloadCount = 0; var downloadCount = 0;

Binary file not shown.

View file

@ -1 +0,0 @@
mkdocs<=0.16.1

View file

@ -1,10 +1,7 @@
pyserial pyserial >=3.0
pillow pillow ==2.7
Pykka Pykka >=1.2
numpy numpy >=1.9
semver semver >=2.0
tornado tornado
mock mock
requests
apscheduler
funcsigs

View file

@ -113,7 +113,6 @@ def params():
('/usr/share/fabscanpi/js/',['src/www/js/app.js', 'src/www/js/lib.js']), ('/usr/share/fabscanpi/js/',['src/www/js/app.js', 'src/www/js/lib.js']),
('/usr/share/fabscanpi/js/locales/en/',['src/www/js/locales/en/i18n.js']), ('/usr/share/fabscanpi/js/locales/en/',['src/www/js/locales/en/i18n.js']),
('/usr/share/fabscanpi/locales/de/',['src/www/js/locales/de/i18n.js']), ('/usr/share/fabscanpi/locales/de/',['src/www/js/locales/de/i18n.js']),
('/usr/bin/', ['src/avrdude/autoreset','src/avrdude/avrdude-autoreset']),
('/usr/share/fabscanpi/icons/', ['src/www/icons/icon_mesh.svg','src/www/icons/icon_scan.svg','src/www/icons/icon_pointcloud.svg','src/www/icons/favicon.png', 'src/www/icons/spinner.gif', 'src/www/icons/logo.png']), ('/usr/share/fabscanpi/icons/', ['src/www/icons/icon_mesh.svg','src/www/icons/icon_scan.svg','src/www/icons/icon_pointcloud.svg','src/www/icons/favicon.png', 'src/www/icons/spinner.gif', 'src/www/icons/logo.png']),
('/usr/share/fabscanpi/fonts/', ['src/www/fonts/fontawesome-webfont.woff2', 'src/www/fonts/fontawesome-webfont.woff', 'src/www/fonts/fontawesome-webfont.ttf']), ('/usr/share/fabscanpi/fonts/', ['src/www/fonts/fontawesome-webfont.woff2', 'src/www/fonts/fontawesome-webfont.woff', 'src/www/fonts/fontawesome-webfont.ttf']),
('/usr/share/fabscanpi/style/fonts/', ['src/www/style/fonts/slick.woff', 'src/www/style/fonts/slick.ttf']) ('/usr/share/fabscanpi/style/fonts/', ['src/www/style/fonts/slick.woff', 'src/www/style/fonts/slick.ttf'])

BIN
src/.DS_Store vendored

Binary file not shown.

View file

@ -1,41 +0,0 @@
#!/usr/bin/python
# from https://github.com/mharizanov/avrdude-rpi
import RPi.GPIO as GPIO
import sys, os, re, time, fcntl
fd = sys.stdin.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
dtr = re.compile('.+TIOCM_DTR.+')
start = time.time()
pin = 7 # 7 = GPIO4
def reset():
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.HIGH)
time.sleep(0.12)
GPIO.output(pin, GPIO.LOW)
def process():
while True:
try:
duration = time.time() - start
input = sys.stdin.readline().strip()
if dtr.match(input):
reset()
return
elif duration > 2.0:
return
except:
continue
print "avrdude-original: Using autoreset DTR on GPIO Pin " +str(pin)
reset()
process()
GPIO.cleanup()
exit

View file

@ -1,8 +0,0 @@
#!/bin/bash
if [[ $@ == */dev/ttyS0* || $@ == */dev/ttyAMA0* ]];
then
sudo strace -o "| tail -n +1 | autoreset" -eioctl sudo /usr/bin/avrdude $@;
else
sudo /usr/bin/avrdude $@;
fi

View file

@ -8,10 +8,8 @@ import time
import threading import threading
import logging import logging
import multiprocessing import multiprocessing
from apscheduler.schedulers.background import BackgroundScheduler
from fabscan.FSVersion import __version__ from fabscan.FSVersion import __version__
from fabscan.FSEvents import FSEventManagerInterface, FSEvents from fabscan.FSEvents import FSEventManagerInterface, FSEvents
from fabscan.worker.FSMeshlab import FSMeshlabTask from fabscan.worker.FSMeshlab import FSMeshlabTask
from fabscan.FSConfig import ConfigInterface from fabscan.FSConfig import ConfigInterface
@ -19,7 +17,6 @@ from fabscan.FSSettings import SettingsInterface
from fabscan.scanner.interfaces.FSScanProcessor import FSScanProcessorCommand, FSScanProcessorInterface from fabscan.scanner.interfaces.FSScanProcessor import FSScanProcessorCommand, FSScanProcessorInterface
from fabscan.lib.util.FSInject import inject, singleton from fabscan.lib.util.FSInject import inject, singleton
from fabscan.lib.util.FSUpdate import upgrade_is_available, do_upgrade from fabscan.lib.util.FSUpdate import upgrade_is_available, do_upgrade
from fabscan.lib.util.FSDiscovery import register_to_discovery
class FSState(object): class FSState(object):
IDLE = "IDLE" IDLE = "IDLE"
@ -49,7 +46,6 @@ class FSCommand(object):
UPDATE_CONFIG = "UPDATE_CONFIG" UPDATE_CONFIG = "UPDATE_CONFIG"
@inject( @inject(
settings=SettingsInterface, settings=SettingsInterface,
config=ConfigInterface, config=ConfigInterface,
@ -75,18 +71,9 @@ class FSScanner(threading.Thread):
self.eventManager.subscribe(FSEvents.ON_CLIENT_CONNECTED, self.on_client_connected) self.eventManager.subscribe(FSEvents.ON_CLIENT_CONNECTED, self.on_client_connected)
self.eventManager.subscribe(FSEvents.COMMAND, self.on_command) self.eventManager.subscribe(FSEvents.COMMAND, self.on_command)
self.scheduler = BackgroundScheduler()
self.scheduler.start()
self._logger.info("Job scheduler started.")
self._logger.info("Scanner initialized...") self._logger.info("Scanner initialized...")
self._logger.info("Number of cpu cores: " + str(multiprocessing.cpu_count())) self._logger.info("Number of cpu cores: " + str(multiprocessing.cpu_count()))
self.config = config
if bool(self.config.discoverable):
self.run_discovery_service()
self.scheduler.add_job(self.run_discovery_service, 'interval', minutes=30, id='register_discovery_service')
self._logger.info("Added discovery scheduling job.")
def run(self): def run(self):
while not self.exit: while not self.exit:
@ -161,11 +148,6 @@ class FSScanner(threading.Thread):
meshlab_task = FSMeshlabTask(event.scan_id, event.filter, event.format) meshlab_task = FSMeshlabTask(event.scan_id, event.filter, event.format)
meshlab_task.start() meshlab_task.start()
elif command == FSCommand.HARDWARE_TEST_FUNCTION:
self._logger.debug("Hardware Device Function called...")
self.scanProcessor.ask({FSEvents.COMMAND: FSScanProcessorCommand.CALL_HARDWARE_TEST_FUNCTION, 'DEVICE_TEST': event.device})
return
# Upgrade server # Upgrade server
elif command == FSCommand.UPGRADE_SERVER: elif command == FSCommand.UPGRADE_SERVER:
if self._upgrade_available: if self._upgrade_available:
@ -196,7 +178,6 @@ class FSScanner(threading.Thread):
} }
} }
eventManager.send_client_message(FSEvents.ON_CLIENT_INIT, message) eventManager.send_client_message(FSEvents.ON_CLIENT_INIT, message)
self.scanProcessor.tell({FSEvents.COMMAND: FSScanProcessorCommand.NOTIFY_HARDWARE_STATE}) self.scanProcessor.tell({FSEvents.COMMAND: FSScanProcessorCommand.NOTIFY_HARDWARE_STATE})
#self.scanProcessor.tell({FSEvents.COMMAND: FSScanProcessorCommand.NOTIFY_IF_NOT_CALIBRATED}) #self.scanProcessor.tell({FSEvents.COMMAND: FSScanProcessorCommand.NOTIFY_IF_NOT_CALIBRATED})
@ -209,13 +190,4 @@ class FSScanner(threading.Thread):
self.eventManager.broadcast_client_message(FSEvents.ON_STATE_CHANGED, {'state': state}) self.eventManager.broadcast_client_message(FSEvents.ON_STATE_CHANGED, {'state': state})
def get_state(self): def get_state(self):
return self._state return self._state
def run_discovery_service(self):
try:
hardware_info = self.scanProcessor.ask({FSEvents.COMMAND: FSScanProcessorCommand.GET_HARDWARE_INFO})
except:
hardware_info = "undefined"
register_to_discovery(str(__version__), str(hardware_info))

View file

@ -62,8 +62,6 @@ class Settings(SettingsInterface):
self.led.blue = settings.led.blue self.led.blue = settings.led.blue
self.led.green = settings.led.green self.led.green = settings.led.green
self.led.red = settings.led.red self.led.red = settings.led.red
self.show_laser_overlay = settings.show_laser_overlay
self.show_calibration_pattern = settings.show_calibration_pattern
def todict(self, obj, classkey=None): def todict(self, obj, classkey=None):

View file

@ -42,8 +42,8 @@
"height": 1232 "height": 1232
}, },
"preview_resolution": { "preview_resolution": {
"width": 800, "width": 320,
"height": 600 "height": 240
}, },
"rotate": "True", "rotate": "True",
"hflip": "True", "hflip": "True",
@ -51,12 +51,10 @@
"type": "PICAM" "type": "PICAM"
}, },
"serial": { "serial": {
"plattform_type": "fabscanpi", "baudrate": 115200,
"baudrate": 57600,
"autoflash": "True", "autoflash": "True",
"port": "/dev/ttyAMA0" "port": "/dev/ttyAMA0"
}, },
"texture_illumination": 140, "texture_illumination": 140,
"keep_raw_images": "True", "keep_raw_images": "True"
"discoverable": "True"
} }

View file

@ -11,9 +11,7 @@
"contrast": 10, "contrast": 10,
"saturation": 0 "saturation": 0
}, },
"resolution": 4, "resolution": 8,
"laser_positions": 1, "laser_positions": 1,
"color" : "True", "color" : "True"
"show_laser_overlay": "True",
"show_calibration_pattern": "True"
} }

View file

@ -19,11 +19,6 @@
"camera_matrix": [], "camera_matrix": [],
"distortion_vector": [], "distortion_vector": [],
"laser_planes": [ "laser_planes": [
{
"deviation": 0,
"distance": 0,
"normal": []
},
{ {
"deviation": 0, "deviation": 0,
"distance": 0, "distance": 0,
@ -47,22 +42,19 @@
"height": 1232 "height": 1232
}, },
"preview_resolution": { "preview_resolution": {
"width": 800, "width": 320,
"height": 600 "height": 240
}, },
"rotate": "True", "rotate": "True",
"hflip": "True", "hflip": "True",
"vflip": "False", "vflip": "False",
"type": "PICAM", "type": "PICAM"
"undistort": "False"
}, },
"serial": { "serial": {
"plattform_type": "fabscanpi", "baudrate": 115200,
"baudrate": 57600,
"autoflash": "True", "autoflash": "True",
"port": "/dev/ttyAMA0" "port": "/dev/ttyAMA0"
}, },
"texture_illumination": 140, "texture_illumination": 140,
"keep_raw_images": "True", "keep_raw_images": "True"
"discoverable": "True"
} }

View file

@ -1,798 +0,0 @@
:100000000C9443010C946B010C946B010C946B01E8
:100010000C946B010C946B010C946B010C946B01B0
:100020000C946B010C946B010C946B010C946B01A0
:100030000C946B010C946B010C946B010C946B0190
:100040000C9429080C946B010C9499080C94730877
:100050000C946B010C946B010C946B010C946B0170
:100060000C946B010C946B01CC01D201D801DE0120
:10007000E401EA01F0012B03320339034003470393
:100080005E034E035E0355034E414E494E4954599B
:10009000494E46CDCCCC3D0AD7233C17B7D1387753
:1000A000CC2B329595E6241FB14F0A000020410069
:1000B00000C84200401C4620BCBE4CCA1B0E5AAEB3
:1000C000C59D744D3131343B202D207265706F72A7
:1000D0007420706F736974696F6E20616E6420663E
:1000E00065656472617465004D3130303B202D20B0
:1000F000746869732068656C70206D6573736167DF
:1001000065004D32323B202D207475726E2072696D
:10011000676874206C61736572206F6666004D328B
:10012000313B202D207475726E20726967687420CF
:100130006C61736572206F6E004D32303B202D2054
:100140007475726E206C656674206C6173657220C4
:100150006F6666004D31393B202D207475726E201C
:100160006C656674206C61736572206F6E004D3132
:10017000383B202D2064697361626C65206D6F745B
:100180006F7273004D31373B202D20656E61626CBC
:1001900065206D6F746F727300473031205B542897
:1001A0007374657073295D205B4C2873746570737C
:1001B000295D205B46286665656472617465295D0A
:1001C0003B202D206D6F766500473030205B542832
:1001D0007374657073295D3B202D206C696E6561B9
:1001E00072206D6F766500436F6D6D616E64733A5A
:1001F000004661625363616E20472D434F4444457E
:1002000020496E74657270726574657220566572ED
:1002100073696F6E3A2000424144434845434B5353
:10022000554D20004241444C494E454E554D20000D
:100230003E0000000000240027002A000000000803
:10024000000201000003040700000000000000009D
:10025000010204081020408001020408102001025D
:100260000408102000000000250028002B000404D2
:10027000040404040404020202020202030303034E
:1002800003034C11BF0D11241FBECFEFD8E0DEBF1A
:10029000CDBF22E0A4E5B1E001C01D92A03AB207B3
:1002A000E1F711E0A0E0B1E0E6E4FFE202C0059072
:1002B0000D92A435B107D9F711E0C2E4D1E004C032
:1002C0002197FE010E945F16C134D107C9F70E9431
:1002D000CF0D0C9496170C940000FC01538D448DA7
:1002E000252F30E0842F90E0821B930B541710F0E1
:1002F000CF96089501970895FC01918D828D9817EE
:1003000061F0828DDF01A80FB11D5D968C91928DF9
:100310009F5F9F73928F90E008958FEF9FEF0895F6
:10032000FC01918D828D981731F0828DE80FF11DBF
:10033000858D90E008958FEF9FEF0895FC01918DDA
:10034000228D892F90E0805C9F4F821B91098F73D3
:100350009927089580E090E0892B29F00E941D08DC
:1003600081110C9400000895CF93DF9347705527B7
:1003700066277727FA013197EC01A881B981E73028
:10038000F10520F4EC5CFF4F0C945F161496ED9190
:10039000FC91159761E029C01496ED91FC91159799
:1003A00065E023C01496ED91FC91159764E01DC0A3
:1003B0001496ED91FC91159766E017C01496ED9197
:1003C000FC91159762E011C01496ED91FC91159780
:1003D0006AE00BC01496ED91FC91159768E005C09A
:1003E0001496ED91FC91159769E0DF91CF910994F6
:1003F000CF93DF93EC01CB01BA0126E030E040E07F
:1004000050E00E944016623071058105910559F156
:100410008CF46115710581059105F1F0613071056C
:1004200081059105C1F5E881F9810480F581E02D10
:1004300065E02DC0643071058105910511F1D4F09E
:10044000653071058105910531F5E881F9810480F8
:10045000F581E02D66E01BC0E881F9810480F5811B
:10046000E02D64E014C0E881F9810480F581E02D7D
:1004700061E00DC0E881F9810480F581E02D63E041
:1004800006C0E881F9810480F581E02D62E0CE01AB
:10049000DF91CF910994DF91CF9108954370552753
:1004A00066277727DC01ED91FC910480F581E02D32
:1004B000423051056105710571F043305105610508
:1004C000710559F0413051056105710511F065E084
:1004D00005C066E003C06AE001C069E00994CF93FB
:1004E000DF93EC01CB01BA0123E030E040E050E0C3
:1004F0000E944016613071058105910581F06230DE
:1005000071058105910591F0672B682B692BC1F46A
:10051000E881F9810480F581E02D64E00DC0E88177
:10052000F9810480F581E02D61E006C0E881F98160
:100530000480F581E02D62E0CE01DF91CF91099436
:10054000DF91CF9108954370552766277727DC0107
:10055000ED91FC910480F581E02D4230510561055B
:10056000710571F0433051056105710559F0413055
:1005700051056105710511F062E005C063E003C03B
:1005800061E001C060E009940F931F93CF93DF9364
:10059000EC01E881F9810480F581E02D8C010D5B8F
:1005A0001F4FD8018C91811102C060E001C062E050
:1005B000CE010995E881F9810480F581E02DD8010B
:1005C0008C91811102C061E001C063E0CE01099508
:1005D0008BA59CA58230910538F0880F991F880F54
:1005E000991F05970197F1F7E881F9810480F5815A
:1005F000E02DD8018C91811102C060E001C062E061
:10060000CE01DF91CF911F910F910994CF93DF938A
:10061000EC0120E030E0A9016B897C898D899E89FD
:100620000E94141618161CF4EFA5F8A902C0E9A937
:10063000FAA9DF91CF9109940F931F93DC011296D1
:10064000EC910E2F10E009301105C0F5F801E55CC2
:10065000FF4F0C945F16DC01ED91FC910084F18555
:10066000E02D29C0DC01ED91FC910284F385E02DA1
:1006700022C0DC01ED91FC910484F585E02D1BC0C6
:10068000DC01ED91FC910684F785E02D14C0DC01BE
:10069000ED91FC910088F189E02D0DC0DC01ED9118
:1006A000FC910288F389E02D06C0DC01ED91FC91FC
:1006B0000488F589E02D1F910F9109941F910F91E6
:1006C0000895CF93DF93FC012281222359F1EC019D
:1006D00061E083810E94080D61E08C810E94080D19
:1006E0008A81843011F0883039F461E08D810E9474
:1006F000080D61E08E8106C0833011F0863021F450
:1007000061E08D810E94080D8EA58F3F59F061E058
:100710000E94080D6DA581E068278EA5DF91CF911D
:100720000C94BB0CDF91CF910895CF93DF93FC0124
:100730002281222389F0EC010190F081E02D0480D8
:10074000F581E02D60E009958EA58F3F29F06DA51C
:10075000DF91CF910C94BB0CDF91CF910895CF9294
:10076000DF92EF92FF920F931F93CF93DF93EC01F1
:100770009A81943041F0983031F0933031F09630D6
:1007800021F012E003C014E001C013E02396E12C35
:10079000F12CC62ED12C01E0C6010E2C02C095957D
:1007A00087950A94E2F76C8180FD602789910E9409
:1007B000BB0C8FEFE81AF80AE11670F3DF91CF91C6
:1007C0001F910F91FF90EF90DF90CF900895FC0163
:1007D000848DDF01A80FB11DA35ABF4F2C91848DCA
:1007E00090E001968F739927848FA689B7892C93FF
:1007F000A089B1898C91837080648C93938D848D52
:10080000981306C00288F389E02D80818F7D808354
:100810000895EF92FF920F931F93CF93DF93EC0114
:1008200081E0888F9B8D8C8D981305C0E889F989AC
:10083000808185FD26C0F62E0B8D10E00F5F1F4FC7
:100840000F731127E02E8C8DE8120CC00FB607FC39
:10085000FACFE889F989808185FFF5CFCE010E9422
:10086000E703F1CF8B8DFE01E80FF11DE35AFF4F37
:10087000F0829FB7F8940B8FEA89FB8980818062B0
:100880000AC09FB7F894EE89FF896083E889F989E7
:1008900080818370806480839FBF81E090E0DF91DE
:1008A000CF911F910F91FF90EF900895CF93DF9319
:1008B000EC01888D8823C9F0EA89FB89808185FD58
:1008C00005C0A889B9898C9186FD0FC00FB607FCB9
:1008D000F5CF808185FFF2CFA889B9898C9185FFFA
:1008E000EDCFCE010E94E703E7CFDF91CF910895CE
:1008F0004F925F926F927F92AF92BF92CF92DF92B0
:10090000EF92FF920F931F93CF93DF93CDB7DEB794
:10091000C454D1090FB6F894DEBF0FBECDBF5C0141
:100920002A013B016801790123E042E064E0CE0145
:1009300001960E941F0A8AE0A816B10421F4CE0194
:1009400001960E94E30BC301B2010E94DE150C85E3
:100950001D852E853F85DC01CB01800F911FA21FD5
:10096000B31F088919892A893B89081719072A079B
:100970003B0741F0888B998BAA8BBB8BCE010196EC
:100980000E94CB08B701A601CE0101960E94BC0AC5
:10099000488959896A897B890C851D852E853F8503
:1009A000CCA0DDA0EEA0FFA004171507260737078F
:1009B00014F481E001C080E040175107620773071B
:1009C00069F0C114D104E104F104B1F325968FAFAD
:1009D0002597CE0101960E94690DDACFCC5BDF4FDF
:1009E0000FB6F894DEBF0FBECDBFDF91CF911F9140
:1009F0000F91FF90EF90DF90CF90BF90AF907F90DE
:100A00006F905F904F9008958F929F92AF92BF9298
:100A1000CF92DF92EF92FF920F931F93CF93DF93CA
:100A2000CDB7DEB7C454D1090FB6F894DEBF0FBE00
:100A3000CDBF6C017B018A0123E042E064E0CE017E
:100A400001960E941F0A8AE0C816D10421F4CE0143
:100A500001960E94E30BC701FF0CAA0BBB0B4C8550
:100A60005D856E857F85840F951FA61FB71F4889FA
:100A700059896A897B89481759076A077B0741F0BA
:100A8000888B998BAA8BBB8BCE0101960E94CB08D9
:100A9000B801110F880B990B0E948E13AB01BC019A
:100AA000CE0101960E94BC0ACC8CDD8CEE8CFF8CB2
:100AB00020E030E04AEF53E4C701B6010E948713FB
:100AC000882381F16CA97DA98EA99FA90E948E130C
:100AD0004B015C0120E030E04AEF53E4C701B6016E
:100AE0000E946C159B01AC01C501B4010E94ED137D
:100AF0000E94DE156CAB7DAB8EAB9FAB80E092E0CD
:100B0000A7E2B7E488AF99AFAAAFBBAF80E090E0AF
:100B1000AAEFB3E48C8F9D8FAE8FBF8FCE0101966D
:100B20000E94CB08488959896A897B898C859D8573
:100B3000AE85BF85481759076A077B0759F18CA115
:100B40009DA1AEA1BFA1892B8A2B8B2B51F0CE0189
:100B500001960E94690D882321F0CE0101960E9422
:100B6000CB0820E030E0A9016C897D898E899F89BE
:100B70000E9487138111E3CF488959896A897B894B
:100B80008C859D85AE85BF85481759076A077B0709
:100B9000B1F6C8CFCC5BDF4F0FB6F894DEBF0FBE07
:100BA000CDBFDF91CF911F910F91FF90EF90DF901C
:100BB000CF90BF90AF909F908F9008958F929F920B
:100BC000AF92BF92CF92DF92EF92FF926A017B01C8
:100BD0000E94380BA7019601C701B6010E941916A1
:100BE000882319F082E391E01AC046015701E89486
:100BF000B7F82FEF3FEF4FE75FE7C501B4010E9461
:100C0000191681110FC02FEF3FEF4FE75FE7C501C6
:100C1000B4010E94871318162CF486E391E00E9419
:100C2000380B76C02FEF3FEF4FE75FE4C701B60107
:100C30000E94141618161CF48AE391E0F0CF2FEFEF
:100C40003FEF4FE75FECC701B6010E94871387FDB6
:100C5000F3CF20E030E0A901C701B6010E9487135D
:100C600087FF09C06DE284EA91E00E940904F7FA67
:100C7000F094F7F8F0942AE037ED43EA5BE3C7011C
:100C8000B6010E9400154B015C010E94E5156B0145
:100C90007C010E948C139B01AC01C501B4010E9430
:100CA000FF144B015C014AE0C701B6010E94730BBF
:100CB0006EE284EA91E00E94090420E030E040E224
:100CC00051E4C501B4010E94ED134B015C010E9487
:100CD000E5156B01E12CF12C4AE0C701B6010E9439
:100CE000730BC701B6010E948C139B01AC01C501B7
:100CF000B4010E94FF1420E030E040E251E40E9481
:100D0000ED130E94E51580E090E04AE00E94730B2D
:100D10008EE391E0FF90EF90DF90CF90BF90AF9087
:100D20009F908F900C94380BFF920F931F93CF934B
:100D3000DF93F82E8B01C0919401D0919501CC5A8C
:100D4000DE4F84E591E00097B9F0FC012081222379
:100D500099F08C179D0780F42F1108C00196DF9140
:100D6000CF911F910F91FF900C94401360E270E0BF
:100D70000E948B170196E7CFC801DF91CF911F9199
:100D80000F91FF9008958F929F92BF92CF92DF9222
:100D9000EF92FF920F931F93CF93DF93CDB7DEB700
:100DA00029970FB6F894DEBF0FBECDBF962F50E047
:100DB00060E070E0592B682BCB01AA27BB27152FC9
:100DC000B82EBC01812C912CA0E0B0E020E030E0F6
:100DD000809187029091880228173907E0F5809169
:100DE0008C02882371F0869F7001879FF00C11247C
:100DF000819F600111240D2D849FC0011124592F62
:100E000003C0542F012FFB2CE0909202D0908F0250
:100E100080918D0290918E02ED1003C08A0F9B1F6E
:100E200007C0880D991D6C01CE0CD11CF6011082F3
:100E3000E0908F026C01CE0CD11CF601F082F09094
:100E40009002FC01EF0DF11D008300919102800FD3
:100E5000911DFC0150832F5F3F4F1396F4E08F0EDE
:100E6000911C2031310509F0B3CF80918D02909112
:100E70008E02892B09F4A1C00E94440D00919302B7
:100E8000109194022091950230919602DC01CB01E1
:100E9000801B910BA20BB30BC297A105B10560F3A8
:100EA000F8948091890290918A029A838983E091D3
:100EB0008D02F0918E02DF011196808189879091D9
:100EC0008502E0919702F09198028091990299230E
:100ED00009F42EC09081982B988790818095892362
:100EE0008F838F818C8388E08B8358856F814985C0
:100EF0003B812C8189819A81508347FD252F3A952A
:100F00002083262F39F0441F00C0000060830000BA
:100F100000C0F2CF38E04D9160830000019761F787
:100F2000F0939802E093970249873B832C8338C063
:100F30009081982B98879081809589238F838F81CA
:100F40008E8388E08D8358856F8149853D812E8110
:100F500089819A81508347FD252F00C000C02083DE
:100F600000C000C000C000C000C060830000262F89
:100F70003A9541F0441F000000C000C000C000C00E
:100F800000C0E8CF38E04D9100C0608300C00197F9
:100F900009F7F0939802E093970249873D832E83E7
:100FA0009A83898378940E94440D6093930270938E
:100FB0009402809395029093960229960FB6F89426
:100FC000DEBF0FBECDBFDF91CF911F910F91FF907C
:100FD000EF90DF90CF90BF909F908F900895CF9229
:100FE000DF92EF92FF920F931F93CF93DF936C01E9
:100FF0007A018B01C0E0D0E0CE15DF0581F0D80189
:101000006D918D01D601ED91FC910190F081E02D63
:10101000C6010995892B11F02196EECF7E01C701FB
:10102000DF91CF911F910F91FF90EF90DF90CF90C4
:101030000895089580E090E0089584EA91E00E9488
:101040009E0121E0892B09F420E0822F08950E945F
:1010500086171F920F920FB60F9211242F933F9372
:101060008F939F93AF93BF9380919C0190919D012B
:10107000A0919E01B0919F0130919B0123E0230F2D
:101080002D3720F40196A11DB11D05C026E8230FC0
:101090000296A11DB11D20939B0180939C0190930A
:1010A0009D01A0939E01B0939F018091A00190911A
:1010B000A101A091A201B091A3010196A11DB11DB2
:1010C0008093A0019093A101A093A201B093A301EA
:1010D000BF91AF919F918F913F912F910F900FBE34
:1010E0000F901F9018951F920F920FB60F92112418
:1010F0002F933F934F935F936F937F938F939F9320
:10110000AF93BF93EF93FF9384EA91E00E94E703CC
:10111000FF91EF91BF91AF919F918F917F916F91CF
:101120005F914F913F912F910F900FBE0F901F90A5
:1011300018951F920F920FB60F9211242F938F9331
:101140009F93EF93FF93E091B401F091B5018081FB
:10115000E091BA01F091BB0182FD12C090818091B3
:10116000BD018F5F8F732091BE01821751F0E09116
:10117000BD01F0E0EC55FE4F958F8093BD0101C09D
:101180008081FF91EF919F918F912F910F900FBED2
:101190000F901F9018954F925F926F927F928F924F
:1011A0009F92AF92BF92CF92DF92EF92FF920F93F6
:1011B0001F93CF93DF93EC018F849888A988BA8816
:1011C0008B859C85AD85BE85881A990AAA0ABB0ABB
:1011D0006B897C898D899E899B01AC010E94ED13EE
:1011E0006B017C016B8D7C8D8D8D9E8D9B01AC0187
:1011F0000E9400159B01AC01C701B6010E946C154D
:101200000E94DE1581149104A104B10499F46230A6
:101210007105810591050CF079C01BA21CA21DA2CD
:101220001EA21B8A1C8A1D8A1E8A1BAA1CAA1DAA12
:101230001EAAF4C00BA91CA92DA93EA9FE01ED5BB5
:10124000FF4F181419041A041B04FCF4101611069D
:10125000120613064CF4681579058A059B054CF5B2
:101260002081211153C025C001151105210531052B
:1012700009F44CC0681579058A059B050CF046C039
:101280008081882309F442C036C010161106120668
:101290001306ECF4002711279801081919092A09E7
:1012A0003B0960177107820793071CF420812223F2
:1012B00069F19B01AC0188279927DC01821B930B04
:1012C000A40BB50B8BAB9CABADABBEAB1FC001157C
:1012D000110521053105D1F0CC24DD247601C81893
:1012E000D908EA08FB086C157D058E059F0574F486
:1012F000808181110BC030952095109501951F4F6D
:101300002F4F3F4F0BAB1CAB2DAB3EABCBA8DCA89C
:10131000EDA8FEA88E010D5B1F4FC114D104E1049E
:10132000F10491F48FA998ADA9ADBAAD8BAF9CAF84
:10133000ADAFBEAF81E0181419041A041B040CF001
:1013400080E0F80180833EC08BAC9CACADACBEAC01
:10135000A5019401C501B4010E9400152B013C01B7
:10136000C701B6010E948E1320E030E040E850E44F
:101370000E94ED1320E030E040E85FE30E9400159A
:101380009B01AC01C301B2010E946C159B01AC0131
:10139000C501B4010E94FF142B013C01FE01FF9620
:1013A00080809180A280B3809401A5010E941416D0
:1013B000181614F442015301C401D5018BAF9CAF40
:1013C000ADAFBEAFFFEFCF1ADF0AEF0AFF0ACBAA1D
:1013D000DCAAEDAAFEAACBACDCACEDACFEACC7013E
:1013E000B6010E94E5156BA37CA38DA39EA3A70164
:1013F000960160E074E284E799E40E946C156B8BBF
:101400007C8B8D8B9E8BF8012081211107C0DC0124
:10141000CB01B0588B8B9C8BAD8BBE8BDF91CF916A
:101420001F910F91FF90EF90DF90CF90BF90AF9002
:101430009F908F907F906F905F904F9008958F92C4
:101440009F92AF92BF92CF92DF92EF92FF92CF9393
:10145000DF93EC018AE091E0998388836A831B869D
:101460001C861D861E861F86188A198A1A8A1B8A60
:101470001C8A1D8A1E8AC12CD12C80E8E82E8FE39D
:10148000F82ECF8AD88EE98EFA8E1B8E1C8E1D8E7A
:101490001E8ECF8ED8A2E9A2FAA21BA21CA21DA268
:1014A0001EA281E090E09CA78BA78FEF8EA71FA2C2
:1014B00018A619A61AA64B832C8384E08D8385E099
:1014C0008E831BAA1CAA1DAA1EAA1FAA18AE19AE9B
:1014D0001AAE1BAE1CAE1DAE1EAEFE01FF96C08244
:1014E000D182E282F382349610821F821886198696
:1014F0001A86CE010E9461038B8C9C8CAD8CBE8CB5
:10150000A7019601C501B4010E948713882349F100
:101510006BA97CA98DA99EA90E948E13A501940197
:101520000E94ED130E94DE156BAB7CAB8DAB9EABC6
:1015300086E896E6A9E6B9E48FAB98AFA9AFBAAF53
:10154000CB8EDC8EED8EFE8ECE01DF91CF91FF90A3
:10155000EF90DF90CF90BF90AF909F908F900C94C2
:10156000CB08DF91CF91FF90EF90DF90CF90BF90AD
:10157000AF909F908F9008954F925F926F927F925D
:10158000AF92BF92CF92DF92EF92FF920F931F9391
:10159000CF93DF93EC015A018B019A01AB016B8968
:1015A0007C898D899E890E948713882309F451C004
:1015B000CF88D88CE98CFA8C2601370177FA7094A1
:1015C00077F87094A3019201B501C8010E948713B6
:1015D00087FD0BC0A7019601B501C8010E94141632
:1015E00018162CF06501780102C07301620120E039
:1015F00030E0A901C701B6010E948713811105C01F
:101600001BA21CA21DA21EA220C0A701960160E081
:1016100074E284E799E40E946C159F770E94E515B7
:101620006BA37CA38DA39EA35E0183E4A80EB11CD3
:1016300011E020E030E0A901C701B6010E941416B4
:1016400018160CF010E0F5011083CB8ADC8AED8AC5
:10165000FE8ADF91CF911F910F91FF90EF90DF9065
:10166000CF90BF90AF907F906F905F904F90089514
:10167000009769F0FC0101900020E9F73197AF0174
:10168000481B590BBC0184EA91E00C94EF0780E001
:1016900090E008950F931F93CF93DF938C01C0E0E8
:1016A000D0E0F801EC0FFD1F6491662341F084EA5D
:1016B00091E00E940904892B11F02196F2CFCE010E
:1016C000DF91CF911F910F910895CF93DF930E94E7
:1016D0004A0BEC018EE391E00E94380B8C0F9D1FAA
:1016E000DF91CF9108958F929F92AF92BF920F9307
:1016F0001F93CF93DF93CDB7DEB7A1970FB6F894C2
:10170000DEBF0FBECDBF19A2423008F44AE08E0101
:101710000F5D1F4F842E912CA12CB12CA50194019B
:101720000E941E16E62FB901CA0101501109EA30C4
:1017300014F4E05D01C0E95CD801EC93232B242B69
:10174000252B61F7C8010E94380BA1960FB6F894BB
:10175000DEBF0FBECDBFDF91CF911F910F91BF9024
:10176000AF909F908F900895CF92DF92EF92FF926B
:10177000CF93DF936B017C016DE284EA91E00E94DC
:101780000904EC0166277727CB016C197D098E09C6
:101790009F094AE00E94730B8C0F9D1FDF91CF9130
:1017A000FF90EF90DF90CF900895CF93DF930E944A
:1017B000380BEC018EE391E00E94380B8C0F9D1FDB
:1017C000DF91CF910895FC01A1E4B2E012968C91D3
:1017D0001297828313968C911397838314968C911E
:1017E0001497848315968C911597858316968C9102
:1017F0001697868317968C911797878318968C91E6
:101800001897808719968C91199781871A968C91D1
:101810001A9782871B964D915D916D917C911E97D1
:1018200043875487658776871F964D915D916D91AB
:101830007C9152974787508B618B728B53964D9159
:101840005D916D917C915697438B548B658B768B14
:1018500057964D915D916D917C915A97478B508F22
:10186000618F728F5B964D915D916D917C915E97CA
:10187000438F548F658F768F5F964D915D916D91FB
:101880007C919297478F50A361A372A393964D9139
:101890005D916D917C91969743A354A365A376A324
:1018A00097964D915D916D917C919A9747A350A722
:1018B00061A772A79B968D919C919C9794A783A7F3
:1018C0009D968C919D9785A79E968C919E9786A7B5
:1018D0009F968D919C91D09790AB87A7D1968D9133
:1018E0009C91D29792AB81ABD3964D915D916D91C6
:1018F0007C91D69743AB54AB65AB76ABD7964D9105
:101900005D916D917C91DA9747AB50AF61AF72AF4B
:10191000DB968D919D910D90BC91A02D83AF94AFDE
:10192000A5AFB6AF409180025091810260918202D2
:1019300070918302DF01DF964D935D936D937C93ED
:1019400013978091840214968C93CF010895CF93BE
:10195000DF9397FF03C00E94B40B03C04AE00E94CC
:10196000730BEC018EE391E00E94380B8C0F9D1FEE
:10197000DF91CF91089590E0FC01E45CFD4F24914C
:10198000FC01E05BFD4F3491FC01E259FD4FE49115
:10199000EE2309F43CC0222339F1233091F038F4CE
:1019A0002130A9F0223001F584B58F7D12C0273097
:1019B00091F02830A1F02430B9F4809180008F7D1F
:1019C00003C0809180008F77809380000DC084B524
:1019D0008F7784BD09C08091B0008F7703C080915C
:1019E000B0008F7D8093B000F0E0EE0FFF1FEC5948
:1019F000FD4FA591B4919FB7F894611104C08C91EB
:101A00003095382302C0EC913E2B3C939FBF089544
:101A1000CF93DF9390E0FC01E05BFD4F2491FC014C
:101A2000E259FD4F8491882361F190E0880F991F5E
:101A3000FC01EE5CFD4FC591D491FC01EC59FD4FCA
:101A4000A591B491611109C09FB7F8948881209540
:101A500082238883EC912E230BC0623061F49FB700
:101A6000F8948881322F309583238883EC912E2B34
:101A70002C939FBF06C08FB7F894E8812E2B288344
:101A80008FBFDF91CF9108953FB7F8948091A00167
:101A90009091A101A091A201B091A30126B5A89BAC
:101AA00005C02F3F19F00196A11DB11D3FBFBA2FF0
:101AB000A92F982F8827820F911DA11DB11DBC0150
:101AC000CD0142E0660F771F881F991F4A95D1F715
:101AD0000895CF92DF92EF92FF92CF93DF93EC01C4
:101AE0000E94440D6B017C014FA158A569A57AA500
:101AF0008BA19CA1ADA1BEA1840F951FA61FB71FEE
:101B000084179507A607B70730F0C816D906EA0666
:101B1000FB0658F405C0C816D906EA06FB0638F1DC
:101B2000C416D506E606F70610F5FE01ED5BFF4F7D
:101B300020818B859C85AD85BE85222321F0019671
:101B4000A11DB11D03C00197A109B1098B879C8715
:101B5000AD87BE874B855C856D857E85CE010E94F5
:101B60001C03CFA2D8A6E9A6FAA681E001C080E0B6
:101B7000DF91CF91FF90EF90DF90CF90089580910B
:101B80008D0290918E02009711F00E94FD168091B7
:101B90008B0287FD03C060E00C94080D08957894D3
:101BA00084B5826084BD84B5816084BD85B5826062
:101BB00085BD85B5816085BD80916E008160809313
:101BC0006E0010928100809181008260809381007C
:101BD000809181008160809381008091800081608C
:101BE000809380008091B10084608093B1008091E7
:101BF000B00081608093B00080917A00846080930F
:101C00007A0080917A00826080937A0080917A00D5
:101C1000816080937A0080917A00806880937A0056
:101C20001092C100E091B401F091B50182E080838F
:101C3000E091B401F091B5011082E091B001F09112
:101C4000B1011082E091B201F091B30180E1808393
:101C50001092BC01E091B801F091B90186E0808357
:101C6000E091B601F091B701808180618083E091BD
:101C7000B601F091B701808188608083E091B60160
:101C8000F091B701808180688083E091B601F09186
:101C9000B70180818F7D808361E089E00E94080D1B
:101CA00061E08AE00E94080D61E08FE00E94080D6B
:101CB00060E08FE00E94BB0C60E089E00E94BB0CFA
:101CC00060E08AE00E94BB0C61E083E10E94080DA5
:101CD00060E083E10E94BB0C61E082E00E94080D9D
:101CE00061E085E00E94080D61E083E00E94080D3C
:101CF00061E086E00E94080D61E083E10E94BB0C78
:101D000020E030E04AEF54E46091580270915902AB
:101D100080915A0290915B020E948713882309F4F4
:101D200053C080E090E0AAEFB4E48093580290930F
:101D30005902A0935A02B0935B0280E090E0AAEFB0
:101D4000B3E48093800290938102A0938202B093C7
:101D500083028091740290917502A0917602B091F5
:101D60007702181619061A061B0674F560915402BC
:101D70007091550280915602909157029B01AC01DF
:101D80000E94ED136B017C0160915C0270915D0219
:101D900080915E0290915F029B01AC010E94001550
:101DA0009B01AC01C701B6010E946C150E94DE15B3
:101DB0006093740270937502809376029093770219
:101DC00081E492E00E94CB0840E050E06FE274E4CE
:101DD00081E492E00E94BC0A61E082E00E94BB0CB8
:101DE00080918B0287FD08C061E00E94080D60E0D1
:101DF00080918B020E94BB0C81E08093860261E09F
:101E000082E00E94BB0C61E085E00E94BB0C84EA8A
:101E100091E00E949E01181619060CF0FAC184EA9E
:101E200091E00E947C01C82F682F84EA91E00E9413
:101E3000090480919401909195018F3391055CF490
:101E40009C012F5F3F4F3093950120939401FC013B
:101E5000EC5AFE4FC083CA3011F0CD30C1F6E0918C
:101E60009401F0919501EC5AFE4F1082C0915401FB
:101E7000CB3309F4C5C16FEF7FEF8EE40E94940667
:101E8000092E000CAA0BBB0B8F3F2FEF9207A20766
:101E9000B20709F45CC0CE3409F059C0C090960175
:101EA000D0909701E0909801F09099018C159D05D4
:101EB000AE05BF0539F084E292E00E944A0BC701EB
:101EC000B6012FC06AE270E084E591E00E948B17B2
:101ED000892B09F495C1E4E5F1E0C0E09F012455A8
:101EE000314091919A3211F0C927F8CF60E070E04B
:101EF000C9018B5A9E4F0E94F2110E94DE152C2FB1
:101F0000CC0F330B2617370779F087E192E00E9458
:101F10004A0B609196017091970180919801909180
:101F200099010E94A70C6CC1809196019091970134
:101F3000A0919801B09199010196A11DB11D8093C6
:101F4000960190939701A0939801B09399016FEF38
:101F50007FEF87E40E9494068230910581F01CF4A3
:101F600097FF30C06EC08630910509F464C0873099
:101F7000910509F464C0049709F063C023C060E0D0
:101F800070E086E40E9494067C0160E070E08CE4DE
:101F90000E949406EC0160E070E084E50E949406E3
:101FA000009731F0A701BC018AE090E00E9404058F
:101FB000209709F446C0A701BE018BE090E00E9483
:101FC00004053FC060E070E086E40E949406BC0116
:101FD000990F880B990B0E948E136B017C0160E0B6
:101FE00070E08CE40E949406EC0160E070E084E50F
:101FF0000E949406009771F0BC01990F880B990B11
:102000000E948E13AB01BC01970186018AE090E02B
:102010000E9478042097A9F0BE01DD0F880B990B70
:102020000E948E13AB01BC01970186018BE090E00A
:102030000E94780406C081E080939A0102C0109249
:102040009A016FEF7FEF8DE40E9494068531910530
:1020500009F4ABC0CCF48131910509F49AC044F481
:102060008430910509F477C0059709F47CC0C8C095
:102070008331910509F494C00CF094C061E082E0D2
:102080000E94BB0C61E08AC08E36910509F494C0B1
:10209000ECF58631910509F48AC08436910509F082
:1020A000AFC081EF91E00E944A0B81E491E00E9471
:1020B000D50B87EE91E00E94650B89EC91E00E94C0
:1020C000650B89E991E00E94650B84E891E00E942C
:1020D000650B8EE691E00E94650B84E591E00E941D
:1020E000650B89E391E00E94650B8EE191E00E940F
:1020F000650B82E091E00E94650B88EE90E00E9403
:10210000650B83EC90E00E94650B7AC0883C9105DA
:1021100009F466C0893C910509F467C082379105CE
:1021200009F06EC040E050E0BA018CE491E00E94FA
:10213000DE0540E050E0BA0182E591E00E94DE0554
:1021400040E050E46CE176E48EE491E00E94DE052C
:1021500080E591E047C060E089E00E94BB0C60E050
:102160008AE00E94BB0C60E070E082E40E9494066A
:102170007C0160E070E087E40E949406EC0160E07E
:1021800070E082E50E949406A701BE010E94C3068A
:1021900037C060E082E00E94BB0C60E085E009C0CF
:1021A00061E001C060E08AE004C061E001C060E07D
:1021B00089E00E94BB0C24C0609196017091970148
:1021C0008EE40E949406092E000CAA0BBB0B809390
:1021D000960190939701A0939801B093990110C034
:1021E00081E491E00E94D50B0BC04AE061E070E011
:1021F00080E090E00E94730B8EE391E00E94380B28
:10220000109295011092940180E392E00E94650B78
:10221000FECD80919A018823E1F140E050E06AE729
:1022200074E481E492E00E94BC0A80914C02909197
:102230004D02A0914E02B0914F020A96A11DB11D10
:10224000409150025091510260915202709153029C
:1022500084179507A607B70761F080935002909303
:102260005102A0935202B093530281E492E00E9483
:10227000CB088091640290916502A0916602B091B2
:102280006702892B8A2B8B2B21F081E492E00E943C
:10229000690D0E94AA01BBCD1092A7011092A60160
:1022A00088EE93E0A0E0B0E08093A8019093A901AC
:1022B000A093AA01B093AB0184E291E09093A501B1
:1022C0008093A40185EC90E09093B1018093B001DC
:1022D00084EC90E09093B3018093B20180EC90E0A5
:1022E0009093B5018093B40181EC90E09093B70195
:1022F0008093B60182EC90E09093B9018093B8018D
:1023000086EC90E09093BB018093BA011092BD01DE
:102310001092BE011092BF011092C00124E043E070
:1023200062E081E492E00E941F0A109286021092FD
:102330008C021092930210929402109295021092C5
:10234000960281E08093920280938F021092900215
:1023500092E0909391028093850280E390E09093C5
:102360008A02809389020E94651690938E02809360
:102370008D02009761F020E3FC0111922A95E9F7A4
:1023800080E190E0909388028093870208C01092C9
:102390008A021092890210928802109287028FE0BE
:1023A00080938B0280918602882341F061E08FE068
:1023B0000E94080D60E08FE00E94BB0CEDE7F2E0A8
:1023C000E491F0E0EE0FFF1FEC59FD4F85919491E1
:1023D0009093980280939702EFE5F2E0E491E09306
:1023E00099020895A0E0B0E0E8EFF1E10C94BF1489
:1023F000EC016B016115710519F0FB01918380837C
:102400007E01FFEFEF1AFF0A0881802F90E00E9403
:102410005E13892B11F0E701F3CF0D3239F47E0101
:1024200082E0E80EF11C098111E008C00B3229F4AA
:102430007E0192E0E90EF11C098110E0E70121978D
:1024400043E050E060E970E0CE010E946713892B01
:10245000C1F4239645E050E06BE870E0CE010E94A5
:102460006713892B09F42596C114D10419F0F601DC
:10247000D183C0831111F6C060E070E080E89FE76F
:10248000FAC043E050E068E870E0CE010E946713B4
:10249000892B59F4C114D10409F4E9C0F2E0EF0E1C
:1024A000F11CF601F182E082E2C020E030E0A901F7
:1024B000C0E0D0E0F70180EDA82EA00E89E08A15DB
:1024C00030F1912F9260B92E812F887012FF04C0D5
:1024D000811124C0219622C081112197A5E0B0E08E
:1024E0000E94AE14DC01CB01880F991FAA1FBB1FED
:1024F0009C01AD012A0D311D411D511D283989E96D
:102500003807480789E1580748F0166006C09EEF73
:10251000A9120AC013FD40C01860B12E8FEFE81A4F
:10252000F80A00811B2DC6CF802F8F7D8534A1F541
:1025300080818D3211F4106106C08B3221F031960A
:1025400061E070E004C08181329662E070E0805307
:102550008A3018F0E61BF70B1FC060E070E06038AF
:102560009CE079075CF4DB01AA0FBB1FAA0FBB1F1D
:102570006A0F7B1F660F771F680F711D3196DF0191
:1025800011978C9180538A3050F314FF03C07195DA
:1025900061957109C60FD71F11FF08C0C114D1047E
:1025A00029F0CF010197F60191838083CA01B90117
:1025B0000E948C13212F2370233019F04B015C01F2
:1025C00006C04B015C01B7FAB094B7F8B09420E0B4
:1025D00030E0A901C501B4010E948713882309F4E2
:1025E0003EC0D7FF06C0D195C195D10907EA10E0DA
:1025F00002C00FEB10E06801F8E1CF1AD10890E2B9
:10260000E92EF12CCE15DF0574F0F80125913591F6
:1026100045915491C501B4010E94ED134B015C0139
:10262000CE19DF09EFCF04501109F594E7940C158A
:102630001D0541F78A2D880F8B2D881F8F3F49F08C
:1026400020E030E0A901C501B4010E948713811187
:1026500006C082E290E090939B0280939A02C501AB
:10266000B40109C060E070E080E89FEF04C060E062
:1026700070E080EC9FE7CDB7DEB7ECE00C94DB14A4
:10268000FC0188279927E89421912032E9F3293029
:1026900010F02E30C8F32B3241F02D3239F468940B
:1026A00004C00E947F13820F911D219120532A3074
:1026B000C0F31EF4909581959F4F089591110C944D
:1026C0005A14803219F089508550C8F70895FB01DB
:1026D000DC014150504088F08D9181341CF08B35E5
:1026E0000CF4805E659161341CF06B350CF4605E17
:1026F000861B611171F3990B0895881BFCCF7AE05A
:10270000979F902D879F802D910D112408950E94F1
:10271000C91308F481E00895E89409C097FB3EF4DA
:1027200090958095709561957F4F8F4F9F4F99231E
:10273000A9F0F92F96E9BB279395F695879577959C
:102740006795B795F111F8CFFAF4BB0F11F460FF5C
:102750001BC06F5F7F4F8F4F9F4F16C0882311F0B4
:1027600096E911C0772321F09EE8872F762F05C0C8
:10277000662371F096E8862F70E060E02AF09A9563
:10278000660F771F881FDAF7880F9695879597F958
:102790000895990F0008550FAA0BE0E8FEEF1616F2
:1027A0001706E807F907C0F012161306E407F50745
:1027B00098F0621B730B840B950B39F40A2661F0B9
:1027C000232B242B252B21F408950A2609F4A1405C
:1027D000A6958FEF811D811D08950E9400140C9411
:1027E00074140E94661438F00E946D1420F0952332
:1027F00011F00C945D140C94631411240C94A8141F
:102800000E94851470F3959FC1F3950F50E0551FFA
:10281000629FF001729FBB27F00DB11D639FAA2735
:10282000F00DB11DAA1F649F6627B00DA11D661F84
:10283000829F2227B00DA11D621F739FB00DA11DA5
:10284000621F839FA00D611D221F749F3327A00D5F
:10285000611D231F849F600D211D822F762F6A2FFB
:1028600011249F5750409AF0F1F088234AF0EE0F60
:10287000FF1FBB1F661F771F881F91505040A9F78D
:102880009E3F510580F00C945D140C94A8145F3F9A
:10289000E4F3983ED4F3869577956795B795F795C9
:1028A000E7959F5FC1F7FE2B880F911D9695879541
:1028B00097F9089599278827089597F99F6780E8E1
:1028C00070E060E008959FEF80EC089500240A9482
:1028D0001616170618060906089500240A941216FB
:1028E0001306140605060895092E0394000C11F42E
:1028F000882352F0BB0F40F4BF2B11F460FF04C0DB
:102900006F5F7F4F8F4F9F4F089557FD9058440F33
:10291000551F59F05F3F71F04795880F97FB991F3E
:1029200061F09F3F79F087950895121613061406FB
:10293000551FF2CF4695F1DF08C016161706180688
:10294000991FF1CF86957105610508940895E89463
:10295000BB2766277727CB0197F908950E94F014CB
:10296000A59F900DB49F900DA49F800D911D1124E3
:1029700008952F923F924F925F926F927F928F9223
:102980009F92AF92BF92CF92DF92EF92FF920F93FE
:102990001F93CF93DF93CDB7DEB7CA1BDB0B0FB608
:1029A000F894DEBF0FBECDBF09942A8839884888C5
:1029B0005F846E847D848C849B84AA84B984C8845B
:1029C000DF80EE80FD800C811B81AA81B981CE0F52
:1029D000D11D0FB6F894DEBF0FBECDBFED01089537
:1029E000A29FB001B39FC001A39F700D811D112450
:1029F000911DB29F700D811D1124911D0895505895
:102A0000BB27AA270E9417150C9474140E94661401
:102A100038F00E946D1420F039F49F3F19F426F429
:102A20000C9463140EF4E095E7FB0C945D14E92F0D
:102A30000E94851458F3BA17620773078407950735
:102A400020F079F4A6F50C94A7140EF4E0950B2E63
:102A5000BA2FA02D0B01B90190010C01CA01A001F0
:102A60001124FF27591B99F0593F50F4503E68F14B
:102A70001A16F040A22F232F342F4427585FF3CF8C
:102A8000469537952795A795F0405395C9F77EF45D
:102A90001F16BA0B620B730B840BBAF09150A1F0A6
:102AA000FF0FBB1F661F771F881FC2F70EC0BA0F2C
:102AB000621F731F841F48F4879577956795B795B4
:102AC000F7959E3F08F0B0CF9395880F08F09927AF
:102AD000EE0F9795879508950E9480150C947414B5
:102AE0000E946D1458F00E94661440F029F45F3F74
:102AF00029F00C945D1451110C94A8140C946314D7
:102B00000E94851468F39923B1F3552391F3951B23
:102B1000550BBB27AA2762177307840738F09F5FFE
:102B20005F4F220F331F441FAA1FA9F335D00E2E6B
:102B30003AF0E0E832D091505040E695001CCAF7D8
:102B40002BD0FE2F29D0660F771F881FBB1F26179B
:102B500037074807AB07B0E809F0BB0B802DBF0172
:102B6000FF2793585F4F3AF09E3F510578F00C9441
:102B70005D140C94A8145F3FE4F3983ED4F386955B
:102B800077956795B795F7959F5FC9F7880F911D62
:102B90009695879597F90895E1E0660F771F881F4E
:102BA000BB1F621773078407BA0720F0621B730B01
:102BB000840BBA0BEE1F88F7E09508950E94E51587
:102BC0006894B1110C94A81408950E948D1488F093
:102BD0009F5798F0B92F9927B751B0F0E1F0660FE1
:102BE000771F881F991F1AF0BA95C9F714C0B13022
:102BF00091F00E94A714B1E008950C94A714672FD8
:102C0000782F8827B85F39F0B93FCCF38695779550
:102C10006795B395D9F73EF4909580957095619539
:102C20007F4F8F4F9F4F08950E94C91308F48FEF75
:102C300008950E94C913880B990B0895A1E21A2EDA
:102C4000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F50
:102C5000A217B307E407F50720F0A21BB30BE40BA0
:102C6000F50B661F771F881F991F1A9469F76095E7
:102C70007095809590959B01AC01BD01CF010895A1
:102C8000052E97FB1EF400940E94571657FD07D09F
:102C90000E941E1607FC03D04EF40C945716509554
:102CA0004095309521953F4F4F4F5F4F0895909538
:102CB0008095709561957F4F8F4F9F4F0895EE0FD0
:102CC000FF1F0590F491E02D09940F931F93CF936C
:102CD000DF938230910510F482E090E0E0919E0253
:102CE000F0919F0220E030E0A0E0B0E0309719F1D1
:102CF000408151810281138148175907C8F0841718
:102D0000950769F4109731F012960C931297139669
:102D10001C9327C000939E0210939F0222C021158E
:102D2000310519F04217530718F49A01BD01EF015C
:102D3000DF01F801DBCF21153105F9F0281B390B34
:102D40002430310580F48A819B816115710521F061
:102D5000FB019383828304C090939F0280939E0221
:102D6000FE01329644C0FE01E20FF31F819391935E
:102D700022503109398328833AC020919C02309136
:102D80009D02232B41F420910201309103013093E5
:102D90009D0220939C022091000130910101211598
:102DA000310541F42DB73EB7409104015091050122
:102DB000241B350BE0919C02F0919D02E217F30772
:102DC000A0F42E1B3F0B2817390778F0AC014E5F9B
:102DD0005F4F2417350748F04E0F5F1F50939D0239
:102DE00040939C028193919302C0E0E0F0E0CF0118
:102DF000DF91CF911F910F910895CF93DF930097AB
:102E000009F481C0FC01329713821282A0919E02C4
:102E1000B0919F02109781F420813181820F931F1E
:102E200020919C0230919D022817390751F5F093AB
:102E30009D02E0939C0267C0ED0120E030E0CE17D8
:102E4000DF0740F44A815B819E0141155105F1F095
:102E5000EA01F5CFD383C28340815181840F951F4E
:102E6000C817D90759F488819981840F951F029654
:102E7000918380838A819B8193838283211531058D
:102E800029F4F0939F02E0939E023DC0E901FB8389
:102E9000EA8349915991C40FD51FEC17FD0761F4DE
:102EA00080819181840F951F0296E901998388831F
:102EB000828193819B838A83E0E0F0E012968D917A
:102EC0009C911397009719F0FD01DC01F7CF8D91CC
:102ED0009C9111979D012E5F3F4F820F931F209170
:102EE0009C0230919D022817390769F4309729F424
:102EF00010929F0210929E0202C013821282B0931F
:102F00009D02A0939C02DF91CF91089581E090E013
:102F1000F8940C949617FC018191861721F0882370
:102F2000D9F7992708953197CF01089511E0C2E4A8
:102F3000D1E004C0FE010E945F162196C334D10780
:062F4000C9F7F894FFCF71
:102F46000000A00280000000000095036103AF03AB
:102F56001C030603C402A3026F024E02F801B40169
:102F6600000000000904EF076D0156049E017C0174
:102F760090016E616E00696E66006F7666000D0ADE
:102F860000762E3230313831313237005400460067
:042F960052454C0054
:107E0000112484B714BE81FFF0D085E080938100F7
:107E100082E08093C00088E18093C10086E0809377
:107E2000C20080E18093C4008EE0C9D0259A86E02C
:107E300020E33CEF91E0309385002093840096BBD3
:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
:107E6000A2D0813461F49FD0082FAFD0023811F036
:107E7000013811F484E001C083E08DD089C08234E0
:107E800011F484E103C0853419F485E0A6D080C0E4
:107E9000853579F488D0E82EFF2485D0082F10E0AE
:107EA000102F00270E291F29000F111F8ED06801E7
:107EB0006FC0863521F484E090D080E0DECF843638
:107EC00009F040C070D06FD0082F6DD080E0C81688
:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
:107F0000A601A0E0B1E02C9130E011968C91119780
:107F100090E0982F8827822B932B1296FA010C0160
:107F200087BEE89511244E5F5F4FF1E0A038BF0790
:107F300051F7F601A7BEE89507B600FCFDCF97BE46
:107F4000E89526C08437B1F42ED02DD0F82E2BD052
:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
:107F7000D11C0EC0853739F428D08EE10CD085E9AC
:107F80000AD08FE07ACF813511F488E018D01DD067
:107F900080E101D065CF982F8091C00085FFFCCF94
:107FA0009093C60008958091C00087FFFCCF809118
:107FB000C00084FD01C0A8958091C6000895E0E648
:107FC000F0E098E1908380830895EDDF803219F02E
:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
:047FF000FF270994CA
:027FFE00040479
:0400000300007E007B
:00000001FF

View file

@ -1,808 +0,0 @@
:100000000C9443010C946B010C946B010C946B01E8
:100010000C946B010C946B010C946B010C946B01B0
:100020000C946B010C946B010C946B010C946B01A0
:100030000C946B010C946B010C946B010C946B0190
:100040000C9478080C946B010C94E8080C94C2088A
:100050000C946B010C946B010C946B010C946B0170
:100060000C946B010C946B01CC01D201D801DE0120
:10007000E401EA01F001210328032F0336033D03C5
:100080005403440354034B034E414E494E495459C3
:10009000494E46CDCCCC3D0AD7233C17B7D1387753
:1000A000CC2B329595E6241FB14F0A000020410069
:1000B00000C84200401C4620BCBE4CCA1B0E5AAEB3
:1000C000C59D744D3131343B202D207265706F72A7
:1000D0007420706F736974696F6E20616E6420663E
:1000E00065656472617465004D3130303B202D20B0
:1000F000746869732068656C70206D6573736167DF
:1001000065004D32323B202D207475726E2072696D
:10011000676874206C61736572206F6666004D328B
:10012000313B202D207475726E20726967687420CF
:100130006C61736572206F6E004D32303B202D2054
:100140007475726E206C656674206C6173657220C4
:100150006F6666004D31393B202D207475726E201C
:100160006C656674206C61736572206F6E004D3132
:10017000383B202D2064697361626C65206D6F745B
:100180006F7273004D31373B202D20656E61626CBC
:1001900065206D6F746F727300473031205B542897
:1001A0007374657073295D205B4C2873746570737C
:1001B000295D205B46286665656472617465295D0A
:1001C0003B202D206D6F766500473030205B542832
:1001D0007374657073295D3B202D206C696E6561B9
:1001E00072206D6F766500436F6D6D616E64733A5A
:1001F000004661625363616E20472D434F4444457E
:1002000020496E74657270726574657220566572ED
:1002100073696F6E3A2000424144434845434B5353
:10022000554D20004241444C494E454E554D20000D
:100230003E0000000000240027002A000000000803
:10024000000201000003040700000000000000009D
:10025000010204081020408001020408102001025D
:100260000408102000000000250028002B000404D2
:10027000040404040404020202020202030303034E
:1002800003033F11B20D11241FBECFEFD8E0DEBF34
:10029000CDBF22E0A4E5B1E001C01D92A03AB207B3
:1002A000E1F711E0A0E0B1E0E2EEFFE202C005906C
:1002B0000D92A435B107D9F711E0C2E4D1E004C032
:1002C0002197FE010E94AD16C134D107C9F70E94E3
:1002D000C20D0C94E4170C940000FC01538D448D66
:1002E000252F30E0842F90E0821B930B541710F0E1
:1002F000CF96089501970895FC01918D828D9817EE
:1003000061F0828DDF01A80FB11D5D968C91928DF9
:100310009F5F9F73928F90E008958FEF9FEF0895F6
:10032000FC01918D828D981731F0828DE80FF11DBF
:10033000858D90E008958FEF9FEF0895FC01918DDA
:10034000228D892F90E0805C9F4F821B91098F73D3
:100350009927089580E090E0892B29F00E946C088D
:1003600081110C9400000895CF93DF9347705527B7
:1003700066277727FA013197EC01A881B981E73028
:10038000F10520F4EC5CFF4F0C94AD161496ED9142
:10039000FC91159761E029C01496ED91FC91159799
:1003A00065E023C01496ED91FC91159764E01DC0A3
:1003B0001496ED91FC91159766E017C01496ED9197
:1003C000FC91159762E011C01496ED91FC91159780
:1003D0006AE00BC01496ED91FC91159768E005C09A
:1003E0001496ED91FC91159769E0DF91CF910994F6
:1003F000CF93DF93EC01CB01BA0126E030E040E07F
:1004000050E00E948E16623071058105910559F108
:100410008CF46115710581059105F1F0613071056C
:1004200081059105C1F5E881F9810480F581E02D10
:1004300065E02DC0643071058105910511F1D4F09E
:10044000653071058105910531F5E881F9810480F8
:10045000F581E02D66E01BC0E881F9810480F5811B
:10046000E02D64E014C0E881F9810480F581E02D7D
:1004700061E00DC0E881F9810480F581E02D63E041
:1004800006C0E881F9810480F581E02D62E0CE01AB
:10049000DF91CF910994DF91CF9108954370552753
:1004A00066277727DC01ED91FC910480F581E02D32
:1004B000423051056105710571F043305105610508
:1004C000710559F0413051056105710511F065E084
:1004D00005C066E003C06AE001C069E00994CF93FB
:1004E000DF93EC01CB01BA0123E030E040E050E0C3
:1004F0000E948E16613071058105910581F0623090
:1005000071058105910591F0672B682B692BC1F46A
:10051000E881F9810480F581E02D64E00DC0E88177
:10052000F9810480F581E02D61E006C0E881F98160
:100530000480F581E02D62E0CE01DF91CF91099436
:10054000DF91CF9108954370552766277727DC0107
:10055000ED91FC910480F581E02D4230510561055B
:10056000710571F0433051056105710559F0413055
:1005700051056105710511F062E005C063E003C03B
:1005800061E001C060E00994CF93DF93EC01E88162
:10059000F9810480F581E02D8A81811102C060E03B
:1005A00001C062E0CE010995E881F9810480F581FE
:1005B000E02D8A81811102C061E001C063E0CE01BB
:1005C00009958CA59DA58230910538F0880F991F5B
:1005D000880F991F05970197F1F7E881F981048049
:1005E000F581E02D8A81811102C060E001C062E0E6
:1005F000CE01DF91CF910994CF93DF93EC0120E0FE
:1006000030E0A9016C897D898E899F890E94071637
:1006100018161CF4E8A9F9A902C0EAA9FBA9DF9100
:10062000CF9109940F931F93DC011396EC910E2F39
:1006300010E009301105C0F5F801E55CFF4F0C949E
:10064000AD16DC01ED91FC910084F185E02D29C00F
:10065000DC01ED91FC910284F385E02D22C0DC01E8
:10066000ED91FC910484F585E02D1BC0DC01ED913A
:10067000FC910684F785E02D14C0DC01ED91FC911E
:100680000088F189E02D0DC0DC01ED91FC9102881C
:10069000F389E02D06C0DC01ED91FC910488F58919
:1006A000E02D1F910F9109941F910F910895CF9301
:1006B000DF93FC012381222359F1EC0161E0848165
:1006C0000E940C0D61E08D810E940C0D8B818430A5
:1006D00011F0883039F461E08E810E940C0D61E0E8
:1006E0008F8106C0833011F0863021F461E08E8165
:1006F0000E940C0D8FA58F3F59F061E00E940C0DF8
:100700006EA581E068278FA5DF91CF910C94BF0C77
:10071000DF91CF910895CF93DF93FC0123812223B2
:10072000A9F0EC010190F081E02D0480F581E02D2D
:1007300060E009958FA58F3F49F061E00E940C0DA4
:100740006EA58FA5DF91CF910C94BF0CDF91CF9157
:100750000895CF92DF92EF92FF920F931F93CF9362
:10076000DF93EC019B81943041F0983031F093306D
:1007700031F0963021F012E003C014E001C013E024
:100780002496E12CF12CC62ED12C01E0C6010E2CB2
:1007900002C0959587950A94E2F76C8180FD6027E9
:1007A00089910E94BF0C8FEFE81AF80AE11670F3E6
:1007B000DF91CF911F910F91FF90EF90DF90CF903D
:1007C0000895FC01848DDF01A80FB11DA35ABF4F0E
:1007D0002C91848D90E001968F739927848FA68940
:1007E000B7892C93A089B1898C91837080648C9394
:1007F000938D848D981306C00288F389E02D808143
:100800008F7D80830895EF92FF920F931F93CF9374
:10081000DF93EC0181E0888F9B8D8C8D981305C050
:10082000E889F989808185FD26C0F62E0B8D10E0C0
:100830000F5F1F4F0F731127E02E8C8DE8120CC035
:100840000FB607FCFACFE889F989808185FFF5CFDB
:10085000CE010E94E103F1CF8B8DFE01E80FF11D67
:10086000E35AFF4FF0829FB7F8940B8FEA89FB8918
:10087000808180620AC09FB7F894EE89FF89608307
:10088000E889F98980818370806480839FBF81E0DB
:1008900090E0DF91CF911F910F91FF90EF9008951D
:1008A000CF93DF93EC01888D8823C9F0EA89FB8917
:1008B000808185FD05C0A889B9898C9186FD0FC00E
:1008C0000FB607FCF5CF808185FFF2CFA889B989E3
:1008D0008C9185FFEDCFCE010E94E103E7CFDF9140
:1008E000CF9108954F925F926F927F92AF92BF9295
:1008F000CF92DF92EF92FF920F931F93CF93DF93EC
:10090000CDB7DEB7C454D1090FB6F894DEBF0FBE21
:10091000CDBF5C012A013B016801790123E042E07F
:1009200064E0CE0101960E94670A8AE0A816B1042D
:1009300021F4CE0101960E94E60BC301B2010E9490
:10094000D1150D851E852F853889DC01CB01800FDF
:10095000911FA21FB31F09891A892B893C89081787
:1009600019072A073B0741F0898B9A8BAB8BBC8B0D
:10097000CE0101960E941A09B701A601CE01019687
:100980000E94C40A49895A896B897C890D851E8514
:100990002F853889CDA0DEA0EFA0F8A40417150795
:1009A0002607370714F481E001C080E040175107A3
:1009B0006207730759F0C114D104E104F104B1F3E3
:1009C0008B83CE0101960E946D0DDCCFCC5BDF4F97
:1009D0000FB6F894DEBF0FBECDBFDF91CF911F9150
:1009E0000F91FF90EF90DF90CF90BF90AF907F90EE
:1009F0006F905F904F9008958F929F92AF92BF92A9
:100A0000CF92DF92EF92FF926A017B010E943B0B33
:100A1000A7019601C701B6010E945216882319F05A
:100A200082E391E01AC046015701E894B7F82FEF2E
:100A30003FEF4FE75FE7C501B4010E9452168111F5
:100A40000FC02FEF3FEF4FE75FE7C501B4010E94F2
:100A50007A1318162CF486E391E00E943B0B76C0C3
:100A60002FEF3FEF4FE75FE4C701B6010E94071683
:100A700018161CF48AE391E0F0CF2FEF3FEF4FE719
:100A80005FECC701B6010E947A1387FDF3CF20E027
:100A900030E0A901C701B6010E947A1387FF09C09F
:100AA0006DE284EA91E00E940304F7FAF094F7F80B
:100AB000F0942AE037ED43EA5BE3C701B6010E94F8
:100AC000F3144B015C010E94D8156B017C010E945C
:100AD0007F139B01AC01C501B4010E94F2144B01CC
:100AE0005C014AE0C701B6010E94760B6EE284EA1F
:100AF00091E00E94030420E030E040E251E4C501AF
:100B0000B4010E94E0134B015C010E94D8156B01F7
:100B1000E12CF12C4AE0C701B6010E94760BC70117
:100B2000B6010E947F139B01AC01C501B4010E9474
:100B3000F21420E030E040E251E40E94E0130E9411
:100B4000D81580E090E04AE00E94760B8EE391E0B9
:100B5000FF90EF90DF90CF90BF90AF909F908F90DD
:100B60000C943B0BFF920F931F93CF93DF93F82EC0
:100B70008B01C0919401D0919501CC5ADE4F84E550
:100B800091E00097B9F0FC012081222399F08C17A5
:100B90009D0780F42F1108C00196DF91CF911F911E
:100BA0000F91FF900C94331360E270E00E94D9170C
:100BB0000196E7CFC801DF91CF911F910F91FF9070
:100BC00008958F929F92AF92BF92CF92DF92EF9251
:100BD000FF920F931F93CF93DF93CDB7DEB7299783
:100BE0000FB6F894DEBF0FBECDBF962F50E060E089
:100BF00070E0592B682BCB01AA27BB27F52E982E26
:100C0000BC0100E010E0A0E0B0E020E030E0809126
:100C100087029091880228173907E0F580918C02AD
:100C2000882371F0869F6001879FD00C11248F9DCF
:100C300050011124EB2C849FC0011124592F03C0B3
:100C4000542FEF2CD92CC0909202B0908F0280913B
:100C50008D0290918E02CB1003C08A0F9B1F07C09C
:100C6000800F911F5C01AC0CB11CF5011082C0908B
:100C70008F025C01AC0CB11CF501D082D0909002C7
:100C8000FC01ED0DF11DE082E09091028E0D911DB1
:100C9000FC0150832F5F3F4F13960C5F1F4F203195
:100CA000310509F0B4CF80918D0290918E02892B8D
:100CB00009F4A2C00E94480DC0909302D090940203
:100CC000E0909502F0909602DC01CB018C199D0911
:100CD000AE09BF098C329140A105B10558F3F894D3
:100CE0008091890290918A029A838983E0918D0292
:100CF000F0918E02DF0111968081898790918502A3
:100D0000E0919702F091980280919902992309F459
:100D10002EC09081982B98879081809589238F830E
:100D20008F818C8388E08B8358856F8149853B81D7
:100D30002C8189819A81508347FD252F3A95208304
:100D4000262F39F0441F00C000006083000000C05F
:100D5000F2CF38E04D9160830000019761F7F09386
:100D60009802E093970249873B832C8338C0908197
:100D7000982B98879081809589238F838F818E838C
:100D800088E08D8358856F8149853D812E818981D9
:100D90009A81508347FD252F00C000C0208300C0EA
:100DA00000C000C000C000C060830000262F3A953C
:100DB00041F0441F000000C000C000C000C000C0DF
:100DC000E8CF38E04D9100C0608300C0019709F77B
:100DD000F0939802E093970249873D832E839A838C
:100DE000898378940E94480D6093930270939402D3
:100DF00080939502909396020E94480D4B015C01EE
:100E000084E6C82ED12CE12CF12C0E94480DDC0187
:100E1000CB0188199909AA09BB09883E9340A1050D
:100E2000B10598F321E0C21AD108E108F10888EE73
:100E3000880E83E0981EA11CB11CC114D104E104EA
:100E4000F10419F729960FB6F894DEBF0FBECDBF97
:100E5000DF91CF911F910F91FF90EF90DF90CF9096
:100E6000BF90AF909F908F9008954F925F926F9236
:100E70007F928F929F92AF92BF92CF92DF92EF922A
:100E8000FF92CF93DF93EC016A017B0120E030E019
:100E9000A901C701B6010E947A1387FF04C0F7FABF
:100EA000F094F7F8F0948C8C9D8CAE8CBF8CA701DD
:100EB0009601C501B4010E947A13882309F449C040
:100EC0006CA97DA98EA99FA90E9481132B013C01C9
:100ED000A7019601C501B4010E945F159B01AC01F9
:100EE000C301B2010E94E0130E94D1156CAB7DAB2F
:100EF0008EAB9FABA701960160E070E080E090E4CC
:100F00000E945F150E94121626E53EE04DE25FE367
:100F10000E94E01320E034E244E759E40E94E01329
:100F200068AF79AF8AAF9BAFCC8EDD8EEE8EFF8E31
:100F3000CE01DF91CF91FF90EF90DF90CF90BF90E7
:100F4000AF909F908F907F906F905F904F900C9498
:100F50001A09DF91CF91FF90EF90DF90CF90BF9073
:100F6000AF909F908F907F906F905F904F9008957B
:100F7000CF92DF92EF92FF920F931F93CF93DF9365
:100F8000CDB7DEB7C454D1090FB6F894DEBF0FBE9B
:100F9000CDBF6C018B017A0123E042E064E0CE0119
:100FA00001960E94670A8AE0C816D10421F4CE0196
:100FB00001960E94E60BB701FF0C880B990B0E946B
:100FC0008113AB01BC01CE0101960E94C40A40E02E
:100FD00050E06AEF73E4CE0101960E943507C80124
:100FE000110FAA0BBB0B49895A896B897C8984171D
:100FF0009507A607B70741F0898B9A8BAB8BBC8B03
:10100000CE0101960E941A098DA19EA1AFA1B8A59B
:10101000892B8A2B8B2B51F0CE0101960E946D0DEE
:10102000882321F0CE0101960E941A0920E030E0C9
:10103000A9016D897E898F89988D0E947A1381110B
:10104000E3CF49895A896B897C898D859E85AF85D7
:10105000B889481759076A077B07B1F6CC5BDF4FA1
:101060000FB6F894DEBF0FBECDBFDF91CF911F91B9
:101070000F91FF90EF90DF90CF900895CF92DF9285
:10108000EF92FF920F931F93CF93DF936C017A013E
:101090008B01C0E0D0E0CE15DF0581F0D8016D9165
:1010A0008D01D601ED91FC910190F081E02DC601FA
:1010B0000995892B11F02196EECF7E01C701DF91B2
:1010C000CF911F910F91FF90EF90DF90CF900895F7
:1010D000089580E090E0089584EA91E00E949E01E6
:1010E00021E0892B09F420E0822F08950E94D41773
:1010F0001F920F920FB60F9211242F933F938F934D
:101100009F93AF93BF9380919C0190919D01A0917B
:101110009E01B0919F0130919B0123E0230F2D3759
:1011200020F40196A11DB11D05C026E8230F0296EB
:10113000A11DB11D20939B0180939C0190939D0163
:10114000A0939E01B0939F018091A0019091A10175
:10115000A091A201B091A3010196A11DB11D8093A0
:10116000A0019093A101A093A201B093A301BF910C
:10117000AF919F918F913F912F910F900FBE0F9044
:101180001F9018951F920F920FB60F9211242F9354
:101190003F934F935F936F937F938F939F93AF93FF
:1011A000BF93EF93FF9384EA91E00E94E103FF91E4
:1011B000EF91BF91AF919F918F917F916F915F91CF
:1011C0004F913F912F910F900FBE0F901F90189548
:1011D0001F920F920FB60F9211242F938F939F930C
:1011E000EF93FF93E091B401F091B5018081E0911C
:1011F000BA01F091BB0182FD12C090818091BD01C6
:101200008F5F8F732091BE01821751F0E091BD0175
:10121000F0E0EC55FE4F958F8093BD0101C08081B9
:10122000FF91EF919F918F912F910F900FBE0F9093
:101230001F9018954F925F926F927F928F929F921C
:10124000AF92BF92CF92DF92EF92FF920F931F93D4
:10125000CF93DF93EC01C888D988EA88FB888C8516
:101260009D85AE85BF85C81AD90AEA0AFB0A6C8932
:101270007D898E899F899B01AC010E94E0134B01FF
:101280005C016C8D7D8D8E8D9F8D9B01AC010E94CC
:10129000F3149B01AC01C501B4010E945F150E94CB
:1012A000D115C114D104E104F10499F4623071053F
:1012B000810591050CF076C01CA21DA21EA21FA2E2
:1012C0001C8A1D8A1E8A1F8A1CAA1DAA1EAA1FAA62
:1012D000EDC00CA91DA92EA93FA91C141D041E04B4
:1012E0001F04FCF410161106120613064CF46C15BC
:1012F0007D058E059F054CF52A81211153C025C01F
:10130000011511052105310509F44CC06C157D0549
:101310008E059F050CF046C08A81882309F442C0DF
:1013200036C01016110612061306ECF4002711271A
:1013300098010C191D092E093F09601771078207D2
:1013400093071CF42A81222369F19B01AC018827B1
:101350009927DC01821B930BA40BB50B8CAB9DABC7
:10136000AEABBFAB1FC00115110521053105D1F092
:101370008824992454018C189D08AE08BF0868156C
:1013800079058A059B0574F48A8181110BC030951B
:101390002095109501951F4F2F4F3F4F0CAB1DAB64
:1013A0002EAB3FAB8CA89DA8AEA8BFA8811491041A
:1013B000A104B10489F488AD99ADAAADBBAD8CAFE1
:1013C0009DAFAEAFBFAF81E01C141D041E041F040F
:1013D0000CF080E08A833FC0CCACDDACEEACFFAC5F
:1013E000A7019601C701B6010E94F3142B013C012D
:1013F000C501B4010E94811320E030E040E850E4D0
:101400000E94E01320E030E040E85FE30E94F31424
:101410009B01AC01C301B2010E945F159B01AC01AD
:10142000C701B6010E94F2143B016C01FE01E05CB1
:10143000FF4FE080F180028113819701A8010E9493
:101440000716181614F473018601C701D8018CAF72
:101450009DAFAEAFBFAF3FEF831A930AA30AB30AA3
:101460008CAA9DAAAEAABFAACCACDDACEEACFFACF8
:10147000C701B6010E94D8156CA37DA38EA39FA3BC
:10148000A701960160E074E284E799E40E945F1589
:101490006C8B7D8B8E8B9F8B2A81211107C0DC0189
:1014A000CB01B0588C8B9D8BAE8BBF8BDF91CF91D6
:1014B0001F910F91FF90EF90DF90CF90BF90AF9072
:1014C0009F908F907F906F905F904F900895CF93F3
:1014D000DF93EC018AE091E0998388836B831C861B
:1014E0001D861E861F86188A198A1A8A1B8A1C8ADC
:1014F0001D8A1E8A1F8A80E090E0A0E8BFE3888FE3
:10150000998FAA8FBB8F1C8E1D8E1E8E1F8E88A357
:1015100099A3AAA3BBA31CA21DA21EA21FA261E0A5
:1015200070E07DA76CA73FEF3FA718A619A61AA6E3
:101530001BA64C832D8324E02E8325E02F831EA63B
:101540001CAA1DAA1EAA1FAA18AE19AE1AAE1BAE5F
:101550001CAE1DAE1EAE1FAEFE01E05CFF4F8083D1
:101560009183A283B3831A82188619861A861B86F2
:10157000CE010E94570340E050E060E87FE3CE01D7
:10158000DF91CF910C9435074F925F926F927F92CB
:10159000AF92BF92CF92DF92EF92FF920F931F9381
:1015A000CF93DF93EC015A018B019A01AB016C8957
:1015B0007D898E899F890E947A13882309F44CC003
:1015C000C88CD98CEA8CFB8C2601370177FA709491
:1015D00077F87094A3019201B501C8010E947A13B3
:1015E00087FD0BC0A7019601B501C8010E9407162F
:1015F00018162CF06501780102C07301620120E029
:1016000030E0A901C701B6010E947A13811105C01B
:101610001CA21DA21EA21FA21BC0A701960160E072
:1016200074E284E799E40E945F159F770E94D815C1
:101630006CA37DA38EA39FA311E020E030E0A9015D
:10164000C701B6010E94071618160CF010E01A83A5
:10165000CC8ADD8AEE8AFF8ADF91CF911F910F91AC
:10166000FF90EF90DF90CF90BF90AF907F906F9002
:101670005F904F900895009769F0FC010190002061
:10168000E9F73197AF01481B590BBC0184EA91E09F
:101690000C943E0880E090E008950F931F93CF9341
:1016A000DF938C01C0E0D0E0F801EC0FFD1F6491E6
:1016B000662341F084EA91E00E940304892B11F033
:1016C0002196F2CFCE01DF91CF911F910F91089516
:1016D000CF93DF930E944D0BEC018EE391E00E94CB
:1016E0003B0B8C0F9D1FDF91CF9108958F929F929E
:1016F000AF92BF920F931F93CF93DF93CDB7DEB717
:10170000A1970FB6F894DEBF0FBECDBF19A242302D
:1017100008F44AE08E010F5D1F4F842E912CA12CFE
:10172000B12CA50194010E946C16E62FB901CA01E3
:1017300001501109EA3014F4E05D01C0E95CD80100
:10174000EC93232B242B252B61F7C8010E943B0B24
:10175000A1960FB6F894DEBF0FBECDBFDF91CF913B
:101760001F910F91BF90AF909F908F900895CF924F
:10177000DF92EF92FF92CF93DF936B017C016DE2DA
:1017800084EA91E00E940304EC0166277727CB01ED
:101790006C197D098E099F094AE00E94760B8C0F17
:1017A0009D1FDF91CF91FF90EF90DF90CF90089534
:1017B000CF93DF930E943B0BEC018EE391E00E94FC
:1017C0003B0B8C0F9D1FDF91CF910895FC01A1E48D
:1017D000B2E012968C911297828313968C91139794
:1017E000838314968C911497848315968C91159706
:1017F000858316968C911697868317968C911797EA
:10180000878318968C911897808719968C911997D1
:1018100081871A968C911A9782871B968C911B97B9
:1018200083871C964D915D916D917C911F974487A4
:1018300055876687778750964D915D916D917C9124
:101840005397408B518B628B738B54964D915D9166
:101850006D917C915797448B558B668B778B5896FF
:101860004D915D916D917C915B97408F518F628F0F
:10187000738F5C964D915D916D917C915F97448FD4
:10188000558F668F778F90964D915D916D917C917C
:10189000939740A351A362A373A394964D915D9136
:1018A0006D917C91979744A355A366A377A39896CF
:1018B0004D915D916D917C919B9740A751A762A737
:1018C00073A79C968D919C919D9795A784A79E96B2
:1018D0008C919E9786A79F968C919F9787A7D0966D
:1018E0008D919C91D19791AB80ABD2968D919C912B
:1018F000D39793AB82ABD4964D915D916D917C91D2
:10190000D79744AB55AB66AB77ABD8964D915D910D
:101910006D917C91DB9740AF51AF62AF73AFDC96B6
:101920008D919D910D90BC91A02D84AF95AFA6AFE8
:10193000B7AF409181025091820260918302709111
:101940008402DF01A05CBF4F4D935D936D937C9348
:101950001397CF010895CF93DF9397FF03C00E94A1
:10196000B70B03C04AE00E94760BEC018EE391E0D6
:101970000E943B0B8C0F9D1FDF91CF91089590E04B
:10198000FC01E45CFD4F2491FC01E05BFD4F3491D0
:10199000FC01E259FD4FE491EE2309F43CC02223FF
:1019A00039F1233091F038F42130A9F0223001F5DB
:1019B00084B58F7D12C0273091F02830A1F02430FB
:1019C000B9F4809180008F7D03C0809180008F7773
:1019D000809380000DC084B58F7784BD09C080914D
:1019E000B0008F7703C08091B0008F7D8093B000EE
:1019F000F0E0EE0FFF1FEC59FD4FA591B4919FB79A
:101A0000F894611104C08C913095382302C0EC9198
:101A10003E2B3C939FBF0895CF93DF9390E0FC0152
:101A2000E05BFD4F2491FC01E259FD4F8491882336
:101A300061F190E0880F991FFC01EE5CFD4FC591AC
:101A4000D491FC01EC59FD4FA591B491611109C0ED
:101A50009FB7F8948881209582238883EC912E2368
:101A60000BC0623061F49FB7F8948881322F3095B3
:101A700083238883EC912E2B2C939FBF06C08FB7B6
:101A8000F894E8812E2B28838FBFDF91CF910895A2
:101A90003FB7F8948091A0019091A101A091A2017B
:101AA000B091A30126B5A89B05C02F3F19F0019660
:101AB000A11DB11D3FBFBA2FA92F982F8827820FD4
:101AC000911DA11DB11DBC01CD0142E0660F771F24
:101AD000881F991F4A95D1F70895CF92DF92EF9210
:101AE000FF92CF93DF93EC010E94480D6B017C01C4
:101AF00088A599A5AAA5BBA5B701A601481B590BA6
:101B00006A0B7B0B8CA19DA1AEA1BFA14817590701
:101B10006A077B07F8F02A818C859D85AE85BF8595
:101B2000222321F00196A11DB11D03C00197A10937
:101B3000B1098C879D87AE87BF874C855D856E8593
:101B40007F85CE010E941203C8A6D9A6EAA6FBA6ED
:101B500081E001C080E0DF91CF91FF90EF90DF90B6
:101B6000CF90089580918D0290918E02009711F090
:101B70000E944B1780918B0287FD03C060E00C949C
:101B80000C0D0895789484B5826084BD84B581601D
:101B900084BD85B5826085BD85B5816085BD809138
:101BA0006E00816080936E001092810080918100B0
:101BB00082608093810080918100816080938100A8
:101BC000809180008160809380008091B10084606A
:101BD0008093B1008091B00081608093B0008091CB
:101BE0007A00846080937A0080917A00826080938A
:101BF0007A0080917A00816080937A0080917A00E7
:101C0000806880937A001092C100E091B401F09155
:101C1000B50182E08083E091B401F091B5011082BA
:101C2000E091B001F091B1011082E091B201F09128
:101C3000B30180E180831092BC01E091B801F09182
:101C4000B90186E08083E091B601F091B70180810F
:101C500080618083E091B601F091B7018081886056
:101C60008083E091B601F091B70180818068808324
:101C7000E091B601F091B70180818F7D808361E0B2
:101C800089E00E940C0D61E08AE00E940C0D61E089
:101C90008FE00E940C0D60E08FE00E94BF0C60E0BE
:101CA00089E00E94BF0C60E08AE00E94BF0C61E006
:101CB00083E10E940C0D60E083E10E94BF0C61E0B3
:101CC00082E00E940C0D61E085E00E940C0D61E055
:101CD00083E00E940C0D61E086E00E940C0D61E043
:101CE00083E10E94BF0C20E030E04AEF54E46091B1
:101CF000590270915A0280915B0290915C020E949D
:101D00007A13882309F453C080E090E0AAEFB4E48A
:101D10008093590290935A02A0935B02B0935C02A5
:101D200080E090E0AAEFB3E4809381029093820276
:101D3000A0938302B0938402809175029091760201
:101D4000A0917702B0917802181619061A061B06A0
:101D500074F56091550270915602809157029091EE
:101D600058029B01AC010E94E0136B017C01609161
:101D70005D0270915E0280915F02909160029B0112
:101D8000AC010E94F3149B01AC01C701B6010E9493
:101D90005F150E94D115609375027093760280934F
:101DA00077029093780281E492E00E941A0940E061
:101DB00050E06FE274E481E492E00E94C40A61E0C2
:101DC00082E00E94BF0C80918B0287FD08C061E019
:101DD0000E940C0D60E080918B020E94BF0C81E09C
:101DE0008093860261E082E00E94BF0C61E085E0A2
:101DF0000E94BF0C84EA91E00E949E011816190609
:101E00000CF0FAC184EA91E00E947C01C82F682F8F
:101E100084EA91E00E9403048091940190919501DD
:101E20008F3391055CF49C012F5F3F4F30939501F8
:101E300020939401FC01EC5AFE4FC083CA3011F08C
:101E4000CD30C1F6E0919401F0919501EC5AFE4F2E
:101E50001082C0915401CB3309F4C5C16FEF7FEFFD
:101E60008EE40E94B205092E000CAA0BBB0B8F3F1B
:101E70002FEF9207A207B20709F45CC0CE3409F035
:101E800059C0C0909601D0909701E0909801F090D1
:101E900099018C159D05AE05BF0539F084E292E0ED
:101EA0000E944D0BC701B6012FC06AE270E084E5C5
:101EB00091E00E94D917892B09F495C1E4E5F1E07E
:101EC000C0E09F012455314091919A3211F0C92709
:101ED000F8CF60E070E0C9018B5A9E4F0E94E51177
:101EE0000E94D1152C2FCC0F330B2617370779F012
:101EF00087E192E00E944D0B6091960170919701ED
:101F000080919801909199010E94AB0C6CC18091D5
:101F1000960190919701A0919801B0919901019635
:101F2000A11DB11D8093960190939701A0939801F4
:101F3000B09399016FEF7FEF87E40E94B205823082
:101F4000910581F01CF497FF30C06EC0863091057A
:101F500009F464C08730910509F464C0049709F05E
:101F600063C023C060E070E086E40E94B2057C019B
:101F700060E070E08CE40E94B205EC0160E070E08B
:101F800084E50E94B205009731F0A701BC018AE008
:101F900090E00E94B807209709F446C0A701BE014F
:101FA0008BE090E00E94B8073FC060E070E086E4FC
:101FB0000E94B205BC01990F880B990B0E948113F6
:101FC0006B017C0160E070E08CE40E94B205EC01E2
:101FD00060E070E084E50E94B205009771F0BC01FA
:101FE000990F880B990B0E948113AB01BC019701DB
:101FF00086018AE090E00E9472042097A9F0BE0159
:10200000DD0F880B990B0E948113AB01BC01970176
:1020100086018BE090E00E94720406C081E080930C
:102020009A0102C010929A016FEF7FEF8DE40E9437
:10203000B2058531910509F4ABC0CCF4813191052D
:1020400009F49AC044F48430910509F477C00597E7
:1020500009F47CC0C8C08331910509F494C00CF028
:1020600094C061E082E00E94BF0C61E08AC08E36BD
:10207000910509F494C0ECF58631910509F48AC004
:102080008436910509F0AFC081EF91E00E944D0BBD
:1020900081E491E00E94D80B87EE91E00E94680BEA
:1020A00089EC91E00E94680B89E991E00E94680B3D
:1020B00084E891E00E94680B8EE691E00E94680B34
:1020C00084E591E00E94680B89E391E00E94680B2F
:1020D0008EE191E00E94680B82E091E00E94680B23
:1020E00088EE90E00E94680B83EC90E00E94680B01
:1020F0007AC0883C910509F466C0893C910509F4D1
:1021000067C08237910509F06EC040E050E0BA0127
:102110008CE491E00E94FC0440E050E0BA0182E5CA
:1021200091E00E94FC0440E050E46CE176E48EE42F
:1021300091E00E94FC0480E591E047C060E089E006
:102140000E94BF0C60E08AE00E94BF0C60E070E07B
:1021500082E40E94B2057C0160E070E087E40E94A6
:10216000B205EC0160E070E082E50E94B205A701D3
:10217000BE010E94E10537C060E082E00E94BF0C12
:1021800060E085E009C061E001C060E08AE004C071
:1021900061E001C060E089E00E94BF0C24C0609152
:1021A0009601709197018EE40E94B205092E000CF1
:1021B000AA0BBB0B8093960190939701A093980173
:1021C000B093990110C081E491E00E94D80B0BC03C
:1021D0004AE061E070E080E090E00E94760B8EE3E0
:1021E00091E00E943B0B109295011092940180E3C4
:1021F00092E00E94680BFECD80919A018823E1F164
:1022000040E050E06AE774E481E492E00E94C40A8E
:1022100080914D0290914E02A0914F02B0915002D8
:102220000A96A11DB11D4091510250915202609138
:1022300053027091540284179507A607B70761F0FF
:102240008093510290935202A0935302B093540290
:1022500081E492E00E941A098091650290916602E1
:10226000A0916702B0916802892B8A2B8B2B21F0F9
:1022700081E492E00E946D0D0E94AA01BBCD1092F4
:10228000A7011092A60188EE93E0A0E0B0E0809351
:10229000A8019093A901A093AA01B093AB0184E295
:1022A00091E09093A5018093A40185EC90E0909338
:1022B000B1018093B00184EC90E09093B3018093DE
:1022C000B20180EC90E09093B5018093B40181EC71
:1022D00090E09093B7018093B60182EC90E09093E8
:1022E000B9018093B80186EC90E09093BB01809394
:1022F000BA011092BD011092BE011092BF0110925E
:10230000C00124E043E062E081E492E00E94670AB9
:102310001092860210928C021092930210929402F4
:10232000109295021092960281E08093920280931F
:102330008F021092900292E0909391028093850216
:1023400080E390E090938A02809389020E94B31602
:1023500090938E0280938D02009761F020E3FC0140
:1023600011922A95E9F780E190E09093880280939A
:10237000870208C010928A02109289021092880285
:10238000109287028FE080938B02809186028823CF
:1023900041F061E08FE00E940C0D60E08FE00E9450
:1023A000BF0CEDE7F2E0E491F0E0EE0FFF1FEC5917
:1023B000FD4F859194919093980280939702EFE559
:1023C000F2E0E491E09399020895A0E0B0E0EBEE32
:1023D000F1E10C94B214EC016B016115710519F077
:1023E000FB01918380837E01FFEFEF1AFF0A0881D2
:1023F000802F90E00E945113892B11F0E701F3CF59
:102400000D3239F47E0182E0E80EF11C098111E001
:1024100008C00B3229F47E0192E0E90EF11C09811B
:1024200010E0E701219743E050E060E970E0CE0161
:102430000E945A13892BC1F4239645E050E06BE8C3
:1024400070E0CE010E945A13892B09F42596C1141D
:10245000D10419F0F601D183C0831111F6C060E0F8
:1024600070E080E89FE7FAC043E050E068E870E081
:10247000CE010E945A13892B59F4C114D10409F4D6
:10248000E9C0F2E0EF0EF11CF601F182E082E2C059
:1024900020E030E0A901C0E0D0E0F70180EDA82EF7
:1024A000A00E89E08A1530F1912F9260B92E812F0C
:1024B000887012FF04C0811124C0219622C08111AE
:1024C0002197A5E0B0E00E94A114DC01CB01880FA8
:1024D000991FAA1FBB1F9C01AD012A0D311D411D73
:1024E000511D283989E93807480789E1580748F01C
:1024F000166006C09EEFA9120AC013FD40C0186006
:10250000B12E8FEFE81AF80A00811B2DC6CF802F5D
:102510008F7D8534A1F580818D3211F4106106C064
:102520008B3221F0319661E070E004C081813296F7
:1025300062E070E080538A3018F0E61BF70B1FC092
:1025400060E070E060389CE079075CF4DB01AA0F82
:10255000BB1FAA0FBB1F6A0F7B1F660F771F680F79
:10256000711D3196DF0111978C9180538A3050F3A1
:1025700014FF03C0719561957109C60FD71F11FF34
:1025800008C0C114D10429F0CF010197F60191834D
:102590008083CA01B9010E947F13212F2370233049
:1025A00019F04B015C0106C04B015C01B7FAB09415
:1025B000B7F8B09420E030E0A901C501B4010E9451
:1025C0007A13882309F43EC0D7FF06C0D195C19580
:1025D000D10907EA10E002C00FEB10E06801F8E152
:1025E000CF1AD10890E2E92EF12CCE15DF0574F058
:1025F000F8012591359145915491C501B4010E948E
:10260000E0134B015C01CE19DF09EFCF0450110933
:10261000F594E7940C151D0541F78A2D880F8B2D35
:10262000881F8F3F49F020E030E0A901C501B401C7
:102630000E947A13811106C082E290E090939B027F
:1026400080939A02C501B40109C060E070E080E89F
:102650009FEF04C060E070E080EC9FE7CDB7DEB78D
:10266000ECE00C94CE14FC0188279927E894219182
:102670002032E9F3293010F02E30C8F32B3241F02C
:102680002D3239F4689404C00E947213820F911D98
:10269000219120532A30C0F31EF4909581959F4FCD
:1026A000089591110C944D14803219F08950855081
:1026B000C8F70895FB01DC014150504088F08D912E
:1026C00081341CF08B350CF4805E659161341CF014
:1026D0006B350CF4605E861B611171F3990B0895E4
:1026E000881BFCCF7AE0979F902D879F802D910DBE
:1026F000112408950E94BC1308F481E00895E89421
:1027000009C097FB3EF490958095709561957F4F39
:102710008F4F9F4F9923A9F0F92F96E9BB279395E7
:10272000F695879577956795B795F111F8CFFAF4F7
:10273000BB0F11F460FF1BC06F5F7F4F8F4F9F4F28
:1027400016C0882311F096E911C0772321F09EE886
:10275000872F762F05C0662371F096E8862F70E0EC
:1027600060E02AF09A95660F771F881FDAF7880FC6
:102770009695879597F90895990F0008550FAA0B1C
:10278000E0E8FEEF16161706E807F907C0F0121684
:102790001306E407F50798F0621B730B840B950B87
:1027A00039F40A2661F0232B242B252B21F40895DC
:1027B0000A2609F4A140A6958FEF811D811D089579
:1027C0000E94F3130C9467140E94591438F00E946D
:1027D000601420F0952311F00C9450140C945614AE
:1027E00011240C949B140E94781470F3959FC1F3EC
:1027F000950F50E0551F629FF001729FBB27F00DAF
:10280000B11D639FAA27F00DB11DAA1F649F662703
:10281000B00DA11D661F829F2227B00DA11D621F52
:10282000739FB00DA11D621F839FA00D611D221F0C
:10283000749F3327A00D611D231F849F600D211DF0
:10284000822F762F6A2F11249F5750409AF0F1F073
:1028500088234AF0EE0FFF1FBB1F661F771F881FDC
:1028600091505040A9F79E3F510580F00C945014B0
:102870000C949B145F3FE4F3983ED4F386957795D0
:102880006795B795F795E7959F5FC1F7FE2B880F82
:10289000911D9695879597F908959927882708950A
:1028A00097F99F6780E870E060E008959FEF80EC03
:1028B000089500240A9416161706180609060895A6
:1028C00000240A9412161306140605060895092E0C
:1028D0000394000C11F4882352F0BB0F40F4BF2B7B
:1028E00011F460FF04C06F5F7F4F8F4F9F4F0895BB
:1028F00057FD9058440F551F59F05F3F71F04795B1
:10290000880F97FB991F61F09F3F79F08795089595
:10291000121613061406551FF2CF4695F1DF08C0B4
:10292000161617061806991FF1CF869571056105D1
:1029300008940895E894BB2766277727CB0197F979
:1029400008950E94E314A59F900DB49F900DA49F3D
:10295000800D911D112408952F923F924F925F9206
:102960006F927F928F929F92AF92BF92CF92DF929F
:10297000EF92FF920F931F93CF93DF93CDB7DEB704
:10298000CA1BDB0B0FB6F894DEBF0FBECDBF099498
:102990002A88398848885F846E847D848C849B84EF
:1029A000AA84B984C884DF80EE80FD800C811B81FD
:1029B000AA81B981CE0FD11D0FB6F894DEBF0FBE2C
:1029C000CDBFED010895A29FB001B39FC001A39FA9
:1029D000700D811D1124911DB29F700D811D112458
:1029E000911D08955058BB27AA270E940A150C94E0
:1029F00067140E94591438F00E94601420F039F4D2
:102A00009F3F19F426F40C9456140EF4E095E7FB5E
:102A10000C945014E92F0E94781458F3BA176207E7
:102A200073078407950720F079F4A6F50C949A149F
:102A30000EF4E0950B2EBA2FA02D0B01B9019001D9
:102A40000C01CA01A0011124FF27591B99F0593F1D
:102A500050F4503E68F11A16F040A22F232F342F65
:102A60004427585FF3CF469537952795A795F040B3
:102A70005395C9F77EF41F16BA0B620B730B840BC8
:102A8000BAF09150A1F0FF0FBB1F661F771F881F80
:102A9000C2F70EC0BA0F621F731F841F48F48795D8
:102AA00077956795B795F7959E3F08F0B0CF9395CA
:102AB000880F08F09927EE0F9795879508950E9443
:102AC00073150C9467140E94601458F00E945914F6
:102AD00040F029F45F3F29F00C94501451110C94EC
:102AE0009B140C9456140E94781468F39923B1F344
:102AF000552391F3951B550BBB27AA276217730724
:102B0000840738F09F5F5F4F220F331F441FAA1FB7
:102B1000A9F335D00E2E3AF0E0E832D09150504073
:102B2000E695001CCAF72BD0FE2F29D0660F771F21
:102B3000881FBB1F261737074807AB07B0E809F007
:102B4000BB0B802DBF01FF2793585F4F3AF09E3F8C
:102B5000510578F00C9450140C949B145F3FE4F3EF
:102B6000983ED4F3869577956795B795F7959F5FCF
:102B7000C9F7880F911D9695879597F90895E1E01B
:102B8000660F771F881FBB1F621773078407BA077A
:102B900020F0621B730B840BBA0BEE1F88F7E095D5
:102BA00008950E94D8156894B1110C949B1408954F
:102BB0000E94801488F09F5798F0B92F9927B75139
:102BC000B0F0E1F0660F771F881F991F1AF0BA95D1
:102BD000C9F714C0B13091F00E949A14B1E0089581
:102BE0000C949A14672F782F8827B85F39F0B93F73
:102BF000CCF3869577956795B395D9F73EF4909584
:102C00008095709561957F4F8F4F9F4F08950E94DB
:102C1000BC1308F48FEF089519F416F40C945614AD
:102C20000C9457160E948014B8F39923C9F3B6F395
:102C30009F57550B87FF0E9465160024A0E640EAC7
:102C4000900180585695979528F4805C660F771F01
:102C5000881F20F026173707480730F4621B730BD4
:102C6000840B202931294A2BA695179407942025F7
:102C700031254A2758F7660F771F881F20F026173F
:102C80003707480730F4620B730B840B200D311D9E
:102C9000411DA09581F7B901842F9158880F969511
:102CA000879508950E94BC13880B990B08959F3F48
:102CB00031F0915020F4879577956795B795880FF7
:102CC000911D9695879597F9089591505040660FFC
:102CD000771F881FD2F70895A1E21A2EAA1BBB1BEB
:102CE000FD010DC0AA1FBB1FEE1FFF1FA217B307D8
:102CF000E407F50720F0A21BB30BE40BF50B661FEE
:102D0000771F881F991F1A9469F7609570958095B1
:102D100090959B01AC01BD01CF010895052E97FB55
:102D20001EF400940E94A51657FD07D00E946C1651
:102D300007FC03D04EF40C94A516509540953095A1
:102D400021953F4F4F4F5F4F089590958095709517
:102D500061957F4F8F4F9F4F0895EE0FFF1F059096
:102D6000F491E02D09940F931F93CF93DF9382305A
:102D7000910510F482E090E0E0919E02F0919F02B4
:102D800020E030E0A0E0B0E0309719F140815181BF
:102D90000281138148175907C8F08417950769F411
:102DA000109731F012960C93129713961C9327C02C
:102DB00000939E0210939F0222C02115310519F045
:102DC0004217530718F49A01BD01EF01DF01F80122
:102DD000DBCF21153105F9F0281B390B24303105E3
:102DE00080F48A819B816115710521F0FB01938339
:102DF000828304C090939F0280939E02FE013296CC
:102E000044C0FE01E20FF31F8193919322503109D8
:102E1000398328833AC020919C0230919D02232B54
:102E200041F4209102013091030130939D022093DF
:102E30009C0220910001309101012115310541F4DE
:102E40002DB73EB74091040150910501241B350B6D
:102E5000E0919C02F0919D02E217F307A0F42E1B73
:102E60003F0B2817390778F0AC014E5F5F4F2417EE
:102E7000350748F04E0F5F1F50939D0240939C0210
:102E80008193919302C0E0E0F0E0CF01DF91CF9118
:102E90001F910F910895CF93DF93009709F481C09C
:102EA000FC01329713821282A0919E02B0919F0280
:102EB000109781F420813181820F931F20919C0211
:102EC00030919D022817390751F5F0939D02E09348
:102ED0009C0267C0ED0120E030E0CE17DF0740F430
:102EE0004A815B819E0141155105F1F0EA01F5CF60
:102EF000D383C28340815181840F951FC817D9079E
:102F000059F488819981840F951F0296918380835B
:102F10008A819B81938382832115310529F4F09363
:102F20009F02E0939E023DC0E901FB83EA83499141
:102F30005991C40FD51FEC17FD0761F48081918171
:102F4000840F951F0296E90199838883828193817A
:102F50009B838A83E0E0F0E012968D919C91139719
:102F6000009719F0FD01DC01F7CF8D919C9111972D
:102F70009D012E5F3F4F820F931F20919C02309145
:102F80009D022817390769F4309729F410929F029F
:102F900010929E0202C013821282B0939D02A093EF
:102FA0009C02DF91CF91089581E090E0F8940C9419
:102FB000E417FC018191861721F08823D9F799271E
:102FC00008953197CF01089511E0C2E4D1E004C023
:102FD000FE010E94AD162196C334D107C9F7F894BB
:022FE000FFCF21
:102FE2000000A0028000000000008B035703A90329
:102FF2001203FC02C402A3026F024E02F801B401E2
:103002000000000003043E086D0150049E017C0193
:1030120090016E616E00696E66006F7666000D0A41
:1030220000762E32303139303231310054004600D0
:0430320052454C00B7
:107E0000112484B714BE81FFF0D085E080938100F7
:107E100082E08093C00088E18093C10086E0809377
:107E2000C20080E18093C4008EE0C9D0259A86E02C
:107E300020E33CEF91E0309385002093840096BBD3
:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
:107E6000A2D0813461F49FD0082FAFD0023811F036
:107E7000013811F484E001C083E08DD089C08234E0
:107E800011F484E103C0853419F485E0A6D080C0E4
:107E9000853579F488D0E82EFF2485D0082F10E0AE
:107EA000102F00270E291F29000F111F8ED06801E7
:107EB0006FC0863521F484E090D080E0DECF843638
:107EC00009F040C070D06FD0082F6DD080E0C81688
:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
:107F0000A601A0E0B1E02C9130E011968C91119780
:107F100090E0982F8827822B932B1296FA010C0160
:107F200087BEE89511244E5F5F4FF1E0A038BF0790
:107F300051F7F601A7BEE89507B600FCFDCF97BE46
:107F4000E89526C08437B1F42ED02DD0F82E2BD052
:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
:107F7000D11C0EC0853739F428D08EE10CD085E9AC
:107F80000AD08FE07ACF813511F488E018D01DD067
:107F900080E101D065CF982F8091C00085FFFCCF94
:107FA0009093C60008958091C00087FFFCCF809118
:107FB000C00084FD01C0A8958091C6000895E0E648
:107FC000F0E098E1908380830895EDDF803219F02E
:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
:047FF000FF270994CA
:027FFE00040479
:0400000300007E007B
:00000001FF

View file

@ -1,48 +0,0 @@
import json
import urllib2
import requests
import socket
import logging
try:
import ssl
except ImportError:
print "error: no ssl support"
_logger = logging.getLogger(__name__)
DISCOVERY_URL = "https://find.fabscan.org/register.php"
def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except:
IP = '127.0.0.1'
finally:
s.close()
return IP
def register_to_discovery(server_version, firmware_version):
_logger.info("Registering ip "+get_ip()+" to discovery service.")
headers = {
'Content-Type': 'application/json'
}
payload = {
'ip': str(get_ip()),
'server_version': str(server_version),
'firmware_version': str(firmware_version)
}
response = requests.post(DISCOVERY_URL, headers=headers, data=json.dumps(payload))
response.raise_for_status()
if response.status_code == 200:
_logger.info('Successfully registered to find.fabscan.org')
else:
_logger.warn('Not able to register to find.fabscan.org')

View file

@ -24,12 +24,7 @@ def get_latest_version_tag():
_logger.debug("Scanner is Online...") _logger.debug("Scanner is Online...")
try: try:
stage = "stable" response = urllib2.urlopen("http://archive.fabscan.org/dists/stable/main/binary-armhf/Packages", timeout=0.4)
if "+" in __version__:
stage = "testing"
response = urllib2.urlopen("http://archive.fabscan.org/dists/" + str(stage) + "/main/binary-armhf/Packages", timeout=0.4)
latest_version = __version__ latest_version = __version__
line = 'START' line = 'START'
while line != '': while line != '':
@ -76,4 +71,4 @@ def upgrade_is_available(current_version):
def do_upgrade(): def do_upgrade():
os.system('nohup bash -c "sudo apt-get update -y && sudo apt-get dist-upgrade -y" >> /var/log/fabscanpi/upgrade.log') os.system('nohup bash -c "sudo apt-get update -y && sudo apt-get dist-upgrade -y" > /var/log/fabscanpi/upgrade.log')

View file

@ -82,7 +82,6 @@ class FSCalibration(FSCalibrationInterface):
def start(self): def start(self):
#self._hardwarecontroller.stop_camera_stream()
tools = FSSystem() tools = FSSystem()
tools.delete_folder(self.config.folders.scans+'calibration') tools.delete_folder(self.config.folders.scans+'calibration')
self._hardwarecontroller.turntable.enable_motors() self._hardwarecontroller.turntable.enable_motors()
@ -107,6 +106,8 @@ class FSCalibration(FSCalibrationInterface):
self._do_calibration(self._capture_camera_calibration, self._calculate_camera_calibration) self._do_calibration(self._capture_camera_calibration, self._calculate_camera_calibration)
self._do_calibration(self._capture_scanner_calibration, self._calculate_scanner_calibration) self._do_calibration(self._capture_scanner_calibration, self._calculate_scanner_calibration)
self._hardwarecontroller.led.off()
self._hardwarecontroller.turntable.disable_motors()
if self._stop: if self._stop:
self._logger.debug("Calibration canceled...") self._logger.debug("Calibration canceled...")
@ -153,7 +154,10 @@ class FSCalibration(FSCalibrationInterface):
# 90 degree turn # 90 degree turn
try: try:
if not self._stop: if not self._stop:
self._logger.debug(self.quater_turn)
self._hardwarecontroller.turntable.step_blocking(self.quater_turn, speed=900) self._hardwarecontroller.turntable.step_blocking(self.quater_turn, speed=900)
# self._hardwarecontroller.start_camera_stream(mode="calibration")
position = 0 position = 0
while abs(position) < self.quater_turn * 2: while abs(position) < self.quater_turn * 2:
@ -215,9 +219,9 @@ class FSCalibration(FSCalibrationInterface):
#TODO: find out if it is better and try this...again. #TODO: find out if it is better and try this...again.
#if (position > self.laser_calib_start and position < self.laser_calib_end): #if (position > self.laser_calib_start and position < self.laser_calib_end):
#flags = cv2.CALIB_CB_FAST_CHECK | cv2.CALIB_CB_ADAPTIVE_THRESH | cv2.CALIB_CB_NORMALIZE_IMAGE flags = cv2.CALIB_CB_FAST_CHECK | cv2.CALIB_CB_ADAPTIVE_THRESH | cv2.CALIB_CB_NORMALIZE_IMAGE
#else: #else:
flags = cv2.CALIB_CB_FAST_CHECK # flags = cv2.CALIB_CB_FAST_CHECK
corners = self._imageprocessor.detect_corners(image, flags) corners = self._imageprocessor.detect_corners(image, flags)

View file

@ -7,7 +7,7 @@ __email__ = "info@mariolukas.de"
import logging import logging
import time import time
import threading import threading
import copy
from fabscan.FSConfig import ConfigInterface from fabscan.FSConfig import ConfigInterface
from fabscan.FSSettings import SettingsInterface from fabscan.FSSettings import SettingsInterface
from fabscan.lib.util.FSInject import singleton from fabscan.lib.util.FSInject import singleton
@ -55,57 +55,10 @@ class FSHardwareControllerSingleton(FSHardwareControllerInterface):
self._logger.debug("Hardware controller initialized...") self._logger.debug("Hardware controller initialized...")
self.lock = threading.Lock() self.lock = threading.Lock()
self.hardware_test_functions = {
"TURNTABLE": {
"FUNCTIONS": {
"START": self.turntable.start_turning,
"STOP": self.turntable.stop_turning
},
"LABEL": "Turntable"
},
"LEFT_LASER": {
"FUNCTIONS": {
"ON": lambda: self.laser.on(0),
"OFF": lambda: self.laser.off(0)
},
"LABEL": "First Laser"
},
#"RIGHT_LASER": {
# "FUNCTIONS": {
# "ON": lambda: self.laser.on(1),
# "OFF": lambda: self.laser.off(1)
# },
# "LABEL": "Second Laser"
#},
"LED_RING": {
"FUNCTIONS": {
"ON": lambda: self.led.on(255, 255, 255),
"OFF": lambda: self.led.off()
},
"LABEL": "Led Ring"
}
}
def flush(self): def flush(self):
self.camera.camera_buffer.flush() self.camera.camera_buffer.flush()
#self.serial_connection.flush() #self.serial_connection.flush()
def get_devices_as_json(self):
devices = copy.deepcopy(self.hardware_test_functions)
for fnct in self.hardware_test_functions:
devices[fnct]['FUNCTIONS'] = self.hardware_test_functions[fnct]['FUNCTIONS'].keys()
return devices
def call_test_function(self, device):
device_name = str(device.name)
device_value = str(device.function)
#self._logger.debug(device)
call_function = self.hardware_test_functions.get(device_name).get("FUNCTIONS").get(device_value)
call_function()
def settings_mode_on(self): def settings_mode_on(self):
while not self.camera.device.is_idle(): while not self.camera.device.is_idle():
time.sleep(0.1) time.sleep(0.1)
@ -113,7 +66,7 @@ class FSHardwareControllerSingleton(FSHardwareControllerInterface):
self._settings_mode_is_off = False self._settings_mode_is_off = False
self.camera.device.flush_stream() self.camera.device.flush_stream()
self.laser.on(laser=0) self.laser.on(laser=0)
#self.turntable.start_turning() self.turntable.start_turning()
def settings_mode_off(self): def settings_mode_off(self):
self.turntable.stop_turning() self.turntable.stop_turning()
@ -122,8 +75,6 @@ class FSHardwareControllerSingleton(FSHardwareControllerInterface):
self.camera.device.stop_stream() self.camera.device.stop_stream()
self.camera.device.flush_stream() self.camera.device.flush_stream()
self._settings_mode_is_off = True self._settings_mode_is_off = True
time.sleep(0.3)
def get_picture(self): def get_picture(self):
img = self.camera.device.get_frame() img = self.camera.device.get_frame()

View file

@ -245,19 +245,13 @@ class ImageProcessor(ImageProcessorInterface):
def get_laser_stream_frame(self, image, type='CAMERA'): def get_laser_stream_frame(self, image, type='CAMERA'):
if bool(self.settings.show_laser_overlay): points, ret_img = self.compute_2d_points(image, roi_mask=False)
points, ret_img = self.compute_2d_points(image, roi_mask=False) u, v = points
u, v = points c = zip(u, v)
c = zip(u, v)
for t in c:
cv2.line(image, (int(t[0]) - 1, int(t[1])), (int(t[0]) + 1, int(t[1])), (255, 0, 0), thickness=1,
lineType=8, shift=0)
if bool(self.settings.show_calibration_pattern):
cv2.line(image, (int(0.5*image.shape[1]), 0), (int(0.5*image.shape[1]), image.shape[0]), (0, 255, 0), thickness=1, lineType=8, shift=0)
cv2.line(image, (0,int(0.5*image.shape[0])), (image.shape[1], int(0.5*image.shape[0])), (0, 255, 0), thickness=1, lineType=8, shift=0)
for t in c:
cv2.line(image, (int(t[0]) - 1, int(t[1])), (int(t[0]) + 1, int(t[1])), (255, 0, 0), thickness=1,
lineType=8, shift=0)
return image return image

View file

@ -202,8 +202,6 @@ class FSScanProcessor(FSScanProcessorInterface):
pass pass
def start_calibration(self): def start_calibration(self):
self.hardwareController.settings_mode_off()
time.sleep(0.5)
self.calibration.start() self.calibration.start()
def stop_calibration(self): def stop_calibration(self):
@ -229,19 +227,9 @@ class FSScanProcessor(FSScanProcessorInterface):
self.eventmanager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message) self.eventmanager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message)
def settings_mode_on(self): def settings_mode_on(self):
#message = {
# "message": "SETTINGS_MODE_ON",
# "level": "info"
#}
#self.eventmanager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message)
self.hardwareController.settings_mode_on() self.hardwareController.settings_mode_on()
def settings_mode_off(self): def settings_mode_off(self):
#message = {
# "message": "SETTINGS_MODE_OFF",
# "level": "info"
#}
#self.eventmanager.broadcast_client_message(FSEvents.ON_INFO_MESSAGE, message)
self.hardwareController.settings_mode_off() self.hardwareController.settings_mode_off()
def start_scan(self): def start_scan(self):
@ -267,7 +255,7 @@ class FSScanProcessor(FSScanProcessorInterface):
self._prefix = datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M%S') self._prefix = datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M%S')
self.point_cloud = FSPointCloud(color=self._is_color_scan) self.point_cloud = FSPointCloud(color=self._is_color_scan)
if not (self.config.calibration.laser_planes[0]['normal'] == []) and self.actor_ref.is_alive(): if not (self.config.calibration.camera_matrix == []) and self.actor_ref.is_alive():
if self._is_color_scan: if self._is_color_scan:
self._total = self._number_of_pictures * 2 * self.config.laser.numbers self._total = self._number_of_pictures * 2 * self.config.laser.numbers
self.actor_ref.tell({FSEvents.COMMAND: FSScanProcessorCommand._SCAN_NEXT_TEXTURE_POSITION}) self.actor_ref.tell({FSEvents.COMMAND: FSScanProcessorCommand._SCAN_NEXT_TEXTURE_POSITION})

View file

@ -124,7 +124,6 @@ class CamProcessor(threading.Thread):
if self.mode == "settings": if self.mode == "settings":
image = self.imageprocessor.get_laser_stream_frame(image) image = self.imageprocessor.get_laser_stream_frame(image)
#if self.use_distortion: #if self.use_distortion:
# if image is not None and \ # if image is not None and \
# self.config.calibration.camera_matrix is not [] and \ # self.config.calibration.camera_matrix is not [] and \
@ -230,15 +229,8 @@ class PiCam(threading.Thread):
# self.resolution = (self.config.camera.preview_resolution.width, self.config.camera.preview_resolution.height) # self.resolution = (self.config.camera.preview_resolution.width, self.config.camera.preview_resolution.height)
self.camera_buffer = cam_ring_buffer self.camera_buffer = cam_ring_buffer
# self.camera = picamera.PiCamera(resolution=self.resolution)
self.newcameramtx = None
self.roi = None
self.mapx = None
self.mapy = None
self.idle = True self.idle = True
self.resolution = (self.config.camera.preview_resolution.width, self.config.camera.preview_resolution.height)
self.camera = picamera.PiCamera(resolution=self.resolution)
self.start() self.start()
def run(self): def run(self):
@ -254,24 +246,11 @@ class PiCam(threading.Thread):
else: else:
time.sleep(0.05) time.sleep(0.05)
def get_frame(self, undistort=False): def get_frame(self):
image = None image = None
while image is None: while image is None:
#with self.camera_buffer._lock: #with self.camera_buffer._lock:
image = self.camera_buffer.get() image = self.camera_buffer.get()
#if undistort:
# self._logger.debug(self.config.calibration.camera_matrix)
# self.newcameramtx, self.roi = cv2.getOptimalNewCameraMatrix(np.asarray(self.config.calibration.camera_matrix), np.asarray(self.config.calibration.distortion_vector), self.resolution, 1, self.resolution )
#image = cv2.remap(image, self.mapx, self.mapy, cv2.INTER_LINEAR)
# image = cv2.undistort(image,
# np.asarray(self.config.calibration.camera_matrix),
# np.asarray(self.config.calibration.distortion_vector),
# None,
# self.newcameramtx)
return image return image
def set_mode(self, mode): def set_mode(self, mode):
@ -307,25 +286,8 @@ class PiCam(threading.Thread):
#self.flush_stream() #self.flush_stream()
self.set_mode(mode) self.set_mode(mode)
if self.camera is None:
#if len(self.config.calibration.camera_matrix) > 0: self.camera = picamera.PiCamera(resolution=self.resolution)
# self.newcameramtx, self.roi = cv2.getOptimalNewCameraMatrix(self.config.calibration.camera_matrix,
# self.config.calibration.distortion_vector,
# self.resolution,
# 1,
# self.resolution)
# self.mapx, self.mapy = cv2.initUndistortRectifyMap(self.config.calibration.camera_matrix,
# self.config.calibration.distortion_vector,
# None,
# self.newcameramtx,
# self.resolution,
# 5)
#if self.camera is None:
# self.camera = picamera.PiCamera(resolution=self.resolution)
if self.camera:
self.camera.resolution = self.resolution
self.idle = False self.idle = False
self.camera.start_recording(self.output, format='mjpeg') self.camera.start_recording(self.output, format='mjpeg')
@ -341,8 +303,8 @@ class PiCam(threading.Thread):
self.camera.stop_recording() self.camera.stop_recording()
while self.camera.recording: while self.camera.recording:
time.sleep(0.4) time.sleep(0.4)
#self.camera.close() self.camera.close()
#self.camera = None self.camera = None
self.idle = True self.idle = True
self._logger.debug("Cam Stream with Resolution " + str(self.resolution) + " stopped") self._logger.debug("Cam Stream with Resolution " + str(self.resolution) + " stopped")
@ -356,7 +318,6 @@ class PiCam(threading.Thread):
def flush_stream(self): def flush_stream(self):
self.camera_buffer.flush() self.camera_buffer.flush()
### ###
# This class is used to catch openCV errors which are not catchable by python # This class is used to catch openCV errors which are not catchable by python
# see https://stackoverflow.com/questions/9131992/how-can-i-catch-corrupt-jpegs-when-loading-an-image-with-imread-in-opencv/45055195 # see https://stackoverflow.com/questions/9131992/how-can-i-catch-corrupt-jpegs-when-loading-an-image-with-imread-in-opencv/45055195
@ -452,7 +413,7 @@ class USBCam(threading.Thread):
def set_settings_preview(self): def set_settings_preview(self):
self.resolution = ( self.resolution = (
self.config.camera.resolution.width, self.config.camera.resolution.height) self.config.camera.preview_resolution.width, self.config.camera.preview_resolution.height)
self.output = ProcessCamOutput(self.camera_buffer, self.resolution, mode="settings") self.output = ProcessCamOutput(self.camera_buffer, self.resolution, mode="settings")
def set_default_mode(self): def set_default_mode(self):

View file

@ -9,12 +9,10 @@ import glob
import serial import serial
import time import time
import logging import logging
import threading
from fabscan.lib.util.FSUtil import FSSystem from fabscan.lib.util.FSUtil import FSSystem
from fabscan.lib.util.FSInject import inject from fabscan.lib.util.FSInject import inject
from fabscan.FSConfig import ConfigInterface from fabscan.FSConfig import ConfigInterface
@inject( @inject(
config=ConfigInterface config=ConfigInterface
) )
@ -43,8 +41,7 @@ class FSSerialCom():
self._openSerial() self._openSerial()
self._logger.debug("Connection baudrate is: "+str(self._baudrate)) self._logger.debug("Connection baudrate is: "+str(self._baudrate))
self._logger.debug("Firmware flashing baudrate is: "+str(self.flash_baudrate)) self._logger.debug("Firmware flashing baudrate is: "+str(self.flash_baudrate))
self.lock = threading.RLock()
self._stop = False
def avr_device_is_available(self): def avr_device_is_available(self):
status = FSSystem.run_command("sudo avrdude-autoreset -p m328p -b "+str(self.flash_baudrate)+" -carduino -P"+str(self._port)) status = FSSystem.run_command("sudo avrdude-autoreset -p m328p -b "+str(self.flash_baudrate)+" -carduino -P"+str(self._port))
@ -61,7 +58,7 @@ class FSSerialCom():
self._logger.debug("Trying to connect Arduino on port: "+str(self._port)) self._logger.debug("Trying to connect Arduino on port: "+str(self._port))
# open serial port # open serial port
try: try:
self._serial = serial.Serial(str(self._port), int(self._baudrate), timeout=5) self._serial = serial.Serial(str(self._port), int(self._baudrate), timeout=0.3)
time.sleep(1) time.sleep(1)
except: except:
self._logger.error("Could not open serial port") self._logger.error("Could not open serial port")
@ -71,10 +68,8 @@ class FSSerialCom():
def _openSerial(self): def _openSerial(self):
basedir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) basedir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
flash_file_version = max(sorted(glob.iglob(basedir+'/firmware/'+str(self.config.serial.plattform_type)+'_*.hex'), key=os.path.getctime, reverse=True)) flash_file_version = max(sorted(glob.iglob(basedir+'/firmware/*.hex'), key=os.path.getctime,reverse=True))
flash_version_number = os.path.basename(os.path.normpath(os.path.splitext(flash_file_version)[0]))
flash_version_number = os.path.basename(os.path.normpath(os.path.splitext(flash_file_version.split('_', 1)[-1])[0]))
self._logger.debug("Latest available firmware version is: "+flash_version_number) self._logger.debug("Latest available firmware version is: "+flash_version_number)
try: try:
@ -149,19 +144,17 @@ class FSSerialCom():
def send_and_receive(self, message): def send_and_receive(self, message):
self.send(message) self.send(message)
# time.sleep(0.2) time.sleep(0.2)
response = "" response = ""
self._stop = False while True:
with self.lock: response += self._serial.read()
while not self._stop: if ">" in response:
response += self._serial.read() response = response.rstrip(">")
if ">" in response: response = response.translate(None, '\n\t\r')
response = response.rstrip(">") if response:
response = response.translate(None, '\n\t\r') self._logger.debug("Command successfully sent: " + response)
if response: break
self._logger.debug("Command successfully sent: " + response)
self._stop = True
break
def flush(self): def flush(self):
self._serial.flushInput() self._serial.flushInput()

View file

@ -4,7 +4,6 @@ __license__ = "GPL v2"
__maintainer__ = "Mario Lukas" __maintainer__ = "Mario Lukas"
__email__ = "info@mariolukas.de" __email__ = "info@mariolukas.de"
import time
from fabscan.lib.util.FSInject import inject from fabscan.lib.util.FSInject import inject
from fabscan.FSConfig import ConfigInterface from fabscan.FSConfig import ConfigInterface
@ -35,9 +34,8 @@ class Turntable(object):
steps *= self.scaler steps *= self.scaler
if self.serial_connection != None: if self.serial_connection != None:
command = "G04 T"+str(steps)+" F"+str(speed)+";" command = "G02 T"+str(steps)+" F"+str(speed)+";"
self.serial_connection.send_and_receive(command) self.serial_connection.send_and_receive(command)
time.sleep(1)
def enable_motors(self): def enable_motors(self):
if self.serial_connection != None: if self.serial_connection != None:

View file

@ -16,29 +16,24 @@ from fabscan.server.services.api.FSScanHandler import FSScanHandler
from fabscan.server.services.api.FSStreamHandler import FSStreamHandler from fabscan.server.services.api.FSStreamHandler import FSStreamHandler
from fabscan.server.services.api.FSStaticFileHandler import FSStaticFileHandler from fabscan.server.services.api.FSStaticFileHandler import FSStaticFileHandler
from fabscan.server.services.api.FSDownloadHandler import FSDownloadHandler from fabscan.server.services.api.FSDownloadHandler import FSDownloadHandler
from fabscan.server.services.api.FSLogHandler import FSLogHandler
from fabscan.server.services.api.FSDeviceHandler import FSDeviceHandler
from fabscan.FSEvents import FSEvents, FSEventManagerSingleton from fabscan.FSEvents import FSEvents, FSEventManagerSingleton
from fabscan.scanner.interfaces.FSScanProcessor import FSScanProcessorInterface from fabscan.scanner.interfaces.FSScanProcessor import FSScanProcessorInterface
from fabscan.scanner.interfaces.FSHardwareController import FSHardwareControllerInterface
from fabscan.FSConfig import ConfigSingleton, ConfigInterface from fabscan.FSConfig import ConfigSingleton, ConfigInterface
from fabscan.lib.util.FSInject import inject from fabscan.lib.util.FSInject import inject
@inject( @inject(
config=ConfigInterface, config=ConfigInterface,
scanprocessor=FSScanProcessorInterface, scanprocessor=FSScanProcessorInterface,
eventmanager=FSEventManagerSingleton, eventmanager=FSEventManagerSingleton
hardwarecontroller=FSHardwareControllerInterface
) )
class FSWebServer(threading.Thread): class FSWebServer(threading.Thread):
def __init__(self, config, scanprocessor, eventmanager, hardwarecontroller): def __init__(self, config, scanprocessor, eventmanager):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.config = config self.config = config
self.exit = False self.exit = False
self.scanprocessor = scanprocessor self.scanprocessor = scanprocessor
self.eventmanager = eventmanager self.eventmanager = eventmanager
self.hardwarecontroller = hardwarecontroller
self.www_folder = os.path.join(os.path.dirname(__file__), self.config.folders.www) self.www_folder = os.path.join(os.path.dirname(__file__), self.config.folders.www)
self.scan_folder = os.path.join(os.path.dirname(__file__), self.config.folders.scans) self.scan_folder = os.path.join(os.path.dirname(__file__), self.config.folders.scans)
self._logger = logging.getLogger(__name__) self._logger = logging.getLogger(__name__)
@ -48,10 +43,7 @@ class FSWebServer(threading.Thread):
return tornado.web.Application([ return tornado.web.Application([
(r"/api/v1/filters/", FSFilterHandler), (r"/api/v1/filters/", FSFilterHandler),
(r"/api/v1/streams/", FSStreamHandler, dict(scanprocessor=self.scanprocessor)), (r"/api/v1/streams/", FSStreamHandler, dict(scanprocessor=self.scanprocessor)),
(r"/api/v1/log/show", FSLogHandler, dict(config=self.config)),
(r"/api/v1/log/download", FSLogHandler, dict(config=self.config)),
(r"/api/v1/scans/", FSScanHandler, dict(config=self.config)), (r"/api/v1/scans/", FSScanHandler, dict(config=self.config)),
(r"/api/v1/devices/", FSDeviceHandler, dict(config=self.config, hardwarecontroller=self.hardwarecontroller)),
(r"/api/v1/scans/(?P<scan_id>\d{8}[-]\d{6}$)", FSScanHandler, dict(config=self.config)), (r"/api/v1/scans/(?P<scan_id>\d{8}[-]\d{6}$)", FSScanHandler, dict(config=self.config)),
(r"/api/v1/scans/(?P<scan_id>\d{8}[-]\d{6})/(?P<files>files)$", FSScanHandler, dict(config=self.config)), (r"/api/v1/scans/(?P<scan_id>\d{8}[-]\d{6})/(?P<files>files)$", FSScanHandler, dict(config=self.config)),
(r"/api/v1/scans/(?P<scan_id>\d{8}[-]\d{6})/(?P<files>downloads)/(?P<file_name>.*)$", FSDownloadHandler, dict(config=self.config)), (r"/api/v1/scans/(?P<scan_id>\d{8}[-]\d{6})/(?P<files>downloads)/(?P<file_name>.*)$", FSDownloadHandler, dict(config=self.config)),

View file

@ -2,10 +2,6 @@ import tornado.web
class BaseHandler(tornado.web.RequestHandler): class BaseHandler(tornado.web.RequestHandler):
def set_extra_headers(self, path):
# Disable cache
self.set_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
def set_default_headers(self): def set_default_headers(self):
self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Origin", "*")
self.set_header("Access-Control-Allow-Headers", "x-requested-with") self.set_header("Access-Control-Allow-Headers", "x-requested-with")

View file

@ -1,19 +0,0 @@
import os
import json
import glob
import shutil
import logging
import tornado.web
from fabscan.lib.file.FSScans import FSScans
from fabscan.server.services.api.FSBaseHandler import BaseHandler
class FSDeviceHandler(BaseHandler):
def initialize(self, *args, **kwargs):
self._logger = logging.getLogger(__name__)
self.config = kwargs.get('config')
self.hardwarecontroller = kwargs.get('hardwarecontroller')
def get(self):
devices = self.hardwarecontroller.get_devices_as_json()
self.write(json.dumps(devices))

View file

@ -1,90 +0,0 @@
import subprocess
import logging
import tornado.web
import time
from os.path import basename
from datetime import datetime
from zipfile import ZipFile
from fabscan.lib.file.FSScans import FSScans
from fabscan.server.services.api.FSBaseHandler import BaseHandler
class FSLogHandler(BaseHandler):
def initialize(self, *args, **kwargs):
self._logger = logging.getLogger(__name__)
self.config = kwargs.get('config')
self.scanlib = FSScans()
@tornado.web.asynchronous
def get(self):
try:
log_file = self._logger.handlers[0].baseFilename
except:
log_file = "/var/log/fabscanpi/fabscanpi.log"
timestamp = datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M%S')
if "download" in self.request.path:
zip_file = "/tmp/fanbscanpi-debug-" + timestamp + ".zip"
config_file = "/etc/fabscanpi/default.config.json"
settings_file = "/etc/fabscanpi/default.settings.json"
process_list = "/tmp/process_list.txt"
cpu_info = "/tmp/cpu_info.txt"
voltage_monitor = "/tmp/voltage_state.txt"
process = subprocess.Popen(["ps -axf > " + process_list], shell=True, stdout=subprocess.PIPE)
process.wait()
process = subprocess.Popen(["cat /proc/cpuinfo > " + cpu_info], shell=True, stdout=subprocess.PIPE)
process.wait()
process = subprocess.Popen(["vcgencmd get_throttled > " + voltage_monitor], shell=True, stdout=subprocess.PIPE)
process.wait()
# put all debug files to zip
with ZipFile(zip_file, 'w') as log_zip:
log_zip.write(log_file, basename(log_file))
log_zip.write(config_file, basename(config_file))
log_zip.write(settings_file, basename(settings_file))
log_zip.write(process_list, basename(process_list))
log_zip.write(cpu_info, basename(cpu_info))
log_zip.write(voltage_monitor, basename(voltage_monitor))
buf_size = 4096
self.set_header('Content-Type', 'application/octet-stream')
self.set_header('Content-Disposition', 'attachment; filename='+basename(zip_file))
with open(zip_file, 'r') as f:
while True:
data = f.read(buf_size)
if not data:
break
self.write(data)
self.finish()
if "show" in self.request.path:
try:
self.p = subprocess.Popen( ["tail", "-f", log_file, "-n+1"], stdout=subprocess.PIPE)
self.write("<pre>")
self.flush()
self.stream = tornado.iostream.PipeIOStream(self.p.stdout.fileno())
self.stream.read_until("\n", self.line_from_nettail)
except:
self.write("No log path configured. Default logging to stdout is active.<br>")
self.write("For seeing a log output here you need to configure a log file path.<br>")
self.flush()
self.finish()
def on_connection_close(self, *args, **kwargs):
"""Clean up the nettail process when the connection is closed.
"""
self.p.terminate()
tornado.web.RequestHandler.on_connection_close(self, *args, **kwargs)
def line_from_nettail(self, data):
self.write(data)
self.flush()
self.stream.read_until("\n", self.line_from_nettail)

View file

@ -6,11 +6,9 @@
type="image/png" type="image/png"
href="icons/favicon.png"> href="icons/favicon.png">
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="Pragma" content="no-cache">
<meta name=viewport content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name=viewport content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-capable content=yes>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<link href="style/lib.css" rel="stylesheet"> <link href="style/lib.css" rel="stylesheet">
<link href="style/app.css" rel="stylesheet"> <link href="style/app.css" rel="stylesheet">
@ -85,150 +83,114 @@
</div> </div>
<!-- Settings View --> <!-- Settings View -->
<div class="settingsWindow" ng-class="{'open':('SETTINGS' | currentState)}">
<div id="settingsWindow" class="settingsWindow" ng-class="{'open':('SETTINGS' | currentState)}"> <div ng-if="('SETTINGS' | currentState)" ng-controller="fabscan.controller.FSSettingsController" >
<div ng-if="('SETTINGS' | currentState)" ng-controller="fabscan.controller.FSSettingsController" >
<div style="z-index:100;" class="settings-preview" id="settings-preview"> <!-- <div style="background-color: black; height:240px; position:absolute; left:0px;"></div>-->
<div style="text-align:center; position:absolute; background-color:black; color: white; height:800px; width:300px; z-index:-1000"> <div>
<div style="margin-top:70%;"> <mjpeg mode="'preview'" url="streamUrl"></mjpeg>
<img style="position:absolute; margin-top:50%; width:50px; height:50px;" src="icons/spinner.gif" /> </div>
Preview is loading... <div class="settings-content">
</div> <div style="height: 40px;">
</div> <div ng-click="selectTab('general')" class="tab icon settings" ng-class="{'active':(selectedTab == 'general')}">
<mjpeg style="z-index:2000" url="streamUrl"></mjpeg> <i class="fa fa-cogs fa-2x"></i>
</div> </div>
<div class="settings-content"> <div ng-click="selectTab('camera')" class="tab icon settings" ng-class="{'active':(selectedTab == 'camera')}">
<i class="fa fa-adjust fa-2x"></i>
</div>
<div ng-click="selectTab('light')" class="tab icon settings" ng-class="{'active':(selectedTab == 'light')}">
<i class="fa fa-sun-o fa-2x"></i>
</div>
<!--
<div ng-click="setCalibrationTab()" class="tab icon settings" ng-class="{'active':(selectedTab == 'calibration')}">
<i class="fa fa-crosshairs fa-2x"></i>
</div>
-->
<div class="tab" sytle="width:100%">
</div>
</div>
<div style="height: 40px;"> <div class="tab-content" ng-show="(selectedTab == 'general')">
<div ng-click="selectTab('general')" class="tab icon settings" ng-class="{'active':(selectedTab == 'general')}"> <div>
<i class="fa fa-cogs fa-2x"></i> <div ng-class="{'fadeOut':!showThresholdValue}" class="slider-value-label">{{settings.threshold}}</div>
</div> <div style="display:inline-block; width:5em; color:white; padding-left:1em;">Threshold</div>
<div ng-click="selectTab('camera')" class="tab icon settings" ng-class="{'active':(selectedTab == 'camera')}"> <slider style="width:70%; margin-left:1em;" floor="0" ceiling="60" step="1" precision="1" ng-model="settings.threshold"></slider>
<i class="fa fa-adjust fa-2x"></i> </div>
</div> <div>
<div ng-click="selectTab('light')" class="tab icon settings" ng-class="{'active':(selectedTab == 'light')}"> <div ng-class="{'longFadeOut':!showResolutionValue}" class="slider-value-label" >{{settings.resolution | toResolutionValue }}</div>
<i class="fa fa-sun-o fa-2x"></i> <div style="display:inline-block; width:5em; color:white; padding-left:1em;">Resolution</div>
</div> <slider class="resolution" style="width:70%; margin-left:1em;" show-steps="true" floor="-16" ceiling="-1" step="4" precision="1" ng-model="settings.resolution"></slider>
<div ng-click="selectTab('hardware')" class="tab icon settings" ng-class="{'active':(selectedTab == 'hardware')}"> </div>
<i class="fa fa-sliders fa-2x"></i> <!--
</div> <div>
<div ng-class="{'longFadeOut':!showResolutionValue}" class="slider-value-label" >{{settings.laser_positions}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Positions</div>
<slider class="resolution" style="width:70%; margin-left:1em;" floor="1" ceiling="4" step="1" precision="1" ng-model="settings.laser_positions"></slider>
</div>
-->
<div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;" >Color Scan</div><input style="width:1em; height:1em; margin-left:1.5em; margin-top:0.5em;" type="checkbox" ng-change="setColor()" ng-checked="colorIsSelected()" ng-model="settings.color">
<div ng-click="setCalibrationTab()" class="tab icon settings" ng-class="{'active':(selectedTab == 'calibration')}"> <a class="hvr-grow" style="margin-right: 13%; margin-top:0.2em; text-decoration:none; float:right; color:white; font-size:1.5em;" ng-click="startScan()" href="#">Start Scan</a>
<i class="fa fa-crosshairs fa-2x"></i> </div>
</div> </div>
<div class="tab-content" ng-show="(selectedTab == 'camera')">
<div>
<div ng-class="{'fadeOut':!showSaturationValue}" class="slider-value-label" >{{settings.camera.saturation}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Saturation</div>
<slider style="width:70%; margin-left:1em;" floor="-100" ceiling="100" step="1" precision="1" ng-model="settings.camera.saturation"></slider>
</div>
<div>
<div ng-class="{'fadeOut':!showBrightnessValue}" class="slider-value-label" >{{settings.camera.brightness}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Brightness</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="100" step="1" precision="1" ng-model="settings.camera.brightness"></slider>
</div>
<div>
<div ng-class="{'fadeOut':!showContrastValue}" class="slider-value-label" >{{settings.camera.contrast}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Contrast</div>
<slider style="width:70%; margin-left:1em;" floor="-100" ceiling="100" step="1" precision="1" ng-model="settings.camera.contrast"></slider>
</div>
</div>
<div class="tab-content" ng-show="(selectedTab == 'light')">
<div>
<div ng-class="{'fadeOut':!showLedRedValue}" class="slider-value-label" >{{settings.led.red}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Red</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="255" step="1" precision="1" ng-model="settings.led.red"></slider>
</div>
<div>
<div ng-class="{'fadeOut':!showLedGreenValue}" class="slider-value-label" >{{settings.led.green}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Green</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="255" step="1" precision="1" ng-model="settings.led.green"></slider>
</div>
<div>
<div ng-class="{'fadeOut':!showLedBlueValue}" class="slider-value-label" >{{settings.led.blue}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Blue</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="255" step="1" precision="1" ng-model="settings.led.blue"></slider>
</div>
</div>
<!--
<div class="tab-content" ng-if="(selectedTab == 'calibration')">
<div style="display:inline-block; width:100%; margin-top:1em; color:white; padding-left:1em;">
Calibration<br>
<br>
Before calibration remove objects!
<a class="hvr-grow" style="margin-right: 13%; margin-top:0.2em; bottom: 0px; text-decoration:none; float:right; color:white; font-size:1.5em;" ng-click="startCalibration()" href="#">Start Calibration</a>
</div>
</div>-->
</div>
</div>
<div class="tab" sytle="width:100%"> </div>
</div>
</div>
<div class="tab-content" ng-show="(selectedTab == 'general')">
<div style="margin-right:20em;">
<div ng-class="{'fadeOut':!showThresholdValue}" class="slider-value-label">{{settings.threshold}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Threshold</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="60" step="1" precision="1" ng-model="settings.threshold"></slider>
</div>
<div style="margin-right:20em;">
<div ng-class="{'longFadeOut':!showResolutionValue}" class="slider-value-label" >{{settings.resolution | toResolutionValue }}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Resolution</div>
<slider class="resolution" style="width:70%; margin-left:1em;" show-steps="true" floor="-16" ceiling="-1" step="4" precision="1" ng-model="settings.resolution"></slider>
</div>
<!--
<div>
<div ng-class="{'longFadeOut':!showResolutionValue}" class="slider-value-label" >{{settings.laser_positions}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Positions</div>
<slider class="resolution" style="width:70%; margin-left:1em;" floor="1" ceiling="4" step="1" precision="1" ng-model="settings.laser_positions"></slider>
</div>
-->
<div style="margin-right:20em;">
<div style="width:100%; margin-bottom:1em; margin-top:1em;">
<div style="display:inline-block; width:15em; color:white; padding-left:1em;" >Scan with Color</div><input style="width:1em; height:1em; margin-left:1.5em; margin-top:0.5em;" type="checkbox" ng-change="setColor()" ng-checked="colorIsSelected()" ng-model="settings.color">
</div>
</div>
<div style="margin-right:20em;">
<div >
<button class="fsButton" style="margin-top:2em; margin-left:1em; text-decoration:none; color:white;" ng-click="startScan()" href="#">Start Scan</button>
</div>
</div>
</div>
<div class="tab-content" ng-show="(selectedTab == 'camera')">
<div style="margin-right:20em;">
<div ng-class="{'fadeOut':!showSaturationValue}" class="slider-value-label" >{{settings.camera.saturation}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Saturation</div>
<slider style="width:70%; margin-left:1em;" floor="-100" ceiling="100" step="1" precision="1" ng-model="settings.camera.saturation"></slider>
</div>
<div style="margin-right:20em;">
<div ng-class="{'fadeOut':!showBrightnessValue}" class="slider-value-label" >{{settings.camera.brightness}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Brightness</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="100" step="1" precision="1" ng-model="settings.camera.brightness"></slider>
</div>
<div style="margin-right:20em;">
<div ng-class="{'fadeOut':!showContrastValue}" class="slider-value-label" >{{settings.camera.contrast}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Contrast</div>
<slider style="width:70%; margin-left:1em;" floor="-100" ceiling="100" step="1" precision="1" ng-model="settings.camera.contrast"></slider>
</div>
</div>
<div class="tab-content" ng-show="(selectedTab == 'light')">
<div style="margin-right:20em;">
<div ng-class="{'fadeOut':!showLedRedValue}" class="slider-value-label" >{{settings.led.red}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Red</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="255" step="1" precision="1" ng-model="settings.led.red"></slider>
</div>
<div style="margin-right:20em;">
<div ng-class="{'fadeOut':!showLedGreenValue}" class="slider-value-label" >{{settings.led.green}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Green</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="255" step="1" precision="1" ng-model="settings.led.green"></slider>
</div>
<div style="margin-right:20em;">
<div ng-class="{'fadeOut':!showLedBlueValue}" class="slider-value-label" >{{settings.led.blue}}</div>
<div style="display:inline-block; width:5em; color:white; padding-left:1em;">Blue</div>
<slider style="width:70%; margin-left:1em;" floor="0" ceiling="255" step="1" precision="1" ng-model="settings.led.blue"></slider>
</div>
</div>
<div class="tab-content" ng-show="(selectedTab == 'hardware')">
<div ng-repeat="(key,values) in devices">
<div style="padding:1em;">
<span style="display:inline-block; width:8em; color:white; padding-left:1em;">{{devices[key]['LABEL']}}</span>
<button style="margin-right:1em;" class="fsButton" ng-repeat="function in devices[key]['FUNCTIONS']" ng-click="sendDeviceCommand(key, function)">{{function}}</button>
</div>
</div>
<div style="margin-right:20em;">
<div style="width:100%; margin-bottom:1em;">
<div style="display:inline-block; width:15em; color:white; padding-left:1em;" >Show Laser Overlay</div><input style="width:1em; height:1em; margin-left:1.5em; margin-top:0.5em;" type="checkbox" ng-change="setLaserOverlay()" ng-checked="laserOverlaySelected()" ng-model="settings.show_laser_overlay">
</div>
<div style="width:100%; margin-bottom:1em;">
<div style="display:inline-block; width:15em; color:white; padding-left:1em;" >Show Alignment Cross</div><input style="width:1em; height:1em; margin-left:1.5em; margin-top:0.5em;" type="checkbox" ng-change="setCalibrationPattern()" ng-checked="calibrationPatternSelected()" ng-model="settings.show_calibration_pattern">
</div>
</div>
</div>
<div class="tab-content" ng-if="(selectedTab == 'calibration')">
<div style="display:inline-block; width:100%; margin-top:1em; color:white; padding-left:1em;">
<div style="margin-top:2em;">
<button class="fsButton" ng-click="startCalibration()">Start Calibration</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Scan View --> <!-- Scan View -->
<div ng-controller="fabscan.controller.FSPreviewController" style="margin: 0 auto; z-index:-100;"> <div ng-controller="fabscan.controller.FSPreviewController" style="margin: 0 auto; z-index:-100;">
<div style="z-index:100;" ng-if="showStream" class="texture-preview"> <div ng-if="showStream" class="texture-preview">
<mjpeg url="streamUrl"></mjpeg> <mjpeg mode="'texture'" url="streamUrl"></mjpeg>
</div> </div>
<div ng-click="manviewhandler()"> <div ng-click="manviewhandler()">
<div <div
id="webgl" id="webgl"
@ -245,7 +207,6 @@
<span>Server: {{server_version}} <br> Firmware: {{firmware_version}}</span> <span>Server: {{server_version}} <br> Firmware: {{firmware_version}}</span>
</div> </div>
<!--
<div style="position:absolute; left:10px; top:2px; color:white"> <div style="position:absolute; left:10px; top:2px; color:white">
<a class="icon" style="" ng-click="startCalibration()" ng-show="(!scanIsLoading() && ('IDLE' | currentState) && !('CALIBRATING' | currentState))"> <a class="icon" style="" ng-click="startCalibration()" ng-show="(!scanIsLoading() && ('IDLE' | currentState) && !('CALIBRATING' | currentState))">
<span class="hvr-grow"> <span class="hvr-grow">
@ -253,7 +214,6 @@
</span> </span>
</a> </a>
</div> </div>
-->
<!--<div style="position:absolute;"> <!--<div style="position:absolute;">
<a href="#" ng-click="renderObjectAsType('MESH')">Show Mesh</a> <a href="#" ng-click="renderObjectAsType('MESH')">Show Mesh</a>
@ -413,7 +373,6 @@
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -422,7 +381,7 @@
</div> </div>
<div id="controlpanel" class="footer row" style="z-index:1000; background-color: grey"> <div id="controlpanel" class="footer row" style="background-color: grey">
<!--<div ng-show="isConnected">--> <!--<div ng-show="isConnected">-->
<div ng-if="appIsInitialized"> <div ng-if="appIsInitialized">

View file

@ -9,7 +9,7 @@
(function() { (function() {
var m, mods; var m, mods;
mods = ['common.services.envProvider', 'common.filters.currentStateFilter', 'common.filters.toLabelFilter', 'common.filters.toResolutionValue', 'fabscan.directives.FSWebglDirective', 'fabscan.directives.FSMJPEGStream', 'fabscan.directives.FSModalDialog', 'fabscan.directives.text', 'fabscan.services.FSMessageHandlerService', 'fabscan.services.FSEnumService', 'fabscan.services.FSWebsocketConnectionFactory', 'fabscan.services.FSScanService', 'fabscan.services.FSi18nService', 'common.filters.scanDataAvailableFilter', 'fabscan.directives.onSizeChanged', 'common.services.Configuration', 'common.services.toastrWrapperSvc', 'fabscan.controller.FSPreviewController', 'fabscan.controller.FSAppController', 'fabscan.controller.FSNewsController', 'fabscan.controller.FSSettingsController', 'fabscan.controller.FSScanController', 'fabscan.controller.FSLoadingController', 'fabscan.controller.FSShareController', 'ngSanitize', 'ngTouch', 'ngCookies', '720kb.tooltips', 'ngProgress', 'vr.directives.slider', 'slickCarousel']; mods = ['common.services.envProvider', 'common.filters.currentStateFilter', 'common.filters.toLabelFilter', 'common.filters.toResolutionValue', 'fabscan.directives.FSWebglDirective', 'fabscan.directives.FSMJPEGStream', 'fabscan.directives.FSModalDialog', 'fabscan.directives.text', 'fabscan.services.FSMessageHandlerService', 'fabscan.services.FSEnumService', 'fabscan.services.FSWebsocketConnectionFactory', 'fabscan.services.FSScanService', 'fabscan.services.FSi18nService', 'common.filters.scanDataAvailableFilter', 'common.services.Configuration', 'common.services.toastrWrapperSvc', 'fabscan.controller.FSPreviewController', 'fabscan.controller.FSAppController', 'fabscan.controller.FSNewsController', 'fabscan.controller.FSSettingsController', 'fabscan.controller.FSScanController', 'fabscan.controller.FSLoadingController', 'fabscan.controller.FSShareController', 'ngSanitize', 'ngTouch', 'ngCookies', '720kb.tooltips', 'ngProgress', 'vr.directives.slider', 'slickCarousel'];
/* /*
*/ */
@ -62,25 +62,38 @@
name = 'fabscan.directives.FSMJPEGStream'; name = 'fabscan.directives.FSMJPEGStream';
angular.module(name, []).directive('mjpeg', function() { angular.module(name, []).directive('mjpeg', [
return { '$log', function($log) {
restrict: 'E', return {
replace: true, restrict: 'E',
template: '<span></span>', replace: true,
scope: { template: '<span></span>',
'url': '=' scope: {
}, 'url': '=',
link: function(scope, element, attrs) { 'mode': '='
scope.$watch('url', (function(newVal, oldVal) { },
var doc, iframe, iframeHtml; link: function(scope, element, attrs) {
scope.createFrame = function(newVal) {
var doc, iframe, iframeHtml;
if (newVal) {
iframe = document.createElement('iframe'); iframe = document.createElement('iframe');
iframe.setAttribute('width', '100%');
iframe.setAttribute('frameborder', '0'); iframe.setAttribute('frameborder', '0');
iframe.setAttribute('scrolling', 'no'); iframe.setAttribute('scrolling', 'no');
element.replaceWith(iframe); iframe.setAttribute('style', "height:100%; position:absolute;");
iframeHtml = '<html><head><base target="_parent" /><style type="text/css">html, body { margin: 0; padding: 0; height: 100%; width: 100%; }</style><script> function resizeParent() { var ifs = window.top.document.getElementsByTagName("iframe"); for (var i = 0, len = ifs.length; i < len; i++) { var f = ifs[i]; var fDoc = f.contentDocument || f.contentWindow.document; if (fDoc === document) { f.height = 0; f.height = document.body.scrollHeight; } } }</script></head><body onresize="resizeParent()"><img src=\"' + newVal + '\" style="width: 100%; height: auto" onload="resizeParent()" /></body></html>'; if (element.childElementCount > 0) {
element.childNodes[0].destroy();
element.append(iframe);
} else {
element.append(iframe);
}
if (scope.mode === "texture") {
iframe.setAttribute('width', '100%');
iframeHtml = '<html><head><base target="_parent" /><style type="text/css">html, body { margin: 0; padding: 0; height: 320px; }</style><script> function resizeParent() { var ifs = window.top.document.getElementsByTagName("iframe"); for (var i = 0, len = ifs.length; i < len; i++) { var f = ifs[i]; var fDoc = f.contentDocument || f.contentWindow.document; if (fDoc === document) { f.height = 0; f.height = document.body.scrollHeight; } } }</script></head><body style="" onresize="resizeParent()"><div><img src="' + newVal + '" style="z-index:1000; display: block; margin-left: auto; margin-right: auto; width: 30em; margin-top:1em; -webkit-mask-image: radial-gradient(ellipse 106% 148% at 50% 50%, black 35%, transparent 48%); mask-image: radial-gradient(ellipse 106% 148% at 50% 50%, black 35%, transparent 48%);" onload="resizeParent()" /></div></body></html>';
}
if (scope.mode === "preview") {
iframe.setAttribute('height', '240px');
iframeHtml = '<html><head><base target="_parent" /><style type="text/css">html, body { margin: 0; padding: 0; height: 240px; }</style><script> function resizeParent() { var ifs = window.top.document.getElementsByTagName("iframe"); for (var i = 0, len = ifs.length; i < len; i++) { var f = ifs[i]; var fDoc = f.contentDocument || f.contentWindow.document; if (fDoc === document) { f.width = 0; f.width = document.body.scrollWidth; } } }</script></head><body onresize="resizeParent()"><img src="' + newVal + '" style="z-index:1000; opacity: 1.0; height:240px; position:absolute;" onload="resizeParent()" /><div style="position:absolute; text-align:center; background-color:black; width:180px; height:240px; float:left; z-index:-1000;"><img style="margin-top:100px; margin-left:70px width:50px; height:50px;" src="icons/spinner.gif" /></div></body></html>';
}
doc = iframe.document; doc = iframe.document;
if (iframe.contentDocument) { if (iframe.contentDocument) {
doc = iframe.contentDocument; doc = iframe.contentDocument;
@ -89,14 +102,15 @@
} }
doc.open(); doc.open();
doc.writeln(iframeHtml); doc.writeln(iframeHtml);
doc.close(); return doc.close();
} else { };
element.html('<span></span>'); scope.$watch('url', (function(newVal, oldVal) {
} return scope.createFrame(newVal);
}), true); }), true);
} }
}; };
}); }
]);
}).call(this); }).call(this);
@ -309,7 +323,7 @@
var screenshot; var screenshot;
screenshot = renderer.domElement.toDataURL('image/png'); screenshot = renderer.domElement.toDataURL('image/png');
return $http.post(Configuration.installation.apiurl + "api/v1/scans/" + id + "/previews", { return $http.post(Configuration.installation.httpurl + "api/v1/scans/" + id + "/previews", {
image: screenshot image: screenshot
}).success(function(response) { }).success(function(response) {
$log.info(response); $log.info(response);
@ -596,44 +610,6 @@
}).call(this); }).call(this);
(function() {
var name;
name = 'fabscan.directives.onSizeChanged';
angular.module(name, []).directive('onSizeChanged', [
'$window', function($window) {
return {
restrict: 'A',
scope: {
onSizeChanged: '&'
},
link: function(scope, $element, attr) {
var cacheElementSize, element, onWindowResize;
element = $element[0];
cacheElementSize = function(scope, element) {
scope.cachedElementWidth = element.offsetWidth;
scope.cachedElementHeight = element.offsetHeight;
};
onWindowResize = function() {
var expression, isSizeChanged;
isSizeChanged = scope.cachedElementWidth !== element.offsetWidth || scope.cachedElementHeight !== element.offsetHeight;
if (isSizeChanged) {
expression = scope.onSizeChanged();
expression();
}
};
cacheElementSize(scope, element);
$window.addEventListener('resize', onWindowResize);
}
};
}
]);
}).call(this);
/* /*
Takes a string and makes it lowercase Takes a string and makes it lowercase
Example of a 'common' filter that can be shared by all views Example of a 'common' filter that can be shared by all views
@ -765,36 +741,28 @@ Example of a 'common' filter that can be shared by all views
angular.module(name, []).factory(name, [ angular.module(name, []).factory(name, [
'$log', '$location', function($log, $location) { '$log', '$location', function($log, $location) {
var config, host, http, localDebug, ws; var config, host, localDebug;
localDebug = $location.host() === 'localhost'; localDebug = $location.host() === 'localhost';
config = null; config = null;
host = $location.host(); host = $location.host();
http = 'http'; $log.info(host);
ws = 'ws';
console.log($location.protocol());
if ($location.protocol() === 'https') {
http = 'https';
ws = 'wss';
}
if (localDebug) { if (localDebug) {
config = { config = {
installation: { installation: {
host: "fabscanpi.local", host: "fabscanpi.local",
websocketurl: ws + '://fabscanpi.local/websocket', websocketurl: 'ws://fabscanpi.local/websocket',
httpurl: http + '://fabscanpi.local/', httpurl: 'http://fabscanpi.local:8080/',
newsurl: http + '://fabscanpi-server.readthedocs.io/en/latest/news/', newsurl: 'http://mariolukas.github.io/FabScanPi-Server/news/'
apiurl: http + '://fabscanpi.local/'
} }
}; };
} else { } else {
config = { config = {
installation: { installation: {
host: host, host: host,
websocketurl: ws + '://' + host + '/websocket', websocketurl: 'ws://' + host + '/websocket',
httpurl: http + '://' + host + ':8080/', httpurl: 'http://' + host + ':8080/',
newsurl: http + '://fabscanpi-server.readthedocs.io/en/latest/news/', newsurl: 'http://mariolukas.github.io/FabScanPi-Server/news/'
apiurl: http + '://' + host + '/'
} }
}; };
} }
@ -836,8 +804,7 @@ Example of a 'common' filter that can be shared by all views
UPDATE_SETTINGS: 'UPDATE_SETTINGS', UPDATE_SETTINGS: 'UPDATE_SETTINGS',
MESHING: 'MESHING', MESHING: 'MESHING',
UPGRADE_SERVER: 'UPGRADE_SERVER', UPGRADE_SERVER: 'UPGRADE_SERVER',
RESTART_SERVER: 'RESTART_SERVER', RESTART_SERVER: 'RESTART_SERVER'
HARDWARE_TEST_FUNCTION: 'HARDWARE_TEST_FUNCTION'
}; };
return FSEnumService; return FSEnumService;
}); });
@ -1365,7 +1332,7 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
name = "fabscan.controller.FSLoadingController"; name = "fabscan.controller.FSLoadingController";
angular.module(name, []).controller(name, [ angular.module(name, []).controller(name, [
'$log', '$scope', '$rootScope', 'fabscan.services.FSScanService', 'fabscan.services.FSEnumService', 'common.services.Configuration', function($log, $scope, $rootScope, FSScanService, FSEnum, Configuration) { '$log', '$scope', '$rootScope', 'fabscan.services.FSScanService', 'fabscan.services.FSEnumService', function($log, $scope, $rootScope, FSScanService, FSEnum) {
$scope.loadPointCloud = function(pointcloud, id) { $scope.loadPointCloud = function(pointcloud, id) {
$scope.setScanIsLoading(true); $scope.setScanIsLoading(true);
$scope.setScanIsComplete(false); $scope.setScanIsComplete(false);
@ -1412,17 +1379,7 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
$scope.displayNews(false); $scope.displayNews(false);
}), 30); }), 30);
deferred = $q.defer(); deferred = $q.defer();
$scope.news = "No news available."; return $scope.news = "No news available.";
return $http({
method: 'GET',
url: configuration.installation.newsurl,
timeout: deferred.promise
}).success(function(data, status, headers, config) {
$scope.news = data;
return $timeout.cancel(timeoutPromise);
}).error(function(data, status, headers, config) {
return $scope.news = "Error retrieving news.";
});
} }
]); ]);
@ -1460,7 +1417,7 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
return $scope.$apply(); return $scope.$apply();
}; };
startStream = function() { startStream = function() {
$scope.streamUrl = Configuration.installation.apiurl + 'api/v1/streams/?type=textures'; $scope.streamUrl = Configuration.installation.httpurl + 'api/v1/streams/?type=textures';
$scope.showStream = true; $scope.showStream = true;
return $scope.$apply(); return $scope.$apply();
}; };
@ -1612,7 +1569,7 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
$scope.loadFilters = function() { $scope.loadFilters = function() {
var filter_promise; var filter_promise;
filter_promise = $http.get(Configuration.installation.apiurl + 'api/v1/filters/'); filter_promise = $http.get(Configuration.installation.httpurl + 'api/v1/filters/');
return filter_promise.then(function(payload) { return filter_promise.then(function(payload) {
$log.info(payload); $log.info(payload);
$scope.m_filters = payload.data.filters; $scope.m_filters = payload.data.filters;
@ -1674,7 +1631,7 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
$scope.displayNews(false); $scope.displayNews(false);
if (!$scope.loadDialog) { if (!$scope.loadDialog) {
promise = $http.get(Configuration.installation.apiurl + 'api/v1/scans/'); promise = $http.get(Configuration.installation.httpurl + 'api/v1/scans/');
return promise.then(function(payload) { return promise.then(function(payload) {
$scope.scans = payload.data.scans; $scope.scans = payload.data.scans;
$scope.scanListLoaded = true; $scope.scanListLoaded = true;
@ -1727,33 +1684,12 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
name = "fabscan.controller.FSSettingsController"; name = "fabscan.controller.FSSettingsController";
angular.module(name, []).controller(name, [ angular.module(name, []).controller(name, [
'$log', '$scope', '$timeout', '$swipe', '$http', 'common.services.Configuration', 'fabscan.services.FSEnumService', 'fabscan.services.FSMessageHandlerService', 'fabscan.services.FSScanService', function($log, $scope, $timeout, $swipe, $http, Configuration, FSEnumService, FSMessageHandlerService, FSScanService) { '$log', '$scope', '$timeout', '$swipe', 'common.services.Configuration', 'fabscan.services.FSEnumService', 'fabscan.services.FSMessageHandlerService', 'fabscan.services.FSScanService', function($log, $scope, $timeout, $swipe, Configuration, FSEnumService, FSMessageHandlerService, FSScanService) {
var devices_promise, updateSettings; var updateSettings;
$scope.streamUrl = Configuration.installation.apiurl + 'api/v1/streams/?type=laser'; $scope.streamUrl = Configuration.installation.httpurl + 'api/v1/streams/?type=laser';
$scope.previewMode = "laser"; $scope.previewMode = "laser";
$scope.selectedTab = 'general'; $scope.selectedTab = 'general';
devices_promise = $http.get(Configuration.installation.httpurl + 'api/v1/devices/');
devices_promise.then(function(payload) {
$log.info(payload);
return $scope.devices = payload.data;
});
$scope.sendDeviceCommand = function(device, f_name) {
var message;
message = {};
message = {
event: FSEnumService.events.COMMAND,
data: {
command: FSEnumService.commands.HARDWARE_TEST_FUNCTION,
device: {
name: device,
"function": f_name
}
}
};
return FSMessageHandlerService.sendData(message);
};
$scope.timeout = null; $scope.timeout = null;
updateSettings = function() { updateSettings = function() {
var _settings; var _settings;
@ -1787,32 +1723,14 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
} }
}; };
$scope.showCalibrationPreview = function() { $scope.showCalibrationPreview = function() {
$scope.streamUrl = Configuration.installation.apiurl + 'api/v1/streams/?type=texture'; $scope.streamUrl = Configuration.installation.httpurl + 'api/v1/streams/?type=texture';
return $scope.previewMode = "calibration"; $scope.previewMode = "calibration";
return $scope.$apply();
}; };
$scope.showLaserPreview = function() { $scope.showLaserPreview = function() {
$scope.streamUrl = Configuration.installation.apiurl + 'api/v1/streams/?type=laser'; $scope.streamUrl = Configuration.installation.httpurl + 'api/v1/streams/?type=laser';
return $scope.previewMode = "laser"; $scope.previewMode = "laser";
}; return $scope.$apply();
$scope.calibrationPatternSelected = function() {
if ($scope.settings.show_calibration_pattern) {
return true;
} else {
return false;
}
};
$scope.laserOverlaySelected = function() {
if ($scope.settings.show_laser_overlay) {
return true;
} else {
return false;
}
};
$scope.setCalibrationPattern = function() {
return updateSettings();
};
$scope.setLaserOverlay = function() {
return updateSettings();
}; };
$scope.setColor = function() { $scope.setColor = function() {
return updateSettings(); return updateSettings();
@ -1938,7 +1856,7 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
$scope.getScans = function() { $scope.getScans = function() {
var scan_promise; var scan_promise;
scan_promise = $http.get(Configuration.installation.apiurl + 'api/v1/scans/' + FSScanService.getScanId()); scan_promise = $http.get(Configuration.installation.httpurl + 'api/v1/scans/' + FSScanService.getScanId());
return scan_promise.then(function(payload) { return scan_promise.then(function(payload) {
$log.debug(payload); $log.debug(payload);
$scope.raw_scans = payload.data.raw_scans; $scope.raw_scans = payload.data.raw_scans;
@ -1998,7 +1916,7 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
var promise; var promise;
$scope.toggleShareDialog(); $scope.toggleShareDialog();
promise = $http["delete"](Configuration.installation.apiurl + 'api/v1/scans/' + FSScanService.getScanId() + '/files?filename=' + filename); promise = $http["delete"](Configuration.installation.httpurl + 'api/v1/scans/' + FSScanService.getScanId() + '/files?filename=' + filename);
return promise.then(function(payload) { return promise.then(function(payload) {
$log.info(payload.data); $log.info(payload.data);
$scope.getScans(); $scope.getScans();
@ -2017,7 +1935,7 @@ Example of how to wrap a 3rd party library, allowing it to be injectable instead
var promise; var promise;
$scope.toggleShareDialog(); $scope.toggleShareDialog();
promise = $http["delete"](Configuration.installation.apiurl + 'api/v1/scans/' + FSScanService.getScanId()); promise = $http["delete"](Configuration.installation.httpurl + 'api/v1/scans/' + FSScanService.getScanId());
return promise.then(function(payload) { return promise.then(function(payload) {
$log.info(payload.data); $log.info(payload.data);
toaster.info('Scan ' + FSScanService.getScanId() + ' deleted'); toaster.info('Scan ' + FSScanService.getScanId() + ' deleted');

View file

@ -7,135 +7,12 @@ body, html {
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
position: fixed !important; position: fixed !important;
overflow: hidden overflow: hidden
height: 100%;
} }
* { * {
margin: 0 margin: 0
} }
button:focus {outline:0;}
.control {
font-family: arial;
display: block;
position: relative;
padding-left: 30px;
margin-bottom: 5px;
padding-top: 3px;
cursor: pointer;
font-size: 16px;
}
.control input {
position: absolute;
z-index: -1;
opacity: 0;
}
.control_indicator {
position: absolute;
top: 2px;
left: 0;
height: 20px;
width: 20px;
background: #e6e6e6;
border: 0px solid #000000;
}
.control-radio .control_indicator {
border-radius: undefined%;
}
.control:hover input ~ .control_indicator,
.control input:focus ~ .control_indicator {
background: #cccccc;
}
.control input:checked ~ .control_indicator {
background: #838383;
}
.control:hover input:not([disabled]):checked ~ .control_indicator,
.control input:checked:focus ~ .control_indicator {
background: #0e6647d;
}
.control input:disabled ~ .control_indicator {
background: #e6e6e6;
opacity: 0.6;
pointer-events: none;
}
.control_indicator:after {
box-sizing: unset;
content: '';
position: absolute;
display: none;
}
.control input:checked ~ .control_indicator:after {
display: block;
}
.control-checkbox .control_indicator:after {
left: 8px;
top: 2px;
width: 3px;
height: 11px;
border: solid #ffffff;
border-width: 0 3px 3px 0;
transform: rotate(45deg);
}
.control-checkbox input:disabled ~ .control_indicator:after {
border-color: #7b7b7b;
}
.video-container {
/* width: 50%;*/
width:33.3em;
float: left;
bottom: 100px;
}
.video {
position: relative;
/*padding-bottom: 56.25%;*/
min-width: 30em;
min-height: 800px;
bottom:60px;
height: inherit !important;
overflow: hidden;
}
.video iframe{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.side-div{
float: left;
width: 50%;
}
.wrapper {
width:100%;
display:flex;
background-color:#CCC;
}
.wrapper-top {
width:100%;
height:60px;
background-color:#000;
}
.wrapper-bottom {
width:100%;
height:40px;
background-color:#000;
clear: both
}
.slick-slider { .slick-slider {
margin-bottom: 0em; margin-bottom: 0em;
} }
@ -391,7 +268,6 @@ a:active .icon {
bottom: 60px; bottom: 60px;
position: fixed; position: fixed;
left: 0px; left: 0px;
z-index:1000;
/*background-color:grey;*/ /*background-color:grey;*/
background-color: rgba(53, 53, 53, 0.5); background-color: rgba(53, 53, 53, 0.5);
transition: height 0.3s; transition: height 0.3s;
@ -439,10 +315,7 @@ a:active .icon {
.settings-content { .settings-content {
height: 100%; height: 100%;
position: absolute; margin-left: 180px;
left: 300px;
width: 100%;
/*margin-left: 180px;*/
} }
.config-content { .config-content {
@ -455,7 +328,7 @@ a:active .icon {
} }
.settingsWindow.open { .settingsWindow.open {
height: 400px; height: 240px;
bottom: 60px; bottom: 60px;
transition: height 0.3s; transition: height 0.3s;
border-top: 2px solid rgb(73, 73, 73); border-top: 2px solid rgb(73, 73, 73);
@ -469,35 +342,11 @@ a:active .icon {
opacity: 0.75; opacity: 0.75;
} }
.fsButton {
background-color:transparent;
-moz-border-radius:31px;
-webkit-border-radius:31px;
border-radius:31px;
border:3px solid #dcdcdc;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:15px;
font-weight:bold;
padding:6px 24px;
text-decoration:none;
}
.fsButton:hover {
background-color:rgba(53, 53, 53, 0.4);
}
.fsButton:active {
position:relative;
top:1px;
}
.hide { .hide {
height: 150px; height: 150px;
} }
.footer { .footer {
z-index:1000;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
@ -554,7 +403,6 @@ html, body {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
z-index:1000;
text-align: center; text-align: center;
margin-bottom: 1em; margin-bottom: 1em;
border-top: 2px solid rgb(73, 73, 73); border-top: 2px solid rgb(73, 73, 73);
@ -568,59 +416,14 @@ html, body {
overflow-y: auto; overflow-y: auto;
} }
.settings-preview {
/* position: absolute;
top: 100px;
z-index: 2;
margin-left:-160px;
left:50%;*/
position:absolute;
margin-left: auto;
margin-right: auto;
}
.settings-preview img {
height: 70%;
width: 70%;
opacity: 0.6;
border-radius: 70px;
/* -webkit-mask-box-image: -webkit-linear-gradient(left,transparent, transparent 15%, white 50%, white 50%, transparent 85%);*/
-webkit-mask-box-image: -webkit-radial-gradient(white, transparent 69%);
display: block;
margin: 0 auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
margin-top: 12%;
}
.texture-preview { .texture-preview {
/* position: absolute; /* position: absolute;
top: 100px; top: 100px;
z-index: 2; z-index: 2;
margin-left:-160px; margin-left:-160px;
left:50%;*/ left:50%;*/
width: 50%;
position:absolute;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
bottom:59px;
} }
.texture-preview img { .texture-preview img {
height: 70%; height: 70%;
width: 70%; width: 70%;
@ -680,8 +483,7 @@ html, body {
.tab-content { .tab-content {
background-color: rgba(53, 53, 53, 0.4); background-color: rgba(53, 53, 53, 0.4);
height: 100%; height: 200px;
/*height:100%;*/
-webkit-transition: all 0.5s ease; -webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease; -moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease; -o-transition: all 0.5s ease;
@ -827,7 +629,7 @@ and (max-device-width: 450px) {
margin-left: 0px; margin-left: 0px;
width: 100%; width: 100%;
float: left; float: left;
height: 200px; height: 100%;
} }
.preview-image { .preview-image {
@ -915,7 +717,7 @@ and (max-device-width: 480px) {
} }
*/ */
.settingsWindow.open { .settingsWindow.open {
/* height: 100%;*/ height: 100%;
} }
.optionsWindow.open { .optionsWindow.open {