├── .gitignore ├── Makefile ├── README.md ├── angular ├── .gitignore ├── Gruntfile.js ├── README.md ├── config.example.js ├── imgs │ └── favicon.ico ├── index.html ├── js │ ├── app.js │ ├── dashboardView.js │ ├── index.js │ ├── loginView.js │ ├── vehicleListView.js │ └── vehicleView.js ├── package.json ├── scripts │ └── launch-chrome.sh ├── scss │ ├── _bootstrap.scss │ ├── _reset.scss │ └── main.scss ├── views │ ├── dashboard.html │ ├── login.html │ ├── vehicle.html │ └── vehicle_list.html └── webpack.config.js ├── assets ├── .gitattributes ├── .gitignore └── README.md ├── dragonfly └── README.md ├── models ├── README.md ├── fleet-tracker-body.stl └── fleet-tracker-cover-plate.dxf └── runtime ├── .gitignore ├── Authenticator ├── Authenticator.js ├── descriptor.yaml ├── spec │ └── main.js ├── specs.js └── testdata │ ├── invalid.yaml │ └── simple.yaml ├── FleetManager ├── FleetManager.js ├── descriptor.yaml ├── spec │ └── main.js ├── specs.js └── testdata │ ├── add.yaml │ ├── delete.yaml │ ├── genkey.yaml │ └── list.yaml ├── README.md ├── example-context.yaml ├── package.json ├── simpledialer.js └── specs.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 27 | node_modules 28 | 29 | # ignore sqlite database 30 | *.sqlite 31 | *.sqlite3 32 | 33 | # ignore dump 34 | dump.rdb 35 | 36 | # Ignore sftp info 37 | sftp-config.json 38 | 39 | .DS_Store 40 | .sass-cache 41 | 42 | # Project Specific 43 | # generated css 44 | bean-counter/node/public/css/main.css 45 | connected-cars/node/public/css/main.css 46 | remote-monitor/node/public/css/main.css 47 | # remote monitor images 48 | remote-monitor/node/public/imgs/camera_photos/* 49 | # compiled electron code 50 | bean-counter/electron/compiled 51 | 52 | package-lock.json 53 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: build 2 | 3 | prepare-angular: 4 | (cd angular; npm install) 5 | 6 | build-angular: 7 | (cd angular; ./node_modules/.bin/grunt build) 8 | 9 | assets/index.html: angular/build/assets/index.html 10 | cp $< $@ 11 | 12 | assets/vendor.js: angular/build/assets/vendor.js 13 | cp $< $@ 14 | assets/vendor.js.map: angular/build/assets/vendor.js.map 15 | cp $< $@ 16 | assets/styles.js: angular/build/assets/styles.js 17 | cp $< $@ 18 | assets/styles.js.map: angular/build/assets/styles.js.map 19 | cp $< $@ 20 | assets/index.js: angular/build/assets/index.js 21 | cp $< $@ 22 | assets/index.js.map: angular/build/assets/index.js.map 23 | cp $< $@ 24 | 25 | build-angular-assets: build-angular assets/index.html \ 26 | assets/index.js assets/index.js.map \ 27 | assets/styles.js assets/styles.js.map \ 28 | assets/vendor.js assets/vendor.js.map 29 | 30 | .PHONY: prepare-angular build-angular build-angular-assets 31 | 32 | assets/Authenticator-deployment-instructions.txt: runtime/Authenticator/descriptor.yaml runtime/Authenticator/Authenticator.js runtime/Authenticator/descriptor.yaml runtime/context-local.yaml 33 | twilio-runtime-utils -c runtime/context-local.yaml deploy runtime/Authenticator/descriptor.yaml > $@ 34 | 35 | assets/FleetManager-deployment-instructions.txt: runtime/FleetManager/descriptor.yaml runtime/FleetManager/FleetManager.js runtime/FleetManager/descriptor.yaml runtime/context-local.yaml 36 | twilio-runtime-utils -c runtime/context-local.yaml deploy runtime/FleetManager/descriptor.yaml > $@ 37 | 38 | build-runtime: assets/Authenticator-deployment-instructions.txt assets/FleetManager-deployment-instructions.txt 39 | 40 | clean-runtime: 41 | rm -f assets/Authenticator-deployment-instructions.txt 42 | rm -f assets/FleetManager-deployment-instructions.txt 43 | 44 | .PHONY: clean-runtime build-runtime 45 | 46 | prepare: prepare-angular 47 | 48 | build: build-angular-assets #build-runtime 49 | 50 | dev: 51 | (cd angular; ./node_modules/.bin/grunt dev) 52 | 53 | clean: 54 | rm -rf angular/build/assets 55 | 56 | full-clean: clean 57 | rm -f angular/package-lock.json 58 | rm -rf angular/node_modules 59 | rm -rf angular/build 60 | 61 | rebuild: clean build 62 | 63 | full-rebuild: full-clean prepare build 64 | 65 | .PHONY: default prepare build dev clean full-clean rebuild full-rebuild 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fleet Tracker Blueprint 2 | 3 | **Disclaimer: The blueprints and information made available on this page are examples only and are not to be used for production purposes. Twilio disclaims any warranties and liabilities under any legal theory (including, without limitation, breach of contract, tort, and indemnification) in connection with your use of or reliance on the blueprints. Any liabilities that arise in connection with your use of these blueprints shall solely be borne by you. By accessing and downloading these blueprints, you agree to the foregoing terms.** 4 | 5 | **Problem** Commercial vehicle fleet managers are required by law to track various driver and vehicle behaviors. Beyond the data logging mandated by law, there are other behaviors that employers might want to track. If they had a low-cost, reliable, and technical monitoring solution, they could remove or minimize the risks associated with their fleet management. 6 | 7 | **Solution** We will create a Twilio-powered Fleet Tracker that uses off-the-shelf components to track and log: miles driven, hours of uptime and downtime, locations, average speed, and fuel consumption. 8 | 9 | **Degree of Difficulty (1-5): 2** This device requires some knowledge of the C programming language, microcontroller basics, and GPIO wiring. 10 | 11 | ### What You’ll Need 12 | Before we get started, here's a quick overview of what you'll need to build the Fleet Tracker: 13 | 14 | **Electronic Components** In order to build your own Fleet Tracker, you'll need the following items: 15 | 16 | * 1x [Twilio Programmable Wireless SIM](https://www.twilio.com/wireless) 17 | * 1x [Programmable Wireless Starter Pack](http://bit.ly/2fJXrnE) 18 | * 1x [OBD-II adapter](http://www.semiconductorstore.com/cart/pc/viewPrd.asp?idproduct=70453) 19 | * 1x [GPS antenna](http://freematics.com/store/index.php?route=product/product&product_id=83) 20 | * 1x [RF antenna](http://www.semiconductorstore.com/cart/pc/viewPrd.asp?idproduct=70343) 21 | * 1x [Arduino header pins](https://www.amazon.com/2-54mm-Breakaway-Female-Connector-Arduino/dp/B01MQ48T2V/ref=sr_1_4?ie=UTF8&qid=1505424045&sr=8-4&keywords=arduino+header+pins) 22 | 23 | # Fleet Tracker Blueprint Development Flow 24 | Serverless _Twilio Fleet Tracker_ involes 3 separate development process 25 | 26 | - Twilio Runtime Functions 27 | - Angular Single Page Application 28 | - MultiTech Dragonfly hardware 29 | 30 | ## Prebuilt Assets 31 | If you do not want to build everything yourself, you could skip all steps related to building assets, and take artifacts and instructions from https://github.com/twilio/wireless-fleet-tracker/tree/serverless/assets directly. 32 | 33 | ## Preparations 34 | - Build [twilio-runtime-utils](https://github.com/hellwolf/twilio-runtime-utils) with `make build` 35 | - Setup PATH to twilio-runtime-utils.sh shell script 36 | - Checkout `twilio-connected-devices` branch of [wireless-co-pilot](https://code.hq.twilio.com/zmiao/wireless-co-pilot/tree/twilio-connected-devices) 37 | 38 | ## Developing Twilio Runtime Functions 39 | 40 | ### Test function locally 41 | 42 | Go to `runtime` directory. 43 | 44 | ``` 45 | $ twilio-runtime-utils.sh -c context-local.yaml run Authenticator/descriptor.yaml Authenticator/testdata/simple.yaml 46 | {"success":true,"username":"twilio","ttl":3600,"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTSzI2MzQ3MTM2N2E0OGI2Yjc4NjEyZTQyYzA5ZmFkNmI3LTE0OTUyMDQ5NDkiLCJncmFudHMiOnsiaWRlbnRpdHkiOiJ0cnVtcCIsImRhdGFfc3luYyI6eyJzZXJ2aWNlX3NpZCI6IklTYzg5NThjOGIzODNmZmM2YjhkMTc2ZmJlYmViMWE1YTkifX0sImlhdCI6MTQ5NTIwNDk0OSwiZXhwIjoxNDk1MjA4NTQ5LCJpc3MiOiJTSzI2MzQ3MTM2N2E0OGI2Yjc4NjEyZTQyYzA5ZmFkNmI3Iiwic3ViIjoiQUM3OTMzOTk2M2E5OWY0NzZlNmYwYjMyMTRhYmQ0OGE5ZCJ9.IPQ5QTkTacXaQ4YI4nifii_yrabI5Fk5gzYse8M4tT4"} 47 | 48 | $ twilio-runtime-utils.sh -c context-local.yaml run FleetManager/descriptor.yaml FleetManager/testdata/list.yaml 49 | 50 | $ twilio-runtime-utils.sh -c context-local.yaml run FleetManager/descriptor.yaml FleetManager/testdata/add.yaml 51 | 52 | ... 53 | ``` 54 | 55 | ### Deploy function 56 | Currently twilio runtime RESTful API is not available, manual deployment process is needed. However you could follow instruction generated by the following commands: 57 | ``` 58 | $ twilio-runtime-utils.sh -c context-local.yaml deploy FleetManager/descriptor.yaml 59 | 60 | $ twilio-runtime-utils.sh -c context-local.yaml deploy Authenticator/descriptor.yaml 61 | ``` 62 | 63 | ### Required functions 64 | For _Twilio Fleet Tracker_, two functions are required: 65 | - Authenticator, token authentication for Admin UI 66 | - FleetManager, list/add/delete/genkey for vehicles 67 | 68 | ## Developing Angular Single Page Application 69 | Go to `angular` directory. 70 | 71 | ### Run webpack dev server locally 72 | ``` 73 | $ npm install 74 | $ ./node_modules/.bin/grunt dev 75 | ``` 76 | 77 | ### Build assets 78 | ``` 79 | $ ./node_modules/.bin/grunt build 80 | ``` 81 | 82 | ### Deploy assets to Twilio Runtime 83 | Upload these files to _Twilio Runtime_ assets: 84 | ``` 85 | $ ls -lh angular/build/assets/*.{js,html,js.map} 86 | -rw-r--r-- 1 zmiao TWILIO\Domain Users 1.7K Aug 16 16:41 angular/build/assets/index.html 87 | -rw-r--r-- 1 zmiao TWILIO\Domain Users 16K Aug 16 16:41 angular/build/assets/index.js 88 | -rw-r--r-- 1 zmiao TWILIO\Domain Users 63K Aug 16 16:41 angular/build/assets/index.js.map 89 | -rw-r--r-- 1 zmiao TWILIO\Domain Users 160K Aug 16 16:41 angular/build/assets/styles.js 90 | -rw-r--r-- 1 zmiao TWILIO\Domain Users 343K Aug 16 16:41 angular/build/assets/styles.js.map 91 | -rw-r--r-- 1 zmiao TWILIO\Domain Users 465K Aug 16 16:41 angular/build/assets/vendor.js 92 | -rw-r--r-- 1 zmiao TWILIO\Domain Users 2.0M Aug 16 16:41 angular/build/assets/vendor.js.map 93 | ``` 94 | ## Developing MultiTech Dragonfly hardware 95 | 1. Create an [ARMmbed developer account](https://developer.mbed.org/) 96 | 2. Visit the [Dragonfly Fleet Tracker repository](https://developer.mbed.org/users/miaotwilio/code/DragonflyMQTT/) 97 | 3. Click the yellow **Import into Compiler** button 98 | 4. Click the **Import** button 99 | 100 | That's it! As a reminder, full instructions for this tutorial can be found in the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/). 101 | -------------------------------------------------------------------------------- /angular/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /config.js 3 | -------------------------------------------------------------------------------- /angular/Gruntfile.js: -------------------------------------------------------------------------------- 1 | var config = require("./config"); // copy and modify config.example.js 2 | 3 | module.exports = function(grunt) { 4 | var webpack = require("webpack"); 5 | var webpackConfig = require("./webpack.config.js"); 6 | 7 | // Project configuration. 8 | grunt.initConfig({ 9 | pkg: grunt.file.readJSON('package.json'), 10 | 11 | webpack: { 12 | options: webpackConfig, 13 | build: { 14 | plugins: [ 15 | new webpack.optimize.UglifyJsPlugin({ 16 | test: /.js$/, 17 | mangle: { 18 | except: ["App", "app"] 19 | }, 20 | sourceMap: true 21 | }) 22 | ] 23 | } 24 | }, 25 | 26 | "webpack-dev-server": { 27 | options: { 28 | webpack: webpackConfig, 29 | publicPath: webpackConfig.output.publicPath, 30 | contentBase: "build/assets", 31 | proxy: { 32 | // redirect all API calls to deployed runtime functions 33 | "/**": { 34 | target: config.RUNTIME_DOMAIN, 35 | changeOrigin: true, 36 | secure: false, 37 | bypass: function (req, res, proxyOptions) { 38 | console.log("req.url", req.url); 39 | if (req.url === "/") { 40 | return "/index.html"; 41 | } 42 | }, 43 | } 44 | } 45 | }, 46 | start: { 47 | keepalive: true, 48 | port: 23745, 49 | webpack: { 50 | devtool: "eval" 51 | }, 52 | } 53 | }, 54 | 55 | clean: { 56 | folder: [ 57 | 'build/assets' 58 | ] 59 | } 60 | }); 61 | 62 | grunt.loadNpmTasks("grunt-webpack"); 63 | 64 | grunt.loadNpmTasks('grunt-contrib-clean'); 65 | 66 | grunt.registerTask("build", ["webpack:build"]); 67 | 68 | grunt.registerTask("dev", ["build", "webpack-dev-server:start"]); 69 | 70 | grunt.registerTask('default', ['build']); 71 | }; 72 | -------------------------------------------------------------------------------- /angular/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Fleet Tracker Blueprint 3 | The scripts located in this directory are meant to run on [Twilio Runtime](https://www.twilio.com/docs/api/runtime/functions). These scripts are meant to be bundled into SPA artifacts to be uploaded to Twilio Runtime. 4 | 5 | Full instructions for this tutorial can be found in the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/). Below you will find the minimum steps necessary to build these SPA artifacts. 6 | 7 | ### What is Twilio Runtime? 8 | Twilio Runtime is a suite designed to help you build, scale and operate your application, consisting of a plethora of tools including helper libraries, API keys, asset storage, debugging tools, and a node based serverless hosting environment [Twilio Functions](https://www.twilio.com/docs/api/runtime/functions). 9 | 10 | ### Deploy Runtime assets 11 | Runtime assets are used to host the front-end of this Blueprint. The front-end is written using the [AngularJS](https://angularjs.org/) framework and compiled as a [single page application](https://en.wikipedia.org/wiki/Single-page_application). To deploy, you need to download the latest version of **index.html** and **index.min.js** from the **assets** folder. 12 | 13 | ### Run webpack dev server locally 14 | ``` 15 | $ npm install 16 | $ ./node_modules/.bin/grunt dev 17 | ``` 18 | 19 | ### Build assets 20 | ``` 21 | $ ./node_modules/.bin/grunt build 22 | ``` 23 | 24 | Visit the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/) for more information. -------------------------------------------------------------------------------- /angular/config.example.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // for local testing you need to point this to the runtime domain you use 3 | RUNTIME_DOMAIN: "https://your-runtime-domain.twil.io", 4 | // obtain your api key from https://developers.google.com/maps/documentation/javascript/get-api-key 5 | CONFIG_GOOGLE_MAP_API_KEY: "XXXXXXXXXXXXXXXXXXXXXXXXXXX" 6 | }; 7 | -------------------------------------------------------------------------------- /angular/imgs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twilio/wireless-fleet-tracker/6572d392e860796b92a42b140c0517cf6cc1293d/angular/imgs/favicon.ico -------------------------------------------------------------------------------- /angular/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Twilio's Fleet Tracker Blueprint 5 | 6 | 7 | 8 | 9 | 10 | 27 | 28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /angular/js/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const MOMENT_FORMAT = "MMM DD YYYY @ hh:mm"; 4 | 5 | var moment = require("moment"); 6 | 7 | module.exports = function(callbacks) { 8 | var $ = require("jquery"); 9 | var SyncClient = require("twilio-sync").Client; 10 | var syncClient; 11 | var token; 12 | var auth; 13 | 14 | var vehicles = {}; 15 | 16 | function initVehicleExtraInfo(id, extraInfo) { 17 | return syncClient.document("vehicle-" + id + "-info").then(function (document) { 18 | console.log("initVehicleExtraInfo", id, extraInfo); 19 | return document.set(extraInfo); 20 | }); 21 | } 22 | 23 | function fetchVehicleExtraInfo(id) { 24 | return syncClient.document("vehicle-" + id + "-info").then(function (document) { 25 | console.log("fetchVehicleExtraInfo", id, document.value); 26 | return document.value; 27 | }); 28 | }; 29 | 30 | function subscribeToVehicleData(id) { 31 | syncClient.list("vehicle-" + id + "-data").then(function (list) { 32 | list.getItems({ limit: 100, order: "desc" }).then(function (page) { 33 | console.info("items arrived", id, page.items.length); 34 | vehicles[id].driving_data = page.items.reverse().map(function (item) { 35 | item.data.value.id = item.index; 36 | callbacks.onVehicleData(vehicles[id], item.data.value); 37 | return item.data.value; 38 | }); 39 | }); 40 | list.on("itemAdded", function (item) { 41 | console.info("itemAdded", id, item); 42 | item.data.value.id = item.index; 43 | vehicles[id].driving_data.push(item.data.value); 44 | callbacks.onVehicleData(vehicles[id], item.data.value); 45 | }); 46 | }); 47 | }; 48 | 49 | return { 50 | vehicles: vehicles, 51 | 52 | updateToken: function (cb) { 53 | var that = this; 54 | return $.get("/authenticate?" + auth, function (result) { 55 | if (result.success) { 56 | console.log("token updated:", result); 57 | if (cb) { 58 | cb(result.sync_token, result.twiml_app_token); 59 | } else { 60 | syncClient.updateToken(result.sync_token); 61 | Twilio.Device.setup(result.twiml_app_token); 62 | } 63 | setTimeout(that.updateToken.bind(that), result.ttl*1000 * 0.96); // update token slightly in adance of ttl 64 | } else { 65 | console.error("failed to authenticate the user: ", result.error); 66 | auth=""; 67 | callbacks.authFailed(result.error); 68 | } 69 | }).fail(function (jqXHR, textStatus, error) { 70 | console.error("failed to send authentication request:", textStatus, error); 71 | auth=""; 72 | callbacks.authFailed(error); 73 | }); 74 | }, 75 | 76 | refreshVehicleList: function () { 77 | $.get("/fleetmanager?"+ auth + "&op=list", function (result) { 78 | if (result.success) { 79 | $.when.apply($, $.map(result.vehicles, function (vehicle) { 80 | var id = vehicle.uniqueName; 81 | vehicles[id] = { 82 | info: { 83 | id: id, 84 | name: vehicle.friendlyName, 85 | created_at: moment(vehicle.date_created).format(MOMENT_FORMAT) 86 | }, 87 | driving_data: [] 88 | }; 89 | return fetchVehicleExtraInfo(id).then(function (extraInfo) { 90 | vehicles[id].info = $.extend(vehicles[id].info, extraInfo); 91 | subscribeToVehicleData(vehicle.uniqueName); 92 | }); 93 | })).done(function () { 94 | callbacks.refresh(); 95 | }); 96 | } else { 97 | console.error("failed to list vehicles:", result); 98 | } 99 | }).fail(function (jqXHR, textStatus, error) { 100 | console.error("failed to send list vehicles request:", textStatus, error.toString()); 101 | }); 102 | }, 103 | 104 | addVehicle: function (newVehicle, callback) { 105 | if (!newVehicle.id) { 106 | return callback({success: false, error: "Vehicle id should not be empty"}); 107 | } 108 | $.get("/fleetmanager?" + auth + "&op=add&vehicle_id="+newVehicle.id.toUpperCase()+"&vehicle_name="+(newVehicle.name||""), function (result) { 109 | if (result.success) { 110 | var extraInfo = { 111 | type: newVehicle.type, 112 | mobile: newVehicle.mobile, 113 | }; 114 | var vehicleAdded = { 115 | info: $.extend({ 116 | id: result.vehicle.uniqueName, 117 | name: result.vehicle.friendlyName, 118 | created_at: moment(result.vehicle.date_created).format(MOMENT_FORMAT), 119 | key: result.key.sid, 120 | secret: result.key.secret 121 | }, extraInfo), 122 | driving_data: [] 123 | }; 124 | vehicles[result.vehicle.uniqueName] = vehicleAdded; 125 | initVehicleExtraInfo(result.vehicle.uniqueName, extraInfo) 126 | .then(function () { 127 | subscribeToVehicleData(result.vehicle.uniqueName); 128 | callback(null, vehicleAdded); 129 | }); 130 | } else { 131 | callback(result); 132 | } 133 | }).fail(function (jqXHR, textStatus, error) { 134 | callback({success: false, error: error}); 135 | console.error("failed to send add vehicle request:", textStatus, error.toString()); 136 | }); 137 | }, 138 | 139 | deleteVehicle: function (vehicleId) { 140 | $.get("/fleetmanager?"+ auth + "&op=delete&vehicle_id="+vehicleId, function (result) { 141 | if (result.success) { 142 | delete vehicles[vehicleId]; 143 | callbacks.refresh(); 144 | } else { 145 | console.error("failed to delete vehicle", result); 146 | } 147 | }).fail(function (jqXHR, textStatus, error) { 148 | console.error("failed to send delete vehicle request:", textStatus, error.toString()); 149 | }); 150 | }, 151 | 152 | generateKey: function (vehicleId) { 153 | $.get("/fleetmanager?"+ auth + "&op=genkey&vehicle_id="+vehicleId, function (result) { 154 | if (result.success) { 155 | vehicles[vehicleId].info.key = result.key.sid; 156 | vehicles[vehicleId].info.secret = result.key.secret; 157 | callbacks.refresh(); 158 | } else { 159 | console.error("failed to generate key", result); 160 | } 161 | }).fail(function (jqXHR, textStatus, error) { 162 | console.error("failed to send generate key request:", textStatus, error.toString()); 163 | }); 164 | }, 165 | 166 | call: function (vehicle, currentTarget) { 167 | var activeConnection = Twilio.Device.activeConnection(); 168 | console.log("call", vehicle); 169 | if (!vehicle.voiceConnection) { 170 | $(".btn-call").prop('disabled', true); 171 | $(currentTarget).prop('disabled', false); 172 | if (!activeConnection) { 173 | console.log("call.connect"); 174 | $(currentTarget).addClass('btn-danger'); 175 | $(currentTarget).html("End Call"); 176 | Twilio.Device.disconnect(function () { 177 | console.log("call.disconnected"); 178 | $(".btn-call").prop('disabled', false); 179 | $(currentTarget).removeClass('btn-danger'); 180 | $(currentTarget).html("Call"); 181 | }); 182 | vehicle.voiceConnection = Twilio.Device.connect({ number: vehicle.info.mobile }); 183 | } else { 184 | console.log("call.incall"); 185 | } 186 | } else { 187 | console.log("call.disconnect"); 188 | vehicle.voiceConnection.disconnect(); 189 | vehicle.voiceConnection = null; 190 | $(".btn-call").prop('disabled', false); 191 | } 192 | }, 193 | 194 | checkLoggedIn: function () { 195 | if (!auth) { 196 | callbacks.authRequired(); 197 | } 198 | }, 199 | 200 | login: function (username, password) { 201 | var that = this; 202 | auth = "username=" + username + "&pincode=" + password; 203 | this.updateToken(function (syncToken, twimlAppToken) { 204 | syncClient = new SyncClient(syncToken); 205 | Twilio.Device.setup(twimlAppToken); 206 | that.refreshVehicleList(); 207 | callbacks.onAuthenticated(); 208 | }); 209 | }, 210 | 211 | init: function () { 212 | this.checkLoggedIn(); 213 | //this.login("twilio", "wireless"); 214 | } 215 | }; 216 | }; 217 | -------------------------------------------------------------------------------- /angular/js/dashboardView.js: -------------------------------------------------------------------------------- 1 | require("../views/dashboard.html"); 2 | 3 | var vehicleView = require("./vehicleView"); 4 | 5 | var all_maps; 6 | var infowindows_map; 7 | 8 | var dashboardView = { 9 | init: function ($scope, latestStats) { 10 | all_maps = {}; 11 | infowindows_map = {}; 12 | 13 | for (var id in $scope.vehicles) { 14 | var vehicle = $scope.vehicles[id]; 15 | vehicle.driving_data.forEach(function (data) { 16 | dashboardView.onVehicleData(vehicle, data); 17 | dashboardView.onVehicleStats(vehicle, latestStats[vehicle.info.id]); 18 | }); 19 | } 20 | }, 21 | 22 | onVehicleData: function (vehicle, data) { 23 | if (!infowindows_map[vehicle.info.id]) { 24 | var mapElementName = 'map-'+vehicle.info.id; 25 | var newMap = vehicleView.initMapElement(mapElementName); 26 | all_maps[vehicle.info.id] = newMap; 27 | infowindows_map[vehicle.info.id] = {}; 28 | } 29 | var map = all_maps[vehicle.info.id]; 30 | var infowindows = infowindows_map[vehicle.info.id]; 31 | vehicleView.addDataToMap(map, infowindows, data); 32 | }, 33 | 34 | onVehicleStats: function (vehicle, stats) { 35 | if (!stats) return; 36 | 37 | var vehicleElemementName = 'vehicle'+vehicle.info.id; 38 | 39 | vehicleView.updateStats(vehicleElemementName, stats); 40 | } 41 | }; 42 | 43 | module.exports = dashboardView; 44 | -------------------------------------------------------------------------------- /angular/js/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var angular = require("angular"); 4 | require("angular-route"); 5 | 6 | // style sheets 7 | require("bootstrap-webpack"); 8 | require("../scss/main.scss"); 9 | 10 | // index.html 11 | require("../index.html"); 12 | 13 | var loginView = require("./loginView.js"); 14 | var dashboardView = require("./dashboardView"); 15 | var vehicleView = require("./vehicleView"); 16 | var vehicleListView = require("./vehicleListView"); 17 | var currentView; 18 | var $currentViewScope; 19 | 20 | var auth = {}; 21 | var n_data_map = {}; 22 | var total_speed_map = {}; 23 | var total_driver_scores_map = {}; 24 | var latestStats = {}; 25 | 26 | function initVehicleStats(vehicle) { 27 | if (!(vehicle.info.id in n_data_map)) { 28 | n_data_map[vehicle.info.id] = 0; 29 | total_speed_map[vehicle.info.id] = 0; 30 | total_driver_scores_map[vehicle.info.id] = 0; 31 | } 32 | } 33 | 34 | function updateVehicleStats(vehicle, data) { 35 | initVehicleStats(vehicle); 36 | 37 | var n_data = ++n_data_map[vehicle.info.id]; 38 | var total_speed = total_speed_map[vehicle.info.id]; 39 | var total_driver_scores = total_driver_scores_map[vehicle.info.id]; 40 | 41 | var stats = { 42 | miles : (data.miles).toFixed(0), 43 | avg_speed : (total_speed/n_data).toFixed(0), 44 | driver_score : (total_driver_scores/n_data).toFixed(0), 45 | fuel : (data.fuel).toFixed(0), 46 | brake : (data.brake).toFixed(0), 47 | runtime : data.runtime 48 | }; 49 | 50 | total_speed_map[vehicle.info.id] = total_speed_map[vehicle.info.id] + data.speed; 51 | total_driver_scores_map[vehicle.info.id] = total_driver_scores_map[vehicle.info.id] + data.avgT; 52 | 53 | latestStats[vehicle.info.id] = stats; 54 | } 55 | 56 | var App = require("./app"); 57 | window.app = new App({ 58 | refresh: function () { 59 | $currentViewScope.$apply(); 60 | }, 61 | 62 | onVehicleData: function (vehicle, data) { 63 | if (currentView.onVehicleData) currentView.onVehicleData(vehicle, data); 64 | if (vehicle.info.type === "CAR") { 65 | updateVehicleStats(vehicle, data); 66 | if (currentView.onVehicleStats) currentView.onVehicleStats(vehicle, latestStats[vehicle.info.id]); 67 | } 68 | }, 69 | 70 | onAuthenticated: function () { 71 | window.location.href = '/#!/dashboard'; 72 | $currentViewScope.$apply(); 73 | }, 74 | 75 | authFailed: function (reason) { 76 | auth.reason = reason; 77 | window.location.href = '/#!/login'; 78 | $currentViewScope.$apply(); 79 | }, 80 | 81 | authRequired: function () { 82 | auth.reason = ""; 83 | window.location.href = '/#!/login'; 84 | }, 85 | }); 86 | 87 | angular 88 | .module("app", [ 89 | 'ngRoute' 90 | ]) 91 | .controller('LoginViewCtrl', ['$scope', '$timeout', function ($scope, $timeout) { 92 | $currentViewScope = $scope; 93 | $scope.auth = auth; 94 | currentView = loginView; 95 | $timeout(function () { 96 | loginView.init(app, $scope.auth); 97 | }); 98 | }]) 99 | .controller('DashboardViewCtrl', ['$scope', '$timeout', function ($scope, $timeout) { 100 | app.checkLoggedIn(); 101 | $currentViewScope = $scope; 102 | $scope.app = app; 103 | $scope.vehicles = app.vehicles; 104 | currentView = dashboardView; 105 | // use timeout service to wait until view is loaded 106 | $timeout(function () { 107 | dashboardView.init($scope, latestStats); 108 | }, 0); 109 | }]) 110 | .controller('VehicleViewCtrl', ['$routeParams', '$scope', '$timeout', function ($routeParams, $scope, $timeout) { 111 | app.checkLoggedIn(); 112 | $currentViewScope = $scope; 113 | $scope.app = app; 114 | $scope.vehicles = app.vehicles; 115 | $scope.id = $routeParams.id; 116 | $scope.vehicle = app.vehicles[$routeParams.id]; 117 | currentView = vehicleView; 118 | if ($scope.vehicle) { 119 | $timeout(function () { 120 | vehicleView.init($scope); 121 | vehicleView.onVehicleStats($scope.vehicle, latestStats[$scope.vehicle.info.id]); 122 | }, 0); 123 | } 124 | }]) 125 | .controller('VehicleListViewCtrl', ['$scope', '$timeout', function ($scope, $timeout) { 126 | app.checkLoggedIn(); 127 | $currentViewScope = $scope; 128 | $scope.vehicles = app.vehicles; 129 | $scope.newVehicle = {}; 130 | $scope.addVehicle = function () { 131 | var err = app.addVehicle(angular.copy($scope.newVehicle), function (err, vehicleAdded) { 132 | if (err) { 133 | vehicleListView.onVehicleAddingFailed(err); 134 | } else { 135 | $scope.vehicleAdded = vehicleAdded; 136 | vehicleListView.onVehicleAdded(); 137 | $scope.$apply(); 138 | } 139 | }); 140 | }; 141 | $scope.deleteVehicle = function (vehicleId) { 142 | app.deleteVehicle(vehicleId); 143 | }; 144 | $scope.generateVehicleKey = function (vehicleId) { 145 | app.generateKey(vehicleId); 146 | }; 147 | currentView = vehicleListView; 148 | vehicleListView.init(); 149 | }]) 150 | .config(['$routeProvider', function ($routeProvider) { 151 | $routeProvider 152 | .when('/dashboard', { controller: 'DashboardViewCtrl', templateUrl: "views/dashboard.html" } ) 153 | .when('/vehicles/:id', { controller: 'VehicleViewCtrl', templateUrl: "views/vehicle.html" } ) 154 | .when('/vehicles', { controller: 'VehicleListViewCtrl', templateUrl: "views/vehicle_list.html" } ) 155 | .when('/login', { controller: 'LoginViewCtrl', templateUrl: 'views/login.html' }) 156 | .otherwise({ redirectTo: '/dashboard' }); 157 | }]); 158 | -------------------------------------------------------------------------------- /angular/js/loginView.js: -------------------------------------------------------------------------------- 1 | require("../views/login.html"); 2 | 3 | var loginView = { 4 | init: function (app, auth) { 5 | $('#input-form-submit').click(function () { 6 | app.login(auth.username, auth.password); 7 | }); 8 | } 9 | }; 10 | 11 | module.exports = loginView; 12 | -------------------------------------------------------------------------------- /angular/js/vehicleListView.js: -------------------------------------------------------------------------------- 1 | require("../views/vehicle_list.html"); 2 | 3 | var $ = require("jquery"); 4 | 5 | var vehicleListView = { 6 | init: function () { 7 | $('.add-vehicle-show').click(function() { 8 | $(this).hide(); 9 | $('.add-vehicle').fadeIn(333); 10 | $('#id').val(''); 11 | $('#name').val(''); 12 | $('#sim_sid').val(''); 13 | }); 14 | $('.add-vehicle-cancel').click(function() { 15 | $('.add-vehicle').hide(); 16 | $('.add-vehicle-show').fadeIn(333); 17 | }); 18 | }, 19 | 20 | onVehicleAddingFailed: function (err) { 21 | $('#add-vehicle-failed').text(JSON.stringify(err)); 22 | }, 23 | 24 | onVehicleAdded: function () { 25 | $('.add-vehicle').hide(); 26 | $('.add-vehicle-show').fadeIn(333); 27 | } 28 | } 29 | 30 | module.exports = vehicleListView; 31 | -------------------------------------------------------------------------------- /angular/js/vehicleView.js: -------------------------------------------------------------------------------- 1 | require("../views/vehicle.html"); 2 | 3 | var $ = require("jquery"); 4 | 5 | var map; 6 | var infowindows = {}; 7 | var vehicleId; 8 | 9 | var vehicleView = { 10 | init: function ($scope) { 11 | vehicleId = $scope.id; 12 | map = vehicleView.initMapElement('map'); 13 | $scope.vehicle.driving_data.forEach(function (data) { 14 | vehicleView.onVehicleData($scope.vehicle, data); 15 | }); 16 | }, 17 | 18 | onVehicleData: function (vehicle, data) { 19 | console.log("vehicle.info", vehicle.info); 20 | if (vehicle.info.id != vehicleId) return; 21 | vehicleView.addDataToMap(map, infowindows, data); 22 | }, 23 | 24 | onVehicleStats: function (vehicle, stats) { 25 | vehicleView.updateStats('vehicle', stats); 26 | }, 27 | 28 | /* static */ initMapElement: function (mapElementName) { 29 | var map = new google.maps.Map(document.getElementById(mapElementName), { 30 | zoom: 14 31 | }); 32 | return map; 33 | }, 34 | 35 | /* static */ addDataToMap: function (map, infowindows, data) { 36 | var latLon = { lat: data.lat, lng: data.lon} 37 | var marker = new google.maps.Marker({ 38 | position: latLon, 39 | map: map, 40 | title: String(data.id) 41 | }); 42 | 43 | var content_string = '
\ 44 |

Point data

' + 45 | (!!data.miles ? '

Distance: '+data.miles.toFixed(0)+' Miles

' : '') + 46 | (!!data.speed ? '

Speed: '+data.speed.toFixed(0)+' mph

' : '') + 47 | (!!data.fuel ? '

Fuel: '+data.fuel.toFixed(0)+'%

' : '') + 48 | '
'; 49 | 50 | var infowindow = new google.maps.InfoWindow({ 51 | content: content_string, 52 | }); 53 | infowindows[data.id] = infowindow; 54 | map.panTo(marker.getPosition()); 55 | 56 | google.maps.event.addListener(marker, 'click', function(e) { 57 | if('_current' in infowindows) { 58 | infowindows['_current'].close(); 59 | } 60 | infowindows[this.getTitle()].open(map, this); 61 | infowindows['_current'] = infowindows[this.getTitle()]; 62 | }); 63 | }, 64 | 65 | /* static */ updateStats: function (vehicleElemementName, stats) { 66 | if (!stats) return; 67 | 68 | $('.' + vehicleElemementName + ' .miles span').text(stats.miles); 69 | $('.' + vehicleElemementName + ' .speed span').text(stats.avg_speed); 70 | $('.' + vehicleElemementName + ' .fuel span').text(stats.fuel); 71 | $('.' + vehicleElemementName + ' .brake span').text(stats.brake); 72 | 73 | var runtime_string; 74 | if(stats.runtime < 60) { 75 | runtime_string = stats.runtime+' seconds'; 76 | } else if(stats.runtime < 3600) { 77 | runtime_string = (stats.runtime/60).toFixed(0)+" minutes"; 78 | } else { 79 | var hours = Math.floor(runtime/3600); 80 | var minutes = ((runtime - (hours*3600))/60).toFixed(0); 81 | runtime_string = hours+" hours and "+minutes+" minutes"; 82 | } 83 | 84 | $('.' + vehicleElemementName + ' .runtime').text(runtime_string); 85 | }, 86 | }; 87 | 88 | module.exports = vehicleView; 89 | -------------------------------------------------------------------------------- /angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twilio-fleet-tracker-ui", 3 | "version": "1.0.0", 4 | "description": "Create a Twilio-powered Fleet Tracker that uses off-the-shelf components to track and log: miles driven, hours of uptime and downtime, locations, average speed, and fuel consumption. This package includes its angular UI.", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/twilio/wireless-fleet-tracker.git" 12 | }, 13 | "keywords": [ 14 | "twilio", 15 | "twilio-sync", 16 | "iot" 17 | ], 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/twilio/wireless-fleet-tracker/issues" 21 | }, 22 | "homepage": "https://github.com/twilio/wireless-fleet-tracker#readme", 23 | "devDependencies": {}, 24 | "dependencies": { 25 | "bootstrap": ">=3.0.2", 26 | "bootstrap-webpack": "^0.0.6", 27 | "copy-webpack-plugin": "^2.1.6", 28 | "css-loader": "^0.28.1", 29 | "exports-loader": "^0.6.4", 30 | "extract-text-webpack-plugin": "^2.1.0", 31 | "file-loader": "^0.11.1", 32 | "grunt": "^1.0.1", 33 | "grunt-cli": "^1.2.0", 34 | "grunt-contrib-clean": "^1.1.0", 35 | "grunt-webpack": "^3.0.0", 36 | "html-loader": "^0.4.5", 37 | "imports-loader": "^0.7.1", 38 | "less": "^2.7.2", 39 | "less-loader": "^4.0.3", 40 | "moment": "^2.18.1", 41 | "ngtemplate-loader": "^1.3.1", 42 | "node-bourbon": "^4.2.8", 43 | "node-sass": "^4.5.2", 44 | "path": "^0.12.7", 45 | "sass-loader": "^6.0.5", 46 | "string-replace-loader": "^1.2.0", 47 | "string-replace-webpack-plugin": "^0.1.3", 48 | "style-loader": "^0.17.0", 49 | "url-loader": "^0.5.8", 50 | "webpack": "^2.5.1", 51 | "webpack-dev-server": "^2.4.5", 52 | "webpack-vendor-chunk-plugin": "^1.0.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /angular/scripts/launch-chrome.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | D=$(dirname "$0") 3 | /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \ 4 | --disable-web-security \ 5 | --auto-open-devtools-for-tabs \ 6 | --user-data-dir=$D/../build/chrome.data \ 7 | http://localhost:23745/assets/index.html 8 | -------------------------------------------------------------------------------- /angular/scss/_reset.scss: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /angular/scss/main.scss: -------------------------------------------------------------------------------- 1 | @import 'reset'; 2 | @import 'bourbon'; 3 | @import 'bootstrap'; 4 | 5 | // Colors 6 | $white: #FFFFFF; 7 | $darkest-grey: #222222; 8 | $dark-grey: #3d3d3d; 9 | $grey: #464545; 10 | $blue: #3498db; 11 | $purple: #454DE1; 12 | $green: #00bc8c; 13 | $red: #e74c3c; 14 | $peach: #E78F3C; 15 | $orange: #f39c12; 16 | $wireless: #7D60A9; 17 | $tred: #F22F46; 18 | $tblue: #0D122B; 19 | $chalk: #F5F5F5; 20 | $ash: #E8E8E8; 21 | $smoke: #94979B; 22 | 23 | body { 24 | @include font-feature-settings("kern", "liga", "pnum"); 25 | -webkit-font-smoothing: antialiased; 26 | padding-top: 50px; 27 | background-color: white; 28 | color: $tblue; 29 | } 30 | 31 | a:link { 32 | color: $tred; 33 | text-decoration: none; 34 | border-bottom: 1px solid $tblue; 35 | } 36 | 37 | a:hover { 38 | color: white; 39 | border-bottom-color: $tred; 40 | } 41 | 42 | select { 43 | border: 1px solid $tblue; 44 | } 45 | 46 | h1 { 47 | margin-bottom: 20px; 48 | font-size: 30px; 49 | } 50 | 51 | .add-vehicle-show { 52 | margin-top: 40px; 53 | background-color: $green; 54 | border: none; 55 | } 56 | 57 | .add-vehicle { 58 | margin-top: 40px; 59 | display: none; 60 | } 61 | 62 | .btn-primary { 63 | background-color: $green; 64 | } 65 | 66 | .btn-primary:hover { 67 | background-color: #008966 !important; 68 | border-color: #007f5e !important; 69 | } 70 | 71 | .alerts-list { 72 | color: $tblue; 73 | margin-top: 20px; 74 | display: flex; 75 | align-items: center; 76 | select { 77 | display: inline; 78 | height: auto; 79 | width: auto; 80 | border: 1px solid $tblue; 81 | } 82 | select:focus { 83 | border: 1px solid $tblue; 84 | } 85 | } 86 | 87 | .archive-view { 88 | margin-top: 20px; 89 | display: flex; 90 | align-items: center; 91 | } 92 | 93 | .selectpicker { 94 | color: black; 95 | } 96 | 97 | .navbar-custom { 98 | background-color: $tred !important; 99 | a { 100 | color: white; 101 | border-bottom: none; 102 | } 103 | :link, 104 | :hover, 105 | :focus { 106 | color: white; 107 | background-color: $tred !important; 108 | } 109 | } 110 | 111 | .chalk-background { 112 | background-color: $chalk !important; 113 | color: $tblue; 114 | margin-left: 10px; 115 | input, 116 | p 117 | { 118 | width:100%; 119 | } 120 | a { 121 | color: $tblue; 122 | border-bottom: 1px solid $tblue; 123 | } 124 | a:hover { 125 | border-bottom-color: $tred; 126 | text-decoration: none; 127 | } 128 | a:focus { 129 | text-decoration: none; 130 | } 131 | label { 132 | margin-left: 5px; 133 | } 134 | p { 135 | color: $smoke; 136 | margin: 5px 0px 0px 5px; 137 | } 138 | .btn-primary, 139 | .btn-default { 140 | border: none; 141 | } 142 | } 143 | 144 | h1, 145 | h2, 146 | h3 span { 147 | color: $tblue !important; 148 | } 149 | 150 | .bs-component { 151 | td, 152 | th { 153 | color: $tblue; 154 | } 155 | } 156 | 157 | .table-striped > tbody > tr:nth-of-type(odd) { 158 | background-color: $chalk; 159 | } 160 | 161 | .table-hover > tbody > tr:hover { 162 | background-color: $ash; 163 | } 164 | 165 | .navigate-archive { 166 | text-align: center; 167 | color: $tblue; 168 | a { 169 | color: $tblue; 170 | text-decoration: none; 171 | border-bottom-color: 1px solid $tblue; 172 | } 173 | a:hover { 174 | border-bottom-color: $tred; 175 | } 176 | } 177 | 178 | .archive-notification { 179 | color: $tblue; 180 | } 181 | 182 | @media only screen and (min-width : 1000px) { 183 | .sensor-feed { 184 | margin: 0 auto; 185 | max-width: 703px; 186 | } 187 | } 188 | 189 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { 190 | display: none !important; 191 | } 192 | 193 | .vehicle { 194 | padding-top: 20px; 195 | padding-bottom: 20px; 196 | h3 { 197 | a { 198 | font-size: 14px; 199 | } 200 | } 201 | .panel-body { 202 | text-align: center; 203 | font-size: 24px; 204 | } 205 | .map-cont { 206 | .map { 207 | height: 420px; 208 | margin-bottom: 40px; 209 | p { 210 | color: black; 211 | } 212 | .infowindow-label { 213 | margin-left: 15px; 214 | margin-right: -5px; 215 | margin-top: 15px; 216 | h1 { 217 | font-size: 24px; 218 | margin-bottom: 17px; 219 | color: black; 220 | text-decoration: underline; 221 | text-align: center; 222 | } 223 | p { 224 | font-size: 14px; 225 | margin-bottom: 15px; 226 | span { 227 | font-size: 16px; 228 | } 229 | span.label { 230 | display: inline-block; 231 | min-width: 90px; 232 | } 233 | .value { 234 | margin-right: 10px; 235 | margin-left: 7px; 236 | font-weight: 400; 237 | } 238 | } 239 | } 240 | } 241 | } 242 | } 243 | 244 | .add-vehicle-show { 245 | margin-top: 40px; 246 | } 247 | 248 | .add-vehicle { 249 | margin-top: 40px; 250 | display: none; 251 | } 252 | 253 | .add-driver-show { 254 | margin-top: 40px; 255 | } 256 | 257 | .add-driver { 258 | margin-top: 40px; 259 | display: none; 260 | } 261 | 262 | .login-form { 263 | position: fixed; /* Stay in place */ 264 | z-index: 1; /* Sit on top */ 265 | left: 0; 266 | top: 0; 267 | width: 100%; /* Full width */ 268 | height: 100%; /* Full height */ 269 | overflow: auto; /* Enable scroll if needed */ 270 | padding-top: 60px; 271 | } 272 | 273 | .login-form > #input-form-username, #input-form-password { 274 | width: 100%; 275 | padding: 12px 20px; 276 | margin: 8px 0; 277 | display: inline-block; 278 | border: 1px solid #ccc; 279 | box-sizing: border-box; 280 | } 281 | 282 | /* Set a style for all buttons */ 283 | .login-form > button { 284 | background-color: $green; 285 | color: white; 286 | padding: 14px 20px; 287 | margin: 8px 0; 288 | border: none; 289 | cursor: pointer; 290 | width: 100%; 291 | } 292 | 293 | .login-form > button:hover { 294 | opacity: 0.8; 295 | } 296 | 297 | .col-sm-1 { 298 | margin-left: 10px; 299 | width:100%; 300 | } -------------------------------------------------------------------------------- /angular/views/dashboard.html: -------------------------------------------------------------------------------- 1 |

Active Fleet Trackers

2 | 3 |

There are currently no vehicles on the road.

4 | 5 |
6 |
7 |
8 |

({{ vehicle.info.type }}) | {{vehicle.info.name}}

9 |

Current trip time: 0

10 |
11 |
12 | 13 |
14 |
15 |
16 |
17 | 19 |
20 |
21 |
22 | 28 |
29 |
30 |
31 |
32 |
33 |

Trip Distance

34 |
35 |
36 | 00 miles 37 |
38 |
39 |
40 |
41 |
42 |
43 |

Average Speed

44 |
45 |
46 | 00 mph 47 |
48 |
49 |
50 |
51 |
52 |
53 |

Hard Brakes

54 |
55 |
56 | 00 57 |
58 |
59 |
60 |
61 |
62 |
63 |

Fuel Guage

64 |
65 |
66 | 00% 67 |
68 |
69 |
70 |
71 | 72 | -------------------------------------------------------------------------------- /angular/views/login.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ auth.reason }}

3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | -------------------------------------------------------------------------------- /angular/views/vehicle.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

({{ vehicle.info.type }}) | {{ vehicle.info.name }}

5 |

Total trip time: 0

6 |
7 |
8 | 9 |
10 |
11 |
12 |
13 |
14 | 21 |
22 |
23 |
24 |
25 |

Trip Distance

26 |
27 |
28 | 00 miles 29 |
30 |
31 |
32 |
33 |
34 |
35 |

Average Speed

36 |
37 |
38 | 00 mph 39 |
40 |
41 |
42 |
43 |
44 |
45 |

Hard Brakes

46 |
47 |
48 | 00 49 |
50 |
51 |
52 |
53 |
54 |
55 |

Fuel Guage

56 |
57 |
58 | 00% 59 |
60 |
61 |
62 |
63 |
64 | -------------------------------------------------------------------------------- /angular/views/vehicle_list.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 30 | 34 | 35 | 38 | 42 | 43 | 44 |
IdNameKeyCreatedOperations
{{ vehicle.info.id }}{{ vehicle.info.name }} 31 |
{{ vehicle.info.key }}
Secret: {{ vehicle.info.secret }}
32 |
Hidden
33 |
{{ vehicle.info.created_at }} 39 | 40 | 41 |
45 |
46 |
47 |
48 | 49 | Add New Fleet Tracker 50 | 51 |
52 |
53 |
54 |
55 |

Add Fleet Tracker

56 | 57 |
58 | 59 |
60 | 64 |

What type of vehicle are you tracking?

65 |
66 |
67 | 68 |
69 | 70 |
71 | 72 |

This can be any unique alphanumeric identifier.

73 |
74 |
75 | 76 |
77 | 78 |
79 | 80 |

Give your Fleet Tracker a descriptive name for the dashboard.

81 |
82 |
83 | 84 | 92 | 93 |
94 |
95 | 96 | 97 |
98 |
99 | 100 |

101 |
102 |
103 |
104 |
105 | -------------------------------------------------------------------------------- /angular/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var webpack = require("webpack"); 3 | var config = require("./config"); // copy and modify config.example.js 4 | var StringReplacePlugin = require("string-replace-webpack-plugin"); 5 | 6 | module.exports = { 7 | cache: true, 8 | // Group dependencies into different entries and use CommonsChunkPlugin to share 9 | // the common parts and generate smaller chunks 10 | entry: { 11 | "index": "./js/index.js", 12 | "styles": [ 13 | "./scss/main.scss", 14 | ], 15 | "vendor": [ 16 | "bootstrap", "bootstrap-webpack", 17 | "moment", 18 | ] 19 | }, 20 | externals: { 21 | "jquery": 'jQuery', 22 | "twilio-sync": "Twilio.Sync", 23 | "angular": "angular", 24 | "angular-route": { amd: "angular-route" }, 25 | }, 26 | output: { 27 | path: path.join(__dirname, "build", "assets"), 28 | publicPath: "/assets/", 29 | filename: "[name].js", 30 | chunkFilename: "[name]-[chunkhash].js" 31 | }, 32 | module: { 33 | loaders: [ 34 | // required to write "require('./style.css')" 35 | { test: /\.css$/, loader: "style-loader!css-loader" }, 36 | 37 | // required to write "require('./style.scss')" 38 | { 39 | test: /\.scss$/, use: [{ 40 | loader: "style-loader" 41 | }, { 42 | loader: "css-loader" 43 | }, { 44 | loader: "sass-loader", 45 | options: { 46 | includePaths : 47 | require('node-bourbon').includePaths 48 | } 49 | }] 50 | }, 51 | 52 | // required for bootstrap icons 53 | { test: /\.woff$/, loader: "url-loader?limit=5000&mimetype=application/font-woff" }, 54 | { test: /\.woff2$/, loader: "url-loader?limit=5000&mimetype=application/font-woff2" }, 55 | { test: /\.ttf$/, loader: "file-loader" }, 56 | { test: /\.eot$/, loader: "file-loader" }, 57 | { test: /\.svg$/, loader: "file-loader" }, 58 | 59 | // generate index.html 60 | { test: /\/index\.html$/, use: [{ 61 | loader : "file-loader?name=index.html" 62 | }, { 63 | loader : StringReplacePlugin.replace({ 64 | replacements: [ 65 | { 66 | pattern: //g, 67 | replacement: function () { return config.CONFIG_GOOGLE_MAP_API_KEY; } 68 | } 69 | ] 70 | }) 71 | }] 72 | }, 73 | 74 | { test: /views\/\w+\.html$/, loader: "ngtemplate-loader?relativeTo=" + __dirname + "/!html-loader" } 75 | ] 76 | }, 77 | devtool: 'source-map', 78 | plugins: [ 79 | new webpack.optimize.CommonsChunkPlugin({ 80 | names: ['styles', 'vendor'], 81 | minChunks: Infinity 82 | }), 83 | ] 84 | }; 85 | -------------------------------------------------------------------------------- /assets/.gitattributes: -------------------------------------------------------------------------------- 1 | /* binary 2 | /.gitattributes test diff 3 | /README.md text diff 4 | -------------------------------------------------------------------------------- /assets/.gitignore: -------------------------------------------------------------------------------- 1 | /*-deployment-instructions.txt 2 | -------------------------------------------------------------------------------- /assets/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Fleet Tracker Blueprint 3 | The scripts located in this directory are meant to run on [Twilio Runtime](https://www.twilio.com/docs/api/runtime/functions). These scripts are meant to be bundled into SPA artifacts to be uploaded to Twilio Runtime. 4 | 5 | Full instructions for this tutorial can be found in the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/). Below you will find the minimum steps necessary to build these SPA artifacts. 6 | 7 | ### What is Twilio Runtime? 8 | Twilio Runtime is a suite designed to help you build, scale and operate your application, consisting of a plethora of tools including helper libraries, API keys, asset storage, debugging tools, and a node based serverless hosting environment [Twilio Functions](https://www.twilio.com/docs/api/runtime/functions). 9 | 10 | ### Deploy Runtime assets 11 | Runtime assets are used to host the front-end of this Blueprint. The front-end is written using the [AngularJS](https://angularjs.org/) framework and compiled as a [single page application](https://en.wikipedia.org/wiki/Single-page_application). To deploy, you need to download the latest version of **index.html**, **index.js**, **index.js.map**, **styles.js**, **styles.js.map**, **vendor.js**, and **vendor.js.map** from the **assets** folder. 12 | 13 | 14 | Visit the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/) for more information. -------------------------------------------------------------------------------- /dragonfly/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Fleet Tracker Blueprint 3 | Full instructions for this tutorial can be found in the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-traker/). Below you will find the minimum steps necessary to compile the Dragonfly custom code. 4 | 5 | 1. Create an [ARMmbed developer account](https://developer.mbed.org/) 6 | 2. Visit the [Dragonfly Fleet Tracker repository](https://developer.mbed.org/users/miaotwilio/code/DragonflyMQTT/) 7 | 3. Click the yellow **Import into Compiler** button 8 | 4. Click the **Import** button 9 | 10 | Visit the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/) for more information. -------------------------------------------------------------------------------- /models/README.md: -------------------------------------------------------------------------------- 1 | # Fleet Tracker Blueprint 2 | ### 3d-printed enclosure 3 | This Fleet Tracker Blueprint comes with CAD files designed for this 3D printout. You can find the CAD files here. Visit [Voodoo Manufacturing](https://voodoomfg.com/) to take advantage of their developer-first API driven 3d-printers to print out the models. Use [Sculpteo](http://sculpteo.com/) to print out the acrylic cover plate. 4 | 5 | **Note:** these files are optional and not necessary to construct this Blueprint. 6 | 7 | ### File descriptions 8 | 9 | | Filename | Description | 10 | |--------------------------------------|------------------------------------------------------------------------| 11 | | fleet-tracker-body.stl | The base of the Fleet Tracker enclosure. | 12 | | fleet-tracker-cover-plate.dxf | The acrilyric plate of the Fleet Tracker. | 13 | 14 | Full instructions for this tutorial can be found in the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/). -------------------------------------------------------------------------------- /models/fleet-tracker-body.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twilio/wireless-fleet-tracker/6572d392e860796b92a42b140c0517cf6cc1293d/models/fleet-tracker-body.stl -------------------------------------------------------------------------------- /models/fleet-tracker-cover-plate.dxf: -------------------------------------------------------------------------------- 1 | 0 2 | SECTION 3 | 2 4 | HEADER 5 | 9 6 | $ACADVER 7 | 1 8 | AC1024 9 | 9 10 | $ACADMAINTVER 11 | 70 12 | 6 13 | 9 14 | $DWGCODEPAGE 15 | 3 16 | ANSI_1252 17 | 9 18 | $INSBASE 19 | 10 20 | 0.0 21 | 20 22 | 0.0 23 | 30 24 | 0.0 25 | 9 26 | $EXTMIN 27 | 10 28 | 1.000000000000000E+20 29 | 20 30 | 1.000000000000000E+20 31 | 30 32 | 1.000000000000000E+20 33 | 9 34 | $EXTMAX 35 | 10 36 | -1.000000000000000E+20 37 | 20 38 | -1.000000000000000E+20 39 | 30 40 | -1.000000000000000E+20 41 | 9 42 | $LIMMIN 43 | 10 44 | 0.0 45 | 20 46 | 0.0 47 | 9 48 | $LIMMAX 49 | 10 50 | 12.0 51 | 20 52 | 9.0 53 | 9 54 | $ORTHOMODE 55 | 70 56 | 0 57 | 9 58 | $REGENMODE 59 | 70 60 | 1 61 | 9 62 | $FILLMODE 63 | 70 64 | 1 65 | 9 66 | $QTEXTMODE 67 | 70 68 | 0 69 | 9 70 | $MIRRTEXT 71 | 70 72 | 1 73 | 9 74 | $LTSCALE 75 | 40 76 | 1.0 77 | 9 78 | $ATTMODE 79 | 70 80 | 1 81 | 9 82 | $TEXTSIZE 83 | 40 84 | 0.2 85 | 9 86 | $TRACEWID 87 | 40 88 | 0.05 89 | 9 90 | $TEXTSTYLE 91 | 7 92 | Standard 93 | 9 94 | $CLAYER 95 | 8 96 | 0 97 | 9 98 | $CELTYPE 99 | 6 100 | ByLayer 101 | 9 102 | $CECOLOR 103 | 62 104 | 256 105 | 9 106 | $CELTSCALE 107 | 40 108 | 1.0 109 | 9 110 | $DISPSILH 111 | 70 112 | 0 113 | 9 114 | $DIMSCALE 115 | 40 116 | 1.0 117 | 9 118 | $DIMASZ 119 | 40 120 | 0.18 121 | 9 122 | $DIMEXO 123 | 40 124 | 0.0625 125 | 9 126 | $DIMDLI 127 | 40 128 | 0.38 129 | 9 130 | $DIMRND 131 | 40 132 | 0.0 133 | 9 134 | $DIMDLE 135 | 40 136 | 0.0 137 | 9 138 | $DIMEXE 139 | 40 140 | 0.18 141 | 9 142 | $DIMTP 143 | 40 144 | 0.0 145 | 9 146 | $DIMTM 147 | 40 148 | 0.0 149 | 9 150 | $DIMTXT 151 | 40 152 | 0.18 153 | 9 154 | $DIMCEN 155 | 40 156 | 0.09 157 | 9 158 | $DIMTSZ 159 | 40 160 | 0.0 161 | 9 162 | $DIMTOL 163 | 70 164 | 0 165 | 9 166 | $DIMLIM 167 | 70 168 | 0 169 | 9 170 | $DIMTIH 171 | 70 172 | 1 173 | 9 174 | $DIMTOH 175 | 70 176 | 1 177 | 9 178 | $DIMSE1 179 | 70 180 | 0 181 | 9 182 | $DIMSE2 183 | 70 184 | 0 185 | 9 186 | $DIMTAD 187 | 70 188 | 0 189 | 9 190 | $DIMZIN 191 | 70 192 | 0 193 | 9 194 | $DIMBLK 195 | 1 196 | 197 | 9 198 | $DIMASO 199 | 70 200 | 1 201 | 9 202 | $DIMSHO 203 | 70 204 | 1 205 | 9 206 | $DIMPOST 207 | 1 208 | 209 | 9 210 | $DIMAPOST 211 | 1 212 | 213 | 9 214 | $DIMALT 215 | 70 216 | 0 217 | 9 218 | $DIMALTD 219 | 70 220 | 2 221 | 9 222 | $DIMALTF 223 | 40 224 | 25.4 225 | 9 226 | $DIMLFAC 227 | 40 228 | 1.0 229 | 9 230 | $DIMTOFL 231 | 70 232 | 0 233 | 9 234 | $DIMTVP 235 | 40 236 | 0.0 237 | 9 238 | $DIMTIX 239 | 70 240 | 0 241 | 9 242 | $DIMSOXD 243 | 70 244 | 0 245 | 9 246 | $DIMSAH 247 | 70 248 | 0 249 | 9 250 | $DIMBLK1 251 | 1 252 | 253 | 9 254 | $DIMBLK2 255 | 1 256 | 257 | 9 258 | $DIMSTYLE 259 | 2 260 | Standard 261 | 9 262 | $DIMCLRD 263 | 70 264 | 0 265 | 9 266 | $DIMCLRE 267 | 70 268 | 0 269 | 9 270 | $DIMCLRT 271 | 70 272 | 0 273 | 9 274 | $DIMTFAC 275 | 40 276 | 1.0 277 | 9 278 | $DIMGAP 279 | 40 280 | 0.09 281 | 9 282 | $DIMJUST 283 | 70 284 | 0 285 | 9 286 | $DIMSD1 287 | 70 288 | 0 289 | 9 290 | $DIMSD2 291 | 70 292 | 0 293 | 9 294 | $DIMTOLJ 295 | 70 296 | 1 297 | 9 298 | $DIMTZIN 299 | 70 300 | 0 301 | 9 302 | $DIMALTZ 303 | 70 304 | 0 305 | 9 306 | $DIMALTTZ 307 | 70 308 | 0 309 | 9 310 | $DIMUPT 311 | 70 312 | 0 313 | 9 314 | $DIMDEC 315 | 70 316 | 4 317 | 9 318 | $DIMTDEC 319 | 70 320 | 4 321 | 9 322 | $DIMALTU 323 | 70 324 | 2 325 | 9 326 | $DIMALTTD 327 | 70 328 | 2 329 | 9 330 | $DIMTXSTY 331 | 7 332 | Standard 333 | 9 334 | $DIMAUNIT 335 | 70 336 | 0 337 | 9 338 | $DIMADEC 339 | 70 340 | 0 341 | 9 342 | $DIMALTRND 343 | 40 344 | 0.0 345 | 9 346 | $DIMAZIN 347 | 70 348 | 0 349 | 9 350 | $DIMDSEP 351 | 70 352 | 46 353 | 9 354 | $DIMATFIT 355 | 70 356 | 3 357 | 9 358 | $DIMFRAC 359 | 70 360 | 0 361 | 9 362 | $DIMLDRBLK 363 | 1 364 | 365 | 9 366 | $DIMLUNIT 367 | 70 368 | 2 369 | 9 370 | $DIMLWD 371 | 70 372 | -2 373 | 9 374 | $DIMLWE 375 | 70 376 | -2 377 | 9 378 | $DIMTMOVE 379 | 70 380 | 0 381 | 9 382 | $DIMFXL 383 | 40 384 | 1.0 385 | 9 386 | $DIMFXLON 387 | 70 388 | 0 389 | 9 390 | $DIMJOGANG 391 | 40 392 | 0.7853981633974483 393 | 9 394 | $DIMTFILL 395 | 70 396 | 0 397 | 9 398 | $DIMTFILLCLR 399 | 70 400 | 0 401 | 9 402 | $DIMARCSYM 403 | 70 404 | 0 405 | 9 406 | $DIMLTYPE 407 | 6 408 | 409 | 9 410 | $DIMLTEX1 411 | 6 412 | 413 | 9 414 | $DIMLTEX2 415 | 6 416 | 417 | 9 418 | $DIMTXTDIRECTION 419 | 70 420 | 0 421 | 9 422 | $LUNITS 423 | 70 424 | 2 425 | 9 426 | $LUPREC 427 | 70 428 | 4 429 | 9 430 | $SKETCHINC 431 | 40 432 | 0.1 433 | 9 434 | $FILLETRAD 435 | 40 436 | 0.5 437 | 9 438 | $AUNITS 439 | 70 440 | 0 441 | 9 442 | $AUPREC 443 | 70 444 | 0 445 | 9 446 | $MENU 447 | 1 448 | . 449 | 9 450 | $ELEVATION 451 | 40 452 | 0.0 453 | 9 454 | $PELEVATION 455 | 40 456 | 0.0 457 | 9 458 | $THICKNESS 459 | 40 460 | 0.0 461 | 9 462 | $LIMCHECK 463 | 70 464 | 0 465 | 9 466 | $CHAMFERA 467 | 40 468 | 0.5 469 | 9 470 | $CHAMFERB 471 | 40 472 | 0.5 473 | 9 474 | $CHAMFERC 475 | 40 476 | 1.0 477 | 9 478 | $CHAMFERD 479 | 40 480 | 0.0 481 | 9 482 | $SKPOLY 483 | 70 484 | 0 485 | 9 486 | $TDCREATE 487 | 40 488 | 2457833.444204039 489 | 9 490 | $TDUCREATE 491 | 40 492 | 2457833.610870706 493 | 9 494 | $TDUPDATE 495 | 40 496 | 2457833.44420471 497 | 9 498 | $TDUUPDATE 499 | 40 500 | 2457833.610871377 501 | 9 502 | $TDINDWG 503 | 40 504 | 0.0000000116 505 | 9 506 | $TDUSRTIMER 507 | 40 508 | 0.0000000116 509 | 9 510 | $USRTIMER 511 | 70 512 | 1 513 | 9 514 | $ANGBASE 515 | 50 516 | 0.0 517 | 9 518 | $ANGDIR 519 | 70 520 | 0 521 | 9 522 | $PDMODE 523 | 70 524 | 0 525 | 9 526 | $PDSIZE 527 | 40 528 | 0.0 529 | 9 530 | $PLINEWID 531 | 40 532 | 0.0 533 | 9 534 | $SPLFRAME 535 | 70 536 | 0 537 | 9 538 | $SPLINETYPE 539 | 70 540 | 6 541 | 9 542 | $SPLINESEGS 543 | 70 544 | 8 545 | 9 546 | $HANDSEED 547 | 5 548 | 85 549 | 9 550 | $SURFTAB1 551 | 70 552 | 6 553 | 9 554 | $SURFTAB2 555 | 70 556 | 6 557 | 9 558 | $SURFTYPE 559 | 70 560 | 6 561 | 9 562 | $SURFU 563 | 70 564 | 6 565 | 9 566 | $SURFV 567 | 70 568 | 6 569 | 9 570 | $UCSBASE 571 | 2 572 | 573 | 9 574 | $UCSNAME 575 | 2 576 | 577 | 9 578 | $UCSORG 579 | 10 580 | 0.0 581 | 20 582 | 0.0 583 | 30 584 | 0.0 585 | 9 586 | $UCSXDIR 587 | 10 588 | 1.0 589 | 20 590 | 0.0 591 | 30 592 | 0.0 593 | 9 594 | $UCSYDIR 595 | 10 596 | 0.0 597 | 20 598 | 1.0 599 | 30 600 | 0.0 601 | 9 602 | $UCSORTHOREF 603 | 2 604 | 605 | 9 606 | $UCSORTHOVIEW 607 | 70 608 | 0 609 | 9 610 | $UCSORGTOP 611 | 10 612 | 0.0 613 | 20 614 | 0.0 615 | 30 616 | 0.0 617 | 9 618 | $UCSORGBOTTOM 619 | 10 620 | 0.0 621 | 20 622 | 0.0 623 | 30 624 | 0.0 625 | 9 626 | $UCSORGLEFT 627 | 10 628 | 0.0 629 | 20 630 | 0.0 631 | 30 632 | 0.0 633 | 9 634 | $UCSORGRIGHT 635 | 10 636 | 0.0 637 | 20 638 | 0.0 639 | 30 640 | 0.0 641 | 9 642 | $UCSORGFRONT 643 | 10 644 | 0.0 645 | 20 646 | 0.0 647 | 30 648 | 0.0 649 | 9 650 | $UCSORGBACK 651 | 10 652 | 0.0 653 | 20 654 | 0.0 655 | 30 656 | 0.0 657 | 9 658 | $PUCSBASE 659 | 2 660 | 661 | 9 662 | $PUCSNAME 663 | 2 664 | 665 | 9 666 | $PUCSORG 667 | 10 668 | 0.0 669 | 20 670 | 0.0 671 | 30 672 | 0.0 673 | 9 674 | $PUCSXDIR 675 | 10 676 | 1.0 677 | 20 678 | 0.0 679 | 30 680 | 0.0 681 | 9 682 | $PUCSYDIR 683 | 10 684 | 0.0 685 | 20 686 | 1.0 687 | 30 688 | 0.0 689 | 9 690 | $PUCSORTHOREF 691 | 2 692 | 693 | 9 694 | $PUCSORTHOVIEW 695 | 70 696 | 0 697 | 9 698 | $PUCSORGTOP 699 | 10 700 | 0.0 701 | 20 702 | 0.0 703 | 30 704 | 0.0 705 | 9 706 | $PUCSORGBOTTOM 707 | 10 708 | 0.0 709 | 20 710 | 0.0 711 | 30 712 | 0.0 713 | 9 714 | $PUCSORGLEFT 715 | 10 716 | 0.0 717 | 20 718 | 0.0 719 | 30 720 | 0.0 721 | 9 722 | $PUCSORGRIGHT 723 | 10 724 | 0.0 725 | 20 726 | 0.0 727 | 30 728 | 0.0 729 | 9 730 | $PUCSORGFRONT 731 | 10 732 | 0.0 733 | 20 734 | 0.0 735 | 30 736 | 0.0 737 | 9 738 | $PUCSORGBACK 739 | 10 740 | 0.0 741 | 20 742 | 0.0 743 | 30 744 | 0.0 745 | 9 746 | $USERI1 747 | 70 748 | 0 749 | 9 750 | $USERI2 751 | 70 752 | 0 753 | 9 754 | $USERI3 755 | 70 756 | 0 757 | 9 758 | $USERI4 759 | 70 760 | 0 761 | 9 762 | $USERI5 763 | 70 764 | 0 765 | 9 766 | $USERR1 767 | 40 768 | 0.0 769 | 9 770 | $USERR2 771 | 40 772 | 0.0 773 | 9 774 | $USERR3 775 | 40 776 | 0.0 777 | 9 778 | $USERR4 779 | 40 780 | 0.0 781 | 9 782 | $USERR5 783 | 40 784 | 0.0 785 | 9 786 | $WORLDVIEW 787 | 70 788 | 1 789 | 9 790 | $SHADEDGE 791 | 70 792 | 3 793 | 9 794 | $SHADEDIF 795 | 70 796 | 70 797 | 9 798 | $TILEMODE 799 | 70 800 | 1 801 | 9 802 | $MAXACTVP 803 | 70 804 | 64 805 | 9 806 | $PINSBASE 807 | 10 808 | 0.0 809 | 20 810 | 0.0 811 | 30 812 | 0.0 813 | 9 814 | $PLIMCHECK 815 | 70 816 | 0 817 | 9 818 | $PEXTMIN 819 | 10 820 | 1.000000000000000E+20 821 | 20 822 | 1.000000000000000E+20 823 | 30 824 | 1.000000000000000E+20 825 | 9 826 | $PEXTMAX 827 | 10 828 | -1.000000000000000E+20 829 | 20 830 | -1.000000000000000E+20 831 | 30 832 | -1.000000000000000E+20 833 | 9 834 | $PLIMMIN 835 | 10 836 | 0.0 837 | 20 838 | 0.0 839 | 9 840 | $PLIMMAX 841 | 10 842 | 12.0 843 | 20 844 | 9.0 845 | 9 846 | $UNITMODE 847 | 70 848 | 0 849 | 9 850 | $VISRETAIN 851 | 70 852 | 1 853 | 9 854 | $PLINEGEN 855 | 70 856 | 0 857 | 9 858 | $PSLTSCALE 859 | 70 860 | 1 861 | 9 862 | $TREEDEPTH 863 | 70 864 | 3020 865 | 9 866 | $CMLSTYLE 867 | 2 868 | Standard 869 | 9 870 | $CMLJUST 871 | 70 872 | 0 873 | 9 874 | $CMLSCALE 875 | 40 876 | 1.0 877 | 9 878 | $PROXYGRAPHICS 879 | 70 880 | 1 881 | 9 882 | $MEASUREMENT 883 | 70 884 | 0 885 | 9 886 | $CELWEIGHT 887 | 370 888 | -1 889 | 9 890 | $ENDCAPS 891 | 280 892 | 0 893 | 9 894 | $JOINSTYLE 895 | 280 896 | 0 897 | 9 898 | $LWDISPLAY 899 | 290 900 | 1 901 | 9 902 | $INSUNITS 903 | 70 904 | 1 905 | 9 906 | $HYPERLINKBASE 907 | 1 908 | 909 | 9 910 | $STYLESHEET 911 | 1 912 | 913 | 9 914 | $XEDIT 915 | 290 916 | 1 917 | 9 918 | $CEPSNTYPE 919 | 380 920 | 0 921 | 9 922 | $PSTYLEMODE 923 | 290 924 | 1 925 | 9 926 | $FINGERPRINTGUID 927 | 2 928 | {C6AC4533-F0A0-4420-9836-06D2372AAED4} 929 | 9 930 | $VERSIONGUID 931 | 2 932 | {FAEB1C32-E019-11D5-929B-00C0DF256EC4} 933 | 9 934 | $EXTNAMES 935 | 290 936 | 1 937 | 9 938 | $PSVPSCALE 939 | 40 940 | 0.0 941 | 9 942 | $OLESTARTUP 943 | 290 944 | 0 945 | 9 946 | $SORTENTS 947 | 280 948 | 127 949 | 9 950 | $INDEXCTL 951 | 280 952 | 0 953 | 9 954 | $HIDETEXT 955 | 280 956 | 1 957 | 9 958 | $XCLIPFRAME 959 | 280 960 | 2 961 | 9 962 | $HALOGAP 963 | 280 964 | 0 965 | 9 966 | $OBSCOLOR 967 | 70 968 | 257 969 | 9 970 | $OBSLTYPE 971 | 280 972 | 0 973 | 9 974 | $INTERSECTIONDISPLAY 975 | 280 976 | 0 977 | 9 978 | $INTERSECTIONCOLOR 979 | 70 980 | 257 981 | 9 982 | $DIMASSOC 983 | 280 984 | 2 985 | 9 986 | $PROJECTNAME 987 | 1 988 | 989 | 9 990 | $CAMERADISPLAY 991 | 290 992 | 0 993 | 9 994 | $LENSLENGTH 995 | 40 996 | 50.0 997 | 9 998 | $CAMERAHEIGHT 999 | 40 1000 | 0.0 1001 | 9 1002 | $STEPSPERSEC 1003 | 40 1004 | 2.0 1005 | 9 1006 | $STEPSIZE 1007 | 40 1008 | 6.0 1009 | 9 1010 | $3DDWFPREC 1011 | 40 1012 | 2.0 1013 | 9 1014 | $PSOLWIDTH 1015 | 40 1016 | 0.25 1017 | 9 1018 | $PSOLHEIGHT 1019 | 40 1020 | 4.0 1021 | 9 1022 | $LOFTANG1 1023 | 40 1024 | 1.570796326794897 1025 | 9 1026 | $LOFTANG2 1027 | 40 1028 | 1.570796326794897 1029 | 9 1030 | $LOFTMAG1 1031 | 40 1032 | 0.0 1033 | 9 1034 | $LOFTMAG2 1035 | 40 1036 | 0.0 1037 | 9 1038 | $LOFTPARAM 1039 | 70 1040 | 7 1041 | 9 1042 | $LOFTNORMALS 1043 | 280 1044 | 1 1045 | 9 1046 | $LATITUDE 1047 | 40 1048 | 37.795 1049 | 9 1050 | $LONGITUDE 1051 | 40 1052 | -122.394 1053 | 9 1054 | $NORTHDIRECTION 1055 | 40 1056 | 0.0 1057 | 9 1058 | $TIMEZONE 1059 | 70 1060 | -8000 1061 | 9 1062 | $LIGHTGLYPHDISPLAY 1063 | 280 1064 | 1 1065 | 9 1066 | $TILEMODELIGHTSYNCH 1067 | 280 1068 | 1 1069 | 9 1070 | $CMATERIAL 1071 | 347 1072 | 3C 1073 | 9 1074 | $SOLIDHIST 1075 | 280 1076 | 1 1077 | 9 1078 | $SHOWHIST 1079 | 280 1080 | 1 1081 | 9 1082 | $DWFFRAME 1083 | 280 1084 | 2 1085 | 9 1086 | $DGNFRAME 1087 | 280 1088 | 2 1089 | 9 1090 | $REALWORLDSCALE 1091 | 290 1092 | 1 1093 | 9 1094 | $INTERFERECOLOR 1095 | 62 1096 | 256 1097 | 9 1098 | $CSHADOW 1099 | 280 1100 | 0 1101 | 9 1102 | $SHADOWPLANELOCATION 1103 | 40 1104 | 0.0 1105 | 0 1106 | ENDSEC 1107 | 0 1108 | SECTION 1109 | 2 1110 | CLASSES 1111 | 0 1112 | CLASS 1113 | 1 1114 | ACDBDICTIONARYWDFLT 1115 | 2 1116 | AcDbDictionaryWithDefault 1117 | 3 1118 | ObjectDBX Classes 1119 | 90 1120 | 0 1121 | 91 1122 | 4 1123 | 280 1124 | 0 1125 | 281 1126 | 0 1127 | 0 1128 | CLASS 1129 | 1 1130 | VISUALSTYLE 1131 | 2 1132 | AcDbVisualStyle 1133 | 3 1134 | ObjectDBX Classes 1135 | 90 1136 | 4095 1137 | 91 1138 | 4 1139 | 280 1140 | 0 1141 | 281 1142 | 0 1143 | 0 1144 | CLASS 1145 | 1 1146 | MATERIAL 1147 | 2 1148 | AcDbMaterial 1149 | 3 1150 | ObjectDBX Classes 1151 | 90 1152 | 1153 1153 | 91 1154 | 4 1155 | 280 1156 | 0 1157 | 281 1158 | 0 1159 | 0 1160 | CLASS 1161 | 1 1162 | SUN 1163 | 2 1164 | AcDbSun 1165 | 3 1166 | SCENEOE 1167 | 90 1168 | 1024 1169 | 91 1170 | 4 1171 | 280 1172 | 0 1173 | 281 1174 | 0 1175 | 0 1176 | ENDSEC 1177 | 0 1178 | SECTION 1179 | 2 1180 | TABLES 1181 | 0 1182 | TABLE 1183 | 2 1184 | VPORT 1185 | 5 1186 | 8 1187 | 330 1188 | 0 1189 | 100 1190 | AcDbSymbolTable 1191 | 70 1192 | 1 1193 | 0 1194 | VPORT 1195 | 5 1196 | 29 1197 | 330 1198 | 8 1199 | 100 1200 | AcDbSymbolTableRecord 1201 | 100 1202 | AcDbViewportTableRecord 1203 | 2 1204 | *Active 1205 | 70 1206 | 0 1207 | 10 1208 | 0.0 1209 | 20 1210 | 0.0 1211 | 11 1212 | 1.0 1213 | 21 1214 | 1.0 1215 | 12 1216 | 0.0 1217 | 22 1218 | 0.0 1219 | 13 1220 | 0.0 1221 | 23 1222 | 0.0 1223 | 14 1224 | 0.5 1225 | 24 1226 | 0.5 1227 | 15 1228 | 0.5 1229 | 25 1230 | 0.5 1231 | 16 1232 | 0.0 1233 | 26 1234 | 0.0 1235 | 36 1236 | 1.0 1237 | 17 1238 | 4.25 1239 | 27 1240 | 5.5 1241 | 37 1242 | 0.0 1243 | 40 1244 | 11.0 1245 | 41 1246 | 0.7727272727272727 1247 | 42 1248 | 50.0 1249 | 43 1250 | 0.0 1251 | 44 1252 | 0.0 1253 | 50 1254 | 0.0 1255 | 51 1256 | 0.0 1257 | 71 1258 | 0 1259 | 72 1260 | 100 1261 | 73 1262 | 1 1263 | 74 1264 | 3 1265 | 75 1266 | 0 1267 | 76 1268 | 0 1269 | 77 1270 | 0 1271 | 78 1272 | 0 1273 | 281 1274 | 0 1275 | 65 1276 | 1 1277 | 110 1278 | 0.0 1279 | 120 1280 | 0.0 1281 | 130 1282 | 0.0 1283 | 111 1284 | 1.0 1285 | 121 1286 | 0.0 1287 | 131 1288 | 0.0 1289 | 112 1290 | 0.0 1291 | 122 1292 | 1.0 1293 | 132 1294 | 0.0 1295 | 79 1296 | 0 1297 | 146 1298 | 0.0 1299 | 60 1300 | 3 1301 | 61 1302 | 5 1303 | 292 1304 | 1 1305 | 282 1306 | 1 1307 | 141 1308 | 0.0 1309 | 142 1310 | 0.0 1311 | 63 1312 | 250 1313 | 361 1314 | 3F 1315 | 0 1316 | ENDTAB 1317 | 0 1318 | TABLE 1319 | 2 1320 | LTYPE 1321 | 5 1322 | 5 1323 | 330 1324 | 0 1325 | 100 1326 | AcDbSymbolTable 1327 | 70 1328 | 1 1329 | 0 1330 | LTYPE 1331 | 5 1332 | 14 1333 | 330 1334 | 5 1335 | 100 1336 | AcDbSymbolTableRecord 1337 | 100 1338 | AcDbLinetypeTableRecord 1339 | 2 1340 | ByBlock 1341 | 70 1342 | 0 1343 | 3 1344 | 1345 | 72 1346 | 65 1347 | 73 1348 | 0 1349 | 40 1350 | 0.0 1351 | 0 1352 | LTYPE 1353 | 5 1354 | 15 1355 | 330 1356 | 5 1357 | 100 1358 | AcDbSymbolTableRecord 1359 | 100 1360 | AcDbLinetypeTableRecord 1361 | 2 1362 | ByLayer 1363 | 70 1364 | 0 1365 | 3 1366 | 1367 | 72 1368 | 65 1369 | 73 1370 | 0 1371 | 40 1372 | 0.0 1373 | 0 1374 | LTYPE 1375 | 5 1376 | 16 1377 | 330 1378 | 5 1379 | 100 1380 | AcDbSymbolTableRecord 1381 | 100 1382 | AcDbLinetypeTableRecord 1383 | 2 1384 | Continuous 1385 | 70 1386 | 0 1387 | 3 1388 | Solid line 1389 | 72 1390 | 65 1391 | 73 1392 | 0 1393 | 40 1394 | 0.0 1395 | 0 1396 | ENDTAB 1397 | 0 1398 | TABLE 1399 | 2 1400 | LAYER 1401 | 5 1402 | 2 1403 | 330 1404 | 0 1405 | 100 1406 | AcDbSymbolTable 1407 | 70 1408 | 1 1409 | 0 1410 | LAYER 1411 | 5 1412 | 10 1413 | 330 1414 | 2 1415 | 100 1416 | AcDbSymbolTableRecord 1417 | 100 1418 | AcDbLayerTableRecord 1419 | 2 1420 | 0 1421 | 70 1422 | 0 1423 | 62 1424 | 7 1425 | 6 1426 | Continuous 1427 | 370 1428 | -3 1429 | 390 1430 | F 1431 | 347 1432 | 3E 1433 | 0 1434 | ENDTAB 1435 | 0 1436 | TABLE 1437 | 2 1438 | STYLE 1439 | 5 1440 | 3 1441 | 330 1442 | 0 1443 | 100 1444 | AcDbSymbolTable 1445 | 70 1446 | 1 1447 | 0 1448 | STYLE 1449 | 5 1450 | 11 1451 | 330 1452 | 3 1453 | 100 1454 | AcDbSymbolTableRecord 1455 | 100 1456 | AcDbTextStyleTableRecord 1457 | 2 1458 | Standard 1459 | 70 1460 | 0 1461 | 40 1462 | 0.0 1463 | 41 1464 | 1.0 1465 | 50 1466 | 0.0 1467 | 71 1468 | 0 1469 | 42 1470 | 0.2 1471 | 3 1472 | txt 1473 | 4 1474 | 1475 | 0 1476 | ENDTAB 1477 | 0 1478 | TABLE 1479 | 2 1480 | VIEW 1481 | 5 1482 | 6 1483 | 330 1484 | 0 1485 | 100 1486 | AcDbSymbolTable 1487 | 70 1488 | 0 1489 | 0 1490 | ENDTAB 1491 | 0 1492 | TABLE 1493 | 2 1494 | UCS 1495 | 5 1496 | 7 1497 | 330 1498 | 0 1499 | 100 1500 | AcDbSymbolTable 1501 | 70 1502 | 0 1503 | 0 1504 | ENDTAB 1505 | 0 1506 | TABLE 1507 | 2 1508 | APPID 1509 | 5 1510 | 9 1511 | 330 1512 | 0 1513 | 100 1514 | AcDbSymbolTable 1515 | 70 1516 | 1 1517 | 0 1518 | APPID 1519 | 5 1520 | 12 1521 | 330 1522 | 9 1523 | 100 1524 | AcDbSymbolTableRecord 1525 | 100 1526 | AcDbRegAppTableRecord 1527 | 2 1528 | ACAD 1529 | 70 1530 | 0 1531 | 0 1532 | ENDTAB 1533 | 0 1534 | TABLE 1535 | 2 1536 | DIMSTYLE 1537 | 5 1538 | A 1539 | 330 1540 | 0 1541 | 100 1542 | AcDbSymbolTable 1543 | 70 1544 | 1 1545 | 100 1546 | AcDbDimStyleTable 1547 | 0 1548 | DIMSTYLE 1549 | 105 1550 | 27 1551 | 330 1552 | A 1553 | 100 1554 | AcDbSymbolTableRecord 1555 | 100 1556 | AcDbDimStyleTableRecord 1557 | 2 1558 | Standard 1559 | 70 1560 | 0 1561 | 178 1562 | 0 1563 | 340 1564 | 11 1565 | 0 1566 | ENDTAB 1567 | 0 1568 | TABLE 1569 | 2 1570 | BLOCK_RECORD 1571 | 5 1572 | 1 1573 | 330 1574 | 0 1575 | 100 1576 | AcDbSymbolTable 1577 | 70 1578 | 12 1579 | 0 1580 | BLOCK_RECORD 1581 | 5 1582 | 1F 1583 | 330 1584 | 1 1585 | 100 1586 | AcDbSymbolTableRecord 1587 | 100 1588 | AcDbBlockTableRecord 1589 | 2 1590 | *Model_Space 1591 | 340 1592 | 22 1593 | 70 1594 | 0 1595 | 280 1596 | 1 1597 | 281 1598 | 0 1599 | 0 1600 | BLOCK_RECORD 1601 | 5 1602 | 1B 1603 | 330 1604 | 1 1605 | 100 1606 | AcDbSymbolTableRecord 1607 | 100 1608 | AcDbBlockTableRecord 1609 | 2 1610 | *Paper_Space 1611 | 340 1612 | 1E 1613 | 70 1614 | 0 1615 | 280 1616 | 1 1617 | 281 1618 | 0 1619 | 0 1620 | BLOCK_RECORD 1621 | 5 1622 | 23 1623 | 330 1624 | 1 1625 | 100 1626 | AcDbSymbolTableRecord 1627 | 100 1628 | AcDbBlockTableRecord 1629 | 2 1630 | *Paper_Space0 1631 | 340 1632 | 26 1633 | 70 1634 | 0 1635 | 280 1636 | 1 1637 | 281 1638 | 0 1639 | 0 1640 | BLOCK_RECORD 1641 | 5 1642 | 40 1643 | 330 1644 | 1 1645 | 100 1646 | AcDbSymbolTableRecord 1647 | 100 1648 | AcDbBlockTableRecord 1649 | 2 1650 | block 2 1651 | 340 1652 | 0 1653 | 102 1654 | {BLKREFS 1655 | 331 1656 | 41 1657 | 102 1658 | } 1659 | 70 1660 | 0 1661 | 280 1662 | 1 1663 | 281 1664 | 0 1665 | 0 1666 | BLOCK_RECORD 1667 | 5 1668 | 45 1669 | 330 1670 | 1 1671 | 100 1672 | AcDbSymbolTableRecord 1673 | 100 1674 | AcDbBlockTableRecord 1675 | 2 1676 | block 3 1677 | 340 1678 | 0 1679 | 102 1680 | {BLKREFS 1681 | 331 1682 | 46 1683 | 102 1684 | } 1685 | 70 1686 | 0 1687 | 280 1688 | 1 1689 | 281 1690 | 0 1691 | 0 1692 | BLOCK_RECORD 1693 | 5 1694 | 4D 1695 | 330 1696 | 1 1697 | 100 1698 | AcDbSymbolTableRecord 1699 | 100 1700 | AcDbBlockTableRecord 1701 | 2 1702 | block 4 1703 | 340 1704 | 0 1705 | 102 1706 | {BLKREFS 1707 | 331 1708 | 4E 1709 | 102 1710 | } 1711 | 70 1712 | 0 1713 | 280 1714 | 1 1715 | 281 1716 | 0 1717 | 0 1718 | BLOCK_RECORD 1719 | 5 1720 | 52 1721 | 330 1722 | 1 1723 | 100 1724 | AcDbSymbolTableRecord 1725 | 100 1726 | AcDbBlockTableRecord 1727 | 2 1728 | block 5 1729 | 340 1730 | 0 1731 | 102 1732 | {BLKREFS 1733 | 331 1734 | 53 1735 | 102 1736 | } 1737 | 70 1738 | 0 1739 | 280 1740 | 1 1741 | 281 1742 | 0 1743 | 0 1744 | BLOCK_RECORD 1745 | 5 1746 | 57 1747 | 330 1748 | 1 1749 | 100 1750 | AcDbSymbolTableRecord 1751 | 100 1752 | AcDbBlockTableRecord 1753 | 2 1754 | block 6 1755 | 340 1756 | 0 1757 | 102 1758 | {BLKREFS 1759 | 331 1760 | 58 1761 | 102 1762 | } 1763 | 70 1764 | 0 1765 | 280 1766 | 1 1767 | 281 1768 | 0 1769 | 0 1770 | BLOCK_RECORD 1771 | 5 1772 | 5C 1773 | 330 1774 | 1 1775 | 100 1776 | AcDbSymbolTableRecord 1777 | 100 1778 | AcDbBlockTableRecord 1779 | 2 1780 | block 7 1781 | 340 1782 | 0 1783 | 102 1784 | {BLKREFS 1785 | 331 1786 | 5D 1787 | 102 1788 | } 1789 | 70 1790 | 0 1791 | 280 1792 | 1 1793 | 281 1794 | 0 1795 | 0 1796 | BLOCK_RECORD 1797 | 5 1798 | 61 1799 | 330 1800 | 1 1801 | 100 1802 | AcDbSymbolTableRecord 1803 | 100 1804 | AcDbBlockTableRecord 1805 | 2 1806 | block 8 1807 | 340 1808 | 0 1809 | 102 1810 | {BLKREFS 1811 | 331 1812 | 62 1813 | 102 1814 | } 1815 | 70 1816 | 0 1817 | 280 1818 | 1 1819 | 281 1820 | 0 1821 | 0 1822 | BLOCK_RECORD 1823 | 5 1824 | 69 1825 | 330 1826 | 1 1827 | 100 1828 | AcDbSymbolTableRecord 1829 | 100 1830 | AcDbBlockTableRecord 1831 | 2 1832 | block 9 1833 | 340 1834 | 0 1835 | 102 1836 | {BLKREFS 1837 | 331 1838 | 6A 1839 | 102 1840 | } 1841 | 70 1842 | 0 1843 | 280 1844 | 1 1845 | 281 1846 | 0 1847 | 0 1848 | BLOCK_RECORD 1849 | 5 1850 | 71 1851 | 330 1852 | 1 1853 | 100 1854 | AcDbSymbolTableRecord 1855 | 100 1856 | AcDbBlockTableRecord 1857 | 2 1858 | block 10 1859 | 340 1860 | 0 1861 | 102 1862 | {BLKREFS 1863 | 331 1864 | 72 1865 | 102 1866 | } 1867 | 70 1868 | 0 1869 | 280 1870 | 1 1871 | 281 1872 | 0 1873 | 0 1874 | BLOCK_RECORD 1875 | 5 1876 | 76 1877 | 330 1878 | 1 1879 | 100 1880 | AcDbSymbolTableRecord 1881 | 100 1882 | AcDbBlockTableRecord 1883 | 2 1884 | block 11 1885 | 340 1886 | 0 1887 | 102 1888 | {BLKREFS 1889 | 331 1890 | 77 1891 | 102 1892 | } 1893 | 70 1894 | 0 1895 | 280 1896 | 1 1897 | 281 1898 | 0 1899 | 0 1900 | BLOCK_RECORD 1901 | 5 1902 | 7B 1903 | 330 1904 | 1 1905 | 100 1906 | AcDbSymbolTableRecord 1907 | 100 1908 | AcDbBlockTableRecord 1909 | 2 1910 | block 12 1911 | 340 1912 | 0 1913 | 102 1914 | {BLKREFS 1915 | 331 1916 | 7C 1917 | 102 1918 | } 1919 | 70 1920 | 0 1921 | 280 1922 | 1 1923 | 281 1924 | 0 1925 | 0 1926 | ENDTAB 1927 | 0 1928 | ENDSEC 1929 | 0 1930 | SECTION 1931 | 2 1932 | BLOCKS 1933 | 0 1934 | BLOCK 1935 | 5 1936 | 20 1937 | 330 1938 | 1F 1939 | 100 1940 | AcDbEntity 1941 | 8 1942 | 0 1943 | 100 1944 | AcDbBlockBegin 1945 | 2 1946 | *Model_Space 1947 | 70 1948 | 0 1949 | 10 1950 | 0.0 1951 | 20 1952 | 0.0 1953 | 30 1954 | 0.0 1955 | 3 1956 | *Model_Space 1957 | 1 1958 | 1959 | 0 1960 | ENDBLK 1961 | 5 1962 | 21 1963 | 330 1964 | 1F 1965 | 100 1966 | AcDbEntity 1967 | 8 1968 | 0 1969 | 100 1970 | AcDbBlockEnd 1971 | 0 1972 | BLOCK 1973 | 5 1974 | 1C 1975 | 330 1976 | 1B 1977 | 100 1978 | AcDbEntity 1979 | 67 1980 | 1 1981 | 8 1982 | 0 1983 | 100 1984 | AcDbBlockBegin 1985 | 2 1986 | *Paper_Space 1987 | 70 1988 | 0 1989 | 10 1990 | 0.0 1991 | 20 1992 | 0.0 1993 | 30 1994 | 0.0 1995 | 3 1996 | *Paper_Space 1997 | 1 1998 | 1999 | 0 2000 | ENDBLK 2001 | 5 2002 | 1D 2003 | 330 2004 | 1B 2005 | 100 2006 | AcDbEntity 2007 | 67 2008 | 1 2009 | 8 2010 | 0 2011 | 100 2012 | AcDbBlockEnd 2013 | 0 2014 | BLOCK 2015 | 5 2016 | 24 2017 | 330 2018 | 23 2019 | 100 2020 | AcDbEntity 2021 | 8 2022 | 0 2023 | 100 2024 | AcDbBlockBegin 2025 | 2 2026 | *Paper_Space0 2027 | 70 2028 | 0 2029 | 10 2030 | 0.0 2031 | 20 2032 | 0.0 2033 | 30 2034 | 0.0 2035 | 3 2036 | *Paper_Space0 2037 | 1 2038 | 2039 | 0 2040 | ENDBLK 2041 | 5 2042 | 25 2043 | 330 2044 | 23 2045 | 100 2046 | AcDbEntity 2047 | 8 2048 | 0 2049 | 100 2050 | AcDbBlockEnd 2051 | 0 2052 | BLOCK 2053 | 5 2054 | 42 2055 | 330 2056 | 40 2057 | 100 2058 | AcDbEntity 2059 | 8 2060 | 0 2061 | 100 2062 | AcDbBlockBegin 2063 | 2 2064 | block 2 2065 | 70 2066 | 0 2067 | 10 2068 | 0.0 2069 | 20 2070 | 0.0 2071 | 30 2072 | 0.0 2073 | 3 2074 | block 2 2075 | 1 2076 | 2077 | 0 2078 | SPLINE 2079 | 5 2080 | 44 2081 | 330 2082 | 40 2083 | 100 2084 | AcDbEntity 2085 | 8 2086 | 0 2087 | 62 2088 | 7 2089 | 420 2090 | 16777215 2091 | 370 2092 | 25 2093 | 100 2094 | AcDbSpline 2095 | 210 2096 | 0.0 2097 | 220 2098 | 0.0 2099 | 230 2100 | 1.0 2101 | 70 2102 | 8 2103 | 71 2104 | 3 2105 | 72 2106 | 8 2107 | 73 2108 | 4 2109 | 74 2110 | 0 2111 | 42 2112 | 0.0000000001 2113 | 43 2114 | 0.0000000001 2115 | 12 2116 | 1.0 2117 | 22 2118 | 0.0 2119 | 32 2120 | 0.0 2121 | 13 2122 | 1.0 2123 | 23 2124 | 0.0 2125 | 33 2126 | 0.0 2127 | 40 2128 | 0.0 2129 | 40 2130 | 0.0 2131 | 40 2132 | 0.0 2133 | 40 2134 | 0.0 2135 | 40 2136 | 1.0 2137 | 40 2138 | 1.0 2139 | 40 2140 | 1.0 2141 | 40 2142 | 1.0 2143 | 10 2144 | 7.800000000000004 2145 | 20 2146 | 7.699999999999995 2147 | 30 2148 | 0.0 2149 | 10 2150 | 7.800000000000004 2151 | 20 2152 | 7.865685424949232 2153 | 30 2154 | 0.0 2155 | 10 2156 | 7.665685424949237 2157 | 20 2158 | 8.0 2159 | 30 2160 | 0.0 2161 | 10 2162 | 7.5 2163 | 20 2164 | 8.0 2165 | 30 2166 | 0.0 2167 | 0 2168 | ENDBLK 2169 | 5 2170 | 43 2171 | 330 2172 | 40 2173 | 100 2174 | AcDbEntity 2175 | 8 2176 | 0 2177 | 100 2178 | AcDbBlockEnd 2179 | 0 2180 | BLOCK 2181 | 5 2182 | 47 2183 | 330 2184 | 45 2185 | 100 2186 | AcDbEntity 2187 | 8 2188 | 0 2189 | 100 2190 | AcDbBlockBegin 2191 | 2 2192 | block 3 2193 | 70 2194 | 0 2195 | 10 2196 | 0.0 2197 | 20 2198 | 0.0 2199 | 30 2200 | 0.0 2201 | 3 2202 | block 3 2203 | 1 2204 | 2205 | 0 2206 | POLYLINE 2207 | 5 2208 | 49 2209 | 330 2210 | 45 2211 | 100 2212 | AcDbEntity 2213 | 8 2214 | 0 2215 | 62 2216 | 7 2217 | 420 2218 | 16777215 2219 | 370 2220 | 25 2221 | 100 2222 | AcDb2dPolyline 2223 | 66 2224 | 1 2225 | 10 2226 | 0.0 2227 | 20 2228 | 0.0 2229 | 30 2230 | 0.0 2231 | 0 2232 | VERTEX 2233 | 5 2234 | 4A 2235 | 330 2236 | 49 2237 | 100 2238 | AcDbEntity 2239 | 8 2240 | 0 2241 | 62 2242 | 7 2243 | 420 2244 | 16777215 2245 | 370 2246 | 25 2247 | 100 2248 | AcDbVertex 2249 | 100 2250 | AcDb2dVertex 2251 | 10 2252 | 1.0 2253 | 20 2254 | 8.0 2255 | 30 2256 | 0.0 2257 | 0 2258 | VERTEX 2259 | 5 2260 | 4B 2261 | 330 2262 | 49 2263 | 100 2264 | AcDbEntity 2265 | 8 2266 | 0 2267 | 62 2268 | 7 2269 | 420 2270 | 16777215 2271 | 370 2272 | 25 2273 | 100 2274 | AcDbVertex 2275 | 100 2276 | AcDb2dVertex 2277 | 10 2278 | 7.5 2279 | 20 2280 | 8.0 2281 | 30 2282 | 0.0 2283 | 0 2284 | SEQEND 2285 | 5 2286 | 4C 2287 | 330 2288 | 49 2289 | 100 2290 | AcDbEntity 2291 | 8 2292 | 0 2293 | 62 2294 | 7 2295 | 420 2296 | 16777215 2297 | 370 2298 | 25 2299 | 0 2300 | ENDBLK 2301 | 5 2302 | 48 2303 | 330 2304 | 45 2305 | 100 2306 | AcDbEntity 2307 | 8 2308 | 0 2309 | 100 2310 | AcDbBlockEnd 2311 | 0 2312 | BLOCK 2313 | 5 2314 | 4F 2315 | 330 2316 | 4D 2317 | 100 2318 | AcDbEntity 2319 | 8 2320 | 0 2321 | 100 2322 | AcDbBlockBegin 2323 | 2 2324 | block 4 2325 | 70 2326 | 0 2327 | 10 2328 | 0.0 2329 | 20 2330 | 0.0 2331 | 30 2332 | 0.0 2333 | 3 2334 | block 4 2335 | 1 2336 | 2337 | 0 2338 | SPLINE 2339 | 5 2340 | 51 2341 | 330 2342 | 4D 2343 | 100 2344 | AcDbEntity 2345 | 8 2346 | 0 2347 | 62 2348 | 7 2349 | 420 2350 | 16777215 2351 | 370 2352 | 25 2353 | 100 2354 | AcDbSpline 2355 | 210 2356 | 0.0 2357 | 220 2358 | 0.0 2359 | 230 2360 | 1.0 2361 | 70 2362 | 8 2363 | 71 2364 | 3 2365 | 72 2366 | 8 2367 | 73 2368 | 4 2369 | 74 2370 | 0 2371 | 42 2372 | 0.0000000001 2373 | 43 2374 | 0.0000000001 2375 | 12 2376 | 1.0 2377 | 22 2378 | 0.0 2379 | 32 2380 | 0.0 2381 | 13 2382 | 1.0 2383 | 23 2384 | 0.0 2385 | 33 2386 | 0.0 2387 | 40 2388 | 0.0 2389 | 40 2390 | 0.0 2391 | 40 2392 | 0.0 2393 | 40 2394 | 0.0 2395 | 40 2396 | 1.0 2397 | 40 2398 | 1.0 2399 | 40 2400 | 1.0 2401 | 40 2402 | 1.0 2403 | 10 2404 | 1.0 2405 | 20 2406 | 8.0 2407 | 30 2408 | 0.0 2409 | 10 2410 | 0.8343145750507625 2411 | 20 2412 | 8.0 2413 | 30 2414 | 0.0 2415 | 10 2416 | 0.699999999999995 2417 | 20 2418 | 7.865685424949245 2419 | 30 2420 | 0.0 2421 | 10 2422 | 0.699999999999995 2423 | 20 2424 | 7.699999999999995 2425 | 30 2426 | 0.0 2427 | 0 2428 | ENDBLK 2429 | 5 2430 | 50 2431 | 330 2432 | 4D 2433 | 100 2434 | AcDbEntity 2435 | 8 2436 | 0 2437 | 100 2438 | AcDbBlockEnd 2439 | 0 2440 | BLOCK 2441 | 5 2442 | 54 2443 | 330 2444 | 52 2445 | 100 2446 | AcDbEntity 2447 | 8 2448 | 0 2449 | 100 2450 | AcDbBlockBegin 2451 | 2 2452 | block 5 2453 | 70 2454 | 0 2455 | 10 2456 | 0.0 2457 | 20 2458 | 0.0 2459 | 30 2460 | 0.0 2461 | 3 2462 | block 5 2463 | 1 2464 | 2465 | 0 2466 | SPLINE 2467 | 5 2468 | 56 2469 | 330 2470 | 52 2471 | 100 2472 | AcDbEntity 2473 | 8 2474 | 0 2475 | 62 2476 | 7 2477 | 420 2478 | 16777215 2479 | 370 2480 | 25 2481 | 100 2482 | AcDbSpline 2483 | 210 2484 | 0.0 2485 | 220 2486 | 0.0 2487 | 230 2488 | 1.0 2489 | 70 2490 | 11 2491 | 71 2492 | 3 2493 | 72 2494 | 20 2495 | 73 2496 | 16 2497 | 74 2498 | 0 2499 | 42 2500 | 0.0000000001 2501 | 43 2502 | 0.0000000001 2503 | 12 2504 | 1.0 2505 | 22 2506 | 0.0 2507 | 32 2508 | 0.0 2509 | 13 2510 | 1.0 2511 | 23 2512 | 0.0 2513 | 33 2514 | 0.0 2515 | 40 2516 | 0.0 2517 | 40 2518 | 0.0 2519 | 40 2520 | 0.0 2521 | 40 2522 | 0.0 2523 | 40 2524 | 1.0 2525 | 40 2526 | 1.0 2527 | 40 2528 | 1.0 2529 | 40 2530 | 2.0 2531 | 40 2532 | 2.0 2533 | 40 2534 | 2.0 2535 | 40 2536 | 3.0 2537 | 40 2538 | 3.0 2539 | 40 2540 | 3.0 2541 | 40 2542 | 4.0 2543 | 40 2544 | 4.0 2545 | 40 2546 | 4.0 2547 | 40 2548 | 5.0 2549 | 40 2550 | 5.0 2551 | 40 2552 | 5.0 2553 | 40 2554 | 5.0 2555 | 10 2556 | 0.921875 2557 | 20 2558 | 7.699999999999995 2559 | 30 2560 | 0.0 2561 | 10 2562 | 0.921875 2563 | 20 2564 | 7.743147246080525 2565 | 30 2566 | 0.0 2567 | 10 2568 | 0.9568527539194696 2569 | 20 2570 | 7.778124999999995 2571 | 30 2572 | 0.0 2573 | 10 2574 | 1.0 2575 | 20 2576 | 7.778124999999995 2577 | 30 2578 | 0.0 2579 | 10 2580 | 1.04314724608053 2581 | 20 2582 | 7.778124999999995 2583 | 30 2584 | 0.0 2585 | 10 2586 | 1.078125 2587 | 20 2588 | 7.743147246080525 2589 | 30 2590 | 0.0 2591 | 10 2592 | 1.078125 2593 | 20 2594 | 7.699999999999995 2595 | 30 2596 | 0.0 2597 | 10 2598 | 1.078125 2599 | 20 2600 | 7.656852753919464 2601 | 30 2602 | 0.0 2603 | 10 2604 | 1.04314724608053 2605 | 20 2606 | 7.621874999999995 2607 | 30 2608 | 0.0 2609 | 10 2610 | 1.0 2611 | 20 2612 | 7.621874999999995 2613 | 30 2614 | 0.0 2615 | 10 2616 | 0.9568527539194696 2617 | 20 2618 | 7.621874999999995 2619 | 30 2620 | 0.0 2621 | 10 2622 | 0.921875 2623 | 20 2624 | 7.656852753919464 2625 | 30 2626 | 0.0 2627 | 10 2628 | 0.921875 2629 | 20 2630 | 7.699999999999995 2631 | 30 2632 | 0.0 2633 | 10 2634 | 0.921875 2635 | 20 2636 | 7.699999999999995 2637 | 30 2638 | 0.0 2639 | 10 2640 | 0.921875 2641 | 20 2642 | 7.699999999999995 2643 | 30 2644 | 0.0 2645 | 10 2646 | 0.921875 2647 | 20 2648 | 7.699999999999995 2649 | 30 2650 | 0.0 2651 | 0 2652 | ENDBLK 2653 | 5 2654 | 55 2655 | 330 2656 | 52 2657 | 100 2658 | AcDbEntity 2659 | 8 2660 | 0 2661 | 100 2662 | AcDbBlockEnd 2663 | 0 2664 | BLOCK 2665 | 5 2666 | 59 2667 | 330 2668 | 57 2669 | 100 2670 | AcDbEntity 2671 | 8 2672 | 0 2673 | 100 2674 | AcDbBlockBegin 2675 | 2 2676 | block 6 2677 | 70 2678 | 0 2679 | 10 2680 | 0.0 2681 | 20 2682 | 0.0 2683 | 30 2684 | 0.0 2685 | 3 2686 | block 6 2687 | 1 2688 | 2689 | 0 2690 | SPLINE 2691 | 5 2692 | 5B 2693 | 330 2694 | 57 2695 | 100 2696 | AcDbEntity 2697 | 8 2698 | 0 2699 | 62 2700 | 7 2701 | 420 2702 | 16777215 2703 | 370 2704 | 25 2705 | 100 2706 | AcDbSpline 2707 | 210 2708 | 0.0 2709 | 220 2710 | 0.0 2711 | 230 2712 | 1.0 2713 | 70 2714 | 11 2715 | 71 2716 | 3 2717 | 72 2718 | 20 2719 | 73 2720 | 16 2721 | 74 2722 | 0 2723 | 42 2724 | 0.0000000001 2725 | 43 2726 | 0.0000000001 2727 | 12 2728 | 1.0 2729 | 22 2730 | 0.0 2731 | 32 2732 | 0.0 2733 | 13 2734 | 1.0 2735 | 23 2736 | 0.0 2737 | 33 2738 | 0.0 2739 | 40 2740 | 0.0 2741 | 40 2742 | 0.0 2743 | 40 2744 | 0.0 2745 | 40 2746 | 0.0 2747 | 40 2748 | 1.0 2749 | 40 2750 | 1.0 2751 | 40 2752 | 1.0 2753 | 40 2754 | 2.0 2755 | 40 2756 | 2.0 2757 | 40 2758 | 2.0 2759 | 40 2760 | 3.0 2761 | 40 2762 | 3.0 2763 | 40 2764 | 3.0 2765 | 40 2766 | 4.0 2767 | 40 2768 | 4.0 2769 | 40 2770 | 4.0 2771 | 40 2772 | 5.0 2773 | 40 2774 | 5.0 2775 | 40 2776 | 5.0 2777 | 40 2778 | 5.0 2779 | 10 2780 | 7.421875 2781 | 20 2782 | 7.699999999999995 2783 | 30 2784 | 0.0 2785 | 10 2786 | 7.421875 2787 | 20 2788 | 7.743147246080525 2789 | 30 2790 | 0.0 2791 | 10 2792 | 7.45685275391947 2793 | 20 2794 | 7.778124999999995 2795 | 30 2796 | 0.0 2797 | 10 2798 | 7.5 2799 | 20 2800 | 7.778124999999995 2801 | 30 2802 | 0.0 2803 | 10 2804 | 7.54314724608053 2805 | 20 2806 | 7.778124999999995 2807 | 30 2808 | 0.0 2809 | 10 2810 | 7.578125 2811 | 20 2812 | 7.743147246080525 2813 | 30 2814 | 0.0 2815 | 10 2816 | 7.578125 2817 | 20 2818 | 7.699999999999995 2819 | 30 2820 | 0.0 2821 | 10 2822 | 7.578125 2823 | 20 2824 | 7.656852753919464 2825 | 30 2826 | 0.0 2827 | 10 2828 | 7.54314724608053 2829 | 20 2830 | 7.621874999999995 2831 | 30 2832 | 0.0 2833 | 10 2834 | 7.5 2835 | 20 2836 | 7.621874999999995 2837 | 30 2838 | 0.0 2839 | 10 2840 | 7.45685275391947 2841 | 20 2842 | 7.621874999999995 2843 | 30 2844 | 0.0 2845 | 10 2846 | 7.421875 2847 | 20 2848 | 7.656852753919464 2849 | 30 2850 | 0.0 2851 | 10 2852 | 7.421875 2853 | 20 2854 | 7.699999999999995 2855 | 30 2856 | 0.0 2857 | 10 2858 | 7.421875 2859 | 20 2860 | 7.699999999999995 2861 | 30 2862 | 0.0 2863 | 10 2864 | 7.421875 2865 | 20 2866 | 7.699999999999995 2867 | 30 2868 | 0.0 2869 | 10 2870 | 7.421875 2871 | 20 2872 | 7.699999999999995 2873 | 30 2874 | 0.0 2875 | 0 2876 | ENDBLK 2877 | 5 2878 | 5A 2879 | 330 2880 | 57 2881 | 100 2882 | AcDbEntity 2883 | 8 2884 | 0 2885 | 100 2886 | AcDbBlockEnd 2887 | 0 2888 | BLOCK 2889 | 5 2890 | 5E 2891 | 330 2892 | 5C 2893 | 100 2894 | AcDbEntity 2895 | 8 2896 | 0 2897 | 100 2898 | AcDbBlockBegin 2899 | 2 2900 | block 7 2901 | 70 2902 | 0 2903 | 10 2904 | 0.0 2905 | 20 2906 | 0.0 2907 | 30 2908 | 0.0 2909 | 3 2910 | block 7 2911 | 1 2912 | 2913 | 0 2914 | SPLINE 2915 | 5 2916 | 60 2917 | 330 2918 | 5C 2919 | 100 2920 | AcDbEntity 2921 | 8 2922 | 0 2923 | 62 2924 | 7 2925 | 420 2926 | 16777215 2927 | 370 2928 | 25 2929 | 100 2930 | AcDbSpline 2931 | 210 2932 | 0.0 2933 | 220 2934 | 0.0 2935 | 230 2936 | 1.0 2937 | 70 2938 | 11 2939 | 71 2940 | 3 2941 | 72 2942 | 20 2943 | 73 2944 | 16 2945 | 74 2946 | 0 2947 | 42 2948 | 0.0000000001 2949 | 43 2950 | 0.0000000001 2951 | 12 2952 | 1.0 2953 | 22 2954 | 0.0 2955 | 32 2956 | 0.0 2957 | 13 2958 | 1.0 2959 | 23 2960 | 0.0 2961 | 33 2962 | 0.0 2963 | 40 2964 | 0.0 2965 | 40 2966 | 0.0 2967 | 40 2968 | 0.0 2969 | 40 2970 | 0.0 2971 | 40 2972 | 1.0 2973 | 40 2974 | 1.0 2975 | 40 2976 | 1.0 2977 | 40 2978 | 2.0 2979 | 40 2980 | 2.0 2981 | 40 2982 | 2.0 2983 | 40 2984 | 3.0 2985 | 40 2986 | 3.0 2987 | 40 2988 | 3.0 2989 | 40 2990 | 4.0 2991 | 40 2992 | 4.0 2993 | 40 2994 | 4.0 2995 | 40 2996 | 5.0 2997 | 40 2998 | 5.0 2999 | 40 3000 | 5.0 3001 | 40 3002 | 5.0 3003 | 10 3004 | 2.93 3005 | 20 3006 | 3.300000000000005 3007 | 30 3008 | 0.0 3009 | 10 3010 | 2.93 3011 | 20 3012 | 3.343147246080535 3013 | 30 3014 | 0.0 3015 | 10 3016 | 2.96497775391947 3017 | 20 3018 | 3.378125000000005 3019 | 30 3020 | 0.0 3021 | 10 3022 | 3.008125 3023 | 20 3024 | 3.378125000000005 3025 | 30 3026 | 0.0 3027 | 10 3028 | 3.051272246080531 3029 | 20 3030 | 3.378125000000005 3031 | 30 3032 | 0.0 3033 | 10 3034 | 3.08625 3035 | 20 3036 | 3.343147246080535 3037 | 30 3038 | 0.0 3039 | 10 3040 | 3.08625 3041 | 20 3042 | 3.300000000000005 3043 | 30 3044 | 0.0 3045 | 10 3046 | 3.08625 3047 | 20 3048 | 3.256852753919475 3049 | 30 3050 | 0.0 3051 | 10 3052 | 3.051272246080531 3053 | 20 3054 | 3.221875000000005 3055 | 30 3056 | 0.0 3057 | 10 3058 | 3.008125 3059 | 20 3060 | 3.221875000000005 3061 | 30 3062 | 0.0 3063 | 10 3064 | 2.96497775391947 3065 | 20 3066 | 3.221875000000005 3067 | 30 3068 | 0.0 3069 | 10 3070 | 2.93 3071 | 20 3072 | 3.256852753919475 3073 | 30 3074 | 0.0 3075 | 10 3076 | 2.93 3077 | 20 3078 | 3.300000000000005 3079 | 30 3080 | 0.0 3081 | 10 3082 | 2.93 3083 | 20 3084 | 3.300000000000005 3085 | 30 3086 | 0.0 3087 | 10 3088 | 2.93 3089 | 20 3090 | 3.300000000000005 3091 | 30 3092 | 0.0 3093 | 10 3094 | 2.93 3095 | 20 3096 | 3.300000000000005 3097 | 30 3098 | 0.0 3099 | 0 3100 | ENDBLK 3101 | 5 3102 | 5F 3103 | 330 3104 | 5C 3105 | 100 3106 | AcDbEntity 3107 | 8 3108 | 0 3109 | 100 3110 | AcDbBlockEnd 3111 | 0 3112 | BLOCK 3113 | 5 3114 | 63 3115 | 330 3116 | 61 3117 | 100 3118 | AcDbEntity 3119 | 8 3120 | 0 3121 | 100 3122 | AcDbBlockBegin 3123 | 2 3124 | block 8 3125 | 70 3126 | 0 3127 | 10 3128 | 0.0 3129 | 20 3130 | 0.0 3131 | 30 3132 | 0.0 3133 | 3 3134 | block 8 3135 | 1 3136 | 3137 | 0 3138 | POLYLINE 3139 | 5 3140 | 65 3141 | 330 3142 | 61 3143 | 100 3144 | AcDbEntity 3145 | 8 3146 | 0 3147 | 62 3148 | 7 3149 | 420 3150 | 16777215 3151 | 370 3152 | 25 3153 | 100 3154 | AcDb2dPolyline 3155 | 66 3156 | 1 3157 | 10 3158 | 0.0 3159 | 20 3160 | 0.0 3161 | 30 3162 | 0.0 3163 | 0 3164 | VERTEX 3165 | 5 3166 | 66 3167 | 330 3168 | 65 3169 | 100 3170 | AcDbEntity 3171 | 8 3172 | 0 3173 | 62 3174 | 7 3175 | 420 3176 | 16777215 3177 | 370 3178 | 25 3179 | 100 3180 | AcDbVertex 3181 | 100 3182 | AcDb2dVertex 3183 | 10 3184 | 7.800000000000004 3185 | 20 3186 | 7.699999999999995 3187 | 30 3188 | 0.0 3189 | 0 3190 | VERTEX 3191 | 5 3192 | 67 3193 | 330 3194 | 65 3195 | 100 3196 | AcDbEntity 3197 | 8 3198 | 0 3199 | 62 3200 | 7 3201 | 420 3202 | 16777215 3203 | 370 3204 | 25 3205 | 100 3206 | AcDbVertex 3207 | 100 3208 | AcDb2dVertex 3209 | 10 3210 | 7.800000000000004 3211 | 20 3212 | 3.300000000000005 3213 | 30 3214 | 0.0 3215 | 0 3216 | SEQEND 3217 | 5 3218 | 68 3219 | 330 3220 | 65 3221 | 100 3222 | AcDbEntity 3223 | 8 3224 | 0 3225 | 62 3226 | 7 3227 | 420 3228 | 16777215 3229 | 370 3230 | 25 3231 | 0 3232 | ENDBLK 3233 | 5 3234 | 64 3235 | 330 3236 | 61 3237 | 100 3238 | AcDbEntity 3239 | 8 3240 | 0 3241 | 100 3242 | AcDbBlockEnd 3243 | 0 3244 | BLOCK 3245 | 5 3246 | 6B 3247 | 330 3248 | 69 3249 | 100 3250 | AcDbEntity 3251 | 8 3252 | 0 3253 | 100 3254 | AcDbBlockBegin 3255 | 2 3256 | block 9 3257 | 70 3258 | 0 3259 | 10 3260 | 0.0 3261 | 20 3262 | 0.0 3263 | 30 3264 | 0.0 3265 | 3 3266 | block 9 3267 | 1 3268 | 3269 | 0 3270 | POLYLINE 3271 | 5 3272 | 6D 3273 | 330 3274 | 69 3275 | 100 3276 | AcDbEntity 3277 | 8 3278 | 0 3279 | 62 3280 | 7 3281 | 420 3282 | 16777215 3283 | 370 3284 | 25 3285 | 100 3286 | AcDb2dPolyline 3287 | 66 3288 | 1 3289 | 10 3290 | 0.0 3291 | 20 3292 | 0.0 3293 | 30 3294 | 0.0 3295 | 0 3296 | VERTEX 3297 | 5 3298 | 6E 3299 | 330 3300 | 6D 3301 | 100 3302 | AcDbEntity 3303 | 8 3304 | 0 3305 | 62 3306 | 7 3307 | 420 3308 | 16777215 3309 | 370 3310 | 25 3311 | 100 3312 | AcDbVertex 3313 | 100 3314 | AcDb2dVertex 3315 | 10 3316 | 0.699999999999995 3317 | 20 3318 | 3.300000000000005 3319 | 30 3320 | 0.0 3321 | 0 3322 | VERTEX 3323 | 5 3324 | 6F 3325 | 330 3326 | 6D 3327 | 100 3328 | AcDbEntity 3329 | 8 3330 | 0 3331 | 62 3332 | 7 3333 | 420 3334 | 16777215 3335 | 370 3336 | 25 3337 | 100 3338 | AcDbVertex 3339 | 100 3340 | AcDb2dVertex 3341 | 10 3342 | 0.699999999999995 3343 | 20 3344 | 7.699999999999995 3345 | 30 3346 | 0.0 3347 | 0 3348 | SEQEND 3349 | 5 3350 | 70 3351 | 330 3352 | 6D 3353 | 100 3354 | AcDbEntity 3355 | 8 3356 | 0 3357 | 62 3358 | 7 3359 | 420 3360 | 16777215 3361 | 370 3362 | 25 3363 | 0 3364 | ENDBLK 3365 | 5 3366 | 6C 3367 | 330 3368 | 69 3369 | 100 3370 | AcDbEntity 3371 | 8 3372 | 0 3373 | 100 3374 | AcDbBlockEnd 3375 | 0 3376 | BLOCK 3377 | 5 3378 | 73 3379 | 330 3380 | 71 3381 | 100 3382 | AcDbEntity 3383 | 8 3384 | 0 3385 | 100 3386 | AcDbBlockBegin 3387 | 2 3388 | block 10 3389 | 70 3390 | 0 3391 | 10 3392 | 0.0 3393 | 20 3394 | 0.0 3395 | 30 3396 | 0.0 3397 | 3 3398 | block 10 3399 | 1 3400 | 3401 | 0 3402 | SPLINE 3403 | 5 3404 | 75 3405 | 330 3406 | 71 3407 | 100 3408 | AcDbEntity 3409 | 8 3410 | 0 3411 | 62 3412 | 7 3413 | 420 3414 | 16777215 3415 | 370 3416 | 25 3417 | 100 3418 | AcDbSpline 3419 | 210 3420 | 0.0 3421 | 220 3422 | 0.0 3423 | 230 3424 | 1.0 3425 | 70 3426 | 8 3427 | 71 3428 | 3 3429 | 72 3430 | 8 3431 | 73 3432 | 4 3433 | 74 3434 | 0 3435 | 42 3436 | 0.0000000001 3437 | 43 3438 | 0.0000000001 3439 | 12 3440 | 1.0 3441 | 22 3442 | 0.0 3443 | 32 3444 | 0.0 3445 | 13 3446 | 1.0 3447 | 23 3448 | 0.0 3449 | 33 3450 | 0.0 3451 | 40 3452 | 0.0 3453 | 40 3454 | 0.0 3455 | 40 3456 | 0.0 3457 | 40 3458 | 0.0 3459 | 40 3460 | 1.0 3461 | 40 3462 | 1.0 3463 | 40 3464 | 1.0 3465 | 40 3466 | 1.0 3467 | 10 3468 | 0.699999999999995 3469 | 20 3470 | 3.300000000000005 3471 | 30 3472 | 0.0 3473 | 10 3474 | 0.699999999999995 3475 | 20 3476 | 3.134314575050767 3477 | 30 3478 | 0.0 3479 | 10 3480 | 0.8343145750507625 3481 | 20 3482 | 3.0 3483 | 30 3484 | 0.0 3485 | 10 3486 | 1.0 3487 | 20 3488 | 3.0 3489 | 30 3490 | 0.0 3491 | 0 3492 | ENDBLK 3493 | 5 3494 | 74 3495 | 330 3496 | 71 3497 | 100 3498 | AcDbEntity 3499 | 8 3500 | 0 3501 | 100 3502 | AcDbBlockEnd 3503 | 0 3504 | BLOCK 3505 | 5 3506 | 78 3507 | 330 3508 | 76 3509 | 100 3510 | AcDbEntity 3511 | 8 3512 | 0 3513 | 100 3514 | AcDbBlockBegin 3515 | 2 3516 | block 11 3517 | 70 3518 | 0 3519 | 10 3520 | 0.0 3521 | 20 3522 | 0.0 3523 | 30 3524 | 0.0 3525 | 3 3526 | block 11 3527 | 1 3528 | 3529 | 0 3530 | SPLINE 3531 | 5 3532 | 7A 3533 | 330 3534 | 76 3535 | 100 3536 | AcDbEntity 3537 | 8 3538 | 0 3539 | 62 3540 | 7 3541 | 420 3542 | 16777215 3543 | 370 3544 | 25 3545 | 100 3546 | AcDbSpline 3547 | 210 3548 | 0.0 3549 | 220 3550 | 0.0 3551 | 230 3552 | 1.0 3553 | 70 3554 | 8 3555 | 71 3556 | 3 3557 | 72 3558 | 8 3559 | 73 3560 | 4 3561 | 74 3562 | 0 3563 | 42 3564 | 0.0000000001 3565 | 43 3566 | 0.0000000001 3567 | 12 3568 | 1.0 3569 | 22 3570 | 0.0 3571 | 32 3572 | 0.0 3573 | 13 3574 | 1.0 3575 | 23 3576 | 0.0 3577 | 33 3578 | 0.0 3579 | 40 3580 | 0.0 3581 | 40 3582 | 0.0 3583 | 40 3584 | 0.0 3585 | 40 3586 | 0.0 3587 | 40 3588 | 1.0 3589 | 40 3590 | 1.0 3591 | 40 3592 | 1.0 3593 | 40 3594 | 1.0 3595 | 10 3596 | 7.5 3597 | 20 3598 | 3.0 3599 | 30 3600 | 0.0 3601 | 10 3602 | 7.665685424949237 3603 | 20 3604 | 3.0 3605 | 30 3606 | 0.0 3607 | 10 3608 | 7.800000000000004 3609 | 20 3610 | 3.134314575050767 3611 | 30 3612 | 0.0 3613 | 10 3614 | 7.800000000000004 3615 | 20 3616 | 3.300000000000005 3617 | 30 3618 | 0.0 3619 | 0 3620 | ENDBLK 3621 | 5 3622 | 79 3623 | 330 3624 | 76 3625 | 100 3626 | AcDbEntity 3627 | 8 3628 | 0 3629 | 100 3630 | AcDbBlockEnd 3631 | 0 3632 | BLOCK 3633 | 5 3634 | 7D 3635 | 330 3636 | 7B 3637 | 100 3638 | AcDbEntity 3639 | 8 3640 | 0 3641 | 100 3642 | AcDbBlockBegin 3643 | 2 3644 | block 12 3645 | 70 3646 | 0 3647 | 10 3648 | 0.0 3649 | 20 3650 | 0.0 3651 | 30 3652 | 0.0 3653 | 3 3654 | block 12 3655 | 1 3656 | 3657 | 0 3658 | POLYLINE 3659 | 5 3660 | 7F 3661 | 330 3662 | 7B 3663 | 100 3664 | AcDbEntity 3665 | 8 3666 | 0 3667 | 62 3668 | 7 3669 | 420 3670 | 16777215 3671 | 370 3672 | 25 3673 | 100 3674 | AcDb2dPolyline 3675 | 66 3676 | 1 3677 | 10 3678 | 0.0 3679 | 20 3680 | 0.0 3681 | 30 3682 | 0.0 3683 | 0 3684 | VERTEX 3685 | 5 3686 | 80 3687 | 330 3688 | 7F 3689 | 100 3690 | AcDbEntity 3691 | 8 3692 | 0 3693 | 62 3694 | 7 3695 | 420 3696 | 16777215 3697 | 370 3698 | 25 3699 | 100 3700 | AcDbVertex 3701 | 100 3702 | AcDb2dVertex 3703 | 10 3704 | 7.5 3705 | 20 3706 | 3.0 3707 | 30 3708 | 0.0 3709 | 0 3710 | VERTEX 3711 | 5 3712 | 81 3713 | 330 3714 | 7F 3715 | 100 3716 | AcDbEntity 3717 | 8 3718 | 0 3719 | 62 3720 | 7 3721 | 420 3722 | 16777215 3723 | 370 3724 | 25 3725 | 100 3726 | AcDbVertex 3727 | 100 3728 | AcDb2dVertex 3729 | 10 3730 | 1.0 3731 | 20 3732 | 3.0 3733 | 30 3734 | 0.0 3735 | 0 3736 | SEQEND 3737 | 5 3738 | 82 3739 | 330 3740 | 7F 3741 | 100 3742 | AcDbEntity 3743 | 8 3744 | 0 3745 | 62 3746 | 7 3747 | 420 3748 | 16777215 3749 | 370 3750 | 25 3751 | 0 3752 | ENDBLK 3753 | 5 3754 | 7E 3755 | 330 3756 | 7B 3757 | 100 3758 | AcDbEntity 3759 | 8 3760 | 0 3761 | 100 3762 | AcDbBlockEnd 3763 | 0 3764 | ENDSEC 3765 | 0 3766 | SECTION 3767 | 2 3768 | ENTITIES 3769 | 0 3770 | INSERT 3771 | 5 3772 | 41 3773 | 330 3774 | 1F 3775 | 100 3776 | AcDbEntity 3777 | 8 3778 | 0 3779 | 100 3780 | AcDbBlockReference 3781 | 2 3782 | block 2 3783 | 10 3784 | 0.0 3785 | 20 3786 | 0.0 3787 | 30 3788 | 0.0 3789 | 0 3790 | INSERT 3791 | 5 3792 | 46 3793 | 330 3794 | 1F 3795 | 100 3796 | AcDbEntity 3797 | 8 3798 | 0 3799 | 100 3800 | AcDbBlockReference 3801 | 2 3802 | block 3 3803 | 10 3804 | 0.0 3805 | 20 3806 | 0.0 3807 | 30 3808 | 0.0 3809 | 0 3810 | INSERT 3811 | 5 3812 | 4E 3813 | 330 3814 | 1F 3815 | 100 3816 | AcDbEntity 3817 | 8 3818 | 0 3819 | 100 3820 | AcDbBlockReference 3821 | 2 3822 | block 4 3823 | 10 3824 | 0.0 3825 | 20 3826 | 0.0 3827 | 30 3828 | 0.0 3829 | 0 3830 | INSERT 3831 | 5 3832 | 53 3833 | 330 3834 | 1F 3835 | 100 3836 | AcDbEntity 3837 | 8 3838 | 0 3839 | 100 3840 | AcDbBlockReference 3841 | 2 3842 | block 5 3843 | 10 3844 | 0.0 3845 | 20 3846 | 0.0 3847 | 30 3848 | 0.0 3849 | 0 3850 | INSERT 3851 | 5 3852 | 58 3853 | 330 3854 | 1F 3855 | 100 3856 | AcDbEntity 3857 | 8 3858 | 0 3859 | 100 3860 | AcDbBlockReference 3861 | 2 3862 | block 6 3863 | 10 3864 | 0.0 3865 | 20 3866 | 0.0 3867 | 30 3868 | 0.0 3869 | 0 3870 | INSERT 3871 | 5 3872 | 5D 3873 | 330 3874 | 1F 3875 | 100 3876 | AcDbEntity 3877 | 8 3878 | 0 3879 | 100 3880 | AcDbBlockReference 3881 | 2 3882 | block 7 3883 | 10 3884 | 0.0 3885 | 20 3886 | 0.0 3887 | 30 3888 | 0.0 3889 | 0 3890 | INSERT 3891 | 5 3892 | 62 3893 | 330 3894 | 1F 3895 | 100 3896 | AcDbEntity 3897 | 8 3898 | 0 3899 | 100 3900 | AcDbBlockReference 3901 | 2 3902 | block 8 3903 | 10 3904 | 0.0 3905 | 20 3906 | 0.0 3907 | 30 3908 | 0.0 3909 | 0 3910 | INSERT 3911 | 5 3912 | 6A 3913 | 330 3914 | 1F 3915 | 100 3916 | AcDbEntity 3917 | 8 3918 | 0 3919 | 100 3920 | AcDbBlockReference 3921 | 2 3922 | block 9 3923 | 10 3924 | 0.0 3925 | 20 3926 | 0.0 3927 | 30 3928 | 0.0 3929 | 0 3930 | INSERT 3931 | 5 3932 | 72 3933 | 330 3934 | 1F 3935 | 100 3936 | AcDbEntity 3937 | 8 3938 | 0 3939 | 100 3940 | AcDbBlockReference 3941 | 2 3942 | block 10 3943 | 10 3944 | 0.0 3945 | 20 3946 | 0.0 3947 | 30 3948 | 0.0 3949 | 0 3950 | INSERT 3951 | 5 3952 | 77 3953 | 330 3954 | 1F 3955 | 100 3956 | AcDbEntity 3957 | 8 3958 | 0 3959 | 100 3960 | AcDbBlockReference 3961 | 2 3962 | block 11 3963 | 10 3964 | 0.0 3965 | 20 3966 | 0.0 3967 | 30 3968 | 0.0 3969 | 0 3970 | INSERT 3971 | 5 3972 | 7C 3973 | 330 3974 | 1F 3975 | 100 3976 | AcDbEntity 3977 | 8 3978 | 0 3979 | 100 3980 | AcDbBlockReference 3981 | 2 3982 | block 12 3983 | 10 3984 | 0.0 3985 | 20 3986 | 0.0 3987 | 30 3988 | 0.0 3989 | 0 3990 | ENDSEC 3991 | 0 3992 | SECTION 3993 | 2 3994 | OBJECTS 3995 | 0 3996 | DICTIONARY 3997 | 5 3998 | C 3999 | 330 4000 | 0 4001 | 100 4002 | AcDbDictionary 4003 | 281 4004 | 1 4005 | 3 4006 | ACAD_GROUP 4007 | 350 4008 | D 4009 | 3 4010 | ACAD_LAYOUT 4011 | 350 4012 | 1A 4013 | 3 4014 | ACAD_MATERIAL 4015 | 350 4016 | 3B 4017 | 3 4018 | ACAD_MLEADERSTYLE 4019 | 350 4020 | 84 4021 | 3 4022 | ACAD_MLINESTYLE 4023 | 350 4024 | 17 4025 | 3 4026 | ACAD_PLOTSETTINGS 4027 | 350 4028 | 19 4029 | 3 4030 | ACAD_PLOTSTYLENAME 4031 | 350 4032 | E 4033 | 3 4034 | ACAD_TABLESTYLE 4035 | 350 4036 | 83 4037 | 3 4038 | ACAD_VISUALSTYLE 4039 | 350 4040 | 2A 4041 | 0 4042 | SUN 4043 | 5 4044 | 3F 4045 | 330 4046 | 29 4047 | 100 4048 | AcDbSun 4049 | 90 4050 | 1 4051 | 290 4052 | 0 4053 | 63 4054 | 7 4055 | 421 4056 | 16777215 4057 | 40 4058 | 1.0 4059 | 291 4060 | 1 4061 | 91 4062 | 2455826 4063 | 92 4064 | 54000000 4065 | 292 4066 | 0 4067 | 70 4068 | 2 4069 | 71 4070 | 256 4071 | 280 4072 | 1 4073 | 0 4074 | DICTIONARY 4075 | 5 4076 | D 4077 | 102 4078 | {ACAD_REACTORS 4079 | 330 4080 | C 4081 | 102 4082 | } 4083 | 330 4084 | C 4085 | 100 4086 | AcDbDictionary 4087 | 281 4088 | 1 4089 | 0 4090 | DICTIONARY 4091 | 5 4092 | 1A 4093 | 102 4094 | {ACAD_REACTORS 4095 | 330 4096 | C 4097 | 102 4098 | } 4099 | 330 4100 | C 4101 | 100 4102 | AcDbDictionary 4103 | 281 4104 | 1 4105 | 3 4106 | Layout1 4107 | 350 4108 | 1E 4109 | 3 4110 | Layout2 4111 | 350 4112 | 26 4113 | 3 4114 | Model 4115 | 350 4116 | 22 4117 | 0 4118 | DICTIONARY 4119 | 5 4120 | 3B 4121 | 102 4122 | {ACAD_REACTORS 4123 | 330 4124 | C 4125 | 102 4126 | } 4127 | 330 4128 | C 4129 | 100 4130 | AcDbDictionary 4131 | 281 4132 | 1 4133 | 3 4134 | ByBlock 4135 | 350 4136 | 3D 4137 | 3 4138 | ByLayer 4139 | 350 4140 | 3C 4141 | 3 4142 | Global 4143 | 350 4144 | 3E 4145 | 0 4146 | DICTIONARY 4147 | 5 4148 | 84 4149 | 102 4150 | {ACAD_REACTORS 4151 | 330 4152 | C 4153 | 102 4154 | } 4155 | 330 4156 | C 4157 | 100 4158 | AcDbDictionary 4159 | 281 4160 | 1 4161 | 0 4162 | DICTIONARY 4163 | 5 4164 | 17 4165 | 102 4166 | {ACAD_REACTORS 4167 | 330 4168 | C 4169 | 102 4170 | } 4171 | 330 4172 | C 4173 | 100 4174 | AcDbDictionary 4175 | 281 4176 | 1 4177 | 3 4178 | Standard 4179 | 350 4180 | 18 4181 | 0 4182 | DICTIONARY 4183 | 5 4184 | 19 4185 | 102 4186 | {ACAD_REACTORS 4187 | 330 4188 | C 4189 | 102 4190 | } 4191 | 330 4192 | C 4193 | 100 4194 | AcDbDictionary 4195 | 281 4196 | 1 4197 | 0 4198 | ACDBDICTIONARYWDFLT 4199 | 5 4200 | E 4201 | 102 4202 | {ACAD_REACTORS 4203 | 330 4204 | C 4205 | 102 4206 | } 4207 | 330 4208 | C 4209 | 100 4210 | AcDbDictionary 4211 | 281 4212 | 1 4213 | 3 4214 | Normal 4215 | 350 4216 | F 4217 | 100 4218 | AcDbDictionaryWithDefault 4219 | 340 4220 | F 4221 | 0 4222 | DICTIONARY 4223 | 5 4224 | 83 4225 | 102 4226 | {ACAD_REACTORS 4227 | 330 4228 | C 4229 | 102 4230 | } 4231 | 330 4232 | C 4233 | 100 4234 | AcDbDictionary 4235 | 281 4236 | 1 4237 | 0 4238 | DICTIONARY 4239 | 5 4240 | 2A 4241 | 102 4242 | {ACAD_REACTORS 4243 | 330 4244 | C 4245 | 102 4246 | } 4247 | 330 4248 | C 4249 | 100 4250 | AcDbDictionary 4251 | 281 4252 | 1 4253 | 3 4254 | 2dWireframe 4255 | 350 4256 | 2F 4257 | 3 4258 | 3D Hidden 4259 | 350 4260 | 31 4261 | 3 4262 | 3dWireframe 4263 | 350 4264 | 30 4265 | 3 4266 | Basic 4267 | 350 4268 | 32 4269 | 3 4270 | Brighten 4271 | 350 4272 | 36 4273 | 3 4274 | ColorChange 4275 | 350 4276 | 3A 4277 | 3 4278 | Conceptual 4279 | 350 4280 | 34 4281 | 3 4282 | Dim 4283 | 350 4284 | 35 4285 | 3 4286 | Facepattern 4287 | 350 4288 | 39 4289 | 3 4290 | Flat 4291 | 350 4292 | 2B 4293 | 3 4294 | FlatWithEdges 4295 | 350 4296 | 2C 4297 | 3 4298 | Gouraud 4299 | 350 4300 | 2D 4301 | 3 4302 | GouraudWithEdges 4303 | 350 4304 | 2E 4305 | 3 4306 | Linepattern 4307 | 350 4308 | 38 4309 | 3 4310 | Realistic 4311 | 350 4312 | 33 4313 | 3 4314 | Thicken 4315 | 350 4316 | 37 4317 | 0 4318 | LAYOUT 4319 | 5 4320 | 1E 4321 | 102 4322 | {ACAD_REACTORS 4323 | 330 4324 | 1A 4325 | 102 4326 | } 4327 | 330 4328 | 1A 4329 | 100 4330 | AcDbPlotSettings 4331 | 1 4332 | 4333 | 2 4334 | none_device 4335 | 4 4336 | 4337 | 6 4338 | 4339 | 40 4340 | 0.0 4341 | 41 4342 | 0.0 4343 | 42 4344 | 0.0 4345 | 43 4346 | 0.0 4347 | 44 4348 | 0.0 4349 | 45 4350 | 0.0 4351 | 46 4352 | 0.0 4353 | 47 4354 | 0.0 4355 | 48 4356 | 0.0 4357 | 49 4358 | 0.0 4359 | 140 4360 | 0.0 4361 | 141 4362 | 0.0 4363 | 142 4364 | 1.0 4365 | 143 4366 | 1.0 4367 | 70 4368 | 688 4369 | 72 4370 | 0 4371 | 73 4372 | 0 4373 | 74 4374 | 5 4375 | 7 4376 | 4377 | 75 4378 | 16 4379 | 76 4380 | 0 4381 | 77 4382 | 2 4383 | 78 4384 | 300 4385 | 147 4386 | 1.0 4387 | 148 4388 | 0.0 4389 | 149 4390 | 0.0 4391 | 100 4392 | AcDbLayout 4393 | 1 4394 | Layout1 4395 | 70 4396 | 1 4397 | 71 4398 | 1 4399 | 10 4400 | 0.0 4401 | 20 4402 | 0.0 4403 | 11 4404 | 12.0 4405 | 21 4406 | 9.0 4407 | 12 4408 | 0.0 4409 | 22 4410 | 0.0 4411 | 32 4412 | 0.0 4413 | 14 4414 | 1.000000000000000E+20 4415 | 24 4416 | 1.000000000000000E+20 4417 | 34 4418 | 1.000000000000000E+20 4419 | 15 4420 | -1.000000000000000E+20 4421 | 25 4422 | -1.000000000000000E+20 4423 | 35 4424 | -1.000000000000000E+20 4425 | 146 4426 | 0.0 4427 | 13 4428 | 0.0 4429 | 23 4430 | 0.0 4431 | 33 4432 | 0.0 4433 | 16 4434 | 1.0 4435 | 26 4436 | 0.0 4437 | 36 4438 | 0.0 4439 | 17 4440 | 0.0 4441 | 27 4442 | 1.0 4443 | 37 4444 | 0.0 4445 | 76 4446 | 0 4447 | 330 4448 | 1B 4449 | 0 4450 | LAYOUT 4451 | 5 4452 | 26 4453 | 102 4454 | {ACAD_REACTORS 4455 | 330 4456 | 1A 4457 | 102 4458 | } 4459 | 330 4460 | 1A 4461 | 100 4462 | AcDbPlotSettings 4463 | 1 4464 | 4465 | 2 4466 | none_device 4467 | 4 4468 | 4469 | 6 4470 | 4471 | 40 4472 | 0.0 4473 | 41 4474 | 0.0 4475 | 42 4476 | 0.0 4477 | 43 4478 | 0.0 4479 | 44 4480 | 0.0 4481 | 45 4482 | 0.0 4483 | 46 4484 | 0.0 4485 | 47 4486 | 0.0 4487 | 48 4488 | 0.0 4489 | 49 4490 | 0.0 4491 | 140 4492 | 0.0 4493 | 141 4494 | 0.0 4495 | 142 4496 | 1.0 4497 | 143 4498 | 1.0 4499 | 70 4500 | 688 4501 | 72 4502 | 0 4503 | 73 4504 | 0 4505 | 74 4506 | 5 4507 | 7 4508 | 4509 | 75 4510 | 16 4511 | 76 4512 | 0 4513 | 77 4514 | 2 4515 | 78 4516 | 300 4517 | 147 4518 | 1.0 4519 | 148 4520 | 0.0 4521 | 149 4522 | 0.0 4523 | 100 4524 | AcDbLayout 4525 | 1 4526 | Layout2 4527 | 70 4528 | 1 4529 | 71 4530 | 2 4531 | 10 4532 | 0.0 4533 | 20 4534 | 0.0 4535 | 11 4536 | 0.0 4537 | 21 4538 | 0.0 4539 | 12 4540 | 0.0 4541 | 22 4542 | 0.0 4543 | 32 4544 | 0.0 4545 | 14 4546 | 0.0 4547 | 24 4548 | 0.0 4549 | 34 4550 | 0.0 4551 | 15 4552 | 0.0 4553 | 25 4554 | 0.0 4555 | 35 4556 | 0.0 4557 | 146 4558 | 0.0 4559 | 13 4560 | 0.0 4561 | 23 4562 | 0.0 4563 | 33 4564 | 0.0 4565 | 16 4566 | 1.0 4567 | 26 4568 | 0.0 4569 | 36 4570 | 0.0 4571 | 17 4572 | 0.0 4573 | 27 4574 | 1.0 4575 | 37 4576 | 0.0 4577 | 76 4578 | 0 4579 | 330 4580 | 23 4581 | 0 4582 | LAYOUT 4583 | 5 4584 | 22 4585 | 102 4586 | {ACAD_REACTORS 4587 | 330 4588 | 1A 4589 | 102 4590 | } 4591 | 330 4592 | 1A 4593 | 100 4594 | AcDbPlotSettings 4595 | 1 4596 | 4597 | 2 4598 | none_device 4599 | 4 4600 | 4601 | 6 4602 | 4603 | 40 4604 | 0.0 4605 | 41 4606 | 0.0 4607 | 42 4608 | 0.0 4609 | 43 4610 | 0.0 4611 | 44 4612 | 0.0 4613 | 45 4614 | 0.0 4615 | 46 4616 | 0.0 4617 | 47 4618 | 0.0 4619 | 48 4620 | 0.0 4621 | 49 4622 | 0.0 4623 | 140 4624 | 0.0 4625 | 141 4626 | 0.0 4627 | 142 4628 | 1.0 4629 | 143 4630 | 1.0 4631 | 70 4632 | 1712 4633 | 72 4634 | 0 4635 | 73 4636 | 0 4637 | 74 4638 | 0 4639 | 7 4640 | 4641 | 75 4642 | 0 4643 | 76 4644 | 0 4645 | 77 4646 | 2 4647 | 78 4648 | 300 4649 | 147 4650 | 1.0 4651 | 148 4652 | 0.0 4653 | 149 4654 | 0.0 4655 | 100 4656 | AcDbLayout 4657 | 1 4658 | Model 4659 | 70 4660 | 1 4661 | 71 4662 | 0 4663 | 10 4664 | 0.0 4665 | 20 4666 | 0.0 4667 | 11 4668 | 12.0 4669 | 21 4670 | 9.0 4671 | 12 4672 | 0.0 4673 | 22 4674 | 0.0 4675 | 32 4676 | 0.0 4677 | 14 4678 | 1.000000000000000E+20 4679 | 24 4680 | 1.000000000000000E+20 4681 | 34 4682 | 1.000000000000000E+20 4683 | 15 4684 | -1.000000000000000E+20 4685 | 25 4686 | -1.000000000000000E+20 4687 | 35 4688 | -1.000000000000000E+20 4689 | 146 4690 | 0.0 4691 | 13 4692 | 0.0 4693 | 23 4694 | 0.0 4695 | 33 4696 | 0.0 4697 | 16 4698 | 1.0 4699 | 26 4700 | 0.0 4701 | 36 4702 | 0.0 4703 | 17 4704 | 0.0 4705 | 27 4706 | 1.0 4707 | 37 4708 | 0.0 4709 | 76 4710 | 0 4711 | 330 4712 | 1F 4713 | 331 4714 | 29 4715 | 0 4716 | MATERIAL 4717 | 5 4718 | 3D 4719 | 102 4720 | {ACAD_REACTORS 4721 | 330 4722 | 3B 4723 | 102 4724 | } 4725 | 330 4726 | 3B 4727 | 100 4728 | AcDbMaterial 4729 | 1 4730 | ByBlock 4731 | 72 4732 | 1 4733 | 94 4734 | 127 4735 | 0 4736 | MATERIAL 4737 | 5 4738 | 3C 4739 | 102 4740 | {ACAD_REACTORS 4741 | 330 4742 | 3B 4743 | 102 4744 | } 4745 | 330 4746 | 3B 4747 | 100 4748 | AcDbMaterial 4749 | 1 4750 | ByLayer 4751 | 72 4752 | 1 4753 | 94 4754 | 127 4755 | 0 4756 | MATERIAL 4757 | 5 4758 | 3E 4759 | 102 4760 | {ACAD_REACTORS 4761 | 330 4762 | 3B 4763 | 102 4764 | } 4765 | 330 4766 | 3B 4767 | 100 4768 | AcDbMaterial 4769 | 1 4770 | Global 4771 | 72 4772 | 1 4773 | 94 4774 | 127 4775 | 0 4776 | MLINESTYLE 4777 | 5 4778 | 18 4779 | 102 4780 | {ACAD_REACTORS 4781 | 330 4782 | 17 4783 | 102 4784 | } 4785 | 330 4786 | 17 4787 | 100 4788 | AcDbMlineStyle 4789 | 2 4790 | Standard 4791 | 70 4792 | 0 4793 | 3 4794 | 4795 | 62 4796 | 256 4797 | 51 4798 | 90.0 4799 | 52 4800 | 90.0 4801 | 71 4802 | 2 4803 | 49 4804 | 0.5 4805 | 62 4806 | 256 4807 | 6 4808 | BYLAYER 4809 | 49 4810 | -0.5 4811 | 62 4812 | 256 4813 | 6 4814 | BYLAYER 4815 | 0 4816 | ACDBPLACEHOLDER 4817 | 5 4818 | F 4819 | 102 4820 | {ACAD_REACTORS 4821 | 330 4822 | E 4823 | 102 4824 | } 4825 | 330 4826 | E 4827 | 0 4828 | VISUALSTYLE 4829 | 5 4830 | 2F 4831 | 102 4832 | {ACAD_REACTORS 4833 | 330 4834 | 2A 4835 | 102 4836 | } 4837 | 330 4838 | 2A 4839 | 100 4840 | AcDbVisualStyle 4841 | 2 4842 | 2dWireframe 4843 | 70 4844 | 4 4845 | 177 4846 | 2 4847 | 291 4848 | 0 4849 | 71 4850 | 0 4851 | 176 4852 | 1 4853 | 72 4854 | 2 4855 | 176 4856 | 1 4857 | 73 4858 | 0 4859 | 176 4860 | 1 4861 | 90 4862 | 0 4863 | 176 4864 | 1 4865 | 40 4866 | -0.6 4867 | 176 4868 | 1 4869 | 41 4870 | -30.0 4871 | 176 4872 | 1 4873 | 62 4874 | 5 4875 | 63 4876 | 7 4877 | 421 4878 | 16777215 4879 | 176 4880 | 1 4881 | 74 4882 | 1 4883 | 176 4884 | 1 4885 | 91 4886 | 4 4887 | 176 4888 | 1 4889 | 64 4890 | 7 4891 | 176 4892 | 1 4893 | 65 4894 | 257 4895 | 176 4896 | 1 4897 | 75 4898 | 1 4899 | 176 4900 | 1 4901 | 175 4902 | 1 4903 | 176 4904 | 1 4905 | 42 4906 | 1.0 4907 | 176 4908 | 1 4909 | 92 4910 | 0 4911 | 176 4912 | 1 4913 | 66 4914 | 257 4915 | 176 4916 | 1 4917 | 43 4918 | 1.0 4919 | 176 4920 | 1 4921 | 76 4922 | 1 4923 | 176 4924 | 1 4925 | 77 4926 | 6 4927 | 176 4928 | 1 4929 | 78 4930 | 2 4931 | 176 4932 | 1 4933 | 67 4934 | 7 4935 | 176 4936 | 1 4937 | 79 4938 | 5 4939 | 176 4940 | 1 4941 | 170 4942 | 0 4943 | 176 4944 | 1 4945 | 171 4946 | 0 4947 | 176 4948 | 1 4949 | 290 4950 | 0 4951 | 176 4952 | 1 4953 | 93 4954 | 1 4955 | 176 4956 | 1 4957 | 44 4958 | 0.0 4959 | 176 4960 | 1 4961 | 173 4962 | 0 4963 | 176 4964 | 1 4965 | 0 4966 | VISUALSTYLE 4967 | 5 4968 | 31 4969 | 102 4970 | {ACAD_REACTORS 4971 | 330 4972 | 2A 4973 | 102 4974 | } 4975 | 330 4976 | 2A 4977 | 100 4978 | AcDbVisualStyle 4979 | 2 4980 | 3D Hidden 4981 | 70 4982 | 6 4983 | 177 4984 | 2 4985 | 291 4986 | 0 4987 | 71 4988 | 1 4989 | 176 4990 | 1 4991 | 72 4992 | 2 4993 | 176 4994 | 1 4995 | 73 4996 | 2 4997 | 176 4998 | 1 4999 | 90 5000 | 0 5001 | 176 5002 | 1 5003 | 40 5004 | -0.6 5005 | 176 5006 | 1 5007 | 41 5008 | -30.0 5009 | 176 5010 | 1 5011 | 62 5012 | 5 5013 | 63 5014 | 7 5015 | 421 5016 | 16777215 5017 | 176 5018 | 1 5019 | 74 5020 | 2 5021 | 176 5022 | 1 5023 | 91 5024 | 2 5025 | 176 5026 | 1 5027 | 64 5028 | 7 5029 | 176 5030 | 1 5031 | 65 5032 | 257 5033 | 176 5034 | 1 5035 | 75 5036 | 2 5037 | 176 5038 | 1 5039 | 175 5040 | 1 5041 | 176 5042 | 1 5043 | 42 5044 | 40.0 5045 | 176 5046 | 1 5047 | 92 5048 | 0 5049 | 176 5050 | 1 5051 | 66 5052 | 257 5053 | 176 5054 | 1 5055 | 43 5056 | 1.0 5057 | 176 5058 | 1 5059 | 76 5060 | 1 5061 | 176 5062 | 1 5063 | 77 5064 | 6 5065 | 176 5066 | 1 5067 | 78 5068 | 2 5069 | 176 5070 | 1 5071 | 67 5072 | 7 5073 | 176 5074 | 1 5075 | 79 5076 | 3 5077 | 176 5078 | 1 5079 | 170 5080 | 0 5081 | 176 5082 | 1 5083 | 171 5084 | 0 5085 | 176 5086 | 1 5087 | 290 5088 | 0 5089 | 176 5090 | 1 5091 | 93 5092 | 1 5093 | 176 5094 | 1 5095 | 44 5096 | 0.0 5097 | 176 5098 | 1 5099 | 173 5100 | 0 5101 | 176 5102 | 1 5103 | 0 5104 | VISUALSTYLE 5105 | 5 5106 | 30 5107 | 102 5108 | {ACAD_REACTORS 5109 | 330 5110 | 2A 5111 | 102 5112 | } 5113 | 330 5114 | 2A 5115 | 100 5116 | AcDbVisualStyle 5117 | 2 5118 | 3dWireframe 5119 | 70 5120 | 5 5121 | 177 5122 | 2 5123 | 291 5124 | 0 5125 | 71 5126 | 0 5127 | 176 5128 | 1 5129 | 72 5130 | 2 5131 | 176 5132 | 1 5133 | 73 5134 | 0 5135 | 176 5136 | 1 5137 | 90 5138 | 0 5139 | 176 5140 | 1 5141 | 40 5142 | -0.6 5143 | 176 5144 | 1 5145 | 41 5146 | -30.0 5147 | 176 5148 | 1 5149 | 62 5150 | 5 5151 | 63 5152 | 7 5153 | 421 5154 | 16777215 5155 | 176 5156 | 1 5157 | 74 5158 | 1 5159 | 176 5160 | 1 5161 | 91 5162 | 4 5163 | 176 5164 | 1 5165 | 64 5166 | 7 5167 | 176 5168 | 1 5169 | 65 5170 | 257 5171 | 176 5172 | 1 5173 | 75 5174 | 1 5175 | 176 5176 | 1 5177 | 175 5178 | 1 5179 | 176 5180 | 1 5181 | 42 5182 | 1.0 5183 | 176 5184 | 1 5185 | 92 5186 | 0 5187 | 176 5188 | 1 5189 | 66 5190 | 257 5191 | 176 5192 | 1 5193 | 43 5194 | 1.0 5195 | 176 5196 | 1 5197 | 76 5198 | 1 5199 | 176 5200 | 1 5201 | 77 5202 | 6 5203 | 176 5204 | 1 5205 | 78 5206 | 2 5207 | 176 5208 | 1 5209 | 67 5210 | 7 5211 | 176 5212 | 1 5213 | 79 5214 | 5 5215 | 176 5216 | 1 5217 | 170 5218 | 0 5219 | 176 5220 | 1 5221 | 171 5222 | 0 5223 | 176 5224 | 1 5225 | 290 5226 | 0 5227 | 176 5228 | 1 5229 | 93 5230 | 1 5231 | 176 5232 | 1 5233 | 44 5234 | 0.0 5235 | 176 5236 | 1 5237 | 173 5238 | 0 5239 | 176 5240 | 1 5241 | 0 5242 | VISUALSTYLE 5243 | 5 5244 | 32 5245 | 102 5246 | {ACAD_REACTORS 5247 | 330 5248 | 2A 5249 | 102 5250 | } 5251 | 330 5252 | 2A 5253 | 100 5254 | AcDbVisualStyle 5255 | 2 5256 | Basic 5257 | 70 5258 | 7 5259 | 177 5260 | 2 5261 | 291 5262 | 1 5263 | 71 5264 | 1 5265 | 176 5266 | 1 5267 | 72 5268 | 0 5269 | 176 5270 | 1 5271 | 73 5272 | 1 5273 | 176 5274 | 1 5275 | 90 5276 | 0 5277 | 176 5278 | 1 5279 | 40 5280 | -0.6 5281 | 176 5282 | 1 5283 | 41 5284 | -30.0 5285 | 176 5286 | 1 5287 | 62 5288 | 5 5289 | 63 5290 | 7 5291 | 421 5292 | 16777215 5293 | 176 5294 | 1 5295 | 74 5296 | 0 5297 | 176 5298 | 1 5299 | 91 5300 | 4 5301 | 176 5302 | 1 5303 | 64 5304 | 7 5305 | 176 5306 | 1 5307 | 65 5308 | 257 5309 | 176 5310 | 1 5311 | 75 5312 | 1 5313 | 176 5314 | 1 5315 | 175 5316 | 1 5317 | 176 5318 | 1 5319 | 42 5320 | 1.0 5321 | 176 5322 | 1 5323 | 92 5324 | 8 5325 | 176 5326 | 1 5327 | 66 5328 | 7 5329 | 176 5330 | 1 5331 | 43 5332 | 1.0 5333 | 176 5334 | 1 5335 | 76 5336 | 1 5337 | 176 5338 | 1 5339 | 77 5340 | 6 5341 | 176 5342 | 1 5343 | 78 5344 | 2 5345 | 176 5346 | 1 5347 | 67 5348 | 7 5349 | 176 5350 | 1 5351 | 79 5352 | 5 5353 | 176 5354 | 1 5355 | 170 5356 | 0 5357 | 176 5358 | 1 5359 | 171 5360 | 0 5361 | 176 5362 | 1 5363 | 290 5364 | 0 5365 | 176 5366 | 1 5367 | 93 5368 | 1 5369 | 176 5370 | 1 5371 | 44 5372 | 0.0 5373 | 176 5374 | 1 5375 | 173 5376 | 0 5377 | 176 5378 | 1 5379 | 0 5380 | VISUALSTYLE 5381 | 5 5382 | 36 5383 | 102 5384 | {ACAD_REACTORS 5385 | 330 5386 | 2A 5387 | 102 5388 | } 5389 | 330 5390 | 2A 5391 | 100 5392 | AcDbVisualStyle 5393 | 2 5394 | Brighten 5395 | 70 5396 | 12 5397 | 177 5398 | 2 5399 | 291 5400 | 1 5401 | 71 5402 | 2 5403 | 176 5404 | 1 5405 | 72 5406 | 2 5407 | 176 5408 | 1 5409 | 73 5410 | 0 5411 | 176 5412 | 1 5413 | 90 5414 | 0 5415 | 176 5416 | 1 5417 | 40 5418 | -0.6 5419 | 176 5420 | 1 5421 | 41 5422 | -30.0 5423 | 176 5424 | 1 5425 | 62 5426 | 5 5427 | 63 5428 | 7 5429 | 421 5430 | 16777215 5431 | 176 5432 | 1 5433 | 74 5434 | 1 5435 | 176 5436 | 1 5437 | 91 5438 | 4 5439 | 176 5440 | 1 5441 | 64 5442 | 7 5443 | 176 5444 | 1 5445 | 65 5446 | 257 5447 | 176 5448 | 1 5449 | 75 5450 | 1 5451 | 176 5452 | 1 5453 | 175 5454 | 1 5455 | 176 5456 | 1 5457 | 42 5458 | 1.0 5459 | 176 5460 | 1 5461 | 92 5462 | 8 5463 | 176 5464 | 1 5465 | 66 5466 | 7 5467 | 176 5468 | 1 5469 | 43 5470 | 1.0 5471 | 176 5472 | 1 5473 | 76 5474 | 1 5475 | 176 5476 | 1 5477 | 77 5478 | 6 5479 | 176 5480 | 1 5481 | 78 5482 | 2 5483 | 176 5484 | 1 5485 | 67 5486 | 7 5487 | 176 5488 | 1 5489 | 79 5490 | 5 5491 | 176 5492 | 1 5493 | 170 5494 | 0 5495 | 176 5496 | 1 5497 | 171 5498 | 0 5499 | 176 5500 | 1 5501 | 290 5502 | 0 5503 | 176 5504 | 1 5505 | 93 5506 | 1 5507 | 176 5508 | 1 5509 | 44 5510 | 50.0 5511 | 176 5512 | 1 5513 | 173 5514 | 0 5515 | 176 5516 | 1 5517 | 0 5518 | VISUALSTYLE 5519 | 5 5520 | 3A 5521 | 102 5522 | {ACAD_REACTORS 5523 | 330 5524 | 2A 5525 | 102 5526 | } 5527 | 330 5528 | 2A 5529 | 100 5530 | AcDbVisualStyle 5531 | 2 5532 | ColorChange 5533 | 70 5534 | 16 5535 | 177 5536 | 2 5537 | 291 5538 | 1 5539 | 71 5540 | 2 5541 | 176 5542 | 1 5543 | 72 5544 | 2 5545 | 176 5546 | 1 5547 | 73 5548 | 3 5549 | 176 5550 | 1 5551 | 90 5552 | 0 5553 | 176 5554 | 1 5555 | 40 5556 | -0.6 5557 | 176 5558 | 1 5559 | 41 5560 | -30.0 5561 | 176 5562 | 1 5563 | 62 5564 | 5 5565 | 63 5566 | 8 5567 | 421 5568 | 8421504 5569 | 176 5570 | 1 5571 | 74 5572 | 1 5573 | 176 5574 | 1 5575 | 91 5576 | 4 5577 | 176 5578 | 1 5579 | 64 5580 | 7 5581 | 176 5582 | 1 5583 | 65 5584 | 257 5585 | 176 5586 | 1 5587 | 75 5588 | 1 5589 | 176 5590 | 1 5591 | 175 5592 | 1 5593 | 176 5594 | 1 5595 | 42 5596 | 1.0 5597 | 176 5598 | 1 5599 | 92 5600 | 8 5601 | 176 5602 | 1 5603 | 66 5604 | 8 5605 | 424 5606 | 8421504 5607 | 176 5608 | 1 5609 | 43 5610 | 1.0 5611 | 176 5612 | 1 5613 | 76 5614 | 1 5615 | 176 5616 | 1 5617 | 77 5618 | 6 5619 | 176 5620 | 1 5621 | 78 5622 | 2 5623 | 176 5624 | 1 5625 | 67 5626 | 7 5627 | 176 5628 | 1 5629 | 79 5630 | 5 5631 | 176 5632 | 1 5633 | 170 5634 | 0 5635 | 176 5636 | 1 5637 | 171 5638 | 0 5639 | 176 5640 | 1 5641 | 290 5642 | 0 5643 | 176 5644 | 1 5645 | 93 5646 | 1 5647 | 176 5648 | 1 5649 | 44 5650 | 0.0 5651 | 176 5652 | 1 5653 | 173 5654 | 0 5655 | 176 5656 | 1 5657 | 0 5658 | VISUALSTYLE 5659 | 5 5660 | 34 5661 | 102 5662 | {ACAD_REACTORS 5663 | 330 5664 | 2A 5665 | 102 5666 | } 5667 | 330 5668 | 2A 5669 | 100 5670 | AcDbVisualStyle 5671 | 2 5672 | Conceptual 5673 | 70 5674 | 9 5675 | 177 5676 | 2 5677 | 291 5678 | 0 5679 | 71 5680 | 3 5681 | 176 5682 | 1 5683 | 72 5684 | 2 5685 | 176 5686 | 1 5687 | 73 5688 | 0 5689 | 176 5690 | 1 5691 | 90 5692 | 0 5693 | 176 5694 | 1 5695 | 40 5696 | -0.6 5697 | 176 5698 | 1 5699 | 41 5700 | -30.0 5701 | 176 5702 | 1 5703 | 62 5704 | 5 5705 | 63 5706 | 7 5707 | 421 5708 | 16777215 5709 | 176 5710 | 1 5711 | 74 5712 | 2 5713 | 176 5714 | 1 5715 | 91 5716 | 2 5717 | 176 5718 | 1 5719 | 64 5720 | 7 5721 | 176 5722 | 1 5723 | 65 5724 | 257 5725 | 176 5726 | 1 5727 | 75 5728 | 1 5729 | 176 5730 | 1 5731 | 175 5732 | 1 5733 | 176 5734 | 1 5735 | 42 5736 | 40.0 5737 | 176 5738 | 1 5739 | 92 5740 | 8 5741 | 176 5742 | 1 5743 | 66 5744 | 7 5745 | 176 5746 | 1 5747 | 43 5748 | 1.0 5749 | 176 5750 | 1 5751 | 76 5752 | 1 5753 | 176 5754 | 1 5755 | 77 5756 | 6 5757 | 176 5758 | 1 5759 | 78 5760 | 2 5761 | 176 5762 | 1 5763 | 67 5764 | 7 5765 | 176 5766 | 1 5767 | 79 5768 | 3 5769 | 176 5770 | 1 5771 | 170 5772 | 0 5773 | 176 5774 | 1 5775 | 171 5776 | 0 5777 | 176 5778 | 1 5779 | 290 5780 | 0 5781 | 176 5782 | 1 5783 | 93 5784 | 1 5785 | 176 5786 | 1 5787 | 44 5788 | 0.0 5789 | 176 5790 | 1 5791 | 173 5792 | 0 5793 | 176 5794 | 1 5795 | 0 5796 | VISUALSTYLE 5797 | 5 5798 | 35 5799 | 102 5800 | {ACAD_REACTORS 5801 | 330 5802 | 2A 5803 | 102 5804 | } 5805 | 330 5806 | 2A 5807 | 100 5808 | AcDbVisualStyle 5809 | 2 5810 | Dim 5811 | 70 5812 | 11 5813 | 177 5814 | 2 5815 | 291 5816 | 1 5817 | 71 5818 | 2 5819 | 176 5820 | 1 5821 | 72 5822 | 2 5823 | 176 5824 | 1 5825 | 73 5826 | 0 5827 | 176 5828 | 1 5829 | 90 5830 | 0 5831 | 176 5832 | 1 5833 | 40 5834 | -0.6 5835 | 176 5836 | 1 5837 | 41 5838 | -30.0 5839 | 176 5840 | 1 5841 | 62 5842 | 5 5843 | 63 5844 | 7 5845 | 421 5846 | 16777215 5847 | 176 5848 | 1 5849 | 74 5850 | 1 5851 | 176 5852 | 1 5853 | 91 5854 | 4 5855 | 176 5856 | 1 5857 | 64 5858 | 7 5859 | 176 5860 | 1 5861 | 65 5862 | 257 5863 | 176 5864 | 1 5865 | 75 5866 | 1 5867 | 176 5868 | 1 5869 | 175 5870 | 1 5871 | 176 5872 | 1 5873 | 42 5874 | 1.0 5875 | 176 5876 | 1 5877 | 92 5878 | 8 5879 | 176 5880 | 1 5881 | 66 5882 | 7 5883 | 176 5884 | 1 5885 | 43 5886 | 1.0 5887 | 176 5888 | 1 5889 | 76 5890 | 1 5891 | 176 5892 | 1 5893 | 77 5894 | 6 5895 | 176 5896 | 1 5897 | 78 5898 | 2 5899 | 176 5900 | 1 5901 | 67 5902 | 7 5903 | 176 5904 | 1 5905 | 79 5906 | 5 5907 | 176 5908 | 1 5909 | 170 5910 | 0 5911 | 176 5912 | 1 5913 | 171 5914 | 0 5915 | 176 5916 | 1 5917 | 290 5918 | 0 5919 | 176 5920 | 1 5921 | 93 5922 | 1 5923 | 176 5924 | 1 5925 | 44 5926 | -50.0 5927 | 176 5928 | 1 5929 | 173 5930 | 0 5931 | 176 5932 | 1 5933 | 0 5934 | VISUALSTYLE 5935 | 5 5936 | 39 5937 | 102 5938 | {ACAD_REACTORS 5939 | 330 5940 | 2A 5941 | 102 5942 | } 5943 | 330 5944 | 2A 5945 | 100 5946 | AcDbVisualStyle 5947 | 2 5948 | Facepattern 5949 | 70 5950 | 15 5951 | 177 5952 | 2 5953 | 291 5954 | 1 5955 | 71 5956 | 2 5957 | 176 5958 | 1 5959 | 72 5960 | 2 5961 | 176 5962 | 1 5963 | 73 5964 | 0 5965 | 176 5966 | 1 5967 | 90 5968 | 0 5969 | 176 5970 | 1 5971 | 40 5972 | -0.6 5973 | 176 5974 | 1 5975 | 41 5976 | -30.0 5977 | 176 5978 | 1 5979 | 62 5980 | 5 5981 | 63 5982 | 7 5983 | 421 5984 | 16777215 5985 | 176 5986 | 1 5987 | 74 5988 | 1 5989 | 176 5990 | 1 5991 | 91 5992 | 4 5993 | 176 5994 | 1 5995 | 64 5996 | 7 5997 | 176 5998 | 1 5999 | 65 6000 | 257 6001 | 176 6002 | 1 6003 | 75 6004 | 1 6005 | 176 6006 | 1 6007 | 175 6008 | 1 6009 | 176 6010 | 1 6011 | 42 6012 | 1.0 6013 | 176 6014 | 1 6015 | 92 6016 | 8 6017 | 176 6018 | 1 6019 | 66 6020 | 7 6021 | 176 6022 | 1 6023 | 43 6024 | 1.0 6025 | 176 6026 | 1 6027 | 76 6028 | 1 6029 | 176 6030 | 1 6031 | 77 6032 | 6 6033 | 176 6034 | 1 6035 | 78 6036 | 2 6037 | 176 6038 | 1 6039 | 67 6040 | 7 6041 | 176 6042 | 1 6043 | 79 6044 | 5 6045 | 176 6046 | 1 6047 | 170 6048 | 0 6049 | 176 6050 | 1 6051 | 171 6052 | 0 6053 | 176 6054 | 1 6055 | 290 6056 | 0 6057 | 176 6058 | 1 6059 | 93 6060 | 1 6061 | 176 6062 | 1 6063 | 44 6064 | 0.0 6065 | 176 6066 | 1 6067 | 173 6068 | 0 6069 | 176 6070 | 1 6071 | 0 6072 | VISUALSTYLE 6073 | 5 6074 | 2B 6075 | 102 6076 | {ACAD_REACTORS 6077 | 330 6078 | 2A 6079 | 102 6080 | } 6081 | 330 6082 | 2A 6083 | 100 6084 | AcDbVisualStyle 6085 | 2 6086 | Flat 6087 | 70 6088 | 0 6089 | 177 6090 | 2 6091 | 291 6092 | 1 6093 | 71 6094 | 2 6095 | 176 6096 | 1 6097 | 72 6098 | 1 6099 | 176 6100 | 1 6101 | 73 6102 | 1 6103 | 176 6104 | 1 6105 | 90 6106 | 2 6107 | 176 6108 | 1 6109 | 40 6110 | -0.6 6111 | 176 6112 | 1 6113 | 41 6114 | 30.0 6115 | 176 6116 | 1 6117 | 62 6118 | 5 6119 | 63 6120 | 7 6121 | 421 6122 | 16777215 6123 | 176 6124 | 1 6125 | 74 6126 | 0 6127 | 176 6128 | 1 6129 | 91 6130 | 4 6131 | 176 6132 | 1 6133 | 64 6134 | 7 6135 | 176 6136 | 1 6137 | 65 6138 | 257 6139 | 176 6140 | 1 6141 | 75 6142 | 1 6143 | 176 6144 | 1 6145 | 175 6146 | 1 6147 | 176 6148 | 1 6149 | 42 6150 | 1.0 6151 | 176 6152 | 1 6153 | 92 6154 | 8 6155 | 176 6156 | 1 6157 | 66 6158 | 7 6159 | 176 6160 | 1 6161 | 43 6162 | 1.0 6163 | 176 6164 | 1 6165 | 76 6166 | 1 6167 | 176 6168 | 1 6169 | 77 6170 | 6 6171 | 176 6172 | 1 6173 | 78 6174 | 2 6175 | 176 6176 | 1 6177 | 67 6178 | 7 6179 | 176 6180 | 1 6181 | 79 6182 | 5 6183 | 176 6184 | 1 6185 | 170 6186 | 0 6187 | 176 6188 | 1 6189 | 171 6190 | 0 6191 | 176 6192 | 1 6193 | 290 6194 | 0 6195 | 176 6196 | 1 6197 | 93 6198 | 13 6199 | 176 6200 | 1 6201 | 44 6202 | 0.0 6203 | 176 6204 | 1 6205 | 173 6206 | 0 6207 | 176 6208 | 1 6209 | 0 6210 | VISUALSTYLE 6211 | 5 6212 | 2C 6213 | 102 6214 | {ACAD_REACTORS 6215 | 330 6216 | 2A 6217 | 102 6218 | } 6219 | 330 6220 | 2A 6221 | 100 6222 | AcDbVisualStyle 6223 | 2 6224 | FlatWithEdges 6225 | 70 6226 | 1 6227 | 177 6228 | 2 6229 | 291 6230 | 1 6231 | 71 6232 | 2 6233 | 176 6234 | 1 6235 | 72 6236 | 1 6237 | 176 6238 | 1 6239 | 73 6240 | 1 6241 | 176 6242 | 1 6243 | 90 6244 | 2 6245 | 176 6246 | 1 6247 | 40 6248 | -0.6 6249 | 176 6250 | 1 6251 | 41 6252 | 30.0 6253 | 176 6254 | 1 6255 | 62 6256 | 5 6257 | 63 6258 | 7 6259 | 421 6260 | 16777215 6261 | 176 6262 | 1 6263 | 74 6264 | 1 6265 | 176 6266 | 1 6267 | 91 6268 | 4 6269 | 176 6270 | 1 6271 | 64 6272 | 7 6273 | 176 6274 | 1 6275 | 65 6276 | 257 6277 | 176 6278 | 1 6279 | 75 6280 | 1 6281 | 176 6282 | 1 6283 | 175 6284 | 1 6285 | 176 6286 | 1 6287 | 42 6288 | 1.0 6289 | 176 6290 | 1 6291 | 92 6292 | 0 6293 | 176 6294 | 1 6295 | 66 6296 | 257 6297 | 176 6298 | 1 6299 | 43 6300 | 1.0 6301 | 176 6302 | 1 6303 | 76 6304 | 1 6305 | 176 6306 | 1 6307 | 77 6308 | 6 6309 | 176 6310 | 1 6311 | 78 6312 | 2 6313 | 176 6314 | 1 6315 | 67 6316 | 7 6317 | 176 6318 | 1 6319 | 79 6320 | 5 6321 | 176 6322 | 1 6323 | 170 6324 | 0 6325 | 176 6326 | 1 6327 | 171 6328 | 0 6329 | 176 6330 | 1 6331 | 290 6332 | 0 6333 | 176 6334 | 1 6335 | 93 6336 | 13 6337 | 176 6338 | 1 6339 | 44 6340 | 0.0 6341 | 176 6342 | 1 6343 | 173 6344 | 0 6345 | 176 6346 | 1 6347 | 0 6348 | VISUALSTYLE 6349 | 5 6350 | 2D 6351 | 102 6352 | {ACAD_REACTORS 6353 | 330 6354 | 2A 6355 | 102 6356 | } 6357 | 330 6358 | 2A 6359 | 100 6360 | AcDbVisualStyle 6361 | 2 6362 | Gouraud 6363 | 70 6364 | 2 6365 | 177 6366 | 2 6367 | 291 6368 | 1 6369 | 71 6370 | 2 6371 | 176 6372 | 1 6373 | 72 6374 | 2 6375 | 176 6376 | 1 6377 | 73 6378 | 1 6379 | 176 6380 | 1 6381 | 90 6382 | 2 6383 | 176 6384 | 1 6385 | 40 6386 | -0.6 6387 | 176 6388 | 1 6389 | 41 6390 | 30.0 6391 | 176 6392 | 1 6393 | 62 6394 | 5 6395 | 63 6396 | 7 6397 | 421 6398 | 16777215 6399 | 176 6400 | 1 6401 | 74 6402 | 0 6403 | 176 6404 | 1 6405 | 91 6406 | 4 6407 | 176 6408 | 1 6409 | 64 6410 | 7 6411 | 176 6412 | 1 6413 | 65 6414 | 257 6415 | 176 6416 | 1 6417 | 75 6418 | 1 6419 | 176 6420 | 1 6421 | 175 6422 | 1 6423 | 176 6424 | 1 6425 | 42 6426 | 1.0 6427 | 176 6428 | 1 6429 | 92 6430 | 0 6431 | 176 6432 | 1 6433 | 66 6434 | 7 6435 | 176 6436 | 1 6437 | 43 6438 | 1.0 6439 | 176 6440 | 1 6441 | 76 6442 | 1 6443 | 176 6444 | 1 6445 | 77 6446 | 6 6447 | 176 6448 | 1 6449 | 78 6450 | 2 6451 | 176 6452 | 1 6453 | 67 6454 | 7 6455 | 176 6456 | 1 6457 | 79 6458 | 5 6459 | 176 6460 | 1 6461 | 170 6462 | 0 6463 | 176 6464 | 1 6465 | 171 6466 | 0 6467 | 176 6468 | 1 6469 | 290 6470 | 0 6471 | 176 6472 | 1 6473 | 93 6474 | 13 6475 | 176 6476 | 1 6477 | 44 6478 | 0.0 6479 | 176 6480 | 1 6481 | 173 6482 | 0 6483 | 176 6484 | 1 6485 | 0 6486 | VISUALSTYLE 6487 | 5 6488 | 2E 6489 | 102 6490 | {ACAD_REACTORS 6491 | 330 6492 | 2A 6493 | 102 6494 | } 6495 | 330 6496 | 2A 6497 | 100 6498 | AcDbVisualStyle 6499 | 2 6500 | GouraudWithEdges 6501 | 70 6502 | 3 6503 | 177 6504 | 2 6505 | 291 6506 | 1 6507 | 71 6508 | 2 6509 | 176 6510 | 1 6511 | 72 6512 | 2 6513 | 176 6514 | 1 6515 | 73 6516 | 1 6517 | 176 6518 | 1 6519 | 90 6520 | 2 6521 | 176 6522 | 1 6523 | 40 6524 | -0.6 6525 | 176 6526 | 1 6527 | 41 6528 | 30.0 6529 | 176 6530 | 1 6531 | 62 6532 | 5 6533 | 63 6534 | 7 6535 | 421 6536 | 16777215 6537 | 176 6538 | 1 6539 | 74 6540 | 1 6541 | 176 6542 | 1 6543 | 91 6544 | 4 6545 | 176 6546 | 1 6547 | 64 6548 | 7 6549 | 176 6550 | 1 6551 | 65 6552 | 257 6553 | 176 6554 | 1 6555 | 75 6556 | 1 6557 | 176 6558 | 1 6559 | 175 6560 | 1 6561 | 176 6562 | 1 6563 | 42 6564 | 1.0 6565 | 176 6566 | 1 6567 | 92 6568 | 0 6569 | 176 6570 | 1 6571 | 66 6572 | 257 6573 | 176 6574 | 1 6575 | 43 6576 | 1.0 6577 | 176 6578 | 1 6579 | 76 6580 | 1 6581 | 176 6582 | 1 6583 | 77 6584 | 6 6585 | 176 6586 | 1 6587 | 78 6588 | 2 6589 | 176 6590 | 1 6591 | 67 6592 | 7 6593 | 176 6594 | 1 6595 | 79 6596 | 5 6597 | 176 6598 | 1 6599 | 170 6600 | 0 6601 | 176 6602 | 1 6603 | 171 6604 | 0 6605 | 176 6606 | 1 6607 | 290 6608 | 0 6609 | 176 6610 | 1 6611 | 93 6612 | 13 6613 | 176 6614 | 1 6615 | 44 6616 | 0.0 6617 | 176 6618 | 1 6619 | 173 6620 | 0 6621 | 176 6622 | 1 6623 | 0 6624 | VISUALSTYLE 6625 | 5 6626 | 38 6627 | 102 6628 | {ACAD_REACTORS 6629 | 330 6630 | 2A 6631 | 102 6632 | } 6633 | 330 6634 | 2A 6635 | 100 6636 | AcDbVisualStyle 6637 | 2 6638 | Linepattern 6639 | 70 6640 | 14 6641 | 177 6642 | 2 6643 | 291 6644 | 1 6645 | 71 6646 | 2 6647 | 176 6648 | 1 6649 | 72 6650 | 2 6651 | 176 6652 | 1 6653 | 73 6654 | 0 6655 | 176 6656 | 1 6657 | 90 6658 | 0 6659 | 176 6660 | 1 6661 | 40 6662 | -0.6 6663 | 176 6664 | 1 6665 | 41 6666 | -30.0 6667 | 176 6668 | 1 6669 | 62 6670 | 5 6671 | 63 6672 | 7 6673 | 421 6674 | 16777215 6675 | 176 6676 | 1 6677 | 74 6678 | 1 6679 | 176 6680 | 1 6681 | 91 6682 | 4 6683 | 176 6684 | 1 6685 | 64 6686 | 7 6687 | 176 6688 | 1 6689 | 65 6690 | 257 6691 | 176 6692 | 1 6693 | 75 6694 | 7 6695 | 176 6696 | 1 6697 | 175 6698 | 7 6699 | 176 6700 | 1 6701 | 42 6702 | 1.0 6703 | 176 6704 | 1 6705 | 92 6706 | 8 6707 | 176 6708 | 1 6709 | 66 6710 | 7 6711 | 176 6712 | 1 6713 | 43 6714 | 1.0 6715 | 176 6716 | 1 6717 | 76 6718 | 1 6719 | 176 6720 | 1 6721 | 77 6722 | 6 6723 | 176 6724 | 1 6725 | 78 6726 | 2 6727 | 176 6728 | 1 6729 | 67 6730 | 7 6731 | 176 6732 | 1 6733 | 79 6734 | 5 6735 | 176 6736 | 1 6737 | 170 6738 | 0 6739 | 176 6740 | 1 6741 | 171 6742 | 0 6743 | 176 6744 | 1 6745 | 290 6746 | 0 6747 | 176 6748 | 1 6749 | 93 6750 | 1 6751 | 176 6752 | 1 6753 | 44 6754 | 0.0 6755 | 176 6756 | 1 6757 | 173 6758 | 0 6759 | 176 6760 | 1 6761 | 0 6762 | VISUALSTYLE 6763 | 5 6764 | 33 6765 | 102 6766 | {ACAD_REACTORS 6767 | 330 6768 | 2A 6769 | 102 6770 | } 6771 | 330 6772 | 2A 6773 | 100 6774 | AcDbVisualStyle 6775 | 2 6776 | Realistic 6777 | 70 6778 | 8 6779 | 177 6780 | 2 6781 | 291 6782 | 0 6783 | 71 6784 | 2 6785 | 176 6786 | 1 6787 | 72 6788 | 2 6789 | 176 6790 | 1 6791 | 73 6792 | 0 6793 | 176 6794 | 1 6795 | 90 6796 | 0 6797 | 176 6798 | 1 6799 | 40 6800 | -0.6 6801 | 176 6802 | 1 6803 | 41 6804 | -30.0 6805 | 176 6806 | 1 6807 | 62 6808 | 5 6809 | 63 6810 | 7 6811 | 421 6812 | 16777215 6813 | 176 6814 | 1 6815 | 74 6816 | 1 6817 | 176 6818 | 1 6819 | 91 6820 | 0 6821 | 176 6822 | 1 6823 | 64 6824 | 7 6825 | 176 6826 | 1 6827 | 65 6828 | 257 6829 | 176 6830 | 1 6831 | 75 6832 | 1 6833 | 176 6834 | 1 6835 | 175 6836 | 1 6837 | 176 6838 | 1 6839 | 42 6840 | 1.0 6841 | 176 6842 | 1 6843 | 92 6844 | 8 6845 | 176 6846 | 1 6847 | 66 6848 | 8 6849 | 424 6850 | 7895160 6851 | 176 6852 | 1 6853 | 43 6854 | 1.0 6855 | 176 6856 | 1 6857 | 76 6858 | 1 6859 | 176 6860 | 1 6861 | 77 6862 | 6 6863 | 176 6864 | 1 6865 | 78 6866 | 2 6867 | 176 6868 | 1 6869 | 67 6870 | 7 6871 | 176 6872 | 1 6873 | 79 6874 | 5 6875 | 176 6876 | 1 6877 | 170 6878 | 0 6879 | 176 6880 | 1 6881 | 171 6882 | 0 6883 | 176 6884 | 1 6885 | 290 6886 | 0 6887 | 176 6888 | 1 6889 | 93 6890 | 13 6891 | 176 6892 | 1 6893 | 44 6894 | 0.0 6895 | 176 6896 | 1 6897 | 173 6898 | 0 6899 | 176 6900 | 1 6901 | 0 6902 | VISUALSTYLE 6903 | 5 6904 | 37 6905 | 102 6906 | {ACAD_REACTORS 6907 | 330 6908 | 2A 6909 | 102 6910 | } 6911 | 330 6912 | 2A 6913 | 100 6914 | AcDbVisualStyle 6915 | 2 6916 | Thicken 6917 | 70 6918 | 13 6919 | 177 6920 | 2 6921 | 291 6922 | 1 6923 | 71 6924 | 2 6925 | 176 6926 | 1 6927 | 72 6928 | 2 6929 | 176 6930 | 1 6931 | 73 6932 | 0 6933 | 176 6934 | 1 6935 | 90 6936 | 0 6937 | 176 6938 | 1 6939 | 40 6940 | -0.6 6941 | 176 6942 | 1 6943 | 41 6944 | -30.0 6945 | 176 6946 | 1 6947 | 62 6948 | 5 6949 | 63 6950 | 7 6951 | 421 6952 | 16777215 6953 | 176 6954 | 1 6955 | 74 6956 | 1 6957 | 176 6958 | 1 6959 | 91 6960 | 4 6961 | 176 6962 | 1 6963 | 64 6964 | 7 6965 | 176 6966 | 1 6967 | 65 6968 | 257 6969 | 176 6970 | 1 6971 | 75 6972 | 1 6973 | 176 6974 | 1 6975 | 175 6976 | 1 6977 | 176 6978 | 1 6979 | 42 6980 | 1.0 6981 | 176 6982 | 1 6983 | 92 6984 | 12 6985 | 176 6986 | 1 6987 | 66 6988 | 7 6989 | 176 6990 | 1 6991 | 43 6992 | 1.0 6993 | 176 6994 | 1 6995 | 76 6996 | 1 6997 | 176 6998 | 1 6999 | 77 7000 | 6 7001 | 176 7002 | 1 7003 | 78 7004 | 2 7005 | 176 7006 | 1 7007 | 67 7008 | 7 7009 | 176 7010 | 1 7011 | 79 7012 | 5 7013 | 176 7014 | 1 7015 | 170 7016 | 0 7017 | 176 7018 | 1 7019 | 171 7020 | 0 7021 | 176 7022 | 1 7023 | 290 7024 | 0 7025 | 176 7026 | 1 7027 | 93 7028 | 1 7029 | 176 7030 | 1 7031 | 44 7032 | 0.0 7033 | 176 7034 | 1 7035 | 173 7036 | 0 7037 | 176 7038 | 1 7039 | 0 7040 | ENDSEC 7041 | 0 7042 | EOF 7043 | -------------------------------------------------------------------------------- /runtime/.gitignore: -------------------------------------------------------------------------------- 1 | \context-local.yaml 2 | \context-test.yaml 3 | -------------------------------------------------------------------------------- /runtime/Authenticator/Authenticator.js: -------------------------------------------------------------------------------- 1 | global.Authorization = { 2 | auth: function (context, username, pincode) { 3 | var pincodes = JSON.parse(context.PINCODES); 4 | return pincodes[username] === pincode; 5 | } 6 | }; 7 | 8 | const AccessToken = Twilio.jwt.AccessToken; 9 | const ClientCapability = Twilio.jwt.ClientCapability; 10 | const SyncGrant = AccessToken.SyncGrant; 11 | 12 | function getSyncToken(context, username) { 13 | // Create a "grant" which enables a client to use Sync as a given user, 14 | // on a given device 15 | let syncGrant = new SyncGrant({ 16 | serviceSid: context.SYNC_SERVICE_SID 17 | }); 18 | 19 | // Create an access token which we will sign and return to the client, 20 | // containing the grant we just created 21 | let token = new AccessToken( 22 | context.ACCOUNT_SID, 23 | context.API_KEY, 24 | context.API_SECRET, { 25 | ttl : parseInt(context.TOKEN_TTL) // WARNING: int and string are different for AccessToken 26 | } 27 | ); 28 | token.addGrant(syncGrant); 29 | token.identity = username; 30 | 31 | return token.toJwt(); 32 | } 33 | 34 | function getTwimlAppToken(context) { 35 | const capability = new ClientCapability({ 36 | accountSid: context.ACCOUNT_SID, 37 | authToken: context.AUTH_TOKEN, 38 | ttl : parseInt(context.TOKEN_TTL) 39 | }); 40 | 41 | capability.addScope( 42 | new ClientCapability.OutgoingClientScope({ 43 | applicationSid: context.TWIML_APP_SID}) 44 | ); 45 | 46 | return capability.toJwt(); 47 | } 48 | 49 | exports.handler = function(context, event, callback) { 50 | let username = event.username; 51 | let pincode = event.pincode; 52 | 53 | if (!username) return callback(null, { success: false, error: "username is not defined in event" }); 54 | if (!pincode) return callback(null, { success: false, error: "pincode is not defined in event" }); 55 | 56 | if (!Authorization.auth(context, username, pincode)) return callback(null, { success: false, error: "username or token provided is invalid" }); 57 | 58 | // Serialize the token to a JWT string and include it in a JSON response 59 | callback(null, { 60 | success: true, 61 | username: username, 62 | ttl: context.TOKEN_TTL, 63 | sync_token: getSyncToken(context, username), 64 | twiml_app_token: getTwimlAppToken(context), 65 | }); 66 | }; 67 | -------------------------------------------------------------------------------- /runtime/Authenticator/descriptor.yaml: -------------------------------------------------------------------------------- 1 | type: function 2 | name: Authenticator 3 | description: | 4 | Generate short-term jwt token for admins to use UI application. 5 | path: /authenticate 6 | script: Authenticator.js 7 | includes: 8 | - ../Common/Authorization.js 9 | -------------------------------------------------------------------------------- /runtime/Authenticator/spec/main.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const chai = require('chai'); 3 | const expect = chai.expect; 4 | const assert = chai.assert; 5 | const TwilioRuntimeHelper = require("TwilioRuntimeHelper"); 6 | const jwt = require("jwt-simple"); 7 | 8 | // hard coded values required: 9 | // TOKEN_TTL = 3600 10 | // twilio: 928462 11 | const contextFile = path.resolve(__dirname, "../../context-test.yaml"); 12 | const descriptorFile = path.resolve(__dirname, "../descriptor.yaml"); 13 | 14 | describe('Authenticator main test cases', function () { 15 | it('return valid jwt token on correct pincode', function (done) { 16 | TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "928462"}, function (err, result) { 17 | expect(result.success).to.true; 18 | expect(result.username).to.equal("twilio"); 19 | let sync_token = jwt.decode(result.sync_token, null, true /* noVerify */); 20 | expect(sync_token.grants.data_sync).to.not.equal.null; 21 | expect(sync_token.exp - sync_token.iat).to.equal(3600); 22 | done(); 23 | }) 24 | }); 25 | 26 | it('fail on incorrect pincode', function (done) { 27 | TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "666666"}, function (err, result) { 28 | expect(result.success).to.false; 29 | done(); 30 | }); 31 | }); 32 | 33 | it('fail on missing username', function (done) { 34 | TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {pincode: "666666"}, function (err, result) { 35 | expect(result.success).to.false; 36 | done(); 37 | }); 38 | }); 39 | 40 | it('fail on missing pincode', function (done) { 41 | TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio"}, function (err, result) { 42 | expect(result.success).to.false; 43 | done(); 44 | }); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /runtime/Authenticator/specs.js: -------------------------------------------------------------------------------- 1 | require("./spec/main.js"); 2 | -------------------------------------------------------------------------------- /runtime/Authenticator/testdata/invalid.yaml: -------------------------------------------------------------------------------- 1 | username: "twilio" 2 | -------------------------------------------------------------------------------- /runtime/Authenticator/testdata/simple.yaml: -------------------------------------------------------------------------------- 1 | username: "twilio" 2 | pincode: "928462" 3 | -------------------------------------------------------------------------------- /runtime/FleetManager/FleetManager.js: -------------------------------------------------------------------------------- 1 | global.Authorization = { 2 | auth: function (context, username, pincode) { 3 | var pincodes = JSON.parse(context.PINCODES); 4 | return pincodes[username] === pincode; 5 | } 6 | }; 7 | 8 | var AccessToken = Twilio.jwt.AccessToken; 9 | 10 | exports.handler = function(context, event, callback) { 11 | //let client = context.getTwilioClient(); // this returns a wrong version of Twilio, waiting for the fix 12 | let client = new Twilio(context.ACCOUNT_SID, context.AUTH_TOKEN); 13 | let DeployedDevices = client.preview.deployed_devices; 14 | let username = event.username; 15 | let pincode = event.pincode; 16 | 17 | if (!username) return callback(null, { success: false, error: "username is not defined in event" }); 18 | if (!pincode) return callback(null, { success: false, error: "pincode is not defined in event" }); 19 | if (!Authorization.auth(context, username, pincode)) return callback(null, { success: false, error: "username or token provided is invalid" }); 20 | 21 | let op = event.op; 22 | 23 | switch (op) { 24 | case 'list': { 25 | DeployedDevices.fleets(context.FLEET_SID).devices.list() 26 | .then(function (response) { 27 | callback(null, { success: true, vehicles: response }); 28 | }) 29 | .catch(function (error) { 30 | callback(null, { success: false, error: error.toString() }); 31 | }); 32 | } 33 | break; 34 | case 'add': { 35 | let vehicle_id = event.vehicle_id; 36 | if (!vehicle_id) return callback(null, { success: false, error: "vehicle_id is not defined in event" }); 37 | if (!vehicle_id.match(/^[a-zA-Z0-9-]+$/)) return callback(null, { success: false, error: "Invalid vehicle id (use english alphabet and numbers only): " + vehicle_id }); 38 | let vehicle_name = event.vehicle_name; 39 | if (!vehicle_name) return callback(null, { success: false, error: "vehicle_name is not defined in event" }); 40 | let result = { success: true }; 41 | DeployedDevices.fleets(context.FLEET_SID).devices.create({ 42 | friendlyName: vehicle_name, 43 | uniqueName: vehicle_id 44 | }) 45 | .then(function (response) { 46 | result.vehicle = response; 47 | return DeployedDevices.fleets(context.FLEET_SID).keys.create({ 48 | deviceSid: response.sid 49 | }) 50 | }) 51 | .then(function (response) { 52 | result.key = response; 53 | callback(null, result); 54 | }) 55 | .catch(function (error) { 56 | if (error) return callback(null, { success: false, error: error.toString() }); 57 | }); 58 | } 59 | break; 60 | case 'delete': { 61 | let vehicle_id = event.vehicle_id; 62 | if (!vehicle_id) return callback(null, { success: false, error: "vehicle_id is not defined in event" }); 63 | DeployedDevices.fleets(context.FLEET_SID).devices(vehicle_id).remove() 64 | .then(function () { 65 | callback(null, { success: true }); 66 | }) 67 | .catch(function (error) { 68 | callback(null, { success: false, error: error.toString() }); 69 | }); 70 | } 71 | break; 72 | case 'genkey': { 73 | let vehicle_id = event.vehicle_id; 74 | if (!vehicle_id) return callback(null, { success: false, error: "vehicle_id is not defined in event" }); 75 | DeployedDevices.fleets(context.FLEET_SID).devices(vehicle_id).fetch() 76 | .then(function (response) { 77 | return DeployedDevices.fleets(context.FLEET_SID).keys.create({ 78 | deviceSid: response.sid 79 | }); 80 | }) 81 | .then(function (response) { 82 | callback(null, { success: true, vehicle_id: vehicle_id, key: response }); 83 | }) 84 | .catch(function (error) { 85 | callback(null, { success: false, error: error.toString() }); 86 | }); 87 | } 88 | break; 89 | default: 90 | return callback(null, { 91 | success: false, 92 | error: "Unknown operation request: " + op 93 | }); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /runtime/FleetManager/descriptor.yaml: -------------------------------------------------------------------------------- 1 | type: function 2 | name: FleetManager 3 | description: | 4 | Operations for managing the fleet. 5 | path: /fleetmanager 6 | script: FleetManager.js 7 | includes: 8 | - ../Common/Authorization.js 9 | -------------------------------------------------------------------------------- /runtime/FleetManager/spec/main.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const chai = require('chai'); 3 | const expect = chai.expect; 4 | const assert = chai.assert; 5 | const TwilioRuntimeHelper = require("TwilioRuntimeHelper"); 6 | 7 | // hard coded values required: 8 | // TOKEN_TTL = 3600 9 | // twilio: 928462 10 | const contextFile = path.resolve(__dirname, "../../context-test.yaml"); 11 | const descriptorFile = path.resolve(__dirname, "../descriptor.yaml"); 12 | 13 | function randomString() { 14 | return Math.random().toString(36).slice(2); 15 | } 16 | 17 | describe('FleetManager main test cases', function () { 18 | before(function (done) { 19 | TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "928462", op: "list"}) 20 | .then(function(data) { 21 | let promises = []; 22 | data.vehicles.forEach(function (v) { 23 | console.log("deleting old vehicle: " + v.uniqueName); 24 | promises.push(TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "928462", op: "delete", vehicle_id: v.uniqueName})); 25 | }); 26 | return Promise.all(promises); 27 | }) 28 | .then(() => { console.log("done before()"); done(); }) 29 | .catch(done); 30 | }); 31 | 32 | it('add/list/genkey/delete ops', function (done) { 33 | let oldKey = null; 34 | let vehicleId = randomString(); 35 | let vehicleSid; 36 | console.log("creating new vehicle: " + vehicleId); 37 | TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "928462", op: "add", vehicle_id: vehicleId, vehicle_name: "BMW-" + vehicleId}) 38 | .then((data) => { 39 | expect(data.success).to.be.true; 40 | expect(data.vehicle.uniqueName).to.equal(vehicleId); 41 | expect(data.key.secret).to.be.a('string'); 42 | oldKey = data.key; 43 | console.log("listing vehicles and find created one"); 44 | return TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "928462", op: "list"}); 45 | }) 46 | .then((data) => { 47 | expect(data.success).to.be.true; 48 | let vehicle = data.vehicles.find((v) => v.uniqueName === vehicleId); 49 | vehicleSid = vehicle.sid; 50 | expect(vehicle).to.not.be.an('undefined'); 51 | console.log("generate new key for created vehicle"); 52 | return TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "928462", op: "genkey", vehicle_id: vehicleId}); 53 | }) 54 | .then((data) => { 55 | expect(data.success).to.be.true; 56 | expect(data.key.deviceSid).to.equal(vehicleSid); 57 | expect(data.key.secret).to.be.a('string'); 58 | expect(oldKey.sid).to.not.equal(data.key.sid); 59 | console.log("delete created vehicle"); 60 | return TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "928462", op: "delete", vehicle_id: vehicleId}); 61 | }) 62 | .then((data) => { 63 | expect(data.success).to.be.true; 64 | done(); 65 | }) 66 | .catch(done); 67 | }); 68 | 69 | it('add with wrong pincode', function (done) { 70 | TwilioRuntimeHelper.runTestDataJSON(contextFile, descriptorFile, {username: "twilio", pincode: "66666", op: "add", vehicle_id: "bogus", vehicle_name: "BMW-bogus"}) 71 | .then((data) => { 72 | expect(data.success).to.be.false; 73 | done(); 74 | }) 75 | .catch(done); 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /runtime/FleetManager/specs.js: -------------------------------------------------------------------------------- 1 | require("./spec/main.js"); 2 | -------------------------------------------------------------------------------- /runtime/FleetManager/testdata/add.yaml: -------------------------------------------------------------------------------- 1 | username: "twilio" 2 | pincode: "928462" 3 | op: add 4 | vehicle_id: EE888RUS 5 | vehicle_name: Vladimir Putin 6 | -------------------------------------------------------------------------------- /runtime/FleetManager/testdata/delete.yaml: -------------------------------------------------------------------------------- 1 | username: "twilio" 2 | pincode: "928462" 3 | op: delete 4 | vehicle_id: EE888RUS 5 | -------------------------------------------------------------------------------- /runtime/FleetManager/testdata/genkey.yaml: -------------------------------------------------------------------------------- 1 | username: "twilio" 2 | pincode: "928462" 3 | op: genkey 4 | vehicle_id: EE888RUS 5 | -------------------------------------------------------------------------------- /runtime/FleetManager/testdata/list.yaml: -------------------------------------------------------------------------------- 1 | username: "twilio" 2 | pincode: "928462" 3 | op: list 4 | -------------------------------------------------------------------------------- /runtime/README.md: -------------------------------------------------------------------------------- 1 | # Industrial Sensor Blueprint 2 | ### Twilio Functions scripts 3 | The scripts located in this directory are meant to run on [Twilio Functions](https://www.twilio.com/functions). 4 | 5 | ### What is Functions? 6 | Serverless architecture is a software design pattern where applications are hosted by a third-party service, eliminating the need for server software and hardware management by the developer. Applications are broken up into individual functions that can be invoked and scaled individually. 7 | 8 | ### What is Twilio Runtime? 9 | Twilio Runtime is a suite designed to help you build, scale and operate your application, consisting of a plethora of tools including helper libraries, API keys, asset storage, debugging tools, and a node based serverless hosting environment [Twilio Functions](https://www.twilio.com/docs/api/runtime/functions). 10 | 11 | 12 | #### (Bonus step) Enable voice dialer 13 | In the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/), there is a required step to set up a [TwiML App](https://www.twilio.com/console/voice/runtime/twiml-apps). The TwiML app can be used to enable a browser-initiated voice call feature that is disabled in the front-end code. To enable the dialer feature, search for any commented out code (in the angular folder) dealing with mobile phone numbers and dialing. The final step is to upload (simpledialer.js)[simpledialer.js] to [Twilio Functions](https://www.twilio.com/docs/api/runtime/functions) and link the ***Voice input field*** in your [TwiML App](https://www.twilio.com/console/voice/runtime/twiml-apps) to your newly created Function, and finally, make sure you enter a valid number when you create a Fleet Tracker. 14 | 15 | Full instructions for this tutorial can be found in the [Fleet Tracker Blueprint](https://www.twilio.com/wireless/blueprints/fleet-tracker/). Below you will find the minimum steps necessary to get this up and running. -------------------------------------------------------------------------------- /runtime/example-context.yaml: -------------------------------------------------------------------------------- 1 | # required field 2 | ACCOUNT_SID: AC00000000000000000000000000000000 3 | AUTH_TOKEN: 00000 4 | 5 | # common 6 | API_KEY: SK00000000000000000000000000000000 7 | API_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 8 | PINCODES: 9 | twilio: "928462" 10 | 11 | # Authenticator 12 | SYNC_SERVICE_SID: IS000000000000000000000000000000 13 | TWIML_APP_SID: AP000000000000000000000000000000 14 | TOKEN_TTL: 3600 # in seconds 15 | 16 | # FleetManager 17 | FLEET_SID: FL0000000000000000000000000 18 | -------------------------------------------------------------------------------- /runtime/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twilio-fleet-tracker-runtime", 3 | "version": "1.0.0", 4 | "description": "Tracking your fleet with twilio wireless SIM card and connected devices services. This package include its runtime functions.", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "twilio-runtime-exec ./node_modules/.bin/mocha --timeout 20000 specs.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/twilio/wireless-co-pilot.git" 12 | }, 13 | "keywords": [ 14 | "twilio", 15 | "twilio-sync", 16 | "iot" 17 | ], 18 | "author": "zmiao@twilio.com", 19 | "license": "ISC", 20 | "bugs": { 21 | "url": "https://github.com/twilio/wireless-co-pilot/issues" 22 | }, 23 | "homepage": "https://github.com/twilio/wireless-co-pilot#readme", 24 | "devDependencies": { 25 | "chai": "^3.5.0", 26 | "jwt-simple": "^0.5.1", 27 | "mocha": "^3.4.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /runtime/simpledialer.js: -------------------------------------------------------------------------------- 1 | exports.handler = function(context, event, callback) { 2 | let twiml = new Twilio.twiml.VoiceResponse(); 3 | twiml.dial({ 4 | callerId: "???" 5 | }, event.number); 6 | callback(null, twiml); 7 | }; 8 | -------------------------------------------------------------------------------- /runtime/specs.js: -------------------------------------------------------------------------------- 1 | require("./Authenticator/specs.js"); 2 | require("./FleetManager/specs.js"); 3 | --------------------------------------------------------------------------------